This is an automated email from the ASF dual-hosted git repository. twalthr pushed a commit to branch release-1.11 in repository https://gitbox.apache.org/repos/asf/flink.git
commit 1651d9a8a8365b4b2e8dd5a9279cc3fc28231f69 Author: Timo Walther <[email protected]> AuthorDate: Mon Jun 22 13:56:08 2020 +0200 [FLINK-18066] Add new Table source/sink documentation This closes #12724. --- docs/dev/table/sourceSinks.md | 741 ++++++++++++++++++++++++++++++++++++++++++ docs/fig/table_connectors.svg | 666 +++++++++++++++++++++++++++++++++++++ 2 files changed, 1407 insertions(+) diff --git a/docs/dev/table/sourceSinks.md b/docs/dev/table/sourceSinks.md new file mode 100644 index 0000000..6b1df8a --- /dev/null +++ b/docs/dev/table/sourceSinks.md @@ -0,0 +1,741 @@ +--- +title: "User-defined Sources & Sinks" +nav-parent_id: tableapi +nav-pos: 130 +--- +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + +_Dynamic tables_ are the core concept of Flink's Table & SQL API for processing both bounded and unbounded +data in a unified fashion. + +Because dynamic tables are only a logical concept, Flink does not own the data itself. Instead, the content +of a dynamic table is stored in external systems (such as databases, key-value stores, message queues) or files. + +_Dynamic sources_ and _dynamic sinks_ can be used to read and write data from and to an external system. In +the documentation, sources and sinks are often summarized under the term _connector_. + +Flink provides pre-defined connectors for Kafka, Hive, and different file systems. See the [connector section]({% link dev/table/connectors/index.md %}) +for more information about built-in table sources and sinks. + +This page focuses on how to develop a custom, user-defined connector. + +<span class="label label-danger">Attention</span> New table source and table sink interfaces have been +introduced in Flink 1.11 as part of [FLIP-95](https://cwiki.apache.org/confluence/display/FLINK/FLIP-95%3A+New+TableSource+and+TableSink+interfaces). +Also the factory interfaces have been reworked. FLIP-95 is not fully implemented yet. Many ability interfaces +are not supported yet (e.g. for filter or partition push down). If necessary, please also have a look +at the [old table sources and sinks page]({% link dev/table/legacySourceSinks.md %}). Those interfaces +are still supported for backwards compatibility. + +* This will be replaced by the TOC +{:toc} + +Overview +-------- + +In many cases, implementers don't need to create a new connector from scratch but would like to slightly +modify existing connectors or hook into the existing stack. In other cases, implementers would like to +create specialized connectors. + +This section helps for both kinds of use cases. It explains the general architecture of table connectors +from pure declaration in the API to runtime code that will be executed on the cluster. + +The filled arrows show how objects are transformed to other objects from one stage to the next stage during +the translation process. + +<div style="text-align: center"> + <img width="90%" src="{% link fig/table_connectors.svg %}" alt="Translation of table connectors" /> +</div> + +### Metadata + +Both Table API and SQL are declarative APIs. This includes the declaration of tables. Thus, executing +a `CREATE TABLE` statement results in updated metadata in the target catalog. + +For most catalog implementations, physical data in the external system is not modified for such an +operation. Connector-specific dependencies don't have to be present in the classpath yet. The options declared +in the `WITH` clause are neither validated nor otherwise interpreted. + +The metadata for dynamic tables (created via DDL or provided by the catalog) is represented as instances +of `CatalogTable`. A table name will be resolved into a `CatalogTable` internally when necessary. + +### Planning + +When it comes to planning and optimization of the table program, a `CatalogTable` needs to be resolved +into a `DynamicTableSource` (for reading in a `SELECT` query) and `DynamicTableSink` (for writing in +an `INSERT INTO` statement). + +`DynamicTableSourceFactory` and `DynamicTableSinkFactory` provide connector-specific logic for translating +the metadata of a `CatalogTable` into instances of `DynamicTableSource` and `DynamicTableSink`. In most +of the cases, a factory's purpose is to validate options (such as `'port' = '5022'` in the example), +configure encoding/decoding formats (if required), and create a parameterized instance of the table +connector. + +By default, instances of `DynamicTableSourceFactory` and `DynamicTableSinkFactory` are discovered using +Java's [Service Provider Interfaces (SPI)](https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html). The +`connector` option (such as `'connector' = 'custom'` in the example) must correspond to a valid factory +identifier. + +Although it might not be apparent in the class naming, `DynamicTableSource` and `DynamicTableSink` +can also be seen as stateful factories that eventually produce concrete runtime implementation for reading/writing +the actual data. + +The planner uses the source and sink instances to perform connector-specific bidirectional comunication +until an optimal logical plan could be found. Depending on the optionally declared ability interfaces (e.g. +`SupportsProjectionPushDown` or `SupportsOverwrite`), the planner might apply changes to an instance and +thus mutate the produced runtime implementation. + +### Runtime + +Once the logical planning is complete, the planner will obtain the _runtime implementation_ from the table +connector. Runtime logic is implemented in Flink's core connector interfaces such as `InputFormat` or `SourceFunction`. + +Those interfaces are grouped by another level of abstraction as subclasses of `ScanRuntimeProvider`, +`LookupRuntimeProvider`, and `SinkRuntimeProvider`. + +For example, both `OutputFormatProvider` (providing `org.apache.flink.api.common.io.OutputFormat`) and `SinkFunctionProvider` (providing `org.apache.flink.streaming.api.functions.sink.SinkFunction`) are concrete instances of `SinkRuntimeProvider` +that the planner can handle. + +{% top %} + +Extension Points +---------------- + +This section explains the available interfaces for extending Flink's table connectors. + +### Dynamic Table Factories + +Dynamic table factories are used to configure a dynamic table connector for an external storage system from catalog +and session information. + +`org.apache.flink.table.factories.DynamicTableSourceFactory` can be implemented to construct a `DynamicTableSource`. + +`org.apache.flink.table.factories.DynamicTableSinkFactory` can be implemented to construct a `DynamicTableSink`. + +By default, the factory is discovered using the value of the `connector` option as the factory identifier +and Java's Service Provider Interface. + +In JAR files, references to new implementations can be added to the service file: + +`META-INF/services/org.apache.flink.table.factories.Factory` + +The framework will check for a single matching factory that is uniquely identified by factory identifier +and requested base class (e.g. `DynamicTableSourceFactory`). + +The factory discovery process can be bypassed by the catalog implementation if necessary. For this, a +catalog needs to return an instance that implements the requested base class in `org.apache.flink.table.catalog.Catalog#getFactory`. + +### Dynamic Table Source + +By definition, a dynamic table can change over time. + +When reading a dynamic table, the content can either be considered as: +- A changelog (finite or infinite) for which all changes are consumed continuously until the changelog + is exhausted. This is represented by the `ScanTableSource` interface. +- A continuously changing or very large external table whose content is usually never read entirely + but queried for individual values when necessary. This is represented by the `LookupTableSource` + interface. + +A class can implement both of these interfaces at the same time. The planner decides about their usage depending +on the specified query. + +#### Scan Table Source + +A `ScanTableSource` scans all rows from an external storage system during runtime. + +The scanned rows don't have to contain only insertions but can also contain updates and deletions. Thus, +the table source can be used to read a (finite or infinite) changelog. The returned _changelog mode_ indicates +the set of changes that the planner can expect during runtime. + +For regular batch scenarios, the source can emit a bounded stream of insert-only rows. + +For regular streaming scenarios, the source can emit an unbounded stream of insert-only rows. + +For change data capture (CDC) scenarios, the source can emit bounded or unbounded streams with insert, +update, and delete rows. + +A table source can implement further abilitiy interfaces such as `SupportsProjectionPushDown` that might +mutate an instance during planning. All abilities are listed in the `org.apache.flink.table.connector.source.abilities` +package and in the documentation of `org.apache.flink.table.connector.source.ScanTableSource`. + +The runtime implementation of a `ScanTableSource` must produce internal data structures. Thus, records +must be emitted as `org.apache.flink.table.data.RowData`. The framework provides runtime converters such +that a source can still work on common data structures and perform a conversion at the end. + +#### Lookup Table Source + +A `LookupTableSource` looks up rows of an external storage system by one or more keys during runtime. + +Compared to `ScanTableSource`, the source does not have to read the entire table and can lazily fetch individual +values from a (possibly continuously changing) external table when necessary. + +Compared to `ScanTableSource`, a `LookupTableSource` does only support emitting insert-only changes currently. + +Further abilities are not supported. See the documentation of `org.apache.flink.table.connector.source.LookupTableSource` +for more information. + +The runtime implementation of a `LookupTableSource` is a `TableFunction` or `AsyncTableFunction`. The function +will be called with values for the given lookup keys during runtime. + +### Dynamic Table Sink + +By definition, a dynamic table can change over time. + +When writing a dynamic table, the content can always be considered as a changelog (finite or infinite) +for which all changes are written out continuously until the changelog is exhausted. The returned _changelog mode_ +indicates the set of changes that the sink accepts during runtime. + +For regular batch scenarios, the sink can solely accept insert-only rows and write out bounded streams. + +For regular streaming scenarios, the sink can solely accept insert-only rows and can write out unbounded streams. + +For change data capture (CDC) scenarios, the sink can write out bounded or unbounded streams with insert, +update, and delete rows. + +A table sink can implement further abilitiy interfaces such as `SupportsOverwrite` that might mutate an +instance during planning. All abilities are listed in the `org.apache.flink.table.connector.sink.abilities` +package and in the documentation of `org.apache.flink.table.connector.sink.DynamicTableSink`. + +The runtime implementation of a `DynamicTableSink` must consume internal data structures. Thus, records +must be accepted as `org.apache.flink.table.data.RowData`. The framework provides runtime converters such +that a sink can still work on common data structures and perform a conversion at the beginning. + +### Encoding / Decoding Formats + +Some table connectors accept different formats that encode and decode keys and/or values. + +Formats work similar to the pattern `DynamicTableSourceFactory -> DynamicTableSource -> ScanRuntimeProvider`, +where the factory is responsible for translating options and the source is responsible for creating runtime logic. + +Because formats might be located in different modules, they are discovered using Java's Service Provider +Interface similar to [table factories](#dynamic-table-factories). In order to discover a format factory, +the dynamic table factory searches for a factory that corresponds to a factory identifier and connector-specific +base class. + +For example, the Kafka table source requires a `DeserializationSchema` as runtime interface for a decoding +format. Therefore, the Kafka table source factory uses the value of the `value.format` option to discover +a `DeserializationFormatFactory`. + +The following format factories are currently supported: + +``` +org.apache.flink.table.factories.DeserializationFormatFactory +org.apache.flink.table.factories.SerializationFormatFactory +``` + +The format factory translates the options into an `EncodingFormat` or a `DecodingFormat`. Those interfaces are +another kind of factory that produce specialized format runtime logic for the given data type. + +For example, for a Kafka table source factory, the `DeserializationFormatFactory` would return an `EncodingFormat<DeserializationSchema>` +that can be passed into the Kafka table source. + +{% top %} + +Full Stack Example +------------------ + +This section sketches how to implement a scan table source with a decoding format that supports changelog +semantics. The example illustrates how all of the mentioned components play together. It can serve as +a reference implementation. + +In particular, it shows how to +- create factories that parse and validate options, +- implement table connectors, +- implement and discover custom formats, +- and use provided utilities such as data structure converters and the `FactoryUtil`. + +The table source uses a simple single-threaded `SourceFunction` to open a socket that listens for incoming +bytes. The raw bytes are decoded into rows by a pluggable format. The format expects a changelog flag +as the first column. + +We will use most of the interfaces metioned above to enable the following DDL: + +{% highlight sql %} +CREATE TABLE UserScores (name STRING, score INT) +WITH ( + 'connector' = 'socket', + 'hostname' = 'localhost', + 'port' = '9999', + 'byte-delimiter' = '10', + 'format' = 'changelog-csv', + 'changelog-csv.column-delimiter' = '|' +); +{% endhighlight %} + +Because the format supports changelog semantics, we are able to ingest updates during runtime and create +an updating view that can continuously evaluate changing data: + +{% highlight sql %} +SELECT name, SUM(score) FROM UserScores GROUP BY name; +{% endhighlight %} + +Use the following command to ingest data in a terminal: +{% highlight text %} +> nc -lk 9999 +INSERT|Alice|12 +INSERT|Bob|5 +DELETE|Alice|12 +INSERT|Alice|18 +{% endhighlight %} + +### Factories + +This section illustrates how to translate metadata coming from the catalog to concrete connector instances. + +Both factories have been added to the `META-INF/services` directory. + +**`SocketDynamicTableFactory`** + +The `SocketDynamicTableFactory` translates the catalog table to a table source. Because the table source +requires a decoding format, we are discovering the format using the provided `FactoryUtil` for convenience. + +{% highlight java %} +import org.apache.flink.api.common.serialization.DeserializationSchema; +import org.apache.flink.configuration.ConfigOption; +import org.apache.flink.configuration.ConfigOptions; +import org.apache.flink.configuration.ReadableConfig; +import org.apache.flink.table.connector.format.DecodingFormat; +import org.apache.flink.table.connector.source.DynamicTableSource; +import org.apache.flink.table.data.RowData; +import org.apache.flink.table.factories.DeserializationFormatFactory; +import org.apache.flink.table.factories.DynamicTableSourceFactory; +import org.apache.flink.table.factories.FactoryUtil; +import org.apache.flink.table.types.DataType; + +public class SocketDynamicTableFactory implements DynamicTableSourceFactory { + + // define all options statically + public static final ConfigOption<String> HOSTNAME = ConfigOptions.key("hostname") + .stringType() + .noDefaultValue(); + + public static final ConfigOption<Integer> PORT = ConfigOptions.key("port") + .intType() + .noDefaultValue(); + + public static final ConfigOption<Integer> BYTE_DELIMITER = ConfigOptions.key("byte-delimiter") + .intType() + .defaultValue(10); // corresponds to '\n' + + @Override + public String factoryIdentifier() { + return "socket"; // used for matching to `connector = '...'` + } + + @Override + public Set<ConfigOption<?>> requiredOptions() { + final Set<ConfigOption<?>> options = new HashSet<>(); + options.add(HOSTNAME); + options.add(PORT); + options.add(FactoryUtil.FORMAT); // use pre-defined option for format + return options; + } + + @Override + public Set<ConfigOption<?>> optionalOptions() { + final Set<ConfigOption<?>> options = new HashSet<>(); + options.add(BYTE_DELIMITER); + return options; + } + + @Override + public DynamicTableSource createDynamicTableSource(Context context) { + // either implement your custom validation logic here ... + // or use the provided helper utility + final FactoryUtil.TableFactoryHelper helper = FactoryUtil.createTableFactoryHelper(this, context); + + // discover a suitable decoding format + final DecodingFormat<DeserializationSchema<RowData>> decodingFormat = helper.discoverDecodingFormat( + DeserializationFormatFactory.class, + FactoryUtil.FORMAT); + + // validate all options + helper.validate(); + + // get the validated options + final ReadableConfig options = helper.getOptions(); + final String hostname = options.get(HOSTNAME); + final int port = options.get(PORT); + final byte byteDelimiter = (byte) (int) options.get(BYTE_DELIMITER); + + // derive the produced data type (excluding computed columns) from the catalog table + final DataType producedDataType = context.getCatalogTable().getSchema().toPhysicalRowDataType(); + + // create and return dynamic table source + return new SocketDynamicTableSource(hostname, port, byteDelimiter, decodingFormat, producedDataType); + } +} +{% endhighlight %} + +**`ChangelogCsvFormatFactory`** + +The `ChangelogCsvFormatFactory` translates format-specific options to a format. The `FactoryUtil` in `SocketDynamicTableFactory` +takes care of adapting the option keys accordingly and handles the prefixing like `changelog-csv.column-delimiter`. + +Because this factory implements `DeserializationFormatFactory`, it could also be used for other connectors +that support deserialization formats such as the Kafka connector. + +{% highlight java %} +import org.apache.flink.api.common.serialization.DeserializationSchema; +import org.apache.flink.configuration.ConfigOption; +import org.apache.flink.configuration.ConfigOptions; +import org.apache.flink.configuration.ReadableConfig; +import org.apache.flink.table.connector.format.DecodingFormat; +import org.apache.flink.table.data.RowData; +import org.apache.flink.table.factories.DeserializationFormatFactory; +import org.apache.flink.table.factories.DynamicTableFactory; + +public class ChangelogCsvFormatFactory implements DeserializationFormatFactory { + + // define all options statically + public static final ConfigOption<String> COLUMN_DELIMITER = ConfigOptions.key("column-delimiter") + .stringType() + .defaultValue("|"); + + @Override + public String factoryIdentifier() { + return "changelog-csv"; + } + + @Override + public Set<ConfigOption<?>> requiredOptions() { + return Collections.emptySet(); + } + + @Override + public Set<ConfigOption<?>> optionalOptions() { + final Set<ConfigOption<?>> options = new HashSet<>(); + options.add(COLUMN_DELIMITER); + return options; + } + + @Override + public DecodingFormat<DeserializationSchema<RowData>> createDecodingFormat( + DynamicTableFactory.Context context, + ReadableConfig formatOptions) { + // get the validated options + final String columnDelimiter = formatOptions.get(COLUMN_DELIMITER); + + // create and return the format + return new ChangelogCsvFormat(columnDelimiter); + } +} +{% endhighlight %} + +### Table Source and Decoding Format + +This section illustrates how to translate from instances of the planning layer to runtime instances that +are shipped to the cluster. + +**`SocketDynamicTableSource`** + +The `SocketDynamicTableSource` is used during planning. In our example, we don't implement any of the +available ability interfaces. Therefore, the main logic can be found in `getScanRuntimeProvider(...)` +where we instantiate the required `SourceFunction` and its `DeserializationSchema` for runtime. Both +instances are parameterized to return internal data structures (i.e. `RowData`). + +{% highlight java %} +import org.apache.flink.api.common.serialization.DeserializationSchema; +import org.apache.flink.streaming.api.functions.source.SourceFunction; +import org.apache.flink.table.connector.ChangelogMode; +import org.apache.flink.table.connector.format.DecodingFormat; +import org.apache.flink.table.connector.source.DynamicTableSource; +import org.apache.flink.table.connector.source.ScanTableSource; +import org.apache.flink.table.connector.source.SourceFunctionProvider; +import org.apache.flink.table.data.RowData; +import org.apache.flink.table.types.DataType; + +public class SocketDynamicTableSource implements ScanTableSource { + + private final String hostname; + private final int port; + private final byte byteDelimiter; + private final DecodingFormat<DeserializationSchema<RowData>> decodingFormat; + private final DataType producedDataType; + + public SocketDynamicTableSource( + String hostname, + int port, + byte byteDelimiter, + DecodingFormat<DeserializationSchema<RowData>> decodingFormat, + DataType producedDataType) { + this.hostname = hostname; + this.port = port; + this.byteDelimiter = byteDelimiter; + this.decodingFormat = decodingFormat; + this.producedDataType = producedDataType; + } + + @Override + public ChangelogMode getChangelogMode() { + // in our example the format decides about the changelog mode + // but it could also be the source itself + return decodingFormat.getChangelogMode(); + } + + @Override + public ScanRuntimeProvider getScanRuntimeProvider(ScanContext runtimeProviderContext) { + + // create runtime classes that are shipped to the cluster + + final DeserializationSchema<RowData> deserializer = decodingFormat.createRuntimeDecoder( + runtimeProviderContext, + producedDataType); + + final SourceFunction<RowData> sourceFunction = new SocketSourceFunction( + hostname, + port, + byteDelimiter, + deserializer); + + return SourceFunctionProvider.of(sourceFunction, false); + } + + @Override + public DynamicTableSource copy() { + return new SocketDynamicTableSource(hostname, port, byteDelimiter, decodingFormat, producedDataType); + } + + @Override + public String asSummaryString() { + return "Socket Table Source"; + } +} +{% endhighlight %} + +**`ChangelogCsvFormat`** + +The `ChangelogCsvFormat` is a decoding format that uses a `DeserializationSchema` during runtime. It +supports emitting `INSERT` and `DELETE` changes. + +{% highlight java %} +import org.apache.flink.api.common.serialization.DeserializationSchema; +import org.apache.flink.api.common.typeinfo.TypeInformation; +import org.apache.flink.table.connector.ChangelogMode; +import org.apache.flink.table.connector.format.DecodingFormat; +import org.apache.flink.table.connector.source.DynamicTableSource; +import org.apache.flink.table.connector.source.DynamicTableSource.DataStructureConverter; +import org.apache.flink.table.data.RowData; +import org.apache.flink.table.types.DataType; +import org.apache.flink.table.types.logical.LogicalType; +import org.apache.flink.types.RowKind; + +public class ChangelogCsvFormat implements DecodingFormat<DeserializationSchema<RowData>> { + + private final String columnDelimiter; + + public ChangelogCsvFormat(String columnDelimiter) { + this.columnDelimiter = columnDelimiter; + } + + @Override + @SuppressWarnings("unchecked") + public DeserializationSchema<RowData> createRuntimeDecoder( + DynamicTableSource.Context context, + DataType producedDataType) { + // create type information for the DeserializationSchema + final TypeInformation<RowData> producedTypeInfo = (TypeInformation<RowData>) context.createTypeInformation( + producedDataType); + + // most of the code in DeserializationSchema will not work on internal data structures + // create a converter for conversion at the end + final DataStructureConverter converter = context.createDataStructureConverter(producedDataType); + + // use logical types during runtime for parsing + final List<LogicalType> parsingTypes = producedDataType.getLogicalType().getChildren(); + + // create runtime class + return new ChangelogCsvDeserializer(parsingTypes, converter, producedTypeInfo, columnDelimiter); + } + + @Override + public ChangelogMode getChangelogMode() { + // define that this format can produce INSERT and DELETE rows + return ChangelogMode.newBuilder() + .addContainedKind(RowKind.INSERT) + .addContainedKind(RowKind.DELETE) + .build(); + } +} +{% endhighlight %} + +### Runtime + +For completeness, this section illustrates the runtime logic for both `SourceFunction` and `DeserializationSchema`. + +**ChangelogCsvDeserializer** + +The `ChangelogCsvDeserializer` contains a simple parsing logic for converting bytes into `Row` of `Integer` +and `String` with a row kind. The final conversion step converts those into internal data structures. + +{% highlight java %} +import org.apache.flink.api.common.serialization.DeserializationSchema; +import org.apache.flink.api.common.typeinfo.TypeInformation; +import org.apache.flink.table.connector.RuntimeConverter.Context; +import org.apache.flink.table.connector.source.DynamicTableSource.DataStructureConverter; +import org.apache.flink.table.data.RowData; +import org.apache.flink.table.types.logical.LogicalType; +import org.apache.flink.table.types.logical.LogicalTypeRoot; +import org.apache.flink.types.Row; +import org.apache.flink.types.RowKind; + +public class ChangelogCsvDeserializer implements DeserializationSchema<RowData> { + + private final List<LogicalType> parsingTypes; + private final DataStructureConverter converter; + private final TypeInformation<RowData> producedTypeInfo; + private final String columnDelimiter; + + public ChangelogCsvDeserializer( + List<LogicalType> parsingTypes, + DataStructureConverter converter, + TypeInformation<RowData> producedTypeInfo, + String columnDelimiter) { + this.parsingTypes = parsingTypes; + this.converter = converter; + this.producedTypeInfo = producedTypeInfo; + this.columnDelimiter = columnDelimiter; + } + + @Override + public TypeInformation<RowData> getProducedType() { + // return the type information required by Flink's core interfaces + return producedTypeInfo; + } + + @Override + public void open(InitializationContext context) { + // converters must be opened + converter.open(Context.create(ChangelogCsvDeserializer.class.getClassLoader())); + } + + @Override + public RowData deserialize(byte[] message) { + // parse the columns including a changelog flag + final String[] columns = new String(message).split(Pattern.quote(columnDelimiter)); + final RowKind kind = RowKind.valueOf(columns[0]); + final Row row = new Row(kind, parsingTypes.size()); + for (int i = 0; i < parsingTypes.size(); i++) { + row.setField(i, parse(parsingTypes.get(i).getTypeRoot(), columns[i + 1])); + } + // convert to internal data structure + return (RowData) converter.toInternal(row); + } + + private static Object parse(LogicalTypeRoot root, String value) { + switch (root) { + case INTEGER: + return Integer.parseInt(value); + case VARCHAR: + return value; + default: + throw new IllegalArgumentException(); + } + } + + @Override + public boolean isEndOfStream(RowData nextElement) { + return false; + } +} +{% endhighlight %} + +**SocketSourceFunction** + +The `SocketSourceFunction` opens a socket and consumes bytes. It splits records by the given byte +delimiter (`\n` by default) and delegates the decoding to a pluggable `DeserializationSchema`. The +source function can only work with a parallelism of 1. + +{% highlight java %} +import org.apache.flink.api.common.serialization.DeserializationSchema; +import org.apache.flink.api.common.typeinfo.TypeInformation; +import org.apache.flink.api.java.typeutils.ResultTypeQueryable; +import org.apache.flink.configuration.Configuration; +import org.apache.flink.streaming.api.functions.source.RichSourceFunction; +import org.apache.flink.table.data.RowData; + +public class SocketSourceFunction extends RichSourceFunction<RowData> implements ResultTypeQueryable<RowData> { + + private final String hostname; + private final int port; + private final byte byteDelimiter; + private final DeserializationSchema<RowData> deserializer; + + private volatile boolean isRunning = true; + private Socket currentSocket; + + public SocketSourceFunction(String hostname, int port, byte byteDelimiter, DeserializationSchema<RowData> deserializer) { + this.hostname = hostname; + this.port = port; + this.byteDelimiter = byteDelimiter; + this.deserializer = deserializer; + } + + @Override + public TypeInformation<RowData> getProducedType() { + return deserializer.getProducedType(); + } + + @Override + public void open(Configuration parameters) throws Exception { + deserializer.open(() -> getRuntimeContext().getMetricGroup()); + } + + @Override + public void run(SourceContext<RowData> ctx) throws Exception { + while (isRunning) { + // open and consume from socket + try (final Socket socket = new Socket()) { + currentSocket = socket; + socket.connect(new InetSocketAddress(hostname, port), 0); + try (InputStream stream = socket.getInputStream()) { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + int b; + while ((b = stream.read()) >= 0) { + // buffer until delimiter + if (b != byteDelimiter) { + buffer.write(b); + } + // decode and emit record + else { + ctx.collect(deserializer.deserialize(buffer.toByteArray())); + buffer.reset(); + } + } + } + } catch (Throwable t) { + t.printStackTrace(); // print and continue + } + Thread.sleep(1000); + } + } + + @Override + public void cancel() { + isRunning = false; + try { + currentSocket.close(); + } catch (Throwable t) { + // ignore + } + } +} +{% endhighlight %} + +{% top %} diff --git a/docs/fig/table_connectors.svg b/docs/fig/table_connectors.svg new file mode 100644 index 0000000..f41d0cb --- /dev/null +++ b/docs/fig/table_connectors.svg @@ -0,0 +1,666 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1361pt" height="822pt" viewBox="0 0 1361 822" version="1.1"> +<defs> +<g> +<symbol overflow="visible" id="glyph0-0"> +<path style="stroke:none;" d="M 5.65625 -9.09375 C 4.550781 -9.09375 3.679688 -8.726562 3.046875 -8 C 2.410156 -7.269531 2.09375 -6.269531 2.09375 -5 C 2.09375 -3.6875 2.398438 -2.671875 3.015625 -1.953125 C 3.628906 -1.242188 4.503906 -0.890625 5.640625 -0.890625 C 6.335938 -0.890625 7.132812 -1.015625 8.03125 -1.265625 L 8.03125 -0.25 C 7.332031 0.0078125 6.476562 0.140625 5.46875 0.140625 C 3.988281 0.140625 2.847656 -0.304688 2.046875 -1.203125 C 1.253906 -2.097656 0.859375 -3.367188 [...] +</symbol> +<symbol overflow="visible" id="glyph0-1"> +<path style="stroke:none;" d="M 2.53125 -4.15625 L 2.53125 0 L 1.375 0 L 1.375 -10 L 4.109375 -10 C 5.335938 -10 6.242188 -9.765625 6.828125 -9.296875 C 7.421875 -8.828125 7.71875 -8.117188 7.71875 -7.171875 C 7.71875 -5.847656 7.046875 -4.953125 5.703125 -4.484375 L 8.421875 0 L 7.046875 0 L 4.625 -4.15625 Z M 2.53125 -5.15625 L 4.125 -5.15625 C 4.945312 -5.15625 5.550781 -5.316406 5.9375 -5.640625 C 6.320312 -5.960938 6.515625 -6.453125 6.515625 -7.109375 C 6.515625 -7.765625 6.316406 [...] +</symbol> +<symbol overflow="visible" id="glyph0-2"> +<path style="stroke:none;" d="M 6.953125 0 L 1.375 0 L 1.375 -10 L 6.953125 -10 L 6.953125 -8.96875 L 2.53125 -8.96875 L 2.53125 -5.75 L 6.671875 -5.75 L 6.671875 -4.71875 L 2.53125 -4.71875 L 2.53125 -1.046875 L 6.953125 -1.046875 Z M 6.953125 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-3"> +<path style="stroke:none;" d="M 7.65625 0 L 6.40625 -3.171875 L 2.40625 -3.171875 L 1.171875 0 L 0 0 L 3.953125 -10.03125 L 4.921875 -10.03125 L 8.859375 0 Z M 6.046875 -4.21875 L 4.890625 -7.328125 C 4.734375 -7.710938 4.578125 -8.191406 4.421875 -8.765625 C 4.316406 -8.328125 4.175781 -7.847656 4 -7.328125 L 2.8125 -4.21875 Z M 6.046875 -4.21875 "/> +</symbol> +<symbol overflow="visible" id="glyph0-4"> +<path style="stroke:none;" d="M 4.453125 0 L 3.28125 0 L 3.28125 -8.96875 L 0.125 -8.96875 L 0.125 -10 L 7.609375 -10 L 7.609375 -8.96875 L 4.453125 -8.96875 Z M 4.453125 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-5"> +<path style="stroke:none;" d=""/> +</symbol> +<symbol overflow="visible" id="glyph0-6"> +<path style="stroke:none;" d="M 1.375 -10 L 4.203125 -10 C 5.523438 -10 6.484375 -9.800781 7.078125 -9.40625 C 7.671875 -9.007812 7.96875 -8.378906 7.96875 -7.515625 C 7.96875 -6.921875 7.800781 -6.429688 7.46875 -6.046875 C 7.132812 -5.660156 6.648438 -5.414062 6.015625 -5.3125 L 6.015625 -5.234375 C 7.535156 -4.972656 8.296875 -4.175781 8.296875 -2.84375 C 8.296875 -1.945312 7.992188 -1.25 7.390625 -0.75 C 6.785156 -0.25 5.941406 0 4.859375 0 L 1.375 0 Z M 2.53125 -5.71875 L 4.453125 - [...] +</symbol> +<symbol overflow="visible" id="glyph0-7"> +<path style="stroke:none;" d="M 1.375 0 L 1.375 -10 L 2.53125 -10 L 2.53125 -1.046875 L 6.953125 -1.046875 L 6.953125 0 Z M 1.375 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-8"> +<path style="stroke:none;" d="M 8.921875 -10 L 8.921875 -3.53125 C 8.921875 -2.382812 8.578125 -1.484375 7.890625 -0.828125 C 7.203125 -0.179688 6.253906 0.140625 5.046875 0.140625 C 3.847656 0.140625 2.914062 -0.1875 2.25 -0.84375 C 1.59375 -1.5 1.265625 -2.40625 1.265625 -3.5625 L 1.265625 -10 L 2.4375 -10 L 2.4375 -3.46875 C 2.4375 -2.632812 2.660156 -1.992188 3.109375 -1.546875 C 3.566406 -1.097656 4.238281 -0.875 5.125 -0.875 C 5.96875 -0.875 6.617188 -1.097656 7.078125 -1.546875 C [...] +</symbol> +<symbol overflow="visible" id="glyph0-9"> +<path style="stroke:none;" d="M 6.03125 -2.046875 C 6.03125 -1.347656 5.769531 -0.804688 5.25 -0.421875 C 4.738281 -0.046875 4.007812 0.140625 3.0625 0.140625 C 2.070312 0.140625 1.300781 -0.015625 0.75 -0.328125 L 0.75 -1.390625 C 1.101562 -1.203125 1.484375 -1.054688 1.890625 -0.953125 C 2.304688 -0.847656 2.707031 -0.796875 3.09375 -0.796875 C 3.6875 -0.796875 4.140625 -0.890625 4.453125 -1.078125 C 4.773438 -1.273438 4.9375 -1.566406 4.9375 -1.953125 C 4.9375 -2.242188 4.8125 -2.4921 [...] +</symbol> +<symbol overflow="visible" id="glyph0-10"> +<path style="stroke:none;" d="M 4.375 0.140625 C 3.257812 0.140625 2.378906 -0.195312 1.734375 -0.875 C 1.097656 -1.550781 0.78125 -2.488281 0.78125 -3.6875 C 0.78125 -4.894531 1.078125 -5.851562 1.671875 -6.5625 C 2.273438 -7.269531 3.078125 -7.625 4.078125 -7.625 C 5.015625 -7.625 5.753906 -7.316406 6.296875 -6.703125 C 6.847656 -6.085938 7.125 -5.273438 7.125 -4.265625 L 7.125 -3.546875 L 1.96875 -3.546875 C 1.988281 -2.660156 2.207031 -1.988281 2.625 -1.53125 C 3.050781 -1.082031 3.6 [...] +</symbol> +<symbol overflow="visible" id="glyph0-11"> +<path style="stroke:none;" d="M 4.625 -7.625 C 4.957031 -7.625 5.253906 -7.597656 5.515625 -7.546875 L 5.359375 -6.5 C 5.046875 -6.5625 4.773438 -6.59375 4.546875 -6.59375 C 3.929688 -6.59375 3.410156 -6.347656 2.984375 -5.859375 C 2.554688 -5.367188 2.34375 -4.753906 2.34375 -4.015625 L 2.34375 0 L 1.203125 0 L 1.203125 -7.5 L 2.140625 -7.5 L 2.265625 -6.109375 L 2.328125 -6.109375 C 2.597656 -6.597656 2.929688 -6.972656 3.328125 -7.234375 C 3.722656 -7.492188 4.15625 -7.625 4.625 -7.62 [...] +</symbol> +<symbol overflow="visible" id="glyph0-12"> +<path style="stroke:none;" d="M 0.5625 -3.828125 C 0.5625 -5.035156 0.738281 -6.164062 1.09375 -7.21875 C 1.445312 -8.28125 1.957031 -9.207031 2.625 -10 L 3.71875 -10 C 3.0625 -9.113281 2.566406 -8.144531 2.234375 -7.09375 C 1.910156 -6.039062 1.75 -4.957031 1.75 -3.84375 C 1.75 -2.75 1.914062 -1.679688 2.25 -0.640625 C 2.59375 0.398438 3.082031 1.351562 3.71875 2.21875 L 2.625 2.21875 C 1.945312 1.4375 1.429688 0.53125 1.078125 -0.5 C 0.734375 -1.53125 0.5625 -2.640625 0.5625 -3.828125 [...] +</symbol> +<symbol overflow="visible" id="glyph0-13"> +<path style="stroke:none;" d="M 6.328125 0 L 6.328125 -4.84375 C 6.328125 -5.457031 6.1875 -5.914062 5.90625 -6.21875 C 5.632812 -6.519531 5.203125 -6.671875 4.609375 -6.671875 C 3.828125 -6.671875 3.253906 -6.457031 2.890625 -6.03125 C 2.523438 -5.601562 2.34375 -4.90625 2.34375 -3.9375 L 2.34375 0 L 1.203125 0 L 1.203125 -7.5 L 2.125 -7.5 L 2.3125 -6.46875 L 2.359375 -6.46875 C 2.597656 -6.832031 2.925781 -7.113281 3.34375 -7.3125 C 3.757812 -7.519531 4.226562 -7.625 4.75 -7.625 C 5.64 [...] +</symbol> +<symbol overflow="visible" id="glyph0-14"> +<path style="stroke:none;" d="M 5.8125 0 L 5.578125 -1.0625 L 5.53125 -1.0625 C 5.15625 -0.59375 4.78125 -0.273438 4.40625 -0.109375 C 4.039062 0.0546875 3.578125 0.140625 3.015625 0.140625 C 2.273438 0.140625 1.691406 -0.0507812 1.265625 -0.4375 C 0.847656 -0.820312 0.640625 -1.367188 0.640625 -2.078125 C 0.640625 -3.585938 1.847656 -4.378906 4.265625 -4.453125 L 5.546875 -4.484375 L 5.546875 -4.953125 C 5.546875 -5.546875 5.414062 -5.976562 5.15625 -6.25 C 4.90625 -6.53125 4.503906 -6. [...] +</symbol> +<symbol overflow="visible" id="glyph0-15"> +<path style="stroke:none;" d="M 10.75 0 L 10.75 -4.875 C 10.75 -5.46875 10.617188 -5.914062 10.359375 -6.21875 C 10.109375 -6.519531 9.71875 -6.671875 9.1875 -6.671875 C 8.476562 -6.671875 7.953125 -6.46875 7.609375 -6.0625 C 7.273438 -5.65625 7.109375 -5.03125 7.109375 -4.1875 L 7.109375 0 L 5.96875 0 L 5.96875 -4.875 C 5.96875 -5.46875 5.835938 -5.914062 5.578125 -6.21875 C 5.328125 -6.519531 4.929688 -6.671875 4.390625 -6.671875 C 3.679688 -6.671875 3.160156 -6.457031 2.828125 -6.0312 [...] +</symbol> +<symbol overflow="visible" id="glyph0-16"> +<path style="stroke:none;" d="M 7.015625 -2.65625 C 7.015625 -1.78125 6.691406 -1.09375 6.046875 -0.59375 C 5.410156 -0.101562 4.546875 0.140625 3.453125 0.140625 C 2.273438 0.140625 1.363281 -0.015625 0.71875 -0.328125 L 0.71875 -1.4375 C 1.132812 -1.269531 1.582031 -1.132812 2.0625 -1.03125 C 2.550781 -0.925781 3.03125 -0.875 3.5 -0.875 C 4.269531 -0.875 4.851562 -1.019531 5.25 -1.3125 C 5.644531 -1.613281 5.84375 -2.023438 5.84375 -2.546875 C 5.84375 -2.890625 5.769531 -3.171875 5.625 [...] +</symbol> +<symbol overflow="visible" id="glyph0-17"> +<path style="stroke:none;" d="M 1.375 0 L 1.375 -10 L 2.53125 -10 L 2.53125 0 Z M 1.375 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-18"> +<path style="stroke:none;" d="M 9.1875 0 L 7.859375 0 L 2.390625 -8.390625 L 2.34375 -8.390625 C 2.414062 -7.398438 2.453125 -6.5 2.453125 -5.6875 L 2.453125 0 L 1.375 0 L 1.375 -10 L 2.6875 -10 L 8.140625 -1.640625 L 8.1875 -1.640625 C 8.175781 -1.765625 8.15625 -2.160156 8.125 -2.828125 C 8.09375 -3.492188 8.082031 -3.972656 8.09375 -4.265625 L 8.09375 -10 L 9.1875 -10 Z M 9.1875 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-19"> +<path style="stroke:none;" d="M 5.765625 -5.234375 L 9.171875 -5.234375 L 9.171875 -0.375 C 8.640625 -0.207031 8.097656 -0.0820312 7.546875 0 C 7.003906 0.09375 6.375 0.140625 5.65625 0.140625 C 4.144531 0.140625 2.96875 -0.304688 2.125 -1.203125 C 1.28125 -2.109375 0.859375 -3.375 0.859375 -5 C 0.859375 -6.039062 1.066406 -6.953125 1.484375 -7.734375 C 1.898438 -8.515625 2.5 -9.109375 3.28125 -9.515625 C 4.0625 -9.929688 4.976562 -10.140625 6.03125 -10.140625 C 7.101562 -10.140625 8.097 [...] +</symbol> +<symbol overflow="visible" id="glyph0-20"> +<path style="stroke:none;" d="M 2.390625 -1.625 L 2.5 -1.46875 C 2.375 -1.007812 2.195312 -0.476562 1.96875 0.125 C 1.75 0.726562 1.519531 1.289062 1.28125 1.8125 L 0.4375 1.8125 C 0.550781 1.332031 0.679688 0.742188 0.828125 0.046875 C 0.984375 -0.648438 1.09375 -1.207031 1.15625 -1.625 Z M 2.390625 -1.625 "/> +</symbol> +<symbol overflow="visible" id="glyph0-21"> +<path style="stroke:none;" d="M 7.328125 -7.5 L 7.328125 -6.78125 L 5.953125 -6.609375 C 6.078125 -6.453125 6.1875 -6.242188 6.28125 -5.984375 C 6.382812 -5.722656 6.4375 -5.429688 6.4375 -5.109375 C 6.4375 -4.378906 6.1875 -3.796875 5.6875 -3.359375 C 5.1875 -2.921875 4.5 -2.703125 3.625 -2.703125 C 3.394531 -2.703125 3.1875 -2.71875 3 -2.75 C 2.507812 -2.5 2.265625 -2.179688 2.265625 -1.796875 C 2.265625 -1.585938 2.347656 -1.429688 2.515625 -1.328125 C 2.691406 -1.234375 2.984375 -1.1 [...] +</symbol> +<symbol overflow="visible" id="glyph0-22"> +<path style="stroke:none;" d="M 3.578125 -3.828125 C 3.578125 -2.628906 3.398438 -1.515625 3.046875 -0.484375 C 2.691406 0.546875 2.1875 1.445312 1.53125 2.21875 L 0.4375 2.21875 C 1.0625 1.363281 1.539062 0.414062 1.875 -0.625 C 2.21875 -1.675781 2.390625 -2.75 2.390625 -3.84375 C 2.390625 -4.957031 2.222656 -6.039062 1.890625 -7.09375 C 1.566406 -8.144531 1.078125 -9.113281 0.421875 -10 L 1.53125 -10 C 2.195312 -9.195312 2.703125 -8.269531 3.046875 -7.21875 C 3.398438 -6.164062 3.57812 [...] +</symbol> +<symbol overflow="visible" id="glyph0-23"> +<path style="stroke:none;" d="M 10.09375 0 L 8.953125 0 L 6.9375 -6.6875 C 6.832031 -6.988281 6.722656 -7.363281 6.609375 -7.8125 C 6.492188 -8.257812 6.429688 -8.53125 6.421875 -8.625 C 6.328125 -8.019531 6.171875 -7.363281 5.953125 -6.65625 L 4 0 L 2.84375 0 L 0.1875 -10 L 1.421875 -10 L 3 -3.828125 C 3.21875 -2.953125 3.375 -2.164062 3.46875 -1.46875 C 3.59375 -2.300781 3.773438 -3.117188 4.015625 -3.921875 L 5.8125 -10 L 7.046875 -10 L 8.921875 -3.859375 C 9.140625 -3.148438 9.320312 [...] +</symbol> +<symbol overflow="visible" id="glyph0-24"> +<path style="stroke:none;" d="M 8.96875 0 L 7.796875 0 L 7.796875 -4.703125 L 2.53125 -4.703125 L 2.53125 0 L 1.375 0 L 1.375 -10 L 2.53125 -10 L 2.53125 -5.75 L 7.796875 -5.75 L 7.796875 -10 L 8.96875 -10 Z M 8.96875 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-25"> +<path style="stroke:none;" d="M 2.1875 -10 L 1.90625 -6.390625 L 1.1875 -6.390625 L 0.90625 -10 Z M 2.1875 -10 "/> +</symbol> +<symbol overflow="visible" id="glyph0-26"> +<path style="stroke:none;" d="M 4.203125 0.140625 C 3.117188 0.140625 2.273438 -0.191406 1.671875 -0.859375 C 1.078125 -1.523438 0.78125 -2.472656 0.78125 -3.703125 C 0.78125 -4.953125 1.082031 -5.914062 1.6875 -6.59375 C 2.289062 -7.28125 3.148438 -7.625 4.265625 -7.625 C 4.628906 -7.625 4.988281 -7.582031 5.34375 -7.5 C 5.707031 -7.425781 5.992188 -7.335938 6.203125 -7.234375 L 5.859375 -6.28125 C 5.597656 -6.375 5.320312 -6.453125 5.03125 -6.515625 C 4.738281 -6.585938 4.476562 -6.625 [...] +</symbol> +<symbol overflow="visible" id="glyph0-27"> +<path style="stroke:none;" d="M 7.671875 -3.75 C 7.671875 -2.53125 7.363281 -1.578125 6.75 -0.890625 C 6.132812 -0.203125 5.285156 0.140625 4.203125 0.140625 C 3.523438 0.140625 2.925781 -0.015625 2.40625 -0.328125 C 1.894531 -0.648438 1.492188 -1.101562 1.203125 -1.6875 C 0.921875 -2.28125 0.78125 -2.96875 0.78125 -3.75 C 0.78125 -4.96875 1.085938 -5.914062 1.703125 -6.59375 C 2.316406 -7.28125 3.164062 -7.625 4.25 -7.625 C 5.289062 -7.625 6.117188 -7.273438 6.734375 -6.578125 C 7.35937 [...] +</symbol> +<symbol overflow="visible" id="glyph0-28"> +<path style="stroke:none;" d="M 3.625 -0.796875 C 3.820312 -0.796875 4.015625 -0.8125 4.203125 -0.84375 C 4.390625 -0.875 4.539062 -0.90625 4.65625 -0.9375 L 4.65625 -0.0625 C 4.53125 -0.0078125 4.347656 0.0351562 4.109375 0.078125 C 3.867188 0.117188 3.648438 0.140625 3.453125 0.140625 C 2.003906 0.140625 1.28125 -0.625 1.28125 -2.15625 L 1.28125 -6.609375 L 0.21875 -6.609375 L 0.21875 -7.15625 L 1.28125 -7.625 L 1.765625 -9.234375 L 2.421875 -9.234375 L 2.421875 -7.5 L 4.59375 -7.5 L 4 [...] +</symbol> +<symbol overflow="visible" id="glyph0-29"> +<path style="stroke:none;" d="M 0.8125 -5.859375 L 0.8125 -6.796875 L 7.171875 -6.796875 L 7.171875 -5.859375 Z M 0.8125 -3.0625 L 0.8125 -4 L 7.171875 -4 L 7.171875 -3.0625 Z M 0.8125 -3.0625 "/> +</symbol> +<symbol overflow="visible" id="glyph0-30"> +<path style="stroke:none;" d="M 2.265625 -7.5 L 2.265625 -2.625 C 2.265625 -2.019531 2.40625 -1.566406 2.6875 -1.265625 C 2.96875 -0.960938 3.40625 -0.8125 4 -0.8125 C 4.78125 -0.8125 5.347656 -1.023438 5.703125 -1.453125 C 6.066406 -1.878906 6.25 -2.582031 6.25 -3.5625 L 6.25 -7.5 L 7.390625 -7.5 L 7.390625 0 L 6.453125 0 L 6.296875 -1 L 6.234375 -1 C 5.992188 -0.632812 5.664062 -0.351562 5.25 -0.15625 C 4.84375 0.0390625 4.375 0.140625 3.84375 0.140625 C 2.9375 0.140625 2.253906 -0.070 [...] +</symbol> +<symbol overflow="visible" id="glyph0-31"> +<path style="stroke:none;" d="M 4.6875 0.140625 C 4.195312 0.140625 3.75 0.0507812 3.34375 -0.125 C 2.945312 -0.3125 2.613281 -0.59375 2.34375 -0.96875 L 2.25 -0.96875 C 2.3125 -0.53125 2.34375 -0.113281 2.34375 0.28125 L 2.34375 3.359375 L 1.203125 3.359375 L 1.203125 -7.5 L 2.125 -7.5 L 2.28125 -6.46875 L 2.34375 -6.46875 C 2.632812 -6.875 2.972656 -7.164062 3.359375 -7.34375 C 3.742188 -7.53125 4.1875 -7.625 4.6875 -7.625 C 5.6875 -7.625 6.453125 -7.285156 6.984375 -6.609375 C 7.52343 [...] +</symbol> +<symbol overflow="visible" id="glyph0-32"> +<path style="stroke:none;" d="M 3.8125 -6.109375 C 4.863281 -6.109375 5.691406 -5.847656 6.296875 -5.328125 C 6.898438 -4.804688 7.203125 -4.085938 7.203125 -3.171875 C 7.203125 -2.140625 6.867188 -1.328125 6.203125 -0.734375 C 5.546875 -0.148438 4.640625 0.140625 3.484375 0.140625 C 2.359375 0.140625 1.5 -0.0390625 0.90625 -0.40625 L 0.90625 -1.5 C 1.226562 -1.289062 1.625 -1.128906 2.09375 -1.015625 C 2.570312 -0.898438 3.039062 -0.84375 3.5 -0.84375 C 4.300781 -0.84375 4.921875 -1.031 [...] +</symbol> +<symbol overflow="visible" id="glyph0-33"> +<path style="stroke:none;" d="M 7.3125 -5.015625 C 7.3125 -3.285156 7.035156 -1.992188 6.484375 -1.140625 C 5.941406 -0.285156 5.113281 0.140625 4 0.140625 C 2.914062 0.140625 2.09375 -0.296875 1.53125 -1.171875 C 0.976562 -2.046875 0.703125 -3.328125 0.703125 -5.015625 C 0.703125 -6.753906 0.972656 -8.046875 1.515625 -8.890625 C 2.054688 -9.734375 2.882812 -10.15625 4 -10.15625 C 5.082031 -10.15625 5.90625 -9.710938 6.46875 -8.828125 C 7.03125 -7.953125 7.3125 -6.679688 7.3125 -5.015625 [...] +</symbol> +<symbol overflow="visible" id="glyph0-34"> +<path style="stroke:none;" d="M 7.25 0 L 0.6875 0 L 0.6875 -0.984375 L 3.3125 -3.625 C 4.113281 -4.4375 4.640625 -5.015625 4.890625 -5.359375 C 5.148438 -5.703125 5.34375 -6.035156 5.46875 -6.359375 C 5.601562 -6.691406 5.671875 -7.050781 5.671875 -7.4375 C 5.671875 -7.96875 5.507812 -8.390625 5.1875 -8.703125 C 4.863281 -9.015625 4.410156 -9.171875 3.828125 -9.171875 C 3.421875 -9.171875 3.03125 -9.097656 2.65625 -8.953125 C 2.28125 -8.816406 1.867188 -8.570312 1.421875 -8.21875 L 0.812 [...] +</symbol> +<symbol overflow="visible" id="glyph1-0"> +<path style="stroke:none;" d="M 18.03125 -18.84375 L 18.03125 -15.921875 C 17.101562 -16.796875 16.113281 -17.445312 15.0625 -17.875 C 14.007812 -18.300781 12.890625 -18.515625 11.703125 -18.515625 C 9.367188 -18.515625 7.582031 -17.800781 6.34375 -16.375 C 5.101562 -14.945312 4.484375 -12.882812 4.484375 -10.1875 C 4.484375 -7.5 5.101562 -5.441406 6.34375 -4.015625 C 7.582031 -2.585938 9.367188 -1.875 11.703125 -1.875 C 12.890625 -1.875 14.007812 -2.085938 15.0625 -2.515625 C 16.113281 [...] +</symbol> +<symbol overflow="visible" id="glyph1-1"> +<path style="stroke:none;" d="M 9.59375 -7.703125 C 7.5625 -7.703125 6.15625 -7.46875 5.375 -7 C 4.59375 -6.53125 4.203125 -5.738281 4.203125 -4.625 C 4.203125 -3.726562 4.492188 -3.015625 5.078125 -2.484375 C 5.671875 -1.960938 6.472656 -1.703125 7.484375 -1.703125 C 8.878906 -1.703125 9.992188 -2.195312 10.828125 -3.1875 C 11.671875 -4.175781 12.09375 -5.492188 12.09375 -7.140625 L 12.09375 -7.703125 Z M 14.609375 -8.734375 L 14.609375 0 L 12.09375 0 L 12.09375 -2.328125 C 11.519531 -1 [...] +</symbol> +<symbol overflow="visible" id="glyph1-2"> +<path style="stroke:none;" d="M 5.125 -19.65625 L 5.125 -15.3125 L 10.3125 -15.3125 L 10.3125 -13.359375 L 5.125 -13.359375 L 5.125 -5.046875 C 5.125 -3.796875 5.296875 -2.992188 5.640625 -2.640625 C 5.984375 -2.285156 6.675781 -2.109375 7.71875 -2.109375 L 10.3125 -2.109375 L 10.3125 0 L 7.71875 0 C 5.78125 0 4.441406 -0.359375 3.703125 -1.078125 C 2.960938 -1.804688 2.59375 -3.128906 2.59375 -5.046875 L 2.59375 -13.359375 L 0.75 -13.359375 L 0.75 -15.3125 L 2.59375 -15.3125 L 2.59375 - [...] +</symbol> +<symbol overflow="visible" id="glyph1-3"> +<path style="stroke:none;" d="M 2.640625 -21.28125 L 5.15625 -21.28125 L 5.15625 0 L 2.640625 0 Z M 2.640625 -21.28125 "/> +</symbol> +<symbol overflow="visible" id="glyph1-4"> +<path style="stroke:none;" d="M 8.578125 -13.546875 C 7.222656 -13.546875 6.15625 -13.019531 5.375 -11.96875 C 4.59375 -10.914062 4.203125 -9.472656 4.203125 -7.640625 C 4.203125 -5.804688 4.585938 -4.363281 5.359375 -3.3125 C 6.140625 -2.257812 7.210938 -1.734375 8.578125 -1.734375 C 9.910156 -1.734375 10.96875 -2.257812 11.75 -3.3125 C 12.539062 -4.375 12.9375 -5.816406 12.9375 -7.640625 C 12.9375 -9.453125 12.539062 -10.890625 11.75 -11.953125 C 10.96875 -13.015625 9.910156 -13.546875 [...] +</symbol> +<symbol overflow="visible" id="glyph1-5"> +<path style="stroke:none;" d="M 12.71875 -7.828125 C 12.71875 -9.648438 12.335938 -11.0625 11.578125 -12.0625 C 10.828125 -13.070312 9.773438 -13.578125 8.421875 -13.578125 C 7.078125 -13.578125 6.023438 -13.070312 5.265625 -12.0625 C 4.515625 -11.0625 4.140625 -9.648438 4.140625 -7.828125 C 4.140625 -6.015625 4.515625 -4.609375 5.265625 -3.609375 C 6.023438 -2.609375 7.078125 -2.109375 8.421875 -2.109375 C 9.773438 -2.109375 10.828125 -2.609375 11.578125 -3.609375 C 12.335938 -4.609375 [...] +</symbol> +<symbol overflow="visible" id="glyph1-6"> +<path style="stroke:none;" d="M -0.078125 -20.40625 L 17.1875 -20.40625 L 17.1875 -18.09375 L 9.9375 -18.09375 L 9.9375 0 L 7.171875 0 L 7.171875 -18.09375 L -0.078125 -18.09375 Z M -0.078125 -20.40625 "/> +</symbol> +<symbol overflow="visible" id="glyph1-7"> +<path style="stroke:none;" d="M 13.625 -7.640625 C 13.625 -9.492188 13.242188 -10.945312 12.484375 -12 C 11.722656 -13.050781 10.679688 -13.578125 9.359375 -13.578125 C 8.023438 -13.578125 6.976562 -13.050781 6.21875 -12 C 5.457031 -10.945312 5.078125 -9.492188 5.078125 -7.640625 C 5.078125 -5.796875 5.457031 -4.34375 6.21875 -3.28125 C 6.976562 -2.226562 8.023438 -1.703125 9.359375 -1.703125 C 10.679688 -1.703125 11.722656 -2.226562 12.484375 -3.28125 C 13.242188 -4.34375 13.625 -5.7968 [...] +</symbol> +<symbol overflow="visible" id="glyph1-8"> +<path style="stroke:none;" d="M 15.734375 -8.28125 L 15.734375 -7.0625 L 4.171875 -7.0625 C 4.273438 -5.320312 4.796875 -4 5.734375 -3.09375 C 6.671875 -2.1875 7.972656 -1.734375 9.640625 -1.734375 C 10.609375 -1.734375 11.546875 -1.851562 12.453125 -2.09375 C 13.359375 -2.332031 14.257812 -2.6875 15.15625 -3.15625 L 15.15625 -0.78125 C 14.25 -0.394531 13.320312 -0.101562 12.375 0.09375 C 11.425781 0.289062 10.460938 0.390625 9.484375 0.390625 C 7.046875 0.390625 5.113281 -0.316406 3.687 [...] +</symbol> +<symbol overflow="visible" id="glyph1-9"> +<path style="stroke:none;" d="M 5.515625 -18.140625 L 5.515625 -2.265625 L 8.84375 -2.265625 C 11.664062 -2.265625 13.726562 -2.898438 15.03125 -4.171875 C 16.34375 -5.453125 17 -7.472656 17 -10.234375 C 17 -12.960938 16.34375 -14.960938 15.03125 -16.234375 C 13.726562 -17.503906 11.664062 -18.140625 8.84375 -18.140625 Z M 2.75 -20.40625 L 8.421875 -20.40625 C 12.378906 -20.40625 15.28125 -19.582031 17.125 -17.9375 C 18.976562 -16.300781 19.90625 -13.734375 19.90625 -10.234375 C 19.90625 [...] +</symbol> +<symbol overflow="visible" id="glyph1-10"> +<path style="stroke:none;" d="M 9.015625 1.421875 C 8.296875 3.242188 7.597656 4.429688 6.921875 4.984375 C 6.253906 5.546875 5.351562 5.828125 4.21875 5.828125 L 2.21875 5.828125 L 2.21875 3.71875 L 3.6875 3.71875 C 4.382812 3.71875 4.921875 3.550781 5.296875 3.21875 C 5.679688 2.894531 6.109375 2.125 6.578125 0.90625 L 7.03125 -0.25 L 0.828125 -15.3125 L 3.5 -15.3125 L 8.28125 -3.34375 L 13.078125 -15.3125 L 15.734375 -15.3125 Z M 9.015625 1.421875 "/> +</symbol> +<symbol overflow="visible" id="glyph1-11"> +<path style="stroke:none;" d="M 15.375 -9.25 L 15.375 0 L 12.859375 0 L 12.859375 -9.15625 C 12.859375 -10.601562 12.570312 -11.6875 12 -12.40625 C 11.4375 -13.132812 10.59375 -13.5 9.46875 -13.5 C 8.101562 -13.5 7.03125 -13.0625 6.25 -12.1875 C 5.46875 -11.320312 5.078125 -10.144531 5.078125 -8.65625 L 5.078125 0 L 2.546875 0 L 2.546875 -15.3125 L 5.078125 -15.3125 L 5.078125 -12.9375 C 5.671875 -13.851562 6.375 -14.539062 7.1875 -15 C 8.007812 -15.457031 8.953125 -15.6875 10.015625 -15 [...] +</symbol> +<symbol overflow="visible" id="glyph1-12"> +<path style="stroke:none;" d="M 14.5625 -12.375 C 15.1875 -13.5 15.9375 -14.332031 16.8125 -14.875 C 17.6875 -15.414062 18.71875 -15.6875 19.90625 -15.6875 C 21.5 -15.6875 22.726562 -15.125 23.59375 -14 C 24.457031 -12.882812 24.890625 -11.300781 24.890625 -9.25 L 24.890625 0 L 22.375 0 L 22.375 -9.15625 C 22.375 -10.625 22.113281 -11.710938 21.59375 -12.421875 C 21.070312 -13.140625 20.273438 -13.5 19.203125 -13.5 C 17.898438 -13.5 16.867188 -13.0625 16.109375 -12.1875 C 15.359375 -11.3 [...] +</symbol> +<symbol overflow="visible" id="glyph1-13"> +<path style="stroke:none;" d="M 2.640625 -15.3125 L 5.15625 -15.3125 L 5.15625 0 L 2.640625 0 Z M 2.640625 -21.28125 L 5.15625 -21.28125 L 5.15625 -18.09375 L 2.640625 -18.09375 Z M 2.640625 -21.28125 "/> +</symbol> +<symbol overflow="visible" id="glyph1-14"> +<path style="stroke:none;" d="M 13.65625 -14.71875 L 13.65625 -12.375 C 12.945312 -12.769531 12.234375 -13.0625 11.515625 -13.25 C 10.804688 -13.445312 10.085938 -13.546875 9.359375 -13.546875 C 7.722656 -13.546875 6.453125 -13.03125 5.546875 -12 C 4.648438 -10.96875 4.203125 -9.515625 4.203125 -7.640625 C 4.203125 -5.773438 4.648438 -4.320312 5.546875 -3.28125 C 6.453125 -2.25 7.722656 -1.734375 9.359375 -1.734375 C 10.085938 -1.734375 10.804688 -1.832031 11.515625 -2.03125 C 12.234375 [...] +</symbol> +<symbol overflow="visible" id="glyph1-15"> +<path style="stroke:none;" d="M 14.984375 -19.75 L 14.984375 -17.046875 C 13.929688 -17.546875 12.941406 -17.921875 12.015625 -18.171875 C 11.085938 -18.421875 10.191406 -18.546875 9.328125 -18.546875 C 7.816406 -18.546875 6.65625 -18.253906 5.84375 -17.671875 C 5.03125 -17.085938 4.625 -16.253906 4.625 -15.171875 C 4.625 -14.273438 4.894531 -13.59375 5.4375 -13.125 C 5.976562 -12.664062 7.003906 -12.296875 8.515625 -12.015625 L 10.1875 -11.671875 C 12.25 -11.285156 13.769531 -10.597656 [...] +</symbol> +<symbol overflow="visible" id="glyph1-16"> +<path style="stroke:none;" d="M 2.375 -6.046875 L 2.375 -15.3125 L 4.890625 -15.3125 L 4.890625 -6.140625 C 4.890625 -4.691406 5.171875 -3.601562 5.734375 -2.875 C 6.304688 -2.15625 7.15625 -1.796875 8.28125 -1.796875 C 9.644531 -1.796875 10.71875 -2.226562 11.5 -3.09375 C 12.289062 -3.957031 12.6875 -5.132812 12.6875 -6.625 L 12.6875 -15.3125 L 15.203125 -15.3125 L 15.203125 0 L 12.6875 0 L 12.6875 -2.359375 C 12.070312 -1.421875 11.363281 -0.726562 10.5625 -0.28125 C 9.757812 0.164062 [...] +</symbol> +<symbol overflow="visible" id="glyph1-17"> +<path style="stroke:none;" d="M 11.515625 -12.96875 C 11.234375 -13.125 10.925781 -13.238281 10.59375 -13.3125 C 10.257812 -13.394531 9.890625 -13.4375 9.484375 -13.4375 C 8.066406 -13.4375 6.976562 -12.972656 6.21875 -12.046875 C 5.457031 -11.128906 5.078125 -9.800781 5.078125 -8.0625 L 5.078125 0 L 2.546875 0 L 2.546875 -15.3125 L 5.078125 -15.3125 L 5.078125 -12.9375 C 5.597656 -13.863281 6.28125 -14.550781 7.125 -15 C 7.976562 -15.457031 9.015625 -15.6875 10.234375 -15.6875 C 10.3984 [...] +</symbol> +<symbol overflow="visible" id="glyph1-18"> +<path style="stroke:none;" d="M 2.75 -20.40625 L 14.484375 -20.40625 L 14.484375 -18.09375 L 5.515625 -18.09375 L 5.515625 -12.078125 L 13.609375 -12.078125 L 13.609375 -9.75 L 5.515625 -9.75 L 5.515625 0 L 2.75 0 Z M 2.75 -20.40625 "/> +</symbol> +<symbol overflow="visible" id="glyph1-19"> +<path style="stroke:none;" d="M 2.546875 -21.28125 L 5.078125 -21.28125 L 5.078125 -8.703125 L 12.578125 -15.3125 L 15.796875 -15.3125 L 7.671875 -8.15625 L 16.140625 0 L 12.859375 0 L 5.078125 -7.484375 L 5.078125 0 L 2.546875 0 Z M 2.546875 -21.28125 "/> +</symbol> +<symbol overflow="visible" id="glyph1-20"> +<path style="stroke:none;" d="M 5.515625 -18.140625 L 5.515625 -10.46875 L 8.984375 -10.46875 C 10.265625 -10.46875 11.253906 -10.800781 11.953125 -11.46875 C 12.660156 -12.132812 13.015625 -13.082031 13.015625 -14.3125 C 13.015625 -15.53125 12.660156 -16.472656 11.953125 -17.140625 C 11.253906 -17.804688 10.265625 -18.140625 8.984375 -18.140625 Z M 2.75 -20.40625 L 8.984375 -20.40625 C 11.273438 -20.40625 13.003906 -19.890625 14.171875 -18.859375 C 15.335938 -17.828125 15.921875 -16.312 [...] +</symbol> +<symbol overflow="visible" id="glyph1-21"> +<path style="stroke:none;" d="M 12.421875 -9.578125 C 13.015625 -9.367188 13.59375 -8.9375 14.15625 -8.28125 C 14.71875 -7.625 15.28125 -6.722656 15.84375 -5.578125 L 18.65625 0 L 15.6875 0 L 13.078125 -5.234375 C 12.398438 -6.597656 11.742188 -7.503906 11.109375 -7.953125 C 10.472656 -8.398438 9.609375 -8.625 8.515625 -8.625 L 5.515625 -8.625 L 5.515625 0 L 2.75 0 L 2.75 -20.40625 L 8.984375 -20.40625 C 11.316406 -20.40625 13.054688 -19.914062 14.203125 -18.9375 C 15.347656 -17.96875 15 [...] +</symbol> +<symbol overflow="visible" id="glyph1-22"> +<path style="stroke:none;" d="M 2.75 -20.40625 L 6.859375 -20.40625 L 12.078125 -6.515625 L 17.3125 -20.40625 L 21.421875 -20.40625 L 21.421875 0 L 18.734375 0 L 18.734375 -17.921875 L 13.46875 -3.921875 L 10.6875 -3.921875 L 5.421875 -17.921875 L 5.421875 0 L 2.75 0 Z M 2.75 -20.40625 "/> +</symbol> +<symbol overflow="visible" id="glyph1-23"> +<path style="stroke:none;" d="M 12.71875 -12.984375 L 12.71875 -21.28125 L 15.234375 -21.28125 L 15.234375 0 L 12.71875 0 L 12.71875 -2.296875 C 12.1875 -1.390625 11.515625 -0.710938 10.703125 -0.265625 C 9.898438 0.171875 8.9375 0.390625 7.8125 0.390625 C 5.957031 0.390625 4.445312 -0.34375 3.28125 -1.8125 C 2.125 -3.289062 1.546875 -5.234375 1.546875 -7.640625 C 1.546875 -10.046875 2.125 -11.988281 3.28125 -13.46875 C 4.445312 -14.945312 5.957031 -15.6875 7.8125 -15.6875 C 8.9375 -15.6 [...] +</symbol> +<symbol overflow="visible" id="glyph2-0"> +<path style="stroke:none;" d="M 12.3125 -16.21875 L 12.3125 -14 C 11.445312 -14.414062 10.628906 -14.722656 9.859375 -14.921875 C 9.097656 -15.128906 8.363281 -15.234375 7.65625 -15.234375 C 6.425781 -15.234375 5.472656 -14.992188 4.796875 -14.515625 C 4.128906 -14.035156 3.796875 -13.351562 3.796875 -12.46875 C 3.796875 -11.726562 4.015625 -11.164062 4.453125 -10.78125 C 4.898438 -10.40625 5.75 -10.101562 7 -9.875 L 8.359375 -9.59375 C 10.054688 -9.269531 11.304688 -8.703125 12.109375 - [...] +</symbol> +<symbol overflow="visible" id="glyph2-1"> +<path style="stroke:none;" d="M 11.21875 -12.09375 L 11.21875 -10.15625 C 10.632812 -10.476562 10.046875 -10.71875 9.453125 -10.875 C 8.867188 -11.039062 8.28125 -11.125 7.6875 -11.125 C 6.34375 -11.125 5.300781 -10.695312 4.5625 -9.84375 C 3.820312 -9 3.453125 -7.8125 3.453125 -6.28125 C 3.453125 -4.738281 3.820312 -3.539062 4.5625 -2.6875 C 5.300781 -1.84375 6.34375 -1.421875 7.6875 -1.421875 C 8.28125 -1.421875 8.867188 -1.5 9.453125 -1.65625 C 10.046875 -1.820312 10.632812 -2.066406 [...] +</symbol> +<symbol overflow="visible" id="glyph2-2"> +<path style="stroke:none;" d="M 7.890625 -6.328125 C 6.210938 -6.328125 5.050781 -6.132812 4.40625 -5.75 C 3.769531 -5.363281 3.453125 -4.710938 3.453125 -3.796875 C 3.453125 -3.066406 3.691406 -2.484375 4.171875 -2.046875 C 4.648438 -1.617188 5.304688 -1.40625 6.140625 -1.40625 C 7.285156 -1.40625 8.203125 -1.8125 8.890625 -2.625 C 9.585938 -3.4375 9.9375 -4.515625 9.9375 -5.859375 L 9.9375 -6.328125 Z M 12 -7.171875 L 12 0 L 9.9375 0 L 9.9375 -1.90625 C 9.46875 -1.144531 8.878906 -0.58 [...] +</symbol> +<symbol overflow="visible" id="glyph2-3"> +<path style="stroke:none;" d="M 12.625 -7.59375 L 12.625 0 L 10.5625 0 L 10.5625 -7.53125 C 10.5625 -8.71875 10.328125 -9.601562 9.859375 -10.1875 C 9.398438 -10.78125 8.703125 -11.078125 7.765625 -11.078125 C 6.648438 -11.078125 5.769531 -10.722656 5.125 -10.015625 C 4.488281 -9.304688 4.171875 -8.335938 4.171875 -7.109375 L 4.171875 0 L 2.09375 0 L 2.09375 -12.578125 L 4.171875 -12.578125 L 4.171875 -10.625 C 4.660156 -11.382812 5.238281 -11.945312 5.90625 -12.3125 C 6.582031 -12.6875 [...] +</symbol> +<symbol overflow="visible" id="glyph2-4"> +<path style="stroke:none;" d="M -0.0625 -16.765625 L 14.109375 -16.765625 L 14.109375 -14.859375 L 8.171875 -14.859375 L 8.171875 0 L 5.890625 0 L 5.890625 -14.859375 L -0.0625 -14.859375 Z M -0.0625 -16.765625 "/> +</symbol> +<symbol overflow="visible" id="glyph2-5"> +<path style="stroke:none;" d="M 11.203125 -6.28125 C 11.203125 -7.800781 10.890625 -8.992188 10.265625 -9.859375 C 9.640625 -10.722656 8.78125 -11.15625 7.6875 -11.15625 C 6.59375 -11.15625 5.734375 -10.722656 5.109375 -9.859375 C 4.484375 -8.992188 4.171875 -7.800781 4.171875 -6.28125 C 4.171875 -4.757812 4.484375 -3.566406 5.109375 -2.703125 C 5.734375 -1.835938 6.59375 -1.40625 7.6875 -1.40625 C 8.78125 -1.40625 9.640625 -1.835938 10.265625 -2.703125 C 10.890625 -3.566406 11.203125 -4 [...] +</symbol> +<symbol overflow="visible" id="glyph2-6"> +<path style="stroke:none;" d="M 2.171875 -17.46875 L 4.234375 -17.46875 L 4.234375 0 L 2.171875 0 Z M 2.171875 -17.46875 "/> +</symbol> +<symbol overflow="visible" id="glyph2-7"> +<path style="stroke:none;" d="M 12.921875 -6.8125 L 12.921875 -5.796875 L 3.421875 -5.796875 C 3.515625 -4.367188 3.941406 -3.28125 4.703125 -2.53125 C 5.472656 -1.789062 6.546875 -1.421875 7.921875 -1.421875 C 8.710938 -1.421875 9.476562 -1.519531 10.21875 -1.71875 C 10.96875 -1.914062 11.707031 -2.207031 12.4375 -2.59375 L 12.4375 -0.640625 C 11.695312 -0.328125 10.9375 -0.0859375 10.15625 0.078125 C 9.382812 0.242188 8.597656 0.328125 7.796875 0.328125 C 5.785156 0.328125 4.191406 -0. [...] +</symbol> +<symbol overflow="visible" id="glyph2-8"> +<path style="stroke:none;" d="M 7.046875 -11.125 C 5.929688 -11.125 5.050781 -10.691406 4.40625 -9.828125 C 3.769531 -8.960938 3.453125 -7.78125 3.453125 -6.28125 C 3.453125 -4.769531 3.769531 -3.582031 4.40625 -2.71875 C 5.050781 -1.851562 5.929688 -1.421875 7.046875 -1.421875 C 8.140625 -1.421875 9.007812 -1.851562 9.65625 -2.71875 C 10.300781 -3.59375 10.625 -4.78125 10.625 -6.28125 C 10.625 -7.769531 10.300781 -8.945312 9.65625 -9.8125 C 9.007812 -10.6875 8.140625 -11.125 7.046875 -1 [...] +</symbol> +<symbol overflow="visible" id="glyph2-9"> +<path style="stroke:none;" d="M 1.953125 -4.96875 L 1.953125 -12.578125 L 4.015625 -12.578125 L 4.015625 -5.046875 C 4.015625 -3.847656 4.242188 -2.953125 4.703125 -2.359375 C 5.171875 -1.765625 5.875 -1.46875 6.8125 -1.46875 C 7.925781 -1.46875 8.804688 -1.820312 9.453125 -2.53125 C 10.097656 -3.25 10.421875 -4.222656 10.421875 -5.453125 L 10.421875 -12.578125 L 12.484375 -12.578125 L 12.484375 0 L 10.421875 0 L 10.421875 -1.9375 C 9.921875 -1.164062 9.335938 -0.59375 8.671875 -0.21875 [...] +</symbol> +<symbol overflow="visible" id="glyph2-10"> +<path style="stroke:none;" d="M 9.453125 -10.640625 C 9.222656 -10.773438 8.96875 -10.875 8.6875 -10.9375 C 8.414062 -11.007812 8.117188 -11.046875 7.796875 -11.046875 C 6.628906 -11.046875 5.734375 -10.664062 5.109375 -9.90625 C 4.484375 -9.144531 4.171875 -8.050781 4.171875 -6.625 L 4.171875 0 L 2.09375 0 L 2.09375 -12.578125 L 4.171875 -12.578125 L 4.171875 -10.625 C 4.597656 -11.382812 5.160156 -11.945312 5.859375 -12.3125 C 6.554688 -12.6875 7.40625 -12.875 8.40625 -12.875 C 8.53906 [...] +</symbol> +<symbol overflow="visible" id="glyph2-11"> +<path style="stroke:none;" d="M 2.25 -16.765625 L 4.53125 -16.765625 L 4.53125 -1.90625 L 12.6875 -1.90625 L 12.6875 0 L 2.25 0 Z M 2.25 -16.765625 "/> +</symbol> +<symbol overflow="visible" id="glyph2-12"> +<path style="stroke:none;" d="M 2.09375 -17.46875 L 4.171875 -17.46875 L 4.171875 -7.15625 L 10.328125 -12.578125 L 12.96875 -12.578125 L 6.296875 -6.6875 L 13.25 0 L 10.5625 0 L 4.171875 -6.140625 L 4.171875 0 L 2.09375 0 Z M 2.09375 -17.46875 "/> +</symbol> +<symbol overflow="visible" id="glyph2-13"> +<path style="stroke:none;" d="M 4.171875 -1.890625 L 4.171875 4.78125 L 2.09375 4.78125 L 2.09375 -12.578125 L 4.171875 -12.578125 L 4.171875 -10.671875 C 4.597656 -11.421875 5.144531 -11.972656 5.8125 -12.328125 C 6.476562 -12.691406 7.269531 -12.875 8.1875 -12.875 C 9.71875 -12.875 10.957031 -12.269531 11.90625 -11.0625 C 12.863281 -9.851562 13.34375 -8.257812 13.34375 -6.28125 C 13.34375 -4.300781 12.863281 -2.703125 11.90625 -1.484375 C 10.957031 -0.273438 9.71875 0.328125 8.1875 0.3 [...] +</symbol> +<symbol overflow="visible" id="glyph2-14"> +<path style="stroke:none;" d="M 10.203125 -7.859375 C 10.691406 -7.691406 11.164062 -7.335938 11.625 -6.796875 C 12.082031 -6.265625 12.546875 -5.523438 13.015625 -4.578125 L 15.3125 0 L 12.875 0 L 10.734375 -4.296875 C 10.179688 -5.421875 9.644531 -6.164062 9.125 -6.53125 C 8.601562 -6.90625 7.894531 -7.09375 7 -7.09375 L 4.53125 -7.09375 L 4.53125 0 L 2.25 0 L 2.25 -16.765625 L 7.375 -16.765625 C 9.289062 -16.765625 10.71875 -16.363281 11.65625 -15.5625 C 12.601562 -14.757812 13.078125 [...] +</symbol> +<symbol overflow="visible" id="glyph2-15"> +<path style="stroke:none;" d="M 4.21875 -16.15625 L 4.21875 -12.578125 L 8.46875 -12.578125 L 8.46875 -10.96875 L 4.21875 -10.96875 L 4.21875 -4.140625 C 4.21875 -3.117188 4.351562 -2.460938 4.625 -2.171875 C 4.90625 -1.878906 5.476562 -1.734375 6.34375 -1.734375 L 8.46875 -1.734375 L 8.46875 0 L 6.34375 0 C 4.75 0 3.648438 -0.296875 3.046875 -0.890625 C 2.441406 -1.484375 2.140625 -2.566406 2.140625 -4.140625 L 2.140625 -10.96875 L 0.625 -10.96875 L 0.625 -12.578125 L 2.140625 -12.57812 [...] +</symbol> +<symbol overflow="visible" id="glyph2-16"> +<path style="stroke:none;" d="M 2.171875 -12.578125 L 4.234375 -12.578125 L 4.234375 0 L 2.171875 0 Z M 2.171875 -17.46875 L 4.234375 -17.46875 L 4.234375 -14.859375 L 2.171875 -14.859375 Z M 2.171875 -17.46875 "/> +</symbol> +<symbol overflow="visible" id="glyph2-17"> +<path style="stroke:none;" d="M 11.953125 -10.15625 C 12.472656 -11.09375 13.09375 -11.78125 13.8125 -12.21875 C 14.53125 -12.65625 15.378906 -12.875 16.359375 -12.875 C 17.660156 -12.875 18.664062 -12.414062 19.375 -11.5 C 20.09375 -10.582031 20.453125 -9.28125 20.453125 -7.59375 L 20.453125 0 L 18.375 0 L 18.375 -7.53125 C 18.375 -8.726562 18.160156 -9.617188 17.734375 -10.203125 C 17.304688 -10.785156 16.65625 -11.078125 15.78125 -11.078125 C 14.707031 -11.078125 13.859375 -10.722656 [...] +</symbol> +<symbol overflow="visible" id="glyph2-18"> +<path style="stroke:none;" d="M 4.53125 -14.90625 L 4.53125 -8.609375 L 7.375 -8.609375 C 8.4375 -8.609375 9.253906 -8.878906 9.828125 -9.421875 C 10.398438 -9.972656 10.6875 -10.753906 10.6875 -11.765625 C 10.6875 -12.765625 10.398438 -13.535156 9.828125 -14.078125 C 9.253906 -14.628906 8.4375 -14.90625 7.375 -14.90625 Z M 2.25 -16.765625 L 7.375 -16.765625 C 9.257812 -16.765625 10.679688 -16.335938 11.640625 -15.484375 C 12.597656 -14.640625 13.078125 -13.398438 13.078125 -11.765625 C [...] +</symbol> +<symbol overflow="visible" id="glyph2-19"> +<path style="stroke:none;" d="M 0.6875 -12.578125 L 2.875 -12.578125 L 6.8125 -2.015625 L 10.734375 -12.578125 L 12.921875 -12.578125 L 8.203125 0 L 5.40625 0 Z M 0.6875 -12.578125 "/> +</symbol> +<symbol overflow="visible" id="glyph2-20"> +<path style="stroke:none;" d="M 10.4375 -10.671875 L 10.4375 -17.46875 L 12.515625 -17.46875 L 12.515625 0 L 10.4375 0 L 10.4375 -1.890625 C 10.007812 -1.140625 9.460938 -0.582031 8.796875 -0.21875 C 8.140625 0.144531 7.34375 0.328125 6.40625 0.328125 C 4.894531 0.328125 3.660156 -0.273438 2.703125 -1.484375 C 1.742188 -2.703125 1.265625 -4.300781 1.265625 -6.28125 C 1.265625 -8.257812 1.742188 -9.851562 2.703125 -11.0625 C 3.660156 -12.269531 4.894531 -12.875 6.40625 -12.875 C 7.34375 - [...] +</symbol> +</g> +</defs> +<g id="surface613896"> +<rect x="0" y="0" width="1361" height="822" style="fill:rgb(100%,100%,100%);fill-opacity:1;stroke:none;"/> +<path style="fill-rule:evenodd;fill:rgb(78.039217%,100%,78.039217%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 6 -1 L 66 -1 L 66 11 L 6 11 Z M 6 -1 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(90.196079%,90.196079%,98.039216%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 6 12 L 66 12 L 66 34 L 6 34 Z M 6 12 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(67.843139%,84.705883%,90.196079%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 6 35 L 66 35 L 66 40 L 6 40 Z M 6 35 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(100%,100%,80.000001%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 8 -0.000000000745058 L 23.982422 -0.000000000745058 L 23.982422 9.745312 L 8 9.745312 Z M 8 -0.000000000745058 " transform="matrix(20,0,0,20,40,21)"/> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph0-0" x="219" y="56.550781"/> + <use xlink:href="#glyph0-1" x="227.828125" y="56.550781"/> + <use xlink:href="#glyph0-2" x="236.480469" y="56.550781"/> + <use xlink:href="#glyph0-3" x="244.273438" y="56.550781"/> + <use xlink:href="#glyph0-4" x="253.140625" y="56.550781"/> + <use xlink:href="#glyph0-2" x="260.894531" y="56.550781"/> + <use xlink:href="#glyph0-5" x="268.6875" y="56.550781"/> + <use xlink:href="#glyph0-4" x="272.320312" y="56.550781"/> + <use xlink:href="#glyph0-3" x="280.074219" y="56.550781"/> + <use xlink:href="#glyph0-6" x="288.941406" y="56.550781"/> + <use xlink:href="#glyph0-7" x="298.003906" y="56.550781"/> + <use xlink:href="#glyph0-2" x="305.269531" y="56.550781"/> + <use xlink:href="#glyph0-5" x="313.0625" y="56.550781"/> + <use xlink:href="#glyph0-8" x="316.695312" y="56.550781"/> + <use xlink:href="#glyph0-9" x="326.890625" y="56.550781"/> + <use xlink:href="#glyph0-10" x="333.570312" y="56.550781"/> + <use xlink:href="#glyph0-11" x="341.421875" y="56.550781"/> + <use xlink:href="#glyph0-5" x="347.144531" y="56.550781"/> + <use xlink:href="#glyph0-12" x="350.777344" y="56.550781"/> + <use xlink:href="#glyph0-13" x="354.917969" y="56.550781"/> + <use xlink:href="#glyph0-14" x="363.511719" y="56.550781"/> + <use xlink:href="#glyph0-15" x="371.304688" y="56.550781"/> + <use xlink:href="#glyph0-10" x="384.332031" y="56.550781"/> + <use xlink:href="#glyph0-5" x="392.183594" y="56.550781"/> + <use xlink:href="#glyph0-16" x="395.816406" y="56.550781"/> + <use xlink:href="#glyph0-4" x="403.492188" y="56.550781"/> + <use xlink:href="#glyph0-1" x="411.246094" y="56.550781"/> + <use xlink:href="#glyph0-17" x="419.898438" y="56.550781"/> + <use xlink:href="#glyph0-18" x="423.804688" y="56.550781"/> + <use xlink:href="#glyph0-19" x="434.351563" y="56.550781"/> + <use xlink:href="#glyph0-20" x="444.546875" y="56.550781"/> + <use xlink:href="#glyph0-5" x="447.984375" y="56.550781"/> + <use xlink:href="#glyph0-14" x="451.617188" y="56.550781"/> + <use xlink:href="#glyph0-21" x="459.410156" y="56.550781"/> + <use xlink:href="#glyph0-10" x="467.085938" y="56.550781"/> + <use xlink:href="#glyph0-5" x="474.9375" y="56.550781"/> + <use xlink:href="#glyph0-17" x="478.570313" y="56.550781"/> + <use xlink:href="#glyph0-18" x="482.476563" y="56.550781"/> + <use xlink:href="#glyph0-4" x="493.023438" y="56.550781"/> + <use xlink:href="#glyph0-22" x="500.777344" y="56.550781"/> +</g> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph0-23" x="219" y="90.53125"/> + <use xlink:href="#glyph0-17" x="231.96875" y="90.53125"/> + <use xlink:href="#glyph0-4" x="235.875" y="90.53125"/> + <use xlink:href="#glyph0-24" x="243.628906" y="90.53125"/> + <use xlink:href="#glyph0-5" x="253.960938" y="90.53125"/> + <use xlink:href="#glyph0-12" x="257.59375" y="90.53125"/> +</g> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph0-5" x="219" y="124.507812"/> + <use xlink:href="#glyph0-5" x="222.632813" y="124.507812"/> + <use xlink:href="#glyph0-5" x="226.265625" y="124.507812"/> + <use xlink:href="#glyph0-5" x="229.898438" y="124.507812"/> + <use xlink:href="#glyph0-5" x="233.53125" y="124.507812"/> + <use xlink:href="#glyph0-25" x="237.164063" y="124.507812"/> + <use xlink:href="#glyph0-26" x="240.269531" y="124.507812"/> + <use xlink:href="#glyph0-27" x="246.929688" y="124.507812"/> + <use xlink:href="#glyph0-13" x="255.386719" y="124.507812"/> + <use xlink:href="#glyph0-13" x="263.980469" y="124.507812"/> + <use xlink:href="#glyph0-10" x="272.574219" y="124.507812"/> + <use xlink:href="#glyph0-26" x="280.425781" y="124.507812"/> + <use xlink:href="#glyph0-28" x="287.085938" y="124.507812"/> + <use xlink:href="#glyph0-27" x="292.027344" y="124.507812"/> + <use xlink:href="#glyph0-11" x="300.484375" y="124.507812"/> + <use xlink:href="#glyph0-25" x="306.207031" y="124.507812"/> + <use xlink:href="#glyph0-5" x="309.3125" y="124.507812"/> + <use xlink:href="#glyph0-29" x="312.945312" y="124.507812"/> + <use xlink:href="#glyph0-5" x="320.953125" y="124.507812"/> + <use xlink:href="#glyph0-25" x="324.585938" y="124.507812"/> + <use xlink:href="#glyph0-26" x="327.691406" y="124.507812"/> + <use xlink:href="#glyph0-30" x="334.351562" y="124.507812"/> + <use xlink:href="#glyph0-9" x="342.945312" y="124.507812"/> + <use xlink:href="#glyph0-28" x="349.625" y="124.507812"/> + <use xlink:href="#glyph0-27" x="354.566406" y="124.507812"/> + <use xlink:href="#glyph0-15" x="363.023438" y="124.507812"/> + <use xlink:href="#glyph0-25" x="376.050781" y="124.507812"/> + <use xlink:href="#glyph0-20" x="379.15625" y="124.507812"/> +</g> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph0-5" x="219" y="158.488281"/> + <use xlink:href="#glyph0-5" x="222.632813" y="158.488281"/> + <use xlink:href="#glyph0-5" x="226.265625" y="158.488281"/> + <use xlink:href="#glyph0-5" x="229.898438" y="158.488281"/> + <use xlink:href="#glyph0-5" x="233.53125" y="158.488281"/> + <use xlink:href="#glyph0-25" x="237.164063" y="158.488281"/> + <use xlink:href="#glyph0-31" x="240.269531" y="158.488281"/> + <use xlink:href="#glyph0-27" x="248.84375" y="158.488281"/> + <use xlink:href="#glyph0-11" x="257.300781" y="158.488281"/> + <use xlink:href="#glyph0-28" x="263.023438" y="158.488281"/> + <use xlink:href="#glyph0-25" x="267.964844" y="158.488281"/> + <use xlink:href="#glyph0-5" x="271.070312" y="158.488281"/> + <use xlink:href="#glyph0-29" x="274.703125" y="158.488281"/> + <use xlink:href="#glyph0-5" x="282.710938" y="158.488281"/> + <use xlink:href="#glyph0-25" x="286.34375" y="158.488281"/> + <use xlink:href="#glyph0-32" x="289.449219" y="158.488281"/> + <use xlink:href="#glyph0-33" x="297.457031" y="158.488281"/> + <use xlink:href="#glyph0-34" x="305.464844" y="158.488281"/> + <use xlink:href="#glyph0-34" x="313.472656" y="158.488281"/> + <use xlink:href="#glyph0-25" x="321.480469" y="158.488281"/> +</g> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph0-22" x="219" y="192.46875"/> +</g> +<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 30 1.922656 L 46 1.922656 L 46 7.822656 L 30 7.822656 Z M 30 1.922656 " transform="matrix(20,0,0,20,40,21)"/> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph1-0" x="710.214844" y="127.015625"/> + <use xlink:href="#glyph1-1" x="729.765625" y="127.015625"/> + <use xlink:href="#glyph1-2" x="746.933594" y="127.015625"/> + <use xlink:href="#glyph1-1" x="757.910156" y="127.015625"/> + <use xlink:href="#glyph1-3" x="775.078125" y="127.015625"/> + <use xlink:href="#glyph1-4" x="782.851562" y="127.015625"/> + <use xlink:href="#glyph1-5" x="799.980469" y="127.015625"/> + <use xlink:href="#glyph1-6" x="817.753906" y="127.015625"/> + <use xlink:href="#glyph1-1" x="829.863281" y="127.015625"/> + <use xlink:href="#glyph1-7" x="847.03125" y="127.015625"/> + <use xlink:href="#glyph1-3" x="864.804688" y="127.015625"/> + <use xlink:href="#glyph1-8" x="872.578125" y="127.015625"/> +</g> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 23.982422 4.872656 L 29.463281 4.872656 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 29.838281 4.872656 L 29.338281 5.122656 L 29.463281 4.872656 L 29.338281 4.622656 Z M 29.838281 4.872656 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 13 13 L 33.959961 13 L 33.959961 18.9 L 13 18.9 Z M 13 13 " transform="matrix(20,0,0,20,40,21)"/> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph1-9" x="313.019531" y="348.5625"/> + <use xlink:href="#glyph1-10" x="334.582031" y="348.5625"/> + <use xlink:href="#glyph1-11" x="351.144531" y="348.5625"/> + <use xlink:href="#glyph1-1" x="368.898438" y="348.5625"/> + <use xlink:href="#glyph1-12" x="386.066406" y="348.5625"/> + <use xlink:href="#glyph1-13" x="413.351562" y="348.5625"/> + <use xlink:href="#glyph1-14" x="421.125" y="348.5625"/> + <use xlink:href="#glyph1-6" x="436.515625" y="348.5625"/> + <use xlink:href="#glyph1-1" x="448.625" y="348.5625"/> + <use xlink:href="#glyph1-7" x="465.792969" y="348.5625"/> + <use xlink:href="#glyph1-3" x="483.566406" y="348.5625"/> + <use xlink:href="#glyph1-8" x="491.339844" y="348.5625"/> + <use xlink:href="#glyph1-15" x="508.566406" y="348.5625"/> + <use xlink:href="#glyph1-4" x="526.339844" y="348.5625"/> + <use xlink:href="#glyph1-16" x="543.46875" y="348.5625"/> + <use xlink:href="#glyph1-17" x="561.222656" y="348.5625"/> + <use xlink:href="#glyph1-14" x="571.730469" y="348.5625"/> + <use xlink:href="#glyph1-8" x="587.121094" y="348.5625"/> + <use xlink:href="#glyph1-18" x="604.347656" y="348.5625"/> + <use xlink:href="#glyph1-1" x="617.472656" y="348.5625"/> + <use xlink:href="#glyph1-14" x="634.640625" y="348.5625"/> + <use xlink:href="#glyph1-2" x="650.03125" y="348.5625"/> + <use xlink:href="#glyph1-4" x="661.007812" y="348.5625"/> + <use xlink:href="#glyph1-17" x="678.136719" y="348.5625"/> + <use xlink:href="#glyph1-10" x="689.640625" y="348.5625"/> +</g> +<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 44 13 L 64.959961 13 L 64.959961 18.9 L 44 18.9 Z M 44 13 " transform="matrix(20,0,0,20,40,21)"/> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph1-9" x="951.144531" y="348.5625"/> + <use xlink:href="#glyph1-10" x="972.707031" y="348.5625"/> + <use xlink:href="#glyph1-11" x="989.269531" y="348.5625"/> + <use xlink:href="#glyph1-1" x="1007.023438" y="348.5625"/> + <use xlink:href="#glyph1-12" x="1024.191406" y="348.5625"/> + <use xlink:href="#glyph1-13" x="1051.476562" y="348.5625"/> + <use xlink:href="#glyph1-14" x="1059.25" y="348.5625"/> + <use xlink:href="#glyph1-6" x="1074.640625" y="348.5625"/> + <use xlink:href="#glyph1-1" x="1086.75" y="348.5625"/> + <use xlink:href="#glyph1-7" x="1103.917969" y="348.5625"/> + <use xlink:href="#glyph1-3" x="1121.691406" y="348.5625"/> + <use xlink:href="#glyph1-8" x="1129.464844" y="348.5625"/> + <use xlink:href="#glyph1-15" x="1146.691406" y="348.5625"/> + <use xlink:href="#glyph1-13" x="1164.464844" y="348.5625"/> + <use xlink:href="#glyph1-11" x="1172.238281" y="348.5625"/> + <use xlink:href="#glyph1-19" x="1189.992188" y="348.5625"/> + <use xlink:href="#glyph1-18" x="1206.203125" y="348.5625"/> + <use xlink:href="#glyph1-1" x="1219.328125" y="348.5625"/> + <use xlink:href="#glyph1-14" x="1236.496094" y="348.5625"/> + <use xlink:href="#glyph1-2" x="1251.886719" y="348.5625"/> + <use xlink:href="#glyph1-4" x="1262.863281" y="348.5625"/> + <use xlink:href="#glyph1-17" x="1279.992188" y="348.5625"/> + <use xlink:href="#glyph1-10" x="1291.496094" y="348.5625"/> +</g> +<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 15 22 L 32 22 L 32 27.9 L 15 27.9 Z M 15 22 " transform="matrix(20,0,0,20,40,21)"/> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph1-9" x="364.335938" y="528.5625"/> + <use xlink:href="#glyph1-10" x="385.898438" y="528.5625"/> + <use xlink:href="#glyph1-11" x="402.460938" y="528.5625"/> + <use xlink:href="#glyph1-1" x="420.214844" y="528.5625"/> + <use xlink:href="#glyph1-12" x="437.382812" y="528.5625"/> + <use xlink:href="#glyph1-13" x="464.667969" y="528.5625"/> + <use xlink:href="#glyph1-14" x="472.441406" y="528.5625"/> + <use xlink:href="#glyph1-6" x="487.832031" y="528.5625"/> + <use xlink:href="#glyph1-1" x="499.941406" y="528.5625"/> + <use xlink:href="#glyph1-7" x="517.109375" y="528.5625"/> + <use xlink:href="#glyph1-3" x="534.882812" y="528.5625"/> + <use xlink:href="#glyph1-8" x="542.65625" y="528.5625"/> + <use xlink:href="#glyph1-15" x="559.882812" y="528.5625"/> + <use xlink:href="#glyph1-4" x="577.65625" y="528.5625"/> + <use xlink:href="#glyph1-16" x="594.785156" y="528.5625"/> + <use xlink:href="#glyph1-17" x="612.539062" y="528.5625"/> + <use xlink:href="#glyph1-14" x="623.046875" y="528.5625"/> + <use xlink:href="#glyph1-8" x="638.4375" y="528.5625"/> +</g> +<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 46 22 L 63 22 L 63 27.9 L 46 27.9 Z M 46 22 " transform="matrix(20,0,0,20,40,21)"/> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph1-9" x="1002.480469" y="528.5625"/> + <use xlink:href="#glyph1-10" x="1024.042969" y="528.5625"/> + <use xlink:href="#glyph1-11" x="1040.605469" y="528.5625"/> + <use xlink:href="#glyph1-1" x="1058.359375" y="528.5625"/> + <use xlink:href="#glyph1-12" x="1075.527344" y="528.5625"/> + <use xlink:href="#glyph1-13" x="1102.8125" y="528.5625"/> + <use xlink:href="#glyph1-14" x="1110.585938" y="528.5625"/> + <use xlink:href="#glyph1-6" x="1125.976562" y="528.5625"/> + <use xlink:href="#glyph1-1" x="1138.085938" y="528.5625"/> + <use xlink:href="#glyph1-7" x="1155.253906" y="528.5625"/> + <use xlink:href="#glyph1-3" x="1173.027344" y="528.5625"/> + <use xlink:href="#glyph1-8" x="1180.800781" y="528.5625"/> + <use xlink:href="#glyph1-15" x="1198.027344" y="528.5625"/> + <use xlink:href="#glyph1-13" x="1215.800781" y="528.5625"/> + <use xlink:href="#glyph1-11" x="1223.574219" y="528.5625"/> + <use xlink:href="#glyph1-19" x="1241.328125" y="528.5625"/> +</g> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 42 7.822656 L 54.030273 12.813477 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 54.376758 12.957227 L 53.819141 12.996484 L 54.030273 12.813477 L 54.010742 12.53457 Z M 54.376758 12.957227 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 34 7.822656 L 23.916797 12.784961 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 23.580273 12.950586 L 23.918555 12.505469 L 23.916797 12.784961 L 24.139258 12.954102 Z M 23.580273 12.950586 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 35.666602 24 L 42.333398 24 C 43.253711 24 44 24.462109 44 25.032031 C 44 25.601953 43.253711 26.063867 42.333398 26.063867 L 35.666602 26.063867 C 34.746289 26.063867 34 25.601953 34 25.032031 C 34 24.462109 34.746289 24 35.666602 24 " transform="matrix(20,0,0,20,40,21)"/> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph1-20" x="766.972656" y="530.457031"/> + <use xlink:href="#glyph1-3" x="783.867188" y="530.457031"/> + <use xlink:href="#glyph1-1" x="791.640625" y="530.457031"/> + <use xlink:href="#glyph1-11" x="808.808594" y="530.457031"/> + <use xlink:href="#glyph1-11" x="826.5625" y="530.457031"/> + <use xlink:href="#glyph1-8" x="844.316406" y="530.457031"/> + <use xlink:href="#glyph1-17" x="861.542969" y="530.457031"/> +</g> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.1,0.1;stroke-miterlimit:10;" d="M 33.776367 25.030273 L 32.273438 25.018555 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 33.386328 25.277148 L 33.888281 25.031055 L 33.390234 24.777148 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 32.663477 24.771484 L 32.161719 25.017578 L 32.659766 25.271484 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.1,0.1;stroke-miterlimit:10;" d="M 44.223438 25.022852 L 45.776563 24.95918 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 44.600977 24.757031 L 44.111719 25.027344 L 44.621484 25.256641 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 45.399023 25.224805 L 45.888281 24.954492 L 45.378516 24.725195 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 23.480078 18.9 L 23.496875 21.513281 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 23.499219 21.888281 L 23.246094 21.389844 L 23.496875 21.513281 L 23.746094 21.386523 Z M 23.499219 21.888281 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 54.480078 18.9 L 54.496875 21.513281 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 54.499219 21.888281 L 54.246094 21.389844 L 54.496875 21.513281 L 54.746094 21.386523 Z M 54.499219 21.888281 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 9 30 L 21 30 L 21 33 L 9 33 Z M 9 30 " transform="matrix(20,0,0,20,40,21)"/> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph2-0" x="242.148438" y="657.890625"/> + <use xlink:href="#glyph2-1" x="256.757812" y="657.890625"/> + <use xlink:href="#glyph2-2" x="269.394531" y="657.890625"/> + <use xlink:href="#glyph2-3" x="283.496094" y="657.890625"/> + <use xlink:href="#glyph2-4" x="298.066406" y="657.890625"/> + <use xlink:href="#glyph2-2" x="309.121094" y="657.890625"/> + <use xlink:href="#glyph2-5" x="323.222656" y="657.890625"/> + <use xlink:href="#glyph2-6" x="337.832031" y="657.890625"/> + <use xlink:href="#glyph2-7" x="344.21875" y="657.890625"/> + <use xlink:href="#glyph2-0" x="358.378906" y="657.890625"/> + <use xlink:href="#glyph2-8" x="372.988281" y="657.890625"/> + <use xlink:href="#glyph2-9" x="387.050781" y="657.890625"/> + <use xlink:href="#glyph2-10" x="401.621094" y="657.890625"/> + <use xlink:href="#glyph2-1" x="411.074219" y="657.890625"/> + <use xlink:href="#glyph2-7" x="423.710938" y="657.890625"/> +</g> +<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 26 30 L 37.952539 30 L 37.952539 33 L 26 33 Z M 26 30 " transform="matrix(20,0,0,20,40,21)"/> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph2-11" x="568.410156" y="657.890625"/> + <use xlink:href="#glyph2-8" x="581.222656" y="657.890625"/> + <use xlink:href="#glyph2-8" x="595.285156" y="657.890625"/> + <use xlink:href="#glyph2-12" x="609.347656" y="657.890625"/> + <use xlink:href="#glyph2-9" x="621.671875" y="657.890625"/> + <use xlink:href="#glyph2-13" x="636.242188" y="657.890625"/> + <use xlink:href="#glyph2-4" x="650.851562" y="657.890625"/> + <use xlink:href="#glyph2-2" x="661.90625" y="657.890625"/> + <use xlink:href="#glyph2-5" x="676.007812" y="657.890625"/> + <use xlink:href="#glyph2-6" x="690.617188" y="657.890625"/> + <use xlink:href="#glyph2-7" x="697.003906" y="657.890625"/> + <use xlink:href="#glyph2-0" x="711.164063" y="657.890625"/> + <use xlink:href="#glyph2-8" x="725.773438" y="657.890625"/> + <use xlink:href="#glyph2-9" x="739.835938" y="657.890625"/> + <use xlink:href="#glyph2-10" x="754.40625" y="657.890625"/> + <use xlink:href="#glyph2-1" x="763.859375" y="657.890625"/> + <use xlink:href="#glyph2-7" x="776.496094" y="657.890625"/> +</g> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 15 30 L 18.701563 28.171094 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 18.812305 28.395117 L 19.149805 27.949609 L 18.59082 27.946875 Z M 18.812305 28.395117 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 31.976172 30 L 28.297852 28.172266 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 28.40918 27.948437 L 27.850195 27.949805 L 28.186719 28.396094 Z M 28.40918 27.948437 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 7 36 L 23 36 L 23 39 L 7 39 Z M 7 36 " transform="matrix(20,0,0,20,40,21)"/> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph2-0" x="216.191406" y="777.890625"/> + <use xlink:href="#glyph2-1" x="230.800781" y="777.890625"/> + <use xlink:href="#glyph2-2" x="243.4375" y="777.890625"/> + <use xlink:href="#glyph2-3" x="257.539062" y="777.890625"/> + <use xlink:href="#glyph2-14" x="272.109375" y="777.890625"/> + <use xlink:href="#glyph2-9" x="287.089844" y="777.890625"/> + <use xlink:href="#glyph2-3" x="301.660156" y="777.890625"/> + <use xlink:href="#glyph2-15" x="316.230469" y="777.890625"/> + <use xlink:href="#glyph2-16" x="325.253906" y="777.890625"/> + <use xlink:href="#glyph2-17" x="331.640625" y="777.890625"/> + <use xlink:href="#glyph2-7" x="354.042969" y="777.890625"/> + <use xlink:href="#glyph2-18" x="368.203125" y="777.890625"/> + <use xlink:href="#glyph2-10" x="382.070312" y="777.890625"/> + <use xlink:href="#glyph2-8" x="391.523438" y="777.890625"/> + <use xlink:href="#glyph2-19" x="405.585938" y="777.890625"/> + <use xlink:href="#glyph2-16" x="419.199219" y="777.890625"/> + <use xlink:href="#glyph2-20" x="425.585938" y="777.890625"/> + <use xlink:href="#glyph2-7" x="440.195312" y="777.890625"/> + <use xlink:href="#glyph2-10" x="454.355469" y="777.890625"/> +</g> +<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 24 36 L 40 36 L 40 39 L 24 39 Z M 24 36 " transform="matrix(20,0,0,20,40,21)"/> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph2-11" x="542.929688" y="777.890625"/> + <use xlink:href="#glyph2-8" x="555.742188" y="777.890625"/> + <use xlink:href="#glyph2-8" x="569.804688" y="777.890625"/> + <use xlink:href="#glyph2-12" x="583.867188" y="777.890625"/> + <use xlink:href="#glyph2-9" x="596.191406" y="777.890625"/> + <use xlink:href="#glyph2-13" x="610.761719" y="777.890625"/> + <use xlink:href="#glyph2-14" x="625.371094" y="777.890625"/> + <use xlink:href="#glyph2-9" x="640.351562" y="777.890625"/> + <use xlink:href="#glyph2-3" x="654.921875" y="777.890625"/> + <use xlink:href="#glyph2-15" x="669.492188" y="777.890625"/> + <use xlink:href="#glyph2-16" x="678.515625" y="777.890625"/> + <use xlink:href="#glyph2-17" x="684.902344" y="777.890625"/> + <use xlink:href="#glyph2-7" x="707.304688" y="777.890625"/> + <use xlink:href="#glyph2-18" x="721.464844" y="777.890625"/> + <use xlink:href="#glyph2-10" x="735.332031" y="777.890625"/> + <use xlink:href="#glyph2-8" x="744.785156" y="777.890625"/> + <use xlink:href="#glyph2-19" x="758.847656" y="777.890625"/> + <use xlink:href="#glyph2-16" x="772.460938" y="777.890625"/> + <use xlink:href="#glyph2-20" x="778.847656" y="777.890625"/> + <use xlink:href="#glyph2-7" x="793.457031" y="777.890625"/> + <use xlink:href="#glyph2-10" x="807.617188" y="777.890625"/> +</g> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 15 33 L 15 35.513281 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 15 35.888281 L 14.75 35.388281 L 15 35.513281 L 15.25 35.388281 Z M 15 35.888281 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 31.976172 33 L 31.996094 35.513281 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 31.999023 35.888281 L 31.745117 35.390234 L 31.996094 35.513281 L 32.245117 35.386328 Z M 31.999023 35.888281 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 47 36 L 62 36 L 62 39 L 47 39 Z M 47 36 " transform="matrix(20,0,0,20,40,21)"/> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph2-0" x="1009.707031" y="777.890625"/> + <use xlink:href="#glyph2-16" x="1024.316406" y="777.890625"/> + <use xlink:href="#glyph2-3" x="1030.703125" y="777.890625"/> + <use xlink:href="#glyph2-12" x="1045.273438" y="777.890625"/> + <use xlink:href="#glyph2-14" x="1058.59375" y="777.890625"/> + <use xlink:href="#glyph2-9" x="1073.574219" y="777.890625"/> + <use xlink:href="#glyph2-3" x="1088.144531" y="777.890625"/> + <use xlink:href="#glyph2-15" x="1102.714844" y="777.890625"/> + <use xlink:href="#glyph2-16" x="1111.738281" y="777.890625"/> + <use xlink:href="#glyph2-17" x="1118.125" y="777.890625"/> + <use xlink:href="#glyph2-7" x="1140.527344" y="777.890625"/> + <use xlink:href="#glyph2-18" x="1154.6875" y="777.890625"/> + <use xlink:href="#glyph2-10" x="1168.554688" y="777.890625"/> + <use xlink:href="#glyph2-8" x="1178.007812" y="777.890625"/> + <use xlink:href="#glyph2-19" x="1192.070312" y="777.890625"/> + <use xlink:href="#glyph2-16" x="1205.683594" y="777.890625"/> + <use xlink:href="#glyph2-20" x="1212.070312" y="777.890625"/> + <use xlink:href="#glyph2-7" x="1226.679688" y="777.890625"/> + <use xlink:href="#glyph2-10" x="1240.839844" y="777.890625"/> +</g> +<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 54.5 27.9 L 54.5 35.513281 " transform="matrix(20,0,0,20,40,21)"/> +<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 54.5 35.888281 L 54.25 35.388281 L 54.5 35.513281 L 54.75 35.388281 Z M 54.5 35.888281 " transform="matrix(20,0,0,20,40,21)"/> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph1-21" x="0" y="781"/> + <use xlink:href="#glyph1-16" x="18.457031" y="781"/> + <use xlink:href="#glyph1-11" x="36.210938" y="781"/> + <use xlink:href="#glyph1-2" x="53.964844" y="781"/> + <use xlink:href="#glyph1-13" x="64.941406" y="781"/> + <use xlink:href="#glyph1-12" x="72.714844" y="781"/> + <use xlink:href="#glyph1-8" x="100" y="781"/> +</g> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph1-20" x="0" y="481"/> + <use xlink:href="#glyph1-3" x="16.894531" y="481"/> + <use xlink:href="#glyph1-1" x="24.667969" y="481"/> + <use xlink:href="#glyph1-11" x="41.835938" y="481"/> + <use xlink:href="#glyph1-11" x="59.589844" y="481"/> + <use xlink:href="#glyph1-13" x="77.34375" y="481"/> + <use xlink:href="#glyph1-11" x="85.117188" y="481"/> + <use xlink:href="#glyph1-5" x="102.871094" y="481"/> +</g> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph1-22" x="0" y="121"/> + <use xlink:href="#glyph1-8" x="24.160156" y="121"/> + <use xlink:href="#glyph1-2" x="41.386719" y="121"/> + <use xlink:href="#glyph1-1" x="52.363281" y="121"/> + <use xlink:href="#glyph1-23" x="69.53125" y="121"/> + <use xlink:href="#glyph1-1" x="87.304688" y="121"/> + <use xlink:href="#glyph1-2" x="104.472656" y="121"/> + <use xlink:href="#glyph1-1" x="115.449219" y="121"/> +</g> +<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> + <use xlink:href="#glyph1-0" x="380" y="181"/> + <use xlink:href="#glyph1-1" x="399.550781" y="181"/> + <use xlink:href="#glyph1-2" x="416.71875" y="181"/> + <use xlink:href="#glyph1-1" x="427.695312" y="181"/> + <use xlink:href="#glyph1-3" x="444.863281" y="181"/> + <use xlink:href="#glyph1-4" x="452.636719" y="181"/> + <use xlink:href="#glyph1-5" x="469.765625" y="181"/> +</g> +</g> +</svg>
