summaryrefslogtreecommitdiffstats
path: root/src/plugins/memif/cli.c
blob: e1bd04441e010379dac6bf4e9a155a9165a4a78f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
/*
 *------------------------------------------------------------------
 * Copyright (c) 2016 Cisco and/or its affiliates.
 * Licensed 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.
 *------------------------------------------------------------------
 */
#include <stdint.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <inttypes.h>

#include <vlib/vlib.h>
#include <vlib/unix/unix.h>
#include <vnet/ethernet/ethernet.h>

#include <memif/memif.h>
#include <memif/private.h>

static clib_error_t *
memif_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
			 vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  int r;
  u32 ring_size = MEMIF_DEFAULT_RING_SIZE;
  memif_create_if_args_t args = { 0 };
  args.buffer_size = MEMIF_DEFAULT_BUFFER_SIZE;
  u32 rx_queues = MEMIF_DEFAULT_RX_QUEUES;
  u32 tx_queues = MEMIF_DEFAULT_TX_QUEUES;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "id %u", &args.id))
	;
      else if (unformat (line_input, "socket %s", &args.socket_filename))
	;
      else if (unformat (line_input, "secret %s", &args.secret))
	;
      else if (unformat (line_input, "ring-size %u", &ring_size))
	;
      else if (unformat (line_input, "rx-queues %u", &rx_queues))
	;
      else if (unformat (line_input, "tx-queues %u", &tx_queues))
	;
      else if (unformat (line_input, "buffer-size %u", &args.buffer_size))
	;
      else if (unformat (line_input, "master"))
	args.is_master = 1;
      else if (unformat (line_input, "slave"))
	args.is_master = 0;
      else if (unformat (line_input, "mode ip"))
	args.mode = MEMIF_INTERFACE_MODE_IP;
      else if (unformat (line_input, "hw-addr %U",
			 unformat_ethernet_address, args.hw_addr))
	args.hw_addr_set = 1;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }
  unformat_free (line_input);

  if (!is_pow2 (ring_size))
    return clib_error_return (0, "ring size must be power of 2");

  args.log2_ring_size = min_log2 (ring_size);

  if (rx_queues > 255 || rx_queues < 1)
    return clib_error_return (0, "rx queue must be between 1 - 255");
  if (tx_queues > 255 || tx_queues < 1)
    return clib_error_return (0, "tx queue must be between 1 - 255");

  args.rx_queues = rx_queues;
  args.tx_queues = tx_queues;

  r = memif_create_if (vm, &args);

  vec_free (args.socket_filename);
  vec_free (args.secret);

  if (r <= VNET_API_ERROR_SYSCALL_ERROR_1
      && r >= VNET_API_ERROR_SYSCALL_ERROR_10)
    return clib_error_return (0, "%s (errno %d)", strerror (errno), errno);

  if (r == VNET_API_ERROR_INVALID_INTERFACE)
    return clib_error_return (0, "Invalid interface name");

  if (r == VNET_API_ERROR_SUBIF_ALREADY_EXISTS)
    return clib_error_return (0, "Interface with same id already exists");

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (memif_create_command, static) = {
  .path = "create memif",
  .short_help = "create memif [id <id>] [socket <path>] "
                "[ring-size <size>] [buffer-size <size>] [hw-addr <mac-address>] "
		"<master|slave> [rx-queues <number>] [tx-queues <number>] "
		"[mode ip] [secret <string>]",
  .function = memif_create_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
memif_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
			 vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  u32 sw_if_index = ~0;
  vnet_hw_interface_t *hw;
  memif_main_t *mm = &memif_main;
  memif_if_t *mif;
  vnet_main_t *vnm = vnet_get_main ();

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "sw_if_index %d", &sw_if_index))
	;
      else if (unformat (line_input, "%U", unformat_vnet_sw_interface,
			 vnm, &sw_if_index))
	;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }
  unformat_free (line_input);

  if (sw_if_index == ~0)
    return clib_error_return (0,
			      "please specify interface name or sw_if_index");

  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
  if (hw == NULL || memif_device_class.index != hw->dev_class_index)
    return clib_error_return (0, "not a memif interface");

  mif = pool_elt_at_index (mm->interfaces, hw->dev_instance);
  memif_delete_if (vm, mif);

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (memif_delete_command, static) = {
  .path = "delete memif",
  .short_help = "delete memif {<interface> | sw_if_index <sw_idx>}",
  .function = memif_delete_command_fn,
};
/* *INDENT-ON* */

static u8 *
format_memif_if_flags (u8 * s, va_list * args)
{
  u32 flags = va_arg (*args, u32);
#define _(a,b,c) if ( flags & (1 << a)) s = format (s, " %s", c);
  foreach_memif_if_flag
#undef _
    return s;
}

static u8 *
format_memif_if_mode (u8 * s, va_list * args)
{
  memif_if_t *mif = va_arg (*args, memif_if_t *);
  if (mif->mode == MEMIF_INTERFACE_MODE_ETHERNET)
    return format (s, "ethernet");
  if (mif->mode == MEMIF_INTERFACE_MODE_IP)
    return format (s, "ip");
  if (mif->mode == MEMIF_INTERFACE_MODE_PUNT_INJECT)
    return format (s, "punt-inject");
  return format (s, "unknown mode (%u)", mif->mode);;
}

static u8 *
format_memif_queue (u8 * s, va_list * args)
{
  memif_if_t *mif = va_arg (*args, memif_if_t *);
  memif_queue_t *mq = va_arg (*args, memif_queue_t *);
  uword i = va_arg (*args, uword);
  uword indent = format_get_indent (s);

  s = format (s, "%U%s ring %u:\n",
	      format_white_space, indent,
	      (mif->flags & MEMIF_IF_FLAG_IS_SLAVE) ?
	      "slave-to-master" : "master-to-slave", i);
  s = format (s, "%Uregion %u offset %u ring-size %u int-fd %d\n",
	      format_white_space, indent + 4,
	      mq->region, mq->offset, (1 << mq->log2_ring_size), mq->int_fd);

  if (mq->ring)
    s = format (s, "%Uhead %u tail %u flags 0x%04x interrupts %u\n",
		format_white_space, indent + 4,
		mq->ring->head, mq->ring->tail, mq->ring->flags,
		mq->int_count);

  return s;
}

static u8 *
format_memif_descriptor (u8 * s, va_list * args)
{
  memif_if_t *mif = va_arg (*args, memif_if_t *);
  memif_queue_t *mq = va_arg (*args, memif_queue_t *);
  uword indent = format_get_indent (s);
  memif_ring_t *ring;
  u16 ring_size;
  u16 slot;

  ring_size = 1 << mq->log2_ring_size;
  ring = mq->ring;
  if (ring)
    {
      s = format (s, "%Udescriptor table:\n", format_white_space, indent);
      s =
	format (s,
		"%Uid    flags buf len desc len      address       offset    user address\n",
		format_white_space, indent);
      s =
	format (s,
		"%U===== ===== ======= ======== ================== ====== ==================\n",
		format_white_space, indent);
      for (slot = 0; slot < ring_size; slot++)
	{
	  s = format (s, "%U%-5d %-5d %-7d %-7d  0x%016lx %-6d 0x%016lx\n",
		      format_white_space, indent, slot,
		      ring->desc[slot].flags, ring->desc[slot].buffer_length,
		      ring->desc[slot].length,
		      mif->regions[ring->desc[slot].region].shm,
		      ring->desc[slot].offset, memif_get_buffer (mif, ring,
								 slot));
	}
      s = format (s, "\n");
    }

  return s;
}

static clib_error_t *
memif_show_command_fn (vlib_main_t * vm, unformat_input_t * input,
		       vlib_cli_command_t * cmd)
{
  memif_main_t *mm = &memif_main;
  memif_if_t *mif;
  vnet_main_t *vnm = vnet_get_main ();
  memif_queue_t *mq;
  uword i;
  int show_descr = 0;
  clib_error_t *error = 0;
  u32 hw_if_index, *hw_if_indices = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat
	  (input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index))
	vec_add1 (hw_if_indices, hw_if_index);
      else if (unformat (input, "descriptors"))
	show_descr = 1;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, input);
	  goto done;
	}
    }

  if (vec_len (hw_if_indices) == 0)
    {
      /* *INDENT-OFF* */
      pool_foreach (mif, mm->interfaces,
	  vec_add1 (hw_if_indices, mif->hw_if_index);
      );
      /* *INDENT-ON* */
    }

  for (hw_if_index = 0; hw_if_index < vec_len (hw_if_indices); hw_if_index++)
    {
      vnet_hw_interface_t *hi =
	vnet_get_hw_interface (vnm, hw_if_indices[hw_if_index]);
      mif = pool_elt_at_index (mm->interfaces, hi->dev_instance);
      memif_socket_file_t *msf = vec_elt_at_index (mm->socket_files,
						   mif->socket_file_index);
      vlib_cli_output (vm, "interface %U", format_vnet_sw_if_index_name,
		       vnm, mif->sw_if_index);
      if (mif->remote_name)
	vlib_cli_output (vm, "  remote-name \"%s\"", mif->remote_name);
      if (mif->remote_if_name)
	vlib_cli_output (vm, "  remote-interface \"%s\"",
			 mif->remote_if_name);
      vlib_cli_output (vm, "  id %d mode %U file %s", mif->id,
		       format_memif_if_mode, mif, msf->filename);
      vlib_cli_output (vm, "  flags%U", format_memif_if_flags, mif->flags);
      vlib_cli_output (vm, "  listener-fd %d conn-fd %d", msf->fd,
		       mif->conn_fd);
      vlib_cli_output (vm,
		       "  num-s2m-rings %u num-m2s-rings %u buffer-size %u",
		       mif->run.num_s2m_rings, mif->run.num_m2s_rings,
		       mif->run.buffer_size);

      if (mif->local_disc_string)
	vlib_cli_output (vm, "  local-disc-reason \"%s\"",
			 mif->local_disc_string);
      if (mif->remote_disc_string)
	vlib_cli_output (vm, "  remote-disc-reason \"%s\"",
			 mif->remote_disc_string);

      vec_foreach_index (i, mif->tx_queues)
      {
	mq = vec_elt_at_index (mif->tx_queues, i);
	vlib_cli_output (vm, "  %U", format_memif_queue, mif, mq, i);
	if (show_descr)
	  vlib_cli_output (vm, "  %U", format_memif_descriptor, mif, mq);
      }
      vec_foreach_index (i, mif->rx_queues)
      {
	mq = vec_elt_at_index (mif->rx_queues, i);
	vlib_cli_output (vm, "  %U", format_memif_queue, mif, mq, i);
	if (show_descr)
	  vlib_cli_output (vm, "  %U", format_memif_descriptor, mif, mq);
      }
    }
done:
  vec_free (hw_if_indices);
  return error;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (memif_show_command, static) = {
  .path = "show memif",
  .short_help = "show memif {<interface>] [descriptors]",
  .function = memif_show_command_fn,
};
/* *INDENT-ON* */

clib_error_t *
memif_cli_init (vlib_main_t * vm)
{
  return 0;
}

VLIB_INIT_FUNCTION (memif_cli_init);

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
0780 16100,610 20919,610 20919,10780 18510,10780 Z"/> <path fill="none" stroke="rgb(52,101,164)" d="M 18510,10780 L 16100,10780 16100,610 20919,610 20919,10780 18510,10780 Z"/> </g> </g> <g class="com.sun.star.drawing.CustomShape"> <g id="id12"> <rect class="BoundingBox" stroke="none" fill="none" x="4525" y="8873" width="10942" height="1654"/> <path fill="rgb(114,159,207)" stroke="none" d="M 9996,10525 L 4526,10525 4526,8874 15465,8874 15465,10525 9996,10525 Z"/> <path fill="none" stroke="rgb(255,255,255)" d="M 9996,10525 L 4526,10525 4526,8874 15465,8874 15465,10525 9996,10525 Z"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="9183" y="9477"/><tspan class="TextPosition" x="9183" y="9477"><tspan fill="rgb(255,255,255)" stroke="none">pandas</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="8393" y="9901"/><tspan class="TextPosition" x="8393" y="9901"><tspan fill="rgb(255,255,255)" stroke="none">Data model in JSON</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="6817" y="10295"/><tspan class="TextPosition" x="6817" y="10295"><tspan fill="rgb(255,255,255)" stroke="none">Specification, Input data (Pandas.Series)</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id13"> <rect class="BoundingBox" stroke="none" fill="none" x="4315" y="8140" width="5437" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="4565" y="8714"/><tspan class="TextPosition" x="4565" y="8714"><tspan fill="rgb(255,255,255)" stroke="none">Data processing</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id14"> <rect class="BoundingBox" stroke="none" fill="none" x="4315" y="4340" width="5437" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="4565" y="4914"/><tspan class="TextPosition" x="4565" y="4914"><tspan fill="rgb(255,255,255)" stroke="none">Data presentation</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.CustomShape"> <g id="id15"> <rect class="BoundingBox" stroke="none" fill="none" x="4525" y="5073" width="2560" height="1654"/> <path fill="rgb(114,159,207)" stroke="none" d="M 5805,6725 L 4526,6725 4526,5074 7083,5074 7083,6725 5805,6725 Z"/> <path fill="none" stroke="rgb(255,255,255)" d="M 5805,6725 L 4526,6725 4526,5074 7083,5074 7083,6725 5805,6725 Z"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="5252" y="5677"/><tspan class="TextPosition" x="5252" y="5677"><tspan fill="rgb(255,255,255)" stroke="none">Plots</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="4697" y="6495"/><tspan class="TextPosition" x="4697" y="6495"><tspan fill="rgb(255,255,255)" stroke="none">plot.ly → .html</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.CustomShape"> <g id="id16"> <rect class="BoundingBox" stroke="none" fill="none" x="8826" y="5073" width="2451" height="1654"/> <path fill="rgb(114,159,207)" stroke="none" d="M 10051,6725 L 8827,6725 8827,5074 11275,5074 11275,6725 10051,6725 Z"/> <path fill="none" stroke="rgb(255,255,255)" d="M 10051,6725 L 8827,6725 8827,5074 11275,5074 11275,6725 10051,6725 Z"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="9528" y="5677"/><tspan class="TextPosition" x="9528" y="5677"><tspan fill="rgb(255,255,255)" stroke="none">Files</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="9649" y="6495"/><tspan class="TextPosition" x="9649" y="6495"><tspan fill="rgb(255,255,255)" stroke="none">.RST</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.CustomShape"> <g id="id17"> <rect class="BoundingBox" stroke="none" fill="none" x="12925" y="5073" width="2560" height="1654"/> <path fill="rgb(114,159,207)" stroke="none" d="M 14205,6725 L 12926,6725 12926,5074 15483,5074 15483,6725 14205,6725 Z"/> <path fill="none" stroke="rgb(255,255,255)" d="M 14205,6725 L 12926,6725 12926,5074 15483,5074 15483,6725 14205,6725 Z"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="13489" y="5677"/><tspan class="TextPosition" x="13489" y="5677"><tspan fill="rgb(255,255,255)" stroke="none">Tables</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="13023" y="6495"/><tspan class="TextPosition" x="13023" y="6495"><tspan fill="rgb(255,255,255)" stroke="none">Pandas → .csv</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id18"> <rect class="BoundingBox" stroke="none" fill="none" x="1715" y="540" width="5437" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="1965" y="1114"/><tspan class="TextPosition" x="1965" y="1114"><tspan fill="rgb(255,255,255)" stroke="none">Report generation</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.CustomShape"> <g id="id19"> <rect class="BoundingBox" stroke="none" fill="none" x="2003" y="1273" width="13465" height="1654"/> <path fill="rgb(114,159,207)" stroke="none" d="M 8735,2925 L 2004,2925 2004,1274 15466,1274 15466,2925 8735,2925 Z"/> <path fill="none" stroke="rgb(255,255,255)" d="M 8735,2925 L 2004,2925 2004,1274 15466,1274 15466,2925 8735,2925 Z"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="7982" y="1877"/><tspan class="TextPosition" x="7982" y="1877"><tspan fill="rgb(255,255,255)" stroke="none">Sphinx</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="6163" y="2695"/><tspan class="TextPosition" x="6163" y="2695"><tspan fill="rgb(255,255,255)" stroke="none">.html / .pdf (then stored in nexus)</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id20"> <rect class="BoundingBox" stroke="none" fill="none" x="16015" y="540" width="4659" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="16265" y="1114"/><tspan class="TextPosition" x="16265" y="1114"><tspan fill="rgb(255,255,255)" stroke="none">Jenkins plots</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.CustomShape"> <g id="id21"> <rect class="BoundingBox" stroke="none" fill="none" x="16354" y="1243" width="4317" height="9284"/> <path fill="rgb(114,159,207)" stroke="none" d="M 18512,10525 L 16355,10525 16355,1244 20669,1244 20669,10525 18512,10525 Z"/> <path fill="none" stroke="rgb(255,255,255)" d="M 18512,10525 L 16355,10525 16355,1244 20669,1244 20669,10525 18512,10525 Z"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="17200" y="5385"/><tspan class="TextPosition" x="17200" y="5385"><tspan fill="rgb(255,255,255)" stroke="none">Jenkins plot</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="17852" y="5940"/><tspan class="TextPosition" x="17852" y="5940"><tspan fill="rgb(255,255,255)" stroke="none">plugin</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="18129" y="6758"/><tspan class="TextPosition" x="18129" y="6758"><tspan fill="rgb(255,255,255)" stroke="none">.html</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id22"> <rect class="BoundingBox" stroke="none" fill="none" x="415" y="11840" width="1303" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="665" y="12414"/><tspan class="TextPosition" x="665" y="12414"><tspan fill="rgb(0,0,0)" stroke="none">sL1</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id23"> <rect class="BoundingBox" stroke="none" fill="none" x="415" y="8140" width="1303" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="665" y="8714"/><tspan class="TextPosition" x="665" y="8714"><tspan fill="rgb(0,0,0)" stroke="none">sL2</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id24"> <rect class="BoundingBox" stroke="none" fill="none" x="415" y="4340" width="1303" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="665" y="4914"/><tspan class="TextPosition" x="665" y="4914"><tspan fill="rgb(0,0,0)" stroke="none">sL3</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id25"> <rect class="BoundingBox" stroke="none" fill="none" x="415" y="540" width="1303" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="665" y="1114"/><tspan class="TextPosition" x="665" y="1114"><tspan fill="rgb(0,0,0)" stroke="none">sL4</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.LineShape"> <g id="id26"> <rect class="BoundingBox" stroke="none" fill="none" x="3031" y="2896" width="431" height="10007"/> <path fill="none" stroke="rgb(0,102,204)" stroke-width="53" stroke-linejoin="round" d="M 3222,12548 L 3271,3439"/> <path fill="rgb(0,102,204)" stroke="none" d="M 3257,12528 L 3291,12537 3325,12555 3356,12579 3380,12610 3397,12645 3406,12679 3411,12714 3406,12748 3396,12784 3379,12818 3355,12847 3323,12871 3289,12888 3255,12899 3219,12902 3185,12899 3150,12887 3117,12870 3086,12846 3062,12816 3045,12782 3036,12746 3032,12712 3036,12677 3046,12643 3063,12609 3088,12578 3119,12554 3152,12537 3187,12527 3221,12523 3257,12528 Z"/> <path fill="rgb(0,102,204)" stroke="none" d="M 3274,2896 L 3081,3463 3460,3466 3274,2896 Z"/> </g> </g> <g class="com.sun.star.drawing.LineShape"> <g id="id27"> <rect class="BoundingBox" stroke="none" fill="none" x="11096" y="10516" width="411" height="2388"/> <path fill="none" stroke="rgb(0,102,204)" stroke-width="53" stroke-linejoin="round" d="M 11313,12548 L 11285,11059"/> <path fill="rgb(0,102,204)" stroke="none" d="M 11348,12527 L 11382,12536 11416,12552 11448,12576 11473,12607 11491,12640 11501,12674 11506,12709 11502,12744 11493,12779 11477,12814 11453,12844 11422,12869 11389,12886 11355,12898 11319,12902 11285,12900 11250,12889 11216,12873 11185,12849 11160,12820 11142,12786 11132,12751 11127,12717 11131,12681 11140,12647 11156,12612 11180,12581 11210,12556 11243,12538 11278,12528 11312,12523 11348,12527 Z"/> <path fill="rgb(0,102,204)" stroke="none" d="M 11275,10516 L 11096,11088 11475,11081 11275,10516 Z"/> </g> </g> <g class="com.sun.star.drawing.LineShape"> <g id="id28"> <rect class="BoundingBox" stroke="none" fill="none" x="15000" y="10517" width="411" height="2388"/> <path fill="none" stroke="rgb(0,102,204)" stroke-width="53" stroke-linejoin="round" d="M 15217,12549 L 15189,11060"/> <path fill="rgb(0,102,204)" stroke="none" d="M 15252,12528 L 15286,12537 15320,12553 15352,12577 15377,12608 15395,12641 15405,12675 15410,12710 15406,12745 15397,12780 15381,12815 15357,12845 15326,12870 15293,12887 15259,12899 15223,12903 15189,12901 15154,12890 15120,12874 15089,12850 15064,12821 15046,12787 15036,12752 15031,12718 15035,12682 15044,12648 15060,12613 15084,12582 15114,12557 15147,12539 15182,12529 15216,12524 15252,12528 Z"/> <path fill="rgb(0,102,204)" stroke="none" d="M 15179,10517 L 15000,11089 15379,11082 15179,10517 Z"/> </g> </g> <g class="com.sun.star.drawing.LineShape"> <g id="id29"> <rect class="BoundingBox" stroke="none" fill="none" x="18304" y="10518" width="411" height="2388"/> <path fill="none" stroke="rgb(0,102,204)" stroke-width="53" stroke-linejoin="round" d="M 18521,12550 L 18493,11061"/> <path fill="rgb(0,102,204)" stroke="none" d="M 18556,12529 L 18590,12538 18624,12554 18656,12578 18681,12609 18699,12642 18709,12676 18714,12711 18710,12746 18701,12781 18685,12816 18661,12846 18630,12871 18597,12888 18563,12900 18527,12904 18493,12902 18458,12891 18424,12875 18393,12851 18368,12822 18350,12788 18340,12753 18335,12719 18339,12683 18348,12649 18364,12614 18388,12583 18418,12558 18451,12540 18486,12530 18520,12525 18556,12529 Z"/> <path fill="rgb(0,102,204)" stroke="none" d="M 18483,10518 L 18304,11090 18683,11083 18483,10518 Z"/> </g> </g> <g class="com.sun.star.drawing.LineShape"> <g id="id30"> <rect class="BoundingBox" stroke="none" fill="none" x="5497" y="2896" width="381" height="2414"/> <path fill="none" stroke="rgb(0,102,204)" stroke-width="53" stroke-linejoin="round" d="M 5687,4955 L 5687,3439"/> <path fill="rgb(0,102,204)" stroke="none" d="M 5722,4934 L 5756,4944 5790,4961 5821,4985 5845,5016 5862,5051 5872,5085 5877,5120 5872,5154 5862,5190 5845,5224 5821,5254 5790,5278 5756,5295 5722,5306 5686,5309 5652,5306 5617,5295 5584,5278 5553,5254 5529,5224 5512,5190 5502,5154 5498,5120 5502,5085 5512,5051 5529,5016 5553,4985 5584,4961 5617,4944 5652,4934 5686,4930 5722,4934 Z"/> <path fill="rgb(0,102,204)" stroke="none" d="M 5687,2896 L 5498,3465 5877,3465 5687,2896 Z"/> </g> </g> <g class="com.sun.star.drawing.LineShape"> <g id="id31"> <rect class="BoundingBox" stroke="none" fill="none" x="9815" y="2896" width="381" height="2414"/> <path fill="none" stroke="rgb(0,102,204)" stroke-width="53" stroke-linejoin="round" d="M 10005,4955 L 10005,3439"/> <path fill="rgb(0,102,204)" stroke="none" d="M 10040,4934 L 10074,4944 10108,4961 10139,4985 10163,5016 10180,5051 10190,5085 10195,5120 10190,5154 10180,5190 10163,5224 10139,5254 10108,5278 10074,5295 10040,5306 10004,5309 9970,5306 9935,5295 9902,5278 9871,5254 9847,5224 9830,5190 9820,5154 9816,5120 9820,5085 9830,5051 9847,5016 9871,4985 9902,4961 9935,4944 9970,4934 10004,4930 10040,4934 Z"/> <path fill="rgb(0,102,204)" stroke="none" d="M 10005,2896 L 9816,3465 10195,3465 10005,2896 Z"/> </g> </g> <g class="com.sun.star.drawing.LineShape"> <g id="id32"> <rect class="BoundingBox" stroke="none" fill="none" x="13999" y="2919" width="387" height="2392"/> <path fill="none" stroke="rgb(0,102,204)" stroke-width="53" stroke-linejoin="round" d="M 14195,4955 L 14189,3462"/> <path fill="rgb(0,102,204)" stroke="none" d="M 14229,4934 L 14263,4944 14298,4961 14329,4985 14353,5016 14370,5050 14380,5084 14385,5119 14381,5153 14371,5189 14354,5223 14330,5253 14299,5277 14265,5294 14231,5306 14195,5309 14161,5306 14126,5295 14093,5278 14062,5254 14037,5224 14020,5190 14010,5155 14006,5121 14010,5086 14020,5051 14037,5017 14061,4986 14092,4962 14124,4944 14160,4934 14194,4930 14229,4934 Z"/> <path fill="rgb(0,102,204)" stroke="none" d="M 14187,2919 L 14000,3488 14379,3487 14187,2919 Z"/> </g> </g> <g class="com.sun.star.drawing.LineShape"> <g id="id33"> <rect class="BoundingBox" stroke="none" fill="none" x="6957" y="5627" width="1906" height="381"/> <path fill="none" stroke="rgb(0,102,204)" stroke-width="53" stroke-linejoin="round" d="M 7311,5817 L 8319,5817"/> <path fill="rgb(0,102,204)" stroke="none" d="M 7332,5852 L 7322,5886 7305,5920 7281,5951 7250,5975 7215,5992 7181,6002 7146,6007 7112,6002 7076,5992 7042,5975 7012,5951 6988,5920 6971,5886 6960,5852 6957,5816 6960,5782 6971,5747 6988,5714 7012,5683 7042,5659 7076,5642 7112,5632 7146,5628 7181,5632 7215,5642 7250,5659 7281,5683 7305,5714 7322,5747 7332,5782 7336,5816 7332,5852 Z"/> <path fill="rgb(0,102,204)" stroke="none" d="M 8862,5817 L 8294,5628 8294,6007 8862,5817 Z"/> </g> </g> <g class="com.sun.star.drawing.LineShape"> <g id="id34"> <rect class="BoundingBox" stroke="none" fill="none" x="11275" y="5627" width="1779" height="381"/> <path fill="none" stroke="rgb(0,102,204)" stroke-width="53" stroke-linejoin="round" d="M 12699,5817 L 11818,5817"/> <path fill="rgb(0,102,204)" stroke="none" d="M 12678,5782 L 12688,5748 12705,5714 12729,5683 12760,5659 12795,5642 12829,5632 12864,5628 12898,5632 12934,5642 12968,5659 12998,5683 13022,5714 13039,5748 13050,5782 13053,5818 13050,5852 13039,5887 13022,5920 12998,5951 12968,5975 12934,5992 12898,6002 12864,6007 12829,6002 12795,5992 12760,5975 12729,5951 12705,5920 12688,5887 12678,5852 12674,5818 12678,5782 Z"/> <path fill="rgb(0,102,204)" stroke="none" d="M 11275,5817 L 11844,6007 11844,5628 11275,5817 Z"/> </g> </g> <g class="com.sun.star.drawing.LineShape"> <g id="id35"> <rect class="BoundingBox" stroke="none" fill="none" x="5524" y="6706" width="381" height="2160"/> <path fill="none" stroke="rgb(0,102,204)" stroke-width="53" stroke-linejoin="round" d="M 5714,7249 L 5714,8322"/> <path fill="rgb(0,102,204)" stroke="none" d="M 5714,6706 L 5525,7275 5904,7275 5714,6706 Z"/> <path fill="rgb(0,102,204)" stroke="none" d="M 5714,8865 L 5904,8297 5525,8297 5714,8865 Z"/> </g> </g> <g class="com.sun.star.drawing.LineShape"> <g id="id36"> <rect class="BoundingBox" stroke="none" fill="none" x="9824" y="6707" width="381" height="2160"/> <path fill="none" stroke="rgb(0,102,204)" stroke-width="53" stroke-linejoin="round" d="M 10014,7250 L 10014,8323"/> <path fill="rgb(0,102,204)" stroke="none" d="M 10014,6707 L 9825,7276 10204,7276 10014,6707 Z"/> <path fill="rgb(0,102,204)" stroke="none" d="M 10014,8866 L 10204,8298 9825,8298 10014,8866 Z"/> </g> </g> <g class="com.sun.star.drawing.LineShape"> <g id="id37"> <rect class="BoundingBox" stroke="none" fill="none" x="14024" y="6708" width="381" height="2160"/> <path fill="none" stroke="rgb(0,102,204)" stroke-width="53" stroke-linejoin="round" d="M 14214,7251 L 14214,8324"/> <path fill="rgb(0,102,204)" stroke="none" d="M 14214,6708 L 14025,7277 14404,7277 14214,6708 Z"/> <path fill="rgb(0,102,204)" stroke="none" d="M 14214,8867 L 14404,8299 14025,8299 14214,8867 Z"/> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id38"> <rect class="BoundingBox" stroke="none" fill="none" x="3115" y="11440" width="2065" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="3365" y="11883"/><tspan class="TextPosition" x="3365" y="11883"><tspan fill="rgb(0,69,134)" stroke="none">Read files</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id39"> <rect class="BoundingBox" stroke="none" fill="none" x="11215" y="11440" width="2065" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="11465" y="11883"/><tspan class="TextPosition" x="11465" y="11883"><tspan fill="rgb(0,69,134)" stroke="none">Read files</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id40"> <rect class="BoundingBox" stroke="none" fill="none" x="15115" y="11440" width="2065" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="15365" y="11883"/><tspan class="TextPosition" x="15365" y="11883"><tspan fill="rgb(0,69,134)" stroke="none">Read files</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id41"> <rect class="BoundingBox" stroke="none" fill="none" x="18415" y="11440" width="2065" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="18665" y="11883"/><tspan class="TextPosition" x="18665" y="11883"><tspan fill="rgb(0,69,134)" stroke="none">Read files</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id42"> <rect class="BoundingBox" stroke="none" fill="none" x="14115" y="3840" width="2065" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="14365" y="4283"/><tspan class="TextPosition" x="14365" y="4283"><tspan fill="rgb(0,69,134)" stroke="none">Read files</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id43"> <rect class="BoundingBox" stroke="none" fill="none" x="9915" y="3840" width="2065" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="10165" y="4283"/><tspan class="TextPosition" x="10165" y="4283"><tspan fill="rgb(0,69,134)" stroke="none">Read files</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id44"> <rect class="BoundingBox" stroke="none" fill="none" x="5615" y="3840" width="2065" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="5865" y="4283"/><tspan class="TextPosition" x="5865" y="4283"><tspan fill="rgb(0,69,134)" stroke="none">Read files</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id45"> <rect class="BoundingBox" stroke="none" fill="none" x="6915" y="5140" width="2065" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="7165" y="5583"/><tspan class="TextPosition" x="7165" y="5583"><tspan fill="rgb(0,69,134)" stroke="none">Read files</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id46"> <rect class="BoundingBox" stroke="none" fill="none" x="11115" y="5140" width="2065" height="807"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="11365" y="5583"/><tspan class="TextPosition" x="11365" y="5583"><tspan fill="rgb(0,69,134)" stroke="none">Read files</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id47"> <rect class="BoundingBox" stroke="none" fill="none" x="5615" y="7640" width="2613" height="718"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="5865" y="8083"/><tspan class="TextPosition" x="5865" y="8083"><tspan fill="rgb(0,69,134)" stroke="none">Python calls</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id48"> <rect class="BoundingBox" stroke="none" fill="none" x="9915" y="7641" width="2613" height="718"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="10165" y="8084"/><tspan class="TextPosition" x="10165" y="8084"><tspan fill="rgb(0,69,134)" stroke="none">Python calls</tspan></tspan></tspan></text> </g> </g> <g class="com.sun.star.drawing.TextShape"> <g id="id49"> <rect class="BoundingBox" stroke="none" fill="none" x="12915" y="7642" width="2613" height="718"/> <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="353px" font-weight="400"><tspan class="TextPosition" x="13165" y="8085"/><tspan class="TextPosition" x="13165" y="8085"><tspan fill="rgb(0,69,134)" stroke="none">Python calls</tspan></tspan></tspan></text> </g> </g> </g> </g> </g> </g> </svg>