tjs-lang 0.6.45 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/CLAUDE.md +70 -444
  2. package/README.md +15 -82
  3. package/bin/benchmarks.ts +7 -7
  4. package/bin/dev.ts +2 -1
  5. package/demo/autocomplete.test.ts +1 -1
  6. package/demo/docs.json +743 -47
  7. package/demo/src/demo-nav.ts +5 -5
  8. package/demo/src/index.ts +28 -36
  9. package/demo/src/module-sw.ts +1 -1
  10. package/demo/src/playground-shared.ts +17 -17
  11. package/demo/src/playground.ts +13 -1
  12. package/demo/src/style.ts +4 -1
  13. package/demo/src/tjs-playground.ts +5 -5
  14. package/demo/src/user-store.ts +2 -1
  15. package/demo/static/favicon.svg +17 -24
  16. package/demo/static/tosi-platform.json +9304 -0
  17. package/dist/index.js +176 -175
  18. package/dist/index.js.map +5 -43
  19. package/dist/scripts/compat-effect.d.ts +16 -0
  20. package/dist/scripts/compat-kysely.d.ts +13 -0
  21. package/dist/scripts/compat-radash.d.ts +13 -0
  22. package/dist/scripts/compat-superstruct.d.ts +13 -0
  23. package/dist/scripts/compat-ts-pattern.d.ts +13 -0
  24. package/dist/scripts/compat-zod.d.ts +12 -0
  25. package/dist/src/lang/emitters/from-ts.d.ts +1 -1
  26. package/dist/src/lang/emitters/js-tests.d.ts +4 -0
  27. package/dist/src/lang/emitters/js.d.ts +2 -2
  28. package/dist/src/lang/index.d.ts +1 -0
  29. package/dist/src/lang/json-schema.d.ts +40 -0
  30. package/dist/src/lang/parser-transforms.d.ts +14 -0
  31. package/dist/src/lang/runtime.d.ts +39 -20
  32. package/dist/src/types/Type.d.ts +5 -0
  33. package/dist/tjs-batteries.js +3 -4
  34. package/dist/tjs-batteries.js.map +5 -13
  35. package/dist/tjs-eval.js +47 -0
  36. package/dist/tjs-eval.js.map +7 -0
  37. package/dist/tjs-from-ts.js +58 -0
  38. package/dist/tjs-from-ts.js.map +7 -0
  39. package/dist/tjs-lang.js +349 -0
  40. package/dist/tjs-lang.js.map +7 -0
  41. package/dist/tjs-vm.js +51 -51
  42. package/dist/tjs-vm.js.map +4 -19
  43. package/docs/README.md +21 -20
  44. package/docs/WASM-QUICKSTART.md +283 -0
  45. package/docs/diagrams/architecture-shift.svg +117 -0
  46. package/docs/diagrams/compile-runtime.svg +130 -0
  47. package/docs/diagrams/icon-riff-1.svg +55 -0
  48. package/docs/diagrams/icon-riff-2.svg +62 -0
  49. package/docs/diagrams/icon-riff-3.svg +61 -0
  50. package/docs/diagrams/platform-overview.svg +114 -0
  51. package/docs/diagrams/safe-eval.svg +147 -0
  52. package/docs/eval-v4/arch-comparison.svg +277 -0
  53. package/docs/eval-v4/bundler-tree.svg +250 -0
  54. package/docs/eval-v4/http-lifecycle.svg +148 -0
  55. package/docs/function-predicate-design.md +8 -8
  56. package/docs/native-engine-integration.md +2 -2
  57. package/editors/codemirror/autocomplete.test.ts +29 -29
  58. package/package.json +24 -12
  59. package/src/cli/commands/convert.test.ts +11 -8
  60. package/src/lang/codegen.test.ts +117 -112
  61. package/src/lang/docs.test.ts +22 -22
  62. package/src/lang/docs.ts +5 -8
  63. package/src/lang/emitters/dts.test.ts +13 -13
  64. package/src/lang/emitters/from-ts.ts +36 -9
  65. package/src/lang/emitters/js-tests.ts +143 -28
  66. package/src/lang/emitters/js.ts +44 -31
  67. package/src/lang/features.test.ts +259 -43
  68. package/src/lang/from-ts.test.ts +3 -3
  69. package/src/lang/function-predicate.test.ts +1 -1
  70. package/src/lang/index.ts +8 -47
  71. package/src/lang/json-schema.test.ts +261 -0
  72. package/src/lang/json-schema.ts +167 -0
  73. package/src/lang/parser-params.ts +28 -44
  74. package/src/lang/parser-transforms.ts +255 -0
  75. package/src/lang/parser.test.ts +32 -13
  76. package/src/lang/parser.ts +49 -11
  77. package/src/lang/perf.test.ts +11 -11
  78. package/src/lang/roundtrip.test.ts +3 -3
  79. package/src/lang/runtime.test.ts +167 -0
  80. package/src/lang/runtime.ts +213 -64
  81. package/src/lang/transpiler.test.ts +21 -21
  82. package/src/lang/typescript-syntax.test.ts +11 -9
  83. package/src/types/Type.ts +38 -1
  84. package/src/use-cases/bootstrap.test.ts +7 -7
  85. package/src/use-cases/client-server.test.ts +1 -1
  86. package/src/use-cases/malicious-actor.test.ts +1 -1
  87. package/src/use-cases/rag-processor.test.ts +1 -1
  88. package/src/use-cases/sophisticated-agents.test.ts +2 -2
  89. package/src/use-cases/transpiler-llm.test.ts +1 -1
  90. package/src/use-cases/unbundled-imports.test.ts +9 -9
  91. package/tjs-lang.svg +17 -25
  92. package/dist/tjs-full.js +0 -435
  93. package/dist/tjs-full.js.map +0 -45
  94. package/dist/tjs-transpiler.js +0 -3
  95. package/dist/tjs-transpiler.js.map +0 -11
@@ -10,8 +10,8 @@
10
10
 
11
11
  import { Component, elements, ElementCreator, vars, bind } from 'tosijs'
12
12
  import {
13
- xinFloat,
14
- XinFloat,
13
+ tosiFloat,
14
+ TosiFloat,
15
15
  markdownViewer,
16
16
  MarkdownViewer,
17
17
  icons,
@@ -76,7 +76,7 @@ export class DemoNav extends Component {
76
76
  private _docs: DocItem[] = []
77
77
  private _appState: any = null // boxed proxy from index.ts
78
78
  private _built = false
79
- private floatViewer: XinFloat | null = null
79
+ private floatViewer: TosiFloat | null = null
80
80
  private mdViewer: MarkdownViewer | null = null
81
81
 
82
82
  // Computed example arrays from docs
@@ -495,7 +495,7 @@ export class DemoNav extends Component {
495
495
  } else {
496
496
  // Update existing viewer
497
497
  if (this.mdViewer) {
498
- this.mdViewer.value = doc.text
498
+ this.mdViewer.value = doc.text ?? ''
499
499
  }
500
500
  // Update title
501
501
  const title = this.floatViewer.querySelector('.float-title')
@@ -538,7 +538,7 @@ export class DemoNav extends Component {
538
538
  icons.x({ size: 16 })
539
539
  )
540
540
 
541
- this.floatViewer = xinFloat(
541
+ this.floatViewer = tosiFloat(
542
542
  {
543
543
  drag: true,
544
544
  remainOnResize: 'remain',
package/demo/src/index.ts CHANGED
@@ -208,13 +208,13 @@ initAuth()
208
208
 
209
209
  // Custom bindings
210
210
  bindings.docLink = {
211
- toDOM(elt: HTMLElement, filename: string) {
211
+ toDOM(elt: Element, filename: string) {
212
212
  elt.setAttribute('href', `?${filename}`)
213
213
  },
214
214
  }
215
215
 
216
216
  bindings.current = {
217
- toDOM(elt: HTMLElement, currentFile: string) {
217
+ toDOM(elt: Element, currentFile: string) {
218
218
  const boundFile = elt.getAttribute('href') || ''
219
219
  elt.classList.toggle('current', currentFile === boundFile.substring(1))
220
220
  },
@@ -464,13 +464,13 @@ if (main) {
464
464
  deepseek: settings.deepseekKey || undefined,
465
465
  })
466
466
  // Also save to localStorage for offline use
467
- prefs.preferredProvider =
467
+ prefs.preferredProvider.value =
468
468
  settings.preferredProvider
469
- prefs.openaiKey = settings.openaiKey
470
- prefs.anthropicKey = settings.anthropicKey
471
- prefs.geminiKey = settings.geminiKey
472
- prefs.deepseekKey = settings.deepseekKey
473
- prefs.customLlmUrl = settings.customLlmUrl
469
+ prefs.openaiKey.value = settings.openaiKey
470
+ prefs.anthropicKey.value = settings.anthropicKey
471
+ prefs.geminiKey.value = settings.geminiKey
472
+ prefs.deepseekKey.value = settings.deepseekKey
473
+ prefs.customLlmUrl.value = settings.customLlmUrl
474
474
  savePrefs()
475
475
  }
476
476
  )
@@ -508,12 +508,13 @@ if (main) {
508
508
  customLlmUrl: prefs.customLlmUrl.valueOf(),
509
509
  },
510
510
  (settings) => {
511
- prefs.preferredProvider = settings.preferredProvider
512
- prefs.openaiKey = settings.openaiKey
513
- prefs.anthropicKey = settings.anthropicKey
514
- prefs.geminiKey = settings.geminiKey
515
- prefs.deepseekKey = settings.deepseekKey
516
- prefs.customLlmUrl = settings.customLlmUrl
511
+ prefs.preferredProvider.value =
512
+ settings.preferredProvider
513
+ prefs.openaiKey.value = settings.openaiKey
514
+ prefs.anthropicKey.value = settings.anthropicKey
515
+ prefs.geminiKey.value = settings.geminiKey
516
+ prefs.deepseekKey.value = settings.deepseekKey
517
+ prefs.customLlmUrl.value = settings.customLlmUrl
517
518
  savePrefs()
518
519
  }
519
520
  )
@@ -537,12 +538,13 @@ if (main) {
537
538
  customLlmUrl: prefs.customLlmUrl.valueOf(),
538
539
  },
539
540
  (settings) => {
540
- prefs.preferredProvider = settings.preferredProvider
541
- prefs.openaiKey = settings.openaiKey
542
- prefs.anthropicKey = settings.anthropicKey
543
- prefs.geminiKey = settings.geminiKey
544
- prefs.deepseekKey = settings.deepseekKey
545
- prefs.customLlmUrl = settings.customLlmUrl
541
+ prefs.preferredProvider.value =
542
+ settings.preferredProvider
543
+ prefs.openaiKey.value = settings.openaiKey
544
+ prefs.anthropicKey.value = settings.anthropicKey
545
+ prefs.geminiKey.value = settings.geminiKey
546
+ prefs.deepseekKey.value = settings.deepseekKey
547
+ prefs.customLlmUrl.value = settings.customLlmUrl
546
548
  savePrefs()
547
549
  }
548
550
  )
@@ -563,7 +565,7 @@ if (main) {
563
565
  caption: 'System',
564
566
  checked: () => prefs.theme.valueOf() === 'system',
565
567
  action: () => {
566
- prefs.theme = 'system'
568
+ prefs.theme.value = 'system'
567
569
  savePrefs()
568
570
  },
569
571
  },
@@ -571,7 +573,7 @@ if (main) {
571
573
  caption: 'Dark',
572
574
  checked: () => prefs.theme.valueOf() === 'dark',
573
575
  action: () => {
574
- prefs.theme = 'dark'
576
+ prefs.theme.value = 'dark'
575
577
  savePrefs()
576
578
  },
577
579
  },
@@ -579,7 +581,7 @@ if (main) {
579
581
  caption: 'Light',
580
582
  checked: () => prefs.theme.valueOf() === 'light',
581
583
  action: () => {
582
- prefs.theme = 'light'
584
+ prefs.theme.value = 'light'
583
585
  savePrefs()
584
586
  },
585
587
  },
@@ -588,7 +590,7 @@ if (main) {
588
590
  caption: 'High Contrast',
589
591
  checked: () => prefs.highContrast.valueOf(),
590
592
  action: () => {
591
- prefs.highContrast = !prefs.highContrast.valueOf()
593
+ prefs.highContrast.value = !prefs.highContrast.valueOf()
592
594
  savePrefs()
593
595
  },
594
596
  },
@@ -712,18 +714,8 @@ if (main) {
712
714
  // Load example when selected
713
715
  bind(pg, 'app.currentExample', {
714
716
  toDOM(element: Playground, example: any) {
715
- if (
716
- example &&
717
- app.currentView.valueOf() === 'ajs' &&
718
- element.editor
719
- ) {
720
- element.editor.dispatch({
721
- changes: {
722
- from: 0,
723
- to: element.editor.state.doc.length,
724
- insert: example.code,
725
- },
726
- })
717
+ if (example && app.currentView.valueOf() === 'ajs') {
718
+ element.setCode(example.code)
727
719
  }
728
720
  },
729
721
  })
@@ -122,7 +122,7 @@ self.addEventListener('message', (event: MessageEvent) => {
122
122
  })
123
123
 
124
124
  // TypeScript declarations for service worker globals
125
- declare const self: ServiceWorkerGlobalScope
125
+ declare const self: any // ServiceWorkerGlobalScope (webworker lib not available)
126
126
  interface ExtendableEvent extends Event {
127
127
  waitUntil(promise: Promise<any>): void
128
128
  }
@@ -272,14 +272,16 @@ export function renderTestResults(
272
272
  const passed = tests.filter((t: any) => t.passed).length
273
273
  const failed = tests.filter((t: any) => !t.passed).length
274
274
 
275
- // Set gutter markers for failed tests
276
- const failedTests = tests.filter((t: any) => !t.passed && t.line)
277
- if (failedTests.length > 0) {
275
+ // Set gutter markers for ALL tests (pass and fail)
276
+ const testsWithLines = tests.filter((t: any) => t.line)
277
+ if (testsWithLines.length > 0) {
278
278
  editor.setMarkers(
279
- failedTests.map((t: any) => ({
279
+ testsWithLines.map((t: any) => ({
280
280
  line: t.line,
281
- message: t.error || t.description,
282
- severity: 'error' as const,
281
+ message: t.passed
282
+ ? `✓ ${t.description}`
283
+ : `✗ ${t.description}: ${t.error || 'failed'}`,
284
+ severity: t.passed ? ('info' as const) : ('error' as const),
283
285
  }))
284
286
  )
285
287
  } else {
@@ -300,11 +302,10 @@ export function renderTestResults(
300
302
  ? ' <span class="sig-badge">signature</span>'
301
303
  : ''
302
304
  const dataLine = test.line ? ` data-line="${test.line}"` : ''
303
- html += `<li class="${cls}"${dataLine}>${icon} ${test.description}${sigBadge}`
305
+ const clickable = test.line ? ' clickable-test' : ''
306
+ html += `<li class="${cls}${clickable}"${dataLine}>${icon} ${test.description}${sigBadge}`
304
307
  if (!test.passed && test.error) {
305
- html += `<div class="test-error${
306
- test.line ? ' clickable-error' : ''
307
- }"${dataLine}>${test.error}</div>`
308
+ html += `<div class="test-error">${test.error}</div>`
308
309
  }
309
310
  html += `</li>`
310
311
  }
@@ -312,8 +313,8 @@ export function renderTestResults(
312
313
 
313
314
  outputEl.innerHTML = html
314
315
 
315
- // Add click handlers for clickable errors
316
- outputEl.querySelectorAll('.clickable-error').forEach((el) => {
316
+ // Add click handlers any test with a line number is clickable
317
+ outputEl.querySelectorAll('.clickable-test').forEach((el) => {
317
318
  el.addEventListener('click', (e) => {
318
319
  const line = parseInt(
319
320
  (e.currentTarget as HTMLElement).dataset.line || '0',
@@ -587,14 +588,13 @@ export const sharedPlaygroundStyles: Record<string, Record<string, string>> = {
587
588
  fontFamily: 'var(--font-mono, monospace)',
588
589
  },
589
590
 
590
- ':host .clickable-error': {
591
+ ':host .clickable-test': {
591
592
  cursor: 'pointer',
592
- textDecoration: 'underline',
593
- textDecorationStyle: 'dotted',
594
593
  },
595
594
 
596
- ':host .clickable-error:hover': {
597
- background: 'rgba(220, 38, 38, 0.2)',
595
+ ':host .clickable-test:hover': {
596
+ textDecoration: 'underline',
597
+ textDecorationStyle: 'dotted',
598
598
  },
599
599
 
600
600
  ':host .sig-badge': {
@@ -3,6 +3,7 @@
3
3
  */
4
4
 
5
5
  import { elements, Component, PartsMap } from 'tosijs'
6
+ import type { XinStyleSheet } from 'tosijs'
6
7
 
7
8
  import { icons } from 'tosijs-ui'
8
9
 
@@ -104,7 +105,7 @@ export class Playground extends Component<PlaygroundParts> {
104
105
 
105
106
  // Use Shadow DOM styles (static styleSpec)
106
107
  // CSS variables for theming
107
- static styleSpec = {
108
+ static styleSpec: XinStyleSheet = {
108
109
  ':host': {
109
110
  display: 'block',
110
111
  height: '100%',
@@ -938,6 +939,17 @@ export class Playground extends Component<PlaygroundParts> {
938
939
  this.isRunning = false
939
940
  }
940
941
 
942
+ setCode(code: string) {
943
+ if (!this.editor) return
944
+ this.editor.dispatch({
945
+ changes: {
946
+ from: 0,
947
+ to: this.editor.state.doc.length,
948
+ insert: code,
949
+ },
950
+ })
951
+ }
952
+
941
953
  render() {
942
954
  super.render()
943
955
  }
package/demo/src/style.ts CHANGED
@@ -24,7 +24,8 @@ export const styleSpec = {
24
24
  _fontMono: "'SF Mono', Monaco, 'Cascadia Code', Consolas, monospace",
25
25
  _fontSize: '15px',
26
26
  _lineHeight: '1.6',
27
- _xinTabsSelectedColor: vars.brandColor,
27
+ _xinTabsSelectedColor: '#3ea9f5',
28
+ _tosiTabsSelectedColor: '#3ea9f5',
28
29
  // Light mode colors
29
30
  _background: '#ffffff',
30
31
  _textColor: '#1f2937',
@@ -41,6 +42,8 @@ export const styleSpec = {
41
42
  _codeBorder: '#374151',
42
43
  _linkColor: '#818cf8',
43
44
  // tosi-tabs uses these
45
+ _tosiTabsSelectedColor: '#3ea9f5',
46
+ _xinTabsSelectedColor: '#3ea9f5',
44
47
  _tosiTabsBarColor: '#374151',
45
48
  },
46
49
 
@@ -1232,8 +1232,8 @@ export class TJSPlayground extends Component<TJSPlaygroundParts> {
1232
1232
  return
1233
1233
  }
1234
1234
 
1235
- // Show JS output immediately after successful transpilation
1236
- this.parts.outputTabs.value = 0 // JS is first tab (index 0)
1235
+ // Show Docs tab by default; Preview tab takes over if DOM content appears
1236
+ this.parts.outputTabs.value = 3 // Docs (index 3)
1237
1237
 
1238
1238
  this.parts.statusBar.textContent = 'Running...'
1239
1239
 
@@ -1241,14 +1241,14 @@ export class TJSPlayground extends Component<TJSPlaygroundParts> {
1241
1241
  // Log WASM compilation results (WASM is now compiled at transpile time)
1242
1242
  const wasmCompiled = this.lastTranspileResult.wasmCompiled
1243
1243
  if (wasmCompiled && wasmCompiled.length > 0) {
1244
- const success = wasmCompiled.filter((w) => w.success).length
1245
- const failed = wasmCompiled.filter((w) => !w.success).length
1244
+ const success = wasmCompiled.filter((w: any) => w.success).length
1245
+ const failed = wasmCompiled.filter((w: any) => !w.success).length
1246
1246
  if (success > 0) {
1247
1247
  this.log(`WASM: ${success} block(s) compiled at transpile time`)
1248
1248
  }
1249
1249
  if (failed > 0) {
1250
1250
  this.log(`WASM: ${failed} failed (using JS fallback)`)
1251
- for (const w of wasmCompiled.filter((w) => !w.success)) {
1251
+ for (const w of wasmCompiled.filter((w: any) => !w.success)) {
1252
1252
  this.log(` ${w.id}: ${w.error}`)
1253
1253
  }
1254
1254
  }
@@ -77,7 +77,7 @@ async function encrypt(plaintext: string, keyBase64: string): Promise<string> {
77
77
  combined.set(iv)
78
78
  combined.set(new Uint8Array(ciphertext), iv.length)
79
79
 
80
- return bufferToBase64(combined)
80
+ return bufferToBase64(combined.buffer)
81
81
  }
82
82
 
83
83
  async function decrypt(
@@ -129,6 +129,7 @@ export interface UserDoc {
129
129
  apiKeys: {
130
130
  openai?: string
131
131
  anthropic?: string
132
+ gemini?: string
132
133
  deepseek?: string
133
134
  }
134
135
  created: number
@@ -1,30 +1,23 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
- <svg x="0pt" y="0pt" width="48pt" height="48pt" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
2
+ <svg x="0px" y="0px" width="48px" height="48px" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
3
  <!--Generated by AMDN-->
4
- <g id="Layer_1">
5
- <g id="Layer_1-1">
6
- <g id="Layer_1_1">
7
- <g id="Group">
8
- <path id="Path" style="fill:#ff1c24;fill-opacity:1;fill-rule:evenodd;opacity:1;stroke:none;" d="M1,9 C1,4.58172,4.58172,1,9,1 C9,1,39,1,39,1 C43.4183,1,47,4.58172,47,9 C47,9,47,39,47,39 C47,43.4183,43.4183,47,39,47 C39,47,9,47,9,47 C4.58172,47,1,43.4183,1,39 C1,39,1,9,1,9 z"/>
9
- <g id="Group_1">
10
- <path id="Path_1" style="fill:#9e9e9e;fill-opacity:1;fill-rule:nonzero;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M16,29 C16,29,10,31,10,35 C10,39,16,39,16,39"/>
11
- <path id="Path_Copy" style="fill:#9e9e9e;fill-opacity:1;fill-rule:nonzero;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M32.0002,29 C32.0002,29,38.0002,31,38.0002,35 C38.0002,39,32.0002,39,32.0002,39"/>
12
- <path id="Path_2" style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M9,10.1818 C9,7.87226,10.7909,6,13,6 C13,6,35,6,35,6 C37.2091,6,39,7.87226,39,10.1818 C39,10.1818,39,24.8182,39,24.8182 C39,27.1277,37.2091,29,35,29 C35,29,13,29,13,29 C10.7909,29,9,27.1277,9,24.8182 C9,24.8182,9,10.1818,9,10.1818 z"/>
13
- <path id="Path_3" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M24,11 C24,11,24,23,24,23"/>
14
- <path id="Path_4" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M28,15 C28,15,28,17,28,17"/>
15
- <path id="Path_Copy_1" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M20,15 C20,15,20,17,20,17"/>
16
- <path id="Path_5" style="fill:none;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M32,43 C32,43,30,41,30,41 C30,41,28,43,28,43"/>
17
- <path id="Path_Copy_2" style="fill:none;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M20,43 C20,43,18,41,18,41 C18,41,16,43,16,43"/>
18
- <path id="Path_6" style="fill:#e4e4e4;fill-opacity:1;fill-rule:evenodd;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M16,29 C16,29,32,29,32,29 C32,29,32,39,32,39 C32,39,16,39,16,39 C16,39,16,29,16,29 z"/>
19
- </g>
20
- </g>
4
+ <g id="Layer 1">
5
+ <g id="Group">
6
+ <g id="Group">
7
+ <path id="Path 17" style="fill:#3ea9f5;fill-opacity:1;fill-rule:evenodd;opacity:1;stroke:none;" d="M23.9725,47 C23.9725,47,39,47,39,47 C43.4183,47,47,43.4183,47,39 C47,39,47,9,47,9 C47,4.58172,43.4183,1,39,1 C39,1,9,1,9,1 C4.58172,1,1,4.58172,1,9 C1,9,1,39,1,39 C1,41.6412,2.27995,43.9835,4.25342,45.4404 C4.08812,44.8215,4,44.171,4,43.5 C4,39.3579,7.35786,36,11.5,36 C15.1444,36,18.1817,38.5994,18.859,42.0453 C19.0684,42.0154,19.2824,42,19.5,42 C21.9853,42,24,44.0147,24,46.5 C24,46.669,23.9907,46.8358,23.9725,47 z"/>
8
+ <path id="Path 18" style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;opacity:1;stroke:none;" d="M4.25342,45.4404 C4.08812,44.8215,4,44.171,4,43.5 C4,39.3579,7.35786,36,11.5,36 C15.1444,36,18.1817,38.5994,18.859,42.0453 C19.0684,42.0154,19.2824,42,19.5,42 C21.9853,42,24,44.0147,24,46.5 C24,46.669,23.9907,46.8358,23.9725,47 C23.9725,47,9,47,9,47 C7.22294,47,5.58121,46.4206,4.25342,45.4404 z"/>
9
+ </g>
10
+ <path id="Path" style="fill:none;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M35,35 C35,35,32.1716,35,32.1716,35 C32.1716,35,32.1716,37.8284,32.1716,37.8284"/>
11
+ <path id="Path Copy" style="fill:none;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M31,39 C31,39,28.1716,39,28.1716,39 C28.1716,39,28.1716,41.8284,28.1716,41.8284"/>
12
+ <path id="Path Copy" style="fill:#9e9e9e;fill-opacity:1;fill-rule:nonzero;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M7.48047,16 C4.45369,16,2,18.4537,2,21.4805 C2,21.4805,2,21.4805,2,21.4805 C2,23.9765,4.02346,26,6.51953,26 C6.51953,26,6.61997,26,6.61997,26 C7.38213,26,8,26.6179,8,27.38 C8,27.38,8,27.38,8,27.38 C8,29.9316,10.0684,32,12.62,32 C12.62,32,16,32,16,32 C18.5834,32,20.6777,29.9057,20.6777,27.3223 C20.6777,27.3223,20.6777,21.4215,20.6777,21.4215 C20.6777,18.4273,18.2504,16,15.2561,16 C15.2561,16,7.48047,16,7.48047,16 z"/>
13
+ <path id="Path" style="fill:#e4e4e4;fill-opacity:1;fill-rule:evenodd;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M17,29 C17,29,33,29,33,29 C33,29,33,29,33,29 C33,34.5228,28.5228,39,23,39 C23,39,23,39,23,39 C19.6863,39,17,36.3137,17,33 C17,33,17,29,17,29 z"/>
14
+ <path id="Path Copy" style="fill:#9e9e9e;fill-opacity:1;fill-rule:nonzero;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M40.5195,16 C43.5463,16,46,18.4537,46,21.4805 C46,21.4805,46,21.4805,46,21.4805 C46,23.9765,43.9765,26,41.4805,26 C41.4805,26,41.38,26,41.38,26 C40.6179,26,40,26.6179,40,27.38 C40,27.38,40,27.38,40,27.38 C40,29.9316,37.9316,32,35.38,32 C35.38,32,32,32,32,32 C29.4166,32,27.3223,29.9057,27.3223,27.3223 C27.3223,27.3223,27.3223,21.4215,27.3223,21.4215 C27.3223,18.4273,29.7496,16,32.7439,16 C32.7439,16,40.5195,16,40.5195,16 z"/>
15
+ <g id="Group">
16
+ <path id="Path" style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M6,10.1818 C6,7.87226,7.79086,6,10,6 C10,6,32,6,32,6 C34.2091,6,36,7.87226,36,10.1818 C36,10.1818,36,24.8182,36,24.8182 C36,27.1277,34.2091,29,32,29 C32,29,10,29,10,29 C7.79086,29,6,27.1277,6,24.8182 C6,24.8182,6,10.1818,6,10.1818 z"/>
17
+ <path id="Path" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M21,11 C21,11,21,23,21,23"/>
18
+ <path id="Path" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M25,15 C25,15,25,17,25,17"/>
19
+ <path id="Path Copy" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M17,15 C17,15,17,17,17,17"/>
21
20
  </g>
22
21
  </g>
23
- <path id="Path-1" style="fill:#006736;fill-opacity:1;fill-rule:evenodd;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M27,16 C27,16,34,16,34,16 C34,16,34,21,34,21 C34,21,27,21,27,21 C27,21,27,16,27,16 z"/>
24
- <path id="Path-2" style="fill:none;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M21,18 C21,18,21,18,21,18 C21,16.8954,21.8954,16,23,16 C23,16,25,16,25,16 C26.1046,16,27,16.8954,27,18 C27,18,27,18,27,18"/>
25
- <path id="Path_Copy-1" style="fill:#006736;fill-opacity:1;fill-rule:evenodd;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M14,16 C14,16,21,16,21,16 C21,16,21,21,21,21 C21,21,14,21,14,21 C14,21,14,16,14,16 z"/>
26
- <path id="Path_Copy-2" style="fill:#8e7f6d;fill-opacity:1;fill-rule:nonzero;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M7,17 C7,17,12,16,12,16 C12,16,13,21,13,21 C13,21,16,20,16,20 C16,20,25,27,25,27 C25,27,25,39,25,39 C25,39,23,41,23,41 C23,41,6,41,6,41 C6,41,6,23,6,23 C6,23,8,22,8,22 C8,22,7,17,7,17 z"/>
27
- <path id="Compound_Group" style="fill:#c6b199;fill-opacity:1;fill-rule:evenodd;opacity:1;stroke:#000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M21.7198,23.9799 C21.7198,23.9799,30.1325,25.1948,30.1325,25.1948 C30.9524,25.3132,31.5211,26.0738,31.4027,26.8938 C31.4027,26.8938,29.9734,36.7911,29.9734,36.7911 C29.855,37.611,29.0944,38.1797,28.2744,38.0613 C28.2744,38.0613,12.4387,35.7744,12.4387,35.7744 C11.6188,35.656,11.0501,34.8954,11.1685,34.0754 C11.1685,34.0754,12.7407,23.1884,12.7407,23.1884 C12.7407,23.1884,13.0266,21.2089,13.0266,21.2089 C13.145,20.389,13.9056,19.8203,14.7256,19.9387 C14.7256,19.9387,20.664,20.7963,20.664,20.7963 C21.4839,20.9147,22.0526,21.6754,21.9342,22.4953 C21.9342,22.4953,21.7198,23.9799,21.7198,23.9799 z"/>
28
- <path id="Path-3" style="fill:#8e7f6d;fill-opacity:1;fill-rule:nonzero;opacity:1;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-width:2;" d="M41,17 C41,17,36,16,36,16 C36,16,35,21,35,21 C35,21,32,20,32,20 C32,20,23,27,23,27 C23,27,23,39,23,39 C23,39,25,41,25,41 C25,41,42,41,42,41 C42,41,42,23,42,23 C42,23,40,22,40,22 C40,22,41,17,41,17 z"/>
29
22
  </g>
30
23
  </svg>