@cpwc/node-red-contrib-ai-intent 3.1.0-alpha

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 (70) hide show
  1. package/.eslintrc +49 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/node-red-contrib-ai-intent.iml +12 -0
  4. package/.idea/vcs.xml +6 -0
  5. package/LICENSE +21 -0
  6. package/README.md +233 -0
  7. package/call-intent/icons/promotion-icon.svg +8 -0
  8. package/call-intent/index.html +114 -0
  9. package/call-intent/index.js +110 -0
  10. package/constants.js +31 -0
  11. package/database.js +9 -0
  12. package/examples/home-assistant-automation.json +167 -0
  13. package/examples/llm-chat-node-example.json +208 -0
  14. package/examples/openai-call-registered-intent-example.json +174 -0
  15. package/examples/openai-system-node-example.json +178 -0
  16. package/examples/openai-tool-node-example.json +120 -0
  17. package/examples/openai-user-node-exampe.json +234 -0
  18. package/geminiai-chat/geminiai-configuration/index.html +18 -0
  19. package/geminiai-chat/geminiai-configuration/index.js +7 -0
  20. package/geminiai-chat/icons/diamond.svg +8 -0
  21. package/geminiai-chat/icons/gemini-icon.svg +1 -0
  22. package/geminiai-chat/icons/gemini.svg +8 -0
  23. package/geminiai-chat/index.html +189 -0
  24. package/geminiai-chat/index.js +92 -0
  25. package/globalUtils.js +39 -0
  26. package/images/call_register_intent.jpeg +0 -0
  27. package/images/finally.jpg +0 -0
  28. package/images/set-config-node.gif +0 -0
  29. package/llm-chat/AzureOpenAIHelper.js +204 -0
  30. package/llm-chat/ChatGPTHelper.js +197 -0
  31. package/llm-chat/GeminiHelper.js +260 -0
  32. package/llm-chat/OllamaHelper.js +196 -0
  33. package/llm-chat/icons/bot-message-square.svg +1 -0
  34. package/llm-chat/icons/brain-circuit.svg +1 -0
  35. package/llm-chat/icons/chatgpt-icon.svg +7 -0
  36. package/llm-chat/index.html +205 -0
  37. package/llm-chat/index.js +73 -0
  38. package/llm-chat/platform-configuration/index.html +136 -0
  39. package/llm-chat/platform-configuration/index.js +16 -0
  40. package/localai-chat/icons/gem-icon.svg +1 -0
  41. package/localai-chat/icons/llama.svg +8 -0
  42. package/localai-chat/index.html +244 -0
  43. package/localai-chat/index.js +108 -0
  44. package/localai-chat/localai-configuration/index.html +18 -0
  45. package/localai-chat/localai-configuration/index.js +7 -0
  46. package/openai-chat/icons/chatgpt-icon.svg +7 -0
  47. package/openai-chat/index.html +196 -0
  48. package/openai-chat/index.js +58 -0
  49. package/openai-chat/openai-configuration/index.html +18 -0
  50. package/openai-chat/openai-configuration/index.js +7 -0
  51. package/openai-response/index.html +66 -0
  52. package/openai-response/index.js +154 -0
  53. package/openai-system/index.html +68 -0
  54. package/openai-system/index.js +28 -0
  55. package/openai-tool/index.html +57 -0
  56. package/openai-tool/index.js +50 -0
  57. package/openai-user/index.html +76 -0
  58. package/openai-user/index.js +26 -0
  59. package/package.json +49 -0
  60. package/register-intent/icons/register-icon.svg +8 -0
  61. package/register-intent/index.html +195 -0
  62. package/register-intent/index.js +72 -0
  63. package/register-intent/utils.js +10 -0
  64. package/utilities/chat-controller.js +249 -0
  65. package/utilities/chat-ledger.js +122 -0
  66. package/utilities/conversationHistory.js +68 -0
  67. package/utilities/format.js +94 -0
  68. package/utilities/gemini-controller.js +243 -0
  69. package/utilities/global-context.js +30 -0
  70. package/utilities/validateSchema.js +74 -0
@@ -0,0 +1,178 @@
1
+ [
2
+ {
3
+ "id": "8fc448b752df95d3",
4
+ "type": "inject",
5
+ "z": "d312f6d5f62126f3",
6
+ "name": "Ask about boiler status",
7
+ "props": [
8
+ {
9
+ "p": "payload"
10
+ },
11
+ {
12
+ "p": "test",
13
+ "v": "foobar",
14
+ "vt": "str"
15
+ }
16
+ ],
17
+ "repeat": "",
18
+ "crontab": "",
19
+ "once": false,
20
+ "onceDelay": 0.1,
21
+ "topic": "",
22
+ "payload": "",
23
+ "payloadType": "date",
24
+ "x": 220,
25
+ "y": 1160,
26
+ "wires": [
27
+ [
28
+ "e9989674f89d04ad"
29
+ ]
30
+ ]
31
+ },
32
+ {
33
+ "id": "e9989674f89d04ad",
34
+ "type": "OpenAI User",
35
+ "z": "d312f6d5f62126f3",
36
+ "name": "",
37
+ "content": "Are there any boilers i should be concerned about?",
38
+ "x": 250,
39
+ "y": 1200,
40
+ "wires": [
41
+ [
42
+ "00a05563456186da"
43
+ ]
44
+ ]
45
+ },
46
+ {
47
+ "id": "00a05563456186da",
48
+ "type": "OpenAI System",
49
+ "z": "d312f6d5f62126f3",
50
+ "name": "",
51
+ "instruction": "You are an engineer observing the boiler status. \nNormal ranges for boilers are 180 - 250 degrees.\n\nTheses are the boilers and their status:\n\n[\n {{\n \"name\": \"btar1,\n \"temp\": 130.2\n }},\n {{\n \"name\": \"trag32\",\n \"temp\": 212\n }},\n {{\n \"name\": \"simt11\",\n \"temp\": 300.91\n }},\n {{\n \"name\": \"n00p\",\n \"temp\": 250.1\n }},\n {{\n \"name\": \"foobar\",\n \"temp\": 180.8\n }}\n]",
52
+ "x": 520,
53
+ "y": 1200,
54
+ "wires": [
55
+ [
56
+ "f35e1d642fd02513"
57
+ ]
58
+ ]
59
+ },
60
+ {
61
+ "id": "f35e1d642fd02513",
62
+ "type": "OpenAI Tool",
63
+ "z": "d312f6d5f62126f3",
64
+ "name": "",
65
+ "tool": "{\"type\":\"function\",\"function\":{\"name\":\"adjust_boilers\",\"description\":\"Run this function when boilers are too hot or too cool\",\"parameters\":{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\",\"description\":\"name of boiler\"},\"action\":{\"type\":\"string\",\"description\":\"Choose the action appropriate for the boilers\",\"enum\":[\"warm_up\",\"cool_down\"]},\"response\":{\"type\":\"string\",\"description\":\"Explaination of what is happening\"}},\"required\":[\"name\",\"action\",\"response\"]}}}",
66
+ "x": 530,
67
+ "y": 1240,
68
+ "wires": [
69
+ [
70
+ "8e61aa15dbdfa57f"
71
+ ]
72
+ ]
73
+ },
74
+ {
75
+ "id": "2e71ce6e4a9bcc3e",
76
+ "type": "debug",
77
+ "z": "d312f6d5f62126f3",
78
+ "name": "debug 48",
79
+ "active": true,
80
+ "tosidebar": true,
81
+ "console": false,
82
+ "tostatus": false,
83
+ "complete": "true",
84
+ "targetType": "full",
85
+ "statusVal": "",
86
+ "statusType": "auto",
87
+ "x": 740,
88
+ "y": 1320,
89
+ "wires": []
90
+ },
91
+ {
92
+ "id": "aa7f596eea390db8",
93
+ "type": "OpenAI Response",
94
+ "z": "d312f6d5f62126f3",
95
+ "name": "",
96
+ "x": 510,
97
+ "y": 1320,
98
+ "wires": [
99
+ [
100
+ "2e71ce6e4a9bcc3e"
101
+ ]
102
+ ]
103
+ },
104
+ {
105
+ "id": "5260df988ebc6089",
106
+ "type": "inject",
107
+ "z": "d312f6d5f62126f3",
108
+ "name": "Issue Command to fix boilers",
109
+ "props": [
110
+ {
111
+ "p": "payload"
112
+ },
113
+ {
114
+ "p": "test",
115
+ "v": "foobar",
116
+ "vt": "str"
117
+ }
118
+ ],
119
+ "repeat": "",
120
+ "crontab": "",
121
+ "once": false,
122
+ "onceDelay": 0.1,
123
+ "topic": "",
124
+ "payload": "",
125
+ "payloadType": "date",
126
+ "x": 200,
127
+ "y": 1260,
128
+ "wires": [
129
+ [
130
+ "5de6b8ce49a24023"
131
+ ]
132
+ ]
133
+ },
134
+ {
135
+ "id": "5de6b8ce49a24023",
136
+ "type": "OpenAI User",
137
+ "z": "d312f6d5f62126f3",
138
+ "name": "",
139
+ "content": "Please readjust the boilers \nthat are out of range",
140
+ "x": 250,
141
+ "y": 1300,
142
+ "wires": [
143
+ [
144
+ "00a05563456186da"
145
+ ]
146
+ ]
147
+ },
148
+ {
149
+ "id": "c4c0509f726b5c27",
150
+ "type": "comment",
151
+ "z": "d312f6d5f62126f3",
152
+ "name": "Example: OpenAI Tools node can be used to get specific values for actions",
153
+ "info": "",
154
+ "x": 360,
155
+ "y": 1120,
156
+ "wires": []
157
+ },
158
+ {
159
+ "id": "8e61aa15dbdfa57f",
160
+ "type": "OpenAI Chat",
161
+ "z": "d312f6d5f62126f3",
162
+ "name": "",
163
+ "token": "",
164
+ "model": "gpt-3.5-turbo",
165
+ "temperature": 0.7,
166
+ "max_tokens": 1200,
167
+ "top_p": 1,
168
+ "frequency_penalty": 0,
169
+ "presence_penalty": 0,
170
+ "x": 530,
171
+ "y": 1280,
172
+ "wires": [
173
+ [
174
+ "aa7f596eea390db8"
175
+ ]
176
+ ]
177
+ }
178
+ ]
@@ -0,0 +1,120 @@
1
+ [
2
+ {
3
+ "id": "e4635021cdeaacaa",
4
+ "type": "inject",
5
+ "z": "d312f6d5f62126f3",
6
+ "name": "",
7
+ "props": [
8
+ {
9
+ "p": "payload"
10
+ },
11
+ {
12
+ "p": "test",
13
+ "v": "foobar",
14
+ "vt": "str"
15
+ }
16
+ ],
17
+ "repeat": "",
18
+ "crontab": "",
19
+ "once": false,
20
+ "onceDelay": 0.1,
21
+ "topic": "",
22
+ "payload": "",
23
+ "payloadType": "date",
24
+ "x": 220,
25
+ "y": 880,
26
+ "wires": [
27
+ [
28
+ "53e38c029c8507da"
29
+ ]
30
+ ]
31
+ },
32
+ {
33
+ "id": "23d78dc85792fc51",
34
+ "type": "debug",
35
+ "z": "d312f6d5f62126f3",
36
+ "name": "debug 47",
37
+ "active": true,
38
+ "tosidebar": true,
39
+ "console": false,
40
+ "tostatus": false,
41
+ "complete": "true",
42
+ "targetType": "full",
43
+ "statusVal": "",
44
+ "statusType": "auto",
45
+ "x": 460,
46
+ "y": 1040,
47
+ "wires": []
48
+ },
49
+ {
50
+ "id": "53e38c029c8507da",
51
+ "type": "OpenAI User",
52
+ "z": "d312f6d5f62126f3",
53
+ "name": "",
54
+ "content": "What is on the agenda today?",
55
+ "x": 210,
56
+ "y": 920,
57
+ "wires": [
58
+ [
59
+ "62f7c0e77f156c69"
60
+ ]
61
+ ]
62
+ },
63
+ {
64
+ "id": "1069caa745871f7f",
65
+ "type": "OpenAI Chat",
66
+ "z": "d312f6d5f62126f3",
67
+ "name": "",
68
+ "token": "",
69
+ "model": "gpt-3.5-turbo",
70
+ "temperature": 0.7,
71
+ "max_tokens": 1200,
72
+ "top_p": 1,
73
+ "frequency_penalty": 0,
74
+ "presence_penalty": 0,
75
+ "x": 210,
76
+ "y": 1000,
77
+ "wires": [
78
+ [
79
+ "eda369f64ccc7874"
80
+ ]
81
+ ]
82
+ },
83
+ {
84
+ "id": "eda369f64ccc7874",
85
+ "type": "OpenAI Response",
86
+ "z": "d312f6d5f62126f3",
87
+ "name": "",
88
+ "x": 190,
89
+ "y": 1040,
90
+ "wires": [
91
+ [
92
+ "23d78dc85792fc51"
93
+ ]
94
+ ]
95
+ },
96
+ {
97
+ "id": "62f7c0e77f156c69",
98
+ "type": "OpenAI System",
99
+ "z": "d312f6d5f62126f3",
100
+ "name": "",
101
+ "instruction": "You are are alfred, batman's butler. Treat me\nas you would bruce wayne.",
102
+ "x": 200,
103
+ "y": 960,
104
+ "wires": [
105
+ [
106
+ "1069caa745871f7f"
107
+ ]
108
+ ]
109
+ },
110
+ {
111
+ "id": "46538276df96ae02",
112
+ "type": "comment",
113
+ "z": "d312f6d5f62126f3",
114
+ "name": "Example: OpenAI System node gives GPT the context it is Alfred and you are Bruce wayne",
115
+ "info": "",
116
+ "x": 410,
117
+ "y": 840,
118
+ "wires": []
119
+ }
120
+ ]
@@ -0,0 +1,234 @@
1
+ [
2
+ {
3
+ "id": "1fa43f81455fbfaa",
4
+ "type": "GeminiAI Chat",
5
+ "z": "9b143868e984b7d2",
6
+ "name": "",
7
+ "tool_choice": [
8
+ {
9
+ "value": "auto",
10
+ "label": "Automatic"
11
+ },
12
+ {
13
+ "value": "any",
14
+ "label": "Any"
15
+ },
16
+ {
17
+ "value": "none",
18
+ "label": "None"
19
+ }
20
+ ],
21
+ "conversation_id": "",
22
+ "token": "",
23
+ "model": "gemini-1.5-flash",
24
+ "temperature": 0.7,
25
+ "max_tokens": 1200,
26
+ "top_p": 1,
27
+ "top_k": 16,
28
+ "x": 980,
29
+ "y": 1040,
30
+ "wires": [
31
+ [
32
+ "743157a166429126"
33
+ ]
34
+ ]
35
+ },
36
+ {
37
+ "id": "02b5d6d18a1d0464",
38
+ "type": "LocalAI Chat",
39
+ "z": "9b143868e984b7d2",
40
+ "name": "",
41
+ "local_settings": "d2693fb6d73b277d",
42
+ "conversation_id": "",
43
+ "model": "HomeAssistantAI:latest",
44
+ "temperature": 0.7,
45
+ "max_tokens": 1200,
46
+ "top_p": 1,
47
+ "frequency_penalty": 0,
48
+ "presence_penalty": 0,
49
+ "stream": false,
50
+ "keep_alive": 5,
51
+ "seed": 42,
52
+ "json": false,
53
+ "x": 990,
54
+ "y": 1000,
55
+ "wires": [
56
+ [
57
+ "666c8eec91e99263"
58
+ ]
59
+ ]
60
+ },
61
+ {
62
+ "id": "4629835899ef6a94",
63
+ "type": "inject",
64
+ "z": "9b143868e984b7d2",
65
+ "name": "",
66
+ "props": [
67
+ {
68
+ "p": "payload"
69
+ },
70
+ {
71
+ "p": "test",
72
+ "v": "foobar",
73
+ "vt": "str"
74
+ }
75
+ ],
76
+ "repeat": "",
77
+ "crontab": "",
78
+ "once": false,
79
+ "onceDelay": 0.1,
80
+ "topic": "",
81
+ "payload": "",
82
+ "payloadType": "date",
83
+ "x": 620,
84
+ "y": 1040,
85
+ "wires": [
86
+ [
87
+ "34bc5dbf3f85c1c6"
88
+ ]
89
+ ]
90
+ },
91
+ {
92
+ "id": "8c4e6be9d8f809b2",
93
+ "type": "debug",
94
+ "z": "9b143868e984b7d2",
95
+ "name": "debug 44",
96
+ "active": true,
97
+ "tosidebar": true,
98
+ "console": false,
99
+ "tostatus": false,
100
+ "complete": "true",
101
+ "targetType": "full",
102
+ "statusVal": "",
103
+ "statusType": "auto",
104
+ "x": 1340,
105
+ "y": 1040,
106
+ "wires": []
107
+ },
108
+ {
109
+ "id": "34bc5dbf3f85c1c6",
110
+ "type": "OpenAI User",
111
+ "z": "9b143868e984b7d2",
112
+ "name": "",
113
+ "content": "What color is the sky",
114
+ "x": 770,
115
+ "y": 1040,
116
+ "wires": [
117
+ [
118
+ "265bcb5f2a387d15",
119
+ "02b5d6d18a1d0464",
120
+ "1fa43f81455fbfaa"
121
+ ]
122
+ ]
123
+ },
124
+ {
125
+ "id": "265bcb5f2a387d15",
126
+ "type": "OpenAI Chat",
127
+ "z": "9b143868e984b7d2",
128
+ "name": "",
129
+ "tool_choice": "auto",
130
+ "conversation_id": "",
131
+ "token": "",
132
+ "model": "gpt-3.5-turbo",
133
+ "temperature": 0.7,
134
+ "max_tokens": 1200,
135
+ "top_p": 1,
136
+ "frequency_penalty": 0,
137
+ "presence_penalty": 0,
138
+ "x": 980,
139
+ "y": 1080,
140
+ "wires": [
141
+ [
142
+ "1fcf3793f61d08cf"
143
+ ]
144
+ ]
145
+ },
146
+ {
147
+ "id": "743157a166429126",
148
+ "type": "OpenAI Response",
149
+ "z": "9b143868e984b7d2",
150
+ "name": "",
151
+ "x": 1180,
152
+ "y": 1040,
153
+ "wires": [
154
+ [
155
+ "8c4e6be9d8f809b2"
156
+ ]
157
+ ]
158
+ },
159
+ {
160
+ "id": "4aec75bc6fa6f5a8",
161
+ "type": "comment",
162
+ "z": "9b143868e984b7d2",
163
+ "name": "Example: Simple question to GPT, Gemini, and Local LLM with only the OpenAI User node",
164
+ "info": "",
165
+ "x": 990,
166
+ "y": 960,
167
+ "wires": []
168
+ },
169
+ {
170
+ "id": "0dd4a932f110a383",
171
+ "type": "debug",
172
+ "z": "9b143868e984b7d2",
173
+ "name": "debug 45",
174
+ "active": true,
175
+ "tosidebar": true,
176
+ "console": false,
177
+ "tostatus": false,
178
+ "complete": "true",
179
+ "targetType": "full",
180
+ "statusVal": "",
181
+ "statusType": "auto",
182
+ "x": 1340,
183
+ "y": 1080,
184
+ "wires": []
185
+ },
186
+ {
187
+ "id": "1fcf3793f61d08cf",
188
+ "type": "OpenAI Response",
189
+ "z": "9b143868e984b7d2",
190
+ "name": "",
191
+ "x": 1180,
192
+ "y": 1080,
193
+ "wires": [
194
+ [
195
+ "0dd4a932f110a383"
196
+ ]
197
+ ]
198
+ },
199
+ {
200
+ "id": "d72b07737e957317",
201
+ "type": "debug",
202
+ "z": "9b143868e984b7d2",
203
+ "name": "debug 46",
204
+ "active": true,
205
+ "tosidebar": true,
206
+ "console": false,
207
+ "tostatus": false,
208
+ "complete": "true",
209
+ "targetType": "full",
210
+ "statusVal": "",
211
+ "statusType": "auto",
212
+ "x": 1340,
213
+ "y": 1000,
214
+ "wires": []
215
+ },
216
+ {
217
+ "id": "666c8eec91e99263",
218
+ "type": "OpenAI Response",
219
+ "z": "9b143868e984b7d2",
220
+ "name": "",
221
+ "x": 1180,
222
+ "y": 1000,
223
+ "wires": [
224
+ [
225
+ "d72b07737e957317"
226
+ ]
227
+ ]
228
+ },
229
+ {
230
+ "id": "d2693fb6d73b277d",
231
+ "type": "localai-configuration",
232
+ "url": "http://10.0.0.40/"
233
+ }
234
+ ]
@@ -0,0 +1,18 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('geminiai-configuration', {
3
+ category: 'config',
4
+ defaults: {
5
+ api: { value: "", required: true }
6
+ },
7
+ label: function () {
8
+ return "GeminiAI API Token"
9
+ }
10
+ });
11
+ </script>
12
+
13
+ <script type="text/html" data-template-name="geminiai-configuration">
14
+ <div class="form-row">
15
+ <label for="node-config-input-api"><i class="fa fa-bookmark"></i> API Token</label>
16
+ <input type="text" id="node-config-input-api">
17
+ </div>
18
+ </script>
@@ -0,0 +1,7 @@
1
+ module.exports = function (RED) {
2
+ function GeminiAIConfigNode(prop) {
3
+ RED.nodes.createNode(this, prop);
4
+ this.api = prop.api;
5
+ }
6
+ RED.nodes.registerType("geminiai-configuration", GeminiAIConfigNode);
7
+ };
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="100%" height="100%" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
4
+ <use xlink:href="#_Image1" x="0" y="0" width="16px" height="16px"/>
5
+ <defs>
6
+ <image id="_Image1" width="16px" height="16px" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAoklEQVQ4jaWTwRGCMBREXxg52IcMbdCCxWkbtMDZVMCMdejxeRAHRSBh2Jl/yu7m/78JrECt1NMa57B2CDSAwH2JUGQYNAnOPNRafQxVbxWXanREVMst4qv/uCRNhrbjjPi7k59xgloxLusMHBNNPoEW6ICu4B3Tp3Ixr8kY4ZZMZNcSJyZxcnOeeDJO8iEt/oUQQq+2gCGEfrPBgI5EOrsNXu9n7RUmnsUcAAAAAElFTkSuQmCC"/>
7
+ </defs>
8
+ </svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M16 8.016A8.522 8.522 0 008.016 16h-.032A8.521 8.521 0 000 8.016v-.032A8.521 8.521 0 007.984 0h.032A8.522 8.522 0 0016 7.984v.032z" fill="url(#prefix__paint0_radial_980_20147)"/><defs><radialGradient id="prefix__paint0_radial_980_20147" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(16.1326 5.4553 -43.70045 129.2322 1.588 6.503)"><stop offset=".067" stop-color="#9168C0"/><stop offset=".343" stop-color="#5684D1"/><stop offset=".672" stop-color="#1BA1E3"/></radialGradient></defs></svg>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="100%" height="100%" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
4
+ <use xlink:href="#_Image1" x="2.395" y="2.395" width="11.435px" height="11.435px" transform="matrix(0.952912,0,0,0.952912,0,0)"/>
5
+ <defs>
6
+ <image id="_Image1" width="12px" height="12px" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAh0lEQVQokZWRwRWDMAxD5Tw2aQZpd+kCDRt1EugeXYQDn4uBAk7eq462ZMuWFADIwC3qdVFR0l0Skr7nhgXTk6RhFZrZXBm6CXp2lBYxOXn6EUxA8a0bMQNP4EMdo3Ny8uNo+vTZB55bKoGl18HSv0e33oqkx/mtl+DMbAbekogyqCW9brhgAclCo2QRE5bMAAAAAElFTkSuQmCC"/>
7
+ </defs>
8
+ </svg>