Browse Source

Doorsensor von Dohle

master
Johannes Krug 4 years ago
parent
commit
2190f5e362
100 changed files with 25604 additions and 0 deletions
  1. 96
    0
      arduino/Doorsensor_Dohle/doorsensor/doorsensor.ino
  2. 1
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/CONTRIBUTING.md
  3. 23
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/doxygen.sh
  4. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/KGSecondChancesSketch.ttf
  5. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/KGSecondChancesSolid.ttf
  6. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/RobotoCondensed-Regular-webfont.eot
  7. 644
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/RobotoCondensed-Regular-webfont.svg
  8. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/RobotoCondensed-Regular-webfont.ttf
  9. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/RobotoCondensed-Regular-webfont.woff
  10. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/RobotoCondensed-Regular.ttf
  11. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessketch-webfont.eot
  12. 668
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessketch-webfont.svg
  13. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessketch-webfont.ttf
  14. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessketch-webfont.woff
  15. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessolid-webfont.eot
  16. 668
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessolid-webfont.svg
  17. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessolid-webfont.ttf
  18. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessolid-webfont.woff
  19. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/alicenbob.png
  20. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/alicenfriends.png
  21. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/alicenfriends2.png
  22. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/signingillustrated1.png
  23. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/signingillustrated2.gif
  24. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/signingillustrated2.png
  25. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/signingsequence.png
  26. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/wiring.png
  27. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/logo.png
  28. 44
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/mainpage.dox
  29. BIN
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/plantuml.jar
  30. 194
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/styles/DoxygenLayout.xml
  31. 20
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/styles/html/footerFile.html
  32. 55
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/styles/html/headerFile.html
  33. 1430
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/styles/html/styleSheetFile.css
  34. 2295
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Doxyfile
  35. 154
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Makefile
  36. 1074
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/MyASM.S
  37. 2347
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/MyConfig.h
  38. 456
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/MySensors.h
  39. 17
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/README.md
  40. 701
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/configure
  41. 244
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyCapabilities.h
  42. 92
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyEepromAddresses.h
  43. 69
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyGatewayTransport.cpp
  44. 120
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyGatewayTransport.h
  45. 502
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyGatewayTransportEthernet.cpp
  46. 294
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyGatewayTransportMQTTClient.cpp
  47. 82
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyGatewayTransportSerial.cpp
  48. 72
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyInclusionMode.cpp
  49. 33
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyInclusionMode.h
  50. 52
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyIndication.cpp
  51. 80
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyIndication.h
  52. 119
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyLeds.cpp
  53. 59
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyLeds.h
  54. 323
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyMessage.cpp
  55. 534
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyMessage.h
  56. 287
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyOTAFirmwareUpdate.cpp
  57. 197
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyOTAFirmwareUpdate.h
  58. 157
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyOTALogging.cpp
  59. 73
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyOTALogging.h
  60. 61
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyPrivateConfig.h.sample
  61. 34
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyProtocol.h
  62. 208
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyProtocolMySensors.cpp
  63. 763
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySensorsCore.cpp
  64. 469
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySensorsCore.h
  65. 585
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySigning.cpp
  66. 896
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySigning.h
  67. 374
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySigningAtsha204.cpp
  68. 393
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySigningAtsha204Soft.cpp
  69. 52
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySplashScreen.cpp
  70. 28
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySplashScreen.h
  71. 1182
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyTransport.cpp
  72. 533
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyTransport.h
  73. 65
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/Version.h
  74. 631
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AES/AES.cpp
  75. 381
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AES/AES.h
  76. 50
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AES/AES_config.h
  77. 91
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AES/README.MD
  78. 7
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AES/keywords.txt
  79. 594
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/ATSHA204/ATSHA204.cpp
  80. 253
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/ATSHA204/ATSHA204.h
  81. 377
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/AltSoftSerial.cpp
  82. 117
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/AltSoftSerial.h
  83. 9
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/README.md
  84. 147
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/config/AltSoftSerial_Boards.h
  85. 187
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/config/AltSoftSerial_Timers.h
  86. 64
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/docs/issue_template.md
  87. 40
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/examples/Echo/Echo.ino
  88. 56
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/examples/ReceiveTest/ReceiveTest.ino
  89. 97
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/examples/ShowConfiguration/ShowConfiguration.ino
  90. 4
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/keywords.txt
  91. 80
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/BCM.cpp
  92. 92
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/BCM.h
  93. 167
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/RPi.cpp
  94. 82
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/RPi.h
  95. 110
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/SPIBCM.cpp
  96. 262
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/SPIBCM.h
  97. 213
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/Wire.cpp
  98. 94
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/Wire.h
  99. 1480
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/bcm2835.c
  100. 0
    0
      arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/bcm2835.h

+ 96
- 0
arduino/Doorsensor_Dohle/doorsensor/doorsensor.ino View File

@@ -0,0 +1,96 @@
#define MY_DEBUG
#define MY_RADIO_NRF24
#define MY_NODE_ID 5

#define CHILD_ID_DOOR 1
#define CHILD_ID_VOLTAGE 2
#define DOOR_SENSOR_PIN 3

int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point

#include <MyConfig.h>
#include <MySensors.h>


/**************************************************/
/****************** CONSTANTS *********************/
/**************************************************/

static const uint64_t UPDATE_INTERVAL = 1800000;
int oldBatteryPcnt = 0;
int oldValue = 0;
float VBAT_PER_BITS = 0.0032551319648094;
float VMIN = 1.9;
float VMAX = 3.24;

/**************************************************/
/****************** VARIABLES *********************/
/**************************************************/


/**************************************************/
/****************** MESSAGES **********************/
/**************************************************/


MyMessage msgDoor(CHILD_ID_DOOR,V_TRIPPED);
MyMessage msgVBat(CHILD_ID_VOLTAGE,V_CUSTOM);


void presentation()
{
present(CHILD_ID_DOOR, S_DOOR);
}


void setup()
{

// use the 1.1 V internal reference
#if defined(__AVR_ATmega2560__)
analogReference(INTERNAL1V1);
#else
analogReference(INTERNAL);
#endif
pinMode(DOOR_SENSOR_PIN,INPUT);
}


void loop()
{
sleep(digitalPinToInterrupt(DOOR_SENSOR_PIN),CHANGE, UPDATE_INTERVAL);
motion_on();
getBatteryLevel();
}



/**************************************************/
/**************** AUX. FUNCTIONS ******************/
/**************************************************/
void getBatteryLevel()
{
// Battery monitoring reading
int sensorValue = analogRead(BATTERY_SENSE_PIN);
delay(500);

// Calculate the battery in %
float Vbat = sensorValue * VBAT_PER_BITS;
send(msgVBat.set(Vbat, 3));
int batteryPcnt = static_cast<int>(((Vbat - VMIN) / (VMAX - VMIN))*100.);
if (batteryPcnt > 100) {
batteryPcnt = 100;
}
sendBatteryLevel(batteryPcnt);
}

void motion_on()
{
bool tripped = digitalRead(DOOR_SENSOR_PIN) == LOW;
send(msgDoor.set(tripped?"0":"1")); // Send tripped value to gw
}

+ 1
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/CONTRIBUTING.md View File

@@ -0,0 +1 @@
<a href="https://www.mysensors.org/download/contributing">MySensors Code Contribution Guidelines</a>

+ 23
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/doxygen.sh View File

@@ -0,0 +1,23 @@
#!/bin/bash
## Invoke from project root, e.g Documentation/doxygen.sh

# Generate doxygen file for Raspberry Pi configure command
echo -e "/**\n * @defgroup RaspberryPiGateway Raspberry Pi Gateway\n * @ingroup MyConfigGrp\n * @brief Configuration options for the Raspberry Pi Gateway\n@{\n@verbatim" > configure.h
./configure --help >> configure.h
echo -e "@endverbatim\n@}*/\n" >> configure.h

# Generate version information
export PROJECTNUMBER=$(git fetch --tags; git describe --tags;)

# Generate any UML diagrams in the code tree that has the proper tags
export PLANTUML_JAR_PATH=Documentation/plantuml.jar
java -Djava.awt.headless=true -jar $PLANTUML_JAR_PATH -failfast2 -nbthread auto -o "$PWD/Documentation/img" "./**.(c|cpp|dox|h|hpp|ino)"

# Launch Doxygen (assumed to be in the PATH)
doxygen

# Show any warnings created
cat doxygen.log

# Clean up autogenerated (temporary) artifacts
rm configure.h

BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/KGSecondChancesSketch.ttf View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/KGSecondChancesSolid.ttf View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/RobotoCondensed-Regular-webfont.eot View File


+ 644
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/RobotoCondensed-Regular-webfont.svg View File

@@ -0,0 +1,644 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata></metadata>
<defs>
<font id="roboto_condensedregular" horiz-adv-x="995" >
<font-face units-per-em="2048" ascent="1638" descent="-410" />
<missing-glyph horiz-adv-x="446" />
<glyph unicode="&#xfb01;" horiz-adv-x="1025" d="M29 937v145h141v111q0 186 97.5 287t271.5 101q62 0 124.5 -15.5t135.5 -44.5l-31 -158q-50 22 -102 35.5t-113 13.5q-92 0 -136 -55t-44 -164v-111h183v-145h-183v-937h-203v937h-141zM692 0v1082h203v-1082h-203z" />
<glyph horiz-adv-x="0" />
<glyph unicode="&#xd;" horiz-adv-x="446" />
<glyph horiz-adv-x="0" />
<glyph horiz-adv-x="0" />
<glyph horiz-adv-x="16" />
<glyph unicode="&#x9;" horiz-adv-x="16" />
<glyph unicode=" " horiz-adv-x="446" />
<glyph unicode="&#x09;" horiz-adv-x="446" />
<glyph unicode="&#xa0;" horiz-adv-x="446" />
<glyph unicode="!" horiz-adv-x="474" d="M136 0v204h204v-204h-204zM136 485v971h203v-971h-203z" />
<glyph unicode="&#x22;" horiz-adv-x="589" d="M83 1057l1 245v258h152v-249l-56 -254h-97zM354 1057l1 252v251h152v-249l-57 -254h-96z" />
<glyph unicode="#" horiz-adv-x="1069" d="M57 410v130h217l58 368h-211v132h231l66 416h138l-65 -416h192l66 416h138l-65 -416h179v-132h-200l-57 -368h194v-130h-214l-64 -410h-139l64 410h-192l-64 -410h-139l64 410h-197zM413 540h192l58 368h-193z" />
<glyph unicode="$" horiz-adv-x="1000" d="M93 432h202q0 -158 60.5 -226t149.5 -68q93 0 145.5 64t52.5 168q0 96 -47 158.5t-159 116.5q-179 70 -268 167.5t-89 269.5q0 163 86 267.5t233 123.5v212h131v-214q145 -24 228 -142.5t83 -314.5h-203q0 136 -48.5 219.5t-131.5 83.5q-87 0 -131.5 -65t-44.5 -168 q0 -98 45 -158t164 -117q179 -73 266.5 -169.5t87.5 -267.5q0 -168 -88.5 -269t-242.5 -120v-193h-130v193q-153 17 -252 126t-99 323z" />
<glyph unicode="%" horiz-adv-x="1350" d="M97 1099v77q0 128 72.5 214.5t197.5 86.5q126 0 198.5 -86.5t72.5 -214.5v-77q0 -128 -72 -213.5t-197 -85.5q-126 0 -199 85.5t-73 213.5zM240 1099q0 -74 33.5 -126.5t95.5 -52.5q60 0 93 52t33 127v77q0 75 -33.5 128t-94.5 53t-94 -53t-33 -128v-77zM309 176 l601 1138l104 -63l-601 -1138zM720 279v78q0 127 73 213.5t198 86.5q126 0 198.5 -86t72.5 -214v-78q0 -129 -72.5 -214.5t-196.5 -85.5q-126 0 -199.5 86t-73.5 214zM864 279q0 -74 34.5 -127t94.5 -53q63 0 94.5 51.5t31.5 128.5v78q0 76 -33.5 128t-94.5 52t-94 -52 t-33 -128v-78z" />
<glyph unicode="&#x26;" horiz-adv-x="1172" d="M67 383q0 121 62.5 213.5t185.5 188.5q-68 98 -101 177.5t-33 162.5q0 166 89.5 259t242.5 93q139 0 225 -89.5t86 -218.5q0 -96 -44 -168t-125 -137l-104 -86l293 -393l6 1q31 58 48.5 131.5t17.5 157.5h165q0 -131 -32 -240t-97 -195l179 -240h-237l-77 104 q-75 -61 -158 -93t-175 -32q-191 0 -304 111.5t-113 292.5zM272 388q0 -110 58 -182.5t160 -72.5q62 0 123 23.5t114 68.5l-320 433l-23 -19q-67 -72 -89.5 -134.5t-22.5 -116.5zM373 1127q0 -51 22.5 -105.5t66.5 -120.5l104 82q50 40 68.5 84t18.5 97q0 64 -38 110.5 t-102 46.5q-67 0 -103.5 -55.5t-36.5 -138.5z" />
<glyph unicode="'" horiz-adv-x="319" d="M82 1055l1 266v239h150v-226l-55 -279h-96z" />
<glyph unicode="(" horiz-adv-x="602" d="M117 574v16q0 379 130.5 660.5t283.5 372.5h6l37 -108q-112 -102 -193.5 -344t-81.5 -579v-20q0 -337 81.5 -578t193.5 -349l-37 -102h-6q-154 92 -284 369.5t-130 661.5z" />
<glyph unicode=")" horiz-adv-x="606" d="M25 -355q110 102 192.5 346t82.5 581v20q0 333 -84.5 578.5t-190.5 350.5l38 102h6q154 -91 287.5 -374t133.5 -659v-16q0 -380 -133 -660t-288 -371h-6z" />
<glyph unicode="*" horiz-adv-x="806" d="M32 1080l44 140l268 -119l-11 355h145l-12 -361l262 121l44 -141l-274 -100l179 -278l-118 -87l-162 295l-159 -289l-118 84l181 284z" />
<glyph unicode="+" horiz-adv-x="1023" d="M67 600v174h342v432h198v-432h342v-174h-342v-454h-198v454h-342z" />
<glyph unicode="," horiz-adv-x="397" d="M53 -271l59 302v183h189v-190l-127 -295h-121z" />
<glyph unicode="-" horiz-adv-x="598" d="M73 542v155h446v-155h-446z" />
<glyph unicode="." horiz-adv-x="497" d="M137 0v203h204v-203h-204z" />
<glyph unicode="/" horiz-adv-x="693" d="M9 -125l482 1581h159l-482 -1581h-159z" />
<glyph unicode="0" horiz-adv-x="1002" d="M96 563v329q0 281 109 433t295 152t295.5 -152t109.5 -433v-329q0 -283 -108.5 -433.5t-294.5 -150.5q-187 0 -296.5 151t-109.5 433zM299 535q0 -198 52.5 -300t150.5 -102q97 0 149 101.5t52 300.5v386q0 198 -52.5 299t-150.5 101t-149.5 -101.5t-51.5 -298.5v-386z " />
<glyph unicode="1" horiz-adv-x="1000" d="M143 1234v131l487 92v-1459h-202v1255z" />
<glyph unicode="2" horiz-adv-x="1000" d="M82 1028q-4 189 107 319t304 130q178 0 281.5 -112.5t103.5 -297.5q0 -125 -63.5 -246.5t-184.5 -271.5l-275 -395h563v-154h-817v135l400 526q97 137 135.5 226.5t38.5 173.5q0 115 -48.5 187.5t-133.5 72.5q-107 0 -160.5 -80t-53.5 -218h-195z" />
<glyph unicode="3" horiz-adv-x="1000" d="M79 386l3 6h194q0 -115 57 -187t150 -72q98 0 153.5 69.5t55.5 197.5q0 136 -53 200.5t-160 64.5h-139v153h139q101 0 147.5 67.5t46.5 182.5q0 118 -48.5 185.5t-141.5 67.5q-85 0 -139.5 -67.5t-54.5 -177.5h-193l-3 6q-4 169 106 282t280 113q180 0 288 -107.5 t108 -303.5q0 -97 -51 -185.5t-145 -134.5q110 -41 163 -132.5t53 -211.5q0 -198 -116.5 -310.5t-298.5 -112.5q-170 0 -287.5 107.5t-113.5 299.5z" />
<glyph unicode="4" horiz-adv-x="1000" d="M56 456l529 1000h208v-959h156v-155h-156v-342h-202v342h-529zM256 497h335v665l-6 1l-20 -42z" />
<glyph unicode="5" horiz-adv-x="1000" d="M121 382l2 5l191 4q0 -124 52.5 -191t138.5 -67q99 0 149 87.5t50 242.5q0 146 -52 234.5t-149 88.5q-86 0 -128.5 -37.5t-59.5 -111.5l-175 17l70 802h653v-167h-484l-38 -432q37 38 86 62.5t112 26.5q172 2 270 -127.5t98 -353.5q0 -217 -102.5 -351.5t-299.5 -134.5 q-164 0 -276 104t-108 299z" />
<glyph unicode="6" horiz-adv-x="1000" d="M107 558v316q0 271 135 437t339 166q66 0 127 -17t111 -46l-39 -149q-45 27 -91 41t-107 14q-122 0 -197.5 -117.5t-75.5 -314.5v-41q50 57 118 88.5t149 31.5q165 0 260.5 -136t95.5 -349q0 -220 -110 -361.5t-288 -141.5q-187 0 -307 153t-120 426zM309 546 q0 -196 63 -305t162 -109q90 0 143 101.5t53 248.5q0 148 -54.5 242t-149.5 94q-77 0 -132.5 -37t-84.5 -101v-134z" />
<glyph unicode="7" horiz-adv-x="1000" d="M66 1300v156h850v-156q-209 -278 -286.5 -532.5t-109.5 -628.5l-13 -139h-202l12 139q33 352 131.5 634t270.5 527h-653z" />
<glyph unicode="8" horiz-adv-x="1000" d="M89 392q0 123 63 216.5t171 138.5q-94 42 -148 128.5t-54 200.5q0 191 104 296t274 105q169 0 275 -105t106 -296q0 -115 -55 -201.5t-149 -128.5q107 -45 170.5 -138.5t63.5 -215.5q0 -200 -113.5 -306.5t-295.5 -106.5q-185 0 -298.5 106.5t-113.5 306.5zM292 399 q0 -125 56.5 -195.5t152.5 -70.5q91 0 149 71t58 195q0 120 -59 195.5t-150 75.5q-92 0 -149.5 -75t-57.5 -196zM324 1071q0 -113 48 -180t129 -67q79 0 127 67t48 180q0 110 -49 180t-128 70q-80 0 -127.5 -67.5t-47.5 -182.5z" />
<glyph unicode="9" horiz-adv-x="1000" d="M78 957q0 223 114.5 371.5t283.5 148.5q189 0 303.5 -144t114.5 -415v-380q0 -266 -126 -412.5t-325 -146.5q-62 0 -130 15.5t-126 44.5l27 148q53 -29 107.5 -41.5t121.5 -12.5q111 0 179.5 102.5t68.5 295.5v71q-42 -71 -103 -107.5t-133 -36.5q-174 0 -275.5 134.5 t-101.5 364.5zM281 957q0 -154 51.5 -250.5t143.5 -96.5q78 0 132.5 44.5t82.5 114.5v169q0 188 -56 285.5t-156 97.5q-85 0 -141.5 -105t-56.5 -259z" />
<glyph unicode=":" horiz-adv-x="476" d="M137 0v203h204v-203h-204zM137 878v203h204v-203h-204z" />
<glyph unicode=";" horiz-adv-x="470" d="M91 -271l59 302v183h189v-190l-127 -295h-121zM134 879v203h204v-203h-204z" />
<glyph unicode="&#x3c;" horiz-adv-x="898" d="M61 477v151l711 374v-192l-496 -243l-64 -14v-6l64 -14l496 -240v-192z" />
<glyph unicode="=" horiz-adv-x="1003" d="M130 390v160h732v-160h-732zM130 808v160h732v-160h-732z" />
<glyph unicode="&#x3e;" horiz-adv-x="916" d="M114 101v189l516 247l63 13v6l-63 15l-516 243v188l731 -374v-151z" />
<glyph unicode="?" horiz-adv-x="857" d="M49 1109q-3 173 100.5 270.5t266.5 97.5q177 0 277.5 -105t100.5 -286q0 -130 -60.5 -236t-160.5 -209q-49 -51 -61.5 -97.5t-12.5 -135.5h-203q1 133 28 191t121 151q71 90 108.5 162.5t37.5 170.5q0 110 -45.5 171.5t-129.5 61.5q-70 0 -120 -56.5t-50 -156.5h-195z M295 0v198h208v-198h-208z" />
<glyph unicode="@" horiz-adv-x="1635" d="M89 478q16 425 223 684.5t544 259.5q340 0 520 -245t166 -668q-8 -216 -109.5 -373t-301.5 -157q-69 0 -118 45t-68 127q-43 -86 -104 -128.5t-142 -42.5q-119 0 -182.5 120t-47.5 316q21 255 125 409.5t252 154.5q96 0 154.5 -26.5t128.5 -80.5l-3 -3h5l-46 -577 q-7 -115 17 -157.5t63 -42.5q108 0 172.5 117t72.5 299q15 376 -124.5 586t-433.5 210q-272 0 -438.5 -227t-178.5 -600q-16 -370 132.5 -590.5t425.5 -220.5q77 0 157 21t136 55l32 -107q-59 -42 -150.5 -65.5t-178.5 -23.5q-343 0 -529.5 249.5t-170.5 681.5zM637 416 q-10 -142 18.5 -221.5t92.5 -79.5q56 0 102 31t83 112v14.5t2 20.5l42 536q-24 11 -49 17.5t-51 6.5q-106 0 -164.5 -109t-75.5 -328z" />
<glyph unicode="A" horiz-adv-x="1137" d="M27 0l448 1456h196l444 -1456h-206l-106 368h-464l-106 -368h-206zM386 529h371l-182 636h-6z" />
<glyph unicode="B" horiz-adv-x="1122" d="M141 0v1456h406q206 0 321.5 -98t115.5 -294q0 -104 -52.5 -183.5t-145.5 -116.5q118 -26 181.5 -123.5t63.5 -228.5q0 -201 -113.5 -306.5t-313.5 -105.5h-463zM344 154h260q108 0 166.5 66.5t58.5 190.5q0 123 -50 195.5t-154 72.5h-281v-525zM344 825h223 q100 0 157 60.5t57 174.5q0 120 -59.5 180t-174.5 60h-203v-475z" />
<glyph unicode="C" horiz-adv-x="1084" d="M94 525v404q0 258 126.5 403t337.5 145q214 0 329 -117t118 -342l-3 -6h-192q-3 159 -63 234t-189 75q-125 0 -194 -101t-69 -288v-407q0 -190 70.5 -291t198.5 -101q126 0 184.5 73.5t60.5 235.5h193l3 -6q-1 -218 -116 -337.5t-325 -119.5q-214 0 -342 144t-128 402z " />
<glyph unicode="D" horiz-adv-x="1154" d="M141 0v1456h400q232 0 378.5 -175t146.5 -450v-207q0 -276 -146.5 -450t-378.5 -174h-400zM344 154h190q153 0 241.5 131t88.5 339v209q0 206 -88.5 336.5t-241.5 130.5h-190v-1146z" />
<glyph unicode="E" horiz-adv-x="1018" d="M141 0v1456h823v-156h-620v-469h540v-155h-540v-522h626v-154h-829z" />
<glyph unicode="F" horiz-adv-x="1020" d="M141 0v1456h831v-156h-628v-498h541v-155h-541v-647h-203z" />
<glyph unicode="G" horiz-adv-x="1198" d="M102 514v432q0 253 133 392t353 139q223 0 341 -112.5t126 -315.5l-2 -6h-192q-5 136 -71.5 207t-198.5 71q-133 0 -210 -95.5t-77 -277.5v-434q0 -186 82.5 -283.5t224.5 -97.5q104 0 161.5 35.5t85.5 90.5v331h-249v147h452v-530q-50 -88 -162.5 -158t-287.5 -70 q-229 0 -369 139t-140 396z" />
<glyph unicode="H" horiz-adv-x="1246" d="M141 0v1456h203v-659h558v659h202v-1456h-202v642h-558v-642h-203z" />
<glyph unicode="I" horiz-adv-x="513" d="M155 0v1456h202v-1456h-202z" />
<glyph unicode="J" horiz-adv-x="989" d="M63 402l3 6h195q0 -138 53.5 -206.5t146.5 -68.5q82 0 136 77t54 207v1039h202v-1039q0 -201 -110 -319.5t-282 -118.5q-185 0 -293 107q-105 104 -105 301v15z" />
<glyph unicode="K" horiz-adv-x="1131" d="M141 0v1456h203v-640h121l385 640h242l-458 -691l493 -765h-248l-396 653h-139v-653h-203z" />
<glyph unicode="L" horiz-adv-x="951" d="M141 0v1456h203v-1302h568v-154h-771z" />
<glyph unicode="M" horiz-adv-x="1483" d="M136 0v1456h261l340 -1188h6l341 1188h262v-1456h-201v559l18 560l-6 1l-350 -1120h-134l-349 1119l-6 -1l19 -559v-559h-201z" />
<glyph unicode="N" horiz-adv-x="1247" d="M141 0v1456h203l552 -1080l6 2v1078h202v-1456h-202l-552 1083l-6 -2v-1081h-203z" />
<glyph unicode="O" horiz-adv-x="1160" d="M91 527v400q0 258 131.5 404t352.5 146q224 0 358.5 -146t134.5 -404v-400q0 -259 -134 -403.5t-359 -144.5q-222 0 -353 144.5t-131 403.5zM292 527q0 -192 73.5 -291t209.5 -99q140 0 215.5 98.5t75.5 291.5v403q0 190 -76 288.5t-215 98.5q-137 0 -210 -98.5 t-73 -288.5v-403z" />
<glyph unicode="P" horiz-adv-x="1132" d="M141 0v1456h478q204 0 320 -121.5t116 -319.5q0 -199 -116 -320t-320 -121h-275v-574h-203zM344 730h275q115 0 174 80.5t59 202.5q0 124 -58.5 205.5t-174.5 81.5h-275v-570z" />
<glyph unicode="Q" horiz-adv-x="1212" d="M93 527v400q0 258 131.5 404t352.5 146q224 0 358.5 -146t134.5 -404v-400q0 -129 -35 -231t-99 -172l220 -234l-132 -111l-226 245q-50 -23 -105.5 -34t-115.5 -11q-222 0 -353 144.5t-131 403.5zM294 527q0 -192 73.5 -291t209.5 -99q140 0 215.5 98.5t75.5 291.5v403 q0 190 -76 288.5t-215 98.5q-137 0 -210 -98.5t-73 -288.5v-403z" />
<glyph unicode="R" horiz-adv-x="1162" d="M141 0v1455h453q207 0 320 -107t113 -307q0 -114 -52.5 -199t-151.5 -133q109 -37 157.5 -125.5t48.5 -218.5v-127q0 -67 13.5 -124.5t46.5 -90.5v-23h-209q-34 33 -43.5 99.5t-9.5 140.5v123q0 122 -55.5 193t-152.5 71h-275v-627h-203zM344 782h240q123 0 181.5 66.5 t58.5 188.5q0 125 -57 194t-173 69h-250v-518z" />
<glyph unicode="S" horiz-adv-x="1087" d="M83 420l2 6h195q0 -150 78.5 -222t205.5 -72q114 0 178.5 63.5t64.5 170.5q0 103 -58 169t-203 116q-208 63 -319 164.5t-111 268.5q0 172 123.5 282.5t317.5 110.5q201 1 325 -127q120 -124 120 -297v-11l-2 -6h-195q0 127 -65.5 206.5t-184.5 79.5q-113 0 -174.5 -66.5 t-61.5 -169.5q0 -93 66 -156.5t218 -115.5q199 -62 303 -169t104 -277q0 -179 -123 -284t-323 -105q-194 -1 -340 115q-141 112 -141 312v14z" />
<glyph unicode="T" horiz-adv-x="1018" d="M35 1300v156h949v-156h-374v-1300h-203v1300h-372z" />
<glyph unicode="U" horiz-adv-x="1160" d="M117 447v1009h201v-1009q0 -156 70 -235t189 -79q124 0 195 76t71 238v1009h202v-1009q0 -226 -129.5 -347t-338.5 -121q-206 0 -333 121t-127 347z" />
<glyph unicode="V" horiz-adv-x="1119" d="M24 1456h216l296 -1134l20 -85h6l21 84l297 1135h215l-438 -1456h-196z" />
<glyph unicode="W" horiz-adv-x="1551" d="M41 1456h199l197 -1038h6l248 1038h161l251 -1038h6l196 1038h199l-294 -1456h-187l-247 1034h-6l-249 -1034h-187z" />
<glyph unicode="X" horiz-adv-x="1112" d="M48 0l388 735l-378 721h237l258 -568h6l260 568h239l-379 -721l395 -735h-243l-269 582h-6l-268 -582h-240z" />
<glyph unicode="Y" horiz-adv-x="1100" d="M23 1456h227l297 -707h6l298 707h225l-428 -932v-524h-202v537z" />
<glyph unicode="Z" horiz-adv-x="1010" d="M79 0v125l621 1176h-617v155h836v-121l-624 -1181h644v-154h-860z" />
<glyph unicode="[" horiz-adv-x="503" d="M127 -319v1991h353v-153h-148v-1686h148v-152h-353z" />
<glyph unicode="\" horiz-adv-x="736" d="M25 1456h197l515 -1581h-197z" />
<glyph unicode="]" horiz-adv-x="503" d="M17 -167h150v1686h-150v153h355v-1991h-355v152z" />
<glyph unicode="^" horiz-adv-x="758" d="M53 729l253 727h145l252 -727h-170l-143 444l-10 48h-6l-10 -48l-140 -444h-171z" />
<glyph unicode="_" horiz-adv-x="793" d="M10 0h772v-152h-772v152z" />
<glyph unicode="`" horiz-adv-x="591" d="M80 1472l2 5h227l169 -266h-170z" />
<glyph unicode="a" horiz-adv-x="955" d="M84 297q0 155 105.5 243.5t296.5 88.5h151v111q0 99 -44 154.5t-125 55.5q-73 0 -117.5 -50t-44.5 -125l-193 1l-3 6v11q0 117 100 211q105 98 271 98q160 0 259.5 -94.5t99.5 -269.5v-502q0 -63 7.5 -121.5t24.5 -114.5h-205q-11 37 -18 72.5t-9 71.5q-45 -73 -113 -119 t-151 -46q-137 0 -214.5 86.5t-77.5 231.5zM287 298q0 -73 35 -118t100 -45q71 0 129.5 42t85.5 105v221h-154q-93 0 -144.5 -59.5t-51.5 -145.5z" />
<glyph unicode="b" d="M116 0v1560h203v-592q42 65 102 99.5t139 34.5q171 0 264 -137.5t93 -366.5v-147q0 -215 -93 -343.5t-262 -128.5q-85 0 -148.5 37.5t-106.5 110.5l-15 -127h-176zM319 275q27 -66 75 -102.5t117 -36.5q107 0 155.5 85t48.5 230v147q0 156 -49.5 251t-156.5 95 q-68 0 -115.5 -40.5t-74.5 -108.5v-520z" />
<glyph unicode="c" horiz-adv-x="921" d="M75 465v149q0 212 107.5 350t308.5 138q165 0 267 -110q100 -106 99 -273v-10l-3 -6h-182q0 108 -49.5 175.5t-131.5 67.5q-116 0 -164.5 -94t-48.5 -238v-149q0 -146 48.5 -239t165.5 -93q76 0 128 58.5t52 156.5h182l2 -6v-11q0 -146 -104 -247q-108 -105 -260 -105 q-202 0 -309.5 137t-107.5 349z" />
<glyph unicode="d" d="M78 507v21q0 259 93.5 416.5t263.5 157.5q76 0 135.5 -34t102.5 -98v590h202v-1560h-177l-15 124q-43 -71 -105.5 -108t-143.5 -37q-169 0 -262.5 144t-93.5 384zM281 507q0 -171 49 -271t155 -100q66 0 112.5 36t75.5 101v526q-29 67 -75.5 106t-110.5 39 q-106 0 -156 -115t-50 -301v-21z" />
<glyph unicode="e" horiz-adv-x="930" d="M82 456v158q0 212 113.5 350t288.5 138q184 0 283 -125.5t99 -337.5v-140h-582v-43q0 -140 61.5 -231.5t174.5 -91.5q84 0 144 26.5t114 77.5l64 -126q-51 -58 -137 -95t-198 -37q-193 0 -309 134t-116 343zM284 644h381v41q0 115 -46 188t-135 73q-88 0 -141 -85.5 t-59 -216.5z" />
<glyph unicode="f" horiz-adv-x="623" d="M47 937v145h140v139q0 172 82.5 266t231.5 94q29 0 59.5 -5.5t68.5 -15.5l-20 -149q-17 5 -38 8t-45 3q-67 0 -101.5 -52t-34.5 -149v-139h189v-145h-189v-937h-203v937h-140z" />
<glyph unicode="g" horiz-adv-x="994" d="M78 451v133q0 233 95.5 375.5t265.5 142.5q82 0 144 -38.5t106 -111.5l15 130h175v-1077q0 -208 -110.5 -325t-308.5 -117q-68 0 -145.5 21t-138.5 57l43 152q51 -31 112 -48.5t127 -17.5q111 0 164.5 71t53.5 208v98q-43 -62 -102.5 -93.5t-136.5 -31.5 q-169 0 -264 129.5t-95 342.5zM281 451q0 -144 50 -229.5t157 -85.5q66 0 112.5 34t75.5 96v539q-30 64 -76 101.5t-110 37.5q-106 0 -157.5 -100t-51.5 -260v-133z" />
<glyph unicode="h" d="M113 0v1560h203v-623q45 78 111 121.5t147 43.5q146 0 227 -108t81 -332v-662h-203v664q0 149 -43.5 214.5t-129.5 65.5q-62 0 -110.5 -35.5t-79.5 -97.5v-811h-203z" />
<glyph unicode="i" horiz-adv-x="462" d="M129 0v1082h203v-1082h-203zM129 1366v194h203v-194h-203z" />
<glyph unicode="j" horiz-adv-x="467" d="M-64 -419l11 155q16 -6 36.5 -10t38.5 -4q53 0 84 50.5t31 153.5v1156h203v-1156q0 -174 -78.5 -268.5t-219.5 -94.5q-30 0 -54 4.5t-52 13.5zM137 1366v194h203v-194h-203z" />
<glyph unicode="k" horiz-adv-x="922" d="M117 0v1560h202v-909h83l239 431h237l-314 -488l359 -594h-236l-282 496h-86v-496h-202z" />
<glyph unicode="l" horiz-adv-x="462" d="M129 0v1560h203v-1560h-203z" />
<glyph unicode="m" horiz-adv-x="1525" d="M116 0v1082h185l11 -147q44 80 112 123.5t159 43.5q89 0 153 -49.5t97 -150.5q42 94 112 147t166 53q138 0 217.5 -113.5t79.5 -345.5v-643h-203v644q0 166 -41 233t-121 67q-69 0 -115.5 -52.5t-67.5 -139.5q-1 8 1 -25.5t2 -48.5v-678h-202v644q0 161 -42 230.5 t-122 69.5q-64 0 -109 -35.5t-70 -98.5v-810h-202z" />
<glyph unicode="n" d="M114 0v1082h186l11 -160q45 85 114 132.5t156 47.5q142 0 221 -105t79 -326v-671h-203v669q0 151 -43 213t-130 62q-62 0 -110 -38.5t-78 -104.5v-801h-203z" />
<glyph unicode="o" d="M76 471v138q0 215 112.5 354t308.5 139q195 0 308 -138.5t113 -354.5v-138q0 -217 -112.5 -354.5t-307.5 -137.5q-197 0 -309.5 137.5t-112.5 354.5zM279 471q0 -148 54 -243t165 -95q108 0 162.5 95t54.5 243v138q0 146 -54.5 241.5t-163.5 95.5q-110 0 -164 -95 t-54 -242v-138z" />
<glyph unicode="p" d="M116 -416v1498h181l13 -124q43 69 105 106.5t144 37.5q169 0 263 -142t94 -376v-133q0 -214 -94 -343t-261 -129q-79 0 -139 31t-103 91v-517h-203zM319 259q27 -61 73 -93.5t113 -32.5q105 0 156.5 87.5t51.5 230.5v133q0 159 -52.5 259.5t-156.5 100.5q-65 0 -111 -37 t-74 -101v-547z" />
<glyph unicode="q" d="M78 451v133q0 234 94 376t263 142q79 0 139.5 -36t104.5 -104l15 120h176v-1498h-203v513q-43 -58 -101 -88t-132 -30q-169 0 -262.5 129t-93.5 343zM281 451q0 -144 49 -231t155 -87q63 0 108 32t74 91v561q-28 60 -73 94.5t-107 34.5q-106 0 -156 -100.5t-50 -261.5 v-133z" />
<glyph unicode="r" horiz-adv-x="633" d="M116 0v1082h185l15 -163q34 86 89 134.5t127 48.5q20 0 41 -3.5t33 -8.5l-24 -179l-95 5q-63 0 -104.5 -38t-63.5 -107v-771h-203z" />
<glyph unicode="s" horiz-adv-x="891" d="M69 318l2 6h189q4 -105 58 -151.5t134 -46.5q79 0 123.5 40.5t44.5 104.5q0 63 -41.5 106.5t-156.5 95.5q-167 65 -247.5 138.5t-80.5 190.5q0 125 98.5 212.5t258.5 87.5q167 0 266 -94q95 -91 95 -225v-11l-2 -6h-195q0 77 -43.5 132.5t-120.5 55.5q-76 0 -118.5 -43 t-42.5 -101q0 -62 36.5 -98t157.5 -94q170 -61 252.5 -138.5t82.5 -198.5q0 -134 -102 -218t-268 -84q-179 -1 -282 101q-98 97 -98 225v13z" />
<glyph unicode="t" horiz-adv-x="628" d="M32 937v145h141v269h202v-269h169v-145h-169v-644q0 -84 25 -119.5t65 -35.5q24 0 44.5 3t48.5 9l21 -140q-34 -14 -76.5 -22.5t-87.5 -8.5q-115 0 -178.5 75.5t-63.5 238.5v644h-141z" />
<glyph unicode="u" d="M112 443v639h202v-641q0 -166 39.5 -235.5t118.5 -69.5q75 0 125.5 35t80.5 100v811h203v-1082h-181l-13 145q-43 -80 -110 -123t-154 -43q-147 0 -229 113t-82 351z" />
<glyph unicode="v" horiz-adv-x="892" d="M34 1082h210l186 -757l17 -84h6l17 84l184 757h209l-324 -1082h-179z" />
<glyph unicode="w" horiz-adv-x="1308" d="M41 1082h194l146 -725h6l192 725h146l195 -731h6l143 731h194l-248 -1082h-167l-194 719h-6l-191 -719h-168z" />
<glyph unicode="x" horiz-adv-x="892" d="M35 0l296 548l-287 534h230l166 -395h6l170 395h232l-287 -534l297 -548h-231l-177 408h-6l-178 -408h-231z" />
<glyph unicode="y" horiz-adv-x="892" d="M22 1082h220l178 -709l15 -71h6l208 780h221l-379 -1250q-38 -112 -103 -190.5t-187 -78.5q-25 0 -53.5 5.5t-56.5 12.5l22 150q11 -2 30 -4t30 -2q59 0 93.5 50.5t53.5 119.5l36 110z" />
<glyph unicode="z" horiz-adv-x="865" d="M76 0v128l474 797h-464v157h690v-126l-478 -802h499v-154h-721z" />
<glyph unicode="{" horiz-adv-x="594" d="M55 535v146q83 0 123.5 61.5t40.5 174.5v215q0 171 69.5 290.5t233.5 174.5l39 -114q-83 -36 -117.5 -126.5t-34.5 -224.5v-215q0 -106 -40 -186.5t-121 -122.5q81 -44 121 -125t40 -186v-212q0 -134 34.5 -223t118.5 -126l-40 -115q-164 55 -233.5 174.5t-69.5 289.5 v212q0 112 -40.5 175t-123.5 63z" />
<glyph unicode="|" horiz-adv-x="446" d="M155 -270v1726h137v-1726h-137z" />
<glyph unicode="}" horiz-adv-x="594" d="M30 -264q83 37 119 126.5t36 222.5v212q0 108 41 188.5t126 121.5q-85 40 -126 120.5t-41 189.5v215q0 133 -35.5 223.5t-118.5 127.5l40 114q163 -55 233 -174.5t70 -290.5v-215q0 -113 39.5 -174.5t124.5 -61.5v-146q-84 0 -124 -63t-40 -175v-212q0 -170 -70 -289.5 t-233 -174.5z" />
<glyph unicode="~" horiz-adv-x="1165" d="M108 466q0 141 72 239t185 98q72 0 135.5 -35.5t132.5 -105.5q44 -52 80.5 -75t77.5 -23q50 0 86.5 58t36.5 143l143 -20q0 -142 -74 -242.5t-185 -100.5q-73 0 -134.5 34t-131.5 108q-47 50 -83.5 74t-77.5 24q-51 0 -86 -56t-35 -140z" />
<glyph unicode="&#xa1;" horiz-adv-x="473" d="M129 869v213h205v-213h-205zM130 -374v970h203v-970h-203z" />
<glyph unicode="&#xa2;" horiz-adv-x="991" d="M97 465v149q0 186 84 317.5t244 162.5v224h163v-223q134 -25 215 -130.5t81 -261.5h-190q0 108 -49.5 175.5t-131.5 67.5q-116 0 -164.5 -94t-48.5 -238v-149q0 -146 48.5 -239t165.5 -93q76 0 128 58.5t52 156.5h183l3 -5q2 -133 -81.5 -232.5t-210.5 -124.5v-231h-163 v232q-160 30 -244 161t-84 317z" />
<glyph unicode="&#xa3;" horiz-adv-x="1034" d="M77 618v155h135l-8 263q0 205 98 323t263 118q175 0 270.5 -107t92.5 -282l-3 -6h-195q0 123 -46 181t-119 58t-115.5 -75t-42.5 -210l9 -263h328v-155h-322l5 -141q0 -93 -24 -177.5t-69 -145.5h629v-154h-832v154h7q42 13 63 113t21 206l-5 145h-140z" />
<glyph unicode="&#xa4;" horiz-adv-x="1290" d="M90 92l129 147q-48 78 -73.5 172t-25.5 197q0 107 27 203t79 176l-136 157l116 120l129 -149q67 57 146.5 88t166.5 31q86 0 165.5 -31.5t147.5 -89.5l132 152l116 -121l-139 -160q49 -81 76 -176.5t27 -199.5q0 -102 -25 -194.5t-71 -170.5l132 -151l-116 -119l-121 139 q-68 -64 -151 -98t-173 -34q-91 0 -173.5 33.5t-150.5 96.5l-118 -136zM273 608q0 -198 109.5 -336.5t265.5 -138.5q154 0 263 138.5t109 336.5q0 196 -109 334t-263 138q-156 0 -265.5 -138t-109.5 -334z" />
<glyph unicode="&#xa5;" horiz-adv-x="1070" d="M31 1456h226l273 -632h6l272 632h226l-350 -730h247v-155h-300v-137h300v-155h-300v-279h-203v279h-304v155h304v137h-304v155h256z" />
<glyph unicode="&#xa6;" horiz-adv-x="442" d="M123 -270v784h190v-784h-190zM123 698v758h190v-758h-190z" />
<glyph unicode="&#xa7;" horiz-adv-x="1091" d="M88 546q0 91 42 160.5t121 110.5q-67 50 -100 120.5t-33 171.5q0 166 116.5 267t310.5 101q201 0 313.5 -111.5t108.5 -312.5l-2 -6h-194q0 118 -60 196t-166 78q-112 0 -168 -59t-56 -151q0 -97 52.5 -147.5t216.5 -106.5q209 -66 305 -154.5t96 -258.5 q0 -93 -43.5 -162t-122.5 -108q68 -51 102.5 -120.5t34.5 -171.5q0 -172 -115.5 -269t-310.5 -97q-191 0 -320 101.5t-124 320.5l2 6l194 2q0 -144 72.5 -209.5t175.5 -65.5q104 0 163.5 58.5t59.5 150.5q0 90 -56.5 140.5t-214.5 108.5q-205 64 -302.5 154.5t-97.5 262.5z M291 556q0 -101 52.5 -152.5t218.5 -111.5q29 -10 58 -20.5t58 -20.5q53 22 83 70t30 113q0 92 -58 146.5t-217 116.5q-36 10 -66.5 20.5t-56.5 22.5q-52 -22 -77 -70t-25 -114z" />
<glyph unicode="&#xa8;" horiz-adv-x="940" d="M151 1271v185h208v-185h-208zM580 1271v185h207v-185h-207z" />
<glyph unicode="&#xa9;" horiz-adv-x="1440" d="M88 729q0 315 182.5 531t444.5 216q261 0 444.5 -216t183.5 -531q0 -316 -184 -533t-444 -217q-261 0 -444 217t-183 533zM190 729q0 -271 153.5 -457t371.5 -186t371.5 186t153.5 457q0 268 -153.5 453t-371.5 185q-219 0 -372 -185t-153 -453zM397 669v119 q0 173 83 280t224 107q137 0 214.5 -79.5t74.5 -228.5l-3 -6h-121q0 102 -42 150t-123 48q-86 0 -132.5 -75t-46.5 -195v-120q0 -123 46.5 -197.5t132.5 -74.5q82 0 123 47t41 152h121l3 -6q3 -150 -74 -229t-214 -79q-141 0 -224 106.5t-83 280.5z" />
<glyph unicode="&#xaa;" horiz-adv-x="788" d="M107 919q0 109 71 168t208 59h118v56q0 71 -25.5 110t-75.5 39q-58 0 -90 -31.5t-32 -88.5l-133 12l-1 6q-5 98 66.5 163t189.5 65q112 0 178 -71t66 -205v-315q0 -51 5 -95t17 -86h-144q-7 22 -11.5 47t-7.5 53q-27 -50 -74.5 -82t-113.5 -32q-100 0 -155.5 61.5 t-55.5 166.5zM249 923q0 -53 25.5 -81.5t77.5 -28.5q45 0 91 33t61 73v124h-117q-66 0 -102 -35.5t-36 -84.5z" />
<glyph unicode="&#xab;" horiz-adv-x="857" d="M81 507v19l243 384h139l-210 -394l210 -394h-139zM387 507v19l243 384h139l-210 -394l210 -394h-139z" />
<glyph unicode="&#xac;" horiz-adv-x="972" d="M115 649v143h704v-414h-162v271h-542z" />
<glyph unicode="&#xad;" horiz-adv-x="598" d="M73 542v155h446v-155h-446z" />
<glyph unicode="&#xae;" horiz-adv-x="1441" d="M87 729q0 315 183 531t445 216q261 0 444 -216t183 -531q0 -316 -183.5 -533t-443.5 -217q-262 0 -445 217t-183 533zM189 729q0 -271 153.5 -457t372.5 -186q217 0 370.5 186t153.5 457q0 268 -153.5 453t-370.5 185q-219 0 -372.5 -185t-153.5 -453zM459 316v850h245 q133 0 209 -65.5t76 -189.5q0 -63 -29.5 -109.5t-85.5 -77.5q58 -27 84.5 -80.5t26.5 -128.5v-56q0 -42 3 -74t11 -53v-16h-129q-8 21 -9.5 61.5t-1.5 82.5v54q0 76 -30.5 111t-99.5 35h-144v-344h-126zM585 776h131q62 0 105 35t43 97q0 77 -36 110t-124 33h-119v-275z" />
<glyph unicode="&#xaf;" horiz-adv-x="879" d="M125 1324v132h635v-132h-635z" />
<glyph unicode="&#xb0;" horiz-adv-x="706" d="M122 1216q0 106 68.5 183.5t164.5 77.5q93 0 161 -77.5t68 -183.5q0 -108 -67.5 -182.5t-161.5 -74.5q-96 0 -164.5 74.5t-68.5 182.5zM239 1216q0 -59 33.5 -98.5t82.5 -39.5q47 0 79.5 39t32.5 99t-32.5 100.5t-79.5 40.5q-49 0 -82.5 -40.5t-33.5 -100.5z" />
<glyph unicode="&#xb1;" horiz-adv-x="986" d="M90 716v157h320v407h182v-407h308v-157h-308v-414h-182v414h-320zM123 21v155h706v-155h-706z" />
<glyph unicode="&#xb2;" horiz-adv-x="745" d="M106 1236q-5 100 67.5 171.5t194.5 71.5q117 0 182.5 -63t65.5 -179q0 -78 -43.5 -140.5t-141.5 -159.5l-122 -144l2 -5h311v-121h-513v121l260 267q55 60 72 99t17 84q0 53 -22.5 85.5t-69.5 32.5q-53 0 -80.5 -35t-27.5 -91h-150z" />
<glyph unicode="&#xb3;" horiz-adv-x="747" d="M97 885l2 6h149q0 -52 30 -83.5t84 -31.5q55 0 87.5 31t32.5 85q0 64 -31 94.5t-91 30.5h-102v113h102q56 0 83 30t27 85q0 48 -27.5 79t-81.5 31q-48 0 -75.5 -27.5t-27.5 -72.5h-148l-2 6q-6 97 67.5 157t183.5 60q124 0 196.5 -59.5t72.5 -168.5q0 -56 -30.5 -102 t-83.5 -72q60 -23 92.5 -71t32.5 -117q0 -110 -75.5 -171.5t-200.5 -61.5q-116 0 -193.5 59t-72.5 171z" />
<glyph unicode="&#xb4;" horiz-adv-x="615" d="M112 1212l172 266h226l2 -5l-238 -261h-162z" />
<glyph unicode="&#xb5;" horiz-adv-x="1042" d="M132 -416v1498h202v-626q0 -185 43.5 -253.5t126.5 -68.5q75 0 122 36t73 105v807h202v-1082h-186l-6 88q-38 -53 -89.5 -81t-116.5 -28q-53 0 -94.5 15t-74.5 49v-459h-202z" />
<glyph unicode="&#xb6;" horiz-adv-x="896" d="M62 988q0 207 109.5 337.5t306.5 130.5h275v-1456h-203v520h-72q-197 0 -306.5 129.5t-109.5 338.5z" />
<glyph unicode="&#xb7;" horiz-adv-x="505" d="M143 606v214h205v-214h-205z" />
<glyph unicode="&#xb8;" horiz-adv-x="464" d="M100 -132l26 134h150l-10 -58q56 -10 92.5 -50.5t36.5 -121.5q0 -98 -72.5 -156t-205.5 -58l-6 113q53 0 85.5 25t32.5 76q0 50 -29 69.5t-100 26.5z" />
<glyph unicode="&#xb9;" horiz-adv-x="491" d="M92 1328v126l268 23v-812h-159v666z" />
<glyph unicode="&#xba;" horiz-adv-x="806" d="M109 1025v117q0 148 79.5 241.5t211.5 93.5q133 0 212 -93.5t79 -241.5v-117q0 -149 -78.5 -241.5t-210.5 -92.5q-134 0 -213.5 92.5t-79.5 241.5zM252 1025q0 -95 38 -153t112 -58q71 0 109 58t38 153v117q0 92 -38.5 150.5t-110.5 58.5t-110 -58.5t-38 -150.5v-117z " />
<glyph unicode="&#xbb;" horiz-adv-x="857" d="M85 155l209 395l-209 396h139l243 -386v-19l-243 -386h-139zM402 155l209 395l-209 396h139l243 -386v-19l-243 -386h-139z" />
<glyph unicode="&#xbc;" horiz-adv-x="1318" d="M134 1327v126l268 23v-812h-159v666zM254 184l601 1138l104 -63l-601 -1138zM639 250l358 551h158v-524h98v-122h-98v-155h-157v155h-351zM804 277h194v321l-6 1l-11 -19z" />
<glyph unicode="&#xbd;" horiz-adv-x="1383" d="M127 1327v126l268 23v-812h-159v666zM258 184l601 1138l104 -63l-601 -1138zM752 569q-5 100 67.5 171.5t194.5 71.5q117 0 182.5 -63t65.5 -179q0 -78 -43.5 -140.5t-141.5 -159.5l-122 -144l2 -5h311v-121h-513v121l260 267q55 60 72 99t17 84q0 53 -22.5 85.5 t-69.5 32.5q-53 0 -80.5 -35t-27.5 -91h-150z" />
<glyph unicode="&#xbe;" horiz-adv-x="1485" d="M100 886l2 6h149q0 -52 30 -83.5t84 -31.5q55 0 87.5 31t32.5 85q0 64 -31 94.5t-91 30.5h-102v113h102q56 0 83 30t27 85q0 48 -27.5 79t-81.5 31q-48 0 -75.5 -27.5t-27.5 -72.5h-148l-2 6q-6 97 67.5 157t183.5 60q124 0 196.5 -59.5t72.5 -168.5q0 -56 -30.5 -102 t-83.5 -72q60 -23 92.5 -71t32.5 -117q0 -110 -75.5 -171.5t-200.5 -61.5q-116 0 -193.5 59t-72.5 171zM425 184l601 1138l104 -63l-601 -1138zM799 250l358 551h158v-524h98v-122h-98v-155h-157v155h-351zM964 277h194v321l-6 1l-11 -19z" />
<glyph unicode="&#xbf;" horiz-adv-x="879" d="M87 -3q0 128 59.5 234t159.5 209q48 50 61.5 96.5t13.5 136.5h203q-2 -134 -29 -192t-121 -150q-72 -92 -108.5 -163.5t-36.5 -167.5q0 -110 45 -171.5t129 -61.5q70 0 120 56t51 157h195l2 -6q2 -173 -102 -270.5t-266 -97.5q-177 0 -276.5 104.5t-99.5 286.5zM377 883 v199h208v-199h-208z" />
<glyph unicode="&#xc0;" horiz-adv-x="1137" d="M27 0l448 1456h196l444 -1456h-206l-106 368h-464l-106 -368h-206zM291 1822l2 5h227l169 -266h-170zM386 529h371l-182 636h-6z" />
<glyph unicode="&#xc1;" horiz-adv-x="1137" d="M27 0l448 1456h196l444 -1456h-206l-106 368h-464l-106 -368h-206zM386 529h371l-182 636h-6zM486 1558l172 266h226l2 -5l-238 -261h-162z" />
<glyph unicode="&#xc2;" horiz-adv-x="1137" d="M27 0l448 1456h196l444 -1456h-206l-106 368h-464l-106 -368h-206zM305 1599v23l222 232h122l226 -233v-22h-164l-123 151l-122 -151h-161zM386 529h371l-182 636h-6z" />
<glyph unicode="&#xc3;" horiz-adv-x="1137" d="M27 0l448 1456h196l444 -1456h-206l-106 368h-464l-106 -368h-206zM282 1630q0 90 50 155t126 65q48 0 124 -49.5t120 -49.5q33 0 56.5 34t23.5 84l110 -31q0 -92 -50 -155t-126 -63q-61 0 -131 49t-113 49q-33 0 -56 -33.5t-23 -82.5zM386 529h371l-182 636h-6z" />
<glyph unicode="&#xc4;" horiz-adv-x="1137" d="M27 0l448 1456h196l444 -1456h-206l-106 368h-464l-106 -368h-206zM271 1617v185h208v-185h-208zM386 529h371l-182 636h-6zM700 1617v185h207v-185h-207z" />
<glyph unicode="&#xc5;" horiz-adv-x="1137" d="M27 0l448 1456h196l444 -1456h-206l-106 368h-464l-106 -368h-206zM386 529h371l-182 636h-6zM408 1734q0 78 53 131t128 53q74 0 126 -53t52 -131q0 -80 -51.5 -130.5t-126.5 -50.5q-76 0 -128.5 51t-52.5 130zM501 1734q0 -41 25.5 -68.5t62.5 -27.5q36 0 60 27t24 69 q0 43 -24 71t-60 28q-37 0 -62.5 -28.5t-25.5 -70.5z" />
<glyph unicode="&#xc6;" horiz-adv-x="1639" d="M3 0l703 1456h832v-157h-544l17 -467h458v-155h-453l18 -522h556v-155h-752l-13 361h-416l-164 -361h-242zM487 531h332l-24 665l-5 1z" />
<glyph unicode="&#xc7;" horiz-adv-x="1084" d="M94 525v404q0 258 126.5 403t337.5 145q214 0 329 -117t118 -342l-3 -6h-192q-3 159 -63 234t-189 75q-125 0 -194 -101t-69 -288v-407q0 -190 70.5 -291t198.5 -101q126 0 184.5 73.5t60.5 235.5h193l3 -6q-1 -218 -116 -337.5t-325 -119.5q-214 0 -342 144t-128 402z M459 -137l26 134h150l-10 -58q56 -10 92.5 -50.5t36.5 -121.5q0 -98 -72.5 -156t-205.5 -58l-6 113q53 0 85.5 25t32.5 76q0 50 -29 69.5t-100 26.5z" />
<glyph unicode="&#xc8;" horiz-adv-x="1018" d="M141 0v1456h823v-156h-620v-469h540v-155h-540v-522h626v-154h-829zM231 1822l2 5h227l169 -266h-170z" />
<glyph unicode="&#xc9;" horiz-adv-x="1018" d="M141 0v1456h823v-156h-620v-469h540v-155h-540v-522h626v-154h-829zM426 1558l172 266h226l2 -5l-238 -261h-162z" />
<glyph unicode="&#xca;" horiz-adv-x="1018" d="M141 0v1456h823v-156h-620v-469h540v-155h-540v-522h626v-154h-829zM245 1599v23l222 232h122l226 -233v-22h-164l-123 151l-122 -151h-161z" />
<glyph unicode="&#xcb;" horiz-adv-x="1018" d="M141 0v1456h823v-156h-620v-469h540v-155h-540v-522h626v-154h-829zM211 1617v185h208v-185h-208zM640 1617v185h207v-185h-207z" />
<glyph unicode="&#xcc;" horiz-adv-x="513" d="M-39 1822l2 5h227l169 -266h-170zM155 0v1456h202v-1456h-202z" />
<glyph unicode="&#xcd;" horiz-adv-x="513" d="M154 1558l172 266h226l2 -5l-238 -261h-162zM155 0v1456h202v-1456h-202z" />
<glyph unicode="&#xce;" horiz-adv-x="513" d="M-25 1599v23l222 232h122l226 -233v-22h-164l-123 151l-122 -151h-161zM155 0v1456h202v-1456h-202z" />
<glyph unicode="&#xcf;" horiz-adv-x="513" d="M-59 1617v185h208v-185h-208zM155 0v1456h202v-1456h-202zM370 1617v185h207v-185h-207z" />
<glyph unicode="&#xd0;" horiz-adv-x="1184" d="M44 670v141h127v645h400q232 0 378.5 -175t146.5 -450v-207q0 -276 -146.5 -450t-378.5 -174h-400v670h-127zM374 154h190q153 0 241.5 131t88.5 339v209q0 206 -88.5 336.5t-241.5 130.5h-190v-489h225v-141h-225v-516z" />
<glyph unicode="&#xd1;" horiz-adv-x="1247" d="M141 0v1456h203l552 -1080l6 2v1078h202v-1456h-202l-552 1083l-6 -2v-1081h-203zM316 1630q0 90 50 155t126 65q48 0 124 -49.5t120 -49.5q33 0 56.5 34t23.5 84l110 -31q0 -92 -50 -155t-126 -63q-61 0 -131 49t-113 49q-33 0 -56 -33.5t-23 -82.5z" />
<glyph unicode="&#xd2;" horiz-adv-x="1160" d="M91 527v400q0 258 131.5 404t352.5 146q224 0 358.5 -146t134.5 -404v-400q0 -259 -134 -403.5t-359 -144.5q-222 0 -353 144.5t-131 403.5zM282 1843l2 5h227l169 -266h-170zM292 527q0 -192 73.5 -291t209.5 -99q140 0 215.5 98.5t75.5 291.5v403q0 190 -76 288.5 t-215 98.5q-137 0 -210 -98.5t-73 -288.5v-403z" />
<glyph unicode="&#xd3;" horiz-adv-x="1160" d="M91 527v400q0 258 131.5 404t352.5 146q224 0 358.5 -146t134.5 -404v-400q0 -259 -134 -403.5t-359 -144.5q-222 0 -353 144.5t-131 403.5zM292 527q0 -192 73.5 -291t209.5 -99q140 0 215.5 98.5t75.5 291.5v403q0 190 -76 288.5t-215 98.5q-137 0 -210 -98.5 t-73 -288.5v-403zM477 1579l172 266h226l2 -5l-238 -261h-162z" />
<glyph unicode="&#xd4;" horiz-adv-x="1160" d="M91 527v400q0 258 131.5 404t352.5 146q224 0 358.5 -146t134.5 -404v-400q0 -259 -134 -403.5t-359 -144.5q-222 0 -353 144.5t-131 403.5zM292 527q0 -192 73.5 -291t209.5 -99q140 0 215.5 98.5t75.5 291.5v403q0 190 -76 288.5t-215 98.5q-137 0 -210 -98.5 t-73 -288.5v-403zM296 1620v23l222 232h122l226 -233v-22h-164l-123 151l-122 -151h-161z" />
<glyph unicode="&#xd5;" horiz-adv-x="1160" d="M91 527v400q0 258 131.5 404t352.5 146q224 0 358.5 -146t134.5 -404v-400q0 -259 -134 -403.5t-359 -144.5q-222 0 -353 144.5t-131 403.5zM273 1651q0 90 50 155t126 65q48 0 124 -49.5t120 -49.5q33 0 56.5 34t23.5 84l110 -31q0 -92 -50 -155t-126 -63q-61 0 -131 49 t-113 49q-33 0 -56 -33.5t-23 -82.5zM292 527q0 -192 73.5 -291t209.5 -99q140 0 215.5 98.5t75.5 291.5v403q0 190 -76 288.5t-215 98.5q-137 0 -210 -98.5t-73 -288.5v-403z" />
<glyph unicode="&#xd6;" horiz-adv-x="1160" d="M91 527v400q0 258 131.5 404t352.5 146q224 0 358.5 -146t134.5 -404v-400q0 -259 -134 -403.5t-359 -144.5q-222 0 -353 144.5t-131 403.5zM262 1638v185h208v-185h-208zM292 527q0 -192 73.5 -291t209.5 -99q140 0 215.5 98.5t75.5 291.5v403q0 190 -76 288.5 t-215 98.5q-137 0 -210 -98.5t-73 -288.5v-403zM691 1638v185h207v-185h-207z" />
<glyph unicode="&#xd7;" horiz-adv-x="977" d="M76 344l293 339l-291 336l125 119l280 -324l281 324l125 -119l-292 -336l295 -339l-125 -119l-284 326l-283 -326z" />
<glyph unicode="&#xd8;" horiz-adv-x="1202" d="M93 527v400q0 258 131.5 404t352.5 146q91 0 170 -26t141 -75l68 136h121l-110 -219q50 -70 76.5 -162.5t26.5 -203.5v-400q0 -259 -134 -403.5t-359 -144.5q-69 0 -129.5 14t-111.5 42l-63 -125h-120l95 189q-75 70 -115 178.5t-40 249.5zM294 527q0 -76 11 -136 t33 -100l6 -1l458 915q-38 55 -95 83.5t-130 28.5q-137 0 -210 -98.5t-73 -288.5v-403zM413 189q32 -27 73 -39.5t91 -12.5q140 0 215.5 98.5t75.5 291.5v403q0 37 -3.5 70.5t-8.5 58.5l-6 1z" />
<glyph unicode="&#xd9;" horiz-adv-x="1160" d="M117 447v1009h201v-1009q0 -156 70 -235t189 -79q124 0 195 76t71 238v1009h202v-1009q0 -226 -129.5 -347t-338.5 -121q-206 0 -333 121t-127 347zM284 1822l2 5h227l169 -266h-170z" />
<glyph unicode="&#xda;" horiz-adv-x="1160" d="M117 447v1009h201v-1009q0 -156 70 -235t189 -79q124 0 195 76t71 238v1009h202v-1009q0 -226 -129.5 -347t-338.5 -121q-206 0 -333 121t-127 347zM479 1558l172 266h226l2 -5l-238 -261h-162z" />
<glyph unicode="&#xdb;" horiz-adv-x="1160" d="M117 447v1009h201v-1009q0 -156 70 -235t189 -79q124 0 195 76t71 238v1009h202v-1009q0 -226 -129.5 -347t-338.5 -121q-206 0 -333 121t-127 347zM298 1599v23l222 232h122l226 -233v-22h-164l-123 151l-122 -151h-161z" />
<glyph unicode="&#xdc;" horiz-adv-x="1160" d="M117 447v1009h201v-1009q0 -156 70 -235t189 -79q124 0 195 76t71 238v1009h202v-1009q0 -226 -129.5 -347t-338.5 -121q-206 0 -333 121t-127 347zM264 1617v185h208v-185h-208zM693 1617v185h207v-185h-207z" />
<glyph unicode="&#xdd;" horiz-adv-x="1100" d="M23 1456h227l297 -707h6l298 707h225l-428 -932v-524h-202v537zM450 1554l172 266h226l2 -5l-238 -261h-162z" />
<glyph unicode="&#xde;" horiz-adv-x="1055" d="M133 0v1456h203v-290h211q205 0 319.5 -119t114.5 -309q0 -192 -114.5 -310.5t-319.5 -118.5h-211v-309h-203zM336 464h211q116 0 173.5 79t57.5 193q0 115 -57.5 195t-173.5 80h-211v-547z" />
<glyph unicode="&#xdf;" horiz-adv-x="1079" d="M124 0v1088q0 215 103 335t275 120q143 0 236 -86.5t93 -246.5q0 -111 -49.5 -215.5t-49.5 -173.5q0 -76 136.5 -218t136.5 -283q0 -170 -93 -255.5t-259 -85.5q-69 0 -140 20t-104 50l40 154q35 -28 87 -49.5t106 -21.5q79 0 120.5 49.5t41.5 131.5q0 86 -137.5 226 t-137.5 280q0 88 52 194.5t52 184.5q0 85 -41 138t-94 53q-78 0 -125 -79.5t-47 -223.5v-1086h-202z" />
<glyph unicode="&#xe0;" horiz-adv-x="955" d="M84 297q0 155 105.5 243.5t296.5 88.5h151v111q0 99 -44 154.5t-125 55.5q-73 0 -117.5 -50t-44.5 -125l-193 1l-3 6q-5 125 100 222.5t271 97.5q160 0 259.5 -94.5t99.5 -269.5v-502q0 -63 7.5 -121.5t24.5 -114.5h-205q-11 37 -18 72.5t-9 71.5q-45 -73 -113 -119 t-151 -46q-137 0 -214.5 86.5t-77.5 231.5zM174 1500l2 5h227l169 -266h-170zM287 298q0 -73 35 -118t100 -45q71 0 129.5 42t85.5 105v221h-154q-93 0 -144.5 -59.5t-51.5 -145.5z" />
<glyph unicode="&#xe1;" horiz-adv-x="955" d="M84 297q0 155 105.5 243.5t296.5 88.5h151v111q0 99 -44 154.5t-125 55.5q-73 0 -117.5 -50t-44.5 -125l-193 1l-3 6q-5 125 100 222.5t271 97.5q160 0 259.5 -94.5t99.5 -269.5v-502q0 -63 7.5 -121.5t24.5 -114.5h-205q-11 37 -18 72.5t-9 71.5q-45 -73 -113 -119 t-151 -46q-137 0 -214.5 86.5t-77.5 231.5zM287 298q0 -73 35 -118t100 -45q71 0 129.5 42t85.5 105v221h-154q-93 0 -144.5 -59.5t-51.5 -145.5zM369 1236l172 266h226l2 -5l-238 -261h-162z" />
<glyph unicode="&#xe2;" horiz-adv-x="955" d="M84 297q0 155 105.5 243.5t296.5 88.5h151v111q0 99 -44 154.5t-125 55.5q-73 0 -117.5 -50t-44.5 -125l-193 1l-3 6q-5 125 100 222.5t271 97.5q160 0 259.5 -94.5t99.5 -269.5v-502q0 -63 7.5 -121.5t24.5 -114.5h-205q-11 37 -18 72.5t-9 71.5q-45 -73 -113 -119 t-151 -46q-137 0 -214.5 86.5t-77.5 231.5zM188 1277v23l222 232h122l226 -233v-22h-164l-123 151l-122 -151h-161zM287 298q0 -73 35 -118t100 -45q71 0 129.5 42t85.5 105v221h-154q-93 0 -144.5 -59.5t-51.5 -145.5z" />
<glyph unicode="&#xe3;" horiz-adv-x="955" d="M84 297q0 155 105.5 243.5t296.5 88.5h151v111q0 99 -44 154.5t-125 55.5q-73 0 -117.5 -50t-44.5 -125l-193 1l-3 6q-5 125 100 222.5t271 97.5q160 0 259.5 -94.5t99.5 -269.5v-502q0 -63 7.5 -121.5t24.5 -114.5h-205q-11 37 -18 72.5t-9 71.5q-45 -73 -113 -119 t-151 -46q-137 0 -214.5 86.5t-77.5 231.5zM165 1308q0 90 50 155t126 65q48 0 124 -49.5t120 -49.5q33 0 56.5 34t23.5 84l110 -31q0 -92 -50 -155t-126 -63q-61 0 -131 49t-113 49q-33 0 -56 -33.5t-23 -82.5zM287 298q0 -73 35 -118t100 -45q71 0 129.5 42t85.5 105v221 h-154q-93 0 -144.5 -59.5t-51.5 -145.5z" />
<glyph unicode="&#xe4;" horiz-adv-x="955" d="M84 297q0 155 105.5 243.5t296.5 88.5h151v111q0 99 -44 154.5t-125 55.5q-73 0 -117.5 -50t-44.5 -125l-193 1l-3 6q-5 125 100 222.5t271 97.5q160 0 259.5 -94.5t99.5 -269.5v-502q0 -63 7.5 -121.5t24.5 -114.5h-205q-11 37 -18 72.5t-9 71.5q-45 -73 -113 -119 t-151 -46q-137 0 -214.5 86.5t-77.5 231.5zM154 1295v185h208v-185h-208zM287 298q0 -73 35 -118t100 -45q71 0 129.5 42t85.5 105v221h-154q-93 0 -144.5 -59.5t-51.5 -145.5zM583 1295v185h207v-185h-207z" />
<glyph unicode="&#xe5;" horiz-adv-x="955" d="M84 297q0 155 105.5 243.5t296.5 88.5h151v111q0 99 -44 154.5t-125 55.5q-73 0 -117.5 -50t-44.5 -125l-193 1l-3 6q-5 125 100 222.5t271 97.5q160 0 259.5 -94.5t99.5 -269.5v-502q0 -63 7.5 -121.5t24.5 -114.5h-205q-11 37 -18 72.5t-9 71.5q-45 -73 -113 -119 t-151 -46q-137 0 -214.5 86.5t-77.5 231.5zM287 298q0 -73 35 -118t100 -45q71 0 129.5 42t85.5 105v221h-154q-93 0 -144.5 -59.5t-51.5 -145.5zM291 1412q0 78 53 131t128 53q74 0 126 -53t52 -131q0 -80 -51.5 -130.5t-126.5 -50.5q-76 0 -128.5 51t-52.5 130zM384 1412 q0 -41 25.5 -68.5t62.5 -27.5q36 0 60 27t24 69q0 43 -24 71t-60 28q-37 0 -62.5 -28.5t-25.5 -70.5z" />
<glyph unicode="&#xe6;" horiz-adv-x="1479" d="M53 304q0 158 102.5 246t297.5 88h176v78q0 109 -40 169.5t-114 60.5q-80 0 -126.5 -54.5t-46.5 -134.5l-194 16l-2 6q-5 139 97.5 231t272.5 92q92 0 164.5 -33.5t119.5 -97.5q53 63 124.5 97t156.5 34q179 0 278.5 -128.5t99.5 -350.5v-124h-583q1 -166 61 -266 t185 -100q83 0 139 26.5t119 76.5l59 -132q-47 -48 -133 -86.5t-198 -38.5t-198.5 45t-142.5 129q-49 -75 -139 -124.5t-215 -49.5q-153 0 -236.5 87t-83.5 238zM256 300q0 -80 39 -126.5t118 -46.5q57 0 119.5 40t96.5 92v242h-174q-94 0 -146.5 -58.5t-52.5 -142.5z M839 639h380v30q0 124 -44 200.5t-134 76.5q-91 0 -141.5 -84t-60.5 -223z" />
<glyph unicode="&#xe7;" horiz-adv-x="921" d="M75 465v149q0 212 107.5 350t308.5 138q164 0 266.5 -109.5t99.5 -283.5l-3 -6h-182q0 108 -49.5 175.5t-131.5 67.5q-116 0 -164.5 -94t-48.5 -238v-149q0 -146 48.5 -239t165.5 -93q76 0 128 58.5t52 156.5h182l2 -6q4 -153 -103.5 -258t-260.5 -105q-202 0 -309.5 137 t-107.5 349zM372 -137l26 134h150l-10 -58q56 -10 92.5 -50.5t36.5 -121.5q0 -98 -72.5 -156t-205.5 -58l-6 113q53 0 85.5 25t32.5 76q0 50 -29 69.5t-100 26.5z" />
<glyph unicode="&#xe8;" horiz-adv-x="930" d="M82 456v158q0 212 113.5 350t288.5 138q184 0 283 -125.5t99 -337.5v-140h-582v-43q0 -140 61.5 -231.5t174.5 -91.5q84 0 144 26.5t114 77.5l64 -126q-51 -58 -137 -95t-198 -37q-193 0 -309 134t-116 343zM177 1501l2 5h227l169 -266h-170zM284 644h381v41 q0 115 -46 188t-135 73q-88 0 -141 -85.5t-59 -216.5z" />
<glyph unicode="&#xe9;" horiz-adv-x="930" d="M82 456v158q0 212 113.5 350t288.5 138q184 0 283 -125.5t99 -337.5v-140h-582v-43q0 -140 61.5 -231.5t174.5 -91.5q84 0 144 26.5t114 77.5l64 -126q-51 -58 -137 -95t-198 -37q-193 0 -309 134t-116 343zM284 644h381v41q0 115 -46 188t-135 73q-88 0 -141 -85.5 t-59 -216.5zM372 1237l172 266h226l2 -5l-238 -261h-162z" />
<glyph unicode="&#xea;" horiz-adv-x="930" d="M82 456v158q0 212 113.5 350t288.5 138q184 0 283 -125.5t99 -337.5v-140h-582v-43q0 -140 61.5 -231.5t174.5 -91.5q84 0 144 26.5t114 77.5l64 -126q-51 -58 -137 -95t-198 -37q-193 0 -309 134t-116 343zM191 1278v23l222 232h122l226 -233v-22h-164l-123 151 l-122 -151h-161zM284 644h381v41q0 115 -46 188t-135 73q-88 0 -141 -85.5t-59 -216.5z" />
<glyph unicode="&#xeb;" horiz-adv-x="930" d="M82 456v158q0 212 113.5 350t288.5 138q184 0 283 -125.5t99 -337.5v-140h-582v-43q0 -140 61.5 -231.5t174.5 -91.5q84 0 144 26.5t114 77.5l64 -126q-51 -58 -137 -95t-198 -37q-193 0 -309 134t-116 343zM157 1296v185h208v-185h-208zM284 644h381v41q0 115 -46 188 t-135 73q-88 0 -141 -85.5t-59 -216.5zM586 1296v185h207v-185h-207z" />
<glyph unicode="&#xec;" horiz-adv-x="468" d="M-64 1479l2 5h227l169 -266h-170zM129 0v1082h203v-1082h-203z" />
<glyph unicode="&#xed;" horiz-adv-x="468" d="M129 0v1082h203v-1082h-203zM129 1215l172 266h226l2 -5l-238 -261h-162z" />
<glyph unicode="&#xee;" horiz-adv-x="468" d="M-50 1256v23l222 232h122l226 -233v-22h-164l-123 151l-122 -151h-161zM129 0v1082h203v-1082h-203z" />
<glyph unicode="&#xef;" horiz-adv-x="468" d="M-84 1274v185h208v-185h-208zM129 0v1082h203v-1082h-203zM345 1274v185h207v-185h-207z" />
<glyph unicode="&#xf0;" horiz-adv-x="1039" d="M60 462q0 230 114.5 368t303.5 138q69 0 130 -27t104 -73l4 4q-16 94 -50.5 173t-82.5 142l-218 -146l-64 94l202 135q-35 28 -71.5 50.5t-73.5 39.5l63 157q66 -25 126.5 -60.5t112.5 -81.5l195 130l63 -94l-179 -120q97 -120 150 -285t53 -369v-87q0 -251 -127 -411 t-318 -160q-192 0 -314.5 138.5t-122.5 344.5zM263 462q0 -132 64.5 -230t172.5 -98t173.5 117t65.5 299v89q0 7 -0.5 21.5t-0.5 21.5q-30 58 -91.5 96.5t-148.5 38.5q-110 0 -172.5 -101t-62.5 -254z" />
<glyph unicode="&#xf1;" d="M114 0v1082h186l11 -160q45 85 114 132.5t156 47.5q142 0 221 -105t79 -326v-671h-203v669q0 151 -43 213t-130 62q-62 0 -110 -38.5t-78 -104.5v-801h-203zM189 1308q0 90 50 155t126 65q48 0 124 -49.5t120 -49.5q33 0 56.5 34t23.5 84l110 -31q0 -92 -50 -155 t-126 -63q-61 0 -131 49t-113 49q-33 0 -56 -33.5t-23 -82.5z" />
<glyph unicode="&#xf2;" d="M76 471v138q0 215 112.5 354t308.5 139q195 0 308 -138.5t113 -354.5v-138q0 -217 -112.5 -354.5t-307.5 -137.5q-197 0 -309.5 137.5t-112.5 354.5zM201 1500l2 5h227l169 -266h-170zM279 471q0 -148 54 -243t165 -95q108 0 162.5 95t54.5 243v138q0 146 -54.5 241.5 t-163.5 95.5q-110 0 -164 -95t-54 -242v-138z" />
<glyph unicode="&#xf3;" d="M76 471v138q0 215 112.5 354t308.5 139q195 0 308 -138.5t113 -354.5v-138q0 -217 -112.5 -354.5t-307.5 -137.5q-197 0 -309.5 137.5t-112.5 354.5zM279 471q0 -148 54 -243t165 -95q108 0 162.5 95t54.5 243v138q0 146 -54.5 241.5t-163.5 95.5q-110 0 -164 -95 t-54 -242v-138zM396 1236l172 266h226l2 -5l-238 -261h-162z" />
<glyph unicode="&#xf4;" d="M76 471v138q0 215 112.5 354t308.5 139q195 0 308 -138.5t113 -354.5v-138q0 -217 -112.5 -354.5t-307.5 -137.5q-197 0 -309.5 137.5t-112.5 354.5zM215 1277v23l222 232h122l226 -233v-22h-164l-123 151l-122 -151h-161zM279 471q0 -148 54 -243t165 -95 q108 0 162.5 95t54.5 243v138q0 146 -54.5 241.5t-163.5 95.5q-110 0 -164 -95t-54 -242v-138z" />
<glyph unicode="&#xf5;" d="M76 471v138q0 215 112.5 354t308.5 139q195 0 308 -138.5t113 -354.5v-138q0 -217 -112.5 -354.5t-307.5 -137.5q-197 0 -309.5 137.5t-112.5 354.5zM192 1308q0 90 50 155t126 65q48 0 124 -49.5t120 -49.5q33 0 56.5 34t23.5 84l110 -31q0 -92 -50 -155t-126 -63 q-61 0 -131 49t-113 49q-33 0 -56 -33.5t-23 -82.5zM279 471q0 -148 54 -243t165 -95q108 0 162.5 95t54.5 243v138q0 146 -54.5 241.5t-163.5 95.5q-110 0 -164 -95t-54 -242v-138z" />
<glyph unicode="&#xf6;" d="M76 471v138q0 215 112.5 354t308.5 139q195 0 308 -138.5t113 -354.5v-138q0 -217 -112.5 -354.5t-307.5 -137.5q-197 0 -309.5 137.5t-112.5 354.5zM181 1295v185h208v-185h-208zM279 471q0 -148 54 -243t165 -95q108 0 162.5 95t54.5 243v138q0 146 -54.5 241.5 t-163.5 95.5q-110 0 -164 -95t-54 -242v-138zM610 1295v185h207v-185h-207z" />
<glyph unicode="&#xf7;" horiz-adv-x="1005" d="M64 608v171h858v-171h-858zM392 188v195h205v-195h-205zM392 995v195h205v-195h-205z" />
<glyph unicode="&#xf8;" horiz-adv-x="996" d="M76 471v138q0 215 112.5 354t308.5 139q45 0 87 -8.5t80 -24.5l60 144h121l-85 -204q76 -66 117 -170t41 -230v-138q0 -217 -112.5 -354.5t-307.5 -137.5q-42 0 -80.5 7t-73.5 20l-60 -145h-121l83 200q-83 64 -126.5 170.5t-43.5 239.5zM279 471q0 -67 10 -122.5 t32 -91.5h6l273 659q-22 14 -48 22t-55 8q-110 0 -164 -95t-54 -242v-138zM406 155q20 -11 42.5 -16.5t49.5 -5.5q108 0 162.5 95t54.5 243v138q0 58 -9 108.5t-25 85.5l-6 1z" />
<glyph unicode="&#xf9;" d="M112 443v639h202v-641q0 -166 39.5 -235.5t118.5 -69.5q75 0 125.5 35t80.5 100v811h203v-1082h-181l-13 145q-43 -80 -110 -123t-154 -43q-147 0 -229 113t-82 351zM199 1479l2 5h227l169 -266h-170z" />
<glyph unicode="&#xfa;" d="M112 443v639h202v-641q0 -166 39.5 -235.5t118.5 -69.5q75 0 125.5 35t80.5 100v811h203v-1082h-181l-13 145q-43 -80 -110 -123t-154 -43q-147 0 -229 113t-82 351zM394 1215l172 266h226l2 -5l-238 -261h-162z" />
<glyph unicode="&#xfb;" d="M112 443v639h202v-641q0 -166 39.5 -235.5t118.5 -69.5q75 0 125.5 35t80.5 100v811h203v-1082h-181l-13 145q-43 -80 -110 -123t-154 -43q-147 0 -229 113t-82 351zM213 1256v23l222 232h122l226 -233v-22h-164l-123 151l-122 -151h-161z" />
<glyph unicode="&#xfc;" d="M112 443v639h202v-641q0 -166 39.5 -235.5t118.5 -69.5q75 0 125.5 35t80.5 100v811h203v-1082h-181l-13 145q-43 -80 -110 -123t-154 -43q-147 0 -229 113t-82 351zM179 1274v185h208v-185h-208zM608 1274v185h207v-185h-207z" />
<glyph unicode="&#xfd;" horiz-adv-x="892" d="M22 1082h220l178 -709l15 -71h6l208 780h221l-379 -1250q-38 -112 -103 -190.5t-187 -78.5q-25 0 -53.5 5.5t-56.5 12.5l22 150q11 -2 30 -4t30 -2q59 0 93.5 50.5t53.5 119.5l36 110zM343 1215l172 266h226l2 -5l-238 -261h-162z" />
<glyph unicode="&#xfe;" horiz-adv-x="1006" d="M120 0v1560h203v-590q42 64 102.5 98t138.5 34q169 0 263 -142t94 -376v-133q0 -214 -94 -343t-261 -129q-79 0 -139 31t-103 91v-517h-203v416h-1zM324 259q27 -61 73 -93.5t113 -32.5q105 0 156.5 87.5t51.5 230.5v133q0 159 -52.5 259.5t-156.5 100.5q-65 0 -111 -37 t-74 -101v-547z" />
<glyph unicode="&#xff;" horiz-adv-x="892" d="M22 1082h220l178 -709l15 -71h6l208 780h221l-379 -1250q-38 -112 -103 -190.5t-187 -78.5q-25 0 -53.5 5.5t-56.5 12.5l22 150q11 -2 30 -4t30 -2q59 0 93.5 50.5t53.5 119.5l36 110zM130 1274v185h208v-185h-208zM559 1274v185h207v-185h-207z" />
<glyph unicode="&#x152;" horiz-adv-x="1681" d="M93 576v304q0 265 136 431t356 166q58 0 118.5 -6t128.5 -15h759v-156h-620v-469h540v-155h-540v-522h626v-154h-765q-78 -10 -133.5 -15.5t-112.5 -5.5q-219 0 -356 166t-137 431zM296 576q0 -210 77.5 -326t212.5 -116q46 0 92 3.5t90 10.5v1160q-45 6 -90.5 10 t-92.5 4q-135 0 -212 -115.5t-77 -324.5v-306z" />
<glyph unicode="&#x153;" horiz-adv-x="1584" d="M84 526v27q0 241 112 395t307 154q104 0 186.5 -46.5t138.5 -130.5q54 84 132.5 130.5t172.5 46.5q184 0 283 -129.5t99 -347.5v-126h-581q2 -161 62.5 -263.5t172.5 -102.5q85 0 144.5 26.5t114.5 77.5l64 -126q-51 -58 -137 -95t-199 -37q-104 0 -188 45.5t-140 129.5 q-55 -84 -137 -129.5t-186 -45.5q-197 0 -309 152.5t-112 394.5zM286 526q0 -172 54.5 -282.5t164.5 -110.5q108 0 162.5 110.5t54.5 282.5v27q0 170 -54.5 281.5t-164.5 111.5q-109 0 -163 -112t-54 -281v-27zM938 644h377v28q0 120 -46.5 197t-135.5 77q-80 0 -131.5 -84 t-63.5 -218z" />
<glyph unicode="&#x178;" horiz-adv-x="1100" d="M23 1456h227l297 -707h6l298 707h225l-428 -932v-524h-202v537zM235 1613v185h208v-185h-208zM664 1613v185h207v-185h-207z" />
<glyph unicode="&#x2c6;" horiz-adv-x="853" d="M137 1252v23l222 232h122l226 -233v-22h-164l-123 151l-122 -151h-161z" />
<glyph unicode="&#x2dc;" horiz-adv-x="841" d="M112 1276q0 90 50 155t126 65q48 0 124 -49.5t120 -49.5q33 0 56.5 34t23.5 84l110 -31q0 -92 -50 -155t-126 -63q-61 0 -131 49t-113 49q-33 0 -56 -33.5t-23 -82.5z" />
<glyph unicode="&#x2000;" horiz-adv-x="959" />
<glyph unicode="&#x2001;" horiz-adv-x="1918" />
<glyph unicode="&#x2002;" horiz-adv-x="959" />
<glyph unicode="&#x2003;" horiz-adv-x="1918" />
<glyph unicode="&#x2004;" horiz-adv-x="639" />
<glyph unicode="&#x2005;" horiz-adv-x="479" />
<glyph unicode="&#x2006;" horiz-adv-x="319" />
<glyph unicode="&#x2007;" horiz-adv-x="319" />
<glyph unicode="&#x2008;" horiz-adv-x="239" />
<glyph unicode="&#x2009;" horiz-adv-x="383" />
<glyph unicode="&#x200a;" horiz-adv-x="106" />
<glyph unicode="&#x2010;" horiz-adv-x="598" d="M73 542v155h446v-155h-446z" />
<glyph unicode="&#x2011;" horiz-adv-x="598" d="M73 542v155h446v-155h-446z" />
<glyph unicode="&#x2012;" horiz-adv-x="598" d="M73 542v155h446v-155h-446z" />
<glyph unicode="&#x2013;" horiz-adv-x="1213" d="M150 649v155h918v-155h-918z" />
<glyph unicode="&#x2014;" horiz-adv-x="1425" d="M128 649v155h1130v-155h-1130z" />
<glyph unicode="&#x2018;" horiz-adv-x="360" d="M63 1040v182l133 338h100l-51 -339v-181h-182z" />
<glyph unicode="&#x2019;" horiz-adv-x="360" d="M67 1041l50 329v190h183v-188l-133 -331h-100z" />
<glyph unicode="&#x201a;" horiz-adv-x="358" d="M63 -239l50 265v239h183v-225l-126 -279h-107z" />
<glyph unicode="&#x201c;" horiz-adv-x="635" d="M63 1040v182l133 338h100l-51 -339v-181h-182zM337 1040v182l133 338h100l-51 -339v-181h-182z" />
<glyph unicode="&#x201d;" horiz-adv-x="642" d="M66 1041l50 329v190h183v-188l-133 -331h-100zM345 1041l50 329v190h183v-188l-133 -331h-100z" />
<glyph unicode="&#x201e;" horiz-adv-x="623" d="M63 -219l50 294v208h176v-199l-132 -303h-94zM333 -219l50 300v202h176v-199l-132 -303h-94z" />
<glyph unicode="&#x2022;" horiz-adv-x="644" d="M129 721v72q0 87 52.5 143t140.5 56q89 0 142 -56t53 -143v-72q0 -89 -52.5 -143.5t-140.5 -54.5q-89 0 -142 54.5t-53 143.5z" />
<glyph unicode="&#x2026;" horiz-adv-x="1240" d="M142 0v203h204v-203h-204zM528 0v203h204v-203h-204zM900 0v203h204v-203h-204z" />
<glyph unicode="&#x202f;" horiz-adv-x="383" />
<glyph unicode="&#x2039;" horiz-adv-x="547" d="M99 541v19l243 384h139l-210 -394l210 -394h-139z" />
<glyph unicode="&#x203a;" horiz-adv-x="538" d="M80 155l209 395l-209 396h139l243 -386v-19l-243 -386h-139z" />
<glyph unicode="&#x205f;" horiz-adv-x="479" />
<glyph unicode="&#x20ac;" horiz-adv-x="948" d="M71 491v155h126v141h-126v155h126v23q0 223 123 367.5t323 144.5q50 0 99 -8t106 -23l-17 -160q-45 16 -92.5 25.5t-95.5 9.5q-113 0 -178 -100.5t-65 -253.5v-25h391v-155h-391v-141h391v-155h-391v-9q0 -150 66 -249.5t178 -99.5q49 0 96 8.5t91 25.5l17 -157 q-48 -15 -100 -23t-104 -8q-200 0 -323.5 142t-123.5 361v9h-126z" />
<glyph unicode="&#x2122;" horiz-adv-x="1104" d="M92 1371v85h331v-85h-117v-453h-99v453h-115zM485 917v539h116l118 -392h6l119 392h110v-539h-92v318l-6 1l-108 -319h-52l-112 331h-6v-331h-93z" />
<glyph unicode="&#xe000;" horiz-adv-x="1080" d="M0 0v1080h1080v-1080h-1080z" />
<glyph unicode="&#xfb02;" horiz-adv-x="1085" d="M47 937v145h140v139q0 172 82.5 266t231.5 94q29 0 59.5 -5.5t68.5 -15.5l-20 -149q-17 5 -38 8t-45 3q-67 0 -101.5 -52t-34.5 -149v-139h189v-145h-189v-937h-203v937h-140zM752 0v1560h203v-1560h-203z" />
<glyph unicode="&#xfb03;" horiz-adv-x="1648" d="M47 937v145h140v139q0 172 82.5 266t231.5 94q29 0 59.5 -5.5t68.5 -15.5l-20 -149q-17 5 -38 8t-45 3q-67 0 -101.5 -52t-34.5 -149v-139h189v-145h-189v-937h-203v937h-140zM652 937v145h141v111q0 186 97.5 287t271.5 101q62 0 124.5 -15.5t135.5 -44.5l-31 -158 q-50 22 -102 35.5t-113 13.5q-92 0 -136 -55t-44 -164v-111h183v-145h-183v-937h-203v937h-141zM1315 0v1082h203v-1082h-203z" />
<glyph unicode="&#xfb04;" horiz-adv-x="1708" d="M47 937v145h140v139q0 172 82.5 266t231.5 94q29 0 59.5 -5.5t68.5 -15.5l-20 -149q-17 5 -38 8t-45 3q-67 0 -101.5 -52t-34.5 -149v-139h189v-145h-189v-937h-203v937h-140zM670 937v145h140v139q0 172 82.5 266t231.5 94q29 0 59.5 -5.5t68.5 -15.5l-20 -149 q-17 5 -38 8t-45 3q-67 0 -101.5 -52t-34.5 -149v-139h189v-145h-189v-937h-203v937h-140zM1375 0v1560h203v-1560h-203z" />
<hkern u1="&#x22;" u2="w" k="-11" />
<hkern u1="&#x27;" u2="w" k="-11" />
<hkern u1="&#x28;" u2="&#x178;" k="-22" />
<hkern u1="&#x28;" u2="&#xdd;" k="-22" />
<hkern u1="&#x28;" u2="Y" k="-22" />
<hkern u1="&#x28;" u2="W" k="-18" />
<hkern u1="&#x28;" u2="V" k="-20" />
<hkern u1="&#x2f;" u2="&#x2f;" k="224" />
<hkern u1="A" u2="w" k="33" />
<hkern u1="A" u2="t" k="17" />
<hkern u1="A" u2="&#x3f;" k="61" />
<hkern u1="C" u2="&#x7d;" k="17" />
<hkern u1="C" u2="]" k="12" />
<hkern u1="C" u2="&#x29;" k="26" />
<hkern u1="D" u2="&#xc6;" k="33" />
<hkern u1="E" u2="w" k="22" />
<hkern u1="E" u2="f" k="18" />
<hkern u1="F" u2="&#x2026;" k="234" />
<hkern u1="F" u2="&#x201e;" k="234" />
<hkern u1="F" u2="&#x201a;" k="234" />
<hkern u1="F" u2="&#x153;" k="21" />
<hkern u1="F" u2="&#xff;" k="24" />
<hkern u1="F" u2="&#xfd;" k="24" />
<hkern u1="F" u2="&#xfc;" k="22" />
<hkern u1="F" u2="&#xfb;" k="22" />
<hkern u1="F" u2="&#xfa;" k="22" />
<hkern u1="F" u2="&#xf9;" k="22" />
<hkern u1="F" u2="&#xf6;" k="21" />
<hkern u1="F" u2="&#xf5;" k="21" />
<hkern u1="F" u2="&#xf4;" k="21" />
<hkern u1="F" u2="&#xf3;" k="21" />
<hkern u1="F" u2="&#xf2;" k="21" />
<hkern u1="F" u2="&#xeb;" k="21" />
<hkern u1="F" u2="&#xea;" k="21" />
<hkern u1="F" u2="&#xe9;" k="21" />
<hkern u1="F" u2="&#xe8;" k="21" />
<hkern u1="F" u2="&#xe7;" k="21" />
<hkern u1="F" u2="&#xe5;" k="34" />
<hkern u1="F" u2="&#xe4;" k="34" />
<hkern u1="F" u2="&#xe3;" k="34" />
<hkern u1="F" u2="&#xe2;" k="34" />
<hkern u1="F" u2="&#xe1;" k="34" />
<hkern u1="F" u2="&#xe0;" k="34" />
<hkern u1="F" u2="&#xc5;" k="59" />
<hkern u1="F" u2="&#xc4;" k="59" />
<hkern u1="F" u2="&#xc3;" k="59" />
<hkern u1="F" u2="&#xc2;" k="59" />
<hkern u1="F" u2="&#xc1;" k="59" />
<hkern u1="F" u2="&#xc0;" k="59" />
<hkern u1="F" u2="y" k="24" />
<hkern u1="F" u2="v" k="24" />
<hkern u1="F" u2="u" k="22" />
<hkern u1="F" u2="r" k="26" />
<hkern u1="F" u2="q" k="21" />
<hkern u1="F" u2="o" k="21" />
<hkern u1="F" u2="g" k="21" />
<hkern u1="F" u2="e" k="21" />
<hkern u1="F" u2="d" k="21" />
<hkern u1="F" u2="c" k="21" />
<hkern u1="F" u2="a" k="34" />
<hkern u1="F" u2="T" k="-20" />
<hkern u1="F" u2="J" k="264" />
<hkern u1="F" u2="A" k="59" />
<hkern u1="F" u2="&#x2e;" k="234" />
<hkern u1="F" u2="&#x2c;" k="234" />
<hkern u1="K" u2="w" k="63" />
<hkern u1="L" u2="w" k="92" />
<hkern u1="O" u2="&#xc6;" k="33" />
<hkern u1="P" u2="&#xc6;" k="97" />
<hkern u1="P" u2="t" k="-14" />
<hkern u1="Q" u2="&#x178;" k="35" />
<hkern u1="Q" u2="&#xdd;" k="35" />
<hkern u1="Q" u2="Y" k="35" />
<hkern u1="Q" u2="W" k="20" />
<hkern u1="Q" u2="V" k="28" />
<hkern u1="Q" u2="T" k="43" />
<hkern u1="R" u2="&#x178;" k="48" />
<hkern u1="R" u2="&#xdd;" k="48" />
<hkern u1="R" u2="Y" k="48" />
<hkern u1="R" u2="V" k="19" />
<hkern u1="R" u2="T" k="80" />
<hkern u1="T" u2="&#xf8;" k="95" />
<hkern u1="T" u2="&#xe6;" k="114" />
<hkern u1="T" u2="&#xc6;" k="179" />
<hkern u1="T" u2="&#xbb;" k="216" />
<hkern u1="T" u2="&#xab;" k="328" />
<hkern u1="T" u2="w" k="57" />
<hkern u1="T" u2="r" k="75" />
<hkern u1="V" u2="&#x7d;" k="-19" />
<hkern u1="V" u2="r" k="30" />
<hkern u1="V" u2="]" k="-17" />
<hkern u1="V" u2="&#x29;" k="-20" />
<hkern u1="W" u2="&#x7d;" k="-14" />
<hkern u1="W" u2="r" k="21" />
<hkern u1="W" u2="]" k="-12" />
<hkern u1="W" u2="&#x29;" k="-15" />
<hkern u1="Y" u2="&#x2022;" k="45" />
<hkern u1="Y" u2="&#xf8;" k="64" />
<hkern u1="Y" u2="&#xe6;" k="63" />
<hkern u1="Y" u2="&#xc6;" k="96" />
<hkern u1="Y" u2="&#xbb;" k="51" />
<hkern u1="Y" u2="&#xab;" k="82" />
<hkern u1="Y" u2="&#x7d;" k="-19" />
<hkern u1="Y" u2="t" k="22" />
<hkern u1="Y" u2="r" k="40" />
<hkern u1="Y" u2="f" k="22" />
<hkern u1="Y" u2="]" k="-18" />
<hkern u1="Y" u2="&#x2a;" k="49" />
<hkern u1="Y" u2="&#x29;" k="-20" />
<hkern u1="Y" u2="&#x26;" k="30" />
<hkern u1="Z" u2="w" k="27" />
<hkern u1="[" u2="&#xdc;" k="18" />
<hkern u1="[" u2="&#xdb;" k="18" />
<hkern u1="[" u2="&#xda;" k="18" />
<hkern u1="[" u2="&#xd9;" k="18" />
<hkern u1="[" u2="U" k="18" />
<hkern u1="[" u2="J" k="18" />
<hkern u1="f" u2="&#x201d;" k="-16" />
<hkern u1="f" u2="&#x201c;" k="-16" />
<hkern u1="f" u2="&#x2019;" k="-16" />
<hkern u1="f" u2="&#x2018;" k="-16" />
<hkern u1="f" u2="&#x153;" k="24" />
<hkern u1="f" u2="&#xeb;" k="24" />
<hkern u1="f" u2="&#xea;" k="24" />
<hkern u1="f" u2="&#xe9;" k="24" />
<hkern u1="f" u2="&#xe8;" k="24" />
<hkern u1="f" u2="&#xe7;" k="24" />
<hkern u1="f" u2="&#x7d;" k="-19" />
<hkern u1="f" u2="q" k="24" />
<hkern u1="f" u2="g" k="24" />
<hkern u1="f" u2="e" k="24" />
<hkern u1="f" u2="d" k="24" />
<hkern u1="f" u2="c" k="24" />
<hkern u1="f" u2="]" k="-18" />
<hkern u1="f" u2="&#x29;" k="-20" />
<hkern u1="f" u2="&#x27;" k="-16" />
<hkern u1="f" u2="&#x22;" k="-16" />
<hkern u1="k" u2="&#x153;" k="20" />
<hkern u1="k" u2="&#xeb;" k="20" />
<hkern u1="k" u2="&#xea;" k="20" />
<hkern u1="k" u2="&#xe9;" k="20" />
<hkern u1="k" u2="&#xe8;" k="20" />
<hkern u1="k" u2="&#xe7;" k="20" />
<hkern u1="k" u2="q" k="20" />
<hkern u1="k" u2="g" k="20" />
<hkern u1="k" u2="e" k="20" />
<hkern u1="k" u2="d" k="20" />
<hkern u1="k" u2="c" k="20" />
<hkern u1="r" u2="w" k="-17" />
<hkern u1="r" u2="t" k="-32" />
<hkern u1="r" u2="f" k="-15" />
<hkern u1="t" u2="&#xf6;" k="20" />
<hkern u1="t" u2="&#xf5;" k="20" />
<hkern u1="t" u2="&#xf4;" k="20" />
<hkern u1="t" u2="&#xf3;" k="20" />
<hkern u1="t" u2="&#xf2;" k="20" />
<hkern u1="t" u2="o" k="20" />
<hkern u1="v" u2="f" k="-13" />
<hkern u1="w" u2="&#x2026;" k="124" />
<hkern u1="w" u2="&#x201e;" k="124" />
<hkern u1="w" u2="&#x201a;" k="124" />
<hkern u1="w" u2="&#x2e;" k="124" />
<hkern u1="w" u2="&#x2c;" k="124" />
<hkern u1="y" u2="f" k="-13" />
<hkern u1="&#x7b;" u2="&#xdc;" k="20" />
<hkern u1="&#x7b;" u2="&#xdb;" k="20" />
<hkern u1="&#x7b;" u2="&#xda;" k="20" />
<hkern u1="&#x7b;" u2="&#xd9;" k="20" />
<hkern u1="&#x7b;" u2="U" k="20" />
<hkern u1="&#x7b;" u2="J" k="20" />
<hkern u1="&#xc0;" u2="w" k="33" />
<hkern u1="&#xc0;" u2="t" k="17" />
<hkern u1="&#xc0;" u2="&#x3f;" k="61" />
<hkern u1="&#xc1;" u2="w" k="33" />
<hkern u1="&#xc1;" u2="t" k="17" />
<hkern u1="&#xc1;" u2="&#x3f;" k="61" />
<hkern u1="&#xc2;" u2="w" k="33" />
<hkern u1="&#xc2;" u2="t" k="17" />
<hkern u1="&#xc2;" u2="&#x3f;" k="61" />
<hkern u1="&#xc3;" u2="w" k="33" />
<hkern u1="&#xc3;" u2="t" k="17" />
<hkern u1="&#xc3;" u2="&#x3f;" k="61" />
<hkern u1="&#xc4;" u2="w" k="33" />
<hkern u1="&#xc4;" u2="t" k="17" />
<hkern u1="&#xc4;" u2="&#x3f;" k="61" />
<hkern u1="&#xc5;" u2="w" k="33" />
<hkern u1="&#xc5;" u2="t" k="17" />
<hkern u1="&#xc5;" u2="&#x3f;" k="61" />
<hkern u1="&#xc7;" u2="&#x7d;" k="17" />
<hkern u1="&#xc7;" u2="]" k="12" />
<hkern u1="&#xc7;" u2="&#x29;" k="26" />
<hkern u1="&#xc8;" u2="w" k="22" />
<hkern u1="&#xc8;" u2="f" k="18" />
<hkern u1="&#xc9;" u2="w" k="22" />
<hkern u1="&#xc9;" u2="f" k="18" />
<hkern u1="&#xca;" u2="w" k="22" />
<hkern u1="&#xca;" u2="f" k="18" />
<hkern u1="&#xcb;" u2="w" k="22" />
<hkern u1="&#xcb;" u2="f" k="18" />
<hkern u1="&#xd0;" u2="&#xc6;" k="33" />
<hkern u1="&#xd2;" u2="&#xc6;" k="33" />
<hkern u1="&#xd3;" u2="&#xc6;" k="33" />
<hkern u1="&#xd4;" u2="&#xc6;" k="33" />
<hkern u1="&#xd5;" u2="&#xc6;" k="33" />
<hkern u1="&#xd6;" u2="&#xc6;" k="33" />
<hkern u1="&#xdd;" u2="&#x2022;" k="45" />
<hkern u1="&#xdd;" u2="&#xf8;" k="64" />
<hkern u1="&#xdd;" u2="&#xe6;" k="63" />
<hkern u1="&#xdd;" u2="&#xc6;" k="96" />
<hkern u1="&#xdd;" u2="&#xbb;" k="51" />
<hkern u1="&#xdd;" u2="&#xab;" k="82" />
<hkern u1="&#xdd;" u2="&#x7d;" k="-19" />
<hkern u1="&#xdd;" u2="t" k="22" />
<hkern u1="&#xdd;" u2="r" k="40" />
<hkern u1="&#xdd;" u2="f" k="22" />
<hkern u1="&#xdd;" u2="]" k="-18" />
<hkern u1="&#xdd;" u2="&#x2a;" k="49" />
<hkern u1="&#xdd;" u2="&#x29;" k="-20" />
<hkern u1="&#xdd;" u2="&#x26;" k="30" />
<hkern u1="&#xfd;" u2="f" k="-13" />
<hkern u1="&#xff;" u2="f" k="-13" />
<hkern u1="&#x178;" u2="&#x2022;" k="45" />
<hkern u1="&#x178;" u2="&#xf8;" k="64" />
<hkern u1="&#x178;" u2="&#xe6;" k="63" />
<hkern u1="&#x178;" u2="&#xc6;" k="96" />
<hkern u1="&#x178;" u2="&#xbb;" k="51" />
<hkern u1="&#x178;" u2="&#xab;" k="82" />
<hkern u1="&#x178;" u2="&#x7d;" k="-19" />
<hkern u1="&#x178;" u2="t" k="22" />
<hkern u1="&#x178;" u2="r" k="40" />
<hkern u1="&#x178;" u2="f" k="22" />
<hkern u1="&#x178;" u2="]" k="-18" />
<hkern u1="&#x178;" u2="&#x2a;" k="49" />
<hkern u1="&#x178;" u2="&#x29;" k="-20" />
<hkern u1="&#x178;" u2="&#x26;" k="30" />
<hkern u1="&#x2018;" u2="w" k="-11" />
<hkern u1="&#x2019;" u2="w" k="-11" />
<hkern u1="&#x201c;" u2="w" k="-11" />
<hkern u1="&#x201d;" u2="w" k="-11" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright" k="170" />
<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright" k="120" />
<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="o,ograve,oacute,ocircumflex,otilde,odieresis" k="12" />
<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="11" />
<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="T" k="129" />
<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="17" />
<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="V" k="87" />
<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="W" k="69" />
<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="Y,Yacute,Ydieresis" k="94" />
<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="u,ugrave,uacute,ucircumflex,udieresis" k="11" />
<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="v,y,yacute,ydieresis" k="50" />
<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="z" k="-12" />
<hkern g1="B" g2="T" k="27" />
<hkern g1="B" g2="V" k="24" />
<hkern g1="B" g2="Y,Yacute,Ydieresis" k="55" />
<hkern g1="C,Ccedilla" g2="T" k="29" />
<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="21" />
<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis" g2="T" k="27" />
<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis" g2="V" k="22" />
<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis" g2="Y,Yacute,Ydieresis" k="43" />
<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="102" />
<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis" g2="X" k="22" />
<hkern g1="D,O,Eth,Ograve,Oacute,Ocircumflex,Otilde,Odieresis" g2="Z" k="23" />
<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis" g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe" k="19" />
<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis" g2="o,ograve,oacute,ocircumflex,otilde,odieresis" k="19" />
<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis" g2="T" k="-20" />
<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis" g2="u,ugrave,uacute,ucircumflex,udieresis" k="17" />
<hkern g1="E,Egrave,Eacute,Ecircumflex,Edieresis" g2="v,y,yacute,ydieresis" k="26" />
<hkern g1="H,I,M,N,Igrave,Iacute,Icircumflex,Idieresis,Ntilde" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="-18" />
<hkern g1="H,I,M,N,Igrave,Iacute,Icircumflex,Idieresis,Ntilde" g2="T" k="29" />
<hkern g1="H,I,M,N,Igrave,Iacute,Icircumflex,Idieresis,Ntilde" g2="Y,Yacute,Ydieresis" k="28" />
<hkern g1="H,I,M,N,Igrave,Iacute,Icircumflex,Idieresis,Ntilde" g2="X" k="-17" />
<hkern g1="J,U,Ugrave,Uacute,Ucircumflex,Udieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="22" />
<hkern g1="K" g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe" k="26" />
<hkern g1="K" g2="m,n,p,ntilde" k="23" />
<hkern g1="K" g2="o,ograve,oacute,ocircumflex,otilde,odieresis" k="27" />
<hkern g1="K" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="31" />
<hkern g1="K" g2="u,ugrave,uacute,ucircumflex,udieresis" k="23" />
<hkern g1="K" g2="v,y,yacute,ydieresis" k="40" />
<hkern g1="K" g2="hyphen,uni00AD,endash,emdash" k="64" />
<hkern g1="L" g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright" k="138" />
<hkern g1="L" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="-19" />
<hkern g1="L" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="65" />
<hkern g1="L" g2="T" k="275" />
<hkern g1="L" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="54" />
<hkern g1="L" g2="V" k="175" />
<hkern g1="L" g2="W" k="143" />
<hkern g1="L" g2="Y,Yacute,Ydieresis" k="239" />
<hkern g1="L" g2="u,ugrave,uacute,ucircumflex,udieresis" k="44" />
<hkern g1="L" g2="v,y,yacute,ydieresis" k="133" />
<hkern g1="P" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="138" />
<hkern g1="P" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring" k="11" />
<hkern g1="P" g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe" k="13" />
<hkern g1="P" g2="o,ograve,oacute,ocircumflex,otilde,odieresis" k="13" />
<hkern g1="P" g2="v,y,yacute,ydieresis" k="-15" />
<hkern g1="P" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="324" />
<hkern g1="P" g2="X" k="31" />
<hkern g1="P" g2="Z" k="26" />
<hkern g1="P" g2="J" k="200" />
<hkern g1="T" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="79" />
<hkern g1="T" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring" k="113" />
<hkern g1="T" g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe" k="99" />
<hkern g1="T" g2="m,n,p,ntilde" k="109" />
<hkern g1="T" g2="o,ograve,oacute,ocircumflex,otilde,odieresis" k="99" />
<hkern g1="T" g2="s" k="116" />
<hkern g1="T" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="28" />
<hkern g1="T" g2="T" k="-16" />
<hkern g1="T" g2="V" k="-16" />
<hkern g1="T" g2="W" k="-15" />
<hkern g1="T" g2="Y,Yacute,Ydieresis" k="-16" />
<hkern g1="T" g2="u,ugrave,uacute,ucircumflex,udieresis" k="95" />
<hkern g1="T" g2="v,y,yacute,ydieresis" k="72" />
<hkern g1="T" g2="z" k="60" />
<hkern g1="T" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="218" />
<hkern g1="T" g2="hyphen,uni00AD,endash,emdash" k="232" />
<hkern g1="T" g2="J" k="240" />
<hkern g1="T" g2="S" k="16" />
<hkern g1="T" g2="x" k="77" />
<hkern g1="V" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="75" />
<hkern g1="V" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring" k="46" />
<hkern g1="V" g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe" k="44" />
<hkern g1="V" g2="o,ograve,oacute,ocircumflex,otilde,odieresis" k="46" />
<hkern g1="V" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="13" />
<hkern g1="V" g2="u,ugrave,uacute,ucircumflex,udieresis" k="28" />
<hkern g1="V" g2="v,y,yacute,ydieresis" k="11" />
<hkern g1="V" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="225" />
<hkern g1="V" g2="hyphen,uni00AD,endash,emdash" k="37" />
<hkern g1="W" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="43" />
<hkern g1="W" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring" k="33" />
<hkern g1="W" g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe" k="31" />
<hkern g1="W" g2="o,ograve,oacute,ocircumflex,otilde,odieresis" k="31" />
<hkern g1="W" g2="T" k="-14" />
<hkern g1="W" g2="u,ugrave,uacute,ucircumflex,udieresis" k="19" />
<hkern g1="W" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="123" />
<hkern g1="W" g2="hyphen,uni00AD,endash,emdash" k="60" />
<hkern g1="X" g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe" k="26" />
<hkern g1="X" g2="o,ograve,oacute,ocircumflex,otilde,odieresis" k="21" />
<hkern g1="X" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="25" />
<hkern g1="X" g2="V" k="-14" />
<hkern g1="X" g2="u,ugrave,uacute,ucircumflex,udieresis" k="21" />
<hkern g1="X" g2="v,y,yacute,ydieresis" k="31" />
<hkern g1="X" g2="hyphen,uni00AD,endash,emdash" k="46" />
<hkern g1="Y,Yacute,Ydieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="94" />
<hkern g1="Y,Yacute,Ydieresis" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring" k="73" />
<hkern g1="Y,Yacute,Ydieresis" g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe" k="65" />
<hkern g1="Y,Yacute,Ydieresis" g2="m,n,p,ntilde" k="40" />
<hkern g1="Y,Yacute,Ydieresis" g2="o,ograve,oacute,ocircumflex,otilde,odieresis" k="65" />
<hkern g1="Y,Yacute,Ydieresis" g2="s" k="58" />
<hkern g1="Y,Yacute,Ydieresis" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="29" />
<hkern g1="Y,Yacute,Ydieresis" g2="T" k="-17" />
<hkern g1="Y,Yacute,Ydieresis" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="96" />
<hkern g1="Y,Yacute,Ydieresis" g2="V" k="-18" />
<hkern g1="Y,Yacute,Ydieresis" g2="W" k="-17" />
<hkern g1="Y,Yacute,Ydieresis" g2="Y,Yacute,Ydieresis" k="-18" />
<hkern g1="Y,Yacute,Ydieresis" g2="u,ugrave,uacute,ucircumflex,udieresis" k="39" />
<hkern g1="Y,Yacute,Ydieresis" g2="v,y,yacute,ydieresis" k="20" />
<hkern g1="Y,Yacute,Ydieresis" g2="z" k="30" />
<hkern g1="Y,Yacute,Ydieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="211" />
<hkern g1="Y,Yacute,Ydieresis" g2="X" k="-13" />
<hkern g1="Y,Yacute,Ydieresis" g2="hyphen,uni00AD,endash,emdash" k="52" />
<hkern g1="Y,Yacute,Ydieresis" g2="J" k="96" />
<hkern g1="Y,Yacute,Ydieresis" g2="S" k="16" />
<hkern g1="Y,Yacute,Ydieresis" g2="x" k="23" />
<hkern g1="Z" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="-13" />
<hkern g1="Z" g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe" k="21" />
<hkern g1="Z" g2="o,ograve,oacute,ocircumflex,otilde,odieresis" k="21" />
<hkern g1="Z" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="26" />
<hkern g1="Z" g2="u,ugrave,uacute,ucircumflex,udieresis" k="19" />
<hkern g1="Z" g2="v,y,yacute,ydieresis" k="27" />
<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring" g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright" k="67" />
<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring" g2="v,y,yacute,ydieresis" k="15" />
<hkern g1="b,p,thorn" g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright" k="29" />
<hkern g1="b,p,thorn" g2="v,y,yacute,ydieresis" k="11" />
<hkern g1="b,p,thorn" g2="z" k="15" />
<hkern g1="b,p,thorn" g2="x" k="15" />
<hkern g1="c,ccedilla" g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright" k="11" />
<hkern g1="e,egrave,eacute,ecircumflex,edieresis" g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright" k="14" />
<hkern g1="e,egrave,eacute,ecircumflex,edieresis" g2="v,y,yacute,ydieresis" k="13" />
<hkern g1="h,m,n,ntilde" g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright" k="16" />
<hkern g1="o,ograve,oacute,ocircumflex,otilde,odieresis" g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright" k="20" />
<hkern g1="o,ograve,oacute,ocircumflex,otilde,odieresis" g2="v,y,yacute,ydieresis" k="15" />
<hkern g1="o,ograve,oacute,ocircumflex,otilde,odieresis" g2="z" k="16" />
<hkern g1="o,ograve,oacute,ocircumflex,otilde,odieresis" g2="x" k="21" />
<hkern g1="r" g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright" k="-16" />
<hkern g1="r" g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe" k="19" />
<hkern g1="r" g2="o,ograve,oacute,ocircumflex,otilde,odieresis" k="20" />
<hkern g1="r" g2="v,y,yacute,ydieresis" k="-18" />
<hkern g1="r" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="123" />
<hkern g1="v,y,yacute,ydieresis" g2="quotedbl,quotesingle,quoteleft,quoteright,quotedblleft,quotedblright" k="-15" />
<hkern g1="v,y,yacute,ydieresis" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring" k="15" />
<hkern g1="v,y,yacute,ydieresis" g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe" k="13" />
<hkern g1="v,y,yacute,ydieresis" g2="o,ograve,oacute,ocircumflex,otilde,odieresis" k="15" />
<hkern g1="v,y,yacute,ydieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="107" />
<hkern g1="x" g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe" k="20" />
<hkern g1="x" g2="o,ograve,oacute,ocircumflex,otilde,odieresis" k="20" />
<hkern g1="z" g2="c,d,e,g,q,ccedilla,egrave,eacute,ecircumflex,edieresis,oe" k="16" />
<hkern g1="z" g2="o,ograve,oacute,ocircumflex,otilde,odieresis" k="16" />
</font>
</defs></svg>

BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/RobotoCondensed-Regular-webfont.ttf View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/RobotoCondensed-Regular-webfont.woff View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/RobotoCondensed-Regular.ttf View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessketch-webfont.eot View File


+ 668
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessketch-webfont.svg
File diff suppressed because it is too large
View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessketch-webfont.ttf View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessketch-webfont.woff View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessolid-webfont.eot View File


+ 668
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessolid-webfont.svg View File

@@ -0,0 +1,668 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata></metadata>
<defs>
<font id="kg_second_chances_solidRg" horiz-adv-x="1800" >
<font-face units-per-em="2048" ascent="1638" descent="-410" />
<missing-glyph horiz-adv-x="579" />
<glyph horiz-adv-x="2048" />
<glyph horiz-adv-x="2048" />
<glyph unicode="&#xd;" horiz-adv-x="579" />
<glyph unicode=" " horiz-adv-x="579" />
<glyph unicode="&#x09;" horiz-adv-x="579" />
<glyph unicode="&#xa0;" horiz-adv-x="579" />
<glyph unicode="!" horiz-adv-x="524" d="M462 919q0 -13 1 -47t1.5 -72t1.5 -72t1 -47q-1 -3 -2 -11t-2 -17.5t-1.5 -17.5t-0.5 -11v-121q-6 -9 -22 -13.5t-25 -4.5h-286q-8 3 -14.5 4t-11.5 6.5t-8 19.5t-3 44q-1 2 -2 8.5t-2 14t-1.5 14t-0.5 8.5q0 14 -1.5 51t-3 78.5t-3 78.5t-1.5 51q0 7 -2 35.5t-5 60.5 t-5 60t-2 36q0 9 -1 34.5t-3 59t-4 71.5t-4 72t-3.5 59t-1.5 34q-1 15 -1 47t-0.5 67.5t-1.5 67.5t-3 47v14q-5 39 5.5 60t40.5 15l317 -2q22 0 31 -13.5t11.5 -35t2 -50t4.5 -58.5q2 -23 2 -49t-1 -52.5t-1.5 -52.5t1.5 -48q3 -58 5 -109.5t3 -102t1.5 -102.5t0.5 -109z M489 152v-28.5t-7 -29.5q-11 -21 -19.5 -40.5t-25.5 -36.5q-5 -5 -13 -11t-16.5 -12.5t-16 -12t-9.5 -7.5q-11 -9 -23.5 -12.5t-26 -4t-27.5 0.5t-27 1q-17 0 -28.5 4.5t-28.5 11.5q-8 2 -21.5 9.5t-21.5 13.5q-40 28 -68.5 67t-33.5 93q0 31 2 53.5t9 41t21 35t38 36.5 q22 19 54 33t61 14q3 0 10.5 -0.5t15.5 -1.5t15.5 -2t9.5 -2l12 -3t16.5 -5t15.5 -5t9 -3q1 -2 8.5 -5t16.5 -6.5t17 -7t10 -4.5q22 -18 36.5 -36.5t22 -39t10.5 -44.5t3 -54z" />
<glyph unicode="&#x22;" horiz-adv-x="1207" d="M147 686q1 1 3.5 6.5t6 11t6 10.5l3.5 7q14 34 24 64t18 60t14.5 62t12.5 68q0 3 1 12t2 19.5t2 20t1 12.5q-9 0 -13.5 -2t-8.5 -4.5t-8.5 -5t-12.5 -4.5q-35 -6 -68 -6q-11 0 -26 8.5t-15 22.5q0 63 0.5 117t-1.5 116q2 4 2 10.5t1.5 12.5t6 11.5t15.5 9.5h76 q3 0 11.5 0.5t18 1.5t18 2t12.5 2q4 0 22.5 -0.5t40 -0.5h39.5t23 1q2 0 10.5 0.5t18.5 1.5t18 1.5t10 0.5t12.5 1t16.5 1q11 0 23.5 -0.5t23.5 -5.5q12 -6 18.5 -24t9.5 -38.5t4 -39t1 -27.5v-14q0 -2 -3 -6.5t-3 -6.5q-1 -2 -2 -10t-2 -17t-1.5 -17.5t-0.5 -12.5 q1 -10 -1.5 -27.5t-7 -34t-10 -29t-10.5 -11.5q-14 -26 -22.5 -54.5t-22.5 -56.5q-18 -32 -41 -65t-49.5 -63t-57.5 -54.5t-65 -39.5q-2 -1 -9.5 -4.5t-17 -8t-19 -8.5t-13.5 -5q-9 -3 -12.5 -4.5t-11.5 -1.5q-10 0 -10.5 6t-0.5 14v15zM728 789q1 1 3.5 6.5t6 11t6 10.5 l3.5 7q14 34 24 64t18 60t14.5 62t12.5 68q0 3 1 12t2 19.5t2 20t1 12.5q-9 0 -13.5 -2t-8.5 -4.5t-8.5 -5t-12.5 -4.5q-35 -6 -68 -6q-11 0 -26 8.5t-15 22.5q0 63 0.5 117t-1.5 116q2 4 2 10.5t1.5 12.5t6 11.5t15.5 9.5h76q3 0 11.5 0.5t18 1.5t18 2t12.5 2 q4 0 22.5 -0.5t40 -0.5h39.5t23 1q2 0 10.5 0.5t18.5 1.5t18 1.5t10 0.5t12.5 1t16.5 1q11 0 23.5 -0.5t23.5 -5.5q12 -6 18.5 -24t9.5 -38.5t4 -39t1 -27.5v-14q0 -2 -3 -6.5t-3 -6.5q-1 -2 -2 -10t-2 -17t-1.5 -17.5t-0.5 -12.5q1 -10 -1.5 -27.5t-7 -34t-10 -29 t-10.5 -11.5q-14 -26 -22.5 -54.5t-22.5 -56.5q-18 -32 -41 -65t-49.5 -63t-57.5 -54.5t-65 -39.5q-2 -1 -9.5 -4.5t-17 -8t-19 -8.5t-13.5 -5q-9 -3 -12.5 -4.5t-11.5 -1.5q-10 0 -10.5 6t-0.5 14v15z" />
<glyph unicode="#" horiz-adv-x="1200" d="M730 214q-2 0 -4 10t-3.5 25.5t-3 33.5t-1.5 33q-1 13 -1 21.5t-0.5 17t-1 19t-1.5 28.5q0 9 -3.5 11t-11.5 2h-8q-2 -1 -13.5 -3t-13.5 -2q-3 0 -13.5 -0.5t-22 -1t-22 -1t-14.5 -0.5q-6 -4 -9 -14t-4.5 -21.5l-3 -23t-2.5 -18.5q0 -5 -2.5 -21.5t-5 -36t-5 -36.5 t-3.5 -22q0 -16 -12 -23q-23 -1 -42 -3t-37.5 -3.5t-38 -3t-43.5 -0.5h-20q-3 1 -8.5 4.5t-10.5 7.5t-8.5 8.5t-3.5 8.5l-1 4q0 4 1 19t2.5 32t2.5 32t1 20q0 3 1 9t1.5 12.5t1 12t0.5 6.5q0 3 -1 9.5t-1.5 13.5t-1.5 13.5t-1 8.5h-1q-1 0 -2 1l-32 1q-30 1 -60 -2t-59 -3 q-3 0 -8 0.5t-10 1.5t-11 1l-5 5q-6 42 -8 88.5t-4 92.5v3q0 2 1 7t3 7q3 1 6 3q6 2 6 4q44 12 74.5 14t53.5 1t41.5 -2t37.5 4q2 31 4.5 59t0.5 59q0 2 -0.5 5t-0.5 6q-1 4 -1 7l-6 5h-5t-11 0.5t-12 0.5h-9q-17 1 -27 2t-18.5 1.5t-16 1t-18.5 2.5q-2 0 -5 -2t-5 -2 q-15 2 -26 2.5t-18.5 0.5t-12 2t-7.5 7t-3.5 14t0 20t0.5 23t-3 24q1 3 0.5 12.5t-1 20.5t-0.5 22v16q0 9 0.5 12.5t0.5 6.5t0.5 7t1.5 13q1 11 5.5 17t18.5 5h14.5t5 1t4 1.5t11.5 0.5l150 -7q6 36 12 70t9 68.5t1.5 70t-8.5 74.5q1 12 3.5 18t5.5 8.5t7 2t7 -0.5l158 -8 q9 -1 23 -0.5t28 0t24.5 -5t10.5 -16.5q1 -17 -1 -32t-6 -29.5t-7.5 -29t-5.5 -30.5q0 -6 -0.5 -19.5t-1 -28.5t-1.5 -28t-1 -16l1 -22q-1 -17 -6 -38t-5 -38q0 -1 3 -0.5l6 1t6 0.5t3 -1q19 -5 37 0.5t36 4.5h8.5h12t12 -0.5t7.5 -0.5q4 5 6 12t3 12q1 6 5 29.5t9 50.5 t9 51t6 30q1 8 0 22t0 17q1 2 1 11v20t0.5 21.5t2.5 16.5q2 9 8 17t16 7h15t21 -0.5t21 -0.5h15q20 -1 34.5 -3t36.5 -2h40q2 -3 7.5 -11t6.5 -11v-2q0 -4 3.5 -13.5t2.5 -14.5q-2 -2 -3 -6.5t-1 -6.5q1 -2 1 -13.5v-13.5t-2 -5.5t-2 -4.5q-1 -2 -2 -9t-2 -9q-5 -45 -7 -87 t0 -88q1 0 6.5 -0.5t11.5 -1t12 -0.5t8 1q3 0 15 1t25.5 2.5t26 2t15.5 0.5h4q2 0 3 0.5t2 0.5q21 -2 23 -24l3 -67v-14q0 -4 -0.5 -13.5t-0.5 -20.5t-0.5 -20.5t-0.5 -13.5q0 -3 -0.5 -9t-0.5 -12.5t-0.5 -12t-0.5 -6.5q0 -2 -3 -2h-6.5t-7 0.5t-3.5 -0.5q-3 -3 -16 -5 t-29.5 -2.5t-32.5 -0.5h-24q-22 1 -43 3.5t-43 2.5l-11 1q-1 -1 -1.5 -6t-2.5 -6v-9v-15t-0.5 -15t-1.5 -8q0 -2 -0.5 -14t-0.5 -25.5t-0.5 -25.5t-0.5 -15v-11q0 -11 3 -13t13 -2l13 -1q1 0 7 1.5t13.5 3t14.5 3t9 1.5h5.5h9.5t9.5 -0.5t5.5 -0.5q3 0 12.5 0.5t20 1.5 t20 1.5t11.5 0.5l11 -1q6 1 12 -1.5t11 -7t7 -9.5t0 -9q0 -3 -0.5 -10t-1 -14.5t-1 -14.5t-0.5 -10v-4q0 -2 0.5 -3.5t0.5 -2.5v-5q0 -2 1 -3q0 -2 -1.5 -8.5t-3 -14t-2.5 -15t0 -10.5v-8.5v-16.5t-0.5 -16.5t-1.5 -8.5q2 -11 -5 -12.5t-15 -2.5l-103 -10q-2 0 -5 1t-8 1 q-14 0 -24 -0.5t-25 -2.5q-4 -2 -4.5 -4.5t-0.5 -5.5q-2 -17 0.5 -34.5t2.5 -46.5v-10q1 -11 1.5 -26t0.5 -29v-33l-9 -7q-2 0 -17 0.5t-35.5 1.5t-43 2t-37.5 0h-5.5h-10.5t-12 -0.5t-9 -0.5q-4 1 -13.5 1.5t-10.5 0.5zM594 642q0 -4 4 -4h6q13 0 24 -1.5t21.5 -2.5t22 -1 t25.5 3q6 0 18.5 2.5t12.5 4.5v109q0 5 -5 10h-4q-1 -1 -7 -2t-12.5 -2t-12.5 -2t-7 -1q-6 0 -17 2t-22.5 4t-22 3.5t-17.5 1.5l-4 -3z" />
<glyph unicode="$" horiz-adv-x="1175" d="M482 -206q-6 0 -9 3t-5 7t-3.5 8.5t-4.5 7.5q1 4 1 15t-0.5 22.5t-1 22t-1.5 15.5q0 1 -1 7l-2 12t-2 11.5t-2 7.5q0 3 -2 13t-4 22t-4 22.5t-2 13.5q-2 2 -4.5 12.5t-2.5 13.5l-6 5q-2 1 -10 4.5t-17 7.5t-17 8l-10 5l-10 5t-17 9.5t-17 9.5l-10 5t-4 1.5t-4 1.5 q-3 1 -4 2l-37 24q-3 3 -8.5 6.5t-10.5 7t-9 6t-5 3.5q-2 0 -11.5 1t-11.5 1l-11.5 11.5t-10.5 11.5q-1 1 -5.5 3.5t-10 5.5t-10.5 5.5t-6 4.5q-2 1 -7 5.5t-11 10t-11.5 11l-8.5 8.5q-1 1 -4.5 5.5t-8 9.5l-9 10t-6.5 7q-10 11 -25.5 28.5t-16.5 31.5q0 2 1 4q0 2 0.5 3 t0.5 2q2 3 8 10t13.5 15t14 15t9.5 9q3 3 16.5 13t29 21t28.5 21t16 13q2 2 8 7t12.5 11t13 11.5t9.5 7.5q11 11 26.5 25.5t31.5 15.5h10q1 -1 9 -7t11 -9q4 -3 17.5 -17t29 -30.5t29 -31t16.5 -17.5q3 -2 11.5 -8.5t18 -14t17.5 -14.5t11 -9q23 -14 42.5 -26.5t39.5 -22.5 t42 -15t51 -4q19 1 42 9t45 21t40.5 29t28.5 32q9 15 10.5 33.5t3.5 34.5l-1 9q-1 30 -9.5 53.5t-23 44.5t-32.5 40.5t-37 39.5q-3 3 -11.5 10.5t-18 16.5t-18.5 16.5t-13 10.5q-3 4 -10 9.5t-15 11t-15 10t-9 5.5q-3 2 -19 9.5t-35 15.5t-35 15.5t-19 9.5q-57 28 -109 62 t-106 69q-34 13 -55.5 39t-42.5 55q-2 3 -8 11l-13.5 18t-14 19t-9.5 12q-13 19 -17 44.5t-8 40.5q-1 4 -2 10.5t-2 13.5t-1.5 12t-0.5 7l-1 33q-1 20 -1 38t3 37q0 2 4 12t7 15q6 27 23 60t41.5 66t54.5 63.5t62 53t63.5 34.5t60.5 8l6 6l2 102l5 10q29 4 58.5 8.5 t58.5 12.5h130q5 0 10 -1t9.5 -1.5t7.5 -1.5q19 -5 22 -15t5 -28q0 -4 1.5 -19t3.5 -32.5t3.5 -32.5t1.5 -20q4 -4 13.5 -6.5t20 -4.5t20 -3.5t14.5 -3.5q37 -8 69.5 -23t57 -30t39 -25.5t15.5 -9.5t6.5 -3t12 -10t12.5 -12t8 -7q1 0 8 -3t7 -5v-9q1 -14 -3 -29.5 t-10.5 -30.5t-15 -29.5t-15.5 -27.5q-4 -6 -10 -17.5t-12.5 -22.5t-11.5 -20t-6 -12q-2 -2 -6.5 -14.5t-7.5 -18.5q-6 -6 -13 -11t-14 -5l-6 -1q-5 0 -10.5 -1.5t-11.5 -1.5t-14 3t-17 13q-38 29 -73.5 48t-69.5 29.5t-67 14.5t-67 3q-4 0 -11 -0.5t-14 -1.5t-12.5 -1.5 t-6.5 -0.5q-12 -1 -24.5 -7.5t-24 -16t-20.5 -21t-14 -21.5q-4 -10 -4 -23v-22q1 -13 1.5 -21t5.5 -19l5 -6q2 0 6.5 -2.5t6.5 -2.5l6 -5q6 -10 12.5 -15.5t13 -9.5t14.5 -7.5t17 -7.5q1 -1 6.5 -4t11.5 -7l10.5 -7t5.5 -4q2 0 8.5 -1.5t8.5 -1.5q40 -13 77.5 -31.5 t73.5 -38.5q4 -2 21 -11.5t36.5 -20.5t36.5 -20.5t21 -12.5q2 -2 5.5 -4t5.5 -2q10 -4 15 -6.5t7.5 -5.5t5.5 -7t11 -10q2 -2 11 -9t19 -15t19.5 -14.5t12.5 -7.5q20 -17 42 -44t41 -50q-2 -6 0.5 -14t5.5 -13q20 -41 36 -81.5t23 -87.5l11 -59q1 -2 2.5 -10t3 -18t2.5 -18 t1 -10v-6q1 -24 -5 -52.5t-8 -51.5q0 -2 -0.5 -7t-1 -11t-1 -11.5t-0.5 -6.5q-3 -11 -10 -19.5t-10 -19.5q-8 -19 -13.5 -35.5t-16.5 -33.5q-36 -57 -91.5 -100.5t-118.5 -63.5q-7 -3 -22 -5t-31.5 -4t-31.5 -4.5t-22 -5.5q0 -6 -0.5 -19t-0.5 -17q1 -22 4.5 -43t4.5 -43 q1 -15 0.5 -26.5t-2.5 -28.5q-2 -14 -12 -21t-24 -15q-8 -2 -10.5 -3.5t-10.5 -1.5l-26 -1q-20 -1 -39.5 0.5t-39.5 0.5q-5 -1 -8.5 -3t-8.5 -2h-2q-2 0 -5.5 1.5t-5.5 1.5z" />
<glyph unicode="%" horiz-adv-x="1320" d="M511 -45q-3 1 -18.5 6t-33.5 10.5t-33 10t-16 5.5q-2 0 -3 0.5l-3 1.5q-16 6 -31 13.5t-30 12.5q-15 6 -24 8.5t-27 4.5q-2 -2 -9.5 -2h-9.5v2q-12 3 -16 16q0 4 1 15.5t1.5 24t1.5 23t1 14.5l1 2q0 3 1 4q0 1 1 1q5 18 13 44t16.5 54t17 55.5t15 50t10.5 36.5t4 15 q1 3 4 11t6.5 17.5t6.5 18t4 11.5l122 434q19 117 51.5 226t64.5 224q1 5 5.5 24.5t9.5 42t9.5 41.5t5.5 24q0 1 1.5 6t3.5 12t3.5 13.5t2.5 9.5q1 4 3 10l4 12t3 10.5t1 5.5q18 58 32.5 109t28.5 111q5 8 11.5 7.5t13.5 -3.5q2 -1 4.5 -1.5t4.5 -2.5q3 -2 6 -3t17.5 -5 t31.5 -9t32 -9.5t18 -5.5q1 0 5.5 -1.5t9.5 -3.5l10 -4t6 -2q11 -5 30 -10.5t39 -10t39.5 -9t31.5 -8.5q10 -4 13 -5t13 -4l1 -1q2 -2 8 -12.5t9 -13.5l9 -8q1 -4 2 -17t-1 -15q0 -3 -1.5 -9t-2.5 -13t-2 -13.5t-1 -8.5q-1 -5 -7.5 -20.5t-14.5 -33t-15 -33.5t-8 -21 q2 -8 2.5 -21.5t-1.5 -18.5q-1 -1 -8 -9t-9 -11q-1 -2 -2.5 -8.5t-3.5 -11.5q0 -3 -2.5 -11t-3.5 -10q0 -3 -1.5 -15.5t-3.5 -26t-3.5 -25.5t-2.5 -15q-2 -5 -6.5 -21.5t-10 -36t-10 -36t-5.5 -20.5q-14 -70 -36 -163.5t-47 -194t-50.5 -199.5t-48 -181t-39.5 -138.5 t-23 -70.5q-8 -23 -14.5 -46t-12.5 -49q-4 -7 -11.5 -28t-15 -43.5t-12.5 -40.5t-5 -19q-6 -20 -26 -25.5t-41.5 -4t-38 5.5t-16.5 3zM490 1486v-28.5t-6 -30.5q-11 -22 -19 -41.5t-25 -38.5q-5 -5 -13 -12t-16.5 -13.5t-15.5 -12t-9 -8.5q-22 -20 -50 -20.5t-54 -1.5 q-17 -2 -28.5 2t-28.5 10q-8 1 -22 7.5t-22 11.5q-40 25 -69.5 62t-35.5 90q0 31 1 54t8 41.5t21 36.5t38 39q21 20 53 36.5t61 18.5h10.5h15.5t15.5 -0.5t9.5 -1.5q4 0 12 -2t16.5 -4t15.5 -4t9 -2q1 -2 8.5 -4.5l16.5 -5.5t17 -5.5t11 -3.5q22 -17 36.5 -34t22.5 -37 t11.5 -44t4.5 -54zM1249 209v-28.5t-6 -30.5q-11 -22 -19 -41.5t-25 -38.5q-5 -5 -13 -12t-16.5 -13.5t-15.5 -12t-9 -8.5q-22 -20 -50 -20.5t-54 -1.5q-17 -2 -28.5 2t-28.5 10q-8 1 -22 7.5t-22 11.5q-40 25 -69.5 62t-35.5 90q0 31 1 54t8 41.5t21 36.5t38 39 q21 20 53 36.5t61 18.5h10.5h15.5t15.5 -0.5t9.5 -1.5q4 0 12 -2t16.5 -4t15.5 -4t9 -2q1 -2 8.5 -4.5l16.5 -5.5t17 -5.5t11 -3.5q22 -17 36.5 -34t22.5 -37t11.5 -44t4.5 -54z" />
<glyph unicode="&#x26;" horiz-adv-x="1450" d="M1105 -12q-23 26 -51.5 61.5t-57.5 83.5q-5 7 -10 18t-15 11q-8 0 -19 -5.5t-23 -13t-24.5 -15.5t-23.5 -12q-1 0 -6 -1.5t-11 -3.5t-11.5 -3.5t-6.5 -1.5q-2 -2 -10 -5t-17 -6.5t-17.5 -7t-12.5 -4.5q0 -2 -6 -4q-3 -1 -5 -2q-37 -11 -63 -15.5t-51 -7.5t-52 -5.5 t-65 -8.5h-33q-13 0 -23.5 0.5t-11.5 0.5h-12q-47 4 -90 6.5t-89 18.5q-10 4 -27 8.5t-35 10t-34 12.5t-22 16q-29 33 -51.5 61t-38.5 57.5t-24.5 64t-8.5 80.5q0 96 27.5 179t81.5 161q3 3 9.5 11.5t8.5 10.5q5 6 18 19l27.5 27.5t28 27.5t18.5 19q2 2 13 10.5t16 11.5 q4 4 13 11.5t18 16.5t16 17.5t7 13.5v2q-15 24 -30 50.5t-29.5 58t-28.5 69t-27 83.5q0 7 -3 26t-6.5 40t-6.5 40t-3 27v12v10q7 41 16.5 74t25 61.5t38.5 53t57 47.5q22 17 41.5 27.5t45.5 25.5q14 8 38 13.5t50.5 9t52 5t43.5 1.5q35 0 71.5 -2t71.5 -10q38 -9 69 -25.5 t58 -38t50.5 -48t47.5 -54.5q16 -20 25.5 -45t14 -51.5t5.5 -53.5t1 -51q0 -37 -10.5 -73.5t-24.5 -71.5q-6 -17 -20 -40t-29.5 -47t-31 -45.5t-25.5 -36.5q-13 -19 -22 -30t-17.5 -21t-17.5 -21t-22 -30v-12l18 -28q8 -12 16 -25t13 -21q23 -38 51.5 -68.5t57.5 -64.5 q2 -2 10 -11.5t16.5 -20t16.5 -20t10 -11.5q2 -5 6 -7q2 -2 5 -4l10 -16q4 -6 7.5 -11t4.5 -5l2 2q2 0 6 2t6 4q15 15 28 30.5t25.5 31t27 30t32.5 28.5q9 8 12 10.5t11 2.5h6q23 -20 36 -33t22.5 -25.5t19.5 -27.5t27 -40q2 -2 9.5 -8t9.5 -8v-6q3 -18 -3.5 -32.5 t-18.5 -28t-26.5 -27.5t-26.5 -30q-5 -3 -5.5 -5t-0.5 -7t9.5 -21t22 -33t24 -31.5t15.5 -15.5l25 -29q1 -8 6 -16t11.5 -15.5t12.5 -14.5t9 -11l2 -4l-2 -2q-5 -9 -15.5 -26t-19.5 -25q-6 -7 -19 -17.5t-28 -22t-29 -21.5t-21 -16q-3 -2 -12 -7.5t-18.5 -12.5t-18.5 -13 l-12 -8q-13 -1 -25.5 -11t-24.5 -19.5t-23 -14.5t-22 4zM416 487q0 -26 9.5 -50.5t27 -44t41 -33.5t51.5 -18q6 -1 16.5 -2t21.5 -2t20 -1.5t12 -0.5q2 0 13 4.5t16 7.5q4 1 13.5 6t21 10.5t21 11t13.5 7.5q3 2 14.5 8.5t14.5 8.5v6q0 6 -1.5 8t-4.5 8q-29 46 -60.5 90.5 t-60.5 87.5q-5 4 -11 12t-12.5 15.5t-13.5 13.5t-14 6h-7q-27 -16 -52.5 -30.5t-45 -32t-31.5 -40.5t-12 -56zM585 1161q7 -11 8.5 -21t11.5 -23q0 -3 1.5 -9t4.5 -12t7 -11.5t9 -6.5q1 2 6 7t10.5 10t10 9.5l6.5 6.5q4 6 8.5 15.5t8.5 20.5t7 21t5 16q10 29 14 51t4 54 q0 25 -18 36t-39 11q-53 0 -75 -24.5t-22 -72.5q0 -9 3.5 -20.5t8.5 -22.5t10.5 -20.5t9.5 -14.5z" />
<glyph unicode="'" horiz-adv-x="586" d="M135 859q1 1 3.5 6.5t6 11t6 10.5l3.5 7q14 34 24 64t18 60t14.5 62t12.5 68q0 3 1 12t2 19.5t2 20t1 12.5q-9 0 -13.5 -2t-8.5 -4.5t-8.5 -5t-12.5 -4.5q-35 -6 -68 -6q-11 0 -26 8.5t-15 22.5q0 63 0.5 117t-1.5 116q2 4 2 10.5t1.5 12.5t6 11.5t15.5 9.5h76 q3 0 11.5 0.5t18 1.5t18 2t12.5 2q4 0 22.5 -0.5t40 -0.5h39.5t23 1q2 0 10.5 0.5t18.5 1.5t18 1.5t10 0.5t12.5 1t16.5 1q11 0 23.5 -0.5t23.5 -5.5q12 -6 18.5 -24t9.5 -38.5t4 -39t1 -27.5v-14q0 -2 -3 -6.5t-3 -6.5q-1 -2 -2 -10t-2 -17t-1.5 -17.5t-0.5 -12.5 q1 -10 -1.5 -27.5t-7 -34t-10 -29t-10.5 -11.5q-14 -26 -22.5 -54.5t-22.5 -56.5q-18 -32 -41 -65t-49.5 -63t-57.5 -54.5t-65 -39.5q-2 -1 -9.5 -4.5t-17 -8t-19 -8.5t-13.5 -5q-9 -3 -12.5 -4.5t-11.5 -1.5q-10 0 -10.5 6t-0.5 14v15z" />
<glyph unicode="(" horiz-adv-x="674" d="M31 1130q1 3 2 11t2 17.5t1.5 17.5t0.5 11q2 31 7 54.5t10 54.5q1 2 2 9t2 15t1.5 14.5t0.5 8.5q8 48 22.5 87.5t34.5 84.5q-2 12 1.5 26t9 28t12.5 27t12 23t14.5 27t18.5 33.5t16 28.5t8 14t6 9t11 14.5t11 14.5t7 9q1 2 2 5q2 5 4 5q3 6 8 15.5t9.5 19.5t9 18.5 t7.5 11.5q35 42 62 48.5t42 -13.5q38 -28 72 -58.5t53 -56.5l47 -57q17 -8 20 -26.5t-14 -44.5l-6 -6q-22 -37 -38 -78.5t-30 -81.5q-2 -5 -5 -13.5t-5.5 -17t-4.5 -15t-3 -7.5q-2 -11 0.5 -18t-7.5 -15q-14 -81 -24 -148t-16.5 -129t-9 -121.5t-0.5 -125t8.5 -140.5 t17.5 -167q1 -2 2.5 -7t3.5 -12t3.5 -13t2.5 -9t5 -15.5t9.5 -27.5t9.5 -27.5t5 -15.5q8 -45 29.5 -85t41.5 -79q0 -3 2.5 -10.5l5.5 -16.5l5.5 -16.5l3.5 -10.5l2 -4q2 -4 4 -6q4 -6 12 -24t16.5 -37.5t15.5 -36t9 -19.5q9 -7 4.5 -16.5t-14.5 -19t-22.5 -19.5t-20.5 -18 q-7 -7 -25 -21t-38.5 -29t-38.5 -29t-25 -20q-15 -8 -28.5 -12t-30.5 -4h-15q-1 0 -4.5 2.5t-8 6.5t-9.5 7.5t-8 6.5q-5 4 -13.5 12t-16.5 15.5t-14.5 13t-7.5 6.5q-2 1 -10.5 12.5t-19.5 26.5t-21.5 29.5t-15.5 23.5q-9 11 -15.5 25t-15.5 26q-1 1 -4 6.5t-7 11t-7 10.5 t-4 7q-15 28 -26.5 59t-20.5 63t-17 64t-16 62q-8 24 -10.5 49t-8.5 53q0 2 -2 6t-2 6q-1 1 -2 7t-2 12.5t-1.5 12t-0.5 7.5q-1 4 -4.5 17.5t-7.5 29t-7.5 29t-3.5 16.5q-2 8 -4 24.5t-3.5 34.5t-3 32.5t-1.5 19.5v385v0z" />
<glyph unicode=")" horiz-adv-x="715" d="M654 669q-1 -3 -2 -11t-2 -17.5t-1.5 -17.5t-0.5 -11q-2 -31 -7 -54.5t-10 -54.5q-1 -2 -2 -9t-2 -15t-1.5 -15t-0.5 -8q-8 -48 -22.5 -87.5t-34.5 -84.5q1 -12 -2 -26t-8.5 -28t-12.5 -27t-12 -23t-14.5 -27t-18.5 -33.5t-16 -29t-8 -13.5q-1 -2 -6 -9t-11 -14.5 t-11.5 -14.5t-6.5 -9q-1 -3 -2 -5q-2 -5 -4 -5q-3 -6 -8 -15.5t-9.5 -19.5t-9 -18.5t-7.5 -11.5q-35 -42 -62 -48.5t-42 13.5q-38 28 -72 58.5t-53 56.5l-47 57q-17 8 -20 26.5t14 44.5l6 6q22 37 38 78.5t30 81.5q2 5 5 13.5t5.5 16.5t4.5 14.5t3 8.5q2 11 -0.5 18t7.5 15 q13 81 23.5 148t17 129t9 121.5t0.5 125t-8.5 140.5t-17.5 167q-1 1 -2.5 6.5t-3.5 12.5t-3.5 13t-2.5 9t-5 15.5t-9.5 27.5t-9.5 27.5t-5 15.5q-8 45 -29.5 85t-41.5 79q0 3 -2.5 10.5l-5.5 16.5l-5.5 16.5l-3.5 10.5l-2 4q-2 4 -4 6q-4 6 -12 24t-16.5 37.5t-16 36 t-8.5 19.5q-9 7 -4.5 16.5t14.5 19t22.5 19.5t20.5 18q7 7 25 21t38.5 29t38.5 29t25 20q15 8 28.5 12t30.5 4h15q1 0 4.5 -2.5t8 -6.5t9.5 -7.5t8 -6.5q5 -5 13.5 -12.5t16.5 -15t14.5 -13t7.5 -6.5q1 -2 10 -13t20 -26t21.5 -29.5t15.5 -23.5q9 -11 15.5 -25t15.5 -26 q1 -2 4 -7t7 -10.5t7 -11t4 -6.5q15 -28 26.5 -59t20.5 -63t17 -64t16 -62q8 -24 10.5 -49t8.5 -53q0 -2 2 -6t2 -6q1 -2 2 -7.5t2 -12t1.5 -12.5t0.5 -7q1 -4 4.5 -17.5t7.5 -29t7.5 -29t3.5 -16.5q1 -8 3.5 -24.5t4 -34.5t3 -33t1.5 -19v-385v0z" />
<glyph unicode="*" horiz-adv-x="1053" d="M455 366q0 26 5.5 62t13.5 61q4 14 5 26l2 24t2 26t4 34q1 4 1.5 5t1 3.5t2 9.5t3.5 22q-21 0 -50 -15.5t-58.5 -37t-56 -44.5t-43.5 -38q-11 -9 -22.5 -18.5t-28.5 -9.5h-6q-3 2 -8.5 8.5t-7.5 9.5q-2 1 -8 10l-13 19.5t-12.5 19t-6.5 10.5q-12 21 -22 35t-17.5 27.5 t-11.5 30t-4 40.5v9.5t6 6.5q2 0 8.5 2.5t8.5 4.5q17 6 30 13t25.5 15t25.5 16.5t29 16.5q18 9 33.5 15t35.5 20l2 2q2 2 4 2q-2 2 -6 4t-6 2q-2 1 -8.5 2.5t-14 3.5t-14.5 3.5t-10 2.5q-1 0 -6 1t-10.5 2t-10.5 2t-6 2q-4 1 -13.5 3t-21 5t-21 5t-13.5 3q-6 1 -17 3.5 t-21.5 7t-18 11t-7.5 15.5q0 15 11.5 32.5t17.5 28.5q18 34 42 63.5t44 63.5q1 2 3 4q1 2 2 3.5t1 3.5q2 3 6 14.5t6 13.5q3 6 13 16.5t15 15.5h4h2q4 6 19.5 -3t37.5 -27t49.5 -41t55.5 -45q5 -5 17.5 -16.5t23.5 -14.5v6q0 15 -1.5 34t-4.5 38.5t-6.5 38t-7.5 33.5 q-3 17 -8 35t-8 35q0 2 -3 11t-3 11t6.5 8.5t11.5 8.5h2h2q3 0 14.5 -1t24 -1.5t23.5 -1.5t14 -1h2h4q3 0 15 1t25.5 1.5t25 1.5t14.5 1h17q3 1 10 2t14.5 2t14 1.5t8.5 0.5q2 2 8.5 0t8.5 -2q14 0 19.5 -10.5t5.5 -27t-2.5 -37t-5.5 -41.5l-29 -188q10 7 22 18.5t24 24 t22.5 25t18.5 21.5q12 14 18 25t27 16q6 14 16 18.5t29 -12.5h4q5 0 10 -5t9.5 -11.5t8 -13.5t5.5 -10q13 -21 28 -42.5t29 -42t25 -39t17 -33.5v-4q0 -5 -2 -14t-4 -11q-6 -14 -23 -19.5t-31 -10.5q-8 -2 -28 -6.5t-43 -10t-43.5 -10.5t-29.5 -6q0 -2 2.5 -4t4.5 -2 q18 -9 39.5 -23.5t39.5 -23.5q3 -1 8.5 -3.5t12 -5t12.5 -5t8 -3.5q17 -7 31.5 -13t29 -12.5t29 -14t31.5 -17.5l6 -6t4 -6v-2q0 -8 -2 -15t-8 -12q-32 -25 -68.5 -50.5t-70.5 -51.5q-7 -6 -13.5 -16.5t-14 -20t-16 -16.5t-20.5 -7q-6 0 -8 2.5t-8 10.5q-4 4 -19 22t-32 38 t-32 37.5t-19 22.5l-41 41q-2 0 -6.5 2t-6.5 2v-18q0 -38 4 -72.5t9 -74.5h2q2 0 3 -4.5t1 -32.5q0 -22 6 -42t6 -40q0 -1 -0.5 -2t-0.5 -3q-1 -2 -1 -3q-2 -4 -8 -10.5t-8 -6.5l-175 3q-6 1 -14.5 0t-16 0t-12.5 5t-5 14z" />
<glyph unicode="+" horiz-adv-x="973" d="M323 426q-9 -2 -14 2.5t-7.5 12t-3 15.5t-1.5 13l1 217q-39 -1 -83 0t-84 6q0 1 -4 10q0 1 -4 0.5t-2 0.5q-1 11 -3 41.5t-4 65t-4.5 65.5t-3.5 42v9q0 14 9.5 24t26.5 14q36 -5 76.5 2t74.5 7q8 0 16 -0.5t15 4.5v17q1 31 0.5 54.5t-1.5 45.5t-1.5 45t0.5 55v11.5 t0.5 18t0.5 18v11.5q1 6 8 6.5t35 -4.5q7 1 23.5 2t34.5 2.5t34.5 3t22.5 2.5q3 0 16.5 -0.5t29 -0.5t28 -0.5t14.5 -0.5h13h30q9 0 18 1l22 -14q0 -5 0.5 -15.5t2.5 -15.5q1 -2 0 -8.5t-1 -8.5q3 -16 3.5 -24.5t0 -15.5t-1 -16t-0.5 -27q0 -9 0.5 -26t1 -37.5t1 -42 t-0.5 -39.5q0 -5 3 -7t8.5 -2t11 0.5t9.5 0.5h5q32 8 68 8h71q3 0 9 -0.5t12 -0.5h16l6 -28q1 -43 -0.5 -82.5t6.5 -84.5v-10v-19.5v-19.5v-9v-5q0 -9 -5 -14t-11.5 -7.5t-14.5 -4t-14 -3.5l-29 -5l-126 1l-2 -71v-19.5t-0.5 -41t-0.5 -47.5v-39q0 -17 -10.5 -19.5 t-26.5 -5.5z" />
<glyph unicode="," horiz-adv-x="634" d="M158 -292q1 1 3.5 6.5t6 11t6 10.5l3.5 7q14 34 24 64t18 60t14.5 62t12.5 68q0 3 1 12t2 19.5t2 20t1 12.5q-9 0 -13.5 -2t-8.5 -4.5t-8.5 -5t-12.5 -4.5q-35 -6 -68 -6q-11 0 -26 8.5t-15 22.5q0 63 0.5 117t-1.5 116q2 4 2 10.5t1.5 12.5t6 11.5t15.5 9.5h76 q3 0 11.5 0.5t18 1.5t18 2t12.5 2q4 0 22.5 -0.5t40 -0.5h39.5t23 1q2 0 10.5 0.5t18.5 1.5t18 1.5t10 0.5t12.5 1t16.5 1q11 0 23.5 -0.5t23.5 -5.5q12 -6 18.5 -24t9.5 -38.5t4 -39t1 -27.5v-14q0 -2 -3 -6.5t-3 -6.5q-1 -2 -2 -10t-2 -17t-1.5 -17.5t-0.5 -12.5 q1 -10 -1.5 -27.5t-7 -34t-10 -29t-10.5 -11.5q-14 -26 -22.5 -54.5t-22.5 -56.5q-18 -32 -41 -65t-49.5 -63t-57.5 -54.5t-65 -39.5q-2 -1 -9.5 -4.5t-17 -8t-19 -8.5t-13.5 -5q-9 -3 -12.5 -4.5t-11.5 -1.5q-10 0 -10.5 6t-0.5 14v15z" />
<glyph unicode="-" horiz-adv-x="802" d="M67 748q-2 10 -1 20.5t0 20.5q0 3 0.5 14t1.5 24t1.5 24t0.5 14q0 30 -2 59.5t1 58.5q1 15 16 25.5t28 11.5q4 0 18.5 -2t31.5 -3.5t32 -2.5t18 -1h17.5t29 0.5t29 0.5h16.5t15 -1.5t26.5 -2.5t27 -2t16.5 -1q45 -4 88.5 0.5t89.5 3.5q1 1 19.5 0t43 -2.5t50 -3.5 t41.5 -3q2 0 4.5 -0.5t4.5 -0.5q18 -2 23 -13t4 -27t-5 -32.5t-4 -28.5q0 -3 1 -11.5t2 -18t2 -18t1 -11.5q1 -11 0 -18t-3 -15q-2 -18 3 -37t3 -33q-1 -1 -1 -4v-3q-2 -2 -9 -8t-10 -6q-6 1 -18.5 -1.5t-19.5 -4.5h-18.5h-38h-48.5h-48h-38h-18h-9t-15 -0.5t-15 -0.5h-9 q-3 0 -13.5 -0.5t-22 -1.5t-22 -1.5t-13.5 -1.5q-5 0 -22 0.5t-36.5 1t-36.5 0.5h-22q-31 -1 -45.5 -0.5t-26.5 2t-27 3.5t-47 5q-3 1 -12.5 3.5t-14.5 3.5q-5 3 -9 12.5t-6 13.5z" />
<glyph unicode="." horiz-adv-x="541" d="M494 172v-28.5t-6 -30.5q-11 -22 -19 -41.5t-25 -38.5q-5 -5 -13 -12t-16.5 -13.5t-15.5 -12t-9 -8.5q-22 -20 -50 -20.5t-54 -1.5q-17 -2 -28.5 2t-28.5 10q-8 1 -22 7.5t-22 11.5q-40 25 -69.5 62t-35.5 90q0 31 1 54t8 41.5t21 36.5t38 39q21 20 53 36.5t61 18.5h10.5 h15.5t15.5 -0.5t9.5 -1.5q4 0 12 -2t16.5 -4t15.5 -4t9 -2q1 -2 8.5 -4.5l16.5 -5.5t17 -5.5t11 -3.5q22 -17 36.5 -34t22.5 -37t11.5 -44t4.5 -54z" />
<glyph unicode="/" horiz-adv-x="889" d="M274 -45q-3 1 -18.5 6t-33.5 10.5t-33 10t-16 5.5q-2 0 -3 0.5l-3 1.5q-16 6 -31 13.5t-30 12.5q-15 6 -24 8.5t-27 4.5q-2 -2 -9.5 -2h-9.5v2q-12 3 -16 16q0 4 1 15.5t1.5 24t1.5 23t1 14.5l1 2q0 3 1 4q0 1 1 1q5 18 13 44t16.5 54t17 55.5t15 50t10.5 36.5t4 15 q1 3 4 11t6.5 17.5t6.5 18t4 11.5l122 434q19 117 51.5 226t64.5 224q1 5 5.5 24.5t9.5 42t9.5 41.5t5.5 24q0 1 1.5 6t3.5 12t3.5 13.5t2.5 9.5q1 4 3 10l4 12t3 10.5t1 5.5q18 58 32.5 109t28.5 111q5 8 11.5 7.5t13.5 -3.5q2 -1 4.5 -1.5t4.5 -2.5q3 -2 6 -3t17.5 -5 t31.5 -9t32 -9.5t18 -5.5q1 0 5.5 -1.5t9.5 -3.5l10 -4t6 -2q11 -5 30 -10.5t39 -10t39.5 -9t31.5 -8.5q10 -4 13 -5t13 -4l1 -1q2 -2 8 -12.5t9 -13.5l9 -8q1 -4 2 -17t-1 -15q0 -3 -1.5 -9t-2.5 -13t-2 -13.5t-1 -8.5q-1 -5 -7.5 -20.5t-14.5 -33t-15 -33.5t-8 -21 q2 -8 2.5 -21.5t-1.5 -18.5q-1 -1 -8 -9t-9 -11q-1 -2 -2.5 -8.5t-3.5 -11.5q0 -3 -2.5 -11t-3.5 -10q0 -3 -1.5 -15.5t-3.5 -26t-3.5 -25.5t-2.5 -15q-2 -5 -6.5 -21.5t-10 -36t-10 -36t-5.5 -20.5q-14 -70 -36 -163.5t-47 -194t-50.5 -199.5t-48 -181t-39.5 -138.5 t-23 -70.5q-8 -23 -14.5 -46t-12.5 -49q-4 -7 -11.5 -28t-15 -43.5t-12.5 -40.5t-5 -19q-6 -20 -26 -25.5t-41.5 -4t-38 5.5t-16.5 3z" />
<glyph unicode="0" horiz-adv-x="1320" d="M88 470q-5 15 -9.5 49t-9 71.5t-8.5 71t-7 47.5q-2 61 -1.5 108.5t2 87.5t3 76.5t3.5 76.5v2q1 4 2.5 12.5t2.5 16.5t1.5 14.5t0.5 7.5q1 8 7 29.5t12.5 45.5t12.5 44.5t8 27.5q0 2 1.5 7.5t3.5 8.5q2 4 8 18.5t13 31t13 31t8 19.5q65 140 197 226q27 19 59.5 32t62.5 28 q39 19 73.5 29.5t78.5 18.5q11 1 31.5 2t42.5 0.5t41 -3t28 -6.5q4 -2 16 -4.5t25 -5t24.5 -4.5t16.5 -2q3 -5 7.5 -7.5t9.5 -4.5q2 -1 7.5 -3.5t12 -5.5t12 -5.5t7.5 -2.5q8 -6 29.5 -19t45.5 -26.5t45.5 -26t30.5 -16.5q3 -2 11 -9t10 -9t4 -3t2 -3q5 -5 14 -16.5t18 -24 t16 -23l9 -13.5q43 -54 69 -115.5t40 -127.5q5 -32 10 -68.5t8.5 -74t6.5 -74t5 -68.5q3 -50 2.5 -93.5t-2.5 -94.5q0 -8 -0.5 -20.5l-1 -25t-1 -21.5t-0.5 -10q-1 -8 -4 -29.5t-6.5 -46t-7 -47t-5.5 -32.5q-3 -19 -8.5 -42t-12.5 -46.5t-15 -45.5t-17 -39q-29 -55 -61 -101 t-68 -95l-6 -6q-43 -34 -91.5 -69t-102.5 -53q-6 -2 -19.5 -5.5t-27.5 -7t-26.5 -6t-15.5 -3.5q-3 0 -13 -0.5t-22 -0.5t-22 -0.5t-13 -1.5h-14.5h-25t-25 0.5t-14.5 0.5q-1 0 -6 0.5t-11.5 0.5t-13 0.5t-10.5 0.5q-31 2 -63.5 4.5t-61.5 13.5q-43 16 -85 41.5t-78.5 56 t-67 64t-49.5 66.5q-7 11 -16 24.5t-18 28t-16.5 29t-11.5 28.5q0 1 -1 2t-2 3q-2 2 -3 4q-2 2 -6 12.5t-5 12.5v16q0 1 -3.5 5.5t-8 10.5t-8 11t-3.5 7q-2 2 -1.5 6.5t1.5 9.5t1.5 9t-0.5 5zM433 731q13 -42 19 -83t12.5 -81t17.5 -79.5t36 -76.5q5 -6 16 -20.5t18 -18.5 q17 -1 25.5 -12.5t19.5 -20.5q6 -5 18 -7.5t21 -3.5h7h13.5h14h9.5q1 0 12 1t15 2q65 27 118 64.5t93 96.5q2 2 6 14.5t4 18.5q12 43 19.5 85t9.5 87q1 23 -0.5 44t-2.5 44q0 6 -1 28.5t-2 49t-2 49.5t-1 29q-2 38 -5.5 73.5t-9.5 72t-15.5 77.5t-22.5 90q-10 9 -14.5 15 t-7 10.5t-4.5 8t-7 7.5q-2 2 -7.5 10.5t-9.5 12.5q-5 5 -14 16t-12 13q-2 2 -8 2h-8q-2 1 -3 3q-3 1 -3 4l-2 6q-2 6 -4 6q-1 1 -9.5 5.5t-12.5 6.5q-3 1 -9.5 2t-13.5 2.5t-13 3t-8 2.5q-7 0 -12 1q-5 0 -10 0.5t-7 0.5q-14 1 -23 0.5t-17 -2.5t-16 -5.5t-20 -8.5h-2 q-3 0 -3 1q-3 -2 -8.5 -6t-12 -8.5t-12 -8t-6.5 -4.5q-2 -1 -6.5 -8.5t-6.5 -9.5q-3 -3 -13.5 -17.5t-21.5 -31t-21.5 -31t-13.5 -17.5q-20 -31 -33 -72.5t-20.5 -85.5t-10.5 -87.5t-4 -79.5q-1 -2 -1 -6.5v-6.5q0 -9 1.5 -32.5t3 -50t3 -50.5t1.5 -33z" />
<glyph unicode="1" horiz-adv-x="550" d="M379 15q-3 0 -20 -0.5t-37 -1t-37 -1t-19 -0.5h-6q-18 0 -36.5 2t-35.5 2t-26.5 -0.5t-28.5 -3.5q-2 -2 -9 -4t-9 -2h-2q-14 0 -21 10q-1 4 -3 14t-5 21.5t-5 21t-3 13.5v2v4q1 27 2 68.5t2 81t1.5 68t0.5 30.5q0 3 0.5 11t1.5 17.5t1.5 17.5t0.5 11v420q-7 54 -9 107.5 t-2 107.5t1 108t0 109q0 5 -1 23.5t-2 39.5t-2 39t-1 23v39v37q2 57 2 106t-3 106q3 9 10 10.5t15 1.5q2 0 4 -0.5t5 -0.5q3 -1 7 -1t20 0.5t35 1.5t35 1.5t20 0.5h35q13 -2 33.5 -0.5t42.5 3t43 3.5t35 2h29h2q2 -2 11.5 -9t12.5 -9l11 -5q3 -3 7.5 -14.5t4.5 -13.5 q0 -5 2 -20.5t4 -20.5q0 -5 -2.5 -20.5t-5.5 -33t-5.5 -33.5t-2.5 -20q5 -6 8.5 -18t3.5 -17q0 -2 -5 -11.5t-7 -11.5v-20v-21q1 -3 3 -14t4 -23.5t3.5 -23.5t1.5 -14v-109q4 -50 8 -113t7 -133t5 -143.5t3.5 -143.5t2.5 -133.5t1 -114t-1 -84t-3 -44.5q-2 -23 -2 -45.5 v-46.5q-2 -8 -3 -28.5t-2 -42.5t-1.5 -39.5t0.5 -18.5q-1 -20 -20 -30.5t-41 -16t-40.5 -6.5t-17.5 -2z" />
<glyph unicode="2" horiz-adv-x="1248" d="M70 133q0 2 -2 6t-4 6v2q0 8 3 12.5t3 10.5q0 29 3.5 64t3.5 62q0 9 13.5 19t31.5 19.5t36.5 19.5t29.5 19q7 7 30.5 28t51 45.5t53.5 47.5t38 34q28 25 52.5 54.5t48 59.5l47 60t49.5 57q9 12 32.5 41t50.5 62.5t51 63.5t33 44q1 -2 9.5 10t20 32t23.5 45t21 48 q11 15 15.5 41.5t10.5 70.5q0 29 -8.5 53t-21.5 51q0 16 -13 31.5t-30.5 26.5t-35 16t-26.5 0q-34 1 -67.5 -15.5t-64.5 -46t-58.5 -69t-48.5 -82.5q0 -1 -1.5 -6t-3.5 -11t-3.5 -11t-2.5 -6q-5 -11 -17 -23t-23 -15h-21q-32 -2 -58 -5t-51 -5.5t-51.5 -4t-59.5 -1.5h-2 q-2 2 -9.5 4t-9.5 2h-72l-5 6q0 2 -7.5 9t-7.5 14q0 32 6.5 60.5t11.5 60.5q5 17 7.5 34t10.5 33q19 46 43.5 84t53.5 71.5t63.5 63.5t74.5 60q4 3 12 8.5t17 11.5t17 10.5t10 6.5q5 2 20 8.5t32 14t33.5 14.5t25.5 10q29 11 68 14t71 3q85 0 166.5 -14.5t157.5 -52.5 q5 2 12.5 -2t15.5 -10t15 -12.5t12 -9.5q1 -1 7 -5t13 -8.5t12.5 -9t7.5 -5.5q40 -35 63 -70.5t39 -86.5q1 -3 5 -13.5t9.5 -22.5t9.5 -22.5t5 -13.5q4 -15 7 -27.5t5 -30t2.5 -42t-0.5 -63.5q-1 -33 -8.5 -63.5t-17.5 -56t-20 -46t-16 -34.5q-23 -53 -49 -102t-55 -99 q-2 0 -4 -5t-2 -7q-2 -1 -6.5 -5.5t-10.5 -10t-11 -10.5l-6 -6q-2 -2 -6.5 -10.5t-10.5 -18t-11 -17.5t-6 -9q-2 -3 -8 -12.5t-8 -11.5q-9 -12 -15.5 -26.5t-18.5 -23.5q-38 -59 -83.5 -118.5t-94.5 -110.5q-2 -2 -4.5 -6t-2.5 -6l2 -2q3 -3 5 -3h6q4 0 22 -0.5t39 -1.5 t39 -1.5t23 -0.5h9q33 0 64.5 2t63.5 2h13q9 0 27 -1.5t37 -3t34 -3t20 -2.5q3 -1 9.5 -2.5t13.5 -4t12.5 -4t7.5 -2.5q14 -6 19 -18.5t7 -26.5t4 -27.5t10 -22.5q-1 -6 -1.5 -23.5t-0.5 -37t0.5 -36.5t1.5 -24q0 -2 0.5 -9t1.5 -14.5t1.5 -14.5t0.5 -8q0 -2 1 -5 q0 -2 0.5 -4.5t0.5 -3.5q0 -27 -9 -46t-39 -19h-155h-9.5t-17 -0.5t-18 -0.5h-10.5h-151q-5 -2 -8 -3.5t-8 -1.5q-6 0 -11 2.5t-11 2.5h-6q-58 -3 -115 -2.5t-114 2t-114 2.5t-115 -1q-3 0 -14 -1t-24.5 -1.5t-25.5 -1.5t-15 -1h-16q-6 1 -17 1.5t-22.5 1.5t-21 1.5 t-12.5 0.5t-14 2t-14 4l-2 2q-2 2 -4 2q0 3 -2 11.5t-2 12.5q-2 6 -4.5 21t-5.5 32t-5 32t-3 21z" />
<glyph unicode="3" horiz-adv-x="1227" d="M654 0q-14 -3 -41 -2.5t-60.5 4t-69.5 10.5t-69 17t-58.5 22.5t-37.5 27.5q-3 1 -11.5 7.5t-18.5 14t-18.5 14.5t-10.5 9q-3 3 -12.5 12t-21 19.5t-22 20t-15.5 14.5q-39 41 -64.5 98.5t-42.5 110.5q-12 33 -25 61.5t-15 62.5q0 18 6.5 26.5t18 12t25.5 5t28 4.5 q13 0 33 3.5t46 7.5t57.5 6t69.5 -1q30 5 51.5 -8.5t38.5 -37.5t33 -54t36.5 -58.5t47.5 -51.5t66 -33q8 0 24 -5.5t23 -5.5q1 -1 5.5 -0.5t10.5 1t11 1.5t7 1h2h4q47 12 79 27.5t51 40t26.5 59.5t6.5 85q-1 36 -11 67t-27.5 58t-40 52t-49.5 49q-17 14 -40.5 18.5 t-45.5 6.5q-39 -4 -67 -7t-46 -3t-25.5 3.5t-4.5 13.5l-6 13l5 205l2 4q1 2 1.5 3.5t1.5 2.5q0 2 2 4.5t4 2.5q20 7 35.5 12.5t30.5 11.5t30.5 13.5t35.5 19.5q26 16 46.5 39t29.5 51q5 11 7.5 33.5t3 44t-2 38t-6.5 15.5q-6 20 -12 37.5t-15.5 30.5t-24 20.5t-38.5 7.5 q-9 7 -27 7t-35 -8q-2 0 -4 -0.5t-4 -0.5q-3 -1 -5 -1q-20 -6 -36 -19t-30 -29.5t-26 -34t-24 -32.5q-10 -14 -23.5 -19t-29.5 -5q-32 -1 -61 1.5t-62 9.5q-3 0 -13.5 2t-23.5 4.5t-24 5t-14 2.5q-3 1 -9.5 5t-13.5 8t-13.5 7.5t-9.5 2.5q-2 1 -7.5 7.5t-11.5 13.5t-10.5 13 t-5.5 7v4q0 6 7 13.5t11 15.5q7 21 12.5 30.5t10.5 16t12.5 14.5t19.5 25q10 17 25.5 32t27.5 30q17 26 39.5 51t47.5 42q2 1 14.5 7t28.5 13.5t32.5 15.5t27.5 13q23 14 48.5 19t51.5 6q3 0 13 2t21.5 4.5t20.5 4.5t10 2t6.5 -1t11 -1.5t10.5 -1.5t7 -1q7 -1 31 -3.5 t52 -5.5t52.5 -5.5t31.5 -3.5q2 0 12.5 -1.5t15.5 -3.5q3 0 12 -2t11 -4q3 0 14 -4t13 -4q34 -18 54 -31.5t31.5 -24t17.5 -17.5t14 -10q2 -2 6 -4t6 -2q4 -3 5.5 -5.5t2 -5t1.5 -6t5 -8.5q1 -2 8 -11t15 -18.5t14.5 -18.5t8.5 -11q11 -18 17 -38.5t9 -42.5t4 -44t1 -42 q1 -49 -8.5 -99.5t-29 -98.5t-47.5 -91t-64 -76q2 -4 8 -6t13.5 -4t16 -5t14.5 -7q20 -14 40 -27.5t34 -33.5q17 -22 37.5 -43t29.5 -47q4 -6 11.5 -27t16 -46.5t15 -50.5t7.5 -40q1 -4 3.5 -14.5t5 -22.5t4.5 -22.5t2 -14.5v-8.5t0.5 -17.5t1 -20.5t0.5 -17.5 q1 -30 -3 -56.5t-9 -53.5q-5 -32 -17.5 -64.5t-29 -62.5t-36 -55t-38.5 -41q-14 -20 -37.5 -36.5t-40.5 -32.5q-31 -26 -55.5 -41.5t-50 -24.5t-55 -15t-70.5 -13q-6 -2 -18.5 -3t-25 -1.5t-23 -0.5h-12.5h-15v0z" />
<glyph unicode="4" horiz-adv-x="1339" d="M731 364h-7q-3 0 -5.5 0.5t-4.5 0.5q-26 1 -53.5 3t-55 3.5t-52.5 1.5t-44 -2q-14 1 -42 2.5t-58.5 3t-58 3t-40.5 2.5q-5 -1 -21.5 -2t-36 -2t-36.5 -1.5t-21 -0.5q-2 0 -10.5 0.5t-13.5 0.5q-2 0 -11.5 2t-20.5 4.5t-19.5 4.5t-9.5 2q-6 1 -16 3.5t-12 4.5q-1 1 -2 5.5 t-2 9.5t-1.5 9t-1.5 5q0 2 -2 6.5t-3 6.5q0 4 -2 12.5t-2 10.5q-1 5 0.5 18.5t3.5 28t4 28t3 18.5q-5 5 -5 8.5v8.5q0 11 6.5 18t9.5 15q0 5 0.5 17.5t1 26t1.5 25.5t1 17q1 62 -4.5 120t-10.5 117q0 2 0.5 9t0.5 9q0 3 -2 12t-4 12q-14 141 -18 278t-2 278v19.5t0.5 30.5 t1 30.5t0.5 19.5q6 13 18 15.5t23 1.5h4q34 -12 69 -12.5t69 -4.5q9 0 33 1t51.5 2t51.5 2t33 1q3 0 11 -2.5t10 -2.5q2 -2 12 -7.5t13 -6.5q10 -3 10 -14t-4.5 -22.5t-9 -19t-2.5 -3.5q0 -1 -0.5 -8.5t-1.5 -15.5q-1 -11 -1 -23q0 -5 1 -23t1.5 -38.5t1.5 -38t1 -21.5v-4 q0 -8 -3.5 -14.5t-3.5 -14.5q0 -1 -0.5 -2t-0.5 -3v-3q13 -19 12.5 -35t-5 -32t-9.5 -33t0 -39v-29l-1 -45v-7.5t-0.5 -11.5t-0.5 -11.5v-6.5v-39q0 -2 3 -11t3 -11l-7 -10q-2 -10 -3.5 -16.5t-2 -12.5t-1 -13t-0.5 -17v-23.5t6 -22.5l-2 -98q5 -8 6 -12.5t1 -12.5 q0 -3 -0.5 -5.5t-0.5 -4.5q-2 -3 -4 -7q-3 -6 -3 -9t3 -9l4 -8q0 -2 0.5 -7t1 -11t1.5 -11t2 -6q2 -6 11 -10t11 -4q4 0 13 -0.5t19.5 -1t20 -1.5t13.5 -1q7 0 17.5 -0.5l21 -1t18 -1t8.5 -0.5h9.5t14 0.5t14 1t9.5 1.5q2 0 6.5 1.5t6.5 3.5h2q9 -1 20.5 -1.5t27.5 -1.5 q12 -1 19.5 -1t13 2t10.5 7.5t13 16.5v31q1 51 0.5 100.5t-9.5 100.5q-8 40 -7.5 83t1.5 83q1 34 -1 63t-1 63v16t0.5 19t0.5 15.5v7.5q0 2 -1 11t-2 19t-2 19t-1 11q0 5 -1.5 28t-3 51.5t-3.5 56t-2 42.5v8t0.5 14.5t0.5 14v8.5q-2 25 -3.5 42.5t-1.5 42.5v8q-3 4 -2 10 t5.5 12t12.5 9.5t20 1.5q9 7 25.5 5t25.5 -2q1 0 8 0.5t14.5 1t14 1t8.5 0.5q1 0 8.5 -0.5t17 -1l19 -1t14.5 -0.5q6 0 14.5 -0.5t16.5 -1t14 -1t7 -0.5q24 -3 50 -5t49 -13q11 -5 11.5 -6.5t-0.5 -10.5q0 -9 -0.5 -13.5t-0.5 -9t-0.5 -10.5t-0.5 -17q0 -5 -0.5 -14 t-0.5 -11t1 -8.5t2 -14.5t2 -15t1 -9q0 -6 -0.5 -23.5t-2 -37t-2.5 -37t-1 -24.5l5 -10q-4 -60 1 -119t2 -117q5 -10 8.5 -15.5t3.5 -13.5q0 -9 -4 -15t-9 -13l20 -180q1 -1 4 -5.5t5 -10.5t4 -11.5t2 -6.5q0 -9 -3 -13.5t-3 -18.5q-1 -20 0.5 -37t4.5 -37q1 -3 3 -6l2 -4 t1 -3v-4q0 -6 -1 -9.5t-6 -8.5l-2 -80q0 -3 4.5 -3t10.5 0.5t12 2t8 1.5q22 -2 41.5 2t41.5 2q8 0 17.5 -0.5t15.5 -7.5q0 -9 -0.5 -33t-1 -51t-1 -51t-0.5 -33q0 -2 1 -13t1.5 -23.5t1.5 -23.5t1 -14v-24q-1 -32 -9.5 -45t-42.5 -14q-4 0 -15 -0.5t-23 -0.5h-23.5h-15.5 q0 -5 -1 -19t-1.5 -30t-1.5 -30t-1 -19v-15t-0.5 -25.5t-0.5 -25v-14.5q-1 -10 -3 -29.5t-4.5 -40.5t-4 -38t-1.5 -21q-1 -3 -3 -10.5t-4 -15.5t-3.5 -15.5t-2.5 -10.5q-7 -6 -17 -9q-8 0 -23 0.5t-32 0.5h-32.5h-23.5q-2 0 -10.5 -1t-18.5 -2.5t-19.5 -3t-15.5 -2.5 q-2 0 -11 0.5t-20 0.5t-20.5 0.5t-11.5 0.5q-3 -1 -7.5 -1t-9.5 -1t-11 -2q-4 0 -12.5 -1t-17.5 -1.5t-16.5 0t-9.5 4.5q-2 6 -6 15t-4 11q-2 2 -1 8t1 8q-1 2 -1.5 14t-0.5 26v26v14q-1 3 -2 10t-1.5 14t-1 13t-0.5 8q-1 12 -3 38t-4.5 54t-4 54t-1.5 38z" />
<glyph unicode="5" horiz-adv-x="1172" d="M484 0q-2 0 -13 2t-16 3t-16 4t-23.5 7t-23.5 7.5t-15 5.5q-2 -1 -6 1t-6 4q-2 1 -8.5 5.5t-14 9t-14 9t-8.5 5.5l-7 3.5t-10.5 5l-11 5t-6.5 3.5q-5 0 -5 5q-4 1 -13.5 4t-19.5 7t-19 7.5t-12 5.5q-2 2 -7.5 5.5t-7.5 5.5q-35 48 -58.5 81t-40 59.5t-27 50t-19.5 53.5 q-7 28 -16.5 54t-10.5 54v35q3 5 10.5 7.5t12.5 2.5q2 1 9 1.5t15.5 1.5t15.5 1h10q9 1 33 2t51 2t51 1.5t33 0.5q8 4 12.5 5t10.5 1h10t14.5 -1.5t14.5 -4.5t9 -7q22 0 30 -7t19 -27q2 -2 3.5 -11.5t3.5 -11.5t6.5 -8.5t6.5 -7.5q2 -3 8.5 -9.5t13.5 -14t13 -14t9 -9.5 q26 -21 59.5 -24.5t62.5 -3.5q5 -1 13 -1h16h19q2 0 17.5 4t23.5 7t22.5 9.5t30 14.5t29 16t19.5 16q8 11 15.5 27.5t13.5 34.5t9 36t2 33q0 2 -1.5 13t-3.5 25.5t-3.5 28.5t-2.5 23q-5 27 -18 50t-32.5 41t-43.5 30.5t-50 19.5q-2 0 -9 0.5t-14.5 0.5t-14.5 -0.5t-10 -0.5 q-5 0 -13 0.5t-15.5 1t-13.5 0.5h-7q-4 -1 -12 -2.5t-16 -3.5t-16 -5t-12 -6l-66 -49q-1 0 -7 -2.5t-14 -6t-16.5 -6.5t-13.5 -3l-45 -1q-32 0 -63 2t-61 4q-1 0 -10 -0.5t-20.5 -2t-20.5 -2.5t-10 -1t-5 -4q-5 -1 -14 -1t-18 0.5t-16.5 2t-8.5 2.5q-1 9 -1.5 30t-0.5 44 v43.5t-1 28.5q0 2 1.5 12.5t0.5 12.5q-1 4 -2 18t-2.5 30t-2.5 30t-1 17q-2 21 0.5 42.5t5 43.5t4.5 43.5t-1 41.5q-8 44 -7 89.5t0 89.5q-1 45 2 84t6.5 77.5t5 77.5t-1.5 84q-5 9 -2 16.5t9.5 12.5t14.5 6.5t14 -1.5q2 0 8.5 -0.5t13 -0.5h12.5h8q110 -1 214 4.5t214 4.5 q2 1 16.5 -1t34 -4t41 -3.5t36.5 0.5l4 1q1 0 8.5 1t16 1.5t16.5 1.5t10 1q6 0 31 1t53 2t53 2t31 1h15h26.5t27 -0.5t16.5 -0.5h6h7h10q2 0 6 -6t6 -10q10 -29 15 -65.5t10 -64.5q0 -2 2 -11.5t4 -11.5v-1q0 -2 1 -3v-2q-2 -2 -4 -6t-2 -6l2 -112q0 -16 -8 -24.5t-20 -12.5 t-26 -5t-26 -2q-4 -1 -20.5 -2t-35.5 -2t-36 -1.5t-21 -0.5q-50 -1 -97 -6.5t-99 -4.5q-48 1 -89.5 3t-89.5 2q-6 0 -19 -2t-13 -13v-1q0 -2 1 -3q0 -2 -1.5 -7.5t-4 -12t-4 -12.5t-1.5 -8q1 -9 2 -32t1 -48v-47v-30q2 -3 4 -6.5t3 -5.5l5 1q1 0 6 1.5t10.5 3.5t10.5 3.5 t7 2.5q1 0 7 0.5t13 1.5t13.5 1h10.5q3 1 14 2t23.5 2t23.5 1.5t14 0.5q2 0 8 3t7 3h13l12 -6q2 0 15 -2.5t17 -3.5q2 0 6 -0.5t6 -0.5l21 -3t27.5 -5t24.5 -5t13 -3q1 -1 7.5 -4t14.5 -6.5t15.5 -7t11.5 -6.5q35 -16 61.5 -37t55.5 -45q21 -16 37.5 -37.5t29.5 -45 t23.5 -48t19.5 -47.5q0 -2 2.5 -6t4.5 -6q0 -2 4.5 -9.5t4.5 -9.5q1 -2 0.5 -13t-0.5 -14q1 -2 3 -9t4 -15.5t4 -16t2 -9.5q1 -5 2 -17t2 -25.5t2 -26t1 -16.5q5 -5 6 -11t1 -12v-7q0 -2 1 -4q0 -2 -3.5 -8.5t-3.5 -8.5q-1 -5 -1 -17t0.5 -25.5t0.5 -26t-1 -16.5q1 1 1 -8.5 t-1 -22t-2.5 -23.5t-2.5 -13q-3 -37 -15.5 -68t-26.5 -63q-8 -14 -16.5 -37.5t-16.5 -36.5q-10 -14 -25 -30t-32 -31.5t-34.5 -29t-32.5 -22.5q-10 -7 -27 -18t-34.5 -22t-31 -19.5t-16.5 -9.5q-4 -3 -14 -6.5t-21 -6.5t-21.5 -6t-14.5 -5q-1 0 -5 -1t-8.5 -1.5l-9 -1 t-5.5 -0.5q-6 -2 -19 -6.5t-16 -6.5q-2 0 -10.5 -6t-9.5 -8h-4q-8 1 -13.5 2t-11.5 4h-159z" />
<glyph unicode="6" horiz-adv-x="1222" d="M266 135q-4 3 -12 11.5t-17 18t-16.5 18.5t-9.5 13q-2 0 -6 10.5t-6 11.5t-10.5 10.5t-10.5 12.5q-2 2 -9 6.5t-9 6.5q-1 3 -2 7q-2 7 -4 9q1 2 -1.5 6.5t-2.5 6.5q-2 1 -7 8.5t-10.5 16.5t-10 17t-5.5 10q-2 2 -6 10t-6 11q-1 2 -4 11t-6.5 19t-6.5 18.5t-4 10.5l-17 40 q0 3 -2.5 15.5t-6 27t-7 27.5t-3.5 16q-10 42 -10.5 82.5t-2.5 83.5q0 2 -0.5 13.5t-1.5 25t-1.5 25t-0.5 14.5v10q0 4 0.5 8.5t0.5 6.5q1 42 7.5 82t13.5 80q1 4 3 15t4 23.5t4 24t3 16.5q0 2 1 10.5t2.5 17.5t2.5 17.5t2 10.5q14 75 42 139t63 130q1 1 5 8.5t9 16t9 16 t5 8.5q2 2 10 11t10 11q31 40 60 72t69 67q2 2 7 6.5t10.5 8.5t10 7.5t6.5 4.5q3 2 18 8.5t34 14.5t38 16.5t30 13.5q42 18 80.5 29t77 16.5t78.5 6.5t85 0q5 0 18 -0.5t27.5 -1.5t27.5 -1.5t18 -0.5q20 -6 39 -10.5t36.5 -11t33.5 -16t30 -26.5q2 -3 4 -7t5 -8t7 -9 q0 -2 -1.5 -15t-4.5 -17q-1 -2 -2.5 -6.5t-3.5 -10t-3.5 -9.5t-2.5 -5q-2 -3 -6 -9.5t-4 -8.5q-2 -2 -4 -11t-2 -11q-1 -2 -3.5 -11t-5 -19t-5 -19t-3.5 -11q-2 -5 -5.5 -15.5t-5.5 -15.5q0 -1 -4 -6.5t-8.5 -11.5t-8.5 -11.5t-5 -6.5q-6 -9 -10.5 -8t-20.5 1 q-13 1 -23.5 2.5t-20.5 3.5t-20.5 4t-23.5 2q-67 5 -125 -14.5t-106.5 -56.5t-86 -89t-64.5 -112q-4 -12 -11.5 -30t-15.5 -37.5t-14.5 -38.5t-9.5 -32q-3 -11 -3.5 -15t0.5 -15v-16q2 0 8.5 5t8.5 5q1 1 7 5.5t13 9t12.5 8.5t7.5 5q1 1 9 4.5t18.5 8.5t20.5 10t15 8 q28 13 49.5 19.5t42.5 9t44 1.5t55 -2q23 -1 44 -4t42 -11q7 -2 24.5 -6t35.5 -8.5l32 -8t16 -4.5q12 -2 16.5 -8t9.5 -10q6 -4 15 -9t18.5 -11.5t19 -14t15.5 -15.5q3 -4 8 -10l10 -12t8.5 -11.5t4.5 -6.5q4 -5 12.5 -20t18.5 -31.5t18 -32t11 -21.5q14 -2 17 -11.5 t1 -21.5q0 -2 2 -10.5t4 -18.5t4.5 -20l3.5 -14q0 -2 1.5 -6t3.5 -6q1 -1 3 -2q3 -3 3 -4v-23q1 -12 7.5 -17.5t8.5 -16.5q1 -1 1.5 -9.5t1 -19t1 -19.5t0.5 -10q2 -4 2.5 -18.5t2.5 -19.5q3 -14 4.5 -38t3.5 -49q1 -2 1 -9v-15t-1 -15.5t-2 -10.5q0 -5 -8 -18.5t-13 -42.5 q-2 -1 -4 -5l-3 -6t-4.5 -13t-7 -23.5t-7 -23l-4.5 -13.5q-1 -2 -3.5 -7.5t-5.5 -11.5t-6 -11.5t-5 -7.5q0 -4 -4 -9.5t-6 -7.5q-6 -5 -16.5 -16t-22 -22.5t-21 -22t-13.5 -13.5q-43 -37 -87.5 -61t-91.5 -38t-98 -19.5t-108 -3.5q-6 0 -17.5 0.5t-22.5 0.5t-19 0.5t-9 0.5 q-31 2 -61 10t-59 20t-57 26t-55 27zM439 557q0 -7 1 -20t0 -15q0 -3 2 -11l4.5 -18l5 -20t4.5 -15q10 -29 31 -47t47 -35q23 -13 44 -19t47 -7q13 0 30 1.5t35 5t34.5 9.5t27.5 15q35 28 61 59t28 80q0 5 -2 23.5t-4 26.5q-1 2 -2 5l-2 4l-2 4q-2 5 -8.5 16t-6.5 13 q-11 15 -19 28t-16.5 25t-18.5 23t-24 23q-29 9 -60.5 20.5t-62.5 12.5q-18 1 -39 -2t-37 -13l-6 -6t-11.5 -11t-13.5 -12t-11 -9q-27 -31 -40.5 -60.5t-15.5 -73.5z" />
<glyph unicode="7" horiz-adv-x="1212" d="M112 168q-3 6 -3 9q5 10 19 36.5t29.5 55.5t29 55.5t18.5 36.5q1 2 4.5 9.5t6.5 16t6 16t5 9.5q11 17 25.5 40t24.5 40q20 35 36 68.5t34 66.5q1 2 7.5 14t14.5 27.5t16 31.5t14 27q0 2 3.5 5.5t3.5 5.5q2 3 9.5 14.5t16 24.5t15.5 24.5t8 14.5q1 1 8.5 15t17 32t19.5 36 t16 29q33 62 70.5 120.5t64.5 121.5l28 57q6 8 12 21t10.5 27.5t8 28t6.5 22.5q-2 2 -12 -1t-12 -3q-3 0 -14.5 -3t-13.5 -3t-8.5 0.5t-14.5 1t-15 0.5h-9l-10 -4q-2 -1 -10 -0.5t-17 1t-16.5 1t-10.5 0.5h-30.5h-55h-67.5h-68h-56h-32q-2 0 -6 0.5t-6 0.5h-26.5h-33 t-29 -0.5t-14.5 -1.5q-3 0 -14.5 -2.5t-13.5 -2.5t-11 0.5t-14 0.5q-11 1 -20 2t-19 6q-1 4 -1.5 13.5t-1 19.5t-1 19.5t-1.5 14.5q-9 65 -8.5 134t-1.5 134q0 8 1 12.5t12 6.5q2 2 14.5 3.5t17.5 1.5q3 1 10 0t14 -1.5t13.5 -1.5t8.5 0q6 1 28.5 3.5t48.5 5t49 5t29 2.5 q1 1 8 1t14.5 -0.5t14 -1.5t8.5 -1h43t65 0.5t75.5 1t75 1t63 0.5t40.5 1q68 2 134 5.5t135 0.5h12t16 -0.5t14 -1t7 -0.5q8 0 29.5 -2t45 -4.5t45 -5t29.5 -3.5q11 -12 14 -26.5t4 -28.5q1 -2 1 -12v-21.5v-21.5v-12q5 -48 7.5 -101t3.5 -100q1 -23 -11.5 -50t-23.5 -49 q-3 -9 -13.5 -29.5t-22 -44t-22 -44t-13.5 -29.5q-2 -2 -6 -8t-6 -8l-123 -243q2 -6 -3.5 -18.5t-11.5 -20.5q-2 -2 -5 -8t-6 -12.5t-6 -12t-5 -6.5q-3 -8 -11.5 -28.5t-18.5 -43t-19 -42t-13 -26.5q-2 -3 -7.5 -13.5t-12 -22t-12 -21.5t-6.5 -12q-18 -26 -43 -68.5 t-50.5 -90.5t-48.5 -94.5t-37 -79.5q-3 -5 -10.5 -20.5t-17.5 -37t-22 -45.5t-22 -45.5t-18 -37.5t-10 -21q-7 -12 -20 -25t-30 -12h-9q-2 0 -6 3t-6 4q-22 9 -45.5 16t-47 14.5t-46 16t-43.5 21.5q-4 2 -17.5 11l-30 20t-32.5 21l-24 15q-6 3 -16 5.5t-12 4.5q-9 6 -11.5 8 t-2.5 10z" />
<glyph unicode="8" horiz-adv-x="1207" d="M53 511q0 4 0.5 10.5t0.5 13t0.5 11.5t0.5 6q1 3 3.5 20t6 38l7 42t5.5 32q3 17 17 39t25 35q14 18 24 31.5t19 25.5t20 24.5t26 29.5q14 14 30.5 27t29.5 27q-24 13 -42 31t-32 40t-25.5 46t-21.5 49q-18 43 -25.5 85.5t-7.5 87.5v61q24 106 100 187q26 28 53.5 54.5 t57.5 49t63.5 39.5t71.5 27q3 2 15.5 4t17.5 2q4 0 19 1.5t33 3.5t33.5 3.5t19.5 1.5q2 2 16 3.5t16 1.5q1 0 6 -0.5t11 -1.5t10.5 -1.5t5.5 -1.5q31 -5 54.5 -8t54.5 -13q1 0 6.5 -2.5t12.5 -5.5t12.5 -5.5t7.5 -2.5l44 -28q3 -2 28.5 -9.5t61 -35.5t75.5 -83.5t73 -152.5 q14 -153 -30 -295q-1 -2 -6.5 -15t-12.5 -29.5t-14 -33.5t-11 -27q-4 -11 -16 -20t-12 -15l2 -2q0 -2 3.5 -8.5t5.5 -9.5q1 -2 7 -8.5t12.5 -15t12 -15.5t7.5 -9q35 -58 55 -97.5t32 -76t19.5 -77.5t18.5 -103q1 -4 0 -24.5t-2 -44t-2.5 -44t-2.5 -24.5q-8 -48 -26 -83.5 t-39 -64t-42.5 -53t-35.5 -49.5q-39 -24 -82.5 -46t-89.5 -38.5t-92 -26t-89 -9.5q-65 0 -127.5 5t-124.5 23q-35 10 -69 33t-62 43q-3 2 -11.5 8t-11.5 9q-1 1 -5.5 5t-10.5 9t-10.5 9t-5.5 5q-1 0 -8 1.5t-9 3.5q-6 3 -6.5 9.5t-5.5 11.5q-14 26 -34 47.5t-36 47.5 q-5 5 -13.5 16.5t-8.5 13.5q-4 12 -12.5 28.5t-16.5 39.5t-14.5 51.5t-5.5 64.5q0 2 -1 17.5t-1 23.5zM427 425q1 -2 5 -5.5t6 -5.5q2 0 8.5 -10t8.5 -12q1 -1 5 -5.5t9 -10.5t9 -11t6 -6q10 -5 19 -9q8 -4 16 -7.5t13 -5.5q26 -11 47 -13t50 -2q11 0 31.5 3.5t31.5 8.5 q73 20 102 70.5t29 123.5q0 25 -2 40.5t-6.5 28t-10.5 25.5t-14 33q-1 1 -2 3l-2 4l-2 4q-12 14 -23 21.5t-23 12t-26 8.5t-32 10q-8 5 -20 9t-21 4q-26 0 -59 -2.5t-59 -7.5q-15 -2 -28.5 -11t-25 -21t-21.5 -26t-18 -26l-6 -9t-4 -8q-2 -3 -4.5 -10.5t-5 -17t-5.5 -18 t-4 -12.5v-14q0 -63 28 -123zM518 1045q2 -2 10.5 -4.5t17.5 -4t17 -1.5t9 3h30q1 1 6.5 1.5t12 0.5h12.5h8q2 2 13 3t14 3q20 7 39 20t34 27.5t25.5 27.5t13.5 22q2 2 4 6t2 6q2 33 -5.5 73.5t-26.5 75.5t-50 59.5t-74 26.5q-8 2 -23 0t-32 -6.5t-32 -11.5t-23 -16 q-20 -9 -35.5 -24.5t-26 -35t-16.5 -41.5t-6 -43q1 -23 2 -44t8 -41.5t23.5 -41t48.5 -40.5z" />
<glyph unicode="9" horiz-adv-x="1251" d="M794 58l6 167q0 2 1 10t1.5 18t0.5 19v14q0 3 -2.5 14t-2.5 13t1.5 13t3.5 24t3.5 24t0.5 13v31.5t-0.5 52t-0.5 63t-1.5 65t-3.5 58.5t-5 44h-5q-2 0 -11 -2.5t-19.5 -5.5t-19.5 -5.5t-10 -3.5l-20 -2.5t-24.5 -3t-22.5 -2.5t-12 -1h-8.5t-14 0.5t-14 1t-7.5 0.5 q-2 0 -8.5 -0.5t-14 -1.5t-14.5 -1.5t-9 -0.5l-28 1q-32 1 -60.5 7.5t-60.5 17.5q-2 0 -10 2t-13 4q-26 8 -46 15.5t-44 21.5q-2 1 -8.5 4.5t-13.5 7.5t-13.5 7t-8.5 4t-7 5t-11 8q-7 4 -15 10q-5 6 -15.5 16t-21 20.5t-19 19.5t-10.5 12q-4 5 -14.5 20.5t-22 32.5 t-21.5 32.5t-13 21.5q-10 22 -13 43t-11 44q-14 42 -19 80.5t-3 83.5q0 4 1 15t2 23.5t1.5 23t0.5 15.5q2 3 4.5 11.5t2.5 10.5l1 6q1 5 4.5 16t7.5 23.5t7.5 23l4.5 13.5q0 1 2.5 5t4.5 6q33 48 64.5 91.5t67.5 81t79.5 67.5t102.5 50q27 9 51 13t48 5t48.5 0t51.5 -2 l61 -2q4 -2 16 -6t17 -6q10 -3 23 -5t26.5 -5t26 -7t21.5 -10q6 -5 19 -13.5t20 -13.5l31 39q0 1 6 8t9 9q9 5 15 5.5t14 0.5l18 -1q3 -1 16.5 -2t29.5 -2t29.5 -1.5t17.5 -0.5q3 0 16 -3t28 -6t28.5 -5.5t16.5 -1.5h22q11 -1 18 -1.5t16 -6.5q17 6 25.5 -5.5t13.5 -45.5 q-6 -34 -6 -77t3.5 -94.5t8.5 -110.5t8 -123l-1 -12q-2 -19 -1.5 -55t1.5 -72.5t2 -64.5t1 -31q0 -2 -1 -7t-2.5 -11.5t-2.5 -12t-1 -7.5l-4 -94q-6 -6 -6 -14.5v-15.5l-3 -70q-4 -8 -6 -24.5t-2 -27.5q3 -6 4.5 -11.5t1 -13t-3 -19.5t-6.5 -31v-4q1 -4 1.5 -10.5t1.5 -13 t1.5 -11t0.5 -5.5q-1 -2 4 -11t7 -11l-1 -5q0 -11 -6 -17.5t-7 -16.5l-1 -15q0 -3 2.5 -17t2.5 -17l10 -43q0 -13 -3 -33t-6.5 -39t-6 -33t-1.5 -15l5 -12l-3 -71q0 -2 2.5 -8.5t2.5 -8.5l-1 -37q0 -3 4.5 -10.5t6.5 -9.5v-5q-1 -14 -13 -27q0 -17 4 -34t5.5 -32.5t-2 -30 t-18.5 -24.5q-63 4 -131 -1t-131 -3l-71 2q-12 -2 -26 6t-15 24zM398 1224q-2 -61 14 -108t67 -81q10 -6 24 -10.5t29.5 -6.5t30.5 -3.5t27 -1.5q25 -1 48 7.5t42.5 22.5t34.5 33.5t24 41.5q8 23 11.5 47.5t4.5 47.5q1 9 0.5 23.5t-0.5 15.5q-1 2 -2 6q-2 6 -2 10 q-12 34 -30.5 66t-50.5 52q-5 1 -19.5 6t-19.5 5q-28 2 -67 -6t-75 -28.5t-62.5 -54.5t-28.5 -84z" />
<glyph unicode=":" horiz-adv-x="553" d="M472 518v-28.5t-6 -30.5q-11 -22 -19 -41.5t-25 -38.5q-5 -5 -13 -12t-16.5 -13.5t-15.5 -12t-9 -8.5q-22 -20 -50 -20.5t-54 -1.5q-17 -2 -28.5 2t-28.5 10q-8 1 -22 7.5t-22 11.5q-40 25 -69.5 62t-35.5 90q0 31 1 54t8 41.5t21 36.5t38 39q21 20 53 36.5t61 18.5h10.5 h15.5t15.5 -0.5t9.5 -1.5q4 0 12 -2t16.5 -4t15.5 -4t9 -2q1 -2 8.5 -4.5l16.5 -5.5t17 -5.5t11 -3.5q22 -17 36.5 -34t22.5 -37t11.5 -44t4.5 -54zM483 1035v-28.5t-6 -30.5q-11 -22 -19 -41.5t-25 -38.5q-5 -5 -13 -12t-16.5 -13.5t-15.5 -12t-9 -8.5q-22 -20 -50 -20.5 t-54 -1.5q-17 -2 -28.5 2t-28.5 10q-8 1 -22 7.5t-22 11.5q-40 25 -69.5 62t-35.5 90q0 31 1 54t8 41.5t21 36.5t38 39q21 20 53 36.5t61 18.5h10.5h15.5t15.5 -0.5t9.5 -1.5q4 0 12 -2t16.5 -4t15.5 -4t9 -2q1 -2 8.5 -4.5l16.5 -5.5t17 -5.5t11 -3.5q22 -17 36.5 -34 t22.5 -37t11.5 -44t4.5 -54z" />
<glyph unicode=";" horiz-adv-x="634" d="M520 680v-28.5t-6 -30.5q-11 -22 -19 -41.5t-25 -38.5q-5 -5 -13 -12t-16.5 -13.5t-15.5 -12t-9 -8.5q-22 -20 -50 -20.5t-54 -1.5q-17 -2 -28.5 2t-28.5 10q-8 1 -22 7.5t-22 11.5q-40 25 -69.5 62t-35.5 90q0 31 1 54t8 41.5t21 36.5t38 39q21 20 53 36.5t61 18.5h10.5 h15.5t15.5 -0.5t9.5 -1.5q4 0 12 -2t16.5 -4t15.5 -4t9 -2q1 -2 8.5 -4.5l16.5 -5.5t17 -5.5t11 -3.5q22 -17 36.5 -34t22.5 -37t11.5 -44t4.5 -54zM158 -292q1 1 3.5 6.5t6 11t6 10.5l3.5 7q14 34 24 64t18 60t14.5 62t12.5 68q0 3 1 12t2 19.5t2 20t1 12.5q-9 0 -13.5 -2 t-8.5 -4.5t-8.5 -5t-12.5 -4.5q-35 -6 -68 -6q-11 0 -26 8.5t-15 22.5q0 63 0.5 117t-1.5 116q2 4 2 10.5t1.5 12.5t6 11.5t15.5 9.5h76q3 0 11.5 0.5t18 1.5t18 2t12.5 2q4 0 22.5 -0.5t40 -0.5h39.5t23 1q2 0 10.5 0.5t18.5 1.5t18 1.5t10 0.5t12.5 1t16.5 1 q11 0 23.5 -0.5t23.5 -5.5q12 -6 18.5 -24t9.5 -38.5t4 -39t1 -27.5v-14q0 -2 -3 -6.5t-3 -6.5q-1 -2 -2 -10t-2 -17t-1.5 -17.5t-0.5 -12.5q1 -10 -1.5 -27.5t-7 -34t-10 -29t-10.5 -11.5q-14 -26 -22.5 -54.5t-22.5 -56.5q-18 -32 -41 -65t-49.5 -63t-57.5 -54.5 t-65 -39.5q-2 -1 -9.5 -4.5t-17 -8t-19 -8.5t-13.5 -5q-9 -3 -12.5 -4.5t-11.5 -1.5q-10 0 -10.5 6t-0.5 14v15z" />
<glyph unicode="&#x3c;" horiz-adv-x="1036" d="M982 266q-2 1 -13.5 7t-13.5 7q-9 3 -25 9t-33 12t-31 11t-18 6q-3 1 -21.5 6t-42 11t-47.5 12t-37 9q-2 0 -7.5 1t-12.5 2.5t-13 3t-7 1.5q-2 0 -17 5t-35.5 11.5t-42 13t-34.5 10.5q-20 8 -41.5 14t-41.5 15q-18 8 -35 15.5t-36 14.5q-4 1 -21 5.5t-36.5 10.5t-36.5 11 t-21 6q-23 7 -48 18.5t-46 22.5q-2 -1 -4.5 0t-4.5 1q0 1 -5.5 2t-6.5 1q-19 5 -40 11t-37 15q0 1 -0.5 1.5t-0.5 1.5v2v4q0 1 -1 8t-1.5 15.5t-1.5 15.5l-1 7q1 7 1.5 12t0 9.5t-1 10t-1.5 13.5q-2 16 -0.5 27.5t2 22t0 21.5t-4.5 26q5 11 12.5 13.5t15.5 7.5q4 3 17 14 t28.5 23.5t29 23.5t18.5 13q38 26 76.5 45.5t73.5 48.5q1 2 3.5 4.5l4.5 4.5q1 0 5.5 2t9.5 4t9 4t5 3q2 1 11.5 7.5t21 14t22 14t13.5 8.5q1 1 6 4t11 6t11 6t7 4q5 3 23 13.5t38.5 22.5t38.5 23t22 14q23 16 45 26.5t46 25.5q3 2 10.5 5.5t15.5 7t14.5 6.5t7.5 4 q6 3 20.5 11t30.5 17t30 16.5t20 10.5l23 8q18 5 31.5 -1.5t19.5 -26.5q1 -9 3.5 -30t5.5 -45t5.5 -45.5t3.5 -29.5q2 -20 9 -42t11 -42q1 -8 -5.5 -15t-16 -12.5t-19.5 -9.5t-16 -7q-33 -22 -65 -43t-64 -45q-4 -3 -15.5 -11.5t-24.5 -18t-24.5 -18t-16.5 -11.5 q-17 -13 -33 -22.5t-32.5 -18.5t-33 -18.5t-33.5 -21.5v-3v-2q2 -1 5.5 -1.5t5.5 -1.5q1 -1 2 -8t3 -8q27 -14 58.5 -24.5t60.5 -18.5q1 0 6.5 -0.5t6.5 -1.5q3 -2 14.5 -7t14.5 -6q1 -2 6 -1.5t6 -0.5q12 -3 24.5 -7t24.5 -8q24 -10 48 -17t49 -14q1 0 6 -1.5t6 -1.5 q1 -1 8 -3.5t15.5 -6t17.5 -7t14 -5.5q14 -7 28 -17.5t16 -27.5q5 -50 10 -99t7 -100v-1q0 -1 0.5 -1.5t0.5 -1.5q1 -5 0.5 -8.5t0.5 -8.5v-3v-2q-1 -4 -3 -12.5t-5 -9.5q-2 0 -4 -1q-4 -2 -6 -2h-11z" />
<glyph unicode="=" horiz-adv-x="857" d="M67 870q-2 10 -1 20.5t0 20.5q0 3 0.5 14t1.5 24t1.5 24t0.5 14q0 30 -2 59.5t1 58.5q1 15 16 25.5t28 11.5q4 0 18.5 -2t31.5 -3.5t32 -2.5t18 -1h17.5t29 0.5t29 0.5h16.5t15 -1.5t26.5 -2.5t27 -2t16.5 -1q45 -4 88.5 0.5t89.5 3.5q1 1 19.5 0t43 -2.5t50 -3.5 t41.5 -3q2 0 4.5 -0.5t4.5 -0.5q18 -2 23 -13t4 -27t-5 -32.5t-4 -28.5q0 -3 1 -11.5t2 -18t2 -18t1 -11.5q1 -11 0 -18t-3 -15q-2 -18 3 -37t3 -33q-1 -1 -1 -4v-3q-2 -2 -9 -8t-10 -6q-6 1 -18.5 -1.5t-19.5 -4.5h-18.5h-38h-48.5h-48h-38h-18h-9t-15 -0.5t-15 -0.5h-9 q-3 0 -13.5 -0.5t-22 -1.5t-22 -1.5t-13.5 -1.5q-5 0 -22 0.5t-36.5 1t-36.5 0.5h-22q-31 -1 -45.5 -0.5t-26.5 2t-27 3.5t-47 5q-3 1 -12.5 3.5t-14.5 3.5q-5 3 -9 12.5t-6 13.5zM68 473q-2 10 -1 20.5t0 20.5q0 3 0.5 14t1.5 24t1.5 24t0.5 14q0 30 -2 59.5t1 58.5 q1 15 16 25.5t28 11.5q4 0 18.5 -2t31.5 -3.5t32 -2.5t18 -1h17.5t29 0.5t29 0.5h16.5t15 -1.5t26.5 -2.5t27 -2t16.5 -1q45 -4 88.5 0.5t89.5 3.5q1 1 19.5 0t43 -2.5t50 -3.5t41.5 -3q2 0 4.5 -0.5t4.5 -0.5q18 -2 23 -13t4 -27t-5 -32.5t-4 -28.5q0 -3 1 -11.5t2 -18 t2 -18t1 -11.5q1 -11 0 -18t-3 -15q-2 -18 3 -37t3 -33q-1 -1 -1 -4v-3q-2 -2 -9 -8t-10 -6q-6 1 -18.5 -1.5t-19.5 -4.5h-18.5h-38h-48.5h-48h-38h-18h-9t-15 -0.5t-15 -0.5h-9q-3 0 -13.5 -0.5t-22 -1.5t-22 -1.5t-13.5 -1.5q-5 0 -22 0.5t-36.5 1t-36.5 0.5h-22 q-31 -1 -45.5 -0.5t-26.5 2t-27 3.5t-47 5q-3 1 -12.5 3.5t-14.5 3.5q-5 3 -9 12.5t-6 13.5z" />
<glyph unicode="&#x3e;" horiz-adv-x="1059" d="M88 1257q2 -1 13.5 -7t13.5 -7q9 -3 25 -9t33 -12t31 -11t18 -6q3 -1 21.5 -6t42 -11l47 -12t37.5 -9q1 0 7 -1t13 -2.5t12.5 -3t7.5 -1.5q1 0 16.5 -5t36 -11.5t42 -13t34.5 -10.5q20 -8 41.5 -14t41.5 -15q18 -8 35 -15.5t36 -14.5q4 -1 21 -5.5t36.5 -10.5t36 -11 t21.5 -6q23 -7 48 -18.5t46 -22.5q2 1 4.5 0t4.5 -1q0 -1 5.5 -2t6.5 -1q19 -5 40 -11t37 -15v-3q0 -1 1 -2v-4q0 -1 1 -8t1.5 -15.5t1.5 -15.5l1 -7q-2 -14 -1.5 -21.5t2.5 -23.5q1 -16 0 -27.5t-1.5 -22t-0.5 -21.5t5 -26q-5 -11 -12.5 -13.5t-15.5 -7.5q-4 -3 -17 -14 t-28.5 -23.5t-29 -23.5t-18.5 -13q-38 -26 -76.5 -45.5t-73.5 -48.5q-1 -2 -3.5 -4.5l-4.5 -4.5q-1 0 -5.5 -2t-9.5 -4t-9 -4t-5 -3q-2 -1 -11.5 -7.5t-21 -14t-22 -14.5t-13.5 -8q-1 -1 -6 -4t-11 -6t-11.5 -6t-6.5 -4q-5 -3 -23 -13.5t-38.5 -22.5t-38.5 -23t-22 -14 q-23 -16 -45 -26.5t-46 -25.5q-3 -2 -10.5 -5.5t-15.5 -7t-14.5 -6.5t-7.5 -4q-6 -3 -20.5 -11t-30.5 -17t-30 -16.5t-20 -10.5l-23 -8q-18 -5 -31.5 1.5t-19.5 26.5q-1 9 -3.5 30t-5.5 45t-5.5 45.5t-3.5 29.5q-2 20 -9 42t-11 42q-1 8 5.5 15t16 12.5t19.5 9.5t16 7 q33 22 65 43t64 45q4 3 15.5 11.5t24.5 18t24.5 18t16.5 11.5q34 25 65.5 41t66.5 40v3v2q-2 1 -5.5 1.5t-5.5 1.5q-1 1 -2 8t-3 8q-27 14 -58.5 24.5t-60.5 18.5q-1 0 -6.5 0.5t-6.5 1.5q-3 2 -14.5 7t-14.5 6q-1 2 -6 1.5t-6 0.5q-12 3 -24.5 7t-24.5 8q-24 10 -48 17 t-49 14q-1 0 -6 1.5t-6 1.5q-2 1 -8.5 3.5t-15 6t-17.5 7t-14 5.5q-14 7 -28 17.5t-16 27.5q-5 50 -10 99t-7 100q-1 0 -1 1v3q-1 5 -0.5 8.5t-0.5 8.5v3v2q1 4 3 12.5t5 9.5q1 0 3 1t3.5 1t3.5 1h11z" />
<glyph unicode="?" horiz-adv-x="1164" d="M375 235q2 26 8 48.5t17 48.5q2 4 6.5 12t9 16.5t8.5 15t5 8.5q1 1 7 6t14.5 12t17 13.5t13.5 10.5q28 23 65.5 33t72.5 9q81 -2 141 -50t87 -123v-6v-11v-11.5v-7.5q-1 -28 -6 -56.5t-16 -55t-28.5 -49t-41.5 -38.5q-27 -19 -51.5 -30.5t-49 -17.5t-52 -7.5t-60.5 -0.5 q-3 0 -7 1.5t-6 1.5q-41 9 -70.5 31.5t-48.5 53.5t-28 68t-7 75zM460 511q-1 -2 -12 -2.5t-23.5 3t-23 12t-9.5 23.5v2v4q0 1 -1.5 6t-3 11.5t-3 12t-1.5 6.5q-1 5 -2.5 14.5t-1.5 11.5v8t0.5 16t1 18.5t0.5 15.5q1 26 3 52.5t13 50.5q16 41 33 74.5t46 65.5q5 4 24 22 t41 38t41 38t25 22q1 1 5.5 7t10.5 13.5l12 15t10 11.5q2 2 4 4.5t4 5.5q2 4 4 7l28 41q7 5 15 18t15.5 29t13.5 31t9 24q0 4 0.5 19.5t0.5 20.5q1 8 1.5 23t0.5 17q0 27 -13 49t-33 38t-45 25t-49 9q-34 -5 -63.5 -17.5t-53 -30t-40.5 -38t-26 -39.5q-13 -26 -16.5 -44 t-9.5 -43q0 -3 -8 -7q-4 -2 -8 -3q-3 1 -12.5 1h-18.5h-14t1 0q-9 -2 -30.5 -3t-49 -0.5t-58 2t-57.5 3.5t-47 5.5t-27 7.5v2q0 1 -2.5 2.5t-6 2.5t-6 2t-1.5 3v2q0 6 -3 11t-2 10q1 42 12.5 85.5t29.5 85.5t41 81t48 71q0 1 2 3l2 2q6 4 17.5 11t23.5 15.5t23 16t17 12.5 q5 1 13.5 4.5t18.5 8t19 8.5t14 6q45 18 93 26t96 7q9 1 33.5 0.5t55.5 -2t65 -3.5t62.5 -4.5t47 -5t18.5 -4.5l15 -6t20.5 -8.5t19.5 -8.5t12 -5q4 -2 13 -7t19.5 -11t19.5 -11.5t13 -8.5q25 -18 49 -35.5t44 -37t36 -43t26 -52.5q9 -26 18.5 -53.5t17 -56.5t12 -58 t3.5 -57q-2 -38 -14.5 -69.5t-26.5 -66.5q-8 -17 -16 -33.5t-20 -29.5q-15 -17 -37.5 -37t-36.5 -42q-12 -8 -30 -23t-34 -32t-27 -32.5t-9 -22.5q-23 -27 -37 -56.5t-22 -61.5v-4l-19 -60q0 -2 -1.5 -7.5t-3.5 -12.5t-4.5 -13t-4.5 -9q0 -5 -2.5 -15t-2.5 -12v-22 q-2 0 -6 -10.5t-6 -10.5q-31 -12 -61 -16t-63 -10q-2 0 -10.5 -0.5t-19 -1t-19.5 -1.5t-11 -1q-11 -3 -27.5 -5.5t-34.5 -4t-35.5 -2.5t-30.5 -3z" />
<glyph unicode="@" horiz-adv-x="1873" d="M861 -130q-17 7 -32.5 6.5t-35.5 4.5q-51 13 -89 27t-68 28t-55.5 29t-50.5 32q-2 1 -10 5.5t-17.5 10t-18 10.5t-12.5 7q-24 13 -41 33t-42 31l-30 28v6q-2 1 -10 8.5t-17 16.5t-17.5 16.5t-9.5 9.5q-1 1 -4.5 5.5t-7.5 9t-7.5 8l-4.5 4.5l-12 12q-1 0 -4 1.5t-9 8.5 t-15.5 22.5t-23.5 43.5h-1.5t-2.5 3.5t-7 13t-14.5 30t-24 54t-36.5 84.5l-24 41v21q-15 40 -25 74t-16.5 68t-10 70.5t-4.5 81.5q-2 46 1 82.5t10 81.5q1 2 2 13t2.5 23.5t3 23.5t2.5 14q16 37 37.5 83t46.5 92t53 86.5t58 66.5q5 4 20.5 18t34.5 31.5l38 35t31 28.5 q3 2 16 10.5t18 11.5q49 30 97.5 53.5t100.5 49.5q2 0 8.5 2t9.5 2q26 8 41 14t28 11.5t27.5 11t40.5 12.5q2 2 9 4l8 2q5 2 13.5 4.5t10.5 2.5l227 19q3 -2 14.5 -3.5t15.5 -1.5h34q6 0 18 -1t24.5 -3t23.5 -4t15 -3q1 -1 5 -3t9 -4t9 -3.5t6 -1.5h16q3 -1 10 -5t10 -6 l15 -3t21.5 -5t21.5 -6t16 -6q-2 -6 22.5 -12t62.5 -18t82 -33t80 -57q2 -1 12 -8.5t20.5 -17.5t19 -20t7.5 -17q3 -5 10 -13.5t14.5 -17t14.5 -16.5t11 -12l29 -41v-6q14 -16 23 -34.5t15.5 -38.5t11.5 -40.5t12 -40.5q2 -2 4 -11.5t2 -11.5q1 -3 1.5 -13t1 -21t1 -20.5 t1.5 -10.5q1 -2 2.5 -11t3 -20.5t3 -21t2.5 -10.5q1 -3 2.5 -10t4 -14.5t4 -14t2.5 -8.5l-8 -109q-1 -19 -0.5 -32t0.5 -24.5t-1.5 -23.5t-5.5 -30q0 -2 -1 -9t-1.5 -15.5t-1.5 -15.5t-1 -9t-1 -9t-3 -16t-3.5 -16.5t-1.5 -8.5t-2.5 -8t-5.5 -15t-5.5 -15t-2.5 -8 q-2 -2 -5.5 -11.5t-8 -20t-8.5 -20t-5 -12.5q-23 -66 -63.5 -125.5t-96.5 -101.5q-1 0 -9 -2q-4 -1 -7 -2q-3 -2 -8 -4.5t-10.5 -5.5t-10 -5.5t-5.5 -3.5l-74 -24h-6q-4 0 -18 -5t-18 -5q-4 -1 -16 -2.5t-26 -3t-26.5 -3t-16.5 -2.5l-66 -5q-4 0 -12.5 1t-17.5 2.5t-17.5 3 t-11.5 2.5q-9 4 -17.5 9t-19 14t-23.5 22.5t-30 33.5v1l-2 1l-2 -2q-32 -14 -64.5 -28t-67.5 -19q-7 -1 -24.5 -2.5t-38 -3t-38.5 -2.5t-26 -1l-45 12q-2 1 -8 2.5t-12.5 3t-13 2.5t-7.5 1q-2 2 -8.5 4.5t-8.5 2.5t-5 1t-5 1l-48 19q0 2 -5 6t-8 6q-5 3 -15.5 11.5 t-13.5 10.5q-11 8 -17 7.5t-18 4.5l-18 34q-2 2 -9 10.5t-10 12.5l-30 43q-1 14 -11.5 31.5t-18.5 28.5q-2 4 -6 16.5t-8 26.5t-7.5 26t-4.5 17q0 2 -2.5 8t-4.5 8l-7 197q3 14 6 27q2 11 5 22t5 19q5 24 17 43t25 39q27 39 61 76.5t79 57.5q7 4 23 11t33.5 14.5t32 14 t19.5 9.5q2 0 8.5 2t8.5 4q5 1 12 2.5t15 3.5q9 2 18 5l154 -15q29 -10 51 -16.5t41.5 -15t38.5 -21t40 -35.5h6q0 12 -0.5 21t-0.5 16.5t-0.5 16.5t-0.5 21l-1 20q2 2 6.5 6t6.5 6h8q22 0 47.5 1.5t52 2t51.5 -0.5t47 -4q2 0 9 -0.5t15 -1.5t14.5 -1.5t8.5 -0.5 q5 -1 12.5 -3t9.5 -2q2 -2 4.5 -9t2.5 -10l2 -65q3 -81 -2.5 -160t-8.5 -160q-1 -2 -2 -7.5t-1.5 -12l-1 -13t-0.5 -9.5q-5 -37 -7 -73.5t-1 -73.5q0 -11 2.5 -24t7.5 -24.5t13.5 -19t22.5 -7.5q26 0 51 11.5t32 35.5q11 39 22 74.5t19 70.5t12.5 71.5t3.5 77.5 q0 3 -0.5 8.5t-1.5 11.5q-1 7 -1 15q0 2 -1.5 21.5t-3.5 43t-4 45.5t-3 30q-2 8 -4.5 19.5t-9.5 19.5q-1 5 -5 17t-9 25.5t-10 25.5t-6 18q-7 27 -17 46t-24 45q-37 63 -98.5 109t-130.5 66q-70 20 -140.5 25.5t-142.5 4.5l-86 -2q-51 -2 -95.5 -12t-93.5 -26 q-80 -26 -144.5 -68.5t-118.5 -109.5q-3 -3 -13 -19t-20 -34t-18 -33t-8 -17q-1 -1 -4.5 -5t-8 -9.5t-8 -9.5t-3.5 -5q-1 -2 -3 -6.5t-4.5 -10.5t-4.5 -11.5t-3 -7.5q-8 -21 -20.5 -50t-17.5 -54q-6 -28 -8 -59t-2 -62.5t0.5 -62.5t0.5 -59l1 -4q0 -6 1 -16t2.5 -20t3 -17.5 t2.5 -8.5q0 -2 2 -9.5t2 -9.5q6 -29 9 -57t13 -57q24 -72 65.5 -134t93.5 -116q1 -3 9 -12t17.5 -18.5t18.5 -19t14 -13.5q45 -45 102 -71.5t115 -45.5q48 -17 104.5 -31.5t107.5 -13.5q54 1 104.5 7.5t103.5 16.5q22 4 48 17t52 29.5t50 33.5t44 30q5 3 13 9.5t11 8.5 q8 8 22 21t21 21q2 0 14 -0.5t14 -0.5q19 0 35.5 1t32 0.5t31.5 -3t34 -8.5q13 -5 30.5 -5.5t33.5 -2.5t29 -9t18 -24q1 -35 -7 -62.5t-23 -51.5t-35 -46t-44 -45q-45 -34 -91 -57t-92 -39.5t-92 -29.5t-90 -26q-3 -1 -15.5 -3t-27.5 -4t-28.5 -4.5t-18.5 -3.5q-2 0 -6.5 -1 t-9.5 -2q-6 -1 -13 -2q-4 -2 -12.5 -4t-10.5 -2q-1 0 -8.5 0.5t-16.5 0.5t-18.5 0.5t-15.5 0.5q-35 -1 -65.5 -0.5t-67.5 0.5zM799 674q2 -11 6 -20q2 -8 5 -14.5t5 -8.5q16 -20 28.5 -31.5t26 -16.5t31 -6t43.5 -1q20 1 35.5 0t32.5 7q36 15 59 32t38 39.5t23 50.5t13 64 q1 8 2.5 23t1.5 17q0 3 -2.5 12t-4.5 12l-1 53q-1 6 -1 13t-6 13q-7 15 -16.5 24t-18 16.5t-15.5 14.5t-10 17q-5 2 -16.5 6.5t-13.5 4.5l-33 -1h-32.5t-38 -5.5t-46 -20.5t-57.5 -45q-5 -5 -14.5 -28t-17 -57.5t-11 -77t4.5 -86.5z" />
<glyph unicode="A" d="M1262 173q-8 5 -11 13t-3.5 17.5t-0.5 18.5t-1 15q0 2 -5 14.5t-7 18.5q-1 1 -4 6.5t-6 11.5t-6.5 12t-4.5 10q-2 4 -7 11.5t-11 9.5q-2 0 -13 1.5t-16 3.5h-12h-17t-17 0.5t-11 1.5q-6 0 -25.5 -1t-41.5 -1.5t-41.5 -1.5t-24.5 -1q-6 0 -29 2.5t-50 5t-50 5t-29 2.5 q-40 2 -83 -1t-81 -5q-1 0 -2 -0.5t-3 -0.5h-3q-7 0 -19.5 -1.5l-25 -3t-22.5 -3t-12 -1.5q-3 -2 -8 -2.5t-10 -2.5t-11 -3q-10 -8 -21 -22.5t-17 -26.5q-18 -39 -33.5 -76t-31.5 -79q-5 -15 -9 -31t-8.5 -31.5t-10.5 -31t-16 -30.5q-3 0 -15 -1t-15 -1q-29 -2 -59.5 -1.5 t-59.5 5.5q-23 5 -47 12.5t-47 10.5q-2 1 -8.5 1.5t-14 0.5t-14 0.5t-8.5 0.5t-10 -1t-17 -1.5t-16.5 -1t-10.5 0.5q-3 0 -10 3.5t-7 8.5v4q-1 5 0.5 18t2.5 17q14 5 21 17.5t12 24.5q13 39 26 77.5t28 76.5q15 43 36.5 82.5t39.5 82.5q0 2 2 8t4 13t4 13t3 8q1 3 6.5 15.5 t11.5 26t11 26t7 15.5q0 2 3 10t6 17t6 17t3 10q14 35 31.5 65.5t30.5 69.5q26 84 56.5 167t59.5 165q22 62 46.5 123.5t48.5 124.5q0 1 1.5 8t4 15t4.5 14.5t3 8.5q2 2 5.5 12t5.5 12q0 1 1.5 5.5l3 9t2.5 8.5t1 5q1 4 5 14t7.5 20.5t7 19.5t4.5 12q1 1 4 8t6.5 15.5 t6.5 15.5t3 10q1 3 4 10.5t6.5 15.5t6.5 15.5t5 10.5q0 2 1.5 9.5t3.5 7.5q0 3 3.5 11t7.5 17t8 17l5 10q3 5 7 17t10 12l4 1q39 -5 76.5 -8t77.5 -1q43 2 66.5 0t36.5 -4t20 -3t18 4q5 0 14 -3t18 -8t16.5 -10t9.5 -8q5 -8 16 -25.5t22.5 -36.5t21.5 -36.5t15 -26.5 q15 -27 33.5 -61.5t29.5 -64.5q2 -3 4.5 -9t2.5 -8q1 -2 4 -6.5t6 -10t5.5 -10.5t2.5 -6q24 -50 37.5 -101t34.5 -102q20 -47 44 -92.5t44 -93.5q1 -2 4.5 -11.5t8 -20.5t8.5 -21t5 -12q14 -35 33.5 -67.5t32.5 -67.5q31 -77 59 -155t56 -156.5t59 -155.5t69 -152 q1 -2 6 -10t10.5 -17.5t10 -18t6.5 -10.5q2 -4 7 -14.5t5 -12.5t-1.5 -8t-3.5 -9q-1 -2 -11.5 -5t-23.5 -5.5t-25 -4.5t-15 -2q-42 -3 -82.5 0.5t-82.5 0.5q-12 -1 -22.5 -7t-23.5 -8q-2 0 -13.5 -0.5t-16.5 -1.5q-7 0 -19 -1t-14 -1q-5 0 -14.5 1t-20 2.5t-19 5.5t-11.5 10 zM738 710q31 5 62 5t62.5 -2t62.5 -3.5t62 0.5q3 0 10.5 0.5t15.5 1t14.5 1t9.5 0.5q12 5 15 10t1 18v14q-1 1 -3.5 6.5t-4.5 11.5l-4 12t-3 8l-10.5 24.5t-16 36t-16 35t-10.5 22.5q-3 5 -10 17.5t-11 16.5q0 2 -5 5.5t-6 5.5q-2 2 -4.5 13.5t-2.5 14.5q-2 4 -7.5 16.5 t-7.5 17.5q-3 5 -9.5 18.5t-14 28.5t-14 28.5t-9.5 18.5q-2 5 -9.5 17.5t-9.5 15.5l-2 2q-1 0 -3 -2l-1 -1q-2 -2 -5.5 -8t-3.5 -8q-1 -3 -5 -14t-8 -23l-7.5 -22.5t-3.5 -12.5q-2 -2 -5.5 -9.5t-8 -16.5l-8.5 -17t-6 -10q-25 -63 -46.5 -124.5t-45.5 -123.5q0 -1 -1.5 -6.5 t-4 -12t-4 -12t-1.5 -6.5q-2 -2 -1.5 -4t0.5 -4q3 0 9.5 2.5t13.5 4t13 0.5t8 -7z" />
<glyph unicode="B" horiz-adv-x="1173" d="M60 65v4q7 14 10 24t4 27q1 11 1 20.5t-5 18.5q5 77 3 153.5t3 151.5l-5 12l8 195l-4 12q0 7 0.5 24.5t1.5 36.5t2 36t1 24q-1 6 -2 30.5t-1.5 53t-1 53t-0.5 31.5v30.5t0.5 55t0.5 68.5t0.5 72t0.5 65v48q0 2 0.5 10.5t0.5 18.5t0.5 18t0.5 10q3 66 -1.5 130t-4.5 130v8 v6t1 5q0 15 4.5 19t11 4.5t13.5 1.5t13 12q53 -1 99.5 0.5t91 2.5t89 0.5t93.5 -5.5q61 -3 128.5 -8.5t132.5 -22t121.5 -47t95.5 -82.5q13 -18 25 -43.5t21.5 -54t16 -56.5t10.5 -50v-13.5t1 -17.5t1 -16.5v-9.5t-2 -12.5t-4 -24.5t-4.5 -28t-3.5 -21q-10 -48 -37 -84.5 t-56 -73.5q-4 -6 -14.5 -18t-22 -25t-21.5 -24.5t-14 -15.5q0 -2 -1 -4q0 -6 12.5 -10t15.5 -6q32 -21 54.5 -41.5t44.5 -49.5q3 -4 7 -4.5l8 -1l8 -1t7 -4.5q0 -3 2 -12.5t2 -11.5q3 -8 10 -15t14.5 -13t13 -11t7.5 -9q0 -2 -0.5 -11t-0.5 -11q0 -9 5.5 -14t11.5 -9 t10.5 -9t4.5 -12v-4q-2 -2 -6.5 -8.5t-6.5 -8.5v-4v-2q2 -5 7.5 -17t7.5 -17q2 -9 6.5 -31.5t9 -47.5t8 -47.5t4.5 -31.5q1 -1 2 -6t2 -11t1.5 -11.5t0.5 -6.5l5 -4v-12q0 -2 -0.5 -6.5t-0.5 -6.5t-6 -13.5t-8 -14.5q0 -1 -1 -5.5t-1.5 -10.5t-1.5 -11.5t-1 -6.5 q-17 -68 -57 -120.5t-91 -97.5q-2 -1 -6.5 -4t-9 -6.5t-9 -6.5t-5.5 -4q-22 -13 -48 -19.5t-46 -23.5q-7 -2 -25 -5.5t-38 -7t-38.5 -7t-26.5 -4.5q-54 -8 -104 -10t-104 -4q-91 -4 -181.5 -6t-181.5 3q-6 -2 -10 -4.5t-7.5 -5t-8 -4t-11.5 -1.5q-8 0 -11.5 -0.5t-8.5 7.5 q-2 3 -6 12t-4 11q-2 2 -0.5 14t1.5 14q-3 3 -10.5 8.5t-12.5 5.5v2zM435 367q0 -10 -0.5 -19t2 -16.5t8 -12.5t16.5 -8q2 0 8.5 -0.5t11.5 -0.5q3 0 11 -0.5t10 -0.5q1 0 6.5 1.5t11.5 3.5t11 3.5t7 2.5q1 0 7 -0.5t13 -1t12.5 -1t6.5 0.5q33 4 67.5 21.5t63 44t47 59.5 t20.5 68q1 20 -3.5 36.5t-16.5 33.5q-24 35 -53.5 55.5t-63.5 32.5t-71.5 18t-76.5 14q-15 4 -38.5 9t-43.5 6v-6t2 -6q0 -2 1.5 -11.5t1.5 -11.5v-10t-0.5 -16.5t-1 -16.5t-0.5 -10q0 -20 6.5 -42t8.5 -44q0 -2 0.5 -16.5t1.5 -33l2 -37t1 -28.5v-13q2 -2 5.5 -11t5.5 -11 v-2q-1 -7 -4 -12t-3 -11zM411 1309q-2 -38 2 -73t10 -71q2 -22 2 -44t4 -42q1 -7 3 -9.5t4.5 -4t5 -4t5.5 -8.5q0 -2 2 -9t4 -7q4 -5 20 -13t24 -8q2 0 8.5 2t9.5 4q4 1 17.5 7.5t16.5 9.5q3 1 11 5.5t17.5 9.5t18 9.5t12.5 7.5q12 6 29.5 17t34 24.5t28.5 28.5t12 30 q1 6 0 11t-7 10q-29 36 -58 61.5t-62 42t-71 25t-84 10.5q-3 0 -10 -1.5t-9 -3.5v-17z" />
<glyph unicode="C" horiz-adv-x="1465" d="M620 22q-71 27 -121 51t-85 44.5t-56.5 38t-36 31.5t-24 25t-19.5 19q-2 0 -6.5 4.5t-4.5 6.5q-2 2 -4 6t-2 6l-12 12l-13.5 13.5t-11.5 11t-6 4.5l-22 35v1q0 1 0.5 1.5t0.5 1.5v2q-23 31 -38 67.5t-25.5 75t-19.5 77.5t-20 75q-5 17 -5 31.5t-4 31.5q-6 23 -13 46 t-9 46q0 9 -1.5 33t-3.5 51.5t-3.5 52t-2.5 35.5v25q1 40 7 72.5t17 70.5q1 2 4 12t6 22l5.5 22t3.5 12q10 35 22 60t22.5 41t17.5 24l7 8q8 24 26 50.5t42 53t52 52.5t56 49q34 34 82 56.5t91 39.5q3 1 15.5 7.5t27.5 13t27.5 12.5t15.5 8q1 0 8 2t15 5t15 5.5t9 3.5 q2 2 12 6t12 6q1 0 5.5 -0.5t10.5 -0.5h11t7 1q2 0 8.5 1t15 2.5t16.5 3t12 2.5q42 12 82 11.5t84 -0.5h24t29.5 -0.5t25.5 -0.5h13q4 0 14 -0.5t22 -1.5t23 -2.5t16 -2.5q2 0 12.5 -2t16.5 -4q2 0 11.5 -2t11.5 -4q2 0 12 -1t21.5 -1.5t22 -1.5t13.5 -1q3 -2 11.5 -4 t10.5 -2q2 -2 10.5 -7t18 -10.5t18 -11t10.5 -6.5q2 -2 11.5 -6.5t11.5 -6.5q2 0 9 -5.5t9 -5.5q0 -1 5 -1q2 0 5 1q10 -3 14.5 -18t4.5 -25v-10q-2 -4 -5 -7q-3 -4 -8 -9q-2 -2 -8.5 -11.5t-14.5 -20.5t-14.5 -20t-8.5 -11q-11 -5 -25 -28t-31 -47t-36.5 -41t-41.5 -10 q-55 14 -106 23t-107 10q-5 0 -12 -0.5t-15 -0.5q-9 -1 -18 -1q-2 0 -9 -1.5t-14.5 -3.5t-14.5 -3.5t-9 -1.5q-3 -1 -16.5 -2.5t-29 -3.5t-29 -3.5t-17.5 -2.5q-2 0 -10 -2.5t-18 -6l-20 -7t-15 -5.5q-46 -19 -82.5 -48t-68.5 -66q-3 -3 -12 -15t-19.5 -25.5t-20 -25.5 t-12.5 -15q-10 -11 -19.5 -22.5t-14.5 -28.5q-2 -5 -5.5 -19t-7 -29.5t-7.5 -29.5t-5 -20q-1 -2 -1 -4v-7q0 -11 3 -21.5t3 -23.5v-2q-2 -2 -9 -11t-7 -11v-4q-1 -47 2.5 -102t18.5 -101l16 -55l-1 -2q1 -4 4.5 -13.5t7.5 -19.5t7 -19t5 -12q13 -8 17 -21.5t12 -26.5 q25 -37 54 -70.5t63 -61t73.5 -47.5t84.5 -30q7 -2 23.5 -4.5t34 -5.5t32 -5t18.5 -2q1 0 8 -0.5t16.5 -0.5t19.5 -0.5t16 -0.5q42 -1 80.5 3.5t78.5 18.5q3 1 9 4t12.5 6t11.5 5.5t6 3.5q12 5 21 11t17.5 11t18 8.5t21.5 3.5q3 0 11 -1t10 -1q24 -22 44.5 -46t33.5 -52 q3 -4 9.5 -17.5t14 -29t14.5 -29t9 -16.5q1 -2 5.5 -8t9 -12.5t8.5 -13t5 -7.5q6 -25 4.5 -35t-11 -15.5t-25.5 -11.5t-38 -24q-2 -1 -3 -2q-2 -1 -2.5 -2t-1.5 -2q-25 -19 -52 -30.5t-56 -19t-59.5 -11.5t-61.5 -7q-6 0 -31.5 -2t-54.5 -4t-54.5 -4t-31.5 -3h-31h-33 q-3 0 -14 1t-23.5 2t-23.5 2t-14 1h-17.5h-31h-31t-17.5 1q-2 0 -11 2t-20.5 4.5t-22 5.5t-15.5 5z" />
<glyph unicode="D" horiz-adv-x="1465" d="M64 1q-2 12 -5 40t-6 59.5t-5 59.5t-2 39q0 4 -0.5 21t-0.5 36.5v36.5v22q0 2 -0.5 10t-1.5 16.5t-1.5 15.5t-0.5 9t0.5 9.5t0.5 10.5q2 40 8 79t13 77.5t12.5 77.5t7.5 78q2 24 2 51.5t-5 52.5l-13 645l10 191l13 11q6 -1 21.5 -2.5t34 -2t35 -1t23.5 -0.5q6 0 30 2 t51 4.5t50.5 5t28.5 3.5q60 5 121 2.5t118 -2.5q1 0 8.5 0.5t16 0.5t16.5 0.5t10 0.5h2q71 -4 137.5 -15.5t135.5 -31.5q35 -9 67 -29.5t61 -40.5q58 -42 108.5 -86t95.5 -98q24 -29 41 -63.5t30 -71t23 -74t19 -72.5q0 -2 1.5 -7.5t3 -11.5t3 -11t2.5 -6q1 -2 3.5 -11 t6 -19t6 -18.5t3.5 -9.5q2 -9 1.5 -21.5t0 -25.5t4 -24t13.5 -16l-7 -139q8 -3 9.5 -8t1.5 -13q-1 -1 -1 -5v-3q-1 -1 -3 -3.5t-4 -4.5q-3 -4 -6 -7q0 -1 -1 -8t-2.5 -16t-2.5 -18.5t-2 -15.5q-1 -1 -1 -3v-1q0 -8 5.5 -14t5.5 -15q0 -2 -0.5 -3t-0.5 -3v-3q0 -2 -5 -5.5 t-7 -5.5q-4 -8 -4.5 -18t-1.5 -19v-8l-29 -74l-45 -119q0 -2 -0.5 -10.5t-0.5 -11.5q-1 -2 -5 -6l-8.5 -8.5t-8 -8.5t-4.5 -5t-5 -7t-9 -14t-10 -16.5t-7 -12.5q-23 -38 -50 -71.5t-66 -61.5q-37 -26 -77 -48.5t-77 -46.5q-2 -2 -6 -4t-6 -2h-2h-2q-1 0 -7 4q-3 2 -6 3 q-2 0 -10.5 -1.5t-11.5 -3.5q-2 -1 -7 -2.5t-11 -3t-11.5 -2.5t-6.5 -2q-2 -1 -10.5 -2t-19 -1.5t-20 -1.5t-14.5 -2q-5 0 -22.5 -2t-38 -4t-38.5 -4t-22 -3q-3 0 -12 -1.5t-11 -3.5q-104 9 -190 6.5t-159.5 -7t-136 -7t-119.5 5.5q-2 -3 -6.5 -6.5t-6.5 -5.5h-2 q-7 1 -9.5 7.5t-4.5 9.5zM484 344q5 -2 9.5 -4t7.5 -7q2 0 9.5 -1.5t11.5 -1.5q29 -2 58.5 4t58.5 8t60.5 1t60.5 5q35 6 69.5 21.5t66.5 29.5q56 26 95.5 63.5t65 84t38.5 100t16 112.5q0 4 0.5 14t0.5 20.5t0.5 19.5t0.5 12q-11 46 -21.5 91t-27.5 89q0 3 -2 8t-4 5 q0 2 -4.5 6.5t-4.5 6.5q-2 2 -2.5 11t-2.5 11t-5.5 9t-5.5 9q-3 4 -12.5 14t-20 22t-19.5 22t-13 14q-19 20 -45.5 34t-49.5 22q-36 17 -67.5 28.5t-69.5 13.5l-299 15q0 -4 -0.5 -14.5t-1 -22.5t-1 -22.5t-0.5 -14.5q1 -6 2.5 -19t1.5 -15l-3 -52q0 -5 -0.5 -18t-0.5 -16 q-1 -8 -1.5 -20.5t-0.5 -14.5t1.5 -7t3.5 -11t3.5 -11.5t1.5 -6.5q0 -2 -3 -5.5t-3 -5.5q-1 -1 -1 -3v-5v-9l18 -201q-2 -14 0 -23t4 -25q1 -5 2.5 -23t3 -38t3 -38t1.5 -22q2 -2 3.5 -9t1.5 -9q0 -3 -0.5 -13t-1 -21.5t-1 -21.5t-0.5 -12t1.5 -7t3 -11t3 -11.5t2.5 -6.5 q0 -2 -1 -12t-1.5 -22t-1 -22.5t0.5 -13.5q0 -3 0.5 -11t2 -17t3 -17t2.5 -12z" />
<glyph unicode="E" horiz-adv-x="1186" d="M269 16q-2 1 -11 2.5t-19.5 4t-20.5 4t-13 2.5h-8h-8q-2 0 -6 -3t-6 -3q-8 0 -16.5 10t-12.5 12q-10 6 -24 8.5t-20 16.5q3 78 0 152.5t-1 152.5q2 54 5.5 107.5t4.5 107.5v14q0 1 -1 6.5t-1.5 11t-1.5 10.5t-1 7v10.5t0.5 18t0.5 18v10.5q0 4 -1 13t-3 19t-4 19t-3 13 q-11 223 -17 442.5t-13 442.5v10q0 7 3.5 19t9.5 23.5t12.5 20t12.5 8.5q20 0 40 -6t40 -6h21q3 0 12.5 3t11.5 3q97 14 196.5 15.5t196.5 1.5q98 0 192 -9t191 -14q7 -4 10.5 -9t6.5 -10.5t6.5 -11t10.5 -10.5q1 -8 2.5 -27.5t3 -41t2.5 -41.5t1 -27v-7.5t0.5 -14.5 t0.5 -16.5v-12.5q0 -3 -0.5 -10.5t-1 -16t-1 -16t-0.5 -10.5q-9 -15 -15.5 -25.5t-20 -17.5t-39.5 -10.5t-76 -4.5q-3 0 -12 0.5t-19.5 0.5t-20.5 0.5t-14 0.5q-6 0 -16.5 -0.5t-21 -0.5t-18.5 -0.5t-9 -0.5q-31 -1 -77 -2.5t-89 -3.5q-50 -2 -104 -4l-8 -12q-1 -2 -3.5 -19 t-5.5 -40t-6 -46.5t-5 -38.5v-11.5t-1 -14.5v-19.5t6 -17.5q2 -2 6 -4t6 -2q47 -7 97 -9t96 -2h14q3 0 16 1t27.5 1.5t27 1.5t15.5 1h4q42 0 78 -8.5t79 -14.5q9 -2 20.5 -2.5t22 -2.5t19 -7.5t12.5 -16.5q2 -7 5.5 -18l7 -22t6.5 -19.5t3 -9.5q-3 -20 0 -40l6 -40t3.5 -40 t-6.5 -40q-5 -25 -29.5 -41.5t-82.5 -22.5h-62q-6 0 -30.5 -1t-52.5 -2t-52.5 -2t-30.5 -1q-12 0 -40.5 0.5t-60 0.5t-59.5 0.5t-39 0.5q-1 -51 -6.5 -102.5t-6.5 -103.5q0 -7 -0.5 -21t-0.5 -16q1 -5 2.5 -18.5t3 -29.5t3 -30.5t1.5 -20.5l2.5 -12.5t3.5 -14.5t3.5 -12.5 t2.5 -5.5l35 -6l483 3q22 1 35.5 0.5t21.5 -3t11 -5.5t5 -7q1 -12 1 -23v-34q0 -9 -0.5 -23.5l-1 -29t-1 -26t-0.5 -14.5q0 -2 -1 -7.5t-2.5 -12t-2.5 -12t-1 -7.5v-28q-2 -15 0 -31.5t1.5 -33t-6 -31t-21.5 -25.5q-86 -8 -170.5 -19.5t-171.5 -11.5q-43 0 -83.5 4t-83.5 4 q-17 7 -34.5 3t-34 -9t-32 -6.5t-28.5 10.5h-156z" />
<glyph unicode="F" horiz-adv-x="1069" d="M92 51q0 3 4.5 7.5t7.5 4.5v23q0 69 -4 138t-2 138q-10 0 -13 8.5t-2 19t4 19.5t5 11v16q0 4 -1 17.5t-2 29t-2 29t-1 16.5v26t0.5 45t0.5 54.5v53.5t-0.5 44t-0.5 25q0 4 -1 21.5t-2 37t-2 36t-1 20.5v311v47q-2 96 3.5 189.5t2.5 189.5l12 12q23 1 44 2q18 1 37.5 2 t33.5 1h70q1 0 8.5 0.5t16.5 1.5l18 2t14 2q65 8 126.5 13t129.5 5h2q3 -1 15.5 -2t27.5 -2t27.5 -1.5t15.5 -0.5q74 -3 147.5 -5.5t147.5 -0.5q17 -13 20.5 -34.5t8.5 -41.5q1 -5 2.5 -16t3 -23t3 -22t1.5 -13q1 -2 1 -8v-12.5t-0.5 -13t-0.5 -7.5l6 -10v-4 q-7 -26 -16.5 -43.5t-19 -29t-17 -17.5t-10.5 -10l-103 -23q-29 -2 -58.5 -6t-58.5 -6h-106h-105q-3 0 -10 0.5t-14.5 1.5t-14 2t-8.5 2q-1 -4 -2 -13.5t-2 -21t-1.5 -21.5t-0.5 -14q0 -2 1.5 -7.5t3.5 -12t4 -12t3 -7.5v-6q0 -5 -0.5 -7.5t-5.5 -4.5v-96q0 -5 4 -11t9 -8 h96q71 0 140 6.5t140 6.5h18.5t23.5 -1.5t22 -5.5t14 -12q0 -2 4.5 -14t6.5 -14l6 -46v-213q-2 1 -3 2q-3 1 -3 0q-1 -19 -11.5 -31.5t-25 -19.5t-30.5 -10.5t-28 -4t-17 0t3 0.5q-23 0 -45 -3t-45 -3h-8q-2 0 -10.5 1t-18.5 2t-18.5 2t-10.5 1t-11.5 -1t-20 -2t-20 -2 t-11.5 -1h-144l-6 -10v-99l6 -53v-90q0 -3 2.5 -9t4.5 -9v-3v-4q-2 -2 -4.5 -5t-2.5 -5v-96v-94q0 -6 1 -19.5l2 -27t2 -25t2 -14.5q-9 -20 -10.5 -41t-7 -40.5t-19.5 -36t-49 -26.5h-78h-78q-5 -8 -8.5 -10t-9.5 -2h-7q-3 2 -7 5q-8 6 -9 7q-2 0 -8.5 -0.5t-14 -0.5h-14.5 t-8 1q-5 0 -18 3.5t-26.5 8.5t-23.5 12t-8 15z" />
<glyph unicode="G" horiz-adv-x="1664" d="M54 903v98q0 2 1 7.5t2 12t2 12t1 7.5q6 41 17.5 79.5t25.5 76t30 75t30 75.5q1 1 3.5 7t5.5 13t5.5 12.5t3.5 7.5q14 33 36.5 60t43.5 55q7 7 24.5 23.5t36.5 34.5t36 34.5t24 22.5q5 4 18 14.5t28 21.5t28 21t18 13q28 18 52.5 29t48.5 19.5t49.5 14.5t57.5 13q3 0 9 3 q4 1 7 3q42 12 81 12h81h98q6 -2 17 -1.5t23.5 1t23 0.5t15.5 -2q9 0 30 -3t44 -7t43.5 -7.5t28.5 -4.5q3 0 12 -1.5t19 -3.5t19.5 -3.5t13.5 -2.5q2 -2 10.5 -6t11.5 -6q4 -3 14.5 -7.5l21 -9t19 -8.5t10.5 -6q13 -9 18 -28t5 -39v-7q0 -3 -5 -12.5t-7 -11.5 q-12 -30 -19 -55.5t-13.5 -50.5t-15 -50.5t-23.5 -55.5q-2 -3 -6.5 -9.5t-6.5 -6.5q0 -2 -5.5 -2h-8.5h-7t-7 2q-3 0 -15.5 0.5t-12.5 3.5q-62 20 -116 27.5t-117 7.5h-78q-12 -9 -30 -11t-33 -5q-6 -2 -17.5 -5.5t-24.5 -7t-23.5 -7.5t-14.5 -5q-42 -14 -78.5 -46t-67 -72 t-54.5 -83t-42 -79v-4v-3l-23 -51q-1 -2 -4 -11t-6.5 -20t-7.5 -21.5t-6 -16.5q0 -3 -2 -14.5t-2 -14.5v-6v-6q0 -9 0.5 -30t1.5 -45t1.5 -45t0.5 -30q5 -20 13 -46.5t16 -45.5q4 -7 9 -13.5t9.5 -13t6.5 -14t-1 -16.5q1 -4 6 -14t10.5 -21.5t11 -21t7.5 -13.5q0 -1 3 -5 t7 -9t7.5 -9.5t4.5 -5.5q1 -3 3 -7q2 -7 4 -9q0 -2 4 -8t6 -8q17 -23 33 -41t33.5 -33t37.5 -26.5t45 -20.5q3 -2 15 -6.5t14 -6.5q3 -2 9.5 -4t8.5 -2h17q2 0 10 -2.5t16.5 -5.5t15.5 -5.5t9 -2.5q5 -2 20 -4t21 -2h35q1 0 7.5 -1l13 -2t12.5 -2t8 -1h2q20 0 51 6.5 t64 17.5t62 24t44 27q11 9 24.5 23.5t25.5 31t21 34t11 32.5q0 1 1 6t2 10.5t2 10.5t2 6q0 11 1.5 23t1.5 24q0 8 -1 13.5t-9 5.5q-1 0 -2 -0.5t-2 -0.5q-1 -1 -2 -1q-2 0 -6 -2.5t-6 -2.5q-1 -1 -5.5 -1h-9.5t-9 0.5t-5 0.5q-5 -1 -23.5 -3.5t-40 -5.5t-40.5 -5.5t-23 -3.5 h-19q-27 0 -51.5 1.5t-56.5 4.5q-10 3 -16 12q-2 3 -5 12t-5.5 19t-4.5 19t-2 12q0 2 -1 14t-1 19q0 8 1 21.5t1 15.5t2 9t2 9q10 40 10.5 82t8.5 84q2 2 8 4t8 2q58 5 122.5 8.5t131 6t131 5.5t122.5 8q3 0 16.5 2t18.5 4q24 -6 40.5 -21.5t28 -42.5t19.5 -67t16 -95 q1 -2 1 -12t-0.5 -22t-1 -21.5t-0.5 -10.5v-14q1 -83 -18.5 -162t-48 -146.5t-61.5 -118.5t-58 -77q-42 -44 -85.5 -72t-94.5 -44t-113.5 -22t-141.5 -4h-108.5t-100.5 4.5t-98 16.5t-102 35q-2 1 -12 5.5t-22 10.5t-22.5 11t-13.5 6q-1 1 -5.5 2t-10.5 2t-11.5 1.5 t-6.5 0.5q-2 2 -8.5 9t-8.5 9q-2 1 -11.5 8t-20 14.5t-20 14t-11.5 8.5q-22 17 -38.5 35.5t-35.5 40.5q-4 4 -20 19.5t-35 33.5t-35.5 34t-20.5 21q-21 25 -31 48t-26 51q-2 2 -8 13.5t-8 14.5q-29 56 -48 107t-34 113q-6 23 -7.5 48t-9.5 48v98z" />
<glyph unicode="H" horiz-adv-x="1434" d="M969 169q0 2 0.5 8.5t0.5 14t0.5 14t0.5 8.5q0 5 -0.5 12t-0.5 15q-1 9 -1 18q0 3 -2.5 18.5t-3.5 22.5q0 2 -2 11t-2 11v2v4q0 5 0.5 22t1.5 36.5t1.5 36t0.5 20.5v21v20q0 9 -0.5 25.5t-1.5 33.5t-1.5 31.5t-0.5 18.5q-1 5 -1.5 19.5t-2 30t-4.5 28.5t-9 16 q-2 0 -9.5 0.5t-15.5 1.5t-16 1.5t-11 0.5q-11 1 -41.5 2.5t-64 2.5t-64 2t-41.5 0q-35 8 -61 9t-48 -1.5t-42.5 -6t-44.5 -3.5h-8.5t-7.5 -2l-4 -11q0 -11 2.5 -39t6 -60t6 -60.5t2.5 -39.5v-98q1 -4 2 -14t2 -20.5t1.5 -20t0.5 -13.5l6 -184v-47q0 -6 -0.5 -16t-1.5 -19.5 t-2 -16t-2 -6.5l-6 -6q-45 2 -93.5 1t-95.5 -7q-35 -3 -67.5 -9.5t-67.5 -6.5h-43q-3 2 -8 9t-10 15.5t-8.5 16t-3.5 10.5q0 10 7 14t7 15q0 1 -0.5 3t-0.5 4q-1 3 -1 5q0 1 -1 3.5t-2 5.5q-2 4 -3 7q0 3 2 7t4 6l-2 143v29l-27 311q-8 17 -6 31t0 32q-3 106 -4 214t-1 213 q0 137 4.5 269t6.5 271q2 0 3 2t3 4q2 1 4.5 2.5t5.5 3.5q4 2 7 4h4h2q59 -9 117 -9.5t118 -0.5q19 0 36 3t36 3q8 0 18.5 -3t21 -7.5t19.5 -11t15 -13.5q-1 -9 -1.5 -31.5t-0.5 -47t0.5 -46.5t1.5 -30q0 -3 0.5 -13.5t1.5 -22.5t1.5 -22t0.5 -12v-6q0 -5 0.5 -6.5 t-4.5 -3.5v-178l4 -47v-15q0 -17 0.5 -38t11.5 -34q6 0 21 -0.5t31.5 -1.5t31.5 -2t21 -2q3 0 11 -0.5t17.5 -1.5t17.5 -2t11 -2q2 0 14 -2t15 -4h2h4q3 1 17 2t30.5 2t31 1.5t17.5 0.5h6h6q2 0 11.5 -3t11.5 -3q1 0 12 -0.5t25.5 -1t30 -1t24.5 -1.5h4q9 0 11.5 3t2.5 11 q0 104 -9 204.5t-9 203.5q0 19 -0.5 40.5t0 43.5t3 44t9.5 42l6 6q4 2 8 5q3 2 5.5 3.5t3.5 1.5q4 3 4.5 6.5t0.5 7.5t1 6.5t6 4.5q31 -2 60.5 1t60.5 3q62 0 123 -3t123 -1l6 -6q2 -3 4 -14.5t2 -14.5q-1 -11 -2.5 -37.5t-3 -55.5t-3.5 -55t-3 -36q0 -2 -2 -14.5t-2 -14.5 q-1 -3 -1 -7q-1 -4 -1 -11q0 -2 1 -8.5t1 -8.5v-51v-76v-51v-115q5 -6 5.5 -11t0.5 -11q0 -10 -0.5 -16t-5.5 -15q0 -2 -0.5 -9.5t-0.5 -16t-0.5 -16.5t-0.5 -11q0 -6 0.5 -15t0.5 -17.5t0.5 -15t0.5 -7.5q0 -5 0.5 -17.5t1.5 -26t1.5 -26t0.5 -17.5q8 -4 10 -8.5t0.5 -10 t-3.5 -12.5t-1 -16v-79q0 -10 6 -13t6 -12v-10l-6 -11v-26q-2 -5 0.5 -17.5t5 -28t2 -30.5t-7.5 -25v-22l-6 -184v-7q0 -2 1 -11.5t2 -20t2 -20t1 -11.5v-6v-6q-2 -2 -5.5 -6.5t-6.5 -4.5v-69l6 -51q0 -17 1.5 -29t4.5 -29q5 -8 6 -17.5t-2 -17t-8.5 -12t-13.5 -1.5 q-15 -4 -28.5 -6.5t-41 -5.5t-76 -7t-132.5 -11h-16q-2 0 -8 1.5t-13 4.5t-13.5 6.5t-9.5 8.5q-2 2 -4.5 8t-2.5 8v99z" />
<glyph unicode="I" horiz-adv-x="593" d="M340 23q-3 0 -14 -1.5t-23.5 -4t-23.5 -4t-13 -1.5h-6q-18 0 -36.5 2t-35.5 2t-26.5 -0.5t-28.5 -3.5q-2 -2 -9 -4t-9 -2h-2q-14 0 -21 10q-1 4 -3 14t-5 21.5t-5 21t-3 13.5v2v4q1 27 2 68.5t2 81t1.5 68t0.5 30.5q0 3 0.5 11t1.5 17.5t1.5 17.5t0.5 11v420 q-7 54 -9 107.5t-2 107.5t1 108t0 109q0 5 -1 23.5t-2 39.5t-2 39t-1 23v39v37q2 57 2 106t-3 106q3 9 10 10.5t15 1.5q2 0 4 -0.5t5 -0.5q3 -1 7 -1t22 -0.5t38.5 -1t38.5 -1t22 -0.5h35q13 -2 29.5 -0.5t33.5 3.5t33.5 4t30.5 2q11 0 22.5 3t22.5 3h2q2 -2 11.5 -9 t12.5 -9l11 -5q3 -3 7.5 -14.5t4.5 -13.5q0 -5 2 -20.5t4 -20.5q0 -5 -2.5 -20.5t-5.5 -33t-5.5 -33.5t-2.5 -20q5 -6 8.5 -18t3.5 -17q0 -2 -5 -11.5t-7 -11.5v-20v-21q1 -3 3 -14t4 -23.5t3.5 -23.5t1.5 -14v-109q4 -50 8 -113t7 -133t5 -143.5t3.5 -143.5t2.5 -133.5 t1 -114t-1 -84t-3 -44.5q-2 -23 -2 -45.5v-46.5q-2 -8 -2 -22t0.5 -28.5t1.5 -25.5t2 -12q-14 -41 -42 -59.5t-56 -24.5t-48.5 -4.5t-19.5 0.5z" />
<glyph unicode="J" horiz-adv-x="1050" d="M52 276q-2 0 -4 7t-2 10v6q0 8 5 11t11 5q6 7 21.5 23t33.5 33.5t34 33t22 21.5q1 1 5 4.5t9.5 8.5t11 9.5t8.5 6.5t12.5 9t20.5 15t20.5 15.5t14.5 11.5q9 6 18.5 12t20.5 6q15 0 18 -12t7 -23q1 -4 5 -10.5t8.5 -13t8.5 -11.5t6 -5l25 -31v-4l28 -29q1 -1 5.5 -4 t10 -6.5t10.5 -7t7 -5.5q3 -2 10 -4t9 -2h41q2 0 11 -5t11 -5h2q30 4 43 20.5t17.5 38t4.5 45t5 42.5q0 1 0.5 14t1.5 29t1.5 31t0.5 20q0 40 -4 79.5t-4 77.5v17q0 7 1.5 28.5t2.5 50.5t2.5 61.5t3 61.5t2 50t0.5 28v11q0 75 -5 147.5t-11 147.5v18q0 10 -1 31.5t-1.5 48.5 t-1.5 57t-1.5 57.5t-1 49t-0.5 32.5q-3 14 -4.5 26t-1.5 26v10q2 3 11 5.5t12 0.5q15 1 53 5t80 7.5t79 7t52 5.5h18q36 0 64 -25q2 0 4 -4t2 -6v-49q0 -35 -3 -70t-3 -70v-2q0 -2 1 -6.5t2 -10.5t2 -11t1 -6v-93l4 -41q-1 -12 -2 -23q-1 -9 -1.5 -18.5t-0.5 -15.5v-2v-2 q0 -3 0.5 -10t1.5 -14.5t1.5 -14t0.5 -8.5q10 -2 11 -13t-1.5 -24t-4.5 -25t1 -18v-47v-51l7 -52v-4v-8q-6 -17 -6.5 -58t1 -90t3.5 -96.5t2 -76.5v-105l-7 -10l-6 -198v-36q0 -3 -1.5 -10.5t-3.5 -16t-4.5 -17t-3.5 -12.5q-1 -2 -5.5 -12t-10 -21.5t-10.5 -22t-6 -13.5 q-16 -36 -48.5 -65t-72.5 -52t-82 -40t-76 -29q-34 -11 -69 -9.5t-70 1.5h-36q-32 0 -66 5.5t-67 15.5t-63 25t-52 34q-17 15 -29 35z" />
<glyph unicode="K" horiz-adv-x="1421" d="M98 31q0 2 2 9t2 9q0 5 1 10q0 4 0.5 8.5t0.5 6.5q0 68 -6 141t-6 141q0 39 3 78.5t3 77.5q3 5 0.5 16t-5 23.5t-3 24.5t7.5 18q0 40 -2 79.5t-10 80.5q-3 106 -10.5 223.5t-5.5 247.5q-1 6 -1 29.5v51t0.5 51t0.5 29.5v27q5 35 2.5 73.5t-3.5 75t5.5 68t29.5 52.5 q21 5 45 7.5t44 2.5q1 0 8 -0.5t15.5 -1.5t16.5 -1.5t13 -0.5q2 -1 13.5 -1.5t25 -0.5h25h14.5q1 0 15.5 -1t34 -2l39 -2t31.5 -2q4 1 8 1q8 0 9 -1q3 0 7.5 -4t4.5 -6v-209l-6 -10v-207l-7 -103v-7q4 3 14 17.5t21.5 31t21.5 31t13 18.5q16 18 27 39.5t25 40.5 q36 48 67.5 91.5t62.5 85.5t64 83.5t72 85.5q12 12 22.5 21.5t15.5 20.5q3 7 15.5 5.5t20.5 -2.5q1 1 10 0.5t19 -0.5t19 -0.5t11 0.5l174 6q3 -1 13 -1.5t22 -1.5t22.5 -1.5t14.5 -1.5q1 0 7 -0.5t12.5 -1.5t12 -1.5t7.5 -0.5q11 -5 19.5 -11.5t3.5 -15.5q-6 -12 -9.5 -20 t-7.5 -15.5t-9 -16t-14 -21.5q-38 -38 -64.5 -68t-49.5 -56t-44.5 -51t-48.5 -53q-21 -26 -41 -56.5t-45 -53.5l-196 -252q-1 -1 -11 -14t-22 -29t-21.5 -29.5t-9.5 -14.5q19 -15 34.5 -35.5t29.5 -43t29.5 -44.5t35.5 -40q3 -3 11.5 -12.5t10.5 -12.5q1 0 7 -2l6 -2l6 -6 q11 -2 20 -9.5t16.5 -17.5t14.5 -21t15 -20q11 -12 18 -27.5t17 -29.5q2 0 4 -2t2 -4q17 -2 21.5 -10.5t0.5 -24.5l2 -4q2 -4 4 -6q2 -3 6.5 -10t6.5 -9q1 -2 6 -6.5t10.5 -9.5t10.5 -10t8 -6q-4 -8 -1.5 -13.5t5.5 -11.5q2 -3 6 -8.5t7.5 -11t6.5 -10t4 -5.5q6 -3 11 -5 q8 -5 12 -5q3 -3 7 -15t9 -20q16 -20 27.5 -33t30.5 -30q8 -10 28 -35.5t42 -54t41.5 -53.5t27.5 -35q15 -20 30 -46.5t15 -52.5q0 -6 -1 -15.5t-9 -12.5h-13q-38 -8 -76.5 -8t-78.5 -3q-2 -1 -10.5 -2t-18.5 -2t-18.5 -1.5t-10.5 -0.5h-84q-11 3 -21 0.5t-27 5.5 q-11 5 -27.5 17.5t-30.5 27.5q-17 23 -37 44t-37 42q-3 4 -8 10.5t-10 11.5q-5 6 -11 13l-75 92q-1 2 -4 7.5t-7 11t-7.5 10t-4.5 6.5q-5 6 -16 7.5t-13 9.5q0 2 1 11.5t-1 12.5q-6 8 -11 16q-5 6 -9.5 12.5t-7.5 10.5q0 2 -2 4t-4 2q-2 2 -9.5 6t-7.5 6q-2 0 -4 7.5t-2 9.5 q-2 2 -8 9t-12.5 14.5t-13 14.5t-7.5 9q-14 10 -32 34.5t-38 54t-41 58.5t-41 49q0 -34 4 -72.5t8 -78.5t5.5 -78.5t-2.5 -71.5l-8 -331q-1 -7 -5.5 -11t-26.5 -6.5t-68 -5.5t-128 -8q-6 4 -27.5 4t-45 1t-42 6t-18.5 20z" />
<glyph unicode="L" horiz-adv-x="948" d="M619 15q-5 2 -18.5 3.5t-16.5 1.5q-7 0 -23.5 -1t-35 -2t-34.5 -1.5t-22 -0.5q-2 0 -6 1.5t-6 1.5q-2 1 -11 1.5t-20.5 1.5t-22 1h-16.5h-6t-11 -0.5t-11.5 -0.5h-6.5q-8 0 -38.5 0.5t-66.5 1t-67 1t-39 0.5q-8 -1 -25.5 -0.5t-25.5 -0.5q-6 3 -10 14t-6 14v3v4q0 2 2 5 t4 5v49q0 46 -2.5 91t-2.5 91q0 42 1 82t3 82v19v33t0.5 33.5t0.5 19.5q0 7 0.5 35.5t1.5 61.5t1.5 61.5t0.5 35.5v21t0.5 45t1 60t1 65.5t0.5 62v49.5v34.5v53.5t-0.5 62.5t-0.5 62.5v53.5v34.5q0 6 -0.5 19t-1.5 27.5t-1.5 27.5t-0.5 19v40l-6 11v6q0 6 0.5 9.5t5.5 8.5 l7 108q2 10 7 17.5t18 12.5t35 7.5t57 2.5q9 0 34 0.5t53.5 1t54.5 1t38 0.5q22 -2 39.5 -2.5t30.5 -17.5q1 -4 4 -13.5t5.5 -20.5t5 -21t2.5 -14v-28q0 -3 2 -14.5t2 -14.5v-229q9 -8 10.5 -13t1.5 -14q0 -6 -1 -10t-6 -10v-31q0 -20 3 -38t3 -38q0 -22 -3 -43t-3 -43 l-6 -66q1 -5 1 -16.5v-24t-0.5 -24.5t-1.5 -16q0 -2 -0.5 -8.5t-1.5 -14.5t-1.5 -14.5t-0.5 -8.5v-2v-4q7 -6 7 -25t-2.5 -40.5t-6 -39.5t-4.5 -21v-59l-1 -109l6 -11q-1 -3 -1.5 -12t-0.5 -19t0.5 -19t1.5 -13q0 -2 0.5 -13t1.5 -23.5t1.5 -23.5t0.5 -14q0 -1 -1 -5t-3 -9 q-2 -6 -3 -13q2 -3 9 -5t10 0q11 0 41 -0.5t64 -0.5h64.5t42.5 1q40 0 85 -5t85 -1q19 -11 22.5 -20t3.5 -28q1 -6 1.5 -20.5t1.5 -31t1.5 -31.5t0.5 -20q2 -2 4 -6t2 -6v-2v-4q0 -2 -2 -8.5t-4 -8.5v-178l-6 -6q-4 -1 -7 -1h-9q-7 0 -17 -0.5t-12 -0.5t-10.5 0.5t-18 1.5 t-18 1h-10.5q-10 0 -35 -1t-52.5 -2.5t-51.5 -2.5t-33 -1z" />
<glyph unicode="M" horiz-adv-x="2049" d="M64 12q1 40 6 80t14 82q8 32 13.5 66t9.5 69l18 69q-1 6 0.5 22t4 34t4.5 34t2 22q0 5 2.5 20.5t5 36t6 43.5t6.5 44t5.5 36.5t3.5 20.5q0 2 0.5 11.5t1 20t1 20t1.5 11.5q0 3 2 15t2 14t1 6.5t1 6.5q-9 5 -6 19t9 29.5t10.5 29t-2.5 18.5v25l12 45q11 25 11 54 q0 10 -4 17.5t-4 16.5v4q2 2 7 5.5t5 5.5q12 26 13 55.5t3 55.5q0 2 3.5 5.5t3.5 5.5q1 2 1.5 11.5t1.5 20.5t1.5 20.5t0.5 11.5t3 11t3 11v4q-5 1 -7 8.5t-1 16t4.5 15.5t9.5 9q0 2 2.5 11t4.5 13q3 20 6 42t2 44q-3 3 -3.5 10.5t0.5 15.5t3.5 15.5t5.5 9.5l14 133q2 3 5 7 q2 3 5 6l5 5q5 5 12 5q40 13 81 22.5t86 10.5h15h29.5t46 -0.5t46 -1.5t29.5 -1q6 -5 8 -11.5t4 -11.5t9 -18t10 -17l4 -6q3 -7 4.5 -24t4.5 -34.5t8.5 -30.5t16.5 -12q-2 -20 0 -41t7 -41q1 -2 3 -4l2 -4t2 -3q0 -2 5 -8.5t5 -8.5q1 -2 2 -8.5t2 -14t1.5 -14.5t0.5 -8 q2 -2 4 -6t2 -6q2 0 6 -6t6 -8q1 -2 1.5 -7t1.5 -10t1.5 -9t1.5 -5q0 -2 1.5 -6t3.5 -8.5t3.5 -8.5t1.5 -5q7 -17 10 -38t15 -32q2 -2 7 -3t5 -3q5 -6 6.5 -19.5t-0.5 -21.5q1 -4 5 -14.5t8.5 -22.5t8.5 -22.5t6 -14.5q0 -2 2 -6t4 -5q2 -2 5 -4l3.5 -3.5t1.5 -2.5 q2 -3 4 -15t2 -14t5 -10.5t8 -13.5q32 -56 60 -110.5t55 -111.5q16 -28 27 -61t26 -59l6 8l27 107q-5 14 1 19t12 17q5 12 8 22t4.5 19.5t3.5 20t6 24.5q1 3 4.5 13t7.5 22l7.5 22.5l4.5 13.5q1 4 5 22.5t8 40t8 40t6 24.5q1 2 4.5 12t7.5 22t7.5 22t3.5 12t1 4.5t1 4.5 q-4 3 -4.5 9.5t1 13.5t5 13t7.5 8l28 87q-2 2 -2 10.5t2 11.5q0 2 5 8.5t7 8.5q12 20 17 43.5t13 43.5q12 38 28 75t33 75q2 4 4.5 12t5.5 17t6 17t5 13q3 8 4 12.5t2.5 8t4.5 7t11 9.5q3 0 12 0.5t19 1.5t18.5 1h10.5q37 1 72.5 3t72.5 4h7h10.5t18.5 -1t18.5 -1.5 t10.5 -0.5q1 0 7.5 -1t14.5 -2.5t15 -2.5t9 -2q9 -1 20 -17t20.5 -38.5t16.5 -47t8 -42.5l2 -2q2 -2 5 -2l13 -46v-5v-8q1 -4 2.5 -11t4 -14.5t4 -13t2.5 -6.5q0 -2 7 -8t9 -8v-8q0 -8 -3.5 -13.5t-3.5 -13.5v-6q5 -25 10.5 -46.5t8.5 -44.5q0 -2 -0.5 -14.5t1.5 -14.5 q1 -6 2.5 -16t3.5 -19q2 -11 5 -23l18 -63q0 -4 0.5 -10.5t2 -13.5t5 -13.5t9.5 -9.5q-1 -18 2 -36.5t8 -37.5t9.5 -37.5t6.5 -35.5q2 -2 1 -11.5t-2 -12.5q1 -3 4.5 -26t8 -50t8 -50t3.5 -26q11 -44 16 -68t8 -45.5t6 -48t10 -74.5q0 -3 2 -13t3.5 -21.5t3.5 -21.5t2 -13 q0 -2 2.5 -5.5t2.5 -5.5q0 -3 -0.5 -10.5t-0.5 -15.5v-15.5v-9.5q0 -4 2.5 -26t5.5 -48t5.5 -48.5t2.5 -27.5t0.5 -28t1 -49.5t0.5 -49v-27.5q2 -16 3 -40t0 -42q0 -6 -1 -9.5t-9 -2.5l-191 -8q-24 -8 -46.5 -4.5t-46.5 4.5q-2 0 -9 2t-15.5 5t-15.5 5.5t-9 3.5 q-17 17 -20.5 37.5t-5.5 49.5l-8 50v2v4q-4 29 -5 65.5t-1.5 74t-2 73.5t-5.5 65q0 3 -1 12.5t-2 20t-2.5 19t-2.5 10.5q0 2 -3.5 11t-5.5 11q0 2 0.5 14.5t0.5 16.5q-2 13 -5.5 43.5t-7.5 64.5t-8 64.5t-5 42.5q-3 21 -6 49t-6.5 56.5t-7 54t-7.5 42.5q-2 8 -4 17.5 t-7 15.5q-2 0 -4 -2q-1 -1 -2 -1q-1 -2 -4 -13.5t-6.5 -25.5t-6.5 -26.5t-4 -15.5q-1 -2 -4.5 -12t-8 -22t-8.5 -22.5t-5 -13.5q0 -1 -1.5 -5t-3.5 -9t-3.5 -9.5t-1.5 -5.5q-17 -33 -20 -54t-5 -32q-13 -85 -41 -164t-52 -160q-3 -9 -7.5 -25.5t-8.5 -33t-7 -29.5t-3 -16 l-12 -58q0 -2 -4 -14t-6 -15q-9 -42 -25 -82.5t-36 -77.5q-2 -2 -6.5 -7t-6.5 -7h-23.5h-37h-36.5h-23q-11 0 -29.5 -0.5t-36.5 -1t-32 -1t-15 -0.5q-2 0 -8.5 0.5t-15 1.5t-16 2t-11.5 2q-3 -1 -12 1t-11 4l-2 4q-2 4 -4 6q-3 7 -15 34t-26 58t-25.5 57.5t-14.5 33.5 q0 2 -3 6t-3 6q-1 2 -4 10.5t-7 18t-7.5 18t-4.5 10.5l-24 44q0 17 -5 33t-12.5 32t-15 31t-13.5 30q-2 2 -3 11.5t-3 11.5q0 3 -2 9.5t-4 8.5q-1 3 -6.5 15.5t-11.5 27t-11 27t-6 15.5q-3 8 -9.5 27.5t-14 41.5t-14 41t-8.5 26q-16 25 -26.5 52.5t-19 55t-18 54.5t-23.5 51 q-11 -32 -13 -67t0 -65q0 -2 -2.5 -6.5t-2.5 -6.5q-1 -2 -2 -8.5t-2 -14t-1.5 -14t-0.5 -8.5v-9.5t0.5 -16.5t1 -17t0.5 -10q-2 -1 -5.5 -7.5t-6.5 -8.5q-4 -45 -10.5 -87t-12.5 -86q-3 -24 -7 -57.5t-8.5 -70.5t-8.5 -74t-7.5 -67.5t-5.5 -50t-2 -21.5v-12l-11 -56 q-8 -14 -5.5 -33t3.5 -33q-2 -7 -16.5 -14t-35.5 -13t-45.5 -10t-47 -6.5t-40 -3.5t-23.5 1q-7 0 -18 -0.5t-22.5 -1t-19.5 -0.5h-9h-22.5t-25 1t-24 4t-20.5 10q-2 1 -4.5 5.5t-2.5 6.5z" />
<glyph unicode="N" horiz-adv-x="1572" d="M102 -7q1 54 -2.5 106t-5.5 106q-4 35 -2.5 70.5t0.5 73.5q0 8 -0.5 30t-1.5 52t-2 64.5t-2.5 67t-2.5 59.5t-2 43q0 2 -0.5 10t-1 16.5t-1 16.5t-0.5 10q-1 5 0 24.5t2 41.5t2 41t1 24q0 19 0.5 58.5t0.5 89.5t0.5 105t0.5 105t-0.5 89.5t-0.5 58.5q-6 5 -7 11t0 16v4 q2 3 2.5 8.5t0.5 7.5q8 10 8 23v22q1 30 -0.5 56t-3 51t-3 51t-0.5 56q-2 11 14 15t41.5 4.5t56.5 -2t60 -5.5q40 -1 78.5 2t78.5 3q2 0 6 0.5t7 0.5h8l20 -26q1 -1 10 -15t20.5 -33t23 -39t18.5 -33q1 -1 3 -5.5t4.5 -10.5t5 -10.5t3.5 -5.5q7 -17 18.5 -30.5t18.5 -29.5 q1 -3 3 -7q4 -8 4 -9q0 -2 1.5 -6.5t3.5 -6.5q0 -2 7 -11.5t9 -11.5q1 -2 7 -13t13.5 -23.5t14 -24t8.5 -13.5q1 -2 4 -7t6.5 -10.5t7 -10t5.5 -6.5q16 -26 27 -56t31 -55q2 -3 8 -8.5t8 -7.5q2 1 6 1h6q1 -2 2 -3q1 -2 2 -2.5t2 -1.5q2 -3 5.5 -16t3.5 -18q4 -4 12 -13 t16.5 -19t16 -19.5t10.5 -13.5q18 -21 31.5 -43.5t26.5 -46l26 -47t30 -44.5q3 -5 11.5 -14.5t10.5 -11.5q2 0 6 1t6 -1q6 -1 9 -5.5t4.5 -10.5l3 -12t4.5 -10q3 -3 11.5 -12.5t11.5 -12.5l8 -4q3 -2 5 -3.5t3 -2.5l54 -75q1 -2 4.5 -7t8 -10.5t8.5 -10.5t7 -8l2 41 q3 2 4.5 24t1 56.5t-3 77.5t-6.5 86t-9.5 82t-12.5 66q0 1 -0.5 7.5l-1 13t-1 12.5t-0.5 8v18t1 30.5t2 31t1 18.5q1 91 -2 181t1 183q0 8 1.5 21t3.5 25q3 14 6 30l35 5l277 -8q13 0 22 -12.5t14 -29t7.5 -33.5t2.5 -25q0 -3 2 -16.5t4 -18.5l14 -377l4 -13 q0 -5 -0.5 -16.5t-1.5 -25t-1.5 -26t-0.5 -18.5q0 -7 1 -34.5t2 -59.5t1.5 -59.5t0.5 -34.5q0 -14 -1 -48.5t-2.5 -73t-3 -73t-2.5 -47.5q5 -6 5.5 -10t-1.5 -10q0 -10 -3 -18t-3 -19q-2 -28 5 -51t9 -51q0 -2 -0.5 -13.5t-0.5 -14.5t0.5 -8.5t1 -12t1 -12.5t0.5 -8l-4 -58 v-14q-1 -2 -1 -7t-1 -7l6 -68l-6 -166q-1 -5 0 -14.5l2 -19t-1 -16.5t-9 -7h-2q-2 0 -11 2.5t-11 4.5q-2 0 -11.5 -1.5t-22 -3t-25 -2.5t-19.5 0h-2q-1 -1 -3 -1h-1q-12 -1 -29 -2t-33.5 -2.5t-28.5 -2.5t-13 -1q-21 -1 -31 -3.5t-24 -5.5q-2 0 -6 2t-6 4q-31 -6 -51.5 -1.5 t-36.5 20t-31 42.5t-34 65q-1 2 -8 12t-15.5 22.5t-16.5 24t-12 17.5q-1 1 -3.5 6.5t-5.5 12t-6 12t-5 8.5q0 2 -2 4t-4 2l-130 196q-13 11 -22 27.5t-20 29.5l-28 28q-1 1 -5 7t-8.5 12t-8.5 11t-5 6q-3 3 -13 12.5t-21.5 21t-21 22t-12.5 13.5q-2 4 -12 21t-22 36.5 t-22.5 36.5t-13.5 21q-1 1 -4.5 7t-8 13t-9 12.5t-5.5 7.5q-2 2 -5.5 8.5t-8 14t-8.5 14.5t-5 9t-4.5 9.5t-8 16.5t-8.5 16.5t-5 10.5q-14 23 -27 46t-27 47q-5 6 -5.5 5t-6.5 -1l-2 -45l4 -62q-2 -18 -1 -34t3 -37l5 -52l-4 -98q8 -13 5.5 -28t-0.5 -29q0 -3 0.5 -11.5 t0.5 -18t0.5 -18t0.5 -11.5l-3 -57l12 -184q0 -3 2 -11.5t2 -11.5q0 -4 -0.5 -18.5t-1 -31t-1.5 -30.5t-1 -18v-27v-40t0.5 -39t0.5 -25q5 -9 11 -21t4 -23q0 -9 -6.5 -14t-14.5 -7.5t-17 -3t-13 -0.5q-6 -1 -22 -2t-34 -2t-33.5 -1.5t-21.5 -0.5h-7.5h-15.5h-18h-14 q-44 0 -87.5 2t-86.5 10z" />
<glyph unicode="O" horiz-adv-x="1771" d="M225 335q-8 -2 -12.5 -0.5t-9.5 8.5q-6 11 -5 22.5t-5 23.5q-8 18 -14.5 31.5t-12.5 26t-12 26t-13 30.5q-2 2 -6.5 11.5t-4.5 11.5v16q-1 4 -4.5 13.5t-7.5 21t-7.5 21.5t-4.5 14q-3 8 -7 12t-4 9v4q0 1 1 3q0 2 3 8.5t3 7.5t-1 5t-2 8.5t-2 8.5t-1 5q-1 6 -2.5 16.5 t-3 22t-3 20t-2.5 10.5q0 3 0.5 14.5t1.5 24t1.5 23.5t0.5 14q-1 3 -2.5 14.5t-3.5 25.5t-3.5 26t-1.5 15v36v38q1 6 2.5 21.5t3.5 32t3.5 31.5t3.5 21q0 1 1 6t2.5 11t3 11.5t2.5 8.5q13 37 27 68t30 60t35 56.5t42 57.5q3 3 14 17t23.5 30.5t24 30.5t14.5 18 q21 24 45.5 40.5t50.5 34.5q50 33 101.5 62t107.5 52l13.5 4.5t14.5 4.5q42 11 86 18.5t90 12.5q4 0 15.5 -1t25 -2t25 -2t15.5 -1q42 -2 87.5 -4t85.5 -18q6 -2 22.5 -8t35.5 -13t36 -13.5t24 -8.5q1 -1 6 -4t11.5 -6.5t12 -6t7.5 -3.5q4 -2 10.5 -2.5t12 -3t8.5 -6.5 t1 -11q32 -24 63.5 -42t63.5 -41q59 -42 106.5 -88t90.5 -106q2 -2 6 -8.5t8 -13.5t7.5 -13t5.5 -9q12 -1 17.5 -8.5t5.5 -17.5q0 -5 -1 -9t-6 -9q2 -3 5 -9.5t6 -14.5t6 -15t4 -10q0 -2 2.5 -11.5t4.5 -20.5t4.5 -20.5t2.5 -12.5q5 -14 15 -23.5t10 -21.5q0 -11 -2.5 -16.5 t-2.5 -13.5v-5q0 -2 1.5 -11t3.5 -19.5t3.5 -19.5t2.5 -11v-5.5t-0.5 -10t-0.5 -10v-5.5q0 -6 0.5 -29t0.5 -49.5t0.5 -49.5t0.5 -29v-11v-9q-6 -72 -16.5 -142t-38.5 -137q-2 -2 -7 -14t-8 -18q-2 -3 -5.5 -9.5t-8 -13.5t-8 -13.5t-4.5 -8.5q-74 -88 -137.5 -153 t-115.5 -104q-2 -2 -11 -7t-12 -7q-40 -24 -84.5 -48.5t-90.5 -35.5q-9 -2 -32.5 -6t-49.5 -9.5t-50 -10t-33 -5.5q-23 -5 -47 -3.5t-46 3.5q-34 2 -62.5 4t-64.5 8q-49 9 -104 27t-109 43t-103.5 55t-87.5 62q-5 4 -19 17.5t-29.5 29t-30.5 29.5t-21 20q-2 2 -7 6.5 t-10.5 9t-10 9t-5.5 6.5zM700 367q6 -1 21 -3t32 -4t32 -4t22 -2q1 0 8.5 -0.5t17 -1l19 -1t15.5 -0.5q65 -5 126.5 4.5t116.5 32.5t101.5 61t80.5 92q2 3 7 11.5t5 10.5q17 66 22 132t5 135q0 38 -3 72.5t-11 71.5q-9 31 -17.5 63t-20 64t-26.5 62t-37 56q-2 2 -4.5 4 t-4.5 5q-3 3 -6 7q-2 2 -11 1.5t-11 -0.5q-5 2 -6.5 6.5t-2.5 10t-2 10.5t-5 7q-114 72 -245 81q-4 0 -13 -1t-18.5 -1t-17.5 1t-10 5q-9 -2 -31 -6.5t-46.5 -9.5t-46 -9.5t-30.5 -7.5q-38 -9 -67 -23.5t-53 -34t-45.5 -44.5t-45.5 -55q-14 -19 -26 -39.5t-16 -43.5 q-8 -29 -12.5 -51t-6.5 -41.5t-2.5 -37.5t0.5 -37q4 -17 6 -41.5t3.5 -51.5t3 -55.5t4.5 -53.5q15 -6 22 -19t2 -25q3 -5 9.5 -19.5t14 -31.5t14 -32t9.5 -21q1 -2 3 -7.5t4.5 -12.5t5 -12.5t4.5 -6.5l9 -10q1 -2 4.5 -8.5t7 -14t6.5 -14.5t4 -8q2 -3 8 -9.5t8 -6.5l38 -46 q6 -8 11.5 -11.5t11.5 -4.5t13.5 -1.5t16.5 -2.5q3 0 4 -3.5t2.5 -7t5.5 -7t14 -4.5z" />
<glyph unicode="P" horiz-adv-x="1164" d="M71 483q3 10 4.5 25.5t2.5 32.5t1.5 33t0.5 27q1 8 -2 13t-3 12q0 10 7 18l5 223q-2 15 -2.5 46t0.5 63t4.5 58.5t9.5 33.5q0 1 -1 7.5t-1.5 13t-1.5 12.5t-1 8q0 7 -0.5 27t-1 46.5t-1 56.5t-1 56.5t-1 46.5t-0.5 27q-2 60 -7 118.5t-3 118.5q1 17 2 31t6 32q2 5 11 7 t11 2q23 5 53 6.5t55 0.5h2q7 -1 36 -2.5t62 -3.5t61.5 -3.5t35.5 -2.5q12 0 44 -0.5t68 -1.5t68 -1.5t44 -0.5q60 -11 115.5 -21t114.5 -28q21 -7 47 -17.5t44 -25.5q6 -5 17 -14t22.5 -19.5t21 -19t11.5 -11.5q1 -2 6 -9.5l11 -16.5t10.5 -17t6.5 -9q1 -1 4 -4.5t7 -7 t7 -7t3 -4.5q17 -23 25.5 -49t12 -53.5t3 -56t-0.5 -55.5q-2 -54 -17 -107t-38 -101q-21 -64 -62 -109.5t-98 -81.5l-158 -77q-18 -4 -35 -10t-34.5 -12t-35 -11t-35.5 -6h-15.5t-27 0.5t-27 0.5h-16.5q-2 0 -7.5 -0.5t-12 -1t-12.5 -1.5t-8 -2q-9 -1 -13.5 -6t-7 -11 t-5.5 -12t-10 -9q0 -3 -1 -12.5t-1 -12.5q-1 -21 -1 -38v-29v-4q-5 -21 -5.5 -40t0 -37.5t1.5 -37.5t1 -41q0 -5 -0.5 -12t-0.5 -13.5v-11.5v-6l5 -10l-2 -93l3 -51q0 -2 -0.5 -7.5t-0.5 -11.5t-0.5 -11.5t-0.5 -8.5v-36q0 -4 1 -15t1.5 -23t1 -22.5t0.5 -14.5q1 -3 3 -15.5 t2 -15.5q0 -6 -8.5 -13.5t-14.5 -7.5q-9 0 -10.5 6.5t-6.5 11.5h-10t-15.5 0.5t-16 0.5h-10.5h-13.5t-16.5 0.5t-14 0.5h-7q-2 0 -13 -2t-17 -4q-26 -5 -52 -7.5t-52 -9.5q-2 0 -11.5 -2t-20 -4.5t-20 -5t-11.5 -3.5h-5q-11 1 -13.5 8.5t-4.5 15.5q-5 27 -6.5 54.5 t-2.5 55.5v52v66.5t0.5 62t0.5 37.5q0 2 -1 10.5t-1.5 18t-1.5 18t-1 10.5q0 3 0.5 15t0.5 14q-2 11 -6.5 21.5t-4.5 19.5v6zM442 1322q-1 -22 1 -51.5t5 -52.5q1 -4 2 -19t2.5 -32.5t2.5 -32.5t2 -19q1 -5 2.5 -15.5t3 -22t3 -22.5t1.5 -15h4q2 0 3.5 -0.5t2.5 -0.5 q13 -2 35.5 -2t48.5 4t53.5 11.5t50.5 19.5t39.5 29t20.5 40q1 22 -6 51t-21 47q-15 17 -29 30t-34 21q-33 15 -82 27.5t-111 4.5z" />
<glyph unicode="Q" horiz-adv-x="1815" d="M1322 -17v5q-1 1 -3 5t-4.5 9.5t-5 10.5t-3.5 8q-2 5 -9.5 20t-10.5 20q-4 8 -6 13t-11 5l-5 -2q-38 -19 -78 -36.5t-82 -28.5q-2 0 -11 -1.5t-19.5 -4t-20 -4t-11.5 -1.5q0 -2 -4 -3t-6 -2q-3 -2 -13 -8t-12 -6l-2 -2l-4 2q-4 2 -7 4t-5 3.5t-3 1.5h-2q-29 0 -56 -2.5 t-56 -2.5q-63 1 -119 17t-116 36q-51 10 -95 30t-86 49q-14 9 -31 13.5t-30 15.5q-38 30 -75 63t-73 68q-3 2 -9 7.5t-12 12t-11 11.5t-6 7q-9 12 -19.5 26.5t-19 27.5t-14.5 22t-6 10v7q0 1 -3 7.5t-7 15t-8 17.5t-7 15q-5 10 -9.5 25t-9 30.5t-8.5 30.5t-7 26 q-3 8 -7.5 21t-8.5 25.5t-7 21.5t-3 10l1 12q-6 41 -11 87.5t-3.5 100t11 113.5t31.5 127q0 3 3 12.5t5 14.5q13 41 27 73.5t31 62t38 58.5t49 64q9 10 34 38.5t58.5 62t73 67.5t76.5 57q106 57 221 85.5t233 27.5q51 -1 99.5 -7t99.5 -11q0 -1 5 -1h10.5t10.5 0.5t7 0.5 q-1 -2 3.5 -7t6.5 -5q2 -1 10.5 -4t17.5 -7t16.5 -7.5t9.5 -4.5l78 -39q1 -1 9 -4.5t17 -7.5t17 -7.5t10 -3.5q16 -8 26 -14t23 -20q9 -9 25 -26t32 -33.5t28.5 -30t14.5 -16.5q6 -8 20.5 -27.5t30.5 -41t30 -41t19 -27.5q2 0 3.5 -2t3.5 -4q16 -26 32.5 -54.5t30.5 -59 t24.5 -62t15.5 -64.5q1 -14 4 -39.5t6 -51.5t5.5 -47t2.5 -25v-7t-0.5 -14l-1 -16t-0.5 -13q-5 -85 -27 -163.5t-49 -158.5q-2 -2 -4.5 -11.5t-2.5 -11.5q-2 -3 -4.5 -9t-2.5 -8l-120 -200v-10q24 -23 41.5 -45t29.5 -40t20.5 -31t15.5 -18q17 -40 34.5 -74t40.5 -72 q0 -3 -5.5 -9t-8.5 -7l-4.5 -4.5l-7.5 -7.5t-8 -7t-5 -3q-5 -2 -12 -4.5t-14 -5.5t-12.5 -5.5t-6.5 -3.5q-2 -1 -10.5 -5t-18.5 -8.5t-18.5 -8.5t-10.5 -5q-2 0 -10.5 0.5t-10.5 0.5q-3 0 -12.5 -1.5t-20 -4t-19 -4.5t-10.5 -2t-9 -0.5t-15 -1t-15 -1t-8 -0.5 q-2 -1 -10 -2.5t-17.5 -3.5t-17.5 -3.5t-10 -2.5h-6q-14 0 -21 10.5t-16 17.5zM526 519q3 -4 11.5 -13.5t17.5 -20.5t17.5 -20.5t13.5 -13.5q9 -7 22 -18.5t27 -14.5q2 -2 10 -3.5t10 -1.5t6.5 -6t6.5 -6q1 -1 5.5 -3t9.5 -5t10 -5.5l7 -3.5q48 -21 100.5 -30.5t106.5 -9.5 h12t15.5 -0.5t13.5 -0.5h7q5 0 16.5 1.5t16.5 9.5v2l1 4q-3 3 -8.5 16t-8.5 16l-9 18t-15.5 30.5t-16 30.5t-9.5 17q0 1 -3 8t-6.5 14.5t-6.5 14.5t-4 9q-2 3 -6 10.5t-9 16.5t-9.5 17t-6.5 11q-9 3 -12.5 8.5t-5 12.5t-3 14.5t-4.5 15.5q-14 30 -27.5 52.5t-41.5 43.5l1 2 v4q8 7 14.5 10t13 3.5t13.5 0.5t17 1q1 0 7 0.5t12 1.5t11.5 2t7.5 2q2 0 10.5 0.5t18 1.5t17.5 2t11 2t17.5 5.5t31 10t30.5 10t18 5.5q7 0 12 1q5 0 9.5 0.5t8.5 0.5q3 0 9 -0.5l12 -1t11 -1t6 -0.5q4 0 14.5 -2.5t12.5 -2.5q1 -1 6 -5t11 -9.5t11.5 -10.5t7.5 -8 q2 -2 3.5 -6.5t1.5 -6.5q2 -2 6.5 -8.5t9.5 -13.5t9.5 -13.5t6.5 -8.5t5 -6t5 -6q2 -1 5 -2q6 -2 6 -4q2 -2 5.5 -11t5.5 -11q2 -3 11.5 -15.5t14.5 -17.5q2 -3 7.5 -8.5t11 -12t11 -12t7.5 -6.5q0 -2 5 -4q2 -2 5 -3q2 -2 3.5 -8.5t1.5 -8.5h6q7 0 13 7.5t10.5 18t8 20.5 t6.5 16q2 4 4 12.5t4 16.5l3.5 14l1.5 6q1 1 2.5 7t3 13t2.5 12.5t1 7.5q0 3 3.5 14t3.5 12q0 2 1 17.5t1 22.5q1 8 1 20v14q0 5 -2 22.5t-4 39t-4.5 42t-4.5 30.5q-1 1 -2.5 8t-4 15t-4.5 16l-3 12q0 2 -2.5 5.5t-4.5 5.5q-15 49 -32 96t-48 90l-3 3q-1 1 -2 1h-10 q-1 2 -5 6l-6 6q-13 17 -25.5 32.5t-31.5 29.5q-8 8 -21 13t-21 10q-2 2 -9.5 8.5t-9.5 8.5q-26 15 -50 22.5t-56 16.5q-6 2 -16.5 2t-21 -1t-19 -0.5t-12.5 4.5h-42q-39 0 -77 -7.5t-74.5 -21.5t-71 -33t-67.5 -41q-5 -3 -13.5 -10t-8.5 -9q-36 -31 -66.5 -62.5 t-47.5 -77.5q-20 -47 -33.5 -93t-15.5 -97q0 -3 -0.5 -8t-1 -10.5t-0.5 -10v-5.5l21 -212q0 -7 5.5 -23t13 -33t15 -31t11.5 -18q2 -2 9 -4q4 -2 7 -3q5 -4 7 -10.5t4 -11.5q-1 -2 1 -6t4 -6z" />
<glyph unicode="R" horiz-adv-x="1278" d="M171 6q-3 7 -9.5 9t-14 3t-14 2.5t-9.5 7.5q-2 25 -3.5 54t-3 58.5t-2.5 58.5t-1 54q-1 10 -1 42.5v75.5v92t0.5 92t0.5 75.5v42.5q-1 9 -2.5 33t-4 50.5t-4 50.5t-2.5 34q-8 17 -6 29.5t0 32.5q0 5 -1 20.5t-2.5 36.5t-3.5 44t-4 44t-3.5 36.5t-1.5 20.5q-6 66 -6 133 v134q0 74 2.5 141t13.5 139l6 6t6 4l2 2q1 0 1.5 -0.5t1.5 -0.5l1 -1q2 0 8.5 -5t8.5 -5q2 -2 9 1t9 3t8.5 -2t8.5 -2q2 -1 6 -1q2 -1 5 -1h5q45 0 90 6t90 13q3 0 11 -1t17.5 -2t18 -1.5t11.5 0.5q9 0 25 0.5t32.5 1.5t29.5 1.5t15 0.5t9 -0.5t15 -1.5t14.5 -1.5t8.5 -0.5 q4 -1 18 -1h30.5t31 0.5t18.5 0.5q42 -2 81 -5t79 -14q3 0 15 -2t14 -4q3 -2 11.5 -9.5t10.5 -7.5q16 -9 34 -16.5t35.5 -19t33.5 -28t29 -42.5q9 -6 12.5 -9.5t5.5 -11.5q8 -20 21.5 -41.5t25.5 -39.5q11 -17 17.5 -38.5t11.5 -41.5l16 -66v-8q1 -4 2.5 -13t3.5 -19.5 t3.5 -19.5t2.5 -12v-53l-12 -74q-18 -41 -33 -77.5t-30.5 -69.5t-34.5 -62.5t-45 -54.5q-22 -20 -50 -33t-53 -24q0 -1 -0.5 -2t-0.5 -2q-1 -1 -1 -2q0 -7 6.5 -19t15 -25t17.5 -24.5t14 -17.5q0 -2 2.5 -4t4.5 -2l51 -93h12q6 -9 9.5 -20t6.5 -22t8 -22.5t15 -21.5l18 -18 q0 -2 -1 -8t1 -8q1 -2 3.5 -8t6.5 -13.5t7.5 -14.5l5.5 -11l57 -93q2 0 11.5 -2t11.5 -8q1 -2 2 -7t2 -10.5t1.5 -11t0.5 -6.5q1 -5 8 -18t10 -16q13 -25 22 -50t15 -46t11 -37t10 -23l-19 -17q-8 -1 -27 -2.5t-41 -3.5t-41.5 -3.5t-27.5 -2.5q-2 0 -8.5 -0.5t-14.5 -1.5 t-15 -2t-9 -2q-2 0 -11.5 -0.5t-22 -1.5t-25.5 -1.5t-21 -0.5h-6q-2 -1 -8.5 -2.5t-14 -3.5t-14.5 -3.5t-8 -2.5q-3 -1 -8 -2l-10 -2t-11 -2q-2 0 -6 4.5t-6 7.5q-23 32 -42 67.5t-38 69.5q-10 18 -20 39.5t-20 43.5t-20 43.5t-20 39.5q-2 2 -5 8.5t-6 14t-6.5 14t-4.5 8.5 q-10 25 -25.5 56t-33 63t-37 64t-38 59.5t-35.5 47.5t-29 30q0 -2 1.5 -16t4 -31t4 -31t1.5 -15v-22q2 -8 3 -23.5t3 -17.5l11 -76q0 -22 1.5 -38.5t4.5 -41.5q6 -2 7 -4.5t1 -7.5q0 -9 -4 -16.5t-4 -18.5v-264q0 -2 3 -8.5t3 -8.5q0 -1 1 -3q0 -2 0.5 -3t0.5 -2 q0 -11 -6 -20t-12 -19q-3 0 -10 -0.5t-14 -1.5t-13.5 -1.5t-9.5 -0.5h-39q-25 -3 -48.5 -7.5t-48.5 -4.5q-35 0 -72.5 9t-72.5 14zM492 1057q2 -6 6.5 -6h7.5q11 0 28.5 3.5t26.5 3.5q6 0 8.5 -4t10.5 -4q34 0 73 9t72 28t55 47t22 67q-1 22 -8 35t-16.5 22t-20.5 15t-20 14 q-3 2 -9.5 6.5t-8.5 4.5q-5 3 -20 9t-31.5 13t-31 12t-20.5 7q-11 5 -20.5 5.5t-20.5 0.5q-20 0 -43.5 -3.5t-42.5 -8.5q-3 0 -9.5 -2.5t-6.5 -4.5q-1 -1 -1 -3q-1 -2 -1 -5q0 -14 7 -24.5t7 -24.5l-2 -4q0 -2 -3 -6t-3 -6t3 -14.5t3 -14.5q4 -25 4 -46t-0.5 -40.5t0 -39 t5.5 -41.5z" />
<glyph unicode="S" horiz-adv-x="1114" d="M60 287q1 20 -7.5 37.5t-19.5 33.5q0 2 -6.5 9.5t-8.5 10.5q-1 2 -1 4v6q0 2 1 6t1 6q3 2 9 7.5t13 11.5t13 11t9 7q4 4 17 14.5t27.5 21.5t27.5 21t18 13q1 1 8 6t15.5 10.5t15 10t8.5 5.5q1 1 6.5 4.5t12 8t11.5 8t7 5.5q3 2 14.5 8t15.5 7l1 1q1 0 1.5 0.5t1.5 0.5 l2 -2q7 -8 25.5 -29t39 -44t38.5 -44t26 -29q3 -2 13 -11.5t22 -20.5t24 -21.5t19 -15.5q4 -3 11.5 -9.5t15.5 -12.5l14 -10.5t8 -5.5q2 0 12 -3t17 -5h6q11 -3 30 -4t37.5 3t34.5 14.5t21 30.5l-13 95q0 2 -3.5 13t-4.5 16l-32 53q-1 2 -2 5l-2 4t-1 4q-20 33 -44 60 t-49.5 51.5t-53 47.5t-55.5 49q-25 23 -49 47t-48 45q-28 24 -54.5 46.5t-51.5 46.5q-34 37 -67 83.5t-59 98t-41 105.5t-12 105q3 42 17.5 78.5t36.5 70.5q2 0 5 5q2 2 3 5q5 7 12.5 18.5t15 22t12.5 18t5 8.5q1 1 11 10t22 20.5t24.5 22.5t19.5 17q25 21 50.5 34.5 t52.5 24t55 19t58 18.5q10 3 26 4.5t33 2t33 0t27 -1.5q43 -3 79 -10.5t68.5 -20t64.5 -30t67 -39.5q1 -1 3 -2l4 -2q2 -2 4 -3l34 -24q0 -2 6 -9t9 -9q3 -3 16 -15.5t28 -27t27.5 -28t15.5 -17.5q1 -1 5 -6t9 -11.5t10.5 -13t8.5 -10.5q8 -13 14.5 -22.5t5.5 -25.5v-10 q-2 -2 -7.5 -8t-11.5 -12l-11.5 -11.5l-7.5 -7.5q-1 -1 -5 -4t-9 -6.5t-10 -6.5t-6 -3q-7 -7 -26 -24t-41 -35.5t-41.5 -35.5t-26.5 -24t-22 -5q-5 0 -14.5 1.5t-14.5 6.5q-1 1 -3 6t-4 11t-4.5 11l-3.5 7q-9 19 -21.5 39t-28 38t-33 33.5t-35.5 24.5q-2 0 -8.5 2t-14.5 4.5 t-15 5t-10 2.5q1 2 -6 4.5t-9 2.5h-4h-4t-4 1h-35.5t-33.5 -3t-30 -11t-25 -24q-2 -5 -6.5 -13.5t-4.5 -10.5t-0.5 -8.5t-1 -14t-1 -14.5t-0.5 -8q0 -2 -3.5 -6t-3.5 -6v-2v-4q10 -25 26.5 -47.5t35 -43t39 -40t39.5 -38.5q1 -2 8 -9.5t7 -9.5q4 -3 17.5 -14t30 -24t33 -25 t25.5 -18l10 -7l5.5 -5.5t9 -9.5t8.5 -10t6 -6l10 -6q34 -24 64 -58t56 -65q3 -3 13.5 -16t22 -27t21.5 -26.5t12 -15.5q2 -2 6 -6.5t6 -6.5t5.5 -11.5t4.5 -12.5q1 -2 5 -9t9.5 -15.5t10 -16.5t7.5 -12q0 -2 2 -5.5t5 -7.5t5.5 -7.5t3.5 -4.5q1 -3 6 -15t11 -26t11.5 -26 t7.5 -15q0 -2 6.5 -12t8.5 -12q0 -2 -0.5 -11t-0.5 -11q-1 -2 3 -11.5t7 -14.5l13 -68l-7 -121q0 -3 -2.5 -9.5t-4.5 -9.5q-9 -33 -23 -59.5t-42 -50.5q-3 -4 -15.5 -15t-28 -24t-30.5 -24.5t-23 -16.5q-35 -29 -78 -57t-88 -44q-19 -5 -34 -6t-36 -6q-32 -6 -61.5 -14 t-61.5 -6q-29 2 -57 8t-57 14q-75 23 -132 59t-99 85q-2 3 -12.5 13.5t-22 22.5t-21.5 23t-12 14q-4 4 -14 15.5t-21.5 24t-21.5 23.5t-13 15z" />
<glyph unicode="T" horiz-adv-x="1106" d="M401 15l-5 141q-2 2 -4 8.5t-2 8.5t3 8.5t3 8.5v12v10.5t1 8.5v33q-6 1 -8 7.5t-1.5 13.5t3 12.5t6.5 5.5q0 4 1 15t2 23t2 22.5t2 15.5v2l1 84q0 48 -3.5 95t-1.5 95q-2 2 -6.5 11.5t-6.5 12.5v2q0 1 0.5 2t0.5 2q0 5 1 8t6 8q0 4 -0.5 15t-1 23t-1 22.5t-0.5 15.5 q1 72 -2.5 143t-8.5 143q-1 6 -2.5 30t-3 51t-3 51t-2.5 30q0 1 -1 7.5t-3 14.5t-4 16.5t-4 13.5q-3 14 -9.5 29t-18.5 23q-28 7 -53 7.5t-54 2.5h-14t-17 0.5t-14.5 1t-7.5 0.5q-2 0 -8 -0.5t-13.5 -1.5t-14.5 -1.5t-11 -1.5q-2 0 -11.5 -1.5t-11.5 -3.5h-2 q-17 1 -27.5 5.5t-15.5 19.5q-11 55 -11.5 107t-0.5 107q0 7 0.5 23t1.5 33t1.5 32.5t0.5 22.5q5 11 18.5 13.5t22.5 1.5q10 0 35 -0.5t53.5 -0.5h53.5h36q35 1 69 4t70 2q9 0 29.5 0.5t46 1t53.5 1t54 0.5h46t30 -1q65 7 128 5.5t130 -2.5q2 0 15 1.5t19 3.5h7t13 0.5 t13 0.5h7q13 -1 19.5 -6.5t9 -14t2.5 -19t2 -20.5q1 -10 2.5 -35t3 -52.5t3 -52t2.5 -33.5q0 -3 -0.5 -15.5t-0.5 -17.5q0 -41 -6 -60t-19.5 -25t-36.5 -5t-58 0q-4 0 -17 -1t-28.5 -2t-30.5 -2.5t-23 -2.5q-4 0 -13.5 -1t-20.5 -3t-20.5 -4t-13.5 -3q-5 -15 -5.5 -26 t-0.5 -25q0 -12 0.5 -20.5t5.5 -24.5l-2 -207q7 -24 4 -45.5t-1 -46.5q1 -2 2 -9.5t1.5 -15.5l1 -16t0.5 -12q5 -36 7.5 -70.5t4 -68.5t4 -69t7.5 -72l5 -115q-1 -32 -0.5 -57t5.5 -57q0 -2 2 -6.5t2 -6.5v-2v-4l-2 -4q-2 -4 -2 -6l2 -152l2 -4q2 -4 2 -6t-2 -9.5t-2 -9.5 q-5 -31 -8 -71t-1 -71l-12 -11l-355 -8z" />
<glyph unicode="U" horiz-adv-x="1289" d="M60 1661q1 19 8 34.5t29 17.5q28 -2 57 -6.5t57 -7.5t53.5 -2.5t45.5 9.5q3 0 16.5 -0.5t29 -1.5t28.5 -1.5t16 -0.5q2 0 5 1q2 0 3.5 0.5t2.5 0.5q15 -2 21 -14.5t12 -28.5q1 -8 1.5 -16t-0.5 -16q-1 -27 -2 -49t-2.5 -43.5t-2.5 -44t-2 -49.5q-2 -52 -0.5 -112 t6.5 -113q0 -3 0.5 -14t1 -23t1 -22.5t0.5 -12.5v-7t-0.5 -10.5l-1 -11t-0.5 -6.5q0 -2 0.5 -7.5t1 -12.5t1.5 -14t1 -11q11 -93 25 -182t31 -182q1 -2 2 -7.5t2.5 -12.5t3 -13t2.5 -7q0 -1 0.5 -5.5t1.5 -9.5t2 -9t1 -5v-6t1 -8t2 -9l16 -58q2 -14 6 -32.5t9.5 -37.5 t12.5 -36t15 -28q23 -35 58 -50.5t73 1.5h4q1 1 6 3q2 1 5 2q4 3 12.5 11t17.5 16.5t17.5 16t11.5 10.5q2 2 7 7.5t7 10.5q25 39 47 91t28 100q1 12 3 34t3.5 44.5t3.5 41t3 24.5v8.5t0.5 16.5t1 18.5t0.5 14.5q2 60 -2.5 119.5t-6.5 118.5v16.5t-0.5 29t-1 29t-1.5 17.5 q0 9 -1.5 32t-3 49t-3.5 48.5t-3 31.5q0 4 -2 21.5t-4.5 37t-4.5 36t-2 20.5q0 3 -3.5 28.5t-7.5 59t-7.5 68.5t-3.5 58v4q0 2 0.5 3.5t0.5 2.5q0 7 -1.5 10t-1.5 4.5t2 2.5t9 4q58 4 122 6.5t121 -0.5q10 -2 23.5 -1.5t27 0.5t24 -1.5t15.5 -6.5q4 -5 11 -6.5t13 -3 t10.5 -3.5t5.5 -7q4 -21 6 -38.5t3 -34t2 -34t2 -39.5v-29q1 -3 2.5 -15t1.5 -15q-5 -8 -4.5 -28t2.5 -43t5 -42.5t3 -25.5q-2 -39 -4.5 -79.5t-4.5 -79.5t-4.5 -75.5t-3.5 -66.5q0 -3 -0.5 -19t-1 -34.5t-1 -34.5t-0.5 -19q-1 -4 -1.5 -14t-1 -21t-0.5 -21v-14l-5 -12 l-31 -393q-14 -77 -37 -135t-56 -102t-76.5 -76.5t-98.5 -57.5q-21 -6 -42.5 -15.5t-43.5 -18.5t-44.5 -15.5t-43.5 -5.5q-32 -5 -55 -7t-42 -2.5t-35 1.5t-34 6q-34 5 -67.5 9.5t-65.5 22.5q-38 19 -68.5 40.5t-57 46.5t-50 54t-46.5 64q-19 30 -27.5 56t-19.5 61 q-4 14 -11.5 32.5t-9.5 32.5q-1 4 -3 22t-4 38.5t-3.5 38.5t-2.5 23q0 3 -2 14t-4.5 23.5t-4.5 23.5t-2 14q-11 100 -13 199t-7 201v10q0 5 -0.5 15t-1.5 20t-1.5 18t-0.5 10q0 6 -2.5 26.5t-5.5 44.5t-5.5 44.5t-2.5 26.5q0 2 0.5 12t0.5 21.5t0.5 21.5t0.5 12 q-2 50 -5.5 92t-6.5 87q0 3 2 15t0 14q0 2 -2 6t-2 6q-8 31 -8.5 65t0.5 66z" />
<glyph unicode="V" horiz-adv-x="1612" d="M408 702q-2 2 -4.5 5.5t-2.5 5.5q-1 2 -3 10t-5 16.5t-5 16.5t-3 10q-12 31 -27 60.5t-26 60.5q-1 2 -4 12t-7 21.5t-7.5 21.5t-4.5 12q-9 24 -22 51.5t-26.5 56t-27 56.5t-22.5 52q-15 41 -32 78.5t-34.5 74.5t-34.5 75.5t-32 80.5q-1 4 -5.5 18t-10.5 30.5t-11.5 31 t-7.5 19.5q-1 3 -4.5 10.5t-7 16.5t-7 16.5t-4.5 10.5v6q0 8 5 15t11 13q10 2 38.5 4.5t60.5 5t60.5 4.5t39.5 3q1 0 10 0.5t20.5 0.5t23.5 0.5t19 0.5q5 0 15.5 -0.5t22.5 -0.5t22.5 -0.5t15.5 -0.5l2 -2q2 -2 2 -4q2 -2 9.5 -11.5t9.5 -11.5l64 -163q0 -3 4 -16t6 -19 q4 -8 12.5 -29.5t17.5 -45t17.5 -45t12.5 -29.5q7 -12 16 -32t17.5 -40t13.5 -36t4 -20q0 -2 1 -9t3 -14t5 -12.5t7 -5.5l23 -50q0 -9 0.5 -13t5.5 -13l142 -335q6 -30 16 -56.5t24 -64.5q1 -2 2.5 -6.5t4 -10.5t5.5 -11.5t6 -7.5q17 31 24.5 58.5t17.5 61.5q2 2 4 9t2 10 q1 1 4 9.5t7 18t7 18.5t4 11q1 3 4 11t6 17t5.5 17t3.5 12q0 1 0.5 6t1.5 11t2 11t2 7q0 2 5 11.5t5 11.5q1 1 2.5 7t3.5 12.5t3.5 12t2.5 7.5q1 4 7 18t13 30.5t12.5 31t6.5 18.5q2 3 4 9t2 9q10 35 25 67.5t29 70.5q1 4 5.5 20t10 34t10 34t6.5 20q1 1 3.5 6.5t6 11.5 t6 11t3.5 6q1 4 4 11t5.5 14.5l4.5 13.5t2 8l70 240q3 9 14.5 18t19.5 11q2 1 7 3t11 4.5t11 4.5t7 2t8.5 3t8.5 3q60 0 97.5 1t64.5 3t48.5 4t49.5 4h23q3 -6 5 -9t3.5 -5.5t2.5 -5.5t1 -10q0 -11 -3 -25t-6.5 -29.5t-7.5 -30t-6 -25.5q-9 -31 -16.5 -57.5t-15 -52 t-16 -51.5t-19.5 -56q-15 -43 -25 -78.5t-25 -78.5q-1 -2 -4.5 -10.5t-7.5 -18t-7.5 -18t-3.5 -10.5l-25 -64q-1 -3 -2 -5q-2 -6 -2 -7q-26 -60 -52.5 -120t-51.5 -122q-2 -2 -4 -8t-2 -8q-1 -8 0 -13t1 -9t-0.5 -8t-4.5 -11q-1 0 -3 -1.5t-4 -3.5q-3 -3 -6 -5 q-3 -5 -6.5 -15.5t-5.5 -15.5q0 -2 -1.5 -10t-3.5 -18t-3.5 -18.5t-1.5 -10.5q-2 -6 -7 -20.5t-10.5 -31l-10.5 -31.5t-7 -20q2 -11 1 -28.5t-7 -28.5q-1 -1 -3.5 -4.5t-5.5 -7.5t-5 -8t-2 -5q-20 -42 -32 -87.5t-28 -90.5l-4 -10q-3 -5 -7.5 -16t-4.5 -13q-2 -5 -4 -18 t-5 -28t-5.5 -29t-3.5 -20q-11 -11 -11.5 -29.5t-2 -37.5t-9 -35t-31.5 -22q-35 0 -70.5 6t-72.5 6q-47 0 -93.5 -6t-93.5 -6h-28q-7 3 -12 10.5t-8.5 16t-6 17t-4.5 13.5q-1 2 -5 11.5t-9.5 20.5t-9.5 20.5t-5 11.5q-29 72 -53.5 145t-48 145.5t-47.5 145.5t-51 145z" />
<glyph unicode="W" horiz-adv-x="2181" d="M1358 36q-2 6 -7.5 15t-11 19.5t-11 19.5t-7.5 15q-8 21 -17.5 50.5t-11.5 51.5q-4 9 -11.5 34t-16 52.5t-16 52.5t-10.5 34q-1 2 -3.5 11.5t-6 20t-7 20.5t-4.5 13q0 2 -5.5 11t-5.5 11q-8 19 -12.5 40t-9.5 40q-16 46 -27 94t-20 96q-5 27 -11 60.5t-12.5 67t-14 64 t-14.5 51.5h-2q-1 -3 -3 -17t-4.5 -29.5t-5 -29.5t-3.5 -17q-3 -14 -12 -47.5t-19 -71t-19 -71t-13 -46.5q-16 -35 -23.5 -72.5t-21.5 -72.5q-2 -2 -2.5 -11t-2.5 -11q-11 -26 -19 -54.5t-17 -54.5q-7 -25 -14.5 -47.5t-12.5 -45t-7.5 -46.5t-0.5 -51l-11 -17 q-2 -5 -5 -17.5t-6.5 -26t-6.5 -26t-4 -16.5q-3 -12 -9.5 -30t-19.5 -23q-18 -6 -37 -7.5t-37.5 -1.5t-37.5 -1t-37 -7q-2 0 -9.5 -5t-9.5 -7h-6q-5 0 -6.5 1t-3.5 2t-5.5 2t-10.5 1q-32 0 -55.5 0.5t-54.5 0.5h-21q-2 2 -3 4t-3 2q-12 3 -25 10.5t-23.5 18.5t-17.5 25.5 t-6 32.5q-4 10 -10.5 33.5t-13.5 49.5t-13.5 49t-9.5 33q-13 42 -25 81t-23 77t-21.5 77t-21.5 82q-9 34 -18.5 66.5t-15.5 66.5q-5 23 -6.5 45t-6.5 47q0 1 -1.5 9.5t-3.5 18t-3.5 18.5t-1.5 11q-2 8 -6 39t-9 67t-9 67.5t-5 39.5q-1 23 -9.5 67t-21 98t-27 111.5 t-27.5 108t-22.5 88t-12.5 50.5q-1 1 -3 6t-4.5 11t-4 11t-1.5 7v12q0 8 3.5 15t13.5 7q6 0 11 -1.5t13 -4.5h60q49 0 97 6t97 6h19t22 -0.5t21.5 -3t17.5 -8.5q4 -4 8 -7q3 -3 6 -5t4 -4q0 -2 3.5 -6t3.5 -6q7 -1 11.5 -18.5t7.5 -38.5t7 -40t12 -23q8 -18 12.5 -32.5 t7.5 -28t5.5 -28t7.5 -33.5q8 -31 16 -57t13 -58q1 -4 2.5 -17.5t3.5 -29t3.5 -29t2.5 -16.5l42 -281q7 -3 9.5 -22.5t3.5 -42.5t2.5 -42t6.5 -20q1 0 4 -3q1 -2 2 -3q0 -1 1.5 -10.5t3.5 -21.5t3.5 -21.5t1.5 -10.5q2 -3 6.5 -11.5t6.5 -10.5q5 3 6.5 7t3.5 9q4 13 12.5 33 t18 43t18 46.5t14.5 44.5q1 2 2.5 10t3.5 16.5t4 16.5t3 10q1 5 6 19.5t10.5 31l10.5 31.5t7 20q-2 9 1 17.5t5 17.5q11 67 30.5 131t37.5 129q9 34 17.5 63.5t16.5 59t16 59.5t17 64q2 5 4 15.5t2 12.5v19q1 4 4 11t6.5 14.5t7 13t7.5 6.5q67 12 140 12h16q2 0 8.5 -0.5 t14 -1.5t14.5 -2t10 -2q3 0 12 -2t11 -4q1 -4 2 -7t2 -5l2 -4q21 -2 25 -14t8 -38q3 -3 9 -16t9 -18q0 -2 1.5 -7t3.5 -10.5t3.5 -11t1.5 -6.5l19 -58v-4v-2q17 -68 39 -130.5t47 -127.5q0 -3 3 -12.5t3 -11.5q0 -3 2 -10t4 -7q40 -88 75.5 -172.5t67.5 -177.5l6 -6 q4 72 20 141.5t38 139.5q17 61 32.5 124t30.5 123v4v2q-2 2 -4 6.5t-2 6.5q17 28 23 56t12 58q8 39 19.5 76t25.5 74q1 1 2.5 6t3.5 11t3.5 11t2.5 7q5 12 15 19t24 9q3 0 15.5 -3t15.5 -3h6h10q12 0 43.5 0.5t66.5 1.5t66 2t43 2q10 3 18 2.5t15 -2t14.5 -3.5t17.5 -2 q1 0 3 -0.5t4 -0.5q3 -1 6 -1q1 -5 2 -9q2 -10 2 -14v-2v-4q-4 -21 -5.5 -40t-3 -37t-3.5 -37t-6 -40q-1 -2 -3.5 -11.5t-5.5 -20t-5.5 -20t-3.5 -11.5q-2 -6 -6 -28t-8.5 -47.5t-9 -47.5t-5.5 -27q0 -2 -3 -11.5t-6.5 -21.5t-7.5 -23.5t-6 -17.5q0 -2 -2 -6t-4 -6 q-5 -14 -15.5 -49t-22 -75t-22 -75t-14.5 -49q-14 -42 -21 -85.5t-20 -86.5q0 -2 -5 -11t-7 -11q-8 -19 -10 -44t-4 -42v-35q0 -2 -5 -13t-8 -16q0 -2 -2 -6t-2 -6q1 -12 -4.5 -39.5t-15 -62t-20.5 -72t-20 -70.5t-14.5 -57.5t-3.5 -32.5q-1 -2 -3.5 -11.5t-5.5 -20t-5 -20 t-2 -11.5v-23q0 -2 2 -6q1 -2 3 -4l-5.5 -16.5t-7 -21.5t-6.5 -19.5t-3 -9.5q-10 -38 -44 -55t-75.5 -22t-83 -3t-66.5 3q-12 1 -28 1.5t-32.5 2t-31 7t-23.5 17.5z" />
<glyph unicode="X" horiz-adv-x="1630" d="M844 532q-21 -19 -34 -42t-24 -47q-3 -8 -10 -10t-11 -10q-2 -3 -8.5 -15t-14.5 -26.5t-15 -26.5t-8 -15q0 -2 -2 -4t-4 -2l-178 -276q-2 -2 -4 -6t-2 -6q-2 0 -3.5 -7.5t-1.5 -9.5t-6 -6l-13.5 -9t-14 -9t-8.5 -4l-168 17h-34q-14 0 -28 1t-21 4q-19 5 -37 9.5t-38 2.5 q-5 0 -6.5 1.5t-2.5 3t-2.5 3t-6.5 1.5q-21 -2 -39.5 6t-20.5 31q0 2 0.5 8t0.5 8q2 5 6 14.5t7.5 20t7 19.5t5.5 14q2 3 8 13.5t12.5 22.5t12.5 22.5t8 14.5q3 5 17 28.5t30.5 50.5t30.5 50t17 28q1 2 7.5 12t13 21.5t12.5 21t8 11.5q1 3 9.5 14t18 23t18 22.5t9.5 13.5 q19 29 32.5 52.5t33.5 51.5q4 4 20.5 21.5t35.5 38.5t35 39t20 23q2 3 9.5 13.5t16.5 23.5t16.5 23.5t9.5 13.5q1 1 4 5.5t7 9.5t7 9t5 6v1q0 1 -0.5 1.5t-0.5 1.5q0 11 -8.5 25.5t-11.5 20.5q-1 1 -4 5.5t-6 10.5t-6 11t-4 7q-41 61 -85.5 120t-86.5 122q-15 25 -26 52.5 t-25 54.5q-3 3 -6 7q-2 2 -4 4.5t-3 3.5q-3 6 -16.5 29t-28.5 49.5t-28.5 49.5t-16.5 29q-8 15 -22 34t-28.5 39t-26.5 40t-16.5 37.5t1.5 31.5t28 21q2 0 13.5 4t14.5 4q6 0 27.5 2t46.5 4.5t47 4.5t28 2q4 1 16 1.5t26.5 0.5h26.5h16q5 1 9 1h8t6 1q6 0 17 0.5t18 -4.5 q25 -26 48 -55.5t40 -61.5q26 -46 53.5 -92.5t56.5 -90.5q2 -2 9.5 -4t9.5 -7q0 -1 1 -5t2 -9t2 -9.5t1 -5.5q8 -21 21 -39t25 -38q1 -2 7 -12t12.5 -21t12 -21.5t7.5 -13.5l11 -9q2 -3 4 -9t4.5 -11.5t5.5 -9.5t8 -4h4q1 9 9.5 29t21.5 45.5t29 54t31 54t28 45.5t21 29l4 5 q6 10 23 34t35.5 50.5t35.5 50.5t23 34q1 1 6.5 8.5t12 15.5t12 15.5t7.5 10.5q1 1 4 5t6.5 9t6.5 9.5t4 6.5q2 0 4 2l2 2q19 9 42 10.5t45 3.5q4 0 13 -2.5l18 -5t16 -5t8 -2.5q1 -1 25.5 -2t57.5 -5t67.5 -12.5t57.5 -23.5l6 -2q6 -2 7 -2v-6q1 -6 6 -9.5t2 -9.5 q-1 -3 -3 -8t-4.5 -10.5t-4.5 -10.5t-3 -6q-17 -25 -31 -49t-27.5 -48l-27 -48t-29.5 -49q-16 -22 -30.5 -41.5t-27.5 -42.5q-1 -2 -5 -8t-8.5 -12.5t-8 -13t-4.5 -7.5q-1 -4 -5 -10.5t-8.5 -13t-9 -12t-6.5 -7.5q-3 -3 -6.5 -10.5t-7 -16t-7.5 -16.5t-8 -12q-4 -5 -10 -13 t-13 -16.5t-12.5 -15.5t-8.5 -10q0 -2 -4.5 -7t-10 -11t-10 -11t-5.5 -6q0 -2 -5 -7t-10.5 -11.5t-11 -12l-6.5 -6.5q-3 -4 -8 -11t-11 -14.5t-10.5 -14t-5.5 -7.5l-58 -95v-4q6 -10 8.5 -18.5t4 -17t4 -17t8.5 -17.5q16 -26 36 -44.5t35 -43.5q3 -7 11.5 -7.5t12.5 -7.5 v-12q5 -14 16.5 -30.5t22.5 -24.5q2 -2 9.5 -6t7.5 -6q2 0 4.5 -10t2.5 -12q8 -17 21 -30.5t24 -30.5q0 -2 5.5 -10.5t7.5 -10.5q2 -3 6 -9.5t8 -12.5t7.5 -11.5t4.5 -6.5q1 -2 9.5 -12t18 -22t17.5 -22.5t10 -13.5q17 -23 28.5 -42.5t27.5 -40.5l125 -212q4 -9 5 -15.5 t0 -11t-2.5 -8.5t-1.5 -8q1 -13 -9 -23.5t-21 -18.5q-9 -2 -31.5 -7.5t-48 -11.5t-48.5 -11t-33 -6q-18 -3 -35.5 -8.5t-35 -12t-35 -11.5t-36.5 -6q-7 0 -19 6.5t-17 14.5q-26 38 -50.5 77t-50.5 77q-1 2 -5 9t-9.5 15.5t-10 16t-7.5 10.5q-12 21 -29 40.5t-28 42.5 q-2 4 -9.5 20t-16.5 35t-17 35.5t-11 21.5q-9 19 -18 39.5t-20.5 40.5t-25 38t-31.5 31z" />
<glyph unicode="Y" horiz-adv-x="1485" d="M528 39q7 32 5 55t-2 55q0 74 3.5 152.5t-2.5 150.5q0 5 0.5 23t1.5 38.5t1.5 38t0.5 22.5q0 2 -1 18.5t-1 24.5q0 47 2.5 98t2.5 99v2q-2 3 -11 12.5t-11 11.5t-6.5 11.5t-6.5 11.5q-48 77 -98.5 158.5t-92.5 163.5q-5 7 -16.5 24.5t-24.5 36.5t-24.5 36t-15.5 24 q-14 29 -28 63t-37 57q-4 8 -12.5 22.5t-18 30t-18 29t-12.5 21.5q-11 25 -23.5 54t-21.5 55v4q0 14 7.5 21t17.5 9.5t17.5 2.5h7.5q3 1 17 1h30.5t30.5 -0.5t18 -0.5t17.5 2t32 4t39 5t38.5 5l31.5 3.5t17.5 2.5q21 0 27.5 -4.5t13.5 -13.5q9 -15 20 -30.5t22.5 -32 t21.5 -33t17 -31.5q23 -53 42.5 -96.5t46.5 -93.5q3 -4 11.5 -19t18.5 -33t19 -33t11 -19q6 -11 12 -27.5t13 -33t15.5 -31.5t18.5 -22q1 1 5 10.5t8.5 20.5t8.5 20t5 11q2 5 12 23t21.5 38t21.5 37.5t12 22.5q2 2 9 12t15 22l15 22.5l9 13.5q1 1 2.5 5t3 8.5t3 8.5t1.5 6 q1 3 5 11.5t8.5 18t8.5 17.5t6 11q-5 12 3.5 19.5t15.5 15.5q11 12 18 29.5t17 31.5q1 3 8 12.5t14.5 20t14 19.5t8.5 12q9 13 16 22t15 14.5t19 8t28 2.5q22 0 41.5 -2.5t39 -6t39 -7.5t42.5 -6q22 -1 47.5 -1t50 -2.5t46 -9.5t34.5 -20q5 -6 5.5 -11t0.5 -11v-6 q-41 -86 -87 -162t-94 -150t-97 -149t-95 -158q-2 -3 -9.5 -16t-9.5 -16q-17 -24 -30.5 -45.5t-26 -43t-24.5 -44.5t-25 -49q-5 0 -5.5 -8t0 -17.5t2 -19t1.5 -12.5q0 -5 0.5 -14.5t0.5 -18.5t0.5 -16t0.5 -8q0 -3 0.5 -11t1.5 -18l2 -20t2 -15q4 -33 3.5 -81.5t-1 -100 t0 -99.5t6.5 -80l-8 -132q1 -3 1.5 -9.5t1.5 -14t1.5 -14t1.5 -9.5v-8q0 -8 -5.5 -12.5t-13 -7.5t-15.5 -4.5t-13 -2.5q-4 0 -17.5 -1t-29 -2.5t-29 -2.5t-17.5 -1q-8 0 -27.5 -0.5t-40.5 -1.5t-39.5 -1.5t-25.5 -0.5q-26 -3 -54 -1.5t-56 1.5q-8 0 -14 9.5t-6 17.5v2z" />
<glyph unicode="Z" horiz-adv-x="1231" d="M63 53q0 16 7 32t10 30q1 2 3.5 10t5.5 16.5t5.5 15.5t3.5 9v18l2 6q1 4 4 7q1 2 4 10t6.5 17t7 17.5t5.5 12.5q0 2 2 8t4 8q0 1 0.5 6.5t1.5 11t2 10.5t2 7q0 2 5.5 11.5t5.5 11.5q1 1 3.5 8t5.5 15t5.5 15t3.5 9q9 25 21.5 50.5t23.5 51.5q2 3 4 10t2 9v10q0 2 5 9t5 9 q1 1 5.5 8t9.5 15t9.5 16t6.5 12q5 11 9 20t7 21q0 2 2.5 14t4.5 15l10 10q1 3 6 12t10.5 20.5t11 22t7.5 15.5q2 3 6 14.5t6 14.5q0 2 2 11t4 11q0 2 5 9.5t5 9.5q13 29 25.5 61.5t26.5 66.5t31.5 67t40.5 63q19 29 30 47t17.5 29.5t10.5 20.5t9 20t12.5 28t22.5 45 q1 1 4 8.5t7 16t7 16.5t4 10q0 2 3 6.5t3 6.5q0 3 -1 16t-1 16h-291q-5 0 -16.5 -1.5t-24 -3t-24.5 -3t-16 -2.5h-121l-11 41v293q4 15 5 27t5 20t13.5 12t30.5 4q43 0 84.5 -6t85.5 -6l757 -6q19 -2 34 -3.5t24 -6.5t11 -15.5t-6 -30.5q-9 -29 -15.5 -43t-4.5 -16 q-9 -30 -21 -67t-26.5 -73t-30 -67.5t-32.5 -50.5v-18l-68 -123l2 -2q7 -5 3.5 -17.5t-11 -26.5t-15.5 -26.5t-9 -18.5q-18 -51 -41.5 -105.5t-41.5 -105.5q0 -2 -3 -6t-3 -6l-18 -36l-27.5 -55l-32.5 -65t-33 -64.5t-29.5 -54.5t-21.5 -35q-5 -10 -14.5 -37.5t-21.5 -59 t-24.5 -60t-23.5 -41.5l37 1q12 0 35.5 1t49 2t48 2t33.5 1q3 1 16.5 1t29 0.5t29 0.5t17.5 1h2h4q3 -1 17.5 -1t31 -0.5t31 -0.5t17.5 -1q3 0 15 0.5t26 0.5h26t15 -1q4 0 13 -2t18.5 -4.5t18.5 -5.5t13 -5q7 -1 10 -9.5t3 -23t-1 -32.5t-1 -39v-19v-15t-1 -10v-8v-8 q1 -2 2 -9.5t2 -16.5t2 -17.5t1 -11.5v-51v-51q-6 -22 -22.5 -25.5t-35.5 -3.5q-6 -1 -30.5 -2t-52 -2t-52 -1.5t-30.5 -0.5h-121q-2 0 -11 -1t-19 -2t-18.5 -2t-11.5 -1h-22h-29q-9 0 -32.5 0.5t-50 1.5t-50.5 2t-33 2q-5 -2 -20.5 -4t-20.5 -2h-4h-8q-43 2 -93 1t-101 -1 t-100 4.5t-90 18.5q-9 3 -16.5 10.5t-7.5 19.5z" />
<glyph unicode="[" horiz-adv-x="708" d="M123 -174q-6 30 -8 56t-2.5 51.5t0 51.5t-1.5 56q-1 6 -1 31.5v54.5t0.5 54t0.5 30q0 8 -1.5 35t-4 57.5t-4 57t-1.5 33.5q-1 8 -1.5 34.5t-1.5 62.5t-2 76.5t-2 76t-2 62t-2 34.5l4 837q0 4 0.5 13.5t0.5 20t0.5 20t0.5 13.5q0 6 -0.5 16.5t-0.5 21t-0.5 18.5t-0.5 10 q0 10 -1.5 35t-3 53.5t-3 54t-2.5 35.5l-2 19q0 7 1.5 12.5t11.5 8.5q5 2 19.5 4.5t20.5 2.5t31.5 -0.5t54.5 -0.5h54.5t31.5 1q3 0 14.5 1.5t25 3t26.5 3t20 2.5q9 1 23.5 1.5t31 0.5h31t23.5 2q2 0 8.5 1t9.5 1q21 0 34 -1.5t21 -6.5t12 -15t7 -27q7 -38 10 -71.5t3 -75.5 q0 -7 -0.5 -19.5t-0.5 -25t-0.5 -22.5t-0.5 -11q0 -2 -0.5 -8.5t-1.5 -15t-2 -16t-2 -11.5q0 -9 -4 -22t-13 -19q-7 0 -19.5 -1.5t-26 -3.5t-26 -3.5t-19.5 -2.5q-2 0 -16.5 -5t-24.5 -8q-4 -2 -10 -4q-4 -1 -6 -2l7 -137q2 -2 3 -8.5t3 -9.5v-5q0 -14 -3 -25.5t-3 -25.5 q0 -55 -1.5 -106t-3 -100.5t-1 -100t3.5 -104.5q5 -59 7 -123t8 -123q0 -2 2 -4t4 -2v-4v-2q-2 -2 -4 -6t-2 -6v-88q0 -47 3 -92.5t3 -92.5q0 -9 -1.5 -14t-4.5 -16l23 -220q0 -2 2 -6t4 -6q12 -9 38.5 -9.5l53 -1t46.5 -5t20 -21.5v-14q-1 -17 -2.5 -49t-3.5 -65 t-3.5 -59.5t-2.5 -33.5v-25t-11 -20q-29 -20 -67 -23t-72 -6q-2 -1 -15 -0.5t-28 0.5t-27.5 0.5t-15.5 -0.5q-51 -8 -101.5 -13t-101.5 -5q-15 0 -24.5 3t-16.5 9t-12.5 15.5t-12.5 21.5z" />
<glyph unicode="\" horiz-adv-x="839" d="M425 -3q-7 62 -26.5 116.5t-36.5 111.5q0 3 -2 10.5t-4.5 16.5t-4.5 16.5t-2 9.5q-4 13 -6 25.5t-7 22.5q-3 12 -11 41.5t-17 62t-17 61t-11 39.5q-1 2 -2.5 9t-3 14.5t-3 13.5t-2.5 8q-1 4 -5 18t-9.5 30.5t-10 31.5t-7.5 22q-14 41 -21 87.5t-11.5 95.5t-9.5 97.5 t-15 92.5q-1 2 -2 6t-1 6q-7 20 -16 42.5t-11 47.5q-5 31 -6.5 59.5t-4 56t-7 54.5t-13.5 55q-1 2 -4.5 10.5t-7.5 18t-7.5 18t-3.5 11.5q-5 13 -7 30.5t-4 35.5t-4.5 35.5t-8.5 30.5q1 2 -3 7.5t-3 7.5q0 2 -1.5 9.5t-3.5 16.5t-3.5 17t-1.5 10q1 3 0 8t-1 7q-1 2 -4 13 t-3 13t5 8t8 7q8 3 21.5 7t22.5 5q2 1 7.5 3t7.5 4q21 6 38.5 7.5t31 1t23 -2t15.5 0.5q1 0 9 1.5t18 3t19.5 3t15.5 3.5q4 0 13 1.5t18.5 3t18.5 3t12 2.5q7 4 17 7.5t19.5 3t17.5 -5t12 -16.5q0 -2 0.5 -9.5t-0.5 -9.5q3 -11 7 -27t8 -23q0 -2 5 -4.5t5 -4.5q-1 -3 -1 -7 q-1 -3 -1 -5.5v-3.5q2 -25 12 -47.5t17 -46.5q3 -20 6 -39t9 -35q0 -1 3.5 -7t3.5 -7q0 -2 0.5 -6.5t0.5 -10.5v-11v-7q1 -3 3.5 -11.5t5.5 -18.5t6 -18.5t4 -10.5t2 -8t2 -13t2.5 -13t2.5 -9q5 -39 12 -73t15 -72q4 -19 6.5 -41t7.5 -43q17 -57 28 -118.5t31 -118.5 q1 0 1.5 0.5t1.5 0.5h1l20 -140q4 -37 9 -75t12 -74q2 -1 5 -9t3 -10q1 -1 1.5 -5.5t0.5 -10v-9.5v-5q2 -23 9.5 -44t14.5 -43q8 -29 18 -56t18 -54q3 -11 5 -27.5t8 -26.5q0 -1 7 -9t6 -11q2 1 0.5 -5.5t-2.5 -8.5q1 0 1.5 -4.5t1.5 -10.5t1.5 -11.5t1.5 -8.5 q0 -2 1.5 -7.5t1.5 -7.5q2 -6 6 -19t7.5 -26t6.5 -24t4 -14t6.5 -14t6.5 -14q-1 -1 -1 -3v-5q-1 -8 -3 -21t-13 -18q-2 0 -9 -2t-9 -2q-2 -1 -4.5 -1t-5.5 -1q-4 -1 -7 -1q-5 0 -24 -1.5t-40 -3.5t-40 -3.5t-24 -1.5q-1 0 -5.5 -1t-10 -1.5t-10 -1t-5.5 -0.5q-3 0 -13 -1.5 t-21.5 -2.5t-21.5 -2.5t-13 -1.5q-8 0 -23.5 -1.5t-32 -1.5t-30 2t-15.5 9z" />
<glyph unicode="]" horiz-adv-x="703" d="M598 1902q6 -30 8 -56t2.5 -51.5t0 -51.5t1.5 -56q1 -6 1 -31.5v-54.5t-0.5 -54t-0.5 -30q0 -8 1.5 -35t4 -57.5t4 -57t1.5 -33.5q0 -8 1 -34.5t2 -62.5t2 -76.5t2 -76t2 -62t2 -34.5l-4 -837q0 -4 -0.5 -13.5t-0.5 -20t-0.5 -20t-0.5 -13.5q0 -6 0.5 -16.5t0.5 -21 t0.5 -19t0.5 -9.5q0 -10 1.5 -35t3 -53.5t3 -54t2.5 -35.5l2 -19q0 -7 -1.5 -12.5t-11.5 -8.5q-5 -2 -19.5 -4.5t-20.5 -2.5t-31.5 0.5t-54.5 0.5h-54.5t-31.5 -1q-3 0 -14.5 -1.5t-25 -3t-26.5 -3t-20 -2.5q-9 -2 -23.5 -2h-31t-31 -0.5t-23.5 -1.5q-2 0 -8.5 -1t-9.5 -1 q-21 0 -34 1.5t-21 6.5t-12 15t-7 27q-7 38 -10 71.5t-3 75.5q0 7 0.5 19.5t0.5 25t0.5 22t0.5 11.5q0 1 0.5 8t1.5 15l2 16t2 12q0 9 4 22t13 19q7 0 19.5 1.5t26 3.5t26 3.5t19.5 2.5q2 0 16.5 5t24.5 8l4 2t5 2t7 2l-7 137q-2 2 -3 8.5t-3 9.5v5q0 14 3 25.5t3 25.5 q0 55 1.5 106t3 100.5t1 100t-3.5 104.5q-5 59 -7 123t-8 123q0 2 -2 4t-4 2v4v2q2 2 4 6t2 6v88q0 47 -3 92.5t-3 92.5q0 9 1.5 14t4.5 16l-23 220q0 2 -2 6t-4 6q-12 9 -38.5 9.5l-53 1t-46.5 5t-20 21.5v14q1 17 2.5 49t3.5 65t3.5 59.5t2.5 33.5v25t11 20q29 20 67 23 t72 6q2 1 15 0.5t28 -0.5t27.5 -0.5t15.5 0.5q51 8 101.5 13t101.5 5q15 0 24.5 -3t16.5 -9t12 -15.5t13 -21.5z" />
<glyph unicode="^" horiz-adv-x="799" d="M213 747q-18 4 -21 10t-5 8v1v2q5 13 12.5 28l13.5 27q3 7 9 18.5t12 25t11.5 27.5t9.5 27q5 8 8 16.5t6 18.5q8 28 13.5 40.5t13.5 22.5q1 2 4 3.5t5 1.5q4 0 14 0.5t21 1t21 0.5h14h35q2 0 12.5 2t12.5 2h4q11 2 11.5 -5t2.5 -12q1 -1 2 -5.5t1 -5.5l3 -6t3 -4 q-3 4 1.5 -11t12.5 -37t17 -46t15 -37q3 -5 3 -12t2 -12q3 -10 6.5 -20t7.5 -21q2 -5 6.5 -13t4.5 -14q0 -2 -2 -6t-4 -5h-13q-1 0 -3 -1.5t-3 -1.5t-11.5 -1t-15.5 -1q-20 -1 -40 -9q-11 -2 -20.5 -6t-20.5 -4q-7 0 -14 0.5t-11 7.5q-7 14 -10.5 29t-11.5 28q-2 -2 -2.5 -4 t-2.5 -4q-1 -4 -6 -14.5t-6 -13.5l-4 -8t-7.5 -11.5t-10 -9t-11.5 -1.5h-3q-16 0 -23.5 -0.5t-23.5 4.5q-3 1 -9.5 2.5t-13.5 3t-13.5 3t-8.5 1.5z" />
<glyph unicode="_" horiz-adv-x="805" d="M50 -38q-2 10 -1 20.5t0 20.5q0 3 0.5 14t1.5 24t1.5 24t0.5 14q0 30 -2 59.5t1 58.5q1 15 16 25.5t28 11.5q4 0 18.5 -2t31.5 -3.5t32 -2.5t18 -1h17.5t29 0.5t29 0.5h16.5t15 -1.5t26.5 -2.5t27 -2t16.5 -1q45 -4 88.5 0.5t89.5 3.5q1 1 19.5 0t43 -2.5t50 -3.5 t41.5 -3q2 0 4.5 -0.5t4.5 -0.5q18 -2 23 -13t4 -27t-5 -32.5t-4 -28.5q0 -3 1 -11.5t2 -18t2 -18t1 -11.5q1 -11 0 -18t-3 -15q-2 -18 3 -37t3 -33q-1 -1 -1 -4v-3q-2 -2 -9 -8t-10 -6q-6 1 -18.5 -1.5t-19.5 -4.5h-18.5h-38h-48.5h-48h-38h-18h-9t-15 -0.5t-15 -0.5h-9 q-3 0 -13.5 -0.5t-22 -1.5t-22 -1.5t-13.5 -1.5q-5 0 -22 0.5t-36.5 1t-36.5 0.5h-22q-31 -1 -45.5 -0.5t-26.5 2t-27 3.5t-47 5q-3 1 -12.5 3.5t-14.5 3.5q-5 3 -9 12.5t-6 13.5z" />
<glyph unicode="`" horiz-adv-x="379" d="M53 1601v3l3 6q1 4 5 6t9 3t9.5 1.5t6.5 0.5h22h1h2q5 0 17 1t14 1q1 1 6.5 2.5t7.5 1.5t7.5 0.5t12 1t12 1t7.5 0.5t8 1.5t8 1.5h1q5 0 13 -2.5t10 -7.5q1 0 2 -3.5t1 -4.5q1 -2 6 -11.5t11 -20t11 -20t6 -11.5t3.5 -8.5t5 -14t4.5 -14.5t2 -8q3 -3 3 -6 q11 -18 14 -32.5t11 -32.5q2 -2 6.5 -12.5t5.5 -12.5v-3q0 -2 0.5 -3t0.5 -2q0 -12 -2 -21.5t-14 -5.5q-1 0 -6 -1.5t-11 -3t-11 -2.5t-6 -1q-14 -2 -25 -5.5t-20.5 -7t-20 -6t-24.5 -2.5q-4 0 -11.5 0.5t-8.5 0.5l-9 6l-2.5 4.5t-5.5 11.5t-6.5 14t-6.5 12 q-14 29 -25.5 58.5t-25.5 57.5q-11 23 -17 43t-17 43v3z" />
<glyph unicode="a" horiz-adv-x="1470" d="M1031 6q-12 7 -10.5 20t0.5 25q0 2 -3 6t-3 6v9q0 14 6 25t6 24v6q-3 0 -9.5 -2t-8.5 -4q-7 -5 -22.5 -15t-33.5 -21t-35 -20t-26 -10l-78 -32h-6q-2 0 -7 -1t-10.5 -2.5t-11 -2.5t-6.5 -1h-61h-34t-28.5 1t-28 2t-32.5 4q-2 1 -10.5 3t-18 4t-18 3.5t-10.5 1.5h-52 l-33 13q-7 3 -21.5 11t-31 17t-31.5 17t-22 11q-6 3 -18 8.5t-24.5 12t-23.5 11.5t-14 7q-1 1 -5 4.5t-9.5 8.5t-11 9.5t-8.5 6.5q-25 25 -48 55t-46 57q-21 25 -35 66t-23 86.5t-13 89.5t-4 76q0 41 0.5 76t4 68.5t10.5 67.5t20 73q1 6 7.5 25.5t13.5 39t12 31.5t4 1 q16 46 42 85.5t59 73.5t71.5 63t79.5 54q4 3 18.5 10.5t31 15.5t32 15.5t21.5 9.5q1 1 6.5 2.5t13 3.5t15 3.5l12.5 2.5q6 2 16 4t12 2h197q35 -10 68 -18.5t63.5 -21t59 -30t55.5 -45.5h4q0 3 0.5 8.5t0.5 11.5t0.5 11.5t0.5 7.5q0 1 1 7t2.5 13t3 12.5t1.5 6.5 q-5 7 -1 14.5t11.5 12.5t16.5 6.5t15 -2.5q50 0 88 -0.5t74 -2t74.5 -5.5t88.5 -10q3 -2 10 -5.5t7 -8.5q0 -9 1 -22t2 -27.5t2 -28t0 -23.5q0 -2 -1 -12t-2 -22t-2 -22t-1 -12q0 -3 -3 -14.5t-3 -13.5q0 -3 0.5 -12.5t0.5 -20v-20t-1 -11.5q0 -3 -2 -9t-4 -9l-2 -236v-16 v-44t0.5 -94.5t1.5 -125.5t2 -137.5t2 -129.5t3 -102q0 -3 -1.5 -15.5t-3 -27.5t-3 -27.5t-0.5 -15.5v-8v-8q-2 -3 -13.5 -7t-13.5 -6q-27 0 -46.5 -2t-37 -4.5t-36 -4.5t-45.5 -1h-47q-7 0 -23.5 0.5t-35 1.5t-35 2t-23.5 2zM440 664q0 -53 17.5 -98t45.5 -89q2 -3 6 -9.5 t6 -6.5q24 -26 49.5 -50t54 -42.5t60.5 -29.5t70 -11q32 0 65 11t62 23q4 2 11.5 5.5l15 7t13 6.5t7.5 4q37 28 61 66.5t38.5 82t20 90t7.5 89.5q0 5 -0.5 17t-1.5 25t-2 24.5t-2 15.5l-9 18q-4 8 -8 15t-6 12q-20 38 -40.5 73.5t-54.5 56.5l-18 13.5t-21.5 15t-22.5 14 t-20 8.5q-4 1 -14.5 4t-22.5 6t-22.5 5t-14.5 3q-6 9 -18 10.5t-26.5 0t-28.5 -4.5t-23 -3q-15 0 -32 -5.5t-32.5 -14.5t-30 -20t-25.5 -23q-2 -2 -8.5 -10t-14 -16.5t-14.5 -16.5t-8 -10q-38 -42 -53 -99q-9 -40 -12.5 -80.5t-3.5 -82.5z" />
<glyph unicode="b" horiz-adv-x="1565" d="M803 11q-13 4 -28.5 11t-31.5 15.5t-30.5 16.5t-26.5 15q-1 1 -5.5 4.5t-10.5 8t-12 9.5t-9 8q-11 7 -16 13t-9.5 12t-11 11t-19.5 9q0 -2 -1.5 -6.5t-1.5 -6.5q-1 -2 -1.5 -7t-1 -11.5t-1 -12t-0.5 -8.5q-1 -4 -1.5 -13.5t-1 -21t-0.5 -21v-13.5l-11 -13l-224 -11 q-9 5 -18 5t-19 -1l-65 6q-14 -2 -25 -2.5t-21 0.5t-20 4t-23 7q-3 1 -8.5 4.5t-8.5 5.5q-5 2 -11 9.5t-7 12.5q-8 32 -9.5 61t-3.5 61q0 6 -0.5 15t-0.5 17.5t-0.5 15t-0.5 7.5l16 470v6q3 65 7 133.5t6 133.5q0 7 -0.5 33t-0.5 55.5t0.5 55.5t0.5 33q1 54 -0.5 113 t-4.5 116q0 3 -0.5 10.5t-1 15.5t-1 15.5t-0.5 9.5v54v77.5t0.5 76.5t2.5 52q3 10 9 12t14 2q12 1 23 -2t24 -2q26 2 51 7.5t50 8.5q37 5 70 8t67 5h16q4 0 9 1q3 0 15 -1.5t14 -3.5q1 0 7.5 -0.5t13 -0.5t12.5 -0.5t8 -0.5q9 -3 14.5 -19.5t8.5 -36t4 -37t1 -22.5v-10 q0 -4 1 -7l-16 -254l-33 -147q19 15 39.5 37t45 43.5t55 39t69.5 24.5q44 14 83.5 20.5t87.5 8.5q79 1 157 -26.5t161 -70.5q8 -7 25.5 -22t37 -31t36.5 -30t23 -19q23 -23 42.5 -44.5t36 -44t30.5 -47.5t27 -54q7 -18 14.5 -41.5t13 -48.5t9 -50t4.5 -46q1 -24 0.5 -43 t-2.5 -37t-4.5 -36.5t-5.5 -42.5q-22 -151 -86.5 -281t-184.5 -227q-29 -24 -56 -41.5t-55.5 -30.5t-60 -22.5t-68.5 -15.5q-2 0 -8.5 -0.5t-9.5 -0.5q-5 -1 -13 -1h-10q-8 0 -29 0.5t-44 1t-43.5 1.5t-27.5 2zM560 614q0 -3 3 -14.5t5 -13.5q9 -34 22 -60.5t31 -48.5 t41 -41t52 -38q23 -14 48 -27t53 -15q2 0 15.5 -2t23.5 -1q0 -2 8.5 0t20 5.5l23 7t17.5 5.5q40 22 67 45.5t54 61.5q4 5 11.5 16.5t15 24.5t13.5 24.5t7 16.5q2 5 6 17.5t8 27t7.5 26.5t3.5 17q1 1 1 11.5v25t0.5 30t0.5 25.5q-1 1 -1 3v5v8l-2.5 15t-2.5 18t-2 16t-2 9 q0 2 -2.5 5.5t-4.5 5.5q-1 1 -4.5 4t-7.5 6.5t-7.5 7l-4.5 4.5q0 2 -0.5 11.5t-0.5 12.5l-2 4q-1 2 -2.5 3.5l-2.5 2.5q-3 3 -13.5 14t-15.5 13q4 11 -6 18t-18 6q-37 24 -66.5 40t-60.5 23.5t-69.5 5t-93.5 -15.5q-47 -20 -79.5 -63t-52.5 -95.5t-28 -108t-6 -100.5v-4z " />
<glyph unicode="c" horiz-adv-x="1453" d="M120 379q-3 6 -9.5 21t-14 32t-13.5 32t-8 21q0 2 -1.5 13.5t-2.5 17.5q-14 94 -3.5 192t33.5 187q20 72 53.5 140t81 124.5t109 98t138.5 60.5q52 13 110.5 22t112.5 13q5 0 13.5 1t16.5 1.5t14 1t7 0.5q46 0 98 -2t101 -13q43 -9 92 -22t90 -35q3 -1 15 -7t25.5 -13 t25 -13t14.5 -7q27 -23 39 -34t21.5 -20.5l22.5 -22.5t42 -41q3 -5 8.5 -11t8 -14.5t-1 -20.5t-17.5 -27q-1 -1 -17.5 -13t-38.5 -29.5t-44 -36t-33 -31.5q-24 -36 -47.5 -45t-40.5 -4h-4h-2q-18 3 -26.5 6t-14.5 7t-13 10t-22 15q-17 10 -41.5 18t-43.5 11q-14 3 -35.5 7 t-42.5 7.5t-37 6.5t-18 4q-7 0 -14 -1q-6 -1 -12.5 -1.5t-10.5 -0.5q-21 -2 -37 -2.5t-33 -8.5q-37 -17 -64 -46t-47 -63.5t-34 -72t-26 -73.5q-9 -29 -12.5 -61t1.5 -63q6 -43 19.5 -78.5t36 -62.5t54.5 -45.5t77 -27.5q9 -2 25 -4.5t31 -5t26.5 -4.5t13.5 -2h8.5t17.5 0.5 t19.5 1t15.5 0.5q3 0 12 1t18.5 2.5t18 2.5t11.5 1q14 7 28 10.5t26 11.5q19 10 46.5 27.5t44.5 31.5q20 15 35.5 26.5t42.5 13.5l20 2t18 -5q2 -2 11 -8.5t11 -6.5q2 -2 14 -10l25.5 -17t26 -17t16.5 -10l7 -4q3 -2 12.5 -8.5t20.5 -13.5t20.5 -13t11.5 -7q6 -5 8.5 -7 t4 -4t2 -5t1.5 -10q2 -12 1.5 -17t-8.5 -16q-51 -69 -109 -126t-124 -111q-46 -26 -85 -40.5t-73.5 -21.5t-66 -9.5t-61.5 -5.5q-5 0 -17 -1t-25 -2t-24.5 -1.5t-17.5 -0.5q-52 3 -99.5 7.5t-96.5 21.5q-3 1 -15.5 4.5t-27.5 7.5t-28 7.5t-17 4.5q-43 15 -86 40t-83.5 56 t-76 66.5t-62.5 70.5q-2 3 -9.5 14.5t-16 25t-16 25t-9.5 14.5q-2 2 -7.5 8t-7.5 8z" />
<glyph unicode="d" horiz-adv-x="1407" d="M45 477q0 8 3 15t3 15q0 31 -3 60.5t-3 60.5v41q3 64 9.5 123t19 115.5t32 111.5t48.5 111q1 2 5.5 10.5t9 18t8.5 18t5 10.5q2 3 9 12t10 11q4 5 14 15l20 20t18.5 18t10.5 10q1 1 6.5 5t13 8.5t14.5 9t11 6.5t11 6t14 7.5t13.5 6t8.5 2.5q6 3 23 9.5t36.5 13t36.5 11.5 t25 7l12 3t17 4t17.5 3.5t11.5 2.5h53q37 0 66 -6t64 -16q39 -7 76 -20.5t71.5 -31t66.5 -36t61 -34.5q1 1 2 6.5t2 12t1.5 12.5t0.5 8v8q0 47 -3 93.5t-3 93.5v41q1 11 1 30t-0.5 39t-1 37.5t-0.5 25.5q2 12 6 24.5t4 14.5l6 6l18 2q8 1 15 2t12 2q34 2 59.5 3t54.5 1 q25 0 45.5 1.5t40 2.5t40 0.5t44.5 -4.5q23 -13 26 -29q0 -2 0.5 -9.5t0.5 -15.5t0.5 -15.5t0.5 -10.5q0 -5 -0.5 -13.5t-0.5 -16.5t-0.5 -14.5t-0.5 -7.5q-2 -53 -2.5 -102.5t-0.5 -98t-1 -98t-3 -102.5q-2 -57 -4.5 -121.5t-2.5 -121.5q0 -8 0.5 -36t1 -60.5t1 -61 t0.5 -36.5q0 -1 -0.5 -10t-0.5 -21.5t-0.5 -25.5t-0.5 -20q0 -8 0.5 -21t0.5 -26t0.5 -23.5t0.5 -11.5q0 -3 -1.5 -14t-3 -23t-3 -22.5t-1.5 -13.5q1 -5 0.5 -21t-1.5 -34t-1.5 -34.5t-0.5 -22.5q0 -5 -0.5 -27t-1 -47t-1 -47t-0.5 -27q0 -2 0.5 -11.5t0.5 -22.5t0.5 -26 t0.5 -20q0 -5 -0.5 -20.5t-0.5 -33.5t-0.5 -34t-0.5 -20q-2 -21 -24 -30t-49 -11t-50.5 -1t-27.5 -1h-30t-30 -6h-127l-10 11l-12 98q-41 -38 -87 -59t-88.5 -32.5t-78.5 -15t-57 -5.5h-32q-15 1 -39.5 2t-50 1.5t-46 1.5t-27.5 2t-22 4.5t-31.5 7t-31 7.5t-19.5 6 q-3 1 -13 5.5t-21 10t-20.5 11t-13.5 8.5q-5 3 -17 11l-25.5 17t-24.5 17t-15 12q-6 7 -11 13q-5 5 -10 11t-8 9q-24 32 -39.5 63.5t-33.5 69.5q-11 23 -23 48.5t-18 49.5q-1 2 -3.5 13t-5 24t-5 24t-3.5 13q-2 2 -6 9t-6 9v3zM506 434q0 -1 5 -7t12 -13t15 -14.5t13 -11.5 q2 -2 11 -6t11 -6t9.5 -6t9.5 -6q3 -2 11.5 -6t10.5 -4q17 -7 29.5 -7h32.5q49 0 97.5 16t100.5 51q9 8 19.5 15t18.5 15q0 1 5 7t11.5 13.5t12 13.5t6.5 8q2 4 7.5 14t11 21t11 20.5t7.5 14.5q3 8 4.5 12.5t1.5 12.5l4 13q3 9 8 28.5t14 54.5q0 2 2 14.5t4 20.5q1 5 1.5 16 t0.5 24v32q0 3 -0.5 12t-1.5 19t-2 19t-2 13q0 2 -2 6t-4 6t-6.5 7.5t-10 12t-11 12.5t-7.5 9q-28 29 -61.5 53t-71.5 40q-2 0 -10 2q-4 1 -7 2h-137q-5 9 -8.5 10.5t-11.5 1.5q-18 0 -39 -4t-41 -12.5t-38 -20t-30 -26.5q-2 -3 -8.5 -12.5t-15 -21.5t-16 -23.5t-11.5 -16.5 q0 -2 -3 -6.5t-3 -6.5q-17 -30 -31.5 -59.5t-19.5 -66.5q-1 -5 -2 -15.5t-2 -22.5t-1.5 -22t-0.5 -14q0 -3 2 -14.5t4 -14.5l9 -27t12 -36.5t11 -34t7 -19.5z" />
<glyph unicode="e" horiz-adv-x="1433" d="M67 689q6 37 15 72.5t20 71.5q8 26 13.5 46t13.5 45q0 2 2.5 11t6 19.5t6.5 19t4 10.5q11 35 32 63t44 56q1 1 6.5 7.5t12.5 14t13 14.5t9 10q1 1 4 5t6.5 9.5t6.5 9.5t5 5q42 36 92.5 65t105 50t111 32.5t111.5 12.5q62 5 129 -2t125 -33q49 -15 84.5 -34t60 -37 t40.5 -32.5t28 -20.5q31 -27 56 -53t45.5 -54t38.5 -59.5t35 -70.5q3 -9 8.5 -32.5t11.5 -49.5t11 -49.5t6 -32.5q1 -2 1.5 -9t0.5 -17v-19.5v-15.5t-0.5 -16.5t-0.5 -21v-18.5t-1 -9q0 -3 -3 -12.5t-6 -20t-5.5 -20t-2.5 -11.5q-20 -20 -40.5 -27.5t-48 -9.5t-66 -2.5 t-93.5 -6.5h-19h-33t-33 -0.5t-19 -0.5h-10q-2 -2 -8.5 -3t-13.5 -0.5t-12.5 2.5t-6.5 6q-1 0 -9 -0.5t-17.5 -0.5h-19t-12.5 1q-1 -1 -3 -1h-5q-24 -1 -55 -2t-63.5 -2t-63.5 -1.5t-55 -0.5q-36 -2 -64.5 -0.5t-55 3t-55 2.5t-64.5 0q-5 0 -10 -0.5t-7 -5.5q0 -5 2.5 -15 t2.5 -13q9 -36 12.5 -51.5t6.5 -22t7.5 -11t14.5 -18.5q0 -1 3.5 -4.5t8 -7.5t8 -7.5t3.5 -4.5q33 -53 87 -76.5t111 -21.5q8 0 22 0.5t16 0.5q20 2 29 1.5t15 -1.5t12.5 -1.5t21 1.5t40 7.5t70.5 16.5q1 0 11 5t21.5 11t22 11.5t12.5 6.5q26 16 47 31.5t38.5 28.5t33 23 t30.5 16h2h4q2 1 6 -1.5t4 -4.5q9 -8 27 -20.5t36.5 -25.5t35.5 -25.5t25 -21.5q3 -2 14 -10t23 -17.5t21 -18t9 -9.5v-4q0 -2 0.5 -3t0.5 -3q1 -25 -14.5 -44t-32.5 -37q-47 -51 -99.5 -99.5t-114.5 -80.5q-20 -9 -40 -13.5t-40 -11.5q-26 -8 -50 -11.5t-47 -4.5 t-47.5 -0.5t-52.5 -0.5q-72 -2 -137 5t-134 27q-26 8 -48 17.5t-41.5 21t-38.5 26t-39 31.5q-35 30 -71 58t-68 66q-2 1 -8.5 12t-7.5 14q-2 2 -8 9.5t-12.5 16t-13 16t-7.5 9.5q-2 3 -8.5 15.5t-15 29t-16 32.5t-11.5 26q-2 2 -4 8t-2 8q-12 66 -20.5 129t-7.5 131v5z M779 1009q-51 -1 -95 -12.5t-86 -40.5q-14 -9 -31.5 -23t-34 -30.5t-27.5 -35t-11 -36.5q26 2 48 6t47 5h4q2 -1 12.5 -1.5t23 -1t23.5 -1t14 -0.5h13h27h31h25t25 1t32.5 2t29.5 1.5t15 0.5q10 0 36.5 0.5t56.5 1t56.5 1.5t36.5 2q2 0 4 2l2 2q0 2 -2 6t-4 6 q-2 4 -5.5 10.5t-7.5 13t-7 11t-4 5.5q-44 55 -111.5 81t-135.5 24z" />
<glyph unicode="f" horiz-adv-x="938" d="M339 -2q-5 0 -16.5 -0.5t-23.5 -1.5t-23.5 -2t-16.5 -2q-25 3 -30 15t-5 35q0 21 3 42.5t3 43.5v10q-14 184 -20.5 363.5t-4.5 363.5l-4 57q-1 5 -8.5 7.5t-17.5 4t-20 1.5h-16q-18 0 -35 -3t-34 -3h-19l-6 6q-1 0 -2.5 11t-3.5 26t-3.5 31t-1.5 25v200q0 3 2 10t4 9h4 q11 0 20.5 -3t20.5 -3q31 0 65 8.5t65 7.5l6 6l-3 164q1 6 2 11l2 10t2 8q1 6 4.5 18.5t7 26.5t6.5 26.5t5 18.5q0 3 2 8.5t4 7.5l6.5 13t9 18.5t8 17t5.5 9.5q18 30 40.5 50t48.5 33t56 20.5t62 13.5h29q2 0 11.5 0.5t20.5 1t20 1t11 0.5l41 -6q30 -5 56.5 -10t53.5 -13 t55.5 -20t61.5 -29q9 -5 19 -6.5t16 -9.5q3 -3 9 -12t9 -11q-11 -23 -27 -53t-24 -53q-8 -20 -15 -38t-13 -38q-3 -5 -4.5 -12t-3.5 -13t-6.5 -10t-12.5 -4h-2q-28 5 -52.5 9t-52.5 4q-2 0 -8 -0.5t-12 -0.5t-11.5 -0.5t-6.5 -0.5q-22 -8 -38.5 -20.5t-21.5 -37.5 q0 -4 -0.5 -12.5t-1.5 -17.5t-1.5 -17t-0.5 -10q0 -4 2 -10q1 -4 2 -6l139 -2h15t15 -3t11 -11t4 -24l-2 -289q-2 -7 -3.5 -10.5t-6.5 -6t-14.5 -5t-25.5 -7.5q-25 0 -50 -2.5t-46 -10.5q-1 -6 -2 -24.5t-1.5 -39t-1 -39t-0.5 -24.5q-1 -11 -1 -37.5v-55.5t0.5 -55t0.5 -36 v-29q0 -15 0.5 -51.5t1 -77t1 -77t-0.5 -52.5v-4q3 -32 3 -59t-1.5 -53.5t-3 -54t-1.5 -58.5v-49l-7 -24q-7 -5 -14 -9q-14 -9 -22 -9q-5 0 -13.5 0.5t-17.5 0.5t-16.5 0.5t-8.5 0.5q-9 1 -24 -1.5t-32 -4t-34 -0.5t-29 9h-64z" />
<glyph unicode="g" horiz-adv-x="1495" d="M99 -9q0 5 5.5 16t10.5 11h183q3 -2 11.5 -4t10.5 -2h7h6q4 0 16.5 0.5t27 1t27 1t16.5 1.5h2h4q5 -3 16 -7.5t13 -4.5q12 -8 18.5 -14.5t14.5 -18.5q1 -2 3 -8.5t5.5 -15t7 -16.5t7.5 -12q11 -30 42.5 -52t81.5 -28h6q56 -8 82.5 -8t41.5 5q50 8 100.5 25.5t89.5 52.5 q19 17 33 40t23 49.5t13.5 55t4.5 55.5v18q-34 -26 -78 -37.5t-84 -19.5q-60 -12 -113.5 -18t-115.5 -6q-5 0 -17 1t-25.5 2.5t-25.5 3t-16 1.5q-59 9 -117 34t-106 62q-4 3 -14 8.5t-21.5 11t-22 11t-14.5 10.5q-6 5 -17.5 16t-23.5 23l-22 22l-13 13q-23 28 -36 55.5 t-27 58.5q-37 82 -47.5 163t-10.5 169q-2 28 -1.5 49t4 40t10 37.5t16.5 41.5q0 1 3.5 13t8.5 27t10 30.5t9 25.5q13 35 23 56.5t21 38t25 32.5l35 40q3 3 9.5 10t14 14.5l14 14t9.5 8.5q1 1 14.5 8.5t31.5 18t36 21.5t27 17q14 8 35 13.5t35 8.5q55 11 102.5 18t103.5 7 q34 0 70.5 -5t73.5 -12.5t72.5 -16.5t68.5 -17q17 -11 34 -15t34 -10q2 0 4 -2l2 -2q9 -12 20 -26.5t27 -20.5v4q0 32 1 53.5t1 53.5v10l12 7q1 0 9 0.5t19 0.5t22 0.5t17 0.5q9 0 26 -0.5t33.5 -0.5t30 -0.5t15.5 -0.5t12 -1t21.5 -2t22 -2t13.5 -2h11q14 0 24 -4t13 -4 q20 -3 30.5 -8t10.5 -24q0 -20 -3 -39t-3 -39v-2q0 -2 3 -6t3 -6v-2q0 -14 -3 -26t-3 -29q0 -66 4.5 -130.5t10.5 -129t10.5 -129t4.5 -129.5q0 -59 -6.5 -115.5t-11.5 -115.5v-35q-11 -128 -41 -250.5t-90 -236.5l-4 -4q-1 -2 -2 -3q-29 -40 -61 -80.5t-72 -68.5 q-8 -5 -25 -16.5t-35 -23.5t-34 -22.5t-21 -13.5q-1 -1 -6 -2.5t-12 -3.5t-14.5 -4.5t-11.5 -4.5q-3 -2 -10 -3t-9 -3q-2 0 -7.5 -1t-12 -2t-12 -2t-7.5 -2q-1 0 -7 -2q-3 -1 -5 -2h-2h-4q-3 0 -19.5 -1t-35 -2.5t-35 -3t-19.5 -2.5q-2 0 -11.5 0.5t-20 1t-20 1t-11.5 0.5 q-28 -2 -48.5 2t-48.5 7q-21 0 -46 4t-51 10t-51 13t-45 13q-35 10 -61.5 21.5t-50.5 25.5t-47.5 31.5t-52.5 40.5l-4 4q-26 32 -51 57t-40 63q-2 3 -6 16t-6 19q-8 25 -14.5 47t-14.5 45v2zM444 607q0 -2 2 -8.5t4 -8.5q2 -5 1.5 -17.5t4.5 -20.5q7 -15 20 -35t29 -39.5 t34 -36t35 -22.5q1 0 6.5 -1.5t13 -3t14.5 -3t11 -2.5q31 -8 60.5 -10t60.5 -2q32 0 69.5 4t72 15t63 31t43.5 52q1 4 5 14t8.5 21t8.5 21t6 14q23 70 17.5 135t-22.5 131q0 12 -5.5 23t-11.5 22q-2 4 -8 13.5t-12.5 21t-12.5 21.5t-8 14q-26 24 -50 37.5t-49 19.5t-53 6.5 t-61 -2.5q-65 0 -119 -35t-93.5 -87.5t-61.5 -115t-22 -117.5v-49z" />
<glyph unicode="h" horiz-adv-x="1284" d="M97 -16h-11.5t-6.5 8v2q-9 -8 -17 5.5t-6 62.5v14q-2 63 1 124t6.5 117.5t6.5 108.5t2 99q0 11 -6 17.5t-6 15.5v6q0 2 5 9.5t7 9.5q0 1 -2 7t-4 14.5t-4 16.5t-2 13q1 7 2 22t2 30.5t1.5 28.5t0.5 17q1 7 0.5 29.5t-1.5 48.5t-2 48.5t-1 29.5q2 88 4 172.5t2 169.5 q0 6 0.5 10.5t5.5 9.5v127q-1 32 0.5 57.5t3 50t3 50t1.5 57.5q0 5 1 21.5t1 21.5q1 4 0 15.5t-0.5 23.5t2.5 21.5t9 9.5l67 16q1 0 7.5 1l13 2t12.5 2t8 1h143q3 0 12 -0.5t19 -1.5t19.5 -2t13.5 -2q8 0 19.5 -8t14.5 -19q9 -36 12.5 -74t9.5 -67q0 -9 1.5 -37t3 -65.5 t3 -79t3 -79t2.5 -65.5t2 -37v-12q22 8 37 19.5t34 23.5q1 0 6.5 2.5t11.5 5.5l11 5.5t6 3.5q54 31 114.5 39t122.5 8q6 0 15.5 -0.5t18.5 -0.5t16 -0.5t8 -0.5t9 -2t17.5 -5t19.5 -6t15 -4q2 -1 12 -4.5t22 -8l24 -9t18 -6.5q21 -9 40.5 -23t37.5 -30.5t34 -34.5t31 -33 q2 -2 6 -15t6 -15q3 -7 8.5 -18l11 -22t9.5 -19.5t5 -9.5q0 -2 2 -8.5t5 -15t5.5 -16t3.5 -11.5q2 -8 3.5 -39t2.5 -69t1 -76.5t-1 -62.5l-4 -99l7 -75l-1 -17q-2 -40 3.5 -102t5.5 -136v-60q-1 -12 -1.5 -41t-1 -61t-1 -61t-1.5 -41q-5 -12 -23 -25.5t-32 -15.5 q-6 0 -47.5 -1.5t-137.5 3.5q-2 -2 -8.5 -4t-9.5 0q-2 0 -8 0.5t-13.5 1.5t-13.5 2t-7 2q-5 1 -14 1.5t-19.5 1t-20 1t-14.5 0.5q-2 0 -10.5 1.5t-10.5 -0.5h-6q-2 2 -6.5 6t-6.5 6v6q1 1 2.5 8t2.5 14.5t1.5 14t0.5 8.5q1 7 1.5 35t1.5 60t1.5 60t1.5 35q0 5 1.5 24.5 t3.5 41.5t3.5 41.5t1.5 24.5q0 3 1 23t2.5 46.5l3 53t1.5 41.5q0 10 -0.5 33.5t-0.5 50t-0.5 49.5t-0.5 33q0 3 -1.5 12t-3.5 18.5t-3.5 18.5t-1.5 12v6q-2 5 -6 18t-8.5 28t-9 28t-5.5 18q-4 11 -7.5 17t-8 10t-10.5 8t-15 12q-13 11 -21.5 17t-17 9t-19 3.5t-28.5 0.5 q-15 0 -28.5 -0.5t-28.5 -5.5q-27 -9 -50 -29.5t-41.5 -46.5t-31.5 -55.5t-20 -54.5q-2 -2 -4.5 -12.5t-2.5 -15.5q-1 -2 -2 -8.5t-2 -14t-1.5 -14.5t-0.5 -8q-1 -6 -5.5 -25.5t-10.5 -42t-11.5 -42t-7.5 -24.5t-3 -17t-3 -17q-2 -17 -5.5 -49t-8 -65t-7.5 -59.5t-3 -32.5 v-62q0 -9 0.5 -30t1.5 -43.5t0.5 -41t-2.5 -22.5q0 -20 -1 -45.5t-1 -44.5v-5t-2.5 -8.5t-8 -9t-16.5 -6.5z" />
<glyph unicode="i" horiz-adv-x="631" d="M104 809q0 7 -1 36.5t-1.5 66.5t-1.5 74.5t-1 60.5q1 3 2 11t2 17.5t1.5 17.5t0.5 11v121q6 9 22 13.5t25 4.5h286q8 -3 14.5 -4t11.5 -6.5t8 -19.5t3 -44q1 -2 2 -8.5t2 -14t1.5 -14t0.5 -8.5q0 -14 1.5 -51t3 -78.5t3 -78.5t1.5 -51q0 -8 2 -36t5 -60t5 -60.5t2 -35.5 q0 -9 1 -34.5t3 -59t4 -71.5t4 -72t3 -59.5t2 -33.5q1 -15 1 -47t0.5 -67.5t1.5 -67.5t3 -47v-14q5 -39 -5.5 -60t-40.5 -15l-317 2q-23 0 -31.5 13.5t-11 35t-2.5 50t-4 58.5q-2 22 -2 48.5t0.5 53t1 52.5t-0.5 48q-3 58 -5 109.5t-3 102t-1.5 102.5t-0.5 109zM77 1576 v28.5t7 29.5q11 21 19.5 40.5t25.5 36.5q4 4 12.5 10.5l17 13t16 12t9.5 7.5q11 9 23.5 12.5t26 4t27.5 -0.5t27 -1q17 0 28.5 -4.5t28.5 -11.5q8 -2 21.5 -9.5t21.5 -13.5q40 -28 68.5 -67t33.5 -93q0 -32 -2 -54t-9 -40.5t-21 -35t-38 -36.5q-22 -19 -54 -33t-61 -14 q-3 0 -10.5 0.5t-16 1.5t-15.5 2t-9 2q-5 1 -13 3t-16 5t-15 5t-9 3l-9 4.5t-16 7t-17 6.5t-10 5q-23 18 -37 36.5t-21.5 39t-10.5 44.5t-3 54z" />
<glyph unicode="j" horiz-adv-x="550" d="M-182 -276q0 2 3.5 13.5t3.5 14.5q0 4 0.5 18t1.5 30.5t2 32t2 22.5q0 4 -1 -0.5t1 -1.5q0 6 1.5 14.5t5.5 17t9.5 14t14.5 5.5h2l60 -11h18q11 0 25 0.5t27.5 3t25.5 8t19 16.5q19 28 27.5 60.5t13 65t6.5 63t7 56.5q1 5 2 12.5l2 15t1.5 13.5t0.5 7q0 3 0.5 15.5 t2 29.5t2.5 37t2.5 37t2 29.5t0.5 15.5q0 2 2 16t4.5 30t4.5 30t2 17q2 17 2.5 44t0.5 54.5t-0.5 49.5t-0.5 30v182v181q1 4 -0.5 10.5t-3.5 14t-3 14.5t1 12q0 3 -3 15t-4 14q-3 27 -5.5 58.5t-4.5 57.5q-6 8 -1 15t5 18q0 10 15.5 16.5t36.5 11t42.5 7t32.5 3.5h54 q4 0 12.5 0.5t16.5 0.5t14 0.5t7 0.5q3 -1 13 -0.5t21.5 1.5t21.5 1t14 -1q8 -5 11.5 -12t5.5 -17q1 -5 2.5 -14.5t3.5 -20.5t3.5 -20.5t2.5 -13.5q1 -12 3.5 -40.5t6 -67.5t8 -84.5t9 -92.5t9 -91t8.5 -80q5 -88 8 -170t13 -170v-23q-4 -33 -5 -81t-2.5 -106t-5.5 -124.5 t-16 -138.5q4 -2 4.5 -8.5t-1 -13.5t-4 -13t-5.5 -6q-9 -22 -11 -45.5t-12 -46.5q-44 -57 -81.5 -93t-76.5 -59t-83.5 -36.5t-101.5 -25.5h-58.5t-58.5 2t-57 8.5t-55 18.5q-14 6 -27 11.5t-18 22.5q-7 20 -7 32v32v29zM46 1578q0 2 0.5 8.5t1.5 14t2 14t2 8.5q0 6 2.5 17.5 t4.5 11.5q1 2 5.5 9.5t10.5 16.5t12.5 16.5t9.5 9.5q2 2 9.5 12t17.5 15q15 9 28.5 14.5t31.5 10.5q20 5 47 8.5t50 3.5q3 0 9.5 -1t8.5 -1t10.5 -3t18 -6.5t19.5 -7.5l15 -6q15 -6 30 -16.5t29 -24t25.5 -28.5t17.5 -29q1 -10 4 -15.5t6 -13.5l3 -82q0 -5 -4 -16t-9 -22.5 t-10.5 -21.5t-8.5 -14q-35 -48 -88 -70t-113 -22q-43 0 -79 14.5t-62.5 41t-41.5 64t-15 82.5v8z" />
<glyph unicode="k" horiz-adv-x="1366" d="M799 143q-2 1 -7.5 6t-11.5 10.5t-10.5 10.5t-5.5 6q-2 2 -6.5 9.5t-6.5 9.5q-8 9 -25 33t-36.5 51t-37.5 51.5t-27 34.5l-18 18q-3 3 -6 7q-5 7 -5 9q-8 10 -29.5 32.5t-46 47t-46 47t-29.5 32.5v-23q4 -31 6 -64.5t3.5 -67t2.5 -66.5t3 -63q3 -57 8.5 -111.5 t7.5 -113.5q2 -29 -6.5 -37t-23.5 -8q-32 0 -62 -1.5t-62 3.5q-36 3 -63.5 0t-53.5 -6t-54 -3.5t-65 7.5q-5 2 -10 5t-5 8v4q1 1 0 6.5t-2.5 11.5t-2.5 11t0 6l-7 455l-5 172l-1 337q0 8 -1 37.5t-2 69t-2.5 85t-2.5 85t-2.5 69t-1.5 37.5q0 60 -2 119.5t-2 117.5v17 q0 26 6.5 37.5t27.5 14.5h23q43 0 87 0.5t87 0.5q22 0 44.5 1t44.5 1t40 -3t35 -15q2 -8 6 -10t4 -8v-6q0 -6 -0.5 -9t-3.5 -9v-65q0 -5 0.5 -14.5t0.5 -18.5t0.5 -16t0.5 -8q0 -2 0.5 -8t1.5 -12.5t1.5 -12t0.5 -6.5q1 -5 1 -25v-42.5t-0.5 -42t-0.5 -23.5q1 -7 2 -23.5 t2 -34.5t1.5 -34.5t0.5 -22.5q0 -2 -2 -15.5t-4.5 -30t-4.5 -30.5t-2 -15v-12q4 -70 8 -129.5t10 -113.5q2 3 12.5 15t25 28t31 34.5t31 34.5t24.5 28t13 15t17.5 17t30.5 30t30 30.5t17 18.5q6 6 18 19.5t25.5 29.5t27 30.5t21.5 23.5q1 1 7 6.5t13 12.5l12.5 12.5l6.5 6.5 q4 2 14 13t21 23.5t20.5 23.5t12.5 13q5 3 13 -1t10 -2h10l289 -64q4 -5 14 -6.5t20.5 -3t18 -4t7.5 -9.5v-6q-23 -40 -43.5 -70t-55.5 -59q-23 -21 -43 -43.5t-42 -43.5l-290 -280q1 2 -2.5 -1.5t-9.5 -9t-13 -12.5t-11 -12q-7 -8 -9 -5.5t-2 -5.5q0 -9 12.5 -21t19.5 -20 q3 -4 14 -19.5t25.5 -35t30.5 -38t29 -27.5q11 -16 24 -27.5t26 -21.5t26.5 -21t25.5 -26q2 -3 13 -15.5t23.5 -27.5t23 -28t13.5 -16q2 -3 11 -14t19.5 -23.5t19.5 -23.5t12 -14q1 -2 6 -8.5t11 -14.5t11 -14.5t7 -8.5q19 -22 38.5 -41t38.5 -38t38 -39t37 -44v-8 q8 -18 -5.5 -30t-30.5 -12q-8 -1 -23.5 -3t-33 -4t-33.5 -3.5t-23 -1.5q-5 0 -18.5 -2t-16.5 -4l-74 -12q-16 -3 -25.5 -5.5t-17 -4t-16.5 -4t-24 -5.5q-17 -12 -30 -6t-24 19q-2 2 -4 5q-2 2 -3 3.5t-3 1.5z" />
<glyph unicode="l" horiz-adv-x="563" d="M429 30q-3 0 -16 -2t-28.5 -4t-28.5 -4t-16 -2q-43 0 -86 -4t-86 -4q-8 0 -8 1t-7 1q-3 2 -9 8.5t-9 8.5v6q0 1 -0.5 8t-1.5 14.5t-1.5 14t-0.5 8.5q-1 5 -2 18.5t-2 28.5t-1.5 27.5t-0.5 17.5q0 19 0.5 59.5t1 91.5t1.5 107.5t1.5 107t1 90.5t0.5 59q0 6 -0.5 22.5 t-1.5 34.5t-2 34.5t-2 22.5l-32 825q0 3 -0.5 9t-1 13.5t-0.5 14.5t1 11q2 15 4.5 24.5t13.5 9.5q4 0 13 1t18.5 2l19 2t15.5 1h170q1 0 8 1t16 2t17.5 1t10.5 -1q23 4 35 -7t17.5 -28t5 -36t-1.5 -32q0 -3 1 -14.5t2 -26t2 -28.5t2 -21v-8q0 -8 -2 -13.5t-4 -11.5l6 -152 v-11.5t0.5 -21t1 -22t2.5 -12.5q3 -47 4.5 -67t2 -25.5t0 -4t-0.5 -3t1 -21.5t3 -60v-51v-2v-4q2 -8 5 -22.5t3 -22.5l9 -94v-2q-1 -1 -0.5 -10t1.5 -20.5t2 -20.5t1 -10q-1 -17 0 -56t2.5 -82.5t3 -82.5t0.5 -56v-45v-41l-4 -109v-22v-24v-40v-40t-1 -24v-51 q0 -2 -0.5 -5.5t-0.5 -8.5v-12v-24v-25.5t-3 -21t-10 -18t-21 -15.5q-11 0 -18 -3.5t-15 4.5z" />
<glyph unicode="m" horiz-adv-x="2090" d="M83 182q0 20 1.5 63t3 98t4 115.5t4 115.5t3 97.5t1.5 62.5q-1 5 -1.5 19.5t-2 34.5t-2.5 41.5t-2 41.5t-1.5 34.5t-0.5 19.5q0 3 -1.5 18.5t-3 36t-3 41.5t-1.5 35q0 8 -2 28.5t-4 43.5t-4 43t-2 28q0 2 2 9t4 10q6 6 19.5 6.5t20.5 0.5q2 1 11 2t18.5 2t18.5 1.5 t11 0.5q3 0 16.5 2t29.5 4.5t30 4.5t18 3q6 0 29 2t50 4.5t50 4.5t29 2q2 0 5 1q2 0 4 0.5t3 0.5q13 0 17.5 -8t5 -23t-1.5 -37t-2 -50q4 2 19 16.5t36 32.5t45.5 35.5t47.5 26.5q26 9 46 15.5t39.5 11t40.5 6.5t49 2q38 0 80.5 -9.5t77.5 -26.5q5 -2 16.5 -8t24.5 -12.5 t25.5 -12.5t18.5 -9q1 -1 7 -5.5t13.5 -9.5t14 -10t9.5 -6q4 -2 10.5 -6t8.5 -6q3 -2 14 -14.5t24 -27t24 -27t14 -15.5h2h4q2 2 8.5 9t8.5 7q40 33 74 61t69.5 49.5t74.5 36.5t89 22q23 3 46 1.5t48 -1.5q35 0 64 -11.5t60 -25.5q1 -1 5.5 -3.5t9.5 -5.5t9 -5.5t5 -3.5 q1 0 5 -1.5t8 -3.5t7.5 -3t2.5 1q19 -13 31.5 -25.5t22 -24t17.5 -21.5t18 -18q19 -24 32 -47.5t22 -46.5t15.5 -45t12.5 -44q17 -75 27.5 -144t17.5 -134.5t12.5 -128t12.5 -124.5q0 -14 0.5 -51t1.5 -78.5t2 -78.5t2 -52q0 -3 0.5 -14.5t1.5 -25t1.5 -25.5t0.5 -15v-6 q0 -11 -6 -16.5t-15 -8.5t-19 -4.5t-17 -4.5q-17 -5 -22.5 -3.5t-16.5 -3.5l-188 -4q-12 -3 -20.5 0.5t-13.5 10.5t-7 14.5t-2 11.5q0 69 -2 140t-4 139q0 4 -1 18t-1.5 30t-1.5 30t-1 18q0 14 -0.5 38.5t-1.5 49t-2 44.5t-2 24q0 3 -3 22t-6.5 44t-7.5 49.5t-6 39.5 q-3 20 -7.5 34.5t-13.5 31.5q-29 53 -73.5 87t-107.5 34h-28t-30 -7q-6 -4 -16.5 -6.5t-21 -5.5t-19 -7t-11.5 -11q-5 -5 -12 -12.5t-7 -9.5q-2 -3 -8 -13t-13 -22t-13 -22t-7 -13q-9 -22 -15.5 -39.5t-12 -34t-10 -34.5l-10.5 -42q-4 -12 -6 -32t-2.5 -41t0 -41t0.5 -33 v-41q0 -3 0.5 -15.5t0.5 -27t0.5 -26.5t0.5 -15q0 -6 0.5 -31t1.5 -53.5t1.5 -53.5t0.5 -32q2 -31 4 -59t2 -60q0 -11 -4 -23t-15 -18q-15 1 -26.5 0t-22 -3t-21 -4.5t-25.5 -4.5q-23 -3 -49 -3t-47.5 1t-34.5 2.5t-8 1.5q-6 1 -15 3.5t-17 7t-13.5 11t-5.5 14.5 q0 10 3 15.5t3 13.5v16q0 3 0.5 18t0.5 32.5t-0.5 32.5t-1.5 17q-2 18 -1 39t2 43t1.5 43t-0.5 39q0 6 -1.5 26.5t-3.5 43.5t-3.5 43.5t-1.5 26.5q0 2 -0.5 18.5t-1.5 37.5t-2 42.5t-2 34.5q-1 22 -4.5 40.5t-9.5 36.5t-14.5 36.5t-17.5 40.5q-25 62 -78 92.5t-125 30.5 q-22 0 -42.5 -7t-39.5 -19t-36.5 -28t-33.5 -32q-17 -18 -28.5 -44.5t-19.5 -56t-12.5 -59t-7.5 -53.5q-1 -8 -2.5 -26t-3.5 -38.5t-3.5 -38t-2.5 -24.5v-54v-61q0 -2 1 -13t2 -24t2 -24t1 -13v-47q0 -7 0.5 -22t1.5 -31.5t2 -30.5t2 -18q1 -5 2.5 -21t3.5 -34.5t3.5 -35 t2.5 -20.5v-14q0 -3 -5 -9.5t-11 -8.5q-20 -4 -27.5 -3.5t-9.5 0.5t-11 -2t-11 -2h-23q-29 -2 -52.5 -3t-46 -2.5t-46 -2t-52.5 -0.5h-7q-16 -7 -26 -2.5t-16.5 25t-10 58.5t-6.5 97z" />
<glyph unicode="n" horiz-adv-x="1294" d="M110 4q-13 3 -21 8q-9 6 -13.5 14.5t-6 17.5t-1 17t0.5 14q0 76 -2 151.5t-3.5 151.5t0 152t7.5 152l-4 47q1 8 2 15q1 6 1 12.5t1 11.5v59v27.5v46.5t0.5 47.5t0.5 28.5q0 5 1.5 27t3 47t2 47t0.5 28q1 22 -1.5 50t-3.5 51l2 35q0 12 6.5 16.5t14 5.5t14 0t7.5 0 q3 0 11.5 0.5t18 1.5t17.5 2t10 2h37h33.5t33.5 -0.5t38 -1.5l11 -1q1 0 6.5 -1t12 -2t12.5 -2.5t9 -2.5q21 -4 29.5 -9.5t11 -15t3 -23.5t4.5 -34q43 39 90 63t97 36.5t102.5 15.5t108.5 0q15 0 32 -3.5t34.5 -8.5t34 -12t29.5 -14q9 -6 23.5 -17t28.5 -22.5t24.5 -20 t11.5 -8.5q28 -21 49.5 -48.5t37 -58.5t26 -65t17.5 -67q3 -4 7 -20.5t7.5 -37t6 -41.5t2.5 -33v-17v-20t0.5 -35t1 -35t0.5 -20l1 -166l-2 -35q-1 -3 -2 -12t-2.5 -19t-2.5 -19t-1 -13l-1 -22q-1 -19 -1 -48.5t-0.5 -63t-0.5 -68v-63.5t0.5 -49t0.5 -25v-12.5v-20.5 t0.5 -20.5t0.5 -11.5l-1 -10q0 -11 -12.5 -13.5t-20.5 -3.5q-3 0 -8.5 -0.5t-11.5 -1.5t-10.5 -1.5t-5.5 -1.5h-15h-26t-26 -0.5t-15 -1.5q-47 -2 -87.5 -5.5t-89.5 -1.5q-18 1 -25 9.5t-9 20.5t-1 25.5t1 25.5v23.5t0.5 42.5t0.5 52t0.5 52t0.5 42v24l1 232q2 35 0 81 t-9.5 95t-20.5 96t-32 83.5t-44 57.5t-56 18l-35 2q-35 1 -57.5 -8t-53.5 -27q-2 0 -4 -2.5t-2 -4.5q-28 -21 -47.5 -59.5t-33 -87t-22.5 -103t-15 -107.5q-1 -5 -3 -25t-4.5 -44.5t-4 -49t-2.5 -37.5q0 -1 -0.5 -10t-1.5 -21.5t-2 -24.5t-1 -19q0 -5 -0.5 -16t-0.5 -23.5 t-0.5 -23.5t-0.5 -15l1 -150q-1 -3 1 -12t2 -12q0 -1 0.5 -5.5t0.5 -9.5v-10v-6q0 -8 1 -19t-1 -21.5t-8.5 -17.5t-22.5 -6q-23 1 -50.5 0.5t-57.5 -1.5t-61 -1.5t-59 2.5z" />
<glyph unicode="o" horiz-adv-x="1418" d="M575 28q-7 2 -21 4.5t-35 6.5q-1 0 -9 1.5t-19.5 5t-24 9.5t-22.5 15q-2 1 -8.5 3.5t-14.5 6t-14.5 6t-8.5 3.5q-18 7 -34.5 19t-31.5 25t-29 26.5t-26 25.5q-48 45 -86 95t-65 110q-22 48 -35 87.5t-20 78t-9.5 79.5t-2.5 94v75q13 57 30 107.5t41.5 96.5t56.5 88t75 81 q31 30 64 52t71 40q3 1 8.5 4t12 5.5t11.5 4.5t7 3q3 0 15 1.5t14 1.5q3 2 12 8.5t11 8.5q1 0 6.5 1t11.5 2.5t11 2.5t6 2l18 4.5l30 7.5t30.5 7.5t18.5 3.5q8 3 29 5.5t45 4.5t45.5 4t31.5 3h12q5 0 10.5 -0.5t8.5 -0.5q22 -1 40 -2t38 -6q28 -7 57 -13t57 -10 q7 -3 23.5 -11t35 -18t34.5 -19t22 -13q3 -2 15.5 -14.5l27.5 -27.5t29 -30t21 -23q1 -2 6 -9t11.5 -16.5t13 -18.5t10.5 -15q36 -55 59.5 -109t37.5 -109.5t20.5 -114t6.5 -121.5v-4q-2 -17 -4.5 -46.5t-5 -58.5t-4.5 -52t-3 -27q-7 -51 -21.5 -97t-35.5 -91 q-19 -24 -30.5 -40.5t-23.5 -32t-27.5 -34t-42.5 -46.5q-35 -26 -74.5 -48t-81.5 -38t-85.5 -25t-85.5 -7h-13.5t-21 0.5t-21 1t-13.5 0.5q-2 2 -7 4t-7 2t-9 -1t-15.5 -2.5t-16 -2.5t-9.5 0q-4 0 -18.5 1.5t-31.5 4t-31.5 4.5t-17.5 3h-10zM444 715q1 -28 5 -55t15 -53 q0 -2 5 -11t5 -11q4 -13 8 -28t8.5 -30t10.5 -29t15 -25q3 -3 10 -10.5l14 -15t13 -14t8 -7.5q1 -1 6.5 -5t13 -8.5t15 -9.5t12.5 -7l10 -7q3 -2 13 -9t12 -7q2 -2 10 -4.5t13 -2.5q21 -10 31.5 -11.5t18 0t16 3t26.5 -1.5q1 0 7 0.5t13 1.5l14 2t11 2q47 7 88 32t71.5 62 t47.5 82.5t17 92.5q0 3 0.5 24.5t4.5 75.5q0 26 -10.5 51t-18.5 51q-14 40 -45.5 67.5t-65.5 50.5q-21 14 -38.5 23.5t-35.5 15.5t-37.5 9t-44.5 4q-23 1 -40 0.5t-40 -5.5q-25 -5 -52 -14t-51.5 -22.5t-44 -32.5t-28.5 -44l-17 -48q-6 -8 -11 -23t-8 -32.5t-3 -35t3 -31.5z " />
<glyph unicode="p" horiz-adv-x="1380" d="M1363 864q0 -8 -3 -15t-3 -15q0 -31 3 -60.5t3 -60.5v-41q-3 -64 -9 -118t-18 -104.5t-31.5 -100.5t-48.5 -105q-2 -2 -6 -10.5t-8.5 -18t-8.5 -18t-5 -10.5q-2 -3 -9 -12t-10 -11q-5 -5 -15.5 -14.5t-22 -19t-21 -17.5t-11.5 -9q-2 -3 -15.5 -12.5t-21.5 -14.5 q-4 -2 -11 -6t-14 -7.5t-13.5 -6t-8.5 -2.5q-6 -3 -22.5 -8.5t-35 -10.5t-35.5 -9.5t-24 -5.5q-4 -2 -12 -3.5t-17 -3.5t-17.5 -3.5t-11.5 -2.5h-53h-68.5t-66.5 10q-78 14 -149 35.5t-128 53.5q-1 -2 -2 -7t-2 -11.5t-1.5 -12.5t-0.5 -8v-8q0 -47 3 -93.5t3 -93.5v-41 q-1 -11 -2 -41.5t-2 -63.5t-1.5 -61.5t-0.5 -36.5q-2 -12 -6 -24.5t-4 -14.5l-6 -6l-18 -2q-8 -1 -15 -2t-12 -2q-34 -2 -59.5 -3t-54.5 -1q-25 0 -45.5 -1.5t-40 -2.5t-40 -0.5t-44.5 4.5q-23 13 -26 29q0 2 -0.5 9t-0.5 15.5t-0.5 16t-0.5 10.5q0 5 0.5 13t0.5 16.5 t0.5 15t0.5 7.5q2 53 3.5 113.5t3 122.5t3.5 122.5t4 113.5q2 57 4.5 121.5t2.5 121.5v20t-0.5 34.5t-1 42t-1 42.5t-0.5 35v20q0 1 0.5 10t0.5 21.5t0.5 25t0.5 20.5t-0.5 21t-0.5 26t-0.5 23t-0.5 12q0 3 1.5 14t3 23t3 22.5t1.5 13.5q-1 5 -0.5 21t1 34t1.5 34.5t1 22.5 q0 5 0.5 27t1 47t1 47t0.5 27q0 1 -0.5 11t-0.5 23t-0.5 25.5t-0.5 20.5q0 4 0.5 20t0.5 34t0.5 33.5t0.5 20.5q2 21 24 30t49 11t50.5 1t27.5 1h30t30 6h127l10 -11l12 -98q41 37 87 58.5t88.5 33t78.5 15t57 5.5h32q15 -1 37.5 -3.5t45.5 -6t42 -6t26 -3.5q7 -2 22 -5 t31.5 -7t31 -7.5t19.5 -5.5q3 -1 13 -5.5t21 -10t20.5 -11t13.5 -8.5q5 -3 16 -11t23 -17t22.5 -17.5t14.5 -12.5q7 -7 14 -13q6 -5 11.5 -10.5t9.5 -8.5q24 -32 45.5 -57.5t39.5 -63.5q11 -23 23 -48.5t18 -49.5q1 -2 3.5 -13t5 -24t5 -24t3.5 -13q2 -2 6 -9t6 -9v-3z M902 907q0 1 -5 7t-12 13t-15 14.5t-13 11.5q-2 2 -11 6t-11 6t-9.5 6t-9.5 6q-3 2 -11.5 6t-10.5 4q-17 7 -29.5 7h-32.5q-49 0 -97.5 -16t-100.5 -51q-9 -8 -19.5 -15t-18.5 -15q0 -1 -5 -7t-11.5 -13.5t-12 -14t-6.5 -7.5q-2 -5 -7.5 -14.5t-11 -20.5t-11 -21t-7.5 -14 q-3 -8 -4.5 -12.5t-1.5 -12.5q0 -3 -4 -14q-3 -10 -8.5 -28.5t-13.5 -53.5q0 -2 -2 -14.5t-4 -20.5q-1 -5 -1.5 -17t-0.5 -24v-31q0 -3 0.5 -12t1.5 -19t2 -19t2 -13q0 -2 2 -6t4 -6q1 -2 6 -7.5t10.5 -12t11 -12.5t7.5 -9q14 -15 29.5 -23t32.5 -13.5t35.5 -10.5t37.5 -13 q2 0 10 -2q4 -1 7 -2h137q5 -9 8.5 -10.5t11.5 -1.5q18 0 39 4t41 12.5t38 20t30 26.5q1 3 8 12.5t15 21.5t16 23.5t12 16.5q0 2 3 6.5t3 6.5q17 30 31.5 59.5t19.5 66.5q2 10 3 21.5t1 19.5q0 3 -2 14.5t-4 14.5l-9 27t-12 36.5t-11.5 34t-6.5 19.5z" />
<glyph unicode="q" horiz-adv-x="1488" d="M753 1324q13 -4 28.5 -11t31.5 -15.5t30.5 -16.5t26.5 -15q1 -1 5.5 -4.5t10.5 -8t12 -9.5t9 -8q10 -7 15 -13t9.5 -12t11 -11t20.5 -9q0 2 1.5 6.5t1.5 6.5q1 1 1.5 6.5t1 12t1 12t0.5 8.5q1 4 1.5 13.5t1 21t0.5 21v13.5l11 13l224 11q9 -5 18 -5t19 1l65 -6 q14 2 25 2.5t21 -0.5t20 -4t23 -7q3 -1 8.5 -4.5t8.5 -5.5q5 -2 11 -9.5t7 -12.5q8 -32 9.5 -61t3.5 -61q0 -6 0.5 -15t0.5 -17.5t0.5 -15t0.5 -7.5l-16 -470v-6q-3 -65 -7 -133.5t-6 -133.5q0 -7 0.5 -33t0.5 -55.5t-0.5 -55.5t-0.5 -33q0 -27 -1 -62.5t-1 -73v-74t2 -64.5 q0 -3 0.5 -10.5t1 -16t1 -15.5t0.5 -9v-54v-77.5t-0.5 -76.5t-2.5 -52q-3 -10 -9 -12t-14 -2q-12 -1 -19 3.5t-20 3.5q-26 -2 -51 -7.5t-50 -8.5q-37 -5 -70 -8t-67 -5q-4 0 -8 -0.5t-8 -0.5h-9q-3 0 -15 1.5t-14 3.5q-2 0 -8 0.5t-12.5 0.5t-13 0.5t-7.5 0.5 q-9 3 -14.5 19.5t-8.5 36t-4 37t-1 22.5q0 2 -0.5 4.5t-0.5 5.5v7l16 254l30 189q-19 -15 -39.5 -37t-45 -43.5t-55 -39t-69.5 -24.5q-44 -14 -83.5 -20.5t-87.5 -8.5q-79 -1 -157 26.5t-161 70.5q-8 7 -25.5 22t-37 31t-36.5 30t-23 19q-23 23 -42.5 44.5t-36 44 t-30.5 47.5t-27 54q-8 18 -15 41.5t-12.5 48.5t-9 50t-4.5 46q-2 24 -1 42.5t3 36.5t4.5 37t5.5 43q22 151 86.5 281t184.5 227q28 24 55.5 41.5t56 30.5t60 22.5t68.5 15.5q2 0 8.5 0.5t9.5 0.5q5 1 13 1h10q8 0 29 -0.5t44 -1t43 -1.5t28 -2zM996 721q0 3 -3 14.5t-5 13.5 q-9 34 -22 60.5t-31 48.5t-41 41t-52 38q-23 14 -48 27t-53 15q-2 0 -15.5 2t-23.5 1q0 2 -8.5 0t-20 -5.5t-23 -7.5t-17.5 -5q-20 -11 -36.5 -22t-31 -23.5t-27.5 -27.5t-26 -34q-4 -5 -11.5 -16.5t-15 -24.5t-13.5 -25t-7 -16q-2 -5 -6 -17.5t-8 -27t-7.5 -27t-3.5 -16.5 q-1 -1 -1 -11.5v-25t-0.5 -30t-0.5 -25.5v-3q0 -2 0.5 -3t0.5 -2v-8l2.5 -15t2.5 -18t2 -16.5t2 -8.5q0 -2 2.5 -5.5t4.5 -5.5q1 -1 4.5 -4t7.5 -6.5t7.5 -7l4.5 -4.5q0 -2 0.5 -11.5t0.5 -12.5l2 -4q2 -5 5 -6q3 -3 13.5 -14t15.5 -13q-4 -11 6 -18t18 -6q37 -24 66.5 -40 t60.5 -23.5t69.5 -5.5t93.5 16q47 20 79.5 62.5t52.5 95t28 108.5t6 101v4z" />
<glyph unicode="r" horiz-adv-x="1097" d="M148 -6l-58 5q-8 -1 -9 0.5t-2 6.5q-1 12 -0.5 20.5t-1.5 20.5q-1 11 -5 17.5t-5 15.5q-1 6 -1 11t5 10q2 14 2 63t-2 118.5t-4.5 152t-5.5 164.5t-5 155t-2 124q1 10 -1 26.5t-4.5 35t-4.5 35.5t0 28q0 2 -0.5 9.5t-1.5 10.5q-5 0 -5.5 5t-1.5 10l-1 8l6 10q2 26 1 44.5 t-3 43.5q0 4 -0.5 10t-1.5 13t-1 16q0 2 -3.5 9t-3.5 9t1.5 8.5t2.5 8.5v7.5t0.5 13.5t1 13t1.5 8l2 2q1 1 1 4q34 4 66 11.5t66 8.5q41 2 79 -2t78 -9q5 -1 14.5 -1.5t19 -2t17.5 -6.5t9 -15q2 -17 -1.5 -28t-1.5 -29v-3q0 -2 0.5 -3t0.5 -2q7 3 18 8.5l23 11.5t23.5 11.5 t17.5 8.5q2 1 11.5 6t12.5 7q2 0 11.5 2.5t10.5 4.5q9 6 22.5 12t27.5 11.5t25.5 9.5t14.5 6q25 10 51 12t54 3q45 3 92 -7t90.5 -27.5t79 -40t57.5 -44.5q7 -8 15.5 -19.5t16 -24t13 -24.5t6.5 -22q0 -6 -6 -15.5t-14.5 -19.5t-17 -18t-12.5 -10q-1 -1 -5 -4t-8.5 -6l-9 -6 t-5.5 -4q-4 -3 -11.5 -8.5t-15 -11.5t-14 -11t-7.5 -6q-17 -13 -32.5 -28t-33 -28t-37 -22t-43.5 -10h-20q-3 1 -5 2q-3 1 -7 3q-41 21 -87 39t-92 17q-34 -2 -56 -25t-41 -48q-2 -4 -11 -14t-11 -15q-2 -4 -8 -13.5t-12.5 -20.5t-13 -22.5t-8.5 -18.5q-10 -23 -12 -51 t-4 -53q-14 -101 -12.5 -183.5t10.5 -155.5q5 -54 12 -106t12 -106q1 -6 2 -21.5t2.5 -32t3 -32t1.5 -21.5q-2 -1 -3.5 -2t-3.5 -2l-4 -2h-4h-2q-2 0 -6 1.5t-6 3.5z" />
<glyph unicode="s" horiz-adv-x="1007" d="M249 50q-34 18 -63.5 34t-59.5 39q-14 13 -30 25.5t-29.5 25t-22.5 26.5t-10 30q0 5 0.5 13.5t0.5 10.5q3 6 7 11q2 5 4.5 8t3.5 4q2 2 9 9.5t15 15.5l15.5 15.5l10.5 10.5q2 2 8.5 11.5t8.5 12.5q6 6 15.5 15t18.5 18l16.5 16.5l10.5 10.5q4 3 15.5 9t15.5 7h13 q8 0 15 -7t13.5 -15.5t14.5 -17t17 -12.5q21 -12 44.5 -27.5t52 -30t62 -25t73.5 -12.5q7 -6 22.5 -2.5t31.5 12.5t28 21t13 24q0 7 -1 19t-3.5 24.5t-5.5 23t-7 16.5q-36 49 -74 83.5t-91 63.5q-3 1 -15.5 9t-27.5 17l-27.5 16.5t-14.5 9.5t-11 8t-19.5 13.5t-21 14.5 t-14.5 11q-6 7 -22 18t-23 16q-7 7 -21.5 27.5t-31 43.5t-31 42.5t-20.5 25.5q-40 47 -50 103.5t-8 112.5q1 23 9.5 52t18.5 54.5t18.5 43t10.5 17.5q5 8 13 18t17 19t18 17t16 13q24 19 48.5 30t50.5 18t53.5 12t57.5 11q28 3 72.5 4.5t106.5 -10.5h4q42 -6 84 -20.5 t82 -36t76 -48.5t67 -58q4 -6 13 -17l18 -22t16.5 -20t9.5 -11q4 -6 4.5 -11.5t0.5 -11.5q-1 -6 -1 -11.5t-7 -8.5q-8 -5 -23 -21.5t-30 -33.5t-27 -30t-15 -11q-4 -4 -15.5 -14.5t-24 -22t-24.5 -22t-18 -15.5q-9 -7 -14 -12.5t-16 -4.5h-6q-2 1 -6 4t-8.5 6t-8.5 6t-5 4 q-9 4 -30.5 18t-45.5 29.5t-45 29.5t-29 19q-4 1 -12.5 3t-18 4t-18 4t-12.5 3h-2q-8 -2 -16.5 -6t-16 -10t-12 -14t-2.5 -17q-1 -8 1 -22.5t8 -21.5q24 -37 63 -65.5t80 -43.5q67 -26 119.5 -57t103.5 -81q3 -3 12.5 -13.5t21.5 -22.5t22.5 -23t14.5 -15q5 -5 14 -14.5 t9 -10.5q3 -5 9.5 -15t13.5 -22t13.5 -22.5t9.5 -15.5q6 -8 9.5 -23t5 -33t2 -36.5t-0.5 -31.5q0 -2 -0.5 -8t-0.5 -13t-0.5 -13.5t-0.5 -7.5q-12 -94 -60.5 -163.5t-122.5 -129.5q-24 -19 -48.5 -31.5t-54 -20t-65 -11.5t-81.5 -5q-36 1 -73.5 9t-74.5 18.5t-73.5 21.5 t-71.5 20z" />
<glyph unicode="t" horiz-adv-x="870" d="M246 41q2 2 4 8t2 8q0 5 0.5 17t1 25.5t0.5 25v16.5q0 8 0.5 21.5l1 27t0.5 23.5v12v29.5t-0.5 50.5t-1 50.5t-0.5 29.5q0 3 0.5 15t1 26t0.5 26t-1 15q0 3 -1 16.5t-2.5 28.5t-3 28.5t-1.5 16.5q-1 14 -1.5 42t-1.5 63.5t-2 74.5t-2 74t-2 63t-1 42l-3 12 q-39 -2 -82.5 -0.5t-83.5 7.5q0 2 -1 4.5l-3 7.5q0 2 -4 1t-2 1q0 9 -1.5 29t-3 46t-3 54.5t-3 54.5t-2.5 46.5t-2 29.5v11q0 17 9.5 29.5t26.5 16.5q35 -5 72 1t71 6h16t15 6v19q2 77 -5 151t-5 151v14t0.5 21.5t1 22t0.5 14.5q1 8 11.5 10.5t38.5 -3.5q7 1 23.5 2.5 t34.5 3.5t34 3.5t22 2.5q3 0 16.5 -0.5t28.5 -0.5t28 -0.5t15 -0.5h12q6 0 18 -0.5t24 -1.5q14 -1 29 -2l11 -12q0 -3 -1 -9.5t-2 -13.5t-1.5 -13.5t0.5 -9.5q2 -2 4 -6t2 -6q5 -40 7 -78t2 -82q0 -11 0.5 -31.5t1 -45.5t1 -51t-0.5 -48q0 -6 3 -8.5t8.5 -3t11 0.5t9.5 1h4 q32 10 62 10h65q3 0 9 -0.5t12 -0.5q7 -1 16 -1l6 -34q1 -52 -0.5 -100.5t6.5 -102.5v-13v-23.5v-23v-11.5v-6q0 -11 -5 -17t-11.5 -9t-14 -5t-13.5 -4l-29 -6h-110l-2 -86q0 -2 -1 -9.5t-1.5 -16t-1 -15.5t1.5 -8q-2 -34 -1 -63t3.5 -56.5t6 -56t6.5 -60.5l-11 -524 q0 -10 -10.5 -16.5t-18.5 -6.5l-219 1q-3 -2 -12 -3.5t-11 -1.5t-9 2.5t-9 2.5q-3 0 -11.5 1t-18 2t-18 2t-10.5 2q-11 1 -25.5 4.5t-14.5 20.5v4z" />
<glyph unicode="u" horiz-adv-x="1295" d="M98 471q-2 10 -7 31t-10.5 44.5t-10 44t-5.5 31.5q-1 4 -1.5 17.5t-1.5 29t-1.5 29t-1.5 16.5q0 5 -0.5 13t-1.5 16t-2 15t-2 10l-4 10q-1 2 -1 10.5v18.5t0.5 18t0.5 10q-2 25 -2.5 57t-1 64.5t-0.5 63.5v56q0 35 0.5 63.5t1.5 54t3.5 49t5.5 48.5q2 11 21.5 18.5 t37.5 7.5h47q10 0 25.5 -2t31 -4.5t27.5 -4.5t14 -3q2 0 14 -1t25.5 -2.5t25.5 -3t15 -2.5t14.5 -1.5t25 -0.5t25.5 -0.5t16 -1.5q6 -5 8.5 -9t3 -7.5t0 -9t-0.5 -13.5v-41q-5 -38 -6 -72.5t-1 -74.5q0 -64 2.5 -126.5t0.5 -136.5l6 -54v-16q5 -25 7 -51t4.5 -52.5t6.5 -53 t13 -52.5q2 -5 5.5 -13.5t7.5 -17.5t7 -16.5t4 -8.5q7 -19 23 -33t33.5 -24t33 -15.5t20.5 -6.5q2 -1 14 -5.5t17 -6.5q3 -2 13.5 -0.5t12.5 1.5q18 0 47.5 6.5t61.5 27.5q37 40 54.5 81t24 84t5.5 89.5t-1 98.5v33q0 5 -0.5 26t-1.5 45.5t-1.5 45.5t-0.5 26v99 q-1 5 -2.5 20t-4.5 35.5t-6 43.5t-6 43t-5 34.5t-2 19.5l10 86q4 7 12.5 9.5t18.5 3t19.5 0t16.5 0.5q1 0 6.5 1t11.5 2t11 2t6 1l122 -9q3 -2 15 -2.5t25.5 -0.5h25.5t14 -1q6 1 18.5 2t26 1.5t25 1t15.5 0.5l12 -4q12 0 18.5 -9.5t10 -25t4.5 -36.5t1 -45v-19 q0 -20 -2 -40l-4 -40q-1 -6 -1 -27.5t0.5 -45.5t0.5 -45.5t-1 -27.5q0 -4 -2.5 -20.5t-5.5 -35.5t-5.5 -35.5t-3.5 -20.5q0 -5 -1.5 -24t-3.5 -42.5t-4.5 -46t-3.5 -34.5q0 -2 -1.5 -11.5t-3.5 -20t-4 -20t-3 -11.5v-8.5v-16t-0.5 -16t-1.5 -8.5q0 -1 -1.5 -6t-3.5 -11 t-3.5 -11.5t-1.5 -6.5q-9 -38 -14.5 -70.5t-11 -63t-13 -62t-20.5 -68.5q-7 -21 -24 -48t-36.5 -53.5t-38 -49t-29.5 -32.5q-13 -19 -36 -32.5t-50 -24t-54 -19t-46 -15.5q-32 -13 -65.5 -15.5t-67.5 -2.5q-30 0 -60.5 -0.5t-61.5 1t-61.5 7.5t-58.5 18q-59 26 -110.5 60.5 t-102.5 76.5q-6 5 -15.5 15.5t-20 21.5t-21 20.5t-17.5 12.5q4 -3 -3 15t-21 50q-5 11 -12 33t-13.5 47.5t-12 50t-7.5 39.5z" />
<glyph unicode="v" horiz-adv-x="1500" d="M26 1258v4.5t1 4.5q0 3 1 6q2 5 13.5 9.5t16.5 6.5h6q8 0 13.5 1t13.5 1h5q72 6 143 7t143 1q26 0 43 -18t29 -37q3 -7 9.5 -18.5l13 -23t11.5 -21t6 -11.5q2 -2 5 -8.5t3 -8.5q14 -34 28.5 -68t31.5 -66q8 -17 15.5 -33t14.5 -34q2 -2 3.5 -12t3.5 -12q1 -2 4.5 -7 t7 -11t7 -11.5t4.5 -6.5q2 -2 4 -10t2 -10q15 -41 35 -80.5t45 -76.5q0 -2 8 -8.5t10 -8.5q0 -2 2 -7t4 -7h2h5q28 53 48 107t49 107q4 8 14 26.5t21.5 38.5t22 38t13.5 24q29 49 54 98t50 101q4 8 8.5 22.5t10.5 28.5t14.5 24.5t19.5 10.5q29 0 62 -6.5t62 -6.5h218 q29 -5 35 -23t1 -45l-7 -35q-2 -8 -9 -29.5t-15 -45.5t-15 -46t-10 -31q-1 -2 -3.5 -10t-6.5 -17.5t-7.5 -18.5t-5.5 -14q-17 -37 -30 -76t-32 -76q-3 -4 -10.5 -19t-17.5 -34.5t-21 -42t-21 -42.5l-17.5 -35t-9.5 -20q-1 -3 -4.5 -11t-7 -17t-7 -17t-4.5 -9 q-2 -4 -9.5 -18.5t-16 -31t-15.5 -30.5t-8 -17q-1 -2 -3 -8t-4 -13.5t-3.5 -14t-1.5 -7.5q-2 -2 -6 -6.5t-6 -6.5q-17 -27 -30 -54t-24.5 -55l-23 -56t-26.5 -57q-2 -7 -14.5 -29.5t-27 -48t-27 -48t-15.5 -28.5q-6 -11 -11.5 -28.5t-19.5 -25.5q-45 8 -91.5 10.5t-91.5 2.5 q-23 0 -33.5 -1t-30.5 -6q-2 0 -7 -3t-7 -3h-6h-7q-16 21 -29 46.5t-24 50.5q0 2 -2.5 10t-4.5 8q0 2 -2 6.5t-2 6.5q-18 27 -39 61t-35 66q-2 6 -12 29t-21 49.5t-21 49.5t-12 29q-12 26 -26.5 49.5t-28.5 47.5q-16 28 -28.5 57t-27.5 58q-7 18 -20 47t-25.5 57t-22 49.5 t-10.5 23.5q-1 1 -3.5 9t-6 17.5t-6 17.5t-3.5 10q-6 19 -18.5 52l-25 66t-22.5 59t-12 30q-2 5 -11.5 24l-21 42l-22.5 45l-17 34q-1 1 -5 6.5t-8 11.5t-7.5 11.5t-4.5 7.5t-1 5q-1 2 -1 4.5v4.5z" />
<glyph unicode="w" horiz-adv-x="1968" d="M1033 350q-2 1 -6.5 9.5t-4.5 11.5q-2 2 -1.5 11.5t0.5 11.5l-4 16t-7 26.5t-8 28t-6 20.5q-7 26 -21 61.5t-25 61.5l-6 6q-4 -10 -13 -34t-19 -51t-18.5 -51t-12.5 -34q-3 -7 -14 -33.5t-24 -57t-24.5 -57t-14.5 -33.5q0 -2 -2 -7.5t-4.5 -12t-5.5 -14t-5 -11.5 q-6 -17 -13 -38t-14.5 -42t-15.5 -41.5t-16 -36.5q-7 -17 -17 -29.5t-30 -19.5q-28 -3 -49 -4t-41 -1t-40.5 0.5t-47.5 -0.5q-6 0 -16.5 -0.5t-21.5 -1t-19 -0.5h-9l-10 10q-4 16 -9.5 29t-10.5 26t-9.5 26.5t-5.5 31.5q-2 2 -4 11.5t-2 11.5q-16 50 -36.5 107.5 t-36.5 107.5q-4 13 -8.5 23.5t-9 20t-9.5 19t-9 22.5q-3 14 -5.5 26.5t-5.5 26.5q-3 6 -9 23t-13 36t-13 36t-8 24q-2 1 -6.5 13t-6.5 15v4l-78 250q-16 29 -23.5 59t-18.5 60q-1 3 -6 14.5t-10 24.5t-9.5 25t-5.5 15q-1 2 -2.5 9t-3.5 15t-4 14.5t-3 7.5q0 1 -2.5 8 t-5.5 14.5t-5.5 14t-3.5 8.5q0 2 -1 8.5t-2 9.5q0 8 2 17t13 12q2 0 11 0.5t11 0.5q54 9 109 19.5t110 13.5h4q2 0 11.5 1t11.5 1q3 0 15.5 -4.5t15.5 -6.5q2 -2 6 -4q6 -4 10 -6q1 -1 2 -1.5t2 -1.5l2 -2q0 -2 2.5 -14.5t4.5 -14.5q2 -5 8.5 -18t8.5 -16q6 -14 9.5 -25.5 t9.5 -18.5q1 -5 6 -18.5t11 -28t10.5 -27.5t6.5 -17q2 -3 6.5 -12t6.5 -12q3 -5 10 -9t7 -12l-5 -10v-4v-3l107 -242h6q5 8 9 16q4 7 7.5 14t6.5 12t9.5 18.5t13.5 28.5t13.5 28t8.5 19q1 3 2 7q2 7 4 9q0 2 7 10t9 8q2 2 5 11t6 14t11.5 27.5t19 48t19.5 48.5t12 29 q5 12 11.5 31t16.5 33q1 1 4 6t6.5 11t6.5 11t4 6q0 3 2 16t4 16q2 5 11 8t12 3q5 2 15.5 4.5t12.5 2.5q1 0 8 0.5t15.5 1t17.5 1t15 0.5q38 2 79 3t78 -8q1 -1 3 -2q1 -1 4 -1q15 -23 22.5 -48t17.5 -49q13 -34 24 -68t26 -69q12 -30 25.5 -61t27.5 -62q11 -28 20.5 -57.5 t19.5 -59t21.5 -57.5t27.5 -52q9 6 14 23t8 25l10.5 21t18 36.5t17.5 36.5t10 22q2 4 5.5 12.5t7.5 17.5t6.5 15.5t3.5 8.5q1 4 6 19.5t10.5 33t10 33t6.5 19.5q1 4 7 19t13.5 33t14 34.5t9.5 24.5q1 4 7.5 19t14 31.5t14.5 31.5t9 19q3 7 7 19.5t9.5 25t13 22t18.5 9.5h7 q3 0 6 1h88q1 0 9.5 0.5t18 1t18.5 1t11 0.5q2 -2 11.5 -7t11.5 -5q29 -8 60 -9t60 -7q1 -1 3 -2l4 -2l4 -2q1 -5 7.5 -13.5t6.5 -11.5q1 -23 -2.5 -49.5t-11.5 -47.5q-26 -78 -56.5 -148.5t-60.5 -142.5q-2 -3 -8.5 -20t-15 -36.5t-15.5 -36t-8 -19.5q-26 -63 -50.5 -121.5 t-49.5 -121.5q-11 -27 -20 -51t-18 -47t-18.5 -46.5t-21.5 -50.5q-1 -2 -4 -10t-7 -17t-7 -16.5t-4 -8.5q-5 -12 -13 -29t-17 -35t-17 -34.5t-13 -27.5q-5 -13 -14.5 -31t-23.5 -19q-24 -4 -46 -6.5t-43 -4t-42.5 -2.5t-46.5 -2q-5 0 -18 -0.5t-28 -1t-28 -1.5t-18 -1 q-8 4 -14 12t-10.5 18t-7.5 20t-5 18q-1 2 -2.5 8.5t-3.5 14t-3.5 14t-2.5 8.5t-4.5 11.5t-7.5 21t-8 21.5t-5 13q-2 8 -8 28t-12.5 42.5t-12.5 43t-9 29.5z" />
<glyph unicode="x" horiz-adv-x="1384" d="M708 373q-2 0 -6.5 -2t-6.5 -4q-20 -20 -35 -37.5t-29 -35.5t-27.5 -37.5t-28.5 -43.5q-2 -2 -8.5 -14.5t-15 -27t-15.5 -26.5t-8 -13q-3 -6 -11 -20t-17 -29t-17 -28t-11 -17q-2 -2 -8 -7t-9 -7q-4 -3 -17.5 -8t-16.5 -5q-1 0 -6 0.5t-11.5 1.5t-12.5 1.5t-7 0.5 q-4 2 -15 3.5t-14 1.5l-168 6q-6 -5 -11 -5.5t-11 -0.5q-1 0 -2 -0.5t-2 -0.5h-2q-2 0 -10 5.5t-10 7.5q-23 13 -41.5 18.5t-31 10.5t-19.5 13.5t-5 26.5q1 11 12.5 24t16.5 21q1 1 3.5 6.5t5.5 11.5t6 11t5 7q13 15 24 27t21.5 23t21 24t21.5 30q32 51 63 93t67 87 q3 3 13 16t21.5 28.5t21.5 29t13 16.5q1 1 6.5 9.5t12 18.5t12.5 18t8 10q0 2 2 6t2 6v2q-1 1 -1 3v1q0 2 -6 7.5t-6 7.5t-0.5 6.5t-0.5 6.5t-2.5 3t-4.5 3q-16 23 -29 40.5t-26 41.5l-10 15l-10 15q-26 47 -56 88.5t-57 86.5q-2 3 -9 14.5t-15.5 25t-15.5 25t-8 13.5t-7 9 t-12.5 14.5t-12 14t-6.5 8.5q-2 1 -5.5 6.5t-7.5 12t-8 12.5l-6 9q-3 4 -11 17t-16.5 27.5t-16.5 28t-11 18.5q-1 3 0.5 11.5t3.5 11.5q3 3 10 4t15.5 1.5t15.5 1t9 1.5q6 0 14.5 3t16.5 6t14.5 6t8.5 3q2 1 11.5 2.5t20.5 3.5t20.5 3.5t11.5 2.5q5 2 19.5 3t16.5 1 q4 0 17 1.5t28 4t27.5 4t15.5 1.5q1 1 7.5 1.5t14 1t14 0.5h8.5h6q3 0 9.5 -0.5t14 -1.5t13.5 -3l9 -3q2 -2 4.5 -6.5t2.5 -6.5q2 -2 7 -5.5t7 -5.5q0 -1 1 -6t2.5 -10.5t2.5 -10.5t1 -6q1 -2 7 -13.5t13.5 -27t15.5 -31.5t13 -25q2 -2 4.5 -6t3.5 -6l2 -2q1 -1 2 -1.5 t2 -1.5q1 -4 3 -8q2 -3 2.5 -5.5t2.5 -3.5q3 -6 12 -22t19.5 -34.5t20.5 -34.5t15 -22q2 -5 9.5 -15.5t9.5 -12.5t6.5 -5.5t6.5 -5.5h4q2 0 6.5 2t6.5 4l21 31.5l32 48l32 48l21 31.5q2 3 8 13t13 22t12.5 22.5t7.5 12.5q1 2 5.5 8t10 12.5t11 12.5t8.5 9q3 2 7.5 9t9.5 15 t9.5 14.5t6.5 8.5q7 7 12 10t16 3q30 1 64.5 0.5t70 -2t70 -2.5t64.5 0q5 1 17.5 2t17.5 2q1 1 2.5 2t6.5 1t13.5 -3t23.5 -11q2 -1 7.5 -2t11.5 -1.5t10.5 -1t6.5 -0.5q3 0 15 0.5t14 0.5q3 0 9 -0.5t12.5 -1t12 -1.5t7.5 -2l4 -2q1 -1 3 -2v-6q0 -2 -1.5 -6t-3.5 -6 q-21 -33 -42.5 -60t-44.5 -52.5t-47 -51t-49 -54.5q-3 -4 -18.5 -22t-33.5 -39l-33 -38.5t-18 -21.5q-10 -11 -35 -39t-52.5 -59.5t-52 -59t-33.5 -38.5v-4q2 -3 6.5 -8t9.5 -10.5t9 -10t6 -5.5q3 -5 14 -22t23.5 -37.5t23.5 -38t14 -21.5q2 -3 6.5 -9.5t5.5 -8.5 q2 -2 9.5 -8t9.5 -8q0 -2 3.5 -9t5.5 -9q13 -28 35.5 -56t40.5 -51q2 -2 10.5 -8.5t10.5 -6.5q0 -2 3 -9.5t5 -9.5q0 -2 2 -6l2 -4l192 -260q3 -2 10.5 -10t7.5 -13q2 -5 -1 -18t-6 -16q-6 0 -20.5 -1.5t-31 -3t-31 -3t-20.5 -2.5q-1 0 -5.5 -1t-9.5 -2t-9 -1.5t-5 -0.5 q-32 -6 -65 -7t-67 -4q-2 0 -12 -1.5t-22 -3t-22 -2.5t-12 -1t-7.5 -0.5t-8.5 -0.5q-31 0 -49 22q-11 13 -18.5 27.5t-15.5 28.5q-2 2 -8.5 12.5t-11.5 15.5q0 2 -6.5 9t-6.5 9q-1 1 -5 7.5t-8.5 14t-9 14t-5.5 8.5q-22 33 -47 64t-45 66q-1 2 -5.5 11.5t-10.5 20 t-11.5 19.5t-7.5 12t-6.5 11.5t-5.5 10.5l-6 6h-4z" />
<glyph unicode="y" horiz-adv-x="1465" d="M456 -316q17 45 35 86t34.5 80t30.5 76.5t24 75.5v2l-1 2l11 45q1 2 7.5 6t6.5 7q0 2 2.5 8.5l5 13l5 13t3.5 8.5q3 12 5.5 22.5t0.5 21.5l-20 46q-6 34 -24 66t-35 62l-23 33q-2 2 -2 5v3q-17 24 -30 49.5t-25 51t-24.5 51t-27.5 50.5q-5 6 -17 25.5t-26.5 42 t-27.5 43.5t-19 31q-35 54 -67.5 109t-64.5 110.5t-65.5 110t-69.5 107.5q-1 1 -1 2v4q-3 13 13 24q2 0 6 1t6 2q2 0 6.5 6.5t6.5 9.5q2 0 10 1t16.5 2.5t16.5 3t10 2.5q5 1 27 7t47.5 13.5t47.5 14t28 8.5q2 0 4 1q2 0 3.5 0.5t2.5 0.5q4 0 7 1q3 0 5 1q5 1 15 2t19.5 2 t18 1h10.5q3 1 8.5 -1.5t10.5 -5.5q3 -5 10 -17t14.5 -25.5t15 -25.5t10.5 -17q32 -57 69 -109.5t71 -109.5q1 -2 4.5 -9.5t8 -15.5t8 -15t4.5 -8t3.5 -5t5 -8.5l5 -9t3.5 -6.5q2 -3 12.5 -18t22.5 -32.5t23 -33t14 -19.5q2 -4 11 -21t19.5 -36.5t19.5 -37t12 -21.5 q0 -2 3.5 -5.5l5.5 -5.5q2 10 3.5 24.5t3.5 22.5q8 47 18.5 91t26.5 89q8 28 21 55.5t21 55.5q14 42 31 91t32 89q1 3 5 13t9 22t9 22t5 13q4 12 6.5 21t5.5 17t8 15.5t13 16.5q1 0 6.5 1t11.5 2.5t11.5 3t7.5 2.5q26 4 50.5 4.5t50.5 0.5q5 0 21 1t35 1.5t35 0.5h21 q8 1 28 1.5t42 0.5h41.5t27.5 -1q5 -2 15 -7.5t12 -11.5q1 -9 0 -20.5t-4 -23t-6 -22l-5 -17.5q-13 -49 -26.5 -94.5t-28.5 -89.5t-32 -88t-37 -89q-34 -76 -63.5 -162.5t-56.5 -163.5q-11 -33 -28 -71t-34 -69q-11 -20 -19.5 -40.5t-13.5 -40.5q-4 -18 -7 -31t-7 -25 t-9.5 -25t-12.5 -31q-3 -6 -4 -22t0 -24q0 -2 -4.5 -12t-6.5 -12q0 -1 -3 -4.5t-7.5 -8l-8 -8l-4.5 -4.5q0 -2 -2 -9.5t-4.5 -16t-4 -16t-1.5 -9.5q-3 -5 -8.5 -18.5t-11.5 -28.5t-11 -28.5t-8 -18.5q2 -23 0.5 -36t-16.5 -32l-91 -273q-1 -3 -4.5 -9.5t-8.5 -13t-10 -11.5 t-9 -6q-9 -2 -22.5 -3t-21.5 1q-2 1 -8.5 0t-15 -2.5t-16.5 -2.5t-14 1q-4 1 -10 2t-9 0q-5 1 -20 3.5t-32.5 5.5t-33.5 5.5t-21 2.5q-5 -1 -16.5 -1h-13.5t-11 1.5t-20 2.5t-20.5 2t-10.5 1q-6 0 -15 3t-14.5 13t-5 28t13.5 49z" />
<glyph unicode="z" horiz-adv-x="1100" d="M731 4q-5 -1 -15.5 -1.5t-13.5 -0.5l-47 3h-36t-55.5 -0.5t-56 -1t-37.5 -1.5h-9q-12 0 -31.5 1t-38 1.5t-33 1t-16.5 0.5q-5 0 -28.5 1t-52.5 2.5t-57 3.5t-43 4q-2 1 -9.5 2t-16 2.5t-15.5 3t-8 1.5q-2 0 -10.5 0.5t-18 1t-18 1t-9.5 0.5q-4 1 -11.5 7t-7.5 9l11 40 q2 1 5.5 5.5t4.5 7.5q17 32 29.5 67t28.5 67q16 42 32.5 70t25.5 47q1 2 -2 2t-1 2l17 26q3 14 10.5 28t16 26.5t15.5 22t9 15.5q14 24 22.5 51t19.5 51q8 18 15.5 32.5t15 28t14.5 28t13 33.5l19 41q0 2 6.5 15t15.5 29.5t18.5 33.5t16.5 27q4 12 13.5 29.5t19.5 37.5 t18 41t9 41l-220 -6q-23 -2 -52.5 -4.5t-52.5 2.5q-4 0 -15.5 0.5t-24.5 0.5t-24 0.5t-15 1.5q-2 2 -7 5.5t-7 5.5v2v4q-1 16 2.5 30.5t8 28.5t8 29t2.5 33q-1 7 5 28.5t13.5 46.5t13.5 47t5 30q1 12 10.5 18t20.5 8.5t21.5 2t14.5 -1.5q2 0 8.5 -2t8.5 -4q14 0 24 0.5 t24 2.5q3 0 18.5 1t22.5 1q8 1 19.5 1.5t13.5 1.5l75 -1q14 1 26.5 2.5t26.5 5.5h27.5h39.5h40t28 1q98 7 192 5t194 -6l4 -3q22 -2 40 -5t30 -9t16.5 -17t1.5 -29q-3 -6 -7.5 -19t-9 -27.5t-9 -27.5t-6.5 -19q-32 -57 -59 -119t-59 -118q-23 -36 -32 -51.5t-11 -21t0 -4 t2 0.5q-7 -9 -20 -27t-27 -38t-27.5 -38t-20.5 -27q1 -13 -8 -21t-14 -16q-1 -2 -9 -12.5t-18 -22.5t-18.5 -24t-10.5 -17q-1 -2 -6 -10.5t-10.5 -18.5t-10 -18.5t-5.5 -10.5q-2 -2 -5.5 -9t-8 -15.5t-8 -15.5l-4.5 -9l-10 -15t-5 -11q0 -1 -3 -5.5t-6.5 -10t-6.5 -10 t-2 -5.5q-1 -14 -9.5 -25t-17.5 -21.5t-16 -22.5t-5 -30q10 1 34.5 3t51.5 5t51.5 5t35.5 3q31 1 62.5 -5t60.5 -12h2q1 0 2 0.5t2 0.5q4 0 22.5 0.5t40 1.5t40.5 1.5t24 0.5q1 0 7.5 1t14 1.5t14.5 1t9 0.5q7 -1 12.5 -6t6.5 -11v-2q0 -3 1 -4q1 -2 0 -14t-2 -15 q1 -3 3.5 -14.5t2.5 -14.5l-2 -45q0 -6 -0.5 -15t-1 -18.5t-0.5 -18t1 -12.5q1 -8 3.5 -26.5t5.5 -39.5t6 -40t4 -26l-5 -8l-57 -4l-177 -12q-3 0 -14 1.5t-24 3t-24 2.5t-13 1t-12.5 -1t-15.5 -1z" />
<glyph unicode="{" horiz-adv-x="906" d="M370 -118q-3 5 -8.5 18.5t-12 28.5t-12.5 28t-8 18q-12 37 -15.5 74.5t-8.5 75.5q-5 52 -11 104t-14 104q-2 4 -3 8q-2 8 -2 10t-1 11t-3 11l-6 56q1 17 -4.5 31t-10.5 28q-2 6 -3 17.5t-5 17.5q-3 3 -6.5 10.5t-6.5 15.5t-5.5 14t-3.5 7q-1 2 -10.5 3.5t-12.5 3.5 q-2 0 -6 4.5t-3 7.5q-23 6 -48 10t-51 1l-13 13l-6 55l-11 41v8q0 2 0.5 5.5t0.5 5.5q-1 2 -3 12t-4 22t-3.5 22t-1.5 12q-1 4 -1 22t0.5 38.5t1.5 38t1 22.5q0 2 -2.5 12t-1.5 13q0 8 5.5 15.5t12.5 12.5q25 0 51.5 1.5t50.5 8t45.5 19.5t37.5 36q2 5 7 15t5 14l4 47 l16 145q0 3 0.5 13.5t0.5 13.5l10 47q1 7 3 13q2 5 2.5 10.5t2.5 9.5q0 2 0.5 11.5t1.5 12.5q0 1 1 8t2 14.5t2.5 14t1.5 8.5v4v2l10 52q1 1 2.5 8t3 14.5t3 14.5t1.5 10q1 2 2.5 8.5t4 14t4.5 14t4 8.5q13 35 31.5 80t40.5 80q2 2 8 10q3 4 6 7q40 39 86 74.5t101 50.5 q51 13 95 23t93 10q5 0 9.5 -0.5t7.5 -0.5q13 -7 21 -19q1 -7 1 -25t-0.5 -39t-1 -40t-1.5 -27q0 -12 -1.5 -32t-1.5 -41t1.5 -40.5t7.5 -29.5q-3 -3 -5 -14.5t-4 -16.5l-6 -8q-6 -8 -6 -9q-3 -9 -6.5 -9t-11.5 -3q-48 -13 -84 -31.5t-60.5 -45.5t-38.5 -64t-18 -88 q0 -3 -0.5 -11t-0.5 -10l-10 -56q-5 -14 -7 -32t-4 -33q-2 -35 -1.5 -71t-1.5 -71q-2 -15 -6.5 -32t-8.5 -31q-6 -23 -14.5 -51.5t-27.5 -46.5l-16.5 -16.5t-25 -24t-26 -23.5t-17.5 -15q3 -5 10.5 -11.5t17 -13.5t18.5 -13l15 -10q6 -5 8.5 -8t3.5 -6.5t2 -8.5t5 -12 q1 -2 4.5 -8.5t8 -14t8 -14.5t5.5 -8q0 -2 1.5 -6.5t3.5 -6.5q1 -2 4.5 -12t7.5 -22t7.5 -22t5.5 -12q0 -2 4.5 -9.5t3.5 -9.5q1 -2 2 -9t2.5 -16.5t2.5 -18.5t1 -13q0 -3 1 -16.5t2 -29t2.5 -29t1.5 -17.5q0 -9 2 -33t4.5 -50.5t5.5 -50t5 -33.5q5 -17 6.5 -35.5t5.5 -34.5 q-2 -64 21.5 -100.5t73.5 -27.5q6 0 19 -1t22 0q17 4 29 10.5t31 6.5h4q3 -2 10.5 -11.5t10.5 -12.5q-2 -10 -1 -35t2 -53t2.5 -53.5t1.5 -36.5q-1 -17 1 -39t4 -41q1 -2 2.5 -8.5t3 -14.5t2.5 -15t1 -9q-1 -1 -1 -3v-5q-1 -9 -10 -15.5t-21.5 -10t-25.5 -6t-21 -3.5h-11.5 t-18.5 -0.5t-18.5 -0.5h-11.5q-6 0 -15.5 0.5t-18.5 0.5t-16 0.5t-8 0.5q-2 0 -9.5 1.5t-17 3t-18.5 3.5t-15 4q-3 0 -12 2t-19.5 5t-20 6t-13.5 5q-12 3 -29.5 10t-36 16t-34.5 19t-23 19q-6 7 -9.5 13t-8.5 14t-13 19t-22 29z" />
<glyph unicode="|" horiz-adv-x="593" d="M340 23q-3 0 -14 -1.5t-23.5 -4t-23.5 -4t-13 -1.5h-6q-18 0 -36.5 2t-35.5 2t-26.5 -0.5t-28.5 -3.5q-2 -2 -9 -4t-9 -2h-2q-14 0 -21 10q-1 4 -3 14t-5 21.5t-5 21t-3 13.5v2v4q1 27 2 68.5t2 81t1.5 68t0.5 30.5q0 3 0.5 11t1.5 17.5t1.5 17.5t0.5 11v420 q-7 54 -9 107.5t-2 107.5t1 108t0 109q0 5 -1 23.5t-2 39.5t-2 39t-1 23v39v37q2 57 2 106t-3 106q3 9 10 10.5t15 1.5q2 0 4 -0.5t5 -0.5q3 -1 7 -1t22 -0.5t38.5 -1t38.5 -1t22 -0.5h35q13 -2 29.5 -0.5t33.5 3.5t33.5 4t30.5 2q11 0 22.5 3t22.5 3h2q2 -2 11.5 -9 t12.5 -9l11 -5q3 -3 7.5 -14.5t4.5 -13.5q0 -5 2 -20.5t4 -20.5q0 -5 -2.5 -20.5t-5.5 -33t-5.5 -33.5t-2.5 -20q5 -6 8.5 -18t3.5 -17q0 -2 -5 -11.5t-7 -11.5v-20v-21q1 -3 3 -14t4 -23.5t3.5 -23.5t1.5 -14v-109q4 -50 8 -113t7 -133t5 -143.5t3.5 -143.5t2.5 -133.5 t1 -114t-1 -84t-3 -44.5q-2 -23 -2 -45.5v-46.5q-2 -8 -2 -22t0.5 -28.5t1.5 -25.5t2 -12q-14 -41 -42 -59.5t-56 -24.5t-48.5 -4.5t-19.5 0.5z" />
<glyph unicode="}" horiz-adv-x="886" d="M543 1746q3 -5 8.5 -18.5t12 -28.5t12.5 -28.5t8 -17.5q12 -37 15.5 -74.5t8.5 -75.5q5 -52 11 -104t14 -104l2 -8l2 -6t1 -4q0 -2 1 -11t3 -11l6 -56q-1 -17 4.5 -31t10.5 -28q2 -6 3 -17.5t5 -17.5q3 -3 6.5 -10.5t6.5 -15.5t5.5 -14t3.5 -7q1 -2 10.5 -3.5t12.5 -3.5 q2 0 6 -4.5t3 -7.5q23 -6 48 -10t51 -1l13 -13l6 -55l11 -41v-8q0 -2 -0.5 -5.5t-0.5 -5.5q1 -2 3 -12t4 -22t3.5 -22t1.5 -12q1 -5 1 -22.5t-0.5 -38t-1.5 -38.5t-1 -22q0 -2 2.5 -12t1.5 -13q0 -8 -5.5 -15.5t-12.5 -12.5q-26 0 -52 -1.5t-50 -8t-45.5 -19.5t-37.5 -36 q-2 -5 -7 -15t-5 -14l-4 -47l-16 -145q0 -3 -0.5 -13.5t-0.5 -13.5l-10 -47q-1 -7 -3 -13q-2 -5 -3 -11t-2 -9q0 -2 -0.5 -11.5t-1.5 -12.5q0 -2 -1 -8.5t-2 -14t-2.5 -14.5t-1.5 -8v-4v-2l-10 -52q-1 -2 -2.5 -8.5t-3 -14t-3 -14.5t-1.5 -10q-1 -2 -3 -8.5t-4 -14t-4.5 -14 t-3.5 -8.5q-13 -35 -31.5 -80t-40.5 -80l-4.5 -4.5t-4.5 -5.5q-3 -4 -5 -7q-40 -39 -86 -74.5t-101 -50.5q-51 -13 -95 -23t-93 -10q-5 0 -9.5 0.5t-7.5 0.5q-13 7 -21 19q-1 7 -1 25t0.5 39t1 40t1.5 27q0 12 1.5 32t1.5 41t-1.5 40t-7.5 30q3 3 5 14.5t4 16.5l6 8 q2 3 3.5 5.5t2.5 3.5q3 9 6.5 9t11.5 3q48 13 84 31.5t60.5 45.5t38.5 64t18 88q0 3 0.5 11t0.5 10l10 56q5 14 7 32t4 33q2 35 1.5 71t1.5 71q2 15 6.5 32t8.5 31q6 23 14.5 51.5t27.5 46.5q4 5 16 16.5t25.5 24t26 23.5t17.5 15q-3 5 -10.5 11.5t-17 13.5t-18.5 13l-15 10 q-6 5 -8.5 8t-3.5 6.5t-2 8t-5 12.5q-1 1 -4.5 8t-8 14.5t-8.5 14t-5 8.5q0 2 -1.5 6.5t-3.5 6.5q-1 2 -4.5 12t-7.5 22t-8 22t-5 12q0 2 -4.5 9.5t-3.5 9.5q-1 1 -2 8.5t-2.5 17t-2.5 18t-1 13.5q0 3 -1 16.5t-2 29t-2.5 29t-1.5 17.5q0 9 -2 33t-4.5 50.5t-5.5 50t-5 33.5 q-5 17 -6.5 35.5t-5.5 34.5q1 64 -22 100.5t-73 27.5q-6 0 -19 1t-22 0q-17 -4 -29 -10.5t-31 -6.5h-4q-3 2 -10.5 11.5t-10.5 12.5q1 10 0.5 35t-1.5 53t-2.5 53.5t-1.5 36.5q1 17 -1 39t-4 41q-1 1 -2.5 8t-3 15t-2.5 15t-1 9v3q0 2 0.5 3t0.5 2q1 9 10 15.5t21.5 10 t25.5 5.5t21 4h11.5t18.5 0.5t18.5 0.5h11.5q6 0 15.5 -0.5t18.5 -0.5t16 -0.5t8 -0.5q2 0 9.5 -1.5t17 -3t18.5 -4t15 -3.5q3 0 12 -2.5t19.5 -5.5t20 -6t13.5 -4q12 -3 29.5 -10t36 -16t34 -19t23.5 -19q6 -7 9.5 -13t8.5 -14t13 -19t22 -29z" />
<glyph unicode="~" horiz-adv-x="1036" d="M86 646q-1 1 -2.5 4t-1.5 4t3.5 5.5t5.5 6.5v5q14 37 43 65t56 56q2 2 9.5 10t9.5 9q34 34 77.5 60.5t91.5 26.5q20 0 37.5 -2.5t37.5 -10.5q11 -5 24 -12.5t25 -7.5l35 -25q5 -3 17 -9t25.5 -13t25.5 -13.5t17 -8.5q13 -7 22 -8t22 -1q9 0 19 4.5t20 11t18.5 14.5 t13.5 15l9 12t12 16.5t11 15.5t6 9q5 8 10 14t17 6h4q1 -1 7 -6t8 -7q16 -17 34.5 -30t35 -24.5t30.5 -20.5t23 -17q7 -8 14 -13.5t10.5 -11t3 -12.5t-9.5 -17q-11 -17 -22 -32t-23 -32q-22 -30 -47 -59.5t-54 -52t-62.5 -36.5t-73.5 -14q-11 -1 -30 4.5t-39.5 13t-38.5 16 t-27 13.5q-1 2 -4.5 6t-8 8t-8.5 7.5t-5 5.5q-20 16 -39.5 22t-45.5 6q-31 0 -59 -15t-48 -42q-8 -12 -14.5 -21t-13.5 -15t-17 -8.5t-26 -2.5q-4 0 -9.5 1t-7.5 1q-1 0 -7 5.5t-8 5.5q-2 2 -6.5 4.5t-5.5 4.5q-20 13 -33.5 20.5t-30.5 24.5q-1 1 -7.5 6t-7.5 5 q-3 3 -9.5 10t-14 15t-14 15t-9.5 10z" />
<glyph unicode="&#xa1;" horiz-adv-x="524" d="M62 741q0 13 -1 47t-1.5 72t-1.5 72t-1 47q1 3 2 11t2 17.5t1.5 17.5t0.5 11v121q6 9 22 13.5t25 4.5h286q8 -3 14.5 -4t11.5 -6.5t8 -19.5t3 -44q1 -2 2 -8.5t2 -14t1.5 -14t0.5 -8.5q0 -14 1.5 -51t3 -78.5t3 -78.5t1.5 -51q0 -7 2 -35.5t5 -60.5t5 -60t2 -36 q0 -9 1 -34.5t3 -59t4 -71.5t4 -72t3.5 -59t1.5 -34q1 -15 1 -47t0.5 -67.5t1.5 -67.5t3 -47v-14q5 -39 -5.5 -60t-40.5 -15l-317 2q-22 0 -31 13.5t-11.5 35t-2 50t-4.5 58.5q-2 23 -2 49t1 52.5t1.5 52.5t-1.5 48q-3 58 -5 109.5t-3 102t-1.5 102.5t-0.5 109zM35 1508 v28.5t7 29.5q11 21 19.5 40.5t25.5 36.5q5 5 13 11t16.5 12.5t16 12t9.5 7.5q11 9 23.5 12.5t26 4t27.5 -0.5t27 -1q17 0 28.5 -4.5t28.5 -11.5q8 -2 21.5 -9.5t21.5 -13.5q40 -28 68.5 -67t33.5 -93q0 -31 -2 -53.5t-9 -41t-21 -35t-38 -36.5q-22 -19 -54 -33t-61 -14 q-3 0 -10.5 0.5t-15.5 1.5t-15.5 2t-9.5 2l-12 3t-16.5 5t-15.5 5t-9 3q-1 2 -8.5 5t-16.5 6.5t-17 7t-10 4.5q-22 18 -36.5 36.5t-22 39t-10.5 44.5t-3 54z" />
<glyph unicode="&#xa2;" horiz-adv-x="1164" d="M120 501q-2 4 -7.5 16t-11 25t-10.5 24.5t-6 16.5q0 1 -1 10t-2 14q-11 73 -2.5 149t25.5 145q15 56 41 108.5t63 96.5t85 76t107 47q33 8 70 14.5t73 9.5q3 0 7.5 -1t3.5 2q0 3 1 20t3 36t6 34t10 13q4 -2 10.5 -1.5t12.5 1.5t11 2l5 1q26 0 53 -1t55 -3q7 -1 11 -17 t5.5 -35t1.5 -35t-1 -16q-4 0 -1 -0.5t8 -1.5t11.5 -2t10.5 -2q33 -7 71 -17t70 -27q3 -1 12 -5.5t19.5 -10t19.5 -10l11 -5.5q21 -18 30 -26.5t16.5 -15.5t17.5 -17.5t33 -31.5q2 -4 6.5 -9t6 -11.5t-1 -15.5t-13.5 -21q0 -1 -13 -10.5t-30 -22.5t-34 -27.5t-26 -24.5 q-19 -28 -37 -35.5t-31 -2.5h-5q-14 2 -20.5 4.5t-11 5.5t-10 7.5t-17.5 11.5q-13 8 -32 14.5t-34 8.5q-10 2 -27 5t-33.5 6t-29 5t-13.5 3q-6 -1 -11 -1q-5 -1 -9.5 -1h-7.5q-17 -2 -29 -2t-26 -7q-29 -13 -49.5 -35t-36 -49t-26.5 -56.5t-20 -56.5q-7 -23 -9.5 -48 t0.5 -49q11 -67 43.5 -109.5t101.5 -56.5q7 -1 19.5 -3t24.5 -4l21 -3.5t10 -1.5h7t13.5 0.5t14.5 1t12 0.5q3 0 9.5 0.5t14 1.5t14 2t9.5 1q11 5 21.5 8t19.5 9q15 8 36.5 21.5t34.5 24.5q15 11 27 20t33 11q8 1 15.5 2t14.5 -4q1 -2 8 -7t9 -5q2 -2 11 -8l19.5 -13t20 -13 t12.5 -8l6 -3q2 -2 9.5 -7t16 -10.5t15.5 -10t9 -5.5q4 -4 6.5 -5.5t3.5 -3t1.5 -3.5t1.5 -8q2 -9 1 -13t-7 -12q-39 -54 -84 -98t-96 -86q-52 -30 -93.5 -40.5t-77.5 -14.5q-1 -6 -1 -12.5v-8.5q1 -17 4 -33.5t3 -33.5q0 -6 0 -5v2.5t-0.5 1.5t-1.5 -6q-2 -11 -9.5 -16.5 t-18.5 -11.5q-6 -2 -8.5 -3t-7.5 -1l-21 -1q-9 0 -19 -0.5t-26 -1t-38 -0.5t-55 1q-5 0 -7 2t-3.5 5.5t-2.5 7t-4 5.5q2 7 0 5.5t-3 5.5v7t-0.5 13.5t-1 13.5t-1.5 7q0 3 -1.5 10.5t-3 16.5t-3 17t-1.5 11q-1 2 -5 12q-4 2 -16 2t-16 2q-2 1 -12 3.5t-21.5 5.5t-21.5 5.5 t-13 3.5q-33 12 -67 31.5t-65 43.5t-58.5 51.5t-48.5 54.5q-2 2 -7.5 11t-12.5 19.5l-13 19.5t-7 11q-2 2 -5.5 6.5t-5.5 6.5z" />
<glyph unicode="&#xa3;" horiz-adv-x="1257" d="M441 36q-47 -10 -86.5 -19.5t-70 -16t-49.5 -9t-23 0.5q-2 0 -7.5 1.5t-7.5 3.5l-2 4q-1 2 -2 3.5t-2 3.5q-2 6 -7 19.5t-10.5 28.5t-10 28t-5.5 17q-16 48 -32.5 98t-16.5 103v23q7 10 17 15t21.5 8.5t22.5 6.5t21 9q18 10 38 31t37.5 46.5t30 52t15.5 47.5q5 32 5.5 55 t0.5 55v48q-1 5 -2.5 13t-4.5 15.5t-8 12.5t-13 4q-5 -1 -16.5 -2.5t-24.5 -4t-25 -4t-18 -2.5h-37h-9.5t-16 -0.5t-16 -1t-9.5 -1.5h-10q-4 0 -12 5.5t-16 12.5t-14 14t-6 10v9v17.5v18v11.5q-1 35 -6.5 73t-5.5 74q0 15 7 23t18 12t24 5t24 3q12 2 31.5 5.5t38.5 7.5l45 9 v17q-18 49 -30 91t-15 95q0 1 -0.5 12t-0.5 24.5t-0.5 27.5t-0.5 22q0 4 4 17.5t9 29t9 29t4 17.5q17 90 69 144.5t131 88.5q2 0 11 4.5t11 6.5q3 1 13.5 3.5t22.5 5t23 5t14 3.5q1 0 5 2.5t6 2.5h43q3 0 16 0.5t27.5 1.5t27.5 2t17 2h18q38 0 73.5 -8.5t72.5 -19.5 q2 -2 11 -3.5t11 -1.5q2 -2 11.5 -9t10.5 -9q2 -1 10.5 -6.5t18 -12.5t18 -13t10.5 -7q39 -37 63.5 -64t41 -52t28.5 -53t27 -67q6 -5 9.5 -20t6 -32t4.5 -32t4 -19q0 -5 -5.5 -18.5t-7.5 -15.5q-2 -11 -13.5 -12t-18.5 -1q-14 -1 -33.5 -2t-38 -2t-32.5 -2t-15 -2 q-3 0 -14 0.5t-24 0.5h-24.5t-14.5 -1h-19h-20q-4 0 -15 -1.5t-17 1.5q-2 0 -4 2l-2 2q-1 3 -2.5 10t-3 15t-3 15t-2.5 10q3 21 -8.5 45.5t-29.5 44.5t-39 31t-38 7h-21q-27 0 -46 -17t-31 -41.5t-17.5 -52t-5.5 -49.5q0 -43 5 -85t8 -84q4 -10 14 -13.5t20 -3.5h3 q36 5 71.5 7t70.5 4q3 0 17 1.5t29.5 4t29.5 4t17 1.5q2 0 15 1t19 1q3 0 15.5 -1t17.5 -1q3 -2 14 -10.5t14 -11.5l2 -4q2 -4 4 -6q14 -50 25.5 -101t11.5 -104q0 -31 -12 -44.5t-31 -17.5t-42.5 -2.5t-46.5 0.5q-9 0 -26 1t-34.5 2t-32 1.5t-18.5 -0.5q-6 -1 -15.5 -0.5 t-19 0.5t-16 0.5t-6.5 -0.5l-5 -3q4 -31 6.5 -67t2.5 -67q0 -32 -2 -63t-9 -62q-6 -22 -13.5 -44t-13.5 -43q-4 -13 -8 -29t-4 -30v-10.5t5 -7.5q3 0 13 -1t13 -1h6t8 1q4 0 10 1q2 0 5.5 2t5.5 2q2 2 10.5 1t10.5 -1q11 2 25 2h27.5t26 2t21.5 8q21 -2 35 18.5t22 60.5 q0 2 2 7.5t2 7.5q3 5 5 18t5 17q8 5 15 10.5t15 5.5q1 0 2 -0.5t3 -0.5h3q1 0 10 -2t20 -4t21 -5t14 -4q2 -2 13 -3.5t23.5 -3.5t23 -4t12.5 -3q19 -8 46.5 -16.5t47.5 -11.5h28q1 0 5 -2l6 -3q7 -5 17 -7.5t20 -5.5t17 -8t7 -15q0 -21 -7.5 -43t-16.5 -42q-2 -7 -7 -20 t-10.5 -26t-10 -23.5t-5.5 -12.5q-20 -48 -51 -82.5t-74 -65.5q-32 -22 -62 -41t-61 -33t-65 -22t-73 -8t-74 8.5t-71 19.5q-24 7 -49 7.5t-51 3.5q-28 3 -55 7t-56 4z" />
<glyph unicode="&#xa8;" horiz-adv-x="842" d="M356 1513v-18t-4 -19q-7 -14 -12 -26.5t-16 -24.5q-6 -7 -19 -16.5t-16 -12.5q-14 -13 -31 -13t-34 -1q-11 -1 -18 1t-18 7q-5 0 -13.5 4t-13.5 7q-26 16 -44.5 40t-21.5 57q0 20 0.5 34t4.5 26t13 23t24 24q14 13 34 23.5t38 11.5q5 1 17 0.5t15 -1.5q6 -1 18.5 -4 t14.5 -4q1 -1 6 -2.5t10.5 -3.5t10.5 -3.5t7 -2.5q28 -21 37 -45t11 -61zM667 1510q0 -8 0.5 -17.5t-3.5 -19.5q-7 -14 -12 -26t-16 -24q-3 -3 -8 -7.5t-10 -8.5l-10 -8t-6 -5q-14 -13 -31.5 -13t-34.5 -1q-11 -1 -17.5 1.5t-17.5 5.5q-5 1 -14 5t-14 8q-26 15 -44 38.5 t-23 56.5q0 20 1 34t5.5 26t13.5 23t24 25q13 13 33 23.5t38 11.5q4 1 17 0.5t16 -1.5q5 -1 17.5 -4.5t15.5 -3.5q1 -1 5.5 -3t10 -3.5t10.5 -3t7 -2.5q28 -22 37.5 -45.5t9.5 -61.5z" />
<glyph unicode="&#xa9;" horiz-adv-x="1488" d="M694 227q-6 1 -21.5 5t-32.5 8.5t-32 8.5t-21 6q-3 2 -13 5t-12 4t-7.5 3.5t-12 5.5t-12 5.5t-6.5 2.5q-2 2 -9 1t-9 -1q0 2 -5.5 5t-7.5 4q-34 17 -64.5 31t-62.5 37q-2 1 -6.5 5t-10.5 8t-11 8t-6 5q-1 0 -7 4q-3 2 -5 3h-3l-23 22q-38 40 -70.5 82t-56.5 88t-38 96.5 t-14 107.5v34q0 3 1 15t1.5 26t1.5 25.5t1 14.5v3l4 31q8 11 9 25.5t4 25.5q5 23 14 48.5t19.5 50.5t22.5 48.5t24 43.5q3 5 9.5 14.5t13.5 20t13 18.5t8 10q0 2 5 7.5t11 12t11 12t6 7.5t6.5 9t5.5 9q36 40 71 71t73.5 54t82.5 40t97 30q36 8 73 14.5t75 6.5q33 0 62.5 -6 t61.5 -15q24 -8 48.5 -14t48.5 -17q1 0 8.5 -3.5t9.5 -3.5q3 -2 15 -7.5t26.5 -12t27 -12.5t16.5 -7q5 -2 19 -10t19 -12q1 0 7.5 -4t13.5 -9t13 -9.5t8 -5.5l34 -31q0 -1 7 -6.5t15 -12t15.5 -12t8.5 -6.5q14 -17 28 -32.5t23 -35.5q7 -15 18 -39.5l22 -49t19.5 -44 t10.5 -24.5q19 -66 30 -110t11 -72v-82l-4 -51q-2 -4 -5.5 -9.5t-3.5 -7.5t-1.5 -10.5t-2.5 -17.5t-2.5 -17.5t-1.5 -10.5q-14 -69 -39.5 -130.5t-66.5 -102.5l-7 -7t-7 -6q-1 -1 -6.5 -4.5t-12 -8t-12 -8.5t-7.5 -5q0 -1 -4 -4t-8.5 -6.5t-8.5 -7t-5 -4.5q-2 -1 -8 -5.5 t-8 -5.5q-6 -5 -18 -12.5t-24.5 -16t-22 -15t-11.5 -8.5q-21 -12 -43.5 -25.5t-44.5 -23.5q-1 0 -5 -3.5t-8 -7.5t-7.5 -7t-4.5 -3q-2 -1 -13 -2.5t-13 -1.5q-12 -3 -20 -4.5t-15.5 -3t-15.5 -3.5t-20 -6q-7 -2 -20 -9.5t-18 -7.5h-2q-2 0 -7 1.5t-7 1.5h-1h-2 q-32 -5 -65 -3t-67 2q-8 0 -17 3t-17 2zM694 380q5 -1 17.5 -5t26.5 -8.5t27 -8.5t18 -4h22h24q5 5 8 7t9 2q5 0 8.5 -2.5t8.5 -2.5q4 0 14.5 2t22 5t21.5 6t14 4q37 14 74 33t67 44q33 26 67.5 55.5t55.5 67.5q20 35 35.5 72t24.5 76q1 4 2.5 14t3.5 22t4 22t2 14v38v30 q0 39 -5 72.5t-14 65t-22.5 62.5t-30.5 64q-2 3 -6.5 11t-6.5 10q-20 27 -44 49.5t-50 43.5q-41 35 -88.5 58t-98.5 36q-24 8 -49.5 9t-50.5 1q-104 0 -196 -40q-2 0 -7.5 -2.5t-12 -5.5t-12 -5.5t-6.5 -2.5h-14q-2 0 -6 -1.5t-6 -3.5q-3 -1 -10 -4.5t-15.5 -7.5t-16 -8 t-10.5 -6q-1 0 -5.5 -2.5t-5.5 -4.5q-20 -15 -32.5 -29t-28.5 -31q-27 -30 -43.5 -56.5t-28.5 -66.5q-2 -10 -6.5 -17.5t-6.5 -15.5q-1 -7 -3 -17.5l-4 -21t-3.5 -18t-1.5 -8.5v-186l12 -64l13 -38q0 -11 6 -26.5t14.5 -31.5t18 -30.5t15.5 -22.5q5 -6 11 -20t12 -19 q1 -4 15 -17.5t31 -28t33.5 -27t22.5 -15.5q1 0 4.5 -1t8 -2.5t8.5 -2.5t5 -2q2 -2 5 -4q2 -2 4 -3.5t4 -1.5q3 -2 8 -4.5t10.5 -5t9.5 -4.5t5 -2h17q2 -3 4 -5l3 -3q1 -1 1 -2q1 0 8.5 -3t9.5 -4q4 -2 13.5 -5.5t11.5 -3.5q1 0 4 2t5 2h4q5 0 7.5 -1.5t5.5 -7.5zM418 837 q0 22 4 40.5t8 38.5q1 2 2.5 13t1.5 13q6 23 17 45l22 44q17 34 41 61.5t51 56.5q7 7 14.5 12t17 9.5t21.5 10t28 14.5q27 10 54.5 19t56.5 11q42 4 77.5 -5.5t72.5 -20.5q3 0 13.5 -4.5t12.5 -6.5q1 0 5 -2.5t8 -6t8 -6.5t5 -4q12 -8 25 -16.5t23 -19.5q11 -12 25 -24.5 t22 -25.5q2 -3 6.5 -9.5t9 -13.5t8.5 -13.5t6 -8.5q0 -2 1 -3q0 -1 1 -3q0 -1 -1 -3t-1 -4l-12 -9q-4 -5 -9.5 -10.5t-11.5 -7.5q-26 -17 -49 -23t-29 -8l-28 -2q-5 0 -5 3q-27 46 -68.5 70.5t-101.5 19.5q-3 -1 -10 -1q-4 0 -7 -1q-33 -11 -55.5 -33t-37 -49.5t-20.5 -59.5 t-6 -62q0 -48 13 -96t30 -90q2 -2 7 -11.5t7 -12.5q11 -21 34.5 -27.5t45.5 -11.5q2 0 9 -1.5t8 -2.5h3h2q18 7 35.5 13t31.5 19q1 1 6.5 7t12.5 13.5l14 15t10 11.5q20 22 23.5 50t9.5 54q1 0 4.5 1t4.5 1h8q2 0 8.5 0.5t13.5 1.5t13 2t8 1q3 0 16 -0.5t27 -0.5t26.5 -0.5 t15.5 -0.5q6 1 15.5 -2.5t10.5 -12.5q0 -1 -1.5 -8t-2.5 -9v-2v-2q-3 -13 -3 -21v-16.5t-1 -20t-7 -31.5q-13 -22 -20.5 -46t-20.5 -47q-15 -27 -38.5 -45t-51 -30t-56.5 -19.5t-56 -13.5q-2 -1 -8.5 -1.5t-15 -1t-16 -1t-10.5 -1.5h-7h-6l-98 6q-1 0 -7.5 2.5t-15 5.5 t-16 6t-10.5 5q-16 7 -29.5 16.5t-32.5 20.5q-2 0 -3 1l-2 2q-28 15 -42.5 32.5t-30.5 40.5q-19 24 -34 53t-25.5 60.5t-16 64.5t-5.5 65z" />
<glyph unicode="&#xab;" horiz-adv-x="1893" d="M982 266q-2 1 -13.5 7t-13.5 7q-9 3 -25 9t-33 12t-31 11t-18 6q-3 1 -21.5 6t-42 11t-47.5 12t-37 9q-2 0 -7.5 1t-12.5 2.5t-13 3t-7 1.5q-2 0 -17 5t-35.5 11.5t-42 13t-34.5 10.5q-20 8 -41.5 14t-41.5 15q-18 8 -35 15.5t-36 14.5q-4 1 -21 5.5t-36.5 10.5t-36.5 11 t-21 6q-23 7 -48 18.5t-46 22.5q-2 -1 -4.5 0t-4.5 1q0 1 -5.5 2t-6.5 1q-19 5 -40 11t-37 15q0 1 -0.5 1.5t-0.5 1.5v2v4q0 1 -1 8t-1.5 15.5t-1.5 15.5l-1 7q1 7 1.5 12t0 9.5t-1 10t-1.5 13.5q-2 16 -0.5 27.5t2 22t0 21.5t-4.5 26q5 11 12.5 13.5t15.5 7.5q4 3 17 14 t28.5 23.5t29 23.5t18.5 13q38 26 76.5 45.5t73.5 48.5q1 2 3.5 4.5l4.5 4.5q1 0 5.5 2t9.5 4t9 4t5 3q2 1 11.5 7.5t21 14t22 14t13.5 8.5q1 1 6 4t11 6t11 6t7 4q5 3 23 13.5t38.5 22.5t38.5 23t22 14q23 16 45 26.5t46 25.5q3 2 10.5 5.5t15.5 7t14.5 6.5t7.5 4 q6 3 20.5 11t30.5 17t30 16.5t20 10.5l23 8q18 5 31.5 -1.5t19.5 -26.5q1 -9 3.5 -30t5.5 -45t5.5 -45.5t3.5 -29.5q2 -20 9 -42t11 -42q1 -8 -5.5 -15t-16 -12.5t-19.5 -9.5t-16 -7q-33 -22 -65 -43t-64 -45q-4 -3 -15.5 -11.5t-24.5 -18t-24.5 -18t-16.5 -11.5 q-17 -13 -33 -22.5t-32.5 -18.5t-33 -18.5t-33.5 -21.5v-3v-2q2 -1 5.5 -1.5t5.5 -1.5q1 -1 2 -8t3 -8q27 -14 58.5 -24.5t60.5 -18.5q1 0 6.5 -0.5t6.5 -1.5q3 -2 14.5 -7t14.5 -6q1 -2 6 -1.5t6 -0.5q12 -3 24.5 -7t24.5 -8q24 -10 48 -17t49 -14q1 0 6 -1.5t6 -1.5 q1 -1 8 -3.5t15.5 -6t17.5 -7t14 -5.5q14 -7 28 -17.5t16 -27.5q5 -50 10 -99t7 -100v-1q0 -1 0.5 -1.5t0.5 -1.5q1 -5 0.5 -8.5t0.5 -8.5v-3v-2q-1 -4 -3 -12.5t-5 -9.5q-2 0 -4 -1q-4 -2 -6 -2h-11zM1753 346q-2 1 -13.5 7t-13.5 7q-9 3 -25 9t-33 12t-31 11t-18 6 q-3 1 -21.5 6t-42 11t-47.5 12t-37 9q-2 0 -7.5 1t-12.5 2.5t-13 3t-7 1.5q-2 0 -17 5t-35.5 11.5t-42 13t-34.5 10.5q-20 8 -41.5 14t-41.5 15q-18 8 -35 15.5t-36 14.5q-4 1 -21 5.5t-36.5 10.5t-36.5 11t-21 6q-23 7 -48 18.5t-46 22.5q-2 -1 -4.5 0t-4.5 1q0 1 -5.5 2 t-6.5 1q-19 5 -40 11t-37 15q0 1 -0.5 1.5t-0.5 1.5v2v4q0 1 -1 8t-1.5 15.5t-1.5 15.5l-1 7q1 7 1.5 12t0 9.5t-1 10t-1.5 13.5q-2 16 -0.5 27.5t2 22t0 21.5t-4.5 26q5 11 12.5 13.5t15.5 7.5q4 3 17 14t28.5 23.5t29 23.5t18.5 13q38 26 76.5 45.5t73.5 48.5q1 2 3.5 4.5 l4.5 4.5q1 0 5.5 2t9.5 4t9 4t5 3q2 1 11.5 7.5t21 14t22 14t13.5 8.5q1 1 6 4t11 6t11 6t7 4q5 3 23 13.5t38.5 22.5t38.5 23t22 14q23 16 45 26.5t46 25.5q3 2 10.5 5.5t15.5 7t14.5 6.5t7.5 4q6 3 20.5 11t30.5 17t30 16.5t20 10.5l23 8q18 5 31.5 -1.5t19.5 -26.5 q1 -9 3.5 -30t5.5 -45t5.5 -45.5t3.5 -29.5q2 -20 9 -42t11 -42q1 -8 -5.5 -15t-16 -12.5t-19.5 -9.5t-16 -7q-33 -22 -65 -43t-64 -45q-4 -3 -15.5 -11.5t-24.5 -18t-24.5 -18t-16.5 -11.5q-17 -13 -33 -22.5t-32.5 -18.5t-33 -18.5t-33.5 -21.5v-3v-2q2 -1 5.5 -1.5 t5.5 -1.5q1 -1 2 -8t3 -8q27 -14 58.5 -24.5t60.5 -18.5q1 0 6.5 -0.5t6.5 -1.5q3 -2 14.5 -7t14.5 -6q1 -2 6 -1.5t6 -0.5q12 -3 24.5 -7t24.5 -8q24 -10 48 -17t49 -14q1 0 6 -1.5t6 -1.5q1 -1 8 -3.5t15.5 -6t17.5 -7t14 -5.5q14 -7 28 -17.5t16 -27.5q5 -50 10 -99 t7 -100v-1q0 -1 0.5 -1.5t0.5 -1.5q1 -5 0.5 -8.5t0.5 -8.5v-3v-2q-1 -4 -3 -12.5t-5 -9.5q-2 0 -4 -1q-4 -2 -6 -2h-11z" />
<glyph unicode="&#xad;" horiz-adv-x="802" d="M67 748q-2 10 -1 20.5t0 20.5q0 3 0.5 14t1.5 24t1.5 24t0.5 14q0 30 -2 59.5t1 58.5q1 15 16 25.5t28 11.5q4 0 18.5 -2t31.5 -3.5t32 -2.5t18 -1h17.5t29 0.5t29 0.5h16.5t15 -1.5t26.5 -2.5t27 -2t16.5 -1q45 -4 88.5 0.5t89.5 3.5q1 1 19.5 0t43 -2.5t50 -3.5 t41.5 -3q2 0 4.5 -0.5t4.5 -0.5q18 -2 23 -13t4 -27t-5 -32.5t-4 -28.5q0 -3 1 -11.5t2 -18t2 -18t1 -11.5q1 -11 0 -18t-3 -15q-2 -18 3 -37t3 -33q-1 -1 -1 -4v-3q-2 -2 -9 -8t-10 -6q-6 1 -18.5 -1.5t-19.5 -4.5h-18.5h-38h-48.5h-48h-38h-18h-9t-15 -0.5t-15 -0.5h-9 q-3 0 -13.5 -0.5t-22 -1.5t-22 -1.5t-13.5 -1.5q-5 0 -22 0.5t-36.5 1t-36.5 0.5h-22q-31 -1 -45.5 -0.5t-26.5 2t-27 3.5t-47 5q-3 1 -12.5 3.5t-14.5 3.5q-5 3 -9 12.5t-6 13.5z" />
<glyph unicode="&#xaf;" horiz-adv-x="790" d="M61 1390q-2 7 -1 14.5t0 14.5q0 2 0.5 10t1.5 17t1.5 17t0.5 10q0 22 -2 42.5t1 41.5q1 11 16.5 18.5t28.5 7.5q4 0 19.5 -1t32.5 -2.5t32 -2t19 -0.5h18h29.5t29.5 0.5t17 0.5t15.5 -1t27 -2t27.5 -1.5t17 -0.5q45 -3 90 0t92 3q2 0 21 -0.5t44 -1.5t51 -2.5t43 -2.5 q2 0 4.5 -0.5t4.5 -0.5q18 -1 23 -9t4.5 -19t-4.5 -23t-4 -20q0 -2 1 -8t2 -13t2 -13t1 -9q1 -7 0 -12t-3 -11q-2 -13 3 -26.5t3 -23.5q-1 -1 -1 -3v-2q-2 -2 -9.5 -6t-10.5 -4q-6 1 -19 -0.5t-20 -3.5h-19h-39h-49.5h-49.5h-39h-18h-50q-3 0 -13.5 -0.5t-22.5 -1.5 t-22.5 -1.5t-13.5 -0.5q-5 0 -22.5 0.5t-37.5 0.5h-37.5h-22.5q-32 0 -47 0.5t-27 1.5t-27.5 2t-48.5 3q-3 1 -13 3t-15 2q-5 2 -9 9t-6 10z" />
<glyph unicode="&#xb4;" horiz-adv-x="379" d="M338 1594q-12 -22 -19.5 -42t-19.5 -42q-15 -28 -29 -56.5t-30 -57.5q-3 -5 -6.5 -12.5t-7 -14t-6.5 -11.5l-3 -5l-10 -5q-1 0 -8.5 -0.5t-11.5 -0.5q-14 1 -24 4t-20 6.5l-20 7t-24 5.5q-1 0 -6 1.5t-11 3t-11 3t-6 1.5q-12 -3 -13.5 6.5t-0.5 21.5q0 3 1 5q0 2 1 3 l6 12t7 12q9 18 13 32.5t17 31.5q0 3 3 6q0 1 2.5 8t5.5 14.5t5.5 14t3.5 8.5t6.5 11.5t12.5 20t12.5 20t6.5 11.5q0 1 1.5 4t2.5 3q2 5 10 7.5t13 2.5h1q2 0 8 -2t8 -2q1 0 7 -0.5t12.5 -1.5t12 -1.5t7.5 -0.5t7.5 -1.5t6.5 -2.5q2 0 14 -1t17 -2h2h1h11t11 -1 q1 0 5.5 -0.5t9.5 -1.5t9 -3.5t5 -6.5l3 -6q-1 0 -1 -1v-2v-3v0z" />
<glyph unicode="&#xb8;" horiz-adv-x="498" d="M56 -347q0 33 6.5 60t3.5 59q6 8 17 8h3q3 -1 11.5 -5t18.5 -8.5t18.5 -9t11.5 -6.5q11 -5 17 -5h20q24 0 48.5 10t37.5 29v3q0 5 3.5 7t3.5 8v1q0 2 -4 10q-2 4 -3 8q0 10 -5.5 16.5t-13.5 10.5t-17 5.5t-16 1.5h-2q-4 -1 -13 -1.5t-19 0t-17 3t-6 8.5q0 4 -0.5 15 t-1.5 23t-2 23t-1 15t-1.5 14t-3.5 21t-3.5 21.5t-1.5 15.5q0 7 6 9.5t14 2.5t16.5 -1.5t13.5 -1.5h15q6 0 12 0.5t10 0.5t18.5 -0.5t18.5 -0.5q4 -3 9 -9t5 -12v-3q0 -1 -1 -5t-1.5 -9t-1.5 -9.5t-1 -5.5q0 -3 3 -9.5t8 -9.5q20 2 42.5 1.5t41.5 -10.5q2 -1 7 -4.5t7 -5.5 q42 -36 66 -79.5t24 -97.5q0 -42 -24 -70t-59.5 -45t-76.5 -24t-76 -7h-42l-10 2q-4 1 -8.5 1.5t-6.5 1.5q-5 1 -17 4t-25 6t-23.5 5.5t-13.5 3.5q-5 2 -16 5t-13 5q-2 0 -5 3.5t-5 4.5v2v0z" />
<glyph unicode="&#xbb;" horiz-adv-x="1896" d="M88 1257q2 -1 13.5 -7t13.5 -7q9 -3 25 -9t33 -12t31 -11t18 -6q3 -1 21.5 -6t42 -11l47 -12t37.5 -9q1 0 7 -1t13 -2.5t12.5 -3t7.5 -1.5q1 0 16.5 -5t36 -11.5t42 -13t34.5 -10.5q20 -8 41.5 -14t41.5 -15q18 -8 35 -15.5t36 -14.5q4 -1 21 -5.5t36.5 -10.5t36 -11 t21.5 -6q23 -7 48 -18.5t46 -22.5q2 1 4.5 0t4.5 -1q0 -1 5.5 -2t6.5 -1q19 -5 40 -11t37 -15v-3q0 -1 1 -2v-4q0 -1 1 -8t1.5 -15.5t1.5 -15.5l1 -7q-2 -14 -1.5 -21.5t2.5 -23.5q1 -16 0 -27.5t-1.5 -22t-0.5 -21.5t5 -26q-5 -11 -12.5 -13.5t-15.5 -7.5q-4 -3 -17 -14 t-28.5 -23.5t-29 -23.5t-18.5 -13q-38 -26 -76.5 -45.5t-73.5 -48.5q-1 -2 -3.5 -4.5l-4.5 -4.5q-1 0 -5.5 -2t-9.5 -4t-9 -4t-5 -3q-2 -1 -11.5 -7.5t-21 -14t-22 -14.5t-13.5 -8q-1 -1 -6 -4t-11 -6t-11.5 -6t-6.5 -4q-5 -3 -23 -13.5t-38.5 -22.5t-38.5 -23t-22 -14 q-23 -16 -45 -26.5t-46 -25.5q-3 -2 -10.5 -5.5t-15.5 -7t-14.5 -6.5t-7.5 -4q-6 -3 -20.5 -11t-30.5 -17t-30 -16.5t-20 -10.5l-23 -8q-18 -5 -31.5 1.5t-19.5 26.5q-1 9 -3.5 30t-5.5 45t-5.5 45.5t-3.5 29.5q-2 20 -9 42t-11 42q-1 8 5.5 15t16 12.5t19.5 9.5t16 7 q33 22 65 43t64 45q4 3 15.5 11.5t24.5 18t24.5 18t16.5 11.5q34 25 65.5 41t66.5 40v3v2q-2 1 -5.5 1.5t-5.5 1.5q-1 1 -2 8t-3 8q-27 14 -58.5 24.5t-60.5 18.5q-1 0 -6.5 0.5t-6.5 1.5q-3 2 -14.5 7t-14.5 6q-1 2 -6 1.5t-6 0.5q-12 3 -24.5 7t-24.5 8q-24 10 -48 17 t-49 14q-1 0 -6 1.5t-6 1.5q-2 1 -8.5 3.5t-15 6t-17.5 7t-14 5.5q-14 7 -28 17.5t-16 27.5q-5 50 -10 99t-7 100q-1 0 -1 1v3q-1 5 -0.5 8.5t-0.5 8.5v3v2q1 4 3 12.5t5 9.5q1 0 3 1t3.5 1t3.5 1h11zM921 1345q2 -1 13.5 -7t13.5 -7q9 -3 25 -9t33 -12t31 -11t18 -6 q3 -1 21.5 -6t42 -11l47 -12t37.5 -9q1 0 7 -1t13 -2.5t12.5 -3t7.5 -1.5q1 0 16.5 -5t36 -11.5t42 -13t34.5 -10.5q20 -8 41.5 -14t41.5 -15q18 -8 35 -15.5t36 -14.5q4 -1 21 -5.5t36.5 -10.5t36 -11t21.5 -6q23 -7 48 -18.5t46 -22.5q2 1 4.5 0t4.5 -1q0 -1 5.5 -2 t6.5 -1q19 -5 40 -11t37 -15v-3q0 -1 1 -2v-4q0 -1 1 -8t1.5 -15.5t1.5 -15.5l1 -7q-2 -14 -1.5 -21.5t2.5 -23.5q1 -16 0 -27.5t-1.5 -22t-0.5 -21.5t5 -26q-5 -11 -12.5 -13.5t-15.5 -7.5q-4 -3 -17 -14t-28.5 -23.5t-29 -23.5t-18.5 -13q-38 -26 -76.5 -45.5t-73.5 -48.5 q-1 -2 -3.5 -4.5l-4.5 -4.5q-1 0 -5.5 -2t-9.5 -4t-9 -4t-5 -3q-2 -1 -11.5 -7.5t-21 -14t-22 -14.5t-13.5 -8q-1 -1 -6 -4t-11 -6t-11.5 -6t-6.5 -4q-5 -3 -23 -13.5t-38.5 -22.5t-38.5 -23t-22 -14q-23 -16 -45 -26.5t-46 -25.5q-3 -2 -10.5 -5.5t-15.5 -7t-14.5 -6.5 t-7.5 -4q-6 -3 -20.5 -11t-30.5 -17t-30 -16.5t-20 -10.5l-23 -8q-18 -5 -31.5 1.5t-19.5 26.5q-1 9 -3.5 30t-5.5 45t-5.5 45.5t-3.5 29.5q-2 20 -9 42t-11 42q-1 8 5.5 15t16 12.5t19.5 9.5t16 7q33 22 65 43t64 45q4 3 15.5 11.5t24.5 18t24.5 18t16.5 11.5 q34 25 65.5 41t66.5 40v3v2q-2 1 -5.5 1.5t-5.5 1.5q-1 1 -2 8t-3 8q-27 14 -58.5 24.5t-60.5 18.5q-1 0 -6.5 0.5t-6.5 1.5q-3 2 -14.5 7t-14.5 6q-1 2 -6 1.5t-6 0.5q-12 3 -24.5 7t-24.5 8q-24 10 -48 17t-49 14q-1 0 -6 1.5t-6 1.5q-2 1 -8.5 3.5t-15 6t-17.5 7t-14 5.5 q-14 7 -28 17.5t-16 27.5q-5 50 -10 99t-7 100q-1 0 -1 1v3q-1 5 -0.5 8.5t-0.5 8.5v3v2q1 4 3 12.5t5 9.5q1 0 3 1t3.5 1t3.5 1h11z" />
<glyph unicode="&#xbf;" horiz-adv-x="1164" d="M798 1369q-2 -26 -8 -48.5t-17 -48.5q-2 -4 -6.5 -12t-9 -16.5t-8.5 -15t-5 -8.5q-1 -1 -7 -6t-14.5 -12t-17 -13.5t-13.5 -10.5q-28 -23 -65.5 -33t-72.5 -9q-81 2 -141 50t-87 123v6v11v11.5v7.5q1 28 6 56.5t16 55t28.5 49t41.5 38.5q27 19 51.5 30.5t49 17.5t52 7.5 t60.5 0.5q3 0 7 -1.5t6 -1.5q41 -9 70.5 -31.5t48.5 -53.5t28 -68t7 -75zM713 1093q1 2 12 2.5t23.5 -3t23 -12t9.5 -23.5v-2v-4q0 -1 1.5 -6t3 -11.5t3 -12t1.5 -6.5q1 -5 2.5 -14.5t1.5 -11.5v-8t-0.5 -16t-1 -18.5t-0.5 -15.5q-1 -26 -3 -52.5t-13 -50.5 q-16 -41 -33 -74.5t-46 -65.5q-5 -4 -24 -22t-41 -38t-41 -38t-25 -22q-1 -1 -5.5 -7t-10.5 -13.5l-12 -15t-10 -11.5q-2 -2 -4 -4.5t-4 -5.5q-2 -4 -4 -7l-28 -41q-7 -5 -15 -18t-15.5 -29t-13.5 -31t-9 -24q0 -4 -0.5 -19.5t-0.5 -20.5q-1 -8 -1.5 -23t-0.5 -17 q0 -27 13 -49t33 -38t45 -25t49 -9q34 5 63.5 17.5t53 30t40.5 38t26 39.5q13 26 16.5 44t9.5 43q0 3 8 7q4 2 8 3q3 -1 12.5 -1h18.5h14t-1 0q9 2 30.5 3t49 0.5t58 -2t57.5 -3.5t47 -5.5t27 -7.5v-2q0 -1 2.5 -2.5t6 -2.5t6 -2t1.5 -3v-2q0 -6 3 -11t2 -10 q-1 -42 -12.5 -85.5t-29.5 -85.5t-41 -81t-48 -71q0 -1 -2 -3l-2 -2q-6 -4 -17.5 -11t-23.5 -15.5t-23 -16t-17 -12.5q-5 -1 -13.5 -4.5t-18.5 -8t-19 -8.5t-14 -6q-45 -18 -93 -26t-96 -7q-9 -1 -33.5 -0.5t-55.5 2t-65 3.5t-62.5 4.5t-47 5t-18.5 4.5l-15 6t-20.5 8.5 t-19.5 8.5t-12 5q-4 2 -13 7t-19.5 11t-19.5 11.5t-13 8.5q-25 18 -49 35.5t-44 37t-36 43t-26 52.5q-9 26 -18.5 53.5t-17 56.5t-12 58t-3.5 57q2 38 14.5 69.5t26.5 66.5q8 17 16 33.5t20 29.5q15 17 37.5 37t36.5 42q12 8 30 23t34 32t27 32.5t9 22.5q23 27 37 56.5 t22 61.5v4l19 60q0 2 1.5 7.5t3.5 12.5t4.5 13t4.5 9q0 5 2.5 15t2.5 12v22q2 0 6 10.5t6 10.5q31 12 61 16t63 10q2 0 10.5 0.5t19 1t19.5 1.5t11 1q11 3 27.5 5.5t34.5 4t35.5 2.5t30.5 3z" />
<glyph unicode="&#xc0;" d="M762 1984v3l3 6q1 4 5 6t9 3t9.5 1.5t6.5 0.5h22h1h2q5 0 17 1t14 1q1 1 6.5 2.5t7.5 1.5t7.5 0.5t12 1t12 1t7.5 0.5t8 1.5t8 1.5h1q5 0 13 -2.5t10 -7.5q1 0 2 -3.5t1 -4.5q1 -2 6 -11.5t11 -20t11 -20t6 -11.5t3.5 -8.5t5 -14t4.5 -14.5t2 -8q3 -3 3 -6 q11 -18 14 -32.5t11 -32.5q2 -2 6.5 -12.5t5.5 -12.5v-3q0 -2 0.5 -3t0.5 -2q0 -12 -2 -21.5t-14 -5.5q-1 0 -6 -1.5t-11 -3t-11 -2.5t-6 -1q-14 -2 -25 -5.5t-20.5 -7t-20 -6t-24.5 -2.5q-4 0 -11.5 0.5t-8.5 0.5l-9 6l-2.5 4.5t-5.5 11.5t-6.5 14t-6.5 12 q-14 29 -25.5 58.5t-25.5 57.5q-11 23 -17 43t-17 43v3zM1262 173q-8 5 -11 13t-3.5 17.5t-0.5 18.5t-1 15q0 2 -5 14.5t-7 18.5q-1 1 -4 6.5t-6 11.5t-6.5 12t-4.5 10q-2 4 -7 11.5t-11 9.5q-2 0 -13 1.5t-16 3.5h-12h-17t-17 0.5t-11 1.5q-6 0 -25.5 -1t-41.5 -1.5 t-41.5 -1.5t-24.5 -1q-6 0 -29 2.5t-50 5t-50 5t-29 2.5q-40 2 -83 -1t-81 -5q-1 0 -2 -0.5t-3 -0.5h-3q-7 0 -19.5 -1.5l-25 -3t-22.5 -3t-12 -1.5q-3 -2 -8 -2.5t-10 -2.5t-11 -3q-10 -8 -21 -22.5t-17 -26.5q-18 -39 -33.5 -76t-31.5 -79q-5 -15 -9 -31t-8.5 -31.5 t-10.5 -31t-16 -30.5q-3 0 -15 -1t-15 -1q-29 -2 -59.5 -1.5t-59.5 5.5q-23 5 -47 12.5t-47 10.5q-2 1 -8.5 1.5t-14 0.5t-14 0.5t-8.5 0.5t-10 -1t-17 -1.5t-16.5 -1t-10.5 0.5q-3 0 -10 3.5t-7 8.5v4q-1 5 0.5 18t2.5 17q14 5 21 17.5t12 24.5q13 39 26 77.5t28 76.5 q15 43 36.5 82.5t39.5 82.5q0 2 2 8t4 13t4 13t3 8q1 3 6.5 15.5t11.5 26t11 26t7 15.5q0 2 3 10t6 17t6 17t3 10q14 35 31.5 65.5t30.5 69.5q26 84 56.5 167t59.5 165q22 62 46.5 123.5t48.5 124.5q0 1 1.5 8t4 15t4.5 14.5t3 8.5q2 2 5.5 12t5.5 12q0 1 1.5 5.5l3 9 t2.5 8.5t1 5q1 4 5 14t7.5 20.5t7 19.5t4.5 12q1 1 4 8t6.5 15.5t6.5 15.5t3 10q1 3 4 10.5t6.5 15.5t6.5 15.5t5 10.5q0 2 1.5 9.5t3.5 7.5q0 3 3.5 11t7.5 17t8 17l5 10q3 5 7 17t10 12l4 1q39 -5 76.5 -8t77.5 -1q43 2 66.5 0t36.5 -4t20 -3t18 4q5 0 14 -3t18 -8 t16.5 -10t9.5 -8q5 -8 16 -25.5t22.5 -36.5t21.5 -36.5t15 -26.5q15 -27 33.5 -61.5t29.5 -64.5q2 -3 4.5 -9t2.5 -8q1 -2 4 -6.5t6 -10t5.5 -10.5t2.5 -6q24 -50 37.5 -101t34.5 -102q20 -47 44 -92.5t44 -93.5q1 -2 4.5 -11.5t8 -20.5t8.5 -21t5 -12q14 -35 33.5 -67.5 t32.5 -67.5q31 -77 59 -155t56 -156.5t59 -155.5t69 -152q1 -2 6 -10t10.5 -17.5t10 -18t6.5 -10.5q2 -4 7 -14.5t5 -12.5t-1.5 -8t-3.5 -9q-1 -2 -11.5 -5t-23.5 -5.5t-25 -4.5t-15 -2q-42 -3 -82.5 0.5t-82.5 0.5q-12 -1 -22.5 -7t-23.5 -8q-2 0 -13.5 -0.5t-16.5 -1.5 q-7 0 -19 -1t-14 -1q-5 0 -14.5 1t-20 2.5t-19 5.5t-11.5 10zM738 710q31 5 62 5t62.5 -2t62.5 -3.5t62 0.5q3 0 10.5 0.5t15.5 1t14.5 1t9.5 0.5q12 5 15 10t1 18v14q-1 1 -3.5 6.5t-4.5 11.5l-4 12t-3 8l-10.5 24.5t-16 36t-16 35t-10.5 22.5q-3 5 -10 17.5t-11 16.5 q0 2 -5 5.5t-6 5.5q-2 2 -4.5 13.5t-2.5 14.5q-2 4 -7.5 16.5t-7.5 17.5q-3 5 -9.5 18.5t-14 28.5t-14 28.5t-9.5 18.5q-2 5 -9.5 17.5t-9.5 15.5l-2 2q-1 0 -3 -2l-1 -1q-2 -2 -5.5 -8t-3.5 -8q-1 -3 -5 -14t-8 -23l-7.5 -22.5t-3.5 -12.5q-2 -2 -5.5 -9.5t-8 -16.5 l-8.5 -17t-6 -10q-25 -63 -46.5 -124.5t-45.5 -123.5q0 -1 -1.5 -6.5t-4 -12t-4 -12t-1.5 -6.5q-2 -2 -1.5 -4t0.5 -4q3 0 9.5 2.5t13.5 4t13 0.5t8 -7z" />
<glyph unicode="&#xc1;" d="M1044 1977q-12 -22 -19.5 -42t-19.5 -42q-15 -28 -29 -56.5t-30 -57.5q-3 -5 -6.5 -12.5t-7 -14t-6.5 -11.5l-3 -5l-10 -5q-1 0 -8.5 -0.5t-11.5 -0.5q-14 1 -24 4t-20 6.5l-20 7t-24 5.5q-1 0 -6 1.5t-11 3t-11 3t-6 1.5q-12 -3 -13.5 6.5t-0.5 21.5q0 3 1 5q0 2 1 3 l6 12t7 12q9 18 13 32.5t17 31.5q0 3 3 6q0 1 2.5 8t5.5 14.5t5.5 14t3.5 8.5t6.5 11.5t12.5 20t12.5 20t6.5 11.5q0 1 1.5 4t2.5 3q2 5 10 7.5t13 2.5h1q2 0 8 -2t8 -2q1 0 7 -0.5t12.5 -1.5t12 -1.5t7.5 -0.5t7.5 -1.5t6.5 -2.5q2 0 14 -1t17 -2h2h1h11t11 -1 q1 0 5.5 -0.5t9.5 -1.5t9 -3.5t5 -6.5l3 -6q-1 0 -1 -1v-2v-3v0zM1262 173q-8 5 -11 13t-3.5 17.5t-0.5 18.5t-1 15q0 2 -5 14.5t-7 18.5q-1 1 -4 6.5t-6 11.5t-6.5 12t-4.5 10q-2 4 -7 11.5t-11 9.5q-2 0 -13 1.5t-16 3.5h-12h-17t-17 0.5t-11 1.5q-6 0 -25.5 -1 t-41.5 -1.5t-41.5 -1.5t-24.5 -1q-6 0 -29 2.5t-50 5t-50 5t-29 2.5q-40 2 -83 -1t-81 -5q-1 0 -2 -0.5t-3 -0.5h-3q-7 0 -19.5 -1.5l-25 -3t-22.5 -3t-12 -1.5q-3 -2 -8 -2.5t-10 -2.5t-11 -3q-10 -8 -21 -22.5t-17 -26.5q-18 -39 -33.5 -76t-31.5 -79q-5 -15 -9 -31 t-8.5 -31.5t-10.5 -31t-16 -30.5q-3 0 -15 -1t-15 -1q-29 -2 -59.5 -1.5t-59.5 5.5q-23 5 -47 12.5t-47 10.5q-2 1 -8.5 1.5t-14 0.5t-14 0.5t-8.5 0.5t-10 -1t-17 -1.5t-16.5 -1t-10.5 0.5q-3 0 -10 3.5t-7 8.5v4q-1 5 0.5 18t2.5 17q14 5 21 17.5t12 24.5q13 39 26 77.5 t28 76.5q15 43 36.5 82.5t39.5 82.5q0 2 2 8t4 13t4 13t3 8q1 3 6.5 15.5t11.5 26t11 26t7 15.5q0 2 3 10t6 17t6 17t3 10q14 35 31.5 65.5t30.5 69.5q26 84 56.5 167t59.5 165q22 62 46.5 123.5t48.5 124.5q0 1 1.5 8t4 15t4.5 14.5t3 8.5q2 2 5.5 12t5.5 12q0 1 1.5 5.5 l3 9t2.5 8.5t1 5q1 4 5 14t7.5 20.5t7 19.5t4.5 12q1 1 4 8t6.5 15.5t6.5 15.5t3 10q1 3 4 10.5t6.5 15.5t6.5 15.5t5 10.5q0 2 1.5 9.5t3.5 7.5q0 3 3.5 11t7.5 17t8 17l5 10q3 5 7 17t10 12l4 1q39 -5 76.5 -8t77.5 -1q43 2 66.5 0t36.5 -4t20 -3t18 4q5 0 14 -3t18 -8 t16.5 -10t9.5 -8q5 -8 16 -25.5t22.5 -36.5t21.5 -36.5t15 -26.5q15 -27 33.5 -61.5t29.5 -64.5q2 -3 4.5 -9t2.5 -8q1 -2 4 -6.5t6 -10t5.5 -10.5t2.5 -6q24 -50 37.5 -101t34.5 -102q20 -47 44 -92.5t44 -93.5q1 -2 4.5 -11.5t8 -20.5t8.5 -21t5 -12q14 -35 33.5 -67.5 t32.5 -67.5q31 -77 59 -155t56 -156.5t59 -155.5t69 -152q1 -2 6 -10t10.5 -17.5t10 -18t6.5 -10.5q2 -4 7 -14.5t5 -12.5t-1.5 -8t-3.5 -9q-1 -2 -11.5 -5t-23.5 -5.5t-25 -4.5t-15 -2q-42 -3 -82.5 0.5t-82.5 0.5q-12 -1 -22.5 -7t-23.5 -8q-2 0 -13.5 -0.5t-16.5 -1.5 q-7 0 -19 -1t-14 -1q-5 0 -14.5 1t-20 2.5t-19 5.5t-11.5 10zM738 710q31 5 62 5t62.5 -2t62.5 -3.5t62 0.5q3 0 10.5 0.5t15.5 1t14.5 1t9.5 0.5q12 5 15 10t1 18v14q-1 1 -3.5 6.5t-4.5 11.5l-4 12t-3 8l-10.5 24.5t-16 36t-16 35t-10.5 22.5q-3 5 -10 17.5t-11 16.5 q0 2 -5 5.5t-6 5.5q-2 2 -4.5 13.5t-2.5 14.5q-2 4 -7.5 16.5t-7.5 17.5q-3 5 -9.5 18.5t-14 28.5t-14 28.5t-9.5 18.5q-2 5 -9.5 17.5t-9.5 15.5l-2 2q-1 0 -3 -2l-1 -1q-2 -2 -5.5 -8t-3.5 -8q-1 -3 -5 -14t-8 -23l-7.5 -22.5t-3.5 -12.5q-2 -2 -5.5 -9.5t-8 -16.5 l-8.5 -17t-6 -10q-25 -63 -46.5 -124.5t-45.5 -123.5q0 -1 -1.5 -6.5t-4 -12t-4 -12t-1.5 -6.5q-2 -2 -1.5 -4t0.5 -4q3 0 9.5 2.5t13.5 4t13 0.5t8 -7z" />
<glyph unicode="&#xc2;" d="M681 1755q-22 4 -25 10t-6 8v1v1q5 13 14.5 27.5t16.5 25.5q4 7 11 18t14.5 24t14 26.5t11.5 25.5q6 8 9.5 16.5t7.5 17.5q11 27 17.5 39t15.5 22q1 1 5 2.5t6 1.5q4 0 16.5 0.5t26 1t25.5 0.5h17h42q1 0 5.5 0.5t9.5 1.5t9.5 1.5t5.5 0.5h5q7 1 10 -0.5t4 -4t1 -6 t2 -5.5q1 -1 2.5 -5.5t1.5 -5.5q1 -2 3.5 -5.5t3.5 -3.5q-4 4 2 -10.5t15.5 -36t20.5 -44t18 -35.5q4 -5 4 -11.5t2 -11.5q4 -10 8 -19.5t9 -20.5q2 -4 7.5 -12t5.5 -14q0 -2 -2.5 -5.5t-4.5 -4.5h-16q-1 0 -3.5 -1.5t-3.5 -1.5t-13.5 -1t-19.5 -1q-26 -2 -48 -9 q-13 -2 -25 -5.5t-25 -3.5q-8 0 -16.5 0.5t-13.5 6.5q-8 14 -12.5 28.5t-14.5 26.5q-2 -2 -3 -3.5t-3 -3.5q-1 -4 -7 -14.5t-8 -12.5q-1 -2 -4.5 -7.5t-9 -11t-12 -9t-13.5 -1.5h-4h-16.5h-12.5t-12.5 1t-15.5 3q-3 1 -11 2t-17 2.5t-16.5 3t-10.5 1.5zM1262 173 q-8 5 -11 13t-3.5 17.5t-0.5 18.5t-1 15q0 2 -5 14.5t-7 18.5q-1 1 -4 6.5t-6 11.5t-6.5 12t-4.5 10q-2 4 -7 11.5t-11 9.5q-2 0 -13 1.5t-16 3.5h-12h-17t-17 0.5t-11 1.5q-6 0 -25.5 -1t-41.5 -1.5t-41.5 -1.5t-24.5 -1q-6 0 -29 2.5t-50 5t-50 5t-29 2.5q-40 2 -83 -1 t-81 -5q-1 0 -2 -0.5t-3 -0.5h-3q-7 0 -19.5 -1.5l-25 -3t-22.5 -3t-12 -1.5q-3 -2 -8 -2.5t-10 -2.5t-11 -3q-10 -8 -21 -22.5t-17 -26.5q-18 -39 -33.5 -76t-31.5 -79q-5 -15 -9 -31t-8.5 -31.5t-10.5 -31t-16 -30.5q-3 0 -15 -1t-15 -1q-29 -2 -59.5 -1.5t-59.5 5.5 q-23 5 -47 12.5t-47 10.5q-2 1 -8.5 1.5t-14 0.5t-14 0.5t-8.5 0.5t-10 -1t-17 -1.5t-16.5 -1t-10.5 0.5q-3 0 -10 3.5t-7 8.5v4q-1 5 0.5 18t2.5 17q14 5 21 17.5t12 24.5q13 39 26 77.5t28 76.5q15 43 36.5 82.5t39.5 82.5q0 2 2 8t4 13t4 13t3 8q1 3 6.5 15.5t11.5 26 t11 26t7 15.5q0 2 3 10t6 17t6 17t3 10q14 35 31.5 65.5t30.5 69.5q26 84 56.5 167t59.5 165q22 62 46.5 123.5t48.5 124.5q0 1 1.5 8t4 15t4.5 14.5t3 8.5q2 2 5.5 12t5.5 12q0 1 1.5 5.5l3 9t2.5 8.5t1 5q1 4 5 14t7.5 20.5t7 19.5t4.5 12q1 1 4 8t6.5 15.5t6.5 15.5t3 10 q1 3 4 10.5t6.5 15.5t6.5 15.5t5 10.5q0 2 1.5 9.5t3.5 7.5q0 3 3.5 11t7.5 17t8 17l5 10q3 5 7 17t10 12l4 1q39 -5 76.5 -8t77.5 -1q43 2 66.5 0t36.5 -4t20 -3t18 4q5 0 14 -3t18 -8t16.5 -10t9.5 -8q5 -8 16 -25.5t22.5 -36.5t21.5 -36.5t15 -26.5q15 -27 33.5 -61.5 t29.5 -64.5q2 -3 4.5 -9t2.5 -8q1 -2 4 -6.5t6 -10t5.5 -10.5t2.5 -6q24 -50 37.5 -101t34.5 -102q20 -47 44 -92.5t44 -93.5q1 -2 4.5 -11.5t8 -20.5t8.5 -21t5 -12q14 -35 33.5 -67.5t32.5 -67.5q31 -77 59 -155t56 -156.5t59 -155.5t69 -152q1 -2 6 -10t10.5 -17.5 t10 -18t6.5 -10.5q2 -4 7 -14.5t5 -12.5t-1.5 -8t-3.5 -9q-1 -2 -11.5 -5t-23.5 -5.5t-25 -4.5t-15 -2q-42 -3 -82.5 0.5t-82.5 0.5q-12 -1 -22.5 -7t-23.5 -8q-2 0 -13.5 -0.5t-16.5 -1.5q-7 0 -19 -1t-14 -1q-5 0 -14.5 1t-20 2.5t-19 5.5t-11.5 10zM738 710q31 5 62 5 t62.5 -2t62.5 -3.5t62 0.5q3 0 10.5 0.5t15.5 1t14.5 1t9.5 0.5q12 5 15 10t1 18v14q-1 1 -3.5 6.5t-4.5 11.5l-4 12t-3 8l-10.5 24.5t-16 36t-16 35t-10.5 22.5q-3 5 -10 17.5t-11 16.5q0 2 -5 5.5t-6 5.5q-2 2 -4.5 13.5t-2.5 14.5q-2 4 -7.5 16.5t-7.5 17.5 q-3 5 -9.5 18.5t-14 28.5t-14 28.5t-9.5 18.5q-2 5 -9.5 17.5t-9.5 15.5l-2 2q-1 0 -3 -2l-1 -1q-2 -2 -5.5 -8t-3.5 -8q-1 -3 -5 -14t-8 -23l-7.5 -22.5t-3.5 -12.5q-2 -2 -5.5 -9.5t-8 -16.5l-8.5 -17t-6 -10q-25 -63 -46.5 -124.5t-45.5 -123.5q0 -1 -1.5 -6.5t-4 -12 t-4 -12t-1.5 -6.5q-2 -2 -1.5 -4t0.5 -4q3 0 9.5 2.5t13.5 4t13 0.5t8 -7z" />
<glyph unicode="&#xc3;" d="M508 1845q0 1 -1.5 3.5t-1.5 3.5t3 5t5 5v5q12 32 37.5 56.5t48.5 49.5q2 1 8.5 8t8.5 8q29 30 67.5 53t80.5 23q18 0 33.5 -1.5t32.5 -9.5q10 -4 20.5 -10.5t21.5 -6.5l31 -22q4 -2 14.5 -8t22.5 -12t22.5 -11.5t14.5 -7.5q11 -6 19.5 -7t19.5 -1q15 0 34 13.5t28 26.5 q3 3 8 10t10.5 14.5t9.5 13.5t5 8q5 8 9 13t15 5h3q1 -1 6.5 -5.5t7.5 -6.5q14 -14 30 -26t30.5 -21.5t26.5 -17.5t20 -15q6 -7 12.5 -12t9.5 -10t2 -11t-8 -15q-9 -15 -18.5 -27.5t-20.5 -28.5q-20 -26 -41.5 -51.5t-47 -45.5t-55 -32t-64.5 -12q-9 -1 -26 3.5t-34.5 11.5 t-33.5 14t-24 12q-2 3 -11 12t-12 11q-17 14 -34 19.5t-40 5.5q-27 0 -51.5 -13t-42.5 -37q-7 -11 -12.5 -18.5t-12 -12.5t-15 -7.5t-22.5 -2.5q-3 0 -8 1t-7 1q-1 0 -6 4.5t-7 4.5q-2 2 -5.5 4t-4.5 4q-17 11 -29 18t-27 22q-1 0 -7 4q-3 2 -6 5q-3 2 -8.5 8.5t-12.5 13.5 t-12.5 13t-8.5 9zM1262 173q-8 5 -11 13t-3.5 17.5t-0.5 18.5t-1 15q0 2 -5 14.5t-7 18.5q-1 1 -4 6.5t-6 11.5t-6.5 12t-4.5 10q-2 4 -7 11.5t-11 9.5q-2 0 -13 1.5t-16 3.5h-12h-17t-17 0.5t-11 1.5q-6 0 -25.5 -1t-41.5 -1.5t-41.5 -1.5t-24.5 -1q-6 0 -29 2.5t-50 5 t-50 5t-29 2.5q-40 2 -83 -1t-81 -5q-1 0 -2 -0.5t-3 -0.5h-3q-7 0 -19.5 -1.5l-25 -3t-22.5 -3t-12 -1.5q-3 -2 -8 -2.5t-10 -2.5t-11 -3q-10 -8 -21 -22.5t-17 -26.5q-18 -39 -33.5 -76t-31.5 -79q-5 -15 -9 -31t-8.5 -31.5t-10.5 -31t-16 -30.5q-3 0 -15 -1t-15 -1 q-29 -2 -59.5 -1.5t-59.5 5.5q-23 5 -47 12.5t-47 10.5q-2 1 -8.5 1.5t-14 0.5t-14 0.5t-8.5 0.5t-10 -1t-17 -1.5t-16.5 -1t-10.5 0.5q-3 0 -10 3.5t-7 8.5v4q-1 5 0.5 18t2.5 17q14 5 21 17.5t12 24.5q13 39 26 77.5t28 76.5q15 43 36.5 82.5t39.5 82.5q0 2 2 8t4 13t4 13 t3 8q1 3 6.5 15.5t11.5 26t11 26t7 15.5q0 2 3 10t6 17t6 17t3 10q14 35 31.5 65.5t30.5 69.5q26 84 56.5 167t59.5 165q22 62 46.5 123.5t48.5 124.5q0 1 1.5 8t4 15t4.5 14.5t3 8.5q2 2 5.5 12t5.5 12q0 1 1.5 5.5l3 9t2.5 8.5t1 5q1 4 5 14t7.5 20.5t7 19.5t4.5 12 q1 1 4 8t6.5 15.5t6.5 15.5t3 10q1 3 4 10.5t6.5 15.5t6.5 15.5t5 10.5q0 2 1.5 9.5t3.5 7.5q0 3 3.5 11t7.5 17t8 17l5 10q3 5 7 17t10 12l4 1q39 -5 76.5 -8t77.5 -1q43 2 66.5 0t36.5 -4t20 -3t18 4q5 0 14 -3t18 -8t16.5 -10t9.5 -8q5 -8 16 -25.5t22.5 -36.5 t21.5 -36.5t15 -26.5q15 -27 33.5 -61.5t29.5 -64.5q2 -3 4.5 -9t2.5 -8q1 -2 4 -6.5t6 -10t5.5 -10.5t2.5 -6q24 -50 37.5 -101t34.5 -102q20 -47 44 -92.5t44 -93.5q1 -2 4.5 -11.5t8 -20.5t8.5 -21t5 -12q14 -35 33.5 -67.5t32.5 -67.5q31 -77 59 -155t56 -156.5 t59 -155.5t69 -152q1 -2 6 -10t10.5 -17.5t10 -18t6.5 -10.5q2 -4 7 -14.5t5 -12.5t-1.5 -8t-3.5 -9q-1 -2 -11.5 -5t-23.5 -5.5t-25 -4.5t-15 -2q-42 -3 -82.5 0.5t-82.5 0.5q-12 -1 -22.5 -7t-23.5 -8q-2 0 -13.5 -0.5t-16.5 -1.5q-7 0 -19 -1t-14 -1q-5 0 -14.5 1 t-20 2.5t-19 5.5t-11.5 10zM738 710q31 5 62 5t62.5 -2t62.5 -3.5t62 0.5q3 0 10.5 0.5t15.5 1t14.5 1t9.5 0.5q12 5 15 10t1 18v14q-1 1 -3.5 6.5t-4.5 11.5l-4 12t-3 8l-10.5 24.5t-16 36t-16 35t-10.5 22.5q-3 5 -10 17.5t-11 16.5q0 2 -5 5.5t-6 5.5q-2 2 -4.5 13.5 t-2.5 14.5q-2 4 -7.5 16.5t-7.5 17.5q-3 5 -9.5 18.5t-14 28.5t-14 28.5t-9.5 18.5q-2 5 -9.5 17.5t-9.5 15.5l-2 2q-1 0 -3 -2l-1 -1q-2 -2 -5.5 -8t-3.5 -8q-1 -3 -5 -14t-8 -23l-7.5 -22.5t-3.5 -12.5q-2 -2 -5.5 -9.5t-8 -16.5l-8.5 -17t-6 -10q-25 -63 -46.5 -124.5 t-45.5 -123.5q0 -1 -1.5 -6.5t-4 -12t-4 -12t-1.5 -6.5q-2 -2 -1.5 -4t0.5 -4q3 0 9.5 2.5t13.5 4t13 0.5t8 -7z" />
<glyph unicode="&#xc4;" d="M832 1896v-18t-4 -19q-7 -14 -12 -26.5t-16 -24.5q-6 -7 -19 -16.5t-16 -12.5q-14 -13 -31 -13t-34 -1q-11 -1 -18 1t-18 7q-5 0 -13.5 4t-13.5 7q-26 16 -44.5 40t-21.5 57q0 20 0.5 34t4.5 26t13 23t24 24q14 13 34 23.5t38 11.5q5 1 17 0.5t15 -1.5q6 -1 18.5 -4 t14.5 -4q1 -1 6 -2.5t10.5 -3.5t10.5 -3.5t7 -2.5q28 -21 37 -45t11 -61zM1143 1893q0 -8 0.5 -17.5t-3.5 -19.5q-7 -14 -12 -26t-16 -24q-3 -3 -8 -7.5t-10 -8.5l-10 -8t-6 -5q-14 -13 -31.5 -13t-34.5 -1q-11 -1 -17.5 1.5t-17.5 5.5q-5 1 -14 5t-14 8q-26 15 -44 38.5 t-23 56.5q0 20 1 34t5.5 26t13.5 23t24 25q13 13 33 23.5t38 11.5q4 1 17 0.5t16 -1.5q5 -1 17.5 -4.5t15.5 -3.5q1 -1 5.5 -3t10 -3.5t10.5 -3t7 -2.5q28 -22 37.5 -45.5t9.5 -61.5zM1262 173q-8 5 -11 13t-3.5 17.5t-0.5 18.5t-1 15q0 2 -5 14.5t-7 18.5q-1 1 -4 6.5 t-6 11.5t-6.5 12t-4.5 10q-2 4 -7 11.5t-11 9.5q-2 0 -13 1.5t-16 3.5h-12h-17t-17 0.5t-11 1.5q-6 0 -25.5 -1t-41.5 -1.5t-41.5 -1.5t-24.5 -1q-6 0 -29 2.5t-50 5t-50 5t-29 2.5q-40 2 -83 -1t-81 -5q-1 0 -2 -0.5t-3 -0.5h-3q-7 0 -19.5 -1.5l-25 -3t-22.5 -3t-12 -1.5 q-3 -2 -8 -2.5t-10 -2.5t-11 -3q-10 -8 -21 -22.5t-17 -26.5q-18 -39 -33.5 -76t-31.5 -79q-5 -15 -9 -31t-8.5 -31.5t-10.5 -31t-16 -30.5q-3 0 -15 -1t-15 -1q-29 -2 -59.5 -1.5t-59.5 5.5q-23 5 -47 12.5t-47 10.5q-2 1 -8.5 1.5t-14 0.5t-14 0.5t-8.5 0.5t-10 -1 t-17 -1.5t-16.5 -1t-10.5 0.5q-3 0 -10 3.5t-7 8.5v4q-1 5 0.5 18t2.5 17q14 5 21 17.5t12 24.5q13 39 26 77.5t28 76.5q15 43 36.5 82.5t39.5 82.5q0 2 2 8t4 13t4 13t3 8q1 3 6.5 15.5t11.5 26t11 26t7 15.5q0 2 3 10t6 17t6 17t3 10q14 35 31.5 65.5t30.5 69.5 q26 84 56.5 167t59.5 165q22 62 46.5 123.5t48.5 124.5q0 1 1.5 8t4 15t4.5 14.5t3 8.5q2 2 5.5 12t5.5 12q0 1 1.5 5.5l3 9t2.5 8.5t1 5q1 4 5 14t7.5 20.5t7 19.5t4.5 12q1 1 4 8t6.5 15.5t6.5 15.5t3 10q1 3 4 10.5t6.5 15.5t6.5 15.5t5 10.5q0 2 1.5 9.5t3.5 7.5 q0 3 3.5 11t7.5 17t8 17l5 10q3 5 7 17t10 12l4 1q39 -5 76.5 -8t77.5 -1q43 2 66.5 0t36.5 -4t20 -3t18 4q5 0 14 -3t18 -8t16.5 -10t9.5 -8q5 -8 16 -25.5t22.5 -36.5t21.5 -36.5t15 -26.5q15 -27 33.5 -61.5t29.5 -64.5q2 -3 4.5 -9t2.5 -8q1 -2 4 -6.5t6 -10t5.5 -10.5 t2.5 -6q24 -50 37.5 -101t34.5 -102q20 -47 44 -92.5t44 -93.5q1 -2 4.5 -11.5t8 -20.5t8.5 -21t5 -12q14 -35 33.5 -67.5t32.5 -67.5q31 -77 59 -155t56 -156.5t59 -155.5t69 -152q1 -2 6 -10t10.5 -17.5t10 -18t6.5 -10.5q2 -4 7 -14.5t5 -12.5t-1.5 -8t-3.5 -9 q-1 -2 -11.5 -5t-23.5 -5.5t-25 -4.5t-15 -2q-42 -3 -82.5 0.5t-82.5 0.5q-12 -1 -22.5 -7t-23.5 -8q-2 0 -13.5 -0.5t-16.5 -1.5q-7 0 -19 -1t-14 -1q-5 0 -14.5 1t-20 2.5t-19 5.5t-11.5 10zM738 710q31 5 62 5t62.5 -2t62.5 -3.5t62 0.5q3 0 10.5 0.5t15.5 1t14.5 1 t9.5 0.5q12 5 15 10t1 18v14q-1 1 -3.5 6.5t-4.5 11.5l-4 12t-3 8l-10.5 24.5t-16 36t-16 35t-10.5 22.5q-3 5 -10 17.5t-11 16.5q0 2 -5 5.5t-6 5.5q-2 2 -4.5 13.5t-2.5 14.5q-2 4 -7.5 16.5t-7.5 17.5q-3 5 -9.5 18.5t-14 28.5t-14 28.5t-9.5 18.5q-2 5 -9.5 17.5 t-9.5 15.5l-2 2q-1 0 -3 -2l-1 -1q-2 -2 -5.5 -8t-3.5 -8q-1 -3 -5 -14t-8 -23l-7.5 -22.5t-3.5 -12.5q-2 -2 -5.5 -9.5t-8 -16.5l-8.5 -17t-6 -10q-25 -63 -46.5 -124.5t-45.5 -123.5q0 -1 -1.5 -6.5t-4 -12t-4 -12t-1.5 -6.5q-2 -2 -1.5 -4t0.5 -4q3 0 9.5 2.5t13.5 4 t13 0.5t8 -7z" />
<glyph unicode="&#xc5;" d="M914 1848q0 17 -4 27.5t-17 20.5q-2 0 -7.5 2t-7.5 3q-1 0 -6.5 1.5t-7.5 2.5h-16q-8 0 -16.5 -5.5t-14.5 -10.5q-14 -11 -17 -20.5t-3 -27.5q4 -27 31 -43q2 -2 5.5 -3.5t6.5 -1.5l7.5 -3t7.5 0h16t14 5q2 2 7.5 6t8.5 7q5 5 7 11t5 13q2 4 1.5 8t-0.5 8zM975 1841 q0 -8 -0.5 -15t-2.5 -15l-3 -11q-8 -17 -21 -35q-3 -3 -9.5 -8t-11.5 -9l-3 -3l-2 -2l-2 -2q-13 -14 -26 -16t-27 -2h-9q-9 -1 -15.5 0.5t-12.5 3.5l-5 1q-2 2 -0.5 0.5t-1.5 -0.5q-7 3 -16.5 8t-13.5 8q-24 14 -40 35t-19 52q0 18 1 32t5.5 25.5t13 22t22.5 22.5 q12 12 30.5 21.5t35.5 9.5h26q2 -1 5 -2q6 -2 9 -2l-2 1q2 -1 5 -1t6 -1q4 -1 7 -2q4 -2 15 -5.5t16 -4.5q29 -22 37.5 -44.5t8.5 -56.5v-5zM1262 173q-8 5 -11 13t-3.5 17.5t-0.5 18.5t-1 15q0 2 -5 14.5t-7 18.5q-1 1 -4 6.5t-6 11.5t-6.5 12t-4.5 10q-2 4 -7 11.5 t-11 9.5q-2 0 -13 1.5t-16 3.5h-12h-17t-17 0.5t-11 1.5q-6 0 -25.5 -1t-41.5 -1.5t-41.5 -1.5t-24.5 -1q-6 0 -29 2.5t-50 5t-50 5t-29 2.5q-40 2 -83 -1t-81 -5q-1 0 -2 -0.5t-3 -0.5h-3q-7 0 -19.5 -1.5l-25 -3t-22.5 -3t-12 -1.5q-3 -2 -8 -2.5t-10 -2.5t-11 -3 q-10 -8 -21 -22.5t-17 -26.5q-18 -39 -33.5 -76t-31.5 -79q-5 -15 -9 -31t-8.5 -31.5t-10.5 -31t-16 -30.5q-3 0 -15 -1t-15 -1q-29 -2 -59.5 -1.5t-59.5 5.5q-23 5 -47 12.5t-47 10.5q-2 1 -8.5 1.5t-14 0.5t-14 0.5t-8.5 0.5t-10 -1t-17 -1.5t-16.5 -1t-10.5 0.5 q-3 0 -10 3.5t-7 8.5v4q-1 5 0.5 18t2.5 17q14 5 21 17.5t12 24.5q13 39 26 77.5t28 76.5q15 43 36.5 82.5t39.5 82.5q0 2 2 8t4 13t4 13t3 8q1 3 6.5 15.5t11.5 26t11 26t7 15.5q0 2 3 10t6 17t6 17t3 10q14 35 31.5 65.5t30.5 69.5q26 84 56.5 167t59.5 165 q22 62 46.5 123.5t48.5 124.5q0 1 1.5 8t4 15t4.5 14.5t3 8.5q2 2 5.5 12t5.5 12q0 1 1.5 5.5l3 9t2.5 8.5t1 5q1 4 5 14t7.5 20.5t7 19.5t4.5 12q1 1 4 8t6.5 15.5t6.5 15.5t3 10q1 3 4 10.5t6.5 15.5t6.5 15.5t5 10.5q0 2 1.5 9.5t3.5 7.5q0 3 3.5 11t7.5 17t8 17l5 10 q3 5 7 17t10 12l4 1q39 -5 76.5 -8t77.5 -1q43 2 66.5 0t36.5 -4t20 -3t18 4q5 0 14 -3t18 -8t16.5 -10t9.5 -8q5 -8 16 -25.5t22.5 -36.5t21.5 -36.5t15 -26.5q15 -27 33.5 -61.5t29.5 -64.5q2 -3 4.5 -9t2.5 -8q1 -2 4 -6.5t6 -10t5.5 -10.5t2.5 -6q24 -50 37.5 -101 t34.5 -102q20 -47 44 -92.5t44 -93.5q1 -2 4.5 -11.5t8 -20.5t8.5 -21t5 -12q14 -35 33.5 -67.5t32.5 -67.5q31 -77 59 -155t56 -156.5t59 -155.5t69 -152q1 -2 6 -10t10.5 -17.5t10 -18t6.5 -10.5q2 -4 7 -14.5t5 -12.5t-1.5 -8t-3.5 -9q-1 -2 -11.5 -5t-23.5 -5.5 t-25 -4.5t-15 -2q-42 -3 -82.5 0.5t-82.5 0.5q-12 -1 -22.5 -7t-23.5 -8q-2 0 -13.5 -0.5t-16.5 -1.5q-7 0 -19 -1t-14 -1q-5 0 -14.5 1t-20 2.5t-19 5.5t-11.5 10zM738 710q31 5 62 5t62.5 -2t62.5 -3.5t62 0.5q3 0 10.5 0.5t15.5 1t14.5 1t9.5 0.5q12 5 15 10t1 18v14 q-1 1 -3.5 6.5t-4.5 11.5l-4 12t-3 8l-10.5 24.5t-16 36t-16 35t-10.5 22.5q-3 5 -10 17.5t-11 16.5q0 2 -5 5.5t-6 5.5q-2 2 -4.5 13.5t-2.5 14.5q-2 4 -7.5 16.5t-7.5 17.5q-3 5 -9.5 18.5t-14 28.5t-14 28.5t-9.5 18.5q-2 5 -9.5 17.5t-9.5 15.5l-2 2q-1 0 -3 -2l-1 -1 q-2 -2 -5.5 -8t-3.5 -8q-1 -3 -5 -14t-8 -23l-7.5 -22.5t-3.5 -12.5q-2 -2 -5.5 -9.5t-8 -16.5l-8.5 -17t-6 -10q-25 -63 -46.5 -124.5t-45.5 -123.5q0 -1 -1.5 -6.5t-4 -12t-4 -12t-1.5 -6.5q-2 -2 -1.5 -4t0.5 -4q3 0 9.5 2.5t13.5 4t13 0.5t8 -7z" />
<glyph unicode="&#xc6;" horiz-adv-x="1977" d="M1102 16q-2 1 -11 2.5t-19.5 4t-20.5 4t-13 2.5h-16q-2 0 -6 -3t-6 -3q-8 0 -16.5 10t-12.5 12q-10 6 -24 8.5t-20 16.5q2 69 0 135t-2 135q-15 1 -36.5 3.5t-42.5 4.5t-37.5 4t-20.5 2q-40 2 -83 -1t-81 -5q-1 0 -2 -0.5t-3 -0.5h-3q-7 0 -19.5 -1.5l-25 -3t-22.5 -3 t-12 -1.5q-3 -2 -8 -2.5t-10 -2.5t-11 -3q-10 -8 -21 -22.5t-17 -26.5q-18 -39 -33.5 -76t-31.5 -79q-5 -15 -9 -31t-8.5 -31.5t-10.5 -31t-16 -30.5q-3 0 -15 -1t-15 -1q-29 -2 -59.5 -1.5t-59.5 5.5q-23 5 -47 12.5t-47 10.5q-2 1 -8.5 1.5t-14 0.5t-14 0.5t-8.5 0.5 t-10 -1t-17 -1.5t-16.5 -1t-10.5 0.5q-3 0 -10 3.5t-7 8.5v4q-1 5 0.5 18t2.5 17q14 5 21 17.5t12 24.5q13 39 26 77.5t28 76.5q15 43 36.5 82.5t39.5 82.5q0 2 2 8t4 13t4 13t3 8q1 3 6.5 15.5t11.5 26t11 26t7 15.5q0 2 3 10t6 17t6 17t3 10q14 35 31.5 65.5t30.5 69.5 q26 84 56.5 167t59.5 165q22 62 46.5 123.5t48.5 124.5q0 1 1.5 8t4 15t4.5 14.5t3 8.5q2 2 5.5 12t5.5 12q0 1 1.5 5.5l3 9t2.5 8.5t1 5q1 4 5 14t7.5 20.5t7 19.5t4.5 12q1 1 4 8t6.5 15.5t6.5 15.5t3 10q1 3 4 10.5t6.5 15.5t6.5 15.5t5 10.5q0 2 1.5 9.5t3.5 7.5 q0 3 3.5 11t7.5 17t8 17l5 10q3 5 7 17t10 12l4 1q39 -5 76.5 -8t77.5 -1q21 1 48 5t54 8.5t52.5 7.5t44.5 2h21q3 0 12.5 3t11.5 3q97 14 196.5 15.5t196.5 1.5q98 0 192 -9t191 -14q7 -4 10.5 -9t6.5 -10.5t6.5 -11t10.5 -10.5q1 -8 2.5 -27.5t3 -41t2.5 -41.5t1 -27v-7.5 t0.5 -14.5t0.5 -16.5v-12.5q0 -3 -0.5 -10.5t-1 -16t-1 -16t-0.5 -10.5q-9 -15 -15.5 -25.5t-20 -17.5t-39.5 -10.5t-76 -4.5q-3 0 -12 0.5t-19.5 0.5t-20.5 0.5t-14 0.5q-6 0 -16.5 -0.5t-21 -0.5t-18.5 -0.5t-9 -0.5q-31 -1 -77 -2.5t-89 -3.5q-50 -2 -104 -4l-8 -12 q-1 -2 -3.5 -19t-5.5 -40t-6 -46.5t-5 -38.5v-11.5t-1 -14.5v-19.5t6 -17.5q2 -2 6 -4t6 -2q47 -7 97 -9t96 -2h14q3 0 16 1t27.5 1.5t27 1.5t15.5 1h4q42 0 78 -8.5t79 -14.5q9 -2 20.5 -2.5t22 -2.5t19 -7.5t12.5 -16.5q2 -7 5.5 -18l7 -22t6.5 -19.5t3 -9.5q-3 -20 0 -40 l6 -40t3.5 -40t-6.5 -40q-5 -25 -29.5 -41.5t-82.5 -22.5h-62q-6 0 -30.5 -1t-52.5 -2t-52.5 -2t-30.5 -1q-12 0 -40.5 0.5t-60 0.5t-59.5 0.5t-39 0.5q-1 -51 -6.5 -102.5t-6.5 -103.5q0 -7 -0.5 -21t-0.5 -16q1 -5 2.5 -18.5t3 -29.5t3 -30.5t1.5 -20.5l2.5 -12.5 t3.5 -14.5t3.5 -12.5t2.5 -5.5l35 -6l483 3q22 1 35.5 0.5t21.5 -3t11 -5.5t5 -7q1 -12 1 -23v-34q0 -9 -0.5 -23.5l-1 -29t-1 -26t-0.5 -14.5q0 -2 -1 -7.5t-2.5 -12t-2.5 -12t-1 -7.5v-28q-2 -15 0 -31.5t1.5 -33t-6 -31t-21.5 -25.5q-86 -8 -170.5 -19.5t-171.5 -11.5 q-43 0 -83.5 4t-83.5 4q-17 7 -34.5 3t-34 -9t-32 -6.5t-28.5 10.5h-156zM718 716q30 5 65 4t66.5 -3.5t56 -5t34.5 -0.5q-2 13 -4.5 28.5t-4.5 20.5q-3 60 -5.5 120t-4.5 120q-3 7 0 17t1 13q-3 5 -2.5 25.5t2 43.5t2.5 43t-2 25q-2 5 -9.5 17.5t-9.5 15.5l-2 2q-1 0 -3 -2 l-1 -1q-2 -2 -5.5 -8t-3.5 -8q-1 -2 -7 -11.5t-15 -22.5t-19.5 -27.5t-19.5 -27.5t-15 -22t-6 -10q-2 -2 -5.5 -9.5t-8 -16.5l-8.5 -17t-6 -10q-25 -63 -46.5 -124.5t-45.5 -123.5q0 -1 -1.5 -6.5t-4 -12t-4 -12t-1.5 -6.5q-2 -2 -1.5 -4t0.5 -4q3 0 9.5 2.5t13.5 4t13 0.5 t8 -7z" />
<glyph unicode="&#xc7;" horiz-adv-x="1465" d="M677 -335q0 33 6.5 60t3.5 59q6 8 17 8h3q3 -1 11.5 -5t18.5 -8.5t18.5 -9t11.5 -6.5q11 -5 17 -5h20q24 0 48.5 10t37.5 29v3q0 5 3.5 7t3.5 8v1q0 2 -4 10q-2 4 -3 8q0 10 -5.5 16.5t-13.5 10.5t-17 5.5t-16 1.5h-2q-4 -1 -13 -1.5t-19 0t-17 3t-6 8.5q0 4 -0.5 15 t-1.5 23t-2 23t-1 15t-1.5 14t-3.5 21t-3.5 21.5t-1.5 15.5q0 7 6 9.5t14 2.5t16.5 -1.5t13.5 -1.5h15q6 0 12 0.5t10 0.5t18.5 -0.5t18.5 -0.5q4 -3 9 -9t5 -12v-3q0 -1 -1 -5t-1.5 -9t-1.5 -9.5t-1 -5.5q0 -3 3 -9.5t8 -9.5q20 2 42.5 1.5t41.5 -10.5q2 -1 7 -4.5t7 -5.5 q42 -36 66 -79.5t24 -97.5q0 -42 -24 -70t-59.5 -45t-76.5 -24t-76 -7h-42l-10 2q-4 1 -8.5 1.5t-6.5 1.5q-5 1 -17 4t-25 6t-23.5 5.5t-13.5 3.5q-5 2 -16 5t-13 5q-2 0 -5 3.5t-5 4.5v2v0zM620 22q-71 27 -121 51t-85 44.5t-56.5 38t-36 31.5t-24 25t-19.5 19 q-2 0 -6.5 4.5t-4.5 6.5q-2 2 -4 6t-2 6l-12 12l-13.5 13.5t-11.5 11t-6 4.5l-22 35v1q0 1 0.5 1.5t0.5 1.5v2q-23 31 -38 67.5t-25.5 75t-19.5 77.5t-20 75q-5 17 -5 31.5t-4 31.5q-6 23 -13 46t-9 46q0 9 -1.5 33t-3.5 51.5t-3.5 52t-2.5 35.5v25q1 40 7 72.5t17 70.5 q1 2 4 12t6 22l5.5 22t3.5 12q10 35 22 60t22.5 41t17.5 24l7 8q8 24 26 50.5t42 53t52 52.5t56 49q34 34 82 56.5t91 39.5q3 1 15.5 7.5t27.5 13t27.5 12.5t15.5 8q1 0 8 2t15 5t15 5.5t9 3.5q2 2 12 6t12 6q1 0 5.5 -0.5t10.5 -0.5h11t7 1q2 0 8.5 1t15 2.5t16.5 3t12 2.5 q42 12 82 11.5t84 -0.5h24t29.5 -0.5t25.5 -0.5h13q4 0 14 -0.5t22 -1.5t23 -2.5t16 -2.5q2 0 12.5 -2t16.5 -4q2 0 11.5 -2t11.5 -4q2 0 12 -1t21.5 -1.5t22 -1.5t13.5 -1q3 -2 11.5 -4t10.5 -2q2 -2 10.5 -7t18 -10.5t18 -11t10.5 -6.5q2 -2 11.5 -6.5t11.5 -6.5 q2 0 9 -5.5t9 -5.5q0 -1 5 -1q2 0 5 1q10 -3 14.5 -18t4.5 -25v-10q-2 -4 -5 -7q-3 -4 -8 -9q-2 -2 -8.5 -11.5t-14.5 -20.5t-14.5 -20t-8.5 -11q-11 -5 -25 -28t-31 -47t-36.5 -41t-41.5 -10q-55 14 -106 23t-107 10q-5 0 -12 -0.5t-15 -0.5q-9 -1 -18 -1q-2 0 -9 -1.5 t-14.5 -3.5t-14.5 -3.5t-9 -1.5q-3 -1 -16.5 -2.5t-29 -3.5t-29 -3.5t-17.5 -2.5q-2 0 -10 -2.5t-18 -6l-20 -7t-15 -5.5q-46 -19 -82.5 -48t-68.5 -66q-3 -3 -12 -15t-19.5 -25.5t-20 -25.5t-12.5 -15q-10 -11 -19.5 -22.5t-14.5 -28.5q-2 -5 -5.5 -19t-7 -29.5t-7.5 -29.5 t-5 -20q-1 -2 -1 -4v-7q0 -11 3 -21.5t3 -23.5v-2q-2 -2 -9 -11t-7 -11v-4q-1 -47 2.5 -102t18.5 -101l16 -55l-1 -2q1 -4 4.5 -13.5t7.5 -19.5t7 -19t5 -12q13 -8 17 -21.5t12 -26.5q25 -37 54 -70.5t63 -61t73.5 -47.5t84.5 -30q7 -2 23.5 -4.5t34 -5.5t32 -5t18.5 -2 q1 0 8 -0.5t16.5 -0.5t19.5 -0.5t16 -0.5q42 -1 80.5 3.5t78.5 18.5q3 1 9 4t12.5 6t11.5 5.5t6 3.5q12 5 21 11t17.5 11t18 8.5t21.5 3.5q3 0 11 -1t10 -1q24 -22 44.5 -46t33.5 -52q3 -4 9.5 -17.5t14 -29t14.5 -29t9 -16.5q1 -2 5.5 -8t9 -12.5t8.5 -13t5 -7.5 q6 -25 4.5 -35t-11 -15.5t-25.5 -11.5t-38 -24q-2 -1 -3 -2q-2 -1 -2.5 -2t-1.5 -2q-25 -19 -52 -30.5t-56 -19t-59.5 -11.5t-61.5 -7q-6 0 -31.5 -2t-54.5 -4t-54.5 -4t-31.5 -3h-31h-33q-3 0 -14 1t-23.5 2t-23.5 2t-14 1h-17.5h-31h-31t-17.5 1q-2 0 -11 2t-20.5 4.5 t-22 5.5t-15.5 5z" />
<glyph unicode="&#xc8;" horiz-adv-x="1186" d="M405 2031v3l3 6q1 4 5 6t9 3t9.5 1.5t6.5 0.5h22h1h2q5 0 17 1t14 1q1 1 6.5 2.5t7.5 1.5t7.5 0.5t12 1t12 1t7.5 0.5t8 1.5t8 1.5h1q5 0 13 -2.5t10 -7.5q1 0 2 -3.5t1 -4.5q1 -2 6 -11.5t11 -20t11 -20t6 -11.5t3.5 -8.5t5 -14t4.5 -14.5t2 -8q3 -3 3 -6 q11 -18 14 -32.5t11 -32.5q2 -2 6.5 -12.5t5.5 -12.5v-3q0 -2 0.5 -3t0.5 -2q0 -12 -2 -21.5t-14 -5.5q-1 0 -6 -1.5t-11 -3t-11 -2.5t-6 -1q-14 -2 -25 -5.5t-20.5 -7t-20 -6t-24.5 -2.5q-4 0 -11.5 0.5t-8.5 0.5l-9 6l-2.5 4.5t-5.5 11.5t-6.5 14t-6.5 12 q-14 29 -25.5 58.5t-25.5 57.5q-11 23 -17 43t-17 43v3zM269 16q-2 1 -11 2.5t-19.5 4t-20.5 4t-13 2.5h-8h-8q-2 0 -6 -3t-6 -3q-8 0 -16.5 10t-12.5 12q-10 6 -24 8.5t-20 16.5q3 78 0 152.5t-1 152.5q2 54 5.5 107.5t4.5 107.5v14q0 1 -1 6.5t-1.5 11t-1.5 10.5t-1 7 v10.5t0.5 18t0.5 18v10.5q0 4 -1 13t-3 19t-4 19t-3 13q-11 223 -17 442.5t-13 442.5v10q0 7 3.5 19t9.5 23.5t12.5 20t12.5 8.5q20 0 40 -6t40 -6h21q3 0 12.5 3t11.5 3q97 14 196.5 15.5t196.5 1.5q98 0 192 -9t191 -14q7 -4 10.5 -9t6.5 -10.5t6.5 -11t10.5 -10.5 q1 -8 2.5 -27.5t3 -41t2.5 -41.5t1 -27v-7.5t0.5 -14.5t0.5 -16.5v-12.5q0 -3 -0.5 -10.5t-1 -16t-1 -16t-0.5 -10.5q-9 -15 -15.5 -25.5t-20 -17.5t-39.5 -10.5t-76 -4.5q-3 0 -12 0.5t-19.5 0.5t-20.5 0.5t-14 0.5q-6 0 -16.5 -0.5t-21 -0.5t-18.5 -0.5t-9 -0.5 q-31 -1 -77 -2.5t-89 -3.5q-50 -2 -104 -4l-8 -12q-1 -2 -3.5 -19t-5.5 -40t-6 -46.5t-5 -38.5v-11.5t-1 -14.5v-19.5t6 -17.5q2 -2 6 -4t6 -2q47 -7 97 -9t96 -2h14q3 0 16 1t27.5 1.5t27 1.5t15.5 1h4q42 0 78 -8.5t79 -14.5q9 -2 20.5 -2.5t22 -2.5t19 -7.5t12.5 -16.5 q2 -7 5.5 -18l7 -22t6.5 -19.5t3 -9.5q-3 -20 0 -40l6 -40t3.5 -40t-6.5 -40q-5 -25 -29.5 -41.5t-82.5 -22.5h-62q-6 0 -30.5 -1t-52.5 -2t-52.5 -2t-30.5 -1q-12 0 -40.5 0.5t-60 0.5t-59.5 0.5t-39 0.5q-1 -51 -6.5 -102.5t-6.5 -103.5q0 -7 -0.5 -21t-0.5 -16 q1 -5 2.5 -18.5t3 -29.5t3 -30.5t1.5 -20.5l2.5 -12.5t3.5 -14.5t3.5 -12.5t2.5 -5.5l35 -6l483 3q22 1 35.5 0.5t21.5 -3t11 -5.5t5 -7q1 -12 1 -23v-34q0 -9 -0.5 -23.5l-1 -29t-1 -26t-0.5 -14.5q0 -2 -1 -7.5t-2.5 -12t-2.5 -12t-1 -7.5v-28q-2 -15 0 -31.5t1.5 -33 t-6 -31t-21.5 -25.5q-86 -8 -170.5 -19.5t-171.5 -11.5q-43 0 -83.5 4t-83.5 4q-17 7 -34.5 3t-34 -9t-32 -6.5t-28.5 10.5h-156z" />
<glyph unicode="&#xc9;" horiz-adv-x="1186" d="M771 2050q-12 -22 -19.5 -42t-19.5 -42q-15 -28 -29 -56.5t-30 -57.5q-3 -5 -6.5 -12.5t-7 -14t-6.5 -11.5l-3 -5l-10 -5q-1 0 -8.5 -0.5t-11.5 -0.5q-14 1 -24 4t-20 6.5l-20 7t-24 5.5q-1 0 -6 1.5t-11 3t-11 3t-6 1.5q-12 -3 -13.5 6.5t-0.5 21.5q0 3 1 5q0 2 1 3 l6 12t7 12q9 18 13 32.5t17 31.5q0 3 3 6q0 1 2.5 8t5.5 14.5t5.5 14t3.5 8.5t6.5 11.5t12.5 20t12.5 20t6.5 11.5q0 1 1.5 4t2.5 3q2 5 10 7.5t13 2.5h1q2 0 8 -2t8 -2q1 0 7 -0.5t12.5 -1.5t12 -1.5t7.5 -0.5t7.5 -1.5t6.5 -2.5q2 0 14 -1t17 -2h2h1h11t11 -1 q1 0 5.5 -0.5t9.5 -1.5t9 -3.5t5 -6.5l3 -6q-1 0 -1 -1v-2v-3v0zM269 16q-2 1 -11 2.5t-19.5 4t-20.5 4t-13 2.5h-8h-8q-2 0 -6 -3t-6 -3q-8 0 -16.5 10t-12.5 12q-10 6 -24 8.5t-20 16.5q3 78 0 152.5t-1 152.5q2 54 5.5 107.5t4.5 107.5v14q0 1 -1 6.5t-1.5 11t-1.5 10.5 t-1 7v10.5t0.5 18t0.5 18v10.5q0 4 -1 13t-3 19t-4 19t-3 13q-11 223 -17 442.5t-13 442.5v10q0 7 3.5 19t9.5 23.5t12.5 20t12.5 8.5q20 0 40 -6t40 -6h21q3 0 12.5 3t11.5 3q97 14 196.5 15.5t196.5 1.5q98 0 192 -9t191 -14q7 -4 10.5 -9t6.5 -10.5t6.5 -11t10.5 -10.5 q1 -8 2.5 -27.5t3 -41t2.5 -41.5t1 -27v-7.5t0.5 -14.5t0.5 -16.5v-12.5q0 -3 -0.5 -10.5t-1 -16t-1 -16t-0.5 -10.5q-9 -15 -15.5 -25.5t-20 -17.5t-39.5 -10.5t-76 -4.5q-3 0 -12 0.5t-19.5 0.5t-20.5 0.5t-14 0.5q-6 0 -16.5 -0.5t-21 -0.5t-18.5 -0.5t-9 -0.5 q-31 -1 -77 -2.5t-89 -3.5q-50 -2 -104 -4l-8 -12q-1 -2 -3.5 -19t-5.5 -40t-6 -46.5t-5 -38.5v-11.5t-1 -14.5v-19.5t6 -17.5q2 -2 6 -4t6 -2q47 -7 97 -9t96 -2h14q3 0 16 1t27.5 1.5t27 1.5t15.5 1h4q42 0 78 -8.5t79 -14.5q9 -2 20.5 -2.5t22 -2.5t19 -7.5t12.5 -16.5 q2 -7 5.5 -18l7 -22t6.5 -19.5t3 -9.5q-3 -20 0 -40l6 -40t3.5 -40t-6.5 -40q-5 -25 -29.5 -41.5t-82.5 -22.5h-62q-6 0 -30.5 -1t-52.5 -2t-52.5 -2t-30.5 -1q-12 0 -40.5 0.5t-60 0.5t-59.5 0.5t-39 0.5q-1 -51 -6.5 -102.5t-6.5 -103.5q0 -7 -0.5 -21t-0.5 -16 q1 -5 2.5 -18.5t3 -29.5t3 -30.5t1.5 -20.5l2.5 -12.5t3.5 -14.5t3.5 -12.5t2.5 -5.5l35 -6l483 3q22 1 35.5 0.5t21.5 -3t11 -5.5t5 -7q1 -12 1 -23v-34q0 -9 -0.5 -23.5l-1 -29t-1 -26t-0.5 -14.5q0 -2 -1 -7.5t-2.5 -12t-2.5 -12t-1 -7.5v-28q-2 -15 0 -31.5t1.5 -33 t-6 -31t-21.5 -25.5q-86 -8 -170.5 -19.5t-171.5 -11.5q-43 0 -83.5 4t-83.5 4q-17 7 -34.5 3t-34 -9t-32 -6.5t-28.5 10.5h-156z" />
<glyph unicode="&#xca;" horiz-adv-x="1186" d="M399 1793q-22 4 -25 10t-6 8v1v1q5 13 14.5 27.5t16.5 25.5q4 7 11 18t14.5 24t14 26.5t11.5 25.5q6 8 9.5 16.5t7.5 17.5q11 27 17.5 39t15.5 22q1 1 5 2.5t6 1.5q4 0 16.5 0.5t26 1t25.5 0.5h17h42q1 0 5.5 0.5t9.5 1.5t9.5 1.5t5.5 0.5h5q7 1 10 -0.5t4 -4t1 -6 t2 -5.5q1 -1 2.5 -5.5t1.5 -5.5q1 -2 3.5 -5.5t3.5 -3.5q-4 4 2 -10.5t15.5 -36t20.5 -44t18 -35.5q4 -5 4 -11.5t2 -11.5q4 -10 8 -19.5t9 -20.5q2 -4 7.5 -12t5.5 -14q0 -2 -2.5 -5.5t-4.5 -4.5h-16q-1 0 -3.5 -1.5t-3.5 -1.5t-13.5 -1t-19.5 -1q-26 -2 -48 -9 q-13 -2 -25 -5.5t-25 -3.5q-8 0 -16.5 0.5t-13.5 6.5q-8 14 -12.5 28.5t-14.5 26.5q-2 -2 -3 -3.5t-3 -3.5q-1 -4 -7 -14.5t-8 -12.5q-1 -2 -4.5 -7.5t-9 -11t-12 -9t-13.5 -1.5h-4h-16.5h-12.5t-12.5 1t-15.5 3q-3 1 -11 2t-17 2.5t-16.5 3t-10.5 1.5zM269 16q-2 1 -11 2.5 t-19.5 4t-20.5 4t-13 2.5h-8h-8q-2 0 -6 -3t-6 -3q-8 0 -16.5 10t-12.5 12q-10 6 -24 8.5t-20 16.5q3 78 0 152.5t-1 152.5q2 54 5.5 107.5t4.5 107.5v14q0 1 -1 6.5t-1.5 11t-1.5 10.5t-1 7v10.5t0.5 18t0.5 18v10.5q0 4 -1 13t-3 19t-4 19t-3 13q-11 223 -17 442.5 t-13 442.5v10q0 7 3.5 19t9.5 23.5t12.5 20t12.5 8.5q20 0 40 -6t40 -6h21q3 0 12.5 3t11.5 3q97 14 196.5 15.5t196.5 1.5q98 0 192 -9t191 -14q7 -4 10.5 -9t6.5 -10.5t6.5 -11t10.5 -10.5q1 -8 2.5 -27.5t3 -41t2.5 -41.5t1 -27v-7.5t0.5 -14.5t0.5 -16.5v-12.5 q0 -3 -0.5 -10.5t-1 -16t-1 -16t-0.5 -10.5q-9 -15 -15.5 -25.5t-20 -17.5t-39.5 -10.5t-76 -4.5q-3 0 -12 0.5t-19.5 0.5t-20.5 0.5t-14 0.5q-6 0 -16.5 -0.5t-21 -0.5t-18.5 -0.5t-9 -0.5q-31 -1 -77 -2.5t-89 -3.5q-50 -2 -104 -4l-8 -12q-1 -2 -3.5 -19t-5.5 -40 t-6 -46.5t-5 -38.5v-11.5t-1 -14.5v-19.5t6 -17.5q2 -2 6 -4t6 -2q47 -7 97 -9t96 -2h14q3 0 16 1t27.5 1.5t27 1.5t15.5 1h4q42 0 78 -8.5t79 -14.5q9 -2 20.5 -2.5t22 -2.5t19 -7.5t12.5 -16.5q2 -7 5.5 -18l7 -22t6.5 -19.5t3 -9.5q-3 -20 0 -40l6 -40t3.5 -40t-6.5 -40 q-5 -25 -29.5 -41.5t-82.5 -22.5h-62q-6 0 -30.5 -1t-52.5 -2t-52.5 -2t-30.5 -1q-12 0 -40.5 0.5t-60 0.5t-59.5 0.5t-39 0.5q-1 -51 -6.5 -102.5t-6.5 -103.5q0 -7 -0.5 -21t-0.5 -16q1 -5 2.5 -18.5t3 -29.5t3 -30.5t1.5 -20.5l2.5 -12.5t3.5 -14.5t3.5 -12.5t2.5 -5.5 l35 -6l483 3q22 1 35.5 0.5t21.5 -3t11 -5.5t5 -7q1 -12 1 -23v-34q0 -9 -0.5 -23.5l-1 -29t-1 -26t-0.5 -14.5q0 -2 -1 -7.5t-2.5 -12t-2.5 -12t-1 -7.5v-28q-2 -15 0 -31.5t1.5 -33t-6 -31t-21.5 -25.5q-86 -8 -170.5 -19.5t-171.5 -11.5q-43 0 -83.5 4t-83.5 4 q-17 7 -34.5 3t-34 -9t-32 -6.5t-28.5 10.5h-156z" />
<glyph unicode="&#xcb;" horiz-adv-x="1186" d="M521 1950v-18t-4 -19q-7 -14 -12 -26.5t-16 -24.5q-6 -7 -19 -16.5t-16 -12.5q-14 -13 -31 -13t-34 -1q-11 -1 -18 1t-18 7q-5 0 -13.5 4t-13.5 7q-26 16 -44.5 40t-21.5 57q0 20 0.5 34t4.5 26t13 23t24 24q14 13 34 23.5t38 11.5q5 1 17 0.5t15 -1.5q6 -1 18.5 -4 t14.5 -4q1 -1 6 -2.5t10.5 -3.5t10.5 -3.5t7 -2.5q28 -21 37 -45t11 -61zM832 1947q0 -8 0.5 -17.5t-3.5 -19.5q-7 -14 -12 -26t-16 -24q-3 -3 -8 -7.5t-10 -8.5l-10 -8t-6 -5q-14 -13 -31.5 -13t-34.5 -1q-11 -1 -17.5 1.5t-17.5 5.5q-5 1 -14 5t-14 8q-26 15 -44 38.5 t-23 56.5q0 20 1 34t5.5 26t13.5 23t24 25q13 13 33 23.5t38 11.5q4 1 17 0.5t16 -1.5q5 -1 17.5 -4.5t15.5 -3.5q1 -1 5.5 -3t10 -3.5t10.5 -3t7 -2.5q28 -22 37.5 -45.5t9.5 -61.5zM269 16q-2 1 -11 2.5t-19.5 4t-20.5 4t-13 2.5h-8h-8q-2 0 -6 -3t-6 -3q-8 0 -16.5 10 t-12.5 12q-10 6 -24 8.5t-20 16.5q3 78 0 152.5t-1 152.5q2 54 5.5 107.5t4.5 107.5v14q0 1 -1 6.5t-1.5 11t-1.5 10.5t-1 7v10.5t0.5 18t0.5 18v10.5q0 4 -1 13t-3 19t-4 19t-3 13q-11 223 -17 442.5t-13 442.5v10q0 7 3.5 19t9.5 23.5t12.5 20t12.5 8.5q20 0 40 -6t40 -6 h21q3 0 12.5 3t11.5 3q97 14 196.5 15.5t196.5 1.5q98 0 192 -9t191 -14q7 -4 10.5 -9t6.5 -10.5t6.5 -11t10.5 -10.5q1 -8 2.5 -27.5t3 -41t2.5 -41.5t1 -27v-7.5t0.5 -14.5t0.5 -16.5v-12.5q0 -3 -0.5 -10.5t-1 -16t-1 -16t-0.5 -10.5q-9 -15 -15.5 -25.5t-20 -17.5 t-39.5 -10.5t-76 -4.5q-3 0 -12 0.5t-19.5 0.5t-20.5 0.5t-14 0.5q-6 0 -16.5 -0.5t-21 -0.5t-18.5 -0.5t-9 -0.5q-31 -1 -77 -2.5t-89 -3.5q-50 -2 -104 -4l-8 -12q-1 -2 -3.5 -19t-5.5 -40t-6 -46.5t-5 -38.5v-11.5t-1 -14.5v-19.5t6 -17.5q2 -2 6 -4t6 -2q47 -7 97 -9 t96 -2h14q3 0 16 1t27.5 1.5t27 1.5t15.5 1h4q42 0 78 -8.5t79 -14.5q9 -2 20.5 -2.5t22 -2.5t19 -7.5t12.5 -16.5q2 -7 5.5 -18l7 -22t6.5 -19.5t3 -9.5q-3 -20 0 -40l6 -40t3.5 -40t-6.5 -40q-5 -25 -29.5 -41.5t-82.5 -22.5h-62q-6 0 -30.5 -1t-52.5 -2t-52.5 -2 t-30.5 -1q-12 0 -40.5 0.5t-60 0.5t-59.5 0.5t-39 0.5q-1 -51 -6.5 -102.5t-6.5 -103.5q0 -7 -0.5 -21t-0.5 -16q1 -5 2.5 -18.5t3 -29.5t3 -30.5t1.5 -20.5l2.5 -12.5t3.5 -14.5t3.5 -12.5t2.5 -5.5l35 -6l483 3q22 1 35.5 0.5t21.5 -3t11 -5.5t5 -7q1 -12 1 -23v-34 q0 -9 -0.5 -23.5l-1 -29t-1 -26t-0.5 -14.5q0 -2 -1 -7.5t-2.5 -12t-2.5 -12t-1 -7.5v-28q-2 -15 0 -31.5t1.5 -33t-6 -31t-21.5 -25.5q-86 -8 -170.5 -19.5t-171.5 -11.5q-43 0 -83.5 4t-83.5 4q-17 7 -34.5 3t-34 -9t-32 -6.5t-28.5 10.5h-156z" />
<glyph unicode="&#xcc;" horiz-adv-x="593" d="M159 1984v3l3 6q1 4 5 6t9 3t9.5 1.5t6.5 0.5h22h1h2q5 0 17 1t14 1q1 1 6.5 2.5t7.5 1.5t7.5 0.5t12 1t12 1t7.5 0.5t8 1.5t8 1.5h1q5 0 13 -2.5t10 -7.5q1 0 2 -3.5t1 -4.5q1 -2 6 -11.5t11 -20t11 -20t6 -11.5t3.5 -8.5t5 -14t4.5 -14.5t2 -8q3 -3 3 -6 q11 -18 14 -32.5t11 -32.5q2 -2 6.5 -12.5t5.5 -12.5v-3q0 -2 0.5 -3t0.5 -2q0 -12 -2 -21.5t-14 -5.5q-1 0 -6 -1.5t-11 -3t-11 -2.5t-6 -1q-14 -2 -25 -5.5t-20.5 -7t-20 -6t-24.5 -2.5q-4 0 -11.5 0.5t-8.5 0.5l-9 6l-2.5 4.5t-5.5 11.5t-6.5 14t-6.5 12 q-14 29 -25.5 58.5t-25.5 57.5q-11 23 -17 43t-17 43v3zM340 23q-3 0 -14 -1.5t-23.5 -4t-23.5 -4t-13 -1.5h-6q-18 0 -36.5 2t-35.5 2t-26.5 -0.5t-28.5 -3.5q-2 -2 -9 -4t-9 -2h-2q-14 0 -21 10q-1 4 -3 14t-5 21.5t-5 21t-3 13.5v2v4q1 27 2 68.5t2 81t1.5 68t0.5 30.5 q0 3 0.5 11t1.5 17.5t1.5 17.5t0.5 11v420q-7 54 -9 107.5t-2 107.5t1 108t0 109q0 5 -1 23.5t-2 39.5t-2 39t-1 23v39v37q2 57 2 106t-3 106q3 9 10 10.5t15 1.5q2 0 4 -0.5t5 -0.5q3 -1 7 -1t22 -0.5t38.5 -1t38.5 -1t22 -0.5h35q13 -2 29.5 -0.5t33.5 3.5t33.5 4t30.5 2 q11 0 22.5 3t22.5 3h2q2 -2 11.5 -9t12.5 -9l11 -5q3 -3 7.5 -14.5t4.5 -13.5q0 -5 2 -20.5t4 -20.5q0 -5 -2.5 -20.5t-5.5 -33t-5.5 -33.5t-2.5 -20q5 -6 8.5 -18t3.5 -17q0 -2 -5 -11.5t-7 -11.5v-20v-21q1 -3 3 -14t4 -23.5t3.5 -23.5t1.5 -14v-109q4 -50 8 -113t7 -133 t5 -143.5t3.5 -143.5t2.5 -133.5t1 -114t-1 -84t-3 -44.5q-2 -23 -2 -45.5v-46.5q-2 -8 -2 -22t0.5 -28.5t1.5 -25.5t2 -12q-14 -41 -42 -59.5t-56 -24.5t-48.5 -4.5t-19.5 0.5z" />
<glyph unicode="&#xcd;" horiz-adv-x="593" d="M440 1977q-12 -22 -19.5 -42t-19.5 -42q-15 -28 -29 -56.5t-30 -57.5q-3 -5 -6.5 -12.5t-7 -14t-6.5 -11.5l-3 -5l-10 -5q-1 0 -8.5 -0.5t-11.5 -0.5q-14 1 -24 4t-20 6.5l-20 7t-24 5.5q-1 0 -6 1.5t-11 3t-11 3t-6 1.5q-12 -3 -13.5 6.5t-0.5 21.5q0 3 1 5q0 2 1 3 l6 12t7 12q9 18 13 32.5t17 31.5q0 3 3 6q0 1 2.5 8t5.5 14.5t5.5 14t3.5 8.5t6.5 11.5t12.5 20t12.5 20t6.5 11.5q0 1 1.5 4t2.5 3q2 5 10 7.5t13 2.5h1q2 0 8 -2t8 -2q1 0 7 -0.5t12.5 -1.5t12 -1.5t7.5 -0.5t7.5 -1.5t6.5 -2.5q2 0 14 -1t17 -2h2h1h11t11 -1 q1 0 5.5 -0.5t9.5 -1.5t9 -3.5t5 -6.5l3 -6q-1 0 -1 -1v-2v-3v0zM340 23q-3 0 -14 -1.5t-23.5 -4t-23.5 -4t-13 -1.5h-6q-18 0 -36.5 2t-35.5 2t-26.5 -0.5t-28.5 -3.5q-2 -2 -9 -4t-9 -2h-2q-14 0 -21 10q-1 4 -3 14t-5 21.5t-5 21t-3 13.5v2v4q1 27 2 68.5t2 81t1.5 68 t0.5 30.5q0 3 0.5 11t1.5 17.5t1.5 17.5t0.5 11v420q-7 54 -9 107.5t-2 107.5t1 108t0 109q0 5 -1 23.5t-2 39.5t-2 39t-1 23v39v37q2 57 2 106t-3 106q3 9 10 10.5t15 1.5q2 0 4 -0.5t5 -0.5q3 -1 7 -1t22 -0.5t38.5 -1t38.5 -1t22 -0.5h35q13 -2 29.5 -0.5t33.5 3.5 t33.5 4t30.5 2q11 0 22.5 3t22.5 3h2q2 -2 11.5 -9t12.5 -9l11 -5q3 -3 7.5 -14.5t4.5 -13.5q0 -5 2 -20.5t4 -20.5q0 -5 -2.5 -20.5t-5.5 -33t-5.5 -33.5t-2.5 -20q5 -6 8.5 -18t3.5 -17q0 -2 -5 -11.5t-7 -11.5v-20v-21q1 -3 3 -14t4 -23.5t3.5 -23.5t1.5 -14v-109 q4 -50 8 -113t7 -133t5 -143.5t3.5 -143.5t2.5 -133.5t1 -114t-1 -84t-3 -44.5q-2 -23 -2 -45.5v-46.5q-2 -8 -2 -22t0.5 -28.5t1.5 -25.5t2 -12q-14 -41 -42 -59.5t-56 -24.5t-48.5 -4.5t-19.5 0.5z" />
<glyph unicode="&#xce;" horiz-adv-x="593" d="M115 1755q-22 4 -25 10t-6 8v1v1q5 13 14.5 27.5t16.5 25.5q4 7 11 18t14.5 24t14 26.5t11.5 25.5q6 8 9.5 16.5t7.5 17.5q11 27 17.5 39t15.5 22q1 1 5 2.5t6 1.5q4 0 16.5 0.5t26 1t25.5 0.5h17h42q1 0 5.5 0.5t9.5 1.5t9.5 1.5t5.5 0.5h5q7 1 10 -0.5t4 -4t1 -6 t2 -5.5q1 -1 2.5 -5.5t1.5 -5.5q1 -2 3.5 -5.5t3.5 -3.5q-4 4 2 -10.5t15.5 -36t20.5 -44t18 -35.5q4 -5 4 -11.5t2 -11.5q4 -10 8 -19.5t9 -20.5q2 -4 7.5 -12t5.5 -14q0 -2 -2.5 -5.5t-4.5 -4.5h-16q-1 0 -3.5 -1.5t-3.5 -1.5t-13.5 -1t-19.5 -1q-26 -2 -48 -9 q-13 -2 -25 -5.5t-25 -3.5q-8 0 -16.5 0.5t-13.5 6.5q-8 14 -12.5 28.5t-14.5 26.5q-2 -2 -3 -3.5t-3 -3.5q-1 -4 -7 -14.5t-8 -12.5q-1 -2 -4.5 -7.5t-9 -11t-12 -9t-13.5 -1.5h-4h-16.5h-12.5t-12.5 1t-15.5 3q-3 1 -11 2t-17 2.5t-16.5 3t-10.5 1.5zM340 23 q-3 0 -14 -1.5t-23.5 -4t-23.5 -4t-13 -1.5h-6q-18 0 -36.5 2t-35.5 2t-26.5 -0.5t-28.5 -3.5q-2 -2 -9 -4t-9 -2h-2q-14 0 -21 10q-1 4 -3 14t-5 21.5t-5 21t-3 13.5v2v4q1 27 2 68.5t2 81t1.5 68t0.5 30.5q0 3 0.5 11t1.5 17.5t1.5 17.5t0.5 11v420q-7 54 -9 107.5 t-2 107.5t1 108t0 109q0 5 -1 23.5t-2 39.5t-2 39t-1 23v39v37q2 57 2 106t-3 106q3 9 10 10.5t15 1.5q2 0 4 -0.5t5 -0.5q3 -1 7 -1t22 -0.5t38.5 -1t38.5 -1t22 -0.5h35q13 -2 29.5 -0.5t33.5 3.5t33.5 4t30.5 2q11 0 22.5 3t22.5 3h2q2 -2 11.5 -9t12.5 -9l11 -5 q3 -3 7.5 -14.5t4.5 -13.5q0 -5 2 -20.5t4 -20.5q0 -5 -2.5 -20.5t-5.5 -33t-5.5 -33.5t-2.5 -20q5 -6 8.5 -18t3.5 -17q0 -2 -5 -11.5t-7 -11.5v-20v-21q1 -3 3 -14t4 -23.5t3.5 -23.5t1.5 -14v-109q4 -50 8 -113t7 -133t5 -143.5t3.5 -143.5t2.5 -133.5t1 -114t-1 -84 t-3 -44.5q-2 -23 -2 -45.5v-46.5q-2 -8 -2 -22t0.5 -28.5t1.5 -25.5t2 -12q-14 -41 -42 -59.5t-56 -24.5t-48.5 -4.5t-19.5 0.5z" />
<glyph unicode="&#xcf;" horiz-adv-x="593" d="M230 1896v-18t-4 -19q-7 -14 -12 -26.5t-16 -24.5q-6 -7 -19 -16.5t-16 -12.5q-14 -13 -31 -13t-34 -1q-11 -1 -18 1t-18 7q-5 0 -13.5 4t-13.5 7q-26 16 -44.5 40t-21.5 57q0 20 0.5 34t4.5 26t13 23t24 24q14 13 34 23.5t38 11.5q5 1 17 0.5t15 -1.5q6 -1 18.5 -4 t14.5 -4q1 -1 6 -2.5t10.5 -3.5t10.5 -3.5t7 -2.5q28 -21 37 -45t11 -61zM541 1893q0 -8 0.5 -17.5t-3.5 -19.5q-7 -14 -12 -26t-16 -24q-3 -3 -8 -7.5t-10 -8.5l-10 -8t-6 -5q-14 -13 -31.5 -13t-34.5 -1q-11 -1 -17.5 1.5t-17.5 5.5q-5 1 -14 5t-14 8q-26 15 -44 38.5 t-23 56.5q0 20 1 34t5.5 26t13.5 23t24 25q13 13 33 23.5t38 11.5q4 1 17 0.5t16 -1.5q5 -1 17.5 -4.5t15.5 -3.5q1 -1 5.5 -3t10 -3.5t10.5 -3t7 -2.5q28 -22 37.5 -45.5t9.5 -61.5zM340 23q-3 0 -14 -1.5t-23.5 -4t-23.5 -4t-13 -1.5h-6q-18 0 -36.5 2t-35.5 2t-26.5 -0.5 t-28.5 -3.5q-2 -2 -9 -4t-9 -2h-2q-14 0 -21 10q-1 4 -3 14t-5 21.5t-5 21t-3 13.5v2v4q1 27 2 68.5t2 81t1.5 68t0.5 30.5q0 3 0.5 11t1.5 17.5t1.5 17.5t0.5 11v420q-7 54 -9 107.5t-2 107.5t1 108t0 109q0 5 -1 23.5t-2 39.5t-2 39t-1 23v39v37q2 57 2 106t-3 106 q3 9 10 10.5t15 1.5q2 0 4 -0.5t5 -0.5q3 -1 7 -1t22 -0.5t38.5 -1t38.5 -1t22 -0.5h35q13 -2 29.5 -0.5t33.5 3.5t33.5 4t30.5 2q11 0 22.5 3t22.5 3h2q2 -2 11.5 -9t12.5 -9l11 -5q3 -3 7.5 -14.5t4.5 -13.5q0 -5 2 -20.5t4 -20.5q0 -5 -2.5 -20.5t-5.5 -33t-5.5 -33.5 t-2.5 -20q5 -6 8.5 -18t3.5 -17q0 -2 -5 -11.5t-7 -11.5v-20v-21q1 -3 3 -14t4 -23.5t3.5 -23.5t1.5 -14v-109q4 -50 8 -113t7 -133t5 -143.5t3.5 -143.5t2.5 -133.5t1 -114t-1 -84t-3 -44.5q-2 -23 -2 -45.5v-46.5q-2 -8 -2 -22t0.5 -28.5t1.5 -25.5t2 -12 q-14 -41 -42 -59.5t-56 -24.5t-48.5 -4.5t-19.5 0.5z" />
<glyph unicode="&#xd0;" horiz-adv-x="1743" d="M342 1q-2 12 -5 40t-6 59.5t-5 59.5t-2 39q0 4 -0.5 21t-0.5 36.5v36.5v22q0 2 -0.5 10t-1.5 16.5t-1.5 15.5t-0.5 9t0.5 9.5t0.5 10.5q4 73 18 142.5t21 141.5q-11 0 -28 0.5t-34.5 0.5h-31.5h-18q-33 0 -48.5 0.5t-28 1.5t-28.5 2.5t-49 3.5q-4 1 -14 3t-15 2 q-5 2 -9.5 9.5t-6.5 10.5q-2 8 -1 15.5t0 15.5q0 2 0.5 10.5t1.5 18t1.5 18.5t0.5 11q0 23 -2 45t1 44q1 11 17 19t30 9q4 0 19.5 -1.5t33.5 -2.5t33.5 -2t19.5 -1h19t38.5 -0.5t48.5 -1t47 -0.5l-11 546l10 191l13 11q6 -1 21.5 -2.5t34 -2t35 -1t23.5 -0.5q6 0 30 2 t51 4.5t50.5 5t28.5 3.5q60 5 121 2.5t118 -2.5q1 0 8.5 0.5t16 0.5t16.5 0.5t10 0.5h2q71 -4 137.5 -15.5t135.5 -31.5q35 -9 67 -29.5t61 -40.5q58 -42 108.5 -86t95.5 -98q24 -29 41 -63.5t30 -71t23 -74t19 -72.5q0 -2 1.5 -7.5t3 -11.5t3 -11t2.5 -6q1 -2 3.5 -11 t6 -19t6 -18.5t3.5 -9.5q2 -9 1.5 -21.5t0 -25.5t4 -24t13.5 -16l-7 -139q8 -3 9.5 -8t1.5 -13q-1 -1 -1 -5v-3q-1 -1 -3 -3.5t-4 -4.5q-3 -4 -6 -7q0 -1 -1 -8t-2.5 -16t-2.5 -18.5t-2 -15.5q-1 -1 -1 -3v-1q0 -8 5.5 -14t5.5 -15q0 -2 -0.5 -3t-0.5 -3v-3q0 -2 -5 -5.5 t-7 -5.5q-4 -8 -4.5 -18t-1.5 -19v-8q9 6 16 5q9 0 13.5 -6.5t4.5 -14.5q0 -1 -2 -5q-1 -2 -1 -3q-14 -7 -33.5 -20t-26.5 -30l-45 -119q0 -2 -0.5 -10.5t-0.5 -11.5q-1 -2 -5 -6l-8.5 -8.5t-8 -8.5t-4.5 -5t-5 -7t-9 -14t-10 -16.5t-7 -12.5q-23 -38 -50 -71.5t-66 -61.5 q-37 -26 -77 -48.5t-77 -46.5q-2 -2 -6 -4t-6 -2h-4q-1 0 -7 4q-3 2 -6 3q-2 0 -10.5 -1.5t-11.5 -3.5q-2 -1 -7 -2.5t-11 -3t-11.5 -2.5t-6.5 -2q-2 -1 -10.5 -2t-19 -1.5t-20 -1.5t-14.5 -2q-5 0 -22.5 -2t-38 -4t-38.5 -4t-22 -3q-3 0 -12 -1.5t-11 -3.5q-104 9 -190 6.5 t-159.5 -7t-136 -7t-119.5 5.5q-2 -3 -6.5 -6.5t-6.5 -5.5h-2q-7 1 -9.5 7.5t-4.5 9.5zM762 344q5 -2 9.5 -4t7.5 -7q2 0 9.5 -1.5t11.5 -1.5q29 -2 58.5 4t58.5 8t60.5 1t60.5 5q35 6 69.5 21.5t66.5 29.5q56 26 95.5 63.5t65 84t38.5 100t16 112.5q0 4 0.5 14t0.5 20.5 t0.5 19.5t0.5 12q-11 46 -21.5 91t-27.5 89q0 3 -2 8t-4 5q0 2 -4.5 6.5t-4.5 6.5q-2 2 -2.5 11t-2.5 11t-5.5 9t-5.5 9q-3 4 -12.5 14t-20 22t-19.5 22t-13 14q-19 20 -45.5 34t-49.5 22q-36 17 -67.5 28.5t-69.5 13.5l-299 15q0 -4 -0.5 -14.5t-1 -22.5t-1 -22.5 t-0.5 -14.5q1 -6 2.5 -19t1.5 -15q2 -2 8.5 -9.5t8.5 -10.5v-8q-1 -1 -1 -5v-3q-2 -3 -9 -9.5t-10 -6.5q0 -5 -0.5 -18t-0.5 -16q-1 -8 -1.5 -20.5t-0.5 -14.5t1.5 -7t3.5 -11t3.5 -11.5t1.5 -6.5q0 -2 -3 -5.5t-3 -5.5q-1 -1 -1 -3v-5v-9l4 -49h19q4 2 7.5 2t7.5 1 q4 0 18 -1.5t30.5 -2.5t30.5 -1.5t17 -0.5q13 3 17.5 3.5t8.5 0.5t11 1t25 5q1 1 18.5 0.5t41 -2t48 -3.5t39.5 -3q2 0 4.5 -0.5t4.5 -0.5q17 -1 21.5 -9.5t3.5 -20.5t-4.5 -25.5t-3.5 -22.5q0 -3 1 -9.5t2 -14t2 -14t1 -9.5q1 -8 0 -13.5t-3 -12.5q-2 -14 3 -29t3 -26 q-1 -1 -1 -4v-2q-2 -2 -8.5 -6.5t-9.5 -4.5q-6 1 -18 -1t-19 -4h-17.5h-37h-46h-46h-37h-17.5q-10 0 -19.5 -2t-19.5 -4t-21.5 -2.5t-25.5 1.5q-3 0 -10 3q1 -12 2 -26t2 -26.5t2 -22t1 -12.5q2 -2 3.5 -9t1.5 -9q0 -3 -0.5 -13t-1 -21.5t-1 -21.5t-0.5 -12t1.5 -7t3 -11 t3 -11.5t2.5 -6.5q0 -2 -1 -12t-1.5 -22t-1 -22.5t0.5 -13.5q0 -3 0.5 -11t2 -17t3 -17t2.5 -12z" />
<glyph unicode="&#xd1;" horiz-adv-x="1572" d="M394 1845q0 1 -1.5 3.5t-1.5 3.5t3 5t5 5v5q12 32 37.5 56.5t48.5 49.5q2 1 8.5 8t8.5 8q29 30 67.5 53t80.5 23q18 0 33.5 -1.5t32.5 -9.5q10 -4 20.5 -10.5t21.5 -6.5l31 -22q4 -2 14.5 -8t22.5 -12t22.5 -11.5t14.5 -7.5q11 -6 19.5 -7t19.5 -1q15 0 34 13.5t28 26.5 q3 3 8 10t10.5 14.5t9.5 13.5t5 8q5 8 9 13t15 5h3q1 -1 6.5 -5.5t7.5 -6.5q14 -14 30 -26t30.5 -21.5t26.5 -17.5t20 -15q6 -7 12.5 -12t9.5 -10t2 -11t-8 -15q-9 -15 -18.5 -27.5t-20.5 -28.5q-20 -26 -41.5 -51.5t-47 -45.5t-55 -32t-64.5 -12q-9 -1 -26 3.5t-34.5 11.5 t-33.5 14t-24 12q-2 3 -11 12t-12 11q-17 14 -34 19.5t-40 5.5q-27 0 -51.5 -13t-42.5 -37q-7 -11 -12.5 -18.5t-12 -12.5t-15 -7.5t-22.5 -2.5q-3 0 -8 1t-7 1q-1 0 -6 4.5t-7 4.5q-2 2 -5.5 4t-4.5 4q-17 11 -29 18t-27 22q-1 0 -7 4q-3 2 -6 5q-3 2 -8.5 8.5t-12.5 13.5 t-12.5 13t-8.5 9zM102 -7q1 54 -2.5 106t-5.5 106q-4 35 -2.5 70.5t0.5 73.5q0 8 -0.5 30t-1.5 52t-2 64.5t-2.5 67t-2.5 59.5t-2 43q0 2 -0.5 10t-1 16.5t-1 16.5t-0.5 10q-1 5 0 24.5t2 41.5t2 41t1 24q0 19 0.5 58.5t0.5 89.5t0.5 105t0.5 105t-0.5 89.5t-0.5 58.5 q-6 5 -7 11t0 16v4q2 3 2.5 8.5t0.5 7.5q8 10 8 23v22q1 30 -0.5 56t-3 51t-3 51t-0.5 56q-2 11 14 15t41.5 4.5t56.5 -2t60 -5.5q40 -1 78.5 2t78.5 3q2 0 6 0.5t7 0.5h8l20 -26q1 -1 10 -15t20.5 -33t23 -39t18.5 -33q1 -1 3 -5.5t4.5 -10.5t5 -10.5t3.5 -5.5 q7 -17 18.5 -30.5t18.5 -29.5q1 -3 3 -7q4 -8 4 -9q0 -2 1.5 -6.5t3.5 -6.5q0 -2 7 -11.5t9 -11.5q1 -2 7 -13t13.5 -23.5t14 -24t8.5 -13.5q1 -2 4 -7t6.5 -10.5t7 -10t5.5 -6.5q16 -26 27 -56t31 -55q2 -3 8 -8.5t8 -7.5q2 1 6 1h6q1 -2 2 -3q1 -2 2 -2.5t2 -1.5 q2 -3 5.5 -16t3.5 -18q4 -4 12 -13t16.5 -19t16 -19.5t10.5 -13.5q18 -21 31.5 -43.5t26.5 -46l26 -47t30 -44.5q3 -5 11.5 -14.5t10.5 -11.5q2 0 6 1t6 -1q6 -1 9 -5.5t4.5 -10.5l3 -12t4.5 -10q3 -3 11.5 -12.5t11.5 -12.5l8 -4q3 -2 5 -3.5t3 -2.5l54 -75q1 -2 4.5 -7 t8 -10.5t8.5 -10.5t7 -8l2 41q3 2 4.5 24t1 56.5t-3 77.5t-6.5 86t-9.5 82t-12.5 66q0 1 -0.5 7.5l-1 13t-1 12.5t-0.5 8v18t1 30.5t2 31t1 18.5q1 91 -2 181t1 183q0 8 1.5 21t3.5 25q3 14 6 30l35 5l277 -8q13 0 22 -12.5t14 -29t7.5 -33.5t2.5 -25q0 -3 2 -16.5t4 -18.5 l14 -377l4 -13q0 -5 -0.5 -16.5t-1.5 -25t-1.5 -26t-0.5 -18.5q0 -7 1 -34.5t2 -59.5t1.5 -59.5t0.5 -34.5q0 -14 -1 -48.5t-2.5 -73t-3 -73t-2.5 -47.5q5 -6 5.5 -10t-1.5 -10q0 -10 -3 -18t-3 -19q-2 -28 5 -51t9 -51q0 -2 -0.5 -13.5t-0.5 -14.5t0.5 -8.5t1 -12t1 -12.5 t0.5 -8l-4 -58v-14q-1 -2 -1 -7t-1 -7l6 -68l-6 -166q-1 -5 0 -14.5l2 -19t-1 -16.5t-9 -7h-2q-2 0 -11 2.5t-11 4.5q-2 0 -11.5 -1.5t-22 -3t-25 -2.5t-19.5 0h-2q-1 -1 -3 -1h-1q-12 -1 -29 -2t-33.5 -2.5t-28.5 -2.5t-13 -1q-21 -1 -31 -3.5t-24 -5.5q-2 0 -6 2t-6 4 q-31 -6 -51.5 -1.5t-36.5 20t-31 42.5t-34 65q-1 2 -8 12t-15.5 22.5t-16.5 24t-12 17.5q-1 1 -3.5 6.5t-5.5 12t-6 12t-5 8.5q0 2 -2 4t-4 2l-130 196q-13 11 -22 27.5t-20 29.5l-28 28q-1 1 -5 7t-8.5 12t-8.5 11t-5 6q-3 3 -13 12.5t-21.5 21t-21 22t-12.5 13.5 q-2 4 -12 21t-22 36.5t-22.5 36.5t-13.5 21q-1 1 -4.5 7t-8 13t-9 12.5t-5.5 7.5q-2 2 -5.5 8.5t-8 14t-8.5 14.5t-5 9t-4.5 9.5t-8 16.5t-8.5 16.5t-5 10.5q-14 23 -27 46t-27 47q-5 6 -5.5 5t-6.5 -1l-2 -45l4 -62q-2 -18 -1 -34t3 -37l5 -52l-4 -98q8 -13 5.5 -28 t-0.5 -29q0 -3 0.5 -11.5t0.5 -18t0.5 -18t0.5 -11.5l-3 -57l12 -184q0 -3 2 -11.5t2 -11.5q0 -4 -0.5 -18.5t-1 -31t-1.5 -30.5t-1 -18v-27v-40t0.5 -39t0.5 -25q5 -9 11 -21t4 -23q0 -9 -6.5 -14t-14.5 -7.5t-17 -3t-13 -0.5q-6 -1 -22 -2t-34 -2t-33.5 -1.5t-21.5 -0.5 h-7.5h-15.5h-18h-14q-44 0 -87.5 2t-86.5 10z" />
<glyph unicode="&#xd2;" horiz-adv-x="1771" d="M748 1984v3l3 6q1 4 5 6t9 3t9.5 1.5t6.5 0.5h22h1h2q5 0 17 1t14 1q1 1 6.5 2.5t7.5 1.5t7.5 0.5t12 1t12 1t7.5 0.5t8 1.5t8 1.5h1q5 0 13 -2.5t10 -7.5q1 0 2 -3.5t1 -4.5q1 -2 6 -11.5t11 -20t11 -20t6 -11.5t3.5 -8.5t5 -14t4.5 -14.5t2 -8q3 -3 3 -6 q11 -18 14 -32.5t11 -32.5q2 -2 6.5 -12.5t5.5 -12.5v-3q0 -2 0.5 -3t0.5 -2q0 -12 -2 -21.5t-14 -5.5q-1 0 -6 -1.5t-11 -3t-11 -2.5t-6 -1q-14 -2 -25 -5.5t-20.5 -7t-20 -6t-24.5 -2.5q-4 0 -11.5 0.5t-8.5 0.5l-9 6l-2.5 4.5t-5.5 11.5t-6.5 14t-6.5 12 q-14 29 -25.5 58.5t-25.5 57.5q-11 23 -17 43t-17 43v3zM225 335q-8 -2 -12.5 -0.5t-9.5 8.5q-6 11 -5 22.5t-5 23.5q-8 18 -14.5 31.5t-12.5 26t-12 26t-13 30.5q-2 2 -6.5 11.5t-4.5 11.5v16q-1 4 -4.5 13.5t-7.5 21t-7.5 21.5t-4.5 14q-3 8 -7 12t-4 9v4q0 1 1 3 q0 2 3 8.5t3 7.5t-1 5t-2 8.5t-2 8.5t-1 5q-1 6 -2.5 16.5t-3 22t-3 20t-2.5 10.5q0 3 0.5 14.5t1.5 24t1.5 23.5t0.5 14q-1 3 -2.5 14.5t-3.5 25.5t-3.5 26t-1.5 15v36v38q1 6 2.5 21.5t3.5 32t3.5 31.5t3.5 21q0 1 1 6t2.5 11t3 11.5t2.5 8.5q13 37 27 68t30 60t35 56.5 t42 57.5q3 3 14 17t23.5 30.5t24 30.5t14.5 18q21 24 45.5 40.5t50.5 34.5q50 33 101.5 62t107.5 52l13.5 4.5t14.5 4.5q42 11 86 18.5t90 12.5q4 0 15.5 -1t25 -2t25 -2t15.5 -1q42 -2 87.5 -4t85.5 -18q6 -2 22.5 -8t35.5 -13t36 -13.5t24 -8.5q1 -1 6 -4t11.5 -6.5t12 -6 t7.5 -3.5q4 -2 10.5 -2.5t12 -3t8.5 -6.5t1 -11q32 -24 63.5 -42t63.5 -41q59 -42 106.5 -88t90.5 -106q2 -2 6 -8.5t8 -13.5t7.5 -13t5.5 -9q12 -1 17.5 -8.5t5.5 -17.5q0 -5 -1 -9t-6 -9q2 -3 5 -9.5t6 -14.5t6 -15t4 -10q0 -2 2.5 -11.5t4.5 -20.5t4.5 -20.5t2.5 -12.5 q5 -14 15 -23.5t10 -21.5q0 -11 -2.5 -16.5t-2.5 -13.5v-5q0 -2 1.5 -11t3.5 -19.5t3.5 -19.5t2.5 -11v-5.5t-0.5 -10t-0.5 -10v-5.5q0 -6 0.5 -29t0.5 -49.5t0.5 -49.5t0.5 -29v-11v-9q-6 -72 -16.5 -142t-38.5 -137q-2 -2 -7 -14t-8 -18q-2 -3 -5.5 -9.5t-8 -13.5 t-8 -13.5t-4.5 -8.5q-74 -88 -137.5 -153t-115.5 -104q-2 -2 -11 -7t-12 -7q-40 -24 -84.5 -48.5t-90.5 -35.5q-9 -2 -32.5 -6t-49.5 -9.5t-50 -10t-33 -5.5q-23 -5 -47 -3.5t-46 3.5q-34 2 -62.5 4t-64.5 8q-49 9 -104 27t-109 43t-103.5 55t-87.5 62q-5 4 -19 17.5 t-29.5 29t-30.5 29.5t-21 20q-2 2 -7 6.5t-10.5 9t-10 9t-5.5 6.5zM700 367q6 -1 21 -3t32 -4t32 -4t22 -2q1 0 8.5 -0.5t17 -1l19 -1t15.5 -0.5q65 -5 126.5 4.5t116.5 32.5t101.5 61t80.5 92q2 3 7 11.5t5 10.5q17 66 22 132t5 135q0 38 -3 72.5t-11 71.5q-9 31 -17.5 63 t-20 64t-26.5 62t-37 56q-2 2 -4.5 4t-4.5 5q-3 3 -6 7q-2 2 -11 1.5t-11 -0.5q-5 2 -6.5 6.5t-2.5 10t-2 10.5t-5 7q-114 72 -245 81q-4 0 -13 -1t-18.5 -1t-17.5 1t-10 5q-9 -2 -31 -6.5t-46.5 -9.5t-46 -9.5t-30.5 -7.5q-38 -9 -67 -23.5t-53 -34t-45.5 -44.5t-45.5 -55 q-14 -19 -26 -39.5t-16 -43.5q-8 -29 -12.5 -51t-6.5 -41.5t-2.5 -37.5t0.5 -37q4 -17 6 -41.5t3.5 -51.5t3 -55.5t4.5 -53.5q15 -6 22 -19t2 -25q3 -5 9.5 -19.5t14 -31.5t14 -32t9.5 -21q1 -2 3 -7.5t4.5 -12.5t5 -12.5t4.5 -6.5l9 -10q1 -2 4.5 -8.5t7 -14t6.5 -14.5 t4 -8q2 -3 8 -9.5t8 -6.5l38 -46q6 -8 11.5 -11.5t11.5 -4.5t13.5 -1.5t16.5 -2.5q3 0 4 -3.5t2.5 -7t5.5 -7t14 -4.5z" />
<glyph unicode="&#xd3;" horiz-adv-x="1771" d="M1029 1977q-12 -22 -19.5 -42t-19.5 -42q-15 -28 -29 -56.5t-30 -57.5q-3 -5 -6.5 -12.5t-7 -14t-6.5 -11.5l-3 -5l-10 -5q-1 0 -8.5 -0.5t-11.5 -0.5q-14 1 -24 4t-20 6.5l-20 7t-24 5.5q-1 0 -6 1.5t-11 3t-11 3t-6 1.5q-12 -3 -13.5 6.5t-0.5 21.5q0 3 1 5q0 2 1 3 l6 12t7 12q9 18 13 32.5t17 31.5q0 3 3 6q0 1 2.5 8t5.5 14.5t5.5 14t3.5 8.5t6.5 11.5t12.5 20t12.5 20t6.5 11.5q0 1 1.5 4t2.5 3q2 5 10 7.5t13 2.5h1q2 0 8 -2t8 -2q1 0 7 -0.5t12.5 -1.5t12 -1.5t7.5 -0.5t7.5 -1.5t6.5 -2.5q2 0 14 -1t17 -2h2h1h11t11 -1 q1 0 5.5 -0.5t9.5 -1.5t9 -3.5t5 -6.5l3 -6q-1 0 -1 -1v-2v-3v0zM225 335q-8 -2 -12.5 -0.5t-9.5 8.5q-6 11 -5 22.5t-5 23.5q-8 18 -14.5 31.5t-12.5 26t-12 26t-13 30.5q-2 2 -6.5 11.5t-4.5 11.5v16q-1 4 -4.5 13.5t-7.5 21t-7.5 21.5t-4.5 14q-3 8 -7 12t-4 9v4q0 1 1 3 q0 2 3 8.5t3 7.5t-1 5t-2 8.5t-2 8.5t-1 5q-1 6 -2.5 16.5t-3 22t-3 20t-2.5 10.5q0 3 0.5 14.5t1.5 24t1.5 23.5t0.5 14q-1 3 -2.5 14.5t-3.5 25.5t-3.5 26t-1.5 15v36v38q1 6 2.5 21.5t3.5 32t3.5 31.5t3.5 21q0 1 1 6t2.5 11t3 11.5t2.5 8.5q13 37 27 68t30 60t35 56.5 t42 57.5q3 3 14 17t23.5 30.5t24 30.5t14.5 18q21 24 45.5 40.5t50.5 34.5q50 33 101.5 62t107.5 52l13.5 4.5t14.5 4.5q42 11 86 18.5t90 12.5q4 0 15.5 -1t25 -2t25 -2t15.5 -1q42 -2 87.5 -4t85.5 -18q6 -2 22.5 -8t35.5 -13t36 -13.5t24 -8.5q1 -1 6 -4t11.5 -6.5t12 -6 t7.5 -3.5q4 -2 10.5 -2.5t12 -3t8.5 -6.5t1 -11q32 -24 63.5 -42t63.5 -41q59 -42 106.5 -88t90.5 -106q2 -2 6 -8.5t8 -13.5t7.5 -13t5.5 -9q12 -1 17.5 -8.5t5.5 -17.5q0 -5 -1 -9t-6 -9q2 -3 5 -9.5t6 -14.5t6 -15t4 -10q0 -2 2.5 -11.5t4.5 -20.5t4.5 -20.5t2.5 -12.5 q5 -14 15 -23.5t10 -21.5q0 -11 -2.5 -16.5t-2.5 -13.5v-5q0 -2 1.5 -11t3.5 -19.5t3.5 -19.5t2.5 -11v-5.5t-0.5 -10t-0.5 -10v-5.5q0 -6 0.5 -29t0.5 -49.5t0.5 -49.5t0.5 -29v-11v-9q-6 -72 -16.5 -142t-38.5 -137q-2 -2 -7 -14t-8 -18q-2 -3 -5.5 -9.5t-8 -13.5 t-8 -13.5t-4.5 -8.5q-74 -88 -137.5 -153t-115.5 -104q-2 -2 -11 -7t-12 -7q-40 -24 -84.5 -48.5t-90.5 -35.5q-9 -2 -32.5 -6t-49.5 -9.5t-50 -10t-33 -5.5q-23 -5 -47 -3.5t-46 3.5q-34 2 -62.5 4t-64.5 8q-49 9 -104 27t-109 43t-103.5 55t-87.5 62q-5 4 -19 17.5 t-29.5 29t-30.5 29.5t-21 20q-2 2 -7 6.5t-10.5 9t-10 9t-5.5 6.5zM700 367q6 -1 21 -3t32 -4t32 -4t22 -2q1 0 8.5 -0.5t17 -1l19 -1t15.5 -0.5q65 -5 126.5 4.5t116.5 32.5t101.5 61t80.5 92q2 3 7 11.5t5 10.5q17 66 22 132t5 135q0 38 -3 72.5t-11 71.5q-9 31 -17.5 63 t-20 64t-26.5 62t-37 56q-2 2 -4.5 4t-4.5 5q-3 3 -6 7q-2 2 -11 1.5t-11 -0.5q-5 2 -6.5 6.5t-2.5 10t-2 10.5t-5 7q-114 72 -245 81q-4 0 -13 -1t-18.5 -1t-17.5 1t-10 5q-9 -2 -31 -6.5t-46.5 -9.5t-46 -9.5t-30.5 -7.5q-38 -9 -67 -23.5t-53 -34t-45.5 -44.5t-45.5 -55 q-14 -19 -26 -39.5t-16 -43.5q-8 -29 -12.5 -51t-6.5 -41.5t-2.5 -37.5t0.5 -37q4 -17 6 -41.5t3.5 -51.5t3 -55.5t4.5 -53.5q15 -6 22 -19t2 -25q3 -5 9.5 -19.5t14 -31.5t14 -32t9.5 -21q1 -2 3 -7.5t4.5 -12.5t5 -12.5t4.5 -6.5l9 -10q1 -2 4.5 -8.5t7 -14t6.5 -14.5 t4 -8q2 -3 8 -9.5t8 -6.5l38 -46q6 -8 11.5 -11.5t11.5 -4.5t13.5 -1.5t16.5 -2.5q3 0 4 -3.5t2.5 -7t5.5 -7t14 -4.5z" />
<glyph unicode="&#xd4;" horiz-adv-x="1771" d="M704 1755q-22 4 -25 10t-6 8v1v1q5 13 14.5 27.5t16.5 25.5q4 7 11 18t14.5 24t14 26.5t11.5 25.5q6 8 9.5 16.5t7.5 17.5q11 27 17.5 39t15.5 22q1 1 5 2.5t6 1.5q4 0 16.5 0.5t26 1t25.5 0.5h17h42q1 0 5.5 0.5t9.5 1.5t9.5 1.5t5.5 0.5h5q7 1 10 -0.5t4 -4t1 -6 t2 -5.5q1 -1 2.5 -5.5t1.5 -5.5q1 -2 3.5 -5.5t3.5 -3.5q-4 4 2 -10.5t15.5 -36t20.5 -44t18 -35.5q4 -5 4 -11.5t2 -11.5q4 -10 8 -19.5t9 -20.5q2 -4 7.5 -12t5.5 -14q0 -2 -2.5 -5.5t-4.5 -4.5h-16q-1 0 -3.5 -1.5t-3.5 -1.5t-13.5 -1t-19.5 -1q-26 -2 -48 -9 q-13 -2 -25 -5.5t-25 -3.5q-8 0 -16.5 0.5t-13.5 6.5q-8 14 -12.5 28.5t-14.5 26.5q-2 -2 -3 -3.5t-3 -3.5q-1 -4 -7 -14.5t-8 -12.5q-1 -2 -4.5 -7.5t-9 -11t-12 -9t-13.5 -1.5h-4h-16.5h-12.5t-12.5 1t-15.5 3q-3 1 -11 2t-17 2.5t-16.5 3t-10.5 1.5zM225 335 q-8 -2 -12.5 -0.5t-9.5 8.5q-6 11 -5 22.5t-5 23.5q-8 18 -14.5 31.5t-12.5 26t-12 26t-13 30.5q-2 2 -6.5 11.5t-4.5 11.5v16q-1 4 -4.5 13.5t-7.5 21t-7.5 21.5t-4.5 14q-3 8 -7 12t-4 9v4q0 1 1 3q0 2 3 8.5t3 7.5t-1 5t-2 8.5t-2 8.5t-1 5q-1 6 -2.5 16.5t-3 22t-3 20 t-2.5 10.5q0 3 0.5 14.5t1.5 24t1.5 23.5t0.5 14q-1 3 -2.5 14.5t-3.5 25.5t-3.5 26t-1.5 15v36v38q1 6 2.5 21.5t3.5 32t3.5 31.5t3.5 21q0 1 1 6t2.5 11t3 11.5t2.5 8.5q13 37 27 68t30 60t35 56.5t42 57.5q3 3 14 17t23.5 30.5t24 30.5t14.5 18q21 24 45.5 40.5 t50.5 34.5q50 33 101.5 62t107.5 52l13.5 4.5t14.5 4.5q42 11 86 18.5t90 12.5q4 0 15.5 -1t25 -2t25 -2t15.5 -1q42 -2 87.5 -4t85.5 -18q6 -2 22.5 -8t35.5 -13t36 -13.5t24 -8.5q1 -1 6 -4t11.5 -6.5t12 -6t7.5 -3.5q4 -2 10.5 -2.5t12 -3t8.5 -6.5t1 -11 q32 -24 63.5 -42t63.5 -41q59 -42 106.5 -88t90.5 -106q2 -2 6 -8.5t8 -13.5t7.5 -13t5.5 -9q12 -1 17.5 -8.5t5.5 -17.5q0 -5 -1 -9t-6 -9q2 -3 5 -9.5t6 -14.5t6 -15t4 -10q0 -2 2.5 -11.5t4.5 -20.5t4.5 -20.5t2.5 -12.5q5 -14 15 -23.5t10 -21.5q0 -11 -2.5 -16.5 t-2.5 -13.5v-5q0 -2 1.5 -11t3.5 -19.5t3.5 -19.5t2.5 -11v-5.5t-0.5 -10t-0.5 -10v-5.5q0 -6 0.5 -29t0.5 -49.5t0.5 -49.5t0.5 -29v-11v-9q-6 -72 -16.5 -142t-38.5 -137q-2 -2 -7 -14t-8 -18q-2 -3 -5.5 -9.5t-8 -13.5t-8 -13.5t-4.5 -8.5q-74 -88 -137.5 -153 t-115.5 -104q-2 -2 -11 -7t-12 -7q-40 -24 -84.5 -48.5t-90.5 -35.5q-9 -2 -32.5 -6t-49.5 -9.5t-50 -10t-33 -5.5q-23 -5 -47 -3.5t-46 3.5q-34 2 -62.5 4t-64.5 8q-49 9 -104 27t-109 43t-103.5 55t-87.5 62q-5 4 -19 17.5t-29.5 29t-30.5 29.5t-21 20q-2 2 -7 6.5 t-10.5 9t-10 9t-5.5 6.5zM700 367q6 -1 21 -3t32 -4t32 -4t22 -2q1 0 8.5 -0.5t17 -1l19 -1t15.5 -0.5q65 -5 126.5 4.5t116.5 32.5t101.5 61t80.5 92q2 3 7 11.5t5 10.5q17 66 22 132t5 135q0 38 -3 72.5t-11 71.5q-9 31 -17.5 63t-20 64t-26.5 62t-37 56q-2 2 -4.5 4 t-4.5 5q-3 3 -6 7q-2 2 -11 1.5t-11 -0.5q-5 2 -6.5 6.5t-2.5 10t-2 10.5t-5 7q-114 72 -245 81q-4 0 -13 -1t-18.5 -1t-17.5 1t-10 5q-9 -2 -31 -6.5t-46.5 -9.5t-46 -9.5t-30.5 -7.5q-38 -9 -67 -23.5t-53 -34t-45.5 -44.5t-45.5 -55q-14 -19 -26 -39.5t-16 -43.5 q-8 -29 -12.5 -51t-6.5 -41.5t-2.5 -37.5t0.5 -37q4 -17 6 -41.5t3.5 -51.5t3 -55.5t4.5 -53.5q15 -6 22 -19t2 -25q3 -5 9.5 -19.5t14 -31.5t14 -32t9.5 -21q1 -2 3 -7.5t4.5 -12.5t5 -12.5t4.5 -6.5l9 -10q1 -2 4.5 -8.5t7 -14t6.5 -14.5t4 -8q2 -3 8 -9.5t8 -6.5l38 -46 q6 -8 11.5 -11.5t11.5 -4.5t13.5 -1.5t16.5 -2.5q3 0 4 -3.5t2.5 -7t5.5 -7t14 -4.5z" />
<glyph unicode="&#xd5;" horiz-adv-x="1771" d="M493 1845q0 1 -1.5 3.5t-1.5 3.5t3 5t5 5v5q12 32 37.5 56.5t48.5 49.5q2 1 8.5 8t8.5 8q29 30 67.5 53t80.5 23q18 0 33.5 -1.5t32.5 -9.5q10 -4 20.5 -10.5t21.5 -6.5l31 -22q4 -2 14.5 -8t22.5 -12t22.5 -11.5t14.5 -7.5q11 -6 19.5 -7t19.5 -1q15 0 34 13.5t28 26.5 q3 3 8 10t10.5 14.5t9.5 13.5t5 8q5 8 9 13t15 5h3q1 -1 6.5 -5.5t7.5 -6.5q14 -14 30 -26t30.5 -21.5t26.5 -17.5t20 -15q6 -7 12.5 -12t9.5 -10t2 -11t-8 -15q-9 -15 -18.5 -27.5t-20.5 -28.5q-20 -26 -41.5 -51.5t-47 -45.5t-55 -32t-64.5 -12q-9 -1 -26 3.5t-34.5 11.5 t-33.5 14t-24 12q-2 3 -11 12t-12 11q-17 14 -34 19.5t-40 5.5q-27 0 -51.5 -13t-42.5 -37q-7 -11 -12.5 -18.5t-12 -12.5t-15 -7.5t-22.5 -2.5q-3 0 -8 1t-7 1q-1 0 -6 4.5t-7 4.5q-2 2 -5.5 4t-4.5 4q-17 11 -29 18t-27 22q-1 0 -7 4q-3 2 -6 5q-3 2 -8.5 8.5t-12.5 13.5 t-12.5 13t-8.5 9zM225 335q-8 -2 -12.5 -0.5t-9.5 8.5q-6 11 -5 22.5t-5 23.5q-8 18 -14.5 31.5t-12.5 26t-12 26t-13 30.5q-2 2 -6.5 11.5t-4.5 11.5v16q-1 4 -4.5 13.5t-7.5 21t-7.5 21.5t-4.5 14q-3 8 -7 12t-4 9v4q0 1 1 3q0 2 3 8.5t3 7.5t-1 5t-2 8.5t-2 8.5t-1 5 q-1 6 -2.5 16.5t-3 22t-3 20t-2.5 10.5q0 3 0.5 14.5t1.5 24t1.5 23.5t0.5 14q-1 3 -2.5 14.5t-3.5 25.5t-3.5 26t-1.5 15v36v38q1 6 2.5 21.5t3.5 32t3.5 31.5t3.5 21q0 1 1 6t2.5 11t3 11.5t2.5 8.5q13 37 27 68t30 60t35 56.5t42 57.5q3 3 14 17t23.5 30.5t24 30.5 t14.5 18q21 24 45.5 40.5t50.5 34.5q50 33 101.5 62t107.5 52l13.5 4.5t14.5 4.5q42 11 86 18.5t90 12.5q4 0 15.5 -1t25 -2t25 -2t15.5 -1q42 -2 87.5 -4t85.5 -18q6 -2 22.5 -8t35.5 -13t36 -13.5t24 -8.5q1 -1 6 -4t11.5 -6.5t12 -6t7.5 -3.5q4 -2 10.5 -2.5t12 -3 t8.5 -6.5t1 -11q32 -24 63.5 -42t63.5 -41q59 -42 106.5 -88t90.5 -106q2 -2 6 -8.5t8 -13.5t7.5 -13t5.5 -9q12 -1 17.5 -8.5t5.5 -17.5q0 -5 -1 -9t-6 -9q2 -3 5 -9.5t6 -14.5t6 -15t4 -10q0 -2 2.5 -11.5t4.5 -20.5t4.5 -20.5t2.5 -12.5q5 -14 15 -23.5t10 -21.5 q0 -11 -2.5 -16.5t-2.5 -13.5v-5q0 -2 1.5 -11t3.5 -19.5t3.5 -19.5t2.5 -11v-5.5t-0.5 -10t-0.5 -10v-5.5q0 -6 0.5 -29t0.5 -49.5t0.5 -49.5t0.5 -29v-11v-9q-6 -72 -16.5 -142t-38.5 -137q-2 -2 -7 -14t-8 -18q-2 -3 -5.5 -9.5t-8 -13.5t-8 -13.5t-4.5 -8.5 q-74 -88 -137.5 -153t-115.5 -104q-2 -2 -11 -7t-12 -7q-40 -24 -84.5 -48.5t-90.5 -35.5q-9 -2 -32.5 -6t-49.5 -9.5t-50 -10t-33 -5.5q-23 -5 -47 -3.5t-46 3.5q-34 2 -62.5 4t-64.5 8q-49 9 -104 27t-109 43t-103.5 55t-87.5 62q-5 4 -19 17.5t-29.5 29t-30.5 29.5 t-21 20q-2 2 -7 6.5t-10.5 9t-10 9t-5.5 6.5zM700 367q6 -1 21 -3t32 -4t32 -4t22 -2q1 0 8.5 -0.5t17 -1l19 -1t15.5 -0.5q65 -5 126.5 4.5t116.5 32.5t101.5 61t80.5 92q2 3 7 11.5t5 10.5q17 66 22 132t5 135q0 38 -3 72.5t-11 71.5q-9 31 -17.5 63t-20 64t-26.5 62 t-37 56q-2 2 -4.5 4t-4.5 5q-3 3 -6 7q-2 2 -11 1.5t-11 -0.5q-5 2 -6.5 6.5t-2.5 10t-2 10.5t-5 7q-114 72 -245 81q-4 0 -13 -1t-18.5 -1t-17.5 1t-10 5q-9 -2 -31 -6.5t-46.5 -9.5t-46 -9.5t-30.5 -7.5q-38 -9 -67 -23.5t-53 -34t-45.5 -44.5t-45.5 -55 q-14 -19 -26 -39.5t-16 -43.5q-8 -29 -12.5 -51t-6.5 -41.5t-2.5 -37.5t0.5 -37q4 -17 6 -41.5t3.5 -51.5t3 -55.5t4.5 -53.5q15 -6 22 -19t2 -25q3 -5 9.5 -19.5t14 -31.5t14 -32t9.5 -21q1 -2 3 -7.5t4.5 -12.5t5 -12.5t4.5 -6.5l9 -10q1 -2 4.5 -8.5t7 -14t6.5 -14.5 t4 -8q2 -3 8 -9.5t8 -6.5l38 -46q6 -8 11.5 -11.5t11.5 -4.5t13.5 -1.5t16.5 -2.5q3 0 4 -3.5t2.5 -7t5.5 -7t14 -4.5z" />
<glyph unicode="&#xd6;" horiz-adv-x="1771" d="M818 1896v-18t-4 -19q-7 -14 -12 -26.5t-16 -24.5q-6 -7 -19 -16.5t-16 -12.5q-14 -13 -31 -13t-34 -1q-11 -1 -18 1t-18 7q-5 0 -13.5 4t-13.5 7q-26 16 -44.5 40t-21.5 57q0 20 0.5 34t4.5 26t13 23t24 24q14 13 34 23.5t38 11.5q5 1 17 0.5t15 -1.5q6 -1 18.5 -4 t14.5 -4q1 -1 6 -2.5t10.5 -3.5t10.5 -3.5t7 -2.5q28 -21 37 -45t11 -61zM1129 1893q0 -8 0.5 -17.5t-3.5 -19.5q-7 -14 -12 -26t-16 -24q-3 -3 -8 -7.5t-10 -8.5l-10 -8t-6 -5q-14 -13 -31.5 -13t-34.5 -1q-11 -1 -17.5 1.5t-17.5 5.5q-5 1 -14 5t-14 8q-26 15 -44 38.5 t-23 56.5q0 20 1 34t5.5 26t13.5 23t24 25q13 13 33 23.5t38 11.5q4 1 17 0.5t16 -1.5q5 -1 17.5 -4.5t15.5 -3.5q1 -1 5.5 -3t10 -3.5t10.5 -3t7 -2.5q28 -22 37.5 -45.5t9.5 -61.5zM225 335q-8 -2 -12.5 -0.5t-9.5 8.5q-6 11 -5 22.5t-5 23.5q-8 18 -14.5 31.5t-12.5 26 t-12 26t-13 30.5q-2 2 -6.5 11.5t-4.5 11.5v16q-1 4 -4.5 13.5t-7.5 21t-7.5 21.5t-4.5 14q-3 8 -7 12t-4 9v4q0 1 1 3q0 2 3 8.5t3 7.5t-1 5t-2 8.5t-2 8.5t-1 5q-1 6 -2.5 16.5t-3 22t-3 20t-2.5 10.5q0 3 0.5 14.5t1.5 24t1.5 23.5t0.5 14q-1 3 -2.5 14.5t-3.5 25.5 t-3.5 26t-1.5 15v36v38q1 6 2.5 21.5t3.5 32t3.5 31.5t3.5 21q0 1 1 6t2.5 11t3 11.5t2.5 8.5q13 37 27 68t30 60t35 56.5t42 57.5q3 3 14 17t23.5 30.5t24 30.5t14.5 18q21 24 45.5 40.5t50.5 34.5q50 33 101.5 62t107.5 52l13.5 4.5t14.5 4.5q42 11 86 18.5t90 12.5 q4 0 15.5 -1t25 -2t25 -2t15.5 -1q42 -2 87.5 -4t85.5 -18q6 -2 22.5 -8t35.5 -13t36 -13.5t24 -8.5q1 -1 6 -4t11.5 -6.5t12 -6t7.5 -3.5q4 -2 10.5 -2.5t12 -3t8.5 -6.5t1 -11q32 -24 63.5 -42t63.5 -41q59 -42 106.5 -88t90.5 -106q2 -2 6 -8.5t8 -13.5t7.5 -13t5.5 -9 q12 -1 17.5 -8.5t5.5 -17.5q0 -5 -1 -9t-6 -9q2 -3 5 -9.5t6 -14.5t6 -15t4 -10q0 -2 2.5 -11.5t4.5 -20.5t4.5 -20.5t2.5 -12.5q5 -14 15 -23.5t10 -21.5q0 -11 -2.5 -16.5t-2.5 -13.5v-5q0 -2 1.5 -11t3.5 -19.5t3.5 -19.5t2.5 -11v-5.5t-0.5 -10t-0.5 -10v-5.5 q0 -6 0.5 -29t0.5 -49.5t0.5 -49.5t0.5 -29v-11v-9q-6 -72 -16.5 -142t-38.5 -137q-2 -2 -7 -14t-8 -18q-2 -3 -5.5 -9.5t-8 -13.5t-8 -13.5t-4.5 -8.5q-74 -88 -137.5 -153t-115.5 -104q-2 -2 -11 -7t-12 -7q-40 -24 -84.5 -48.5t-90.5 -35.5q-9 -2 -32.5 -6t-49.5 -9.5 t-50 -10t-33 -5.5q-23 -5 -47 -3.5t-46 3.5q-34 2 -62.5 4t-64.5 8q-49 9 -104 27t-109 43t-103.5 55t-87.5 62q-5 4 -19 17.5t-29.5 29t-30.5 29.5t-21 20q-2 2 -7 6.5t-10.5 9t-10 9t-5.5 6.5zM700 367q6 -1 21 -3t32 -4t32 -4t22 -2q1 0 8.5 -0.5t17 -1l19 -1t15.5 -0.5 q65 -5 126.5 4.5t116.5 32.5t101.5 61t80.5 92q2 3 7 11.5t5 10.5q17 66 22 132t5 135q0 38 -3 72.5t-11 71.5q-9 31 -17.5 63t-20 64t-26.5 62t-37 56q-2 2 -4.5 4t-4.5 5q-3 3 -6 7q-2 2 -11 1.5t-11 -0.5q-5 2 -6.5 6.5t-2.5 10t-2 10.5t-5 7q-114 72 -245 81 q-4 0 -13 -1t-18.5 -1t-17.5 1t-10 5q-9 -2 -31 -6.5t-46.5 -9.5t-46 -9.5t-30.5 -7.5q-38 -9 -67 -23.5t-53 -34t-45.5 -44.5t-45.5 -55q-14 -19 -26 -39.5t-16 -43.5q-8 -29 -12.5 -51t-6.5 -41.5t-2.5 -37.5t0.5 -37q4 -17 6 -41.5t3.5 -51.5t3 -55.5t4.5 -53.5 q15 -6 22 -19t2 -25q3 -5 9.5 -19.5t14 -31.5t14 -32t9.5 -21q1 -2 3 -7.5t4.5 -12.5t5 -12.5t4.5 -6.5l9 -10q1 -2 4.5 -8.5t7 -14t6.5 -14.5t4 -8q2 -3 8 -9.5t8 -6.5l38 -46q6 -8 11.5 -11.5t11.5 -4.5t13.5 -1.5t16.5 -2.5q3 0 4 -3.5t2.5 -7t5.5 -7t14 -4.5z" />
<glyph unicode="&#xd7;" horiz-adv-x="976" d="M671 397q-4 -9 -11 -9.5t-14 2.5t-14 7.5t-11 6.5l-166 139q-12 -15 -26.5 -34.5t-29.5 -39.5t-30.5 -38.5t-30.5 -32.5q-1 0 -11 3q0 1 -2.5 -2t-1.5 -1q-9 6 -35.5 23.5t-56.5 37t-56.5 37t-35.5 23.5l-7 6q-23 20 -6 52q13 12 27 31.5t27.5 40.5t26 40.5t23.5 32.5 q5 6 10.5 12.5t6.5 14.5l-13 10q-24 21 -42 35.5t-35.5 28t-35.5 27.5t-42 35q-3 2 -9 7.5t-13.5 12t-13.5 12t-9 7.5q-5 5 -0.5 10.5t26.5 23.5l13 19.5t19.5 28.5t20 28.5t12.5 18.5q2 3 11 13t19 21.5t18.5 21t9.5 11.5l8 10q4 5 9 11l10 12q5 7 11 14l25 8q4 -3 12.5 -9 t13.5 -8q2 -1 6.5 -5.5t5.5 -6.5q14 -8 21 -13t12 -9.5t11.5 -11t20.5 -17.5q7 -6 20.5 -16t29.5 -23t33 -26.5t30 -25.5q4 -4 7.5 -2.5t7 5.5t6.5 9t6 8l3 3q7 15 20.5 34t30 38.5t32.5 38t27 32.5q2 2 6 6.5t8 9.5t10 11l25 -13q34 -26 63.5 -52.5t69.5 -49.5q0 -1 7 -6.5 t15.5 -12.5t15 -12.5l6.5 -5.5l4 -3q7 -6 8 -13t-1.5 -13.5t-6 -13.5l-6.5 -13l-42 -55l-81 -97l54 -47q1 -1 14.5 -12t31.5 -26t36.5 -31t29.5 -25q7 -6 8.5 -11t0 -10t-5 -11t-7.5 -13z" />
<glyph unicode="&#xd8;" horiz-adv-x="1771" d="M225 335q-8 -2 -12.5 -0.5t-9.5 8.5q-6 11 -5 22.5t-5 23.5q-8 18 -14.5 31.5t-12.5 26t-12 26t-13 30.5q-2 2 -6.5 11.5t-4.5 11.5v16q-1 4 -4.5 13.5t-7.5 21t-7.5 21.5t-4.5 14q-3 8 -7 12t-4 9v4q0 1 1 3q0 2 3 8.5t3 7.5t-1 5t-2 8.5t-2 8.5t-1 5q-1 6 -2.5 16.5 t-3 22t-3 20t-2.5 10.5q0 3 0.5 14.5t1.5 24t1.5 23.5t0.5 14q-1 3 -2.5 14.5t-3.5 25.5t-3.5 26t-1.5 15v74q1 6 2.5 21.5t3.5 32t3.5 31.5t3.5 21q0 1 1 6t2.5 11t3 11.5t2.5 8.5q13 37 27 68t30 60t35 56.5t42 57.5q3 3 14 17t23.5 30.5t24 30.5t14.5 18q21 24 45.5 40.5 t50.5 34.5q50 33 101.5 62t107.5 52l13.5 4.5t14.5 4.5q42 11 86 18.5t90 12.5q4 0 15.5 -1t25 -2t25 -2t15.5 -1q4 -1 8 -1h9l-25 9v2q18 58 32.5 109t28.5 111q5 8 11.5 7.5t13.5 -3.5q2 -1 4.5 -1.5t4.5 -2.5q3 -2 6 -3t17.5 -5t31.5 -9t32 -9.5t18 -5.5q1 0 5.5 -1.5 t9.5 -3.5l10 -4t6 -2q11 -5 30 -10.5t39 -10t39.5 -9t31.5 -8.5q10 -4 13 -5t13 -4l1 -1q2 -2 8 -12.5t9 -13.5l9 -8q1 -4 2 -17t-1 -15q0 -3 -1.5 -9t-2.5 -13t-2 -13.5t-1 -8.5q-1 -5 -7.5 -20.5t-14.5 -33t-15 -33.5t-8 -21q2 -6 2.5 -16.5t-0.5 -18.5q29 -22 59.5 -39 t60.5 -38q59 -42 106.5 -88t90.5 -106q2 -2 6 -8.5t8 -13.5t7.5 -13t5.5 -9q12 -1 17.5 -8.5t5.5 -17.5q0 -5 -1 -9t-6 -9q2 -3 5 -9.5t6 -14.5t6 -15t4 -10q0 -2 2.5 -11.5t4.5 -20.5t4.5 -20.5t2.5 -12.5q5 -14 15 -23.5t10 -21.5q0 -11 -2.5 -16.5t-2.5 -13.5v-5 q0 -2 1.5 -11t3.5 -19.5t3.5 -19.5t2.5 -11v-5.5t-0.5 -10t-0.5 -10v-5.5q0 -6 0.5 -29t0.5 -49.5t0.5 -49.5t0.5 -29v-20q-6 -72 -16.5 -142t-38.5 -137q-2 -2 -7 -14t-8 -18q-2 -3 -5.5 -9.5t-8 -13.5t-8 -13.5t-4.5 -8.5q-74 -88 -137.5 -153t-115.5 -104q-2 -2 -11 -7 t-12 -7q-40 -24 -84.5 -48.5t-90.5 -35.5q-9 -2 -32.5 -6t-49.5 -9.5t-50 -10t-33 -5.5q-23 -5 -47 -3.5t-46 3.5q-23 2 -43.5 3t-41.5 3l41 -15q-9 -26 -16 -48.5t-7 -24.5q-6 -20 -26 -25.5t-41.5 -4t-38 5.5t-16.5 3l-6 -1q-3 1 -18.5 6t-33.5 10.5t-33 10t-16 5.5 q-2 0 -3 0.5l-3 1.5q-16 6 -31 13.5t-30 12.5q-15 6 -24 8.5t-27 4.5q-2 -2 -9.5 -2h-9.5v2q-12 3 -16 16q0 4 1 15.5t1.5 24t1.5 23t1 14.5l1 2q0 3 1 4q0 1 1 1q7 25 17 56q-30 17 -57 35.5t-50 38.5q-5 4 -19 17.5t-29.5 29t-30.5 29.5t-21 20q-2 2 -7 6.5t-10.5 9t-10 9 t-5.5 6.5zM1142 1120q-10 -49 -24 -110.5t-30 -129t-34 -138.5t-36 -140t-35 -133t-32 -118q105 7 194.5 53.5t146.5 136.5q2 3 7 11.5t5 10.5q17 66 22 132t5 135q0 38 -3 72.5t-11 71.5q-9 31 -17.5 63t-20 64t-26.5 62t-37 56q-2 2 -4.5 4t-4.5 5q-3 3 -6 7q-2 2 -11 1.5 t-11 -0.5q-4 0 -5 3v-5q-2 -5 -6.5 -21.5t-10 -36t-10 -36t-5.5 -20.5zM788 1295q1 4 3.5 17.5t6.5 30.5q-28 -6 -55.5 -12t-37.5 -9q-38 -9 -67 -23.5t-53 -34t-45.5 -44.5t-45.5 -55q-14 -19 -26 -39.5t-16 -43.5q-8 -29 -12.5 -51t-6.5 -41.5t-2.5 -37.5t0.5 -37 q4 -17 6 -41.5t3.5 -51.5t3 -55.5t4.5 -53.5q15 -6 22 -19t2 -25q3 -5 9.5 -19.5t14 -31.5t14 -32t9.5 -21q1 -2 3 -7.5t4.5 -12.5t5 -12.5t4.5 -6.5l9 -10q1 -2 4.5 -8t7 -13.5t6 -14.5t3.5 -9l106 374q19 117 51.5 226t64.5 224z" />
<glyph unicode="&#xd9;" horiz-adv-x="1282" d="M503 1984v3l3 6q1 4 5 6t9 3t9.5 1.5t6.5 0.5h22h1h2q5 0 17 1t14 1q1 1 6.5 2.5t7.5 1.5t7.5 0.5t12 1t12 1t7.5 0.5t8 1.5t8 1.5h1q5 0 13 -2.5t10 -7.5q1 0 2 -3.5t1 -4.5q1 -2 6 -11.5t11 -20t11 -20t6 -11.5t3.5 -8.5t5 -14t4.5 -14.5t2 -8q3 -3 3 -6 q11 -18 14 -32.5t11 -32.5q2 -2 6.5 -12.5t5.5 -12.5v-3q0 -2 0.5 -3t0.5 -2q0 -12 -2 -21.5t-14 -5.5q-1 0 -6 -1.5t-11 -3t-11 -2.5t-6 -1q-14 -2 -25 -5.5t-20.5 -7t-20 -6t-24.5 -2.5q-4 0 -11.5 0.5t-8.5 0.5l-9 6l-2.5 4.5t-5.5 11.5t-6.5 14t-6.5 12 q-14 29 -25.5 58.5t-25.5 57.5q-11 23 -17 43t-17 43v3zM60 1661q1 19 8 34.5t29 17.5q28 -2 57 -6.5t57 -7.5t53.5 -2.5t45.5 9.5q3 0 16.5 -0.5t29 -1.5t28.5 -1.5t16 -0.5q2 0 5 1q2 0 3.5 0.5t2.5 0.5q15 -2 21 -14.5t12 -28.5q1 -8 1.5 -16t-0.5 -16q-1 -27 -2 -49 t-2.5 -43.5t-2.5 -44t-2 -49.5q-2 -52 -0.5 -112t6.5 -113q0 -3 0.5 -14t1 -23t1 -22.5t0.5 -12.5v-7t-0.5 -10.5l-1 -11t-0.5 -6.5q0 -2 0.5 -7.5t1 -12.5t1.5 -14t1 -11q11 -93 25 -182t31 -182q1 -2 2 -7.5t2.5 -12.5t3 -13t2.5 -7q0 -1 0.5 -5.5t1.5 -9.5t2 -9t1 -5v-6 t1 -8t2 -9l16 -58q2 -14 6 -32.5t9.5 -37.5t12.5 -36t15 -28q23 -35 58 -50.5t73 1.5h4q1 1 6 3q2 1 5 2q4 3 12.5 11t17.5 16.5t17.5 16t11.5 10.5q2 2 7 7.5t7 10.5q25 39 47 91t28 100q1 12 3 34t3.5 44.5t3.5 41t3 24.5v8.5t0.5 16.5t1 18.5t0.5 14.5q2 60 -2.5 119.5 t-6.5 118.5v16.5t-0.5 29t-1 29t-1.5 17.5q0 9 -1.5 32t-3 49t-3.5 48.5t-3 31.5q0 4 -2 21.5t-4.5 37t-4.5 36t-2 20.5q0 3 -3.5 28.5t-7.5 59t-7.5 68.5t-3.5 58v4q0 2 0.5 3.5t0.5 2.5q0 7 -1.5 10t-1.5 4.5t2 2.5t9 4q58 4 122 6.5t121 -0.5q10 -2 23.5 -1.5t27 0.5 t24 -1.5t15.5 -6.5q4 -5 11 -6.5t13 -3t10.5 -3.5t5.5 -7q4 -21 6 -38.5t3 -34t2 -34t2 -39.5v-29q1 -3 2.5 -15t1.5 -15q-5 -8 -4.5 -28t2.5 -43t5 -42.5t3 -25.5q-2 -39 -4.5 -79.5t-4.5 -79.5t-4.5 -75.5t-3.5 -66.5q0 -3 -0.5 -19t-1 -34.5t-1 -34.5t-0.5 -19 q-1 -4 -1.5 -14t-1 -21t-0.5 -21v-14l-5 -12l-31 -393q-14 -77 -37 -135t-56 -102t-76.5 -76.5t-98.5 -57.5q-21 -6 -42.5 -15.5t-43.5 -18.5t-44.5 -15.5t-43.5 -5.5q-32 -5 -55 -7t-42 -2.5t-35 1.5t-34 6q-34 5 -67.5 9.5t-65.5 22.5q-38 19 -68.5 40.5t-57 46.5t-50 54 t-46.5 64q-19 30 -27.5 56t-19.5 61q-4 14 -11.5 32.5t-9.5 32.5q-1 4 -3 22t-4 38.5t-3.5 38.5t-2.5 23q0 3 -2 14t-4.5 23.5t-4.5 23.5t-2 14q-11 100 -13 199t-7 201v10q0 5 -0.5 15t-1.5 20t-1.5 18t-0.5 10q0 6 -2.5 26.5t-5.5 44.5t-5.5 44.5t-2.5 26.5q0 2 0.5 12 t0.5 21.5t0.5 21.5t0.5 12q-2 50 -5.5 92t-6.5 87q0 3 2 15t0 14q0 2 -2 6t-2 6q-8 31 -8.5 65t0.5 66z" />
<glyph unicode="&#xda;" horiz-adv-x="1282" d="M785 1977q-12 -22 -19.5 -42t-19.5 -42q-15 -28 -29 -56.5t-30 -57.5q-3 -5 -6.5 -12.5t-7 -14t-6.5 -11.5l-3 -5l-10 -5q-1 0 -8.5 -0.5t-11.5 -0.5q-14 1 -24 4t-20 6.5l-20 7t-24 5.5q-1 0 -6 1.5t-11 3t-11 3t-6 1.5q-12 -3 -13.5 6.5t-0.5 21.5q0 3 1 5q0 2 1 3 l6 12t7 12q9 18 13 32.5t17 31.5q0 3 3 6q0 1 2.5 8t5.5 14.5t5.5 14t3.5 8.5t6.5 11.5t12.5 20t12.5 20t6.5 11.5q0 1 1.5 4t2.5 3q2 5 10 7.5t13 2.5h1q2 0 8 -2t8 -2q1 0 7 -0.5t12.5 -1.5t12 -1.5t7.5 -0.5t7.5 -1.5t6.5 -2.5q2 0 14 -1t17 -2h2h1h11t11 -1 q1 0 5.5 -0.5t9.5 -1.5t9 -3.5t5 -6.5l3 -6q-1 0 -1 -1v-2v-3v0zM60 1661q1 19 8 34.5t29 17.5q28 -2 57 -6.5t57 -7.5t53.5 -2.5t45.5 9.5q3 0 16.5 -0.5t29 -1.5t28.5 -1.5t16 -0.5q2 0 5 1q2 0 3.5 0.5t2.5 0.5q15 -2 21 -14.5t12 -28.5q1 -8 1.5 -16t-0.5 -16 q-1 -27 -2 -49t-2.5 -43.5t-2.5 -44t-2 -49.5q-2 -52 -0.5 -112t6.5 -113q0 -3 0.5 -14t1 -23t1 -22.5t0.5 -12.5v-7t-0.5 -10.5l-1 -11t-0.5 -6.5q0 -2 0.5 -7.5t1 -12.5t1.5 -14t1 -11q11 -93 25 -182t31 -182q1 -2 2 -7.5t2.5 -12.5t3 -13t2.5 -7q0 -1 0.5 -5.5t1.5 -9.5 t2 -9t1 -5v-6t1 -8t2 -9l16 -58q2 -14 6 -32.5t9.5 -37.5t12.5 -36t15 -28q23 -35 58 -50.5t73 1.5h4q1 1 6 3q2 1 5 2q4 3 12.5 11t17.5 16.5t17.5 16t11.5 10.5q2 2 7 7.5t7 10.5q25 39 47 91t28 100q1 12 3 34t3.5 44.5t3.5 41t3 24.5v8.5t0.5 16.5t1 18.5t0.5 14.5 q2 60 -2.5 119.5t-6.5 118.5v16.5t-0.5 29t-1 29t-1.5 17.5q0 9 -1.5 32t-3 49t-3.5 48.5t-3 31.5q0 4 -2 21.5t-4.5 37t-4.5 36t-2 20.5q0 3 -3.5 28.5t-7.5 59t-7.5 68.5t-3.5 58v4q0 2 0.5 3.5t0.5 2.5q0 7 -1.5 10t-1.5 4.5t2 2.5t9 4q58 4 122 6.5t121 -0.5 q10 -2 23.5 -1.5t27 0.5t24 -1.5t15.5 -6.5q4 -5 11 -6.5t13 -3t10.5 -3.5t5.5 -7q4 -21 6 -38.5t3 -34t2 -34t2 -39.5v-29q1 -3 2.5 -15t1.5 -15q-5 -8 -4.5 -28t2.5 -43t5 -42.5t3 -25.5q-2 -39 -4.5 -79.5t-4.5 -79.5t-4.5 -75.5t-3.5 -66.5q0 -3 -0.5 -19t-1 -34.5 t-1 -34.5t-0.5 -19q-1 -4 -1.5 -14t-1 -21t-0.5 -21v-14l-5 -12l-31 -393q-14 -77 -37 -135t-56 -102t-76.5 -76.5t-98.5 -57.5q-21 -6 -42.5 -15.5t-43.5 -18.5t-44.5 -15.5t-43.5 -5.5q-32 -5 -55 -7t-42 -2.5t-35 1.5t-34 6q-34 5 -67.5 9.5t-65.5 22.5 q-38 19 -68.5 40.5t-57 46.5t-50 54t-46.5 64q-19 30 -27.5 56t-19.5 61q-4 14 -11.5 32.5t-9.5 32.5q-1 4 -3 22t-4 38.5t-3.5 38.5t-2.5 23q0 3 -2 14t-4.5 23.5t-4.5 23.5t-2 14q-11 100 -13 199t-7 201v10q0 5 -0.5 15t-1.5 20t-1.5 18t-0.5 10q0 6 -2.5 26.5t-5.5 44.5 t-5.5 44.5t-2.5 26.5q0 2 0.5 12t0.5 21.5t0.5 21.5t0.5 12q-2 50 -5.5 92t-6.5 87q0 3 2 15t0 14q0 2 -2 6t-2 6q-8 31 -8.5 65t0.5 66z" />
<glyph unicode="&#xdb;" horiz-adv-x="1282" d="M459 1755q-22 4 -25 10t-6 8v1v1q5 13 14.5 27.5t16.5 25.5q4 7 11 18t14.5 24t14 26.5t11.5 25.5q6 8 9.5 16.5t7.5 17.5q11 27 17.5 39t15.5 22q1 1 5 2.5t6 1.5q4 0 16.5 0.5t26 1t25.5 0.5h17h42q1 0 5.5 0.5t9.5 1.5t9.5 1.5t5.5 0.5h5q7 1 10 -0.5t4 -4t1 -6 t2 -5.5q1 -1 2.5 -5.5t1.5 -5.5q1 -2 3.5 -5.5t3.5 -3.5q-4 4 2 -10.5t15.5 -36t20.5 -44t18 -35.5q4 -5 4 -11.5t2 -11.5q4 -10 8 -19.5t9 -20.5q2 -4 7.5 -12t5.5 -14q0 -2 -2.5 -5.5t-4.5 -4.5h-16q-1 0 -3.5 -1.5t-3.5 -1.5t-13.5 -1t-19.5 -1q-26 -2 -48 -9 q-13 -2 -25 -5.5t-25 -3.5q-8 0 -16.5 0.5t-13.5 6.5q-8 14 -12.5 28.5t-14.5 26.5q-2 -2 -3 -3.5t-3 -3.5q-1 -4 -7 -14.5t-8 -12.5q-1 -2 -4.5 -7.5t-9 -11t-12 -9t-13.5 -1.5h-4h-16.5h-12.5t-12.5 1t-15.5 3q-3 1 -11 2t-17 2.5t-16.5 3t-10.5 1.5zM60 1661q1 19 8 34.5 t29 17.5q28 -2 57 -6.5t57 -7.5t53.5 -2.5t45.5 9.5q3 0 16.5 -0.5t29 -1.5t28.5 -1.5t16 -0.5q2 0 5 1q2 0 3.5 0.5t2.5 0.5q15 -2 21 -14.5t12 -28.5q1 -8 1.5 -16t-0.5 -16q-1 -27 -2 -49t-2.5 -43.5t-2.5 -44t-2 -49.5q-2 -52 -0.5 -112t6.5 -113q0 -3 0.5 -14t1 -23 t1 -22.5t0.5 -12.5v-7t-0.5 -10.5l-1 -11t-0.5 -6.5q0 -2 0.5 -7.5t1 -12.5t1.5 -14t1 -11q11 -93 25 -182t31 -182q1 -2 2 -7.5t2.5 -12.5t3 -13t2.5 -7q0 -1 0.5 -5.5t1.5 -9.5t2 -9t1 -5v-6t1 -8t2 -9l16 -58q2 -14 6 -32.5t9.5 -37.5t12.5 -36t15 -28q23 -35 58 -50.5 t73 1.5h4q1 1 6 3q2 1 5 2q4 3 12.5 11t17.5 16.5t17.5 16t11.5 10.5q2 2 7 7.5t7 10.5q25 39 47 91t28 100q1 12 3 34t3.5 44.5t3.5 41t3 24.5v8.5t0.5 16.5t1 18.5t0.5 14.5q2 60 -2.5 119.5t-6.5 118.5v16.5t-0.5 29t-1 29t-1.5 17.5q0 9 -1.5 32t-3 49t-3.5 48.5 t-3 31.5q0 4 -2 21.5t-4.5 37t-4.5 36t-2 20.5q0 3 -3.5 28.5t-7.5 59t-7.5 68.5t-3.5 58v4q0 2 0.5 3.5t0.5 2.5q0 7 -1.5 10t-1.5 4.5t2 2.5t9 4q58 4 122 6.5t121 -0.5q10 -2 23.5 -1.5t27 0.5t24 -1.5t15.5 -6.5q4 -5 11 -6.5t13 -3t10.5 -3.5t5.5 -7q4 -21 6 -38.5 t3 -34t2 -34t2 -39.5v-29q1 -3 2.5 -15t1.5 -15q-5 -8 -4.5 -28t2.5 -43t5 -42.5t3 -25.5q-2 -39 -4.5 -79.5t-4.5 -79.5t-4.5 -75.5t-3.5 -66.5q0 -3 -0.5 -19t-1 -34.5t-1 -34.5t-0.5 -19q-1 -4 -1.5 -14t-1 -21t-0.5 -21v-14l-5 -12l-31 -393q-14 -77 -37 -135t-56 -102 t-76.5 -76.5t-98.5 -57.5q-21 -6 -42.5 -15.5t-43.5 -18.5t-44.5 -15.5t-43.5 -5.5q-32 -5 -55 -7t-42 -2.5t-35 1.5t-34 6q-34 5 -67.5 9.5t-65.5 22.5q-38 19 -68.5 40.5t-57 46.5t-50 54t-46.5 64q-19 30 -27.5 56t-19.5 61q-4 14 -11.5 32.5t-9.5 32.5q-1 4 -3 22 t-4 38.5t-3.5 38.5t-2.5 23q0 3 -2 14t-4.5 23.5t-4.5 23.5t-2 14q-11 100 -13 199t-7 201v10q0 5 -0.5 15t-1.5 20t-1.5 18t-0.5 10q0 6 -2.5 26.5t-5.5 44.5t-5.5 44.5t-2.5 26.5q0 2 0.5 12t0.5 21.5t0.5 21.5t0.5 12q-2 50 -5.5 92t-6.5 87q0 3 2 15t0 14q0 2 -2 6t-2 6 q-8 31 -8.5 65t0.5 66z" />
<glyph unicode="&#xdc;" horiz-adv-x="1282" d="M573 1896v-18t-4 -19q-7 -14 -12 -26.5t-16 -24.5q-6 -7 -19 -16.5t-16 -12.5q-14 -13 -31 -13t-34 -1q-11 -1 -18 1t-18 7q-5 0 -13.5 4t-13.5 7q-26 16 -44.5 40t-21.5 57q0 20 0.5 34t4.5 26t13 23t24 24q14 13 34 23.5t38 11.5q5 1 17 0.5t15 -1.5q6 -1 18.5 -4 t14.5 -4q1 -1 6 -2.5t10.5 -3.5t10.5 -3.5t7 -2.5q28 -21 37 -45t11 -61zM884 1893q0 -8 0.5 -17.5t-3.5 -19.5q-7 -14 -12 -26t-16 -24q-3 -3 -8 -7.5t-10 -8.5l-10 -8t-6 -5q-14 -13 -31.5 -13t-34.5 -1q-11 -1 -17.5 1.5t-17.5 5.5q-5 1 -14 5t-14 8q-26 15 -44 38.5 t-23 56.5q0 20 1 34t5.5 26t13.5 23t24 25q13 13 33 23.5t38 11.5q4 1 17 0.5t16 -1.5q5 -1 17.5 -4.5t15.5 -3.5q1 -1 5.5 -3t10 -3.5t10.5 -3t7 -2.5q28 -22 37.5 -45.5t9.5 -61.5zM60 1661q1 19 8 34.5t29 17.5q28 -2 57 -6.5t57 -7.5t53.5 -2.5t45.5 9.5q3 0 16.5 -0.5 t29 -1.5t28.5 -1.5t16 -0.5q2 0 5 1q2 0 3.5 0.5t2.5 0.5q15 -2 21 -14.5t12 -28.5q1 -8 1.5 -16t-0.5 -16q-1 -27 -2 -49t-2.5 -43.5t-2.5 -44t-2 -49.5q-2 -52 -0.5 -112t6.5 -113q0 -3 0.5 -14t1 -23t1 -22.5t0.5 -12.5v-7t-0.5 -10.5l-1 -11t-0.5 -6.5q0 -2 0.5 -7.5 t1 -12.5t1.5 -14t1 -11q11 -93 25 -182t31 -182q1 -2 2 -7.5t2.5 -12.5t3 -13t2.5 -7q0 -1 0.5 -5.5t1.5 -9.5t2 -9t1 -5v-6t1 -8t2 -9l16 -58q2 -14 6 -32.5t9.5 -37.5t12.5 -36t15 -28q23 -35 58 -50.5t73 1.5h4q1 1 6 3q2 1 5 2q4 3 12.5 11t17.5 16.5t17.5 16t11.5 10.5 q2 2 7 7.5t7 10.5q25 39 47 91t28 100q1 12 3 34t3.5 44.5t3.5 41t3 24.5v8.5t0.5 16.5t1 18.5t0.5 14.5q2 60 -2.5 119.5t-6.5 118.5v16.5t-0.5 29t-1 29t-1.5 17.5q0 9 -1.5 32t-3 49t-3.5 48.5t-3 31.5q0 4 -2 21.5t-4.5 37t-4.5 36t-2 20.5q0 3 -3.5 28.5t-7.5 59 t-7.5 68.5t-3.5 58v4q0 2 0.5 3.5t0.5 2.5q0 7 -1.5 10t-1.5 4.5t2 2.5t9 4q58 4 122 6.5t121 -0.5q10 -2 23.5 -1.5t27 0.5t24 -1.5t15.5 -6.5q4 -5 11 -6.5t13 -3t10.5 -3.5t5.5 -7q4 -21 6 -38.5t3 -34t2 -34t2 -39.5v-29q1 -3 2.5 -15t1.5 -15q-5 -8 -4.5 -28t2.5 -43 t5 -42.5t3 -25.5q-2 -39 -4.5 -79.5t-4.5 -79.5t-4.5 -75.5t-3.5 -66.5q0 -3 -0.5 -19t-1 -34.5t-1 -34.5t-0.5 -19q-1 -4 -1.5 -14t-1 -21t-0.5 -21v-14l-5 -12l-31 -393q-14 -77 -37 -135t-56 -102t-76.5 -76.5t-98.5 -57.5q-21 -6 -42.5 -15.5t-43.5 -18.5t-44.5 -15.5 t-43.5 -5.5q-32 -5 -55 -7t-42 -2.5t-35 1.5t-34 6q-34 5 -67.5 9.5t-65.5 22.5q-38 19 -68.5 40.5t-57 46.5t-50 54t-46.5 64q-19 30 -27.5 56t-19.5 61q-4 14 -11.5 32.5t-9.5 32.5q-1 4 -3 22t-4 38.5t-3.5 38.5t-2.5 23q0 3 -2 14t-4.5 23.5t-4.5 23.5t-2 14 q-11 100 -13 199t-7 201v10q0 5 -0.5 15t-1.5 20t-1.5 18t-0.5 10q0 6 -2.5 26.5t-5.5 44.5t-5.5 44.5t-2.5 26.5q0 2 0.5 12t0.5 21.5t0.5 21.5t0.5 12q-2 50 -5.5 92t-6.5 87q0 3 2 15t0 14q0 2 -2 6t-2 6q-8 31 -8.5 65t0.5 66z" />
<glyph unicode="&#xdd;" horiz-adv-x="1485" d="M886 1977q-12 -22 -19.5 -42t-19.5 -42q-15 -28 -29 -56.5t-30 -57.5q-3 -5 -6.5 -12.5t-7 -14t-6.5 -11.5l-3 -5l-10 -5q-1 0 -8.5 -0.5t-11.5 -0.5q-14 1 -24 4t-20 6.5l-20 7t-24 5.5q-1 0 -6 1.5t-11 3t-11 3t-6 1.5q-12 -3 -13.5 6.5t-0.5 21.5q0 3 1 5q0 2 1 3 l6 12t7 12q9 18 13 32.5t17 31.5q0 3 3 6q0 1 2.5 8t5.5 14.5t5.5 14t3.5 8.5t6.5 11.5t12.5 20t12.5 20t6.5 11.5q0 1 1.5 4t2.5 3q2 5 10 7.5t13 2.5h1q2 0 8 -2t8 -2q1 0 7 -0.5t12.5 -1.5t12 -1.5t7.5 -0.5t7.5 -1.5t6.5 -2.5q2 0 14 -1t17 -2h2h1h11t11 -1 q1 0 5.5 -0.5t9.5 -1.5t9 -3.5t5 -6.5l3 -6q-1 0 -1 -1v-2v-3v0zM528 39q7 32 5 55t-2 55q0 74 3.5 152.5t-2.5 150.5q0 5 0.5 23t1.5 38.5t1.5 38t0.5 22.5q0 2 -1 18.5t-1 24.5q0 47 2.5 98t2.5 99v2q-2 3 -11 12.5t-11 11.5t-6.5 11.5t-6.5 11.5q-48 77 -98.5 158.5 t-92.5 163.5q-5 7 -16.5 24.5t-24.5 36.5t-24.5 36t-15.5 24q-14 29 -28 63t-37 57q-4 8 -12.5 22.5t-18 30t-18 29t-12.5 21.5q-11 25 -23.5 54t-21.5 55v4q0 14 7.5 21t17.5 9.5t17.5 2.5h7.5q3 1 17 1h30.5t30.5 -0.5t18 -0.5t17.5 2t32 4t39 5t38.5 5l31.5 3.5t17.5 2.5 q21 0 27.5 -4.5t13.5 -13.5q9 -15 20 -30.5t22.5 -32t21.5 -33t17 -31.5q23 -53 42.5 -96.5t46.5 -93.5q3 -4 11.5 -19t18.5 -33t19 -33t11 -19q6 -11 12 -27.5t13 -33t15.5 -31.5t18.5 -22q1 1 5 10.5t8.5 20.5t8.5 20t5 11q2 5 12 23t21.5 38t21.5 37.5t12 22.5q2 2 9 12 t15 22l15 22.5l9 13.5q1 1 2.5 5t3 8.5t3 8.5t1.5 6q1 3 5 11.5t8.5 18t8.5 17.5t6 11q-5 12 3.5 19.5t15.5 15.5q11 12 18 29.5t17 31.5q1 3 8 12.5t14.5 20t14 19.5t8.5 12q9 13 16 22t15 14.5t19 8t28 2.5q22 0 41.5 -2.5t39 -6t39 -7.5t42.5 -6q22 -1 47.5 -1t50 -2.5 t46 -9.5t34.5 -20q5 -6 5.5 -11t0.5 -11v-6q-41 -86 -87 -162t-94 -150t-97 -149t-95 -158q-2 -3 -9.5 -16t-9.5 -16q-17 -24 -30.5 -45.5t-26 -43t-24.5 -44.5t-25 -49q-5 0 -5.5 -8t0 -17.5t2 -19t1.5 -12.5q0 -5 0.5 -14.5t0.5 -18.5t0.5 -16t0.5 -8q0 -3 0.5 -11 t1.5 -18l2 -20t2 -15q4 -33 3.5 -81.5t-1 -100t0 -99.5t6.5 -80l-8 -132q1 -3 1.5 -9.5t1.5 -14t1.5 -14t1.5 -9.5v-8q0 -8 -5.5 -12.5t-13 -7.5t-15.5 -4.5t-13 -2.5q-4 0 -17.5 -1t-29 -2.5t-29 -2.5t-17.5 -1q-8 0 -27.5 -0.5t-40.5 -1.5t-39.5 -1.5t-25.5 -0.5 q-26 -3 -54 -1.5t-56 1.5q-8 0 -14 9.5t-6 17.5v2z" />
<glyph unicode="&#xde;" horiz-adv-x="1537" d="M803 11q-13 4 -28.5 11t-31.5 15.5t-30.5 16.5t-26.5 15q-1 1 -5.5 4.5t-10.5 8t-12 9.5t-9 8q-11 7 -16 13t-9.5 12t-11 11t-19.5 9q0 -2 -1.5 -6.5t-1.5 -6.5q-1 -2 -1.5 -7t-1 -11.5t-1 -12t-0.5 -8.5q-1 -4 -3 -25.5t-4.5 -46.5t-4 -46.5t-1.5 -25.5l-11 -13 l-233 -13q-9 5 -18 5t-19 -1l-65 6q-14 -2 -25 -2.5t-21 0.5t-20 4t-23 7q-3 1 -8.5 4.5t-8.5 5.5q-5 2 -11 9.5t-7 12.5q-4 16 -3 43t3 56.5t4.5 56.5t1.5 43q0 6 -0.5 15t-0.5 17.5t-0.5 15t-0.5 7.5l16 470v6q3 65 7 133.5t6 133.5q0 7 -0.5 33t-0.5 55.5t0.5 55.5 t0.5 33q0 18 0.5 23t1 3.5t0.5 -5.5v-5t-0.5 5t-1.5 25q0 3 -0.5 10.5t-1 15.5t-1 15.5t-0.5 9.5v54v77.5t0.5 76.5t2.5 52q3 10 9 12t14 2q12 1 23 -2t24 -2q26 2 51 7.5t50 8.5q37 5 65.5 4.5t62.5 1.5h16q4 0 9 1q25 9 36.5 -4t16 -36.5t5 -51.5t3.5 -50v-10q0 -4 1 -7 l-12 -64l4 -127q19 15 39.5 37t45 43.5t55 39t69.5 24.5q44 14 83.5 20.5t87.5 8.5q79 1 157 -26.5t161 -70.5q8 -7 25.5 -22t37 -31t36.5 -30t23 -19q23 -23 42.5 -44.5t36 -44t30.5 -47.5t27 -54q7 -18 14.5 -41.5t13 -48.5t9 -50t4.5 -46q1 -24 0.5 -43t-2.5 -37 t-4.5 -36.5t-5.5 -42.5q-22 -151 -86.5 -281t-184.5 -227q-29 -24 -56 -41.5t-55.5 -30.5t-60 -22.5t-68.5 -15.5q-2 0 -8.5 -0.5t-9.5 -0.5q-5 -1 -13 -1h-10q-8 0 -29 0.5t-44 1t-43.5 1.5t-27.5 2zM560 614q0 -3 3 -14.5t5 -13.5q9 -34 22 -60.5t31 -48.5t41 -41t52 -38 q23 -14 48 -27t53 -15q2 0 15.5 -2t23.5 -1q0 -2 8.5 0t20 5.5l23 7t17.5 5.5q40 22 67 45.5t54 61.5q4 5 11.5 16.5t15 24.5t13.5 24.5t7 16.5q2 5 6 17.5t8 27t7.5 26.5t3.5 17q1 1 1 11.5v25t0.5 30t0.5 25.5q-1 1 -1 3v5v8l-2.5 15t-2.5 18t-2 16t-2 9q0 2 -2.5 5.5 t-4.5 5.5q-1 1 -4.5 4t-7.5 6.5t-7.5 7l-4.5 4.5q0 2 -0.5 11.5t-0.5 12.5l-2 4q-1 2 -2.5 3.5l-2.5 2.5q-3 3 -13.5 14t-15.5 13q4 11 -6 18t-18 6q-37 24 -66.5 40t-60.5 23.5t-69.5 5t-93.5 -15.5q-47 -20 -79.5 -63t-52.5 -95.5t-28 -108t-6 -100.5v-4z" />
<glyph unicode="&#xdf;" horiz-adv-x="1173" d="M408 716v-6t2 -6q0 -2 1.5 -11.5t1.5 -11.5v-10t-0.5 -16.5t-1 -16.5t-0.5 -10q0 -20 6.5 -42t8.5 -44q0 -2 0.5 -16.5t1.5 -33l2 -37t1 -28.5v-13q1 0 -0.5 -28.5t-4 -70.5t-5.5 -90.5t-5.5 -90.5t-4 -70.5t-0.5 -28.5v-2q-1 -7 -4 -12t-3 -11l-251 -27q-13 -3 -19.5 2 t-21.5 6q-8 0 -11.5 -0.5t-8.5 7.5q-2 3 -6 12t-4 11q-2 2 -0.5 14t1.5 14q-3 3 -10.5 8.5t-12.5 5.5v2v4q7 14 10 24t4 27q1 11 1 20.5t-5 18.5q5 77 3 153.5t3 151.5l-5 12l8 195l-4 12q0 7 0.5 24.5t1.5 36.5t2 36t1 24q-1 6 -2 30.5t-1.5 53t-1 53t-0.5 31.5v30.5 t0.5 55t0.5 68.5t0.5 72t0.5 65v48q0 2 0.5 10.5t0.5 18.5t0.5 18t0.5 10q3 66 -1.5 130t-4.5 130v8v6t1 5q0 15 4.5 19t11 4.5t13.5 1.5t13 12q53 -1 99.5 0.5t91 2.5t89 0.5t93.5 -5.5q61 -3 128.5 -8.5t132.5 -22t121.5 -47t95.5 -82.5q13 -18 25 -43.5t21.5 -54 t16 -56.5t10.5 -50v-13.5t1 -17.5t1 -16.5v-9.5t-2 -12.5t-4 -24.5t-4.5 -28t-3.5 -21q-10 -48 -37 -84.5t-56 -73.5q-4 -6 -14.5 -18t-22 -25t-21.5 -24.5t-14 -15.5q0 -2 -1 -4q0 -6 12.5 -10t15.5 -6q32 -21 54.5 -41.5t44.5 -49.5q3 -4 7 -4.5l8 -1l8 -1t7 -4.5 q0 -3 2 -12.5t2 -11.5q3 -8 10 -15t14.5 -13t13 -11t7.5 -9q0 -2 -0.5 -11t-0.5 -11q0 -9 5.5 -14t11.5 -9t10.5 -9t4.5 -12v-4q-2 -2 -6.5 -8.5t-6.5 -8.5v-4v-2q2 -5 7.5 -17t7.5 -17q2 -9 6.5 -31.5t9 -47.5t8 -47.5t4.5 -31.5q1 -1 2 -6t2 -11t1.5 -11.5t0.5 -6.5l5 -4 v-12q0 -2 -0.5 -6.5t-0.5 -6.5t-6 -13.5t-8 -14.5q0 -1 -1 -5.5t-1.5 -10.5t-1.5 -11.5t-1 -6.5q-17 -68 -57 -120.5t-91 -97.5q-2 -1 -6.5 -4t-9 -6.5t-9 -6.5t-5.5 -4q-22 -13 -48 -19.5t-46 -23.5q-7 -2 -25 -5.5t-38 -7t-38.5 -7t-26.5 -4.5q-27 -4 -57.5 -8t-62 -6.5 t-62 -1.5t-56.5 7q-7 2 -9.5 23.5t-2.5 53t3.5 68t9.5 68t14.5 52t19.5 20.5q3 0 11 -0.5t10 -0.5q32 0 77 17t84 46.5t62.5 68t13.5 81.5q1 20 -3.5 36.5t-16.5 33.5q-22 34 -50 54t-60 32t-67 18.5t-72 13.5q-1 0 -3.5 0.5t-5 7.5t-5.5 24.5t-4 51.5t-1 87.5t4 134.5 q2 1 10.5 5.5t18.5 10.5t18.5 11t10.5 7q3 1 11 5.5t17.5 9.5t18 9.5t12.5 7.5q12 6 29.5 17t34 24.5t28.5 28.5t12 30q1 6 0 11t-7 10q-29 36 -58 61.5t-62 42t-71 25t-84 10.5q-3 0 -10 -1.5t-9 -3.5v-17q-2 -38 2 -73t10 -71q2 -22 2 -44t4 -42z" />
<glyph unicode="&#xe0;" horiz-adv-x="1470" d="M578 1686v3l3 6q1 4 5 6t9 3t9.5 1.5t6.5 0.5h22h1h2q5 0 17 1t14 1q1 1 6.5 2.5t7.5 1.5t7.5 0.5t12 1t12 1t7.5 0.5t8 1.5t8 1.5h1q5 0 13 -2.5t10 -7.5q1 0 2 -3.5t1 -4.5q1 -2 6 -11.5t11 -20t11 -20t6 -11.5t3.5 -8.5t5 -14t4.5 -14.5t2 -8q3 -3 3 -6 q11 -18 14 -32.5t11 -32.5q2 -2 6.5 -12.5t5.5 -12.5v-3q0 -2 0.5 -3t0.5 -2q0 -12 -2 -21.5t-14 -5.5q-1 0 -6 -1.5t-11 -3t-11 -2.5t-6 -1q-14 -2 -25 -5.5t-20.5 -7t-20 -6t-24.5 -2.5q-4 0 -11.5 0.5t-8.5 0.5l-9 6l-2.5 4.5t-5.5 11.5t-6.5 14t-6.5 12 q-14 29 -25.5 58.5t-25.5 57.5q-11 23 -17 43t-17 43v3zM1031 6q-12 7 -10.5 20t0.5 25q0 2 -3 6t-3 6v9q0 14 6 25t6 24v6q-3 0 -9.5 -2t-8.5 -4q-7 -5 -22.5 -15t-33.5 -21t-35 -20t-26 -10l-78 -32h-6q-2 0 -7 -1t-10.5 -2.5t-11 -2.5t-6.5 -1h-61h-34t-28.5 1t-28 2 t-32.5 4q-2 1 -10.5 3t-18 4t-18 3.5t-10.5 1.5h-52l-33 13q-7 3 -21.5 11t-31 17t-31.5 17t-22 11q-6 3 -18 8.5t-24.5 12t-23.5 11.5t-14 7q-1 1 -5 4.5t-9.5 8.5t-11 9.5t-8.5 6.5q-25 25 -48 55t-46 57q-21 25 -35 66t-23 86.5t-13 89.5t-4 76q0 41 0.5 76t4 68.5 t10.5 67.5t20 73q1 6 7.5 25.5t13.5 39t12 31.5t4 1q16 46 42 85.5t59 73.5t71.5 63t79.5 54q4 3 18.5 10.5t31 15.5t32 15.5t21.5 9.5q1 1 6.5 2.5t13 3.5t15 3.5l12.5 2.5q6 2 16 4t12 2h197q35 -10 68 -18.5t63.5 -21t59 -30t55.5 -45.5h4q0 3 0.5 8.5t0.5 11.5t0.5 11.5 t0.5 7.5q0 1 1 7t2.5 13t3 12.5t1.5 6.5q-5 7 -1 14.5t11.5 12.5t16.5 6.5t15 -2.5q50 0 88 -0.5t74 -2t74.5 -5.5t88.5 -10q3 -2 10 -5.5t7 -8.5q0 -9 1 -22t2 -27.5t2 -28t0 -23.5q0 -2 -1 -12t-2 -22t-2 -22t-1 -12q0 -3 -3 -14.5t-3 -13.5q0 -3 0.5 -12.5t0.5 -20v-20 t-1 -11.5q0 -3 -2 -9t-4 -9l-2 -236v-16v-44t0.5 -94.5t1.5 -125.5t2 -137.5t2 -129.5t3 -102q0 -3 -1.5 -15.5t-3 -27.5t-3 -27.5t-0.5 -15.5v-8v-8q-2 -3 -13.5 -7t-13.5 -6q-27 0 -46.5 -2t-37 -4.5t-36 -4.5t-45.5 -1h-47q-7 0 -23.5 0.5t-35 1.5t-35 2t-23.5 2z M440 664q0 -53 17.5 -98t45.5 -89q2 -3 6 -9.5t6 -6.5q24 -26 49.5 -50t54 -42.5t60.5 -29.5t70 -11q32 0 65 11t62 23q4 2 11.5 5.5l15 7t13 6.5t7.5 4q37 28 61 66.5t38.5 82t20 90t7.5 89.5q0 5 -0.5 17t-1.5 25t-2 24.5t-2 15.5l-9 18q-4 8 -8 15t-6 12 q-20 38 -40.5 73.5t-54.5 56.5l-18 13.5t-21.5 15t-22.5 14t-20 8.5q-4 1 -14.5 4t-22.5 6t-22.5 5t-14.5 3q-6 9 -18 10.5t-26.5 0t-28.5 -4.5t-23 -3q-15 0 -32 -5.5t-32.5 -14.5t-30 -20t-25.5 -23q-2 -2 -8.5 -10t-14 -16.5t-14.5 -16.5t-8 -10q-38 -42 -53 -99 q-9 -40 -12.5 -80.5t-3.5 -82.5z" />
<glyph unicode="&#xe1;" horiz-adv-x="1470" d="M859 1644q-12 -22 -19.5 -42t-19.5 -42q-15 -28 -29 -56.5t-30 -57.5q-3 -5 -6.5 -12.5t-7 -14t-6.5 -11.5l-3 -5l-10 -5q-1 0 -8.5 -0.5t-11.5 -0.5q-14 1 -24 4t-20 6.5l-20 7t-24 5.5q-1 0 -6 1.5t-11 3t-11 3t-6 1.5q-12 -3 -13.5 6.5t-0.5 21.5q0 3 1 5q0 2 1 3 l6 12t7 12q9 18 13 32.5t17 31.5q0 3 3 6q0 1 2.5 8t5.5 14.5t5.5 14t3.5 8.5t6.5 11.5t12.5 20t12.5 20t6.5 11.5q0 1 1.5 4t2.5 3q2 5 10 7.5t13 2.5h1q2 0 8 -2t8 -2q1 0 7 -0.5t12.5 -1.5t12 -1.5t7.5 -0.5t7.5 -1.5t6.5 -2.5q2 0 14 -1t17 -2h2h1h11t11 -1 q1 0 5.5 -0.5t9.5 -1.5t9 -3.5t5 -6.5l3 -6q-1 0 -1 -1v-2v-3v0zM1031 6q-12 7 -10.5 20t0.5 25q0 2 -3 6t-3 6v9q0 14 6 25t6 24v6q-3 0 -9.5 -2t-8.5 -4q-7 -5 -22.5 -15t-33.5 -21t-35 -20t-26 -10l-78 -32h-6q-2 0 -7 -1t-10.5 -2.5t-11 -2.5t-6.5 -1h-61h-34t-28.5 1 t-28 2t-32.5 4q-2 1 -10.5 3t-18 4t-18 3.5t-10.5 1.5h-52l-33 13q-7 3 -21.5 11t-31 17t-31.5 17t-22 11q-6 3 -18 8.5t-24.5 12t-23.5 11.5t-14 7q-1 1 -5 4.5t-9.5 8.5t-11 9.5t-8.5 6.5q-25 25 -48 55t-46 57q-21 25 -35 66t-23 86.5t-13 89.5t-4 76q0 41 0.5 76t4 68.5 t10.5 67.5t20 73q1 6 7.5 25.5t13.5 39t12 31.5t4 1q16 46 42 85.5t59 73.5t71.5 63t79.5 54q4 3 18.5 10.5t31 15.5t32 15.5t21.5 9.5q1 1 6.5 2.5t13 3.5t15 3.5l12.5 2.5q6 2 16 4t12 2h197q35 -10 68 -18.5t63.5 -21t59 -30t55.5 -45.5h4q0 3 0.5 8.5t0.5 11.5t0.5 11.5 t0.5 7.5q0 1 1 7t2.5 13t3 12.5t1.5 6.5q-5 7 -1 14.5t11.5 12.5t16.5 6.5t15 -2.5q50 0 88 -0.5t74 -2t74.5 -5.5t88.5 -10q3 -2 10 -5.5t7 -8.5q0 -9 1 -22t2 -27.5t2 -28t0 -23.5q0 -2 -1 -12t-2 -22t-2 -22t-1 -12q0 -3 -3 -14.5t-3 -13.5q0 -3 0.5 -12.5t0.5 -20v-20 t-1 -11.5q0 -3 -2 -9t-4 -9l-2 -236v-16v-44t0.5 -94.5t1.5 -125.5t2 -137.5t2 -129.5t3 -102q0 -3 -1.5 -15.5t-3 -27.5t-3 -27.5t-0.5 -15.5v-8v-8q-2 -3 -13.5 -7t-13.5 -6q-27 0 -46.5 -2t-37 -4.5t-36 -4.5t-45.5 -1h-47q-7 0 -23.5 0.5t-35 1.5t-35 2t-23.5 2z M440 664q0 -53 17.5 -98t45.5 -89q2 -3 6 -9.5t6 -6.5q24 -26 49.5 -50t54 -42.5t60.5 -29.5t70 -11q32 0 65 11t62 23q4 2 11.5 5.5l15 7t13 6.5t7.5 4q37 28 61 66.5t38.5 82t20 90t7.5 89.5q0 5 -0.5 17t-1.5 25t-2 24.5t-2 15.5l-9 18q-4 8 -8 15t-6 12 q-20 38 -40.5 73.5t-54.5 56.5l-18 13.5t-21.5 15t-22.5 14t-20 8.5q-4 1 -14.5 4t-22.5 6t-22.5 5t-14.5 3q-6 9 -18 10.5t-26.5 0t-28.5 -4.5t-23 -3q-15 0 -32 -5.5t-32.5 -14.5t-30 -20t-25.5 -23q-2 -2 -8.5 -10t-14 -16.5t-14.5 -16.5t-8 -10q-38 -42 -53 -99 q-9 -40 -12.5 -80.5t-3.5 -82.5z" />
<glyph unicode="&#xe2;" horiz-adv-x="1470" d="M526 1415q-22 4 -25 10t-6 8v1v1q5 13 14.5 27.5t16.5 25.5q4 7 11 18t14.5 24t14 26.5t11.5 25.5q6 8 9.5 16.5t7.5 17.5q11 27 17.5 39t15.5 22q1 1 5 2.5t6 1.5q4 0 16.5 0.5t26 1t25.5 0.5h17h42q1 0 5.5 0.5t9.5 1.5t9.5 1.5t5.5 0.5h5q7 1 10 -0.5t4 -4t1 -6 t2 -5.5q1 -1 2.5 -5.5t1.5 -5.5q1 -2 3.5 -5.5t3.5 -3.5q-4 4 2 -10.5t15.5 -36t20.5 -44t18 -35.5q4 -5 4 -11.5t2 -11.5q4 -10 8 -19.5t9 -20.5q2 -4 7.5 -12t5.5 -14q0 -2 -2.5 -5.5t-4.5 -4.5h-16q-1 0 -3.5 -1.5t-3.5 -1.5t-13.5 -1t-19.5 -1q-26 -2 -48 -9 q-13 -2 -25 -5.5t-25 -3.5q-8 0 -16.5 0.5t-13.5 6.5q-8 14 -12.5 28.5t-14.5 26.5q-2 -2 -3 -3.5t-3 -3.5q-1 -4 -7 -14.5t-8 -12.5q-1 -2 -4.5 -7.5t-9 -11t-12 -9t-13.5 -1.5h-4h-16.5h-12.5t-12.5 1t-15.5 3q-3 1 -11 2t-17 2.5t-16.5 3t-10.5 1.5zM1031 6 q-12 7 -10.5 20t0.5 25q0 2 -3 6t-3 6v9q0 14 6 25t6 24v6q-3 0 -9.5 -2t-8.5 -4q-7 -5 -22.5 -15t-33.5 -21t-35 -20t-26 -10l-78 -32h-6q-2 0 -7 -1t-10.5 -2.5t-11 -2.5t-6.5 -1h-61h-34t-28.5 1t-28 2t-32.5 4q-2 1 -10.5 3t-18 4t-18 3.5t-10.5 1.5h-52l-33 13 q-7 3 -21.5 11t-31 17t-31.5 17t-22 11q-6 3 -18 8.5t-24.5 12t-23.5 11.5t-14 7q-1 1 -5 4.5t-9.5 8.5t-11 9.5t-8.5 6.5q-25 25 -48 55t-46 57q-21 25 -35 66t-23 86.5t-13 89.5t-4 76q0 41 0.5 76t4 68.5t10.5 67.5t20 73q1 6 7.5 25.5t13.5 39t12 31.5t4 1 q16 46 42 85.5t59 73.5t71.5 63t79.5 54q4 3 18.5 10.5t31 15.5t32 15.5t21.5 9.5q1 1 6.5 2.5t13 3.5t15 3.5l12.5 2.5q6 2 16 4t12 2h197q35 -10 68 -18.5t63.5 -21t59 -30t55.5 -45.5h4q0 3 0.5 8.5t0.5 11.5t0.5 11.5t0.5 7.5q0 1 1 7t2.5 13t3 12.5t1.5 6.5 q-5 7 -1 14.5t11.5 12.5t16.5 6.5t15 -2.5q50 0 88 -0.5t74 -2t74.5 -5.5t88.5 -10q3 -2 10 -5.5t7 -8.5q0 -9 1 -22t2 -27.5t2 -28t0 -23.5q0 -2 -1 -12t-2 -22t-2 -22t-1 -12q0 -3 -3 -14.5t-3 -13.5q0 -3 0.5 -12.5t0.5 -20v-20t-1 -11.5q0 -3 -2 -9t-4 -9l-2 -236v-16 v-44t0.5 -94.5t1.5 -125.5t2 -137.5t2 -129.5t3 -102q0 -3 -1.5 -15.5t-3 -27.5t-3 -27.5t-0.5 -15.5v-8v-8q-2 -3 -13.5 -7t-13.5 -6q-27 0 -46.5 -2t-37 -4.5t-36 -4.5t-45.5 -1h-47q-7 0 -23.5 0.5t-35 1.5t-35 2t-23.5 2zM440 664q0 -53 17.5 -98t45.5 -89q2 -3 6 -9.5 t6 -6.5q24 -26 49.5 -50t54 -42.5t60.5 -29.5t70 -11q32 0 65 11t62 23q4 2 11.5 5.5l15 7t13 6.5t7.5 4q37 28 61 66.5t38.5 82t20 90t7.5 89.5q0 5 -0.5 17t-1.5 25t-2 24.5t-2 15.5l-9 18q-4 8 -8 15t-6 12q-20 38 -40.5 73.5t-54.5 56.5l-18 13.5t-21.5 15t-22.5 14 t-20 8.5q-4 1 -14.5 4t-22.5 6t-22.5 5t-14.5 3q-6 9 -18 10.5t-26.5 0t-28.5 -4.5t-23 -3q-15 0 -32 -5.5t-32.5 -14.5t-30 -20t-25.5 -23q-2 -2 -8.5 -10t-14 -16.5t-14.5 -16.5t-8 -10q-38 -42 -53 -99q-9 -40 -12.5 -80.5t-3.5 -82.5z" />
<glyph unicode="&#xe3;" horiz-adv-x="1470" d="M331 1500q0 1 -1.5 3.5t-1.5 3.5t3 5t5 5v5q12 32 37.5 56.5t48.5 49.5q2 1 8.5 8t8.5 8q29 30 67.5 53t80.5 23q18 0 33.5 -1.5t32.5 -9.5q10 -4 20.5 -10.5t21.5 -6.5l31 -22q4 -2 14.5 -8t22.5 -12t22.5 -11.5t14.5 -7.5q11 -6 19.5 -7t19.5 -1q15 0 34 13.5t28 26.5 q3 3 8 10t10.5 14.5t9.5 13.5t5 8q5 8 9 13t15 5h3q1 -1 6.5 -5.5t7.5 -6.5q14 -14 30 -26t30.5 -21.5t26.5 -17.5t20 -15q6 -7 12.5 -12t9.5 -10t2 -11t-8 -15q-9 -15 -18.5 -27.5t-20.5 -28.5q-20 -26 -41.5 -51.5t-47 -45.5t-55 -32t-64.5 -12q-9 -1 -26 3.5t-34.5 11.5 t-33.5 14t-24 12q-2 3 -11 12t-12 11q-17 14 -34 19.5t-40 5.5q-27 0 -51.5 -13t-42.5 -37q-7 -11 -12.5 -18.5t-12 -12.5t-15 -7.5t-22.5 -2.5q-3 0 -8 1t-7 1q-1 0 -6 4.5t-7 4.5q-2 2 -5.5 4t-4.5 4q-17 11 -29 18t-27 22q-1 0 -7 4q-3 2 -6 5q-3 2 -8.5 8.5t-12.5 13.5 t-12.5 13t-8.5 9zM1031 6q-12 7 -10.5 20t0.5 25q0 2 -3 6t-3 6v9q0 14 6 25t6 24v6q-3 0 -9.5 -2t-8.5 -4q-7 -5 -22.5 -15t-33.5 -21t-35 -20t-26 -10l-78 -32h-6q-2 0 -7 -1t-10.5 -2.5t-11 -2.5t-6.5 -1h-61h-34t-28.5 1t-28 2t-32.5 4q-2 1 -10.5 3t-18 4t-18 3.5 t-10.5 1.5h-52l-33 13q-7 3 -21.5 11t-31 17t-31.5 17t-22 11q-6 3 -18 8.5t-24.5 12t-23.5 11.5t-14 7q-1 1 -5 4.5t-9.5 8.5t-11 9.5t-8.5 6.5q-25 25 -48 55t-46 57q-21 25 -35 66t-23 86.5t-13 89.5t-4 76q0 41 0.5 76t4 68.5t10.5 67.5t20 73q1 6 7.5 25.5t13.5 39 t12 31.5t4 1q16 46 42 85.5t59 73.5t71.5 63t79.5 54q4 3 18.5 10.5t31 15.5t32 15.5t21.5 9.5q1 1 6.5 2.5t13 3.5t15 3.5l12.5 2.5q6 2 16 4t12 2h197q35 -10 68 -18.5t63.5 -21t59 -30t55.5 -45.5h4q0 3 0.5 8.5t0.5 11.5t0.5 11.5t0.5 7.5q0 1 1 7t2.5 13t3 12.5 t1.5 6.5q-5 7 -1 14.5t11.5 12.5t16.5 6.5t15 -2.5q50 0 88 -0.5t74 -2t74.5 -5.5t88.5 -10q3 -2 10 -5.5t7 -8.5q0 -9 1 -22t2 -27.5t2 -28t0 -23.5q0 -2 -1 -12t-2 -22t-2 -22t-1 -12q0 -3 -3 -14.5t-3 -13.5q0 -3 0.5 -12.5t0.5 -20v-20t-1 -11.5q0 -3 -2 -9t-4 -9 l-2 -236v-16v-44t0.5 -94.5t1.5 -125.5t2 -137.5t2 -129.5t3 -102q0 -3 -1.5 -15.5t-3 -27.5t-3 -27.5t-0.5 -15.5v-8v-8q-2 -3 -13.5 -7t-13.5 -6q-27 0 -46.5 -2t-37 -4.5t-36 -4.5t-45.5 -1h-47q-7 0 -23.5 0.5t-35 1.5t-35 2t-23.5 2zM440 664q0 -53 17.5 -98t45.5 -89 q2 -3 6 -9.5t6 -6.5q24 -26 49.5 -50t54 -42.5t60.5 -29.5t70 -11q32 0 65 11t62 23q4 2 11.5 5.5l15 7t13 6.5t7.5 4q37 28 61 66.5t38.5 82t20 90t7.5 89.5q0 5 -0.5 17t-1.5 25t-2 24.5t-2 15.5l-9 18q-4 8 -8 15t-6 12q-20 38 -40.5 73.5t-54.5 56.5l-18 13.5t-21.5 15 t-22.5 14t-20 8.5q-4 1 -14.5 4t-22.5 6t-22.5 5t-14.5 3q-6 9 -18 10.5t-26.5 0t-28.5 -4.5t-23 -3q-15 0 -32 -5.5t-32.5 -14.5t-30 -20t-25.5 -23q-2 -2 -8.5 -10t-14 -16.5t-14.5 -16.5t-8 -10q-38 -42 -53 -99q-9 -40 -12.5 -80.5t-3.5 -82.5z" />
<glyph unicode="&#xe4;" horiz-adv-x="1470" d="M679 1517v-18t-4 -19q-7 -14 -12 -26.5t-16 -24.5q-6 -7 -19 -16.5t-16 -12.5q-14 -13 -31 -13t-34 -1q-11 -1 -18 1t-18 7q-5 0 -13.5 4t-13.5 7q-26 16 -44.5 40t-21.5 57q0 20 0.5 34t4.5 26t13 23t24 24q14 13 34 23.5t38 11.5q5 1 17 0.5t15 -1.5q6 -1 18.5 -4 t14.5 -4q1 -1 6 -2.5t10.5 -3.5t10.5 -3.5t7 -2.5q28 -21 37 -45t11 -61zM990 1514q0 -8 0.5 -17.5t-3.5 -19.5q-7 -14 -12 -26t-16 -24q-3 -3 -8 -7.5t-10 -8.5l-10 -8t-6 -5q-14 -13 -31.5 -13t-34.5 -1q-11 -1 -17.5 1.5t-17.5 5.5q-5 1 -14 5t-14 8q-26 15 -44 38.5 t-23 56.5q0 20 1 34t5.5 26t13.5 23t24 25q13 13 33 23.5t38 11.5q4 1 17 0.5t16 -1.5q5 -1 17.5 -4.5t15.5 -3.5q1 -1 5.5 -3t10 -3.5t10.5 -3t7 -2.5q28 -22 37.5 -45.5t9.5 -61.5zM1031 6q-12 7 -10.5 20t0.5 25q0 2 -3 6t-3 6v9q0 14 6 25t6 24v6q-3 0 -9.5 -2t-8.5 -4 q-7 -5 -22.5 -15t-33.5 -21t-35 -20t-26 -10l-78 -32h-6q-2 0 -7 -1t-10.5 -2.5t-11 -2.5t-6.5 -1h-61h-34t-28.5 1t-28 2t-32.5 4q-2 1 -10.5 3t-18 4t-18 3.5t-10.5 1.5h-52l-33 13q-7 3 -21.5 11t-31 17t-31.5 17t-22 11q-6 3 -18 8.5t-24.5 12t-23.5 11.5t-14 7 q-1 1 -5 4.5t-9.5 8.5t-11 9.5t-8.5 6.5q-25 25 -48 55t-46 57q-21 25 -35 66t-23 86.5t-13 89.5t-4 76q0 41 0.5 76t4 68.5t10.5 67.5t20 73q1 6 7.5 25.5t13.5 39t12 31.5t4 1q16 46 42 85.5t59 73.5t71.5 63t79.5 54q4 3 18.5 10.5t31 15.5t32 15.5t21.5 9.5q1 1 6.5 2.5 t13 3.5t15 3.5l12.5 2.5q6 2 16 4t12 2h197q35 -10 68 -18.5t63.5 -21t59 -30t55.5 -45.5h4q0 3 0.5 8.5t0.5 11.5t0.5 11.5t0.5 7.5q0 1 1 7t2.5 13t3 12.5t1.5 6.5q-5 7 -1 14.5t11.5 12.5t16.5 6.5t15 -2.5q50 0 88 -0.5t74 -2t74.5 -5.5t88.5 -10q3 -2 10 -5.5t7 -8.5 q0 -9 1 -22t2 -27.5t2 -28t0 -23.5q0 -2 -1 -12t-2 -22t-2 -22t-1 -12q0 -3 -3 -14.5t-3 -13.5q0 -3 0.5 -12.5t0.5 -20v-20t-1 -11.5q0 -3 -2 -9t-4 -9l-2 -236v-16v-44t0.5 -94.5t1.5 -125.5t2 -137.5t2 -129.5t3 -102q0 -3 -1.5 -15.5t-3 -27.5t-3 -27.5t-0.5 -15.5v-8 v-8q-2 -3 -13.5 -7t-13.5 -6q-27 0 -46.5 -2t-37 -4.5t-36 -4.5t-45.5 -1h-47q-7 0 -23.5 0.5t-35 1.5t-35 2t-23.5 2zM440 664q0 -53 17.5 -98t45.5 -89q2 -3 6 -9.5t6 -6.5q24 -26 49.5 -50t54 -42.5t60.5 -29.5t70 -11q32 0 65 11t62 23q4 2 11.5 5.5l15 7t13 6.5t7.5 4 q37 28 61 66.5t38.5 82t20 90t7.5 89.5q0 5 -0.5 17t-1.5 25t-2 24.5t-2 15.5l-9 18q-4 8 -8 15t-6 12q-20 38 -40.5 73.5t-54.5 56.5l-18 13.5t-21.5 15t-22.5 14t-20 8.5q-4 1 -14.5 4t-22.5 6t-22.5 5t-14.5 3q-6 9 -18 10.5t-26.5 0t-28.5 -4.5t-23 -3q-15 0 -32 -5.5 t-32.5 -14.5t-30 -20t-25.5 -23q-2 -2 -8.5 -10t-14 -16.5t-14.5 -16.5t-8 -10q-38 -42 -53 -99q-9 -40 -12.5 -80.5t-3.5 -82.5z" />
<glyph unicode="&#xe5;" horiz-adv-x="1470" d="M707 1547q0 17 -4 27.5t-17 20.5q-2 0 -7.5 2t-7.5 3q-1 0 -6.5 1.5t-7.5 2.5h-16q-8 0 -16.5 -5.5t-14.5 -10.5q-14 -11 -17 -20.5t-3 -27.5q4 -27 31 -43q2 -2 5.5 -3.5t6.5 -1.5l7.5 -3t7.5 0h16t14 5q2 2 7.5 6t8.5 7q5 5 7 11t5 13q2 4 1.5 8t-0.5 8zM768 1540 q0 -8 -0.5 -15t-2.5 -15l-3 -11q-8 -17 -21 -35q-3 -3 -9.5 -8t-11.5 -9l-3 -3l-2 -2l-2 -2q-13 -14 -26 -16t-27 -2h-9q-9 -1 -15.5 0.5t-12.5 3.5l-5 1q-2 2 -0.5 0.5t-1.5 -0.5q-7 3 -16.5 8t-13.5 8q-24 14 -40 35t-19 52q0 18 1 32t5.5 25.5t13 22t22.5 22.5 q12 12 30.5 21.5t35.5 9.5h26q2 -1 5 -2q6 -2 9 -2l-2 1q2 -1 5 -1t6 -1q4 -1 7 -2q4 -2 15 -5.5t16 -4.5q29 -22 37.5 -44.5t8.5 -56.5v-5zM1031 6q-12 7 -10.5 20t0.5 25q0 2 -3 6t-3 6v9q0 14 6 25t6 24v6q-3 0 -9.5 -2t-8.5 -4q-7 -5 -22.5 -15t-33.5 -21t-35 -20 t-26 -10l-78 -32h-6q-2 0 -7 -1t-10.5 -2.5t-11 -2.5t-6.5 -1h-61h-34t-28.5 1t-28 2t-32.5 4q-2 1 -10.5 3t-18 4t-18 3.5t-10.5 1.5h-52l-33 13q-7 3 -21.5 11t-31 17t-31.5 17t-22 11q-6 3 -18 8.5t-24.5 12t-23.5 11.5t-14 7q-1 1 -5 4.5t-9.5 8.5t-11 9.5t-8.5 6.5 q-25 25 -48 55t-46 57q-21 25 -35 66t-23 86.5t-13 89.5t-4 76q0 41 0.5 76t4 68.5t10.5 67.5t20 73q1 6 7.5 25.5t13.5 39t12 31.5t4 1q16 46 42 85.5t59 73.5t71.5 63t79.5 54q4 3 18.5 10.5t31 15.5t32 15.5t21.5 9.5q1 1 6.5 2.5t13 3.5t15 3.5l12.5 2.5q6 2 16 4t12 2 h197q35 -10 68 -18.5t63.5 -21t59 -30t55.5 -45.5h4q0 3 0.5 8.5t0.5 11.5t0.5 11.5t0.5 7.5q0 1 1 7t2.5 13t3 12.5t1.5 6.5q-5 7 -1 14.5t11.5 12.5t16.5 6.5t15 -2.5q50 0 88 -0.5t74 -2t74.5 -5.5t88.5 -10q3 -2 10 -5.5t7 -8.5q0 -9 1 -22t2 -27.5t2 -28t0 -23.5 q0 -2 -1 -12t-2 -22t-2 -22t-1 -12q0 -3 -3 -14.5t-3 -13.5q0 -3 0.5 -12.5t0.5 -20v-20t-1 -11.5q0 -3 -2 -9t-4 -9l-2 -236v-16v-44t0.5 -94.5t1.5 -125.5t2 -137.5t2 -129.5t3 -102q0 -3 -1.5 -15.5t-3 -27.5t-3 -27.5t-0.5 -15.5v-8v-8q-2 -3 -13.5 -7t-13.5 -6 q-27 0 -46.5 -2t-37 -4.5t-36 -4.5t-45.5 -1h-47q-7 0 -23.5 0.5t-35 1.5t-35 2t-23.5 2zM440 664q0 -53 17.5 -98t45.5 -89q2 -3 6 -9.5t6 -6.5q24 -26 49.5 -50t54 -42.5t60.5 -29.5t70 -11q32 0 65 11t62 23q4 2 11.5 5.5l15 7t13 6.5t7.5 4q37 28 61 66.5t38.5 82t20 90 t7.5 89.5q0 5 -0.5 17t-1.5 25t-2 24.5t-2 15.5l-9 18q-4 8 -8 15t-6 12q-20 38 -40.5 73.5t-54.5 56.5l-18 13.5t-21.5 15t-22.5 14t-20 8.5q-4 1 -14.5 4t-22.5 6t-22.5 5t-14.5 3q-6 9 -18 10.5t-26.5 0t-28.5 -4.5t-23 -3q-15 0 -32 -5.5t-32.5 -14.5t-30 -20t-25.5 -23 q-2 -2 -8.5 -10t-14 -16.5t-14.5 -16.5t-8 -10q-38 -42 -53 -99q-9 -40 -12.5 -80.5t-3.5 -82.5z" />
<glyph unicode="&#xe6;" horiz-adv-x="2567" d="M1362 1107q3 4 8.5 10l11 12t10 11.5t7.5 8.5q1 1 4 5t6.5 9.5t6.5 9.5t5 5q42 36 92.5 65t105 50t111 32.5t111.5 12.5q62 5 129 -2t125 -33q49 -15 84.5 -34t60 -37t40.5 -32.5t28 -20.5q31 -27 56 -53t45.5 -54t38.5 -59.5t35 -70.5q3 -9 8.5 -32.5t11.5 -49.5 t11 -49.5t6 -32.5q1 -2 1.5 -9t0.5 -17v-19.5v-15.5t-0.5 -16.5t-0.5 -21v-18.5t-1 -9q0 -3 -3 -12.5t-6 -20t-5.5 -20t-2.5 -11.5q-20 -20 -40.5 -27.5t-48 -9.5t-66 -2.5t-93.5 -6.5h-19h-33t-33 -0.5t-19 -0.5h-10q-2 -2 -8.5 -3t-13.5 -0.5t-12.5 2.5t-6.5 6 q-1 0 -9 -0.5t-17.5 -0.5h-19t-12.5 1q-1 -1 -3 -1h-5q-24 -1 -55 -2t-63.5 -2t-63.5 -1.5t-55 -0.5q-36 -2 -64.5 -0.5t-55 3t-55 2.5t-64.5 0q-5 0 -10 -0.5t-7 -5.5q0 -5 2.5 -15t2.5 -13q9 -36 12.5 -51.5t6.5 -22t7.5 -11t14.5 -18.5q0 -1 3.5 -4.5t8 -7.5t8 -7.5 t3.5 -4.5q33 -53 87 -76.5t111 -21.5q8 0 22 0.5t16 0.5q19 2 28.5 1.5t15.5 -1.5t12.5 -1.5t21 1.5t40 7.5t70.5 16.5q1 0 11 5t21.5 11t22 11.5t12.5 6.5q26 16 47 31.5t38.5 28.5t33 23t30.5 16h6q2 1 6 -1.5t4 -4.5q9 -8 27 -20.5t36.5 -25.5t35.5 -25.5t25 -21.5 q3 -2 14 -10t23 -17.5t21 -18t9 -9.5v-4q0 -2 0.5 -3t0.5 -3q1 -25 -14.5 -44t-32.5 -37q-47 -51 -99.5 -99.5t-114.5 -80.5q-20 -9 -40 -13.5t-40 -11.5q-26 -8 -50 -11.5t-47 -4.5t-47.5 -0.5t-52.5 -0.5q-72 -2 -137 5t-134 27q-26 8 -48 17.5t-41.5 21t-38.5 26 t-39 31.5q-32 27 -65 52.5t-62 57.5q2 -29 4.5 -45t3.5 -24q0 -3 -1.5 -15.5t-3 -27.5t-3 -27.5t-0.5 -15.5v-16q-2 -3 -13.5 -7t-13.5 -6q-27 0 -46.5 -2t-37 -4.5t-36 -4.5t-45.5 -1h-47q-7 0 -23.5 0.5t-35 1.5t-35 2t-23.5 2q-12 7 -10.5 20t0.5 25q0 2 -3 6t-3 6v9 q0 14 6 25t6 24v6q-3 0 -9.5 -2t-8.5 -4q-7 -5 -22.5 -15t-33.5 -21t-35 -20t-26 -10l-78 -32h-6q-2 0 -7 -1t-10.5 -2.5t-11 -2.5t-6.5 -1h-61h-34t-28.5 1t-28 2t-32.5 4q-2 1 -10.5 3t-18 4t-18 3.5t-10.5 1.5h-52l-33 13q-7 3 -21.5 11t-31 17t-31.5 17t-22 11 q-6 3 -18 8.5t-24.5 12t-23.5 11.5t-14 7q-1 1 -5 4.5t-9.5 8.5t-11 9.5t-8.5 6.5q-25 25 -48 55t-46 57q-21 25 -35 66t-23 86.5t-13 89.5t-4 76q0 41 0.5 76t4 68.5t10.5 67.5t20 73q1 6 7.5 25.5t13.5 39t12 31.5t4 1q16 46 42 85.5t59 73.5t71.5 63t79.5 54 q4 3 18.5 10.5t31 15.5t32 15.5t21.5 9.5q1 1 6.5 2.5t13 3.5t15 3.5l12.5 2.5q6 2 16 4t12 2h197q35 -10 68 -18.5t63.5 -21t59 -30t55.5 -45.5h4q0 3 0.5 8.5t0.5 11.5t0.5 11.5t0.5 7.5q0 1 1 7t2.5 13t3 12.5t1.5 6.5q-5 7 -1 14.5t11.5 12.5t16.5 6.5t15 -2.5 q50 0 88 -0.5t74 -2t74.5 -5.5t88.5 -10q3 -2 10 -5.5t7 -8.5q0 -9 1 -22t2 -27.5t2 -28t0 -23.5q0 -2 -1 -12t-2 -22t-2 -22t-1 -12q0 -3 -3 -14.5t-3 -13.5v-5zM408 682q0 -53 17.5 -98t45.5 -89q2 -3 6 -9.5t6 -6.5q24 -26 49.5 -50t54 -42.5t60.5 -29.5t70 -11 q32 0 65 11t62 23q4 2 11.5 5.5l15 7t13 6.5t7.5 4q37 28 61 66.5t38.5 82t20 90t7.5 89.5q0 5 -0.5 17t-1.5 25t-2 24.5t-2 15.5l-9 18q-4 8 -8 15t-6 12q-20 38 -40.5 73.5t-54.5 56.5l-18 13.5t-21.5 15t-22.5 14t-20 8.5q-4 1 -14.5 4t-22.5 6t-22.5 5t-14.5 3 q-6 9 -18 10.5t-26.5 0t-28.5 -4.5t-23 -3q-15 0 -32 -5.5t-32.5 -14.5t-30 -20t-25.5 -23q-2 -2 -8.5 -10t-14 -16.5t-14.5 -16.5t-8 -10q-38 -42 -53 -99q-9 -40 -12.5 -80.5t-3.5 -82.5zM1913 1009q-51 -1 -95 -12.5t-86 -40.5q-14 -9 -31.5 -23t-34 -30.5t-27.5 -35 t-11 -36.5q26 2 48 6t47 5h4q2 -1 12.5 -1.5t23 -1t23.5 -1t14 -0.5h13h27h31h25t25 1t32.5 2t29.5 1.5t15 0.5q10 0 36.5 0.5t56.5 1t56.5 1.5t36.5 2q2 0 4 2l2 2q0 2 -2 6t-4 6q-2 4 -5.5 10.5t-7.5 13t-7 11t-4 5.5q-44 55 -111.5 81t-135.5 24z" />
<glyph unicode="&#xe7;" horiz-adv-x="1453" d="M601 -339q0 33 6.5 60t3.5 59q6 8 17 8h3q3 -1 11.5 -5t18.5 -8.5t18.5 -9t11.5 -6.5q11 -5 17 -5h20q24 0 48.5 10t37.5 29v3q0 5 3.5 7t3.5 8v1q0 2 -4 10q-2 4 -3 8q0 10 -5.5 16.5t-13.5 10.5t-17 5.5t-16 1.5h-2q-4 -1 -13 -1.5t-19 0t-17 3t-6 8.5q0 4 -0.5 15 t-1.5 23t-2 23t-1 15t-1.5 14t-3.5 21t-3.5 21.5t-1.5 15.5q0 7 6 9.5t14 2.5t16.5 -1.5t13.5 -1.5h15q6 0 12 0.5t10 0.5t18.5 -0.5t18.5 -0.5q4 -3 9 -9t5 -12v-3q0 -1 -1 -5t-1.5 -9t-1.5 -9.5t-1 -5.5q0 -3 3 -9.5t8 -9.5q20 2 42.5 1.5t41.5 -10.5q2 -1 7 -4.5t7 -5.5 q42 -36 66 -79.5t24 -97.5q0 -42 -24 -70t-59.5 -45t-76.5 -24t-76 -7h-42l-10 2q-4 1 -8.5 1.5t-6.5 1.5q-5 1 -17 4t-25 6t-23.5 5.5t-13.5 3.5q-5 2 -16 5t-13 5q-2 0 -5 3.5t-5 4.5v2v0zM120 379q-3 6 -9.5 21t-14 32t-13.5 32t-8 21q0 2 -1.5 13.5t-2.5 17.5 q-14 94 -3.5 192t33.5 187q20 72 53.5 140t81 124.5t109 98t138.5 60.5q52 13 110.5 22t112.5 13q5 0 13.5 1t16.5 1.5t14 1t7 0.5q46 0 98 -2t101 -13q43 -9 92 -22t90 -35q3 -1 15 -7t25.5 -13t25 -13t14.5 -7q27 -23 39 -34t21.5 -20.5l22.5 -22.5t42 -41q3 -5 8.5 -11 t8 -14.5t-1 -20.5t-17.5 -27q-1 -1 -17.5 -13t-38.5 -29.5t-44 -36t-33 -31.5q-24 -36 -47.5 -45t-40.5 -4h-4h-2q-18 3 -26.5 6t-14.5 7t-13 10t-22 15q-17 10 -41.5 18t-43.5 11q-14 3 -35.5 7t-42.5 7.5t-37 6.5t-18 4q-7 0 -14 -1q-6 -1 -12.5 -1.5t-10.5 -0.5 q-21 -2 -37 -2.5t-33 -8.5q-37 -17 -64 -46t-47 -63.5t-34 -72t-26 -73.5q-9 -29 -12.5 -61t1.5 -63q6 -43 19.5 -78.5t36 -62.5t54.5 -45.5t77 -27.5q9 -2 25 -4.5t31 -5t26.5 -4.5t13.5 -2h8.5t17.5 0.5t19.5 1t15.5 0.5q3 0 12 1t18.5 2.5t18 2.5t11.5 1q14 7 28 10.5 t26 11.5q19 10 46.5 27.5t44.5 31.5q20 15 35.5 26.5t42.5 13.5l20 2t18 -5q2 -2 11 -8.5t11 -6.5q2 -2 14 -10l25.5 -17t26 -17t16.5 -10l7 -4q3 -2 12.5 -8.5t20.5 -13.5t20.5 -13t11.5 -7q6 -5 8.5 -7t4 -4t2 -5t1.5 -10q2 -12 1.5 -17t-8.5 -16q-51 -69 -109 -126 t-124 -111q-46 -26 -85 -40.5t-73.5 -21.5t-66 -9.5t-61.5 -5.5q-5 0 -17 -1t-25 -2t-24.5 -1.5t-17.5 -0.5q-52 3 -99.5 7.5t-96.5 21.5q-3 1 -15.5 4.5t-27.5 7.5t-28 7.5t-17 4.5q-43 15 -86 40t-83.5 56t-76 66.5t-62.5 70.5q-2 3 -9.5 14.5t-16 25t-16 25t-9.5 14.5 q-2 2 -7.5 8t-7.5 8z" />
<glyph unicode="&#xe8;" horiz-adv-x="1433" d="M606 1628v3l3 6q1 4 5 6t9 3t9.5 1.5t6.5 0.5h22h1h2q5 0 17 1t14 1q1 1 6.5 2.5t7.5 1.5t7.5 0.5t12 1t12 1t7.5 0.5t8 1.5t8 1.5h1q5 0 13 -2.5t10 -7.5q1 0 2 -3.5t1 -4.5q1 -2 6 -11.5t11 -20t11 -20t6 -11.5t3.5 -8.5t5 -14t4.5 -14.5t2 -8q3 -3 3 -6 q11 -18 14 -32.5t11 -32.5q2 -2 6.5 -12.5t5.5 -12.5v-3q0 -2 0.5 -3t0.5 -2q0 -12 -2 -21.5t-14 -5.5q-1 0 -6 -1.5t-11 -3t-11 -2.5t-6 -1q-14 -2 -25 -5.5t-20.5 -7t-20 -6t-24.5 -2.5q-4 0 -11.5 0.5t-8.5 0.5l-9 6l-2.5 4.5t-5.5 11.5t-6.5 14t-6.5 12 q-14 29 -25.5 58.5t-25.5 57.5q-11 23 -17 43t-17 43v3zM67 689q6 37 15 72.5t20 71.5q8 26 13.5 46t13.5 45q0 2 2.5 11t6 19.5t6.5 19t4 10.5q11 35 32 63t44 56q1 1 6.5 7.5t12.5 14t13 14.5t9 10q1 1 4 5t6.5 9.5t6.5 9.5t5 5q42 36 92.5 65t105 50t111 32.5t111.5 12.5 q62 5 129 -2t125 -33q49 -15 84.5 -34t60 -37t40.5 -32.5t28 -20.5q31 -27 56 -53t45.5 -54t38.5 -59.5t35 -70.5q3 -9 8.5 -32.5t11.5 -49.5t11 -49.5t6 -32.5q1 -2 1.5 -9t0.5 -17v-19.5v-15.5t-0.5 -16.5t-0.5 -21v-18.5t-1 -9q0 -3 -3 -12.5t-6 -20t-5.5 -20t-2.5 -11.5 q-20 -20 -40.5 -27.5t-48 -9.5t-66 -2.5t-93.5 -6.5h-19h-33t-33 -0.5t-19 -0.5h-10q-2 -2 -8.5 -3t-13.5 -0.5t-12.5 2.5t-6.5 6q-1 0 -9 -0.5t-17.5 -0.5h-19t-12.5 1q-1 -1 -3 -1h-5q-24 -1 -55 -2t-63.5 -2t-63.5 -1.5t-55 -0.5q-36 -2 -64.5 -0.5t-55 3t-55 2.5 t-64.5 0q-5 0 -10 -0.5t-7 -5.5q0 -5 2.5 -15t2.5 -13q9 -36 12.5 -51.5t6.5 -22t7.5 -11t14.5 -18.5q0 -1 3.5 -4.5t8 -7.5t8 -7.5t3.5 -4.5q33 -53 87 -76.5t111 -21.5q8 0 22 0.5t16 0.5q20 2 29 1.5t15 -1.5t12.5 -1.5t21 1.5t40 7.5t70.5 16.5q1 0 11 5t21.5 11 t22 11.5t12.5 6.5q26 16 47 31.5t38.5 28.5t33 23t30.5 16h2h4q2 1 6 -1.5t4 -4.5q9 -8 27 -20.5t36.5 -25.5t35.5 -25.5t25 -21.5q3 -2 14 -10t23 -17.5t21 -18t9 -9.5v-4q0 -2 0.5 -3t0.5 -3q1 -25 -14.5 -44t-32.5 -37q-47 -51 -99.5 -99.5t-114.5 -80.5 q-20 -9 -40 -13.5t-40 -11.5q-26 -8 -50 -11.5t-47 -4.5t-47.5 -0.5t-52.5 -0.5q-72 -2 -137 5t-134 27q-26 8 -48 17.5t-41.5 21t-38.5 26t-39 31.5q-35 30 -71 58t-68 66q-2 1 -8.5 12t-7.5 14q-2 2 -8 9.5t-12.5 16t-13 16t-7.5 9.5q-2 3 -8.5 15.5t-15 29t-16 32.5 t-11.5 26q-2 2 -4 8t-2 8q-12 66 -20.5 129t-7.5 131v5zM779 1009q-51 -1 -95 -12.5t-86 -40.5q-14 -9 -31.5 -23t-34 -30.5t-27.5 -35t-11 -36.5q26 2 48 6t47 5h4q2 -1 12.5 -1.5t23 -1t23.5 -1t14 -0.5h13h27h31h25t25 1t32.5 2t29.5 1.5t15 0.5q10 0 36.5 0.5t56.5 1 t56.5 1.5t36.5 2q2 0 4 2l2 2q0 2 -2 6t-4 6q-2 4 -5.5 10.5t-7.5 13t-7 11t-4 5.5q-44 55 -111.5 81t-135.5 24z" />
<glyph unicode="&#xe9;" horiz-adv-x="1433" d="M860 1594q-12 -22 -19.5 -42t-19.5 -42q-15 -28 -29 -56.5t-30 -57.5q-3 -5 -6.5 -12.5t-7 -14t-6.5 -11.5l-3 -5l-10 -5q-1 0 -8.5 -0.5t-11.5 -0.5q-14 1 -24 4t-20 6.5l-20 7t-24 5.5q-1 0 -6 1.5t-11 3t-11 3t-6 1.5q-12 -3 -13.5 6.5t-0.5 21.5q0 3 1 5q0 2 1 3 l6 12t7 12q9 18 13 32.5t17 31.5q0 3 3 6q0 1 2.5 8t5.5 14.5t5.5 14t3.5 8.5t6.5 11.5t12.5 20t12.5 20t6.5 11.5q0 1 1.5 4t2.5 3q2 5 10 7.5t13 2.5h1q2 0 8 -2t8 -2q1 0 7 -0.5t12.5 -1.5t12 -1.5t7.5 -0.5t7.5 -1.5t6.5 -2.5q2 0 14 -1t17 -2h2h1h11t11 -1 q1 0 5.5 -0.5t9.5 -1.5t9 -3.5t5 -6.5l3 -6q-1 0 -1 -1v-2v-3v0zM67 689q6 37 15 72.5t20 71.5q8 26 13.5 46t13.5 45q0 2 2.5 11t6 19.5t6.5 19t4 10.5q11 35 32 63t44 56q1 1 6.5 7.5t12.5 14t13 14.5t9 10q1 1 4 5t6.5 9.5t6.5 9.5t5 5q42 36 92.5 65t105 50t111 32.5 t111.5 12.5q62 5 129 -2t125 -33q49 -15 84.5 -34t60 -37t40.5 -32.5t28 -20.5q31 -27 56 -53t45.5 -54t38.5 -59.5t35 -70.5q3 -9 8.5 -32.5t11.5 -49.5t11 -49.5t6 -32.5q1 -2 1.5 -9t0.5 -17v-19.5v-15.5t-0.5 -16.5t-0.5 -21v-18.5t-1 -9q0 -3 -3 -12.5t-6 -20t-5.5 -20 t-2.5 -11.5q-20 -20 -40.5 -27.5t-48 -9.5t-66 -2.5t-93.5 -6.5h-19h-33t-33 -0.5t-19 -0.5h-10q-2 -2 -8.5 -3t-13.5 -0.5t-12.5 2.5t-6.5 6q-1 0 -9 -0.5t-17.5 -0.5h-19t-12.5 1q-1 -1 -3 -1h-5q-24 -1 -55 -2t-63.5 -2t-63.5 -1.5t-55 -0.5q-36 -2 -64.5 -0.5t-55 3 t-55 2.5t-64.5 0q-5 0 -10 -0.5t-7 -5.5q0 -5 2.5 -15t2.5 -13q9 -36 12.5 -51.5t6.5 -22t7.5 -11t14.5 -18.5q0 -1 3.5 -4.5t8 -7.5t8 -7.5t3.5 -4.5q33 -53 87 -76.5t111 -21.5q8 0 22 0.5t16 0.5q20 2 29 1.5t15 -1.5t12.5 -1.5t21 1.5t40 7.5t70.5 16.5q1 0 11 5 t21.5 11t22 11.5t12.5 6.5q26 16 47 31.5t38.5 28.5t33 23t30.5 16h2h4q2 1 6 -1.5t4 -4.5q9 -8 27 -20.5t36.5 -25.5t35.5 -25.5t25 -21.5q3 -2 14 -10t23 -17.5t21 -18t9 -9.5v-4q0 -2 0.5 -3t0.5 -3q1 -25 -14.5 -44t-32.5 -37q-47 -51 -99.5 -99.5t-114.5 -80.5 q-20 -9 -40 -13.5t-40 -11.5q-26 -8 -50 -11.5t-47 -4.5t-47.5 -0.5t-52.5 -0.5q-72 -2 -137 5t-134 27q-26 8 -48 17.5t-41.5 21t-38.5 26t-39 31.5q-35 30 -71 58t-68 66q-2 1 -8.5 12t-7.5 14q-2 2 -8 9.5t-12.5 16t-13 16t-7.5 9.5q-2 3 -8.5 15.5t-15 29t-16 32.5 t-11.5 26q-2 2 -4 8t-2 8q-12 66 -20.5 129t-7.5 131v5zM779 1009q-51 -1 -95 -12.5t-86 -40.5q-14 -9 -31.5 -23t-34 -30.5t-27.5 -35t-11 -36.5q26 2 48 6t47 5h4q2 -1 12.5 -1.5t23 -1t23.5 -1t14 -0.5h13h27h31h25t25 1t32.5 2t29.5 1.5t15 0.5q10 0 36.5 0.5t56.5 1 t56.5 1.5t36.5 2q2 0 4 2l2 2q0 2 -2 6t-4 6q-2 4 -5.5 10.5t-7.5 13t-7 11t-4 5.5q-44 55 -111.5 81t-135.5 24z" />
<glyph unicode="&#xea;" horiz-adv-x="1433" d="M558 1388q-22 4 -25 10t-6 8v1v1q5 13 14.5 27.5t16.5 25.5q4 7 11 18t14.5 24t14 26.5t11.5 25.5q6 8 9.5 16.5t7.5 17.5q11 27 17.5 39t15.5 22q1 1 5 2.5t6 1.5q4 0 16.5 0.5t26 1t25.5 0.5h17h42q1 0 5.5 0.5t9.5 1.5t9.5 1.5t5.5 0.5h5q7 1 10 -0.5t4 -4t1 -6 t2 -5.5q1 -1 2.5 -5.5t1.5 -5.5q1 -2 3.5 -5.5t3.5 -3.5q-4 4 2 -10.5t15.5 -36t20.5 -44t18 -35.5q4 -5 4 -11.5t2 -11.5q4 -10 8 -19.5t9 -20.5q2 -4 7.5 -12t5.5 -14q0 -2 -2.5 -5.5t-4.5 -4.5h-16q-1 0 -3.5 -1.5t-3.5 -1.5t-13.5 -1t-19.5 -1q-26 -2 -48 -9 q-13 -2 -25 -5.5t-25 -3.5q-8 0 -16.5 0.5t-13.5 6.5q-8 14 -12.5 28.5t-14.5 26.5q-2 -2 -3 -3.5t-3 -3.5q-1 -4 -7 -14.5t-8 -12.5q-1 -2 -4.5 -7.5t-9 -11t-12 -9t-13.5 -1.5h-4h-16.5h-12.5t-12.5 1t-15.5 3q-3 1 -11 2t-17 2.5t-16.5 3t-10.5 1.5zM67 689q6 37 15 72.5 t20 71.5q8 26 13.5 46t13.5 45q0 2 2.5 11t6 19.5t6.5 19t4 10.5q11 35 32 63t44 56q1 1 6.5 7.5t12.5 14t13 14.5t9 10q1 1 4 5t6.5 9.5t6.5 9.5t5 5q42 36 92.5 65t105 50t111 32.5t111.5 12.5q62 5 129 -2t125 -33q49 -15 84.5 -34t60 -37t40.5 -32.5t28 -20.5 q31 -27 56 -53t45.5 -54t38.5 -59.5t35 -70.5q3 -9 8.5 -32.5t11.5 -49.5t11 -49.5t6 -32.5q1 -2 1.5 -9t0.5 -17v-19.5v-15.5t-0.5 -16.5t-0.5 -21v-18.5t-1 -9q0 -3 -3 -12.5t-6 -20t-5.5 -20t-2.5 -11.5q-20 -20 -40.5 -27.5t-48 -9.5t-66 -2.5t-93.5 -6.5h-19h-33 t-33 -0.5t-19 -0.5h-10q-2 -2 -8.5 -3t-13.5 -0.5t-12.5 2.5t-6.5 6q-1 0 -9 -0.5t-17.5 -0.5h-19t-12.5 1q-1 -1 -3 -1h-5q-24 -1 -55 -2t-63.5 -2t-63.5 -1.5t-55 -0.5q-36 -2 -64.5 -0.5t-55 3t-55 2.5t-64.5 0q-5 0 -10 -0.5t-7 -5.5q0 -5 2.5 -15t2.5 -13 q9 -36 12.5 -51.5t6.5 -22t7.5 -11t14.5 -18.5q0 -1 3.5 -4.5t8 -7.5t8 -7.5t3.5 -4.5q33 -53 87 -76.5t111 -21.5q8 0 22 0.5t16 0.5q20 2 29 1.5t15 -1.5t12.5 -1.5t21 1.5t40 7.5t70.5 16.5q1 0 11 5t21.5 11t22 11.5t12.5 6.5q26 16 47 31.5t38.5 28.5t33 23t30.5 16h2 h4q2 1 6 -1.5t4 -4.5q9 -8 27 -20.5t36.5 -25.5t35.5 -25.5t25 -21.5q3 -2 14 -10t23 -17.5t21 -18t9 -9.5v-4q0 -2 0.5 -3t0.5 -3q1 -25 -14.5 -44t-32.5 -37q-47 -51 -99.5 -99.5t-114.5 -80.5q-20 -9 -40 -13.5t-40 -11.5q-26 -8 -50 -11.5t-47 -4.5t-47.5 -0.5 t-52.5 -0.5q-72 -2 -137 5t-134 27q-26 8 -48 17.5t-41.5 21t-38.5 26t-39 31.5q-35 30 -71 58t-68 66q-2 1 -8.5 12t-7.5 14q-2 2 -8 9.5t-12.5 16t-13 16t-7.5 9.5q-2 3 -8.5 15.5t-15 29t-16 32.5t-11.5 26q-2 2 -4 8t-2 8q-12 66 -20.5 129t-7.5 131v5zM779 1009 q-51 -1 -95 -12.5t-86 -40.5q-14 -9 -31.5 -23t-34 -30.5t-27.5 -35t-11 -36.5q26 2 48 6t47 5h4q2 -1 12.5 -1.5t23 -1t23.5 -1t14 -0.5h13h27h31h25t25 1t32.5 2t29.5 1.5t15 0.5q10 0 36.5 0.5t56.5 1t56.5 1.5t36.5 2q2 0 4 2l2 2q0 2 -2 6t-4 6q-2 4 -5.5 10.5t-7.5 13 t-7 11t-4 5.5q-44 55 -111.5 81t-135.5 24z" />
<glyph unicode="&#xeb;" horiz-adv-x="1433" d="M691 1513v-18t-4 -19q-7 -14 -12 -26.5t-16 -24.5q-6 -7 -19 -16.5t-16 -12.5q-14 -13 -31 -13t-34 -1q-11 -1 -18 1t-18 7q-5 0 -13.5 4t-13.5 7q-26 16 -44.5 40t-21.5 57q0 20 0.5 34t4.5 26t13 23t24 24q14 13 34 23.5t38 11.5q5 1 17 0.5t15 -1.5q6 -1 18.5 -4 t14.5 -4q1 -1 6 -2.5t10.5 -3.5t10.5 -3.5t7 -2.5q28 -21 37 -45t11 -61zM1002 1510q0 -8 0.5 -17.5t-3.5 -19.5q-7 -14 -12 -26t-16 -24q-3 -3 -8 -7.5t-10 -8.5l-10 -8t-6 -5q-14 -13 -31.5 -13t-34.5 -1q-11 -1 -17.5 1.5t-17.5 5.5q-5 1 -14 5t-14 8q-26 15 -44 38.5 t-23 56.5q0 20 1 34t5.5 26t13.5 23t24 25q13 13 33 23.5t38 11.5q4 1 17 0.5t16 -1.5q5 -1 17.5 -4.5t15.5 -3.5q1 -1 5.5 -3t10 -3.5t10.5 -3t7 -2.5q28 -22 37.5 -45.5t9.5 -61.5zM67 689q6 37 15 72.5t20 71.5q8 26 13.5 46t13.5 45q0 2 2.5 11t6 19.5t6.5 19t4 10.5 q11 35 32 63t44 56q1 1 6.5 7.5t12.5 14t13 14.5t9 10q1 1 4 5t6.5 9.5t6.5 9.5t5 5q42 36 92.5 65t105 50t111 32.5t111.5 12.5q62 5 129 -2t125 -33q49 -15 84.5 -34t60 -37t40.5 -32.5t28 -20.5q31 -27 56 -53t45.5 -54t38.5 -59.5t35 -70.5q3 -9 8.5 -32.5t11.5 -49.5 t11 -49.5t6 -32.5q1 -2 1.5 -9t0.5 -17v-19.5v-15.5t-0.5 -16.5t-0.5 -21v-18.5t-1 -9q0 -3 -3 -12.5t-6 -20t-5.5 -20t-2.5 -11.5q-20 -20 -40.5 -27.5t-48 -9.5t-66 -2.5t-93.5 -6.5h-19h-33t-33 -0.5t-19 -0.5h-10q-2 -2 -8.5 -3t-13.5 -0.5t-12.5 2.5t-6.5 6 q-1 0 -9 -0.5t-17.5 -0.5h-19t-12.5 1q-1 -1 -3 -1h-5q-24 -1 -55 -2t-63.5 -2t-63.5 -1.5t-55 -0.5q-36 -2 -64.5 -0.5t-55 3t-55 2.5t-64.5 0q-5 0 -10 -0.5t-7 -5.5q0 -5 2.5 -15t2.5 -13q9 -36 12.5 -51.5t6.5 -22t7.5 -11t14.5 -18.5q0 -1 3.5 -4.5t8 -7.5t8 -7.5 t3.5 -4.5q33 -53 87 -76.5t111 -21.5q8 0 22 0.5t16 0.5q20 2 29 1.5t15 -1.5t12.5 -1.5t21 1.5t40 7.5t70.5 16.5q1 0 11 5t21.5 11t22 11.5t12.5 6.5q26 16 47 31.5t38.5 28.5t33 23t30.5 16h2h4q2 1 6 -1.5t4 -4.5q9 -8 27 -20.5t36.5 -25.5t35.5 -25.5t25 -21.5 q3 -2 14 -10t23 -17.5t21 -18t9 -9.5v-4q0 -2 0.5 -3t0.5 -3q1 -25 -14.5 -44t-32.5 -37q-47 -51 -99.5 -99.5t-114.5 -80.5q-20 -9 -40 -13.5t-40 -11.5q-26 -8 -50 -11.5t-47 -4.5t-47.5 -0.5t-52.5 -0.5q-72 -2 -137 5t-134 27q-26 8 -48 17.5t-41.5 21t-38.5 26 t-39 31.5q-35 30 -71 58t-68 66q-2 1 -8.5 12t-7.5 14q-2 2 -8 9.5t-12.5 16t-13 16t-7.5 9.5q-2 3 -8.5 15.5t-15 29t-16 32.5t-11.5 26q-2 2 -4 8t-2 8q-12 66 -20.5 129t-7.5 131v5zM779 1009q-51 -1 -95 -12.5t-86 -40.5q-14 -9 -31.5 -23t-34 -30.5t-27.5 -35 t-11 -36.5q26 2 48 6t47 5h4q2 -1 12.5 -1.5t23 -1t23.5 -1t14 -0.5h13h27h31h25t25 1t32.5 2t29.5 1.5t15 0.5q10 0 36.5 0.5t56.5 1t56.5 1.5t36.5 2q2 0 4 2l2 2q0 2 -2 6t-4 6q-2 4 -5.5 10.5t-7.5 13t-7 11t-4 5.5q-44 55 -111.5 81t-135.5 24z" />
<glyph unicode="&#xec;" horiz-adv-x="631" d="M178 1601v3l3 6q1 4 5 6t9 3t9.5 1.5t6.5 0.5h22h1h2q5 0 17 1t14 1q1 1 6.5 2.5t7.5 1.5t7.5 0.5t12 1t12 1t7.5 0.5t8 1.5t8 1.5h1q5 0 13 -2.5t10 -7.5q1 0 2 -3.5t1 -4.5q1 -2 6 -11.5t11 -20t11 -20t6 -11.5t3.5 -8.5t5 -14t4.5 -14.5t2 -8q3 -3 3 -6 q11 -18 14 -32.5t11 -32.5q2 -2 6.5 -12.5t5.5 -12.5v-3q0 -2 0.5 -3t0.5 -2q0 -12 -2 -21.5t-14 -5.5q-1 0 -6 -1.5t-11 -3t-11 -2.5t-6 -1q-14 -2 -25 -5.5t-20.5 -7t-20 -6t-24.5 -2.5q-4 0 -11.5 0.5t-8.5 0.5l-9 6l-2.5 4.5t-5.5 11.5t-6.5 14t-6.5 12 q-14 29 -25.5 58.5t-25.5 57.5q-11 23 -17 43t-17 43v3zM104 809q0 13 -1 47t-1.5 72t-1.5 72t-1 47q1 3 2 11t2 17.5t1.5 17.5t0.5 11v121q6 9 22 13.5t25 4.5h286q8 -3 14.5 -4t11.5 -6.5t8 -19.5t3 -44q1 -2 2 -8.5t2 -14t1.5 -14t0.5 -8.5q0 -14 1.5 -51t3 -78.5 t3 -78.5t1.5 -51q0 -8 2 -36t5 -60t5 -60.5t2 -35.5q0 -9 1 -34.5t3 -59t4 -71.5t4 -72t3 -59.5t2 -33.5q1 -15 1 -47t0.5 -67.5t1.5 -67.5t3 -47v-14q5 -39 -5.5 -60t-40.5 -15l-317 2q-23 0 -31.5 13.5t-11 35t-2.5 50t-4 58.5q-2 22 -2 48.5t0.5 53t1 52.5t-0.5 48 q-3 58 -5 109.5t-3 102t-1.5 102.5t-0.5 109z" />
<glyph unicode="&#xed;" horiz-adv-x="631" d="M459 1594q-12 -22 -19.5 -42t-19.5 -42q-15 -28 -29 -56.5t-30 -57.5q-3 -5 -6.5 -12.5t-7 -14t-6.5 -11.5l-3 -5l-10 -5q-1 0 -8.5 -0.5t-11.5 -0.5q-14 1 -24 4t-20 6.5l-20 7t-24 5.5q-1 0 -6 1.5t-11 3t-11 3t-6 1.5q-12 -3 -13.5 6.5t-0.5 21.5q0 3 1 5q0 2 1 3 l6 12t7 12q9 18 13 32.5t17 31.5q0 3 3 6q0 1 2.5 8t5.5 14.5t5.5 14t3.5 8.5t6.5 11.5t12.5 20t12.5 20t6.5 11.5q0 1 1.5 4t2.5 3q2 5 10 7.5t13 2.5h1q2 0 8 -2t8 -2q1 0 7 -0.5t12.5 -1.5t12 -1.5t7.5 -0.5t7.5 -1.5t6.5 -2.5q2 0 14 -1t17 -2h2h1h11t11 -1 q1 0 5.5 -0.5t9.5 -1.5t9 -3.5t5 -6.5l3 -6q-1 0 -1 -1v-2v-3v0zM104 809q0 13 -1 47t-1.5 72t-1.5 72t-1 47q1 3 2 11t2 17.5t1.5 17.5t0.5 11v121q6 9 22 13.5t25 4.5h286q8 -3 14.5 -4t11.5 -6.5t8 -19.5t3 -44q1 -2 2 -8.5t2 -14t1.5 -14t0.5 -8.5q0 -14 1.5 -51 t3 -78.5t3 -78.5t1.5 -51q0 -8 2 -36t5 -60t5 -60.5t2 -35.5q0 -9 1 -34.5t3 -59t4 -71.5t4 -72t3 -59.5t2 -33.5q1 -15 1 -47t0.5 -67.5t1.5 -67.5t3 -47v-14q5 -39 -5.5 -60t-40.5 -15l-317 2q-23 0 -31.5 13.5t-11 35t-2.5 50t-4 58.5q-2 22 -2 48.5t0.5 53t1 52.5 t-0.5 48q-3 58 -5 109.5t-3 102t-1.5 102.5t-0.5 109z" />
<glyph unicode="&#xee;" horiz-adv-x="631" d="M134 1372q-22 4 -25 10t-6 8v1v1q5 13 14.5 27.5t16.5 25.5q4 7 11 18t14.5 24t14 26.5t11.5 25.5q6 8 9.5 16.5t7.5 17.5q11 27 17.5 39t15.5 22q1 1 5 2.5t6 1.5q4 0 16.5 0.5t26 1t25.5 0.5h17h42q1 0 5.5 0.5t9.5 1.5t9.5 1.5t5.5 0.5h5q7 1 10 -0.5t4 -4t1 -6 t2 -5.5q1 -1 2.5 -5.5t1.5 -5.5q1 -2 3.5 -5.5t3.5 -3.5q-4 4 2 -10.5t15.5 -36t20.5 -44t18 -35.5q4 -5 4 -11.5t2 -11.5q4 -10 8 -19.5t9 -20.5q2 -4 7.5 -12t5.5 -14q0 -2 -2.5 -5.5t-4.5 -4.5h-16q-1 0 -3.5 -1.5t-3.5 -1.5t-13.5 -1t-19.5 -1q-26 -2 -48 -9 q-13 -2 -25 -5.5t-25 -3.5q-8 0 -16.5 0.5t-13.5 6.5q-8 14 -12.5 28.5t-14.5 26.5q-2 -2 -3 -3.5t-3 -3.5q-1 -4 -7 -14.5t-8 -12.5q-1 -2 -4.5 -7.5t-9 -11t-12 -9t-13.5 -1.5h-4h-16.5h-12.5t-12.5 1t-15.5 3q-3 1 -11 2t-17 2.5t-16.5 3t-10.5 1.5zM104 809q0 13 -1 47 t-1.5 72t-1.5 72t-1 47q1 3 2 11t2 17.5t1.5 17.5t0.5 11v121q6 9 22 13.5t25 4.5h286q8 -3 14.5 -4t11.5 -6.5t8 -19.5t3 -44q1 -2 2 -8.5t2 -14t1.5 -14t0.5 -8.5q0 -14 1.5 -51t3 -78.5t3 -78.5t1.5 -51q0 -8 2 -36t5 -60t5 -60.5t2 -35.5q0 -9 1 -34.5t3 -59t4 -71.5 t4 -72t3 -59.5t2 -33.5q1 -15 1 -47t0.5 -67.5t1.5 -67.5t3 -47v-14q5 -39 -5.5 -60t-40.5 -15l-317 2q-23 0 -31.5 13.5t-11 35t-2.5 50t-4 58.5q-2 22 -2 48.5t0.5 53t1 52.5t-0.5 48q-3 58 -5 109.5t-3 102t-1.5 102.5t-0.5 109z" />
<glyph unicode="&#xef;" horiz-adv-x="631" d="M291 1513v-18t-4 -19q-7 -14 -12 -26.5t-16 -24.5q-6 -7 -19 -16.5t-16 -12.5q-14 -13 -31 -13t-34 -1q-11 -1 -18 1t-18 7q-5 0 -13.5 4t-13.5 7q-26 16 -44.5 40t-21.5 57q0 20 0.5 34t4.5 26t13 23t24 24q14 13 34 23.5t38 11.5q5 1 17 0.5t15 -1.5q6 -1 18.5 -4 t14.5 -4q1 -1 6 -2.5t10.5 -3.5t10.5 -3.5t7 -2.5q28 -21 37 -45t11 -61zM602 1510q0 -8 0.5 -17.5t-3.5 -19.5q-7 -14 -12 -26t-16 -24q-3 -3 -8 -7.5t-10 -8.5l-10 -8t-6 -5q-14 -13 -31.5 -13t-34.5 -1q-11 -1 -17.5 1.5t-17.5 5.5q-5 1 -14 5t-14 8q-26 15 -44 38.5 t-23 56.5q0 20 1 34t5.5 26t13.5 23t24 25q13 13 33 23.5t38 11.5q4 1 17 0.5t16 -1.5q5 -1 17.5 -4.5t15.5 -3.5q1 -1 5.5 -3t10 -3.5t10.5 -3t7 -2.5q28 -22 37.5 -45.5t9.5 -61.5zM104 809q0 13 -1 47t-1.5 72t-1.5 72t-1 47q1 3 2 11t2 17.5t1.5 17.5t0.5 11v121 q6 9 22 13.5t25 4.5h286q8 -3 14.5 -4t11.5 -6.5t8 -19.5t3 -44q1 -2 2 -8.5t2 -14t1.5 -14t0.5 -8.5q0 -14 1.5 -51t3 -78.5t3 -78.5t1.5 -51q0 -8 2 -36t5 -60t5 -60.5t2 -35.5q0 -9 1 -34.5t3 -59t4 -71.5t4 -72t3 -59.5t2 -33.5q1 -15 1 -47t0.5 -67.5t1.5 -67.5t3 -47 v-14q5 -39 -5.5 -60t-40.5 -15l-317 2q-23 0 -31.5 13.5t-11 35t-2.5 50t-4 58.5q-2 22 -2 48.5t0.5 53t1 52.5t-0.5 48q-3 58 -5 109.5t-3 102t-1.5 102.5t-0.5 109z" />
<glyph unicode="&#xf1;" horiz-adv-x="1294" d="M255 1462q0 1 -1.5 3.5t-1.5 3.5t3 5t5 5v5q12 32 37.5 56.5t48.5 49.5q2 1 8.5 8t8.5 8q29 30 67.5 53t80.5 23q18 0 33.5 -1.5t32.5 -9.5q10 -4 20.5 -10.5t21.5 -6.5l31 -22q4 -2 14.5 -8t22.5 -12t22.5 -11.5t14.5 -7.5q11 -6 19.5 -7t19.5 -1q15 0 34 13.5t28 26.5 q3 3 8 10t10.5 14.5t9.5 13.5t5 8q5 8 9 13t15 5h3q1 -1 6.5 -5.5t7.5 -6.5q14 -14 30 -26t30.5 -21.5t26.5 -17.5t20 -15q6 -7 12.5 -12t9.5 -10t2 -11t-8 -15q-9 -15 -18.5 -27.5t-20.5 -28.5q-20 -26 -41.5 -51.5t-47 -45.5t-55 -32t-64.5 -12q-9 -1 -26 3.5t-34.5 11.5 t-33.5 14t-24 12q-2 3 -11 12t-12 11q-17 14 -34 19.5t-40 5.5q-27 0 -51.5 -13t-42.5 -37q-7 -11 -12.5 -18.5t-12 -12.5t-15 -7.5t-22.5 -2.5q-3 0 -8 1t-7 1q-1 0 -6 4.5t-7 4.5q-2 2 -5.5 4t-4.5 4q-17 11 -29 18t-27 22q-1 0 -7 4q-3 2 -6 5q-3 2 -8.5 8.5t-12.5 13.5 t-12.5 13t-8.5 9zM110 4q-13 3 -21 8q-9 6 -13.5 14.5t-6 17.5t-1 17t0.5 14q0 76 -2 151.5t-3.5 151.5t0 152t7.5 152l-4 47q1 8 2 15q1 6 1 12.5t1 11.5v59v27.5v46.5t0.5 47.5t0.5 28.5q0 5 1.5 27t3 47t2 47t0.5 28q1 22 -1.5 50t-3.5 51l2 35q0 12 6.5 16.5t14 5.5 t14 0t7.5 0q3 0 11.5 0.5t18 1.5t17.5 2t10 2h37h33.5t33.5 -0.5t38 -1.5l11 -1q1 0 6.5 -1t12 -2t12.5 -2.5t9 -2.5q21 -4 29.5 -9.5t11 -15t3 -23.5t4.5 -34q43 39 90 63t97 36.5t102.5 15.5t108.5 0q15 0 32 -3.5t34.5 -8.5t34 -12t29.5 -14q9 -6 23.5 -17t28.5 -22.5 t24.5 -20t11.5 -8.5q28 -21 49.5 -48.5t37 -58.5t26 -65t17.5 -67q3 -4 7 -20.5t7.5 -37t6 -41.5t2.5 -33v-17v-20t0.5 -35t1 -35t0.5 -20l1 -166l-2 -35q-1 -3 -2 -12t-2.5 -19t-2.5 -19t-1 -13l-1 -22q-1 -19 -1 -48.5t-0.5 -63t-0.5 -68v-63.5t0.5 -49t0.5 -25v-12.5 v-20.5t0.5 -20.5t0.5 -11.5l-1 -10q0 -11 -12.5 -13.5t-20.5 -3.5q-3 0 -8.5 -0.5t-11.5 -1.5t-10.5 -1.5t-5.5 -1.5h-15h-26t-26 -0.5t-15 -1.5q-47 -2 -87.5 -5.5t-89.5 -1.5q-18 1 -25 9.5t-9 20.5t-1 25.5t1 25.5v23.5t0.5 42.5t0.5 52t0.5 52t0.5 42v24l1 232 q2 35 0 81t-9.5 95t-20.5 96t-32 83.5t-44 57.5t-56 18l-35 2q-35 1 -57.5 -8t-53.5 -27q-2 0 -4 -2.5t-2 -4.5q-28 -21 -47.5 -59.5t-33 -87t-22.5 -103t-15 -107.5q-1 -5 -3 -25t-4.5 -44.5t-4 -49t-2.5 -37.5q0 -1 -0.5 -10t-1.5 -21.5t-2 -24.5t-1 -19q0 -5 -0.5 -16 t-0.5 -23.5t-0.5 -23.5t-0.5 -15l1 -150q-1 -3 1 -12t2 -12q0 -1 0.5 -5.5t0.5 -9.5v-10v-6q0 -8 1 -19t-1 -21.5t-8.5 -17.5t-22.5 -6q-23 1 -50.5 0.5t-57.5 -1.5t-61 -1.5t-59 2.5z" />
<glyph unicode="&#xf2;" horiz-adv-x="1418" d="M579 1674v3l3 6q1 4 5 6t9 3t9.5 1.5t6.5 0.5h22h1h2q5 0 17 1t14 1q1 1 6.5 2.5t7.5 1.5t7.5 0.5t12 1t12 1t7.5 0.5t8 1.5t8 1.5h1q5 0 13 -2.5t10 -7.5q1 0 2 -3.5t1 -4.5q1 -2 6 -11.5t11 -20t11 -20t6 -11.5t3.5 -8.5t5 -14t4.5 -14.5t2 -8q3 -3 3 -6 q11 -18 14 -32.5t11 -32.5q2 -2 6.5 -12.5t5.5 -12.5v-3q0 -2 0.5 -3t0.5 -2q0 -12 -2 -21.5t-14 -5.5q-1 0 -6 -1.5t-11 -3t-11 -2.5t-6 -1q-14 -2 -25 -5.5t-20.5 -7t-20 -6t-24.5 -2.5q-4 0 -11.5 0.5t-8.5 0.5l-9 6l-2.5 4.5t-5.5 11.5t-6.5 14t-6.5 12 q-14 29 -25.5 58.5t-25.5 57.5q-11 23 -17 43t-17 43v3zM575 28q-7 2 -21 4.5t-35 6.5q-1 0 -9 1.5t-19.5 5t-24 9.5t-22.5 15q-2 1 -8.5 3.5t-14.5 6t-14.5 6t-8.5 3.5q-18 7 -34.5 19t-31.5 25t-29 26.5t-26 25.5q-48 45 -86 95t-65 110q-22 48 -35 87.5t-20 78t-9.5 79.5 t-2.5 94v75q13 57 30 107.5t41.5 96.5t56.5 88t75 81q31 30 64 52t71 40q3 1 8.5 4t12 5.5t11.5 4.5t7 3q3 0 15 1.5t14 1.5q3 2 12 8.5t11 8.5q1 0 6.5 1t11.5 2.5t11 2.5t6 2l18 4.5l30 7.5t30.5 7.5t18.5 3.5q8 3 29 5.5t45 4.5t45.5 4t31.5 3h12q5 0 10.5 -0.5t8.5 -0.5 q22 -1 40 -2t38 -6q28 -7 57 -13t57 -10q7 -3 23.5 -11t35 -18t34.5 -19t22 -13q3 -2 15.5 -14.5l27.5 -27.5t29 -30t21 -23q1 -2 6 -9t11.5 -16.5t13 -18.5t10.5 -15q36 -55 59.5 -109t37.5 -109.5t20.5 -114t6.5 -121.5v-4q-2 -17 -4.5 -46.5t-5 -58.5t-4.5 -52t-3 -27 q-7 -51 -21.5 -97t-35.5 -91q-19 -24 -30.5 -40.5t-23.5 -32t-27.5 -34t-42.5 -46.5q-35 -26 -74.5 -48t-81.5 -38t-85.5 -25t-85.5 -7h-13.5t-21 0.5t-21 1t-13.5 0.5q-2 2 -7 4t-7 2t-9 -1t-15.5 -2.5t-16 -2.5t-9.5 0q-4 0 -18.5 1.5t-31.5 4t-31.5 4.5t-17.5 3h-10z M444 715q1 -28 5 -55t15 -53q0 -2 5 -11t5 -11q4 -13 8 -28t8.5 -30t10.5 -29t15 -25q3 -3 10 -10.5l14 -15t13 -14t8 -7.5q1 -1 6.5 -5t13 -8.5t15 -9.5t12.5 -7l10 -7q3 -2 13 -9t12 -7q2 -2 10 -4.5t13 -2.5q21 -10 31.5 -11.5t18 0t16 3t26.5 -1.5q1 0 7 0.5t13 1.5 l14 2t11 2q47 7 88 32t71.5 62t47.5 82.5t17 92.5q0 3 0.5 24.5t4.5 75.5q0 26 -10.5 51t-18.5 51q-14 40 -45.5 67.5t-65.5 50.5q-21 14 -38.5 23.5t-35.5 15.5t-37.5 9t-44.5 4q-23 1 -40 0.5t-40 -5.5q-25 -5 -52 -14t-51.5 -22.5t-44 -32.5t-28.5 -44l-17 -48 q-6 -8 -11 -23t-8 -32.5t-3 -35t3 -31.5z" />
<glyph unicode="&#xf3;" horiz-adv-x="1418" d="M884 1672q-12 -22 -19.5 -42t-19.5 -42q-15 -28 -29 -56.5t-30 -57.5q-3 -5 -6.5 -12.5t-7 -14t-6.5 -11.5l-3 -5l-10 -5q-1 0 -8.5 -0.5t-11.5 -0.5q-14 1 -24 4t-20 6.5l-20 7t-24 5.5q-1 0 -6 1.5t-11 3t-11 3t-6 1.5q-12 -3 -13.5 6.5t-0.5 21.5q0 3 1 5q0 2 1 3 l6 12t7 12q9 18 13 32.5t17 31.5q0 3 3 6q0 1 2.5 8t5.5 14.5t5.5 14t3.5 8.5t6.5 11.5t12.5 20t12.5 20t6.5 11.5q0 1 1.5 4t2.5 3q2 5 10 7.5t13 2.5h1q2 0 8 -2t8 -2q1 0 7 -0.5t12.5 -1.5t12 -1.5t7.5 -0.5t7.5 -1.5t6.5 -2.5q2 0 14 -1t17 -2h2h1h11t11 -1 q1 0 5.5 -0.5t9.5 -1.5t9 -3.5t5 -6.5l3 -6q-1 0 -1 -1v-2v-3v0zM575 28q-7 2 -21 4.5t-35 6.5q-1 0 -9 1.5t-19.5 5t-24 9.5t-22.5 15q-2 1 -8.5 3.5t-14.5 6t-14.5 6t-8.5 3.5q-18 7 -34.5 19t-31.5 25t-29 26.5t-26 25.5q-48 45 -86 95t-65 110q-22 48 -35 87.5t-20 78 t-9.5 79.5t-2.5 94v75q13 57 30 107.5t41.5 96.5t56.5 88t75 81q31 30 64 52t71 40q3 1 8.5 4t12 5.5t11.5 4.5t7 3q3 0 15 1.5t14 1.5q3 2 12 8.5t11 8.5q1 0 6.5 1t11.5 2.5t11 2.5t6 2l18 4.5l30 7.5t30.5 7.5t18.5 3.5q8 3 29 5.5t45 4.5t45.5 4t31.5 3h12 q5 0 10.5 -0.5t8.5 -0.5q22 -1 40 -2t38 -6q28 -7 57 -13t57 -10q7 -3 23.5 -11t35 -18t34.5 -19t22 -13q3 -2 15.5 -14.5l27.5 -27.5t29 -30t21 -23q1 -2 6 -9t11.5 -16.5t13 -18.5t10.5 -15q36 -55 59.5 -109t37.5 -109.5t20.5 -114t6.5 -121.5v-4q-2 -17 -4.5 -46.5 t-5 -58.5t-4.5 -52t-3 -27q-7 -51 -21.5 -97t-35.5 -91q-19 -24 -30.5 -40.5t-23.5 -32t-27.5 -34t-42.5 -46.5q-35 -26 -74.5 -48t-81.5 -38t-85.5 -25t-85.5 -7h-13.5t-21 0.5t-21 1t-13.5 0.5q-2 2 -7 4t-7 2t-9 -1t-15.5 -2.5t-16 -2.5t-9.5 0q-4 0 -18.5 1.5t-31.5 4 t-31.5 4.5t-17.5 3h-10zM444 715q1 -28 5 -55t15 -53q0 -2 5 -11t5 -11q4 -13 8 -28t8.5 -30t10.5 -29t15 -25q3 -3 10 -10.5l14 -15t13 -14t8 -7.5q1 -1 6.5 -5t13 -8.5t15 -9.5t12.5 -7l10 -7q3 -2 13 -9t12 -7q2 -2 10 -4.5t13 -2.5q21 -10 31.5 -11.5t18 0t16 3 t26.5 -1.5q1 0 7 0.5t13 1.5l14 2t11 2q47 7 88 32t71.5 62t47.5 82.5t17 92.5q0 3 0.5 24.5t4.5 75.5q0 26 -10.5 51t-18.5 51q-14 40 -45.5 67.5t-65.5 50.5q-21 14 -38.5 23.5t-35.5 15.5t-37.5 9t-44.5 4q-23 1 -40 0.5t-40 -5.5q-25 -5 -52 -14t-51.5 -22.5t-44 -32.5 t-28.5 -44l-17 -48q-6 -8 -11 -23t-8 -32.5t-3 -35t3 -31.5z" />
<glyph unicode="&#xf4;" horiz-adv-x="1418" d="M547 1410q-22 4 -25 10t-6 8v1v1q5 13 14.5 27.5t16.5 25.5q4 7 11 18t14.5 24t14 26.5t11.5 25.5q6 8 9.5 16.5t7.5 17.5q11 27 17.5 39t15.5 22q1 1 5 2.5t6 1.5q4 0 16.5 0.5t26 1t25.5 0.5h17h42q1 0 5.5 0.5t9.5 1.5t9.5 1.5t5.5 0.5h5q7 1 10 -0.5t4 -4t1 -6 t2 -5.5q1 -1 2.5 -5.5t1.5 -5.5q1 -2 3.5 -5.5t3.5 -3.5q-4 4 2 -10.5t15.5 -36t20.5 -44t18 -35.5q4 -5 4 -11.5t2 -11.5q4 -10 8 -19.5t9 -20.5q2 -4 7.5 -12t5.5 -14q0 -2 -2.5 -5.5t-4.5 -4.5h-16q-1 0 -3.5 -1.5t-3.5 -1.5t-13.5 -1t-19.5 -1q-26 -2 -48 -9 q-13 -2 -25 -5.5t-25 -3.5q-8 0 -16.5 0.5t-13.5 6.5q-8 14 -12.5 28.5t-14.5 26.5q-2 -2 -3 -3.5t-3 -3.5q-1 -4 -7 -14.5t-8 -12.5q-1 -2 -4.5 -7.5t-9 -11t-12 -9t-13.5 -1.5h-4h-16.5h-12.5t-12.5 1t-15.5 3q-3 1 -11 2t-17 2.5t-16.5 3t-10.5 1.5zM575 28q-7 2 -21 4.5 t-35 6.5q-1 0 -9 1.5t-19.5 5t-24 9.5t-22.5 15q-2 1 -8.5 3.5t-14.5 6t-14.5 6t-8.5 3.5q-18 7 -34.5 19t-31.5 25t-29 26.5t-26 25.5q-48 45 -86 95t-65 110q-22 48 -35 87.5t-20 78t-9.5 79.5t-2.5 94v75q13 57 30 107.5t41.5 96.5t56.5 88t75 81q31 30 64 52t71 40 q3 1 8.5 4t12 5.5t11.5 4.5t7 3q3 0 15 1.5t14 1.5q3 2 12 8.5t11 8.5q1 0 6.5 1t11.5 2.5t11 2.5t6 2l18 4.5l30 7.5t30.5 7.5t18.5 3.5q8 3 29 5.5t45 4.5t45.5 4t31.5 3h12q5 0 10.5 -0.5t8.5 -0.5q22 -1 40 -2t38 -6q28 -7 57 -13t57 -10q7 -3 23.5 -11t35 -18t34.5 -19 t22 -13q3 -2 15.5 -14.5l27.5 -27.5t29 -30t21 -23q1 -2 6 -9t11.5 -16.5t13 -18.5t10.5 -15q36 -55 59.5 -109t37.5 -109.5t20.5 -114t6.5 -121.5v-4q-2 -17 -4.5 -46.5t-5 -58.5t-4.5 -52t-3 -27q-7 -51 -21.5 -97t-35.5 -91q-19 -24 -30.5 -40.5t-23.5 -32t-27.5 -34 t-42.5 -46.5q-35 -26 -74.5 -48t-81.5 -38t-85.5 -25t-85.5 -7h-13.5t-21 0.5t-21 1t-13.5 0.5q-2 2 -7 4t-7 2t-9 -1t-15.5 -2.5t-16 -2.5t-9.5 0q-4 0 -18.5 1.5t-31.5 4t-31.5 4.5t-17.5 3h-10zM444 715q1 -28 5 -55t15 -53q0 -2 5 -11t5 -11q4 -13 8 -28t8.5 -30 t10.5 -29t15 -25q3 -3 10 -10.5l14 -15t13 -14t8 -7.5q1 -1 6.5 -5t13 -8.5t15 -9.5t12.5 -7l10 -7q3 -2 13 -9t12 -7q2 -2 10 -4.5t13 -2.5q21 -10 31.5 -11.5t18 0t16 3t26.5 -1.5q1 0 7 0.5t13 1.5l14 2t11 2q47 7 88 32t71.5 62t47.5 82.5t17 92.5q0 3 0.5 24.5 t4.5 75.5q0 26 -10.5 51t-18.5 51q-14 40 -45.5 67.5t-65.5 50.5q-21 14 -38.5 23.5t-35.5 15.5t-37.5 9t-44.5 4q-23 1 -40 0.5t-40 -5.5q-25 -5 -52 -14t-51.5 -22.5t-44 -32.5t-28.5 -44l-17 -48q-6 -8 -11 -23t-8 -32.5t-3 -35t3 -31.5z" />
<glyph unicode="&#xf5;" horiz-adv-x="1418" d="M398 1516q0 1 -1.5 3.5t-1.5 3.5t3 5t5 5v5q12 32 37.5 56.5t48.5 49.5q2 1 8.5 8t8.5 8q29 30 67.5 53t80.5 23q18 0 33.5 -1.5t32.5 -9.5q10 -4 20.5 -10.5t21.5 -6.5l31 -22q4 -2 14.5 -8t22.5 -12t22.5 -11.5t14.5 -7.5q11 -6 19.5 -7t19.5 -1q15 0 34 13.5t28 26.5 q3 3 8 10t10.5 14.5t9.5 13.5t5 8q5 8 9 13t15 5h3q1 -1 6.5 -5.5t7.5 -6.5q14 -14 30 -26t30.5 -21.5t26.5 -17.5t20 -15q6 -7 12.5 -12t9.5 -10t2 -11t-8 -15q-9 -15 -18.5 -27.5t-20.5 -28.5q-20 -26 -41.5 -51.5t-47 -45.5t-55 -32t-64.5 -12q-9 -1 -26 3.5t-34.5 11.5 t-33.5 14t-24 12q-2 3 -11 12t-12 11q-17 14 -34 19.5t-40 5.5q-27 0 -51.5 -13t-42.5 -37q-7 -11 -12.5 -18.5t-12 -12.5t-15 -7.5t-22.5 -2.5q-3 0 -8 1t-7 1q-1 0 -6 4.5t-7 4.5q-2 2 -5.5 4t-4.5 4q-17 11 -29 18t-27 22q-1 0 -7 4q-3 2 -6 5q-3 2 -8.5 8.5t-12.5 13.5 t-12.5 13t-8.5 9zM575 28q-7 2 -21 4.5t-35 6.5q-1 0 -9 1.5t-19.5 5t-24 9.5t-22.5 15q-2 1 -8.5 3.5t-14.5 6t-14.5 6t-8.5 3.5q-18 7 -34.5 19t-31.5 25t-29 26.5t-26 25.5q-48 45 -86 95t-65 110q-22 48 -35 87.5t-20 78t-9.5 79.5t-2.5 94v75q13 57 30 107.5t41.5 96.5 t56.5 88t75 81q31 30 64 52t71 40q3 1 8.5 4t12 5.5t11.5 4.5t7 3q3 0 15 1.5t14 1.5q3 2 12 8.5t11 8.5q1 0 6.5 1t11.5 2.5t11 2.5t6 2l18 4.5l30 7.5t30.5 7.5t18.5 3.5q8 3 29 5.5t45 4.5t45.5 4t31.5 3h12q5 0 10.5 -0.5t8.5 -0.5q22 -1 40 -2t38 -6q28 -7 57 -13 t57 -10q7 -3 23.5 -11t35 -18t34.5 -19t22 -13q3 -2 15.5 -14.5l27.5 -27.5t29 -30t21 -23q1 -2 6 -9t11.5 -16.5t13 -18.5t10.5 -15q36 -55 59.5 -109t37.5 -109.5t20.5 -114t6.5 -121.5v-4q-2 -17 -4.5 -46.5t-5 -58.5t-4.5 -52t-3 -27q-7 -51 -21.5 -97t-35.5 -91 q-19 -24 -30.5 -40.5t-23.5 -32t-27.5 -34t-42.5 -46.5q-35 -26 -74.5 -48t-81.5 -38t-85.5 -25t-85.5 -7h-13.5t-21 0.5t-21 1t-13.5 0.5q-2 2 -7 4t-7 2t-9 -1t-15.5 -2.5t-16 -2.5t-9.5 0q-4 0 -18.5 1.5t-31.5 4t-31.5 4.5t-17.5 3h-10zM444 715q1 -28 5 -55t15 -53 q0 -2 5 -11t5 -11q4 -13 8 -28t8.5 -30t10.5 -29t15 -25q3 -3 10 -10.5l14 -15t13 -14t8 -7.5q1 -1 6.5 -5t13 -8.5t15 -9.5t12.5 -7l10 -7q3 -2 13 -9t12 -7q2 -2 10 -4.5t13 -2.5q21 -10 31.5 -11.5t18 0t16 3t26.5 -1.5q1 0 7 0.5t13 1.5l14 2t11 2q47 7 88 32t71.5 62 t47.5 82.5t17 92.5q0 3 0.5 24.5t4.5 75.5q0 26 -10.5 51t-18.5 51q-14 40 -45.5 67.5t-65.5 50.5q-21 14 -38.5 23.5t-35.5 15.5t-37.5 9t-44.5 4q-23 1 -40 0.5t-40 -5.5q-25 -5 -52 -14t-51.5 -22.5t-44 -32.5t-28.5 -44l-17 -48q-6 -8 -11 -23t-8 -32.5t-3 -35t3 -31.5z " />
<glyph unicode="&#xf6;" horiz-adv-x="1418" d="M683 1513v-18t-4 -19q-7 -14 -12 -26.5t-16 -24.5q-6 -7 -19 -16.5t-16 -12.5q-14 -13 -31 -13t-34 -1q-11 -1 -18 1t-18 7q-5 0 -13.5 4t-13.5 7q-26 16 -44.5 40t-21.5 57q0 20 0.5 34t4.5 26t13 23t24 24q14 13 34 23.5t38 11.5q5 1 17 0.5t15 -1.5q6 -1 18.5 -4 t14.5 -4q1 -1 6 -2.5t10.5 -3.5t10.5 -3.5t7 -2.5q28 -21 37 -45t11 -61zM994 1510q0 -8 0.5 -17.5t-3.5 -19.5q-7 -14 -12 -26t-16 -24q-3 -3 -8 -7.5t-10 -8.5l-10 -8t-6 -5q-14 -13 -31.5 -13t-34.5 -1q-11 -1 -17.5 1.5t-17.5 5.5q-5 1 -14 5t-14 8q-26 15 -44 38.5 t-23 56.5q0 20 1 34t5.5 26t13.5 23t24 25q13 13 33 23.5t38 11.5q4 1 17 0.5t16 -1.5q5 -1 17.5 -4.5t15.5 -3.5q1 -1 5.5 -3t10 -3.5t10.5 -3t7 -2.5q28 -22 37.5 -45.5t9.5 -61.5zM575 28q-7 2 -21 4.5t-35 6.5q-1 0 -9 1.5t-19.5 5t-24 9.5t-22.5 15q-2 1 -8.5 3.5 t-14.5 6t-14.5 6t-8.5 3.5q-18 7 -34.5 19t-31.5 25t-29 26.5t-26 25.5q-48 45 -86 95t-65 110q-22 48 -35 87.5t-20 78t-9.5 79.5t-2.5 94v75q13 57 30 107.5t41.5 96.5t56.5 88t75 81q31 30 64 52t71 40q3 1 8.5 4t12 5.5t11.5 4.5t7 3q3 0 15 1.5t14 1.5q3 2 12 8.5 t11 8.5q1 0 6.5 1t11.5 2.5t11 2.5t6 2l18 4.5l30 7.5t30.5 7.5t18.5 3.5q8 3 29 5.5t45 4.5t45.5 4t31.5 3h12q5 0 10.5 -0.5t8.5 -0.5q22 -1 40 -2t38 -6q28 -7 57 -13t57 -10q7 -3 23.5 -11t35 -18t34.5 -19t22 -13q3 -2 15.5 -14.5l27.5 -27.5t29 -30t21 -23q1 -2 6 -9 t11.5 -16.5t13 -18.5t10.5 -15q36 -55 59.5 -109t37.5 -109.5t20.5 -114t6.5 -121.5v-4q-2 -17 -4.5 -46.5t-5 -58.5t-4.5 -52t-3 -27q-7 -51 -21.5 -97t-35.5 -91q-19 -24 -30.5 -40.5t-23.5 -32t-27.5 -34t-42.5 -46.5q-35 -26 -74.5 -48t-81.5 -38t-85.5 -25t-85.5 -7 h-13.5t-21 0.5t-21 1t-13.5 0.5q-2 2 -7 4t-7 2t-9 -1t-15.5 -2.5t-16 -2.5t-9.5 0q-4 0 -18.5 1.5t-31.5 4t-31.5 4.5t-17.5 3h-10zM444 715q1 -28 5 -55t15 -53q0 -2 5 -11t5 -11q4 -13 8 -28t8.5 -30t10.5 -29t15 -25q3 -3 10 -10.5l14 -15t13 -14t8 -7.5q1 -1 6.5 -5 t13 -8.5t15 -9.5t12.5 -7l10 -7q3 -2 13 -9t12 -7q2 -2 10 -4.5t13 -2.5q21 -10 31.5 -11.5t18 0t16 3t26.5 -1.5q1 0 7 0.5t13 1.5l14 2t11 2q47 7 88 32t71.5 62t47.5 82.5t17 92.5q0 3 0.5 24.5t4.5 75.5q0 26 -10.5 51t-18.5 51q-14 40 -45.5 67.5t-65.5 50.5 q-21 14 -38.5 23.5t-35.5 15.5t-37.5 9t-44.5 4q-23 1 -40 0.5t-40 -5.5q-25 -5 -52 -14t-51.5 -22.5t-44 -32.5t-28.5 -44l-17 -48q-6 -8 -11 -23t-8 -32.5t-3 -35t3 -31.5z" />
<glyph unicode="&#xf7;" horiz-adv-x="837" d="M606 393v-28.5t-6 -30.5q-11 -22 -19 -41.5t-25 -38.5q-5 -5 -13 -12t-16.5 -13.5t-15.5 -12t-9 -8.5q-22 -20 -50 -20.5t-54 -1.5q-17 -2 -28.5 2t-28.5 10q-8 1 -22 7.5t-22 11.5q-40 25 -69.5 62t-35.5 90q0 31 1 54t8 41.5t21 36.5t38 39q21 20 53 36.5t61 18.5h10.5 h15.5t15.5 -0.5t9.5 -1.5q4 0 12 -2t16.5 -4t15.5 -4t9 -2q1 -2 8.5 -4.5l16.5 -5.5t17 -5.5t11 -3.5q22 -17 36.5 -34t22.5 -37t11.5 -44t4.5 -54zM604 1291v-28.5t-6 -30.5q-11 -22 -19 -41.5t-25 -38.5q-5 -5 -13 -12t-16.5 -13.5t-15.5 -12t-9 -8.5q-22 -20 -50 -20.5 t-54 -1.5q-17 -2 -28.5 2t-28.5 10q-8 1 -22 7.5t-22 11.5q-40 25 -69.5 62t-35.5 90q0 31 1 54t8 41.5t21 36.5t38 39q21 20 53 36.5t61 18.5h10.5h15.5t15.5 -0.5t9.5 -1.5q4 0 12 -2t16.5 -4t15.5 -4t9 -2q1 -2 8.5 -4.5l16.5 -5.5t17 -5.5t11 -3.5q22 -17 36.5 -34 t22.5 -37t11.5 -44t4.5 -54zM47 748q-2 10 -1 20.5t0 20.5q0 3 0.5 14t1.5 24t1.5 24t0.5 14q0 30 -2 59.5t1 58.5q1 15 16 25.5t28 11.5q4 0 18.5 -2t31.5 -3.5t32 -2.5t18 -1h17.5t29 0.5t29 0.5h16.5t15 -1.5t26.5 -2.5t27 -2t16.5 -1q45 -4 88.5 0.5t89.5 3.5 q1 1 19.5 0t43 -2.5t50 -3.5t41.5 -3q2 0 4.5 -0.5t4.5 -0.5q18 -2 23 -13t4 -27t-5 -32.5t-4 -28.5q0 -3 1 -11.5t2 -18t2 -18t1 -11.5q1 -11 0 -18t-3 -15q-2 -18 3 -37t3 -33q-1 -1 -1 -4v-3q-2 -2 -9 -8t-10 -6q-6 1 -18.5 -1.5t-19.5 -4.5h-18.5h-38h-48.5h-48h-38h-18 h-9t-15 -0.5t-15 -0.5h-9q-3 0 -13.5 -0.5t-22 -1.5t-22 -1.5t-13.5 -1.5q-5 0 -22 0.5t-36.5 1t-36.5 0.5h-22q-31 -1 -45.5 -0.5t-26.5 2t-27 3.5t-47 5q-3 1 -12.5 3.5t-14.5 3.5q-5 3 -9 12.5t-6 13.5z" />
<glyph unicode="&#xf8;" horiz-adv-x="1418" d="M397 -21q5 19 12.5 44t16.5 54q-9 4 -17.5 7.5t-10.5 4.5q-18 7 -34.5 19t-31.5 25t-29 26.5t-26 25.5q-48 45 -86 95t-65 110q-22 48 -35 87.5t-20 78t-9.5 79.5t-2.5 94v75q13 57 30 107.5t41.5 96.5t56.5 88t75 81q31 30 64 52t71 40q3 1 8.5 4t12 5.5t11.5 4.5t7 3 q3 0 15 1.5t14 1.5q3 2 12 8.5t11 8.5q1 0 6.5 1t11.5 2.5t11 2.5t6 2l18 4.5l30 7.5t30.5 7.5t18.5 3.5q8 2 27 4.5t42 4.5q12 42 23 82t22 87q5 8 11.5 7.5t13.5 -3.5q2 -1 4.5 -1.5t4.5 -2.5q3 -2 6 -3t17.5 -5t31.5 -9t32 -9.5t18 -5.5q1 0 5.5 -1.5t9.5 -3.5l10 -4 t6 -2q11 -5 30 -10.5t39 -10t39.5 -9t31.5 -8.5q10 -4 13 -5t13 -4l1 -1q2 -2 8 -12.5t9 -13.5l9 -8q1 -4 2 -17t-1 -15q0 -3 -1.5 -9t-2.5 -13t-2 -13.5t-1 -8.5q-2 -4 -5.5 -13t-8.5 -21q11 -6 19.5 -11.5t12.5 -7.5q3 -2 15.5 -14.5l27.5 -27.5t29 -30t21 -23q1 -2 6 -9 t11.5 -16.5t13 -18.5t10.5 -15q36 -55 59.5 -109t37.5 -109.5t20.5 -114t6.5 -121.5v-4q-2 -17 -4.5 -46.5t-5 -58.5t-4.5 -52t-3 -27q-7 -51 -21.5 -97t-35.5 -91q-19 -24 -30.5 -40.5t-23.5 -32t-27.5 -34t-42.5 -46.5q-35 -26 -74.5 -48t-81.5 -38t-85.5 -25t-85.5 -7 h-15q-7 -22 -12 -47q-4 -7 -11.5 -28t-15 -43.5t-12.5 -40.5t-5 -19q-6 -20 -26 -25.5t-41.5 -4t-38 5.5t-16.5 3l-6 -1q-3 1 -18.5 6t-33.5 10.5t-33 10t-16 5.5q-2 0 -3 0.5l-3 1.5q-16 6 -31 13.5t-30 12.5q-15 6 -24 8.5t-27 4.5q-2 -2 -9.5 -2h-9.5v2q-12 3 -16 16 q0 4 1 15.5t1.5 24t1.5 23t1 14.5l1 2q0 3 1 4q0 1 1 1zM444 715q1 -28 5 -55t15 -53q0 -2 5 -11t5 -11q5 -15 9 -32.5t10 -34.5l62 216q10 66 25.5 128t33.5 125q-43 -13 -81 -37.5t-53 -64.5l-17 -48q-6 -8 -11 -23t-8 -32.5t-3 -35t3 -31.5zM992 856 q-13 -55 -27.5 -114.5t-29.5 -120t-30.5 -120.5t-30.5 -116q34 17 62 43.5t48.5 59t31.5 69t11 74.5q0 3 0.5 24.5t4.5 75.5q0 26 -10.5 51t-18.5 51q-4 11 -11 23z" />
<glyph unicode="&#xf9;" horiz-adv-x="1295" d="M510 1601v3l3 6q1 4 5 6t9 3t9.5 1.5t6.5 0.5h22h1h2q5 0 17 1t14 1q1 1 6.5 2.5t7.5 1.5t7.5 0.5t12 1t12 1t7.5 0.5t8 1.5t8 1.5h1q5 0 13 -2.5t10 -7.5q1 0 2 -3.5t1 -4.5q1 -2 6 -11.5t11 -20t11 -20t6 -11.5t3.5 -8.5t5 -14t4.5 -14.5t2 -8q3 -3 3 -6 q11 -18 14 -32.5t11 -32.5q2 -2 6.5 -12.5t5.5 -12.5v-3q0 -2 0.5 -3t0.5 -2q0 -12 -2 -21.5t-14 -5.5q-1 0 -6 -1.5t-11 -3t-11 -2.5t-6 -1q-14 -2 -25 -5.5t-20.5 -7t-20 -6t-24.5 -2.5q-4 0 -11.5 0.5t-8.5 0.5l-9 6l-2.5 4.5t-5.5 11.5t-6.5 14t-6.5 12 q-14 29 -25.5 58.5t-25.5 57.5q-11 23 -17 43t-17 43v3zM98 471q-2 10 -7 31t-10.5 44.5t-10 44t-5.5 31.5q-1 4 -1.5 17.5t-1.5 29t-1.5 29t-1.5 16.5q0 5 -0.5 13t-1.5 16t-2 15t-2 10l-4 10q-1 2 -1 10.5v18.5t0.5 18t0.5 10q-2 25 -2.5 57t-1 64.5t-0.5 63.5v56 q0 35 0.5 63.5t1.5 54t3.5 49t5.5 48.5q2 11 21.5 18.5t37.5 7.5h47q10 0 25.5 -2t31 -4.5t27.5 -4.5t14 -3q2 0 14 -1t25.5 -2.5t25.5 -3t15 -2.5t14.5 -1.5t25 -0.5t25.5 -0.5t16 -1.5q6 -5 8.5 -9t3 -7.5t0 -9t-0.5 -13.5v-41q-5 -38 -6 -72.5t-1 -74.5q0 -64 2.5 -126.5 t0.5 -136.5l6 -54v-16q5 -25 7 -51t4.5 -52.5t6.5 -53t13 -52.5q2 -5 5.5 -13.5t7.5 -17.5t7 -16.5t4 -8.5q7 -19 23 -33t33.5 -24t33 -15.5t20.5 -6.5q2 -1 14 -5.5t17 -6.5q3 -2 13.5 -0.5t12.5 1.5q18 0 47.5 6.5t61.5 27.5q37 40 54.5 81t24 84t5.5 89.5t-1 98.5v33 q0 5 -0.5 26t-1.5 45.5t-1.5 45.5t-0.5 26v99q-1 5 -2.5 20t-4.5 35.5t-6 43.5t-6 43t-5 34.5t-2 19.5l10 86q4 7 12.5 9.5t18.5 3t19.5 0t16.5 0.5q1 0 6.5 1t11.5 2t11 2t6 1l122 -9q3 -2 15 -2.5t25.5 -0.5h25.5t14 -1q6 1 18.5 2t26 1.5t25 1t15.5 0.5l12 -4 q12 0 18.5 -9.5t10 -25t4.5 -36.5t1 -45v-19q0 -20 -2 -40l-4 -40q-1 -6 -1 -27.5t0.5 -45.5t0.5 -45.5t-1 -27.5q0 -4 -2.5 -20.5t-5.5 -35.5t-5.5 -35.5t-3.5 -20.5q0 -5 -1.5 -24t-3.5 -42.5t-4.5 -46t-3.5 -34.5q0 -2 -1.5 -11.5t-3.5 -20t-4 -20t-3 -11.5v-8.5v-16 t-0.5 -16t-1.5 -8.5q0 -1 -1.5 -6t-3.5 -11t-3.5 -11.5t-1.5 -6.5q-9 -38 -14.5 -70.5t-11 -63t-13 -62t-20.5 -68.5q-7 -21 -24 -48t-36.5 -53.5t-38 -49t-29.5 -32.5q-13 -19 -36 -32.5t-50 -24t-54 -19t-46 -15.5q-32 -13 -65.5 -15.5t-67.5 -2.5q-30 0 -60.5 -0.5 t-61.5 1t-61.5 7.5t-58.5 18q-59 26 -110.5 60.5t-102.5 76.5q-6 5 -15.5 15.5t-20 21.5t-21 20.5t-17.5 12.5q4 -3 -3 15t-21 50q-5 11 -12 33t-13.5 47.5t-12 50t-7.5 39.5z" />
<glyph unicode="&#xfa;" horiz-adv-x="1295" d="M791 1594q-12 -22 -19.5 -42t-19.5 -42q-15 -28 -29 -56.5t-30 -57.5q-3 -5 -6.5 -12.5t-7 -14t-6.5 -11.5l-3 -5l-10 -5q-1 0 -8.5 -0.5t-11.5 -0.5q-14 1 -24 4t-20 6.5l-20 7t-24 5.5q-1 0 -6 1.5t-11 3t-11 3t-6 1.5q-12 -3 -13.5 6.5t-0.5 21.5q0 3 1 5q0 2 1 3 l6 12t7 12q9 18 13 32.5t17 31.5q0 3 3 6q0 1 2.5 8t5.5 14.5t5.5 14t3.5 8.5t6.5 11.5t12.5 20t12.5 20t6.5 11.5q0 1 1.5 4t2.5 3q2 5 10 7.5t13 2.5h1q2 0 8 -2t8 -2q1 0 7 -0.5t12.5 -1.5t12 -1.5t7.5 -0.5t7.5 -1.5t6.5 -2.5q2 0 14 -1t17 -2h2h1h11t11 -1 q1 0 5.5 -0.5t9.5 -1.5t9 -3.5t5 -6.5l3 -6q-1 0 -1 -1v-2v-3v0zM98 471q-2 10 -7 31t-10.5 44.5t-10 44t-5.5 31.5q-1 4 -1.5 17.5t-1.5 29t-1.5 29t-1.5 16.5q0 5 -0.5 13t-1.5 16t-2 15t-2 10l-4 10q-1 2 -1 10.5v18.5t0.5 18t0.5 10q-2 25 -2.5 57t-1 64.5t-0.5 63.5v56 q0 35 0.5 63.5t1.5 54t3.5 49t5.5 48.5q2 11 21.5 18.5t37.5 7.5h47q10 0 25.5 -2t31 -4.5t27.5 -4.5t14 -3q2 0 14 -1t25.5 -2.5t25.5 -3t15 -2.5t14.5 -1.5t25 -0.5t25.5 -0.5t16 -1.5q6 -5 8.5 -9t3 -7.5t0 -9t-0.5 -13.5v-41q-5 -38 -6 -72.5t-1 -74.5q0 -64 2.5 -126.5 t0.5 -136.5l6 -54v-16q5 -25 7 -51t4.5 -52.5t6.5 -53t13 -52.5q2 -5 5.5 -13.5t7.5 -17.5t7 -16.5t4 -8.5q7 -19 23 -33t33.5 -24t33 -15.5t20.5 -6.5q2 -1 14 -5.5t17 -6.5q3 -2 13.5 -0.5t12.5 1.5q18 0 47.5 6.5t61.5 27.5q37 40 54.5 81t24 84t5.5 89.5t-1 98.5v33 q0 5 -0.5 26t-1.5 45.5t-1.5 45.5t-0.5 26v99q-1 5 -2.5 20t-4.5 35.5t-6 43.5t-6 43t-5 34.5t-2 19.5l10 86q4 7 12.5 9.5t18.5 3t19.5 0t16.5 0.5q1 0 6.5 1t11.5 2t11 2t6 1l122 -9q3 -2 15 -2.5t25.5 -0.5h25.5t14 -1q6 1 18.5 2t26 1.5t25 1t15.5 0.5l12 -4 q12 0 18.5 -9.5t10 -25t4.5 -36.5t1 -45v-19q0 -20 -2 -40l-4 -40q-1 -6 -1 -27.5t0.5 -45.5t0.5 -45.5t-1 -27.5q0 -4 -2.5 -20.5t-5.5 -35.5t-5.5 -35.5t-3.5 -20.5q0 -5 -1.5 -24t-3.5 -42.5t-4.5 -46t-3.5 -34.5q0 -2 -1.5 -11.5t-3.5 -20t-4 -20t-3 -11.5v-8.5v-16 t-0.5 -16t-1.5 -8.5q0 -1 -1.5 -6t-3.5 -11t-3.5 -11.5t-1.5 -6.5q-9 -38 -14.5 -70.5t-11 -63t-13 -62t-20.5 -68.5q-7 -21 -24 -48t-36.5 -53.5t-38 -49t-29.5 -32.5q-13 -19 -36 -32.5t-50 -24t-54 -19t-46 -15.5q-32 -13 -65.5 -15.5t-67.5 -2.5q-30 0 -60.5 -0.5 t-61.5 1t-61.5 7.5t-58.5 18q-59 26 -110.5 60.5t-102.5 76.5q-6 5 -15.5 15.5t-20 21.5t-21 20.5t-17.5 12.5q4 -3 -3 15t-21 50q-5 11 -12 33t-13.5 47.5t-12 50t-7.5 39.5z" />
<glyph unicode="&#xfb;" horiz-adv-x="1295" d="M435 1379q-22 4 -25 10t-6 8v1v1q5 13 14.5 27.5t16.5 25.5q4 7 11 18t14.5 24t14 26.5t11.5 25.5q6 8 9.5 16.5t7.5 17.5q11 27 17.5 39t15.5 22q1 1 5 2.5t6 1.5q4 0 16.5 0.5t26 1t25.5 0.5h17h42q1 0 5.5 0.5t9.5 1.5t9.5 1.5t5.5 0.5h5q7 1 10 -0.5t4 -4t1 -6 t2 -5.5q1 -1 2.5 -5.5t1.5 -5.5q1 -2 3.5 -5.5t3.5 -3.5q-4 4 2 -10.5t15.5 -36t20.5 -44t18 -35.5q4 -5 4 -11.5t2 -11.5q4 -10 8 -19.5t9 -20.5q2 -4 7.5 -12t5.5 -14q0 -2 -2.5 -5.5t-4.5 -4.5h-16q-1 0 -3.5 -1.5t-3.5 -1.5t-13.5 -1t-19.5 -1q-26 -2 -48 -9 q-13 -2 -25 -5.5t-25 -3.5q-8 0 -16.5 0.5t-13.5 6.5q-8 14 -12.5 28.5t-14.5 26.5q-2 -2 -3 -3.5t-3 -3.5q-1 -4 -7 -14.5t-8 -12.5q-1 -2 -4.5 -7.5t-9 -11t-12 -9t-13.5 -1.5h-4h-16.5h-12.5t-12.5 1t-15.5 3q-3 1 -11 2t-17 2.5t-16.5 3t-10.5 1.5zM98 471q-2 10 -7 31 t-10.5 44.5t-10 44t-5.5 31.5q-1 4 -1.5 17.5t-1.5 29t-1.5 29t-1.5 16.5q0 5 -0.5 13t-1.5 16t-2 15t-2 10l-4 10q-1 2 -1 10.5v18.5t0.5 18t0.5 10q-2 25 -2.5 57t-1 64.5t-0.5 63.5v56q0 35 0.5 63.5t1.5 54t3.5 49t5.5 48.5q2 11 21.5 18.5t37.5 7.5h47q10 0 25.5 -2 t31 -4.5t27.5 -4.5t14 -3q2 0 14 -1t25.5 -2.5t25.5 -3t15 -2.5t14.5 -1.5t25 -0.5t25.5 -0.5t16 -1.5q6 -5 8.5 -9t3 -7.5t0 -9t-0.5 -13.5v-41q-5 -38 -6 -72.5t-1 -74.5q0 -64 2.5 -126.5t0.5 -136.5l6 -54v-16q5 -25 7 -51t4.5 -52.5t6.5 -53t13 -52.5q2 -5 5.5 -13.5 t7.5 -17.5t7 -16.5t4 -8.5q7 -19 23 -33t33.5 -24t33 -15.5t20.5 -6.5q2 -1 14 -5.5t17 -6.5q3 -2 13.5 -0.5t12.5 1.5q18 0 47.5 6.5t61.5 27.5q37 40 54.5 81t24 84t5.5 89.5t-1 98.5v33q0 5 -0.5 26t-1.5 45.5t-1.5 45.5t-0.5 26v99q-1 5 -2.5 20t-4.5 35.5t-6 43.5 t-6 43t-5 34.5t-2 19.5l10 86q4 7 12.5 9.5t18.5 3t19.5 0t16.5 0.5q1 0 6.5 1t11.5 2t11 2t6 1l122 -9q3 -2 15 -2.5t25.5 -0.5h25.5t14 -1q6 1 18.5 2t26 1.5t25 1t15.5 0.5l12 -4q12 0 18.5 -9.5t10 -25t4.5 -36.5t1 -45v-19q0 -20 -2 -40l-4 -40q-1 -6 -1 -27.5 t0.5 -45.5t0.5 -45.5t-1 -27.5q0 -4 -2.5 -20.5t-5.5 -35.5t-5.5 -35.5t-3.5 -20.5q0 -5 -1.5 -24t-3.5 -42.5t-4.5 -46t-3.5 -34.5q0 -2 -1.5 -11.5t-3.5 -20t-4 -20t-3 -11.5v-8.5v-16t-0.5 -16t-1.5 -8.5q0 -1 -1.5 -6t-3.5 -11t-3.5 -11.5t-1.5 -6.5q-9 -38 -14.5 -70.5 t-11 -63t-13 -62t-20.5 -68.5q-7 -21 -24 -48t-36.5 -53.5t-38 -49t-29.5 -32.5q-13 -19 -36 -32.5t-50 -24t-54 -19t-46 -15.5q-32 -13 -65.5 -15.5t-67.5 -2.5q-30 0 -60.5 -0.5t-61.5 1t-61.5 7.5t-58.5 18q-59 26 -110.5 60.5t-102.5 76.5q-6 5 -15.5 15.5t-20 21.5 t-21 20.5t-17.5 12.5q4 -3 -3 15t-21 50q-5 11 -12 33t-13.5 47.5t-12 50t-7.5 39.5z" />
<glyph unicode="&#xfc;" horiz-adv-x="1295" d="M602 1529v-18t-4 -19q-7 -14 -12 -26.5t-16 -24.5q-6 -7 -19 -16.5t-16 -12.5q-14 -13 -31 -13t-34 -1q-11 -1 -18 1t-18 7q-5 0 -13.5 4t-13.5 7q-26 16 -44.5 40t-21.5 57q0 20 0.5 34t4.5 26t13 23t24 24q14 13 34 23.5t38 11.5q5 1 17 0.5t15 -1.5q6 -1 18.5 -4 t14.5 -4q1 -1 6 -2.5t10.5 -3.5t10.5 -3.5t7 -2.5q28 -21 37 -45t11 -61zM913 1526q0 -8 0.5 -17.5t-3.5 -19.5q-7 -14 -12 -26t-16 -24q-3 -3 -8 -7.5t-10 -8.5l-10 -8t-6 -5q-14 -13 -31.5 -13t-34.5 -1q-11 -1 -17.5 1.5t-17.5 5.5q-5 1 -14 5t-14 8q-26 15 -44 38.5 t-23 56.5q0 20 1 34t5.5 26t13.5 23t24 25q13 13 33 23.5t38 11.5q4 1 17 0.5t16 -1.5q5 -1 17.5 -4.5t15.5 -3.5q1 -1 5.5 -3t10 -3.5t10.5 -3t7 -2.5q28 -22 37.5 -45.5t9.5 -61.5zM98 471q-2 10 -7 31t-10.5 44.5t-10 44t-5.5 31.5q-1 4 -1.5 17.5t-1.5 29t-1.5 29 t-1.5 16.5q0 5 -0.5 13t-1.5 16t-2 15t-2 10l-4 10q-1 2 -1 10.5v18.5t0.5 18t0.5 10q-2 25 -2.5 57t-1 64.5t-0.5 63.5v56q0 35 0.5 63.5t1.5 54t3.5 49t5.5 48.5q2 11 21.5 18.5t37.5 7.5h47q10 0 25.5 -2t31 -4.5t27.5 -4.5t14 -3q2 0 14 -1t25.5 -2.5t25.5 -3t15 -2.5 t14.5 -1.5t25 -0.5t25.5 -0.5t16 -1.5q6 -5 8.5 -9t3 -7.5t0 -9t-0.5 -13.5v-41q-5 -38 -6 -72.5t-1 -74.5q0 -64 2.5 -126.5t0.5 -136.5l6 -54v-16q5 -25 7 -51t4.5 -52.5t6.5 -53t13 -52.5q2 -5 5.5 -13.5t7.5 -17.5t7 -16.5t4 -8.5q7 -19 23 -33t33.5 -24t33 -15.5 t20.5 -6.5q2 -1 14 -5.5t17 -6.5q3 -2 13.5 -0.5t12.5 1.5q18 0 47.5 6.5t61.5 27.5q37 40 54.5 81t24 84t5.5 89.5t-1 98.5v33q0 5 -0.5 26t-1.5 45.5t-1.5 45.5t-0.5 26v99q-1 5 -2.5 20t-4.5 35.5t-6 43.5t-6 43t-5 34.5t-2 19.5l10 86q4 7 12.5 9.5t18.5 3t19.5 0 t16.5 0.5q1 0 6.5 1t11.5 2t11 2t6 1l122 -9q3 -2 15 -2.5t25.5 -0.5h25.5t14 -1q6 1 18.5 2t26 1.5t25 1t15.5 0.5l12 -4q12 0 18.5 -9.5t10 -25t4.5 -36.5t1 -45v-19q0 -20 -2 -40l-4 -40q-1 -6 -1 -27.5t0.5 -45.5t0.5 -45.5t-1 -27.5q0 -4 -2.5 -20.5t-5.5 -35.5 t-5.5 -35.5t-3.5 -20.5q0 -5 -1.5 -24t-3.5 -42.5t-4.5 -46t-3.5 -34.5q0 -2 -1.5 -11.5t-3.5 -20t-4 -20t-3 -11.5v-8.5v-16t-0.5 -16t-1.5 -8.5q0 -1 -1.5 -6t-3.5 -11t-3.5 -11.5t-1.5 -6.5q-9 -38 -14.5 -70.5t-11 -63t-13 -62t-20.5 -68.5q-7 -21 -24 -48t-36.5 -53.5 t-38 -49t-29.5 -32.5q-13 -19 -36 -32.5t-50 -24t-54 -19t-46 -15.5q-32 -13 -65.5 -15.5t-67.5 -2.5q-30 0 -60.5 -0.5t-61.5 1t-61.5 7.5t-58.5 18q-59 26 -110.5 60.5t-102.5 76.5q-6 5 -15.5 15.5t-20 21.5t-21 20.5t-17.5 12.5q4 -3 -3 15t-21 50q-5 11 -12 33 t-13.5 47.5t-12 50t-7.5 39.5z" />
<glyph unicode="&#xfd;" horiz-adv-x="1465" d="M876 1594q-12 -22 -19.5 -42t-19.5 -42q-15 -28 -29 -56.5t-30 -57.5q-3 -5 -6.5 -12.5t-7 -14t-6.5 -11.5l-3 -5l-10 -5q-1 0 -8.5 -0.5t-11.5 -0.5q-14 1 -24 4t-20 6.5l-20 7t-24 5.5q-1 0 -6 1.5t-11 3t-11 3t-6 1.5q-12 -3 -13.5 6.5t-0.5 21.5q0 3 1 5q0 2 1 3 l6 12t7 12q9 18 13 32.5t17 31.5q0 3 3 6q0 1 2.5 8t5.5 14.5t5.5 14t3.5 8.5t6.5 11.5t12.5 20t12.5 20t6.5 11.5q0 1 1.5 4t2.5 3q2 5 10 7.5t13 2.5h1q2 0 8 -2t8 -2q1 0 7 -0.5t12.5 -1.5t12 -1.5t7.5 -0.5t7.5 -1.5t6.5 -2.5q2 0 14 -1t17 -2h2h1h11t11 -1 q1 0 5.5 -0.5t9.5 -1.5t9 -3.5t5 -6.5l3 -6q-1 0 -1 -1v-2v-3v0zM456 -316q17 45 35 86t34.5 80t30.5 76.5t24 75.5v2l-1 2l11 45q1 2 7.5 6t6.5 7q0 2 2.5 8.5l5 13l5 13t3.5 8.5q3 12 5.5 22.5t0.5 21.5l-20 46q-6 34 -24 66t-35 62l-23 33q-2 2 -2 5v3q-17 24 -30 49.5 t-25 51t-24.5 51t-27.5 50.5q-5 6 -17 25.5t-26.5 42t-27.5 43.5t-19 31q-35 54 -67.5 109t-64.5 110.5t-65.5 110t-69.5 107.5q-1 1 -1 2v4q-3 13 13 24q2 0 6 1t6 2q2 0 6.5 6.5t6.5 9.5q2 0 10 1t16.5 2.5t16.5 3t10 2.5q5 1 27 7t47.5 13.5t47.5 14t28 8.5q2 0 4 1 q2 0 3.5 0.5t2.5 0.5q4 0 7 1q3 0 5 1q5 1 15 2t19.5 2t18 1h10.5q3 1 8.5 -1.5t10.5 -5.5q3 -5 10 -17t14.5 -25.5t15 -25.5t10.5 -17q32 -57 69 -109.5t71 -109.5q1 -2 4.5 -9.5t8 -15.5t8 -15t4.5 -8t3.5 -5t5 -8.5l5 -9t3.5 -6.5q2 -3 12.5 -18t22.5 -32.5t23 -33 t14 -19.5q2 -4 11 -21t19.5 -36.5t19.5 -37t12 -21.5q0 -2 3.5 -5.5l5.5 -5.5q2 10 3.5 24.5t3.5 22.5q8 47 18.5 91t26.5 89q8 28 21 55.5t21 55.5q14 42 31 91t32 89q1 3 5 13t9 22t9 22t5 13q4 12 6.5 21t5.5 17t8 15.5t13 16.5q1 0 6.5 1t11.5 2.5t11.5 3t7.5 2.5 q26 4 50.5 4.5t50.5 0.5q5 0 21 1t35 1.5t35 0.5h21q8 1 28 1.5t42 0.5h41.5t27.5 -1q5 -2 15 -7.5t12 -11.5q1 -9 0 -20.5t-4 -23t-6 -22l-5 -17.5q-13 -49 -26.5 -94.5t-28.5 -89.5t-32 -88t-37 -89q-34 -76 -63.5 -162.5t-56.5 -163.5q-11 -33 -28 -71t-34 -69 q-11 -20 -19.5 -40.5t-13.5 -40.5q-4 -18 -7 -31t-7 -25t-9.5 -25t-12.5 -31q-3 -6 -4 -22t0 -24q0 -2 -4.5 -12t-6.5 -12q0 -1 -3 -4.5t-7.5 -8l-8 -8l-4.5 -4.5q0 -2 -2 -9.5t-4.5 -16t-4 -16t-1.5 -9.5q-3 -5 -8.5 -18.5t-11.5 -28.5t-11 -28.5t-8 -18.5q2 -23 0.5 -36 t-16.5 -32l-91 -273q-1 -3 -4.5 -9.5t-8.5 -13t-10 -11.5t-9 -6q-9 -2 -22.5 -3t-21.5 1q-2 1 -8.5 0t-15 -2.5t-16.5 -2.5t-14 1q-4 1 -10 2t-9 0q-5 1 -20 3.5t-32.5 5.5t-33.5 5.5t-21 2.5q-5 -1 -16.5 -1h-13.5t-11 1.5t-20 2.5t-20.5 2t-10.5 1q-6 0 -15 3t-14.5 13 t-5 28t13.5 49z" />
<glyph unicode="&#xfe;" horiz-adv-x="1525" d="M750 128q-13 4 -28.5 11t-31.5 15.5t-30.5 16.5t-26.5 15q-1 1 -5.5 4.5t-10.5 8t-12 9.5t-9 8q-11 7 -16 13t-9.5 12t-11 11t-19.5 9q0 -2 -1.5 -6.5t-1.5 -6.5q-1 -2 -1.5 -7t-1 -11.5t-1 -12t-0.5 -8.5q-1 -4 -3 -25.5t-4.5 -46.5t-4 -46.5t-1.5 -25.5l-11 -13 l-233 -13q-9 5 -18 5t-19 -1l-65 6q-14 -2 -25 -2.5t-21 0.5t-20 4t-23 7q-3 1 -8.5 4.5t-8.5 5.5q-5 2 -11 9.5t-7 12.5q-4 16 -3 43t3 56.5t4.5 56.5t1.5 43q0 6 -0.5 15t-0.5 17.5t-0.5 15t-0.5 7.5l16 470v6q3 65 7 133.5t6 133.5q0 7 -0.5 33t-0.5 55.5t0.5 55.5 t0.5 33q0 18 0.5 23t1 3.5t0.5 -5.5v-5t-0.5 5t-1.5 25q0 3 -0.5 10.5t-1 15.5t-1 15.5t-0.5 9.5v54v77.5t0.5 76.5t2.5 52q3 10 9 12t14 2q12 1 23 -2t24 -2q26 2 51 7.5t50 8.5q37 5 65.5 4.5t62.5 1.5h16q4 0 9 1q25 9 36.5 -4t16 -36.5t5 -51.5t3.5 -50v-10q0 -4 1 -7 l-12 -64l4 -127q19 15 39.5 37t45 43.5t55 39t69.5 24.5q44 14 83.5 20.5t87.5 8.5q79 1 157 -26.5t161 -70.5q8 -7 25.5 -22t37 -31t36.5 -30t23 -19q23 -23 42.5 -44.5t36 -44t30.5 -47.5t27 -54q7 -18 14.5 -41.5t13 -48.5t9 -50t4.5 -46q1 -24 0.5 -43t-2.5 -37 t-4.5 -36.5t-5.5 -42.5q-22 -151 -86.5 -281t-184.5 -227q-29 -24 -56 -41.5t-55.5 -30.5t-60 -22.5t-68.5 -15.5q-2 0 -8.5 -0.5t-9.5 -0.5q-5 -1 -13 -1h-10q-8 0 -29 0.5t-44 1t-43.5 1.5t-27.5 2zM507 731q0 -3 3 -14.5t5 -13.5q9 -34 22 -60.5t31 -48.5t41 -41t52 -38 q23 -14 48 -27t53 -15q2 0 15.5 -2t23.5 -1q0 -2 8.5 0t20 5.5l23 7t17.5 5.5q40 22 67 45.5t54 61.5q4 5 11.5 16.5t15 24.5t13.5 24.5t7 16.5q2 5 6 17.5t8 27t7.5 26.5t3.5 17q1 1 1 11.5v25t0.5 30t0.5 25.5q-1 1 -1 3v5v8l-2.5 15t-2.5 18t-2 16t-2 9q0 2 -2.5 5.5 t-4.5 5.5q-1 1 -4.5 4t-7.5 6.5t-7.5 7l-4.5 4.5q0 2 -0.5 11.5t-0.5 12.5l-2 4q-1 2 -2.5 3.5l-2.5 2.5q-3 3 -13.5 14t-15.5 13q4 11 -6 18t-18 6q-37 24 -66.5 40t-60.5 23.5t-69.5 5t-93.5 -15.5q-47 -20 -79.5 -63t-52.5 -95.5t-28 -108t-6 -100.5v-4z" />
<glyph unicode="&#xff;" horiz-adv-x="1465" d="M707 1513v-18t-4 -19q-7 -14 -12 -26.5t-16 -24.5q-6 -7 -19 -16.5t-16 -12.5q-14 -13 -31 -13t-34 -1q-11 -1 -18 1t-18 7q-5 0 -13.5 4t-13.5 7q-26 16 -44.5 40t-21.5 57q0 20 0.5 34t4.5 26t13 23t24 24q14 13 34 23.5t38 11.5q5 1 17 0.5t15 -1.5q6 -1 18.5 -4 t14.5 -4q1 -1 6 -2.5t10.5 -3.5t10.5 -3.5t7 -2.5q28 -21 37 -45t11 -61zM1018 1510q0 -8 0.5 -17.5t-3.5 -19.5q-7 -14 -12 -26t-16 -24q-3 -3 -8 -7.5t-10 -8.5l-10 -8t-6 -5q-14 -13 -31.5 -13t-34.5 -1q-11 -1 -17.5 1.5t-17.5 5.5q-5 1 -14 5t-14 8q-26 15 -44 38.5 t-23 56.5q0 20 1 34t5.5 26t13.5 23t24 25q13 13 33 23.5t38 11.5q4 1 17 0.5t16 -1.5q5 -1 17.5 -4.5t15.5 -3.5q1 -1 5.5 -3t10 -3.5t10.5 -3t7 -2.5q28 -22 37.5 -45.5t9.5 -61.5zM456 -316q17 45 35 86t34.5 80t30.5 76.5t24 75.5v2l-1 2l11 45q1 2 7.5 6t6.5 7 q0 2 2.5 8.5l5 13l5 13t3.5 8.5q3 12 5.5 22.5t0.5 21.5l-20 46q-6 34 -24 66t-35 62l-23 33q-2 2 -2 5v3q-17 24 -30 49.5t-25 51t-24.5 51t-27.5 50.5q-5 6 -17 25.5t-26.5 42t-27.5 43.5t-19 31q-35 54 -67.5 109t-64.5 110.5t-65.5 110t-69.5 107.5q-1 1 -1 2v4 q-3 13 13 24q2 0 6 1t6 2q2 0 6.5 6.5t6.5 9.5q2 0 10 1t16.5 2.5t16.5 3t10 2.5q5 1 27 7t47.5 13.5t47.5 14t28 8.5q2 0 4 1q2 0 3.5 0.5t2.5 0.5q4 0 7 1q3 0 5 1q5 1 15 2t19.5 2t18 1h10.5q3 1 8.5 -1.5t10.5 -5.5q3 -5 10 -17t14.5 -25.5t15 -25.5t10.5 -17 q32 -57 69 -109.5t71 -109.5q1 -2 4.5 -9.5t8 -15.5t8 -15t4.5 -8t3.5 -5t5 -8.5l5 -9t3.5 -6.5q2 -3 12.5 -18t22.5 -32.5t23 -33t14 -19.5q2 -4 11 -21t19.5 -36.5t19.5 -37t12 -21.5q0 -2 3.5 -5.5l5.5 -5.5q2 10 3.5 24.5t3.5 22.5q8 47 18.5 91t26.5 89q8 28 21 55.5 t21 55.5q14 42 31 91t32 89q1 3 5 13t9 22t9 22t5 13q4 12 6.5 21t5.5 17t8 15.5t13 16.5q1 0 6.5 1t11.5 2.5t11.5 3t7.5 2.5q26 4 50.5 4.5t50.5 0.5q5 0 21 1t35 1.5t35 0.5h21q8 1 28 1.5t42 0.5h41.5t27.5 -1q5 -2 15 -7.5t12 -11.5q1 -9 0 -20.5t-4 -23t-6 -22 l-5 -17.5q-13 -49 -26.5 -94.5t-28.5 -89.5t-32 -88t-37 -89q-34 -76 -63.5 -162.5t-56.5 -163.5q-11 -33 -28 -71t-34 -69q-11 -20 -19.5 -40.5t-13.5 -40.5q-4 -18 -7 -31t-7 -25t-9.5 -25t-12.5 -31q-3 -6 -4 -22t0 -24q0 -2 -4.5 -12t-6.5 -12q0 -1 -3 -4.5t-7.5 -8 l-8 -8l-4.5 -4.5q0 -2 -2 -9.5t-4.5 -16t-4 -16t-1.5 -9.5q-3 -5 -8.5 -18.5t-11.5 -28.5t-11 -28.5t-8 -18.5q2 -23 0.5 -36t-16.5 -32l-91 -273q-1 -3 -4.5 -9.5t-8.5 -13t-10 -11.5t-9 -6q-9 -2 -22.5 -3t-21.5 1q-2 1 -8.5 0t-15 -2.5t-16.5 -2.5t-14 1q-4 1 -10 2t-9 0 q-5 1 -20 3.5t-32.5 5.5t-33.5 5.5t-21 2.5q-5 -1 -16.5 -1h-13.5t-11 1.5t-20 2.5t-20.5 2t-10.5 1q-6 0 -15 3t-14.5 13t-5 28t13.5 49z" />
<glyph unicode="&#x152;" horiz-adv-x="2068" d="M1151 16q-2 1 -11 2.5t-19.5 4t-20.5 4t-13 2.5h-16q-2 0 -6 -3t-6 -3q-8 0 -16.5 10t-12.5 12q-8 4 -15 5l1 -7q-11 1 -33.5 0t-51 -3t-60 -4t-60 -3.5t-51.5 -1.5t-35 2q-49 9 -104 27t-109 43t-103.5 55t-87.5 62q-5 4 -19 17.5t-29.5 29t-30.5 29.5t-21 20 q-2 2 -7 6.5t-10.5 9t-10 9t-5.5 6.5q-8 -2 -12.5 -0.5t-9.5 8.5q-6 11 -5 22.5t-5 23.5q-8 18 -14.5 31.5t-12.5 26t-12 26t-13 30.5q-2 2 -6.5 11.5t-4.5 11.5v16q-1 4 -4.5 13.5t-7.5 21t-7.5 21.5t-4.5 14q-3 8 -7 12t-4 9v4q0 1 1 3q0 2 3 8.5t3 7.5t-1 5t-2 8.5 t-2 8.5t-1 5q-1 6 -2.5 16.5t-3 22t-3 20t-2.5 10.5q0 3 0.5 14.5t1.5 24t1.5 23.5t0.5 14q-1 3 -2.5 14.5t-3.5 25.5t-3.5 26t-1.5 15v74q1 6 2.5 21.5t3.5 32t3.5 31.5t3.5 21q0 1 1 6t2.5 11t3 11.5t2.5 8.5q13 37 27 68t30 60t35 56.5t42 57.5q3 3 14 17t23.5 30.5 t24 30.5t14.5 18q21 24 45.5 40.5t50.5 34.5q50 33 101.5 62t107.5 52l13.5 4.5t14.5 4.5q42 11 86 18.5t90 12.5q-2 -6 16.5 -7.5t47.5 -0.5t64.5 3.5t67.5 5.5t57 5.5t33 2.5h21q3 0 12.5 3t11.5 3q97 14 196.5 15.5t196.5 1.5q98 0 192 -9t191 -14q7 -4 10.5 -9 t6.5 -10.5t6.5 -11t10.5 -10.5q1 -8 2.5 -27.5t3 -41t2.5 -41.5t1 -27v-7.5t0.5 -14.5t0.5 -16.5v-12.5q0 -3 -0.5 -10.5t-1 -16t-1 -16t-0.5 -10.5q-9 -15 -15.5 -25.5t-20 -17.5t-39.5 -10.5t-76 -4.5q-3 0 -12 0.5t-19.5 0.5t-20.5 0.5t-14 0.5q-6 0 -16.5 -0.5t-21 -0.5 t-18.5 -0.5t-9 -0.5q-31 -1 -77 -2.5t-89 -3.5q-50 -2 -104 -4l-8 -12q-1 -2 -3.5 -19t-5.5 -40t-6 -46.5t-5 -38.5v-11.5t-1 -14.5v-19.5t6 -17.5q2 -2 6 -4t6 -2q47 -7 97 -9t96 -2h14q3 0 16 1t27.5 1.5t27 1.5t15.5 1h4q42 0 78 -8.5t79 -14.5q9 -2 20.5 -2.5t22 -2.5 t19 -7.5t12.5 -16.5q2 -7 5.5 -18l7 -22t6.5 -19.5t3 -9.5q-3 -20 0 -40l6 -40t3.5 -40t-6.5 -40q-5 -25 -29.5 -41.5t-82.5 -22.5h-62q-6 0 -30.5 -1t-52.5 -2t-52.5 -2t-30.5 -1q-12 0 -40.5 0.5t-60 0.5t-59.5 0.5t-39 0.5q-1 -51 -6.5 -102.5t-6.5 -103.5q0 -7 -0.5 -21 t-0.5 -16q1 -5 2.5 -18.5t3 -29.5t3 -30.5t1.5 -20.5l2.5 -12.5t3.5 -14.5t3.5 -12.5t2.5 -5.5l35 -6l483 3q22 1 35.5 0.5t21.5 -3t11 -5.5t5 -7q1 -12 1 -23v-34q0 -9 -0.5 -23.5l-1 -29t-1 -26t-0.5 -14.5q0 -2 -1 -7.5t-2.5 -12t-2.5 -12t-1 -7.5v-28q-2 -15 0 -31.5 t1.5 -33t-6 -31t-21.5 -25.5q-86 -8 -170.5 -19.5t-171.5 -11.5q-43 0 -83.5 4t-83.5 4q-17 7 -34.5 3t-34 -9t-32 -6.5t-28.5 10.5h-156zM770 366q1 0 27.5 0.5t62 1.5t71.5 2t54 1v4q2 54 5.5 107.5t4.5 107.5v14q0 1 -1 6.5t-1.5 11t-1.5 10.5t-1 7v10.5t0.5 18t0.5 18 v10.5q0 4 -1 13t-3 19t-4 19t-3 13q-14 289 -21 579q-20 3 -43 6.5t-43.5 7.5t-35 7.5t-15.5 6.5q-9 -2 -31 -6.5t-46.5 -9.5t-46 -9.5t-30.5 -7.5q-38 -9 -67 -23.5t-53 -34t-45.5 -44.5t-45.5 -55q-14 -19 -26 -39.5t-16 -43.5q-8 -29 -12.5 -51t-6.5 -41.5t-2.5 -37.5 t0.5 -37q4 -17 6 -41.5t3.5 -51.5t3 -55.5t4.5 -53.5q15 -6 22 -19t2 -25q3 -5 9.5 -19.5t14 -31.5t14 -32t9.5 -21q1 -2 3 -7.5t4.5 -12.5t5 -12.5t4.5 -6.5l9 -10q1 -2 4.5 -8.5t7 -14t6.5 -14.5t4 -8q2 -3 8 -9.5t8 -6.5q2 -1 11 3.5t11 6.5h1q6 -1 9.5 -7.5t5.5 -10.5 v-38q6 -8 11.5 -11.5t11.5 -4.5t13.5 -1.5t16.5 -2.5q3 0 4 -3.5t2.5 -7t5.5 -7t14 -4.5q6 -1 21 -3t32 -4t32 -4t22 -2z" />
<glyph unicode="&#x153;" horiz-adv-x="2148" d="M987 1148q5 6 10.5 13.5t7.5 9.5q42 36 92.5 65t105 50t111 32.5t111.5 12.5q62 5 129 -2t125 -33q49 -15 84.5 -34t60 -37t40.5 -32.5t28 -20.5q31 -27 56 -53t45.5 -54t38.5 -59.5t35 -70.5q3 -9 8.5 -32.5t11.5 -49.5t11 -49.5t6 -32.5q1 -2 1.5 -9t0.5 -17v-19.5 v-15.5t-0.5 -16.5t-0.5 -21v-18.5t-1 -9q0 -3 -3 -12.5t-6 -20t-5.5 -20t-2.5 -11.5q-20 -20 -40.5 -27.5t-48 -9.5t-66 -2.5t-93.5 -6.5h-19h-33t-33 -0.5t-19 -0.5h-10q-2 -2 -8.5 -3t-13.5 -0.5t-12.5 2.5t-6.5 6q-1 0 -9 -0.5t-17.5 -0.5h-19t-12.5 1q-1 -1 -3 -1h-5 q-24 -1 -55 -2t-63.5 -2t-63.5 -1.5t-55 -0.5q-36 -2 -64.5 -0.5t-55 3t-55 2.5t-64.5 0q-5 0 -10 -0.5t-7 -5.5q0 -5 2.5 -15t2.5 -13q9 -36 12.5 -51.5t6.5 -22t7.5 -11t14.5 -18.5q0 -1 3.5 -4.5t8 -7.5t8 -7.5t3.5 -4.5q33 -53 87 -76.5t111 -21.5q8 0 22 0.5t16 0.5 q19 2 28.5 1.5t15.5 -1.5t12.5 -1.5t21 1.5t40 7.5t70.5 16.5q1 0 11 5t21.5 11t22 11.5t12.5 6.5q26 16 47 31.5t38.5 28.5t33 23t30.5 16h6q2 1 6 -1.5t4 -4.5q9 -8 27 -20.5t36.5 -25.5t35.5 -25.5t25 -21.5q3 -2 14 -10t23 -17.5t21 -18t9 -9.5v-4q0 -2 0.5 -3t0.5 -3 q1 -25 -14.5 -44t-32.5 -37q-47 -51 -99.5 -99.5t-114.5 -80.5q-20 -9 -40 -13.5t-40 -11.5q-26 -8 -50 -11.5t-47 -4.5t-47.5 -0.5t-52.5 -0.5q-72 -2 -137 5t-134 27q-26 8 -48 17.5t-41.5 21t-38.5 26t-39 31.5l-14 12t-14 11q-7 -5 -20.5 -15.5t-30.5 -23t-35.5 -26 t-35 -23.5t-29.5 -16t-18 -4l-78 -32h-6q-2 0 -7 -1t-10.5 -2.5t-11 -2.5t-6.5 -1h-61h-34t-28.5 1t-28 2t-32.5 4q-2 1 -10.5 3t-18 4t-18 3.5t-10.5 1.5h-52l-33 13q-7 3 -21.5 11t-31 17t-31.5 17t-22 11q-6 3 -18 8.5t-24.5 12t-23.5 11.5t-14 7q-1 1 -5 4.5t-9.5 8.5 t-11 9.5t-8.5 6.5q-25 25 -48 55t-46 57q-21 25 -35 66t-23 86.5t-13 89.5t-4 76q0 41 0.5 76t4 68.5t10.5 67.5t20 73q1 6 7.5 25.5t13.5 39t12 31.5t4 1q16 46 42 85.5t59 73.5t71.5 63t79.5 54q4 3 18.5 10.5t31 15.5t32 15.5t21.5 9.5q1 1 6.5 2.5t13 3.5t15 3.5 l12.5 2.5q6 2 16 4t12 2h197q32 -9 67.5 -21t70.5 -27t67 -33t57 -40zM785 682q6 37 15 72.5t20 71.5q8 26 13.5 46t13.5 45q0 1 1.5 7.5t3.5 14t5 15.5t5 14q-27 18 -46.5 24.5t-33 7.5t-22.5 -1.5t-13 -2.5q-6 9 -18 10.5t-26.5 0t-28.5 -4.5t-23 -3q-15 0 -32 -5.5 t-32.5 -14.5t-30 -20t-25.5 -23q-2 -2 -8.5 -10t-14 -16.5t-14.5 -16.5t-8 -10q-38 -42 -53 -99q-9 -40 -12.5 -80.5t-3.5 -82.5q0 -53 17.5 -98t45.5 -89q2 -3 6 -9.5t6 -6.5q24 -26 49.5 -50t54 -42.5t60.5 -29.5t70 -11q27 0 64 12t67 24q-10 19 -21.5 42.5t-16.5 37.5 q-2 2 -4 8t-2 8q-12 66 -20.5 129t-7.5 131v5zM1497 1002q-51 -1 -95 -12.5t-86 -40.5q-14 -9 -31.5 -23t-34 -30.5t-27.5 -35t-11 -36.5q26 2 48 6t47 5h4q2 -1 12.5 -1.5t23 -1t23.5 -1t14 -0.5h13h27h31h25t25 1t32.5 2t29.5 1.5t15 0.5q10 0 36.5 0.5t56.5 1t56.5 1.5 t36.5 2q2 0 4 2l2 2q0 2 -2 6t-4 6q-2 4 -5.5 10.5t-7.5 13t-7 11t-4 5.5q-44 55 -111.5 81t-135.5 24z" />
<glyph unicode="&#x178;" horiz-adv-x="1485" d="M675 1896v-18t-4 -19q-7 -14 -12 -26.5t-16 -24.5q-6 -7 -19 -16.5t-16 -12.5q-14 -13 -31 -13t-34 -1q-11 -1 -18 1t-18 7q-5 0 -13.5 4t-13.5 7q-26 16 -44.5 40t-21.5 57q0 20 0.5 34t4.5 26t13 23t24 24q14 13 34 23.5t38 11.5q5 1 17 0.5t15 -1.5q6 -1 18.5 -4 t14.5 -4q1 -1 6 -2.5t10.5 -3.5t10.5 -3.5t7 -2.5q28 -21 37 -45t11 -61zM986 1893q0 -8 0.5 -17.5t-3.5 -19.5q-7 -14 -12 -26t-16 -24q-3 -3 -8 -7.5t-10 -8.5l-10 -8t-6 -5q-14 -13 -31.5 -13t-34.5 -1q-11 -1 -17.5 1.5t-17.5 5.5q-5 1 -14 5t-14 8q-26 15 -44 38.5 t-23 56.5q0 20 1 34t5.5 26t13.5 23t24 25q13 13 33 23.5t38 11.5q4 1 17 0.5t16 -1.5q5 -1 17.5 -4.5t15.5 -3.5q1 -1 5.5 -3t10 -3.5t10.5 -3t7 -2.5q28 -22 37.5 -45.5t9.5 -61.5zM528 39q7 32 5 55t-2 55q0 74 3.5 152.5t-2.5 150.5q0 5 0.5 23t1.5 38.5t1.5 38 t0.5 22.5q0 2 -1 18.5t-1 24.5q0 47 2.5 98t2.5 99v2q-2 3 -11 12.5t-11 11.5t-6.5 11.5t-6.5 11.5q-48 77 -98.5 158.5t-92.5 163.5q-5 7 -16.5 24.5t-24.5 36.5t-24.5 36t-15.5 24q-14 29 -28 63t-37 57q-4 8 -12.5 22.5t-18 30t-18 29t-12.5 21.5q-11 25 -23.5 54 t-21.5 55v4q0 14 7.5 21t17.5 9.5t17.5 2.5h7.5q3 1 17 1h30.5t30.5 -0.5t18 -0.5t17.5 2t32 4t39 5t38.5 5l31.5 3.5t17.5 2.5q21 0 27.5 -4.5t13.5 -13.5q9 -15 20 -30.5t22.5 -32t21.5 -33t17 -31.5q23 -53 42.5 -96.5t46.5 -93.5q3 -4 11.5 -19t18.5 -33t19 -33t11 -19 q6 -11 12 -27.5t13 -33t15.5 -31.5t18.5 -22q1 1 5 10.5t8.5 20.5t8.5 20t5 11q2 5 12 23t21.5 38t21.5 37.5t12 22.5q2 2 9 12t15 22l15 22.5l9 13.5q1 1 2.5 5t3 8.5t3 8.5t1.5 6q1 3 5 11.5t8.5 18t8.5 17.5t6 11q-5 12 3.5 19.5t15.5 15.5q11 12 18 29.5t17 31.5 q1 3 8 12.5t14.5 20t14 19.5t8.5 12q9 13 16 22t15 14.5t19 8t28 2.5q22 0 41.5 -2.5t39 -6t39 -7.5t42.5 -6q22 -1 47.5 -1t50 -2.5t46 -9.5t34.5 -20q5 -6 5.5 -11t0.5 -11v-6q-41 -86 -87 -162t-94 -150t-97 -149t-95 -158q-2 -3 -9.5 -16t-9.5 -16q-17 -24 -30.5 -45.5 t-26 -43t-24.5 -44.5t-25 -49q-5 0 -5.5 -8t0 -17.5t2 -19t1.5 -12.5q0 -5 0.5 -14.5t0.5 -18.5t0.5 -16t0.5 -8q0 -3 0.5 -11t1.5 -18l2 -20t2 -15q4 -33 3.5 -81.5t-1 -100t0 -99.5t6.5 -80l-8 -132q1 -3 1.5 -9.5t1.5 -14t1.5 -14t1.5 -9.5v-8q0 -8 -5.5 -12.5t-13 -7.5 t-15.5 -4.5t-13 -2.5q-4 0 -17.5 -1t-29 -2.5t-29 -2.5t-17.5 -1q-8 0 -27.5 -0.5t-40.5 -1.5t-39.5 -1.5t-25.5 -0.5q-26 -3 -54 -1.5t-56 1.5q-8 0 -14 9.5t-6 17.5v2z" />
<glyph unicode="&#x2c6;" horiz-adv-x="460" d="M38 1372q-22 4 -25 10t-6 8v1v1q5 13 14.5 27.5t16.5 25.5q4 7 11 18t14.5 24t14 26.5t11.5 25.5q6 8 9.5 16.5t7.5 17.5q11 27 17.5 39t15.5 22q1 1 5 2.5t6 1.5q4 0 16.5 0.5t26 1t25.5 0.5h17h42q1 0 5.5 0.5t9.5 1.5t9.5 1.5t5.5 0.5h5q7 1 10 -0.5t4 -4t1 -6t2 -5.5 q1 -1 2.5 -5.5t1.5 -5.5q1 -2 3.5 -5.5t3.5 -3.5q-4 4 2 -10.5t15.5 -36t20.5 -44t18 -35.5q4 -5 4 -11.5t2 -11.5q4 -10 8 -19.5t9 -20.5q2 -4 7.5 -12t5.5 -14q0 -2 -2.5 -5.5t-4.5 -4.5h-16q-1 0 -3.5 -1.5t-3.5 -1.5t-13.5 -1t-19.5 -1q-26 -2 -48 -9q-13 -2 -25 -5.5 t-25 -3.5q-8 0 -16.5 0.5t-13.5 6.5q-8 14 -12.5 28.5t-14.5 26.5q-2 -2 -3 -3.5t-3 -3.5q-1 -4 -7 -14.5t-8 -12.5q-1 -2 -4.5 -7.5t-9 -11t-12 -9t-13.5 -1.5h-4h-16.5h-12.5t-12.5 1t-15.5 3q-3 1 -11 2t-17 2.5t-16.5 3t-10.5 1.5z" />
<glyph unicode="&#x2dc;" horiz-adv-x="886" d="M40 1462q0 1 -1.5 3.5t-1.5 3.5t3 5t5 5v5q12 32 37.5 56.5t48.5 49.5q2 1 8.5 8t8.5 8q29 30 67.5 53t80.5 23q18 0 33.5 -1.5t32.5 -9.5q10 -4 20.5 -10.5t21.5 -6.5l31 -22q4 -2 14.5 -8t22.5 -12t22.5 -11.5t14.5 -7.5q11 -6 19.5 -7t19.5 -1q15 0 34 13.5t28 26.5 q3 3 8 10t10.5 14.5t9.5 13.5t5 8q5 8 9 13t15 5h3q1 -1 6.5 -5.5t7.5 -6.5q14 -14 30 -26t30.5 -21.5t26.5 -17.5t20 -15q6 -7 12.5 -12t9.5 -10t2 -11t-8 -15q-9 -15 -18.5 -27.5t-20.5 -28.5q-20 -26 -41.5 -51.5t-47 -45.5t-55 -32t-64.5 -12q-9 -1 -26 3.5t-34.5 11.5 t-33.5 14t-24 12q-2 3 -11 12t-12 11q-17 14 -34 19.5t-40 5.5q-27 0 -51.5 -13t-42.5 -37q-7 -11 -12.5 -18.5t-12 -12.5t-15 -7.5t-22.5 -2.5q-3 0 -8 1t-7 1q-1 0 -6 4.5t-7 4.5q-2 2 -5.5 4t-4.5 4q-17 11 -29 18t-27 22q-1 0 -7 4q-3 2 -6 5q-3 2 -8.5 8.5t-12.5 13.5 t-12.5 13t-8.5 9z" />
<glyph unicode="&#x2000;" horiz-adv-x="1045" />
<glyph unicode="&#x2001;" horiz-adv-x="2090" />
<glyph unicode="&#x2002;" horiz-adv-x="1045" />
<glyph unicode="&#x2003;" horiz-adv-x="2090" />
<glyph unicode="&#x2004;" horiz-adv-x="696" />
<glyph unicode="&#x2005;" horiz-adv-x="522" />
<glyph unicode="&#x2006;" horiz-adv-x="348" />
<glyph unicode="&#x2007;" horiz-adv-x="348" />
<glyph unicode="&#x2008;" horiz-adv-x="261" />
<glyph unicode="&#x2009;" horiz-adv-x="418" />
<glyph unicode="&#x200a;" horiz-adv-x="116" />
<glyph unicode="&#x2010;" horiz-adv-x="802" d="M67 748q-2 10 -1 20.5t0 20.5q0 3 0.5 14t1.5 24t1.5 24t0.5 14q0 30 -2 59.5t1 58.5q1 15 16 25.5t28 11.5q4 0 18.5 -2t31.5 -3.5t32 -2.5t18 -1h17.5t29 0.5t29 0.5h16.5t15 -1.5t26.5 -2.5t27 -2t16.5 -1q45 -4 88.5 0.5t89.5 3.5q1 1 19.5 0t43 -2.5t50 -3.5 t41.5 -3q2 0 4.5 -0.5t4.5 -0.5q18 -2 23 -13t4 -27t-5 -32.5t-4 -28.5q0 -3 1 -11.5t2 -18t2 -18t1 -11.5q1 -11 0 -18t-3 -15q-2 -18 3 -37t3 -33q-1 -1 -1 -4v-3q-2 -2 -9 -8t-10 -6q-6 1 -18.5 -1.5t-19.5 -4.5h-18.5h-38h-48.5h-48h-38h-18h-9t-15 -0.5t-15 -0.5h-9 q-3 0 -13.5 -0.5t-22 -1.5t-22 -1.5t-13.5 -1.5q-5 0 -22 0.5t-36.5 1t-36.5 0.5h-22q-31 -1 -45.5 -0.5t-26.5 2t-27 3.5t-47 5q-3 1 -12.5 3.5t-14.5 3.5q-5 3 -9 12.5t-6 13.5z" />
<glyph unicode="&#x2011;" horiz-adv-x="802" d="M67 748q-2 10 -1 20.5t0 20.5q0 3 0.5 14t1.5 24t1.5 24t0.5 14q0 30 -2 59.5t1 58.5q1 15 16 25.5t28 11.5q4 0 18.5 -2t31.5 -3.5t32 -2.5t18 -1h17.5t29 0.5t29 0.5h16.5t15 -1.5t26.5 -2.5t27 -2t16.5 -1q45 -4 88.5 0.5t89.5 3.5q1 1 19.5 0t43 -2.5t50 -3.5 t41.5 -3q2 0 4.5 -0.5t4.5 -0.5q18 -2 23 -13t4 -27t-5 -32.5t-4 -28.5q0 -3 1 -11.5t2 -18t2 -18t1 -11.5q1 -11 0 -18t-3 -15q-2 -18 3 -37t3 -33q-1 -1 -1 -4v-3q-2 -2 -9 -8t-10 -6q-6 1 -18.5 -1.5t-19.5 -4.5h-18.5h-38h-48.5h-48h-38h-18h-9t-15 -0.5t-15 -0.5h-9 q-3 0 -13.5 -0.5t-22 -1.5t-22 -1.5t-13.5 -1.5q-5 0 -22 0.5t-36.5 1t-36.5 0.5h-22q-31 -1 -45.5 -0.5t-26.5 2t-27 3.5t-47 5q-3 1 -12.5 3.5t-14.5 3.5q-5 3 -9 12.5t-6 13.5z" />
<glyph unicode="&#x2012;" horiz-adv-x="802" d="M67 748q-2 10 -1 20.5t0 20.5q0 3 0.5 14t1.5 24t1.5 24t0.5 14q0 30 -2 59.5t1 58.5q1 15 16 25.5t28 11.5q4 0 18.5 -2t31.5 -3.5t32 -2.5t18 -1h17.5t29 0.5t29 0.5h16.5t15 -1.5t26.5 -2.5t27 -2t16.5 -1q45 -4 88.5 0.5t89.5 3.5q1 1 19.5 0t43 -2.5t50 -3.5 t41.5 -3q2 0 4.5 -0.5t4.5 -0.5q18 -2 23 -13t4 -27t-5 -32.5t-4 -28.5q0 -3 1 -11.5t2 -18t2 -18t1 -11.5q1 -11 0 -18t-3 -15q-2 -18 3 -37t3 -33q-1 -1 -1 -4v-3q-2 -2 -9 -8t-10 -6q-6 1 -18.5 -1.5t-19.5 -4.5h-18.5h-38h-48.5h-48h-38h-18h-9t-15 -0.5t-15 -0.5h-9 q-3 0 -13.5 -0.5t-22 -1.5t-22 -1.5t-13.5 -1.5q-5 0 -22 0.5t-36.5 1t-36.5 0.5h-22q-31 -1 -45.5 -0.5t-26.5 2t-27 3.5t-47 5q-3 1 -12.5 3.5t-14.5 3.5q-5 3 -9 12.5t-6 13.5z" />
<glyph unicode="&#x2013;" horiz-adv-x="802" d="M67 748q-2 10 -1 20.5t0 20.5q0 3 0.5 14t1.5 24t1.5 24t0.5 14q0 30 -2 59.5t1 58.5q1 15 16 25.5t28 11.5q4 0 18.5 -2t31.5 -3.5t32 -2.5t18 -1h17.5t29 0.5t29 0.5h16.5t15 -1.5t26.5 -2.5t27 -2t16.5 -1q45 -4 88.5 0.5t89.5 3.5q1 1 19.5 0t43 -2.5t50 -3.5 t41.5 -3q2 0 4.5 -0.5t4.5 -0.5q18 -2 23 -13t4 -27t-5 -32.5t-4 -28.5q0 -3 1 -11.5t2 -18t2 -18t1 -11.5q1 -11 0 -18t-3 -15q-2 -18 3 -37t3 -33q-1 -1 -1 -4v-3q-2 -2 -9 -8t-10 -6q-6 1 -18.5 -1.5t-19.5 -4.5h-18.5h-38h-48.5h-48h-38h-18h-9t-15 -0.5t-15 -0.5h-9 q-3 0 -13.5 -0.5t-22 -1.5t-22 -1.5t-13.5 -1.5q-5 0 -22 0.5t-36.5 1t-36.5 0.5h-22q-31 -1 -45.5 -0.5t-26.5 2t-27 3.5t-47 5q-3 1 -12.5 3.5t-14.5 3.5q-5 3 -9 12.5t-6 13.5z" />
<glyph unicode="&#x2014;" horiz-adv-x="832" d="M67 748q-2 10 -1 20.5t0 20.5q0 3 0.5 14t1.5 24t1.5 24t0.5 14q0 30 -2 59.5t1 58.5q1 15 16 25.5t28 11.5q4 0 18.5 -2t31.5 -3.5t32 -2.5t18 -1h17.5t29 0.5t29 0.5h16.5t15 -1.5t26.5 -2.5t27 -2t16.5 -1q45 -4 88.5 0.5t89.5 3.5q1 1 26.5 1.5t58.5 1t65 0t48 -1.5 q2 0 4.5 -0.5t4.5 -0.5q18 -2 23 -13t4 -27t-5 -32.5t-4 -28.5q0 -3 1 -11.5t2 -18t2 -18t1 -11.5q1 -11 0 -18t-3 -15q-2 -18 3 -37t3 -33q-1 -1 -1 -4v-3q-2 -2 -9 -8t-10 -6q-6 1 -18.5 -1.5t-19.5 -4.5q-2 0 -21.5 -0.5t-46.5 -1.5t-58.5 -2.5t-59 -2.5t-46.5 -2t-21 -1 h-9t-15 -0.5t-15 -0.5h-9q-3 0 -13.5 -0.5t-22 -1.5t-22 -1.5t-13.5 -1.5q-5 0 -22 0.5t-36.5 1t-36.5 0.5h-22q-31 -1 -45.5 -0.5t-26.5 2t-27 3.5t-47 5q-3 1 -12.5 3.5t-14.5 3.5q-5 3 -9 12.5t-6 13.5z" />
<glyph unicode="&#x2018;" horiz-adv-x="586" d="M469 1475l-3.5 -7t-6 -10.5t-6 -11t-3.5 -6.5q-14 -34 -24 -64t-18 -60t-14.5 -62t-12.5 -68q0 -3 -1 -12.5t-2 -20t-2 -19.5t-1 -12q9 0 13.5 2t8.5 4.5t8.5 5t12.5 4.5q34 6 68 6q11 0 26 -8.5t15 -22.5q0 -63 -0.5 -117t1.5 -116q-2 -5 -2 -11t-1.5 -12t-6.5 -11.5 t-15 -9.5h-76q-3 0 -11.5 -0.5t-18 -1.5t-18 -2t-12.5 -2q-5 0 -23 0.5t-39.5 0.5h-40t-22.5 -1q-2 0 -11 -0.5t-18.5 -1.5t-18 -1.5t-9.5 -0.5q-2 0 -12.5 -1t-16.5 -1q-11 0 -23.5 0.5t-23.5 5.5q-12 6 -18.5 24t-9.5 38.5t-4 39t-1 27.5v14q0 2 3 6.5t3 6.5q1 2 2 10 t2 17t1.5 17.5t0.5 12.5q-1 10 1.5 27.5t7 34t10 29t10.5 11.5q14 26 22.5 54.5t22.5 56.5q18 32 41 65t49.5 63t57 54.5t65.5 39.5q2 1 9.5 4.5t17 8t18.5 8t14 5.5q9 3 12.5 4.5t11.5 1.5q10 0 10.5 -6t0.5 -14v-15z" />
<glyph unicode="&#x2019;" horiz-adv-x="586" d="M135 859q1 1 3.5 6.5t6 11t6 10.5l3.5 7q14 34 24 64t18 60t14.5 62t12.5 68q0 3 1 12t2 19.5t2 20t1 12.5q-9 0 -13.5 -2t-8.5 -4.5t-8.5 -5t-12.5 -4.5q-35 -6 -68 -6q-11 0 -26 8.5t-15 22.5q0 63 0.5 117t-1.5 116q2 4 2 10.5t1.5 12.5t6 11.5t15.5 9.5h76 q3 0 11.5 0.5t18 1.5t18 2t12.5 2q4 0 22.5 -0.5t40 -0.5h39.5t23 1q2 0 10.5 0.5t18.5 1.5t18 1.5t10 0.5t12.5 1t16.5 1q11 0 23.5 -0.5t23.5 -5.5q12 -6 18.5 -24t9.5 -38.5t4 -39t1 -27.5v-14q0 -2 -3 -6.5t-3 -6.5q-1 -2 -2 -10t-2 -17t-1.5 -17.5t-0.5 -12.5 q1 -10 -1.5 -27.5t-7 -34t-10 -29t-10.5 -11.5q-14 -26 -22.5 -54.5t-22.5 -56.5q-18 -32 -41 -65t-49.5 -63t-57.5 -54.5t-65 -39.5q-2 -1 -9.5 -4.5t-17 -8t-19 -8.5t-13.5 -5q-9 -3 -12.5 -4.5t-11.5 -1.5q-10 0 -10.5 6t-0.5 14v15z" />
<glyph unicode="&#x201a;" horiz-adv-x="586" d="M126 -159q1 1 3.5 6.5t6 11t6 10.5l3.5 7q14 34 24 64t18 60t14.5 62t12.5 68q0 3 1 12t2 19.5t2 20t1 12.5q-9 0 -13.5 -2t-8.5 -4.5t-8.5 -5t-12.5 -4.5q-35 -6 -68 -6q-11 0 -26 8.5t-15 22.5q0 63 0.5 117t-1.5 116q2 4 2 10.5t1.5 12.5t6 11.5t15.5 9.5h76 q3 0 11.5 0.5t18 1.5t18 2t12.5 2q4 0 22.5 -0.5t40 -0.5h39.5t23 1q2 0 10.5 0.5t18.5 1.5t18 1.5t10 0.5t12.5 1t16.5 1q11 0 23.5 -0.5t23.5 -5.5q12 -6 18.5 -24t9.5 -38.5t4 -39t1 -27.5v-14q0 -2 -3 -6.5t-3 -6.5q-1 -2 -2 -10t-2 -17t-1.5 -17.5t-0.5 -12.5 q1 -10 -1.5 -27.5t-7 -34t-10 -29t-10.5 -11.5q-14 -26 -22.5 -54.5t-22.5 -56.5q-18 -32 -41 -65t-49.5 -63t-57.5 -54.5t-65 -39.5q-2 -1 -9.5 -4.5t-17 -8t-19 -8.5t-13.5 -5q-9 -3 -12.5 -4.5t-11.5 -1.5q-10 0 -10.5 6t-0.5 14v15z" />
<glyph unicode="&#x201c;" horiz-adv-x="1207" d="M1053 1408l-3.5 -7t-6 -10.5t-6 -11t-3.5 -6.5q-14 -34 -24 -64t-18 -60t-14.5 -62t-12.5 -68q0 -3 -1 -12.5t-2 -20t-2 -19.5t-1 -12q9 0 13.5 2t8.5 4.5t8.5 5t12.5 4.5q34 6 68 6q11 0 26 -8.5t15 -22.5q0 -63 -0.5 -117t1.5 -116q-2 -5 -2 -11t-1.5 -12t-6.5 -11.5 t-15 -9.5h-76q-3 0 -11.5 -0.5t-18 -1.5t-18 -2t-12.5 -2q-5 0 -23 0.5t-39.5 0.5h-40t-22.5 -1q-2 0 -11 -0.5t-18.5 -1.5t-18 -1.5t-9.5 -0.5q-2 0 -12.5 -1t-16.5 -1q-11 0 -23.5 0.5t-23.5 5.5q-12 6 -18.5 24t-9.5 38.5t-4 39t-1 27.5v14q0 2 3 6.5t3 6.5q1 2 2 10 t2 17t1.5 17.5t0.5 12.5q-1 10 1.5 27.5t7 34t10 29t10.5 11.5q14 26 22.5 54.5t22.5 56.5q18 32 41 65t49.5 63t57 54.5t65.5 39.5q2 1 9.5 4.5t17 8t18.5 8t14 5.5q9 3 12.5 4.5t11.5 1.5q10 0 10.5 -6t0.5 -14v-15zM472 1305l-3.5 -7t-6 -10.5t-6 -11t-3.5 -6.5 q-14 -34 -24 -64t-18 -60t-14.5 -62t-12.5 -68q0 -3 -1 -12.5t-2 -20t-2 -19.5t-1 -12q9 0 13.5 2t8.5 4.5t8.5 5t12.5 4.5q34 6 68 6q11 0 26 -8.5t15 -22.5q0 -63 -0.5 -117t1.5 -116q-2 -5 -2 -11t-1.5 -12t-6.5 -11.5t-15 -9.5h-76q-3 0 -11.5 -0.5t-18 -1.5t-18 -2 t-12.5 -2q-5 0 -23 0.5t-39.5 0.5h-40t-22.5 -1q-2 0 -11 -0.5t-18.5 -1.5t-18 -1.5t-9.5 -0.5q-2 0 -12.5 -1t-16.5 -1q-11 0 -23.5 0.5t-23.5 5.5q-12 6 -18.5 24t-9.5 38.5t-4 39t-1 27.5v14q0 2 3 6.5t3 6.5q1 2 2 10t2 17t1.5 17.5t0.5 12.5q-1 10 1.5 27.5t7 34t10 29 t10.5 11.5q14 26 22.5 54.5t22.5 56.5q18 32 41 65t49.5 63t57 54.5t65.5 39.5q2 1 9.5 4.5t17 8t18.5 8t14 5.5q9 3 12.5 4.5t11.5 1.5q10 0 10.5 -6t0.5 -14v-15z" />
<glyph unicode="&#x201d;" horiz-adv-x="1207" d="M138 689q1 1 3.5 6.5t6 11t6 10.5l3.5 7q14 34 24 64t18 60t14.5 62t12.5 68q0 3 1 12t2 19.5t2 20t1 12.5q-9 0 -13.5 -2t-8.5 -4.5t-8.5 -5t-12.5 -4.5q-35 -6 -68 -6q-11 0 -26 8.5t-15 22.5q0 63 0.5 117t-1.5 116q2 4 2 10.5t1.5 12.5t6 11.5t15.5 9.5h76 q3 0 11.5 0.5t18 1.5t18 2t12.5 2q4 0 22.5 -0.5t40 -0.5h39.5t23 1q2 0 10.5 0.5t18.5 1.5t18 1.5t10 0.5t12.5 1t16.5 1q11 0 23.5 -0.5t23.5 -5.5q12 -6 18.5 -24t9.5 -38.5t4 -39t1 -27.5v-14q0 -2 -3 -6.5t-3 -6.5q-1 -2 -2 -10t-2 -17t-1.5 -17.5t-0.5 -12.5 q1 -10 -1.5 -27.5t-7 -34t-10 -29t-10.5 -11.5q-14 -26 -22.5 -54.5t-22.5 -56.5q-18 -32 -41 -65t-49.5 -63t-57.5 -54.5t-65 -39.5q-2 -1 -9.5 -4.5t-17 -8t-19 -8.5t-13.5 -5q-9 -3 -12.5 -4.5t-11.5 -1.5q-10 0 -10.5 6t-0.5 14v15zM719 792q1 1 3.5 6.5t6 11t6 10.5 l3.5 7q14 34 24 64t18 60t14.5 62t12.5 68q0 3 1 12t2 19.5t2 20t1 12.5q-9 0 -13.5 -2t-8.5 -4.5t-8.5 -5t-12.5 -4.5q-35 -6 -68 -6q-11 0 -26 8.5t-15 22.5q0 63 0.5 117t-1.5 116q2 4 2 10.5t1.5 12.5t6 11.5t15.5 9.5h76q3 0 11.5 0.5t18 1.5t18 2t12.5 2 q4 0 22.5 -0.5t40 -0.5h39.5t23 1q2 0 10.5 0.5t18.5 1.5t18 1.5t10 0.5t12.5 1t16.5 1q11 0 23.5 -0.5t23.5 -5.5q12 -6 18.5 -24t9.5 -38.5t4 -39t1 -27.5v-14q0 -2 -3 -6.5t-3 -6.5q-1 -2 -2 -10t-2 -17t-1.5 -17.5t-0.5 -12.5q1 -10 -1.5 -27.5t-7 -34t-10 -29 t-10.5 -11.5q-14 -26 -22.5 -54.5t-22.5 -56.5q-18 -32 -41 -65t-49.5 -63t-57.5 -54.5t-65 -39.5q-2 -1 -9.5 -4.5t-17 -8t-19 -8.5t-13.5 -5q-9 -3 -12.5 -4.5t-11.5 -1.5q-10 0 -10.5 6t-0.5 14v15z" />
<glyph unicode="&#x201e;" horiz-adv-x="1207" d="M138 -231q1 1 3.5 6.5t6 11t6 10.5l3.5 7q14 34 24 64t18 60t14.5 62t12.5 68q0 3 1 12t2 19.5t2 20t1 12.5q-9 0 -13.5 -2t-8.5 -4.5t-8.5 -5t-12.5 -4.5q-35 -6 -68 -6q-11 0 -26 8.5t-15 22.5q0 63 0.5 117t-1.5 116q2 4 2 10.5t1.5 12.5t6 11.5t15.5 9.5h76 q3 0 11.5 0.5t18 1.5t18 2t12.5 2q4 0 22.5 -0.5t40 -0.5h39.5t23 1q2 0 10.5 0.5t18.5 1.5t18 1.5t10 0.5t12.5 1t16.5 1q11 0 23.5 -0.5t23.5 -5.5q12 -6 18.5 -24t9.5 -38.5t4 -39t1 -27.5v-14q0 -2 -3 -6.5t-3 -6.5q-1 -2 -2 -10t-2 -17t-1.5 -17.5t-0.5 -12.5 q1 -10 -1.5 -27.5t-7 -34t-10 -29t-10.5 -11.5q-14 -26 -22.5 -54.5t-22.5 -56.5q-18 -32 -41 -65t-49.5 -63t-57.5 -54.5t-65 -39.5q-2 -1 -9.5 -4.5t-17 -8t-19 -8.5t-13.5 -5q-9 -3 -12.5 -4.5t-11.5 -1.5q-10 0 -10.5 6t-0.5 14v15zM719 -128q1 1 3.5 6.5t6 11t6 10.5 l3.5 7q14 34 24 64t18 60t14.5 62t12.5 68q0 3 1 12t2 19.5t2 20t1 12.5q-9 0 -13.5 -2t-8.5 -4.5t-8.5 -5t-12.5 -4.5q-35 -6 -68 -6q-11 0 -26 8.5t-15 22.5q0 63 0.5 117t-1.5 116q2 4 2 10.5t1.5 12.5t6 11.5t15.5 9.5h76q3 0 11.5 0.5t18 1.5t18 2t12.5 2 q4 0 22.5 -0.5t40 -0.5h39.5t23 1q2 0 10.5 0.5t18.5 1.5t18 1.5t10 0.5t12.5 1t16.5 1q11 0 23.5 -0.5t23.5 -5.5q12 -6 18.5 -24t9.5 -38.5t4 -39t1 -27.5v-14q0 -2 -3 -6.5t-3 -6.5q-1 -2 -2 -10t-2 -17t-1.5 -17.5t-0.5 -12.5q1 -10 -1.5 -27.5t-7 -34t-10 -29 t-10.5 -11.5q-14 -26 -22.5 -54.5t-22.5 -56.5q-18 -32 -41 -65t-49.5 -63t-57.5 -54.5t-65 -39.5q-2 -1 -9.5 -4.5t-17 -8t-19 -8.5t-13.5 -5q-9 -3 -12.5 -4.5t-11.5 -1.5q-10 0 -10.5 6t-0.5 14v15z" />
<glyph unicode="&#x2022;" horiz-adv-x="541" d="M481 849v-28.5t-6 -30.5q-11 -22 -19 -41.5t-25 -38.5q-5 -5 -13 -12t-16.5 -13.5t-15.5 -12t-9 -8.5q-22 -20 -50 -20.5t-54 -1.5q-17 -2 -28.5 2t-28.5 10q-8 1 -22 7.5t-22 11.5q-40 25 -69.5 62t-35.5 90q0 31 1 54t8 41.5t21 36.5t38 39q21 20 53 36.5t61 18.5h10.5 h15.5t15.5 -0.5t9.5 -1.5q4 0 12 -2t16.5 -4t15.5 -4t9 -2q1 -2 8.5 -4.5l16.5 -5.5t17 -5.5t11 -3.5q22 -17 36.5 -34t22.5 -37t11.5 -44t4.5 -54z" />
<glyph unicode="&#x2026;" horiz-adv-x="1623" d="M494 172v-28.5t-6 -30.5q-11 -22 -19 -41.5t-25 -38.5q-5 -5 -13 -12t-16.5 -13.5t-15.5 -12t-9 -8.5q-22 -20 -50 -20.5t-54 -1.5q-17 -2 -28.5 2t-28.5 10q-8 1 -22 7.5t-22 11.5q-40 25 -69.5 62t-35.5 90q0 31 1 54t8 41.5t21 36.5t38 39q21 20 53 36.5t61 18.5h10.5 h15.5t15.5 -0.5t9.5 -1.5q4 0 12 -2t16.5 -4t15.5 -4t9 -2q1 -2 8.5 -4.5l16.5 -5.5t17 -5.5t11 -3.5q22 -17 36.5 -34t22.5 -37t11.5 -44t4.5 -54zM1035 172v-28.5t-6 -30.5q-11 -22 -19 -41.5t-25 -38.5q-5 -5 -13 -12t-16.5 -13.5t-15.5 -12t-9 -8.5q-22 -20 -50 -20.5 t-54 -1.5q-17 -2 -28.5 2t-28.5 10q-8 1 -22 7.5t-22 11.5q-40 25 -69.5 62t-35.5 90q0 31 1 54t8 41.5t21 36.5t38 39q21 20 53 36.5t61 18.5h10.5h15.5t15.5 -0.5t9.5 -1.5q4 0 12 -2t16.5 -4t15.5 -4t9 -2q1 -2 8.5 -4.5l16.5 -5.5t17 -5.5t11 -3.5q22 -17 36.5 -34 t22.5 -37t11.5 -44t4.5 -54zM1576 172v-28.5t-6 -30.5q-11 -22 -19 -41.5t-25 -38.5q-5 -5 -13 -12t-16.5 -13.5t-15.5 -12t-9 -8.5q-22 -20 -50 -20.5t-54 -1.5q-17 -2 -28.5 2t-28.5 10q-8 1 -22 7.5t-22 11.5q-40 25 -69.5 62t-35.5 90q0 31 1 54t8 41.5t21 36.5t38 39 q21 20 53 36.5t61 18.5h10.5h15.5t15.5 -0.5t9.5 -1.5q4 0 12 -2t16.5 -4t15.5 -4t9 -2q1 -2 8.5 -4.5l16.5 -5.5t17 -5.5t11 -3.5q22 -17 36.5 -34t22.5 -37t11.5 -44t4.5 -54z" />
<glyph unicode="&#x202f;" horiz-adv-x="418" />
<glyph unicode="&#x2039;" horiz-adv-x="1036" d="M982 266q-2 1 -13.5 7t-13.5 7q-9 3 -25 9t-33 12t-31 11t-18 6q-3 1 -21.5 6t-42 11t-47.5 12t-37 9q-2 0 -7.5 1t-12.5 2.5t-13 3t-7 1.5q-2 0 -17 5t-35.5 11.5t-42 13t-34.5 10.5q-20 8 -41.5 14t-41.5 15q-18 8 -35 15.5t-36 14.5q-4 1 -21 5.5t-36.5 10.5t-36.5 11 t-21 6q-23 7 -48 18.5t-46 22.5q-2 -1 -4.5 0t-4.5 1q0 1 -5.5 2t-6.5 1q-19 5 -40 11t-37 15q0 1 -0.5 1.5t-0.5 1.5v2v4q0 1 -1 8t-1.5 15.5t-1.5 15.5l-1 7q1 7 1.5 12t0 9.5t-1 10t-1.5 13.5q-2 16 -0.5 27.5t2 22t0 21.5t-4.5 26q5 11 12.5 13.5t15.5 7.5q4 3 17 14 t28.5 23.5t29 23.5t18.5 13q38 26 76.5 45.5t73.5 48.5q1 2 3.5 4.5l4.5 4.5q1 0 5.5 2t9.5 4t9 4t5 3q2 1 11.5 7.5t21 14t22 14t13.5 8.5q1 1 6 4t11 6t11 6t7 4q5 3 23 13.5t38.5 22.5t38.5 23t22 14q23 16 45 26.5t46 25.5q3 2 10.5 5.5t15.5 7t14.5 6.5t7.5 4 q6 3 20.5 11t30.5 17t30 16.5t20 10.5l23 8q18 5 31.5 -1.5t19.5 -26.5q1 -9 3.5 -30t5.5 -45t5.5 -45.5t3.5 -29.5q2 -20 9 -42t11 -42q1 -8 -5.5 -15t-16 -12.5t-19.5 -9.5t-16 -7q-33 -22 -65 -43t-64 -45q-4 -3 -15.5 -11.5t-24.5 -18t-24.5 -18t-16.5 -11.5 q-17 -13 -33 -22.5t-32.5 -18.5t-33 -18.5t-33.5 -21.5v-3v-2q2 -1 5.5 -1.5t5.5 -1.5q1 -1 2 -8t3 -8q27 -14 58.5 -24.5t60.5 -18.5q1 0 6.5 -0.5t6.5 -1.5q3 -2 14.5 -7t14.5 -6q1 -2 6 -1.5t6 -0.5q12 -3 24.5 -7t24.5 -8q24 -10 48 -17t49 -14q1 0 6 -1.5t6 -1.5 q1 -1 8 -3.5t15.5 -6t17.5 -7t14 -5.5q14 -7 28 -17.5t16 -27.5q5 -50 10 -99t7 -100v-1q0 -1 0.5 -1.5t0.5 -1.5q1 -5 0.5 -8.5t0.5 -8.5v-3v-2q-1 -4 -3 -12.5t-5 -9.5q-2 0 -4 -1q-4 -2 -6 -2h-11z" />
<glyph unicode="&#x203a;" horiz-adv-x="1059" d="M88 1257q2 -1 13.5 -7t13.5 -7q9 -3 25 -9t33 -12t31 -11t18 -6q3 -1 21.5 -6t42 -11l47 -12t37.5 -9q1 0 7 -1t13 -2.5t12.5 -3t7.5 -1.5q1 0 16.5 -5t36 -11.5t42 -13t34.5 -10.5q20 -8 41.5 -14t41.5 -15q18 -8 35 -15.5t36 -14.5q4 -1 21 -5.5t36.5 -10.5t36 -11 t21.5 -6q23 -7 48 -18.5t46 -22.5q2 1 4.5 0t4.5 -1q0 -1 5.5 -2t6.5 -1q19 -5 40 -11t37 -15v-3q0 -1 1 -2v-4q0 -1 1 -8t1.5 -15.5t1.5 -15.5l1 -7q-2 -14 -1.5 -21.5t2.5 -23.5q1 -16 0 -27.5t-1.5 -22t-0.5 -21.5t5 -26q-5 -11 -12.5 -13.5t-15.5 -7.5q-4 -3 -17 -14 t-28.5 -23.5t-29 -23.5t-18.5 -13q-38 -26 -76.5 -45.5t-73.5 -48.5q-1 -2 -3.5 -4.5l-4.5 -4.5q-1 0 -5.5 -2t-9.5 -4t-9 -4t-5 -3q-2 -1 -11.5 -7.5t-21 -14t-22 -14.5t-13.5 -8q-1 -1 -6 -4t-11 -6t-11.5 -6t-6.5 -4q-5 -3 -23 -13.5t-38.5 -22.5t-38.5 -23t-22 -14 q-23 -16 -45 -26.5t-46 -25.5q-3 -2 -10.5 -5.5t-15.5 -7t-14.5 -6.5t-7.5 -4q-6 -3 -20.5 -11t-30.5 -17t-30 -16.5t-20 -10.5l-23 -8q-18 -5 -31.5 1.5t-19.5 26.5q-1 9 -3.5 30t-5.5 45t-5.5 45.5t-3.5 29.5q-2 20 -9 42t-11 42q-1 8 5.5 15t16 12.5t19.5 9.5t16 7 q33 22 65 43t64 45q4 3 15.5 11.5t24.5 18t24.5 18t16.5 11.5q34 25 65.5 41t66.5 40v3v2q-2 1 -5.5 1.5t-5.5 1.5q-1 1 -2 8t-3 8q-27 14 -58.5 24.5t-60.5 18.5q-1 0 -6.5 0.5t-6.5 1.5q-3 2 -14.5 7t-14.5 6q-1 2 -6 1.5t-6 0.5q-12 3 -24.5 7t-24.5 8q-24 10 -48 17 t-49 14q-1 0 -6 1.5t-6 1.5q-2 1 -8.5 3.5t-15 6t-17.5 7t-14 5.5q-14 7 -28 17.5t-16 27.5q-5 50 -10 99t-7 100q-1 0 -1 1v3q-1 5 -0.5 8.5t-0.5 8.5v3v2q1 4 3 12.5t5 9.5q1 0 3 1t3.5 1t3.5 1h11z" />
<glyph unicode="&#x205f;" horiz-adv-x="522" />
<glyph unicode="&#x20ac;" horiz-adv-x="1876" d="M78 910q-2 8 -1 15.5t0 15.5q0 2 0.5 10.5t1.5 18t1.5 18.5t0.5 11q0 23 -2 45t1 44q1 11 17 19t30 9q4 0 19.5 -1.5t33.5 -2.5t33.5 -2t19.5 -1q3 0 25.5 -0.5t51.5 -1t59 -1t47 -0.5q4 14 7.5 28t4.5 17q10 35 22.5 62.5t23.5 47t18.5 30l7.5 10.5q8 24 26 50.5t42 53 t52 52.5t56 49q34 34 82 56.5t91 39.5q3 1 15.5 7.5t27.5 13t27.5 12.5t15.5 8q1 0 8 2t15 5t15 5.5t9 3.5q2 2 12 6t12 6q1 0 5.5 -0.5t10.5 -0.5h11t7 1q2 0 8.5 1t15 2.5t16.5 3t12 2.5q42 12 82 11.5t84 -0.5h24t29.5 -0.5t25.5 -0.5h13q4 0 14 -0.5t22 -1.5t23 -2.5 t16 -2.5q2 0 12.5 -2t16.5 -4q2 0 11.5 -2t11.5 -4q2 0 12 -1t21.5 -1.5t22 -1.5t13.5 -1q3 -2 11.5 -4t10.5 -2q2 -2 10.5 -7t18 -10.5t18 -11t10.5 -6.5q2 -2 11.5 -6.5t11.5 -6.5q2 0 9 -5.5t9 -5.5q0 -1 5 -1q2 0 5 1q10 -3 14.5 -18t4.5 -25v-10q-2 -4 -5 -7 q-3 -4 -8 -9q-2 -2 -8.5 -11.5t-14.5 -20.5t-14.5 -20t-8.5 -11q-11 -5 -25 -28t-31 -47t-36.5 -41t-41.5 -10q-55 14 -106 23t-107 10q-5 0 -12 -0.5t-15 -0.5q-9 -1 -18 -1q-2 0 -9 -1.5t-14.5 -3.5t-14.5 -3.5t-9 -1.5q-3 -1 -16.5 -2.5t-29 -3.5t-29 -3.5t-17.5 -2.5 q-2 0 -10 -2.5t-18 -6l-20 -7t-15 -5.5q-46 -19 -82.5 -48t-68.5 -66q-3 -3 -12 -15t-19.5 -25.5t-20 -25.5t-12.5 -15q-6 -7 -12.5 -14t-11.5 -15q4 2 7.5 2t7.5 1q4 0 18 -1.5t30.5 -2.5t30.5 -1.5t17 -0.5h16h28h28h16t15 -1t25.5 -2t26 -2t15.5 -1q43 -3 85 1t87 3 q1 1 18.5 0.5t41 -2t48 -3.5t39.5 -3q2 0 4.5 -0.5t4.5 -0.5q17 -1 21.5 -9.5t3.5 -20.5t-4.5 -25.5t-3.5 -22.5q0 -3 1 -9.5t2 -14t2 -14t1 -9.5q1 -8 0 -13.5t-3 -12.5q-2 -14 3 -29t3 -26q-1 -1 -1 -4v-2q-2 -2 -8.5 -6.5t-9.5 -4.5q-6 1 -18 -1t-19 -4h-17.5h-37h-46 h-46h-37h-17.5h-8.5t-14 -0.5t-14.5 -0.5h-9h-12.5t-21 -0.5t-21.5 -1t-13 -1.5q-4 0 -20.5 0.5t-35.5 1t-35.5 0.5h-21.5q-29 -1 -43 -0.5t-25.5 1t-26 2.5t-44.5 4q-3 1 -14 4.5t-16 4.5q-13 2 -18 -9.5t-3 -25.5t10.5 -24.5t23.5 -5.5q3 0 17.5 -1.5t30.5 -2.5t30.5 -2 t17.5 -1q4 0 17 0.5t28 0.5h27.5h15.5t14.5 -1t25.5 -2t26 -2t16 -1q42 -2 84.5 1.5t86.5 2.5q1 0 19 -0.5t41.5 -2t48 -2.5t39.5 -2q2 0 4.5 -0.5t4.5 -0.5q17 -1 21.5 -10t3.5 -21.5t-4.5 -25.5t-3.5 -23q0 -2 1 -8.5t1.5 -14t1.5 -14t1 -9.5q1 -8 0 -13.5t-2 -12.5 q-2 -14 3 -29t3 -26q-1 -1 -1 -4v-2q-2 -1 -8.5 -6t-10.5 -5q-5 1 -17 -1t-19 -3h-17.5h-37h-46.5h-46.5h-36.5h-17h-8.5t-14.5 -0.5t-15 -0.5h-8q-3 0 -13 -0.5t-21 -1t-21 -1t-13 -1.5q-5 0 -21 0.5t-35 1t-35.5 0.5h-21.5q-25 -1 -39 -1t-23.5 1t-19.5 2t-27 3 q8 -8 11.5 -19.5t9.5 -21.5q25 -37 54 -70.5t63 -61t73.5 -47.5t84.5 -30q7 -2 23.5 -4.5t34 -5.5t32 -5t18.5 -2q1 0 8 -0.5t16.5 -0.5t19.5 -0.5t16 -0.5q42 -1 80.5 3.5t78.5 18.5q3 1 9 4t12.5 6t11.5 5.5t6 3.5q12 5 21 11t17.5 11t18 8.5t21.5 3.5q3 0 11 -1t10 -1 q24 -22 44.5 -46t33.5 -52q3 -4 9.5 -17.5t14 -29t14.5 -29t9 -16.5q1 -2 5.5 -8t9 -12.5t8.5 -13t5 -7.5q6 -25 4.5 -35t-11 -15.5t-25.5 -11.5t-38 -24q-2 -1 -3 -2q-2 -1 -2.5 -2t-1.5 -2q-25 -19 -52 -30.5t-56 -19t-59.5 -11.5t-61.5 -7q-6 0 -31.5 -2t-54.5 -4 t-54.5 -4t-31.5 -3h-64q-3 0 -14 1t-23.5 2t-23.5 2t-14 1h-17.5h-31h-31t-17.5 1q-2 0 -11 2t-20.5 4.5t-22 5.5t-15.5 5q-71 22 -132.5 51.5t-109.5 82.5h-29q-2 0 -4 2t-2 4v29q-2 2 -8.5 7t-15 10.5t-15.5 10t-8 6.5q-2 0 -9 2t-9 4q-2 0 -6.5 4.5t-4.5 6.5q-2 2 -4 6 t-2 6l-12 12l-13.5 13.5t-11.5 11t-6 4.5l-22 35v1q0 1 0.5 1.5t0.5 1.5v2q-22 29 -36.5 63t-25 70.5t-18.5 73.5t-18 72q-17 -1 -42.5 -3t-49.5 -4t-42.5 -3.5t-22.5 -1.5q-33 -1 -48.5 -0.5t-27.5 1.5t-28 2.5t-50 3.5q-4 1 -14 3t-15 2q-5 2 -9.5 9.5t-6.5 10.5 q-2 8 -1 15.5t0 15.5q0 2 0.5 10.5t1.5 18t1.5 18.5t0.5 11q0 23 -2 45t1 44q1 11 17 19.5t30 8.5q4 0 19.5 -1t33.5 -2.5t33.5 -2.5t19.5 -1q3 0 21 0.5t42.5 1.5t51.5 2t47 1q-2 15 -2.5 31.5t-1.5 31.5q-10 0 -27.5 0.5t-35.5 0.5h-33h-19q-33 0 -48.5 0.5t-28 1.5 t-28.5 2.5t-49 3.5q-4 1 -14 3t-15 2q-5 2 -9.5 9.5t-6.5 10.5z" />
<glyph unicode="&#x25fc;" horiz-adv-x="1285" d="M0 1285h1285v-1285h-1285v1285z" />
<hkern u1="&#x20;" u2="F" k="24" />
<hkern u1="&#x2f;" u2="&#x2f;" k="192" />
<hkern u1="&#x37;" u2="&#x35;" k="-36" />
<hkern u1="&#x37;" u2="&#x2e;" k="320" />
<hkern u1="&#x37;" u2="&#x2c;" k="224" />
<hkern u1="A" u2="y" k="320" />
<hkern u1="A" u2="x" k="64" />
<hkern u1="A" u2="w" k="235" />
<hkern u1="A" u2="v" k="342" />
<hkern u1="A" u2="u" k="150" />
<hkern u1="A" u2="t" k="171" />
<hkern u1="A" u2="q" k="85" />
<hkern u1="A" u2="o" k="192" />
<hkern u1="A" u2="i" k="43" />
<hkern u1="A" u2="g" k="128" />
<hkern u1="A" u2="f" k="149" />
<hkern u1="A" u2="e" k="128" />
<hkern u1="A" u2="d" k="85" />
<hkern u1="A" u2="c" k="128" />
<hkern u1="A" u2="b" k="42" />
<hkern u1="A" u2="a" k="107" />
<hkern u1="A" u2="Y" k="341" />
<hkern u1="A" u2="W" k="256" />
<hkern u1="A" u2="V" k="384" />
<hkern u1="A" u2="T" k="256" />
<hkern u1="A" u2="S" k="64" />
<hkern u1="A" u2="Q" k="149" />
<hkern u1="A" u2="O" k="224" />
<hkern u1="A" u2="J" k="64" />
<hkern u1="A" u2="G" k="176" />
<hkern u1="A" u2="C" k="192" />
<hkern u1="B" u2="x" k="86" />
<hkern u1="B" u2="v" k="85" />
<hkern u1="B" u2="Y" k="128" />
<hkern u1="B" u2="X" k="64" />
<hkern u1="B" u2="V" k="128" />
<hkern u1="B" u2="T" k="86" />
<hkern u1="C" u2="w" k="192" />
<hkern u1="C" u2="v" k="149" />
<hkern u1="C" u2="u" k="86" />
<hkern u1="C" u2="t" k="149" />
<hkern u1="C" u2="q" k="85" />
<hkern u1="C" u2="g" k="106" />
<hkern u1="C" u2="f" k="128" />
<hkern u1="C" u2="e" k="107" />
<hkern u1="C" u2="c" k="149" />
<hkern u1="C" u2="a" k="85" />
<hkern u1="C" u2="Q" k="128" />
<hkern u1="C" u2="O" k="192" />
<hkern u1="C" u2="J" k="48" />
<hkern u1="C" u2="G" k="171" />
<hkern u1="C" u2="C" k="150" />
<hkern u1="D" u2="x" k="22" />
<hkern u1="D" u2="Z" k="86" />
<hkern u1="D" u2="Y" k="224" />
<hkern u1="D" u2="X" k="192" />
<hkern u1="D" u2="V" k="213" />
<hkern u1="D" u2="T" k="64" />
<hkern u1="D" u2="J" k="112" />
<hkern u1="D" u2="G" k="-16" />
<hkern u1="D" u2="A" k="150" />
<hkern u1="E" u2="o" k="64" />
<hkern u1="E" u2="g" k="85" />
<hkern u1="E" u2="e" k="64" />
<hkern u1="E" u2="c" k="86" />
<hkern u1="E" u2="a" k="64" />
<hkern u1="E" u2="Y" k="64" />
<hkern u1="E" u2="T" k="64" />
<hkern u1="E" u2="Q" k="64" />
<hkern u1="E" u2="O" k="64" />
<hkern u1="E" u2="C" k="64" />
<hkern u1="F" u2="y" k="64" />
<hkern u1="F" u2="x" k="85" />
<hkern u1="F" u2="v" k="21" />
<hkern u1="F" u2="o" k="64" />
<hkern u1="F" u2="g" k="21" />
<hkern u1="F" u2="e" k="43" />
<hkern u1="F" u2="a" k="64" />
<hkern u1="F" u2="X" k="96" />
<hkern u1="F" u2="M" k="80" />
<hkern u1="F" u2="J" k="352" />
<hkern u1="F" u2="A" k="272" />
<hkern u1="F" u2="&#x2e;" k="128" />
<hkern u1="G" u2="y" k="128" />
<hkern u1="G" u2="Y" k="176" />
<hkern u1="G" u2="X" k="112" />
<hkern u1="H" u2="y" k="42" />
<hkern u1="J" u2="X" k="80" />
<hkern u1="J" u2="S" k="16" />
<hkern u1="K" u2="y" k="277" />
<hkern u1="K" u2="w" k="256" />
<hkern u1="K" u2="v" k="256" />
<hkern u1="K" u2="u" k="128" />
<hkern u1="K" u2="s" k="64" />
<hkern u1="K" u2="q" k="171" />
<hkern u1="K" u2="o" k="214" />
<hkern u1="K" u2="g" k="171" />
<hkern u1="K" u2="f" k="171" />
<hkern u1="K" u2="e" k="170" />
<hkern u1="K" u2="d" k="128" />
<hkern u1="K" u2="c" k="170" />
<hkern u1="K" u2="a" k="128" />
<hkern u1="K" u2="Y" k="80" />
<hkern u1="K" u2="W" k="64" />
<hkern u1="K" u2="S" k="112" />
<hkern u1="K" u2="Q" k="160" />
<hkern u1="K" u2="O" k="224" />
<hkern u1="K" u2="J" k="112" />
<hkern u1="K" u2="G" k="224" />
<hkern u1="K" u2="C" k="208" />
<hkern u1="L" u2="y" k="299" />
<hkern u1="L" u2="w" k="213" />
<hkern u1="L" u2="v" k="235" />
<hkern u1="L" u2="Y" k="224" />
<hkern u1="L" u2="W" k="192" />
<hkern u1="L" u2="V" k="288" />
<hkern u1="L" u2="Q" k="48" />
<hkern u1="L" u2="O" k="96" />
<hkern u1="L" u2="G" k="48" />
<hkern u1="L" u2="C" k="112" />
<hkern u1="M" u2="y" k="170" />
<hkern u1="M" u2="w" k="107" />
<hkern u1="M" u2="v" k="128" />
<hkern u1="M" u2="Y" k="160" />
<hkern u1="M" u2="V" k="176" />
<hkern u1="M" u2="O" k="64" />
<hkern u1="M" u2="G" k="32" />
<hkern u1="O" u2="Z" k="128" />
<hkern u1="O" u2="Y" k="144" />
<hkern u1="O" u2="X" k="224" />
<hkern u1="O" u2="W" k="112" />
<hkern u1="O" u2="V" k="128" />
<hkern u1="O" u2="T" k="128" />
<hkern u1="O" u2="M" k="64" />
<hkern u1="O" u2="J" k="128" />
<hkern u1="O" u2="A" k="208" />
<hkern u1="O" u2="&#x2e;" k="128" />
<hkern u1="P" u2="q" k="86" />
<hkern u1="P" u2="o" k="85" />
<hkern u1="P" u2="e" k="86" />
<hkern u1="P" u2="c" k="43" />
<hkern u1="P" u2="X" k="128" />
<hkern u1="P" u2="M" k="128" />
<hkern u1="P" u2="J" k="400" />
<hkern u1="P" u2="A" k="256" />
<hkern u1="P" u2="&#x2e;" k="160" />
<hkern u1="Q" u2="y" k="42" />
<hkern u1="Q" u2="Z" k="64" />
<hkern u1="Q" u2="Y" k="112" />
<hkern u1="Q" u2="X" k="64" />
<hkern u1="Q" u2="W" k="160" />
<hkern u1="Q" u2="V" k="160" />
<hkern u1="Q" u2="J" k="80" />
<hkern u1="R" u2="y" k="128" />
<hkern u1="R" u2="w" k="64" />
<hkern u1="R" u2="v" k="85" />
<hkern u1="R" u2="t" k="86" />
<hkern u1="R" u2="o" k="128" />
<hkern u1="R" u2="g" k="85" />
<hkern u1="R" u2="f" k="86" />
<hkern u1="R" u2="e" k="150" />
<hkern u1="R" u2="d" k="64" />
<hkern u1="R" u2="c" k="107" />
<hkern u1="R" u2="a" k="107" />
<hkern u1="R" u2="Y" k="192" />
<hkern u1="R" u2="W" k="171" />
<hkern u1="R" u2="V" k="171" />
<hkern u1="R" u2="T" k="128" />
<hkern u1="R" u2="Q" k="107" />
<hkern u1="R" u2="O" k="149" />
<hkern u1="R" u2="G" k="85" />
<hkern u1="R" u2="C" k="107" />
<hkern u1="S" u2="t" k="43" />
<hkern u1="S" u2="Y" k="96" />
<hkern u1="S" u2="W" k="80" />
<hkern u1="T" u2="z" k="64" />
<hkern u1="T" u2="y" k="171" />
<hkern u1="T" u2="x" k="107" />
<hkern u1="T" u2="v" k="64" />
<hkern u1="T" u2="s" k="107" />
<hkern u1="T" u2="q" k="149" />
<hkern u1="T" u2="o" k="149" />
<hkern u1="T" u2="n" k="85" />
<hkern u1="T" u2="m" k="64" />
<hkern u1="T" u2="g" k="128" />
<hkern u1="T" u2="e" k="171" />
<hkern u1="T" u2="d" k="128" />
<hkern u1="T" u2="c" k="170" />
<hkern u1="T" u2="a" k="149" />
<hkern u1="T" u2="X" k="48" />
<hkern u1="T" u2="O" k="96" />
<hkern u1="T" u2="M" k="96" />
<hkern u1="T" u2="J" k="144" />
<hkern u1="T" u2="A" k="160" />
<hkern u1="T" u2="&#x2e;" k="192" />
<hkern u1="V" u2="z" k="107" />
<hkern u1="V" u2="y" k="128" />
<hkern u1="V" u2="x" k="64" />
<hkern u1="V" u2="q" k="192" />
<hkern u1="V" u2="o" k="170" />
<hkern u1="V" u2="n" k="107" />
<hkern u1="V" u2="m" k="128" />
<hkern u1="V" u2="k" k="-21" />
<hkern u1="V" u2="g" k="192" />
<hkern u1="V" u2="e" k="213" />
<hkern u1="V" u2="d" k="192" />
<hkern u1="V" u2="c" k="171" />
<hkern u1="V" u2="a" k="170" />
<hkern u1="V" u2="Z" k="64" />
<hkern u1="V" u2="X" k="96" />
<hkern u1="V" u2="Q" k="96" />
<hkern u1="V" u2="O" k="96" />
<hkern u1="V" u2="M" k="160" />
<hkern u1="V" u2="J" k="256" />
<hkern u1="V" u2="C" k="32" />
<hkern u1="V" u2="A" k="320" />
<hkern u1="V" u2="&#x2c;" k="224" />
<hkern u1="W" u2="z" k="144" />
<hkern u1="W" u2="y" k="112" />
<hkern u1="W" u2="w" k="80" />
<hkern u1="W" u2="v" k="96" />
<hkern u1="W" u2="u" k="48" />
<hkern u1="W" u2="t" k="64" />
<hkern u1="W" u2="s" k="112" />
<hkern u1="W" u2="r" k="64" />
<hkern u1="W" u2="q" k="160" />
<hkern u1="W" u2="p" k="64" />
<hkern u1="W" u2="o" k="176" />
<hkern u1="W" u2="n" k="112" />
<hkern u1="W" u2="m" k="128" />
<hkern u1="W" u2="i" k="64" />
<hkern u1="W" u2="g" k="160" />
<hkern u1="W" u2="f" k="80" />
<hkern u1="W" u2="e" k="176" />
<hkern u1="W" u2="d" k="160" />
<hkern u1="W" u2="c" k="144" />
<hkern u1="W" u2="b" k="96" />
<hkern u1="W" u2="X" k="64" />
<hkern u1="W" u2="S" k="64" />
<hkern u1="W" u2="Q" k="128" />
<hkern u1="W" u2="O" k="144" />
<hkern u1="W" u2="M" k="128" />
<hkern u1="W" u2="J" k="224" />
<hkern u1="W" u2="G" k="96" />
<hkern u1="W" u2="C" k="96" />
<hkern u1="W" u2="A" k="320" />
<hkern u1="W" u2="&#x2c;" k="224" />
<hkern u1="X" u2="y" k="192" />
<hkern u1="X" u2="w" k="160" />
<hkern u1="X" u2="v" k="160" />
<hkern u1="X" u2="u" k="96" />
<hkern u1="X" u2="t" k="128" />
<hkern u1="X" u2="o" k="128" />
<hkern u1="X" u2="g" k="160" />
<hkern u1="X" u2="f" k="128" />
<hkern u1="X" u2="e" k="128" />
<hkern u1="X" u2="d" k="96" />
<hkern u1="X" u2="c" k="128" />
<hkern u1="X" u2="a" k="160" />
<hkern u1="X" u2="W" k="64" />
<hkern u1="X" u2="T" k="64" />
<hkern u1="X" u2="Q" k="208" />
<hkern u1="X" u2="O" k="192" />
<hkern u1="X" u2="J" k="112" />
<hkern u1="X" u2="G" k="192" />
<hkern u1="X" u2="C" k="160" />
<hkern u1="Y" u2="z" k="272" />
<hkern u1="Y" u2="y" k="240" />
<hkern u1="Y" u2="x" k="240" />
<hkern u1="Y" u2="w" k="224" />
<hkern u1="Y" u2="v" k="176" />
<hkern u1="Y" u2="u" k="144" />
<hkern u1="Y" u2="t" k="144" />
<hkern u1="Y" u2="s" k="224" />
<hkern u1="Y" u2="r" k="176" />
<hkern u1="Y" u2="q" k="320" />
<hkern u1="Y" u2="p" k="192" />
<hkern u1="Y" u2="o" k="256" />
<hkern u1="Y" u2="n" k="192" />
<hkern u1="Y" u2="m" k="192" />
<hkern u1="Y" u2="g" k="299" />
<hkern u1="Y" u2="e" k="320" />
<hkern u1="Y" u2="d" k="235" />
<hkern u1="Y" u2="c" k="299" />
<hkern u1="Y" u2="a" k="298" />
<hkern u1="Y" u2="Z" k="64" />
<hkern u1="Y" u2="X" k="128" />
<hkern u1="Y" u2="W" k="48" />
<hkern u1="Y" u2="S" k="128" />
<hkern u1="Y" u2="R" k="43" />
<hkern u1="Y" u2="Q" k="272" />
<hkern u1="Y" u2="O" k="224" />
<hkern u1="Y" u2="N" k="80" />
<hkern u1="Y" u2="M" k="208" />
<hkern u1="Y" u2="L" k="48" />
<hkern u1="Y" u2="K" k="80" />
<hkern u1="Y" u2="J" k="416" />
<hkern u1="Y" u2="G" k="224" />
<hkern u1="Y" u2="D" k="42" />
<hkern u1="Y" u2="C" k="224" />
<hkern u1="Y" u2="A" k="416" />
<hkern u1="Y" u2="&#x2e;" k="256" />
<hkern u1="Y" u2="&#x2c;" k="224" />
<hkern u1="Z" u2="y" k="160" />
<hkern u1="Z" u2="x" k="64" />
<hkern u1="Z" u2="w" k="144" />
<hkern u1="Z" u2="v" k="144" />
<hkern u1="Z" u2="u" k="64" />
<hkern u1="Z" u2="t" k="144" />
<hkern u1="Z" u2="o" k="80" />
<hkern u1="Z" u2="i" k="80" />
<hkern u1="Z" u2="g" k="80" />
<hkern u1="Z" u2="f" k="64" />
<hkern u1="Z" u2="e" k="96" />
<hkern u1="Z" u2="c" k="80" />
<hkern u1="Z" u2="S" k="48" />
<hkern u1="Z" u2="Q" k="96" />
<hkern u1="Z" u2="O" k="160" />
<hkern u1="Z" u2="G" k="96" />
<hkern u1="Z" u2="C" k="112" />
<hkern u1="\" u2="\" k="160" />
<hkern u1="b" u2="x" k="106" />
<hkern u1="b" u2="w" k="43" />
<hkern u1="b" u2="v" k="107" />
<hkern u1="b" u2="V" k="235" />
<hkern u1="c" u2="y" k="85" />
<hkern u1="c" u2="v" k="128" />
<hkern u1="c" u2="q" k="64" />
<hkern u1="c" u2="o" k="43" />
<hkern u1="c" u2="g" k="64" />
<hkern u1="c" u2="e" k="86" />
<hkern u1="c" u2="d" k="43" />
<hkern u1="c" u2="a" k="64" />
<hkern u1="c" u2="V" k="192" />
<hkern u1="e" u2="y" k="106" />
<hkern u1="e" u2="w" k="64" />
<hkern u1="e" u2="v" k="128" />
<hkern u1="e" u2="V" k="192" />
<hkern u1="f" u2="y" k="128" />
<hkern u1="f" u2="x" k="107" />
<hkern u1="f" u2="w" k="86" />
<hkern u1="f" u2="v" k="64" />
<hkern u1="f" u2="t" k="85" />
<hkern u1="f" u2="s" k="85" />
<hkern u1="f" u2="r" k="64" />
<hkern u1="f" u2="q" k="150" />
<hkern u1="f" u2="o" k="128" />
<hkern u1="f" u2="m" k="86" />
<hkern u1="f" u2="g" k="128" />
<hkern u1="f" u2="e" k="150" />
<hkern u1="f" u2="d" k="149" />
<hkern u1="f" u2="c" k="128" />
<hkern u1="f" u2="a" k="107" />
<hkern u1="g" u2="j" k="-64" />
<hkern u1="g" u2="V" k="128" />
<hkern u1="h" u2="V" k="192" />
<hkern u1="i" u2="y" k="86" />
<hkern u1="i" u2="v" k="85" />
<hkern u1="j" u2="y" k="85" />
<hkern u1="j" u2="k" k="-36" />
<hkern u1="j" u2="j" k="-128" />
<hkern u1="k" u2="y" k="128" />
<hkern u1="k" u2="s" k="64" />
<hkern u1="k" u2="q" k="149" />
<hkern u1="k" u2="o" k="149" />
<hkern u1="k" u2="g" k="106" />
<hkern u1="k" u2="e" k="170" />
<hkern u1="k" u2="d" k="128" />
<hkern u1="k" u2="c" k="171" />
<hkern u1="k" u2="a" k="170" />
<hkern u1="k" u2="V" k="171" />
<hkern u1="l" u2="y" k="21" />
<hkern u1="m" u2="y" k="192" />
<hkern u1="m" u2="w" k="128" />
<hkern u1="m" u2="v" k="150" />
<hkern u1="m" u2="l" k="85" />
<hkern u1="m" u2="f" k="85" />
<hkern u1="m" u2="e" k="21" />
<hkern u1="m" u2="V" k="299" />
<hkern u1="n" u2="y" k="128" />
<hkern u1="n" u2="w" k="64" />
<hkern u1="n" u2="v" k="128" />
<hkern u1="n" u2="t" k="42" />
<hkern u1="n" u2="o" k="42" />
<hkern u1="n" u2="l" k="64" />
<hkern u1="n" u2="e" k="42" />
<hkern u1="n" u2="b" k="42" />
<hkern u1="n" u2="V" k="256" />
<hkern u1="o" u2="y" k="86" />
<hkern u1="o" u2="x" k="64" />
<hkern u1="o" u2="v" k="86" />
<hkern u1="o" u2="p" k="-22" />
<hkern u1="o" u2="l" k="64" />
<hkern u1="o" u2="V" k="192" />
<hkern u1="p" u2="v" k="64" />
<hkern u1="p" u2="o" k="-22" />
<hkern u1="p" u2="V" k="150" />
<hkern u1="q" u2="j" k="-192" />
<hkern u1="q" u2="V" k="64" />
<hkern u1="r" u2="q" k="128" />
<hkern u1="r" u2="o" k="64" />
<hkern u1="r" u2="l" k="64" />
<hkern u1="r" u2="g" k="85" />
<hkern u1="r" u2="e" k="85" />
<hkern u1="r" u2="d" k="43" />
<hkern u1="r" u2="c" k="43" />
<hkern u1="r" u2="b" k="64" />
<hkern u1="r" u2="a" k="64" />
<hkern u1="r" u2="V" k="86" />
<hkern u1="r" u2="A" k="214" />
<hkern u1="r" u2="&#x2e;" k="256" />
<hkern u1="r" u2="&#x2c;" k="192" />
<hkern u1="v" u2="q" k="128" />
<hkern u1="v" u2="o" k="85" />
<hkern u1="v" u2="g" k="85" />
<hkern u1="v" u2="e" k="106" />
<hkern u1="v" u2="d" k="42" />
<hkern u1="v" u2="c" k="107" />
<hkern u1="v" u2="a" k="85" />
<hkern u1="v" u2="&#x2e;" k="224" />
<hkern u1="v" u2="&#x2c;" k="160" />
<hkern u1="w" u2="q" k="128" />
<hkern u1="w" u2="o" k="107" />
<hkern u1="w" u2="j" k="64" />
<hkern u1="w" u2="g" k="107" />
<hkern u1="w" u2="e" k="150" />
<hkern u1="w" u2="d" k="64" />
<hkern u1="w" u2="c" k="107" />
<hkern u1="w" u2="a" k="128" />
<hkern u1="w" u2="&#x2e;" k="224" />
<hkern u1="w" u2="&#x2c;" k="192" />
<hkern u1="x" u2="q" k="85" />
<hkern u1="x" u2="o" k="86" />
<hkern u1="x" u2="g" k="64" />
<hkern u1="x" u2="e" k="107" />
<hkern u1="x" u2="c" k="85" />
<hkern u1="x" u2="a" k="149" />
<hkern u1="y" u2="q" k="107" />
<hkern u1="y" u2="o" k="107" />
<hkern u1="y" u2="g" k="107" />
<hkern u1="y" u2="e" k="150" />
<hkern u1="y" u2="d" k="85" />
<hkern u1="y" u2="c" k="107" />
<hkern u1="y" u2="a" k="128" />
<hkern u1="y" u2="&#x2e;" k="224" />
<hkern u1="y" u2="&#x2c;" k="224" />
<hkern u1="z" u2="y" k="43" />
<hkern u1="z" u2="e" k="43" />
</font>
</defs></svg>

BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessolid-webfont.ttf View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/html/fonts/kgsecondchancessolid-webfont.woff View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/alicenbob.png View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/alicenfriends.png View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/alicenfriends2.png View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/signingillustrated1.png View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/signingillustrated2.gif View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/signingillustrated2.png View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/signingsequence.png View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/MySigning/wiring.png View File


BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/img/logo.png View File


+ 44
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/mainpage.dox View File

@@ -0,0 +1,44 @@
/**
@mainpage MySensors library and examples documentation

Are you a sketch developer/user, see @ref publics

Are you a core/library developer, see @ref internals

@copyright (C) 2013-2018 Sensnology AB

Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*/

/*
* Doxygen groups that are spread across files/sections
*/
/**
* @defgroup publics MySensors public APIs and functionalities
* @brief The public APIs and functionalities are directly accessible to sketch developers/users.
*
* @defgroup internals MySensors internal APIs and functionalities
* @brief The interal APIs and functionalities should only be used by library developers/advanced
* users.
*
*/

/**
* @defgroup MyConfigGrp Library customisation
* @ingroup publics
*
* @brief The MySensors library can be customized in various ways.
*
* All customizations are set in the sketch. @note It is important to define any customizations
* before including the primary library header. @see MySensors.h
*/
/**
* @defgroup memorysavings Tips for reducing memory footprint
* @ingroup MyConfigGrp
*
* @brief Some settings are optional but add significantly to the memory footprint size.
*
* By disabeling optional features that you don't need you can save memory which can be a valuable
* resource on cheaper hardware like the atmega328p.
* These options can be defined in your sketch to disable such features.
*/

BIN
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/plantuml.jar View File


+ 194
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/styles/DoxygenLayout.xml View File

@@ -0,0 +1,194 @@
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.8.11 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="namespaces" visible="yes" title="">
<tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="yes" title="">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="yes" title="">
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
<tab type="pages" visible="yes" title="" intro=""/>
</navindex>

<!-- Layout definition for a class page -->
<class>
<briefdescription visible="no"/>
<detaileddescription title=""/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>

<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="no"/>
<detaileddescription title=""/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<classes visible="yes" title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>

<!-- Layout definition for a file page -->
<file>
<briefdescription visible="no"/>
<detaileddescription title=""/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>

<!-- Layout definition for a group page -->
<group>
<briefdescription visible="no"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<detaileddescription title=""/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>

<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="no"/>
<detaileddescription title=""/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
</directory>
</doxygenlayout>

+ 20
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/styles/html/footerFile.html View File

@@ -0,0 +1,20 @@
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">$generatedby
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/></a> $doxygenversion </li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<hr class="footer"/><address class="footer"><small>
Copyright (C) 2013-2018 Sensnology AB. $generatedby <a href="http://www.doxygen.org/index.html">doxygen</a>
</a> $doxygenversion
</small></address>
<!--END !GENERATE_TREEVIEW-->
</body>
</html>

+ 55
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/styles/html/headerFile.html View File

@@ -0,0 +1,55 @@
<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
$treeview
$search
$mathjax
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->

<!--BEGIN TITLEAREA-->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<!--BEGIN PROJECT_LOGO-->
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td style="padding-left: 0.5em;">
<div id="projectname">$projectname
<!--BEGIN PROJECT_NUMBER-->&#160;<span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
</div>
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
</td>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->
<!--BEGIN PROJECT_BRIEF-->
<td style="padding-left: 0.5em;">
<div id="projectbrief">$projectbrief</div>
</td>
<!--END PROJECT_BRIEF-->
<!--END !PROJECT_NAME-->
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN SEARCHENGINE-->
<td>$searchbox</td>
<!--END SEARCHENGINE-->
<!--END DISABLE_INDEX-->
</tr>
</tbody>
</table>
</div>
<!--END TITLEAREA-->
<!-- end header part -->

+ 1430
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Documentation/styles/html/styleSheetFile.css
File diff suppressed because it is too large
View File


+ 2295
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Doxyfile
File diff suppressed because it is too large
View File


+ 154
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/Makefile View File

@@ -0,0 +1,154 @@
#############################################################################
#
# Makefile for MySensors
#
#
# The arduino library build part were inspired by
# Arduino-Makefile project, Copyright (C) 2012 Sudar <http://sudarmuthu.com>
#
# Description:
# ------------
# use make all and make install to install the gateway
#

CONFIG_FILE=Makefile.inc

include $(CONFIG_FILE)

CPPFLAGS+=-Ofast -g -Wall -Wextra
DEPFLAGS=-MT $@ -MMD -MP

GATEWAY_BIN=mysgw
GATEWAY=$(BINDIR)/$(GATEWAY_BIN)
GATEWAY_C_SOURCES=$(wildcard drivers/Linux/*.c)
GATEWAY_CPP_SOURCES=$(wildcard drivers/Linux/*.cpp) examples_linux/mysgw.cpp
GATEWAY_OBJECTS=$(patsubst %.c,$(BUILDDIR)/%.o,$(GATEWAY_C_SOURCES)) $(patsubst %.cpp,$(BUILDDIR)/%.o,$(GATEWAY_CPP_SOURCES))

INCLUDES=-I. -I./core -I./drivers/Linux

ifeq ($(SOC),$(filter $(SOC),BCM2835 BCM2836 BCM2837))
BCM_C_SOURCES=$(wildcard drivers/BCM/*.c)
BCM_CPP_SOURCES=$(wildcard drivers/BCM/*.cpp)
GATEWAY_OBJECTS+=$(patsubst %.c,$(BUILDDIR)/%.o,$(BCM_C_SOURCES)) $(patsubst %.cpp,$(BUILDDIR)/%.o,$(BCM_CPP_SOURCES))

INCLUDES+=-I./drivers/BCM
endif

# Gets include flags for library
get_library_includes = $(if $(and $(wildcard $(1)/src), $(wildcard $(1)/library.properties)), \
-I$(1)/src, \
$(addprefix -I,$(1) $(wildcard $(1)/utility)))

# Gets all sources with given extension (param2) for library (path = param1)
# for old (1.0.x) layout looks in . and "utility" directories
# for new (1.5.x) layout looks in src and recursively its subdirectories
get_library_files = $(if $(and $(wildcard $(1)/src), $(wildcard $(1)/library.properties)), \
$(call rwildcard,$(1)/src/,*.$(2)), \
$(wildcard $(1)/*.$(2) $(1)/utility/*.$(2)))

ifdef ARDUINO_LIB_DIR
ARDUINO=arduino
ARDUINO_LIBS:=$(shell find $(ARDUINO_LIB_DIR) -mindepth 1 -maxdepth 1 -type d)
ARDUINO_INCLUDES:=$(foreach lib, $(ARDUINO_LIBS), $(call get_library_includes,$(lib)))
ARDUINO_LIB_CPP_SRCS:=$(foreach lib, $(ARDUINO_LIBS), $(call get_library_files,$(lib),cpp))
ARDUINO_LIB_C_SRCS:=$(foreach lib, $(ARDUINO_LIBS), $(call get_library_files,$(lib),c))
ARDUINO_LIB_AS_SRCS:=$(foreach lib, $(ARDUINO_LIBS), $(call get_library_files,$(lib),S))
ARDUINO_LIB_OBJS=$(patsubst $(ARDUINO_LIB_DIR)/%.cpp,$(BUILDDIR)/arduinolibs/%.cpp.o,$(ARDUINO_LIB_CPP_SRCS)) \
$(patsubst $(ARDUINO_LIB_DIR)/%.c,$(BUILDDIR)/arduinolibs/%.c.o,$(ARDUINO_LIB_C_SRCS)) \
$(patsubst $(ARDUINO_LIB_DIR)/%.S,$(BUILDDIR)/arduinolibs/%.S.o,$(ARDUINO_LIB_AS_SRCS))

INCLUDES+=$(ARDUINO_INCLUDES)
DEPS+=$(ARDUINO_LIB_OBJS:.o=.d)
endif

DEPS+=$(GATEWAY_OBJECTS:.o=.d)

.PHONY: all createdir cleanconfig clean install uninstall

all: createdir $(ARDUINO) $(GATEWAY)

createdir:
@mkdir -p $(BUILDDIR) $(BINDIR)

# Arduino libraries Build
$(ARDUINO): CPPFLAGS+=-DARDUINO=100
$(ARDUINO): $(ARDUINO_LIB_OBJS)
@printf "[Done building Arduino Libraries]\n"

# Gateway Build
$(GATEWAY): $(GATEWAY_OBJECTS) $(ARDUINO_LIB_OBJS)
$(CXX) $(LDFLAGS) -o $@ $(GATEWAY_OBJECTS) $(ARDUINO_LIB_OBJS)

# Include all .d files
-include $(DEPS)

$(BUILDDIR)/arduinolibs/%.cpp.o: $(ARDUINO_LIB_DIR)/%.cpp
@mkdir -p $(dir $@)
$(CXX) $(DEPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $< -o $@

$(BUILDDIR)/arduinolibs/%.c.o: $(ARDUINO_LIB_DIR)/%.c
@mkdir -p $(dir $@)
$(CC) $(DEPFLAGS) $(CPPFLAGS) $(CFLAGS) $(INCLUDES) -c $< -o $@

$(BUILDDIR)/arduinolibs/%.S.o: $(ARDUINO_LIB_DIR)/%.S
@mkdir -p $(dir $@)
$(CC) $(DEPFLAGS) $(CPPFLAGS) $(ASFLAGS) $(INCLUDES) -c $< -o $@

$(BUILDDIR)/%.o: %.cpp
@mkdir -p $(dir $@)
$(CXX) $(DEPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $< -o $@

$(BUILDDIR)/%.o: %.c
@mkdir -p $(dir $@)
$(CC) $(DEPFLAGS) $(CPPFLAGS) $(CFLAGS) $(INCLUDES) -c $< -o $@

# clear configuration files
cleanconfig:
@echo "[Cleaning configuration]"
rm -rf $(CONFIG_FILE)

# clear build files
clean:
@echo "[Cleaning]"
rm -rf $(BUILDDIR) $(BINDIR)

$(CONFIG_FILE):
@echo "[Running configure]"
@./configure --no-clean

install: all install-gateway install-initscripts

install-gateway:
@echo "Installing $(GATEWAY) to ${DESTDIR}$(GATEWAY_DIR)"
@install -m 0755 $(GATEWAY) ${DESTDIR}$(GATEWAY_DIR)

install-initscripts:
ifeq ($(INIT_SYSTEM), systemd)
install -m0644 initscripts/mysgw.systemd ${DESTDIR}/etc/systemd/system/mysgw.service
@sed -i -e "s|%gateway_dir%|${GATEWAY_DIR}|g" ${DESTDIR}/etc/systemd/system/mysgw.service
systemctl daemon-reload
@echo "MySensors gateway has been installed, to add to the boot run:"
@echo " sudo systemctl enable mysgw.service"
@echo "To start the gateway run:"
@echo " sudo systemctl start mysgw.service"
else ifeq ($(INIT_SYSTEM), sysvinit)
install -m0755 initscripts/mysgw.sysvinit ${DESTDIR}/etc/init.d/mysgw
@sed -i -e "s|%gateway_dir%|${GATEWAY_DIR}|g" ${DESTDIR}/etc/init.d/mysgw
@echo "MySensors gateway has been installed, to add to the boot run:"
@echo " sudo update-rc.d mysgw defaults"
@echo "To start the gateway run:"
@echo " sudo service mysgw start"
endif

uninstall:
ifeq ($(INIT_SYSTEM), systemd)
@echo "Stopping daemon mysgw (ignore errors)"
-@systemctl stop mysgw.service
@echo "removing files"
rm /etc/systemd/system/mysgw.service $(GATEWAY_DIR)/$(GATEWAY_BIN)
else ifeq ($(INIT_SYSTEM), sysvinit)
@echo "Stopping daemon mysgw (ignore errors)"
-@service mysgw stop
@echo "removing files"
rm /etc/init.d/mysgw $(GATEWAY_DIR)/$(GATEWAY_BIN)
endif

+ 1074
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/MyASM.S
File diff suppressed because it is too large
View File


+ 2347
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/MyConfig.h
File diff suppressed because it is too large
View File


+ 456
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/MySensors.h View File

@@ -0,0 +1,456 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

/**
* @defgroup MySensorsgrp MySensors
* @ingroup publics
* @{
* @brief The primary public API declaration for the MySensors library
*/

/**
* @file MySensors.h
*
* @brief API declaration for MySensors
*
* Include this header into your sketch to include the MySensors library and harness the power of
* all those sensors!
*/
#ifndef MySensors_h
#define MySensors_h

#ifdef __cplusplus
#include <Arduino.h>
#endif

#include "MyConfig.h"
#include "core/MySplashScreen.h"
#include "core/MySensorsCore.h"

// OTA Debug, has to be defined before HAL
#if defined(MY_OTA_LOG_SENDER_FEATURE) || defined(MY_OTA_LOG_RECEIVER_FEATURE)
#include "core/MyOTALogging.h"
#endif

// HARDWARE
#include "hal/architecture/MyHwHAL.h"
#include "hal/crypto/MyCryptoHAL.h"
#if defined(ARDUINO_ARCH_ESP8266)
#include "hal/architecture/ESP8266/MyHwESP8266.cpp"
#include "hal/crypto/generic/MyCryptoGeneric.cpp"
#elif defined(ARDUINO_ARCH_ESP32)
#include "hal/architecture/ESP32/MyHwESP32.cpp"
#include "hal/crypto/ESP32/MyCryptoESP32.cpp"
#elif defined(ARDUINO_ARCH_AVR)
#include "hal/architecture/AVR/drivers/DigitalWriteFast/digitalWriteFast.h"
#include "hal/architecture/AVR/MyHwAVR.cpp"
#include "hal/crypto/AVR/MyCryptoAVR.cpp"
#elif defined(ARDUINO_ARCH_SAMD)
#include "drivers/extEEPROM/extEEPROM.cpp"
#include "hal/architecture/SAMD/MyHwSAMD.cpp"
#include "hal/crypto/generic/MyCryptoGeneric.cpp"
#elif defined(ARDUINO_ARCH_STM32F1)
#include "hal/architecture/STM32F1/MyHwSTM32F1.cpp"
#include "hal/crypto/generic/MyCryptoGeneric.cpp"
#elif defined(ARDUINO_ARCH_NRF5) || defined(ARDUINO_ARCH_NRF52)
#include "drivers/NVM/VirtualPage.cpp"
#include "drivers/NVM/NVRAM.cpp"
#include "hal/architecture/NRF5/MyHwNRF5.cpp"
#include "hal/crypto/generic/MyCryptoGeneric.cpp"
#elif defined(__arm__) && defined(TEENSYDUINO)
#include "hal/architecture/Teensy3/MyHwTeensy3.cpp"
#include "hal/crypto/generic/MyCryptoGeneric.cpp"
#elif defined(__linux__)
#include "hal/architecture/Linux/MyHwLinuxGeneric.cpp"
#include "hal/crypto/generic/MyCryptoGeneric.cpp"
#else
#error Hardware abstraction not defined (unsupported platform)
#endif

// commonly used macros, sometimes missing in arch definitions
#if !defined(_BV)
#define _BV(x) (1<<(x)) //!< _BV
#endif

#if !defined(min) && !defined(__linux__)
#define min(a,b) ((a)<(b)?(a):(b)) //!< min
#endif

#if !defined(max) && !defined(__linux__)
#define max(a,b) ((a)>(b)?(a):(b)) //!< max
#endif

#if !defined(MIN)
#define MIN min //!< MIN
#endif

#if !defined(MAX)
#define MAX max //!< MAX
#endif

// OTA Debug second part, depends on HAL
#if defined(MY_OTA_LOG_SENDER_FEATURE) || defined(MY_OTA_LOG_RECEIVER_FEATURE)
#include "core/MyOTALogging.cpp"
#endif

#if defined(MY_LEDS_BLINKING_FEATURE)
#error MY_LEDS_BLINKING_FEATURE is now removed from MySensors core,\
define MY_DEFAULT_ERR_LED_PIN, MY_DEFAULT_TX_LED_PIN or\
MY_DEFAULT_RX_LED_PIN in your sketch instead to enable LEDs
#endif

#if defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN)
#include "core/MyLeds.cpp"
#else
#include "core/MyLeds.h"
#endif

#include "core/MyIndication.cpp"


// INCLUSION MODE
#if defined(MY_INCLUSION_MODE_FEATURE)
#include "core/MyInclusionMode.cpp"
#endif


// SIGNING
#include "core/MySigning.cpp"
#if defined(MY_SIGNING_FEATURE)
// SIGNING COMMON FUNCTIONS
#if defined(MY_SIGNING_ATSHA204) && defined(MY_SIGNING_SOFT)
#error Only one signing engine can be activated
#endif
#if defined(MY_SIGNING_ATSHA204) && defined(__linux__)
#error No support for ATSHA204 on this platform
#endif

#if defined(MY_SIGNING_ATSHA204)
#include "core/MySigningAtsha204.cpp"
#include "drivers/ATSHA204/ATSHA204.cpp"
#elif defined(MY_SIGNING_SOFT)
#include "core/MySigningAtsha204Soft.cpp"
#endif
#endif

// FLASH
#if defined(MY_OTA_FIRMWARE_FEATURE)
#ifndef MCUBOOT_PRESENT
#if defined(MY_OTA_USE_I2C_EEPROM)
#include "drivers/I2CEeprom/I2CEeprom.cpp"
#else
#include "drivers/SPIFlash/SPIFlash.cpp"
#endif
#endif
#include "core/MyOTAFirmwareUpdate.cpp"
#endif

// GATEWAY - TRANSPORT
#if defined(MY_CONTROLLER_IP_ADDRESS) || defined(MY_CONTROLLER_URL_ADDRESS)
#define MY_GATEWAY_CLIENT_MODE //!< gateway client mode
#endif

#if defined(MY_USE_UDP) && !defined(MY_GATEWAY_CLIENT_MODE)
#error You must specify MY_CONTROLLER_IP_ADDRESS or MY_CONTROLLER_URL_ADDRESS for UDP
#endif

#if defined(MY_GATEWAY_MQTT_CLIENT)
#if defined(MY_SENSOR_NETWORK)
// We assume that a gateway having a radio also should act as repeater
#define MY_REPEATER_FEATURE
#endif

// GATEWAY - COMMON FUNCTIONS
// We support MQTT Client using W5100, ESP8266, GSM modems supported by TinyGSM library and Linux
#if !defined(MY_GATEWAY_CLIENT_MODE) && !defined(MY_GATEWAY_TINYGSM)
#error You must specify MY_CONTROLLER_IP_ADDRESS or MY_CONTROLLER_URL_ADDRESS
#endif

#if defined(MY_GATEWAY_TINYGSM) && !defined(MY_GATEWAY_MQTT_CLIENT)
// TinyGSM currently only supports MQTTClient mode.
#error MY_GATEWAY_TINYGSM only works with MY_GATEWAY_MQTT_CLIENT
#endif

#if !defined(MY_MQTT_PUBLISH_TOPIC_PREFIX)
#error You must specify a topic publish prefix MY_MQTT_PUBLISH_TOPIC_PREFIX for this MQTT client
#endif

#if !defined(MY_MQTT_SUBSCRIBE_TOPIC_PREFIX)
#error You must specify a topic subscribe prefix MY_MQTT_SUBSCRIBE_TOPIC_PREFIX for this MQTT client
#endif

#if !defined(MY_MQTT_CLIENT_ID)
#error You must define a unique MY_MQTT_CLIENT_ID for this MQTT client
#endif

#include "core/MyGatewayTransport.cpp"
#include "core/MyProtocolMySensors.cpp"

#if defined(MY_GATEWAY_TINYGSM)
#include "drivers/TinyGSM/TinyGsmClient.h"
#endif

#if defined(MY_GATEWAY_LINUX)
#include "drivers/Linux/EthernetClient.h"
#include "drivers/Linux/EthernetServer.h"
#include "drivers/Linux/IPAddress.h"
#endif
#include "drivers/PubSubClient/PubSubClient.cpp"
#include "core/MyGatewayTransportMQTTClient.cpp"
#elif defined(MY_GATEWAY_FEATURE)
// GATEWAY - COMMON FUNCTIONS
#include "core/MyGatewayTransport.cpp"

#include "core/MyProtocolMySensors.cpp"

// GATEWAY - CONFIGURATION
#if defined(MY_SENSOR_NETWORK)
// We assume that a gateway having a radio also should act as repeater
#define MY_REPEATER_FEATURE
#endif

#if !defined(MY_PORT)
#error You must define MY_PORT (controller or gateway port to open)
#endif
#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
// GATEWAY - ESP8266 / ESP32
#include "core/MyGatewayTransportEthernet.cpp"
#elif defined(MY_GATEWAY_LINUX)
// GATEWAY - Generic Linux
#if defined(MY_USE_UDP)
#error UDP mode is not available for Linux
#endif
#include "drivers/Linux/EthernetClient.h"
#include "drivers/Linux/EthernetServer.h"
#include "drivers/Linux/IPAddress.h"
#include "core/MyGatewayTransportEthernet.cpp"
#elif defined(MY_GATEWAY_W5100)
// GATEWAY - W5100
#include "core/MyGatewayTransportEthernet.cpp"
#elif defined(MY_GATEWAY_ENC28J60)
// GATEWAY - ENC28J60
#if defined(MY_USE_UDP)
#error UDP mode is not available for ENC28J60
#endif
#include "core/MyGatewayTransportEthernet.cpp"
#elif defined(MY_GATEWAY_SERIAL)
// GATEWAY - SERIAL
#include "core/MyGatewayTransportSerial.cpp"
#endif
#endif

// TRANSPORT
#ifndef DOXYGEN
// count enabled transports
#if defined(MY_RADIO_RF24)
#define __RF24CNT 1 //!< __RF24CNT
#else
#define __RF24CNT 0 //!< __RF24CNT
#endif
#if defined(MY_RADIO_NRF5_ESB)
#define __NRF5ESBCNT 1 //!< __NRF5ESBCNT
#else
#define __NRF5ESBCNT 0 //!< __NRF5ESBCNT
#endif
#if defined(MY_RADIO_RFM69)
#define __RFM69CNT 1 //!< __RFM69CNT
#else
#define __RFM69CNT 0 //!< __RFM69CNT
#endif
#if defined(MY_RADIO_RFM95)
#define __RFM95CNT 1 //!< __RFM95CNT
#else
#define __RFM95CNT 0 //!< __RFM95CNT
#endif
#if defined(MY_RS485)
#define __RS485CNT 1 //!< __RS485CNT
#else
#define __RS485CNT 0 //!< __RS485CNT
#endif

#if (__RF24CNT + __NRF5ESBCNT + __RFM69CNT + __RFM95CNT + __RS485CNT > 1)
#error Only one forward link driver can be activated
#endif
#endif //DOXYGEN

// SANITY CHECK
#if defined(MY_REPEATER_FEATURE) || defined(MY_GATEWAY_FEATURE)
#define MY_TRANSPORT_SANITY_CHECK //!< enable regular transport sanity checks
#endif

// TRANSPORT INCLUDES
#if defined(MY_RADIO_RF24) || defined(MY_RADIO_NRF5_ESB) || defined(MY_RADIO_RFM69) || defined(MY_RADIO_RFM95) || defined(MY_RS485)
#include "hal/transport/MyTransportHAL.h"
#include "core/MyTransport.h"

// PARENT CHECK
#if defined(MY_PARENT_NODE_IS_STATIC) && (MY_PARENT_NODE_ID == AUTO)
#error Parent is static but no parent ID defined, set MY_PARENT_NODE_ID.
#endif

#if defined(MY_TRANSPORT_DONT_CARE_MODE)
#error MY_TRANSPORT_DONT_CARE_MODE is deprecated, set MY_TRANSPORT_WAIT_READY_MS instead!
#endif

// RAM ROUTING TABLE
#if defined(MY_RAM_ROUTING_TABLE_FEATURE) && defined(MY_REPEATER_FEATURE)
// activate feature based on architecture
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_NRF5) || defined(ARDUINO_ARCH_STM32F1) || defined(TEENSYDUINO) || defined(__linux__)
#define MY_RAM_ROUTING_TABLE_ENABLED
#elif defined(ARDUINO_ARCH_AVR)
#if defined(__avr_atmega1280__) || defined(__avr_atmega1284__) || defined(__avr_atmega2560__)
// >4kb, enable it
#define MY_RAM_ROUTING_TABLE_ENABLED
#else
// memory limited, enable with care
// #define MY_RAM_ROUTING_TABLE_ENABLED
#endif // __avr_atmega1280__, __avr_atmega1284__, __avr_atmega2560__
#endif // ARDUINO_ARCH_AVR
#endif
#ifdef DOXYGEN
/**
* @def MY_RAM_ROUTING_TABLE_ENABLED
* @brief Automatically set if RAM routing table is enabled
*
* @see MY_RAM_ROUTING_TABLE_FEATURE
*/
#define MY_RAM_ROUTING_TABLE_ENABLED
#endif

// SOFTSPI
#ifdef MY_SOFTSPI
#if defined(ARDUINO_ARCH_ESP8266)
#error Soft SPI is not available on ESP8266
#endif
#include "hal/architecture/AVR/drivers/DigitalIO/DigitalIO.h"
#endif

// SOFTSERIAL
#if defined(MY_GSM_TX) != defined(MY_GSM_RX)
#error Both, MY_GSM_TX and MY_GSM_RX need to be defined when using SoftSerial
#endif

#if defined(MY_GATEWAY_TINYGSM) && !defined(SerialAT) && (!defined(MY_GSM_TX) || !defined(MY_GSM_RX))
#error You need to define either SerialAT or MY_GSM_RX and MY_GSM_TX pins
#endif

// POWER PIN
#ifndef DOXYGEN
#if defined(MY_RF24_POWER_PIN) || defined(MY_RFM69_POWER_PIN) || defined(MY_RFM95_POWER_PIN) || defined(MY_RADIO_NRF5_ESB)
#define RADIO_CAN_POWER_OFF (true)
#else
#define RADIO_CAN_POWER_OFF (false)
#endif
#endif

// Transport drivers
#if defined(MY_RADIO_RF24)
#include "hal/transport/RF24/driver/RF24.cpp"
#include "hal/transport/RF24/MyTransportRF24.cpp"
#elif defined(MY_RADIO_NRF5_ESB)
#if !defined(ARDUINO_ARCH_NRF5)
#error No support for nRF5 radio on this platform
#endif
#include "hal/transport/NRF5_ESB/driver/Radio.cpp"
#include "hal/transport/NRF5_ESB/driver/Radio_ESB.cpp"
#include "hal/transport/NRF5_ESB/MyTransportNRF5_ESB.cpp"
#elif defined(MY_RS485)
#if !defined(MY_RS485_HWSERIAL)
#if defined(__linux__)
#error You must specify MY_RS485_HWSERIAL for RS485 transport
#endif
#include "drivers/AltSoftSerial/AltSoftSerial.cpp"
#endif
#include "hal/transport/RS485/MyTransportRS485.cpp"
#elif defined(MY_RADIO_RFM69)
#if defined(MY_RFM69_NEW_DRIVER)
#include "hal/transport/RFM69/driver/new/RFM69_new.cpp"
#else
#include "hal/transport/RFM69/driver/old/RFM69_old.cpp"
#endif
#include "hal/transport/RFM69/MyTransportRFM69.cpp"
#elif defined(MY_RADIO_RFM95)
#include "hal/transport/RFM95/driver/RFM95.cpp"
#include "hal/transport/RFM95/MyTransportRFM95.cpp"
#endif

// PASSIVE MODE
#if defined(MY_PASSIVE_NODE) && !defined(DOXYGEN)
#define MY_TRANSPORT_UPLINK_CHECK_DISABLED
#define MY_PARENT_NODE_IS_STATIC
#undef MY_REGISTRATION_FEATURE
#undef MY_SIGNING_FEATURE
#undef MY_OTA_FIRMWARE_FEATURE
#if (defined(MY_GATEWAY_FEATURE) || defined(MY_REPEATER_FEATURE))
#error This node is configured as GW/repeater, MY_PASSIVE_NODE cannot be set simultaneously
#endif
#if (MY_NODE_ID == AUTO)
#error MY_PASSIVE_NODE configuration requires setting MY_NODE_ID
#endif
#endif

#include "core/MyTransport.cpp"
#endif

// Make sure to disable child features when parent feature is disabled
#if !defined(MY_SENSOR_NETWORK)
#undef MY_OTA_FIRMWARE_FEATURE
#undef MY_REPEATER_FEATURE
#undef MY_SIGNING_NODE_WHITELISTING
#undef MY_SIGNING_FEATURE
#endif

#if !defined(MY_GATEWAY_FEATURE)
#undef MY_INCLUSION_MODE_FEATURE
#undef MY_INCLUSION_BUTTON_FEATURE
#endif

#if !defined(MY_CORE_ONLY)
#if !defined(MY_GATEWAY_FEATURE) && !defined(MY_SENSOR_NETWORK)
#error No forward link or gateway feature activated. This means nowhere to send messages! Pretty pointless.
#endif
#endif

#include "core/MyCapabilities.h"
#include "core/MyMessage.cpp"
#include "core/MySplashScreen.cpp"
#include "core/MySensorsCore.cpp"

// HW mains
#if defined(ARDUINO_ARCH_AVR)
#include "hal/architecture/AVR/MyMainAVR.cpp"
#elif defined(ARDUINO_ARCH_SAMD)
#include "hal/architecture/SAMD/MyMainSAMD.cpp"
#elif defined(ARDUINO_ARCH_ESP8266)
#include "hal/architecture/ESP8266/MyMainESP8266.cpp"
#elif defined(ARDUINO_ARCH_NRF5)
#include "hal/architecture/NRF5/MyMainNRF5.cpp"
#elif defined(ARDUINO_ARCH_ESP32)
#include "hal/architecture/ESP32/MyMainESP32.cpp"
#elif defined(__linux__)
#include "hal/architecture/Linux/MyMainLinuxGeneric.cpp"
#elif defined(ARDUINO_ARCH_STM32F1)
#include "hal/architecture/STM32F1/MyMainSTM32F1.cpp"
#elif defined(TEENSYDUINO)
#include "hal/architecture/Teensy3/MyMainTeensy3.cpp"
#endif

#endif

/** @}*/

+ 17
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/README.md View File

@@ -0,0 +1,17 @@
MySensors Library v2.3.1

Please visit www.mysensors.org for more information

Documentation
-------------
[master](https://www.mysensors.org/apidocs/index.html) [development](https://www.mysensors.org/apidocs-beta/index.html)

CI statuses
-----------
Current build status of master branch: [![Build Status](https://ci.mysensors.org/job/MySensors/job/MySensors/job/master/badge/icon)](https://ci.mysensors.org/job/MySensors/job/MySensors/job/master/)

Current build status of development branch: [![Build Status](https://ci.mysensors.org/job/MySensors/job/MySensors/job/development/badge/icon)](https://ci.mysensors.org/job/MySensors/job/MySensors/job/development/)

Current build status of master branch (nightly build of Arduino IDE): [![Build Status](https://ci.mysensors.org/job/MySensors-nightly-IDE/job/MySensors/job/master/badge/icon)](https://ci.mysensors.org/job/MySensors-nightly-IDE/job/MySensors/job/master/)

Current build status of development branch (nightly build of Arduino IDE): [![Build Status](https://ci.mysensors.org/job/MySensors-nightly-IDE/job/MySensors/job/development/badge/icon)](https://ci.mysensors.org/job/MySensors-nightly-IDE/job/MySensors/job/development/)

+ 701
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/configure View File

@@ -0,0 +1,701 @@
#!/bin/bash
# This version is heavily based on the work of mz-fuzzy (https://github.com/mz-fuzzy)
# adapted to work with MySensors project.
# Original work: https://github.com/TMRh20/RF24/blob/master/configure

function help {
cat <<EOF
configure script for MySensors gateway.
Options:

Help:
-h, --help print this message

SPI driver options:
--spi-driver=[BCM|SPIDEV]
--spi-spidev-device=<DEVICE>
Device path. [/dev/spidev0.0]

Building options:
--soc=[BCM2835|BCM2836|BCM2837|AM33XX|A10|A13|A20|H3]
SoC type to be used. [configure autodetected]
--cpu-flags=<CPUFLAGS> CPU defining/optimizing flags to be used. [configure autodetected]
--extra-cflags=<CFLAGS> Extra C flags passed to C compilation. []
--extra-cxxflags=<CXXFLAGS> Extra C++ flags passed to C++ compilation. []
Example: --extra-cxxflags="-DMY_RX_MESSAGE_BUFFER_SIZE=\(32\) -DMY_RF24_DATARATE=\(RF24_2MBPS\)"
--extra-ldflags=<LDFLAGS> Extra C flags passed to linking. []
--c_compiler=<CC> C compiler. [arm-linux-gnueabihf-gcc][gcc]
--cxx_compiler=<CXX> C++ compiler. [arm-linux-gnueabihf-g++][g++]
--build-dir=<DIR> Compiler directory to store object files. [build]
--bin-dir=<DIR> Compiler directory to store binary files. [bin]
--arduino-lib-dir=<DIR> Arduino library directory.
--no-clean Don't clean previous build artifacts.

Installation options:
--prefix=<PREFIX> Installation prefix path. [/usr/local]
--gateway-dir=<DIR> Gateway files installation directory. [PREFIX/bin]

MySensors options:
--my-debug=[enable|disable] Enables or disables MySensors core debugging. [enable]
--my-config-file=<FILE> Config file path. [/etc/mysensors.conf]
--my-gateway=[none|ethernet|serial|mqtt]
Set the protocol used to communicate with the controller. [ethernet]
--my-node-id=<ID> Disable gateway feature and run as a node with the specified id.
--my-controller-url-address=<URL>
Controller or MQTT broker url.
--my-controller-ip-address=<IP>
Controller or MQTT broker ip.
--my-port=<PORT> The port to keep open on gateway mode.
If gateway is set to mqtt, it sets the broker port.
--my-serial-port=<PORT> Serial port.
--my-serial-baudrate=<BAUD> Serial baud rate. [115200]
--my-serial-is-pty Set the serial port to be a pseudo terminal. Use this if you want
to connect to a controller running on the same device.
You also need to set the symlink name for the PTY device with
the --my-serial-port option.
--my-serial-groupname=<GROUP>
Grant access to the specified system group for the serial device.
--my-mqtt-client-id=<ID> MQTT client id.
--my-mqtt-user=<UID> MQTT user id.
--my-mqtt-password=<PASS> MQTT password.
--my-mqtt-publish-topic-prefix=<PREFIX>
MQTT publish topic prefix.
--my-mqtt-subscribe-topic-prefix=<PREFIX>
MQTT subscribe topic prefix.
--my-transport=[none|rf24|rs485|rfm95|rfm69]
Set the transport to be used to communicate with other nodes. [rf24]
--my-rf24-channel=<0-125> RF channel for the sensor net. [76]
--my-rf24-pa-level=[RF24_PA_MAX|RF24_PA_LOW]
RF24 PA level. [RF24_PA_MAX]
--my-rf24-ce-pin=<PIN> Pin number to use for rf24 Chip-Enable.
--my-rf24-cs-pin=<PIN> Pin number to use for rf24 Chip-Select.
--my-rf24-irq-pin=<PIN> Pin number connected to nRF24L01P IRQ pin.
--my-rf24-encryption-enabled
Enables RF24 encryption.
All nodes and gateway must have this enabled, and all must be
personalized with the same AES key.
--my-rx-message-buffer-size=<SIZE>
Buffer size for incoming messages when using rf24 interrupts. [20]
--my-rfm69-frequency=[315|433|865|868|915]
RFM69 Module Frequency. [868]
--my-is-rfm69hw Enable high-powered rfm69hw.
--my-rfm69-irq-pin=<PIN> Pin number connected to RFM69 IRQ pin.
--my-rfm69-cs-pin=<PIN> Pin number to use for RFM69 Chip-Select.
--my-rfm69-encryption-enabled
Enables RFM69 encryption.
All nodes and gateway must have this enabled, and all must be
personalized with the same AES key.
--my-rfm95-frequency=[169|315|434|868|915]
RFM95 Module Frequency. [868]
--my-rfm95-irq-pin=<PIN> Pin number connected to RFM95 IRQ pin.
--my-rfm95-cs-pin=<PIN> Pin number to use for RFM95 Chip-Select.
--my-rfm95-encryption-enabled
Enables RFM95 encryption.
All nodes and gateway must have this enabled, and all must be
personalized with the same AES key.
--my-rs485-serial-port=<PORT>
RS485 serial port. You must provide a port.
--my-rs485-baudrate=<BAUD> RS485 baudrate. [9600]
--my-rs485-de-pin=<PIN> Pin number connected to RS485 driver enable pin.
--my-rs485-max-msg-length=<LENGTH>
The maximum message length used for RS485. [40]
--my-leds-err-pin=<PIN> Error LED pin.
--my-leds-rx-pin=<PIN> Receive LED pin.
--my-leds-tx-pin=<PIN> Transmit LED pin.
--my-leds-blinking-inverse Inverse the blinking feature.
--my-signing=[none|software|password]
Message signing. [none]
--my-signing-debug Enable signing related debug.
--my-signing-request-signatures
Enable signature request from nodes that in turn requested
gateway signature.
--my-signing-weak_security Enable this to permit downgrade of security preferences and
relaxed gateway signing requirements.
--my-signing-whitelist=<WHITELIST>
If you want to use a whitelist, provide it here, make sure to avoid
spaces in the <whitelist> expression.
--my-signing-verification-timeout-ms=<TIMEOUT>
Signing timeout. [5000]
--my-security-password=<PASSWORD>
If you are using password for signing/encryption, set your password here.
EOF
}

# Colors
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
LIGHT_BLUE='\033[1;34m'
NO_COLOR='\033[0m'

OK="${GREEN}[OK]${NO_COLOR}"
ERROR="${RED}[ERROR]${NO_COLOR}"
FAILED="${YELLOW}[FAILED]${NO_COLOR}"
SECTION="${LIGHT_BLUE}[SECTION]${NO_COLOR}"

function die {
printf "${ERROR} $1 \n"
exit $2
}

function detect_rpi_revision {
# get PI Revision from cpuinfo
local pirev=$(eval "cat /proc/cpuinfo 2>/dev/null | grep Revision | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$$//'")
echo ${pirev}
}

function detect_machine {
local cpu=$(eval "uname -m 2>/dev/null")
local machine=$(eval "cat /sys/firmware/devicetree/base/model 2>/dev/null |tr -d '\0'")
local hardware=$(eval "grep sunxi_platform /sys/class/sunxi_info/sys_info 2>/dev/null | sed 's/^.*: \(.*\)$/\1/'")
if [ -z "$hardware" ]; then
local hardware=$(eval "grep Hardware /proc/cpuinfo 2>/dev/null | sed 's/^.*: \(.*\)$/\1/'")
fi
local soc="unknown"
local tp="unknown"

if [ -z "$cpu" ]; then
cpu="unknown"
fi

case $hardware in
BCM*)
if [[ $machine == "Raspberry"* ]]; then
# Calculation done by joolswills(https://github.com/joolswills) for the RetroPie-Setup project
# and based on information from https://github.com/AndrewFromMelbourne/raspberry_pi_revision
local rev="0x$(sed -n '/^Revision/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo)"
# if bit 23 is not set, we are on a rpi1 (bit 23 means the revision is a bitfield)
if [[ $((($rev >> 23) & 1)) -eq 0 ]]; then
soc="BCM2835"
tp="rpi1"
else
# if bit 23 is set, get the cpu from bits 12-15
case "$((($rev >> 12) & 15))" in
0)
soc="BCM2835"
tp="rpi1"
;;
1)
soc="BCM2836"
tp="rpi2"
;;
2)
soc="BCM2837"
tp="rpi3"
;;
esac
fi
elif [[ $hardware == "BCM2708"* ]]; then
soc="BCM2835"
elif [[ $hardware == "BCM2709"* ]]; then
soc="BCM2836"
elif [[ $hardware == "BCM2710"* ]]; then
soc="BCM2837"
fi
;;
*sun4i*|*Sun4iw1p1*)
soc="A10"
;;
*sun5i*|*Sun4iw2p1*)
soc="A13"
;;
*Sun4iw2p2*)
soc="A12"
;;
*Sun4iw2p3*)
soc="A10s"
;;
*sun6i*|*Sun8iw1p1*)
soc="A31"
;;
*Sun8iw1p2*)
soc="A31s"
;;
*sun7i*|*Sun8iw2p1*)
soc="A20"
if [[ $machine == "Banana Pi"* ]]; then
tp="BananaPi"
elif [[ $machine == "Banana Pro"* ]]; then
tp="BananaPro"
fi
;;
*sun8i*|*Sun8iw7p1*)
soc="H3"
;;
*Sun8iw3p1*)
soc="A23"
;;
*Sun8iw5p1*)
soc="A33"
;;
*Sun8iw6p1*)
soc="A83t"
;;
*sun9i*|*Sun9iw1p1*)
soc="A80"
;;
*Sun9iw1p2*)
soc="A80t"
;;
*sun50i*|*Sun50iw1p1*)
soc="A64"
;;
'Generic AM33XX'*)
soc="AM33XX"
;;
*)
soc="unknown"
esac
echo "${soc} ${tp} ${cpu}"
}

function gcc_cpu_flags {
local soc=$1
case $soc in
BCM2835)
flags="-march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard"
;;
BCM2836)
flags="-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard"
;;
BCM2837)
flags="-march=armv8-a+crc -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard"
;;
AM33XX)
flags="-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard"
;;
A10)
flags="-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard"
;;
A13)
flags="-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard"
;;
A20)
flags="-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard"
;;
H3)
flags="-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard"
;;
*)
flags=""
esac
echo ${flags}
}

# Default values
debug=enable
gateway_type=ethernet
transport_type=rf24
signing=none
signing_request_signatures=false
encryption=false

params="SOC CFLAGS CXXFLAGS CPPFLAGS LDFLAGS PREFIX CC CXX ARDUINO_LIB_DIR BUILDDIR BINDIR GATEWAY_DIR INIT_SYSTEM SPI_DRIVER"

for opt do
if [ "$opt" = "-h" ] || [ "$opt" = "--help" ]; then
help
exit 0
fi
optarg="${opt#*=}"
case "$opt" in
--spi-driver=*)
SPI_DRIVER="$optarg"
;;
--spi-spidev-device=*)
CPPFLAGS="-DSPI_SPIDEV_DEVICE=\\\"${optarg}\\\" $CPPFLAGS"
;;
--soc=*)
SOC="$optarg"
;;
--platform-type=*)
PT="$optarg"
;;
--cpu-flags=*)
CPUFLAGS="$optarg"
;;
--extra-cflags=*)
CFLAGS="$optarg"
;;
--extra-cxxflags=*)
CXXFLAGS="$optarg"
;;
--extra-ldflags=*)
LDFLAGS="$optarg"
;;
--c_compiler=*)
CC="$optarg"
;;
--cxx_compiler=*)
CXX="$optarg"
;;
--arduino-lib-dir=*)
ARDUINO_LIB_DIR=$optarg
;;
--build-dir=*)
BUILDDIR="$optarg"
;;
--bin-dir=*)
BINDIR="$optarg"
;;
--no-clean*)
NO_CLEAN="1"
;;
--prefix=*)
PREFIX="$optarg"
;;
--exec-prefix=*)
PREFIX="$optarg"
;;
--no_init_system*)
NO_INIT="1"
;;
--gateway-dir=*)
GATEWAY_DIR="$optarg"
;;
--my-debug=*)
debug=${optarg}
;;
--my-gateway=*)
gateway_type=${optarg}
;;
--my-node-id=*)
gateway_type="none";
CPPFLAGS="-DMY_NODE_ID=${optarg} $CPPFLAGS"
;;
--my-config-file=*)
CPPFLAGS="-DMY_LINUX_CONFIG_FILE=\\\"${optarg}\\\" $CPPFLAGS"
;;
--my-transport=*)
transport_type=${optarg}
;;
--my-serial-port=*)
CPPFLAGS="-DMY_LINUX_SERIAL_PORT=\\\"${optarg}\\\" $CPPFLAGS"
;;
--my-serial-baudrate=*)
CPPFLAGS="-DMY_BAUD_RATE=${optarg} $CPPFLAGS"
;;
--my-serial-is-pty*)
CPPFLAGS="-DMY_LINUX_SERIAL_IS_PTY $CPPFLAGS"
;;
--my-serial-pty=*)
echo "Warning: --my-serial-pty is deprecated, please use --my-serial-port"
CPPFLAGS="-DMY_LINUX_SERIAL_PORT=\\\"${optarg}\\\" $CPPFLAGS"
;;
--my-serial-groupname=*)
CPPFLAGS="-DMY_LINUX_SERIAL_GROUPNAME=\\\"${optarg}\\\" $CPPFLAGS"
;;
--my-rf24-channel=*)
CPPFLAGS="-DMY_RF24_CHANNEL=${optarg} $CPPFLAGS"
;;
--my-rf24-pa-level=*)
CPPFLAGS="-DMY_RF24_PA_LEVEL=${optarg} $CPPFLAGS"
;;
--my-rf24-ce-pin=*)
CPPFLAGS="-DMY_RF24_CE_PIN=${optarg} $CPPFLAGS"
;;
--my-rf24-cs-pin=*)
CPPFLAGS="-DMY_RF24_CS_PIN=${optarg} $CPPFLAGS"
;;
--my-controller-url-address=*)
CPPFLAGS="-DMY_CONTROLLER_URL_ADDRESS=\\\"${optarg}\\\" $CPPFLAGS"
;;
--my-controller-ip-address=*)
controller_ip=`echo ${optarg//./,}`
CPPFLAGS="-DMY_CONTROLLER_IP_ADDRESS=${controller_ip} $CPPFLAGS"
;;
--my-port=*)
CPPFLAGS="-DMY_PORT=${optarg} $CPPFLAGS"
;;
--my-mqtt-client-id=*)
CPPFLAGS="-DMY_MQTT_CLIENT_ID=\\\"${optarg}\\\" $CPPFLAGS"
;;
--my-mqtt-user=*)
CPPFLAGS="-DMY_MQTT_USER=\\\"${optarg}\\\" $CPPFLAGS"
;;
--my-mqtt-password=*)
CPPFLAGS="-DMY_MQTT_PASSWORD=\\\"${optarg}\\\" $CPPFLAGS"
;;
--my-mqtt-publish-topic-prefix=*)
CPPFLAGS="-DMY_MQTT_PUBLISH_TOPIC_PREFIX=\\\"${optarg}\\\" $CPPFLAGS"
;;
--my-mqtt-subscribe-topic-prefix=*)
CPPFLAGS="-DMY_MQTT_SUBSCRIBE_TOPIC_PREFIX=\\\"${optarg}\\\" $CPPFLAGS"
;;
--my-rf24-irq-pin=*)
CPPFLAGS="-DMY_RX_MESSAGE_BUFFER_FEATURE -DMY_RF24_IRQ_PIN=${optarg} $CPPFLAGS"
;;
--my-rf24-encryption-enabled*)
encryption=true
CPPFLAGS="-DMY_RF24_ENABLE_ENCRYPTION $CPPFLAGS"
;;
--my-rx-message-buffer-size=*)
CPPFLAGS="-DMY_RX_MESSAGE_BUFFER_SIZE=${optarg} $CPPFLAGS"
;;
--my-rfm69-frequency=*)
if [[ ${optarg} == "315" ]]; then
CPPFLAGS="-DMY_RFM69_FREQUENCY=RFM69_315MHZ $CPPFLAGS"
elif [[ ${optarg} == "433" ]]; then
CPPFLAGS="-DMY_RFM69_FREQUENCY=RFM69_433MHZ $CPPFLAGS"
elif [[ ${optarg} == "865" ]]; then
CPPFLAGS="-DMY_RFM69_FREQUENCY=RFM69_865MHZ $CPPFLAGS"
elif [[ ${optarg} == "868" ]]; then
CPPFLAGS="-DMY_RFM69_FREQUENCY=RFM69_868MHZ $CPPFLAGS"
elif [[ ${optarg} == "915" ]]; then
CPPFLAGS="-DMY_RFM69_FREQUENCY=RFM69_915MHZ $CPPFLAGS"
else
echo "[WARNING] Illegal value for --my-rfm69-frequency=${optarg}, ignored"
fi
;;
--my-is-rfm69hw*)
CPPFLAGS="-DMY_IS_RFM69HW $CPPFLAGS"
;;
--my-rfm69-irq-pin=*)
CPPFLAGS="-DMY_RFM69_IRQ_PIN=${optarg} $CPPFLAGS"
;;
--my-rfm69-cs-pin=*)
CPPFLAGS="-DMY_RFM69_CS_PIN=${optarg} $CPPFLAGS"
;;
--my-rfm69-encryption-enabled*)
encryption=true
CPPFLAGS="-DMY_RFM69_ENABLE_ENCRYPTION $CPPFLAGS"
;;
--my-rfm95-frequency=*)
if [[ ${optarg} == "169" ]]; then
CPPFLAGS="-DMY_RFM95_FREQUENCY=RFM95_169MHZ $CPPFLAGS"
elif [[ ${optarg} == "315" ]]; then
CPPFLAGS="-DMY_RFM95_FREQUENCY=RFM95_315MHZ $CPPFLAGS"
elif [[ ${optarg} == "434" ]]; then
CPPFLAGS="-DMY_RFM95_FREQUENCY=RFM95_434MHZ $CPPFLAGS"
elif [[ ${optarg} == "868" ]]; then
CPPFLAGS="-DMY_RFM95_FREQUENCY=RFM95_868MHZ $CPPFLAGS"
elif [[ ${optarg} == "915" ]]; then
CPPFLAGS="-DMY_RFM95_FREQUENCY=RFM95_915MHZ $CPPFLAGS"
else
echo "[WARNING] Illegal value for --my-rfm95-frequency=${optarg}, ignored"
fi
;;
--my-rfm95-irq-pin=*)
CPPFLAGS="-DMY_RFM95_IRQ_NUM=${optarg} $CPPFLAGS"
;;
--my-rfm95-cs-pin=*)
CPPFLAGS="-DMY_RFM95_CS_PIN=${optarg} $CPPFLAGS"
;;
--my-rfm95-encryption-enabled*)
encryption=true
CPPFLAGS="-DMY_RFM95_ENABLE_ENCRYPTION $CPPFLAGS"
;;
--my-rs485-serial-port=*)
CPPFLAGS="-DMY_RS485_HWSERIAL=\\\"${optarg}\\\" $CPPFLAGS"
;;
--my-rs485-baudrate=*)
CPPFLAGS="-DMY_RS485_BAUD_RATE=${optarg} $CPPFLAGS"
;;
--my-rs485-de-pin=*)
CPPFLAGS="-DMY_RS485_DE_PIN=${optarg} $CPPFLAGS"
;;
--my-rs485-max-msg-length=*)
CPPFLAGS="-DMY_RS485_MAX_MESSAGE_LENGTH=${optarg} $CPPFLAGS"
;;
--my-leds-err-pin=*)
CPPFLAGS="-DMY_DEFAULT_ERR_LED_PIN=${optarg} $CPPFLAGS"
;;
--my-leds-rx-pin=*)
CPPFLAGS="-DMY_DEFAULT_RX_LED_PIN=${optarg} $CPPFLAGS"
;;
--my-leds-tx-pin=*)
CPPFLAGS="-DMY_DEFAULT_TX_LED_PIN=${optarg} $CPPFLAGS"
;;
--my-leds-blinking-inverse*)
CPPFLAGS="-DMY_WITH_LEDS_BLINKING_INVERSE $CPPFLAGS"
;;
--my-signing=*)
signing=${optarg}
;;
--my-signing-debug*)
CPPFLAGS="-DMY_DEBUG_VERBOSE_SIGNING $CPPFLAGS"
;;
--my-signing-request-signatures*)
signing_request_signatures=true
;;
--my-signing-weak_security*)
CPPFLAGS="-DMY_SIGNING_WEAK_SECURITY $CPPFLAGS"
;;
--my-signing-whitelist*)
CPPFLAGS="-DMY_SIGNING_NODE_WHITELISTING=${optarg} $CPPFLAGS"
;;
--my-signing-verification-timeout-ms*)
CPPFLAGS="-DMY_VERIFICATION_TIMEOUT_MS=${optarg} $CPPFLAGS"
;;
--my-security-password=*)
security_password=${optarg}
;;
*)
echo "[WARNING] Unknown option detected:$opt, ignored"
;;
esac
done

PREFIX=${PREFIX:-/usr/local}
BUILDDIR=${BUILDDIR:-build}
BINDIR=${BINDIR:-bin}
GATEWAY_DIR=${GATEWAY_DIR:-${PREFIX}/bin}
CC=${CC:-gcc}
CXX=${CXX:-g++}

if [ -z "${SOC}" ]; then
printf "${SECTION} Detecting target machine.\n"
info=($(detect_machine))
SOC=${info[0]}
TYPE=${info[1]}
CPU=${info[2]}
printf " ${OK} machine detected: SoC=${SOC}, Type=${TYPE}, CPU=${CPU}.\n"
fi

if [ -z "${CPUFLAGS}" ]; then
CPUFLAGS=$(gcc_cpu_flags $SOC)
fi

if [[ $SOC == "BCM2835" || $SOC == "BCM2836" || $SOC == "BCM2837" ]]; then
CPPFLAGS="-DLINUX_ARCH_RASPBERRYPI $CPPFLAGS"
else
printf "${SECTION} Checking GPIO Sysfs.\n"
if [[ $(eval 'ls /sys/class/gpio/export 2>/dev/null') ]]; then
printf " ${OK} /sys/class/gpio/export found.\n"
else
echo " [WARNING] /sys/class/gpio/export not found."
fi
fi

if [ -z "${SPI_DRIVER}" ]; then
printf "${SECTION} Detecting SPI driver.\n"
if [[ $SOC == "BCM2835" || $SOC == "BCM2836" || $SOC == "BCM2837" ]]; then
SPI_DRIVER=BCM
elif [[ $(eval 'ls /dev/spidev* 2>/dev/null') ]]; then
SPI_DRIVER=SPIDEV
fi
if [ -n "${SPI_DRIVER}" ]; then
printf " ${OK} SPI driver detected:${SPI_DRIVER}.\n"
else
echo " [WARNING] No supported SPI driver detected. Using SPIDEV."
SPI_DRIVER=SPIDEV
fi
fi
if [ -n "${SPI_DRIVER}" ]; then
case ${SPI_DRIVER} in
BCM)
if [[ $SOC != "BCM2835" && $SOC != "BCM2836" && $SOC != "BCM2837" ]]; then
die "BCM SPI driver is only supported for SOCs BCM2835, BCM2836 or BCM2837" 5
fi
CPPFLAGS="-DLINUX_SPI_BCM $CPPFLAGS"
;;
SPIDEV)
CPPFLAGS="-DLINUX_SPI_SPIDEV $CPPFLAGS"
;;
*)
die "Unsupported SPI driver: ${SPI_DRIVER}." 1
;;
esac
fi

printf "${SECTION} Gateway configuration.\n"

if [[ ${debug} == "enable" ]]; then
CPPFLAGS="-DMY_DEBUG $CPPFLAGS"
fi

if [[ ${gateway_type} == "none" ]]; then
# Node mode selected
:
elif [[ ${gateway_type} == "ethernet" ]]; then
CPPFLAGS="-DMY_GATEWAY_LINUX $CPPFLAGS"
elif [[ ${gateway_type} == "serial" ]]; then
CPPFLAGS="-DMY_GATEWAY_SERIAL $CPPFLAGS"
elif [[ ${gateway_type} == "mqtt" ]]; then
CPPFLAGS="-DMY_GATEWAY_LINUX -DMY_GATEWAY_MQTT_CLIENT $CPPFLAGS"
else
die "Invalid gateway type." 2
fi
printf " ${OK} Type: ${gateway_type}.\n"

if [[ ${transport_type} == "none" ]]; then
# Transport disabled
:
elif [[ ${transport_type} == "rf24" ]]; then
CPPFLAGS="-DMY_RADIO_RF24 $CPPFLAGS"
elif [[ ${transport_type} == "rfm69" ]]; then
CPPFLAGS="-DMY_RADIO_RFM69 -DMY_RFM69_NEW_DRIVER $CPPFLAGS"
elif [[ ${transport_type} == "rs485" ]]; then
CPPFLAGS="-DMY_RS485 $CPPFLAGS"
elif [[ ${transport_type} == "rfm95" ]]; then
CPPFLAGS="-DMY_RADIO_RFM95 $CPPFLAGS"
else
die "Invalid transport type." 3
fi
printf " ${OK} Transport: ${transport_type}.\n"

if [[ ${signing} == "none" ]]; then
# Signing disabled
printf " ${OK} Signing: Disabled.\n"
elif [[ ${signing} == "software" ]]; then
CPPFLAGS="-DMY_SIGNING_SOFT $CPPFLAGS"
if [[ ${signing_request_signatures} == true ]]; then
CPPFLAGS="-DMY_SIGNING_REQUEST_SIGNATURES $CPPFLAGS"
fi
printf " ${OK} Signing: Enabled - Using key from config file.\n"
elif [[ ${signing} == "password" ]]; then
if [ -z "${security_password}" ]; then
die "You need to set the password for signing with --my-security-password option" 6
fi
printf " ${OK} Signing: Enabled - Simplified signing using password.\n"
CPPFLAGS="-DMY_SIGNING_SIMPLE_PASSWD=\\\"${security_password}\\\" $CPPFLAGS"
else
die "Invalid signing type." 7
fi

if [[ ${encryption} == true ]]; then
# Encryption enabled on some transport
if [ -z "${security_password}" ]; then
printf " ${OK} Encryption: Enabled - Using key from config file.\n"
else
printf " ${OK} Encryption: Enabled - Simplified encryption using password.\n"
CPPFLAGS="-DMY_ENCRYPTION_SIMPLE_PASSWD=\\\"${security_password}\\\" $CPPFLAGS"
fi
else
printf " ${OK} Encryption: Disabled.\n"
fi

printf " ${OK} CPPFLAGS: $CPPFLAGS\n"

LDFLAGS="-pthread $LDFLAGS"
CPPFLAGS="$CPUFLAGS $CPPFLAGS"

printf "${SECTION} Detecting init system.\n"
if [ "${NO_INIT}" ]; then
printf " ${OK} No init system chosen.\n"
elif [ -x /usr/bin/systemctl ] || [ -x /bin/systemctl ]; then
INIT_SYSTEM=systemd
printf " ${OK} Init system detected: systemd.\n"
elif [ -f /etc/init.d/cron ] && [ ! -h /etc/init.d/cron ]; then
INIT_SYSTEM=sysvinit
printf " ${OK} Init system detected: sysvinit.\n"
else
printf " ${FAILED} Unknown init system.\n"
fi

printf "${SECTION} Saving configuration.\n"
echo -n "" > Makefile.inc
for param in ${params}; do
if [[ ${!param} ]]; then
echo "${param}=${!param}" >> Makefile.inc
fi
done
printf " ${OK} Saved.\n"

if [ -z "${NO_CLEAN}" ]; then
printf "${SECTION} Cleaning previous builds.\n"
make clean >/dev/null
fi


printf " ${OK} Finished.\n"

+ 244
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyCapabilities.h View File

@@ -0,0 +1,244 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
/**
* @file MyCapabilities.h
* @ingroup MyCapabilities
*/

#ifndef MyCapabilities_h
#define MyCapabilities_h
/**
* @defgroup MyCapabilities Node capabilities indicator
* @ingroup MyConfigGrp
*
* @brief MySensors capabilities indications.
*
* At node startup, a capabilities string is shown as part of the initialization logs.
* This string indicate what configuration the node is running with.
*
* The string symbols are ordered in the following way:
* | Setting | Reset | Radio | OTA | Node | Architecture | Signing | Buffering | Encryption
* |-----------|-------------------|-------------------|--------------------|------------------|------------------|------------------|-------------------|-----------------
* | Indicator | @ref MY_CAP_RESET | @ref MY_CAP_RADIO | @ref MY_CAP_OTA_FW | @ref MY_CAP_TYPE | @ref MY_CAP_ARCH | @ref MY_CAP_SIGN | @ref MY_CAP_RXBUF | @ref MY_CAP_ENCR
*
* @see MY_CAPABILITIES
*
* @{
*/

// Remote reset
/**
* @def MY_CAP_RESET
* @brief Indicate the remote reset setting.
*
* @see MY_DISABLE_REMOTE_RESET
*
* | Setting | Indicator
* |------------|----------
* | Enabled | R
* | Disabled | N
*/
#if defined(MY_DISABLE_REMOTE_RESET)
#define MY_CAP_RESET "N"
#else
#define MY_CAP_RESET "R"
#endif

// OTA firmware update feature
/**
* @def MY_CAP_OTA_FW
* @brief Indicate the OTA update setting.
*
* @see MY_OTA_FIRMWARE_FEATURE
*
* | Setting | Indicator
* |------------|----------
* | Enabled | O
* | Disabled | N
*/
#if defined(MY_OTA_FIRMWARE_FEATURE)
#define MY_CAP_OTA_FW "O"
#else
#define MY_CAP_OTA_FW "N"
#endif

// Transport
/**
* @def MY_CAP_RADIO
* @brief Indicate the type of transport selected.
*
* @see MY_RADIO_RF24, MY_RADIO_NRF5_ESB, MY_RADIO_RFM69, MY_RFM69_NEW_DRIVER, MY_RADIO_RFM95, MY_RS485
*
* | Radio | Indicator
* |--------------|----------
* | nRF24/nRF5 | N
* | %RFM69 (old) | R
* | %RFM69 (new) | P
* | RFM95 | L
* | RS485 | S
* | None | -
*/
#if defined(MY_RADIO_RF24) || defined(MY_RADIO_NRF5_ESB)
#define MY_CAP_RADIO "N"
#elif defined(MY_RADIO_RFM69)
#if !defined(MY_RFM69_NEW_DRIVER)
// old RFM69 driver
#define MY_CAP_RADIO "R"
#else
// new RFM69 driver
#define MY_CAP_RADIO "P"
#endif
#elif defined(MY_RADIO_RFM95)
#define MY_CAP_RADIO "L"
#elif defined(MY_RS485)
#define MY_CAP_RADIO "S"
#else
#define MY_CAP_RADIO "-"
#endif

// Node type
/**
* @def MY_CAP_TYPE
* @brief Indicate the type of node.
*
* @see MY_GATEWAY_FEATURE, MY_REPEATER_FEATURE, MY_PASSIVE_NODE
*
* | Node type | Indicator
* |-----------|----------
* | Gateway | G
* | Repeater | R
* | Passive | P
* | Node | N
*/
#if defined(MY_GATEWAY_FEATURE)
#define MY_CAP_TYPE "G"
#elif defined(MY_REPEATER_FEATURE)
#define MY_CAP_TYPE "R"
#elif defined(MY_PASSIVE_NODE)
#define MY_CAP_TYPE "P"
#else
#define MY_CAP_TYPE "N"
#endif

// Architecture
/**
* @def MY_CAP_ARCH
* @brief Indicate the architecture.
*
* @see ARDUINO_ARCH_SAMD, ARDUINO_ARCH_NRF5, ARDUINO_ARCH_ESP8266, ARDUINO_ARCH_AVR, ARDUINO_ARCH_STM32F1, TEENSYDUINO
*
* | Architecture | Indicator
* |--------------|----------
* | SAMD | S
* | nRF5 | N
* | ESP8266 | E
* | AVR | A
* | STM32F1 | F
* | TEENSY | T
* | Linux | L
* | Unknown | -
*/
#if defined(ARDUINO_ARCH_SAMD)
#define MY_CAP_ARCH "S"
#elif defined(ARDUINO_ARCH_NRF5)
#define MY_CAP_ARCH "N"
#elif defined(ARDUINO_ARCH_ESP8266)
#define MY_CAP_ARCH "E"
#elif defined(ARDUINO_ARCH_ESP32)
#define MY_CAP_ARCH "F"
#elif defined(ARDUINO_ARCH_AVR)
#define MY_CAP_ARCH "A"
#elif defined(ARDUINO_ARCH_STM32F1)
#define MY_CAP_ARCH "F"
#elif defined(__arm__) && defined(TEENSYDUINO)
#define MY_CAP_ARCH "T"
#elif defined(__linux__)
#define MY_CAP_ARCH "L"
#else
#define MY_CAP_ARCH "-"
#endif

// Signing
/**
* @def MY_CAP_SIGN
* @brief Indicate the signing backend used.
*
* @see MY_SIGNING_ATSHA204, MY_SIGNING_SOFT
*
* | Signing backend | Indicator
* |-----------------|----------
* | ATSHA204 | A
* | Software | S
* | No signing | -
*/
#if defined(MY_SIGNING_ATSHA204)
#define MY_CAP_SIGN "A"
#elif defined(MY_SIGNING_SOFT)
#define MY_CAP_SIGN "S"
#else
#define MY_CAP_SIGN "-"
#endif

// RX queue
/**
* @def MY_CAP_RXBUF
* @brief Indicate the rx message buffer setting.
*
* @see MY_RX_MESSAGE_BUFFER_FEATURE
*
* | Setting | Indicator
* |------------|----------
* | Enabled | Q
* | Disabled | -
*/
#if defined(MY_RX_MESSAGE_BUFFER_FEATURE)
#define MY_CAP_RXBUF "Q"
#else
#define MY_CAP_RXBUF "-"
#endif

// Radio encryption
/**
* @def MY_CAP_ENCR
* @brief Indicate the encryption setting.
*
* @see MY_ENCRYPTION_FEATURE
*
* | Setting | Indicator
* |------------|----------
* | Enabled | X
* | Disabled | -
*/
#if defined(MY_ENCRYPTION_FEATURE)
#define MY_CAP_ENCR "X"
#else
#define MY_CAP_ENCR "-"
#endif


/**
* @def MY_CAPABILITIES
* @brief This is the resulting capabilities string.
*
* @see MY_CAP_RESET, MY_CAP_RADIO, MY_CAP_OTA_FW, MY_CAP_TYPE, MY_CAP_ARCH, MY_CAP_SIGN, MY_CAP_RXBUF, MY_CAP_ENCR
*/
#define MY_CAPABILITIES MY_CAP_RESET MY_CAP_RADIO MY_CAP_OTA_FW MY_CAP_TYPE MY_CAP_ARCH MY_CAP_SIGN MY_CAP_RXBUF MY_CAP_ENCR

/** @}*/ // End of MyCapabilities group
#endif /* MyCapabilities_h */

+ 92
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyEepromAddresses.h View File

@@ -0,0 +1,92 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

/**
* @file MyEepromAddresses.h
* @brief Eeprom addresses for MySensors library data
*
* @defgroup MyEepromAddressesgrp MyEepromAddresses
* @ingroup internals
* @{
*
*/


#ifndef MyEepromAddresses_h
#define MyEepromAddresses_h

// EEPROM variable sizes, in bytes
#define SIZE_NODE_ID (1u) //!< Size node ID
#define SIZE_PARENT_NODE_ID (1u) //!< Size parent node ID
#define SIZE_DISTANCE (1u) //!< Size GW distance
#define SIZE_ROUTES (256u) //!< Size routing table
#define SIZE_CONTROLLER_CONFIG (23u) //!< Size controller config
#define SIZE_PERSONALIZATION_CHECKSUM (1u) //!< Size personalization checksum
#define SIZE_FIRMWARE_TYPE (2u) //!< Size firmware type
#define SIZE_FIRMWARE_VERSION (2u) //!< Size firmware version
#define SIZE_FIRMWARE_BLOCKS (2u) //!< Size firmware blocks
#define SIZE_FIRMWARE_CRC (2u) //!< Size firmware CRC
#define SIZE_SIGNING_REQUIREMENT_TABLE (32u) //!< Size signing requirement table
#define SIZE_WHITELIST_REQUIREMENT_TABLE (32u) //!< Size whitelist requirement table
#define SIZE_SIGNING_SOFT_HMAC_KEY (32u) //!< Size soft signing HMAC key
#define SIZE_SIGNING_SOFT_SERIAL (9u) //!< Size soft signing serial
#define SIZE_RF_ENCRYPTION_AES_KEY (16u) //!< Size RF AES encryption key
#define SIZE_NODE_LOCK_COUNTER (1u) //!< Size node lock counter


/** @brief EEPROM start address */
#define EEPROM_START (0u)
/** @brief Address node ID */
#define EEPROM_NODE_ID_ADDRESS EEPROM_START
/** @brief Address parent node ID */
#define EEPROM_PARENT_NODE_ID_ADDRESS (EEPROM_NODE_ID_ADDRESS + SIZE_NODE_ID)
/** @brief Address distance to GW */
#define EEPROM_DISTANCE_ADDRESS (EEPROM_PARENT_NODE_ID_ADDRESS + SIZE_PARENT_NODE_ID)
/** @brief Address routing table */
#define EEPROM_ROUTES_ADDRESS (EEPROM_DISTANCE_ADDRESS + SIZE_DISTANCE)
/** @brief Address configuration bytes sent by controller */
#define EEPROM_CONTROLLER_CONFIG_ADDRESS (EEPROM_ROUTES_ADDRESS + SIZE_ROUTES)
/** @brief Personalization checksum (set by SecurityPersonalizer.ino) */
#define EEPROM_PERSONALIZATION_CHECKSUM_ADDRESS (EEPROM_CONTROLLER_CONFIG_ADDRESS + SIZE_CONTROLLER_CONFIG)
/** @brief Address firmware type */
#define EEPROM_FIRMWARE_TYPE_ADDRESS (EEPROM_PERSONALIZATION_CHECKSUM_ADDRESS + SIZE_PERSONALIZATION_CHECKSUM)
/** @brief Address firmware version */
#define EEPROM_FIRMWARE_VERSION_ADDRESS (EEPROM_FIRMWARE_TYPE_ADDRESS + SIZE_FIRMWARE_TYPE)
/** @brief Address firmware blocks */
#define EEPROM_FIRMWARE_BLOCKS_ADDRESS (EEPROM_FIRMWARE_VERSION_ADDRESS + SIZE_FIRMWARE_VERSION)
/** @brief Address firmware CRC */
#define EEPROM_FIRMWARE_CRC_ADDRESS (EEPROM_FIRMWARE_BLOCKS_ADDRESS + SIZE_FIRMWARE_BLOCKS)
/** @brief Address signing requirement table */
#define EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS (EEPROM_FIRMWARE_CRC_ADDRESS + SIZE_FIRMWARE_CRC)
/** @brief Address whitelist requirement table */
#define EEPROM_WHITELIST_REQUIREMENT_TABLE_ADDRESS (EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS + SIZE_SIGNING_REQUIREMENT_TABLE)
/** @brief Address soft signing HMAC key. This is set with @ref SecurityPersonalizer.ino */
#define EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS (EEPROM_WHITELIST_REQUIREMENT_TABLE_ADDRESS + SIZE_WHITELIST_REQUIREMENT_TABLE)
/** @brief Address soft signing serial key. This is set with @ref SecurityPersonalizer.ino */
#define EEPROM_SIGNING_SOFT_SERIAL_ADDRESS (EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS + SIZE_SIGNING_SOFT_HMAC_KEY)
/** @brief Address RF AES encryption key. This is set with @ref SecurityPersonalizer.ino */
#define EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS (EEPROM_SIGNING_SOFT_SERIAL_ADDRESS + SIZE_SIGNING_SOFT_SERIAL)
/** @brief Address node lock counter. This is set with @ref SecurityPersonalizer.ino */
#define EEPROM_NODE_LOCK_COUNTER_ADDRESS (EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS + SIZE_RF_ENCRYPTION_AES_KEY)
/** @brief First free address for sketch static configuration */
#define EEPROM_LOCAL_CONFIG_ADDRESS (EEPROM_NODE_LOCK_COUNTER_ADDRESS + SIZE_NODE_LOCK_COUNTER)

#endif // MyEepromAddresses_h

/** @}*/

+ 69
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyGatewayTransport.cpp View File

@@ -0,0 +1,69 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Tomas Hozza <thozza@gmail.com>
* Copyright (C) 2015 Tomas Hozza
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#include "MyGatewayTransport.h"

extern bool transportSendRoute(MyMessage &message);

// global variables
extern MyMessage _msg;
extern MyMessage _msgTmp;

inline void gatewayTransportProcess(void)
{
if (gatewayTransportAvailable()) {
_msg = gatewayTransportReceive();
if (_msg.destination == GATEWAY_ADDRESS) {

// Check if sender requests an ack back.
if (mGetRequestAck(_msg)) {
// Copy message
_msgTmp = _msg;
mSetRequestAck(_msgTmp,
false); // Reply without ack flag (otherwise we would end up in an eternal loop)
mSetAck(_msgTmp, true);
_msgTmp.sender = getNodeId();
_msgTmp.destination = _msg.sender;
gatewayTransportSend(_msgTmp);
}
if (mGetCommand(_msg) == C_INTERNAL) {
if (_msg.type == I_VERSION) {
// Request for version. Create the response
gatewayTransportSend(buildGw(_msgTmp, I_VERSION).set(MYSENSORS_LIBRARY_VERSION));
#ifdef MY_INCLUSION_MODE_FEATURE
} else if (_msg.type == I_INCLUSION_MODE) {
// Request to change inclusion mode
inclusionModeSet(atoi(_msg.data) == 1);
#endif
} else {
(void)_processInternalCoreMessage();
}
} else {
// Call incoming message callback if available
if (receive) {
receive(_msg);
}
}
} else {
#if defined(MY_SENSOR_NETWORK)
transportSendRoute(_msg);
#endif
}
}
}

+ 120
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyGatewayTransport.h View File

@@ -0,0 +1,120 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Tomas Hozza <thozza@gmail.com>
* Copyright (C) 2015 Tomas Hozza
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

/**
* @file MyGatewayTransport.h
*
* @defgroup MyGatewayTransportgrp MyGatewayTransport
* @ingroup internals
* @{
*
* Gateway transport-related log messages, format: [!]SYSTEM:[SUB SYSTEM:]MESSAGE
* - [!] Exclamation mark is prepended in case of error
* - SYSTEM:
* - <b>GWT</b>: messages emitted by MyGatewayTransport
* - SUB SYSTEMS:
* - GWT:<b>TIN</b> from @ref gatewayTransportInit()
* - GWT:<b>TPS</b> from @ref gatewayTransportSend()
* - GWT:<b>IMQ</b> from incomingMQTT()
* - GWT:<b>RMQ</b> from reconnectMQTT()
* - GWT:<b>TPC</b> from gatewayTransportConnect()
* - GWT:<b>RFC</b> from _readFromClient()
* - GWT:<b>TSA</b> from @ref gatewayTransportAvailable()
* - GWT:<b>TRC</b> from @ref gatewayTransportReceive()
*
* Gateway transport debug log messages :
*
* |E| SYS | SUB | Message | Comment
* |-|-----|-------|---------------------------|---------------------------------------------------------------------
* | | GWT | TIN | CONNECTING... | Connecting to router
* | | GWT | TIN | IP=%%s | IP address [%%s] obtained
* |!| GWT | TIN | DHCP FAIL | DHCP request failed
* | | GWT | TIN | ETH OK | Connected to network
* |!| GWT | TIN | ETH FAIL | Connection failed
* | | GWT | TPS | TOPIC=%%s,MSG SENT | MQTT message sent on topic [%%s]
* | | GWT | TPS | ETH OK | Connected to network
* |!| GWT | TPS | ETH FAIL | Connection failed
* | | GWT | IMQ | TOPIC=%%s,MSG RECEIVE | MQTT message received on topic [%%s]
* | | GWT | RMQ | MQTT RECONNECT | Reconnecting to MQTT broker
* | | GWT | RMQ | MQTT CONNECTED | Connected to MQTT broker
* | | GWT | TPC | CONNECTING... | Connecting to MQTT broker
* | | GWT | TPC | IP=%%s | IP address [%%s] obtained
* |!| GWT | TPC | DHCP FAIL | DHCP request failed
* | | GWT | RFC | C=%%d,MSG=%%s | Received message [%%s] from client [%%d]
* |!| GWT | RFC | C=%%d,MSG TOO LONG | Received message from client [%%d] too long
* | | GWT | TSA | UDP MSG=%%s | Received UDP message [%%s]
* | | GWT | TSA | ETH OK | Connected to network
* |!| GWT | TSA | ETH FAIL | Connection failed
* | | GWT | TSA | C=%d,DISCONNECTED | Client [%%d] disconnected
* | | GWT | TSA | C=%d,CONNECTED | Client [%%d] connected
* |!| GWT | TSA | NO FREE SLOT | No free slot for client
* |!| GWT | TRC | IP RENEW FAIL | IP renewal failed
*
* @brief API declaration for MyGatewayTransport
*
*/

#ifndef MyGatewayTransport_h
#define MyGatewayTransport_h

#include "MyProtocol.h"
#include "MySensorsCore.h"

#define MSG_GW_STARTUP_COMPLETE "Gateway startup complete." //!< Gateway startup message

#if defined(MY_DEBUG_VERBOSE_GATEWAY)
#define GATEWAY_DEBUG(x,...) DEBUG_OUTPUT(x, ##__VA_ARGS__) //!< debug output
#else
#define GATEWAY_DEBUG(x,...) //!< debug NULL
#endif

/**
* @brief Process gateway-related messages
*/
void gatewayTransportProcess(void);

/**
* @brief Initialize gateway transport driver
* @return true if transport initialized
*/
bool gatewayTransportInit(void);

/**
* @brief Send message to controller
* @param message to send
* @return true if message delivered
*/
bool gatewayTransportSend(MyMessage &message);

/**
* @brief Check if a new message is available from controller
* @return true if message available
*/
bool gatewayTransportAvailable(void);

/**
* @brief Pick up last message received from controller
* @return message
*/
MyMessage& gatewayTransportReceive(void);

#endif /* MyGatewayTransportEthernet_h */

/** @}*/


+ 502
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyGatewayTransportEthernet.cpp View File

@@ -0,0 +1,502 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Tomas Hozza <thozza@gmail.com>
* Copyright (C) 2015 Tomas Hozza
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#include "MyGatewayTransport.h"

// global variables
extern MyMessage _msgTmp;

// housekeeping, remove for 3.0.0
#ifdef MY_ESP8266_SSID
#warning MY_ESP8266_SSID is deprecated, use MY_WIFI_SSID instead!
#define MY_WIFI_SSID MY_ESP8266_SSID
#undef MY_ESP8266_SSID // cleanup
#endif

#ifdef MY_ESP8266_PASSWORD
#warning MY_ESP8266_PASSWORD is deprecated, use MY_WIFI_PASSWORD instead!
#define MY_WIFI_PASSWORD MY_ESP8266_PASSWORD
#undef MY_ESP8266_PASSWORD // cleanup
#endif

#ifdef MY_ESP8266_BSSID
#warning MY_ESP8266_BSSID is deprecated, use MY_WIFI_BSSID instead!
#define MY_WIFI_BSSID MY_ESP8266_BSSID
#undef MY_ESP8266_BSSID // cleanup
#endif

#ifdef MY_ESP8266_HOSTNAME
#warning MY_ESP8266_HOSTNAME is deprecated, use MY_HOSTNAME instead!
#define MY_HOSTNAME MY_ESP8266_HOSTNAME
#undef MY_ESP8266_HOSTNAME // cleanup
#endif

#ifndef MY_WIFI_BSSID
#define MY_WIFI_BSSID NULL
#endif

#if defined(MY_CONTROLLER_IP_ADDRESS)
IPAddress _ethernetControllerIP(MY_CONTROLLER_IP_ADDRESS);
#endif

#if defined(MY_IP_ADDRESS)
IPAddress _ethernetGatewayIP(MY_IP_ADDRESS);
#if defined(MY_IP_GATEWAY_ADDRESS)
IPAddress _gatewayIp(MY_IP_GATEWAY_ADDRESS);
#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
// Assume the gateway will be the machine on the same network as the local IP
// but with last octet being '1'
IPAddress _gatewayIp(_ethernetGatewayIP[0], _ethernetGatewayIP[1], _ethernetGatewayIP[2], 1);
#endif /* End of MY_IP_GATEWAY_ADDRESS */
#if defined(MY_IP_SUBNET_ADDRESS)
IPAddress _subnetIp(MY_IP_SUBNET_ADDRESS);
#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
IPAddress _subnetIp(255, 255, 255, 0);
#endif /* End of MY_IP_SUBNET_ADDRESS */
#endif /* End of MY_IP_ADDRESS */

uint8_t _ethernetGatewayMAC[] = { MY_MAC_ADDRESS };
uint16_t _ethernetGatewayPort = MY_PORT;
MyMessage _ethernetMsg;

#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))

typedef struct {
// Suppress the warning about unused members in this struct because it is used through a complex
// set of preprocessor directives
// cppcheck-suppress unusedStructMember
char string[MY_GATEWAY_MAX_RECEIVE_LENGTH];
// cppcheck-suppress unusedStructMember
uint8_t idx;
} inputBuffer;

#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
// Some re-defines to make code more readable below
#define EthernetServer WiFiServer
#define EthernetClient WiFiClient
#define EthernetUDP WiFiUDP
#endif

#if defined(MY_GATEWAY_CLIENT_MODE)
#if defined(MY_USE_UDP)
EthernetUDP _ethernetServer;
#endif /* End of MY_USE_UDP */
#elif defined(MY_GATEWAY_LINUX) /* Elif part of MY_GATEWAY_CLIENT_MODE */
EthernetServer _ethernetServer(_ethernetGatewayPort, MY_GATEWAY_MAX_CLIENTS);
#else /* Else part of MY_GATEWAY_CLIENT_MODE */
EthernetServer _ethernetServer(_ethernetGatewayPort);
#endif /* End of MY_GATEWAY_CLIENT_MODE */

#if defined(MY_GATEWAY_CLIENT_MODE)
static inputBuffer inputString;
#if defined(MY_USE_UDP)
// Nothing to do here
#else
static EthernetClient client = EthernetClient();
#endif /* End of MY_USE_UDP */
#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) || defined(MY_GATEWAY_LINUX)
static EthernetClient clients[MY_GATEWAY_MAX_CLIENTS];
static bool clientsConnected[MY_GATEWAY_MAX_CLIENTS];
static inputBuffer inputString[MY_GATEWAY_MAX_CLIENTS];
#else /* Else part of MY_GATEWAY_CLIENT_MODE */
static EthernetClient client = EthernetClient();
static inputBuffer inputString;
#endif /* End of MY_GATEWAY_CLIENT_MODE */

#ifndef MY_IP_ADDRESS
void gatewayTransportRenewIP();
#endif

// On W5100 boards with SPI_EN exposed we can use the real SPI bus together with radio
// (if we enable it during usage)
#if defined(MY_W5100_SPI_EN)
void _w5100_spi_en(bool enable)
{
if (enable) {
// Pull up pin
hwPinMode(MY_W5100_SPI_EN, INPUT);
hwDigitalWrite(MY_W5100_SPI_EN, HIGH);
} else {
// Ground pin
hwPinMode(MY_W5100_SPI_EN, OUTPUT);
hwDigitalWrite(MY_W5100_SPI_EN, LOW);
}
}
#else
#define _w5100_spi_en(x)
#endif

bool gatewayTransportInit(void)
{
_w5100_spi_en(true);

#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
#if defined(MY_WIFI_SSID)
// Turn off access point
WiFi.mode(WIFI_STA);
#if defined(MY_HOSTNAME)
#if defined(MY_GATEWAY_ESP8266)
WiFi.hostname(MY_HOSTNAME);
#elif defined(MY_GATEWAY_ESP32)
WiFi.setHostname(MY_HOSTNAME);
#endif
#endif
#ifdef MY_IP_ADDRESS
WiFi.config(_ethernetGatewayIP, _gatewayIp, _subnetIp);
#endif
(void)WiFi.begin(MY_WIFI_SSID, MY_WIFI_PASSWORD, 0, MY_WIFI_BSSID);
while (WiFi.status() != WL_CONNECTED) {
wait(500);
GATEWAY_DEBUG(PSTR("GWT:TIN:CONNECTING...\n"));
}
GATEWAY_DEBUG(PSTR("GWT:TIN:IP: %s\n"), WiFi.localIP().toString().c_str());
#endif
#elif defined(MY_GATEWAY_LINUX)
// Nothing to do here
#else
#if defined(MY_IP_GATEWAY_ADDRESS) && defined(MY_IP_SUBNET_ADDRESS)
// DNS server set to gateway ip
Ethernet.begin(_ethernetGatewayMAC, _ethernetGatewayIP, _gatewayIp, _gatewayIp, _subnetIp);
#elif defined(MY_IP_ADDRESS)
Ethernet.begin(_ethernetGatewayMAC, _ethernetGatewayIP);
#else /* Else part of MY_IP_GATEWAY_ADDRESS && MY_IP_SUBNET_ADDRESS */
// Get IP address from DHCP
if (!Ethernet.begin(_ethernetGatewayMAC)) {
GATEWAY_DEBUG(PSTR("!GWT:TIN:DHCP FAIL\n"));
_w5100_spi_en(false);
return false;
}
#endif /* End of MY_IP_GATEWAY_ADDRESS && MY_IP_SUBNET_ADDRESS */
GATEWAY_DEBUG(PSTR("GWT:TIN:IP=%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 "\n"),
Ethernet.localIP()[0],
Ethernet.localIP()[1], Ethernet.localIP()[2], Ethernet.localIP()[3]);
// give the Ethernet interface a second to initialize
delay(1000);
#endif /* MY_GATEWAY_ESP8266 / MY_GATEWAY_ESP32 */

#if defined(MY_GATEWAY_CLIENT_MODE)
#if defined(MY_USE_UDP)
_ethernetServer.begin(_ethernetGatewayPort);
#else /* Else part of MY_USE_UDP */
#if defined(MY_GATEWAY_LINUX) && defined(MY_IP_ADDRESS)
client.bind(_ethernetGatewayIP);
#endif /* End of MY_GATEWAY_LINUX && MY_IP_ADDRESS */
#if defined(MY_CONTROLLER_URL_ADDRESS)
if (client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
#else
if (client.connect(_ethernetControllerIP, MY_PORT)) {
#endif /* End of MY_CONTROLLER_URL_ADDRESS */
GATEWAY_DEBUG(PSTR("GWT:TIN:ETH OK\n"));
_w5100_spi_en(false);
gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set(MSG_GW_STARTUP_COMPLETE));
_w5100_spi_en(true);
presentNode();
} else {
client.stop();
GATEWAY_DEBUG(PSTR("!GWT:TIN:ETH FAIL\n"));
}
#endif /* End of MY_USE_UDP */
#else /* Else part of MY_GATEWAY_CLIENT_MODE */
#if defined(MY_GATEWAY_LINUX) && defined(MY_IP_ADDRESS)
_ethernetServer.begin(_ethernetGatewayIP);
#else
// we have to use pointers due to the constructor of EthernetServer
_ethernetServer.begin();
#endif /* End of MY_GATEWAY_LINUX && MY_IP_ADDRESS */
#endif /* End of MY_GATEWAY_CLIENT_MODE */

_w5100_spi_en(false);
return true;
}

bool gatewayTransportSend(MyMessage &message)
{
int nbytes = 0;
char *_ethernetMsg = protocolFormat(message);

setIndication(INDICATION_GW_TX);

_w5100_spi_en(true);
#if defined(MY_GATEWAY_CLIENT_MODE)
#if defined(MY_USE_UDP)
#if defined(MY_CONTROLLER_URL_ADDRESS)
_ethernetServer.beginPacket(MY_CONTROLLER_URL_ADDRESS, MY_PORT);
#else
_ethernetServer.beginPacket(_ethernetControllerIP, MY_PORT);
#endif /* End of MY_CONTROLLER_URL_ADDRESS */
_ethernetServer.write(_ethernetMsg, strlen(_ethernetMsg));
// returns 1 if the packet was sent successfully
nbytes = _ethernetServer.endPacket();
#else /* Else part of MY_USE_UDP */
if (!client.connected()) {
client.stop();
#if defined(MY_CONTROLLER_URL_ADDRESS)
if (client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
#else
if (client.connect(_ethernetControllerIP, MY_PORT)) {
#endif /* End of MY_CONTROLLER_URL_ADDRESS */
GATEWAY_DEBUG(PSTR("GWT:TPS:ETH OK\n"));
_w5100_spi_en(false);
gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set(MSG_GW_STARTUP_COMPLETE));
_w5100_spi_en(true);
presentNode();
} else {
// connecting to the server failed!
GATEWAY_DEBUG(PSTR("!GWT:TPS:ETH FAIL\n"));
_w5100_spi_en(false);
return false;
}
}
nbytes = client.write((const uint8_t*)_ethernetMsg, strlen(_ethernetMsg));
#endif /* End of MY_USE_UDP */
#else /* Else part of MY_GATEWAY_CLIENT_MODE */
// Send message to connected clients
#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) {
if (clients[i] && clients[i].connected()) {
nbytes += clients[i].write((uint8_t*)_ethernetMsg, strlen(_ethernetMsg));
}
}
#else /* Else part of MY_GATEWAY_ESP8266 */
nbytes = _ethernetServer.write(_ethernetMsg);
#endif /* End of MY_GATEWAY_ESP8266 */
#endif /* End of MY_GATEWAY_CLIENT_MODE */
_w5100_spi_en(false);
return (nbytes > 0);
}

#if defined(MY_USE_UDP)
// Nothing to do here
#else
#if (defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) || defined(MY_GATEWAY_LINUX)) && !defined(MY_GATEWAY_CLIENT_MODE)
bool _readFromClient(uint8_t i)
{
while (clients[i].connected() && clients[i].available()) {
const char inChar = clients[i].read();
if (inputString[i].idx < MY_GATEWAY_MAX_RECEIVE_LENGTH - 1) {
// if newline then command is complete
if (inChar == '\n' || inChar == '\r') {
// Add string terminator and prepare for the next message
inputString[i].string[inputString[i].idx] = 0;
GATEWAY_DEBUG(PSTR("GWT:RFC:C=%" PRIu8 ",MSG=%s\n"), i, inputString[i].string);
inputString[i].idx = 0;
if (protocolParse(_ethernetMsg, inputString[i].string)) {
return true;
}

} else {
// add it to the inputString:
inputString[i].string[inputString[i].idx++] = inChar;
}
} else {
// Incoming message too long. Throw away
GATEWAY_DEBUG(PSTR("!GWT:RFC:C=%" PRIu8 ",MSG TOO LONG\n"), i);
inputString[i].idx = 0;
// Finished with this client's message. Next loop() we'll see if there's more to read.
break;
}
}
return false;
}
#else /* Else part of MY_GATEWAY_ESP8266 || MY_GATEWAY_LINUX || !MY_GATEWAY_CLIENT_MODE */
bool _readFromClient(void)
{
while (client.connected() && client.available()) {
const char inChar = client.read();
if (inputString.idx < MY_GATEWAY_MAX_RECEIVE_LENGTH - 1) {
// if newline then command is complete
if (inChar == '\n' || inChar == '\r') {
// Add string terminator and prepare for the next message
inputString.string[inputString.idx] = 0;
GATEWAY_DEBUG(PSTR("GWT:RFC:MSG=%s\n"), inputString.string);
inputString.idx = 0;
if (protocolParse(_ethernetMsg, inputString.string)) {
return true;
}

} else {
// add it to the inputString:
inputString.string[inputString.idx++] = inChar;
}
} else {
// Incoming message too long. Throw away
GATEWAY_DEBUG(PSTR("!GWT:RFC:MSG TOO LONG\n"));
inputString.idx = 0;
// Finished with this client's message. Next loop() we'll see if there's more to read.
break;
}
}
return false;
}
#endif /* End of MY_GATEWAY_ESP8266 || MY_GATEWAY_LINUX || !MY_GATEWAY_CLIENT_MODE */
#endif /* End of MY_USE_UDP */

bool gatewayTransportAvailable(void)
{
_w5100_spi_en(true);
#if !defined(MY_IP_ADDRESS) && defined(MY_GATEWAY_W5100)
// renew IP address using DHCP
gatewayTransportRenewIP();
#endif

#if defined(MY_GATEWAY_CLIENT_MODE)
#if defined(MY_USE_UDP)
int packet_size = _ethernetServer.parsePacket();

if (packet_size) {
//GATEWAY_DEBUG(PSTR("UDP packet available. Size:%" PRIu8 "\n"), packet_size);
_ethernetServer.read(inputString.string, MY_GATEWAY_MAX_RECEIVE_LENGTH);
inputString.string[packet_size] = 0;
GATEWAY_DEBUG(PSTR("GWT:TSA:UDP MSG=%s\n"), inputString.string);
_w5100_spi_en(false);
const bool ok = protocolParse(_ethernetMsg, inputString.string);
if (ok) {
setIndication(INDICATION_GW_RX);
}
return ok;
}
#else /* Else part of MY_USE_UDP */
if (!client.connected()) {
client.stop();
#if defined(MY_CONTROLLER_URL_ADDRESS)
if (client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
#else
if (client.connect(_ethernetControllerIP, MY_PORT)) {
#endif /* End of MY_CONTROLLER_URL_ADDRESS */
GATEWAY_DEBUG(PSTR("GWT:TSA:ETH OK\n"));
_w5100_spi_en(false);
gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set(MSG_GW_STARTUP_COMPLETE));
_w5100_spi_en(true);
presentNode();
} else {
GATEWAY_DEBUG(PSTR("!GWT:TSA:ETH FAIL\n"));
_w5100_spi_en(false);
return false;
}
}
if (_readFromClient()) {
setIndication(INDICATION_GW_RX);
_w5100_spi_en(false);
return true;
}
#endif /* End of MY_USE_UDP */
#else /* Else part of MY_GATEWAY_CLIENT_MODE */
#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) || defined(MY_GATEWAY_LINUX)
// ESP8266: Go over list of clients and stop any that are no longer connected.
// If the server has a new client connection it will be assigned to a free slot.
bool allSlotsOccupied = true;
for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) {
if (!clients[i].connected()) {
if (clientsConnected[i]) {
GATEWAY_DEBUG(PSTR("GWT:TSA:C=%" PRIu8 ",DISCONNECTED\n"), i);
clients[i].stop();
}
//check if there are any new clients
if (_ethernetServer.hasClient()) {
clients[i] = _ethernetServer.available();
inputString[i].idx = 0;
GATEWAY_DEBUG(PSTR("GWT:TSA:C=%" PRIu8 ",CONNECTED\n"), i);
gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set(MSG_GW_STARTUP_COMPLETE));
// Send presentation of locally attached sensors (and node if applicable)
presentNode();
}
}
bool connected = clients[i].connected();
clientsConnected[i] = connected;
allSlotsOccupied &= connected;
}
if (allSlotsOccupied && _ethernetServer.hasClient()) {
//no free/disconnected spot so reject
GATEWAY_DEBUG(PSTR("!GWT:TSA:NO FREE SLOT\n"));
EthernetClient c = _ethernetServer.available();
c.stop();
}
// Loop over clients connect and read available data
for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) {
if (_readFromClient(i)) {
setIndication(INDICATION_GW_RX);
_w5100_spi_en(false);
return true;
}
}
#else /* Else part of MY_GATEWAY_ESP8266 || MY_GATEWAY_LINUX */
// W5100/ENC module does not have hasClient-method. We can only serve one client at the time.
EthernetClient newclient = _ethernetServer.available();
// if a new client connects make sure to dispose any previous existing sockets
if (newclient) {
if (client != newclient) {
client.stop();
client = newclient;
GATEWAY_DEBUG(PSTR("GWT:TSA:ETH OK\n"));
_w5100_spi_en(false);
gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set(MSG_GW_STARTUP_COMPLETE));
_w5100_spi_en(true);
presentNode();
}
}
if (client) {
if (!client.connected()) {
GATEWAY_DEBUG(PSTR("!GWT:TSA:ETH FAIL\n"));
client.stop();
} else {
if (_readFromClient()) {
setIndication(INDICATION_GW_RX);
_w5100_spi_en(false);
return true;
}
}
}
#endif /* End of MY_GATEWAY_ESP8266 || MY_GATEWAY_LINUX */
#endif /* End of MY_GATEWAY_CLIENT_MODE */
_w5100_spi_en(false);
return false;
}

MyMessage& gatewayTransportReceive(void)
{
// Return the last parsed message
return _ethernetMsg;
}

#if !defined(MY_IP_ADDRESS) && !defined(MY_GATEWAY_ESP8266) && !defined(MY_GATEWAY_ESP32) && !defined(MY_GATEWAY_LINUX)
void gatewayTransportRenewIP(void)
{
/* renew/rebind IP address
0 - nothing happened
1 - renew failed
2 - renew success
3 - rebind failed
4 - rebind success
*/
static unsigned long next_time = hwMillis() + MY_IP_RENEWAL_INTERVAL_MS;
unsigned long now = hwMillis();

// http://playground.arduino.cc/Code/TimingRollover
if ((long)(now - next_time) < 0) {
return;
}
if (Ethernet.maintain() & ~(0x06)) {
GATEWAY_DEBUG(PSTR("!GWT:TRC:IP RENEW FAIL\n"));
/* Error occurred -> IP was not renewed */
return;
}
_w5100_spi_en(false);
next_time = now + MY_IP_RENEWAL_INTERVAL_MS;
}
#endif

+ 294
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyGatewayTransportMQTTClient.cpp View File

@@ -0,0 +1,294 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/


// Topic structure: MY_MQTT_PUBLISH_TOPIC_PREFIX/NODE-ID/SENSOR-ID/CMD-TYPE/ACK-FLAG/SUB-TYPE

#include "MyGatewayTransport.h"

// housekeeping, remove for 3.0.0
#ifdef MY_ESP8266_SSID
#warning MY_ESP8266_SSID is deprecated, use MY_WIFI_SSID instead!
#define MY_WIFI_SSID MY_ESP8266_SSID
#undef MY_ESP8266_SSID // cleanup
#endif

#ifdef MY_ESP8266_PASSWORD
#warning MY_ESP8266_PASSWORD is deprecated, use MY_WIFI_PASSWORD instead!
#define MY_WIFI_PASSWORD MY_ESP8266_PASSWORD
#undef MY_ESP8266_PASSWORD // cleanup
#endif

#ifdef MY_ESP8266_BSSID
#warning MY_ESP8266_BSSID is deprecated, use MY_WIFI_BSSID instead!
#define MY_WIFI_BSSID MY_ESP8266_BSSID
#undef MY_ESP8266_BSSID // cleanup
#endif

#ifdef MY_ESP8266_HOSTNAME
#warning MY_ESP8266_HOSTNAME is deprecated, use MY_HOSTNAME instead!
#define MY_HOSTNAME MY_ESP8266_HOSTNAME
#undef MY_ESP8266_HOSTNAME // cleanup
#endif

#ifndef MY_WIFI_BSSID
#define MY_WIFI_BSSID NULL
#endif

#if defined MY_CONTROLLER_IP_ADDRESS
IPAddress _brokerIp(MY_CONTROLLER_IP_ADDRESS);
#endif

#if defined(MY_IP_ADDRESS)
IPAddress _MQTT_clientIp(MY_IP_ADDRESS);
#if defined(MY_IP_GATEWAY_ADDRESS)
IPAddress _gatewayIp(MY_IP_GATEWAY_ADDRESS);
#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
// Assume the gateway will be the machine on the same network as the local IP
// but with last octet being '1'
IPAddress _gatewayIp(_MQTT_clientIp[0], _MQTT_clientIp[1], _MQTT_clientIp[2], 1);
#endif /* End of MY_IP_GATEWAY_ADDRESS */

#if defined(MY_IP_SUBNET_ADDRESS)
IPAddress _subnetIp(MY_IP_SUBNET_ADDRESS);
#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
IPAddress _subnetIp(255, 255, 255, 0);
#endif /* End of MY_IP_SUBNET_ADDRESS */
#endif /* End of MY_IP_ADDRESS */

#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
#define EthernetClient WiFiClient
#elif defined(MY_GATEWAY_LINUX)
// Nothing to do here
#else
uint8_t _MQTT_clientMAC[] = { MY_MAC_ADDRESS };
#endif /* End of MY_GATEWAY_ESP8266 */

#if defined(MY_GATEWAY_TINYGSM)
#if defined(MY_GSM_RX) && defined(MY_GSM_TX)
SoftwareSerial SerialAT(MY_GSM_RX, MY_GSM_TX);
#endif
static TinyGsm modem(SerialAT);
static TinyGsmClient _MQTT_gsmClient(modem);
static PubSubClient _MQTT_client(_MQTT_gsmClient);
#if defined(MY_GSM_BAUDRATE)
uint32_t rate = MY_GSM_BAUDRATE;
#else /* Else part of MY_GSM_BAUDRATE */
uint32_t rate = 0;
#endif /* End of MY_GSM_BAUDRATE */
#else /* Else part of MY_GATEWAY_TINYGSM */
static EthernetClient _MQTT_ethClient;
static PubSubClient _MQTT_client(_MQTT_ethClient);
#endif /* End of MY_GATEWAY_TINYGSM */


static bool _MQTT_connecting = true;
static bool _MQTT_available = false;
static MyMessage _MQTT_msg;

bool gatewayTransportSend(MyMessage &message)
{
if (!_MQTT_client.connected()) {
return false;
}
setIndication(INDICATION_GW_TX);
char *topic = protocolFormatMQTTTopic(MY_MQTT_PUBLISH_TOPIC_PREFIX, message);
GATEWAY_DEBUG(PSTR("GWT:TPS:TOPIC=%s,MSG SENT\n"), topic);
#if defined(MY_MQTT_CLIENT_PUBLISH_RETAIN)
bool retain = mGetCommand(message) == C_SET ||
(mGetCommand(message) == C_INTERNAL && message.type == I_BATTERY_LEVEL);
#else
bool retain = false;
#endif /* End of MY_MQTT_CLIENT_PUBLISH_RETAIN */
return _MQTT_client.publish(topic, message.getString(_convBuffer), retain);
}

void incomingMQTT(char *topic, uint8_t *payload, unsigned int length)
{
GATEWAY_DEBUG(PSTR("GWT:IMQ:TOPIC=%s, MSG RECEIVED\n"), topic);
_MQTT_available = protocolMQTTParse(_MQTT_msg, topic, payload, length);
setIndication(INDICATION_GW_RX);
}

bool reconnectMQTT(void)
{
GATEWAY_DEBUG(PSTR("GWT:RMQ:MQTT RECONNECT\n"));
// Attempt to connect
if (_MQTT_client.connect(MY_MQTT_CLIENT_ID
#if defined(MY_MQTT_USER) && defined(MY_MQTT_PASSWORD)
, MY_MQTT_USER, MY_MQTT_PASSWORD
#endif
)) {
GATEWAY_DEBUG(PSTR("GWT:RMQ:MQTT CONNECTED\n"));

// Send presentation of locally attached sensors (and node if applicable)
presentNode();

// Once connected, publish an announcement...
//_MQTT_client.publish("outTopic","hello world");
// ... and resubscribe
_MQTT_client.subscribe(MY_MQTT_SUBSCRIBE_TOPIC_PREFIX "/+/+/+/+/+");
return true;
}
return false;
}

bool gatewayTransportConnect(void)
{
#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
while (WiFi.status() != WL_CONNECTED) {
wait(500);
GATEWAY_DEBUG(PSTR("GWT:TPC:CONNECTING...\n"));
}
GATEWAY_DEBUG(PSTR("GWT:TPC:IP=%s\n"),WiFi.localIP().toString().c_str());
#elif defined(MY_GATEWAY_LINUX)
#if defined(MY_IP_ADDRESS)
_MQTT_ethClient.bind(_MQTT_clientIp);
#endif /* End of MY_IP_ADDRESS */
#elif defined(MY_GATEWAY_TINYGSM)
GATEWAY_DEBUG(PSTR("GWT:TPC:IP=%s\n"), modem.getLocalIP().c_str());
#else
#if defined(MY_IP_ADDRESS)
Ethernet.begin(_MQTT_clientMAC, _MQTT_clientIp);
#else /* Else part of MY_IP_ADDRESS */
// Get IP address from DHCP
if (!Ethernet.begin(_MQTT_clientMAC)) {
GATEWAY_DEBUG(PSTR("!GWT:TPC:DHCP FAIL\n"));
_MQTT_connecting = false;
return false;
}
#endif /* End of MY_IP_ADDRESS */
GATEWAY_DEBUG(PSTR("GWT:TPC:IP=%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 "\n"),
Ethernet.localIP()[0],
Ethernet.localIP()[1], Ethernet.localIP()[2], Ethernet.localIP()[3]);
// give the Ethernet interface a second to initialize
delay(1000);
#endif
return true;
}

bool gatewayTransportInit(void)
{
_MQTT_connecting = true;

#if defined(MY_GATEWAY_TINYGSM)

#if !defined(MY_GSM_BAUDRATE)
rate = TinyGsmAutoBaud(SerialAT);
#endif /* End of MY_GSM_BAUDRATE */

SerialAT.begin(rate);
delay(3000);

modem.restart();

#if defined(MY_GSM_PIN) && !defined(TINY_GSM_MODEM_ESP8266)
modem.simUnlock(MY_GSM_PIN);
#endif /* End of MY_GSM_PIN */

#ifndef TINY_GSM_MODEM_ESP8266
if (!modem.waitForNetwork()) {
GATEWAY_DEBUG(PSTR("!GWT:TIN:ETH FAIL\n"));
while (true);
}
GATEWAY_DEBUG(PSTR("GWT:TIN:ETH OK\n"));

if (!modem.gprsConnect(MY_GSM_APN, MY_GSM_USR, MY_GSM_PSW)) {
GATEWAY_DEBUG(PSTR("!GWT:TIN:ETH FAIL\n"));
while (true);
}
GATEWAY_DEBUG(PSTR("GWT:TIN:ETH OK\n"));
delay(1000);
#else /* Else part of TINY_GSM_MODEM_ESP8266 */
if (!modem.networkConnect(MY_GSM_SSID, MY_GSM_PSW)) {
GATEWAY_DEBUG(PSTR("!GWT:TIN:ETH FAIL\n"));
while (true);
}
GATEWAY_DEBUG(PSTR("GWT:TIN:ETH OK\n"));
delay(1000);
#endif /* End of TINY_GSM_MODEM_ESP8266 */

#endif /* End of MY_GATEWAY_TINYGSM */

#if defined(MY_CONTROLLER_IP_ADDRESS)
_MQTT_client.setServer(_brokerIp, MY_PORT);
#else
_MQTT_client.setServer(MY_CONTROLLER_URL_ADDRESS, MY_PORT);
#endif /* End of MY_CONTROLLER_IP_ADDRESS */

_MQTT_client.setCallback(incomingMQTT);

#if defined(MY_GATEWAY_ESP8266)
// Turn off access point
WiFi.mode(WIFI_STA);
#if defined(MY_HOSTNAME)
WiFi.hostname(MY_HOSTNAME);
#endif /* End of MY_ESP8266_HOSTNAME */
#if defined(MY_IP_ADDRESS)
WiFi.config(_MQTT_clientIp, _gatewayIp, _subnetIp);
#endif /* End of MY_IP_ADDRESS */
#ifndef MY_WIFI_BSSID
#define MY_WIFI_BSSID NULL
#endif
(void)WiFi.begin(MY_WIFI_SSID, MY_WIFI_PASSWORD, 0, MY_WIFI_BSSID);
#elif defined(MY_GATEWAY_ESP32)
// Turn off access point
WiFi.mode(WIFI_STA);
#if defined(MY_HOSTNAME)
WiFi.setHostname(MY_HOSTNAME);
#endif /* End of MY_HOSTNAME */
#if defined(MY_IP_ADDRESS)
WiFi.config(_MQTT_clientIp, _gatewayIp, _subnetIp);
#endif /* End of MY_IP_ADDRESS */
#ifndef MY_WIFI_BSSID
#define MY_WIFI_BSSID NULL
#endif
(void)WiFi.begin(MY_WIFI_SSID, MY_WIFI_PASSWORD, 0, MY_WIFI_BSSID);
#endif

gatewayTransportConnect();

_MQTT_connecting = false;
return true;
}

bool gatewayTransportAvailable(void)
{
if (_MQTT_connecting) {
return false;
}
//keep lease on dhcp address
//Ethernet.maintain();
if (!_MQTT_client.connected()) {
//reinitialise client
if (gatewayTransportConnect()) {
reconnectMQTT();
}
return false;
}
_MQTT_client.loop();
return _MQTT_available;
}

MyMessage & gatewayTransportReceive(void)
{
// Return the last parsed message
_MQTT_available = false;
return _MQTT_msg;
}

+ 82
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyGatewayTransportSerial.cpp View File

@@ -0,0 +1,82 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#include "MyConfig.h"
#include "MyProtocol.h"
#include "MyGatewayTransport.h"
#include "MyMessage.h"
#include "MyProtocol.h"

// global variables
extern MyMessage _msgTmp;

char _serialInputString[MY_GATEWAY_MAX_RECEIVE_LENGTH]; // A buffer for incoming commands from serial interface
uint8_t _serialInputPos;
MyMessage _serialMsg;

bool gatewayTransportSend(MyMessage &message)
{
setIndication(INDICATION_GW_TX);
MY_SERIALDEVICE.print(protocolFormat(message));
// Serial print is always successful
return true;
}

bool gatewayTransportInit(void)
{
(void)gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set(MSG_GW_STARTUP_COMPLETE));
// Send presentation of locally attached sensors (and node if applicable)
presentNode();
return true;
}

bool gatewayTransportAvailable(void)
{
while (MY_SERIALDEVICE.available()) {
// get the new byte:
const char inChar = (char)MY_SERIALDEVICE.read();
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (_serialInputPos < MY_GATEWAY_MAX_RECEIVE_LENGTH - 1) {
if (inChar == '\n') {
_serialInputString[_serialInputPos] = 0;
const bool ok = protocolParse(_serialMsg, _serialInputString);
if (ok) {
setIndication(INDICATION_GW_RX);
}
_serialInputPos = 0;
return ok;
} else {
// add it to the inputString:
_serialInputString[_serialInputPos] = inChar;
_serialInputPos++;
}
} else {
// Incoming message too long. Throw away
_serialInputPos = 0;
}
}
return false;
}

MyMessage & gatewayTransportReceive(void)
{
// Return the last parsed message
return _serialMsg;
}

+ 72
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyInclusionMode.cpp View File

@@ -0,0 +1,72 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#include "MyInclusionMode.h"

// global variables
extern MyMessage _msgTmp;

unsigned long _inclusionStartTime;
bool _inclusionMode;

inline void inclusionInit()
{
_inclusionMode = false;
#if defined(MY_INCLUSION_BUTTON_FEATURE)
// Setup digital in that triggers inclusion mode
hwPinMode(MY_INCLUSION_MODE_BUTTON_PIN, INPUT_PULLUP);
#endif
#if defined (MY_INCLUSION_LED_PIN)
// Setup LED pin that indicates inclusion mode
hwPinMode(MY_INCLUSION_LED_PIN, OUTPUT);
hwDigitalWrite(MY_INCLUSION_LED_PIN, LED_OFF);
#endif

}


void inclusionModeSet(bool newMode)
{
if (newMode != _inclusionMode) {
_inclusionMode = newMode;
// Send back mode change to controller
gatewayTransportSend(buildGw(_msgTmp, I_INCLUSION_MODE).set((uint8_t)(_inclusionMode?1:0)));
if (_inclusionMode) {
_inclusionStartTime = hwMillis();
}
}
#if defined (MY_INCLUSION_LED_PIN)
hwDigitalWrite(MY_INCLUSION_LED_PIN, _inclusionMode ? LED_ON : LED_OFF);
#endif
}

inline void inclusionProcess()
{
#ifdef MY_INCLUSION_BUTTON_FEATURE
if (!_inclusionMode && hwDigitalRead(MY_INCLUSION_MODE_BUTTON_PIN) == MY_INCLUSION_BUTTON_PRESSED) {
// Start inclusion mode
inclusionModeSet(true);
}
#endif

if (_inclusionMode && hwMillis()-_inclusionStartTime>MY_INCLUSION_MODE_DURATION*1000L) {
// inclusionTimeInMinutes minute(s) has passed.. stop inclusion mode
inclusionModeSet(false);
}
}

+ 33
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyInclusionMode.h View File

@@ -0,0 +1,33 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#ifndef MyInclusionMode_h
#define MyInclusionMode_h

#include "MySensorsCore.h"


extern bool gatewayTransportSend(MyMessage &message);

void inclusionInit();
void inclusionModeSet(bool newMode);
void inclusionProcess();


#endif

+ 52
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyIndication.cpp View File

@@ -0,0 +1,52 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#include "MyIndication.h"
#if defined(MY_DEFAULT_TX_LED_PIN)|| defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN)
#include "MyLeds.h"
#endif

void setIndication( const indication_t ind )
{
#if defined(MY_DEFAULT_TX_LED_PIN)
if ((INDICATION_TX == ind) || (INDICATION_GW_TX == ind)) {
ledsBlinkTx(1);
} else
#endif
#if defined(MY_DEFAULT_RX_LED_PIN)
if ((INDICATION_RX == ind) || (INDICATION_GW_RX == ind)) {
ledsBlinkRx(1);
} else
#endif
#if defined(MY_DEFAULT_ERR_LED_PIN)
if (ind > INDICATION_ERR_START) {
// Number of blinks indicates which error occurred.
ledsBlinkErr(ind-INDICATION_ERR_START);
}
#endif
indication(ind);
}

#if !defined(MY_INDICATION_HANDLER)
void indication(indication_t)
{
// empty function, resolves AVR-specific GCC optimization bug (<5.5) if handler not used
// see here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77326
}
#endif

+ 80
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyIndication.h View File

@@ -0,0 +1,80 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#ifndef MyIndication_h
#define MyIndication_h

/**
* Indication type
*/
typedef enum {
INDICATION_TX = 0, //!< Sent a message.
INDICATION_RX, //!< Received a message.

INDICATION_GW_TX, //!< Gateway transmit message.
INDICATION_GW_RX, //!< Gateway receive message.

INDICATION_FIND_PARENT, //!< Start finding parent node.
INDICATION_GOT_PARENT, //!< Found parent node.
INDICATION_REQ_NODEID, //!< Request node ID.
INDICATION_GOT_NODEID, //!< Got a node ID.
INDICATION_CHECK_UPLINK, //!< Check uplink
INDICATION_REQ_REGISTRATION, //!< Request node registration.
INDICATION_GOT_REGISTRATION, //!< Got registration response.
INDICATION_REBOOT, //!< Rebooting node.
INDICATION_PRESENT, //!< Presenting node to gateway.
INDICATION_CLEAR_ROUTING, //!< Clear routing table requested.
INDICATION_SLEEP, //!< Node goes to sleep.
INDICATION_WAKEUP, //!< Node just woke from sleep.
INDICATION_FW_UPDATE_START, //!< Start of OTA firmware update process.
INDICATION_FW_UPDATE_RX, //!< Received a piece of firmware data.
INDICATION_FW_UPDATE_RX_ERR, //!< Received wrong piece of firmware data.

INDICATION_ERR_START = 100,
INDICATION_ERR_HW_INIT, //!< HW initialization error
INDICATION_ERR_TX, //!< Failed to transmit message.
INDICATION_ERR_TRANSPORT_FAILURE, //!< Transport failure.
INDICATION_ERR_INIT_TRANSPORT, //!< MySensors transport hardware (radio) init failure.
INDICATION_ERR_FIND_PARENT, //!< Failed to find parent node.
INDICATION_ERR_GET_NODEID, //!< Failed to receive node ID.
INDICATION_ERR_CHECK_UPLINK, //!< Failed to check uplink
INDICATION_ERR_SIGN, //!< Error signing.
INDICATION_ERR_LENGTH, //!< Invalid message length.
INDICATION_ERR_VERSION, //!< Protocol version mismatch.
INDICATION_ERR_NET_FULL, //!< Network full. All node ID's are taken.
INDICATION_ERR_INIT_GWTRANSPORT, //!< Gateway transport hardware init failure.
INDICATION_ERR_LOCKED, //!< Node is locked.
INDICATION_ERR_FW_FLASH_INIT, //!< Firmware update flash initialisation failure.
INDICATION_ERR_FW_TIMEOUT, //!< Firmware update timeout.
INDICATION_ERR_FW_CHECKSUM, //!< Firmware update checksum mismatch.
INDICATION_ERR_END
} indication_t;

/**
* Function which is called when something changes about the internal state of MySensors.
* @param ind Event indication of what happened.
*/
void setIndication( const indication_t ind );

/**
* Allow user to define their own indication handler.
*/
void indication( const indication_t );

#endif

+ 119
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyLeds.cpp View File

@@ -0,0 +1,119 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#include "MyLeds.h"

#define LED_ON_OFF_RATIO (4) // Power of 2 please
#define LED_PROCESS_INTERVAL_MS (MY_DEFAULT_LED_BLINK_PERIOD/LED_ON_OFF_RATIO)

// these variables don't need to be volatile, since we are not using interrupts
static uint8_t countRx;
static uint8_t countTx;
static uint8_t countErr;
static unsigned long prevTime;

inline void ledsInit()
{
// initialize counters
countRx = 0;
countTx = 0;
countErr = 0;

// Setup led pins
#if defined(MY_DEFAULT_RX_LED_PIN)
hwPinMode(MY_DEFAULT_RX_LED_PIN, OUTPUT);
#endif
#if defined(MY_DEFAULT_TX_LED_PIN)
hwPinMode(MY_DEFAULT_TX_LED_PIN, OUTPUT);
#endif
#if defined(MY_DEFAULT_ERR_LED_PIN)
hwPinMode(MY_DEFAULT_ERR_LED_PIN, OUTPUT);
#endif
prevTime = hwMillis() -
LED_PROCESS_INTERVAL_MS; // Subtract some, to make sure leds gets updated on first run.
ledsProcess();
}

void ledsProcess()
{
// Just return if it is not the time...
if ((hwMillis() - prevTime) < LED_PROCESS_INTERVAL_MS) {
return;
}
prevTime = hwMillis();

#if defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN)
uint8_t state;
#endif

// For an On/Off ratio of 4, the pattern repeated will be [on, on, on, off]
// until the counter becomes 0.
#if defined(MY_DEFAULT_RX_LED_PIN)
if (countRx) {
--countRx;
}
state = (countRx & (LED_ON_OFF_RATIO-1)) ? LED_ON : LED_OFF;
hwDigitalWrite(MY_DEFAULT_RX_LED_PIN, state);
#endif

#if defined(MY_DEFAULT_TX_LED_PIN)
if (countTx) {
--countTx;
}
state = (countTx & (LED_ON_OFF_RATIO-1)) ? LED_ON : LED_OFF;
hwDigitalWrite(MY_DEFAULT_TX_LED_PIN, state);
#endif

#if defined(MY_DEFAULT_ERR_LED_PIN)
if (countErr) {
--countErr;
}
state = (countErr & (LED_ON_OFF_RATIO-1)) ? LED_ON : LED_OFF;
hwDigitalWrite(MY_DEFAULT_ERR_LED_PIN, state);
#endif
}

void ledsBlinkRx(uint8_t cnt)
{
if (!countRx) {
countRx = cnt*LED_ON_OFF_RATIO;
}
ledsProcess();
}

void ledsBlinkTx(uint8_t cnt)
{
if(!countTx) {
countTx = cnt*LED_ON_OFF_RATIO;
}
ledsProcess();
}

void ledsBlinkErr(uint8_t cnt)
{
if(!countErr) {
countErr = cnt*LED_ON_OFF_RATIO;
}
ledsProcess();
}

bool ledsBlinking()
{
return countRx || countTx || countErr;
}

+ 59
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyLeds.h View File

@@ -0,0 +1,59 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#ifndef MyLeds_h
#define MyLeds_h


#ifdef MY_WITH_LEDS_BLINKING_INVERSE
#define LED_ON 0x1
#define LED_OFF 0x0
#else
#define LED_ON 0x0
#define LED_OFF 0x1
#endif

#if defined(MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN)
#define ledBlinkTx(x,...) ledsBlinkTx(x)
#define ledBlinkRx(x,...) ledsBlinkRx(x)
#define ledBlinkErr(x,...) ledsBlinkErr(x)

/**
* Blink with LEDs
* @param cnt how many blink cycles to keep the LED on. Default cycle is 300ms
*/
void ledsInit();
void ledsBlinkRx(uint8_t cnt);
void ledsBlinkTx(uint8_t cnt);
void ledsBlinkErr(uint8_t cnt);
void ledsProcess(); // do the actual blinking
/**
* Test if any LED is currently blinking.
* @return true when one or more LEDs are blinking, false otherwise.
*/
bool ledsBlinking();

#else
// Remove led functions if feature is disabled
#define ledBlinkTx(x,...)
#define ledBlinkRx(x,...)
#define ledBlinkErr(x,...)
#endif

#endif

+ 323
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyMessage.cpp View File

@@ -0,0 +1,323 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/


#include "MyMessage.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

MyMessage::MyMessage(void)
{
clear();
}

MyMessage::MyMessage(const uint8_t _sensor, const uint8_t _type)
{
clear();
sensor = _sensor;
type = _type;
}

void MyMessage::clear(void)
{
last = 0u;
sender = 0u;
destination = 0u; // Gateway is default destination
version_length = 0u;
command_ack_payload = 0u;
type = 0u;
sensor = 0u;
(void)memset(data, 0u, sizeof(data));

// set message protocol version
miSetVersion(PROTOCOL_VERSION);
}

bool MyMessage::isAck(void) const
{
return miGetAck();
}

uint8_t MyMessage::getCommand(void) const
{
return miGetCommand();
}

/* Getters for payload converted to desired form */
void* MyMessage::getCustom(void) const
{
return (void *)data;
}

const char* MyMessage::getString(void) const
{
uint8_t payloadType = miGetPayloadType();
if (payloadType == P_STRING) {
return data;
} else {
return NULL;
}
}

char MyMessage::i2h(const uint8_t i) const
{
uint8_t k = i & 0x0F;
if (k <= 9) {
return '0' + k;
} else {
return 'A' + k - 10;
}
}

char* MyMessage::getCustomString(char *buffer) const
{
for (uint8_t i = 0; i < miGetLength(); i++) {
buffer[i * 2] = i2h(data[i] >> 4);
buffer[(i * 2) + 1] = i2h(data[i]);
}
buffer[miGetLength() * 2] = '\0';
return buffer;
}

char* MyMessage::getStream(char *buffer) const
{
uint8_t cmd = miGetCommand();
if ((cmd == C_STREAM) && (buffer != NULL)) {
return getCustomString(buffer);
} else {
return NULL;
}
}

char* MyMessage::getString(char *buffer) const
{
uint8_t payloadType = miGetPayloadType();
if (buffer != NULL) {
if (payloadType == P_STRING) {
(void)strncpy(buffer, data, miGetLength());
buffer[miGetLength()] = 0;
} else if (payloadType == P_BYTE) {
(void)itoa(bValue, buffer, 10);
} else if (payloadType == P_INT16) {
(void)itoa(iValue, buffer, 10);
} else if (payloadType == P_UINT16) {
(void)utoa(uiValue, buffer, 10);
} else if (payloadType == P_LONG32) {
(void)ltoa(lValue, buffer, 10);
} else if (payloadType == P_ULONG32) {
(void)ultoa(ulValue, buffer, 10);
} else if (payloadType == P_FLOAT32) {
(void)dtostrf(fValue, 2, min(fPrecision, (uint8_t)8), buffer);
} else if (payloadType == P_CUSTOM) {
return getCustomString(buffer);
}
return buffer;
} else {
return NULL;
}
}

bool MyMessage::getBool(void) const
{
return getByte();
}

uint8_t MyMessage::getByte(void) const
{
if (miGetPayloadType() == P_BYTE) {
return data[0];
} else if (miGetPayloadType() == P_STRING) {
return atoi(data);
} else {
return 0;
}
}


float MyMessage::getFloat(void) const
{
if (miGetPayloadType() == P_FLOAT32) {
return fValue;
} else if (miGetPayloadType() == P_STRING) {
return atof(data);
} else {
return 0;
}
}

int32_t MyMessage::getLong(void) const
{
if (miGetPayloadType() == P_LONG32) {
return lValue;
} else if (miGetPayloadType() == P_STRING) {
return atol(data);
} else {
return 0;
}
}

uint32_t MyMessage::getULong(void) const
{
if (miGetPayloadType() == P_ULONG32) {
return ulValue;
} else if (miGetPayloadType() == P_STRING) {
return atol(data);
} else {
return 0;
}
}

int16_t MyMessage::getInt(void) const
{
if (miGetPayloadType() == P_INT16) {
return iValue;
} else if (miGetPayloadType() == P_STRING) {
return atoi(data);
} else {
return 0;
}
}

uint16_t MyMessage::getUInt(void) const
{
if (miGetPayloadType() == P_UINT16) {
return uiValue;
} else if (miGetPayloadType() == P_STRING) {
return atoi(data);
} else {
return 0;
}

}

MyMessage& MyMessage::setType(const uint8_t _type)
{
type = _type;
return *this;
}

MyMessage& MyMessage::setSensor(const uint8_t _sensor)
{
sensor = _sensor;
return *this;
}

MyMessage& MyMessage::setDestination(const uint8_t _destination)
{
destination = _destination;
return *this;
}

// Set payload
MyMessage& MyMessage::set(const void* value, const uint8_t length)
{
uint8_t payloadLength = value == NULL ? 0 : min(length, (uint8_t)MAX_PAYLOAD);
miSetLength(payloadLength);
miSetPayloadType(P_CUSTOM);
memcpy(data, value, payloadLength);
return *this;
}

MyMessage& MyMessage::set(const char* value)
{
uint8_t length = value == NULL ? 0 : min(strlen(value), (size_t)MAX_PAYLOAD);
miSetLength(length);
miSetPayloadType(P_STRING);
if (length) {
strncpy(data, value, length);
}
// null terminate string
data[length] = 0;
return *this;
}

#if !defined(__linux__)
MyMessage& MyMessage::set(const __FlashStringHelper* value)
{
uint8_t length = value == NULL ? 0
: min(strlen_P(reinterpret_cast<const char *>(value)), (size_t)MAX_PAYLOAD);
miSetLength(length);
miSetPayloadType(P_STRING);
if (length) {
strncpy_P(data, reinterpret_cast<const char *>(value), length);
}
// null terminate string
data[length] = 0;
return *this;
}
#endif


MyMessage& MyMessage::set(const bool value)
{
miSetLength(1);
miSetPayloadType(P_BYTE);
data[0] = value;
return *this;
}

MyMessage& MyMessage::set(const uint8_t value)
{
miSetLength(1);
miSetPayloadType(P_BYTE);
data[0] = value;
return *this;
}

MyMessage& MyMessage::set(const float value, const uint8_t decimals)
{
miSetLength(5); // 32 bit float + persi
miSetPayloadType(P_FLOAT32);
fValue=value;
fPrecision = decimals;
return *this;
}

MyMessage& MyMessage::set(const uint32_t value)
{
miSetPayloadType(P_ULONG32);
miSetLength(4);
ulValue = value;
return *this;
}

MyMessage& MyMessage::set(const int32_t value)
{
miSetPayloadType(P_LONG32);
miSetLength(4);
lValue = value;
return *this;
}

MyMessage& MyMessage::set(const uint16_t value)
{
miSetPayloadType(P_UINT16);
miSetLength(2);
uiValue = value;
return *this;
}

MyMessage& MyMessage::set(const int16_t value)
{
miSetPayloadType(P_INT16);
miSetLength(2);
iValue = value;
return *this;
}

+ 534
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyMessage.h View File

@@ -0,0 +1,534 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

/**
* @file MyMessage.h
*
* @brief API and type declarations for MySensors messages
* @defgroup MyMessagegrp MyMessage
* @ingroup publics
* @{
*
* @brief Here you can find all message types used by the MySensors protocol as well as macros for
* parsing and manipulating messages.
*/
#ifndef MyMessage_h
#define MyMessage_h

#ifdef __cplusplus
#include <Arduino.h>
#include <stdint.h>
#endif

#define PROTOCOL_VERSION (2u) //!< The version of the protocol
#define MAX_MESSAGE_LENGTH (32u) //!< The maximum size of a message (including header)
#define HEADER_SIZE (7u) //!< The size of the header
#define MAX_PAYLOAD (MAX_MESSAGE_LENGTH - HEADER_SIZE) //!< The maximum size of a payload depends on #MAX_MESSAGE_LENGTH and #HEADER_SIZE

/// @brief The command field (message-type) defines the overall properties of a message
typedef enum {
C_PRESENTATION = 0, //!< Sent by a node when they present attached sensors. This is usually done in presentation() at startup.
C_SET = 1, //!< This message is sent from or to a sensor when a sensor value should be updated.
C_REQ = 2, //!< Requests a variable value (usually from an actuator destined for controller).
C_INTERNAL = 3, //!< Internal MySensors messages (also include common messages provided/generated by the library).
C_STREAM = 4 //!< For firmware and other larger chunks of data that need to be divided into pieces.
} mysensors_command_t;

#if !DOXYGEN // Hide until we migrate
/// @brief Type of sensor (used when presenting sensors)
typedef enum {
S_DOOR = 0, //!< Door sensor, V_TRIPPED, V_ARMED
S_MOTION = 1, //!< Motion sensor, V_TRIPPED, V_ARMED
S_SMOKE = 2, //!< Smoke sensor, V_TRIPPED, V_ARMED
S_BINARY = 3, //!< Binary light or relay, V_STATUS, V_WATT
S_LIGHT = 3, //!< \deprecated Same as S_BINARY
S_DIMMER = 4, //!< Dimmable light or fan device, V_STATUS (on/off), V_PERCENTAGE (dimmer level 0-100), V_WATT
S_COVER = 5, //!< Blinds or window cover, V_UP, V_DOWN, V_STOP, V_PERCENTAGE (open/close to a percentage)
S_TEMP = 6, //!< Temperature sensor, V_TEMP
S_HUM = 7, //!< Humidity sensor, V_HUM
S_BARO = 8, //!< Barometer sensor, V_PRESSURE, V_FORECAST
S_WIND = 9, //!< Wind sensor, V_WIND, V_GUST
S_RAIN = 10, //!< Rain sensor, V_RAIN, V_RAINRATE
S_UV = 11, //!< Uv sensor, V_UV
S_WEIGHT = 12, //!< Personal scale sensor, V_WEIGHT, V_IMPEDANCE
S_POWER = 13, //!< Power meter, V_WATT, V_KWH, V_VAR, V_VA, V_POWER_FACTOR
S_HEATER = 14, //!< Header device, V_HVAC_SETPOINT_HEAT, V_HVAC_FLOW_STATE, V_TEMP
S_DISTANCE = 15, //!< Distance sensor, V_DISTANCE
S_LIGHT_LEVEL = 16, //!< Light level sensor, V_LIGHT_LEVEL (uncalibrated in percentage), V_LEVEL (light level in lux)
S_ARDUINO_NODE = 17, //!< Used (internally) for presenting a non-repeating Arduino node
S_ARDUINO_REPEATER_NODE = 18, //!< Used (internally) for presenting a repeating Arduino node
S_LOCK = 19, //!< Lock device, V_LOCK_STATUS
S_IR = 20, //!< IR device, V_IR_SEND, V_IR_RECEIVE
S_WATER = 21, //!< Water meter, V_FLOW, V_VOLUME
S_AIR_QUALITY = 22, //!< Air quality sensor, V_LEVEL
S_CUSTOM = 23, //!< Custom sensor
S_DUST = 24, //!< Dust sensor, V_LEVEL
S_SCENE_CONTROLLER = 25, //!< Scene controller device, V_SCENE_ON, V_SCENE_OFF.
S_RGB_LIGHT = 26, //!< RGB light. Send color component data using V_RGB. Also supports V_WATT
S_RGBW_LIGHT = 27, //!< RGB light with an additional White component. Send data using V_RGBW. Also supports V_WATT
S_COLOR_SENSOR = 28, //!< Color sensor, send color information using V_RGB
S_HVAC = 29, //!< Thermostat/HVAC device. V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COLD, V_HVAC_FLOW_STATE, V_HVAC_FLOW_MODE, V_TEMP
S_MULTIMETER = 30, //!< Multimeter device, V_VOLTAGE, V_CURRENT, V_IMPEDANCE
S_SPRINKLER = 31, //!< Sprinkler, V_STATUS (turn on/off), V_TRIPPED (if fire detecting device)
S_WATER_LEAK = 32, //!< Water leak sensor, V_TRIPPED, V_ARMED
S_SOUND = 33, //!< Sound sensor, V_TRIPPED, V_ARMED, V_LEVEL (sound level in dB)
S_VIBRATION = 34, //!< Vibration sensor, V_TRIPPED, V_ARMED, V_LEVEL (vibration in Hz)
S_MOISTURE = 35, //!< Moisture sensor, V_TRIPPED, V_ARMED, V_LEVEL (water content or moisture in percentage?)
S_INFO = 36, //!< LCD text device / Simple information device on controller, V_TEXT
S_GAS = 37, //!< Gas meter, V_FLOW, V_VOLUME
S_GPS = 38, //!< GPS Sensor, V_POSITION
S_WATER_QUALITY = 39 //!< V_TEMP, V_PH, V_ORP, V_EC, V_STATUS
} mysensors_sensor_t;

/// @brief Type of sensor data (for set/req/ack messages)
typedef enum {
V_TEMP = 0, //!< S_TEMP. Temperature S_TEMP, S_HEATER, S_HVAC
V_HUM = 1, //!< S_HUM. Humidity
V_STATUS = 2, //!< S_BINARY, S_DIMMER, S_SPRINKLER, S_HVAC, S_HEATER. Used for setting/reporting binary (on/off) status. 1=on, 0=off
V_LIGHT = 2, //!< \deprecated Same as V_STATUS
V_PERCENTAGE = 3, //!< S_DIMMER. Used for sending a percentage value 0-100 (%).
V_DIMMER = 3, //!< \deprecated Same as V_PERCENTAGE
V_PRESSURE = 4, //!< S_BARO. Atmospheric Pressure
V_FORECAST = 5, //!< S_BARO. Whether forecast. string of "stable", "sunny", "cloudy", "unstable", "thunderstorm" or "unknown"
V_RAIN = 6, //!< S_RAIN. Amount of rain
V_RAINRATE = 7, //!< S_RAIN. Rate of rain
V_WIND = 8, //!< S_WIND. Wind speed
V_GUST = 9, //!< S_WIND. Gust
V_DIRECTION = 10, //!< S_WIND. Wind direction 0-360 (degrees)
V_UV = 11, //!< S_UV. UV light level
V_WEIGHT = 12, //!< S_WEIGHT. Weight(for scales etc)
V_DISTANCE = 13, //!< S_DISTANCE. Distance
V_IMPEDANCE = 14, //!< S_MULTIMETER, S_WEIGHT. Impedance value
V_ARMED = 15, //!< S_DOOR, S_MOTION, S_SMOKE, S_SPRINKLER. Armed status of a security sensor. 1 = Armed, 0 = Bypassed
V_TRIPPED = 16, //!< S_DOOR, S_MOTION, S_SMOKE, S_SPRINKLER, S_WATER_LEAK, S_SOUND, S_VIBRATION, S_MOISTURE. Tripped status of a security sensor. 1 = Tripped, 0
V_WATT = 17, //!< S_POWER, S_BINARY, S_DIMMER, S_RGB_LIGHT, S_RGBW_LIGHT. Watt value for power meters
V_KWH = 18, //!< S_POWER. Accumulated number of KWH for a power meter
V_SCENE_ON = 19, //!< S_SCENE_CONTROLLER. Turn on a scene
V_SCENE_OFF = 20, //!< S_SCENE_CONTROLLER. Turn of a scene
V_HVAC_FLOW_STATE = 21, //!< S_HEATER, S_HVAC. HVAC flow state ("Off", "HeatOn", "CoolOn", or "AutoChangeOver")
V_HEATER = 21, //!< \deprecated Same as V_HVAC_FLOW_STATE
V_HVAC_SPEED = 22, //!< S_HVAC, S_HEATER. HVAC/Heater fan speed ("Min", "Normal", "Max", "Auto")
V_LIGHT_LEVEL = 23, //!< S_LIGHT_LEVEL. Uncalibrated light level. 0-100%. Use V_LEVEL for light level in lux
V_VAR1 = 24, //!< VAR1
V_VAR2 = 25, //!< VAR2
V_VAR3 = 26, //!< VAR3
V_VAR4 = 27, //!< VAR4
V_VAR5 = 28, //!< VAR5
V_UP = 29, //!< S_COVER. Window covering. Up
V_DOWN = 30, //!< S_COVER. Window covering. Down
V_STOP = 31, //!< S_COVER. Window covering. Stop
V_IR_SEND = 32, //!< S_IR. Send out an IR-command
V_IR_RECEIVE = 33, //!< S_IR. This message contains a received IR-command
V_FLOW = 34, //!< S_WATER. Flow of water (in meter)
V_VOLUME = 35, //!< S_WATER. Water volume
V_LOCK_STATUS = 36, //!< S_LOCK. Set or get lock status. 1=Locked, 0=Unlocked
V_LEVEL = 37, //!< S_DUST, S_AIR_QUALITY, S_SOUND (dB), S_VIBRATION (hz), S_LIGHT_LEVEL (lux)
V_VOLTAGE = 38, //!< S_MULTIMETER
V_CURRENT = 39, //!< S_MULTIMETER
V_RGB = 40, //!< S_RGB_LIGHT, S_COLOR_SENSOR. Sent as ASCII hex: RRGGBB (RR=red, GG=green, BB=blue component)
V_RGBW = 41, //!< S_RGBW_LIGHT. Sent as ASCII hex: RRGGBBWW (WW=white component)
V_ID = 42, //!< Used for sending in sensors hardware ids (i.e. OneWire DS1820b).
V_UNIT_PREFIX = 43, //!< Allows sensors to send in a string representing the unit prefix to be displayed in GUI, not parsed by controller! E.g. cm, m, km, inch.
V_HVAC_SETPOINT_COOL = 44, //!< S_HVAC. HVAC cool setpoint (Integer between 0-100)
V_HVAC_SETPOINT_HEAT = 45, //!< S_HEATER, S_HVAC. HVAC/Heater setpoint (Integer between 0-100)
V_HVAC_FLOW_MODE = 46, //!< S_HVAC. Flow mode for HVAC ("Auto", "ContinuousOn", "PeriodicOn")
V_TEXT = 47, //!< S_INFO. Text message to display on LCD or controller device
V_CUSTOM = 48, //!< Custom messages used for controller/inter node specific commands, preferably using S_CUSTOM device type.
V_POSITION = 49, //!< GPS position and altitude. Payload: latitude;longitude;altitude(m). E.g. "55.722526;13.017972;18"
V_IR_RECORD = 50, //!< Record IR codes S_IR for playback
V_PH = 51, //!< S_WATER_QUALITY, water PH
V_ORP = 52, //!< S_WATER_QUALITY, water ORP : redox potential in mV
V_EC = 53, //!< S_WATER_QUALITY, water electric conductivity μS/cm (microSiemens/cm)
V_VAR = 54, //!< S_POWER, Reactive power: volt-ampere reactive (var)
V_VA = 55, //!< S_POWER, Apparent power: volt-ampere (VA)
V_POWER_FACTOR = 56, //!< S_POWER, Ratio of real power to apparent power: floating point value in the range [-1,..,1]
} mysensors_data_t;
#endif


/// @brief Type of internal messages (for internal messages)
typedef enum {
I_BATTERY_LEVEL = 0, //!< Battery level
I_TIME = 1, //!< Time (request/response)
I_VERSION = 2, //!< Version
I_ID_REQUEST = 3, //!< ID request
I_ID_RESPONSE = 4, //!< ID response
I_INCLUSION_MODE = 5, //!< Inclusion mode
I_CONFIG = 6, //!< Config (request/response)
I_FIND_PARENT_REQUEST = 7, //!< Find parent
I_FIND_PARENT_RESPONSE = 8, //!< Find parent response
I_LOG_MESSAGE = 9, //!< Log message
I_CHILDREN = 10, //!< Children
I_SKETCH_NAME = 11, //!< Sketch name
I_SKETCH_VERSION = 12, //!< Sketch version
I_REBOOT = 13, //!< Reboot request
I_GATEWAY_READY = 14, //!< Gateway ready
I_SIGNING_PRESENTATION = 15, //!< Provides signing related preferences (first byte is preference version)
I_NONCE_REQUEST = 16, //!< Request for a nonce
I_NONCE_RESPONSE = 17, //!< Payload is nonce data
I_HEARTBEAT_REQUEST = 18, //!< Heartbeat request
I_PRESENTATION = 19, //!< Presentation message
I_DISCOVER_REQUEST = 20, //!< Discover request
I_DISCOVER_RESPONSE = 21, //!< Discover response
I_HEARTBEAT_RESPONSE = 22, //!< Heartbeat response
I_LOCKED = 23, //!< Node is locked (reason in string-payload)
I_PING = 24, //!< Ping sent to node, payload incremental hop counter
I_PONG = 25, //!< In return to ping, sent back to sender, payload incremental hop counter
I_REGISTRATION_REQUEST = 26, //!< Register request to GW
I_REGISTRATION_RESPONSE = 27, //!< Register response from GW
I_DEBUG = 28, //!< Debug message
I_SIGNAL_REPORT_REQUEST = 29, //!< Device signal strength request
I_SIGNAL_REPORT_REVERSE = 30, //!< Internal
I_SIGNAL_REPORT_RESPONSE = 31, //!< Device signal strength response (RSSI)
I_PRE_SLEEP_NOTIFICATION = 32, //!< Message sent before node is going to sleep
I_POST_SLEEP_NOTIFICATION = 33 //!< Message sent after node woke up (if enabled)
} mysensors_internal_t;


/// @brief Type of data stream (for streamed message)
typedef enum {
ST_FIRMWARE_CONFIG_REQUEST = 0, //!< Request new FW, payload contains current FW details
ST_FIRMWARE_CONFIG_RESPONSE = 1, //!< New FW details to initiate OTA FW update
ST_FIRMWARE_REQUEST = 2, //!< Request FW block
ST_FIRMWARE_RESPONSE = 3, //!< Response FW block
ST_SOUND = 4, //!< Sound
ST_IMAGE = 5, //!< Image
ST_FIRMWARE_CONFIRM = 6, //!< Mark running firmware as valid (MyOTAFirmwareUpdateNVM + mcuboot)
ST_FIRMWARE_RESPONSE_RLE = 7, //!< Response FW block with run length encoded data
} mysensors_stream_t;

/// @brief Type of payload
typedef enum {
P_STRING = 0, //!< Payload type is string
P_BYTE = 1, //!< Payload type is byte
P_INT16 = 2, //!< Payload type is INT16
P_UINT16 = 3, //!< Payload type is UINT16
P_LONG32 = 4, //!< Payload type is INT32
P_ULONG32 = 5, //!< Payload type is UINT32
P_CUSTOM = 6, //!< Payload type is binary
P_FLOAT32 = 7 //!< Payload type is float32
} mysensors_payload_t;



#ifndef BIT
#define BIT(n) ( 1<<(n) ) //!< Bit indexing macro
#endif
#define BIT_MASK(len) ( BIT(len)-1 ) //!< Create a bitmask of length 'len'
#define BF_MASK(start, len) ( BIT_MASK(len)<<(start) ) //!< Create a bitfield mask of length starting at bit 'start'

#define BF_PREP(x, start, len) ( ((x)&BIT_MASK(len)) << (start) ) //!< Prepare a bitmask for insertion or combining
#define BF_GET(y, start, len) ( ((y)>>(start)) & BIT_MASK(len) ) //!< Extract a bitfield of length 'len' starting at bit 'start' from 'y'
#define BF_SET(y, x, start, len) ( y= ((y) &~ BF_MASK(start, len)) | BF_PREP(x, start, len) ) //!< Insert a new bitfield value 'x' into 'y'

// Getters/setters for special bit fields in header
#define mSetVersion(_message,_version) BF_SET(_message.version_length, _version, 0, 2) //!< Set version field
#define mGetVersion(_message) ((uint8_t)BF_GET(_message.version_length, 0, 2)) //!< Get version field

#define mSetSigned(_message,_signed) BF_SET(_message.version_length, _signed, 2, 1) //!< Set signed field
#define mGetSigned(_message) ((bool)BF_GET(_message.version_length, 2, 1)) //!< Get signed field

#define mSetLength(_message,_length) BF_SET(_message.version_length, _length, 3, 5) //!< Set length field
#define mGetLength(_message) ((uint8_t)BF_GET(_message.version_length, 3, 5)) //!< Get length field

#define mSetCommand(_message,_command) BF_SET(_message.command_ack_payload, _command, 0, 3) //!< Set command field
#define mGetCommand(_message) ((uint8_t)BF_GET(_message.command_ack_payload, 0, 3)) //!< Get command field

#define mSetRequestAck(_message,_rack) BF_SET(_message.command_ack_payload, _rack, 3, 1) //!< Set ack-request field
#define mGetRequestAck(_message) ((bool)BF_GET(_message.command_ack_payload, 3, 1)) //!< Get ack-request field

#define mSetAck(_message,_ackMsg) BF_SET(_message.command_ack_payload, _ackMsg, 4, 1) //!< Set ack field
#define mGetAck(_message) ((bool)BF_GET(_message.command_ack_payload, 4, 1)) //!< Get ack field

#define mSetPayloadType(_message, _pt) BF_SET(_message.command_ack_payload, _pt, 5, 3) //!< Set payload type field
#define mGetPayloadType(_message) ((uint8_t)BF_GET(_message.command_ack_payload, 5, 3)) //!< Get payload type field


// internal access for special fields
#define miGetCommand() ((uint8_t)BF_GET(command_ack_payload, 0, 3)) //!< Internal getter for command field

#define miSetLength(_length) BF_SET(version_length, _length, 3, 5) //!< Internal setter for length field
#define miGetLength() ((uint8_t)BF_GET(version_length, 3, 5)) //!< Internal getter for length field

#define miSetVersion(_version) BF_SET(version_length, _version, 0, 2) //!< Internal setter for version field
#define miGetVersion() ((uint8_t)BF_GET(version_length, 0, 2)) //!< Internal getter for version field

#define miSetRequestAck(_rack) BF_SET(command_ack_payload, _rack, 3, 1) //!< Internal setter for ack-request field
#define miGetRequestAck() ((bool)BF_GET(command_ack_payload, 3, 1)) //!< Internal getter for ack-request field

#define miSetAck(_ack) BF_SET(command_ack_payload, _ack, 4, 1) //!< Internal setter for ack field
#define miGetAck() ((bool)BF_GET(command_ack_payload, 4, 1)) //!< Internal getter for ack field

#define miSetPayloadType(_pt) BF_SET(command_ack_payload, _pt, 5, 3) //!< Internal setter for payload type field
#define miGetPayloadType() (uint8_t)BF_GET(command_ack_payload, 5, 3) //!< Internal getter for payload type field


#if defined(__cplusplus) || defined(DOXYGEN)
/**
* @brief MyMessage is used to create, manipulate, send and read MySensors messages
*/
class MyMessage
{
private:
char* getCustomString(char *buffer) const;

public:
/**
* Default constructor
*/
MyMessage(void);

/**
* Constructor
* @param sensor id of the child sensor for this message
* @param type see http://korturl.nu/stupidurl
*/
MyMessage(const uint8_t sensor, const uint8_t type);

/**
* Single character hex (0 - 15) conversion
* @param i byte (only lower 4 bits will be considered)
* @return single char with the hex representation (0 to F) of the parameter
*/
char i2h(const uint8_t i) const;

/**
* @brief Clear message contents.
*/
void clear(void);

/**
* If payload is something else than P_STRING you can have the payload value converted
* into string representation by supplying a buffer with the minimum size of
* 2*MAX_PAYLOAD+1. This is to be able to fit hex-conversion of a full binary payload.
* @param buffer pointer to a buffer that's at least 2*MAX_PAYLOAD+1 bytes large
*/
char* getStream(char *buffer) const;

/**
* @brief Copy the payload into the supplied buffer
*/
char* getString(char *buffer) const;

/**
* @brief Get payload as string
* @return pointer to a char array storing the string
*/
const char* getString(void) const;

/**
* @brief Get custom payload
* @return pointer to the raw payload
*/
void* getCustom(void) const;

/**
* @brief Get bool payload
* @return a bool with the value of the payload (true/false)
*/
bool getBool(void) const;

/**
* @brief Get unsigned 8-bit integer payload
* @return the value of the payload, 0 to 255
*/
uint8_t getByte(void) const;

/**
* @brief Get float payload
* @return the floating-point value of the payload
*/
float getFloat(void) const;

/**
* @brief Get signed 16-bit integer payload
* @return the value of the payload, –32768 to 32767
*/
int16_t getInt(void) const;

/**
* @brief Get unsigned 16-bit integer payload
* @return the value of the payload, 0 to 65535
*/
uint16_t getUInt(void) const;

/**
* @brief Get signed 32-bit integer payload
* @return the value of the payload, –2147483648 to 2147483647
*/
int32_t getLong(void) const;

/**
* @brief Get unsigned 32-bit integer payload
* @return the value of the payload, 0 to 4294967295
*/
uint32_t getULong(void) const;

/**
* @brief Getter for command type
* @return #mysensors_command_t
*/
uint8_t getCommand(void) const;

/**
* @brief Getter for ack-flag.
* @return true if this is an ack message
*/
bool isAck(void) const;

/**
* @brief Set message type
* @param type see http://korturl.nu/stupidurl
*/
MyMessage& setType(const uint8_t type);

/**
* @brief Set which child sensor this message belongs to
* @param sensor
*/
MyMessage& setSensor(const uint8_t sensor);

/**
* @brief Set final destination node id for this message
* @param destination
*/
MyMessage& setDestination(const uint8_t destination);

/**
* @brief Set entire payload
* @param payload pointer to the buffer where the payload is stored
* @param length of the payload
*/
MyMessage& set(const void* payload, const uint8_t length);

/**
* @brief Set payload to character array
* @param value pointer to the character array. The array must be null-terminated.
*/
MyMessage& set(const char* value);
#if !defined(__linux__)
/**
* @brief Set payload to character array from flash
* @param value pointer to the character array. The array must be null-terminated.
*/
MyMessage& set(const __FlashStringHelper* value);
#endif

/**
* @brief Set payload to decimal number
* @param value float
* @param decimals number of decimals to include
*/
MyMessage& set(const float value, const uint8_t decimals);

/**
* @brief Set payload to bool value
* @param value true or false
*/
MyMessage& set(const bool value);

/**
* @brief Set payload to unsigned 8-bit integer value
* @param value (0 to 255)
*/
MyMessage& set(const uint8_t value);

/**
* @brief Set payload to unsigned 32-bit integer value
* @param value (0 to 4294967295)
*/
MyMessage& set(const uint32_t value);

/**
* @brief Set payload to signed 32-bit integer value
* @param value (–2147483648 to 2147483647)
*/
MyMessage& set(const int32_t value);

/**
* @brief Set payload to unsigned 16-bit integer value
* @param value (0 to 65535)
*/
MyMessage& set(const uint16_t value);

/**
* @brief Set payload to signed 16-bit integer value
* @param value (–32768 to 32767)
*/
MyMessage& set(const int16_t value);

#else

typedef union {
struct {

#endif
uint8_t last; //!< 8 bit - Id of last node this message passed
uint8_t sender; //!< 8 bit - Id of sender node (origin)
uint8_t destination; //!< 8 bit - Id of destination node

/**
* 2 bit - Protocol version<br>
* 1 bit - Signed flag<br>
* 5 bit - Length of payload
*/
uint8_t version_length;

/**
* 3 bit - Command type<br>
* 1 bit - Request an ack - Indicator that receiver should send an ack back<br>
* 1 bit - Is ack message - Indicator that this is the actual ack message<br>
* 3 bit - Payload data type
*/
uint8_t command_ack_payload;

uint8_t type; //!< 8 bit - Type varies depending on command
uint8_t sensor; //!< 8 bit - Id of sensor that this message concerns.

/*
* Each message can transfer a payload. We add one extra byte for string
* terminator \0 to be "printable" this is not transferred OTA
* This union is used to simplify the construction of the binary data types transferred.
*/
union {
uint8_t bValue; //!< unsigned byte value (8-bit)
uint16_t uiValue; //!< unsigned integer value (16-bit)
int16_t iValue; //!< signed integer value (16-bit)
uint32_t ulValue; //!< unsigned long value (32-bit)
int32_t lValue; //!< signed long value (32-bit)
struct { //!< Float messages
float fValue;
uint8_t fPrecision; //!< Number of decimals when serializing
};
struct { //!< Presentation messages
uint8_t version; //!< Library version
uint8_t sensorType; //!< Sensor type hint for controller, see table above
};
char data[MAX_PAYLOAD + 1]; //!< Buffer for raw payload data
} __attribute__((packed)); //!< Doxygen will complain without this comment
#if defined(__cplusplus) || defined(DOXYGEN)
} __attribute__((packed));
#else
};
uint8_t array[HEADER_SIZE + MAX_PAYLOAD + 1]; //!< buffer for entire message
} __attribute__((packed)) MyMessage;
#endif

#endif
/** @}*/

+ 287
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyOTAFirmwareUpdate.cpp View File

@@ -0,0 +1,287 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#include "MyOTAFirmwareUpdate.h"

// global variables
extern MyMessage _msg;
extern MyMessage _msgTmp;

// local variables
#ifdef MY_OTA_USE_I2C_EEPROM
I2CEeprom _flash(MY_OTA_I2C_ADDR);
#elif !defined(MCUBOOT_PRESENT)
SPIFlash _flash(MY_OTA_FLASH_SS, MY_OTA_FLASH_JDECID);
#endif

// Map flash functions
#ifndef MCUBOOT_PRESENT
#define _flash_initialize() _flash.initialize()
#define _flash_readByte(addr) _flash.readByte(addr)
#define _flash_writeBytes( dstaddr, data, size) _flash.writeBytes( dstaddr, data, size)
#define _flash_blockErase32K(num) _flash.blockErase32K(num)
#define _flash_busy() _flash.busy()
#else
#define _flash_initialize() true
#define _flash_readByte(addr) (*((uint8_t *)(addr)))
#define _flash_blockErase32K(num) Flash.erase((uint32_t *)FLASH_AREA_IMAGE_1_OFFSET_0, FLASH_AREA_IMAGE_1_SIZE_0)
#define _flash_busy() false
#endif

LOCAL nodeFirmwareConfig_t _nodeFirmwareConfig;
LOCAL bool _firmwareUpdateOngoing = false;
LOCAL uint32_t _firmwareLastRequest;
LOCAL uint16_t _firmwareBlock;
LOCAL uint8_t _firmwareRetry;
LOCAL bool _firmwareResponse(uint16_t block, uint8_t *data);

LOCAL void readFirmwareSettings(void)
{
hwReadConfigBlock((void*)&_nodeFirmwareConfig, (void*)EEPROM_FIRMWARE_TYPE_ADDRESS,
sizeof(nodeFirmwareConfig_t));
}

LOCAL void firmwareOTAUpdateRequest(void)
{
const uint32_t enterMS = hwMillis();
if (_firmwareUpdateOngoing && (enterMS - _firmwareLastRequest > MY_OTA_RETRY_DELAY)) {
if (!_firmwareRetry) {
setIndication(INDICATION_ERR_FW_TIMEOUT);
OTA_DEBUG(PSTR("!OTA:FRQ:FW UPD FAIL\n")); // fw update failed
// Give up. We have requested MY_OTA_RETRY times without any packet in return.
_firmwareUpdateOngoing = false;
return;
}
_firmwareRetry--;
_firmwareLastRequest = enterMS;
// Time to (re-)request firmware block from controller
requestFirmwareBlock_t firmwareRequest;
firmwareRequest.type = _nodeFirmwareConfig.type;
firmwareRequest.version = _nodeFirmwareConfig.version;
firmwareRequest.block = (_firmwareBlock - 1);
OTA_DEBUG(PSTR("OTA:FRQ:FW REQ,T=%04" PRIX16 ",V=%04" PRIX16 ",B=%04" PRIX16 "\n"),
_nodeFirmwareConfig.type,
_nodeFirmwareConfig.version, _firmwareBlock - 1); // request FW update block
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_STREAM, ST_FIRMWARE_REQUEST,
false).set(&firmwareRequest, sizeof(requestFirmwareBlock_t)));
}
}

LOCAL bool firmwareOTAUpdateProcess(void)
{
if (_msg.type == ST_FIRMWARE_CONFIG_RESPONSE) {
if(_firmwareUpdateOngoing) {
OTA_DEBUG(PSTR("!OTA:FWP:UPDO\n")); // FW config response received, FW update already ongoing
return true;
}
nodeFirmwareConfig_t *firmwareConfigResponse = (nodeFirmwareConfig_t *)_msg.data;
// compare with current node configuration, if they differ, start FW fetch process
if (memcmp(&_nodeFirmwareConfig, firmwareConfigResponse, sizeof(nodeFirmwareConfig_t))) {
setIndication(INDICATION_FW_UPDATE_START);
OTA_DEBUG(PSTR("OTA:FWP:UPDATE\n")); // FW update initiated
// copy new FW config
(void)memcpy(&_nodeFirmwareConfig, firmwareConfigResponse, sizeof(nodeFirmwareConfig_t));
// Init flash
if (!_flash_initialize()) {
setIndication(INDICATION_ERR_FW_FLASH_INIT);
OTA_DEBUG(PSTR("!OTA:FWP:FLASH INIT FAIL\n")); // failed to initialise flash
_firmwareUpdateOngoing = false;
} else {
// erase lower 32K -> max flash size for ATMEGA328
_flash_blockErase32K(0);
// wait until flash erased
while ( _flash_busy() ) {}
_firmwareBlock = _nodeFirmwareConfig.blocks;
_firmwareUpdateOngoing = true;
// reset flags
_firmwareRetry = MY_OTA_RETRY + 1;
_firmwareLastRequest = 0;
}
return true;
}
OTA_DEBUG(PSTR("OTA:FWP:UPDATE SKIPPED\n")); // FW update skipped, no newer version available
} else if (_msg.type == ST_FIRMWARE_RESPONSE) {
// extract FW block
replyFirmwareBlock_t *firmwareResponse = (replyFirmwareBlock_t *)_msg.data;
// Proceed firmware data
return _firmwareResponse(firmwareResponse->block, firmwareResponse->data);
#ifdef FIRMWARE_PROTOCOL_31
} else if (_msg.type == ST_FIRMWARE_RESPONSE_RLE) {
// RLE encoded block
// extract FW block
replyFirmwareBlockRLE_t *firmwareResponse = (replyFirmwareBlockRLE_t *)_msg.data;
uint8_t data[FIRMWARE_BLOCK_SIZE];
for (uint8_t i=0; i<FIRMWARE_BLOCK_SIZE; i++) {
data[i]=firmwareResponse->data;
}
while ((_firmwareBlock) && (firmwareResponse->number_of_blocks)) {
_firmwareResponse(firmwareResponse->block, data);
firmwareResponse->number_of_blocks--;
firmwareResponse->block--;
}
return true;
#endif
} else {
#ifdef MCUBOOT_PRESENT
if (_msg.type == ST_FIRMWARE_CONFIRM) {
if (*(uint16_t *)MCUBOOT_IMAGE_0_MAGIC_ADDR == ((uint16_t)MCUBOOT_IMAGE_MAGIC)) {
if (*(uint8_t*)(MCUBOOT_IMAGE_0_IMG_OK_ADDR)!=MCUBOOT_IMAGE_0_IMG_OK_BYTE) {
// Calculate data word to write
uint32_t *img_ok_base_addr = (uint32_t*)(MCUBOOT_IMAGE_0_IMG_OK_ADDR & ~3); // align word wise
uint32_t img_ok_data = *img_ok_base_addr;
// Set copy of MCUBOOT_IMAGE_0_IMG_OK_ADDR to MCUBOOT_IMAGE_0_IMG_OK_BYTE (0x01)
uint8_t * img_ok_array = (uint8_t*)(&img_ok_data);
img_ok_array[MCUBOOT_IMAGE_0_IMG_OK_ADDR % 4] = MCUBOOT_IMAGE_0_IMG_OK_BYTE;
// Write word back
Flash.write(img_ok_base_addr, img_ok_data);
}
OTA_DEBUG(PSTR("!OTA:FWP:IMAGE CONFIRMED\n"));
} else {
OTA_DEBUG(PSTR("!OTA:FWP:INVALID MCUBOOT MAGIC\n"));
}
}
#endif
}
return false;
}

LOCAL void presentBootloaderInformation(void)
{
requestFirmwareConfig_t *requestFirmwareConfig = (requestFirmwareConfig_t *)_msgTmp.data;
mSetLength(_msgTmp, sizeof(requestFirmwareConfig_t));
mSetCommand(_msgTmp, C_STREAM);
mSetPayloadType(_msgTmp, P_CUSTOM);
// copy node settings to reqFWConfig
(void)memcpy(requestFirmwareConfig, &_nodeFirmwareConfig, sizeof(nodeFirmwareConfig_t));
// add bootloader information
requestFirmwareConfig->BLVersion = MY_OTA_BOOTLOADER_VERSION;
#ifdef FIRMWARE_PROTOCOL_31
requestFirmwareConfig->blockSize = FIRMWARE_BLOCK_SIZE;
#ifndef MCUBOOT_PRESENT
requestFirmwareConfig->img_commited = 0x2;
requestFirmwareConfig->img_revision = 0x00;
requestFirmwareConfig->img_build_num = 0x00;
#else
requestFirmwareConfig->img_commited = *((uint8_t*)(MCUBOOT_IMAGE_0_IMG_OK_ADDR));
requestFirmwareConfig->img_revision = *((uint16_t*)(MCUBOOT_IMAGE_0_IMG_REVISION_ADDR));
requestFirmwareConfig->img_build_num = *((uint16_t*)(MCUBOOT_IMAGE_0_IMG_BUILD_NUM_ADDR));
#endif
#endif
_firmwareUpdateOngoing = false;
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_STREAM,
ST_FIRMWARE_CONFIG_REQUEST, false));
}

LOCAL bool isFirmwareUpdateOngoing(void)
{
return _firmwareUpdateOngoing;
}
// do a crc16 on the whole received firmware
LOCAL bool transportIsValidFirmware(void)
{
// init crc
uint16_t crc = ~0;
for (uint32_t i = 0; i < _nodeFirmwareConfig.blocks * FIRMWARE_BLOCK_SIZE; ++i) {
crc ^= _flash_readByte(i + FIRMWARE_START_OFFSET);
for (int8_t j = 0; j < 8; ++j) {
if (crc & 1) {
crc = (crc >> 1) ^ 0xA001;
} else {
crc = (crc >> 1);
}
}
}
OTA_DEBUG(PSTR("OTA:CRC:B=%04" PRIX16 ",C=%04" PRIX16 ",F=%04" PRIX16 "\n"),
_nodeFirmwareConfig.blocks,crc,
_nodeFirmwareConfig.crc);
return crc == _nodeFirmwareConfig.crc;
}

LOCAL bool _firmwareResponse(uint16_t block, uint8_t *data)
{
if (_firmwareUpdateOngoing) {
OTA_DEBUG(PSTR("OTA:FWP:RECV B=%04" PRIX16 "\n"), block); // received FW block
if (block != _firmwareBlock - 1) {
OTA_DEBUG(PSTR("!OTA:FWP:WRONG FWB\n")); // received FW block
// wrong firmware block received
setIndication(INDICATION_FW_UPDATE_RX_ERR);
// no further processing required
return true;
}
setIndication(INDICATION_FW_UPDATE_RX);
// Save block to flash
#ifdef MCUBOOT_PRESENT
uint32_t addr = ((size_t)(((_firmwareBlock - 1) * FIRMWARE_BLOCK_SIZE)) + (size_t)(
FIRMWARE_START_OFFSET));
if (addr<FLASH_AREA_IMAGE_SCRATCH_OFFSET_0) {
Flash.write_block( (uint32_t *)addr, (uint32_t *)data, FIRMWARE_BLOCK_SIZE>>2);
}
#else
_flash_writeBytes( ((_firmwareBlock - 1) * FIRMWARE_BLOCK_SIZE) + FIRMWARE_START_OFFSET,
data, FIRMWARE_BLOCK_SIZE);
#endif
// wait until flash written
while (_flash_busy()) {}
#ifdef OTA_EXTRA_FLASH_DEBUG
{
char prbuf[8];
uint32_t addr = ((_firmwareBlock - 1) * FIRMWARE_BLOCK_SIZE) + FIRMWARE_START_OFFSET;
OTA_DEBUG(PSTR("OTA:FWP:FL DUMP "));
sprintf_P(prbuf,PSTR("%04" PRIX16 ":"), (uint16_t)addr);
MY_SERIALDEVICE.print(prbuf);
for(uint8_t i=0; i<FIRMWARE_BLOCK_SIZE; i++) {
uint8_t data = _flash_readByte(addr + i);
sprintf_P(prbuf,PSTR("%02" PRIX8 ""), (uint8_t)data);
MY_SERIALDEVICE.print(prbuf);
}
OTA_DEBUG(PSTR("\n"));
}
#endif
_firmwareBlock--;
if (!_firmwareBlock) {
// We're done! Do a checksum and reboot.
OTA_DEBUG(PSTR("OTA:FWP:FW END\n")); // received FW block
_firmwareUpdateOngoing = false;
if (transportIsValidFirmware()) {
OTA_DEBUG(PSTR("OTA:FWP:CRC OK\n")); // FW checksum ok
// Write the new firmware config to eeprom
hwWriteConfigBlock((void*)&_nodeFirmwareConfig, (void*)EEPROM_FIRMWARE_TYPE_ADDRESS,
sizeof(nodeFirmwareConfig_t));
#ifndef MCUBOOT_PRESENT
// All seems ok, write size and signature to flash (DualOptiboot will pick this up and flash it)
const uint16_t firmwareSize = FIRMWARE_BLOCK_SIZE * _nodeFirmwareConfig.blocks;
const uint8_t OTAbuffer[FIRMWARE_START_OFFSET] = {'F','L','X','I','M','G',':', (uint8_t)(firmwareSize >> 8), (uint8_t)(firmwareSize & 0xff),':'};
_flash_writeBytes(0, OTAbuffer, FIRMWARE_START_OFFSET);
// wait until flash ready
while (_flash_busy()) {}
#endif
hwReboot();
} else {
setIndication(INDICATION_ERR_FW_CHECKSUM);
OTA_DEBUG(PSTR("!OTA:FWP:CRC FAIL\n"));
}
}
// reset flags
_firmwareRetry = MY_OTA_RETRY + 1;
_firmwareLastRequest = 0;
} else {
OTA_DEBUG(PSTR("!OTA:FWP:NO UPDATE\n"));
}
return true;
}

+ 197
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyOTAFirmwareUpdate.h View File

@@ -0,0 +1,197 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

/**
* @file MyOTAFirmwareUpdate.h
*
* @defgroup MyOTAFirmwaregrp MyOTAFirmwareUpdate
* @ingroup internals
* @{
*
* MyOTAFirmwareUpdate-related log messages, format: [!]SYSTEM:[SUB SYSTEM:]MESSAGE
* - [!] Exclamation mark is prepended in case of error or warning
* - SYSTEM:
* - <b>OTA</b> messages emitted by MyOTAFirmwareUpdate
* - SUB SYSTEMS:
* - OTA:<b>FRQ</b> from @ref firmwareOTAUpdateRequest()
* - OTA:<b>FWP</b> from @ref firmwareOTAUpdateProcess()
*
* MyOTAFirmwareUpdate debug log messages:
*
* |E| SYS | SUB | Message | Comment
* |-|-----|-----|-----------------------------|----------------------------------------------------------------------------
* | | OTA | FWP | UPDATE | FW update initiated
* |!| OTA | FWP | UPDO | FW config response received, FW update already ongoing
* |!| OTA | FWP | FLASH INIT FAIL | Failed to initialise flash
* | | OTA | FWP | UPDATE SKIPPED | FW update skipped, no newer version available
* | | OTA | FWP | RECV B=%04X | Received FW block (B)
* |!| OTA | FWP | WRONG FWB | Wrong FW block received
* | | OTA | FWP | FW END | FW received, proceed to CRC verification
* | | OTA | FWP | CRC OK | FW CRC verification OK
* |!| OTA | FWP | CRC FAIL | FW CRC verification failed
* | | OTA | FRQ | FW REQ,T=%04X,V=%04X,B=%04X | Request FW update, FW type (T), version (V), block (B)
* |!| OTA | FRQ | FW UPD FAIL | FW update failed
* | | OTA | CRC | B=%04X,C=%04X,F=%04X | FW CRC verification. FW blocks (B), calculated CRC (C), FW CRC (F)
*
*
* @brief API declaration for MyOTAFirmwareUpdate
*/


#ifndef MyOTAFirmwareUpdate_h
#define MyOTAFirmwareUpdate_h

#include "MySensorsCore.h"
#ifdef MCUBOOT_PRESENT
#include "generated_dts_board.h"
#define FIRMWARE_PROTOCOL_31
#endif

#define LOCAL static //!< static

#if MAX_PAYLOAD >= 22
#define FIRMWARE_BLOCK_SIZE (16u) //!< Size of each firmware block
#else
#define FIRMWARE_BLOCK_SIZE (8u) //!< Size of each firmware block
#ifndef FIRMWARE_PROTOCOL_31
#define FIRMWARE_PROTOCOL_31
#endif
#endif
#define FIRMWARE_MAX_REQUESTS (5u) //!< Number of times a firmware block should be requested before giving up
#define MY_OTA_RETRY (5u) //!< Number of times to request a fw block before giving up
#define MY_OTA_RETRY_DELAY (500u) //!< Number of milliseconds before re-requesting a FW block
#ifndef MCUBOOT_PRESENT
#define FIRMWARE_START_OFFSET (10u) //!< Start offset for firmware in flash (DualOptiboot wants to keeps a signature first)
#else
#define FIRMWARE_START_OFFSET (FLASH_AREA_IMAGE_1_OFFSET_0) //!< Use offset from generated_dts_board.h (mcuboot)
#endif

#define MY_OTA_BOOTLOADER_MAJOR_VERSION (3u) //!< Bootloader version major
#ifdef FIRMWARE_PROTOCOL_31
#define MY_OTA_BOOTLOADER_MINOR_VERSION (1u) //!< Bootloader version minor
#else
#define MY_OTA_BOOTLOADER_MINOR_VERSION (0u) //!< Bootloader version minor
#endif
#define MY_OTA_BOOTLOADER_VERSION (MY_OTA_BOOTLOADER_MINOR_VERSION * 256 + MY_OTA_BOOTLOADER_MAJOR_VERSION) //!< Bootloader version

#if defined(MY_DEBUG_VERBOSE_OTA_UPDATE)
#define OTA_DEBUG(x,...) DEBUG_OUTPUT(x, ##__VA_ARGS__) //!< debug
//#define OTA_EXTRA_FLASH_DEBUG //!< Dumps flash after each FW block
#else
#define OTA_DEBUG(x,...) //!< debug NULL
#endif

#if defined(DOXYGEN) && !defined(FIRMWARE_PROTOCOL_31)
/**
* @brief Enabled FOTA 3.1 protocol extensions
*
* Supports smaller FIRMWARE_BLOCK_SIZE, RLE and NVM for nRF5 with mcuboot. The
* extension is enabled per default when mcuboot is present or full FIRMWARE_BLOCK_SIZE
* exeeds MAX_PAYLOAD.
*/
#define FIRMWARE_PROTOCOL_31
#endif

/**
* @brief FW config structure, stored in eeprom
*/
typedef struct {
uint16_t type; //!< Type of config
uint16_t version; //!< Version of config
uint16_t blocks; //!< Number of blocks
uint16_t crc; //!< CRC of block data
} __attribute__((packed)) nodeFirmwareConfig_t;

/**
* @brief FW config request structure
*/
typedef struct {
uint16_t type; //!< Type of config
uint16_t version; //!< Version of config
uint16_t blocks; //!< Number of blocks
uint16_t crc; //!< CRC of block data
uint16_t BLVersion; //!< Bootloader version
#ifdef FIRMWARE_PROTOCOL_31
uint8_t blockSize; //!< Blocksize, when protocol version >= 3.1 is reported. Otherwhise the blocksize is 16
uint8_t img_commited; //!< mcuboot image_ok attribute commited firmware=0x01(mcuboot)|0x02(DualOptiboot), when protocol version >= 3.1 is reported
uint16_t img_revision; //!< mcuboot revision attribute, when protocol version >= 3.1 is reported
uint32_t img_build_num; //!< mcuboot build_num attribute, when protocol version >= 3.1 is reported
#endif
} __attribute__((packed)) requestFirmwareConfig_t;

/**
* @brief FW block request structure
*/
typedef struct {
uint16_t type; //!< Type of config
uint16_t version; //!< Version of config
uint16_t block; //!< Block index
} __attribute__((packed)) requestFirmwareBlock_t;

/**
* @brief FW block reply structure
*/
typedef struct {
uint16_t type; //!< Type of config
uint16_t version; //!< Version of config
uint16_t block; //!< Block index
uint8_t data[FIRMWARE_BLOCK_SIZE]; //!< Block data
} __attribute__((packed)) replyFirmwareBlock_t;

/**
* @brief FW block reply structure (RLE)
*/
typedef struct {
uint16_t type; //!< Type of config
uint16_t version; //!< Version of config
uint16_t block; //!< Block index
uint16_t number_of_blocks; //!< Number of blocks to fill with data
uint8_t data; //!< Block data
} __attribute__((packed)) replyFirmwareBlockRLE_t;

/**
* @brief Read firmware settings from EEPROM
*
* Current firmware settings (type, version, crc, blocks) are read into _fc
*/
LOCAL void readFirmwareSettings(void);
/**
* @brief Handle OTA FW update requests
*/
LOCAL void firmwareOTAUpdateRequest(void);
/**
* @brief Handle OTA FW update responses
*
* This function handles incoming OTA FW packets and stores them to external flash (Sensebender)
*/
LOCAL bool firmwareOTAUpdateProcess(void);
/**
* @brief Validate uploaded FW CRC
*
* This function verifies if uploaded FW CRC is valid
*/
LOCAL bool transportIsValidFirmware(void);
/**
* @brief Present bootloader/FW information upon startup
*/
LOCAL void presentBootloaderInformation(void);

#endif

/** @}*/

+ 157
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyOTALogging.cpp View File

@@ -0,0 +1,157 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
#include "MyOTALogging.h"

#ifdef MY_OTA_LOG_SENDER_FEATURE
// global variables
static bool inOTALog = false;

void OTALog(uint8_t logNode, bool enableAck, const char *fmt, ... )
{
// Avoid recursion
if (inOTALog==true) {
return;
}
inOTALog = true;

MyMessage msg(NODE_SENSOR_ID, I_LOG_MESSAGE);
char fmtBuffer[MY_SERIAL_OUTPUT_SIZE];
va_list args;

// create message
va_start (args, fmt );
int n = vsnprintf_P(fmtBuffer, sizeof(fmtBuffer), fmt, args);
va_end (args);

// Check number of chars
if (n<1) {
// Nothing to send
inOTALog = false;
return;
}

// Add \n to the end of string
if (n>(int)(sizeof(fmtBuffer)-2)) {
// String is truncated
n = sizeof(fmtBuffer)-2;
}

// add LF if not set
if (fmtBuffer[n-1]!='\n') {
fmtBuffer[n++]='\n';
fmtBuffer[n++]=0;
}

// Configure message
msg.sender = getNodeId();
msg.setDestination(logNode);
mSetCommand(msg, C_INTERNAL);
mSetRequestAck(msg, enableAck);

// Send package
for (int pos = 0; pos<n; pos+=MAX_PAYLOAD) {
uint8_t length = strlen(&fmtBuffer[pos]);
if (length>MAX_PAYLOAD) {
length = MAX_PAYLOAD;
}
(void)_sendRoute(msg.set((char*)&fmtBuffer[pos]));
}
inOTALog = false;
}
#endif


#ifdef MY_OTA_LOG_RECEIVER_FEATURE
// Global variables
char OTALogfmtBuffer[MY_SERIAL_OUTPUT_SIZE];
int OTALogfmtBufferPos = 0;
uint8_t OTALogBufferNode = BROADCAST_ADDRESS;
uint8_t OTALogBufferSensor = 0;

void OTALogPrintPrefix()
{
char prefix[37];
// prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE)
snprintf_P(prefix, sizeof(prefix),
PSTR("%" PRId8 ";%" PRId8 ";%" PRId8 ";0;%" PRId8 ";%" PRIu32 " "),
OTALogBufferNode, OTALogBufferSensor, C_INTERNAL, I_LOG_MESSAGE, hwMillis());
MY_SERIALDEVICE.print(prefix);
}

void OTALogFlushBuffer()
{
OTALogfmtBuffer[0] = 0;
OTALogfmtBufferPos = 0;
OTALogBufferNode = BROADCAST_ADDRESS;
}

inline void OTALogPrint(const MyMessage &message)
{
// Ignore log messages via broadcast
if (message.destination == BROADCAST_ADDRESS) {
return;
}

// FLush buffer, when node id changes
if ((OTALogBufferNode!=BROADCAST_ADDRESS) && ((OTALogBufferNode != message.sender) ||
(OTALogBufferSensor != message.sensor))) {
OTALogPrintPrefix();
MY_SERIALDEVICE.print(OTALogfmtBuffer);
MY_SERIALDEVICE.println("...");
OTALogFlushBuffer();
}

// Add data to buffer
const char *str = message.getString();
strncpy(&OTALogfmtBuffer[OTALogfmtBufferPos], str,
sizeof(OTALogfmtBuffer)-OTALogfmtBufferPos);
OTALogfmtBufferPos += strlen(str);

// Store node ID and sensor ID
OTALogBufferNode = message.sender;
OTALogBufferSensor = message.sensor;

// Print out buffered lines ending with \n
char *EOLpos;
while (EOLpos = strchr(OTALogfmtBuffer,'\n'), EOLpos != NULL) {
// Add end of string
EOLpos[0]=0;
// Print out line
OTALogPrintPrefix();
MY_SERIALDEVICE.println(OTALogfmtBuffer);
// Check if more content in buffer
int lenAfterEOL = (size_t)&OTALogfmtBuffer[OTALogfmtBufferPos]-(size_t)EOLpos-2;
if (lenAfterEOL>0) {
// More lines, move string to the beginning of the buffer
strcpy((char*)&OTALogfmtBuffer[0], (char*)&EOLpos[1]);
// calculate OTALogfmtBufferPos
OTALogfmtBufferPos -= (size_t)EOLpos-(size_t)&OTALogfmtBuffer[0]+2;
// Security check
if ((OTALogfmtBufferPos<=0) || (OTALogfmtBufferPos>=(int)sizeof(OTALogfmtBuffer))) {
MY_SERIALDEVICE.print("Sec:");
MY_SERIALDEVICE.println(OTALogfmtBufferPos);
OTALogFlushBuffer();
}
} else {
// End of message, prepare new one
OTALogFlushBuffer();
}
}
}
#endif

+ 73
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyOTALogging.h View File

@@ -0,0 +1,73 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

/**
* @file MyOTALogging.h
*
* @brief API declaration for MyOTALogging
* @defgroup MyOTALogginggrp MyOTALogging
* @ingroup internals
* @{
*
* @brief Enables ending and receiving debug messages over the air.
*/
#ifndef MyOTALogging_h
#define MyOTALogging_h

#include "MySensorsCore.h"
#include "MyTransport.h"

/**
* @brief Send a log message to a node
*
* If MY_OTA_LOG_RECEIVER_FEATURE is enabled on the destination node, the given
* message is printed to the serial port. You have to define MY_OTA_LOG_SENDER_FEATURE
* or MY_DEBUG_OTA to enable the OTALog() function.
*
* Output format of each line:
* Node ID;CHILD_NODE_ID;C_INTERNAL;I_LOG_MESSAGE;hwMillis() MESSAGE
*
* You will see the hwMillis() of the receiving node. After each \n character, a
* new debug message line starts. Incomplete messages are ending with '...'
*
* @param logNode Destination node ID
* @param enableAck Enable or disable ACK flag
* @param fmt printf format string
* @param ... arguments
*/
void OTALog(uint8_t logNode, bool enableAck, const char *fmt, ... );

/**
* @brief Handles output of OTA log or debug messages
*
* This function is used by MyTransport.cpp
*
* Output format of each line:
* Node ID;CHILD_NODE_ID;C_INTERNAL;I_LOG_MESSAGE;hwMillis() MESSAGE
*
* You will see the hwMillis() of the receiving node. After each \n character, a
* new debug message line starts. Incomplete messages are ending with '...'
*
* @param message Message buffer to use.
*/
inline void OTALogPrint(const MyMessage &message);

#endif /* MyOTALogging_h */

/** @}*/

+ 61
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyPrivateConfig.h.sample View File

@@ -0,0 +1,61 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
/*
* This file contains settings that for various reasons are unsuitable to store in git
* Rename it by removing the .sample extension and place it in the sketch folder and include
* it in the sketch:
* #include "MyPrivateConfig.h"
* Make sure to include it before
* #include <MySensors.h>
* Then adapt the contents to your personal preference.
*/

#ifndef MyPrivateConfig_h
#define MyPrivateConfig_h

/**********************************
* Node identification Settings
***********************************/
//#define MY_NODE_ID 1

/**********************************
* Message Signing Settings
***********************************/
// Pin used for random generation in soft signing (do not connect anything to this when enabled)
#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 // A7 -

// Enable node whitelisting
//#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}}}

/**********************************
* nRF24L01 Driver Defaults
***********************************/
// Enables RF24 encryption (all nodes and gateway must have this enabled)
//#define MY_RF24_ENABLE_ENCRYPTION

/**********************************
* RFM69 Driver Defaults
***********************************/
// Default network id. Use the same for all nodes that will talk to each other
#define MY_RFM69_NETWORKID 100

// Enable this for encryption of packets
//#define MY_RFM69_ENABLE_ENCRYPTION

#endif

+ 34
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyProtocol.h View File

@@ -0,0 +1,34 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#ifndef MyProtocol_h
#define MyProtocol_h

#include "MySensorsCore.h"


// parse(message, inputString)
// parse a string into a message element
// returns true if successfully parsed the input string
bool protocolParse(MyMessage &message, char *inputString);

// Format MyMessage to the protocol representation
char *protocolFormat(MyMessage &message);

#endif

+ 208
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyProtocolMySensors.cpp View File

@@ -0,0 +1,208 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#include "MyConfig.h"
#include "MyTransport.h"
#include "MyProtocol.h"
#include <string.h>

uint8_t protocolH2i(char c);

char _fmtBuffer[MY_GATEWAY_MAX_SEND_LENGTH];
char _convBuffer[MAX_PAYLOAD*2+1];

bool protocolParse(MyMessage &message, char *inputString)
{
char *str, *p, *value=NULL;
uint8_t bvalue[MAX_PAYLOAD];
uint8_t blen = 0;
int i = 0;
uint8_t command = 0;

// Extract command data coming on serial line
for (str = strtok_r(inputString, ";", &p); // split using semicolon
str && i < 6; // loop while str is not null an max 5 times
str = strtok_r(NULL, ";", &p) // get subsequent tokens
) {
switch (i) {
case 0: // Radio id (destination)
message.destination = atoi(str);
break;
case 1: // Child id
message.sensor = atoi(str);
break;
case 2: // Message type
command = atoi(str);
mSetCommand(message, command);
break;
case 3: // Should we request ack from destination?
mSetRequestAck(message, atoi(str)?1:0);
break;
case 4: // Data type
message.type = atoi(str);
break;
case 5: // Variable value
if (command == C_STREAM) {
while (*str) {
uint8_t val;
val = protocolH2i(*str++) << 4;
val += protocolH2i(*str++);
bvalue[blen] = val;
blen++;
}
} else {
value = str;
// Remove trailing carriage return and newline character (if it exists)
uint8_t lastCharacter = strlen(value)-1;
if (value[lastCharacter] == '\r') {
value[lastCharacter] = 0;
}
if (value[lastCharacter] == '\n') {
value[lastCharacter] = 0;
}
}
break;
}
i++;
}
// Check for invalid input
if (i < 5) {
return false;
}
message.sender = GATEWAY_ADDRESS;
message.last = GATEWAY_ADDRESS;
mSetAck(message, false);
if (command == C_STREAM) {
message.set(bvalue, blen);
} else {
message.set(value);
}
return true;
}

char * protocolFormat(MyMessage &message)
{
snprintf_P(_fmtBuffer, MY_GATEWAY_MAX_SEND_LENGTH,
PSTR("%" PRIu8 ";%" PRIu8 ";%" PRIu8 ";%" PRIu8 ";%" PRIu8 ";%s\n"), message.sender,
message.sensor, (uint8_t)mGetCommand(message), (uint8_t)mGetAck(message), message.type,
message.getString(_convBuffer));
return _fmtBuffer;
}

char * protocolFormatMQTTTopic(const char* prefix, MyMessage &message)
{
snprintf_P(_fmtBuffer, MY_GATEWAY_MAX_SEND_LENGTH,
PSTR("%s/%" PRIu8 "/%" PRIu8 "/%" PRIu8 "/%" PRIu8 "/%" PRIu8 ""), prefix,
message.sender, message.sensor, mGetCommand(message), mGetAck(message), message.type);
return _fmtBuffer;
}

char * protocolFormatMQTTSubscribe(const char* prefix)
{
snprintf_P(_fmtBuffer, MY_GATEWAY_MAX_SEND_LENGTH, PSTR("%s/+/+/+/+/+"), prefix);
return _fmtBuffer;
}

#ifdef MY_GATEWAY_MQTT_CLIENT
bool protocolMQTTParse(MyMessage &message, char* topic, uint8_t* payload, unsigned int length)
{
char *str, *p;
uint8_t i = 0;
uint8_t command = 0;
if (topic != strstr(topic, MY_MQTT_SUBSCRIBE_TOPIC_PREFIX)) {
// Prefix doesn't match incoming topic
return false;
}
for (str = strtok_r(topic + strlen(MY_MQTT_SUBSCRIBE_TOPIC_PREFIX) + 1, "/", &p); str && i <= 5;
str = strtok_r(NULL, "/", &p)) {
switch (i) {
case 0: {
// Node id
message.destination = atoi(str);
break;
}
case 1: {
// Sensor id
message.sensor = atoi(str);
break;
}
case 2: {
// Command type
command = atoi(str);
mSetCommand(message, command);
break;
}
case 3: {
// Ack flag
mSetRequestAck(message, atoi(str)?1:0);
break;
}
case 4: {
// Sub type
message.type = atoi(str);
break;
}
}
i++;
}

if (i != 5) {
return false;
}

message.sender = GATEWAY_ADDRESS;
message.last = GATEWAY_ADDRESS;
mSetAck(message, false);

// Add payload
if (command == C_STREAM) {
uint8_t bvalue[MAX_PAYLOAD];
uint8_t blen = 0;
while (*payload) {
uint8_t val;
val = protocolH2i(*payload++) << 4;
val += protocolH2i(*payload++);
bvalue[blen] = val;
blen++;
}
message.set(bvalue, blen);
} else {
char* ca;
ca = (char *) payload;
ca += length;
*ca = '\0';
message.set((const char*) payload);
}

return true;
}
#endif

uint8_t protocolH2i(char c)
{
uint8_t i = 0;
if (c <= '9') {
i += c - '0';
} else if (c >= 'a') {
i += c - 'a' + 10;
} else {
i += c - 'A' + 10;
}
return i;
}

+ 763
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySensorsCore.cpp View File

@@ -0,0 +1,763 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#include "MySensorsCore.h"

#if defined(__linux__)
#include <stdlib.h>
#include <unistd.h>
#endif

// debug output
#if defined(MY_DEBUG_VERBOSE_CORE)
#define CORE_DEBUG(x,...) DEBUG_OUTPUT(x, ##__VA_ARGS__) //!< debug
#else
#define CORE_DEBUG(x,...) //!< debug NULL
#endif

// message buffers

MyMessage _msg; // Buffer for incoming messages
MyMessage _msgTmp; // Buffer for temporary messages (acks and nonces among others)

// core configuration
static coreConfig_t _coreConfig;

#if defined(DEBUG_OUTPUT_ENABLED)
char _convBuf[MAX_PAYLOAD*2+1];
#endif

// Callback for transport=ok transition
void _callbackTransportReady(void)
{
if (!_coreConfig.presentationSent) {
#if !defined(MY_GATEWAY_FEATURE) // GW calls presentNode() when client connected
presentNode();
#endif
_registerNode();
_coreConfig.presentationSent = true;
}
}

void _process(void)
{
doYield();

#if defined(MY_INCLUSION_MODE_FEATURE)
inclusionProcess();
#endif

#if defined(MY_GATEWAY_FEATURE)
gatewayTransportProcess();
#endif

#if defined(MY_SENSOR_NETWORK)
transportProcess();
#endif

#if defined(__linux__)
// To avoid high cpu usage
usleep(10000); // 10ms
#endif
}

void _infiniteLoop(void)
{
while(1) {
doYield();
#if defined(__linux__)
exit(1);
#endif
}
}

void _begin(void)
{
#if defined(MY_CORE_ONLY)
// initialize HW and run setup if present
(void)hwInit();
if (setup) {
setup();
}
return;
#endif
// reset wdt
hwWatchdogReset();

if (preHwInit) {
preHwInit();
}

const bool hwInitResult = hwInit();

#if !defined(MY_SPLASH_SCREEN_DISABLED) && !defined(MY_GATEWAY_FEATURE)
displaySplashScreen();
#endif

CORE_DEBUG(PSTR("MCO:BGN:INIT " MY_NODE_TYPE ",CP=" MY_CAPABILITIES ",REL=%" PRIu8 ",VER="
MYSENSORS_LIBRARY_VERSION "\n"), MYSENSORS_LIBRARY_VERSION_PRERELEASE_NUMBER);
if (!hwInitResult) {
CORE_DEBUG(PSTR("!MCO:BGN:HW ERR\n"));
setIndication(INDICATION_ERR_HW_INIT);
_infiniteLoop();
}

// set defaults
_coreConfig.presentationSent = false;

// Call sketch before() (if defined)
if (before) {
CORE_DEBUG(PSTR("MCO:BGN:BFR\n")); // before callback
before();
}

#if defined(MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN)
ledsInit();
#endif

signerInit();

// Read latest received controller configuration from EEPROM
// Note: _coreConfig.isMetric is bool, hence empty EEPROM (=0xFF) evaluates to true (default)
hwReadConfigBlock((void*)&_coreConfig.controllerConfig, (void*)EEPROM_CONTROLLER_CONFIG_ADDRESS,
sizeof(controllerConfig_t));

#if defined(MY_OTA_FIRMWARE_FEATURE)
// Read firmware config from EEPROM, i.e. type, version, CRC, blocks
readFirmwareSettings();
#endif

#if defined(MY_SENSOR_NETWORK)
// Save static parent ID in eeprom (used by bootloader)
hwWriteConfig(EEPROM_PARENT_NODE_ID_ADDRESS, MY_PARENT_NODE_ID);
// Initialise transport layer
transportInitialise();
// Register transport=ready callback
transportRegisterReadyCallback(_callbackTransportReady);
// wait until transport is ready
(void)transportWaitUntilReady(MY_TRANSPORT_WAIT_READY_MS);
#endif

_checkNodeLock();

#if defined(MY_GATEWAY_FEATURE)
#if defined(MY_INCLUSION_BUTTON_FEATURE)
inclusionInit();
#endif

// initialise the transport driver
if (!gatewayTransportInit()) {
setIndication(INDICATION_ERR_INIT_GWTRANSPORT);
CORE_DEBUG(PSTR("!MCO:BGN:TSP FAIL\n"));
// Nothing more we can do
_infiniteLoop();
}
#endif

// Call sketch setup() (if defined)
if (setup) {
CORE_DEBUG(PSTR("MCO:BGN:STP\n")); // setup callback
setup();
}
#if defined(MY_SENSOR_NETWORK)
CORE_DEBUG(PSTR("MCO:BGN:INIT OK,TSP=%" PRIu8 "\n"), isTransportReady() && transportSanityCheck());
#else
// no sensor network defined, call presentation & registration
_callbackTransportReady();
CORE_DEBUG(PSTR("MCO:BGN:INIT OK,TSP=NA\n"));
#endif
// reset wdt before handing over to loop
hwWatchdogReset();
}


void _registerNode(void)
{
#if defined (MY_REGISTRATION_FEATURE) && !defined(MY_GATEWAY_FEATURE)
CORE_DEBUG(PSTR("MCO:REG:REQ\n")); // registration request
setIndication(INDICATION_REQ_REGISTRATION);
_coreConfig.nodeRegistered = MY_REGISTRATION_DEFAULT;
uint8_t counter = MY_REGISTRATION_RETRIES;
// only proceed if register response received or retries exceeded
do {
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL,
I_REGISTRATION_REQUEST).set(MY_CORE_VERSION));
} while (!wait(2000, C_INTERNAL, I_REGISTRATION_RESPONSE) && counter--);
#else
_coreConfig.nodeRegistered = true;
CORE_DEBUG(PSTR("MCO:REG:NOT NEEDED\n"));
#endif
}

void presentNode(void)
{
setIndication(INDICATION_PRESENT);
// Present node and request config
#if defined(MY_GATEWAY_FEATURE)
// Send presentation for this gateway device
#if defined(MY_REPEATER_FEATURE)
(void)present(NODE_SENSOR_ID, S_ARDUINO_REPEATER_NODE);
#else
(void)present(NODE_SENSOR_ID, S_ARDUINO_NODE);
#endif
#else

#if defined(MY_OTA_FIRMWARE_FEATURE)
presentBootloaderInformation();
#endif

// Send signing preferences for this node to the GW
signerPresentation(_msgTmp, GATEWAY_ADDRESS);

// Send presentation for this radio node
#if defined(MY_REPEATER_FEATURE)
(void)present(NODE_SENSOR_ID, S_ARDUINO_REPEATER_NODE);
#else
(void)present(NODE_SENSOR_ID, S_ARDUINO_NODE);
#endif

// Send a configuration exchange request to controller
// Node sends parent node. Controller answers with latest node configuration
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL,
I_CONFIG).set(getParentNodeId()));

// Wait configuration reply.
(void)wait(2000, C_INTERNAL, I_CONFIG);

#endif

if (presentation) {
presentation();
}
}


uint8_t getNodeId(void)
{
uint8_t result;
#if defined(MY_GATEWAY_FEATURE)
result = GATEWAY_ADDRESS;
#elif defined(MY_SENSOR_NETWORK)
result = transportGetNodeId();
#else
result = VALUE_NOT_DEFINED;
#endif
return result;
}

uint8_t getParentNodeId(void)
{
uint8_t result;
#if defined(MY_GATEWAY_FEATURE)
result = VALUE_NOT_DEFINED; // GW doesn't have a parent
#elif defined(MY_SENSOR_NETWORK)
result = transportGetParentNodeId();
#else
result = VALUE_NOT_DEFINED;
#endif
return result;
}

uint8_t getDistanceGW(void)
{
uint8_t result;
#if defined(MY_GATEWAY_FEATURE)
result = 0;
#elif defined(MY_SENSOR_NETWORK)
result = transportGetDistanceGW();
#else
result = VALUE_NOT_DEFINED;
#endif
return result;
}

controllerConfig_t getControllerConfig(void)
{
return _coreConfig.controllerConfig;
}


bool _sendRoute(MyMessage &message)
{
#if defined(MY_CORE_ONLY)
(void)message;
#endif
#if defined(MY_GATEWAY_FEATURE)
if (message.destination == getNodeId()) {
// This is a message sent from a sensor attached on the gateway node.
// Pass it directly to the gateway transport layer.
return gatewayTransportSend(message);
}
#endif
#if defined(MY_SENSOR_NETWORK)
return transportSendRoute(message);
#else
return false;
#endif
}

bool send(MyMessage &message, const bool enableAck)
{
message.sender = getNodeId();
mSetCommand(message, C_SET);
mSetRequestAck(message, enableAck);

#if defined(MY_REGISTRATION_FEATURE) && !defined(MY_GATEWAY_FEATURE)
if (_coreConfig.nodeRegistered) {
return _sendRoute(message);
} else {
CORE_DEBUG(PSTR("!MCO:SND:NODE NOT REG\n")); // node not registered
return false;
}
#else
return _sendRoute(message);
#endif
}

bool sendBatteryLevel(const uint8_t value, const bool ack)
{
return _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_BATTERY_LEVEL,
ack).set(value));
}

bool sendHeartbeat(const bool ack)
{
#if defined(MY_SENSOR_NETWORK)
const uint32_t heartbeat = transportGetHeartbeat();
return _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_HEARTBEAT_RESPONSE,
ack).set(heartbeat));
#else
(void)ack;
return false;
#endif
}



bool present(const uint8_t childSensorId, const uint8_t sensorType, const char *description,
const bool ack)
{
return _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, childSensorId, C_PRESENTATION, sensorType,
ack).set(childSensorId == NODE_SENSOR_ID ? MYSENSORS_LIBRARY_VERSION : description));
}

#if !defined(__linux__)
bool present(const uint8_t childSensorId, const uint8_t sensorType,
const __FlashStringHelper *description,
const bool ack)
{
return _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, childSensorId, C_PRESENTATION, sensorType,
ack).set(childSensorId == NODE_SENSOR_ID ? F(" MYSENSORS_LIBRARY_VERSION "): description));
}
#endif


bool sendSketchInfo(const char *name, const char *version, const bool ack)
{
bool result = true;
if (name) {
result &= _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_SKETCH_NAME,
ack).set(name));
}
if (version) {
result &= _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_SKETCH_VERSION,
ack).set(version));
}
return result;
}

#if !defined(__linux__)
bool sendSketchInfo(const __FlashStringHelper *name, const __FlashStringHelper *version,
const bool ack)
{
bool result = true;
if (name) {
result &= _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_SKETCH_NAME,
ack).set(name));
}
if (version) {
result &= _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_SKETCH_VERSION,
ack).set(version));
}
return result;
}
#endif

bool request(const uint8_t childSensorId, const uint8_t variableType, const uint8_t destination)
{
return _sendRoute(build(_msgTmp, destination, childSensorId, C_REQ, variableType).set(""));
}

bool requestTime(const bool ack)
{
return _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_TIME, ack).set(""));
}

// Message delivered through _msg
bool _processInternalCoreMessage(void)
{
const uint8_t type = _msg.type;
if (_msg.sender == GATEWAY_ADDRESS) {
if (type == I_REBOOT) {
#if !defined(MY_DISABLE_REMOTE_RESET)
setIndication(INDICATION_REBOOT);
// WDT fuse should be enabled
hwReboot();
#endif
} else if (type == I_REGISTRATION_RESPONSE) {
#if defined (MY_REGISTRATION_FEATURE) && !defined(MY_GATEWAY_FEATURE)
_coreConfig.nodeRegistered = _msg.getBool();
setIndication(INDICATION_GOT_REGISTRATION);
CORE_DEBUG(PSTR("MCO:PIM:NODE REG=%" PRIu8 "\n"), _coreConfig.nodeRegistered); // node registration
#endif
} else if (type == I_CONFIG) {
// Pick up configuration from controller (currently only metric/imperial) and store it in eeprom if changed
_coreConfig.controllerConfig.isMetric = _msg.data[0] == 0x00 ||
_msg.data[0] == 'M'; // metric if null terminated or M
hwWriteConfigBlock((void*)&_coreConfig.controllerConfig, (void*)EEPROM_CONTROLLER_CONFIG_ADDRESS,
sizeof(controllerConfig_t));
} else if (type == I_PRESENTATION) {
// Re-send node presentation to controller
presentNode();
} else if (type == I_HEARTBEAT_REQUEST) {
(void)sendHeartbeat();
} else if (_msg.type == I_VERSION) {
#if !defined(MY_GATEWAY_FEATURE)
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL,
I_VERSION).set(MYSENSORS_LIBRARY_VERSION_INT));
#endif
} else if (type == I_TIME) {
// Deliver time to callback
if (receiveTime) {
receiveTime(_msg.getULong());
}
} else if (type == I_CHILDREN) {
if (_msg.data[0] == 'C') {
#if defined(MY_REPEATER_FEATURE) && defined(MY_SENSOR_NETWORK)
// Clears child relay data for this node
setIndication(INDICATION_CLEAR_ROUTING);
transportClearRoutingTable();
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_CHILDREN).set("OK"));
#endif
}
} else if (type == I_DEBUG) {
#if defined(MY_SPECIAL_DEBUG)
const char debug_msg = _msg.data[0];
if (debug_msg == 'R') { // routing table
#if defined(MY_REPEATER_FEATURE) && defined(MY_SENSOR_NETWORK)
transportReportRoutingTable();
#endif
} else if (debug_msg == 'V') { // CPU voltage
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL,
I_DEBUG).set(hwCPUVoltage()));
} else if (debug_msg == 'F') { // CPU frequency in 1/10Mhz
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL,
I_DEBUG).set(hwCPUFrequency()));
} else if (debug_msg == 'M') { // free memory
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL,
I_DEBUG).set(hwFreeMem()));
} else if (debug_msg == 'E') { // clear MySensors eeprom area and reboot
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_DEBUG).set("OK"));
for (uint16_t i = EEPROM_START; i<EEPROM_LOCAL_CONFIG_ADDRESS; i++) {
hwWriteConfig(i, 0xFF);
}
setIndication(INDICATION_REBOOT);
hwReboot();
}
#endif
} else {
return false; // further processing required
}
} else {
// sender is a node
if (type == I_REGISTRATION_REQUEST) {
#if defined(MY_GATEWAY_FEATURE)
// registration requests are exclusively handled by GW/Controller
#if !defined(MY_REGISTRATION_CONTROLLER)
bool approveRegistration;

#if defined(MY_CORE_COMPATIBILITY_CHECK)
approveRegistration = (_msg.getByte() >= MY_CORE_MIN_VERSION);
#else
// auto registration if version compatible
approveRegistration = true;
#endif

#if (F_CPU>16000000)
// delay for fast GW and slow nodes
delay(5);
#endif
(void)_sendRoute(build(_msgTmp, _msg.sender, NODE_SENSOR_ID, C_INTERNAL,
I_REGISTRATION_RESPONSE).set(approveRegistration));
#else
return false; // processing of this request via controller
#endif
#endif
} else {
return false; // further processing required
}
}
return true; // if not GW or no further processing required
}


void saveState(const uint8_t pos, const uint8_t value)
{
hwWriteConfig(EEPROM_LOCAL_CONFIG_ADDRESS+pos, value);
}
uint8_t loadState(const uint8_t pos)
{
return hwReadConfig(EEPROM_LOCAL_CONFIG_ADDRESS+pos);
}


void wait(const uint32_t waitingMS)
{
const uint32_t enteringMS = hwMillis();
while (hwMillis() - enteringMS < waitingMS) {
_process();
}
}

bool wait(const uint32_t waitingMS, const uint8_t cmd, const uint8_t msgType)
{
const uint32_t enteringMS = hwMillis();
// invalidate msg type
_msg.type = !msgType;
bool expectedResponse = false;
while ( (hwMillis() - enteringMS < waitingMS) && !expectedResponse ) {
_process();
expectedResponse = (mGetCommand(_msg) == cmd && _msg.type == msgType);
}
return expectedResponse;
}

void doYield(void)
{
hwWatchdogReset();

yield();

#if defined (MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN)
ledsProcess();
#endif
}

int8_t _sleep(const uint32_t sleepingMS, const bool smartSleep, const uint8_t interrupt1,
const uint8_t mode1, const uint8_t interrupt2, const uint8_t mode2)
{
CORE_DEBUG(PSTR("MCO:SLP:MS=%" PRIu32 ",SMS=%" PRIu8 ",I1=%" PRIu8 ",M1=%" PRIu8 ",I2=%" PRIu8
",M2=%" PRIu8 "\n"), sleepingMS, smartSleep,
interrupt1, mode1, interrupt2, mode2);
// repeater feature: sleeping not possible
#if defined(MY_REPEATER_FEATURE)
(void)smartSleep;
(void)interrupt1;
(void)mode1;
(void)interrupt2;
(void)mode2;

CORE_DEBUG(PSTR("!MCO:SLP:REP\n")); // sleeping not possible, repeater feature enabled
wait(sleepingMS);
return MY_SLEEP_NOT_POSSIBLE;
#else
uint32_t sleepingTimeMS = sleepingMS;
#if defined(MY_SENSOR_NETWORK)
// Do not sleep if transport not ready
if (!isTransportReady()) {
CORE_DEBUG(PSTR("!MCO:SLP:TNR\n")); // sleeping not possible, transport not ready
const uint32_t sleepEnterMS = hwMillis();
uint32_t sleepDeltaMS = 0;
while (!isTransportReady() && (sleepDeltaMS < sleepingTimeMS) &&
(sleepDeltaMS < MY_SLEEP_TRANSPORT_RECONNECT_TIMEOUT_MS)) {
_process();
sleepDeltaMS = hwMillis() - sleepEnterMS;
}
// sleep remainder
if (sleepDeltaMS < sleepingTimeMS) {
sleepingTimeMS -= sleepDeltaMS; // calculate remaining sleeping time
CORE_DEBUG(PSTR("MCO:SLP:MS=%" PRIu32 "\n"), sleepingTimeMS);
} else {
// no sleeping time left
return MY_SLEEP_NOT_POSSIBLE;
}
}
// OTA FW feature: do not sleep if FW update ongoing
#if defined(MY_OTA_FIRMWARE_FEATURE)
while (isFirmwareUpdateOngoing() && sleepingTimeMS) {
CORE_DEBUG(PSTR("!MCO:SLP:FWUPD\n")); // sleeping not possible, FW update ongoing
wait(1000ul);
sleepingTimeMS = sleepingTimeMS >= 1000ul ? sleepingTimeMS - 1000ul : 1000ul;
}
#endif // MY_OTA_FIRMWARE_FEATURE
if (smartSleep) {
// sleeping time left?
if (sleepingTimeMS > 0 && sleepingTimeMS < ((uint32_t)MY_SMART_SLEEP_WAIT_DURATION_MS)) {
wait(sleepingMS);
CORE_DEBUG(PSTR("!MCO:SLP:NTL\n")); // sleeping not possible, no time left
return MY_SLEEP_NOT_POSSIBLE;
}
// notify controller about going to sleep, payload indicates smartsleep waiting time in MS
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL,
I_PRE_SLEEP_NOTIFICATION).set((uint32_t)MY_SMART_SLEEP_WAIT_DURATION_MS));
wait(MY_SMART_SLEEP_WAIT_DURATION_MS); // listen for incoming messages
#if defined(MY_OTA_FIRMWARE_FEATURE)
// check if during smart sleep waiting period a FOTA request was received
if (isFirmwareUpdateOngoing()) {
CORE_DEBUG(PSTR("!MCO:SLP:FWUPD\n")); // sleeping not possible, FW update ongoing
return MY_SLEEP_NOT_POSSIBLE;
}
#endif // MY_OTA_FIRMWARE_FEATURE
}
#else
(void)smartSleep;
#endif // MY_SENSOR_NETWORK

#if defined(MY_SENSOR_NETWORK)
transportDisable();
#endif
setIndication(INDICATION_SLEEP);

#if defined (MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN)
// Wait until leds finish their blinking pattern
while (ledsBlinking()) {
doYield();
}
#endif

int8_t result = MY_SLEEP_NOT_POSSIBLE; // default
if (interrupt1 != INTERRUPT_NOT_DEFINED && interrupt2 != INTERRUPT_NOT_DEFINED) {
// both IRQs
result = hwSleep(interrupt1, mode1, interrupt2, mode2, sleepingTimeMS);
} else if (interrupt1 != INTERRUPT_NOT_DEFINED && interrupt2 == INTERRUPT_NOT_DEFINED) {
// one IRQ
result = hwSleep(interrupt1, mode1, sleepingTimeMS);
} else if (interrupt1 == INTERRUPT_NOT_DEFINED && interrupt2 == INTERRUPT_NOT_DEFINED) {
// no IRQ
result = hwSleep(sleepingTimeMS);
}
setIndication(INDICATION_WAKEUP);
CORE_DEBUG(PSTR("MCO:SLP:WUP=%" PRIi8 "\n"), result); // sleep wake-up
#if defined(MY_SENSOR_NETWORK)
transportReInitialise();
#endif
if (smartSleep) {
// notify controller about waking up, payload indicates sleeping time in MS
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL,
I_POST_SLEEP_NOTIFICATION).set(sleepingTimeMS));
}
return result;
#endif
}

// sleep functions
int8_t sleep(const uint32_t sleepingMS, const bool smartSleep)
{
return _sleep(sleepingMS, smartSleep);
}

int8_t sleep(const uint8_t interrupt, const uint8_t mode, const uint32_t sleepingMS,
const bool smartSleep)
{
return _sleep(sleepingMS, smartSleep, interrupt, mode);
}

int8_t sleep(const uint8_t interrupt1, const uint8_t mode1, const uint8_t interrupt2,
const uint8_t mode2, const uint32_t sleepingMS, const bool smartSleep)
{
return _sleep(sleepingMS, smartSleep, interrupt1, mode1, interrupt2, mode2);
}

// deprecated smartSleep() functions
int8_t smartSleep(const uint32_t sleepingMS)
{
// compatibility
return _sleep(sleepingMS, true);
}

int8_t smartSleep(const uint8_t interrupt, const uint8_t mode, const uint32_t sleepingMS)
{
// compatibility
return _sleep(sleepingMS, true, interrupt, mode);
}

int8_t smartSleep(const uint8_t interrupt1, const uint8_t mode1, const uint8_t interrupt2,
const uint8_t mode2, const uint32_t sleepingMS)
{
// compatibility
return _sleep(sleepingMS, true, interrupt1, mode1, interrupt2, mode2);
}



void _nodeLock(const char* str)
{
#ifdef MY_NODE_LOCK_FEATURE
// Make sure EEPROM is updated to locked status
hwWriteConfig(EEPROM_NODE_LOCK_COUNTER_ADDRESS, 0);
while (1) {
setIndication(INDICATION_ERR_LOCKED);
CORE_DEBUG(PSTR("MCO:NLK:NODE LOCKED. TO UNLOCK, GND PIN %" PRIu8 " AND RESET\n"),
MY_NODE_UNLOCK_PIN);
doYield();
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID,C_INTERNAL, I_LOCKED).set(str));
#if defined(MY_SENSOR_NETWORK)
transportSleep();
CORE_DEBUG(PSTR("MCO:NLK:TSL\n")); // sleep transport
#endif
setIndication(INDICATION_SLEEP);
(void)hwSleep((uint32_t)1000*60*30); // Sleep for 30 min before resending LOCKED message
setIndication(INDICATION_WAKEUP);
}
#else
(void)str;
#endif
}

void _checkNodeLock(void)
{
#ifdef MY_NODE_LOCK_FEATURE
// Check if node has been locked down
if (hwReadConfig(EEPROM_NODE_LOCK_COUNTER_ADDRESS) == 0) {
// Node is locked, check if unlock pin is asserted, else hang the node
hwPinMode(MY_NODE_UNLOCK_PIN, INPUT_PULLUP);
// Make a short delay so we are sure any large external nets are fully pulled
uint32_t enter = hwMillis();
while (hwMillis() - enter < 2) {}
if (hwDigitalRead(MY_NODE_UNLOCK_PIN) == 0) {
// Pin is grounded, reset lock counter
hwWriteConfig(EEPROM_NODE_LOCK_COUNTER_ADDRESS, MY_NODE_LOCK_COUNTER_MAX);
// Disable pullup
hwPinMode(MY_NODE_UNLOCK_PIN, INPUT);
setIndication(INDICATION_ERR_LOCKED);
CORE_DEBUG(PSTR("MCO:BGN:NODE UNLOCKED\n"));
} else {
// Disable pullup
hwPinMode(MY_NODE_UNLOCK_PIN, INPUT);
_nodeLock("LDB"); //Locked during boot
}
} else if (hwReadConfig(EEPROM_NODE_LOCK_COUNTER_ADDRESS) == 0xFF) {
// Reset value
hwWriteConfig(EEPROM_NODE_LOCK_COUNTER_ADDRESS, MY_NODE_LOCK_COUNTER_MAX);
}
#endif
}
#if DOXYGEN

#endif

+ 469
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySensorsCore.h View File

@@ -0,0 +1,469 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

/**
* @file MySensorsCore.h
*
* @defgroup MySensorsCoregrp MySensorsCore
* @ingroup internals
* @{
*
* MySensorsCore-related log messages, format: [!]SYSTEM:[SUB SYSTEM:]MESSAGE
* - [!] Exclamation mark is prepended in case of error or warning
* - SYSTEM:
* - <b>MCO</b> messages emitted by MySensorsCore
* - SUB SYSTEMS:
* - MCO:<b>BGN</b> from @ref _begin()
* - MCO:<b>REG</b> from @ref _registerNode()
* - MCO:<b>SND</b> from @ref send()
* - MCO:<b>PIM</b> from @ref _processInternalCoreMessage()
* - MCO:<b>NLK</b> from @ref _nodeLock()
*
* MySensorsCore debug log messages:
*
* |E| SYS | SUB | Message | Comment
* |-|-----|-----|---------------------------------------------|--------------------------------------------------------------------------------------------------
* |!| MCO | BGN | HW ERR | Error HW initialization (e.g. ext. EEPROM)
* | | MCO | BGN | INIT %%s,CP=%%s,REL=%%d,VER=%%s (%%d) | Core initialization, capabilities (CP), release number (REL), library version (VER)
* | | MCO | BGN | BFR | Callback before()
* | | MCO | BGN | STP | Callback setup()
* | | MCO | BGN | INIT OK,TSP=%%d | Core initialised, transport status (TSP): 0=not initialised, 1=initialised, NA=not available
* | | MCO | BGN | NODE UNLOCKED | Node successfully unlocked (see signing chapter)
* |!| MCO | BGN | TSP FAIL | Transport initialization failed
* | | MCO | REG | REQ | Registration request
* | | MCO | REG | NOT NEEDED | No registration needed (i.e. GW)
* |!| MCO | SND | NODE NOT REG | Node is not registered, cannot send message
* | | MCO | PIM | NODE REG=%%d | Registration response received, registration status (REG)
* | | MCO | SLP | MS=%%lu,SMS=%%d,I1=%%d,M1=%%d,I2=%%d,M2=%%d | Sleep node, time (MS), smartSleep (SMS), Int1/M1, Int2/M2
* | | MCO | SLP | WUP=%%d | Node woke-up, reason/IRQ (WUP)
* |!| MCO | SLP | NTL | Sleeping not possible, no time left
* |!| MCO | SLP | FWUPD | Sleeping not possible, FW update ongoing
* |!| MCO | SLP | REP | Sleeping not possible, repeater feature enabled
* |!| MCO | SLP | TNR | Transport not ready, attempt to reconnect until timeout (MY_SLEEP_TRANSPORT_RECONNECT_TIMEOUT_MS)
* | | MCO | NLK | NODE LOCKED. UNLOCK: GND PIN %%d AND RESET | Node locked during booting, see signing chapter for additional information
* | | MCO | NLK | TSL | Set transport to sleep
*
*
* @brief API declaration for MySensorsCore
*/


#ifndef MySensorsCore_h
#define MySensorsCore_h

#include "Version.h" // Auto generated by bot
#include "MyConfig.h"
#include "MyEepromAddresses.h"
#include "MyMessage.h"
#include <stddef.h>
#include <stdarg.h>

#define GATEWAY_ADDRESS ((uint8_t)0) //!< Node ID for GW sketch
#define NODE_SENSOR_ID ((uint8_t)255) //!< Node child is always created/presented when a node is started
#define MY_CORE_VERSION ((uint8_t)2) //!< core version
#define MY_CORE_MIN_VERSION ((uint8_t)2) //!< min core version required for compatibility

#define MY_WAKE_UP_BY_TIMER ((int8_t)-1) //!< Sleeping wake up by timer
#define MY_SLEEP_NOT_POSSIBLE ((int8_t)-2) //!< Sleeping not possible
#define INTERRUPT_NOT_DEFINED ((uint8_t)255) //!< _sleep() param: no interrupt defined
#define MODE_NOT_DEFINED ((uint8_t)255) //!< _sleep() param: no mode defined
#define VALUE_NOT_DEFINED ((uint8_t)255) //!< Value not defined
#define FUNCTION_NOT_SUPPORTED ((uint16_t)0) //!< Function not supported

/**
* @brief Controller configuration
*
* This structure stores controller-related configurations
*/
typedef struct {
uint8_t isMetric; //!< Flag indicating if metric or imperial measurements are used
} controllerConfig_t;

/**
* @brief Node core configuration
*/
typedef struct {
controllerConfig_t controllerConfig; //!< Controller config
// 8 bit
bool nodeRegistered : 1; //!< Flag node registered
bool presentationSent : 1; //!< Flag presentation sent
uint8_t reserved : 6; //!< reserved
} coreConfig_t;


// **** public functions ********

/**
* Return this nodes id.
*/
uint8_t getNodeId(void);

/**
* Return the parent node id.
*/
uint8_t getParentNodeId(void);

/**
* Sends node information to the gateway.
*/
void presentNode(void);

/**
* Each node must present all attached sensors before any values can be handled correctly by the controller.
* It is usually good to present all attached sensors after power-up in setup().
*
* @param sensorId Select a unique sensor id for this sensor. Choose a number between 0-254.
* @param sensorType The sensor type. See sensor typedef in MyMessage.h.
* @param description A textual description of the sensor.
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
* @param description A textual description of the sensor.
* @return true Returns true if message reached the first stop on its way to destination.
*/
bool present(const uint8_t sensorId, const uint8_t sensorType, const char *description="",
const bool ack = false);
#if !defined(__linux__)
bool present(const uint8_t childSensorId, const uint8_t sensorType,
const __FlashStringHelper *description,
const bool ack = false);
#endif
/**
* Sends sketch meta information to the gateway. Not mandatory but a nice thing to do.
* @param name String containing a short Sketch name or NULL if not applicable
* @param version String containing a short Sketch version or NULL if not applicable
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
* @return true Returns true if message reached the first stop on its way to destination.
*/
bool sendSketchInfo(const char *name, const char *version, const bool ack = false);
#if !defined(__linux__)
bool sendSketchInfo(const __FlashStringHelper *name, const __FlashStringHelper *version,
const bool ack = false);
#endif

/**
* Sends a message to gateway or one of the other nodes in the radio network
* @param msg Message to send
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
* @return true Returns true if message reached the first stop on its way to destination.
*/
bool send(MyMessage &msg, const bool ack = false);

/**
* Send this nodes battery level to gateway.
* @param level Level between 0-100(%)
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
* @return true Returns true if message reached the first stop on its way to destination.
*/
bool sendBatteryLevel(const uint8_t level, const bool ack = false);

/**
* Send a heartbeat message (I'm alive!) to the gateway/controller.
* The payload will be an incremental 16 bit integer value starting at 1 when sensor is powered on.
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
* @return true Returns true if message reached the first stop on its way to destination.
*/
bool sendHeartbeat(const bool ack = false);

/**
* Send this nodes signal strength to gateway.
* @param level Signal strength can be RSSI if the radio provide it, or another kind of calculation
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
* @return true Returns true if message reached the first stop on its way to destination.
*/
bool sendSignalStrength(const int16_t level, const bool ack = false);

/**
* Send this nodes TX power level to gateway.
* @param level For instance, can be TX power level in dbm
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
* @return true Returns true if message reached the first stop on its way to destination.
*/
bool sendTXPowerLevel(const uint8_t level, const bool ack = false);

/**
* Requests a value from gateway or some other sensor in the radio network.
* Make sure to add callback-method in begin-method to handle request responses.
*
* @param childSensorId The unique child id for the different sensors connected to this Arduino. 0-254.
* @param variableType The variableType to fetch
* @param destination The nodeId of other node in radio network. Default is gateway
* @return true Returns true if message reached the first stop on its way to destination.
*/
bool request(const uint8_t childSensorId, const uint8_t variableType,
const uint8_t destination = GATEWAY_ADDRESS);

/**
* Requests time from controller. Answer will be delivered to receiveTime function in sketch.
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
* @return true Returns true if message reached the first stop on its way to destination.
*/
bool requestTime(const bool ack = false);

/**
* Returns the most recent node configuration received from controller
*/
controllerConfig_t getControllerConfig(void);

/**
* Save a state (in local EEPROM). Good for actuators to "remember" state between
* power cycles.
*
* You have 256 bytes to play with. Note that there is a limitation on the number
* of writes the EEPROM can handle (~100 000 cycles on ATMega328).
*
* @param pos The position to store value in (0-255)
* @param value to store in position
*/
void saveState(const uint8_t pos, const uint8_t value);

/**
* Load a state (from local EEPROM).
*
* @param pos The position to fetch value from (0-255)
* @return Value to store in position
*/
uint8_t loadState(const uint8_t pos);

/**
* Wait for a specified amount of time to pass. Keeps process()ing.
* This does not power-down the radio nor the Arduino.
* Because this calls process() in a loop, it is a good way to wait
* in your loop() on a repeater node or sensor that listens to messages.
* @param waitingMS Number of milliseconds to wait.
*/
void wait(const uint32_t waitingMS);

/**
* Wait for a specified amount of time to pass or until specified message received. Keeps process()ing.
* This does not power-down the radio nor the Arduino.
* Because this calls process() in a loop, it is a good way to wait
* in your loop() on a repeater node or sensor that listens to messages.
* @param waitingMS Number of milliseconds to wait.
* @param cmd Command of incoming message.
* @param msgtype Message type.
* @return True if specified message received
*/
bool wait(const uint32_t waitingMS, const uint8_t cmd, const uint8_t msgtype);

/**
* Function to allow scheduler to do some work.
* @remark Internally it will call yield, kick the watchdog and update led states.
*/
void doYield(void);


/**
* Sleep (PowerDownMode) the MCU and radio. Wake up on timer.
* @param sleepingMS Number of milliseconds to sleep.
* @param smartSleep Set True if sending heartbeat and process incoming messages before going to sleep.
* @return @ref MY_WAKE_UP_BY_TIMER if timer woke it up, @ref MY_SLEEP_NOT_POSSIBLE if not possible (e.g. ongoing FW update)
*/
int8_t sleep(const uint32_t sleepingMS, const bool smartSleep = false);

/**
* Sleep (PowerDownMode) the MCU and radio. Wake up on timer or pin change.
* See: http://arduino.cc/en/Reference/attachInterrupt for details on modes and which pin
* is assigned to what interrupt. On Nano/Pro Mini: 0=Pin2, 1=Pin3
* @param interrupt Interrupt that should trigger the wakeup
* @param mode RISING, FALLING, CHANGE
* @param sleepingMS Number of milliseconds to sleep or 0 to sleep forever
* @param smartSleep Set True if sending heartbeat and process incoming messages before going to sleep
* @return Interrupt number if wake up was triggered by pin change, @ref MY_WAKE_UP_BY_TIMER if wake up was triggered by timer, @ref MY_SLEEP_NOT_POSSIBLE if sleep was not possible (e.g. ongoing FW update)
*/
int8_t sleep(const uint8_t interrupt, const uint8_t mode, const uint32_t sleepingMS = 0,
const bool smartSleep = false);

/**
* Sleep (PowerDownMode) the MCU and radio. Wake up on timer or pin change for two separate interrupts.
* See: http://arduino.cc/en/Reference/attachInterrupt for details on modes and which pin
* is assigned to what interrupt. On Nano/Pro Mini: 0=Pin2, 1=Pin3
* @param interrupt1 First interrupt that should trigger the wakeup
* @param mode1 Mode for first interrupt (RISING, FALLING, CHANGE)
* @param interrupt2 Second interrupt that should trigger the wakeup
* @param mode2 Mode for second interrupt (RISING, FALLING, CHANGE)
* @param sleepingMS Number of milliseconds to sleep or 0 to sleep forever
* @param smartSleep Set True if sending heartbeat and process incoming messages before going to sleep.
* @return Interrupt number if wake up was triggered by pin change, @ref MY_WAKE_UP_BY_TIMER if wake up was triggered by timer, @ref MY_SLEEP_NOT_POSSIBLE if sleep was not possible (e.g. ongoing FW update)
*/
int8_t sleep(const uint8_t interrupt1, const uint8_t mode1, const uint8_t interrupt2,
const uint8_t mode2, const uint32_t sleepingMS = 0, const bool smartSleep = false);

/**
* \deprecated Use sleep(ms, true) instead
* Same as sleep(), send heartbeat and process incoming messages before going to sleep.
* Specify the time to wait for incoming messages by defining MY_SMART_SLEEP_WAIT_DURATION to a time (ms).
* @param sleepingMS Number of milliseconds to sleep.
* @return @ref MY_WAKE_UP_BY_TIMER if timer woke it up, @ref MY_SLEEP_NOT_POSSIBLE if not possible (e.g. ongoing FW update)
*/
int8_t smartSleep(const uint32_t sleepingMS);

/**
* \deprecated Use sleep(interrupt, mode, ms, true) instead
* Same as sleep(), send heartbeat and process incoming messages before going to sleep.
* Specify the time to wait for incoming messages by defining MY_SMART_SLEEP_WAIT_DURATION to a time (ms).
* @param interrupt Interrupt that should trigger the wakeup
* @param mode RISING, FALLING, CHANGE
* @param sleepingMS Number of milliseconds to sleep or 0 to sleep forever
* @return Interrupt number if wake up was triggered by pin change, @ref MY_WAKE_UP_BY_TIMER if wake up was triggered by timer, @ref MY_SLEEP_NOT_POSSIBLE if sleep was not possible (e.g. ongoing FW update)
*/
int8_t smartSleep(const uint8_t interrupt, const uint8_t mode, const uint32_t sleepingMS = 0);

/**
* \deprecated Use sleep(interrupt1, mode1, interrupt2, mode2, ms, true) instead
* Same as sleep(), send heartbeat and process incoming messages before going to sleep.
* Specify the time to wait for incoming messages by defining MY_SMART_SLEEP_WAIT_DURATION to a time (ms).
* @param interrupt1 First interrupt that should trigger the wakeup
* @param mode1 Mode for first interrupt (RISING, FALLING, CHANGE)
* @param interrupt2 Second interrupt that should trigger the wakeup
* @param mode2 Mode for second interrupt (RISING, FALLING, CHANGE)
* @param sleepingMS Number of milliseconds to sleep or 0 to sleep forever
* @return Interrupt number if wake up was triggered by pin change, @ref MY_WAKE_UP_BY_TIMER if wake up was triggered by timer, @ref MY_SLEEP_NOT_POSSIBLE if sleep was not possible (e.g. ongoing FW update)
*/
int8_t smartSleep(const uint8_t interrupt1, const uint8_t mode1, const uint8_t interrupt2,
const uint8_t mode2, const uint32_t sleepingMS = 0);

/**
* Sleep (PowerDownMode) the MCU and radio. Wake up on timer or pin change for two separate interrupts.
* See: http://arduino.cc/en/Reference/attachInterrupt for details on modes and which pin
* is assigned to what interrupt. On Nano/Pro Mini: 0=Pin2, 1=Pin3
* @param sleepingMS Number of milliseconds to sleep or 0 to sleep forever
* @param interrupt1 (optional) First interrupt that should trigger the wakeup
* @param mode1 (optional) Mode for first interrupt (RISING, FALLING, CHANGE)
* @param interrupt2 (optional) Second interrupt that should trigger the wakeup
* @param mode2 (optional) Mode for second interrupt (RISING, FALLING, CHANGE)
* @param smartSleep (optional) Set True if sending heartbeat and process incoming messages before going to sleep.
* @return Interrupt number if wake up was triggered by pin change, @ref MY_WAKE_UP_BY_TIMER if wake up was triggered by timer, @ref MY_SLEEP_NOT_POSSIBLE if sleep was not possible (e.g. ongoing FW update)
*/
int8_t _sleep(const uint32_t sleepingMS, const bool smartSleep = false,
const uint8_t interrupt1 = INTERRUPT_NOT_DEFINED, const uint8_t mode1 = MODE_NOT_DEFINED,
const uint8_t interrupt2 = INTERRUPT_NOT_DEFINED, const uint8_t mode2 = MODE_NOT_DEFINED);


// **** private functions ********

/**
* @defgroup MyLockgrp MyNodeLock
* @ingroup internals
* @brief API declaration for MyNodeLock
* @{
*/
/**
* @brief Lock a node and transmit provided message with 30m intervals
*
* This function is called if suspicious activity has exceeded the threshold (see
* @ref MY_NODE_LOCK_COUNTER_MAX). Unlocking with a normal Arduino bootloader require erasing the EEPROM
* while unlocking with a custom bootloader require holding @ref MY_NODE_UNLOCK_PIN low during power on/reset.
*
* @param str The string to transmit.
*/
void _nodeLock(const char* str);

/**
* @brief Check node lock status and prevent node execution if locked.
*/
void _checkNodeLock(void);
/** @}*/ // Node lock group

/**
* @brief Node initialisation
*/
void _begin(void);
/**
* @brief Main framework process
*/
void _process(void);
/**
* @brief Processes internal core message
* @return True if no further processing required
*/
bool _processInternalCoreMessage(void);
/**
* @brief Puts node to a infinite loop if unrecoverable situation detected
*/
void _infiniteLoop(void);
/**
* @brief Handles registration request
*/
void _registerNode(void);
/**
* @brief Sends message according to routing table
* @param message
* @return true Returns true if message reached the first stop on its way to destination.
*/
bool _sendRoute(MyMessage &message);

/**
* @brief Callback for incoming messages
* @param message
*/
void receive(const MyMessage &message) __attribute__((weak));
/**
* @brief Callback for incoming time messages
*/
void receiveTime(uint32_t) __attribute__((weak));
/**
* @brief Node presentation
*/
void presentation(void) __attribute__((weak));
/**
* @brief Called before node initialises
*/
void before(void) __attribute__((weak));
/**
* @brief Called before any hwInitialization is done
*/
void preHwInit(void) __attribute__((weak));
/**
* @brief Called after node initialises but before main loop
*/
void setup(void) __attribute__((weak));
/**
* @brief Main loop
*/
void loop(void) __attribute__((weak));


// Inline function and macros
static inline MyMessage& build(MyMessage &msg, const uint8_t destination, const uint8_t sensor,
const uint8_t command, const uint8_t type, const bool ack = false)
{
msg.sender = getNodeId();
msg.destination = destination;
msg.sensor = sensor;
msg.type = type;
mSetCommand(msg,command);
mSetRequestAck(msg,ack);
mSetAck(msg,false);
return msg;
}

static inline MyMessage& buildGw(MyMessage &msg, const uint8_t type)
{
msg.sender = GATEWAY_ADDRESS;
msg.destination = GATEWAY_ADDRESS;
msg.sensor = NODE_SENSOR_ID;
msg.type = type;
mSetCommand(msg, C_INTERNAL);
mSetRequestAck(msg, false);
mSetAck(msg, false);
return msg;
}

#endif

/** @}*/

+ 585
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySigning.cpp View File

@@ -0,0 +1,585 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#include "MySigning.h"

#define SIGNING_PRESENTATION_VERSION_1 1
#define SIGNING_PRESENTATION_REQUIRE_SIGNATURES (1 << 0)
#define SIGNING_PRESENTATION_REQUIRE_WHITELISTING (1 << 1)

#if defined(MY_DEBUG_VERBOSE_SIGNING)
#define SIGN_DEBUG(x,...) DEBUG_OUTPUT(x, ##__VA_ARGS__)
#else
#define SIGN_DEBUG(x,...)
#endif

#if defined(MY_SIGNING_REQUEST_SIGNATURES) &&\
(!defined(MY_SIGNING_ATSHA204) && !defined(MY_SIGNING_SOFT))
#error You have to pick either MY_SIGNING_ATSHA204 or MY_SIGNING_SOFT to reqire signatures!
#endif
#if defined(MY_SIGNING_SOFT) && defined(MY_SIGNING_ATSHA204)
#error You have to pick one and only one signing backend
#endif
#ifdef MY_SIGNING_FEATURE
static uint8_t _doSign[32]; // Bitfield indicating which sensors require signed communication
static uint8_t _doWhitelist[32]; // Bitfield indicating which sensors require salted signatures
static MyMessage _msgSign; // Buffer for message to sign.
static uint8_t _signingNonceStatus;
static bool stateValid = false;

#ifdef MY_NODE_LOCK_FEATURE
static uint8_t nof_nonce_requests = 0;
static uint8_t nof_failed_verifications = 0;
#endif

// Status when waiting for signing nonce in signerSignMsg
enum { SIGN_WAITING_FOR_NONCE = 0, SIGN_OK = 1 };

// Macros for manipulating signing requirement tables
#define DO_SIGN(node) (~_doSign[node>>3]&(1<<node%8))
#define SET_SIGN(node) (_doSign[node>>3]&=~(1<<node%8))
#if defined(MY_SIGNING_WEAK_SECURITY)
#define CLEAR_SIGN(node) (_doSign[node>>3]|=(1<<node%8))
#endif
#define DO_WHITELIST(node) (~_doWhitelist[node>>3]&(1<<node%8))
#define SET_WHITELIST(node) (_doWhitelist[node>>3]&=~(1<<node%8))
#if defined(MY_SIGNING_WEAK_SECURITY)
#define CLEAR_WHITELIST(node) (_doWhitelist[node>>3]|=(1<<node%8))
#endif

#if defined(MY_SIGNING_SOFT)
extern bool signerAtsha204SoftInit(void);
extern bool signerAtsha204SoftCheckTimer(void);
extern bool signerAtsha204SoftGetNonce(MyMessage &msg);
extern void signerAtsha204SoftPutNonce(MyMessage &msg);
extern bool signerAtsha204SoftVerifyMsg(MyMessage &msg);
extern bool signerAtsha204SoftSignMsg(MyMessage &msg);
#define signerBackendInit signerAtsha204SoftInit
#define signerBackendCheckTimer signerAtsha204SoftCheckTimer
#define signerBackendGetNonce signerAtsha204SoftGetNonce
#define signerBackendPutNonce signerAtsha204SoftPutNonce
#define signerBackendVerifyMsg signerAtsha204SoftVerifyMsg
#define signerBackendSignMsg signerAtsha204SoftSignMsg
#elif defined(MY_SIGNING_ATSHA204)
extern bool signerAtsha204Init(void);
extern bool signerAtsha204CheckTimer(void);
extern bool signerAtsha204GetNonce(MyMessage &msg);
extern void signerAtsha204PutNonce(MyMessage &msg);
extern bool signerAtsha204VerifyMsg(MyMessage &msg);
extern bool signerAtsha204SignMsg(MyMessage &msg);
#define signerBackendInit signerAtsha204Init
#define signerBackendCheckTimer signerAtsha204CheckTimer
#define signerBackendGetNonce signerAtsha204GetNonce
#define signerBackendPutNonce signerAtsha204PutNonce
#define signerBackendVerifyMsg signerAtsha204VerifyMsg
#define signerBackendSignMsg signerAtsha204SignMsg
#endif
static bool skipSign(MyMessage &msg);
#else // not MY_SIGNING_FEATURE
#define signerBackendCheckTimer() true
#endif // MY_SIGNING_FEATURE
static void prepareSigningPresentation(MyMessage &msg, uint8_t destination);
static bool signerInternalProcessPresentation(MyMessage &msg);
static bool signerInternalProcessNonceRequest(MyMessage &msg);
static bool signerInternalProcessNonceResponse(MyMessage &msg);
#if (defined(MY_ENCRYPTION_FEATURE) || defined(MY_SIGNING_FEATURE)) &&\
!defined(MY_SIGNING_SIMPLE_PASSWD)
static bool signerInternalValidatePersonalization(void);
#endif

void signerInit(void)
{
#if defined(MY_SIGNING_FEATURE)
stateValid = true;
#endif
#if (defined (MY_ENCRYPTION_FEATURE) || defined (MY_SIGNING_FEATURE)) &&\
!defined (MY_SIGNING_SIMPLE_PASSWD)
// Suppress this warning since it is only fixed on Linux builds and this keeps the code more tidy
// cppcheck-suppress knownConditionTrueFalse
if (!signerInternalValidatePersonalization()) {
SIGN_DEBUG(PSTR("!SGN:PER:TAMPERED\n"));
#if defined(MY_SIGNING_FEATURE)
stateValid = false;
#endif
} else {
SIGN_DEBUG(PSTR("SGN:PER:OK\n"));
}
#endif
#if defined(MY_SIGNING_FEATURE)
// Read out the signing requirements from EEPROM
hwReadConfigBlock((void*)_doSign, (void*)EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS,
sizeof(_doSign));

// Read out the whitelist requirements from EEPROM
hwReadConfigBlock((void*)_doWhitelist, (void*)EEPROM_WHITELIST_REQUIREMENT_TABLE_ADDRESS,
sizeof(_doWhitelist));

if (!signerBackendInit()) {
SIGN_DEBUG(PSTR("!SGN:INI:BND FAIL\n"));
} else {
SIGN_DEBUG(PSTR("SGN:INI:BND OK\n"));
}
#endif
}

void signerPresentation(MyMessage &msg, uint8_t destination)
{
prepareSigningPresentation(msg, destination);

#if defined(MY_SIGNING_REQUEST_SIGNATURES)
msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_SIGNATURES;
SIGN_DEBUG(PSTR("SGN:PRE:SGN REQ\n")); // Signing required
#else
SIGN_DEBUG(PSTR("SGN:PRE:SGN NREQ\n")); // Signing not required
#endif
#if defined(MY_SIGNING_NODE_WHITELISTING)
msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_WHITELISTING;
SIGN_DEBUG(PSTR("SGN:PRE:WHI REQ\n")); // Whitelisting required
#else
SIGN_DEBUG(PSTR("SGN:PRE:WHI NREQ\n")); // Whitelisting not required
#endif

if (!_sendRoute(msg)) {
SIGN_DEBUG(PSTR("!SGN:PRE:XMT,TO=%" PRIu8 " FAIL\n"),
destination); // Failed to transmit presentation!
} else {
SIGN_DEBUG(PSTR("SGN:PRE:XMT,TO=%" PRIu8 "\n"), destination); // Transmitted signing presentation!
}

if (destination == GATEWAY_ADDRESS) {
SIGN_DEBUG(PSTR("SGN:PRE:WAIT GW\n")); // Waiting for GW to send signing preferences...
wait(2000, C_INTERNAL, I_SIGNING_PRESENTATION);
}
}

bool signerProcessInternal(MyMessage &msg)
{
bool ret;
switch (msg.type) {
case I_SIGNING_PRESENTATION:
ret = signerInternalProcessPresentation(msg);
break;
case I_NONCE_REQUEST:
ret = signerInternalProcessNonceRequest(msg);
break;
case I_NONCE_RESPONSE:
ret = signerInternalProcessNonceResponse(msg);
break;
default:
ret = false; // Let the transport process this message further as it is not related to signing
break;
}
return ret;
}

bool signerCheckTimer(void)
{
return signerBackendCheckTimer();
}

bool signerSignMsg(MyMessage &msg)
{
bool ret;
#if defined(MY_SIGNING_FEATURE)
// If destination is known to require signed messages and we are the sender,
// sign this message unless it is identified as an exception
if (DO_SIGN(msg.destination) && msg.sender == getNodeId()) {
if (skipSign(msg)) {
ret = true;
} else {
// Before starting, validate that our state is good, or signing will fail
if (!stateValid) {
SIGN_DEBUG(PSTR("!SGN:SGN:STATE\n")); // Signing system is not in a valid state
ret = false;
} else {
// Send nonce-request
_signingNonceStatus=SIGN_WAITING_FOR_NONCE;
if (!_sendRoute(build(_msgSign, msg.destination, msg.sensor, C_INTERNAL,
I_NONCE_REQUEST).set(""))) {
SIGN_DEBUG(PSTR("!SGN:SGN:NCE REQ,TO=%" PRIu8 " FAIL\n"),
msg.destination); // Failed to transmit nonce request!
ret = false;
} else {
SIGN_DEBUG(PSTR("SGN:SGN:NCE REQ,TO=%" PRIu8 "\n"), msg.destination); // Nonce requested
// We have to wait for the nonce to arrive before we can sign our original message
// Other messages could come in-between. We trust _process() takes care of them
unsigned long enter = hwMillis();
_msgSign = msg; // Copy the message to sign since buffer might be touched in _process()
while (hwMillis() - enter < MY_VERIFICATION_TIMEOUT_MS &&
_signingNonceStatus==SIGN_WAITING_FOR_NONCE) {
_process();
}
if (hwMillis() - enter > MY_VERIFICATION_TIMEOUT_MS) {
SIGN_DEBUG(PSTR("!SGN:SGN:NCE TMO\n")); // Timeout waiting for nonce!
ret = false;
} else {
if (_signingNonceStatus == SIGN_OK) {
// process() received a nonce and signerProcessInternal successfully signed the message
msg = _msgSign; // Write the signed message back
SIGN_DEBUG(PSTR("SGN:SGN:SGN\n")); // Message to send has been signed
ret = true;
// After this point, only the 'last' member of the message structure is allowed to be
// altered if the message has been signed, or signature will become invalid and the
// message rejected by the receiver
} else {
SIGN_DEBUG(PSTR("!SGN:SGN:SGN FAIL\n")); // Message to send could not be signed!
ret = false;
}
}
}
}
}
} else if (getNodeId() == msg.sender) {
mSetSigned(msg, 0); // Message is not supposed to be signed, make sure it is marked unsigned
SIGN_DEBUG(PSTR("SGN:SGN:NREQ=%" PRIu8 "\n"),
msg.destination); // Do not sign message as it is not req
ret = true;
} else {
SIGN_DEBUG(PSTR("SGN:SGN:%" PRIu8 "!=%" PRIu8 " NUS\n"), msg.sender,
getNodeId()); // Will not sign message since it was from someone else
ret = true;
}
#else
(void)msg;
ret = true;
#endif // MY_SIGNING_FEATURE
return ret;
}

bool signerVerifyMsg(MyMessage &msg)
{
bool verificationResult = true;
// Before processing message, reject unsigned messages if signing is required and check signature
// (if it is signed and addressed to us)
// Note that we do not care at all about any signature found if we do not require signing
#if defined(MY_SIGNING_FEATURE) && defined(MY_SIGNING_REQUEST_SIGNATURES)
// If we are a node, or we are a gateway and the sender require signatures (or just a strict gw)
// and we are the destination...
#if defined(MY_SIGNING_WEAK_SECURITY)
if ((!MY_IS_GATEWAY || DO_SIGN(msg.sender)) && msg.destination == getNodeId()) {
#else
if (msg.destination == getNodeId()) {
#endif
// Internal messages of certain types are not verified
if (skipSign(msg)) {
verificationResult = true;
} else if (!mGetSigned(msg)) {
// Got unsigned message that should have been signed
SIGN_DEBUG(PSTR("!SGN:VER:NSG\n")); // Message is not signed, but it should have been!
verificationResult = false;
} else {
// Before starting, validate that our state is good, or signing will fail
if (!stateValid) {
SIGN_DEBUG(PSTR("!SGN:VER:STATE\n")); // Signing system is not in a valid state
verificationResult = false;
} else {
if (!signerBackendVerifyMsg(msg)) {
SIGN_DEBUG(PSTR("!SGN:VER:FAIL\n")); // Signature verification failed!
verificationResult = false;
} else {
SIGN_DEBUG(PSTR("SGN:VER:OK\n"));
}
}
#if defined(MY_NODE_LOCK_FEATURE)
if (verificationResult) {
// On successful verification, clear lock counters
nof_nonce_requests = 0;
nof_failed_verifications = 0;
} else {
nof_failed_verifications++;
SIGN_DEBUG(PSTR("SGN:VER:LEFT=%" PRIu8 "\n"), MY_NODE_LOCK_COUNTER_MAX-nof_failed_verifications);
if (nof_failed_verifications >= MY_NODE_LOCK_COUNTER_MAX) {
_nodeLock("TMFV"); // Too many failed verifications
}
}
#endif
mSetSigned(msg,0); // Clear the sign-flag now as verification is completed
}
}
#else
(void)msg;
#endif // MY_SIGNING_REQUEST_SIGNATURES
return verificationResult;
}

int signerMemcmp(const void* a, const void* b, size_t sz)
{
int retVal;
size_t i;
int done = 0;
const uint8_t* ptrA = (const uint8_t*)a;
const uint8_t* ptrB = (const uint8_t*)b;
for (i=0; i < sz; i++) {
if (ptrA[i] == ptrB[i]) {
if (done > 0) {
done = 1;
} else {
done = 0;
}
} else {
if (done > 0) {
done = 2;
} else {
done = 3;
}
}
}
if (done > 0) {
retVal = -1;
} else {
retVal = 0;
}
return retVal;
}

#if defined(MY_SIGNING_FEATURE)
// Helper function to centralize signing/verification exceptions
static bool skipSign(MyMessage &msg)
{
bool ret = false;
if (mGetAck(msg)) {
ret = true;
} else if (mGetCommand(msg) == C_INTERNAL &&
(msg.type == I_SIGNING_PRESENTATION ||
msg.type == I_REGISTRATION_REQUEST ||
msg.type == I_NONCE_REQUEST || msg.type == I_NONCE_RESPONSE ||
msg.type == I_ID_REQUEST || msg.type == I_ID_RESPONSE ||
msg.type == I_FIND_PARENT_REQUEST || msg.type == I_FIND_PARENT_RESPONSE ||
msg.type == I_HEARTBEAT_REQUEST || msg.type == I_HEARTBEAT_RESPONSE ||
msg.type == I_PING || msg.type == I_PONG ||
msg.type == I_DISCOVER_REQUEST || msg.type == I_DISCOVER_RESPONSE ||
msg.type == I_LOG_MESSAGE)) {
ret = true;
} else if (mGetCommand(msg) == C_STREAM &&
(msg.type == ST_SOUND ||
msg.type == ST_IMAGE ||
msg.type == ST_FIRMWARE_REQUEST || msg.type == ST_FIRMWARE_RESPONSE )) {
ret = true;
}
if (ret) {
SIGN_DEBUG(PSTR("SGN:SKP:%s CMD=%" PRIu8 ",TYPE=%" PRIu8 "\n"), mGetAck(msg) ? "ACK" : "MSG",
mGetCommand(msg),
msg.type); //Skip signing/verification of this message
}
return ret;
}
#endif

// Helper to prepare a signing presentation message
static void prepareSigningPresentation(MyMessage &msg, uint8_t destination)
{
// Only supports version 1 for now
(void)build(msg, destination, NODE_SENSOR_ID, C_INTERNAL, I_SIGNING_PRESENTATION).set("");
mSetLength(msg, 2);
mSetPayloadType(msg, P_CUSTOM); // displayed as hex
msg.data[0] = SIGNING_PRESENTATION_VERSION_1;
msg.data[1] = 0;
}

// Helper to process presentation messages
static bool signerInternalProcessPresentation(MyMessage &msg)
{
const uint8_t sender = msg.sender;
#if defined(MY_SIGNING_FEATURE)
if (msg.data[0] != SIGNING_PRESENTATION_VERSION_1) {
SIGN_DEBUG(PSTR("!SGN:PRE:VER=%" PRIu8 "\n"),
msg.data[0]); // Unsupported signing presentation version
return true; // Just drop this presentation message
}
// We only handle version 1 here...
if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_SIGNATURES) {
// We received an indicator that the sender require us to sign all messages we send to it
SIGN_DEBUG(PSTR("SGN:PRE:SGN REQ,FROM=%" PRIu8 "\n"), sender); // Node require signatures
SET_SIGN(sender);
} else {
#if defined(MY_SIGNING_WEAK_SECURITY)
// We received an indicator that the sender does not require us to sign messages we send to it
SIGN_DEBUG(PSTR("SGN:PRE:SGN NREQ,FROM=%" PRIu8 "\n"), sender); // Node does not require signatures
CLEAR_SIGN(sender);
#else
if (DO_SIGN(sender)) {
SIGN_DEBUG(PSTR("!SGN:PRE:SGN NREQ,FROM=%" PRIu8 " REJ\n"),
sender); // Node does not require signatures but used to do so
}
#endif
}
if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_WHITELISTING) {
// We received an indicator that the sender require us to salt signatures with serial
SIGN_DEBUG(PSTR("SGN:PRE:WHI REQ,FROM=%" PRIu8 "\n"), sender); // Node require whitelisting
SET_WHITELIST(sender);
} else {
#if defined(MY_SIGNING_WEAK_SECURITY)
// We received an indicator that the sender does not require us to sign messages we send to it
SIGN_DEBUG(PSTR("SGN:PRE:WHI NREQ,FROM=%" PRIu8 "\n"),
sender); // Node does not require whitelisting
CLEAR_WHITELIST(sender);
#else
if (DO_WHITELIST(sender)) {
SIGN_DEBUG(PSTR("!SGN:PRE:WHI NREQ,FROM=%" PRIu8 " REJ\n"),
sender); // Node does not require whitelisting but used to do so
}
#endif
}

// Save updated tables
hwWriteConfigBlock((void*)_doSign, (void*)EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS,
sizeof(_doSign));
hwWriteConfigBlock((void*)_doWhitelist, (void*)EEPROM_WHITELIST_REQUIREMENT_TABLE_ADDRESS,
sizeof(_doWhitelist));

// Inform sender about our preference if we are a gateway, but only require signing if the sender
// required signing unless we explicitly configure it to
#if defined(MY_GATEWAY_FEATURE)
prepareSigningPresentation(msg, sender);
#if defined(MY_SIGNING_REQUEST_SIGNATURES)
#if defined(MY_SIGNING_WEAK_SECURITY)
if (DO_SIGN(sender)) {
msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_SIGNATURES;
}
#else
msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_SIGNATURES;
#endif
#endif // MY_SIGNING_REQUEST_SIGNATURES
#if defined(MY_SIGNING_NODE_WHITELISTING)
msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_WHITELISTING;
#endif // MY_SIGNING_NODE_WHITELISTING
if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_SIGNATURES) {
SIGN_DEBUG(PSTR("SGN:PRE:SGN REQ,TO=%" PRIu8 "\n"),
sender); // Inform node that we require signatures
} else {
SIGN_DEBUG(PSTR("SGN:PRE:SGN NREQ,TO=%" PRIu8 "\n"),
sender); // Inform node that we do not require signatures
}
if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_WHITELISTING) {
SIGN_DEBUG(PSTR("SGN:PRE:WHI REQ,TO=%" PRIu8 "\n"),
sender); // Inform node that we require whitelisting
} else {
SIGN_DEBUG(PSTR("SGN:PRE:WHI NREQ,TO=%" PRIu8 "\n"),
sender); // Inform node that we do not require whitelisting
}
if (!_sendRoute(msg)) {
SIGN_DEBUG(PSTR("!SGN:PRE:XMT,TO=%" PRIu8 " FAIL\n"),
sender); // Failed to transmit signing presentation!
} else {
SIGN_DEBUG(PSTR("SGN:PRE:XMT,TO=%" PRIu8 "\n"), sender);
}
#endif // MY_GATEWAY_FEATURE
#else // not MY_SIGNING_FEATURE
#if defined(MY_GATEWAY_FEATURE)
// If we act as gateway and do not have the signing feature and receive a signing request we still
// need to do make sure the requester does not believe the gateway still require signatures
prepareSigningPresentation(msg, sender);
SIGN_DEBUG(PSTR("SGN:PRE:NSUP,TO=%" PRIu8 "\n"),
sender); // Informing node that we do not support signing
if (!_sendRoute(msg)) {
SIGN_DEBUG(PSTR("!SGN:PRE:XMT,TO=%" PRIu8 " FAIL\n"),
sender); // Failed to transmit signing presentation!
} else {
SIGN_DEBUG(PSTR("SGN:PRE:XMT,TO=%" PRIu8 "\n"), sender);
}
#else // not MY_GATEWAY_FEATURE
// If we act as a node and do not have the signing feature then we just silently drop any signing
// presentation messages received
(void)msg;
(void)sender;
// Received signing presentation, but signing is not supported (message ignored)
SIGN_DEBUG(
PSTR("SGN:PRE:NSUP\n"));
#endif // not MY_GATEWAY_FEATURE
#endif // not MY_SIGNING_FEATURE
return true; // No need to further process I_SIGNING_PRESENTATION
}

// Helper to process nonce request messages
static bool signerInternalProcessNonceRequest(MyMessage &msg)
{
#if defined(MY_SIGNING_FEATURE)
#if defined(MY_NODE_LOCK_FEATURE)
nof_nonce_requests++;
SIGN_DEBUG(PSTR("SGN:NCE:LEFT=%" PRIu8 "\n"),
MY_NODE_LOCK_COUNTER_MAX-nof_nonce_requests); // Nonce requests left until lockdown
if (nof_nonce_requests >= MY_NODE_LOCK_COUNTER_MAX) {
_nodeLock("TMNR"); // Too many nonces requested
}
#endif // MY_NODE_LOCK_FEATURE
if (signerBackendGetNonce(msg)) {
if (!_sendRoute(build(msg, msg.sender, NODE_SENSOR_ID, C_INTERNAL, I_NONCE_RESPONSE))) {
SIGN_DEBUG(PSTR("!SGN:NCE:XMT,TO=%" PRIu8 " FAIL\n"), msg.sender); // Failed to transmit nonce!
} else {
SIGN_DEBUG(PSTR("SGN:NCE:XMT,TO=%" PRIu8 "\n"), msg.sender);
}
} else {
SIGN_DEBUG(PSTR("!SGN:NCE:GEN\n")); // Failed to generate nonce!
}
#else // not MY_SIGNING_FEATURE
(void)msg;
SIGN_DEBUG(
PSTR("SGN:NCE:NSUP (DROPPED)\n")); // Received nonce request/response without signing support
#endif // MY_SIGNING_FEATURE
return true; // No need to further process I_NONCE_REQUEST
}

// Helper to process nonce response messages
static bool signerInternalProcessNonceResponse(MyMessage &msg)
{
#if defined(MY_SIGNING_FEATURE)
// Proceed with signing if nonce has been received
SIGN_DEBUG(PSTR("SGN:NCE:FROM=%" PRIu8 "\n"), msg.sender);
if (msg.sender != _msgSign.destination) {
SIGN_DEBUG(PSTR("SGN:NCE:%" PRIu8 "!=%" PRIu8 " (DROPPED)\n"), _msgSign.destination, msg.sender);
} else {
signerBackendPutNonce(msg);
if (signerBackendSignMsg(_msgSign)) {
// _msgSign now contains the signed message pending transmission
_signingNonceStatus = SIGN_OK;
}
}
#else
(void)msg;
SIGN_DEBUG(
PSTR("SGN:NCE:NSUP (DROPPED)\n")); // Received nonce request/response without signing support
#endif
return true; // No need to further process I_NONCE_RESPONSE
}

#if (defined(MY_ENCRYPTION_FEATURE) || defined(MY_SIGNING_FEATURE)) &&\
!defined(MY_SIGNING_SIMPLE_PASSWD)
static bool signerInternalValidatePersonalization(void)
{
#ifdef __linux__
// Personalization on linux is a bit more crude
return true;
#else
uint8_t buffer[SIZE_SIGNING_SOFT_HMAC_KEY + SIZE_RF_ENCRYPTION_AES_KEY + SIZE_SIGNING_SOFT_SERIAL];
uint8_t hash[32];
uint8_t checksum;
hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS,
SIZE_SIGNING_SOFT_HMAC_KEY);
hwReadConfigBlock((void*)&buffer[SIZE_SIGNING_SOFT_HMAC_KEY],
(void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, SIZE_RF_ENCRYPTION_AES_KEY);
hwReadConfigBlock((void*)&buffer[SIZE_SIGNING_SOFT_HMAC_KEY + SIZE_RF_ENCRYPTION_AES_KEY],
(void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, SIZE_SIGNING_SOFT_SERIAL);
hwReadConfigBlock((void*)&checksum, (void*)EEPROM_PERSONALIZATION_CHECKSUM_ADDRESS,
SIZE_PERSONALIZATION_CHECKSUM);

SHA256(hash, buffer, sizeof(buffer));
return (checksum == hash[0]);
#endif
}
#endif

+ 896
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySigning.h View File

@@ -0,0 +1,896 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
/**
* @defgroup MySigninggrpPub Message signing
* @ingroup publics
* @{
*
* @brief The message signing infrastructure provides message authenticity to users by signing
* MySensors messages.
*
* Signing support created by Patrick "Anticimex" Fallberg.
*
* @section MySigninggrptoc Table of contents
*
* @ref MySigninggrphowuse <br>
* @ref MySigningwhitelisting <br>
* @ref MySigninglimitations <br>
* @ref MySigningusecases <br>
* @ref MySigningtechnical <br>
* @ref MySigninggrpbackground <br>
* @ref MySigninggrphow <br>
* @ref MySigninggrpencryption <br>
*
* @section MySigninggrphowuse How to use this
*
* Before we begin with the details, I just want to emphasize that signing is completely optional
* and not enabled by default.
*
* If you do want the additional security layer signing provides, you pick the backend of your
* choice in your sketch. Currently, two compatible backends are supported; @ref MY_SIGNING_ATSHA204
* (hardware backed) and @ref MY_SIGNING_SOFT (software backed). There also exist a simplified
* variant (@ref MY_SIGNING_SIMPLE_PASSWD) of the software backend which only require one setting
* to activate.
*
* If you use hardware backed signing, then connect the device as follows:
* @image html MySigning/wiring.png
* @note The pull-up resistor is optional but recommended.
* @note If you change the default pin (A3) make sure you use a pin that supports input/output
* (ex. A6 & A7 on a Pro Mini are input only pins).
*
* To use signing, you need to perform three major steps which are described below.
*
* <b>Firstly</b>, you need to make sure to pick a backend to use.
* @code{.cpp}
* //#define MY_SIGNING_SOFT
* //#define MY_SIGNING_SIMPLE_PASSWD
* #define MY_SIGNING_ATSHA204
* #include <MySensors.h>
* ...
* @endcode
* Make sure to set the define before the inclusion of MySensors.h.
* It is ok to mix @ref MY_SIGNING_SOFT and @ref MY_SIGNING_ATSHA204 in a network.
* They are fully compatible. It is however not recommended to use @ref MY_SIGNING_SOFT on nodes
* that are publicly accessible (more on that later).
*
* If you use @ref MY_SIGNING_SOFT or @ref MY_SIGNING_ATSHA204 you also need to decide if the node
* (or gateway) in question require messages to be signed in addition to the ability to generate
* signatures for other nodes.
* This has to be set by at least one of the nodes in a "pair" or nobody will actually start
* calculating a signature for a message.
* Just set the flag @ref MY_SIGNING_REQUEST_SIGNATURES and the node will inform the gateway that it
* expects the gateway to sign all messages sent to the node. Note that when set in a gateway, the
* gateway will require ALL nodes in the network to sign messages.
* If this behaviour is undesired, enable the flag @ref MY_SIGNING_WEAK_SECURITY which will allow
* the gateway to only require signatures from nodes that in turn require signatures. It will also
* allow the gateway (and all nodes) to "downgrade" security by clearing the signing/whitelisting
* requirements (whitelisting is described later on in the @ref MySigningwhitelisting section) in
* the EEPROM if a node presents itself as not having any security requirements.
* If @ref MY_SIGNING_WEAK_SECURITY is not set, any node that has presented itself with
* signing/whitelisting requirements will be permanently marked as such by the receiver
* (typically the gateway). The only way then to reset/revert this requirement is to clear the
* EEPROM at the receiver (or disable @ref MY_SIGNING_REQUEST_SIGNATURES, but the preference will be
* remembered if the request flag is re-enabled before EEPROM is cleared).<br>
* If you want to have two nodes communicate securely directly with each other, the nodes that
* require signatures must send a presentation message to all nodes it expect signed messages from
* (only the gateway is informed automatically). See @ref signerPresentation().<br>
* A node can have three "states" with respect to signing:
* 1. Node does not support signing in any way (neither @ref MY_SIGNING_ATSHA204,
* @ref MY_SIGNING_SOFT nor @ref MY_SIGNING_SIMPLE_PASSWD is set)
* 2. Node does support signing but don't require messages sent to it to be signed (neither
* @ref MY_SIGNING_REQUEST_SIGNATURES nor @ref MY_SIGNING_SIMPLE_PASSWD is set)
* 3. Node does support signing and require messages sent to it to be signed (@ref
* MY_SIGNING_SOFT or @ref MY_SIGNING_ATSHA204 together with @ref MY_SIGNING_REQUEST_SIGNATURES or
* @ref MY_SIGNING_SIMPLE_PASSWD are set)
*
* <b>Secondly</b>, you need to verify the configuration for the backend.<br>
* For hardware backed signing it is the pin the device is connected to. In MyConfig.h there are
* defaults which you might need to adjust to match your personal build. The setting is defined
* using @ref MY_SIGNING_ATSHA204_PIN.<br>
* If you use an official MySensors board (like the SenseBender GW) you do not need to set the pin,
* this is configured automatically by the Arduino board definition files.
*
* Similar to picking your backend, this can also be set in your sketch:
* @code{.cpp}
* #define MY_SIGNING_ATSHA204
* #define MY_SIGNING_ATSHA204_PIN 4
* #define MY_SIGNING_REQUEST_SIGNATURES
* #include <MySensors.h>
* ...
* @endcode
* For the software backed signing backend, an unconnected analog pin is required on boards that
* does not provide a hardware based random generator unit to set a random seed for the
* pseudo-random generator.
* It is important that the pin is floating, or the output of the pseudo-random generator will be
* predictable, and thus compromise the signatures. The setting is defined using
* @ref MY_SIGNING_SOFT_RANDOMSEED_PIN. The same configuration possibilities exist as with the other
* configuration options.
*
* @code{.cpp}
* #define MY_SIGNING_SOFT
* #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
* #define MY_SIGNING_REQUEST_SIGNATURES
* #include <MySensors.h>
* ...
* @endcode
*
* An example of a node that require signatures is available in @ref SecureActuator.ino.
*
* <b>Thirdly</b>, if you use a signing backend and you don't use @ref MY_SIGNING_SIMPLE_PASSWD, you
* need to personalize the node.
*
* @anchor personalization If you use the ATSHA204A (@ref MY_SIGNING_ATSHA204), before any signing
* operations can be done, the device needs to be <i>personalized</i>.
* This can be a daunting process as it involves irreversibly writing configurations to the device,
* which cannot be undone. I have however tried to simplify the process as much as possibly by
* creating a helper-sketch specifically for this purpose in @ref SecurityPersonalizer.ino
* Note that you also need to do personalization for @ref MY_SIGNING_SOFT, but then the values are
* stored in EEPROM.
*
* To personalize a ATSHA204A do the following procedure:
* 1. Enable @ref GENERATE_KEYS_ATSHA204A<br>
* This will lock the ATSHA204A and generate random keys for HMAC (signing) and %AES (encryption).
* Copy the keys generated and replace the corresponding definitions under
* "User defined key data", specifically @ref MY_HMAC_KEY and @ref MY_AES_KEY.
* 2. Disable @ref GENERATE_KEYS_ATSHA204A and enable @ref PERSONALIZE_ATSHA204A<br>
* This will store the HMAC key to the ATSHA204A and the %AES key to EEPROM. It will also write
* a checksum of the personalization data in EEPROM to be able to detect if the data is
* altered.<br>
* Personalization is now complete.
*
* To personalize for software signing do the following procedure:
* 1. Enable @ref GENERATE_KEYS_SOFT<br>
* This will generate random keys for HMAC (signing) and %AES (encryption).
* Copy the keys generated and replace the corresponding definitions under
* "User defined key data", specifically @ref MY_HMAC_KEY and @ref MY_AES_KEY.
* 2. Disable @ref GENERATE_KEYS_SOFT and enable @ref PERSONALIZE_SOFT<br>
* This will store the HMAC key and the %AES key to EEPROM. It will also write
* a checksum of the personalization data in EEPROM to be able to detect if the data is
* altered.<br>
* Personalization is now complete.
*
* If you want to use soft signing and you want to use whitelisting (the ability to revoke/ban
* compromised nodes in the network) and your target does not provide a unique device ID, you have
* to generate a unique serial and store it in EEPROM. This can be done by replacing
* @ref PERSONALIZE_SOFT in step 2 above with @ref PERSONALIZE_SOFT_RANDOM_SERIAL. See the output
* under "Hardware security peripherals" to determine if this is necessary.
*
* When you have personalized your first device after step 2 above, you can run the same sketch on
* all devices in your network that needs to be personalized in a compatible manner. Pick
* @ref PERSONALIZE_ATSHA204A or @ref PERSONALIZE_SOFT as needed by the hardware. When the
* personalization has finished, you just program the sketch you plan to use (with the appropriate
* signing flags set).
*
* If you are using a Raspberry PI-based gateway, personalizaion is done slightly differently:
* 1. Generate keys, execute @c mysgw with arguments
* * To generate HMAC key @verbatim --gen-soft-hmac-key @endverbatim
* * To generate %AES key @verbatim --gen-aes-key @endverbatim
* * To generate a soft serial number @verbatim --gen-soft-serial @endverbatim
* 2. Update the gateway config file with the generated keys/valeus
* * For HMAC key @verbatim soft_hmac_key=<DATA> @endverbatim
* * For %AES key @verbatim aes_key=<DATA> @endverbatim
* * For soft serial number @verbatim soft_serial_key=<DATA> @endverbatim
*
* You are now set and ready to use message signing in your network.
* As of now, the following restrictions will be applied to your nodes:
* * If a node does require signing, any unsigned message sent to the node will be rejected.
* This also applies to the gateway.
* * Your radio communication quality is expected to work fine (if any NACK happen on a signing
* related message, it will fail, and enabling signing will put maximum strain on your RF link as
* maximum sized packets are transmitted in the network). See @ref MySigningTroubleshootinggrp.
* * All nodes and gateways in a network maintain a table where the signing preferences of all nodes
* are stored. This is also stored in EEPROM so if a node or gateway reboots, the other nodes does
* not have to retransmit a signing presentation to the node for the node to start expecting signed
* messages from other nodes.<br>
* * By default, the signing preferences are not "downgradeable". That is, any node that at any
* point in time has indicated a signing requirement will not be able to revert this requirement at
* the receiving end (except by manual erase of the EEPROM).<br>
* If you for some reason need to be able to downgrade the security requirements, you can set
* @ref MY_SIGNING_WEAK_SECURITY at the receiver to allow it to downgrade the security expectations
* of the node in question.<br>
* You then need to reset your transmitting node, to force it to transmit updated signing
* preferences.
*
* @section MySigningwhitelisting Whitelisting and node revocation
*
* Consider the situation when you have set up your secure topology. We use the remotely operated
* garage door as an example:
* * You have a node inside your garage (considered physically inaccessible) that controls your
* garage door motor.<br>
* This node requires signing since you do not want an unauthorized person sending it orders to
* open the door.
* * You have a keyfob node with a signing backend that uses the same PSK as your door opener node.
*
* In this setup, your keyfob can securely transmit messages to your door node since the keyfob will
* sign the messages it sends and the door node will verify that these were sent from a trusted node
* (since it used the correct PSK). If the keyfob does not sign the messages, the door node
* will not accept them. Optionally, your keyfob sends a signed message to your gateway (which
* require signatures) and the gateway in turn sends a signed message to your garage door.
*
* One day your keyfob gets stolen or you lost it or it simply broke down.
*
* You now end up with a problem; you need some way of telling your door node that the keyfob in
* question cannot be trusted any more. You could now repersonalize all your node to switch to a
* different PSK but this obviously is a hassle. How do you make sure that the "rogue" keyfob can be
* removed from the "trusted chain"?
*
* The answer to this is whitelisting. You let your door node keep a whitelist of all nodes it
* trusts. If you stop trusting a particular node, you remove it from the nodes whitelist
* (by uploading a new sketch), and it will no longer be able to communicate signed messages to the
* door node.
*
* In case you want to be able to "whitelist" trusted nodes (in order to be able to revoke them in
* case they are lost) you also need to take note of the serial number of the ATSHA device or the
* software value stored in EEPROM. This is unique for each device. The serial number is printed
* in a copy+paste friendly format by the personalizer for this purpose.<br>
* The whitelist is stored on the node that require signatures. When a received message is
* verified, the serial of the sender is looked up in a list stored on the receiving node, and the
* corresponding serial stored in the list for that sender is then included in the signature
* verification process. The list is stored as the value of the flag that enables whitelisting,
* @ref MY_SIGNING_NODE_WHITELISTING.<br>
*
* Whitelisting is achieved by 'salting' the signature with some node-unique information known to
* the receiver. In the case of @ref MY_SIGNING_ATSHA204 this is the unique serial number programmed
* into the circuit. This unique number is never transmitted over the air in clear text, so Eve will
* not be able to figure out a "trusted" serial by snooping on the traffic.<br>
* Instead the value is hashed together with the senders NodeId into the HMAC signature to produce
* the final signature. The receiver will then take the originating NodeId of the signed message and
* do the corresponding calculation with the serial it has stored in it's whitelist if it finds a
* matching entry in it's whitelist.
*
* Whitelisting is an optional alternative because it adds some code and configuration options which
* might not be desirable for every user. So if you want the ability to use whitelists, you need to
* enable @ref MY_SIGNING_NODE_WHITELISTING. You need to remember that the gateway will remember if
* a node has presented it with a whitelisting requirement as described above, if you at some point
* decide to remove the whitelist requirement.<br>
* The whitelist is provided as value of the flag that enable it as follows (example is a node that
* require signing as well):
* @code{.cpp}
* #define MY_SIGNING_ATSHA204
* #define MY_SIGNING_REQUEST_SIGNATURES
* #define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}},{.nodeId = 2,.serial = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09}}}
* #include <MySensors.h>
* ...
* @endcode
* In this example, there are two nodes in the whitelist; the gateway, and a separate node that
* communicates directly with this node (with signed messages). You do not need to do anything
* special for the sending nodes, apart from making sure they support signing.
*
* The "soft" backend of course also support whitelisting. Example:
* @code{.cpp}
* #define MY_SIGNING_SOFT
* #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
* #define MY_SIGNING_REQUEST_SIGNATURES
* #define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}},{.nodeId = 2,.serial = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09}}}
* #include <MySensors.h>
* ...
* @endcode
*
* For a node that should transmit whitelisted messages but not receive whitelisted messages, you do
* not need any special configurations:
* @code{.cpp}
* #define MY_SIGNING_SOFT
* #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
* @endcode
* Remember that you always need to select a signing backend for all nodes that communicate to a
* node that require whitelisting. Also, note that a node that use whitelisting will not accept
* messages from nodes that are not present in it's whitelist.
* And you have to personalize all nodes that use signing with a common HMAC key but different
* serial numbers (@ref MY_SIGNING_ATSHA204 always has unique serials).
*
* @section MySigninglimitations Known limitations
*
* Due to the limiting factor of our cheapest Arduino nodes, the use of diversified keys is not
* implemented. That mean that all nodes in your network share the same PSK (at least the ones that
* are supposed to exchange signed data). It is important to understand the implications of
* this, and that is covered in the "Typical use cases" chapter below.<br>
* Most importantly, if you use @ref MY_SIGNING_SOFT your PSK will be stored in EEPROM and will
* therefore be accessible by anyone with physical access to your node. Therefore it is <b>NOT</b>
* recommended to use @ref MY_SIGNING_SOFT on nodes that are placed in a public place or worn on
* on your person (like a keyfob).<br>
* Also be reminded that the strength of the signature is inversely proportional to the size of the
* message. The larger the message, the weaker the signature.
*
* @section MySigningusecases Typical use cases
*
* "Securely located" in this context mean a node which is not physically publicly accessible.
* Typically at least your gateway.<br>
* "Public" in this context mean a node that is located outside your "trusted environment". This
* includes sensors located outdoors, keyfobs etc.
*
* @subsection MySigninglock Securely located lock
*
* You have a securely located gateway and a lock somewhere inside your "trusted environment" (e.g.
* inside your house door, the door to your dungeon or similar).<br>
* You need to make your node require signed messages but you do not necessarily need to make your
* gateway require signed messages (unless you are concerned that someone might spoof the lock
* status of your lock).<br>
* Configuration example for the secure lock node:<br>
* @code{.cpp}
* #define MY_SIGNING_ATSHA204
* #define MY_SIGNING_REQUEST_SIGNATURES
* #include <MySensors.h>
* ...
* @endcode
* If you do also want your gateway to require signatures from your lock you just enable the same
* (or similar if using software signing) settings in the gateway.
*
* @subsection MySigningpatio Patio motion sensor
*
* Your gateway is securely located inside your house, but your motion sensor is located outside
* your house. You have for some reason elected that this node should sign the messages it send to
* your gateway. You should lock the data (PSK) in this node then, because if someone were to steal
* your patio motion sensor, they could rewrite the firmware and spoof your gateway to use it to
* transmit a correctly signed message to your secure lock inside your house. But if you revoke your
* gateway (and lock) PSK the outside sensor cannot be used for this anymore. Nor can it be changed
* in order to do it in the future. You can also use whitelisting to revoke your lost node.<br>
* This is an unlikely use case because there really is no reason to sign sensor values. If you for
* some reason want to obfuscate sensor data, encryption is a better alternative.<br>
* Configuration example for a motion sensor:<br>
* @code{.cpp}
* #define MY_SIGNING_SOFT
* #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
* #define MY_SIGNING_REQUEST_SIGNATURES
* #include <MySensors.h>
* ...
* @endcode
*
* The gateway needs to be configured with a whitelist (and it has to have an entry for all nodes
* that send and/or require signed messages):<br>
* @code{.cpp}
* #define MY_SIGNING_SOFT
* #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
* #define MY_SIGNING_REQUEST_SIGNATURES
* #define MY_SIGNING_NODE_WHITELISTING {{.nodeId = MOTION_SENSOR_ID,.serial = {0x12,0x34,0x56,0x78,0x90,0x12,0x34,0x56,0x78}}}
* #include <MySensors.h>
* ...
* @endcode

* @subsection MySigningkeyfob Keyfob for garage door opener
*
* Perhaps the most typical usecase for signed messages. Your keyfob should be totally locked down.
* If the garage door opener is secured (and it should be) it can be unlocked. That way, if you
* loose your keyfob, you can revoke the PSK in both the opener and your gateway,
* thus rendering the keyfob useless without having to replace your nodes. You can also use
* whitelisting to revoke your lost keyfob.<br>
* Configuration example for the keyfob (keyfob will only transmit to another node and not receive
* anything):<br>
* @code{.cpp}
* #define MY_SIGNING_ATSHA204
* #include <MySensors.h>
* ...
* @endcode
*
* Configuration example for the door controller node (should require signing from anyone who wants
* to control it):<br>
* @code{.cpp}
* #define MY_SIGNING_SOFT
* #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
* #define MY_SIGNING_REQUEST_SIGNATURES
* #define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88}},{.nodeId = KEYFOB_ID,.serial = {<FROM ATSHA ON KEYFOB>}}}
* #include <MySensors.h>
* ...
* @endcode
*
* @subsection MySigningsketches Relevant sketches
*
* - @ref SecureActuator.ino
* - @ref SecurityPersonalizer.ino
*
* @section MySigningtechnical The technical stuff
*
* The following sequence diagram illustrate how messages are passed in a MySensors network with
* respect to signing:
* @image html MySigning/signingsequence.png
*
* None of this activity is “visible” to you (as the sensor sketch implementor). All you need to do
* is to set your preferences in your sketch and personalize accordingly.
* That is enough to enable protection from both Eve and Mallory in your network
* although if you do not also enable encryption, Eve can eavesdrop, but not do anything about,
* your messages (except possibly preventing them from arriving).
*
* How are the messages actually affected by the signing?<br>
* The following illustration shows what part of the message is signed, and where the signature is
* stored:
* @image html MySigning/signingillustrated1.png
*
* The first byte of the header is not covered by the signature, because in the network, this byte
* is used to track hops in the network and therefore might change if the message is passing a relay
* node. So it cannot be part of the signature, or the signature would be invalid when it arrives to
* its destination. The signature also carries a byte with a signing identifier to prevent false
* results from accidental mixing of incompatible signing backends in the network. Thus, the maximum
* size for a payload is 29-7 bytes. Larger payloads are not possible to sign at the moment. Another
* thing to consider is that the strength of the signature is inversely proportional to the payload
* size.
*
* As for the software backend, it turns out that the ATSHA does not do “vanilla” HMAC processing.
* Fortunately, Atmel has documented exactly how the circuit processes the data and hashes thus
* making it possible to generate signatures that are identical to signatures generated by the
* circuit.
*
* The signatures are calculates in the following way:
* @image html MySigning/signingillustrated2.png
*
* Exactly how this is done can be reviewed in the source for the software backend
* (MySigningAtsha204Soft.cpp) and the ATSHA204A
* <a href="http://www.atmel.com/Images/Atmel-8885-CryptoAuth-ATSHA204A-Datasheet.pdf">datasheet
* </a>. In the MySensors protocol, the following internal messagetypes handles signature
* requirements and nonce requests:<br>
* @ref I_SIGNING_PRESENTATION <br>
* @ref I_NONCE_REQUEST <br>
* @ref I_NONCE_RESPONSE <br>
*
* Also, the version field in the header has been reduced from 3 to 2 bits in order to fit a single
* bit to indicate that a message is signed.
*
* @section MySigninggrpbackground Background and concepts
*
* Suppose two participants, Alice and Bob, wants to exchange a message. Alice sends a message to
* Bob. In MySensors “language” Alice could be a gateway and Bob an actuator (light switch,
* electronic lock, etc). But to be generic, we will substitute the term “gateway” with Alice and a
* “node” with Bob (although the reverse relationship is also supported).
*
* Alice sends a message to Bob. This message can be heard by anyone who wants to listen (and also
* by anyone that is within “hearing” distance). Normally, this is perhaps not a big issue. Nothing
* Alice says to Bob may be secret or sensitive in any way. However, sometimes (or perhaps always)
* Bob want to be sure that the message Bob receives actually came from Alice. In cryptography,
* this is known as <i>authenticity</i>. Bob needs some way of determining that the message is
* authentic from Alice, when Bob receives it. This prevents an eavesdropper, Eve, to trick Bob into
* thinking it was Alice that sent a message Eve in fact transmitted. Bob also needs to know how to
* determine if the message has been repeated. Eve could record a message sent by Alice that Bob
* accepted and then send the same message again. Eve could also in some way prevent Bob from
* receiving the message and delay it in order to permit the message to arrive to Bob at a time Eve
* chooses, instead of Alice. Such an attack is known as a <b>replay attack</b>.<br>
* <i>Authenticity</i> permits Bob to determine if Alice is the true sender of a message.
* @image html MySigning/alicenfriends.png
*
* It can also be interesting for Bob to know that the message Alice sent has not been tampered with
* in any way. This is the <i>integrity</i> of the message. We now introduce Mallory, who could be
* intercepting the communication between Alice and Bob and replace some parts of the message but
* keeping the parts that authenticate the message. That way, Bob still trusts Alice to be the
* source, but the contents of the message was not the content Alice sent. Bob needs to be able to
* determine that the contents of the message was not altered after Alice sent it.<br>
* Mallory would in this case be a <b>man-in-the-middle</b> attacker.<br>
* <i>Integrity</i> permits Bob to verify that the messages received from Alice has not been
* tampered with.<br>
* This is achieved by adding a <i>signature</i> to the message, which Bob can inspect to validate
* that Alice is the author.
* @image html MySigning/alicenfriends2.png
*
* The signing scheme used, needs to address both these attack scenarios. Neither Eve nor Mallory
* must be permitted to interfere with the message exchange between Alice and Bob.
*
* The key challenge to implementing a secure signing scheme is to ensure that every signature is
* different, even if the message is not. If not, <b>replay attacks</b> would be very hard to
* prevent.<br>
* One way of doing this is to increment some counter on the sender side and include it in the
* signature. This is however predictable.<br>
* A better option would be to introduce a random number to the signature. That way, it is
* impossible to predict what the signature will be. The problem is, that also makes it impossible
* for the receiver (Bob) to verify that the signature is valid.<br>
* A solution to this is to let Bob generate the random number, keep it in memory and send it to
* Alice. Alice can then use the random number in the signature calculation and send the signed
* message back to Bob who can validate the signature with the random number used.
* This random number is in cryptography known as a
* <a href="https://en.wikipedia.org/wiki/Cryptographic_nonce">nonce</a> or
* <a href="https://en.wikipedia.org/wiki/Salt_%28cryptography%29">salt</a>.
*
* However, Mallory might be eavesdropping on the communication and snoop up the nonce in order to
* generate a new valid signature for a different message. To counter this, both Alice and Bob keep
* a secret that only they know. This secret is never transmitted over the air,
* nor is it revealed to anybody. This secret is known as a
* <a href="https://en.wikipedia.org/wiki/Pre-shared_key"> pre-shared key</a> (PSK).
*
* If Eve or Mallory are really sophisticated, he/she might use a <b>delayed replay attack</b>.
* This can be done by allowing Bob to transmit a nonce to Alice. But when Alice transmits the
* uniquely signed message, Mallory prevents Bob from receiving it, to a point when Mallory
* decides Bob should receive it. An example of such an attack is described
* <a href="http://spencerwhyte.blogspot.se/2014/03/delay-attack-jam-intercept-and-replay.html">
* here</a>.<br>
* This needs to be addressed as well, and one way of doing this is to have Bob keep track of time
* between a transmitted nonce and a signed message to verify. If Bob is asked for a nonce, Bob
* knows that a signed message is going to arrive “soon”. Bob can then decide that if the signed
* message does not arrive within a predefined timeframe, Bob throws away the generated nonce and
* thus makes it impossible to verify the message if it arrives late.
*
* The flow can be described like this:
* @image html MySigning/alicenbob.png
* The benefits for MySensors to support this are obvious. Nobody wants others to be able to control
* or manipulate any actuators in their home.
*
* @section MySigninggrphow How this is done
*
* There exist many forms of message signature solutions to combat Eve and Mallory.<br>
* Most of these solutions are quite complex in term of computations, so I elected to use an
* algorithm that an external circuit is able to process. This has the added benefit of protecting
* any keys and intermediate data used for calculating the signature so that even if someone were to
* actually steal a sensor and disassembled it, they would not be able to extract the keys and other
* information from the device.<br>
* A common scheme for message signing (authenticity and integrity) is implemented using
* <a href="http://en.wikipedia.org/wiki/Hash-based_message_authentication_code">HMAC</a> which in
* combination with a strong <a href="http://en.wikipedia.org/wiki/Hash_function"> hash function</a>
* provides a very strong level of protection.<br>
* The <a href="http://www.atmel.com/devices/ATSHA204A.aspx">Atmel ATSHA204A</a> is a low-cost,
* low-voltage/current circuit that provides HMAC calculation capabilities with SHA256 hashing which
* is a (currently) virtually unbreakable combination. If SHA256 were to be hacked, a certain
* <a href="http://en.wikipedia.org/wiki/Bitcoin">cryptocurrency</a> would immediately be rendered
* worthless.<br>
* The ATSHA device also contain a random number generator (RNG) which enables the generation of a
* good nonce, as in, <i>non-predictable</i>.<br>
* As I acknowledge that some might not want to use an additional external circuit, I have also
* implemented a software version of the ATSHA device, capable of generating the same signatures as
* the ATSHA device does. Because it is pure-software however, it does not provide as good nonces
* (it uses the <a href="http://arduino.cc/en/reference/random">Arduino pseudo-random generator</a>)
* and the HMAC key is stored in SW and is therefore readable if the memory is dumped. It also
* naturally claims more flash space due to the more complex software. But for indoor
* sensors/actuators this might be good enough for most people.
*
* @section MySigninggrpencryption Why encryption is not part of this
*
* Well, some could be uncomfortable with somebody being able to snoop temperatures, motion or the
* state changes of locks in the environment.
* Signing does <b>not</b> address these issues. Encryption is needed to prevent this.<br>
* It is my personal standpoint that encryption should not be part of the MySensors “protocol”. The
* reason is that a gateway and a node does not really care about messages being readable or not by
* “others”. It makes more sense that such guarantees are provided by the underlying transmission
* layer (RF solution in this case). It is the information transmitted over the air that needs to be
* secret (if user so desires). The “trust” level on the other hand needs to go all the way into the
* sketches (who might have different requirements of trust depending on the message participant),
* and for this reason, it is more important (and less complicated) to ensure authenticity and
* <i>integrity</i> at protocol-level as message contents is still readable throughout the protocol
* stack. But as soon as the message leaves the “stack” it can be scramble into “garbage” when
* transmitted over the air and then reassembled by a receiving node before being fed in “the clear”
* up the stack at the receiving end.
*
* There are methods and possibilities to provide encryption also in software, but if this is done,
* it is my recommendation that this is done after integrity- and authentication information has
* been provided to the message (if this is desired). Integrity and authentication is of course not
* mandatory and some might be happy with only having encryption to cover their need for security.
* I, however, have only focused on <i>integrity</i> and <i>authenticity</i> while at the same time
* keeping the current message routing mechanisms intact and therefore leave the matter of
* <i>secrecy</i> to be implemented in the “physical” transport layer. With the <i>integrity</i> and
* <i>authenticity</i> handled in the protocol it ought to be enough for a simple encryption
* (nonce-less %AES with a PSK for instance) on the message as it is sent to the RF backend. Atmel
* does provide such circuits as well but I have not investigated the matter further as it given the
* current size of the ethernet gateway sketch is close to the size limit on an Arduino Nano, so it
* will be difficult to fit this into some existing gateway designs.<br>
* Also it is worth to consider that the state of a lock can just as readily be determined by simply
* looking at the door in question or attempting to open it, so obfuscating this information will
* not necessarily deter an attacker in any way.<br>
* Nevertheless, I do acknowledge that people find the fact that all information is sent “in the
* clear” even if it require some technical effort for an intruder to obtain and inspect this
* information. So I do encourage the use of encrypting transport layers.<br>
* This is however not covered by this implementation.<br>
* This might change in the future as more powerful platforms emerge which permit more complex
* security schemes and better hardware acceleration.
*/
/** @}*/

/**
* @defgroup MySigninggrp MySigning
* @ingroup internals
* @{
*
* @brief API declaration for MySigning signing backend
*
* @see MySigninggrpPub
*/
/**
* @file MySigning.h
*
* @brief API declaration for MySigning signing backend
*/
#ifndef MySigning_h
#define MySigning_h

#include "MySensorsCore.h"
#include "drivers/ATSHA204/ATSHA204.h"

#ifdef MY_SIGNING_NODE_WHITELISTING
typedef struct {
uint8_t nodeId; /**< @brief The ID of the node */
uint8_t serial[SHA204_SERIAL_SZ]; /**< @brief Node specific serial number */
} whitelist_entry_t;
#endif

/** @brief Helper macro to determine the number of elements in a array */
#define NUM_OF(x) (sizeof(x)/sizeof(x[0]))

/**
* @brief Initializes signing infrastructure and associated backend.
*
* This function makes sure that the internal states of the signing infrastructure
* is set to a known initial state.
* \n@b Usage: This function should be called before any signing related operations take place.
*/
void signerInit(void);

/**
* @brief Does signing specific presentation for a node.
*
* This function makes sure any signing related presentation info is shared with the other part.
* The presentation of the gateways signing preferences is done in @ref signerProcessInternal().
* \n@b Usage: This function should be called by the presentation routine of the MySensors library.
* You only need to call this directly from a sketch to set up a node to node signed message exchange.
* If you do call this directly from a sketch, and you at some point change your sketch to go from
* requiring signing to not requiring signatures, you need to present this change to the node at least
* once, so it can update its requirements tables accordingly. Or it will keep believing that this node
* require signatures and attempt to send signed messages to it.
*
* @param msg Message buffer to use.
* @param destination Node ID of the destination.
*/
void signerPresentation(MyMessage &msg, uint8_t destination);

/**
* @brief Manages internal signing message handshaking.
*
* This function takes care of signing related message handshaking such as nonce exchange.
* \n@b Usage: This function should be called by the incoming message handler before any further message
* processing is performed on internal messages. This function should only be called for @ref C_INTERNAL class
* messages.
*
* @param msg Message buffer to process.
* @returns @c true if caller should stop further message processing.
*/
bool signerProcessInternal(MyMessage &msg);

/**
* @brief Check timeout of verification session.
*
* Nonce will be purged if it takes too long for a signed message to be sent to the receiver.
* \n@b Usage: This function should be called on regular intervals, typically within some process loop.
*
* @returns @c true if session is still valid.
*/
bool signerCheckTimer(void);

/**
* @brief Get nonce from provided message and store for signing operations.
*
* Returns @c false if subsystem is busy processing an ongoing signing operation.<br>
* Returns @c false if signing identifier found in message is not supported by the used backend.<br>
* If successful, this marks the start of a signing operation at the sending side so
* implementation is expected to do any necessary initializations within this call.
* \n@b Usage: This function is typically called as action when receiving a @ref I_NONCE_RESPONSE
* message.
*
* @param msg The message to get the nonce from.
* @returns @c true if successful, else @c false.
*/
bool signerPutNonce(MyMessage &msg);

/**
* @brief Signs provided message. All remaining space in message payload buffer is used for
* signing identifier and signature.
*
* Nonce used for signature calculation is the one generated previously within @ref signerProcessInternal().<br>
* Nonce will be cleared when this function is called to prevent re-use of nonce.<br>
* Returns @c false if subsystem is busy processing an ongoing signing operation.<br>
* Returns @c false if not two bytes or more of free payload space is left in provided message.<br>
* This ends a signing operation at the sending side so implementation is expected to do any
* deinitializations and enter a power saving state within this call.
* \n@b Usage: This function is typically called as action when receiving a @ref I_NONCE_RESPONSE
* message and after @ref signerPutNonce() has successfully been executed.
*
* @param msg The message to sign.
* @returns @c true if successful, else @c false.
*/
bool signerSignMsg(MyMessage &msg);

/**
* @brief Verifies signature in provided message.
*
* Nonce used for verification is the one previously set using @ref signerPutNonce().<br>
* Nonce will be cleared when this function is called to prevent re-use of nonce.<br>
* Returns @c false if subsystem is busy processing an ongoing signing operation.<br>
* Returns @c false if signing identifier found in message is not supported by the used backend.<br>
* This ends a signing operation at the receiving side so implementation is expected to do any
* deinitializations and enter a power saving state within this call.
* \n@b Usage: This function is typically called when receiving a message that is flagged as signed
* and @ref MY_SIGNING_REQUEST_SIGNATURES is activated.
*
* @param msg The message to verify.
* @returns @c true if successful, else @c false.
*/
bool signerVerifyMsg(MyMessage &msg);

/**
* @brief Do a timing neutral memory comparison.
*
* The function behaves similar to memcmp with the difference that it will
* always use the same number of instructions for a given number of bytes,
* no matter how the two buffers differ and the response is either 0 or -1.
*
* @param a First buffer for comparison.
* @param b Second buffer for comparison.
* @param sz The number of bytes to compare.
* @returns 0 if buffers match, -1 if they do not.
*/
int signerMemcmp(const void* a, const void* b, size_t sz);

#endif
/** @}*/

/**
* @defgroup MySigningDebugMessages Signing related debug messages
* @ingroup MySigninggrpPub
* @{
*
* @brief Explanation of the abstract signing related debug messages
*
* MySigning-related log messages, format: [!]SYSTEM:SUB SYSTEM:MESSAGE
* - [!] Exclamation mark is prepended in case of error or warning
* - SYSTEM:
* - <b>SGN</b> messages emitted by MySigning
* - SUB SYSTEMS:
* - SGN:<b>INI</b> from @ref signerInit
* - SGN:<b>PER</b> from @ref signerInit
* - SGN:<b>PRE</b> from @ref signerPresentation
* - SGN:<b>SGN</b> from @ref signerSignMsg
* - SGN:<b>VER</b> from @ref signerVerifyMsg
* - SGN:<b>SKP</b> from @ref signerSignMsg or @ref signerVerifyMsg (skipSign)
* - SGN:<b>NCE</b> from @ref signerProcessInternal (signerInternalProcessNonceRequest)
* - SGN:<b>BND</b> from the signing backends
*
* MySigning debug log messages:
*
* |E| SYS | SUB | Message | Comment
* |-|-----|-----|--------------------------|----------------------------------------------------------------------------
* | | SGN | INI | BND OK | Backend has initialized ok
* |!| SGN | INI | BND FAIL | Backend has not initialized ok
* | | SGN | PER | OK | Personalization data is ok
* |!| SGN | PER | TAMPERED | Personalization data has been tampered
* | | SGN | PRE | SGN REQ | Signing required
* | | SGN | PRE | SGN REQ,TO='node' | Tell 'node' that we require signing
* | | SGN | PRE | SGN REQ,FROM='node' | Node 'node' require signing
* | | SGN | PRE | SGN NREQ | Signing not required
* | | SGN | PRE | SGN REQ,TO='node' | Tell 'node' that we do not require signing
* | | SGN | PRE | SGN NREQ,FROM='node' | Node 'node' does not require signing
* |!| SGN | PRE | SGN NREQ,FROM='node' REJ | Node 'node' does not require signing but used to (requirement remain unchanged)
* | | SGN | PRE | WHI REQ | Whitelisting required
* | | SGN | PRE | WHI REQ;TO='node' | Tell 'node' that we require whitelisting
* | | SGN | PRE | WHI REQ,FROM='node' | Node 'node' require whitelisting
* | | SGN | PRE | WHI NREQ | Whitelisting not required
* | | SGN | PRE | WHI NREQ,TO='node' | Tell 'node' that we do not require whitelisting
* | | SGN | PRE | WHI NREQ,FROM='node' | Node 'node' does not require whitelisting
* |!| SGN | PRE | WHI NREQ,FROM='node' REJ | Node 'node' does not require whitelisting but used to (requirement remain unchanged)
* | | SGN | PRE | XMT,TO='node' | Presentation data transmitted to 'node'
* |!| SGN | PRE | XMT,TO='node' FAIL | Presentation data not properly transmitted to 'node'
* | | SGN | PRE | WAIT GW | Waiting for gateway presentation data
* |!| SGN | PRE | VER='version' | Presentation version 'version' is not supported
* | | SGN | PRE | NSUP | Received signing presentation but signing is not supported
* | | SGN | PRE | NSUP,TO='node' | Informing 'node' that we do not support signing
* | | SGN | SGN | NCE REQ,TO='node' | Nonce request transmitted to 'node'
* |!| SGN | SGN | NCE REQ,TO='node' FAIL | Nonce request not properly transmitted to 'node'
* |!| SGN | SGN | NCE TMO | Timeout waiting for nonce
* | | SGN | SGN | SGN | Message signed
* |!| SGN | SGN | SGN FAIL | Message failed to be signed
* | | SGN | SGN | NREQ='node' | 'node' does not require signed messages
* | | SGN | SGN | 'sender'!='us' NUS | Will not sign because 'sender' is not 'us' (repeater)
* |!| SGN | SGN | STATE | Security system in a invalid state (personalization data tampered)
* |!| SGN | VER | NSG | Message was not signed, but it should have been
* |!| SGN | VER | FAIL | Verification failed
* | | SGN | VER | OK | Verification succeeded
* | | SGN | VER | LEFT='number' | 'number' of failed verifications left in a row before node is locked
* |!| SGN | VER | STATE | Security system in a invalid state (personalization data tampered)
* | | SGN | SKP | MSG CMD='cmd',TYPE='type'| Message with command 'cmd' and type 'type' does not need to be signed
* | | SGN | SKP | ACK CMD='cmd',TYPE='type'| ACK messages does not need to be signed
* | | SGN | NCE | LEFT='number' | 'number' of nonce requests between successful verifications left before node is locked
* | | SGN | NCE | XMT,TO='node' | Nonce data transmitted to 'node'
* |!| SGN | NCE | XMT,TO='node' FAIL | Nonce data not properly transmitted to 'node'
* |!| SGN | NCE | GEN | Failed to generate nonce
* | | SGN | NCE | NSUP (DROPPED) | Ignored nonce/request for nonce (signing not supported)
* | | SGN | NCE | FROM='node' | Received nonce from 'node'
* | | SGN | NCE | 'sender'!='dst' (DROPPED)| Ignoring nonce as it did not come from the designation of the message to sign
* |!| SGN | BND | INIT FAIL | Failed to initialize signing backend
* |!| SGN | BND | PWD<8 | Signing password too short
* |!| SGN | BND | PER | Backend not personalized
* |!| SGN | BND | SER | Could not get device unique serial from backend
* |!| SGN | BND | TMR | Backend timed out
* |!| SGN | BND | SIG,SIZE,'message'>'max' | Refusing to sign 'message' because it is bigger than 'max' allowed size
* | | SGN | BND | SIG WHI,ID='id' | Salting message with our 'id'
* | | SGN | BND | SIG WHI,SERIAL='serial' | Salting message with our 'serial'
* |!| SGN | BND | VER ONGOING | Verification failed, no ongoing session
* |!| SGN | BND | VER,IDENT='identifier' | Verification failed, 'identifier' is unknown
* | | SGN | BND | VER WHI,ID='sender' | 'sender' found in whitelist
* | | SGN | BND | VER WHI,SERIAL='serial' | Expecting 'serial' for this sender
* |!| SGN | BND | VER WHI,ID='id' MISSING | 'id' not found in whitelist
* | | SGN | BND | NONCE='nonce' | Calculating signature using 'nonce'
* | | SGN | BND | HMAC='hmac' | Calculated signature is 'hmac'
*/
/** @}*/

/**
* @defgroup MySigningTroubleshootinggrp Signing troubleshooting
* @ingroup MySigninggrpPub
* @{
*
* @brief Typical signing related failure cases and how to solve them
*
* @section MySigningTroubleshootingSymptoms Symptoms and solutions
*
* The first thing to do if you suspect signing is causing problems, is to enable the verbose debug
* flag for the signing backend. @see MY_DEBUG_VERBOSE_SIGNING
*
* If you are having trouble getting signing to work, please see the following troubleshooting tips.
*
* @subsection MySigningTroubleshootingSymptomStFail Signing fails and logs show st=fail on transmissions
*
* This is actually not a signing problem, although often st=fail becomes st=ok when signing is disabled.
* This is by far the most commonly reported problem with signing, but the problems is not with signing,
* it is with radio performance.<br>
* This is a typical log which might look like a signing related issue but isn't:
* @code{.unparsed}
* 0;255;3;0;9;Skipping security for command 3 type 16
* 0;255;3;0;9;read: 3-3-0 s=255,c=3,t=16,pt=0,l=0,sg=0:
* 0;255;3;0;9;Signing backend: ATSHA204Soft
* 0;255;3;0;9;SHA256: 86DEAE1DAF50D577A4E2262B33ABF9DEE05DD8FAF84F94F50900000000000000
* 0;255;3;0;9;Skipping security for command 3 type 17
* 0;255;3;0;9;send: 0-0-3-3 s=255,c=3,t=17,pt=6,l=25,sg=0,st=fail:86DEAE1DAF50D577A4E2262B33ABF9DEE05DD8FAF84F94F509
* 0;255;3;0;9;Failed to transmit nonce!
* 0;255;3;0;9;Message is not signed, but it should have been!
* 0;255;3;0;9;verify fail
* @endcode
*
* The reason for this is that when signing is used, the messages transmitted become relatively large.<br>
* Because of this, the message is more sensitive to noise, and the chance for a message to get scrambled
* increase with the message size. Please refer to the troubleshooting section at the MySensors forum for
* information on how to improve radio performance.<br>
* This is a good place to start: https://forum.mysensors.org/topic/666/debug-faq-and-how-ask-for-help
*
* @subsection MySigningTroubleshootingSymptomNonce Failed to generate nonce
*
* The signing backend failed to generate the nonce needed to sign a message. This indicate a hardware
* problem. Please post the debug info on the forum together with a description of your hardware setup.
*
* @subsection MySigningTroubleshootingSymptomSign Failed to sign message
*
* The signing backend failed to sign the message. Typically this happens if your message is so large,
* that there is no room left in the buffer to store a signature.
*
* @subsection MySigningTroubleshootingSymptomWrongSource Nonce did not come from the destination (XX) of the message to be signed! It came from YY
*
* This should not really happen. The reason for this message is that the signing backend is only capable
* of handling one signed message session at any time. If for some reason multiple nodes send a nonce message to
* the same node, only the nonce from a node that is the destination of the current message signing session will be
* accepted. Any other nonces will be dropped. This should not happen as no node should send a nonce unless asked to,
* and a node will only ask for a nonce to one destination for every signing session.<br>
* If you see this message, please post the debugging details on the MySensors forum so it can be investigated further
* together with a description of your setup.
*
* @subsection MySigningTroubleshootingSymptomNotSigned Message is not signed, but it should have been
*
* A node has failed to comply with the signing preferences of this node. Check that the node has received a
* signing presentation message from this node. This is automatically transmitted to gateways. For other nodes,
* you need to transmit the presentation from the sketch. @see signerPresentation
*
* @subsection MySigningTroubleshootingSymptomNotSignedGeneral "Messages do not appear to be signed but I think they should be..."
*
* Make sure you have enabled the flag to require signatures to require signatures and have enabled one of the signing
* backends. @see MY_SIGNING_REQUEST_SIGNATURES @see MY_SIGNING_ATSHA204 @see MY_SIGNING_SOFT
*
* @subsection MySigningTroubleshootingSymptomNotWorkingWhitelisting Signature verification failed!
*
* Make sure both source and destination of the signed message has undergone @ref personalization with the same HMAC key.<br>
* Also, if whitelisting is used, make sure the proper serial is paired with the proper node ID at the destination.
* Whitelisting preferences are communicated with the signing presentation (done automatically from nodes to gateway but
* has to be explicitly done by sketch for node to node communication). @see signerPresentation
*/
/** @}*/

+ 374
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySigningAtsha204.cpp View File

@@ -0,0 +1,374 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*******************************
*
* DESCRIPTION
* Signing support created by Patrick "Anticimex" Fallberg <patrick@fallberg.net>
* ATSHA204 signing backend. The Atmel ATSHA204 offers true random number generation and
* HMAC-SHA256 authentication with a readout-protected key.
*
*/

#include "MySigning.h"

#ifdef MY_SIGNING_ATSHA204
#define SIGNING_IDENTIFIER (1) //HMAC-SHA256

#if defined(MY_DEBUG_VERBOSE_SIGNING)
#define SIGN_DEBUG(x,...) DEBUG_OUTPUT(x, ##__VA_ARGS__)
static char printStr[65];
static char i2h(uint8_t i)
{
uint8_t k = i & 0x0F;
if (k <= 9) {
return '0' + k;
} else {
return 'A' + k - 10;
}
}

static void buf2str(const uint8_t* buf, size_t sz)
{
uint8_t i;
if (sz > 32) {
sz = 32; //clamp to 32 bytes
}
for (i = 0; i < sz; i++) {
printStr[i * 2] = i2h(buf[i] >> 4);
printStr[(i * 2) + 1] = i2h(buf[i]);
}
printStr[sz * 2] = '\0';
}
#else
#define SIGN_DEBUG(x,...)
#endif

static unsigned long _signing_timestamp;
static bool _signing_verification_ongoing = false;
static uint8_t _signing_verifying_nonce[32+9+1];
static uint8_t _signing_signing_nonce[32+9+1];
static uint8_t _signing_temp_message[SHA_MSG_SIZE];
static uint8_t _signing_rx_buffer[SHA204_RSP_SIZE_MAX];
static uint8_t _signing_tx_buffer[SHA204_CMD_SIZE_MAX];
static uint8_t* const _signing_hmac = &_signing_rx_buffer[SHA204_BUFFER_POS_DATA];
static uint8_t _signing_node_serial_info[9];
#ifdef MY_SIGNING_NODE_WHITELISTING
static const whitelist_entry_t _signing_whitelist[] = MY_SIGNING_NODE_WHITELISTING;
#endif

static bool init_ok = false;

static void signerCalculateSignature(MyMessage &msg, bool signing);
static uint8_t* signerAtsha204AHmac(const uint8_t* nonce, const uint8_t* data);
static uint8_t* signerSha256(const uint8_t* data, size_t sz);

bool signerAtsha204Init(void)
{
init_ok = true;
atsha204_init(MY_SIGNING_ATSHA204_PIN);

(void)atsha204_wakeup(_signing_temp_message);
// Read the configuration lock flag to determine if device is personalized or not
if (atsha204_read(_signing_tx_buffer, _signing_rx_buffer,
SHA204_ZONE_CONFIG, 0x15<<2) != SHA204_SUCCESS) {
SIGN_DEBUG(PSTR("!SGN:BND:INIT FAIL\n")); //Could not read ATSHA204A lock config
init_ok = false;
} else if (_signing_rx_buffer[SHA204_BUFFER_POS_DATA+3] != 0x00) {
SIGN_DEBUG(PSTR("!SGN:BND:PER\n")); //ATSHA204A not personalized
init_ok = false;
}
if (init_ok) {
// Get and cache the serial of the ATSHA204A
if (atsha204_getSerialNumber(_signing_node_serial_info) != SHA204_SUCCESS) {
SIGN_DEBUG(PSTR("!SGN:BND:SER\n")); //Could not get ATSHA204A serial
init_ok = false;
}
}
return init_ok;
}

bool signerAtsha204CheckTimer(void)
{
if (!init_ok) {
return false;
}
if (_signing_verification_ongoing) {
unsigned long time_now = hwMillis();
// If timestamp is taken so late a rollover can take place during the timeout,
// offset both timestamp and current time to make sure no rollover takes place during the
// timeout
if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < _signing_timestamp) {
_signing_timestamp += MY_VERIFICATION_TIMEOUT_MS;
time_now += MY_VERIFICATION_TIMEOUT_MS;
}
if (time_now > _signing_timestamp + MY_VERIFICATION_TIMEOUT_MS) {
SIGN_DEBUG(PSTR("!SGN:BND:TMR\n")); //Verification timeout
// Purge nonce
memset(_signing_signing_nonce, 0xAA, 32);
memset(_signing_verifying_nonce, 0xAA, 32);
_signing_verification_ongoing = false;
return false;
}
}
return true;
}

bool signerAtsha204GetNonce(MyMessage &msg)
{
if (!init_ok) {
return false;
}

// We used a basic whitening technique that XORs each byte in a 32byte random value with current
// hwMillis() counter. This 32-byte random value is then hashed (SHA256) to produce the resulting
// nonce
(void)atsha204_wakeup(_signing_temp_message);
if (atsha204_execute(SHA204_RANDOM, RANDOM_SEED_UPDATE, 0, 0, NULL,
RANDOM_COUNT, _signing_tx_buffer, RANDOM_RSP_SIZE, _signing_rx_buffer) !=
SHA204_SUCCESS) {
return false;
}
for (int i = 0; i < 32; i++) {
_signing_verifying_nonce[i] = _signing_rx_buffer[SHA204_BUFFER_POS_DATA+i] ^ (hwMillis()&0xFF);
}
memcpy(_signing_verifying_nonce, signerSha256(_signing_verifying_nonce, 32),
min(MAX_PAYLOAD, 32));

// We just idle the chip now since we expect to use it soon when the signed message arrives
atsha204_idle();

if (MAX_PAYLOAD < 32) {
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
memset(&_signing_verifying_nonce[MAX_PAYLOAD], 0xAA, 32-MAX_PAYLOAD);
}

// Transfer the first part of the nonce to the message
msg.set(_signing_verifying_nonce, min(MAX_PAYLOAD, 32));
_signing_verification_ongoing = true;
_signing_timestamp = hwMillis(); // Set timestamp to determine when to purge nonce
return true;
}

void signerAtsha204PutNonce(MyMessage &msg)
{
if (!init_ok) {
return;
}

memcpy(_signing_signing_nonce, (uint8_t*)msg.getCustom(), min(MAX_PAYLOAD, 32));
if (MAX_PAYLOAD < 32) {
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
memset(&_signing_signing_nonce[MAX_PAYLOAD], 0xAA, 32-MAX_PAYLOAD);
}
}

bool signerAtsha204SignMsg(MyMessage &msg)
{
// If we cannot fit any signature in the message, refuse to sign it
if (mGetLength(msg) > MAX_PAYLOAD-2) {
SIGN_DEBUG(PSTR("!SGN:BND:SIG,SIZE,%" PRIu8 ">%" PRIu8 "\n"), mGetLength(msg),
MAX_PAYLOAD-2); //Message too large
return false;
}

// Calculate signature of message
mSetSigned(msg, 1); // make sure signing flag is set before signature is calculated
signerCalculateSignature(msg, true);

if (DO_WHITELIST(msg.destination)) {
// Salt the signature with the senders nodeId and the unique serial of the ATSHA device
// We can reuse the nonce buffer now since it is no longer needed
memcpy(_signing_signing_nonce, _signing_hmac, 32);
_signing_signing_nonce[32] = msg.sender;
memcpy(&_signing_signing_nonce[33], _signing_node_serial_info, 9);
// We can 'void' sha256 because the hash is already put in the correct place
(void)signerSha256(_signing_signing_nonce, 32+1+9);
SIGN_DEBUG(PSTR("SGN:BND:SIG WHI,ID=%" PRIu8 "\n"), msg.sender);
#ifdef MY_DEBUG_VERBOSE_SIGNING
buf2str(_signing_node_serial_info, 9);
SIGN_DEBUG(PSTR("SGN:BND:SIG WHI,SERIAL=%s\n"), printStr);
#endif
}

// Put device back to sleep
atsha204_sleep();

// Overwrite the first byte in the signature with the signing identifier
_signing_hmac[0] = SIGNING_IDENTIFIER;

// Transfer as much signature data as the remaining space in the message permits
memcpy(&msg.data[mGetLength(msg)], _signing_hmac, min(MAX_PAYLOAD-mGetLength(msg), 32));

return true;
}

bool signerAtsha204VerifyMsg(MyMessage &msg)
{
if (!_signing_verification_ongoing) {
SIGN_DEBUG(PSTR("!SGN:BND:VER ONGOING\n"));
return false;
} else {
// Make sure we have not expired
if (!signerCheckTimer()) {
return false;
}

_signing_verification_ongoing = false;

if (msg.data[mGetLength(msg)] != SIGNING_IDENTIFIER) {
SIGN_DEBUG(PSTR("!SGN:BND:VER,IDENT=%" PRIu8 "\n"), msg.data[mGetLength(msg)]);
return false;
}

signerCalculateSignature(msg, false); // Get signature of message

#ifdef MY_SIGNING_NODE_WHITELISTING
// Look up the senders nodeId in our whitelist and salt the signature with that data
size_t j;
for (j=0; j < NUM_OF(_signing_whitelist); j++) {
if (_signing_whitelist[j].nodeId == msg.sender) {
// We can reuse the nonce buffer now since it is no longer needed
memcpy(_signing_verifying_nonce, _signing_hmac, 32);
_signing_verifying_nonce[32] = msg.sender;
memcpy(&_signing_verifying_nonce[33], _signing_whitelist[j].serial, 9);
// We can 'void' sha256 because the hash is already put in the correct place
(void)signerSha256(_signing_verifying_nonce, 32+1+9);
SIGN_DEBUG(PSTR("SGN:BND:VER WHI,ID=%" PRIu8 "\n"), msg.sender);
#ifdef MY_DEBUG_VERBOSE_SIGNING
buf2str(_signing_whitelist[j].serial, 9);
SIGN_DEBUG(PSTR("SGN:BND:VER WHI,SERIAL=%s\n"), printStr);
#endif
break;
}
}
if (j == NUM_OF(_signing_whitelist)) {
SIGN_DEBUG(PSTR("!SGN:BND:VER WHI,ID=%" PRIu8 " MISSING\n"), msg.sender);
// Put device back to sleep
atsha204_sleep();
return false;
}
#endif

// Put device back to sleep
atsha204_sleep();

// Overwrite the first byte in the signature with the signing identifier
_signing_hmac[0] = SIGNING_IDENTIFIER;

// Compare the calculated signature with the provided signature
if (signerMemcmp(&msg.data[mGetLength(msg)], _signing_hmac,
min(MAX_PAYLOAD-mGetLength(msg), 32))) {
return false;
} else {
return true;
}
}
}

// Helper to calculate signature of msg (returned in _signing_rx_buffer[SHA204_BUFFER_POS_DATA])
// (=_signing_hmac)
static void signerCalculateSignature(MyMessage &msg, bool signing)
{
// Signature is calculated on everything expect the first byte in the header
uint16_t bytes_left = mGetLength(msg)+HEADER_SIZE-1;
int16_t current_pos = 1-(int16_t)HEADER_SIZE; // Start at the second byte in the header
uint8_t* nonce = signing ? _signing_signing_nonce : _signing_verifying_nonce;

#ifdef MY_DEBUG_VERBOSE_SIGNING
buf2str(nonce, 32);
SIGN_DEBUG(PSTR("SGN:BND:NONCE=%s\n"), printStr);
#endif

while (bytes_left) {
uint16_t bytes_to_include = min(bytes_left, 32);

(void)atsha204_wakeup(_signing_temp_message); // Issue wakeup to reset watchdog
memset(_signing_temp_message, 0, 32);
memcpy(_signing_temp_message, (uint8_t*)&msg.data[current_pos], bytes_to_include);

// We can 'void' signerAtsha204AHmac because the HMAC is already put in the correct place
(void)signerAtsha204AHmac(nonce, _signing_temp_message);
// Purge nonce when used
memset(nonce, 0xAA, 32);

bytes_left -= bytes_to_include;
current_pos += bytes_to_include;

if (bytes_left > 0) {
// We will do another pass, use current HMAC as nonce for the next HMAC
memcpy(nonce, _signing_hmac, 32);
atsha204_idle(); // Idle the chip to allow the wakeup call to reset the watchdog
}
}
#ifdef MY_DEBUG_VERBOSE_SIGNING
buf2str(_signing_hmac, 32);
SIGN_DEBUG(PSTR("SGN:BND:HMAC=%s\n"), printStr);
#endif
}

// Helper to calculate a ATSHA204A specific HMAC-SHA256 using provided 32 byte nonce and data
// (zero padded to 32 bytes)
// The pointer to the HMAC is returned, but the HMAC is also stored in
// _signing_rx_buffer[SHA204_BUFFER_POS_DATA] (=_signing_hmac)
static uint8_t* signerAtsha204AHmac(const uint8_t* nonce, const uint8_t* data)
{
// Program the data to sign into the ATSHA204
(void)atsha204_execute(SHA204_WRITE, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG, 8 << 3, 32,
(uint8_t*)data,
WRITE_COUNT_LONG, _signing_tx_buffer, WRITE_RSP_SIZE, _signing_rx_buffer);

// Program the nonce to use for the signature (has to be done just before GENDIG
// due to chip limitations)
(void)atsha204_execute(SHA204_NONCE, NONCE_MODE_PASSTHROUGH, 0, 32, (uint8_t*)nonce,
NONCE_COUNT_LONG, _signing_tx_buffer, NONCE_RSP_SIZE_SHORT,
_signing_rx_buffer);

// Generate digest of data and nonce
(void)atsha204_execute(SHA204_GENDIG, GENDIG_ZONE_DATA, 8, 0, NULL,
GENDIG_COUNT_DATA, _signing_tx_buffer, GENDIG_RSP_SIZE,
_signing_rx_buffer);

// Calculate HMAC of message+nonce digest and secret key
(void)atsha204_execute(SHA204_HMAC, HMAC_MODE_SOURCE_FLAG_MATCH, 0, 0, NULL,
HMAC_COUNT, _signing_tx_buffer, HMAC_RSP_SIZE, _signing_rx_buffer);
return &_signing_rx_buffer[SHA204_BUFFER_POS_DATA];
}

// Helper to calculate a generic SHA256 digest of provided buffer (only supports one block)
// The pointer to the hash is returned, but the hash is also stored in
// _signing_rx_buffer[SHA204_BUFFER_POS_DATA])
static uint8_t* signerSha256(const uint8_t* data, size_t sz)
{
// Initiate SHA256 calculator
(void)atsha204_execute(SHA204_SHA, SHA_INIT, 0, 0, NULL,
SHA_COUNT_SHORT, _signing_tx_buffer, SHA_RSP_SIZE_SHORT,
_signing_rx_buffer);

// Calculate a hash
memset(_signing_temp_message, 0x00, SHA_MSG_SIZE);
memcpy(_signing_temp_message, data, sz);
_signing_temp_message[sz] = 0x80;
// Write length data to the last bytes
_signing_temp_message[SHA_MSG_SIZE-2] = (sz >> 5);
_signing_temp_message[SHA_MSG_SIZE-1] = (sz << 3);
(void)atsha204_execute(SHA204_SHA, SHA_CALC, 0, SHA_MSG_SIZE, _signing_temp_message,
SHA_COUNT_LONG, _signing_tx_buffer, SHA_RSP_SIZE_LONG, _signing_rx_buffer);
return &_signing_rx_buffer[SHA204_BUFFER_POS_DATA];
}
#endif //MY_SIGNING_ATSHA204

+ 393
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySigningAtsha204Soft.cpp View File

@@ -0,0 +1,393 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*******************************
*
* DESCRIPTION
* Signing support created by Patrick "Anticimex" Fallberg <patrick@fallberg.net>
* ATSHA204 emulated signing backend. The emulated ATSHA204 implementation offers pseudo random
* number generation and HMAC-SHA256 authentication compatible with a "physical" ATSHA204.
* NOTE: Key is stored in clear text in the Arduino firmware. Therefore, the use of this back-end
* could compromise the key used in the signed message infrastructure if device is lost and its
* memory dumped.
*
*/

#include "MySigning.h"

#ifdef MY_SIGNING_SOFT
#define SIGNING_IDENTIFIER (1) //HMAC-SHA256

#if defined(MY_DEBUG_VERBOSE_SIGNING)
#define SIGN_DEBUG(x,...) DEBUG_OUTPUT(x, ##__VA_ARGS__)
static char printStr[65];
static char i2h(const uint8_t i)
{
uint8_t k = i & 0x0F;
if (k <= 9) {
return '0' + k;
} else {
return 'A' + k - 10;
}
}

static void buf2str(const uint8_t *buf, size_t sz)
{
if (sz > 32) {
sz = 32; //clamp to 32 bytes
}
for (uint8_t i = 0; i < sz; i++) {
printStr[i * 2] = i2h(buf[i] >> 4);
printStr[(i * 2) + 1] = i2h(buf[i]);
}
printStr[sz * 2] = '\0';
}
#else
#define SIGN_DEBUG(x,...)
#endif

static unsigned long _signing_timestamp;
static bool _signing_verification_ongoing = false;
static bool _signing_init_ok = false;
static uint8_t _signing_verifying_nonce[32+9+1];
static uint8_t _signing_nonce[32+9+1];
static uint8_t _signing_hmac_key[SIZE_SIGNING_SOFT_HMAC_KEY];
static uint8_t _signing_hmac[32];
static uint8_t _signing_node_serial_info[SIZE_SIGNING_SOFT_SERIAL];

#ifdef MY_SIGNING_NODE_WHITELISTING
static const whitelist_entry_t _signing_whitelist[] = MY_SIGNING_NODE_WHITELISTING;
#endif

static void signerCalculateSignature(MyMessage &msg, const bool signing);
static void signerAtsha204AHmac(uint8_t *dest, const uint8_t *nonce, const uint8_t *data);

bool signerAtsha204SoftInit(void)
{
_signing_init_ok = true;
// initialize pseudo-RNG
hwRandomNumberInit();
// Set secrets
#ifdef MY_SIGNING_SIMPLE_PASSWD
if (strnlen(MY_SIGNING_SIMPLE_PASSWD, 32) < 8) {
SIGN_DEBUG(PSTR("!SGN:BND:PWD<8\n")); //Password is too short to be acceptable
_signing_init_ok = false;
} else {
(void)memset((void *)_signing_hmac_key, 0x00, sizeof(_signing_hmac_key));
(void)memcpy((void *)_signing_hmac_key, MY_SIGNING_SIMPLE_PASSWD, strnlen(MY_SIGNING_SIMPLE_PASSWD,
32));
(void)memset((void *)_signing_node_serial_info, 0x00, sizeof(_signing_node_serial_info));
(void)memcpy((void *)_signing_node_serial_info, MY_SIGNING_SIMPLE_PASSWD,
strnlen(MY_SIGNING_SIMPLE_PASSWD, 8));
_signing_node_serial_info[8] = getNodeId();
}
#else
hwReadConfigBlock((void *)_signing_hmac_key, (void *)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS,
SIZE_SIGNING_SOFT_HMAC_KEY);
hwReadConfigBlock((void *)_signing_node_serial_info, (void *)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS,
SIZE_SIGNING_SOFT_SERIAL);
#endif

uint16_t chk = 0;
for (uint8_t i = 0; i < SIZE_SIGNING_SOFT_SERIAL; i++) {
chk += _signing_node_serial_info[i];
}
if (chk==SIZE_SIGNING_SOFT_SERIAL *
0xFF) { // test if == { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
unique_id_t uniqueID;
// There is no serial, attempt to get unique ID for serial instead
if (hwUniqueID(&uniqueID)) {
// There is a unique serial, use that
(void)memcpy((void *)_signing_node_serial_info, (const void *)uniqueID, SIZE_SIGNING_SOFT_SERIAL);
}
}
return _signing_init_ok;
}

bool signerAtsha204SoftCheckTimer(void)
{
if (!_signing_init_ok) {
return false;
}
if (_signing_verification_ongoing) {
unsigned long time_now = hwMillis();
// If timestamp is taken so late a rollover can take place during the timeout,
// offset both timestamp and current time to make sure no rollover takes place during the
// timeout
if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < _signing_timestamp) {
_signing_timestamp += MY_VERIFICATION_TIMEOUT_MS;
time_now += MY_VERIFICATION_TIMEOUT_MS;
}
if (time_now > _signing_timestamp + MY_VERIFICATION_TIMEOUT_MS) {
SIGN_DEBUG(PSTR("!SGN:BND:TMR\n")); //Verification timeout
// Purge nonce
(void)memset((void *)_signing_nonce, 0xAA, sizeof(_signing_nonce));
(void)memset((void *)_signing_verifying_nonce, 0xAA, sizeof(_signing_verifying_nonce));
_signing_verification_ongoing = false;
return false;
}
}
return true;
}

bool signerAtsha204SoftGetNonce(MyMessage &msg)
{
if (!_signing_init_ok) {
return false;
}

#ifdef MY_HW_HAS_GETENTROPY
// Try to get MAX_PAYLOAD random bytes
while (hwGetentropy(&_signing_verifying_nonce, MAX_PAYLOAD) != MAX_PAYLOAD);
#else
// We used a basic whitening technique that XORs a random byte with the current hwMillis() counter
// and then the byte is hashed (SHA256) to produce the resulting nonce
uint8_t randBuffer[32];
for (uint8_t i = 0; i < sizeof(randBuffer); i++) {
randBuffer[i] = random(256) ^ (hwMillis() & 0xFF);
}
SHA256(_signing_verifying_nonce, randBuffer, sizeof(randBuffer));
#endif

if (MAX_PAYLOAD < 32) {
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
(void)memset((void *)&_signing_verifying_nonce[MAX_PAYLOAD], 0xAA, 32-MAX_PAYLOAD);
}

// Transfer the first part of the nonce to the message
msg.set(_signing_verifying_nonce, MIN(MAX_PAYLOAD, 32));
_signing_verification_ongoing = true;
_signing_timestamp = hwMillis(); // Set timestamp to determine when to purge nonce
// Be a little fancy to handle turnover (prolong the time allowed to timeout after turnover)
// Note that if message is "too" quick, and arrives before turnover, it will be rejected
// but this is consider such a rare case that it is accepted and rejects are 'safe'
if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < hwMillis()) {
_signing_timestamp = 0;
}
return true;
}

void signerAtsha204SoftPutNonce(MyMessage &msg)
{
if (!_signing_init_ok) {
return;
}
(void)memcpy((void *)_signing_nonce, (const void *)msg.getCustom(), MIN(MAX_PAYLOAD, 32));
if (MAX_PAYLOAD < 32) {
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
(void)memset((void *)&_signing_nonce[MAX_PAYLOAD], 0xAA, 32-MAX_PAYLOAD);
}
}

bool signerAtsha204SoftSignMsg(MyMessage &msg)
{
// If we cannot fit any signature in the message, refuse to sign it
if (mGetLength(msg) > MAX_PAYLOAD-2) {
SIGN_DEBUG(PSTR("!SGN:BND:SIG,SIZE,%" PRIu8 ">%" PRIu8 "\n"), mGetLength(msg),
MAX_PAYLOAD-2); //Message too large
return false;
}

// Calculate signature of message
mSetSigned(msg, 1); // make sure signing flag is set before signature is calculated
signerCalculateSignature(msg, true);

if (DO_WHITELIST(msg.destination)) {
// Salt the signature with the senders nodeId and the (hopefully) unique serial The Creator has
// provided. We can reuse the nonce buffer now since it is no longer needed
(void)memcpy((void *)_signing_nonce, (const void *)_signing_hmac, 32);
_signing_nonce[32] = msg.sender;
(void)memcpy((void *)&_signing_nonce[33], (const void *)_signing_node_serial_info, 9);
SHA256(_signing_hmac, _signing_nonce, 32+1+9);
SIGN_DEBUG(PSTR("SGN:BND:SIG WHI,ID=%" PRIu8 "\n"), msg.sender);
#ifdef MY_DEBUG_VERBOSE_SIGNING
buf2str(_signing_node_serial_info, 9);
SIGN_DEBUG(PSTR("SGN:BND:SIG WHI,SERIAL=%s\n"), printStr);
#endif
}

// Overwrite the first byte in the signature with the signing identifier
_signing_hmac[0] = SIGNING_IDENTIFIER;

// Transfer as much signature data as the remaining space in the message permits
(void)memcpy((void *)&msg.data[mGetLength(msg)], (const void *)_signing_hmac,
MIN(MAX_PAYLOAD-mGetLength(msg), 32));

return true;
}

bool signerAtsha204SoftVerifyMsg(MyMessage &msg)
{
if (!_signing_verification_ongoing) {
SIGN_DEBUG(PSTR("!SGN:BND:VER ONGOING\n"));
return false;
} else {
// Make sure we have not expired
if (!signerCheckTimer()) {
return false;
}

_signing_verification_ongoing = false;

if (msg.data[mGetLength(msg)] != SIGNING_IDENTIFIER) {
SIGN_DEBUG(PSTR("!SGN:BND:VER,IDENT=%" PRIu8 "\n"), msg.data[mGetLength(msg)]);
return false;
}

signerCalculateSignature(msg, false); // Get signature of message

#ifdef MY_SIGNING_NODE_WHITELISTING
// Look up the senders nodeId in our whitelist and salt the signature with that data
size_t j;
for (j = 0; j < NUM_OF(_signing_whitelist); j++) {
if (_signing_whitelist[j].nodeId == msg.sender) {
// We can reuse the nonce buffer now since it is no longer needed
(void)memcpy((void *)_signing_verifying_nonce, (const void *)_signing_hmac, 32);
_signing_verifying_nonce[32] = msg.sender;
(void)memcpy((void *)&_signing_verifying_nonce[33], (const void *)_signing_whitelist[j].serial, 9);
SHA256(_signing_hmac, _signing_verifying_nonce, 32+1+9);
SIGN_DEBUG(PSTR("SGN:BND:VER WHI,ID=%" PRIu8 "\n"), msg.sender);
#ifdef MY_DEBUG_VERBOSE_SIGNING
buf2str(_signing_whitelist[j].serial, 9);
SIGN_DEBUG(PSTR("SGN:BND:VER WHI,SERIAL=%s\n"), printStr);
#endif
break;
}
}
if (j == NUM_OF(_signing_whitelist)) {
SIGN_DEBUG(PSTR("!SGN:BND:VER WHI,ID=%" PRIu8 " MISSING\n"), msg.sender);
return false;
}
#endif

// Overwrite the first byte in the signature with the signing identifier
_signing_hmac[0] = SIGNING_IDENTIFIER;

// Compare the calculated signature with the provided signature
if (signerMemcmp(&msg.data[mGetLength(msg)], _signing_hmac,
MIN(MAX_PAYLOAD-mGetLength(msg), 32))) {
return false;
} else {
return true;
}
}
}

// Helper to calculate signature of msg (returned in _signing_hmac)
static void signerCalculateSignature(MyMessage &msg, const bool signing)
{
// Signature is calculated on everything expect the first byte in the header
uint8_t bytes_left = mGetLength(msg)+HEADER_SIZE-1;
int16_t current_pos = 1-(int16_t)HEADER_SIZE; // Start at the second byte in the header
uint8_t* nonce = signing ? _signing_nonce : _signing_verifying_nonce;

#ifdef MY_DEBUG_VERBOSE_SIGNING
buf2str(nonce, 32);
SIGN_DEBUG(PSTR("SGN:BND:NONCE=%s\n"), printStr);
#endif

uint8_t _signing_temp_message[32];

while (bytes_left) {
uint8_t bytes_to_include = MIN(bytes_left, 32);

(void)memset((void *)_signing_temp_message, 0x00, sizeof(_signing_temp_message));
(void)memcpy((void *)_signing_temp_message, (const void *)&msg.data[current_pos], bytes_to_include);

signerAtsha204AHmac(_signing_hmac, nonce, _signing_temp_message);
// Purge nonce when used
(void)memset((void *)nonce, 0xAA, 32);

bytes_left -= bytes_to_include;
current_pos += bytes_to_include;

if (bytes_left) {
// We will do another pass, use current HMAC as nonce for the next HMAC
(void)memcpy((void *)nonce, (const void *)_signing_hmac, 32);
}
}
#ifdef MY_DEBUG_VERBOSE_SIGNING
buf2str(_signing_hmac, 32);
SIGN_DEBUG(PSTR("SGN:BND:HMAC=%s\n"), printStr);
#endif
}

// Helper to calculate a ATSHA204A specific HMAC-SHA256 using provided 32 byte nonce and data
// (zero padded to 32 bytes)
// The pointer to the HMAC is returned, but the HMAC is also stored in _signing_hmac
static void signerAtsha204AHmac(uint8_t *dest, const uint8_t *nonce, const uint8_t *data)
{
// ATSHA204 calculates the HMAC with a PSK and a SHA256 digest of the following data:
// 32 bytes zeroes
// 32 bytes digest,
// 1 byte OPCODE (0x11)
// 1 byte Mode (0x04)
// 2 bytes SlotID (0x0000)
// 11 bytes zeroes
// SN[8] (0xEE)
// 4 bytes zeroes
// SN[0:1] (0x0123)
// 2 bytes zeroes

// The digest is calculated as a SHA256 digest of the following:
// 32 bytes message
// 1 byte OPCODE (0x15)
// 1 byte param1 (0x02)
// 2 bytes param2 (0x0800)
// SN[8] (0xEE)
// SN[0:1] (0x0123)
// 25 bytes zeroes
// 32 bytes nonce

#if defined(MY_CRYPTO_SHA256_ASM)
static uint8_t _signing_buffer[96]; // static for AVR ASM SHA256
#else
uint8_t _signing_buffer[96];
#endif
// Calculate message digest first
(void)memset((void *)_signing_buffer, 0x00, sizeof(_signing_buffer));
(void)memcpy((void *)_signing_buffer, (const void *)data, 32);
_signing_buffer[0 + 32] = 0x15; // OPCODE
_signing_buffer[1 + 32] = 0x02; // param1
_signing_buffer[2 + 32] = 0x08; // param2(1)
//_signing_buffer[3 + 32] = 0x00; // param2(2)
_signing_buffer[4 + 32] = 0xEE; // SN[8]
_signing_buffer[5 + 32] = 0x01; // SN[0]
_signing_buffer[6 + 32] = 0x23; // SN[1]
// _signing_buffer[7 + 32..31 + 32] => 0x00;
(void)memcpy((void *)&_signing_buffer[64], (const void *)nonce, 32);
SHA256(_signing_hmac, _signing_buffer, 96);

// Feed "message" to HMAC calculator
(void)memset((void *)_signing_buffer, 0x00, sizeof(_signing_buffer));
(void)memcpy((void *)&_signing_buffer[32], (const void *)_signing_hmac, 32);
_signing_buffer[0 + 64] = 0x11; // OPCODE
_signing_buffer[1 + 64] = 0x04; // Mode
//_signing_buffer[2 + 64] = 0x00; // SlotID(1)
//_signing_buffer[3 + 64] = 0x00; // SlotID(2)
//_signing_buffer[4 + 64..14 + 64] => 0x00; // 11 bytes zeroes
_signing_buffer[15 + 64] = 0xEE; // SN[8]
//_signing_buffer[16 + 64..19 + 64] => 0x00; // 4 bytes zeroes
_signing_buffer[20 + 64] = 0x01;
_signing_buffer[21 + 64] = 0x23;
//_signing_buffer[22 + 64] = 0x00; // SN[0]
//_signing_buffer[23 + 64] = 0x00; // SN[1]
SHA256HMAC(dest, _signing_hmac_key, 32, _signing_buffer, 88);
}

#endif //MY_SIGNING_SOFT

+ 52
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySplashScreen.cpp View File

@@ -0,0 +1,52 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#include "MySensorsCore.h"

void displaySplashScreen(void)
{
#if !defined(MY_DISABLED_SERIAL) && defined(MY_DEBUGDEVICE)
static const uint8_t splashScreen[] PROGMEM = {
0x20, 0x7C, 0x5F, 0x5c, 0x2F, 0x60, 0x2C, 0x0A, // substitution matrix
0x07, 0x02, 0x20, 0x02, 0x20, 0xB2, 0x87, 0x10, 0x03, 0x40, 0x01, 0x20, 0x00, 0x24, 0x02, 0x22,
0x10, 0x02, 0x22, 0x02, 0x02, 0x20, 0x02, 0x22, 0x00, 0x22, 0x20, 0x02, 0x02, 0x20, 0x22, 0x27,
0x10, 0x13, 0x41, 0x01, 0x01, 0x01, 0x03, 0x22, 0x20, 0x30, 0x40, 0x20, 0x30, 0x52, 0x03, 0x40,
0x22, 0x14, 0x02, 0x03, 0x10, 0x52, 0x24, 0x02, 0x21, 0x71, 0x01, 0x00, 0x10, 0x10, 0x12, 0x10,
0x12, 0x22, 0x10, 0x10, 0x02, 0x24, 0x01, 0x01, 0x03, 0x22, 0x03, 0x00, 0x20, 0x01, 0x01, 0x00,
0x32, 0x20, 0x37, 0x12, 0x10, 0x01, 0x21, 0x32, 0x26, 0x01, 0x28, 0x40, 0x32, 0x22, 0x12, 0x10,
0x12, 0x12, 0x22, 0x43, 0x22, 0x24, 0x12, 0x10, 0x01, 0x22, 0x24, 0x70, 0xC1, 0x22, 0x24,
0x0F, 0x0F
};
uint8_t pos = 16;
char display = 0;
while (pos<sizeof(splashScreen)*2) {
uint8_t val = pgm_read_byte(&(splashScreen[pos>>1]));
val = (pos % 2) ? val & 0xF : val >> 4;
pos++;
if (val<8) {
display = pgm_read_byte(&(splashScreen[val]));
}
const uint8_t rep = val > 7 ? val - 5 : 1;
for (uint8_t c = 0; c<rep; c++) {
MY_DEBUGDEVICE.print(display);
}
}
MY_DEBUGDEVICE.println(F(MYSENSORS_LIBRARY_VERSION "\n"));
#endif
}

+ 28
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MySplashScreen.h View File

@@ -0,0 +1,28 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#ifndef MySplashScreen_h
#define MySplashScreen_h

/**
* Display MySensors splash screen.
*/
void displaySplashScreen(void);

#endif

+ 1182
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyTransport.cpp
File diff suppressed because it is too large
View File


+ 533
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/MyTransport.h View File

@@ -0,0 +1,533 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

/**
* @file MyTransport.h
*
* @defgroup MyTransportgrp MyTransport
* @ingroup internals
* @{
*
* Transport-related log messages, format: [!]SYSTEM:[SUB SYSTEM:]MESSAGE
* - [!] Exclamation mark is prepended in case of error
* - SYSTEM:
* - <b>TSM</b>: messages emitted by the transport state machine
* - <b>TSF</b>: messages emitted by transport support functions
* - SUB SYSTEMS:
* - Transport state machine (<b>TSM</b>)
* - TSM:<b>INIT</b> from <b>stInit</b> Initialize transport and radio
* - TSM:<b>FPAR</b> from <b>stParent</b> Find parent
* - TSM:<b>ID</b> from <b>stID</b> Check/request node ID, if dynamic node ID set
* - TSM:<b>UPL</b> from <b>stUplink</b> Verify uplink connection by pinging GW
* - TSM:<b>READY</b> from <b>stReady</b> Transport is ready and fully operational
* - TSM:<b>FAIL</b> from <b>stFailure</b> Failure in transport link or transport HW
* - Transport support function (<b>TSF</b>)
* - TSF:<b>CKU</b> from @ref transportCheckUplink(), checks connection to GW
* - TSF:<b>SID</b> from @ref transportAssignNodeID(), assigns node ID
* - TSF:<b>PNG</b> from @ref transportPingNode(), pings a node
* - TSF:<b>WUR</b> from @ref transportWaitUntilReady(), waits until transport is ready
* - TSF:<b>CRT</b> from @ref transportClearRoutingTable(), clears routing table stored in EEPROM
* - TSF:<b>LRT</b> from @ref transportLoadRoutingTable(), loads RAM routing table from EEPROM (only GW/repeaters)
* - TSF:<b>SRT</b> from @ref transportSaveRoutingTable(), saves RAM routing table to EEPROM (only GW/repeaters)
* - TSF:<b>MSG</b> from @ref transportProcessMessage(), processes incoming message
* - TSF:<b>SAN</b> from @ref transportInvokeSanityCheck(), calls transport-specific sanity check
* - TSF:<b>RTE</b> from @ref transportRouteMessage(), sends message
* - TSF:<b>SND</b> from @ref transportSendRoute(), sends message if transport is ready (exposed)
* - TSF:<b>TDI</b> from @ref transportDisable()
* - TSF:<b>TRI</b> from @ref transportReInitialise()
* - TSF:<b>SIR</b> from @ref transportSignalReport()
*
* Transport debug log messages:
*
* |E| SYS | SUB | Message | Comment
* |-|-----|-------|---------------------------|---------------------------------------------------------------------
* | | TSM | INIT | | <b>Transition to stInit state</b>
* | | TSM | INIT | STATID=%%d | Node ID is static
* | | TSM | INIT | TSP OK | Transport device configured and fully operational
* | | TSM | INIT | TSP PSM | Transport passive mode set
* | | TSM | INIT | GW MODE | Node is set up as GW, thus omitting ID and findParent states
* |!| TSM | INIT | TSP FAIL | Transport device initialization failed
* | | TSM | FPAR | | <b>Transition to stParent state</b>
* | | TSM | FPAR | STATP=%%d | Static parent set, skip finding parent
* | | TSM | FPAR | OK | Parent node identified
* |!| TSM | FPAR | NO REPLY | No potential parents replied to find parent request
* |!| TSM | FPAR | FAIL | Finding parent failed
* | | TSM | ID | | <b>Transition to stID state</b>
* | | TSM | ID | OK,ID=%%d | Node ID is valid
* | | TSM | ID | REQ | Request node ID from controller
* |!| TSM | ID | FAIL,ID=%%d | ID verification failed, ID invalid, no ID received from controller
* | | TSM | UPL | | <b>Transition to stUplink state</b>
* | | TSM | UPL | OK | Uplink OK, GW returned ping
* | | TSF | UPL | DGWC,O=%%d,N=%%d | Uplink check revealed changed network topology, old distance (O), new distance (N)
* |!| TSM | UPL | FAIL | Uplink check failed, i.e. GW could not be pinged
* | | TSM | READY | SRT | Save routing table
* | | TSM | READY | ID=%%d,PAR=%%d,DIS=%%d | <b>Transition to stReady</b> Transport ready, node ID (ID), parent node ID (PAR), distance to GW (DIS)
* |!| TSM | READY | UPL FAIL,SNP | Too many failed uplink transmissions, search new parent
* |!| TSM | READY | FAIL,STATP | Too many failed uplink transmissions, static parent enforced
* | | TSM | FAIL | CNT=%%d | <b>Transition to stFailure state</b>, consecutive failure counter (CNT)
* | | TSM | FAIL | DIS | Disable transport
* | | TSM | FAIL | RE-INIT | Attempt to re-initialize transport
* | | TSF | CKU | OK | Uplink OK
* | | TSF | CKU | OK,FCTRL | Uplink OK, flood control prevents pinging GW in too short intervals
* | | TSF | CKU | DGWC,O=%%d,N=%%d | Uplink check revealed changed network topology, old distance (O), new distance (N)
* | | TSF | CKU | FAIL | No reply received when checking uplink
* | | TSF | SID | OK,ID=%%d | Node ID assigned
* |!| TSF | SID | FAIL,ID=%%d | Assigned ID is invalid
* | | TSF | PNG | SEND,TO=%%d | Send ping to destination (TO)
* | | TSF | WUR | MS=%%lu | Wait until transport ready, timeout (MS)
* | | TSF | MSG | ACK REQ | ACK message requested
* | | TSF | MSG | ACK | ACK message, do not proceed but forward to callback
* | | TSF | MSG | FPAR RES,ID=%%d,D=%%d | Response to find parent received from node (ID) with distance (D) to GW
* | | TSF | MSG | FPAR PREF FOUND | Preferred parent found, i.e. parent defined via MY_PARENT_NODE_ID
* | | TSF | MSG | FPAR OK,ID=%%d,D=%%d | Find parent response from node (ID) is valid, distance (D) to GW
* | | TSF | MSG | FPAR INACTIVE | Find parent response received, but no find parent request active, skip response
* | | TSF | MSG | FPAR REQ,ID=%%d | Find parent request from node (ID)
* | | TSF | MSG | PINGED,ID=%%d,HP=%%d | Node pinged by node (ID) with (HP) hops
* | | TSF | MSG | PONG RECV,HP=%%d | Pinged node replied with (HP) hops
* | | TSF | MSG | BC | Broadcast message received
* | | TSF | MSG | GWL OK | Link to GW ok
* | | TSF | MSG | FWD BC MSG | Controlled broadcast message forwarding
* | | TSF | MSG | RCV CB | Hand over message to @ref receive() callback function
* | | TSF | MSG | REL MSG | Relay message
* | | TSF | MSG | REL PxNG,HP=%%d | Relay PING/PONG message, increment hop counter (HP)
* |!| TSF | MSG | LEN=%%d,EXP=%%d | Invalid message length (LEN), exptected length (EXP)
* |!| TSF | MSG | PVER,%%d!=%%d | Message protocol version mismatch (actual!=expected)
* |!| TSF | MSG | SIGN VERIFY FAIL | Signing verification failed
* |!| TSF | MSG | REL MSG,NORP | Node received a message for relaying, but node is not a repeater, message skipped
* |!| TSF | MSG | SIGN FAIL | Signing message failed
* |!| TSF | MSG | GWL FAIL | GW uplink failed
* |!| TSF | MSG | ID TK INVALID | Token for ID request invalid
* | | TSF | SAN | OK | Sanity check passed
* |!| TSF | SAN | FAIL | Sanity check failed, attempt to re-initialize radio
* | | TSF | CRT | OK | Clearing routing table successful
* | | TSF | LRT | OK | Loading routing table successful
* | | TSF | SRT | OK | Saving routing table successful
* |!| TSF | RTE | FPAR ACTIVE | Finding parent active, message not sent
* |!| TSF | RTE | DST %%d UNKNOWN | Routing for destination (DST) unknown, send message to parent
* | | TSF | RTE | N2N OK | Node-to-node communication succeeded
* |!| TSF | RTE | N2N FAIL | Node-to-node communication failed, handing over to parent for re-routing
* | | TSF | RRT | ROUTE N=%%d,R=%%d | Routing table, messages to node (N) are routed via node (R)
* |!| TSF | SND | TNR | Transport not ready, message cannot be sent
* | | TSF | TDI | TSL | Set transport to sleep
* | | TSF | TDI | TPD | Power down transport
* | | TSF | TRI | TRI | Reinitialise transport
* | | TSF | TRI | TSB | Set transport to standby
* | | TSF | SIR | CMD=%d,VAL=%d | Get signal report
*
*
* Incoming / outgoing messages:
*
* See <a href="https://www.mysensors.org/download/serial_api_20">here</a> for more detail on the format and definitions.
*
* Receiving a message
* - TSF:MSG:READ,sender-last-destination,s=%%d,c=%%d,t=%%d,pt=%%d,l=%%d,sg=%%d:%%s
*
* Sending a message
* - [!/?]TSF:MSG:SEND,sender-last-next-destination,s=%%d,c=%%d,t=%%d,pt=%%d,l=%%d,sg=%%d,ft=%%d,st=%%s:%%s
*
* Prepended char:
* - <b>none</b>=sending OK
* - <b>!</b>=error sending
* - <b>?</b>=sending status unknown
* Message fields:
* - <b>s</b>=sensor ID
* - <b>c</b>=command
* - <b>t</b>=msg type
* - <b>pt</b>=payload type
* - <b>l</b>=length
* - <b>sg</b>=signing flag
* - <b>ft</b>=failed uplink transmission counter
* - <b>st</b>=send status, OK=success, NACK=no radio ACK received
*
* @brief API declaration for MyTransport
*
*/

#ifndef MyTransport_h
#define MyTransport_h

#include "hal/transport/MyTransportHAL.h"

#ifndef MY_TRANSPORT_MAX_TX_FAILURES
#if defined(MY_REPEATER_FEATURE)
#define MY_TRANSPORT_MAX_TX_FAILURES (10u) //!< search for a new parent node after this many transmission failures, higher threshold for repeating nodes
#else
#define MY_TRANSPORT_MAX_TX_FAILURES (5u) //!< search for a new parent node after this many transmission failures, lower threshold for non-repeating nodes
#endif
#endif

#ifndef MY_TRANSPORT_MAX_TSM_FAILURES
#define MY_TRANSPORT_MAX_TSM_FAILURES (7u) //!< Max. number of consecutive TSM failure state entries (3bits)
#endif

#ifndef MY_TRANSPORT_TIMEOUT_FAILURE_STATE_MS
#define MY_TRANSPORT_TIMEOUT_FAILURE_STATE_MS (10*1000ul) //!< Duration failure state (in ms)
#endif
#ifndef MY_TRANSPORT_TIMEOUT_EXT_FAILURE_STATE_MS
#define MY_TRANSPORT_TIMEOUT_EXT_FAILURE_STATE_MS (60*1000ul) //!< Duration extended failure state (in ms)
#endif
#ifndef MY_TRANSPORT_STATE_TIMEOUT_MS
#define MY_TRANSPORT_STATE_TIMEOUT_MS (2*1000ul) //!< general state timeout (in ms)
#endif
#ifndef MY_TRANSPORT_CHKUPL_INTERVAL_MS
#define MY_TRANSPORT_CHKUPL_INTERVAL_MS (10*1000ul) //!< Interval to re-check uplink (in ms)
#endif
#ifndef MY_TRANSPORT_STATE_RETRIES
#define MY_TRANSPORT_STATE_RETRIES (3u) //!< retries before switching to FAILURE
#endif

#define AUTO (255u) //!< ID 255 is reserved
#define BROADCAST_ADDRESS (255u) //!< broadcasts are addressed to ID 255
#define DISTANCE_INVALID (255u) //!< invalid distance when searching for parent
#define MAX_HOPS (254u) //!< maximal number of hops for ping/pong
#define INVALID_HOPS (255u) //!< invalid hops
#define MAX_SUBSEQ_MSGS (5u) //!< Maximum number of subsequently processed messages in FIFO (to prevent transport deadlock if HW issue)
#define UPLINK_QUALITY_WEIGHT (0.05f) //!< UPLINK_QUALITY_WEIGHT


// parent node check
#if defined(MY_PARENT_NODE_IS_STATIC) && !defined(MY_PARENT_NODE_ID)
#error MY_PARENT_NODE_IS_STATIC but no MY_PARENT_NODE_ID defined!
#endif

#define _autoFindParent (bool)(MY_PARENT_NODE_ID == AUTO) //!< returns true if static parent id is undefined
#define isValidDistance(_distance) (bool)(_distance!=DISTANCE_INVALID) //!< returns true if distance is valid
#define isValidParent(_parent) (bool)(_parent != AUTO) //!< returns true if parent is valid

/**
* @brief Callback type
*/
typedef void(*transportCallback_t)(void);

/**
* @brief Node configuration
*
* This structure stores node-related configurations
*/
typedef struct {
uint8_t nodeId; //!< Current node id
uint8_t parentNodeId; //!< Where this node sends its messages
uint8_t distanceGW; //!< This nodes distance to sensor net gateway (number of hops)
uint8_t passiveMode : 1; //!< Passive mode
uint8_t reserved : 7; //!< Reserved
} transportConfig_t;

/**
* @brief SM state
*
* This structure stores SM state definitions
*/
typedef struct {
void(*Transition)(void); //!< state transition function
void(*Update)(void); //!< state update function
} transportState_t;
/**
* @brief Datatype for internal RSSI storage
*/
typedef int16_t transportRSSI_t; //!< Datatype for internal RSSI storage

// helper macro for conversion
#define transportInternalToRSSI(__value) ((int16_t)__value>>4) //!< Convert internal RSSI to RSSI
#define transportRSSItoInternal(__value) ((transportRSSI_t)__value<<4) //!< Convert RSSI to internal RSSI

/**
* @brief Status variables and SM state
*
* This structure stores transport status and SM variables
*/
typedef struct {
// SM variables
transportState_t *currentState; //!< pointer to current FSM state
uint32_t stateEnter; //!< state enter timepoint
// general transport variables
uint32_t lastUplinkCheck; //!< last uplink check, required to prevent GW flooding
// 8 bits
bool findingParentNode : 1; //!< flag finding parent node is active
bool preferredParentFound : 1; //!< flag preferred parent found
bool uplinkOk : 1; //!< flag uplink ok
bool pingActive : 1; //!< flag ping active
bool transportActive : 1; //!< flag transport active
uint8_t stateRetries : 3; //!< retries / state re-enter (max 7)
// 8 bits
uint8_t failedUplinkTransmissions : 4; //!< counter failed uplink transmissions (max 15)
uint8_t failureCounter : 3; //!< counter for TSM failures (max 7)
bool msgReceived : 1; //!< flag message received

uint8_t pingResponse; //!< stores I_PONG hops
transportRSSI_t uplinkQualityRSSI; //!< Uplink quality, internal RSSI representation
} transportSM_t;

/**
* @brief RAM routing table
*/
typedef struct {
uint8_t route[SIZE_ROUTES]; //!< route for node
} routingTable_t;

// PRIVATE functions

/**
* @brief Initialize SM variables and transport HW
*/
void stInitTransition(void);
/**
* @brief Initialize transport
*/
void stInitUpdate(void);
/**
* @brief Find parent
*/
void stParentTransition(void);
/**
* @brief Verify find parent responses
*/
void stParentUpdate(void);
/**
* @brief Send ID request
*/
void stIDTransition(void);
/**
* @brief Verify ID response and GW link
*/
void stIDUpdate(void);
/**
* @brief Send uplink ping request
*/
void stUplinkTransition(void);
/**
* @brief Verify uplink response
*/
void stUplinkUpdate(void);
/**
* @brief Set transport OK
*/
void stReadyTransition(void);
/**
* @brief Monitor transport link
*/
void stReadyUpdate(void);
/**
* @brief Transport failure and power down radio
*/
void stFailureTransition(void);
/**
* @brief Re-initialize transport after timeout
*/
void stFailureUpdate(void);
/**
* @brief Switch SM state
* @param newState New state to switch SM to
*/
void transportSwitchSM(transportState_t &newState);
/**
* @brief Update SM state
*/
void transportUpdateSM(void);
/**
* @brief Request time in current SM state
* @return ms in current state
*/
uint32_t transportTimeInState(void);
/**
* @brief Call transport driver sanity check
*/
void transportInvokeSanityCheck(void);
/**
* @brief Process all pending messages in RX FIFO
*/
void transportProcessFIFO(void);
/**
* @brief Receive message from RX FIFO and process
*/
void transportProcessMessage(void);
/**
* @brief Assign node ID
* @param newNodeId New node ID
* @return true if node ID is valid and successfully assigned
*/
bool transportAssignNodeID(const uint8_t newNodeId);
/**
* @brief Wait and process messages for a defined amount of time until specified message received
* @param waitingMS Time to wait and process incoming messages in ms
* @param cmd Specific command
* @param msgType Specific message type
* @return true if specified command received within waiting time
*/
bool transportWait(const uint32_t waitingMS, const uint8_t cmd, const uint8_t msgType);
/**
* @brief Ping node
* @param targetId Node to be pinged
* @return hops from pinged node or 255 if no answer received within 2000ms
*/
uint8_t transportPingNode(const uint8_t targetId);
/**
* @brief Send and route message according to destination
*
* This function is used in MyTransport and omits the transport state check, i.e. message can be sent even if transport is not ready
*
* @param message
* @return true if message sent successfully
*/
bool transportRouteMessage(MyMessage &message);
/**
* @brief Send and route message according to destination with transport state check
* @param message
* @return true if message sent successfully and false if sending error or transport !OK
*/
bool transportSendRoute(MyMessage &message);
/**
* @brief Send message to recipient
* @param to Recipient of message
* @param message
* @return true if message sent successfully
*/
bool transportSendWrite(const uint8_t to, MyMessage &message);
/**
* @brief Check uplink to GW, includes flooding control
* @param force to override flood control timer
* @return true if uplink ok
*/
bool transportCheckUplink(const bool force = false);

// PUBLIC functions

/**
* @brief Wait until transport is ready
* @param waitingMS timeout in MS, set 0 (default) for no timeout, i.e. wait indefinitely. For a node in standalone mode (optional network connection) set >0 to allow a node entering the main loop() function.
* @return true if transport is ready
*/
bool transportWaitUntilReady(const uint32_t waitingMS = 0);
/**
* @brief Initialize transport and SM
*/
void transportInitialise(void);
/**
* @brief Process FIFO msg and update SM
*/
void transportProcess(void);
/**
* @brief Flag transport ready
* @return true if transport is initialized and ready
*/
bool isTransportReady(void);
/**
* @brief Flag searching parent ongoing
* @return true if transport is searching for parent
*/
bool isTransportSearchingParent(void);
/**
* @brief Flag TSM extended failure
* @return true if TSM had too many consecutive failure state entries
*/
bool isTransportExtendedFailure(void);
/**
* @brief Flag valid message received
* @return true if valid message received, needs to be reset if used
*/
bool isMessageReceived(void);
/**
* @brief Reset message received flag
*/
void resetMessageReceived(void);
/**
* @brief Clear routing table
*/
void transportClearRoutingTable(void);
/**
* @brief Return heart beat
* @return MS in current state
*/
uint32_t transportGetHeartbeat(void);
/**
* @brief Load routing table from EEPROM to RAM.
* Only for GW devices with enough RAM, i.e. ESP8266, RPI Sensebender GW, etc.
* Atmega328 has only limited amount of RAM
*/
void transportLoadRoutingTable(void);
/**
* @brief Save routing table to EEPROM.
*/
void transportSaveRoutingTable(void);
/**
* @brief Update routing table
* @param node
* @param route
*/
void transportSetRoute(const uint8_t node, const uint8_t route);
/**
* @brief Load route to node
* @param node
* @return route to node
*/
uint8_t transportGetRoute(const uint8_t node);
/**
* @brief Reports content of routing table
*/
void transportReportRoutingTable(void);
/**
* @brief Get node ID
* @return node ID
*/
uint8_t transportGetNodeId(void);
/**
* @brief Get parent node ID
* @return parent node ID
*/
uint8_t transportGetParentNodeId(void);
/**
* @brief Get distance to GW
* @return distance (=hops) to GW
*/
uint8_t transportGetDistanceGW(void);
/**
* @brief Toggle passive mode, i.e. transport does not wait for ACK
* @param OnOff
*/
void transportTogglePassiveMode(const bool OnOff);
/**
* @brief Disable transport, if xxx_POWER_PIN is defined, transport is powered down, else send to sleep
*/
void transportDisable(void);
/**
* @brief Reinitialise transport. Put transport to standby - If xxx_POWER_PIN set, power up and go to standby
*/
void transportReInitialise(void);
/**
* @brief Get transport signal report
* @param command:
* R = RSSI (if available) of incoming @ref I_SIGNAL_REPORT_REQUEST message (from last hop)
* R! = RSSI (if available) of ACK to @ref I_SIGNAL_REPORT_REVERSE message received from last hop
* S = SNR (if available) of incoming @ref I_SIGNAL_REPORT_REQUEST message (from last hop)
* S! = SNR (if available) of ACK to @ref I_SIGNAL_REPORT_REVERSE message received from last hop
* P = TX powerlevel in %
* T = TX powerlevel in dBm
* U = Uplink quality (via ACK from parent node), avg. RSSI
* @return Signal report (if report is not available, INVALID_RSSI, INVALID_SNR, INVALID_PERCENT, or INVALID_LEVEL is sent instead)
*/
int16_t transportSignalReport(const char command);

/**
* @brief Get transport signal report
* @param signalReport
* @return report
*/
int16_t transportGetSignalReport(const signalReport_t signalReport);

#endif // MyTransport_h
/** @}*/

+ 65
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/core/Version.h View File

@@ -0,0 +1,65 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

/**
* @file Version.h
*
* @defgroup Versiongrp Version
* @ingroup internals
* @{
*
* This file defines the MySensors library version number
* Please adjust for new releases.

* These helper macros generate a numerical and alphanumerical (see http://www.semver.org) representation of the library version number, i.e
*
* | SemVer | Numerical | Comments
* |-------------|-------------|------------------
* | 2.1.0 | 0x020100FF | final
* | 2.1.1-beta | 0x02010100 | first pre-release
* | 2.1.1 | 0x020101FF | final
* | 2.2.0-beta | 0x02020000 | first pre-release
* | 2.2.0-rc.1 | 0x02020001 |
* | 2.2.0-rc.2 | 0x02020002 |
* | 2.2.0 | 0x020200FF | final
*/

#ifndef Version_h
#define Version_h

#define STR_HELPER(x) #x //!< Helper macro, STR_HELPER()
#define STR(x) STR_HELPER(x) //!< Helper macro, STR()

#define MYSENSORS_LIBRARY_VERSION_MAJOR 2 //!< Major release version
#define MYSENSORS_LIBRARY_VERSION_MINOR 3 //!< Minor release version
#define MYSENSORS_LIBRARY_VERSION_PATCH 1 //!< Patch version
#define MYSENSORS_LIBRARY_VERSION_PRERELEASE "beta" //!< Pre-release suffix, i.e. alpha, beta, rc.1, etc
#define MYSENSORS_LIBRARY_VERSION_PRERELEASE_NUMBER 0xFF //!< incremental counter, starting at 0x00. 0xFF for final release


#if (MYSENSORS_LIBRARY_VERSION_PRERELEASE_NUMBER != 0xFF)
#define MYSENSORS_LIBRARY_VERSION STR(MYSENSORS_LIBRARY_VERSION_MAJOR) "." STR(MYSENSORS_LIBRARY_VERSION_MINOR) "." STR(MYSENSORS_LIBRARY_VERSION_PATCH) "-" MYSENSORS_LIBRARY_VERSION_PRERELEASE //!< pre-release versioning
#else
#define MYSENSORS_LIBRARY_VERSION STR(MYSENSORS_LIBRARY_VERSION_MAJOR) "." STR(MYSENSORS_LIBRARY_VERSION_MINOR) "." STR(MYSENSORS_LIBRARY_VERSION_PATCH) //!< final release versioning
#endif

#define MYSENSORS_LIBRARY_VERSION_INT ( ((uint32_t)MYSENSORS_LIBRARY_VERSION_MAJOR) << 24 | ((uint32_t)MYSENSORS_LIBRARY_VERSION_MINOR) << 16 | ((uint32_t)MYSENSORS_LIBRARY_VERSION_PATCH) << 8 | ((uint32_t)MYSENSORS_LIBRARY_VERSION_PRERELEASE_NUMBER) ) //!< numerical versioning

#endif // Version_h
/** @}*/

+ 631
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AES/AES.cpp View File

@@ -0,0 +1,631 @@
#include "AES.h"

/*
---------------------------------------------------------------------------
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.

LICENSE TERMS

The redistribution and use of this software (with or without changes)
is allowed without the payment of fees or royalties provided that:

1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;

2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;

3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.

DISCLAIMER

This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue 09/09/2006

This is an AES implementation that uses only 8-bit byte operations on the
cipher state (there are options to use 32-bit types if available).

The combination of mix columns and byte substitution used here is based on
that developed by Karl Malbrain. His contribution is acknowledged.
*/

/* This version derived by Mark Tillotson 2012-01-23, tidied up, slimmed down
and tailored to 8-bit microcontroller abilities and Arduino datatypes.

The s-box and inverse s-box were retained as tables (0.5kB PROGMEM) but all
the other transformations are coded to save table space. Many efficiency
improvments to the routines mix_sub_columns() and inv_mix_sub_columns()
(mainly common sub-expression elimination).

Only the routines with precalculated subkey schedule are retained (together
with set_key() - this does however mean each AES object takes 240 bytes of
RAM, alas)

The CBC routines side-effect the iv argument (so that successive calls work
together correctly).

All the encryption and decryption routines work with plain == cipher for
in-place encryption, note.

*/


/* functions for finite field multiplication in the AES Galois field */

/* code was modified by george spanos <spaniakos@gmail.com>
* 16/12/14
*/

// GF(2^8) stuff

#define WPOLY 0x011B
#define DPOLY 0x008D

const static byte s_fwd [0x100] PROGMEM = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
} ;

const static byte s_inv [0x100] PROGMEM = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
} ;

// times 2 in the GF(2^8)
#define f2(x) (((x) & 0x80) ? (x << 1) ^ WPOLY : x << 1)
#define d2(x) (((x) >> 1) ^ ((x) & 1 ? DPOLY : 0))

static byte s_box (byte x)
{
// return fwd_affine (pgm_read_byte (&inv [x])) ;
return pgm_read_byte (& s_fwd [x]) ;
}

// Inverse Sbox
static byte is_box (byte x)
{
// return pgm_read_byte (&inv [inv_affine (x)]) ;
return pgm_read_byte (& s_inv [x]) ;
}


static void xor_block (byte * d, byte * s)
{
for (byte i = 0 ; i < N_BLOCK ; i += 4) {
*d++ ^= *s++ ; // some unrolling
*d++ ^= *s++ ;
*d++ ^= *s++ ;
*d++ ^= *s++ ;
}
}

static void copy_and_key (byte * d, byte * s, byte * k)
{
for (byte i = 0 ; i < N_BLOCK ; i += 4) {
*d++ = *s++ ^ *k++ ; // some unrolling
*d++ = *s++ ^ *k++ ;
*d++ = *s++ ^ *k++ ;
*d++ = *s++ ^ *k++ ;
}
}

// #define add_round_key(d, k) xor_block (d, k)

/* SUB ROW PHASE */

static void shift_sub_rows (byte st [N_BLOCK])
{
st [0] = s_box (st [0]) ;
st [4] = s_box (st [4]) ;
st [8] = s_box (st [8]) ;
st [12] = s_box (st [12]) ;

byte tt = st [1] ;
st [1] = s_box (st [5]) ;
st [5] = s_box (st [9]) ;
st [9] = s_box (st [13]) ;
st [13] = s_box (tt) ;

tt = st[2] ;
st [2] = s_box (st [10]) ;
st [10] = s_box (tt) ;
tt = st[6] ;
st [6] = s_box (st [14]) ;
st [14] = s_box (tt) ;

tt = st[15] ;
st [15] = s_box (st [11]) ;
st [11] = s_box (st [7]) ;
st [7] = s_box (st [3]) ;
st [3] = s_box (tt) ;
}

static void inv_shift_sub_rows (byte st[N_BLOCK])
{
st [0] = is_box (st[0]) ;
st [4] = is_box (st [4]);
st [8] = is_box (st[8]) ;
st [12] = is_box (st [12]);

byte tt = st[13] ;
st [13] = is_box (st [9]) ;
st [9] = is_box (st [5]) ;
st [5] = is_box (st [1]) ;
st [1] = is_box (tt) ;

tt = st [2] ;
st [2] = is_box (st [10]) ;
st [10] = is_box (tt) ;
tt = st [6] ;
st [6] = is_box (st [14]) ;
st [14] = is_box (tt) ;

tt = st [3] ;
st [3] = is_box (st [7]) ;
st [7] = is_box (st [11]) ;
st [11] = is_box (st [15]) ;
st [15] = is_box (tt) ;
}

/* SUB COLUMNS PHASE */

static void mix_sub_columns (byte dt[N_BLOCK], byte st[N_BLOCK])
{
byte j = 5 ;
byte k = 10 ;
byte l = 15 ;
for (byte i = 0 ; i < N_BLOCK ; i += N_COL) {
byte a = st [i] ;
byte b = st [j] ;
j = (j+N_COL) & 15 ;
byte c = st [k] ;
k = (k+N_COL) & 15 ;
byte d = st [l] ;
l = (l+N_COL) & 15 ;
byte a1 = s_box (a), b1 = s_box (b), c1 = s_box (c), d1 = s_box (d) ;
byte a2 = f2(a1), b2 = f2(b1), c2 = f2(c1), d2 = f2(d1) ;
dt[i] = a2 ^ b2^b1 ^ c1 ^ d1 ;
dt[i+1] = a1 ^ b2 ^ c2^c1 ^ d1 ;
dt[i+2] = a1 ^ b1 ^ c2 ^ d2^d1 ;
dt[i+3] = a2^a1 ^ b1 ^ c1 ^ d2 ;
}
}

static void inv_mix_sub_columns (byte dt[N_BLOCK], byte st[N_BLOCK])
{
for (byte i = 0 ; i < N_BLOCK ; i += N_COL) {
byte a1 = st [i] ;
byte b1 = st [i+1] ;
byte c1 = st [i+2] ;
byte d1 = st [i+3] ;
byte a2 = f2(a1), b2 = f2(b1), c2 = f2(c1), d2 = f2(d1) ;
byte a4 = f2(a2), b4 = f2(b2), c4 = f2(c2), d4 = f2(d2) ;
byte a8 = f2(a4), b8 = f2(b4), c8 = f2(c4), d8 = f2(d4) ;
byte a9 = a8 ^ a1,b9 = b8 ^ b1,c9 = c8 ^ c1,d9 = d8 ^ d1 ;
byte ac = a8 ^ a4,bc = b8 ^ b4,cc = c8 ^ c4,dc = d8 ^ d4 ;

dt[i] = is_box (ac^a2 ^ b9^b2 ^ cc^c1 ^ d9) ;
dt[(i+5)&15] = is_box (a9 ^ bc^b2 ^ c9^c2 ^ dc^d1) ;
dt[(i+10)&15] = is_box (ac^a1 ^ b9 ^ cc^c2 ^ d9^d2) ;
dt[(i+15)&15] = is_box (a9^a2 ^ bc^b1 ^ c9 ^ dc^d2) ;
}
}

/******************************************************************************/

AES::AES()
{
byte ar_iv[8] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 };
IVC = 0x01;
round = 0;
pad = 0;
size = 0;
memset(key_sched, 0, KEY_SCHEDULE_BYTES);
memcpy(iv,ar_iv,8);
memcpy(iv+8,ar_iv,8);
arr_pad[0] = 0x01;
arr_pad[1] = 0x02;
arr_pad[2] = 0x03;
arr_pad[3] = 0x04;
arr_pad[4] = 0x05;
arr_pad[5] = 0x06;
arr_pad[6] = 0x07;
arr_pad[7] = 0x08;
arr_pad[8] = 0x09;
arr_pad[9] = 0x0a;
arr_pad[10] = 0x0b;
arr_pad[11] = 0x0c;
arr_pad[12] = 0x0d;
arr_pad[13] = 0x0e;
arr_pad[14] = 0x0f;
}

/******************************************************************************/

byte AES::set_key (byte key [], int keylen)
{
byte hi ;
switch (keylen) {
case 16:
case 128:
keylen = 16; // 10 rounds
round = 10 ;
break;
case 24:
case 192:
keylen = 24; // 12 rounds
round = 12 ;
break;
case 32:
case 256:
keylen = 32; // 14 rounds
round = 14 ;
break;
default:
round = 0;
return AES_FAILURE;
}
hi = (round + 1) << 4 ;
copy_n_bytes (key_sched, key, keylen) ;
byte t[4] ;
byte next = keylen ;
for (byte cc = keylen, rc = 1 ; cc < hi ; cc += N_COL) {
for (byte i = 0 ; i < N_COL ; i++) {
t[i] = key_sched [cc-4+i] ;
}
if (cc == next) {
next += keylen ;
byte ttt = t[0] ;
t[0] = s_box (t[1]) ^ rc ;
t[1] = s_box (t[2]) ;
t[2] = s_box (t[3]) ;
t[3] = s_box (ttt) ;
rc = f2 (rc) ;
} else if (keylen == 32 && (cc & 31) == 16) {
for (byte i = 0 ; i < 4 ; i++) {
t[i] = s_box (t[i]) ;
}
}
byte tt = cc - keylen ;
for (byte i = 0 ; i < N_COL ; i++) {
key_sched [cc + i] = key_sched [tt + i] ^ t[i] ;
}
}
return AES_SUCCESS ;
}

/******************************************************************************/

void AES::clean ()
{
for (byte i = 0 ; i < KEY_SCHEDULE_BYTES ; i++) {
key_sched [i] = 0 ;
}
round = 0 ;
}

/******************************************************************************/

void AES::copy_n_bytes (byte * d, byte * s, byte nn)
{
while (nn >= 4) {
*d++ = *s++ ; // some unrolling
*d++ = *s++ ;
*d++ = *s++ ;
*d++ = *s++ ;
nn -= 4 ;
}
while (nn--) {
*d++ = *s++ ;
}
}

/******************************************************************************/

byte AES::encrypt (byte plain [N_BLOCK], byte cipher [N_BLOCK])
{
if (round) {
byte s1 [N_BLOCK], r ;
copy_and_key (s1, plain, (byte*) (key_sched)) ;

for (r = 1 ; r < round ; r++) {
byte s2 [N_BLOCK] ;
mix_sub_columns (s2, s1) ;
copy_and_key (s1, s2, (byte*) (key_sched + r * N_BLOCK)) ;
}
shift_sub_rows (s1) ;
copy_and_key (cipher, s1, (byte*) (key_sched + r * N_BLOCK)) ;
} else {
return AES_FAILURE ;
}
return AES_SUCCESS ;
}

/******************************************************************************/

byte AES::cbc_encrypt (byte * plain, byte * cipher, int n_block, byte iv [N_BLOCK])
{
while (n_block--) {
xor_block (iv, plain) ;
if (encrypt (iv, iv) != AES_SUCCESS) {
return AES_FAILURE ;
}
copy_n_bytes (cipher, iv, N_BLOCK) ;
plain += N_BLOCK ;
cipher += N_BLOCK ;
}
return AES_SUCCESS ;
}

/******************************************************************************/

byte AES::cbc_encrypt (byte * plain, byte * cipher, int n_block)
{
while (n_block--) {
xor_block (iv, plain) ;
if (encrypt (iv, iv) != AES_SUCCESS) {
return AES_FAILURE ;
}
copy_n_bytes (cipher, iv, N_BLOCK) ;
plain += N_BLOCK ;
cipher += N_BLOCK ;
}
return AES_SUCCESS ;
}

/******************************************************************************/

byte AES::decrypt (byte cipher [N_BLOCK], byte plain [N_BLOCK])
{
if (round) {
byte s1 [N_BLOCK] ;
copy_and_key (s1, cipher, (byte*) (key_sched + round * N_BLOCK)) ;
inv_shift_sub_rows (s1) ;

for (byte r = round ; --r ; ) {
byte s2 [N_BLOCK] ;
copy_and_key (s2, s1, (byte*) (key_sched + r * N_BLOCK)) ;
inv_mix_sub_columns (s1, s2) ;
}
copy_and_key (plain, s1, (byte*) (key_sched)) ;
} else {
return AES_FAILURE ;
}
return AES_SUCCESS ;
}

/******************************************************************************/

byte AES::cbc_decrypt (byte * cipher, byte * plain, int n_block, byte iv [N_BLOCK])
{
while (n_block--) {
byte tmp [N_BLOCK] ;
copy_n_bytes (tmp, cipher, N_BLOCK) ;
if (decrypt (cipher, plain) != AES_SUCCESS) {
return AES_FAILURE ;
}
xor_block (plain, iv) ;
copy_n_bytes (iv, tmp, N_BLOCK) ;
plain += N_BLOCK ;
cipher += N_BLOCK;
}
return AES_SUCCESS ;
}

/******************************************************************************/

byte AES::cbc_decrypt (byte * cipher, byte * plain, int n_block)
{
while (n_block--) {
byte tmp [N_BLOCK] ;
copy_n_bytes (tmp, cipher, N_BLOCK) ;
if (decrypt (cipher, plain) != AES_SUCCESS) {
return AES_FAILURE ;
}
xor_block (plain, iv) ;
copy_n_bytes (iv, tmp, N_BLOCK) ;
plain += N_BLOCK ;
cipher += N_BLOCK;
}
return AES_SUCCESS ;
}

/*****************************************************************************/

void AES::set_IV(unsigned long long int IVCl)
{
memcpy(iv,&IVCl,8);
memcpy(iv+8,&IVCl,8);
IVC = IVCl;
}

/******************************************************************************/

void AES::iv_inc()
{
IVC += 1;
memcpy(iv,&IVC,8);
memcpy(iv+8,&IVC,8);
}

/******************************************************************************/

int AES::get_size()
{
return size;
}

/******************************************************************************/

void AES::set_size(int sizel)
{
size = sizel;
}


/******************************************************************************/

void AES::get_IV(byte *out)
{
memcpy(out,&IVC,8);
memcpy(out+8,&IVC,8);
}

/******************************************************************************/

void AES::calc_size_n_pad(int p_size)
{
int s_of_p = p_size - 1;
if ( s_of_p % N_BLOCK == 0) {
size = s_of_p;
} else {
size = s_of_p + (N_BLOCK-(s_of_p % N_BLOCK));
}
pad = size - s_of_p;
}

/******************************************************************************/

void AES::padPlaintext(void* in,byte* out)
{
memcpy(out,in,size);
for (int i = size-pad; i < size; i++) {
;
out[i] = arr_pad[pad - 1];
}
}

/******************************************************************************/

bool AES::CheckPad(byte* in,int lsize)
{
if (in[lsize-1] <= 0x0f) {
int lpad = (int)in[lsize-1];
for (int i = lsize - 1; i >= lsize-lpad; i--) {
if (arr_pad[lpad - 1] != in[i]) {
return false;
}
}
} else {
return true;
}
return true;
}

/******************************************************************************/

void AES::printArray(byte output[],bool p_pad)
{
uint8_t i,j;
uint8_t loops = size/N_BLOCK;
uint8_t outp = N_BLOCK;
for (j = 0; j < loops; j += 1) {
if (p_pad && (j == (loops - 1)) ) {
outp = N_BLOCK - pad;
}
for (i = 0; i < outp; i++) {
printf_P(PSTR("%c"),output[j*N_BLOCK + i]);
}
}
printf_P(PSTR("\n"));
}

/******************************************************************************/

void AES::printArray(byte output[],int sizel)
{
for (int i = 0; i < sizel; i++) {
printf_P(PSTR("%x"),output[i]);
}
printf_P(PSTR("\n"));
}


/******************************************************************************/

void AES::do_aes_encrypt(byte *plain,int size_p,byte *cipher,byte *key, int bits,
byte ivl [N_BLOCK])
{
calc_size_n_pad(size_p);
byte plain_p[get_size()];
padPlaintext(plain,plain_p);
int blocks = get_size() / N_BLOCK;
set_key (key, bits) ;
cbc_encrypt (plain_p, cipher, blocks, ivl);
}

/******************************************************************************/

void AES::do_aes_encrypt(byte *plain,int size_p,byte *cipher,byte *key, int bits)
{
calc_size_n_pad(size_p);
byte plain_p[get_size()];
padPlaintext(plain,plain_p);
int blocks = get_size() / N_BLOCK;
set_key (key, bits) ;
cbc_encrypt (plain_p, cipher, blocks);
}

/******************************************************************************/

void AES::do_aes_decrypt(byte *cipher,int size_c,byte *plain,byte *key, int bits,
byte ivl [N_BLOCK])
{
set_size(size_c);
int blocks = size_c / N_BLOCK;
set_key (key, bits);
cbc_decrypt (cipher,plain, blocks, ivl);
}

/******************************************************************************/

void AES::do_aes_decrypt(byte *cipher,int size_c,byte *plain,byte *key, int bits)
{
set_size(size_c);
int blocks = size_c / N_BLOCK;
set_key (key, bits);
cbc_decrypt (cipher,plain, blocks);
}


/******************************************************************************/

#if defined(AES_LINUX)
double AES::millis()
{
gettimeofday(&tv, NULL);
return (tv.tv_sec + 0.000001 * tv.tv_usec);
}
#endif

+ 381
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AES/AES.h View File

@@ -0,0 +1,381 @@
#ifndef __AES_H__
#define __AES_H__

#include "AES_config.h"
/*
---------------------------------------------------------------------------
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.

LICENSE TERMS

The redistribution and use of this software (with or without changes)
is allowed without the payment of fees or royalties provided that:

1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;

2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;

3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.

DISCLAIMER

This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue 09/09/2006

This is an AES implementation that uses only 8-bit byte operations on the
cipher state.
*/

/* code was modified by george spanos <spaniakos@gmail.com>
* 16/12/14
*/
/** AES class */
class AES
{
public:

/* The following calls are for a precomputed key schedule

NOTE: If the length_type used for the key length is an
unsigned 8-bit character, a key length of 256 bits must
be entered as a length in bytes (valid inputs are hence
128, 192, 16, 24 and 32).
*/
/** \fn AES()
* \brief AES constructor
*
* This function initialized an instance of AES.
*/
AES();

/** Set the cipher key for the pre-keyed version.
* @param key[] pointer to the key string.
* @param keylen Integer that indicates the length of the key.
* @note NOTE: If the length_type used for the key length is an unsigned 8-bit character,
* a key length of 256 bits must be entered as a length in bytes
* (valid inputs are hence 128, 192, 16, 24 and 32).
*
*/
byte set_key (byte key[], int keylen) ;

/** clean up subkeys after use.
*
*/
void clean () ; // delete key schedule after use

/** copying and xoring utilities.
* @param *AESt byte pointer of the AEStination array.
* @param *src byte pointer of the source array.
* @param n byte, indicating the sizeof the bytes to be copied.
* @note this is an alternative for memcpy(void *s1,const void *s2, site_t n),
* i have not updated the function in the implementation yet, but it is considered a future plan.
*
*/
void copy_n_bytes (byte * AESt, byte * src, byte n) ;

/** Encrypt a single block of 16 bytes .
* @param plain Array of the plaintext.
* @param cipher Array of the ciphertext.
* @note The N_BLOCK is defined in AES_config.h as,
* @code #define N_ROW 4
* #define N_COL 4
* #define N_BLOCK (N_ROW * N_COL)
* @endcode
* Changed to that will change the Block_size.
* @return 0 if SUCCESS or -1 if FAILURE
*
*/
byte encrypt (byte plain [N_BLOCK], byte cipher [N_BLOCK]) ;

/** CBC encrypt a number of blocks (input and return an IV).
*
* @param *plain Pointer, points to the plaintex.
* @param *cipher Pointer, points to the ciphertext that will be created.
* @param n_block integer, indicated the number of blocks to be ciphered.
* @param iv byte Array that holds the IV (initialization vector).
* @return 0 if SUCCESS or -1 if FAILURE
*
*/
byte cbc_encrypt (byte * plain, byte * cipher, int n_block, byte iv [N_BLOCK]) ;

/** CBC encrypt a number of blocks (input and return an IV).
*
* @param *plain Pointer, points to the plaintex.
* @param *cipher Pointer, points to the ciphertext that will be created.
* @param n_block integer, indicated the number of blocks to be ciphered.
* @return 0 if SUCCESS or -1 if FAILURE
*
*/
byte cbc_encrypt (byte * plain, byte * cipher, int n_block) ;


/** Decrypt a single block of 16 bytes
* @param cipher Array of the ciphertext.
* @param plain Array of the plaintext.
* @note The N_BLOCK is defined in AES_config.h as,
* @code #define N_ROW 4
* #define N_COL 4
* #define N_BLOCK (N_ROW * N_COL)
* @endcode
* Changed to that will change the Block_size.
* @return 0 if SUCCESS or -1 if FAILURE
*
*/
byte decrypt (byte cipher [N_BLOCK], byte plain [N_BLOCK]) ;

/** CBC decrypt a number of blocks (input and return an IV)
*
* @param *cipher Pointer, points to the ciphertext that will be created.
* @param *plain Pointer, points to the plaintex.
* @param n_block integer, indicated the number of blocks to be ciphered.
* @param iv byte Array that holds the IV (initialization vector).
* @return 0 if SUCCESS or -1 if FAILURE
*
*/
byte cbc_decrypt (byte * cipher, byte * plain, int n_block, byte iv [N_BLOCK]) ;

/** CBC decrypt a number of blocks (input and return an IV)
*
* @param *cipher Pointer, points to the ciphertext that will be created.
* @param *plain Pointer, points to the plaintex.
* @param n_block integer, indicated the number of blocks to be ciphered.
* @return 0 if SUCCESS or -1 if FAILURE
*
*/
byte cbc_decrypt (byte * cipher, byte * plain, int n_block) ;

/** Sets IV (initialization vector) and IVC (IV counter).
* This function changes the ivc and iv variables needed for AES.
*
* @param IVCl int or hex value of iv , ex. 0x0000000000000001
* @note example:
* @code unsigned long long int my_iv = 01234567; @endcode
*/
void set_IV(unsigned long long int IVCl);

/** increase the iv (initialization vector) and IVC (IV counter) by 1
*
* This function increased the VI by one step in order to have a different IV each time
*
*/
void iv_inc();

/** Getter method for size
*
* This function return the size
* @return an integer, that is the size of the of the padded plaintext,
* thus, the size of the ciphertext.
*/
int get_size();

/** Setter method for size
*
* This function sets the size of the plaintext+pad
*
*/
void set_size(int sizel);

/** Getter method for IV
*
* This function return the IV
* @param out byte pointer that gets the IV.
* @return none, the IV is writed to the out pointer.
*/
void get_IV(byte *out);

/** Calculates the size of the plaintext and the padding.
*
* Calculates the size of theplaintext with the padding
* and the size of the padding needed. Moreover it stores them in their class variables.
*
* @param p_size the size of the byte array ex sizeof(plaintext)
*/
void calc_size_n_pad(int p_size);

/** Pads the plaintext
*
* This function pads the plaintext and returns an char array with the
* plaintext and the padding in order for the plaintext to be compatible with
* 16bit size blocks required by AES
*
* @param in the string of the plaintext in a byte array
* @param out The string of the out array.
* @return no return, The padded plaintext is stored in the out pointer.
*/
void padPlaintext(void* in,byte* out);

/** Check the if the padding is correct.
*
* This functions checks the padding of the plaintext.
*
* @param in the string of the plaintext in a byte array
* @param size the size of the string
* @return true if correct / false if not
*/
bool CheckPad(byte* in,int size);

/** Prints the array given.
*
* This function prints the given array and pad,
* It is mainlly used for debugging purpuses or to output the string.
*
* @param output[] the string of the text in a byte array
* @param p_pad optional, used to print with out the padding characters
*/
void printArray(byte output[],bool p_pad = true);

/** Prints the array given.
*
* This function prints the given array in Hexadecimal.
*
* @param output[] the string of the text in a byte array
* @param sizel the size of the array.
*/
void printArray(byte output[],int sizel);

/** User friendly implementation of AES-CBC encryption.
*
* @param *plain pointer to the plaintext
* @param size_p size of the plaintext
* @param *cipher pointer to the ciphertext
* @param *key pointer to the key that will be used.
* @param bits bits of the encryption/decrpytion
* @param ivl the initialization vector IV that will be used for encryption.
* @note The key will be stored in class variable.
*/
void do_aes_encrypt(byte *plain,int size_p,byte *cipher,byte *key, int bits, byte ivl [N_BLOCK]);

/** User friendly implementation of AES-CBC encryption.
*
* @param *plain pointer to the plaintext
* @param size_p size of the plaintext
* @param *cipher pointer to the ciphertext
* @param *key pointer to the key that will be used.
* @param bits bits of the encryption/decrpytion
* @note The key will be stored in class variable.
*/
void do_aes_encrypt(byte *plain,int size_p,byte *cipher,byte *key, int bits);

/** User friendly implementation of AES-CBC decryption.
*
* @param *cipher pointer to the ciphertext
* @param size_c size of the ciphertext
* @param *plain pointer to the plaintext
* @param *key pointer to the key that will be used.
* @param bits bits of the encryption/decrpytion
* @param ivl the initialization vector IV that will be used for decryption.
* @note The key will be stored in class variable.
*/
void do_aes_decrypt(byte *cipher,int size_c,byte *plain,byte *key, int bits, byte ivl [N_BLOCK]);

/** User friendly implementation of AES-CBC decryption.
*
* @param *cipher pointer to the ciphertext
* @param size_c size of the ciphertext
* @param *plain pointer to the plaintext
* @param *key pointer to the key that will be used.
* @param bits bits of the encryption/decrpytion
* @note The key will be stored in class variable.
*/
void do_aes_decrypt(byte *cipher,int size_c,byte *plain,byte *key, int bits);

#if defined(AES_LINUX)
/**
* used in linux in order to retrieve the time in milliseconds.
*
* @return returns the milliseconds in a double format.
*/
double millis();
#endif
private:
int round ;/**< holds the number of rounds to be used. */
byte key_sched [KEY_SCHEDULE_BYTES]
;/**< holds the pre-computed key for the encryption/decrpytion. */
unsigned long long int IVC;/**< holds the initialization vector counter in numerical format. */
byte iv[16];/**< holds the initialization vector that will be used in the cipher. */
int pad;/**< holds the size of the padding. */
int size;/**< hold the size of the plaintext to be ciphered */
#if defined(AES_LINUX)
timeval tv;/**< holds the time value on linux */
byte arr_pad[15];/**< holds the hexadecimal padding values on linux */
#else
byte arr_pad[15];// = { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };/**< holds the hexadecimal padding values */
#endif
} ;


#endif

/**
* @defgroup aeslib AES library for Arduino and Raspberry pi
* @ingroup internals
*
* @section AesGoals design Goals
*
* This library is AESigned to be...
* @li Fast and efficient.
* @li Able to effectively encrypt and decrypt any size of string.
* @li Able to encrypt and decrypt using AES
* @li Able to encrypt and decrypt using AES-CBC
* @li Easy for the user to use in his programs.
*
* @section Acknowledgements Acknowledgements
* This is an AES library for the Arduino, based on tzikis's AES library, which you can find <a href= "https://github.com/tzikis/arduino">here:</a>.<br />
* Tzikis library was based on scottmac`s library, which you can find <a href="https://github.com/scottmac/arduino">here:</a><br />
*
* @section Installation Installation
* <h3>Arduino</h3>
* Create a folder named _AES_ in the _libraries_ folder inside your Arduino sketch folder. If the
* libraries folder doesn't exist, create it. Then copy everything inside. (re)launch the Arduino IDE.<br />
* You're done. Time for a mojito
*
* <h3>Raspberry pi</h3>
* <b>install</b><br /><br />
*
* sudo make install<br />
* cd examples_Rpi<br />
* make<br /><br />
*
* <b>What to do after changes to the library</b><br /><br />
* sudo make clean<br />
* sudo make install<br />
* cd examples_Rpi<br />
* make clean<br />
* make<br /><br />
* <b>What to do after changes to a sketch</b><br /><br />
* cd examples_Rpi<br />
* make \<sketch\><br /><br />
* or <br />
* make clean<br />
* make<br /><br /><br />
* <b>How to start a sketch</b><br /><br />
* cd examples_Rpi<br />
* sudo ./\<sketch\><br /><br />
*
* @section AesNews News
*
* If issues are discovered with the documentation, please report them <a href="https://github.com/spaniakos/spaniakos.github.io/issues"> here</a>
* @section AesUseful Useful References
*
* Please refer to:
*
* @li <a href="http://spaniakos.github.io/AES/classAES.html"><b>AES</b> Class Documentation</a>
* @li <a href="https://github.com/spaniakos/AES/archive/master.zip"><b>Download</b></a>
* @li <a href="https://github.com/spaniakos/AES/"><b>Source Code</b></a>
* @li <a href="http://spaniakos.github.io/">All spaniakos Documentation Main Page</a>
*
* @section AesBoard_Support Board Support
*
* Most standard Arduino based boards are supported:
* - Arduino
* - Intel Galileo support
* - Raspberry Pi Support
*
* - The library has not been tested to other boards, but it should suppport ATMega 328 based boards,Mega Boards,Arduino Due,ATTiny board
*/

+ 50
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AES/AES_config.h View File

@@ -0,0 +1,50 @@
/* code was modified by george spanos <spaniakos@gmail.com>
* 16/12/14
*/

#ifndef __AES_CONFIG_H__
#define __AES_CONFIG_H__

#if (defined(__linux) || defined(linux)) && !defined(__ARDUINO_X86__)

#define AES_LINUX

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#else
#include <Arduino.h>
#endif

#include <stdint.h>
#include <string.h>

#if defined(__ARDUINO_X86__) || (defined (__linux) || defined (linux))
#undef PROGMEM
#define PROGMEM __attribute__(( section(".progmem.data") ))
#define pgm_read_byte(p) (*(p))
typedef unsigned char byte;
#define printf_P printf
#define PSTR(x) (x)
#elif defined(ARDUINO_ARCH_ESP8266)
#include <pgmspace.h>
#elif defined(ARDUINO_ARCH_ESP32)
#include <pgmspace.h>
#elif defined(ARDUINO_ARCH_SAMD)
#define printf_P printf
#else
#include <avr/pgmspace.h>
#endif

#define N_ROW 4
#define N_COL 4
#define N_BLOCK (N_ROW * N_COL)
#define N_MAX_ROUNDS 14
#define KEY_SCHEDULE_BYTES ((N_MAX_ROUNDS + 1) * N_BLOCK)
#define AES_SUCCESS (0)
#define AES_FAILURE (-1)

#endif

+ 91
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AES/README.MD View File

@@ -0,0 +1,91 @@
### Arduino
just run the sketched aftel loading the libraries.

### Raspberry pi
install
```
sudo make install
cd examples_Rpi
make
```

What to do after changes to the library
```
sudo make clean
sudo make install
cd examples_Rpi
make clean
make
```

What to do after changes to a sketch
```
cd examples_Rpi
make <sketch>

or
make clean
make
```

How to start a sketch
```
cd examples_Rpi
sudo ./<sketch>
```

This is a derived work from Brian Gladman's AES implementation for byte-oriented
processors, here's the licence terms:

/*
---------------------------------------------------------------------------
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.

LICENSE TERMS

The redistribution and use of this software (with or without changes)
is allowed without the payment of fees or royalties provided that:

1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;

2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;

3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.

DISCLAIMER

This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue 09/09/2006

This is an AES implementation that uses only 8-bit byte operations on the
cipher state (there are options to use 32-bit types if available).

The combination of mix columns and byte substitution used here is based on
that developed by Karl Malbrain. His contribution is acknowledged.
*/

/* This version derived by Mark Tillotson 2012-01-23, tidied up, slimmed down
and tailored to 8-bit microcontroller abilities and Arduino datatypes.

The s-box and inverse s-box were retained as tables (0.5kB PROGMEM) but all
the other transformations are coded to save table space. Many efficiency
improvments to the routines mix_sub_columns() and inv_mix_sub_columns()
(mainly common sub-expression elimination).

Only the routines with precalculated subkey schedule are retained (together
with set_key() - this does however mean each AES object takes 240 bytes of
RAM, alas)

The CBC routines side-effect the iv argument (so that successive calls work
together correctly).

All the encryption and decryption routines work with plain == cipher for
in-place encryption, note.

*/

+ 7
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AES/keywords.txt View File

@@ -0,0 +1,7 @@
AES KEYWORD1
set_key KEYWORD2
clean KEYWORD2
encrypt KEYWORD2
decrypt KEYWORD2
cbc_encrypt KEYWORD2
cbc_decrypt KEYWORD2

+ 594
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/ATSHA204/ATSHA204.cpp View File

@@ -0,0 +1,594 @@
#include "Arduino.h"
#include "ATSHA204.h"

/* Local data and function prototypes */

static uint8_t device_pin;
#ifdef ARDUINO_ARCH_AVR
static volatile uint8_t *device_port_DDR, *device_port_OUT, *device_port_IN;
#endif
static void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc);
static uint8_t sha204c_check_crc(uint8_t *response);
static void swi_set_signal_pin(uint8_t is_high);
static uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer);
static uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer);
static uint8_t swi_send_byte(uint8_t value);
static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response);
static uint8_t sha204c_resync(uint8_t size, uint8_t *response);
static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer,
uint8_t execution_delay, uint8_t execution_timeout);

/* SWI bit bang functions */

static void swi_set_signal_pin(uint8_t is_high)
{
SHA204_SET_OUTPUT();

if (is_high) {
SHA204_POUT_HIGH();
} else {
SHA204_POUT_LOW();
}
}

static uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer)
{
uint8_t i, bit_mask;

// Disable interrupts while sending.
noInterrupts(); //swi_disable_interrupts();

// Set signal pin as output.
SHA204_POUT_HIGH();
SHA204_SET_OUTPUT();


// Wait turn around time.
delayMicroseconds(RX_TX_DELAY); //RX_TX_DELAY;

for (i = 0; i < count; i++) {
for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) {
if (bit_mask & buffer[i]) {
SHA204_POUT_LOW(); //*device_port_OUT &= ~device_pin;
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
SHA204_POUT_HIGH(); //*device_port_OUT |= device_pin;
delayMicroseconds(7*BIT_DELAY); //BIT_DELAY_7;
} else {
// Send a zero bit.
SHA204_POUT_LOW(); //*device_port_OUT &= ~device_pin;
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
SHA204_POUT_HIGH(); //*device_port_OUT |= device_pin;
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
SHA204_POUT_LOW(); //*device_port_OUT &= ~device_pin;
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
SHA204_POUT_HIGH(); //*device_port_OUT |= device_pin;
delayMicroseconds(5*BIT_DELAY); //BIT_DELAY_5;
}
}
}
interrupts(); //swi_enable_interrupts();
return SWI_FUNCTION_RETCODE_SUCCESS;
}

static uint8_t swi_send_byte(uint8_t value)
{
return swi_send_bytes(1, &value);
}

static uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer)
{
uint8_t status = SWI_FUNCTION_RETCODE_SUCCESS;
uint8_t i;
uint8_t bit_mask;
uint8_t pulse_count;
uint8_t timeout_count;

// Disable interrupts while receiving.
noInterrupts(); //swi_disable_interrupts();

// Configure signal pin as input.
SHA204_SET_INPUT();

// Receive bits and store in buffer.
for (i = 0; i < count; i++) {
for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) {
pulse_count = 0;

// Make sure that the variable below is big enough.
// Change it to uint16_t if 255 is too small, but be aware that
// the loop resolution decreases on an 8-bit controller in that case.
timeout_count = START_PULSE_TIME_OUT;

// Detect start bit.
while (--timeout_count > 0) {
// Wait for falling edge.
if (SHA204_PIN_READ() == 0) {
break;
}
}

if (timeout_count == 0) {
status = SWI_FUNCTION_RETCODE_TIMEOUT;
break;
}

do {
// Wait for rising edge.
if (SHA204_PIN_READ() != 0) {
// For an Atmel microcontroller this might be faster than "pulse_count++".
pulse_count = 1;
break;
}
} while (--timeout_count > 0);

if (pulse_count == 0) {
status = SWI_FUNCTION_RETCODE_TIMEOUT;
break;
}

// Trying to measure the time of start bit and calculating the timeout
// for zero bit detection is not accurate enough for an 8 MHz 8-bit CPU.
// So let's just wait the maximum time for the falling edge of a zero bit
// to arrive after we have detected the rising edge of the start bit.
timeout_count = ZERO_PULSE_TIME_OUT;

// Detect possible edge indicating zero bit.
do {
if (SHA204_PIN_READ() == 0) {
// For an Atmel microcontroller this might be faster than "pulse_count++".
pulse_count = 2;
break;
}
} while (--timeout_count > 0);

// Wait for rising edge of zero pulse before returning. Otherwise we might interpret
// its rising edge as the next start pulse.
if (pulse_count == 2) {
do {
if (SHA204_PIN_READ() != 0) {
break;
}
} while (timeout_count-- > 0);
}

// Update byte at current buffer index.
else {
buffer[i] |= bit_mask; // received "one" bit
}
}

if (status != SWI_FUNCTION_RETCODE_SUCCESS) {
break;
}
}
interrupts(); //swi_enable_interrupts();

if (status == SWI_FUNCTION_RETCODE_TIMEOUT) {
if (i > 0) {
// Indicate that we timed out after having received at least one byte.
status = SWI_FUNCTION_RETCODE_RX_FAIL;
}
}
return status;
}

/* Physical functions */

static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response)
{
uint8_t i;
uint8_t ret_code;

for (i = 0; i < size; i++) {
response[i] = 0;
}

(void) swi_send_byte(SHA204_SWI_FLAG_TX);

ret_code = swi_receive_bytes(size, response);
if (ret_code == SWI_FUNCTION_RETCODE_SUCCESS || ret_code == SWI_FUNCTION_RETCODE_RX_FAIL) {
uint8_t count_byte;
count_byte = response[SHA204_BUFFER_POS_COUNT];
if ((count_byte < SHA204_RSP_SIZE_MIN) || (count_byte > size)) {
return SHA204_INVALID_SIZE;
}

return SHA204_SUCCESS;
}

// Translate error so that the Communication layer
// can distinguish between a real error or the
// device being busy executing a command.
if (ret_code == SWI_FUNCTION_RETCODE_TIMEOUT) {
return SHA204_RX_NO_RESPONSE;
} else {
return SHA204_RX_FAIL;
}
}

/* Communication functions */

static uint8_t sha204c_resync(uint8_t size, uint8_t *response)
{
// Try to re-synchronize without sending a Wake token
// (step 1 of the re-synchronization process).
delay(SHA204_SYNC_TIMEOUT);
uint8_t ret_code = sha204p_receive_response(size, response);
if (ret_code == SHA204_SUCCESS) {
return ret_code;
}

// We lost communication. Send a Wake pulse and try
// to receive a response (steps 2 and 3 of the
// re-synchronization process).
atsha204_sleep();
ret_code = atsha204_wakeup(response);

// Translate a return value of success into one
// that indicates that the device had to be woken up
// and might have lost its TempKey.
return (ret_code == SHA204_SUCCESS ? SHA204_RESYNC_WITH_WAKEUP : ret_code);
}

static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer,
uint8_t execution_delay, uint8_t execution_timeout)
{
uint8_t ret_code = SHA204_FUNC_FAIL;
uint8_t ret_code_resync;
uint8_t n_retries_send;
uint8_t n_retries_receive;
uint8_t i;
uint8_t status_byte;
uint8_t count = tx_buffer[SHA204_BUFFER_POS_COUNT];
uint8_t count_minus_crc = count - SHA204_CRC_SIZE;
uint16_t execution_timeout_us = (uint16_t) (execution_timeout * 1000) + SHA204_RESPONSE_TIMEOUT;
volatile uint16_t timeout_countdown;

// Append CRC.
sha204c_calculate_crc(count_minus_crc, tx_buffer, tx_buffer + count_minus_crc);

// Retry loop for sending a command and receiving a response.
n_retries_send = SHA204_RETRY_COUNT + 1;

while ((n_retries_send-- > 0) && (ret_code != SHA204_SUCCESS)) {
// Send command.
ret_code = swi_send_byte(SHA204_SWI_FLAG_CMD);
if (ret_code != SWI_FUNCTION_RETCODE_SUCCESS) {
ret_code = SHA204_COMM_FAIL;
} else {
ret_code = swi_send_bytes(count, tx_buffer);
}

if (ret_code != SHA204_SUCCESS) {
if (sha204c_resync(rx_size, rx_buffer) == SHA204_RX_NO_RESPONSE) {
return ret_code; // The device seems to be dead in the water.
} else {
continue;
}
}

// Wait minimum command execution time and then start polling for a response.
delay(execution_delay);

// Retry loop for receiving a response.
n_retries_receive = SHA204_RETRY_COUNT + 1;
while (n_retries_receive-- > 0) {
// Reset response buffer.
for (i = 0; i < rx_size; i++) {
rx_buffer[i] = 0;
}

// Poll for response.
timeout_countdown = execution_timeout_us;
do {
ret_code = sha204p_receive_response(rx_size, rx_buffer);
timeout_countdown -= SHA204_RESPONSE_TIMEOUT;
} while ((timeout_countdown > SHA204_RESPONSE_TIMEOUT) && (ret_code == SHA204_RX_NO_RESPONSE));

if (ret_code == SHA204_RX_NO_RESPONSE) {
// We did not receive a response. Re-synchronize and send command again.
if (sha204c_resync(rx_size, rx_buffer) == SHA204_RX_NO_RESPONSE) {
// The device seems to be dead in the water.
return ret_code;
} else {
break;
}
}

// Check whether we received a valid response.
if (ret_code == SHA204_INVALID_SIZE) {
// We see 0xFF for the count when communication got out of sync.
ret_code_resync = sha204c_resync(rx_size, rx_buffer);
if (ret_code_resync == SHA204_SUCCESS) {
// We did not have to wake up the device. Try receiving response again.
continue;
}
if (ret_code_resync == SHA204_RESYNC_WITH_WAKEUP) {
// We could re-synchronize, but only after waking up the device.
// Re-send command.
break;
} else {
// We failed to re-synchronize.
return ret_code;
}
}

// We received a response of valid size.
// Check the consistency of the response.
ret_code = sha204c_check_crc(rx_buffer);
if (ret_code == SHA204_SUCCESS) {
// Received valid response.
if (rx_buffer[SHA204_BUFFER_POS_COUNT] > SHA204_RSP_SIZE_MIN) {
// Received non-status response. We are done.
return ret_code;
}

// Received status response.
status_byte = rx_buffer[SHA204_BUFFER_POS_STATUS];

// Translate the three possible device status error codes
// into library return codes.
if (status_byte == SHA204_STATUS_BYTE_PARSE) {
return SHA204_PARSE_ERROR;
}
if (status_byte == SHA204_STATUS_BYTE_EXEC) {
return SHA204_CMD_FAIL;
}
if (status_byte == SHA204_STATUS_BYTE_COMM) {
// In case of the device status byte indicating a communication
// error this function exits the retry loop for receiving a response
// and enters the overall retry loop
// (send command / receive response).
ret_code = SHA204_STATUS_CRC;
break;
}

// Received status response from CheckMAC, DeriveKey, GenDig,
// Lock, Nonce, Pause, UpdateExtra, or Write command.
return ret_code;
}

else {
// Received response with incorrect CRC.
ret_code_resync = sha204c_resync(rx_size, rx_buffer);
if (ret_code_resync == SHA204_SUCCESS) {
// We did not have to wake up the device. Try receiving response again.
continue;
}
if (ret_code_resync == SHA204_RESYNC_WITH_WAKEUP) {
// We could re-synchronize, but only after waking up the device.
// Re-send command.
break;
} else {
// We failed to re-synchronize.
return ret_code;
}
} // block end of check response consistency

} // block end of receive retry loop

} // block end of send and receive retry loop

return ret_code;
}

/* CRC Calculator and Checker */

static void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc)
{
uint8_t counter;
uint16_t crc_register = 0;
uint16_t polynom = 0x8005;
uint8_t shift_register;
uint8_t data_bit, crc_bit;

for (counter = 0; counter < length; counter++) {
for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) {
data_bit = (data[counter] & shift_register) ? 1 : 0;
crc_bit = crc_register >> 15;

// Shift CRC to the left by 1.
crc_register <<= 1;

if ((data_bit ^ crc_bit) != 0) {
crc_register ^= polynom;
}
}
}
crc[0] = (uint8_t) (crc_register & 0x00FF);
crc[1] = (uint8_t) (crc_register >> 8);
}

static uint8_t sha204c_check_crc(uint8_t *response)
{
uint8_t crc[SHA204_CRC_SIZE];
uint8_t count = response[SHA204_BUFFER_POS_COUNT];

count -= SHA204_CRC_SIZE;
sha204c_calculate_crc(count, response, crc);

return (crc[0] == response[count] && crc[1] == response[count + 1])
? SHA204_SUCCESS : SHA204_BAD_CRC;
}

/* Public functions */

void atsha204_init(uint8_t pin)
{
#if defined(ARDUINO_ARCH_AVR)
device_pin = digitalPinToBitMask(pin); // Find the bit value of the pin
uint8_t port = digitalPinToPort(pin); // temoporarily used to get the next three registers

// Point to data direction register port of pin
device_port_DDR = portModeRegister(port);
// Point to output register of pin
device_port_OUT = portOutputRegister(port);
// Point to input register of pin
device_port_IN = portInputRegister(port);
#else
device_pin = pin;
#endif
}

void atsha204_idle(void)
{
swi_send_byte(SHA204_SWI_FLAG_IDLE);
}

void atsha204_sleep(void)
{
swi_send_byte(SHA204_SWI_FLAG_SLEEP);
}

uint8_t atsha204_wakeup(uint8_t *response)
{
swi_set_signal_pin(0);
delayMicroseconds(10*SHA204_WAKEUP_PULSE_WIDTH);
swi_set_signal_pin(1);
delay(SHA204_WAKEUP_DELAY);

uint8_t ret_code = sha204p_receive_response(SHA204_RSP_SIZE_MIN, response);
if (ret_code != SHA204_SUCCESS) {
return ret_code;
}

// Verify status response.
if (response[SHA204_BUFFER_POS_COUNT] != SHA204_RSP_SIZE_MIN) {
ret_code = SHA204_INVALID_SIZE;
} else if (response[SHA204_BUFFER_POS_STATUS] != SHA204_STATUS_BYTE_WAKEUP) {
ret_code = SHA204_COMM_FAIL;
} else {
if ((response[SHA204_RSP_SIZE_MIN - SHA204_CRC_SIZE] != 0x33)
|| (response[SHA204_RSP_SIZE_MIN + 1 - SHA204_CRC_SIZE] != 0x43)) {
ret_code = SHA204_BAD_CRC;
}
}
if (ret_code != SHA204_SUCCESS) {
delay(SHA204_COMMAND_EXEC_MAX);
}

return ret_code;
}

uint8_t atsha204_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
uint8_t datalen1, uint8_t *data1, uint8_t tx_size, uint8_t *tx_buffer, uint8_t rx_size,
uint8_t *rx_buffer)
{
uint8_t poll_delay, poll_timeout, response_size;
uint8_t *p_buffer;
uint8_t len;
(void)tx_size;

// Supply delays and response size.
switch (op_code) {
case SHA204_GENDIG:
poll_delay = GENDIG_DELAY;
poll_timeout = GENDIG_EXEC_MAX - GENDIG_DELAY;
response_size = GENDIG_RSP_SIZE;
break;

case SHA204_HMAC:
poll_delay = HMAC_DELAY;
poll_timeout = HMAC_EXEC_MAX - HMAC_DELAY;
response_size = HMAC_RSP_SIZE;
break;

case SHA204_NONCE:
poll_delay = NONCE_DELAY;
poll_timeout = NONCE_EXEC_MAX - NONCE_DELAY;
response_size = param1 == NONCE_MODE_PASSTHROUGH
? NONCE_RSP_SIZE_SHORT : NONCE_RSP_SIZE_LONG;
break;

case SHA204_RANDOM:
poll_delay = RANDOM_DELAY;
poll_timeout = RANDOM_EXEC_MAX - RANDOM_DELAY;
response_size = RANDOM_RSP_SIZE;
break;

case SHA204_SHA:
poll_delay = SHA_DELAY;
poll_timeout = SHA_EXEC_MAX - SHA_DELAY;
response_size = param1 == SHA_INIT
? SHA_RSP_SIZE_SHORT : SHA_RSP_SIZE_LONG;
break;

case SHA204_WRITE:
poll_delay = WRITE_DELAY;
poll_timeout = WRITE_EXEC_MAX - WRITE_DELAY;
response_size = WRITE_RSP_SIZE;
break;

default:
poll_delay = 0;
poll_timeout = SHA204_COMMAND_EXEC_MAX;
response_size = rx_size;
}

// Assemble command.
len = datalen1 + SHA204_CMD_SIZE_MIN;
p_buffer = tx_buffer;
*p_buffer++ = len;
*p_buffer++ = op_code;
*p_buffer++ = param1;
*p_buffer++ = param2 & 0xFF;
*p_buffer++ = param2 >> 8;

if (datalen1 > 0) {
memcpy(p_buffer, data1, datalen1);
p_buffer += datalen1;
}

sha204c_calculate_crc(len - SHA204_CRC_SIZE, tx_buffer, p_buffer);

// Send command and receive response.
return sha204c_send_and_receive(&tx_buffer[0], response_size,
&rx_buffer[0], poll_delay, poll_timeout);
}

uint8_t atsha204_getSerialNumber(uint8_t * response)
{
uint8_t readCommand[READ_COUNT];
uint8_t readResponse[READ_4_RSP_SIZE];

/* read from bytes 0->3 of config zone */
uint8_t returnCode = atsha204_read(readCommand, readResponse, SHA204_ZONE_CONFIG, ADDRESS_SN03);
if (!returnCode) {
for (int i=0; i<4; i++) {// store bytes 0-3 into respones array
response[i] = readResponse[SHA204_BUFFER_POS_DATA+i];
}

/* read from bytes 8->11 of config zone */
returnCode = atsha204_read(readCommand, readResponse, SHA204_ZONE_CONFIG, ADDRESS_SN47);

for (int i=4; i<8; i++) {// store bytes 4-7 of SN into response array
response[i] = readResponse[SHA204_BUFFER_POS_DATA+(i-4)];
}

if (!returnCode) {
/* Finally if last two reads were successful, read byte 8 of the SN */
returnCode = atsha204_read(readCommand, readResponse, SHA204_ZONE_CONFIG, ADDRESS_SN8);
response[8] = readResponse[SHA204_BUFFER_POS_DATA]; // Byte 8 of SN should always be 0xEE
}
}

return returnCode;
}

uint8_t atsha204_read(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t zone, uint16_t address)
{
uint8_t rx_size;

address >>= 2;

tx_buffer[SHA204_COUNT_IDX] = READ_COUNT;
tx_buffer[SHA204_OPCODE_IDX] = SHA204_READ;
tx_buffer[READ_ZONE_IDX] = zone;
tx_buffer[READ_ADDR_IDX] = (uint8_t) (address & SHA204_ADDRESS_MASK);
tx_buffer[READ_ADDR_IDX + 1] = 0;

rx_size = (zone & SHA204_ZONE_COUNT_FLAG) ? READ_32_RSP_SIZE : READ_4_RSP_SIZE;

return sha204c_send_and_receive(&tx_buffer[0], rx_size, &rx_buffer[0], READ_DELAY,
READ_EXEC_MAX - READ_DELAY);
}

+ 253
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/ATSHA204/ATSHA204.h View File

@@ -0,0 +1,253 @@
#ifndef ATSHA204_H
#define ATSHA204_H
#if !DOXYGEN
#include <Arduino.h>

/* This is a scaled down variant of the ATSHA204 library, tweaked to meet the specific needs of the MySensors library. */

/* Library return codes */
#define SHA204_SUCCESS ((uint8_t) 0x00) //!< Function succeeded.
#define SHA204_PARSE_ERROR ((uint8_t) 0xD2) //!< response status byte indicates parsing error
#define SHA204_CMD_FAIL ((uint8_t) 0xD3) //!< response status byte indicates command execution error
#define SHA204_STATUS_CRC ((uint8_t) 0xD4) //!< response status byte indicates CRC error
#define SHA204_STATUS_UNKNOWN ((uint8_t) 0xD5) //!< response status byte is unknown
#define SHA204_FUNC_FAIL ((uint8_t) 0xE0) //!< Function could not execute due to incorrect condition / state.
#define SHA204_GEN_FAIL ((uint8_t) 0xE1) //!< unspecified error
#define SHA204_BAD_PARAM ((uint8_t) 0xE2) //!< bad argument (out of range, null pointer, etc.)
#define SHA204_INVALID_ID ((uint8_t) 0xE3) //!< invalid device id, id not set
#define SHA204_INVALID_SIZE ((uint8_t) 0xE4) //!< Count value is out of range or greater than buffer size.
#define SHA204_BAD_CRC ((uint8_t) 0xE5) //!< incorrect CRC received
#define SHA204_RX_FAIL ((uint8_t) 0xE6) //!< Timed out while waiting for response. Number of bytes received is > 0.
#define SHA204_RX_NO_RESPONSE ((uint8_t) 0xE7) //!< Not an error while the Command layer is polling for a command response.
#define SHA204_RESYNC_WITH_WAKEUP ((uint8_t) 0xE8) //!< re-synchronization succeeded, but only after generating a Wake-up

#define SHA204_COMM_FAIL ((uint8_t) 0xF0) //!< Communication with device failed. Same as in hardware dependent modules.
#define SHA204_TIMEOUT ((uint8_t) 0xF1) //!< Timed out while waiting for response. Number of bytes received is 0.

/* bitbang_config.h */

#define PORT_ACCESS_TIME (630) //! time it takes to toggle the pin at CPU clock of 16 MHz (ns)
#define START_PULSE_WIDTH (4340) //! width of start pulse (ns)
#define BIT_DELAY (4) //! delay macro for width of one pulse (start pulse or zero pulse, in ns)
#define RX_TX_DELAY (15) //! turn around time when switching from receive to transmit
#define START_PULSE_TIME_OUT (255) //! This value is decremented while waiting for the falling edge of a start pulse.
#define ZERO_PULSE_TIME_OUT (26) //! This value is decremented while waiting for the falling edge of a zero pulse.

/* swi_phys.h */

#define SWI_FUNCTION_RETCODE_SUCCESS ((uint8_t) 0x00) //!< Communication with device succeeded.
#define SWI_FUNCTION_RETCODE_TIMEOUT ((uint8_t) 0xF1) //!< Communication timed out.
#define SWI_FUNCTION_RETCODE_RX_FAIL ((uint8_t) 0xF9) //!< Communication failed after at least one byte was received.

/* sha204_physical.h */

#define SHA204_RSP_SIZE_MIN ((uint8_t) 4) //!< minimum number of bytes in response
#define SHA204_RSP_SIZE_MAX ((uint8_t) 35) //!< maximum size of response packet
#define SHA204_BUFFER_POS_COUNT (0) //!< buffer index of count byte in command or response
#define SHA204_BUFFER_POS_DATA (1) //!< buffer index of data in response
#define SHA204_WAKEUP_PULSE_WIDTH (uint8_t) (6.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5) //! width of Wakeup pulse in 10 us units
#define SHA204_WAKEUP_DELAY (uint8_t) (3.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5) //! delay between Wakeup pulse and communication in ms

/* sha204_swi.c */
#define SHA204_SWI_FLAG_CMD ((uint8_t) 0x77) //!< flag preceding a command
#define SHA204_SWI_FLAG_TX ((uint8_t) 0x88) //!< flag requesting a response
#define SHA204_SWI_FLAG_IDLE ((uint8_t) 0xBB) //!< flag requesting to go into Idle mode
#define SHA204_SWI_FLAG_SLEEP ((uint8_t) 0xCC) //!< flag requesting to go into Sleep mode

/* sha204_comm_marshaling.h */
// command op-code definitions
#define SHA204_GENDIG ((uint8_t) 0x15) //!< GenDig command op-code
#define SHA204_HMAC ((uint8_t) 0x11) //!< HMAC command op-code
#define SHA204_NONCE ((uint8_t) 0x16) //!< Nonce command op-code
#define SHA204_RANDOM ((uint8_t) 0x1B) //!< Random command op-code
#define SHA204_READ ((uint8_t) 0x02) //!< Read command op-code
#define SHA204_SHA ((uint8_t) 0x47) //!< SHA command op-code
#define SHA204_WRITE ((uint8_t) 0x12) //!< Write command op-code

// packet size definitions
#define SHA204_RSP_SIZE_VAL ((uint8_t) 7) //!< size of response packet containing four bytes of data

// definitions for command packet indexes common to all commands
#define SHA204_COUNT_IDX ( 0) //!< command packet index for count
#define SHA204_OPCODE_IDX ( 1) //!< command packet index for op-code
#define SHA204_PARAM1_IDX ( 2) //!< command packet index for first parameter
#define SHA204_PARAM2_IDX ( 3) //!< command packet index for second parameter
#define SHA204_DATA_IDX ( 5) //!< command packet index for second parameter

// zone definitions
#define SHA204_ZONE_CONFIG ((uint8_t) 0x00) //!< Configuration zone
#define SHA204_ZONE_OTP ((uint8_t) 0x01) //!< OTP (One Time Programming) zone
#define SHA204_ZONE_DATA ((uint8_t) 0x02) //!< Data zone
#define SHA204_ZONE_MASK ((uint8_t) 0x03) //!< Zone mask
#define SHA204_ZONE_COUNT_FLAG ((uint8_t) 0x80) //!< Zone bit 7 set: Access 32 bytes, otherwise 4 bytes.
#define SHA204_ZONE_ACCESS_4 ((uint8_t) 4) //!< Read or write 4 bytes.
#define SHA204_ZONE_ACCESS_32 ((uint8_t) 32) //!< Read or write 32 bytes.
#define SHA204_ADDRESS_MASK_CONFIG ( 0x001F) //!< Address bits 5 to 7 are 0 for Configuration zone.
#define SHA204_ADDRESS_MASK_OTP ( 0x000F) //!< Address bits 4 to 7 are 0 for OTP zone.
#define SHA204_ADDRESS_MASK ( 0x007F) //!< Address bit 7 to 15 are always 0.

// GenDig command definitions
#define GENDIG_ZONE_IDX SHA204_PARAM1_IDX //!< GenDig command index for zone
#define GENDIG_KEYID_IDX SHA204_PARAM2_IDX //!< GenDig command index for key id
#define GENDIG_DATA_IDX SHA204_DATA_IDX //!< GenDig command index for optional data
#define GENDIG_COUNT SHA204_CMD_SIZE_MIN //!< GenDig command packet size without "other data"
#define GENDIG_COUNT_DATA (11) //!< GenDig command packet size with "other data"
#define GENDIG_OTHER_DATA_SIZE (4) //!< GenDig size of "other data"
#define GENDIG_ZONE_CONFIG ((uint8_t) 0) //!< GenDig zone id config
#define GENDIG_ZONE_OTP ((uint8_t) 1) //!< GenDig zone id OTP
#define GENDIG_ZONE_DATA ((uint8_t) 2) //!< GenDig zone id data

// HMAC command definitions
#define HMAC_MODE_IDX SHA204_PARAM1_IDX //!< HMAC command index for mode
#define HMAC_KEYID_IDX SHA204_PARAM2_IDX //!< HMAC command index for key id
#define HMAC_COUNT SHA204_CMD_SIZE_MIN //!< HMAC command packet size
#define HMAC_MODE_MASK ((uint8_t) 0x74) //!< HMAC mode bits 0, 1, 3, and 7 are 0.
#define HMAC_MODE_SOURCE_FLAG_MATCH ((uint8_t) 0x04) //!< HMAC mode bit 2: match TempKey.SourceFlag

// Nonce command definitions
#define NONCE_MODE_IDX SHA204_PARAM1_IDX //!< Nonce command index for mode
#define NONCE_PARAM2_IDX SHA204_PARAM2_IDX //!< Nonce command index for 2. parameter
#define NONCE_INPUT_IDX SHA204_DATA_IDX //!< Nonce command index for input data
#define NONCE_COUNT_SHORT (27) //!< Nonce command packet size for 20 bytes of data
#define NONCE_COUNT_LONG (39) //!< Nonce command packet size for 32 bytes of data
#define NONCE_MODE_MASK ((uint8_t) 3) //!< Nonce mode bits 2 to 7 are 0.
#define NONCE_MODE_SEED_UPDATE ((uint8_t) 0x00) //!< Nonce mode: update seed
#define NONCE_MODE_NO_SEED_UPDATE ((uint8_t) 0x01) //!< Nonce mode: do not update seed
#define NONCE_MODE_INVALID ((uint8_t) 0x02) //!< Nonce mode 2 is invalid.
#define NONCE_MODE_PASSTHROUGH ((uint8_t) 0x03) //!< Nonce mode: pass-through
#define NONCE_NUMIN_SIZE (20) //!< Nonce data length
#define NONCE_NUMIN_SIZE_PASSTHROUGH (32) //!< Nonce data length in pass-through mode (mode = 3)

// Random command definitions
#define RANDOM_MODE_IDX SHA204_PARAM1_IDX //!< Random command index for mode
#define RANDOM_PARAM2_IDX SHA204_PARAM2_IDX //!< Random command index for 2. parameter
#define RANDOM_COUNT SHA204_CMD_SIZE_MIN //!< Random command packet size
#define RANDOM_SEED_UPDATE ((uint8_t) 0x00) //!< Random mode for automatic seed update
#define RANDOM_NO_SEED_UPDATE ((uint8_t) 0x01) //!< Random mode for no seed update

// Read command definitions
#define READ_ZONE_IDX SHA204_PARAM1_IDX //!< Read command index for zone
#define READ_ADDR_IDX SHA204_PARAM2_IDX //!< Read command index for address
#define READ_COUNT SHA204_CMD_SIZE_MIN //!< Read command packet size
#define READ_ZONE_MASK ((uint8_t) 0x83) //!< Read zone bits 2 to 6 are 0.
#define READ_ZONE_MODE_32_BYTES ((uint8_t) 0x80) //!< Read mode: 32 bytes

// SHA command definitions
#define SHA_MODE_IDX SHA204_PARAM1_IDX //!< SHA command index for mode
#define SHA_PARAM2_IDX SHA204_PARAM2_IDX //!< SHA command index for 2. parameter
#define SHA_COUNT_SHORT SHA204_CMD_SIZE_MIN //!< SHA command packet size for init
#define SHA_COUNT_LONG (71) //!< SHA command packet size for calculation
#define SHA_MSG_SIZE (64) //!< SHA message data size
#define SHA_INIT ((uint8_t) 0x00) //!< SHA mode for init
#define SHA_CALC ((uint8_t) 0x01) //!< SHA mode for calculation

// Write command definitions
#define WRITE_ZONE_IDX SHA204_PARAM1_IDX //!< Write command index for zone
#define WRITE_ADDR_IDX SHA204_PARAM2_IDX //!< Write command index for address
#define WRITE_VALUE_IDX SHA204_DATA_IDX //!< Write command index for data
#define WRITE_MAC_VS_IDX ( 9) //!< Write command index for MAC following short data
#define WRITE_MAC_VL_IDX (37) //!< Write command index for MAC following long data
#define WRITE_COUNT_SHORT (11) //!< Write command packet size with short data and no MAC
#define WRITE_COUNT_LONG (39) //!< Write command packet size with long data and no MAC
#define WRITE_COUNT_SHORT_MAC (43) //!< Write command packet size with short data and MAC
#define WRITE_COUNT_LONG_MAC (71) //!< Write command packet size with long data and MAC
#define WRITE_MAC_SIZE (32) //!< Write MAC size
#define WRITE_ZONE_MASK ((uint8_t) 0xC3) //!< Write zone bits 2 to 5 are 0.
#define WRITE_ZONE_WITH_MAC ((uint8_t) 0x40) //!< Write zone bit 6: write encrypted with MAC

// Response size definitions
#define GENDIG_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of GenDig command
#define HMAC_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of HMAC command
#define NONCE_RSP_SIZE_SHORT SHA204_RSP_SIZE_MIN //!< response size of Nonce command with mode[0:1] = 3
#define NONCE_RSP_SIZE_LONG SHA204_RSP_SIZE_MAX //!< response size of Nonce command
#define RANDOM_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of Random command
#define READ_4_RSP_SIZE SHA204_RSP_SIZE_VAL //!< response size of Read command when reading 4 bytes
#define READ_32_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of Read command when reading 32 bytes
#define SHA_RSP_SIZE_SHORT SHA204_RSP_SIZE_MIN //!< response size of SHA command with mode[0:1] = 0
#define SHA_RSP_SIZE_LONG SHA204_RSP_SIZE_MAX //!< response size of SHA command
#define WRITE_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of Write command

// command timing definitions for minimum execution times (ms)
#define GENDIG_DELAY ((uint8_t) (11.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define HMAC_DELAY ((uint8_t) (27.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define NONCE_DELAY ((uint8_t) (22.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define RANDOM_DELAY ((uint8_t) (11.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define READ_DELAY ((uint8_t) ( 0.4 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define SHA_DELAY ((uint8_t) (11.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define WRITE_DELAY ((uint8_t) ( 4.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))

// command timing definitions for maximum execution times (ms)
#define GENDIG_EXEC_MAX ((uint8_t) (43.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define HMAC_EXEC_MAX ((uint8_t) (69.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define NONCE_EXEC_MAX ((uint8_t) (60.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define RANDOM_EXEC_MAX ((uint8_t) (50.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define READ_EXEC_MAX ((uint8_t) ( 4.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define SHA_EXEC_MAX ((uint8_t) (22.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define WRITE_EXEC_MAX ((uint8_t) (42.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))

/* from sha204_config.h */

#define CPU_CLOCK_DEVIATION_POSITIVE (1.01)
#define CPU_CLOCK_DEVIATION_NEGATIVE (0.99)
#define SHA204_RETRY_COUNT (1)
#define SWI_RECEIVE_TIME_OUT ((uint16_t) 163) //! #START_PULSE_TIME_OUT in us instead of loop counts
#define SWI_US_PER_BYTE ((uint16_t) 313) //! It takes 312.5 us to send a byte (9 single-wire bits / 230400 Baud * 8 flag bits).
#define SHA204_SYNC_TIMEOUT ((uint8_t) 85)//! delay before sending a transmit flag in the synchronization routine
#define SHA204_RESPONSE_TIMEOUT ((uint16_t) SWI_RECEIVE_TIME_OUT + SWI_US_PER_BYTE) //! SWI response timeout is the sum of receive timeout and the time it takes to send the TX flag.

/* from sha204_comm.h */

#define SHA204_COMMAND_EXEC_MAX ((uint8_t) (69.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5)) //! maximum command delay
#define SHA204_CMD_SIZE_MIN ((uint8_t) 7) //! minimum number of bytes in command (from count byte to second CRC byte)
#ifndef SHA204_CMD_SIZE_MAX
#define SHA204_CMD_SIZE_MAX ((uint8_t) SHA_COUNT_LONG) //! maximum size of command packet (SHA)
#endif
#define SHA204_CRC_SIZE ((uint8_t) 2) //! number of CRC bytes
#define SHA204_BUFFER_POS_STATUS (1) //! buffer index of status byte in status response
#define SHA204_BUFFER_POS_DATA (1) //! buffer index of first data byte in data response
#define SHA204_STATUS_BYTE_WAKEUP ((uint8_t) 0x11) //! command parse error
#define SHA204_STATUS_BYTE_PARSE ((uint8_t) 0x03) //! command parse error
#define SHA204_STATUS_BYTE_EXEC ((uint8_t) 0x0F) //! command execution error
#define SHA204_STATUS_BYTE_COMM ((uint8_t) 0xFF) //! communication error

/* EEPROM Addresses */
/* Configuration Zone */
#define ADDRESS_SN03 0 // SN[0:3] are bytes 0->3 of configuration zone
#define ADDRESS_RevNum 4 // bytes 4->7 of config zone are RevNum
#define ADDRESS_SN47 8 // SN[4:7] are bytes 8->11 of config zone
#define ADDRESS_SN8 12 // SN[8] is byte 12 of config zone, should be 0xEE
#define ADDRESS_I2CEN 14 // I2C Enable, bit 0 represents I2C enable status
#define ADDRESS_I2CADD 16 // Defines I2C address of SHA204
#define ADDRESS_OTPMODE 18 // Sets the One-time-programmable mode
#define ADDRESS_SELECTOR 19 // Controls writability of Selector

#define SHA204_SERIAL_SZ 9 // The number of bytes the serial number consists of

/* Low level HW access macros */
/* function calls is not working, as it will have too much overhead */
#if !defined(ARDUINO_ARCH_AVR) // For everything else than AVR use pinMode / digitalWrite
#define SHA204_SET_OUTPUT() pinMode(device_pin, OUTPUT)
#define SHA204_SET_INPUT() pinMode(device_pin, INPUT)
#define SHA204_POUT_HIGH() digitalWrite(device_pin, HIGH)
#define SHA204_POUT_LOW() digitalWrite(device_pin, LOW)
#define SHA204_PIN_READ() digitalRead(device_pin)
#else
#define SHA204_SET_INPUT() *device_port_DDR &= ~device_pin
#define SHA204_SET_OUTPUT() *device_port_DDR |= device_pin
#define SHA204_POUT_HIGH() *device_port_OUT |= device_pin
#define SHA204_POUT_LOW() *device_port_OUT &= ~device_pin
#define SHA204_PIN_READ() (*device_port_IN & device_pin)
#endif

void atsha204_init(uint8_t pin);
void atsha204_idle(void);
void atsha204_sleep(void);
uint8_t atsha204_wakeup(uint8_t *response);
uint8_t atsha204_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
uint8_t datalen1, uint8_t *data1, uint8_t tx_size,
uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer);
uint8_t atsha204_getSerialNumber(uint8_t *response);
uint8_t atsha204_read(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t zone, uint16_t address);

#endif
#endif

+ 377
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/AltSoftSerial.cpp View File

@@ -0,0 +1,377 @@
/* An Alternative Software Serial Library
* http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
* Copyright (c) 2014 PJRC.COM, LLC, Paul Stoffregen, paul@pjrc.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

// Revisions are now tracked on GitHub
// https://github.com/PaulStoffregen/AltSoftSerial
//
// Version 1.2: Support Teensy 3.x
//
// Version 1.1: Improve performance in receiver code
//
// Version 1.0: Initial Release


#include "AltSoftSerial.h"
#include "config/AltSoftSerial_Boards.h"
#include "config/AltSoftSerial_Timers.h"

/****************************************/
/** Initialization **/
/****************************************/

static uint16_t ticks_per_bit=0;
bool AltSoftSerial::timing_error=false;

static uint8_t rx_state;
static uint8_t rx_byte;
static uint8_t rx_bit = 0;
static uint16_t rx_target;
static uint16_t rx_stop_ticks=0;
static volatile uint8_t rx_buffer_head;
static volatile uint8_t rx_buffer_tail;
#define RX_BUFFER_SIZE 80
static volatile uint8_t rx_buffer[RX_BUFFER_SIZE];

static volatile uint8_t tx_state=0;
static uint8_t tx_byte;
static uint8_t tx_bit;
static volatile uint8_t tx_buffer_head;
static volatile uint8_t tx_buffer_tail;
#define TX_BUFFER_SIZE 68
static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];


#ifndef INPUT_PULLUP
#define INPUT_PULLUP INPUT
#endif

#define MAX_COUNTS_PER_BIT 6241 // 65536 / 10.5

void AltSoftSerial::init(uint32_t cycles_per_bit)
{
//Serial.printf("cycles_per_bit = %d\n", cycles_per_bit);
if (cycles_per_bit < MAX_COUNTS_PER_BIT) {
CONFIG_TIMER_NOPRESCALE();
} else {
cycles_per_bit /= 8;
//Serial.printf("cycles_per_bit/8 = %d\n", cycles_per_bit);
if (cycles_per_bit < MAX_COUNTS_PER_BIT) {
CONFIG_TIMER_PRESCALE_8();
} else {
#if defined(CONFIG_TIMER_PRESCALE_256)
cycles_per_bit /= 32;
//Serial.printf("cycles_per_bit/256 = %d\n", cycles_per_bit);
if (cycles_per_bit < MAX_COUNTS_PER_BIT) {
CONFIG_TIMER_PRESCALE_256();
} else {
return; // baud rate too low for AltSoftSerial
}
#elif defined(CONFIG_TIMER_PRESCALE_128)
cycles_per_bit /= 16;
//Serial.printf("cycles_per_bit/128 = %d\n", cycles_per_bit);
if (cycles_per_bit < MAX_COUNTS_PER_BIT) {
CONFIG_TIMER_PRESCALE_128();
} else {
return; // baud rate too low for AltSoftSerial
}
#else
return; // baud rate too low for AltSoftSerial
#endif
}
}
ticks_per_bit = cycles_per_bit;
rx_stop_ticks = cycles_per_bit * 37 / 4;
hwPinMode(INPUT_CAPTURE_PIN, INPUT_PULLUP);
hwDigitalWrite(OUTPUT_COMPARE_A_PIN, HIGH);
hwPinMode(OUTPUT_COMPARE_A_PIN, OUTPUT);
rx_state = 0;
rx_buffer_head = 0;
rx_buffer_tail = 0;
tx_state = 0;
tx_buffer_head = 0;
tx_buffer_tail = 0;
ENABLE_INT_INPUT_CAPTURE();
}

void AltSoftSerial::end(void)
{
DISABLE_INT_COMPARE_B();
DISABLE_INT_INPUT_CAPTURE();
flushInput();
flushOutput();
DISABLE_INT_COMPARE_A();
// TODO: restore timer to original settings?
}


/****************************************/
/** Transmission **/
/****************************************/

void AltSoftSerial::writeByte(uint8_t b)
{
uint8_t intr_state, head;

head = tx_buffer_head + 1;
if (head >= TX_BUFFER_SIZE) {
head = 0;
}
while (tx_buffer_tail == head) ; // wait until space in buffer
intr_state = SREG;
cli();
if (tx_state) {
tx_buffer[head] = b;
tx_buffer_head = head;
} else {
tx_state = 1;
tx_byte = b;
tx_bit = 0;
ENABLE_INT_COMPARE_A();
CONFIG_MATCH_CLEAR();
SET_COMPARE_A(GET_TIMER_COUNT() + 16);
}
SREG = intr_state;
}


ISR(COMPARE_A_INTERRUPT)
{
uint8_t state, byte, bit, head, tail;
uint16_t target;

state = tx_state;
byte = tx_byte;
target = GET_COMPARE_A();
while (state < 10) {
target += ticks_per_bit;
if (state < 9) {
bit = byte & 1;
} else {
bit = 1; // stopbit
}
byte >>= 1;
state++;
if (bit != tx_bit) {
if (bit) {
CONFIG_MATCH_SET();
} else {
CONFIG_MATCH_CLEAR();
}
SET_COMPARE_A(target);
tx_bit = bit;
tx_byte = byte;
tx_state = state;
// TODO: how to detect timing_error?
return;
}
}
head = tx_buffer_head;
tail = tx_buffer_tail;
if (head == tail) {
if (state == 10) {
// Wait for final stop bit to finish
tx_state = 11;
SET_COMPARE_A(target + ticks_per_bit);
} else {
tx_state = 0;
CONFIG_MATCH_NORMAL();
DISABLE_INT_COMPARE_A();
}
} else {
if (++tail >= TX_BUFFER_SIZE) {
tail = 0;
}
tx_buffer_tail = tail;
tx_byte = tx_buffer[tail];
tx_bit = 0;
CONFIG_MATCH_CLEAR();
if (state == 10) {
SET_COMPARE_A(target + ticks_per_bit);
} else {
SET_COMPARE_A(GET_TIMER_COUNT() + 16);
}
tx_state = 1;
// TODO: how to detect timing_error?
}
}

void AltSoftSerial::flushOutput(void)
{
while (tx_state) /* wait */ ;
}


/****************************************/
/** Reception **/
/****************************************/

ISR(CAPTURE_INTERRUPT)
{
uint8_t state, bit;
uint16_t capture;

capture = GET_INPUT_CAPTURE();
bit = rx_bit;
if (bit) {
CONFIG_CAPTURE_FALLING_EDGE();
rx_bit = 0;
} else {
CONFIG_CAPTURE_RISING_EDGE();
rx_bit = 0x80;
}
state = rx_state;
if (state == 0) {
if (!bit) {
uint16_t end = capture + rx_stop_ticks;
SET_COMPARE_B(end);
ENABLE_INT_COMPARE_B();
rx_target = capture + ticks_per_bit + ticks_per_bit/2;
rx_state = 1;
}
} else {
uint16_t target = rx_target;
const uint16_t offset_overflow = 65535 - ticks_per_bit;
while (1) {
const uint16_t offset = capture - target;
if (offset > offset_overflow) {
break;
}
rx_byte = (rx_byte >> 1) | rx_bit;
target += ticks_per_bit;
state++;
if (state >= 9) {
DISABLE_INT_COMPARE_B();
uint8_t head = rx_buffer_head + 1;
if (head >= RX_BUFFER_SIZE) {
head = 0;
}
if (head != rx_buffer_tail) {
rx_buffer[head] = rx_byte;
rx_buffer_head = head;
}
CONFIG_CAPTURE_FALLING_EDGE();
rx_bit = 0;
rx_state = 0;
return;
}
}
rx_target = target;
rx_state = state;
}
//if (GET_TIMER_COUNT() - capture > ticks_per_bit) AltSoftSerial::timing_error = true;
}

ISR(COMPARE_B_INTERRUPT)
{
uint8_t head, state, bit;

DISABLE_INT_COMPARE_B();
CONFIG_CAPTURE_FALLING_EDGE();
state = rx_state;
bit = rx_bit ^ 0x80;
while (state < 9) {
rx_byte = (rx_byte >> 1) | bit;
state++;
}
head = rx_buffer_head + 1;
if (head >= RX_BUFFER_SIZE) {
head = 0;
}
if (head != rx_buffer_tail) {
rx_buffer[head] = rx_byte;
rx_buffer_head = head;
}
rx_state = 0;
CONFIG_CAPTURE_FALLING_EDGE();
rx_bit = 0;
}



int AltSoftSerial::read(void)
{
uint8_t head, tail, out;

head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) {
return -1;
}
if (++tail >= RX_BUFFER_SIZE) {
tail = 0;
}
out = rx_buffer[tail];
rx_buffer_tail = tail;
return out;
}

int AltSoftSerial::peek(void)
{
uint8_t head, tail;

head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) {
return -1;
}
if (++tail >= RX_BUFFER_SIZE) {
tail = 0;
}
return rx_buffer[tail];
}

int AltSoftSerial::available(void)
{
uint8_t head, tail;

head = rx_buffer_head;
tail = rx_buffer_tail;
if (head >= tail) {
return head - tail;
}
return RX_BUFFER_SIZE + head - tail;
}

void AltSoftSerial::flushInput(void)
{
rx_buffer_head = rx_buffer_tail;
}


#ifdef ALTSS_USE_FTM0
void ftm0_isr(void)
{
uint32_t flags = FTM0_STATUS;
FTM0_STATUS = 0;
if (flags & (1<<0) && (FTM0_C0SC & 0x40)) {
altss_compare_b_interrupt();
}
if (flags & (1<<5)) {
altss_capture_interrupt();
}
if (flags & (1<<6) && (FTM0_C6SC & 0x40)) {
altss_compare_a_interrupt();
}
}
#endif


+ 117
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/AltSoftSerial.h View File

@@ -0,0 +1,117 @@
/* An Alternative Software Serial Library
* http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
* Copyright (c) 2014 PJRC.COM, LLC, Paul Stoffregen, paul@pjrc.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#ifndef AltSoftSerial_h
#define AltSoftSerial_h

#include <inttypes.h>

#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#include "pins_arduino.h"
#endif

#if defined(__arm__) && defined(CORE_TEENSY)
#define ALTSS_BASE_FREQ F_BUS
#else
#define ALTSS_BASE_FREQ F_CPU
#endif

/** AltSoftSerial class */
class AltSoftSerial : public Stream
{
public:
AltSoftSerial() { } //!< Constructor
~AltSoftSerial()
{
end(); //!< Destructor
}
static void begin(uint32_t baud)
{
init((ALTSS_BASE_FREQ + baud / 2) / baud); //!< begin
}
static void end(); //!< end
int peek(); //!< peek
int read(); //!< read
int available(); //!< available
#if ARDUINO >= 100
size_t write(uint8_t byte)
{
writeByte(byte); //!< write
return 1;
}
void flush()
{
flushOutput(); //!< flush
}
#else
void write(uint8_t byte)
{
writeByte(byte); //!< write
}
void flush()
{
flushInput(); //!< flush
}
#endif
using Print::write;
static void flushInput(); //!< flushInput
static void flushOutput(); //!< flushOutput
// for drop-in compatibility with NewSoftSerial, rxPin & txPin ignored
AltSoftSerial(uint8_t rxPin, uint8_t txPin, bool inverse = false)
{
(void)rxPin; //!< AltSoftSerial
(void)txPin;
(void)inverse;
}
bool listen()
{
return false; //!< listen
}
bool isListening()
{
return true; //!< isListening
}
bool overflow()
{
bool r = timing_error; //!< overflow
timing_error = false;
return r;
}
static int library_version()
{
return 1; //!< library_version
}
static void enable_timer0(bool enable)
{
(void)enable; //!< enable_timer0
}
static bool timing_error; //!< timing_error
private:
static void init(uint32_t cycles_per_bit);
static void writeByte(uint8_t byte);
};

#endif

+ 9
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/README.md View File

@@ -0,0 +1,9 @@
# AltSoftSerial Library

Improved software emulated serial, using hardware timers for precise signal
timing and availability of CPU time for other libraries to respond to interrupts
during data AltSoftSerial data transmission and reception.

http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html

![AltSoftSerial on Teensy 2.0](http://www.pjrc.com/teensy/td_libs_AltSoftSerial_2.jpg)

+ 147
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/config/AltSoftSerial_Boards.h View File

@@ -0,0 +1,147 @@
/* An Alternative Software Serial Library
* http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
* Copyright (c) 2014 PJRC.COM, LLC, Paul Stoffregen, paul@pjrc.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/


// Teensy 2.0
//
#if defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)

//#define ALTSS_USE_TIMER1
//#define INPUT_CAPTURE_PIN 22 // receive
//#define OUTPUT_COMPARE_A_PIN 14 // transmit
//#define OUTPUT_COMPARE_B_PIN 15 // unusable PWM
//#define OUTPUT_COMPARE_C_PIN 4 // unusable PWM

#define ALTSS_USE_TIMER3
#define INPUT_CAPTURE_PIN 10 // receive
#define OUTPUT_COMPARE_A_PIN 9 // transmit



// Teensy++ 2.0
//
#elif defined(__AVR_AT90USB1286__) && defined(CORE_TEENSY)

#define ALTSS_USE_TIMER1
#define INPUT_CAPTURE_PIN 4 // receive
#define OUTPUT_COMPARE_A_PIN 25 // transmit
#define OUTPUT_COMPARE_B_PIN 26 // unusable PWM
#define OUTPUT_COMPARE_C_PIN 27 // unusable PWM

//#define ALTSS_USE_TIMER3
//#define INPUT_CAPTURE_PIN 17 // receive
//#define OUTPUT_COMPARE_A_PIN 16 // transmit
//#define OUTPUT_COMPARE_B_PIN 15 // unusable PWM
//#define OUTPUT_COMPARE_C_PIN 14 // unusable PWM


// Teensy 3.x
//
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define ALTSS_USE_FTM0
#define INPUT_CAPTURE_PIN 20 // receive (FTM0_CH5)
#define OUTPUT_COMPARE_A_PIN 21 // transmit (FTM0_CH6)
#define OUTPUT_COMPARE_B_PIN 22 // unusable PWM (FTM0_CH0)
#define OUTPUT_COMPARE_C_PIN 23 // PWM usable fixed freq
#define OUTPUT_COMPARE_D_PIN 5 // PWM usable fixed freq
#define OUTPUT_COMPARE_E_PIN 6 // PWM usable fixed freq
#define OUTPUT_COMPARE_F_PIN 9 // PWM usable fixed freq
#define OUTPUT_COMPARE_G_PIN 10 // PWM usable fixed freq


// Wiring-S
//
#elif defined(__AVR_ATmega644P__) && defined(WIRING)

#define ALTSS_USE_TIMER1
#define INPUT_CAPTURE_PIN 6 // receive
#define OUTPUT_COMPARE_A_PIN 5 // transmit
#define OUTPUT_COMPARE_B_PIN 4 // unusable PWM



// Arduino Uno, Duemilanove, LilyPad, etc
//
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)

#define ALTSS_USE_TIMER1
#define INPUT_CAPTURE_PIN 8 // receive
#define OUTPUT_COMPARE_A_PIN 9 // transmit
#define OUTPUT_COMPARE_B_PIN 10 // unusable PWM


// Arduino Leonardo & Yun (from Cristian Maglie)
//
#elif defined(ARDUINO_AVR_YUN) || defined(ARDUINO_AVR_LEONARDO) || defined(__AVR_ATmega32U4__)

//#define ALTSS_USE_TIMER1
//#define INPUT_CAPTURE_PIN 4 // receive
//#define OUTPUT_COMPARE_A_PIN 9 // transmit
//#define OUTPUT_COMPARE_B_PIN 10 // unusable PWM
//#define OUTPUT_COMPARE_C_PIN 11 // unusable PWM

#define ALTSS_USE_TIMER3
#define INPUT_CAPTURE_PIN 13 // receive
#define OUTPUT_COMPARE_A_PIN 5 // transmit


// Arduino Mega
//
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)

//#define ALTSS_USE_TIMER4
//#define INPUT_CAPTURE_PIN 49 // receive
//#define OUTPUT_COMPARE_A_PIN 6 // transmit
//#define OUTPUT_COMPARE_B_PIN 7 // unusable PWM
//#define OUTPUT_COMPARE_C_PIN 8 // unusable PWM

#define ALTSS_USE_TIMER5
#define INPUT_CAPTURE_PIN 48 // receive
#define OUTPUT_COMPARE_A_PIN 46 // transmit
#define OUTPUT_COMPARE_B_PIN 45 // unusable PWM
#define OUTPUT_COMPARE_C_PIN 44 // unusable PWM



// EnviroDIY Mayfly, Sodaq Mbili
#elif defined ARDUINO_AVR_ENVIRODIY_MAYFLY || defined ARDUINO_AVR_SODAQ_MBILI
#define ALTSS_USE_TIMER1
#define INPUT_CAPTURE_PIN 6 // receive
#define OUTPUT_COMPARE_A_PIN 5 // transmit
#define OUTPUT_COMPARE_B_PIN 4 // unusable PWM



// Sanguino, Mighty 1284
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1284__)
#define ALTSS_USE_TIMER1
#define INPUT_CAPTURE_PIN 14 // receive
#define OUTPUT_COMPARE_A_PIN 13 // transmit
#define OUTPUT_COMPARE_B_PIN 12 // unusable PWM



// Unknown board
#else
#error "Please define your board timer and pins"
#endif

+ 187
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/config/AltSoftSerial_Timers.h View File

@@ -0,0 +1,187 @@
/* An Alternative Software Serial Library
* http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
* Copyright (c) 2014 PJRC.COM, LLC, Paul Stoffregen, paul@pjrc.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#if defined(ALTSS_USE_TIMER1)
#define CONFIG_TIMER_NOPRESCALE() (TIMSK1 = 0, TCCR1A = 0, TCCR1B = (1<<ICNC1) | (1<<CS10))
#define CONFIG_TIMER_PRESCALE_8() (TIMSK1 = 0, TCCR1A = 0, TCCR1B = (1<<ICNC1) | (1<<CS11))
#define CONFIG_TIMER_PRESCALE_256() (TIMSK1 = 0, TCCR1A = 0, TCCR1B = (1<<ICNC1) | (1<<CS12))
#define CONFIG_MATCH_NORMAL() (TCCR1A = TCCR1A & ~((1<<COM1A1) | (1<<COM1A0)))
#define CONFIG_MATCH_TOGGLE() (TCCR1A = (TCCR1A & ~(1<<COM1A1)) | (1<<COM1A0))
#define CONFIG_MATCH_CLEAR() (TCCR1A = (TCCR1A | (1<<COM1A1)) & ~(1<<COM1A0))
#define CONFIG_MATCH_SET() (TCCR1A = TCCR1A | ((1<<COM1A1) | (1<<COM1A0)))
#define CONFIG_CAPTURE_FALLING_EDGE() (TCCR1B &= ~(1<<ICES1))
#define CONFIG_CAPTURE_RISING_EDGE() (TCCR1B |= (1<<ICES1))
#define ENABLE_INT_INPUT_CAPTURE() (TIFR1 = (1<<ICF1), TIMSK1 = (1<<ICIE1))
#define ENABLE_INT_COMPARE_A() (TIFR1 = (1<<OCF1A), TIMSK1 |= (1<<OCIE1A))
#define ENABLE_INT_COMPARE_B() (TIFR1 = (1<<OCF1B), TIMSK1 |= (1<<OCIE1B))
#define DISABLE_INT_INPUT_CAPTURE() (TIMSK1 &= ~(1<<ICIE1))
#define DISABLE_INT_COMPARE_A() (TIMSK1 &= ~(1<<OCIE1A))
#define DISABLE_INT_COMPARE_B() (TIMSK1 &= ~(1<<OCIE1B))
#define GET_TIMER_COUNT() (TCNT1)
#define GET_INPUT_CAPTURE() (ICR1)
#define GET_COMPARE_A() (OCR1A)
#define GET_COMPARE_B() (OCR1B)
#define SET_COMPARE_A(val) (OCR1A = (val))
#define SET_COMPARE_B(val) (OCR1B = (val))
#define CAPTURE_INTERRUPT TIMER1_CAPT_vect
#define COMPARE_A_INTERRUPT TIMER1_COMPA_vect
#define COMPARE_B_INTERRUPT TIMER1_COMPB_vect


#elif defined(ALTSS_USE_TIMER3)
#define CONFIG_TIMER_NOPRESCALE() (TIMSK3 = 0, TCCR3A = 0, TCCR3B = (1<<ICNC3) | (1<<CS30))
#define CONFIG_TIMER_PRESCALE_8() (TIMSK3 = 0, TCCR3A = 0, TCCR3B = (1<<ICNC3) | (1<<CS31))
#define CONFIG_TIMER_PRESCALE_256() (TIMSK3 = 0, TCCR3A = 0, TCCR3B = (1<<ICNC3) | (1<<CS32))
#define CONFIG_MATCH_NORMAL() (TCCR3A = TCCR3A & ~((1<<COM3A1) | (1<<COM3A0)))
#define CONFIG_MATCH_TOGGLE() (TCCR3A = (TCCR3A & ~(1<<COM3A1)) | (1<<COM3A0))
#define CONFIG_MATCH_CLEAR() (TCCR3A = (TCCR3A | (1<<COM3A1)) & ~(1<<COM3A0))
#define CONFIG_MATCH_SET() (TCCR3A = TCCR3A | ((1<<COM3A1) | (1<<COM3A0)))
#define CONFIG_CAPTURE_FALLING_EDGE() (TCCR3B &= ~(1<<ICES3))
#define CONFIG_CAPTURE_RISING_EDGE() (TCCR3B |= (1<<ICES3))
#define ENABLE_INT_INPUT_CAPTURE() (TIFR3 = (1<<ICF3), TIMSK3 = (1<<ICIE3))
#define ENABLE_INT_COMPARE_A() (TIFR3 = (1<<OCF3A), TIMSK3 |= (1<<OCIE3A))
#define ENABLE_INT_COMPARE_B() (TIFR3 = (1<<OCF3B), TIMSK3 |= (1<<OCIE3B))
#define DISABLE_INT_INPUT_CAPTURE() (TIMSK3 &= ~(1<<ICIE3))
#define DISABLE_INT_COMPARE_A() (TIMSK3 &= ~(1<<OCIE3A))
#define DISABLE_INT_COMPARE_B() (TIMSK3 &= ~(1<<OCIE3B))
#define GET_TIMER_COUNT() (TCNT3)
#define GET_INPUT_CAPTURE() (ICR3)
#define GET_COMPARE_A() (OCR3A)
#define GET_COMPARE_B() (OCR3B)
#define SET_COMPARE_A(val) (OCR3A = (val))
#define SET_COMPARE_B(val) (OCR3B = (val))
#define CAPTURE_INTERRUPT TIMER3_CAPT_vect
#define COMPARE_A_INTERRUPT TIMER3_COMPA_vect
#define COMPARE_B_INTERRUPT TIMER3_COMPB_vect


#elif defined(ALTSS_USE_TIMER4)
#define CONFIG_TIMER_NOPRESCALE() (TIMSK4 = 0, TCCR4A = 0, TCCR4B = (1<<ICNC4) | (1<<CS40))
#define CONFIG_TIMER_PRESCALE_8() (TIMSK4 = 0, TCCR4A = 0, TCCR4B = (1<<ICNC4) | (1<<CS41))
#define CONFIG_TIMER_PRESCALE_256() (TIMSK4 = 0, TCCR4A = 0, TCCR4B = (1<<ICNC4) | (1<<CS42))
#define CONFIG_MATCH_NORMAL() (TCCR4A = TCCR4A & ~((1<<COM4A1) | (1<<COM4A0)))
#define CONFIG_MATCH_TOGGLE() (TCCR4A = (TCCR4A & ~(1<<COM4A1)) | (1<<COM4A0))
#define CONFIG_MATCH_CLEAR() (TCCR4A = (TCCR4A | (1<<COM4A1)) & ~(1<<COM4A0))
#define CONFIG_MATCH_SET() (TCCR4A = TCCR4A | ((1<<COM4A1) | (1<<COM4A0)))
#define CONFIG_CAPTURE_FALLING_EDGE() (TCCR4B &= ~(1<<ICES4))
#define CONFIG_CAPTURE_RISING_EDGE() (TCCR4B |= (1<<ICES4))
#define ENABLE_INT_INPUT_CAPTURE() (TIFR4 = (1<<ICF4), TIMSK4 = (1<<ICIE4))
#define ENABLE_INT_COMPARE_A() (TIFR4 = (1<<OCF4A), TIMSK4 |= (1<<OCIE4A))
#define ENABLE_INT_COMPARE_B() (TIFR4 = (1<<OCF4B), TIMSK4 |= (1<<OCIE4B))
#define DISABLE_INT_INPUT_CAPTURE() (TIMSK4 &= ~(1<<ICIE4))
#define DISABLE_INT_COMPARE_A() (TIMSK4 &= ~(1<<OCIE4A))
#define DISABLE_INT_COMPARE_B() (TIMSK4 &= ~(1<<OCIE4B))
#define GET_TIMER_COUNT() (TCNT4)
#define GET_INPUT_CAPTURE() (ICR4)
#define GET_COMPARE_A() (OCR4A)
#define GET_COMPARE_B() (OCR4B)
#define SET_COMPARE_A(val) (OCR4A = (val))
#define SET_COMPARE_B(val) (OCR4B = (val))
#define CAPTURE_INTERRUPT TIMER4_CAPT_vect
#define COMPARE_A_INTERRUPT TIMER4_COMPA_vect
#define COMPARE_B_INTERRUPT TIMER4_COMPB_vect


#elif defined(ALTSS_USE_TIMER5)
#define CONFIG_TIMER_NOPRESCALE() (TIMSK5 = 0, TCCR5A = 0, TCCR5B = (1<<ICNC5) | (1<<CS50))
#define CONFIG_TIMER_PRESCALE_8() (TIMSK5 = 0, TCCR5A = 0, TCCR5B = (1<<ICNC5) | (1<<CS51))
#define CONFIG_TIMER_PRESCALE_256() (TIMSK5 = 0, TCCR5A = 0, TCCR5B = (1<<ICNC5) | (1<<CS52))
#define CONFIG_MATCH_NORMAL() (TCCR5A = TCCR5A & ~((1<<COM5A1) | (1<<COM5A0)))
#define CONFIG_MATCH_TOGGLE() (TCCR5A = (TCCR5A & ~(1<<COM5A1)) | (1<<COM5A0))
#define CONFIG_MATCH_CLEAR() (TCCR5A = (TCCR5A | (1<<COM5A1)) & ~(1<<COM5A0))
#define CONFIG_MATCH_SET() (TCCR5A = TCCR5A | ((1<<COM5A1) | (1<<COM5A0)))
#define CONFIG_CAPTURE_FALLING_EDGE() (TCCR5B &= ~(1<<ICES5))
#define CONFIG_CAPTURE_RISING_EDGE() (TCCR5B |= (1<<ICES5))
#define ENABLE_INT_INPUT_CAPTURE() (TIFR5 = (1<<ICF5), TIMSK5 = (1<<ICIE5))
#define ENABLE_INT_COMPARE_A() (TIFR5 = (1<<OCF5A), TIMSK5 |= (1<<OCIE5A))
#define ENABLE_INT_COMPARE_B() (TIFR5 = (1<<OCF5B), TIMSK5 |= (1<<OCIE5B))
#define DISABLE_INT_INPUT_CAPTURE() (TIMSK5 &= ~(1<<ICIE5))
#define DISABLE_INT_COMPARE_A() (TIMSK5 &= ~(1<<OCIE5A))
#define DISABLE_INT_COMPARE_B() (TIMSK5 &= ~(1<<OCIE5B))
#define GET_TIMER_COUNT() (TCNT5)
#define GET_INPUT_CAPTURE() (ICR5)
#define GET_COMPARE_A() (OCR5A)
#define GET_COMPARE_B() (OCR5B)
#define SET_COMPARE_A(val) (OCR5A = (val))
#define SET_COMPARE_B(val) (OCR5B = (val))
#define CAPTURE_INTERRUPT TIMER5_CAPT_vect
#define COMPARE_A_INTERRUPT TIMER5_COMPA_vect
#define COMPARE_B_INTERRUPT TIMER5_COMPB_vect


#elif defined(ALTSS_USE_FTM0)
// CH5 = input capture (input, pin 20)
// CH6 = compare a (output, pin 21)
// CH0 = compare b (input timeout)
#define CONFIG_TIMER_NOPRESCALE() FTM0_SC = 0; FTM0_CNT = 0; FTM0_MOD = 0xFFFF; \
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); \
digitalWriteFast(21, HIGH); \
NVIC_SET_PRIORITY(IRQ_FTM0, 48); \
FTM0_C0SC = 0x18; \
NVIC_ENABLE_IRQ(IRQ_FTM0);
#define CONFIG_TIMER_PRESCALE_8() FTM0_SC = 0; FTM0_CNT = 0; FTM0_MOD = 0xFFFF; \
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(3); \
digitalWriteFast(21, HIGH); \
NVIC_SET_PRIORITY(IRQ_FTM0, 48); \
FTM0_C0SC = 0x18; \
NVIC_ENABLE_IRQ(IRQ_FTM0);
#define CONFIG_TIMER_PRESCALE_128() FTM0_SC = 0; FTM0_CNT = 0; FTM0_MOD = 0xFFFF; \
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(7); \
digitalWriteFast(21, HIGH); \
NVIC_SET_PRIORITY(IRQ_FTM0, 48); \
FTM0_C0SC = 0x18; \
NVIC_ENABLE_IRQ(IRQ_FTM0);
#define CONFIG_MATCH_NORMAL() (FTM0_C6SC = 0)
#define CONFIG_MATCH_TOGGLE() (FTM0_C6SC = (FTM0_C6SC & 0xC3) | 0x14)
#define CONFIG_MATCH_CLEAR() (FTM0_C6SC = (FTM0_C6SC & 0xC3) | 0x18)
#define CONFIG_MATCH_SET() (FTM0_C6SC = (FTM0_C6SC & 0xC3) | 0x1C)
#define CONFIG_CAPTURE_FALLING_EDGE() (FTM0_C5SC = (FTM0_C5SC & 0xC3) | 0x08)
#define CONFIG_CAPTURE_RISING_EDGE() (FTM0_C5SC = (FTM0_C5SC & 0xC3) | 0x04)
#define ENABLE_INT_INPUT_CAPTURE() FTM0_C5SC = 0x48; \
CORE_PIN20_CONFIG = PORT_PCR_MUX(4)|PORT_PCR_PE|PORT_PCR_PS
#define ENABLE_INT_COMPARE_A() FTM0_C6SC |= 0x40; \
CORE_PIN21_CONFIG = PORT_PCR_MUX(4)|PORT_PCR_DSE|PORT_PCR_SRE
#define ENABLE_INT_COMPARE_B() (FTM0_C0SC = 0x58)
#define DISABLE_INT_INPUT_CAPTURE() FTM0_C5SC &= ~0x40; \
CORE_PIN20_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_PE|PORT_PCR_PS
#define DISABLE_INT_COMPARE_A() FTM0_C6SC &= ~0x40; \
CORE_PIN21_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_DSE|PORT_PCR_SRE; \
digitalWriteFast(21, HIGH)
#define DISABLE_INT_COMPARE_B() (FTM0_C0SC &= ~0x40)
#define GET_TIMER_COUNT() (FTM0_CNT)
#define GET_INPUT_CAPTURE() (FTM0_C5V)
#define GET_COMPARE_A() (FTM0_C6V)
#define GET_COMPARE_B() (FTM0_C0V)
#define SET_COMPARE_A(val) (FTM0_C6V = val)
#define SET_COMPARE_B(val) if (FTM0_C0SC & FTM_CSC_CHF) FTM0_C0SC = 0x18; \
do { FTM0_C0V = (val); } while (FTM0_C0V != (val));
#define CAPTURE_INTERRUPT altss_capture_interrupt
#define COMPARE_A_INTERRUPT altss_compare_a_interrupt
#define COMPARE_B_INTERRUPT altss_compare_b_interrupt
#ifdef ISR
#undef ISR
#endif
#define ISR(f) static void f (void)


#endif

+ 64
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/docs/issue_template.md View File

@@ -0,0 +1,64 @@
Please use this form only to report code defects or bugs.

For any question, even questions directly pertaining to this code, post your question on the forums related to the board you are using.

Arduino: forum.arduino.cc
Teensy: forum.pjrc.com
ESP8266: www.esp8266.com
ESP32: www.esp32.com
Adafruit Feather/Metro/Trinket: forums.adafruit.com
Particle Photon: community.particle.io

If you are experiencing trouble but not certain of the cause, or need help using this code, ask on the appropriate forum. This is not the place to ask for support or help, even directly related to this code. Only use this form you are certain you have discovered a defect in this code!

Please verify the problem occurs when using the very latest version, using the newest version of Arduino and any other related software.


----------------------------- Remove above -----------------------------



### Description

Describe your problem.



### Steps To Reproduce Problem

Please give detailed instructions needed for anyone to attempt to reproduce the problem.



### Hardware & Software

Board
Shields / modules used
Arduino IDE version
Teensyduino version (if using Teensy)
Version info & package name (from Tools > Boards > Board Manager)
Operating system & version
Any other software or hardware?


### Arduino Sketch

```cpp
// Change the code below by your sketch (please try to give the smallest code which demonstrates the problem)
#include <Arduino.h>

// libraries: give links/details so anyone can compile your code for the same result

void setup() {
}

void loop() {
}
```


### Errors or Incorrect Output

If you see any errors or incorrect output, please show it here. Please use copy & paste to give an exact copy of the message. Details matter, so please show (not merely describe) the actual message or error exactly as it appears.



+ 40
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/examples/Echo/Echo.ino View File

@@ -0,0 +1,40 @@
#include <AltSoftSerial.h>

// AltSoftSerial always uses these pins:
//
// Board Transmit Receive PWM Unusable
// ----- -------- ------- ------------
// Teensy 3.0 & 3.1 21 20 22
// Teensy 2.0 9 10 (none)
// Teensy++ 2.0 25 4 26, 27
// Arduino Uno 9 8 10
// Arduino Leonardo 5 13 (none)
// Arduino Mega 46 48 44, 45
// Wiring-S 5 6 4
// Sanguino 13 14 12

// This example code is in the public domain.

AltSoftSerial altSerial;

void setup() {
Serial.begin(9600);
while (!Serial) ; // wait for Arduino Serial Monitor to open
Serial.println("AltSoftSerial Test Begin");
altSerial.begin(9600);
altSerial.println("Hello World");
}

void loop() {
char c;

if (Serial.available()) {
c = Serial.read();
altSerial.print(c);
}
if (altSerial.available()) {
c = altSerial.read();
Serial.print(c);
}
}


+ 56
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/examples/ReceiveTest/ReceiveTest.ino View File

@@ -0,0 +1,56 @@
// AltSoftSerial Receive Test
//
// Transmit data with Serial1 and try to receive
// it with AltSoftSerial. You must connect a wire
// from Serial1 TX to AltSoftSerial RX.

#include <AltSoftSerial.h>

AltSoftSerial altser;
const int mybaud = 9600;

// Board Serial1 TX AltSoftSerial RX
// ----- ---------- ----------------
// Teensy 3.x 1 20
// Teensy 2.0 8 (D3) 10 (C7)
// Teensy++ 2.0 3 (D3) 4 (D4)
// Arduino Leonardo 1 13
// Arduino Mega 18 48

// Serial1 on AVR @ 16 MHz minimum baud is 245
// Serial1 on Teensy 3.2 @ 96 MHz minimum baud is 733

// This example code is in the public domain.

byte sentbyte;
unsigned long prevmillis;
byte testbyte=0xF0;

void setup()
{
delay(200);
Serial.begin(9600);
while (!Serial) ; // wait for Arduino Serial Monitor
Serial1.begin(mybaud); // connect a wire from TX1
altser.begin(mybaud); // to AltSoftSerial RX
Serial.println("AltSoftSerial Receive Test");
prevmillis = millis();
}

void loop()
{
// transmit a test byte on Serial 1
if (millis() - prevmillis > 250) {
sentbyte = testbyte++;
Serial1.write(sentbyte);
prevmillis = millis();
}
// attempt to receive it by AltSoftSerial
if (altser.available() > 0) {
byte b = altser.read();
Serial.println(b);
if (b != sentbyte) {
Serial.println("***** ERROR *****");
}
}
}

+ 97
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/examples/ShowConfiguration/ShowConfiguration.ino View File

@@ -0,0 +1,97 @@
#include <AltSoftSerial.h>

// AltSoftSerial show configuration example
// Will print library configuration to default serial port
// Open your serial monitor to see config for your board
// Printout would repeat every 10sec (just in case you missed it somehow)

// Print Configuration
// -----------------------

// Direct include AltSoftSerial internals to obtaion PIN setup (you do not need this in regular code)

// This example code is in the public domain.

#include <config/AltSoftSerial_Boards.h>

void printAltSoftSerialSetup(Stream &port)
{
#define PRINT_PFX "AltSoftSerial:"
#define PRINT_PIN_NAME(pin,name) { char buffer[128+1]; sprintf(buffer, PRINT_PFX "PIN:%2d %s", (int)pin, (const char*)name); port.println(buffer); }

port.println(PRINT_PFX "Setup info: begin");

#if defined(ALTSS_USE_FTM0)
port.println(PRINT_PFX "USE FTM0");
#endif

#if defined(ALTSS_USE_TIMER1)
port.println(PRINT_PFX "USE TIMER1");
#endif

#if defined(ALTSS_USE_TIMER2)
port.println(PRINT_PFX "USE TIMER2");
#endif

#if defined(ALTSS_USE_TIMER3)
port.println(PRINT_PFX "USE TIMER3");
#endif

#if defined(ALTSS_USE_TIMER4)
port.println(PRINT_PFX "USE TIMER4");
#endif

#if defined(ALTSS_USE_TIMER5)
port.println(PRINT_PFX "USE TIMER5");
#endif

#if defined(INPUT_CAPTURE_PIN)
PRINT_PIN_NAME(INPUT_CAPTURE_PIN,"RX");
#endif

#if defined(OUTPUT_COMPARE_A_PIN)
PRINT_PIN_NAME(OUTPUT_COMPARE_A_PIN,"TX");
#endif

#if defined(OUTPUT_COMPARE_B_PIN)
PRINT_PIN_NAME(OUTPUT_COMPARE_B_PIN,"(unused PWM)");
#endif

#if defined(OUTPUT_COMPARE_C_PIN)
PRINT_PIN_NAME(OUTPUT_COMPARE_C_PIN,"(unused PWM)");
#endif

#if defined(OUTPUT_COMPARE_D_PIN)
PRINT_PIN_NAME(OUTPUT_COMPARE_D_PIN,"(unused PWM)");
#endif

#if defined(OUTPUT_COMPARE_E_PIN)
PRINT_PIN_NAME(OUTPUT_COMPARE_E_PIN,"(unused PWM)");
#endif

#if defined(OUTPUT_COMPARE_F_PIN)
PRINT_PIN_NAME(OUTPUT_COMPARE_F_PIN,"(unused PWM)");
#endif

port.println(PRINT_PFX "Setup info: end");

#undef PRINT_PIN_NAME
#undef PRINT_PFX
}

void setup()
{
// Open default serial to dump config to
Serial.begin(9600);
while (!Serial) ; // wait for serial monitor
printAltSoftSerialSetup(Serial);
}

void loop()
{
// Repeat every 10 sec (just in case)
delay(10000);
Serial.println("");
printAltSoftSerialSetup(Serial);
}


+ 4
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/AltSoftSerial/keywords.txt View File

@@ -0,0 +1,4 @@
AltSoftSerial KEYWORD1
active KEYWORD2
overflow KEYWORD2
library_version KEYWORD2

+ 80
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/BCM.cpp View File

@@ -0,0 +1,80 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#include "BCM.h"
#include <stdlib.h>
#include "log.h"

// Declare a single default instance
BCMClass BCM = BCMClass();

uint8_t BCMClass::initialized = 0;

BCMClass::~BCMClass()
{
if (initialized) {
bcm2835_close();
initialized = 0;
}
}

uint8_t BCMClass::init()
{
if (!bcm2835_init()) {
logError("Failed to initialized bcm2835.\n");
exit(1);
}
initialized = 1;

return 1;
}

void BCMClass::pinMode(uint8_t gpio, uint8_t mode)
{
if (!initialized) {
init();
}

bcm2835_gpio_fsel(gpio, mode);
}

void BCMClass::digitalWrite(uint8_t gpio, uint8_t value)
{
if (!initialized) {
init();
}

bcm2835_gpio_write(gpio, value);
// Delay to allow any change in state to be reflected in the LEVn, register bit.
delayMicroseconds(1);
}

uint8_t BCMClass::digitalRead(uint8_t gpio)
{
if (!initialized) {
init();
}

return bcm2835_gpio_lev(gpio);
}

uint8_t BCMClass::isInitialized()
{
return initialized;
}

+ 92
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/BCM.h View File

@@ -0,0 +1,92 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#ifndef BCM_h
#define BCM_h

#include <stdint.h>
#include "bcm2835.h"

#define INPUT BCM2835_GPIO_FSEL_INPT
#define OUTPUT BCM2835_GPIO_FSEL_OUTP

/**
* @brief BCM class
*/
class BCMClass
{

public:
/**
* @brief BCMClass destructor.
*/
~BCMClass();
/**
* @brief Initializes BCM.
*
* @return 1 if successful, else exits the program.
*/
uint8_t init();
/**
* @brief Configures the specified pin to behave either as an input or an output.
*
* @param gpio The GPIO pin number.
* @param mode INPUT or OUTPUT.
*/
void pinMode(uint8_t gpio, uint8_t mode);
/**
* @brief Write a high or a low value for the given pin.
*
* @param gpio The GPIO pin number.
* @param value HIGH or LOW.
*/
void digitalWrite(uint8_t gpio, uint8_t value);
/**
* @brief Reads the value from a specified pin.
*
* @param gpio The GPIO pin number.
* @return HIGH or LOW.
*/
uint8_t digitalRead(uint8_t gpio);
/**
* @brief Returns the same GPIO, no conversion is required.
*
* @param gpio The GPIO pin number.
* @return The GPIO pin number.
*/
inline uint8_t digitalPinToInterrupt(uint8_t gpio);
/**
* @brief Checks if SPI was initialized.
*
* @return 1 if initialized, else 0.
*/
uint8_t isInitialized();

private:
static uint8_t initialized; //!< @brief BCM initialized flag.
};

uint8_t BCMClass::digitalPinToInterrupt(uint8_t gpio)
{
return gpio;
}

extern BCMClass BCM;

#endif

+ 167
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/RPi.cpp View File

@@ -0,0 +1,167 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#include "RPi.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "log.h"

const static int phys_to_gpio_rev1[41] = {-1, -1, -1, 0, -1, 1, -1, 4, 14, -1, 15, 17, 18, 21, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
const static int phys_to_gpio_rev2[41] = {-1, -1, -1, 2, -1, 3, -1, 4, 14, -1, 15, 17, 18, 27, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, 5, -1, 6, 12, 13, -1, 19, 16, 26, 20, -1, 21};

// Declare a single default instance
RPiClass RPi = RPiClass();

const int* RPiClass::phys_to_gpio = NULL;

void RPiClass::pinMode(uint8_t physPin, uint8_t mode)
{
uint8_t gpioPin;

if (physToGPIO(physPin, &gpioPin) != 0) {
logError("pinMode: invalid pin: %d\n", physPin);
return;
}

BCM.pinMode(gpioPin, mode);
}

void RPiClass::digitalWrite(uint8_t physPin, uint8_t value)
{
uint8_t gpioPin;

if (physToGPIO(physPin, &gpioPin) != 0) {
logError("digitalWrite: invalid pin: %d\n", physPin);
return;
}

BCM.digitalWrite(gpioPin, value);
}

uint8_t RPiClass::digitalRead(uint8_t physPin)
{
uint8_t gpioPin;

if (physToGPIO(physPin, &gpioPin) != 0) {
logError("digitalRead: invalid pin: %d\n", physPin);
return 0;
}

return BCM.digitalRead(gpioPin);
}

uint8_t RPiClass::digitalPinToInterrupt(uint8_t physPin)
{
uint8_t gpioPin;

if (physToGPIO(physPin, &gpioPin) != 0) {
logError("digitalPinToInterrupt: invalid pin: %d\n", physPin);
return 0;
}

return gpioPin;
}

int RPiClass::rpiGpioLayout()
{
/*
* Based on wiringPi Copyright (c) 2012 Gordon Henderson.
*/
FILE *fd;
char line[120];
char *c;

if ((fd = fopen("/proc/cpuinfo", "r")) == NULL) {
return -1;
}

while (fgets(line, 120, fd) != NULL) {
if (strncmp(line, "Revision", 8) == 0) {
fclose(fd);
// Chop trailing CR/NL
for (c = &line[strlen(line) - 1]; (*c == '\n') || (*c == '\r'); --c) {
*c = 0;
}
// Scan to the first character of the revision number
for (c = line; *c; ++c) {
if (*c == ':') {
// Chop spaces
++c;
while (isspace(*c)) {
++c;
}

// Check hex digit at start
if (!isxdigit(*c)) {
return -1;
}

// Check bogus revision line (too small)
if (strlen(c) < 4) {
return -1;
}

// Isolate last 4 characters: (in-case of overvolting or new encoding scheme)
c = c + strlen(c) - 4;

if ((strcmp(c, "0002") == 0) || (strcmp(c, "0003") == 0) ||
(strcmp(c, "0004") == 0) || (strcmp(c, "0005") == 0) ||
(strcmp(c, "0006") == 0) || (strcmp(c, "0007") == 0) ||
(strcmp(c, "0008") == 0) || (strcmp(c, "0009") == 0) ||
(strcmp(c, "000d") == 0) || (strcmp(c, "000e") == 0) ||
(strcmp(c, "000f") == 0)) {
return 1;
} else {
return 2;
}
}
}
}
}
fclose(fd);
return -1;
}

int RPiClass::physToGPIO(uint8_t physPin, uint8_t *gpio)
{
if (phys_to_gpio == NULL) {
if (rpiGpioLayout() == 1) {
// A, B, Rev 1, 1.1
phys_to_gpio = &phys_to_gpio_rev1[0];
} else {
// A2, B2, A+, B+, CM, Pi2, Pi3, Zero
phys_to_gpio = &phys_to_gpio_rev2[0];
}
}

if (gpio == NULL || physPin > 40) {
return -1;
}

int pin = *(phys_to_gpio+physPin);
if (pin == -1) {
return -1;
} else {
*gpio = pin;
}

return 0;
}

+ 82
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/RPi.h View File

@@ -0,0 +1,82 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/

#ifndef RPi_h
#define RPi_h

#include <stdint.h>
#include "BCM.h"

/**
* @brief RPi class
*/
class RPiClass
{

public:
/**
* @brief Configures the specified pin to behave either as an input or an output.
*
* @param physPin The physical number of the pin.
* @param mode INPUT or OUTPUT.
*/
void pinMode(uint8_t physPin, uint8_t mode);
/**
* @brief Write a high or a low value for the given pin.
*
* @param physPin The physical number of the pin.
* @param value HIGH or LOW.
*/
void digitalWrite(uint8_t physPin, uint8_t value);
/**
* @brief Reads the value from a specified pin.
*
* @param physPin The physical number of the pin.
* @return HIGH or LOW.
*/
uint8_t digitalRead(uint8_t physPin);
/**
* @brief Translate the physical pin number to the GPIO number for use in interrupt.
*
* @param physPin The physical number of the pin.
* @return The GPIO pin number.
*/
uint8_t digitalPinToInterrupt(uint8_t physPin);
/**
* @brief Translate the physical pin number to the GPIO number.
*
* @param physPin The physical number of the pin.
* @param gpio Pointer to write the GPIO pin number when success.
* @return -1 if FAILURE or 0 if SUCCESS.
*/
static int physToGPIO(uint8_t physPin, uint8_t *gpio);

private:
static const int *phys_to_gpio; //!< @brief Pointer to array of GPIO pins numbers.
/**
* @brief Get the gpio layout.
*
* @return The gpio layout number.
*/
static int rpiGpioLayout(void);
};

extern RPiClass RPi;

#endif

+ 110
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/SPIBCM.cpp View File

@@ -0,0 +1,110 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* Based on TMRh20 RF24 library, Copyright (c) 2015 Charles-Henri Hallard <tmrh20@gmail.com>
*/

#include "SPIBCM.h"
#include <pthread.h>
#include <stdlib.h>
#include "log.h"

static pthread_mutex_t spiMutex = PTHREAD_MUTEX_INITIALIZER;

// Declare a single default instance
SPIBCMClass SPIBCM = SPIBCMClass();

uint8_t SPIBCMClass::initialized = 0;

void SPIBCMClass::begin()
{
if (!initialized) {
if (!BCM.isInitialized()) {
BCM.init();
}
if (!bcm2835_spi_begin()) {
logError("You need root privilege to use SPI.\n");
exit(1);
}
}

initialized++; // reference count
}

void SPIBCMClass::end()
{
if (initialized) {
initialized--;
}

if (!initialized) {
// End the SPI
bcm2835_spi_end();
}
}

void SPIBCMClass::setBitOrder(uint8_t bit_order)
{
bcm2835_spi_setBitOrder(bit_order);
}

void SPIBCMClass::setDataMode(uint8_t data_mode)
{
bcm2835_spi_setDataMode(data_mode);
}

void SPIBCMClass::setClockDivider(uint16_t divider)
{
bcm2835_spi_setClockDivider(divider);
}

void SPIBCMClass::chipSelect(int csn_pin)
{
if (csn_pin == RPI_GPIO_P1_26) {
csn_pin = BCM2835_SPI_CS1;
} else if (csn_pin == RPI_GPIO_P1_24) {
csn_pin = BCM2835_SPI_CS0;
} else {
csn_pin = BCM2835_SPI_CS0;
}
bcm2835_spi_chipSelect(csn_pin);
delayMicroseconds(5);
}

void SPIBCMClass::beginTransaction(SPISettings settings)
{
pthread_mutex_lock(&spiMutex);
setBitOrder(settings.border);
setDataMode(settings.dmode);
setClockDivider(settings.cdiv);
}

void SPIBCMClass::endTransaction()
{
pthread_mutex_unlock(&spiMutex);
}

void SPIBCMClass::usingInterrupt(uint8_t interruptNumber)
{
(void)interruptNumber;
}

void SPIBCMClass::notUsingInterrupt(uint8_t interruptNumber)
{
(void)interruptNumber;
}

+ 262
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/SPIBCM.h View File

@@ -0,0 +1,262 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* Based on TMRh20 RF24 library, Copyright (c) 2015 Charles-Henri Hallard <tmrh20@gmail.com>
*/

#ifndef SPIBCM_h
#define SPIBCM_h

#include <stdio.h>
#include "bcm2835.h"
#include "BCM.h"

#define SPI_HAS_TRANSACTION

#define SPI_CLOCK_BASE 256000000

// SPI Clock divider
#define SPI_CLOCK_DIV1 BCM2835_SPI_CLOCK_DIVIDER_1
#define SPI_CLOCK_DIV2 BCM2835_SPI_CLOCK_DIVIDER_2
#define SPI_CLOCK_DIV4 BCM2835_SPI_CLOCK_DIVIDER_4
#define SPI_CLOCK_DIV8 BCM2835_SPI_CLOCK_DIVIDER_8
#define SPI_CLOCK_DIV16 BCM2835_SPI_CLOCK_DIVIDER_16
#define SPI_CLOCK_DIV32 BCM2835_SPI_CLOCK_DIVIDER_32
#define SPI_CLOCK_DIV64 BCM2835_SPI_CLOCK_DIVIDER_64
#define SPI_CLOCK_DIV128 BCM2835_SPI_CLOCK_DIVIDER_128
#define SPI_CLOCK_DIV256 BCM2835_SPI_CLOCK_DIVIDER_256
#define SPI_CLOCK_DIV512 BCM2835_SPI_CLOCK_DIVIDER_512
#define SPI_CLOCK_DIV1024 BCM2835_SPI_CLOCK_DIVIDER_1024
#define SPI_CLOCK_DIV2048 BCM2835_SPI_CLOCK_DIVIDER_2048
#define SPI_CLOCK_DIV4096 BCM2835_SPI_CLOCK_DIVIDER_4096
#define SPI_CLOCK_DIV8192 BCM2835_SPI_CLOCK_DIVIDER_8192
#define SPI_CLOCK_DIV16384 BCM2835_SPI_CLOCK_DIVIDER_16384
#define SPI_CLOCK_DIV32768 BCM2835_SPI_CLOCK_DIVIDER_32768
#define SPI_CLOCK_DIV65536 BCM2835_SPI_CLOCK_DIVIDER_65536

// SPI Data mode
#define SPI_MODE0 BCM2835_SPI_MODE0
#define SPI_MODE1 BCM2835_SPI_MODE1
#define SPI_MODE2 BCM2835_SPI_MODE2
#define SPI_MODE3 BCM2835_SPI_MODE3

#define LSBFIRST BCM2835_SPI_BIT_ORDER_LSBFIRST
#define MSBFIRST BCM2835_SPI_BIT_ORDER_MSBFIRST

const uint8_t SS = 24;
const uint8_t MOSI = 19;
const uint8_t MISO = 21;
const uint8_t SCK = 23;

/**
* SPISettings class
*/
class SPISettings
{

public:
/**
* @brief SPISettings constructor.
*
* Default clock speed is 8Mhz.
*/
SPISettings()
{
init(SPI_CLOCK_DIV32, MSBFIRST, SPI_MODE0);
}
/**
* @brief SPISettings constructor.
*
* @param clock SPI clock speed in Hz.
* @param bitOrder SPI bit order.
* @param dataMode SPI data mode.
*/
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
{
uint16_t divider;

if (clock >= SPI_CLOCK_BASE) {
divider = SPI_CLOCK_DIV1;
} else if (clock >= SPI_CLOCK_BASE / 2) {
divider = SPI_CLOCK_DIV2;
} else if (clock >= SPI_CLOCK_BASE / 4) {
divider = SPI_CLOCK_DIV4;
} else if (clock >= SPI_CLOCK_BASE / 8) {
divider = SPI_CLOCK_DIV8;
} else if (clock >= SPI_CLOCK_BASE / 16) {
divider = SPI_CLOCK_DIV16;
} else if (clock >= SPI_CLOCK_BASE / 32) {
divider = SPI_CLOCK_DIV32;
} else if (clock >= SPI_CLOCK_BASE / 64) {
divider = SPI_CLOCK_DIV64;
} else if (clock >= SPI_CLOCK_BASE / 128) {
divider = SPI_CLOCK_DIV128;
} else if (clock >= SPI_CLOCK_BASE / 256) {
divider = SPI_CLOCK_DIV256;
} else if (clock >= SPI_CLOCK_BASE / 512) {
divider = SPI_CLOCK_DIV512;
} else if (clock >= SPI_CLOCK_BASE / 1024) {
divider = SPI_CLOCK_DIV1024;
} else if (clock >= SPI_CLOCK_BASE / 2048) {
divider = SPI_CLOCK_DIV2048;
} else if (clock >= SPI_CLOCK_BASE / 4096) {
divider = SPI_CLOCK_DIV4096;
} else if (clock >= SPI_CLOCK_BASE / 8192) {
divider = SPI_CLOCK_DIV8192;
} else if (clock >= SPI_CLOCK_BASE / 16384) {
divider = SPI_CLOCK_DIV16384;
} else if (clock >= SPI_CLOCK_BASE / 32768) {
divider = SPI_CLOCK_DIV32768;
} else if (clock >= SPI_CLOCK_BASE / 65536) {
divider = SPI_CLOCK_DIV65536;
} else {
// Default to 8Mhz
divider = SPI_CLOCK_DIV32;
}

init(divider, bitOrder, dataMode);
}

uint16_t cdiv; //!< @brief SPI clock divider.
uint8_t border; //!< @brief SPI bit order.
uint8_t dmode; //!< @brief SPI data mode.

private:
/**
* @brief Initialized class members.
*
* @param divider SPI clock divider.
* @param bitOrder SPI bit order.
* @param dataMode SPI data mode.
*/
void init(uint16_t divider, uint8_t bitOrder, uint8_t dataMode)
{
cdiv = divider;
border = bitOrder;
dmode = dataMode;
}

friend class SPIBCMClass;
};

/**
* SPIBCM class
*/
class SPIBCMClass
{

public:
/**
* @brief Send and receive a byte.
*
* @param data to send.
* @return byte received.
*/
inline static uint8_t transfer(uint8_t data);
/**
* @brief Send and receive a number of bytes.
*
* @param tbuf Sending buffer.
* @param rbuf Receive buffer.
* @param len Buffer length.
*/
inline static void transfernb(char* tbuf, char* rbuf, uint32_t len);
/**
* @brief Send and receive a number of bytes.
*
* @param buf Buffer to read from and write to.
* @param len Buffer length.
*/
inline static void transfern(char* buf, uint32_t len);
/**
* @brief Start SPI operations.
*/
static void begin();
/**
* @brief End SPI operations.
*/
static void end();
/**
* @brief Sets the SPI bit order.
*
* @param bit_order The desired bit order.
*/
static void setBitOrder(uint8_t bit_order);
/**
* @brief Sets the SPI data mode.
*
* @param data_mode The desired data mode.
*/
static void setDataMode(uint8_t data_mode);
/**
* @brief Sets the SPI clock divider and therefore the SPI clock speed.
*
* @param divider The desired SPI clock divider.
*/
static void setClockDivider(uint16_t divider);
/**
* @brief Sets the chip select pin.
*
* @param csn_pin Specifies the CS pin.
*/
static void chipSelect(int csn_pin);
/**
* @brief Start SPI transaction.
*
* @param settings for SPI.
*/
static void beginTransaction(SPISettings settings);
/**
* @brief End SPI transaction.
*/
static void endTransaction();
/**
* @brief Not implemented.
*
* @param interruptNumber ignored parameter.
*/
static void usingInterrupt(uint8_t interruptNumber);
/**
* @brief Not implemented.
*
* @param interruptNumber ignored parameter.
*/
static void notUsingInterrupt(uint8_t interruptNumber);

private:
static uint8_t initialized; //!< @brief SPI initialized flag.
};

uint8_t SPIBCMClass::transfer(uint8_t data)
{
return bcm2835_spi_transfer(data);
}

void SPIBCMClass::transfernb(char* tbuf, char* rbuf, uint32_t len)
{
bcm2835_spi_transfernb( tbuf, rbuf, len);
}

void SPIBCMClass::transfern(char* buf, uint32_t len)
{
transfernb(buf, buf, len);
}

extern SPIBCMClass SPIBCM;

#endif

+ 213
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/Wire.cpp View File

@@ -0,0 +1,213 @@
/*
TwoWire.h - TWI/I2C library for Arduino & Wiring
Copyright (c) 2006 Nicholas Zambetti. All right reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
Modified December 2014 by Ivan Grokhotkov (ivan@esp8266.com) - esp8266 support
Modified April 2015 by Hrsto Gochkov (ficeto@ficeto.com) - alternative esp8266 support
Modified October 2016 by Marcelo Aquino <marceloaqno@gmail.org> for Raspberry Pi
*/

#include "Wire.h"
#include <stdlib.h>
#include <pthread.h>
#include "bcm2835.h"
#include "log.h"

static pthread_mutex_t i2cMutex = PTHREAD_MUTEX_INITIALIZER;

uint8_t TwoWire::rxBuffer[BUFFER_LENGTH];
uint8_t TwoWire::rxBufferIndex = 0;
uint8_t TwoWire::rxBufferLength = 0;

uint8_t TwoWire::txAddress = 0;
uint8_t TwoWire::txBuffer[BUFFER_LENGTH];
uint8_t TwoWire::txBufferIndex = 0;
uint8_t TwoWire::txBufferLength = 0;

uint8_t TwoWire::transmitting = 0;

void TwoWire::begin()
{
if (!bcm2835_i2c_begin()) {
logError("You need root privilege to use I2C.\n");
exit(1);
}
}

void TwoWire::begin(uint8_t address)
{
begin();
bcm2835_i2c_setSlaveAddress(address);
}

void TwoWire::begin(int address)
{
begin(static_cast<uint8_t>(address));
}

void TwoWire::end()
{
bcm2835_i2c_end();
}

void TwoWire::setClock(uint32_t clock)
{
bcm2835_i2c_set_baudrate(clock);
}

void TwoWire::beginTransmission(uint8_t address)
{
pthread_mutex_lock(&i2cMutex);
// indicate that we are transmitting
transmitting = 1;
// set address of targeted slave
txAddress = address;
// reset tx buffer iterator vars
txBufferIndex = 0;
txBufferLength = 0;
}

void TwoWire::beginTransmission(int address)
{
beginTransmission(static_cast<uint8_t>(address));
}

uint8_t TwoWire::endTransmission(void)
{
// transmit buffer
bcm2835_i2c_setSlaveAddress(txAddress);
uint8_t ret = bcm2835_i2c_write(reinterpret_cast<const char *>(txBuffer), txBufferLength);

// reset tx buffer iterator vars
txBufferIndex = 0;
txBufferLength = 0;
// indicate that we are done transmitting
transmitting = 0;

pthread_mutex_unlock(&i2cMutex);

if (ret == BCM2835_I2C_REASON_OK) {
return 0; // success
} else if (ret == BCM2835_I2C_REASON_ERROR_NACK) {
return 3; // error: data send, nack received
}
return 4; // other error
}

size_t TwoWire::requestFrom(uint8_t address, size_t quantity)
{
// clamp to buffer length
if (quantity > BUFFER_LENGTH) {
quantity = BUFFER_LENGTH;
}

rxBufferIndex = 0;
rxBufferLength = 0;

bcm2835_i2c_setSlaveAddress(address);
uint8_t ret = bcm2835_i2c_read(reinterpret_cast<char *>(rxBuffer), quantity);
if (ret == BCM2835_I2C_REASON_OK) {
rxBufferLength = quantity;
}

return rxBufferLength;
}

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
{
return requestFrom(address, static_cast<size_t>(quantity));
}

uint8_t TwoWire::requestFrom(int address, int quantity)
{
return requestFrom(static_cast<uint8_t>(address), static_cast<size_t>(quantity));
}

size_t TwoWire::write(uint8_t data)
{
if (transmitting) {
// in master transmitter mode
// don't bother if buffer is full
if (txBufferLength >= BUFFER_LENGTH) {
setWriteError();
return 0;
}
// put byte in tx buffer
txBuffer[txBufferIndex] = data;
++txBufferIndex;
// update amount in buffer
txBufferLength = txBufferIndex;

return 1;
} else {
return write(&data, 1);
}
}

size_t TwoWire::write(const uint8_t *data, size_t quantity)
{
if (transmitting) {
// in master transmitter mode
for (size_t i = 0; i < quantity; ++i) {
write(data[i]);
}
} else {
uint8_t rc = bcm2835_i2c_write(reinterpret_cast<const char *>(data), quantity);
if (rc != BCM2835_I2C_REASON_OK) {
return 0;
}
}

return quantity;
}

int TwoWire::available()
{
return rxBufferLength - rxBufferIndex;
}

int TwoWire::read()
{
int value = -1;

if (rxBufferIndex < rxBufferLength) {
value = rxBuffer[rxBufferIndex];
++rxBufferIndex;
}

return value;
}

int TwoWire::peek()
{
if (rxBufferIndex < rxBufferLength) {
return rxBuffer[rxBufferIndex];
}

return -1;
}

void TwoWire::flush()
{
rxBufferIndex = 0;
rxBufferLength = 0;
txBufferIndex = 0;
txBufferLength = 0;
}

TwoWire Wire = TwoWire();

+ 94
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/Wire.h View File

@@ -0,0 +1,94 @@
/*
TwoWire.h - TWI/I2C library for Arduino & Wiring
Copyright (c) 2006 Nicholas Zambetti. All right reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
Modified December 2014 by Ivan Grokhotkov (ivan@esp8266.com) - esp8266 support
Modified April 2015 by Hrsto Gochkov (ficeto@ficeto.com) - alternative esp8266 support
Modified October 2016 by Marcelo Aquino <marceloaqno@gmail.org> for Raspberry Pi
*/

#ifndef Wire_h
#define Wire_h

#if !DOXYGEN
#include <stdint.h>
#include "Stream.h"
#include "BCM.h"

#define BUFFER_LENGTH 32

class TwoWire : public Stream
{

private:
static uint8_t rxBuffer[];
static uint8_t rxBufferIndex;
static uint8_t rxBufferLength;

static uint8_t txAddress;
static uint8_t txBuffer[];
static uint8_t txBufferIndex;
static uint8_t txBufferLength;

static uint8_t transmitting;

public:
void begin();
void begin(uint8_t address);
void begin(int address);
void end();
void setClock(uint32_t clock);

void beginTransmission(uint8_t address);
void beginTransmission(int address);
uint8_t endTransmission(void);

size_t requestFrom(uint8_t address, size_t size);
uint8_t requestFrom(uint8_t address, uint8_t quantity);
uint8_t requestFrom(int address, int quantity);

size_t write(uint8_t data);
size_t write(const uint8_t *data, size_t quantity);
int available();
int read();
int peek();
void flush();

inline size_t write(unsigned long n)
{
return write((uint8_t)n);
}
inline size_t write(long n)
{
return write((uint8_t)n);
}
inline size_t write(unsigned int n)
{
return write((uint8_t)n);
}
inline size_t write(int n)
{
return write((uint8_t)n);
}
using Print::write;
};

extern TwoWire Wire;

#endif
#endif

+ 1480
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/bcm2835.c
File diff suppressed because it is too large
View File


+ 0
- 0
arduino/Doorsensor_Dohle/doorsensor/libraries/MySensors/drivers/BCM/bcm2835.h View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save