Sensor Watch Simulator (#35)

* Put something on screen

* Use the 32bit watch_date_time repr to pass from JS

* Implement periodic callbacks

* Clear display on enabling

* Hook up watch_set_led_color() to SVG (green-only)

* Make debug output full-width

* Remove default Emscripten canvas

* Implement sleep and button clicks

* Fix time zone conversion bug in beats-time app

* Clean up warnings

* Fix pin levels

* Set time zone to browser value (if available)

* Add basic backup data saving

* Silence format specifier warnings in both targets

* Remove unnecessary, copied files

* Use RTC pointer to clear callbacks (if available)

* Use preprocessor define to avoid hardcoding MOVEMENT_NUM_FACES

* Change each face to const preprocessor definition

* Remove Intl.DateTimeFormat usage

* Update shell.html title, header

* Add touch start/end event handlers on SVG buttons

* Update shell.html

* Update folder structure (shared, simulator, hardware under watch-library)

* Tease out shared components from watch_slcd

* Clean up simulator watch_slcd.c inline JS calls

* Fix missing newlines at end of file

* Add simulator warnings (except format, unused-paremter)

* Implement remaining watch_rtc functions

* Fix button bug on mouse down then drag out

* Implement remaining watch_slcd functions

* Link keyboard events to buttons (for keys A, L, M)

* Rewrite event handling (mouse, touch, keyboard) in C

* Set explicit text UTF-8 charset in shell.html

* Address PR comments

* Remove unused directories from include paths
This commit is contained in:
Alexsander Akers
2022-01-25 15:03:22 -05:00
committed by GitHub
parent 9e24f6c336
commit b8de35658f
327 changed files with 2303 additions and 570 deletions

View File

@@ -0,0 +1,87 @@
/**
* \file
*
* \brief SAM PORT.
*
* Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include <compiler.h>
#include <hpl_gpio.h>
#include <utils_assert.h>
#include <hpl_port_config.h>
/**
* \brief Set direction on port with mask
*/
static inline void _gpio_set_direction(const enum gpio_port port, const uint32_t mask,
const enum gpio_direction direction)
{
}
/**
* \brief Set output level on port with mask
*/
static inline void _gpio_set_level(const enum gpio_port port, const uint32_t mask, const bool level)
{
}
/**
* \brief Change output level to the opposite with mask
*/
static inline void _gpio_toggle_level(const enum gpio_port port, const uint32_t mask)
{
}
/**
* \brief Get input levels on all port pins
*/
static inline uint32_t _gpio_get_level(const enum gpio_port port)
{
uint32_t tmp = 0;
return tmp;
}
/**
* \brief Set pin pull mode
*/
static inline void _gpio_set_pin_pull_mode(const enum gpio_port port, const uint8_t pin,
const enum gpio_pull_mode pull_mode)
{
}
/**
* \brief Set gpio pin function
*/
static inline void _gpio_set_pin_function(const uint32_t gpio, const uint32_t function)
{
}
static inline void _port_event_init()
{
}

View File

@@ -0,0 +1,70 @@
/*
* MIT License
*
* Copyright (c) 2022 Joey Castillo
*
* 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.
*/
#include <stdio.h>
#include "watch.h"
#include <emscripten.h>
#include <emscripten/html5.h>
static bool sleeping = true;
static EM_BOOL main_loop(double time, void *userData) {
if (sleeping) {
sleeping = false;
app_wake_from_standby();
}
bool can_sleep = app_loop();
if (can_sleep) {
app_prepare_for_standby();
sleeping = true;
return EM_FALSE;
}
return EM_TRUE;
}
// make compiler happy
void resume_main_loop(void);
EMSCRIPTEN_KEEPALIVE
void resume_main_loop(void) {
if (sleeping) {
emscripten_request_animation_frame_loop(main_loop, NULL);
}
}
int main(void) {
printf("Hello, world!\n");
app_init();
_watch_init();
app_setup();
resume_main_loop();
return 0;
}

View File

@@ -0,0 +1,368 @@
<!DOCTYPE html>
<html>
<head>
<!--
Original F-91W SVG by Alexis Philip
https://github.com/alexisphilip/Casio-F-91W
MIT License
Copyright (c) 2020 Alexis Philip
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.
-->
<title>Sensor Watch Emulator</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<style>
body { font-family: Helvetica, Arial, sans-serif; background-color: #808080; margin: 0; padding: 0; }
a { color: #001d5c; }
textarea { margin: 0; padding: 0; border: 0; font-size: medium; font-family: monospace; }
.highlight { fill: #fff !important; }
</style>
</head>
<body>
<div style="max-width: 800px; margin: 0 auto; display: flex; flex-direction: column; align-items: center;">
<h1 style="text-align: center;">Sensor Watch Emulator</h1>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1271 1311" width="320">
<defs>
<radialGradient id="Dégradé_sans_nom_3" data-name="Dégradé sans nom 3" cx="635" cy="687" fx="260.1751499985994" r="374.83" gradientUnits="userSpaceOnUse">
<stop offset="0.28" stop-color="lime"/>
<stop offset="0.46" stop-color="#00b200" stop-opacity="0.7"/>
<stop offset="0.65" stop-color="#006700" stop-opacity="0.4"/>
<stop offset="0.82" stop-color="#002f00" stop-opacity="0.19"/>
<stop offset="0.94" stop-color="#000d00" stop-opacity="0.05"/>
<stop offset="1" stop-opacity="0"/>
</radialGradient>
</defs>
<g id="Calque">
<g id="Contours">
<path id="btn3" d="M1226,777h39.08a5.92,5.92,0,0,1,5.92,5.92v58.16a5.92,5.92,0,0,1-5.92,5.92H1226a0,0,0,0,1,0,0V777A0,0,0,0,1,1226,777Z" style="fill: #999"/>
<path id="btn2" d="M2593.5,686h39.08a5.92,5.92,0,0,1,5.92,5.92v58.16a5.92,5.92,0,0,1-5.92,5.92H2593.5a0,0,0,0,1,0,0V686A0,0,0,0,1,2593.5,686Z" transform="translate(2638.5 1533) rotate(180)" style="fill: #999"/>
<path id="btn1" d="M2593.5,386h39.08a5.92,5.92,0,0,1,5.92,5.92v58.16a5.92,5.92,0,0,1-5.92,5.92H2593.5a0,0,0,0,1,0,0V386A0,0,0,0,1,2593.5,386Z" transform="translate(2638.5 933) rotate(180)" style="fill: #999"/>
<path id="Contour_1" data-name="Contour 1" d="M2855-91h752c16,0,17,13,17,13l35,112c5,14,6,13,6,13l122,206a23,23,0,0,0,6,7l25,24a31.37,31.37,0,0,1,9,17l13,187c0,16-8,19-8,19l-29,24c2,46,0,84,0,84l28,21c6,5,6,15,6,15l-13,187c-1,12-7,16-7,16l-32,30a39.08,39.08,0,0,0-4,5l-121,206h0a107.12,107.12,0,0,0-6,12l-37,101a19.32,19.32,0,0,1-17,12H2868c-21,0-24-12-24-12l-37-99a123.46,123.46,0,0,0-8-18L2679,888c-4-6-12-12-12-12l-22-21c-9-9-8-19-8-19l-15-182c-1-10,4-14,4-14l30-27V532l-28-24a24.69,24.69,0,0,1-7-16l13-190c1-11,7-15,7-15l34-33c6-5,7-9,7-9L2792,52c7-10,9-18,9-18l36-111C2840-91,2855-91,2855-91Z" transform="translate(-2593.5 91)" style="fill: #333"/>
<path id="Contour_2" data-name="Contour 2" d="M2799,1060c18.5,26.5,37,27,37,27,455.44,18.42,790,0,790,0s24,0,41-29l86-154s16.5-20.5,20-55c30-295.67,1-557,1-557s1-17-13-47L3672,87c-14-23-37-22-37-22-389.5-13.5-809,0-809,0-29,1-37,24-37,24l-87,153a119.3,119.3,0,0,0-17,48c-24.58,335.84,3,569,3,569,4.5,16.5,17.86,37.6,17.86,37.6Z" transform="translate(-2593.5 91)" style="fill: #3d3d3d"/>
<g id="Contour_centre" data-name="Contour centre">
<path d="M3712.11,308.15C3711,283,3693,258,3693,258l-43-69c-20-34-60-35-60-35-360-13-725,1-725,1-33.26,1.17-49,25-49,25l-53,84c-15,25-17,46-17,46-22,287-1,518-1,518,3,30,21,56,21,56l42,72c23,37,60,40,60,40,392,15,716.5.5,716.5.5C3633,992,3653,953,3653,953l43-73s10-13.87,13.5-43.5C3739,587,3712.11,308.15,3712.11,308.15ZM3570,728.32A34.68,34.68,0,0,1,3535.32,763H2921.68A34.68,34.68,0,0,1,2887,728.32V463.68A34.68,34.68,0,0,1,2921.68,429h613.64A34.68,34.68,0,0,1,3570,463.68Z" transform="translate(-2593.5 91)" style="fill: #333"/>
</g>
<path id="Contour_bleu" data-name="Contour bleu" d="M2886.5,193.5c-30.78,1.07-51,26-51,26a719.08,719.08,0,0,0-43,69,107.83,107.83,0,0,0-12,45c-20.17,253.56,2,489,2,489,1.06,24.61,18,53,18,53,17,32,39,58,39,58,16,23,47,25,47,25,373.59,13.91,680,1,680,1,37,0,59-36,59-36,17-25.68,35-58,35-58a94.2,94.2,0,0,0,12-38c20.17-223.6,1-496,1-496-1-27-15-49-15-49-15.92-30-37-63-37-63-14-23-50-26-50-26C3207.46,179.59,2886.5,193.5,2886.5,193.5Z" transform="translate(-2593.5 91)" style="fill: none;stroke: #0e57a9;stroke-miterlimit: 10;stroke-width: 16px"/>
<path id="Contour_blanc" data-name="Contour blanc" d="M2894.5,217.5c-29,1-41,22-41,22-23,32-40,68-40,68a103.23,103.23,0,0,0-6,31c-19,237,2,476,2,476,1,23,13,43,13,43,15,30,37,58,37,58,10,14,34,16,34,16,352,13,667,1,667,1,29-1,41-21,41-21,16-24,31-49,31-49,14-24,15-43,15-43,19-209,1-478,1-478-1-27-10-43-10-43-15-28-37-60-37-60-10-16-30-19-30-19C3228.5,206.5,2894.5,217.5,2894.5,217.5Z" transform="translate(-2593.5 91)" style="fill: none;stroke: #fff;stroke-miterlimit: 10;stroke-width: 3px"/>
<g id="Contour_ecran" data-name="Contour ecran">
<path d="M3539,416A45.1,45.1,0,0,1,3584,461.05V733A45.1,45.1,0,0,1,3539,778h-620.9A45.1,45.1,0,0,1,2873,733V461.05A45.1,45.1,0,0,1,2918.05,416H3539m0-3h-620.9A48,48,0,0,0,2870,461.05V733a48,48,0,0,0,48.05,48H3539A48,48,0,0,0,3587,733V461.05A48,48,0,0,0,3539,413Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
</g>
<g id="Ecran">
<rect x="293.5" y="520" width="683" height="334" rx="34.68" style="fill: #777b7a"/>
</g>
<g id="light" style="opacity: 0">
<rect x="293.5" y="520" width="683" height="334" rx="34.68" style="fill: url(#Dégradé_sans_nom_3)"/>
</g>
</g>
<g id="Textes">
<g>
<path d="M3379.84,864.39h20.51q7.28,0,10.5,1.71c2.16,1.12,3.23,3.2,3.23,6.24v1a4.21,4.21,0,0,1-.12,1,6.3,6.3,0,0,1-.67,2.12,4.16,4.16,0,0,1-1.87,1.72,7.5,7.5,0,0,1-1.67.62c-.62.15-1.24.28-1.87.38l-.73.1c-.23,0-.47.07-.73.09v.12a10.14,10.14,0,0,1,5.45,1.46,4.14,4.14,0,0,1,1.71,3.53V890h-8.17v-4.65l.06-.57a2.67,2.67,0,0,0-1.8-2.61,12.68,12.68,0,0,0-4.59-.69h-11.39V890h-7.85Zm19.24,13c2.49,0,4.23-.26,5.22-.87a3.29,3.29,0,0,0,1.49-3.05,6,6,0,0,0-.85-3.55c-.57-.78-2.36-1.17-5.35-1.17h-11.9v8.64Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3426.36,875.15h19.81v3.57h-19.81V886h21v4h-28.87V864.39h28.68v4.08h-20.83Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3476.68,871.88a3,3,0,0,0-1.51-3,12.78,12.78,0,0,0-5.26-.77h-2.21c-.38,0-.8,0-1.24,0s-.88,0-1.3,0a19.65,19.65,0,0,0-2,.17,8.6,8.6,0,0,0-1.77.4,2.55,2.55,0,0,0-1.14.79,3.36,3.36,0,0,0-.57,1.07,3,3,0,0,1,0,.43,1.94,1.94,0,0,0,0,.4,2.76,2.76,0,0,0,1.24,2.63,10.64,10.64,0,0,0,4.52.83,6,6,0,0,1,.61,0l.6,0,1.61,0c.53,0,1,0,1.55,0a62.72,62.72,0,0,1,11,1.06q4.76.95,4.75,6.07a8.23,8.23,0,0,1-1.71,5.37c-1.14,1.4-3.78,2.22-7.91,2.48l-2,.06c-.65,0-1.29,0-1.93.06s-1.34,0-2,0h-2a58,58,0,0,1-11.87-1q-4.59-1-4.59-6.3v-.25a.54.54,0,0,1,.06-.25v-.5l7.66,0a5.67,5.67,0,0,0,.79,3.08c.53.85,2,1.29,4.34,1.31,1,0,2,0,3,0h3a16.05,16.05,0,0,0,5.45-.67q1.71-.68,1.71-3,0-2.54-2.19-3a28.79,28.79,0,0,0-5.6-.5h-1.26c-.43,0-.87,0-1.33,0l-.67,0q-.35,0-.66-.06a45.92,45.92,0,0,1-10.48-1.36q-3.77-1.1-3.77-6.17a5.83,5.83,0,0,1,2.28-4.95q2.28-1.72,7.79-2c1.1-.05,2.2-.09,3.32-.11s2.23,0,3.33,0a66.79,66.79,0,0,1,11.33.84c3.2.57,4.81,2.49,4.81,5.76v1Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3498,890h-8.1V864.39h8.1Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3527.89,871.88a3,3,0,0,0-1.52-3,12.69,12.69,0,0,0-5.25-.77h-2.21c-.38,0-.8,0-1.24,0s-.88,0-1.3,0a19.65,19.65,0,0,0-2,.17,8.6,8.6,0,0,0-1.77.4,2.55,2.55,0,0,0-1.14.79,3.36,3.36,0,0,0-.57,1.07,3,3,0,0,1,0,.43,2.91,2.91,0,0,0,0,.4,2.76,2.76,0,0,0,1.24,2.63,10.64,10.64,0,0,0,4.52.83,5.82,5.82,0,0,1,.6,0l.61,0,1.61,0c.53,0,1,0,1.55,0a62.72,62.72,0,0,1,11,1.06q4.76.95,4.75,6.07a8.23,8.23,0,0,1-1.71,5.37c-1.14,1.4-3.78,2.22-7.91,2.48l-2,.06c-.65,0-1.29,0-1.93.06s-1.34,0-2,0h-2a58,58,0,0,1-11.86-1q-4.59-1-4.59-6.3v-.25a.54.54,0,0,1,.06-.25v-.5l7.66,0a5.67,5.67,0,0,0,.79,3.08c.53.85,2,1.29,4.34,1.31,1,0,2,0,3,0h3a16.05,16.05,0,0,0,5.45-.67q1.71-.68,1.71-3,0-2.54-2.19-3a28.79,28.79,0,0,0-5.6-.5h-1.27c-.42,0-.86,0-1.33,0l-.66,0q-.35,0-.66-.06a45.92,45.92,0,0,1-10.48-1.36q-3.77-1.1-3.77-6.17a5.83,5.83,0,0,1,2.28-4.95q2.28-1.72,7.79-2c1.09-.05,2.2-.09,3.32-.11s2.23,0,3.32,0a66.63,66.63,0,0,1,11.33.84q4.82.86,4.82,5.76v1Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3557.9,890h-8.17V868.73h-12.22v-4.34h32.79v4.34h-12.4Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
</g>
<g id="WR">
<path id="R" d="M3300,854h-43a3.55,3.55,0,0,0-3,2l-20,37s-1,2,2,2h8a4.94,4.94,0,0,0,3-1l6-9a4.33,4.33,0,0,1,4-2h22a6.19,6.19,0,0,1,4,2l6,8a4.33,4.33,0,0,0,4,2h8s3,0,2-2l-5-6s-6-5,1-7l7.38-3.69a8.49,8.49,0,0,0,4.07-4.36C3312.86,866.12,3316,854,3300,854Zm-5,18a6.19,6.19,0,0,1-4,2h-27c-6,0-4-3-4-3l1-2,2-4a6.46,6.46,0,0,1,5-3h23C3299,862,3298.2,868.8,3295,872Z" transform="translate(-2593.5 91)" style="fill: #771217"/>
<path id="W" d="M3156,854s2,0,3,3l9,26c2,3,4,0,4,0l13-27h0a3.55,3.55,0,0,1,3-2h8a3.7,3.7,0,0,1,3,2l9,25h0c2,4,4,0,4,0l14-25h0c1-2,2-2,2-2h9c3,0,1,3,1,3l-20,36h0a6.19,6.19,0,0,1-4,2h-8c-3,0-4-3-4-3l-8-24c-3-6-5,0-5,0l-12,25a3.55,3.55,0,0,1-3,2h-10c-2,0-3-3-3-3l-15-35c-1-3,1-3,1-3h9" transform="translate(-2593.5 91)" style="fill: #771217"/>
</g>
<g id="WATER">
<g>
<path d="M2994.68,890h-8.17V868.73h-12.22v-4.34h32.79v4.34h-12.4Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3016.83,875.15h19.81v3.57h-19.81V886h21v4H3009V864.39h28.68v4.08h-20.83Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3043.54,864.39h20.51q7.27,0,10.51,1.71t3.23,6.24v1a4.22,4.22,0,0,1-.13,1,6.51,6.51,0,0,1-.66,2.12,4.21,4.21,0,0,1-1.87,1.72,7.78,7.78,0,0,1-1.68.62c-.61.15-1.23.28-1.87.38l-.72.1c-.24,0-.48.07-.73.09v.12a10.1,10.1,0,0,1,5.44,1.46,4.14,4.14,0,0,1,1.71,3.53V890h-8.17v-4.65l.07-.57a2.7,2.7,0,0,0-1.81-2.61,12.68,12.68,0,0,0-4.59-.69h-11.39V890h-7.85Zm19.24,13c2.49,0,4.23-.26,5.23-.87a3.28,3.28,0,0,0,1.48-3.05,6,6,0,0,0-.85-3.55q-.85-1.17-5.35-1.17h-11.9v8.64Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
</g>
<path d="M2951,885.1,2948.4,890H2940L2954,864.39h11.9L2980.24,890H2972l-2.73-4.91Zm9.12-16.94-7.22,13.29h14.56Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M2934,890h-9.79l-7-19.55h-.16L2909.8,890h-9.63L2891,864.39h6.74l7.31,21.59h.21l8.05-21.59h7.74l8,21.59,7.63-21.59h6.79Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
</g>
<g id="ALARM_ON" data-name="ALARM ON">
<g>
<path d="M3465.8,817.11v1.58h-19v-3.12c0-1.75.54-2.89,1.63-3.43s3.65-1,7.7-1.25c3.25-.23,5.21-.53,5.88-.92s1-1.4,1-3c0-1.43-.38-2.35-1.13-2.77s-2.4-.64-4.94-.64q-4.74,0-6,.51c-.83.35-1.25,1.17-1.25,2.49l0,1.23h-2.92l0-.86c0-2,.67-3.3,2-4s4-1,8-1q5.32,0,7.16,1.07c1.23.71,1.84,2.1,1.84,4.16s-.57,3.31-1.71,4-3.62,1.12-7.43,1.35c-3.35.21-5.34.51-6,.88s-1,1.42-1,3.16v.56Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3486.12,802.13v11.16h3.94v1.58h-3.94v3.82h-3v-3.82h-14.76v-2.2l13.14-10.54Zm-3,11.16v-10h-.06l-12.25,10Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3513.9,802.13v16.56h-3V811h-15.42v7.68h-3V802.13h3v7.3h15.42v-7.3Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3517.32,818.69V802.13h12.56q4.24,0,6,1.06a3.92,3.92,0,0,1,1.73,3.66,4.35,4.35,0,0,1-.94,3.2,6.32,6.32,0,0,1-3.61,1.17v0q4.18.19,4.19,3.21v4.23h-3v-3.81q0-2.89-4-2.9h-10v6.71Zm3-8.29h8.59a11.06,11.06,0,0,0,4.64-.65,2.5,2.5,0,0,0,1.24-2.44c0-1.49-.31-2.47-.92-2.92s-1.92-.68-3.93-.68h-9.62Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
</g>
<path id="_" data-name="/" d="M3421.46,808h19.33a1.24,1.24,0,0,1,1.24,1.24v.72a1.19,1.19,0,0,1-1.19,1.19H3422a1.83,1.83,0,0,1-1.83-1.83v0a1.32,1.32,0,0,1,1.32-1.32Z" transform="translate(-1763.06 3280.53) rotate(-55.74)" style="fill: #fff"/>
<g>
<path d="M3366.82,801q7.47,0,9.35,1.37c1.25.92,1.87,3.2,1.87,6.86q0,5.89-1.79,7.28t-9.43,1.39q-7.59,0-9.42-1.37t-1.82-7.09v-1.16l0-1.57c0-2.19.78-3.7,2.36-4.5S3362.5,801,3366.82,801Zm0,1.58q-6.26,0-7.32.87t-1.06,6c0,3.42.35,5.43,1.06,6s3.15.87,7.32.87,6.63-.29,7.34-.87,1.06-2.59,1.06-6v-1.08l0-1.56q0-2.75-1.47-3.48C3372.74,802.79,3370.43,802.54,3366.8,802.54Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3384.42,802.71v5.78h12.84v1.58h-12.84v7.62h-3V801.13h16.17v1.58Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3403.75,802.71v5.78h12.85v1.58h-12.85v7.62h-3V801.13h16.16v1.58Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
</g>
<rect id="_." data-name="." x="3341.2" y="806.08" width="6.87" height="6.72" rx="3.36" transform="matrix(0, -1, 1, 0, -58.3, 4245.08)" style="fill: #fff"/>
<g>
<path d="M3294.82,801q7.47,0,9.35,1.37c1.25.92,1.87,3.2,1.87,6.86q0,5.89-1.79,7.28t-9.43,1.39q-7.59,0-9.42-1.37t-1.82-7.09v-1.16l0-1.57c0-2.19.78-3.7,2.36-4.5S3290.5,801,3294.82,801Zm0,1.58q-6.26,0-7.32.87t-1.06,6c0,3.42.35,5.43,1.06,6s3.15.87,7.32.87,6.63-.29,7.34-.87,1.06-2.59,1.06-6v-1.08l0-1.56q0-2.75-1.47-3.48C3300.74,802.79,3298.43,802.54,3294.8,802.54Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3332,801.13v16.56h-4.88l-11-11.27-1.8-1.86-.89-.92-.88-.92h-.08l0,.62,0,.63v13.72h-3V801.13h4.87L3324,811l2.51,2.6,1.25,1.29,1.24,1.29h.08l0-.61,0-.64v-13.8Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
</g>
<g>
<path d="M3153.39,814.18H3140l-2,3.51h-3.15l9.66-16.56h4.17l9.85,16.56h-3.11Zm-.87-1.4-5.86-10.12-5.77,10.12Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3164.22,801.13V816h13.56v1.74h-16.53V801.13Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3196.64,814.18h-13.35l-2,3.51h-3.15l9.66-16.56h4.17l9.85,16.56h-3.11Zm-.87-1.4-5.86-10.12-5.77,10.12Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3204.5,817.69V801.13h12.55c2.84,0,4.83.35,6,1.06a3.92,3.92,0,0,1,1.74,3.66,4.35,4.35,0,0,1-1,3.2,6.29,6.29,0,0,1-3.61,1.17v0c2.8.13,4.19,1.2,4.19,3.21v4.23h-3v-3.81q0-2.89-4-2.9h-10v6.71Zm3-8.29h8.6a11,11,0,0,0,4.63-.65,2.48,2.48,0,0,0,1.24-2.44c0-1.49-.31-2.47-.92-2.92s-1.92-.68-3.93-.68h-9.62Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3258.08,801.13v16.56h-3V803.45l0-.5,0-.5h-.08l-.23.39-.24.38-.5.77-9,13.7h-3l-9-13.54-.52-.76-.23-.39a4.09,4.09,0,0,1-.23-.38h-.08l0,.45,0,.46v14.16h-3V801.13h5.15l7,10.71,1.13,1.74.55.86.55.86h.07l.54-.86c.27-.41.46-.7.54-.86l1.14-1.73,7-10.72Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
</g>
</g>
<g>
<path d="M2948.12,801.13v16.56h-3V803.45l0-.5,0-.5h-.08l-.23.39-.23.38-.5.77-9,13.7h-3l-9-13.54-.52-.76-.24-.39a4.09,4.09,0,0,1-.23-.38h-.07l0,.45,0,.46v14.16h-3V801.13h5.16l7,10.71,1.12,1.74.56.86.54.86h.08l.54-.86c.27-.41.45-.7.54-.86l1.14-1.73,7-10.72Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M2962.76,801q7.47,0,9.35,1.37c1.25.92,1.87,3.2,1.87,6.86q0,5.89-1.8,7.28c-1.19.93-4.34,1.39-9.42,1.39s-8.2-.46-9.42-1.37-1.82-3.28-1.82-7.09v-1.16l0-1.57c0-2.19.79-3.7,2.37-4.5S2958.44,801,2962.76,801Zm0,1.58q-6.25,0-7.32.87t-1.07,6c0,3.42.36,5.43,1.07,6s3.15.87,7.32.87,6.63-.29,7.34-.87,1.06-2.59,1.06-6v-1.08l0-1.56q0-2.75-1.47-3.48T2962.74,802.54Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M2977.38,817.69V801.13h12.21q5.65,0,7.67,1.57t2,6q0,5.38-1.79,7.19t-7.14,1.81Zm3-1.58H2989q4.74,0,6.1-1.19t1.38-5.3q0-4.51-1.19-5.71t-5.69-1.2h-9.19Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3005.14,802.71v5.64h13.38v1.58h-13.38v6.18h14v1.58h-16.94V801.13h16.94v1.58Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
</g>
<g>
<path d="M2920.16,374.13V389h13.55v1.74h-16.53V374.13Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M2939.34,374.13v16.56h-3V374.13Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M2953.82,382.45h11.3a16.4,16.4,0,0,1,.08,1.81q0,4.47-1.75,5.54c-1.16.7-4.2,1.06-9.12,1.06q-7,0-9-1.26c-1.32-.83-2-2.71-2-5.63l0-2.44,0-1.47q0-3.68,2.21-4.88t8.92-1.22q6.72,0,8.67.8t1.95,3.54v.64h-2.91v-.42c0-1.35-.44-2.18-1.33-2.5s-3.18-.48-6.9-.48q-5.16,0-6.45.77c-.87.51-1.3,1.8-1.3,3.85l0,2.2,0,2.36c0,2.09.48,3.37,1.44,3.85s3.52.71,7.68.71q4.77,0,5.9-.68c.75-.45,1.13-1.64,1.13-3.55a7.07,7.07,0,0,0-.15-1h-8.39Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M2990.27,374.13v16.56h-3V383h-15.42v7.68h-3V374.13h3v7.3h15.42v-7.3Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3004.47,375.87v14.82h-3V375.87h-8.6v-1.74H3013v1.74Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
</g>
<g>
<path d="M3293.74,382.93H3299a5.92,5.92,0,0,0,0,.61c0,.19,0,.36,0,.53a5.24,5.24,0,0,0,0,.56c0,.19,0,.38,0,.57,0,3.19-1,5.24-2.84,6.18a16.29,16.29,0,0,1-7.2,1.39h-3.74c-3.95,0-6.55-.93-7.81-2.81s-1.89-4.56-1.89-8c0-.32,0-.65,0-1s0-.67,0-1,0-.33,0-.49a3.93,3.93,0,0,1,0-.49c0-.48,0-1,0-1.48s0-1,0-1.47c0-4.54,1.06-7.43,3.16-8.67s5.26-1.86,9.49-1.86l1.8,0c.2,0,.39,0,.57,0h.57a16,16,0,0,1,3.63.56,5,5,0,0,1,2.84,2.11,5.62,5.62,0,0,1,1,2.29,15.86,15.86,0,0,1,.28,2.45,3,3,0,0,0,0,.42c0,.15,0,.29,0,.43a3.85,3.85,0,0,0,0,.48c0,.17,0,.33,0,.49l-5.33,0a1.86,1.86,0,0,1-.11-.57c0-.21,0-.43-.06-.64v-.29a6.07,6.07,0,0,0-.44-2.08c-.27-.64-1.13-1-2.59-1.08a9.39,9.39,0,0,0-1.19-.08H3287a6.91,6.91,0,0,1-.8,0c-.28,0-.56,0-.84,0a12.86,12.86,0,0,0-1.79.3,2.94,2.94,0,0,0-1.36.71,3.18,3.18,0,0,0-.74,1.18,5.22,5.22,0,0,0-.27,1.35,5,5,0,0,0-.06.56,5.25,5.25,0,0,0,0,.56l-.06,1.28c0,.41,0,.84,0,1.27,0,.87,0,1.74,0,2.61l.06,2.62c0,2.7.51,4.36,1.43,5s2.72.95,5.38.95a15,15,0,0,0,4.09-.49c1.17-.32,1.75-1.4,1.75-3.24v-.85a1.87,1.87,0,0,1,0-.42v-.47Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path d="M3327.84,392.61h-5.38V381.07H3309.4v11.54h-5.33v-27h5.33v11h13.06v-11h5.38Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path d="M3334.47,365.6h13.61c3.22,0,5.55.63,7,1.8s2.15,3.37,2.15,6.58v1a6.23,6.23,0,0,1-.09,1.06,8.92,8.92,0,0,1-.44,2.22,3.92,3.92,0,0,1-1.24,1.83,4.56,4.56,0,0,1-1.11.65,11.18,11.18,0,0,1-1.24.4l-.48.1a3.86,3.86,0,0,1-.49.1v.12a5.1,5.1,0,0,1,3.62,1.54,5.63,5.63,0,0,1,1.13,3.73v5.87h-5.42v-4.9l0-.61a3.06,3.06,0,0,0-1.19-2.75,5.62,5.62,0,0,0-3.05-.73h-7.56v9h-5.21Zm12.77,13.65a4.92,4.92,0,0,0,3.47-.91,4.4,4.4,0,0,0,1-3.22,9.58,9.58,0,0,0-.56-3.75c-.38-.82-1.56-1.24-3.55-1.24h-7.9v9.12Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path d="M3362.32,379.45q0-6.72,1.57-10.37t9.64-3.64a27.5,27.5,0,0,1,8.64,1.24q3.75,1.24,4,7c.05.59.09,1.18.1,1.78s0,1.2,0,1.82v1.77c0,5-.56,8.56-1.7,10.65s-4.71,3.13-10.73,3.13c-4.23,0-7.22-.68-9-2.06s-2.64-4.23-2.64-8.55v-.73a5.79,5.79,0,0,1,0-.72v-1.34Zm5.46-.12v2.43c0,.4,0,.8,0,1.19s0,.79.06,1.2c.17,2,.74,3.25,1.7,3.68a10.76,10.76,0,0,0,4.27.65,11.26,11.26,0,0,0,5.29-.91c1.06-.61,1.64-2.17,1.72-4.68.06-1.1.09-2.21.09-3.3v-3.26q0-3.76-.95-5.14t-4.93-1.38c-3.62,0-5.72.49-6.33,1.48s-.9,2.88-.9,5.69v.36c0,.3,0,.62,0,1v1Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path d="M3417.51,392.61h-8.91L3396.76,370h-.17l.17,22.6h-5.21v-27h8.86l11.85,22.6h.16l-.16-22.6h5.25Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path d="M3423.34,379.45q0-6.72,1.58-10.37t9.64-3.64a27.44,27.44,0,0,1,8.63,1.24q3.76,1.24,4,7c.06.59.09,1.18.11,1.78s0,1.2,0,1.82v1.77c0,5-.57,8.56-1.7,10.65s-4.71,3.13-10.73,3.13c-4.23,0-7.23-.68-9-2.06s-2.65-4.23-2.65-8.55v-.73c0-.24,0-.48,0-.72v-1.34Zm5.46-.12v2.43c0,.4,0,.8,0,1.19s0,.79.06,1.2c.17,2,.73,3.25,1.7,3.68a10.73,10.73,0,0,0,4.26.65,11.3,11.3,0,0,0,5.3-.91q1.59-.92,1.72-4.68c.05-1.1.08-2.21.08-3.3v-3.26q0-3.76-.94-5.14t-4.94-1.38q-5.42,0-6.32,1.48t-.9,5.69v.36c0,.3,0,.62,0,1v1Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path d="M3476.1,378.27V379l.08,4.3a16.39,16.39,0,0,1-1.07,6.21c-.72,1.74-2.53,2.78-5.44,3.1-.92.08-1.85.14-2.77.16s-1.85,0-2.77,0q-6.35,0-9.39-1.92t-3-8.65v-.95a9.08,9.08,0,0,1,0-.91v-4.27c0-.39,0-.79,0-1.2a17.71,17.71,0,0,1,.4-3.3,7.74,7.74,0,0,1,1.36-3,6.22,6.22,0,0,1,3.21-2.37,16.27,16.27,0,0,1,4.06-.75c.42,0,.83,0,1.24,0h1.19l2.48,0q5.3,0,7.79,1.43c1.67.94,2.53,3.25,2.59,6.95l-5.38,0a4.7,4.7,0,0,0-.74-2.8,3.35,3.35,0,0,0-2.7-1.09c-.51,0-1-.05-1.52-.06l-1.51,0q-5.16,0-6.09,1.44t-1,6.25v1.34l0,3.48q0,4.22,1.4,5.21t5.53,1c2.57,0,4.34-.29,5.29-.87s1.43-2.14,1.43-4.68v-.4a.41.41,0,0,1,0-.18v-.19h-7.05v-3.89Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path d="M3481.43,365.6H3495q4.83,0,7,1.8t2.14,6.58v1a7.45,7.45,0,0,1-.08,1.06,9.92,9.92,0,0,1-.44,2.22,3.92,3.92,0,0,1-1.24,1.83,4.75,4.75,0,0,1-1.11.65,11.18,11.18,0,0,1-1.24.4l-.49.1a3.39,3.39,0,0,1-.48.1v.12a5.07,5.07,0,0,1,3.61,1.54,5.58,5.58,0,0,1,1.14,3.73v5.87h-5.42v-4.9l0-.61a3.09,3.09,0,0,0-1.2-2.75,5.59,5.59,0,0,0-3-.73h-7.56v9h-5.21Zm12.77,13.65a4.89,4.89,0,0,0,3.46-.91,4.35,4.35,0,0,0,1-3.22,9.36,9.36,0,0,0-.57-3.75c-.37-.82-1.56-1.24-3.55-1.24h-7.89v9.12Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path d="M3514.82,387.43l-1.72,5.18h-5.59l9.33-27h7.89l9.49,27h-5.46l-1.8-5.18Zm6-17.86-4.79,14h9.66Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path d="M3538.3,365.6h11.21c3.75,0,6.53.56,8.32,1.6s2.69,3.58,2.69,7.63c0,.35,0,.72,0,1.1s0,.75-.06,1.13a10.62,10.62,0,0,1-.52,2.75,5.16,5.16,0,0,1-1.58,2.31,5.76,5.76,0,0,1-2.83,1.44,17.41,17.41,0,0,1-3.26.3,2.12,2.12,0,0,1-.44,0h-8.3v8.71h-5.2Zm11.3,13.81a9.77,9.77,0,0,0,4.22-.59c.82-.42,1.24-1.71,1.24-3.87,0-2-.28-3.32-.84-4s-1.92-1-4.08-1h-6.64v9.4Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path d="M3589.41,392.61H3584V381.07H3571v11.54h-5.33v-27H3571v11H3584v-11h5.38Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
</g>
<g>
<path d="M3118.05,387.43l-1.72,5.18h-5.59l9.33-27H3128l9.5,27H3132l-1.81-5.18Zm6-17.86-4.79,14H3129Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path d="M3147.41,388.08h13v4.53H3142v-27h5.46Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path d="M3169.92,387.43l-1.72,5.18h-5.59l9.33-27h7.89l9.49,27h-5.46l-1.8-5.18Zm6-17.86-4.79,14h9.66Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path d="M3193.78,365.6h13.6q4.83,0,7,1.8c1.42,1.18,2.14,3.37,2.14,6.58v1a6.23,6.23,0,0,1-.09,1.06,8.92,8.92,0,0,1-.44,2.22,3.92,3.92,0,0,1-1.24,1.83,4.38,4.38,0,0,1-1.11.65,11.18,11.18,0,0,1-1.24.4l-.48.1a4.1,4.1,0,0,1-.48.1v.12A5.09,5.09,0,0,1,3215,383a5.63,5.63,0,0,1,1.13,3.73v5.87h-5.42v-4.9l.05-.61a3.09,3.09,0,0,0-1.2-2.75,5.62,5.62,0,0,0-3.05-.73H3199v9h-5.2Zm12.76,13.65a4.9,4.9,0,0,0,3.47-.91,4.35,4.35,0,0,0,1-3.22,9.36,9.36,0,0,0-.57-3.75c-.38-.82-1.56-1.24-3.55-1.24H3199v9.12Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path d="M3252.42,392.61h-4.78l.15-22.76-8,22.76h-4.4L3227.21,370l.23,22.64h-4.78v-27h7.88l6.88,20h.16l6.81-20h8Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
</g>
<g id="F-91W">
<path id="W-2" data-name="W" d="M3464,256h10c3,0,3,2,3,2v10c0,2,2,0,2,0l6-10a3.55,3.55,0,0,1,3-2h7c3,0,3,2,3,2l1,11c1,2,2,0,2,0l7-12a3.1,3.1,0,0,1,2-1h10c3,0,2,2,2,2l-17,29c-2,2-3,2-3,2h-11a2,2,0,0,1-2-2V276c0-3-2,0-2,0l-7,11a3.55,3.55,0,0,1-3,2h-10a2.94,2.94,0,0,1-3-3l-2-28A2,2,0,0,1,3464,256Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path id="_1" data-name="1" d="M3453,257l-5,30h0a3.55,3.55,0,0,1-3,2h-9a2,2,0,0,1-2-2l2-15c0-1-2-1-2-1h-3a1,1,0,0,1-1-1l1-8c8-1,10-6,10-6h10c2,0,2,1,2,1" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path id="_9" data-name="9" d="M3403,256s-11-1-18,5c0,0-9,9,7,17h-10s-3,6,9,10c0,0,9.57,2.73,19.1-.84a16.52,16.52,0,0,0,8.92-8C3422.69,271.92,3425.86,258.86,3403,256Zm-3,27c-6,0-5-5-5-5h10C3405,283,3400,283,3400,283Zm2-12c-5,0-5-4-5-4,0-4,5-4,5-4,5,0,5,4,5,4C3407,271,3402,271,3402,271Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path id="_-" data-name="-" d="M3354,269h16a2,2,0,0,1,2,2l-1,5h0c0,1-3,1-3,1h-15a2,2,0,0,1-2-2l1-5C3352,269,3354,269,3354,269Z" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
<path id="F" d="M3313,256h30a2,2,0,0,1,2,2l-1,4c-1,2-2,2-2,2h-17a2,2,0,0,0-2,2h0a2,2,0,0,0,2,2h12c3,0,2,2,2,2l-1,5a3.1,3.1,0,0,1-2,1h-13a2,2,0,0,0-2,2l-2,9c-1,2-2,2-2,2h-10c-3,0-2-3-2-3l5-28c0-2,3-2,3-2" transform="translate(-2593.5 91)" style="fill: #b6a66e"/>
</g>
<g>
<path d="M2980,275.39h10.59a8.2,8.2,0,0,0,0,.89,7.28,7.28,0,0,1,0,.78,7.7,7.7,0,0,0,.05.83c0,.28,0,.56,0,.83q0,7-5.72,9.08a43.49,43.49,0,0,1-14.52,2.06H2963q-11.94,0-15.75-4.14t-3.81-11.82c0-.47,0-1,0-1.46s0-1,0-1.45a5.79,5.79,0,0,0,0-.72,5.74,5.74,0,0,1,0-.71c0-.72,0-1.44,0-2.18s0-1.45,0-2.17q0-10,6.35-12.74t19.14-2.74l3.65-.06a11.17,11.17,0,0,0,1.14.06h1.14a43.37,43.37,0,0,1,7.33.84,10.33,10.33,0,0,1,5.71,3.09,7.38,7.38,0,0,1,2,3.37,17.45,17.45,0,0,1,.55,3.6,4.56,4.56,0,0,0,0,.62c0,.22,0,.43,0,.63a5.63,5.63,0,0,0,0,.71,5.79,5.79,0,0,1,0,.72l-10.75-.06a2.36,2.36,0,0,1-.21-.84c0-.31-.07-.63-.13-1V261a6.72,6.72,0,0,0-.89-3.06c-.54-.93-2.27-1.46-5.21-1.58a23.86,23.86,0,0,0-2.41-.12h-4.28c-.51,0-1,.06-1.61.06s-1.13,0-1.69.06a31.62,31.62,0,0,0-3.6.44,7.09,7.09,0,0,0-2.75,1,4.84,4.84,0,0,0-1.48,1.75,5.52,5.52,0,0,0-.56,2c-.05.28-.09.56-.12.83a7.69,7.69,0,0,0,0,.83c-.06.63-.1,1.26-.13,1.87s0,1.24,0,1.88c0,1.27,0,2.55,0,3.84s.07,2.57.13,3.84q.07,6,2.87,7.35t10.84,1.4a41.54,41.54,0,0,0,8.26-.72c2.34-.47,3.52-2.06,3.52-4.76V276.7a2.16,2.16,0,0,1-.09-.62v-.69Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3006.88,282l-3.47,7.62h-11.27l18.8-39.71h15.92L3046,289.62h-11l-3.64-7.62Zm12.19-26.25-9.65,20.59h19.48Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3082.25,261.52q0-3.45-2-4.64c-1.36-.8-3.7-1.19-7-1.19h-3c-.51,0-1.06.05-1.65.05s-1.17,0-1.74.06a24.68,24.68,0,0,0-2.7.27,10.42,10.42,0,0,0-2.38.62,3.57,3.57,0,0,0-1.52,1.23,5.89,5.89,0,0,0-.76,1.65,4.94,4.94,0,0,1,0,.68c0,.21,0,.42,0,.62,0,2,.55,3.34,1.65,4.07s3.12,1.16,6.06,1.28c.28,0,.55,0,.8,0s.53,0,.81,0l2.16.09,2.07,0a73,73,0,0,1,14.65,1.64q6.36,1.47,6.36,9.4a14.18,14.18,0,0,1-2.29,8.33q-2.28,3.25-10.59,3.85l-2.66.09c-.88,0-1.74.05-2.59.09s-1.79.06-2.67.06h-2.66a67.51,67.51,0,0,1-15.88-1.53q-6.15-1.51-6.14-9.76v-.39a1,1,0,0,1,.08-.39V277l10.25-.06a9.9,9.9,0,0,0,1.06,4.78c.7,1.32,2.64,2,5.8,2,1.35,0,2.71.06,4.06.06h4.07c3.33,0,5.76-.34,7.28-1s2.29-2.26,2.29-4.69q0-3.94-2.92-4.66a34.1,34.1,0,0,0-7.5-.78h-1.69c-.57,0-1.16,0-1.78-.06l-.89,0c-.31,0-.61-.05-.89-.09a53.19,53.19,0,0,1-14-2.11q-5-1.69-5-9.55c0-3.34,1-5.9,3-7.68s5.5-2.82,10.41-3.1c1.47-.08,2.95-.14,4.45-.18s3-.06,4.45-.06a77.06,77.06,0,0,1,15.15,1.31q6.43,1.32,6.44,8.93v1.49Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3112.14,289.62H3101.3V249.91h10.84Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<path d="M3120.44,270.27q0-9.88,3.18-15.24t19.43-5.36a74.62,74.62,0,0,1,17.41,1.83q7.58,1.81,8.17,10.32.16,1.31.21,2.61c0,.87,0,1.76,0,2.67v2.62q0,11.05-3.43,15.65T3143.82,290q-12.8,0-18.13-3t-5.33-12.56v-1.07a7.59,7.59,0,0,1,.08-1.07v-2Zm11-.18v3.57c0,.6,0,1.19,0,1.76s.07,1.16.13,1.76c.34,3,1.48,4.78,3.43,5.41a29.18,29.18,0,0,0,8.6,1q7.44,0,10.67-1.34t3.47-6.88c.11-1.63.17-3.24.17-4.85v-4.79q0-5.54-1.91-7.56c-1.27-1.35-4.58-2-10-2q-10.92,0-12.74,2.18c-1.22,1.44-1.82,4.23-1.82,8.36v.54a10.15,10.15,0,0,0-.09,1.39v1.52Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
</g>
</g>
<g id="Détails">
<path d="M3515,909.56v6.83a4,4,0,0,1-.68,2.53c-.45.58-1.38.89-2.8.93h-1.29a11.16,11.16,0,0,1-3.67-.48c-.88-.31-1.32-1.28-1.32-2.89v-7h2.26v6.93c0,.74.18,1.22.54,1.43a3.63,3.63,0,0,0,1.7.3h.78a4.15,4.15,0,0,0,1.68-.24c.39-.17.58-.6.58-1.3v-7.11Z" transform="translate(-2593.5 91)" style="fill: #fff"/>
<g id="Flèches">
<path id="Flèche_B_D" data-name="Flèche B D" d="M3594,810l-34,5a2,2,0,0,1-2-2v-9a2,2,0,0,1,2-2l34,6c5,1,0,2,0,2" transform="translate(-2593.5 91)" style="fill: #771217"/>
<path id="Flèche_B_G" data-name="Flèche B G" d="M2865,810l34,5a2,2,0,0,0,2-2v-9a2,2,0,0,0-2-2l-34,6c-5,1,0,2,0,2" transform="translate(-2593.5 91)" style="fill: #771217"/>
<path id="Flèche_H_G" data-name="Flèche H G" d="M2863,383l34,5a2,2,0,0,0,2-2v-9a2,2,0,0,0-2-2l-34,6c-5,1,0,2,0,2" transform="translate(-2593.5 91)" style="fill: #771217"/>
</g>
<g id="Bares_bleu" data-name="Bares bleu">
<path id="Bar_down_M" data-name="Bar down M" d="M3118,837h215c15,0,16,16,16,16v31c0,6-7,12-7,12l-13,13c-6,7-18,7-18,7H3143c-13,0-18-7-18-7l-13.72-13.61C3105,889,3105,885,3105,885V853C3105,837,3118,837,3118,837Z" transform="translate(-2593.5 91)" style="fill: none;stroke: #0e57a9;stroke-miterlimit: 10;stroke-width: 8px"/>
<path id="Bar_down_R" data-name="Bar down R" d="M3619,838c3.21,0,2,3,2,3l-8,10a5,5,0,0,1-3,1H3364a2,2,0,0,1-2-2V840a2,2,0,0,1,2-2Z" transform="translate(-2593.5 91)" style="fill: #0e57a9"/>
<path id="Bar_down_L" data-name="Bar down L" d="M2835,838c-3.21,0-2,3-2,3l8,10a5,5,0,0,0,3,1H3090a2,2,0,0,0,2-2V840a2,2,0,0,0-2-2Z" transform="translate(-2593.5 91)" style="fill: #0e57a9"/>
<path id="Bar_up" data-name="Bar up" d="M3621,336l-4-8a3.55,3.55,0,0,0-3-2H2840a4.33,4.33,0,0,0-4,2l-3,8c-1,3,2.5,3,2.5,3H3619C3623,339,3621,336,3621,336Z" transform="translate(-2593.5 91)" style="fill: #0e57a9"/>
</g>
</g>
<g id="displays">
<g id="dots">
<rect data-com="1" data-seg="16" id="dot_down" x="535.5" y="705" width="19" height="19" rx="9.5" style="fill: #304246"/>
<rect data-com="1" data-seg="16" id="dot_up" x="531.5" y="776" width="19" height="19" rx="9.5" style="fill: #304246"/>
</g>
<g id="hours">
<g id="hour_2">
<path data-com="1" data-seg="18" id="hour_2_A" d="M2979,580h-49c-4,0-5,1-5,1l-2,1a2.19,2.19,0,0,0-1,3l13,13a6.19,6.19,0,0,0,4,2h28c4,0,5-3,5-3l9-14C2983,580,2979,580,2979,580Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="19" id="hour_2_B" d="M2971.57,641.22a3.55,3.55,0,0,0,1.94,3l9.88,6.19s3,1.06,5-.9L2991,646a4.38,4.38,0,0,0,1-3l2-50a4.38,4.38,0,0,0-1-3l-4-5c-2-3-4,0-4,0l-11,17a4.62,4.62,0,0,0-1,3l-1.43,36.22" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="19" id="hour_2_C" d="M2990,669l-4,52a16.85,16.85,0,0,1-4,8l-2,3c-4,5-6,1-6,1l-7-16a9.79,9.79,0,0,1-1-7l2-40a4.33,4.33,0,0,1,2-4l10-6c5-3,7,1,7,1l2,4A10,10,0,0,1,2990,669Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="18" id="hour_2_D" d="M2961,718h-27a12.68,12.68,0,0,0-6,2l-14,8c-4,2-2,4-2,4l6,4a10,10,0,0,0,4,1h46c3,0,2-3,2-3l-6-14a3.55,3.55,0,0,0-3-2" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="18" id="hour_2_E" d="M2930,669l-2,43a3.7,3.7,0,0,1-2,3l-14,8c-4,2-4-1-4-1l2-54c0-3,1-4,1-4l2-3c2-2,5-1,5-1l10,6a3.55,3.55,0,0,1,2,3" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="18" id="hour_2_F" d="M2933,640a6.93,6.93,0,0,1-3,4l-10,7c-8,4-8-5-8-5l3-48a21.8,21.8,0,0,1,1-6l2-3a2.77,2.77,0,0,1,4,0l11,12a7.81,7.81,0,0,1,2,5Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="19" id="hour_2_G" d="M2923,654l11.5-6.5a7.65,7.65,0,0,1,5-1l26.5.5c3,0,4,1,4,1l8,6c3,2,0,3,0,3l-11,6h0a13.38,13.38,0,0,1-5,1h-24a13.83,13.83,0,0,1-7-2l-8-5C2921,655,2923,654,2923,654Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
</g>
<g id="hour_1">
<path data-com="2" data-seg="20" id="hour_1_A" d="M3092,580h-49c-4,0-5,1-5,1l-2,1a2.19,2.19,0,0,0-1,3l13,13a6.19,6.19,0,0,0,4,2h28c4,0,5-3,5-3l9-14C3096,580,3092,580,3092,580Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="21" id="hour_1_B" d="M3084.57,641.22a3.55,3.55,0,0,0,1.94,3l9.88,6.19s3,1.06,5-.9L3104,646a4.38,4.38,0,0,0,1-3l2-50a4.38,4.38,0,0,0-1-3l-4-5c-2-3-4,0-4,0l-11,17a4.62,4.62,0,0,0-1,3l-1.43,36.22" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="21" id="hour_1_C" d="M3103,669l-4,52a16.85,16.85,0,0,1-4,8l-2,3c-4,5-6,1-6,1l-7-16a9.79,9.79,0,0,1-1-7l2-40a4.33,4.33,0,0,1,2-4l10-6c5-3,7,1,7,1l2,4A10,10,0,0,1,3103,669Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="21" id="hour_1_D" d="M3074,718h-27a12.68,12.68,0,0,0-6,2l-14,8c-4,2-2,4-2,4l6,4a10,10,0,0,0,4,1h46c3,0,2-3,2-3l-6-14a3.55,3.55,0,0,0-3-2" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="20" id="hour_1_E" d="M3043,669l-2,43a3.7,3.7,0,0,1-2,3l-14,8c-4,2-4-1-4-1l2-54c0-3,1-4,1-4l2-3c2-2,5-1,5-1l10,6a3.55,3.55,0,0,1,2,3" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="17" id="hour_1_F" d="M3046,640a6.93,6.93,0,0,1-3,4l-10,7c-8,4-8-5-8-5l3-48a21.8,21.8,0,0,1,1-6l2-3a2.77,2.77,0,0,1,4,0l11,12a7.81,7.81,0,0,1,2,5Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="20" id="hour_1_G" d="M3036,654l11.5-6.5a7.65,7.65,0,0,1,5-1l26.5.5c3,0,4,1,4,1l8,6c3,2,0,3,0,3l-11,6h0a13.38,13.38,0,0,1-5,1h-24a13.83,13.83,0,0,1-7-2l-8-5C3034,655,3036,654,3036,654Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
</g>
</g>
<g id="minutes">
<g id="minute_2">
<path data-com="0" data-seg="22" id="minute_2_A" d="M3239,580h-49c-4,0-5,1-5,1l-2,1a2.19,2.19,0,0,0-1,3l13,13a6.19,6.19,0,0,0,4,2h28c4,0,5-3,5-3l9-14C3243,580,3239,580,3239,580Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="23" id="minute_2_B" d="M3231.57,641.22a3.55,3.55,0,0,0,1.94,3l9.88,6.19s3,1.06,5-.9L3251,646a4.38,4.38,0,0,0,1-3l2-50a4.38,4.38,0,0,0-1-3l-4-5c-2-3-4,0-4,0l-11,17a4.62,4.62,0,0,0-1,3l-1.43,36.22" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="23" id="minute_2_C" d="M3250,669l-4,52a16.85,16.85,0,0,1-4,8l-2,3c-4,5-6,1-6,1l-7-16a9.79,9.79,0,0,1-1-7l2-40a4.33,4.33,0,0,1,2-4l10-6c5-3,7,1,7,1l2,4A10,10,0,0,1,3250,669Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="22" id="minute_2_D" d="M3221,718h-27a12.68,12.68,0,0,0-6,2l-14,8c-4,2-2,4-2,4l6,4a10,10,0,0,0,4,1h46c3,0,2-3,2-3l-6-14a3.55,3.55,0,0,0-3-2" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="22" id="minute_2_E" d="M3190,669l-2,43a3.7,3.7,0,0,1-2,3l-14,8c-4,2-4-1-4-1l2-54c0-3,1-4,1-4l2-3c2-2,5-1,5-1l10,6a3.55,3.55,0,0,1,2,3" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="22" id="minute_2_F" d="M3193,640a6.93,6.93,0,0,1-3,4l-10,7c-8,4-8-5-8-5l3-48a21.8,21.8,0,0,1,1-6l2-3a2.77,2.77,0,0,1,4,0l11,12a7.81,7.81,0,0,1,2,5Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="23" id="minute_2_G" d="M3183,654l11.5-6.5a7.65,7.65,0,0,1,5-1l26.5.5c3,0,4,1,4,1l8,6c3,2,0,3,0,3l-11,6h0a13.38,13.38,0,0,1-5,1h-24a13.83,13.83,0,0,1-7-2l-8-5C3181,655,3183,654,3183,654Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
</g>
<g id="minute_1">
<path data-com="2" data-seg="1" id="minute_1_A" d="M3352,580h-49c-4,0-5,1-5,1l-2,1a2.19,2.19,0,0,0-1,3l13,13a6.19,6.19,0,0,0,4,2h28c4,0,5-3,5-3l9-14C3356,580,3352,580,3352,580Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="10" id="minute_1_B" d="M3344.57,641.22a3.55,3.55,0,0,0,1.94,3l9.88,6.19s3,1.06,5-.9L3364,646a4.38,4.38,0,0,0,1-3l2-50a4.38,4.38,0,0,0-1-3l-4-5c-2-3-4,0-4,0l-11,17a4.62,4.62,0,0,0-1,3l-1.43,36.22" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="1" id="minute_1_C" d="M3363,669l-4,52a16.85,16.85,0,0,1-4,8l-2,3c-4,5-6,1-6,1l-7-16a9.79,9.79,0,0,1-1-7l2-40a4.33,4.33,0,0,1,2-4l10-6c5-3,7,1,7,1l2,4A10,10,0,0,1,3363,669Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="0" id="minute_1_D" d="M3334,718h-27a12.68,12.68,0,0,0-6,2l-14,8c-4,2-2,4-2,4l6,4a10,10,0,0,0,4,1h46c3,0,2-3,2-3l-6-14a3.55,3.55,0,0,0-3-2" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="0" id="minute_1_E" d="M3303,669l-2,43a3.7,3.7,0,0,1-2,3l-14,8c-4,2-4-1-4-1l2-54c0-3,1-4,1-4l2-3c2-2,5-1,5-1l10,6a3.55,3.55,0,0,1,2,3" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="0" id="minute_1_F" d="M3306,640a6.93,6.93,0,0,1-3,4l-10,7c-8,4-8-5-8-5l3-48a21.8,21.8,0,0,1,1-6l2-3a2.77,2.77,0,0,1,4,0l11,12a7.81,7.81,0,0,1,2,5Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="1" id="minute_1_G" d="M3296,654l11.5-6.5a7.65,7.65,0,0,1,5-1l26.5.5c3,0,4,1,4,1l8,6c3,2,0,3,0,3l-11,6h0a13.38,13.38,0,0,1-5,1h-24a13.83,13.83,0,0,1-7-2l-8-5C3294,655,3296,654,3296,654Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
</g>
</g>
<g id="seconds">
<g id="second_2">
<path data-com="2" data-seg="2" id="second_2_A" d="M3446.93,619h-37.46c-3,0-3.82.76-3.82.76l-1.53.77a1.68,1.68,0,0,0-.76,2.29l9.94,9.94a4.73,4.73,0,0,0,3,1.53h21.41a3.82,3.82,0,0,0,3.82-2.3l6.88-10.7C3450,619,3446.93,619,3446.93,619Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="3" id="second_2_B" d="M3441.25,665.8a2.72,2.72,0,0,0,1.48,2.32l7.56,4.73a4,4,0,0,0,3.83-.69l2-2.71a3.38,3.38,0,0,0,.76-2.3l1.53-38.21a3.38,3.38,0,0,0-.76-2.3l-3.06-3.82c-1.53-2.29-3.06,0-3.06,0l-8.4,13a3.5,3.5,0,0,0-.77,2.29l-1.09,27.69" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="4" id="second_2_C" d="M3455.33,687l-3,39.74a13,13,0,0,1-3.06,6.12l-1.53,2.29c-3.06,3.82-4.58.76-4.58.76l-5.35-12.23a7.5,7.5,0,0,1-.77-5.35l1.53-30.57a3.32,3.32,0,0,1,1.53-3.06l7.64-4.58c3.82-2.3,5.35.76,5.35.76l1.53,3.06A7.67,7.67,0,0,1,3455.33,687Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="3" id="second_2_D" d="M3433.17,724.48h-20.64A9.66,9.66,0,0,0,3408,726l-10.7,6.11c-3.06,1.53-1.53,3.06-1.53,3.06l4.58,3.06a7.67,7.67,0,0,0,3.06.76h35.16c2.29,0,1.53-2.29,1.53-2.29l-4.59-10.7a2.71,2.71,0,0,0-2.29-1.53" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="2" id="second_2_E" d="M3409.47,687,3408,719.89a2.82,2.82,0,0,1-1.53,2.29l-10.7,6.12c-3.06,1.53-3.06-.76-3.06-.76l1.53-41.28c0-2.29.76-3.06.76-3.06l1.53-2.29a4,4,0,0,1,3.82-.76l7.65,4.58a2.73,2.73,0,0,1,1.52,2.3" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="2" id="second_2_F" d="M3411.77,664.86a5.34,5.34,0,0,1-2.3,3.06l-7.64,5.35c-6.11,3.05-6.11-3.82-6.11-3.82l2.29-36.69a16.73,16.73,0,0,1,.76-4.59l1.53-2.29a2.12,2.12,0,0,1,3.06,0l8.41,9.17a6,6,0,0,1,1.53,3.82Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="3" id="second_2_G" d="M3404.12,675.56l8.79-5a5.9,5.9,0,0,1,3.83-.76l20.25.38c2.29,0,3.06.76,3.06.76l6.11,4.59c2.3,1.53,0,2.29,0,2.29l-8.4,4.59h0a10.32,10.32,0,0,1-3.83.76h-18.34a10.6,10.6,0,0,1-5.35-1.52l-6.12-3.83C3402.6,676.32,3404.12,675.56,3404.12,675.56Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
</g>
<g id="second_1">
<path data-com="2" data-seg="4" id="second_1_A" d="M3528.54,619h-37.46c-3,0-3.82.76-3.82.76l-1.53.77a1.67,1.67,0,0,0-.76,2.29l9.93,9.94a4.74,4.74,0,0,0,3.06,1.53h21.4a3.81,3.81,0,0,0,3.82-2.3l6.88-10.7C3531.59,619,3528.54,619,3528.54,619Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="5" id="second_1_B" d="M3522.85,665.8a2.74,2.74,0,0,0,1.49,2.32l7.55,4.73a4,4,0,0,0,3.84-.69l2-2.71a3.38,3.38,0,0,0,.76-2.3l1.53-38.21a3.38,3.38,0,0,0-.76-2.3l-3.06-3.82c-1.53-2.29-3.06,0-3.06,0l-8.41,13a3.52,3.52,0,0,0-.76,2.29l-1.1,27.69" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="6" id="second_1_C" d="M3536.94,687l-3.05,39.74a13,13,0,0,1-3.06,6.12l-1.53,2.29c-3.06,3.82-4.59.76-4.59.76l-5.35-12.23a7.46,7.46,0,0,1-.76-5.35l1.53-30.57a3.32,3.32,0,0,1,1.53-3.06l7.64-4.58c3.82-2.3,5.35.76,5.35.76l1.53,3.06A7.67,7.67,0,0,1,3536.94,687Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="6" id="second_1_D" d="M3514.78,724.48h-20.64a9.72,9.72,0,0,0-4.59,1.53l-10.7,6.11c-3,1.53-1.53,3.06-1.53,3.06l4.59,3.06a7.67,7.67,0,0,0,3.06.76h35.16c2.29,0,1.53-2.29,1.53-2.29l-4.59-10.7a2.71,2.71,0,0,0-2.29-1.53" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="5" id="second_1_E" d="M3491.08,687l-1.53,32.86a2.82,2.82,0,0,1-1.52,2.29l-10.71,6.12c-3.05,1.53-3.05-.76-3.05-.76l1.53-41.28c0-2.29.76-3.06.76-3.06l1.53-2.29a4,4,0,0,1,3.82-.76l7.64,4.58a2.73,2.73,0,0,1,1.53,2.3" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="4" id="second_1_F" d="M3493.38,664.86a5.34,5.34,0,0,1-2.3,3.06l-7.64,5.35c-6.12,3.05-6.12-3.82-6.12-3.82l2.3-36.69a16.73,16.73,0,0,1,.76-4.59l1.53-2.29a2.12,2.12,0,0,1,3.06,0l8.41,9.17a6,6,0,0,1,1.52,3.82Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="5" id="second_1_G" d="M3485.73,675.56l8.79-5a5.87,5.87,0,0,1,3.82-.76l20.26.38c2.29,0,3.06.76,3.06.76l6.11,4.59c2.29,1.53,0,2.29,0,2.29l-8.41,4.59h0a10.28,10.28,0,0,1-3.82.76H3497.2a10.6,10.6,0,0,1-5.35-1.52l-6.12-3.83C3484.2,676.32,3485.73,675.56,3485.73,675.56Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
</g>
</g>
<g id="days">
<g id="day_2">
<path data-com="1" data-seg="9" id="day_2_A" d="M3454.41,467h-31.34c-2.56,0-3.2.53-3.2.53l-1.28.53a1.05,1.05,0,0,0-.64,1.58l8.32,6.88a4.42,4.42,0,0,0,2.56,1.05h17.9c2.56,0,3.2-1.58,3.2-1.58l5.76-7.4C3457,467,3454.41,467,3454.41,467Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="9" id="day_2_B" d="M3449.65,499.37a1.84,1.84,0,0,0,1.25,1.6l6.32,3.27a4,4,0,0,0,3.21-.47l1.65-1.88a2.11,2.11,0,0,0,.64-1.58l1.28-26.44a2.11,2.11,0,0,0-.64-1.58l-2.56-2.65a1.56,1.56,0,0,0-2.56,0l-7,9a2.21,2.21,0,0,0-.64,1.59l-.92,19.15" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="9" id="day_2_C" d="M3461.44,514.05l-2.56,27.49a8.64,8.64,0,0,1-2.55,4.23l-1.28,1.59c-2.56,2.64-3.84.53-3.84.53l-4.48-8.46a4.37,4.37,0,0,1-.64-3.7l1.28-21.15a2.28,2.28,0,0,1,1.28-2.12l6.4-3.17c3.19-1.58,4.47.53,4.47.53l1.28,2.12A4.48,4.48,0,0,1,3461.44,514.05Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="9" id="day_2_D" d="M3442.9,540h-17.27a9.28,9.28,0,0,0-3.84,1l-8.95,4.23c-2.56,1.06-1.28,2.12-1.28,2.12l3.84,2.11a7.43,7.43,0,0,0,2.55.53h29.42c1.92,0,1.28-1.59,1.28-1.59l-3.84-7.4a2.39,2.39,0,0,0-1.91-1" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="10" id="day_2_E" d="M3423.07,514.05l-1.28,22.73c0,1.06-1.28,1.59-1.28,1.59l-9,4.23c-2.56,1.06-2.56-.53-2.56-.53l1.28-28.55a2.74,2.74,0,0,1,.64-2.11l1.28-1.59a3.92,3.92,0,0,1,3.2-.53l6.39,3.17a1.85,1.85,0,0,1,1.28,1.59" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="9" id="day_2_G" d="M3418.59,506.12l7.36-3.44a5.79,5.79,0,0,1,3.2-.52l16.94.26a4.28,4.28,0,0,1,2.56.53l5.12,3.17c1.92,1.06,0,1.59,0,1.59l-7,3.17h0a10.16,10.16,0,0,1-3.2.53h-15.34a10.16,10.16,0,0,1-4.48-1.06l-5.12-2.64C3417.31,506.65,3418.59,506.12,3418.59,506.12Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
</g>
<g id="day_1">
<path data-com="0" data-seg="7" id="day_1_A" d="M3525.41,468h-31.34c-2.56,0-3.2.53-3.2.53l-1.28.53a1.05,1.05,0,0,0-.64,1.58l8.32,6.88a4.42,4.42,0,0,0,2.56,1.05h17.9c2.56,0,3.2-1.58,3.2-1.58l5.76-7.4C3528,468,3525.41,468,3525.41,468Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="7" id="day_1_B" d="M3520.65,500.37a1.84,1.84,0,0,0,1.25,1.6l6.32,3.27a4,4,0,0,0,3.21-.47l1.65-1.88a2.11,2.11,0,0,0,.64-1.58l1.28-26.44a2.11,2.11,0,0,0-.64-1.58l-2.56-2.65a1.56,1.56,0,0,0-2.56,0l-7,9a2.21,2.21,0,0,0-.64,1.59l-.92,19.15" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="7" id="day_1_C" d="M3532.44,515.05l-2.56,27.49a8.64,8.64,0,0,1-2.55,4.23l-1.28,1.59c-2.56,2.64-3.84.53-3.84.53l-4.48-8.46a4.37,4.37,0,0,1-.64-3.7l1.28-21.15a2.28,2.28,0,0,1,1.28-2.12l6.4-3.17c3.19-1.58,4.47.53,4.47.53l1.28,2.12A4.48,4.48,0,0,1,3532.44,515.05Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="6" id="day_1_D" d="M3513.9,541h-17.27a9.28,9.28,0,0,0-3.84,1l-8.95,4.23c-2.56,1.06-1.28,2.12-1.28,2.12l3.84,2.11a7.43,7.43,0,0,0,2.55.53h29.42c1.92,0,1.28-1.59,1.28-1.59l-3.84-7.4a2.39,2.39,0,0,0-1.91-1" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="8" id="day_1_E" d="M3494.07,515.05l-1.28,22.73c0,1.06-1.28,1.59-1.28,1.59l-9,4.23c-2.56,1.06-2.56-.53-2.56-.53l1.28-28.55a2.74,2.74,0,0,1,.64-2.11l1.28-1.59a3.92,3.92,0,0,1,3.2-.53l6.39,3.17a1.85,1.85,0,0,1,1.28,1.59" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="8" id="day_1_F" d="M3496,499.72a3.89,3.89,0,0,1-1.92,2.11l-6.4,3.71c-5.11,2.11-5.11-2.65-5.11-2.65l1.92-25.37a9.8,9.8,0,0,1,.64-3.18l1.28-1.58a2,2,0,0,1,2.55,0l7,6.34a3.73,3.73,0,0,1,1.28,2.65Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="8" id="day_1_G" d="M3489.59,507.12l7.36-3.44a5.79,5.79,0,0,1,3.2-.52l16.94.26a4.28,4.28,0,0,1,2.56.53l5.12,3.17c1.92,1.06,0,1.59,0,1.59l-7,3.17h0a10.16,10.16,0,0,1-3.2.53h-15.34a10.16,10.16,0,0,1-4.48-1.06l-5.12-2.64C3488.31,507.65,3489.59,507.12,3489.59,507.12Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
</g>
</g>
<g id="mode">
<g id="mode_2">
<path data-com="0" data-seg="13" id="mode_2_A" d="M3170,468l-4,6a3.49,3.49,0,0,1-2,1h-25a3.1,3.1,0,0,1-2-1l-5-7s-1-1,1-1h36C3171,466,3170,468,3170,468Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="13" id="mode_2_B" d="M3168,474l4-5a1.39,1.39,0,0,1,2,0l1,1a3.89,3.89,0,0,1,1,3l-1,22c-1,5-5,3-5,3l-3.56-2.19a3.45,3.45,0,0,1-.9-2L3166,479A7.65,7.65,0,0,1,3168,474Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="13" id="mode_2_C" d="M3165,529.47l3.51,6a1.28,1.28,0,0,0,2,.19l1.09-1a4.66,4.66,0,0,0,1.28-3.29l1-23.8c-.53-5.75-4.7-3.87-4.7-3.87l-3.75,2.13a4.09,4.09,0,0,0-1.09,2.23l-.83,15.59A9.28,9.28,0,0,0,3165,529.47Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="15" id="mode_2_D" d="M3129,537l4-6a3.49,3.49,0,0,1,2-1h26a3.1,3.1,0,0,1,2,1l5,7s1,1-1,1h-37C3128,539,3129,537,3129,537Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="14" id="mode_2_E" d="M3131.4,529.78l-4,5.63a1.29,1.29,0,0,1-2,0l-1-1.11a4.58,4.58,0,0,1-1-3.36l1.12-23.57c1-5.61,5-3.39,5-3.39l3.55,2.43a4.11,4.11,0,0,1,.89,2.29l-.55,15.45A9.15,9.15,0,0,1,3131.4,529.78Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="14" id="mode_2_F" d="M3134.32,474.27l-3.54-5.33a1.38,1.38,0,0,0-2-.18l-1.09.91a3.9,3.9,0,0,0-1.26,2.9l-.87,22c.56,5.07,4.72,3.43,4.72,3.43l3.74-1.86a3.49,3.49,0,0,0,1.08-2l.76-14.75A7.63,7.63,0,0,0,3134.32,474.27Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="15" id="mode_2_G" d="M3143,505l5-1a4.83,4.83,0,0,1,4,0l5,1a10.56,10.56,0,0,0,6,0l5-2s3-2,0-3l-4-2a13.6,13.6,0,0,0-7,0l-5,2a4.83,4.83,0,0,1-4,0l-5-2s-4-1-7,0l-5,2s-3,1,0,3l5,2A13.6,13.6,0,0,0,3143,505Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<polygon data-com="1" data-seg="14" id="mode_2_H" points="552.5 570 562.5 570 561.5 585 556.5 588 551.5 585 552.5 570" style="fill: #304246"/>
<polygon data-com="1" data-seg="14" id="mode_2_I" points="559.5 617 549.5 617 550.5 600 555.5 597 560.5 600 559.5 617" style="fill: #304246"/>
</g>
<g id="mode_1">
<path data-com="0" data-seg="11" id="mode_1_A" d="M3242,469l-4,6a3.49,3.49,0,0,1-2,1h-21a3.1,3.1,0,0,1-2-1l-5-7s-1-1,1-1h32C3243,467,3242,469,3242,469Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="11" id="mode_1_B" d="M3241,475l4-5a1.39,1.39,0,0,1,2,0l1,1a3.89,3.89,0,0,1,1,3l-1,21c-1,5-5,3-5,3l-3.56-2.19a3.45,3.45,0,0,1-.9-2L3239,480A7.65,7.65,0,0,1,3241,475Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="11" id="mode_1_C" d="M3238,530.47l3.51,6a1.28,1.28,0,0,0,2,.19l1.09-1a4.66,4.66,0,0,0,1.28-3.29l1-23.8c-.53-5.75-4.7-3.87-4.7-3.87l-3.75,2.13a4.09,4.09,0,0,0-1.09,2.23l-.83,15.59A9.28,9.28,0,0,0,3238,530.47Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="11" id="mode_1_D" d="M3205,538l4-6a3.49,3.49,0,0,1,2-1h22a3.1,3.1,0,0,1,2,1l5,7s1,1-1,1h-33C3204,540,3205,538,3205,538Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="12" id="mode_1_E" d="M3207.4,530.78l-4,5.63a1.29,1.29,0,0,1-2,0l-1-1.11a4.58,4.58,0,0,1-1-3.36l1.12-23.57c1-5.61,5-3.39,5-3.39l3.55,2.43a4.11,4.11,0,0,1,.89,2.29l-.55,15.45A9.15,9.15,0,0,1,3207.4,530.78Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="12" id="mode_1_F" d="M3210.32,475.27l-3.54-5.33a1.38,1.38,0,0,0-2-.18l-1.09.91a3.9,3.9,0,0,0-1.26,2.9l-.87,21c.56,5.07,4.72,3.43,4.72,3.43l3.74-1.86a3.49,3.49,0,0,0,1.08-2l.76-13.75A7.63,7.63,0,0,0,3210.32,475.27Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="12" id="mode_1_G" d="M3216,497h17a12.13,12.13,0,0,1,5,1l4,2c3,1,0,3,0,3l-5,2a10,10,0,0,1-4,1h-17a10.34,10.34,0,0,1-4-1l-5-2c-3-2,0-3,0-3l5-2A10,10,0,0,1,3216,497Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="12" id="mode_1_H" d="M3202,469l-3,6a3.49,3.49,0,0,1-2,1h-3a3.1,3.1,0,0,1-2-1l-3-7s-1-1,1-1h11C3203,467,3202,469,3202,469Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
</g>
</g>
<g id="lap">
<path data-com="1" data-seg="10" d="M3297.93,536.73h17.61v5.81h-25v-34.6h7.41Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="10" d="M3329,535.9l-2.34,6.64h-7.58l12.65-34.6h10.72l12.88,34.6h-7.41l-2.45-6.64Zm8.21-22.87-6.5,17.94h13.11Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="1" data-seg="10" d="M3361.94,507.94h15.22q7.64.06,11.29,2.05t3.64,9.78c0,.45,0,.92,0,1.4s-.05,1-.09,1.45a13.26,13.26,0,0,1-.71,3.53,6.55,6.55,0,0,1-2.14,3,8.07,8.07,0,0,1-3.85,1.84,24.44,24.44,0,0,1-4.41.39,3.83,3.83,0,0,1-.6,0H3369v11.15h-7.07Zm15.34,17.69a13.87,13.87,0,0,0,5.72-.75c1.12-.54,1.69-2.19,1.69-5,0-2.56-.39-4.26-1.15-5.09s-2.6-1.24-5.52-1.24h-9v12Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
</g>
<g id="timemode_24H">
<path data-com="2" data-seg="16" d="M3018.51,550.54h-17.6V545q0-4.51,1.75-5.8a12.09,12.09,0,0,1,4.93-1.89,3.09,3.09,0,0,1,.46-.12l.49-.08a6,6,0,0,1,.82-.12,7.37,7.37,0,0,0,.75-.12,6.8,6.8,0,0,0,3.1-1.05c.69-.51,1-1.77,1-3.78s-.33-3.31-1-3.73a7.11,7.11,0,0,0-3.49-.62,6.73,6.73,0,0,0-3.71.7c-.63.47-.94,1.82-.94,4v.84h-4.2V532c0-.24,0-.49,0-.74s0-.5,0-.74a13.83,13.83,0,0,1,.46-3,4.3,4.3,0,0,1,1.61-2.34,6.36,6.36,0,0,1,2.2-1.08,12.5,12.5,0,0,1,2.42-.41c.37,0,.73,0,1.08,0h1.05a12.24,12.24,0,0,1,6.5,1.43c1.5.94,2.25,3.25,2.25,6.91s-.66,5.88-2,6.78a13,13,0,0,1-5.06,1.91l-2,.34a17.28,17.28,0,0,0-2.13.51,2.41,2.41,0,0,0-1.91,1.48,10.28,10.28,0,0,0-.3,2.74v.69h13.37Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="16" d="M3042.35,540.92h2.73v3.83h-2.73v5.79h-4.2v-5.79h-12.71v-5.56l10.36-15.5h6.55Zm-4.27-13.48-9.1,13.48h9.17Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="16" d="M3071.71,550.54h-4.48V539.07h-10.88v11.47h-4.45V523.69h4.45v11h10.88v-11h4.48Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
</g>
<g id="timemode_PM">
<path data-com="2" data-seg="17" d="M2922.93,514.49h12.55q6.3.06,9.31,2.14t3,10.18c0,.47,0,1,0,1.46s0,1-.07,1.52a16.64,16.64,0,0,1-.59,3.67,6.84,6.84,0,0,1-1.76,3.08,6.22,6.22,0,0,1-3.17,1.92,16.25,16.25,0,0,1-3.64.41,2.73,2.73,0,0,1-.5,0h-9.28v11.62h-5.83Zm12.65,18.43a9.35,9.35,0,0,0,4.72-.78c.92-.56,1.39-2.28,1.39-5.16,0-2.67-.32-4.44-.94-5.3s-2.15-1.3-4.56-1.3h-7.43v12.54Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="2" data-seg="17" d="M2988.83,550.54H2983l.19-30.37-9.87,30.37h-5.41l-10-30.21.28,30.21h-5.87v-36h9.68l8.46,26.76h.19l8.37-26.76h9.87Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
</g>
<g id="alarm">
<path data-com="0" data-seg="16" id="alarm_inside" d="M3056,494.06c-3.84,0-4.77-4.95-4.77-4.95V476.42c0-6.45-6.71-6.45-6.71-6.45h-3.19v-4.5h-5V470h-3.2s-6.7,0-6.7,6.45v12.69s-.91,4.95-4.77,4.95v4.61H3036a6.21,6.21,0,0,0-1.27,3.84c0,3,1.92,5.39,4.28,5.39s4.27-2.42,4.27-5.39a6.31,6.31,0,0,0-1.23-3.84h14Zm-8,.94h-18V476a2.94,2.94,0,0,1,3-3h12a2.94,2.94,0,0,1,3,3Z" transform="translate(-2593.5 91)" style="fill: #304246"/>
</g>
<g id="signal">
<path data-com="0" data-seg="17" id="signal_5" d="M2992.68,498.36c1,0,1.75-6.25,1.75-14s-.78-13.95-1.75-13.95h-6c.94,0,1.73,6.25,1.73,13.95s-.79,14-1.73,14h6" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="17" id="signal_4" d="M2979.8,498.36c.95,0,1.74-6.25,1.74-14s-.79-13.95-1.74-13.95h-7.41c1,0,1.76,6.25,1.76,13.95s-.79,14-1.76,14h7.41" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="17" id="signal_3" d="M2964.16,498.36c1.48,0,2.67-6.25,2.67-14s-1.19-13.95-2.67-13.95h-7.78c1.48,0,2.67,6.25,2.67,13.95s-1.19,14-2.67,14h7.78" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="17" id="signal_2" d="M2948,498.36c2.58,0,4.71-6.25,4.71-14s-2.13-13.95-4.71-13.95h-8.33c2.59,0,4.71,6.25,4.71,13.95s-2.12,14-4.71,14H2948" transform="translate(-2593.5 91)" style="fill: #304246"/>
<path data-com="0" data-seg="17" id="signal_1" d="M2932.78,498.36c2.61,0,4.71-6.25,4.71-14s-2.1-13.95-4.71-13.95H2923V498.3l9.78.06" transform="translate(-2593.5 91)" style="fill: #304246"/>
</g>
</g>
</g>
</svg>
<p style="text-align: center;"><a href="https://github.com/alexisphilip/Casio-F-91W">Original F-91W SVG</a> is &copy; 2020 Alexis Philip, and is used here under the terms of the MIT license.</p>
</div>
<textarea id="output" rows="8" style="width: 100%"></textarea>
<script type='text/javascript'>
var outputElement = document.getElementById('output');
var Module = {
preRun: [],
postRun: [],
print: (function() {
if (outputElement) outputElement.value = ''; // clear browser cache
return function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
console.log(text);
if (outputElement) {
outputElement.value += text + "\n";
outputElement.scrollTop = outputElement.scrollHeight; // focus on bottom
}
};
})(),
setStatus: function(text) {
if (!text) return;
if (text === 'Running...') text += '\n==========';
if (outputElement) {
outputElement.value += text + "\n";
outputElement.scrollTop = outputElement.scrollHeight; // focus on bottom
}
},
totalDependencies: 0,
monitorRunDependencies: function(left) {
this.totalDependencies = Math.max(this.totalDependencies, left);
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
}
};
Module.setStatus('Downloading...');
window.onerror = function() {
Module.setStatus('Exception thrown, see JavaScript console');
Module.setStatus = function(text) {
if (text) Module.printErr('[post-exception status] ' + text);
};
};
</script>
{{{ SCRIPT }}}
</body>
</html>

View File

@@ -0,0 +1,9 @@
#include "watch.h"
bool watch_is_battery_low(void) {
return false;
}
bool watch_is_buzzer_or_led_enabled(void) {
return false;
}

View File

@@ -0,0 +1,48 @@
/*
* MIT License
*
* Copyright (c) 2020 Joey Castillo
*
* 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.
*/
#include "watch_adc.h"
void watch_enable_adc(void) {}
void watch_enable_analog_input(const uint8_t pin) {}
uint16_t watch_get_analog_pin_level(const uint8_t pin) {
return 0;
}
void watch_set_analog_num_samples(uint16_t samples) {}
void watch_set_analog_sampling_length(uint8_t cycles) {}
void watch_set_analog_reference_voltage(watch_adc_reference_voltage reference) {}
uint16_t watch_get_vcc_voltage(void) {
// TODO: (a2) hook to UI
return 3000;
}
inline void watch_disable_analog_input(const uint8_t pin) {}
inline void watch_disable_adc(void) {}

View File

@@ -0,0 +1,60 @@
/*
* MIT License
*
* Copyright (c) 2020 Joey Castillo
*
* 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.
*/
#include "watch_buzzer.h"
inline void watch_enable_buzzer(void) {
// TODO: (a2) hook to UI
}
inline void watch_set_buzzer_period(uint32_t period) {
// TODO: (a2) hook to UI
}
void watch_disable_buzzer(void) {
_watch_disable_tcc();
}
inline void watch_set_buzzer_on(void) {
// TODO: (a2) hook to UI
}
inline void watch_set_buzzer_off(void) {
// TODO: (a2) hook to UI
}
// note: the buzzer uses a 1 MHz clock. these values were determined by dividing 1,000,000 by the target frequency.
// i.e. for a 440 Hz tone (A4 on the piano), 1MHz/440Hz = 2273
const uint16_t NotePeriods[108] = {0};
void watch_buzzer_play_note(BuzzerNote note, uint16_t duration_ms) {
if (note == BUZZER_NOTE_REST) {
watch_set_buzzer_off();
} // else {
// hri_tcc_write_PERBUF_reg(TCC0, NotePeriods[note]);
// hri_tcc_write_CCBUF_reg(TCC0, WATCH_BUZZER_TCC_CHANNEL, NotePeriods[note] / 2);
// watch_set_buzzer_on();
// }
// delay_ms(duration_ms);
// watch_set_buzzer_off();
}

View File

@@ -0,0 +1,99 @@
/*
* MIT License
*
* Copyright (c) 2020 Joey Castillo
*
* 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.
*/
#include "watch_extint.h"
// this warning only appears when you `make BOARD=OSO-SWAT-A1-02`. it's annoying,
// but i'd rather have it warn us at build-time than fail silently at run-time.
// besides, no one but me really has any of these boards anyway.
#if BTN_ALARM != GPIO(GPIO_PORTA, 2)
#warning This board revision does not support external wake on BTN_ALARM, so watch_register_extwake_callback will not work with it. Use watch_register_interrupt_callback instead.
#endif
static uint32_t watch_backup_data[8];
void watch_register_extwake_callback(uint8_t pin, ext_irq_cb_t callback, bool level) {
if (pin == BTN_ALARM) {
watch_register_interrupt_callback(pin, callback, level ? INTERRUPT_TRIGGER_RISING : INTERRUPT_TRIGGER_FALLING);
}
}
void watch_disable_extwake_interrupt(uint8_t pin) {
if (pin == BTN_ALARM) {
watch_register_interrupt_callback(pin, NULL, INTERRUPT_TRIGGER_NONE);
}
}
void watch_store_backup_data(uint32_t data, uint8_t reg) {
if (reg < 8) {
watch_backup_data[reg] = data;
}
}
uint32_t watch_get_backup_data(uint8_t reg) {
if (reg < 8) {
return watch_backup_data[reg];
}
return 0;
}
void watch_enter_sleep_mode(void) {
// TODO: (a2) hook to UI
// enter standby (4); we basically hang out here until an interrupt wakes us.
// sleep(4);
// call app_setup so the app can re-enable everything we disabled.
app_setup();
// and call app_wake_from_standby (since main won't have a chance to do it)
app_wake_from_standby();
}
void watch_enter_deep_sleep_mode(void) {
// identical to sleep mode except we disable the LCD first.
// TODO: (a2) hook to UI
watch_enter_sleep_mode();
}
void watch_enter_backup_mode(void) {
// TODO: (a2) hook to UI
// go into backup sleep mode (5). when we exit, the reset controller will take over.
// sleep(5);
}
// deprecated
void watch_enter_shallow_sleep(bool display_on) {
if (display_on) watch_enter_sleep_mode();
else watch_enter_deep_sleep_mode();
}
// deprecated
void watch_enter_deep_sleep(void) {
watch_register_extwake_callback(BTN_ALARM, NULL, true);
watch_enter_backup_mode();
}

View File

@@ -0,0 +1,191 @@
/*
* MIT License
*
* Copyright (c) 2020 Joey Castillo
*
* 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.
*/
#include "watch_extint.h"
#include <emscripten.h>
#include <emscripten/html5.h>
static bool output_focused = false;
static bool external_interrupt_enabled = false;
static bool button_callbacks_installed = false;
static ext_irq_cb_t external_interrupt_mode_callback = NULL;
static watch_interrupt_trigger external_interrupt_mode_trigger = INTERRUPT_TRIGGER_NONE;
static ext_irq_cb_t external_interrupt_light_callback = NULL;
static watch_interrupt_trigger external_interrupt_light_trigger = INTERRUPT_TRIGGER_NONE;
static ext_irq_cb_t external_interrupt_alarm_callback = NULL;
static watch_interrupt_trigger external_interrupt_alarm_trigger = INTERRUPT_TRIGGER_NONE;
#define BTN_ID_ALARM 3
#define BTN_ID_LIGHT 1
#define BTN_ID_MODE 2
static const uint8_t BTN_IDS[] = { BTN_ID_ALARM, BTN_ID_LIGHT, BTN_ID_MODE };
static void watch_invoke_interrupt_callback(const uint8_t button_id, watch_interrupt_trigger trigger);
static EM_BOOL watch_invoke_key_callback(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData) {
if (output_focused || keyEvent->repeat) return EM_FALSE;
const char *key = keyEvent->key;
if (key[1] != 0) return EM_FALSE;
uint8_t button_id;
switch (key[0]) {
case 'A':
case 'a':
button_id = BTN_ID_ALARM;
break;
case 'L':
case 'l':
button_id = BTN_ID_LIGHT;
break;
case 'M':
case 'm':
button_id = BTN_ID_MODE;
break;
default:
return EM_FALSE;
}
watch_interrupt_trigger trigger = eventType == EMSCRIPTEN_EVENT_KEYDOWN ? INTERRUPT_TRIGGER_RISING : INTERRUPT_TRIGGER_FALLING;
watch_invoke_interrupt_callback(button_id, trigger);
return EM_TRUE;
}
static EM_BOOL watch_invoke_mouse_callback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) {
if (eventType == EMSCRIPTEN_EVENT_MOUSEOUT && mouseEvent->buttons == 0) return EM_FALSE;
uint8_t button_id = *(const char *)userData;
watch_interrupt_trigger trigger = eventType == EMSCRIPTEN_EVENT_MOUSEDOWN ? INTERRUPT_TRIGGER_RISING : INTERRUPT_TRIGGER_FALLING;
watch_invoke_interrupt_callback(button_id, trigger);
return EM_TRUE;
}
static EM_BOOL watch_invoke_touch_callback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData) {
uint8_t button_id = *(const char *)userData;
watch_interrupt_trigger trigger = eventType == EMSCRIPTEN_EVENT_TOUCHSTART ? INTERRUPT_TRIGGER_RISING : INTERRUPT_TRIGGER_FALLING;
watch_invoke_interrupt_callback(button_id, trigger);
return EM_TRUE;
}
static EM_BOOL watch_invoke_focus_callback(int eventType, const EmscriptenFocusEvent *focusEvent, void *userData) {
output_focused = eventType == EMSCRIPTEN_EVENT_FOCUS;
return EM_TRUE;
}
static void watch_install_button_callbacks(void) {
emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, EM_FALSE, watch_invoke_key_callback);
emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, EM_FALSE, watch_invoke_key_callback);
const char *target_output = "#output";
emscripten_set_focus_callback(target_output, NULL, EM_FALSE, watch_invoke_focus_callback);
emscripten_set_blur_callback(target_output, NULL, EM_FALSE, watch_invoke_focus_callback);
for (int i = 0, count = sizeof(BTN_IDS) / sizeof(BTN_IDS[0]); i < count; i++) {
char target[] = "#btn_";
target[4] = BTN_IDS[i] + '0';
emscripten_set_mousedown_callback(target, (void *)&BTN_IDS[i], EM_FALSE, watch_invoke_mouse_callback);
emscripten_set_mouseup_callback(target, (void *)&BTN_IDS[i], EM_FALSE, watch_invoke_mouse_callback);
emscripten_set_mouseout_callback(target, (void *)&BTN_IDS[i], EM_FALSE, watch_invoke_mouse_callback);
emscripten_set_touchstart_callback(target, (void *)&BTN_IDS[i], EM_FALSE, watch_invoke_touch_callback);
emscripten_set_touchend_callback(target, (void *)&BTN_IDS[i], EM_FALSE, watch_invoke_touch_callback);
}
}
void watch_enable_external_interrupts(void) {
external_interrupt_enabled = true;
if (!button_callbacks_installed) {
watch_install_button_callbacks();
button_callbacks_installed = true;
}
}
void watch_disable_external_interrupts(void) {
external_interrupt_enabled = false;
}
static void watch_invoke_interrupt_callback(const uint8_t button_id, watch_interrupt_trigger event) {
if (!external_interrupt_enabled) return;
ext_irq_cb_t callback;
watch_interrupt_trigger trigger;
uint8_t pin;
switch (button_id) {
case BTN_ID_MODE:
pin = BTN_MODE;
callback = external_interrupt_mode_callback;
trigger = external_interrupt_mode_trigger;
break;
case BTN_ID_LIGHT:
pin = BTN_LIGHT;
callback = external_interrupt_light_callback;
trigger = external_interrupt_light_trigger;
break;
case BTN_ID_ALARM:
pin = BTN_ALARM;
callback = external_interrupt_alarm_callback;
trigger = external_interrupt_alarm_trigger;
break;
default:
return;
}
const bool level = (event & INTERRUPT_TRIGGER_RISING) != 0;
EM_ASM({
const classList = document.querySelector('#btn' + $0).classList;
const highlight = 'highlight';
$1 ? classList.add(highlight) : classList.remove(highlight);
}, button_id, level);
watch_set_pin_level(pin, level);
if (callback && (event & trigger) != 0) {
callback();
void resume_main_loop(void);
resume_main_loop();
}
}
void watch_register_interrupt_callback(const uint8_t pin, ext_irq_cb_t callback, watch_interrupt_trigger trigger) {
if (pin == BTN_MODE) {
external_interrupt_mode_callback = callback;
external_interrupt_mode_trigger = trigger;
} else if (pin == BTN_LIGHT) {
external_interrupt_light_callback = callback;
external_interrupt_light_trigger = trigger;
} else if (pin == BTN_ALARM) {
external_interrupt_alarm_callback = callback;
external_interrupt_alarm_trigger = trigger;
}
}
void watch_register_button_callback(const uint8_t pin, ext_irq_cb_t callback) {
watch_register_interrupt_callback(pin, callback, INTERRUPT_TRIGGER_RISING);
}
void watch_enable_buttons(void) {
watch_enable_external_interrupts();
}

View File

@@ -0,0 +1,47 @@
/*
* MIT License
*
* Copyright (c) 2020 Joey Castillo
*
* 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.
*/
#include "watch_gpio.h"
static bool pin_levels[UINT8_MAX];
void watch_enable_digital_input(const uint8_t pin) {}
void watch_disable_digital_input(const uint8_t pin) {}
void watch_enable_pull_up(const uint8_t pin) {}
void watch_enable_pull_down(const uint8_t pin) {}
bool watch_get_pin_level(const uint8_t pin) {
return pin_levels[pin];
}
void watch_enable_digital_output(const uint8_t pin) {}
void watch_disable_digital_output(const uint8_t pin) {}
void watch_set_pin_level(const uint8_t pin, const bool level) {
pin_levels[pin] = level;
}

View File

@@ -0,0 +1,51 @@
/*
* MIT License
*
* Copyright (c) 2020 Joey Castillo
*
* 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.
*/
#include "watch_i2c.h"
void watch_enable_i2c(void) {}
void watch_disable_i2c(void) {}
void watch_i2c_send(int16_t addr, uint8_t *buf, uint16_t length) {}
void watch_i2c_receive(int16_t addr, uint8_t *buf, uint16_t length) {}
void watch_i2c_write8(int16_t addr, uint8_t reg, uint8_t data) {}
uint8_t watch_i2c_read8(int16_t addr, uint8_t reg) {
return 0;
}
uint16_t watch_i2c_read16(int16_t addr, uint8_t reg) {
return 0;
}
uint32_t watch_i2c_read24(int16_t addr, uint8_t reg) {
return 0;
}
uint32_t watch_i2c_read32(int16_t addr, uint8_t reg) {
return 0;
}

View File

@@ -0,0 +1,63 @@
/*
* MIT License
*
* Copyright (c) 2020 Joey Castillo
*
* 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.
*/
#include "watch_led.h"
#include <emscripten.h>
void watch_enable_leds(void) {}
void watch_disable_leds(void) {}
void watch_enable_led(bool unused) {
(void)unused;
watch_enable_leds();
}
void watch_disable_led(bool unused) {
(void)unused;
watch_disable_leds();
}
void watch_set_led_color(uint8_t red, uint8_t green) {
EM_ASM({
document.getElementById('light').style.opacity = $1 / 255;
}, red, green);
}
void watch_set_led_red(void) {
watch_set_led_color(255, 0);
}
void watch_set_led_green(void) {
watch_set_led_color(0, 255);
}
void watch_set_led_yellow(void) {
watch_set_led_color(255, 255);
}
void watch_set_led_off(void) {
watch_set_led_color(0, 0);
}

View File

@@ -0,0 +1,78 @@
/*
* MIT License
*
* Copyright (c) 2020 Joey Castillo
*
* 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.
*/
#include "watch_private.h"
#include "watch_utility.h"
#include <sys/time.h>
void _watch_init(void) {
// External wake depends on RTC; calendar is a required module.
_watch_rtc_init();
}
// this function is called by arc4random to get entropy for random number generation.
// let's use the SAM L22's true random number generator to seed the PRNG!
int getentropy(void *buf, size_t buflen);
int getentropy(void *buf, size_t buflen) {
// TODO: (a2) hook to RNG
return 0;
}
int _gettimeofday(struct timeval *tv, void *tzvp);
int _gettimeofday(struct timeval *tv, void *tzvp) {
(void)tzvp;
watch_date_time date_time = watch_rtc_get_date_time();
// FIXME: this assumes the system time is UTC! Will break for any other time zone.
tv->tv_sec = watch_utility_date_time_to_unix_time(date_time, 0);
tv->tv_usec = 0;
return 0;
}
void _watch_enable_tcc(void) {}
void _watch_disable_tcc(void) {}
void _watch_enable_usb(void) {}
// this function ends up getting called by printf to log stuff to the USB console.
int _write(int file, char *ptr, int len) {
// TODO: (a2) hook to UI
return 0;
}
// this method could be overridden to read stuff from the USB console? but no need rn.
int _read(void) {
return 0;
}
// Alternate function that outputs to the debug UART. useful for debugging USB issues.
// int _write(int file, char *ptr, int len) {
// (void)file;
// int pos = 0;
// while(pos < len) watch_debug_putc(ptr[pos++]);
// return 0;
// }

View File

@@ -0,0 +1,223 @@
/*
* MIT License
*
* Copyright (c) 2020 Joey Castillo
*
* 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.
*/
#include "watch_rtc.h"
#include <emscripten.h>
#include <emscripten/html5.h>
static double time_offset = 0;
static long tick_callbacks[8];
static long alarm_interval_id;
static long alarm_timeout_id;
static double alarm_interval;
ext_irq_cb_t alarm_callback;
ext_irq_cb_t btn_alarm_callback;
ext_irq_cb_t a2_callback;
ext_irq_cb_t a4_callback;
bool _watch_rtc_is_enabled(void) {
return true;
}
void _watch_rtc_init(void) {
}
void watch_rtc_set_date_time(watch_date_time date_time) {
time_offset = EM_ASM_DOUBLE({
const year = 2020 + (($0 >> 26) & 0x3f);
const month = ($0 >> 22) & 0xf;
const day = ($0 >> 17) & 0x1f;
const hour = ($0 >> 12) & 0x1f;
const minute = ($0 >> 6) & 0x3f;
const second = $0 & 0x3f;
const date = new Date(year, month - 1, day, hour, minute, second);
return date - Date.now();
}, date_time.reg);
}
watch_date_time watch_rtc_get_date_time(void) {
watch_date_time retval;
retval.reg = EM_ASM_INT({
const date = new Date(Date.now() + $0);
return date.getSeconds() |
(date.getMinutes() << 6) |
(date.getHours() << 12) |
(date.getDate() << 17) |
((date.getMonth() + 1) << 22) |
((date.getFullYear() - 2020) << 26);
}, time_offset);
return retval;
}
void watch_rtc_register_tick_callback(ext_irq_cb_t callback) {
watch_rtc_register_periodic_callback(callback, 1);
}
void watch_rtc_disable_tick_callback(void) {
watch_rtc_disable_periodic_callback(1);
}
static void watch_invoke_periodic_callback(void *userData) {
ext_irq_cb_t callback = userData;
callback();
void resume_main_loop(void);
resume_main_loop();
}
void watch_rtc_register_periodic_callback(ext_irq_cb_t callback, uint8_t frequency) {
// we told them, it has to be a power of 2.
if (__builtin_popcount(frequency) != 1) return;
// this left-justifies the period in a 32-bit integer.
uint32_t tmp = frequency << 24;
// now we can count the leading zeroes to get the value we need.
// 0x01 (1 Hz) will have 7 leading zeros for PER7. 0xF0 (128 Hz) will have no leading zeroes for PER0.
uint8_t per_n = __builtin_clz(tmp);
// this also maps nicely to an index for our list of tick callbacks.
double interval = 1000 / frequency; // in msec
tick_callbacks[per_n] = emscripten_set_interval(watch_invoke_periodic_callback, interval, (void *)callback);
}
void watch_rtc_disable_periodic_callback(uint8_t frequency) {
if (__builtin_popcount(frequency) != 1) return;
uint8_t per_n = __builtin_clz(frequency << 24);
emscripten_clear_interval(tick_callbacks[per_n]);
tick_callbacks[per_n] = 0;
}
void watch_rtc_disable_all_periodic_callbacks(void) {
for (int i = 0; i < 8; i++) {
if (tick_callbacks[i] != 0) {
emscripten_clear_interval(tick_callbacks[i]);
tick_callbacks[i] = 0;
}
}
}
static void watch_invoke_alarm_interval_callback(void *userData) {
(void)userData;
if (alarm_callback) alarm_callback();
}
static void watch_invoke_alarm_callback(void *userData) {
(void)userData;
if (alarm_callback) alarm_callback();
alarm_interval_id = emscripten_set_interval(watch_invoke_alarm_interval_callback, alarm_interval, NULL);
}
void watch_rtc_register_alarm_callback(ext_irq_cb_t callback, watch_date_time alarm_time, watch_rtc_alarm_match mask) {
watch_rtc_disable_alarm_callback();
switch (mask) {
case ALARM_MATCH_DISABLED:
return;
case ALARM_MATCH_SS:
alarm_interval = 60 * 1000;
break;
case ALARM_MATCH_MMSS:
alarm_interval = 60 * 60 * 1000;
break;
case ALARM_MATCH_HHMMSS:
alarm_interval = 60 * 60 * 60 * 1000;
break;
}
double timeout = EM_ASM_DOUBLE({
const now = Date.now();
const date = new Date(now + $0);
const hour = ($1 >> 12) & 0x1f;
const minute = ($1 >> 6) & 0x3f;
const second = $1 & 0x3f;
if ($2 == 1) { // SS
if (second < date.getSeconds()) date.setMinutes(date.getMinutes() + 1);
date.setSeconds(second);
} else if ($2 == 2) { // MMSS
if (second < date.getSeconds()) date.setMinutes(date.getMinutes() + 1);
if (minute < date.getMinutes()) date.setHours(date.getHours() + 1);
date.setMinutes(minute, second);
} else if ($2 == 3) { // HHMMSS
if (second < date.getSeconds()) date.setMinutes(date.getMinutes() + 1);
if (minute < date.getMinutes()) date.setHours(date.getHours() + 1);
if (hour < date.getHours()) date.setDate(date.getDate() + 1);
date.setHours(hour, minute, second);
} else {
throw 'Invalid alarm match mask';
}
return date - now;
}, time_offset, alarm_time.reg, mask);
alarm_callback = callback;
alarm_timeout_id = emscripten_set_timeout(watch_invoke_alarm_callback, timeout, NULL);
}
void watch_rtc_disable_alarm_callback(void) {
alarm_callback = NULL;
alarm_interval = 0;
if (alarm_timeout_id) {
emscripten_clear_timeout(alarm_timeout_id);
alarm_timeout_id = 0;
}
if (alarm_interval_id) {
emscripten_clear_interval(alarm_interval_id);
alarm_interval_id = 0;
}
}
///////////////////////
// Deprecated functions
void watch_set_date_time(struct calendar_date_time date_time) {
watch_date_time val;
val.unit.second = date_time.time.sec;
val.unit.minute = date_time.time.min;
val.unit.hour = date_time.time.hour;
val.unit.day = date_time.date.day;
val.unit.month = date_time.date.month;
val.unit.year = date_time.date.year - WATCH_RTC_REFERENCE_YEAR;
watch_rtc_set_date_time(val);
}
void watch_get_date_time(struct calendar_date_time *date_time) {
if (date_time == NULL) return;
watch_date_time val = watch_rtc_get_date_time();
date_time->time.sec = val.unit.second;
date_time->time.min = val.unit.minute;
date_time->time.hour = val.unit.hour;
date_time->date.day = val.unit.day;
date_time->date.month = val.unit.month;
date_time->date.year = val.unit.year + WATCH_RTC_REFERENCE_YEAR;
}
void watch_register_tick_callback(ext_irq_cb_t callback) {
watch_rtc_register_tick_callback(callback);
}

View File

@@ -0,0 +1,115 @@
/*
* MIT License
*
* Copyright (c) 2020 Joey Castillo
*
* 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.
*/
#include "watch_slcd.h"
#include "watch_private_display.h"
#include "hpl_slcd_config.h"
#include <emscripten.h>
#include <emscripten/html5.h>
//////////////////////////////////////////////////////////////////////////////////////////
// Segmented Display
static char blink_character;
static bool blink_state;
static long blink_interval_id;
static bool tick_state;
static long tick_interval_id;
void watch_enable_display(void) {
watch_clear_display();
}
void watch_set_pixel(uint8_t com, uint8_t seg) {
EM_ASM({
document.querySelectorAll("[data-com='" + $0 + "'][data-seg='" + $1 + "']")
.forEach((e) => e.style.opacity = 1);
}, com, seg);
}
void watch_clear_pixel(uint8_t com, uint8_t seg) {
EM_ASM({
document.querySelectorAll("[data-com='" + $0 + "'][data-seg='" + $1 + "']")
.forEach((e) => e.style.opacity = 0);
}, com, seg);
}
void watch_clear_display(void) {
EM_ASM({
document.querySelectorAll("[data-com][data-seg]")
.forEach((e) => e.style.opacity = 0);
});
}
static void watch_invoke_blink_callback(void *userData) {
blink_state = !blink_state;
watch_display_character(blink_state ? blink_character : ' ', 7);
watch_clear_pixel(2, 10); // clear segment B of position 7 since it can't blink
}
void watch_start_character_blink(char character, uint32_t duration) {
watch_display_character(character, 7);
watch_clear_pixel(2, 10); // clear segment B of position 7 since it can't blink
blink_state = true;
blink_character = character;
blink_interval_id = emscripten_set_interval(watch_invoke_blink_callback, (double)duration, NULL);
}
void watch_stop_blink(void) {
emscripten_clear_timeout(blink_interval_id);
blink_interval_id = 0;
blink_state = false;
}
static void watch_invoke_tick_callback(void *userData) {
tick_state = !tick_state;
if (tick_state) {
watch_clear_pixel(0, 2);
watch_set_pixel(0, 3);
} else {
watch_clear_pixel(0, 3);
watch_set_pixel(0, 2);
}
}
void watch_start_tick_animation(uint32_t duration) {
watch_display_character(' ', 8);
tick_state = true;
tick_interval_id = emscripten_set_interval(watch_invoke_tick_callback, (double)duration, NULL);
}
bool watch_tick_animation_is_running(void) {
return tick_interval_id != 0;
}
void watch_stop_tick_animation(void) {
emscripten_clear_timeout(tick_interval_id);
tick_interval_id = 0;
tick_state = false;
watch_display_character(' ', 8);
}

View File

@@ -0,0 +1,65 @@
/*
* MIT License
*
* Copyright (c) 2020 Joey Castillo
*
* 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.
*/
/*
* UART methods are Copyright (c) 2014-2017, Alex Taradov <alex@taradov.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "watch_uart.h"
#include "peripheral_clk_config.h"
void watch_enable_debug_uart(uint32_t baud) {}
void watch_debug_putc(char c) {}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
void watch_debug_puts(char *s) {
while (*s) watch_debug_putc(*s++);
}
#pragma GCC diagnostic pop