@snugdesk/avaya-ipo-widget 0.2.3 → 0.2.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.
- package/fesm2022/snugdesk-avaya-ipo-widget.mjs +532 -171
- package/fesm2022/snugdesk-avaya-ipo-widget.mjs.map +1 -1
- package/index.d.ts +95 -24
- package/package.json +1 -1
- package/src/assets/css/intl-tel-input-dropdown.css +0 -0
- package/src/assets/images/bg-app_color_line.gif +0 -0
- package/src/assets/images/icons/sd-backspace.png +0 -0
- package/src/assets/images/icons/sd-call_failed.gif +0 -0
- package/src/assets/images/logo-avaya_small_color.svg +0 -20
- package/src/assets/images/logo-avaya_small_gray.svg +0 -16
package/index.d.ts
CHANGED
|
@@ -62,6 +62,9 @@ declare class AvayaIPOService {
|
|
|
62
62
|
getActiveCallCount(): number;
|
|
63
63
|
setLastIncomingCall(callId: string, farEndNumber: string): void;
|
|
64
64
|
private startRingTone;
|
|
65
|
+
private ringRetryHandler;
|
|
66
|
+
private armRingRetryOnGesture;
|
|
67
|
+
private disarmRingRetry;
|
|
65
68
|
private stopRingTone;
|
|
66
69
|
private agentId;
|
|
67
70
|
private loginStatusSubject;
|
|
@@ -177,12 +180,18 @@ declare class EntitiesSearchService {
|
|
|
177
180
|
private http;
|
|
178
181
|
private authenticationService;
|
|
179
182
|
private nameCache;
|
|
183
|
+
private entityIdCache;
|
|
180
184
|
constructor(http: HttpClient, authenticationService: AuthenticationService);
|
|
181
185
|
fetchContacts(tenantId: string, size?: number, searchAfter?: [string, string]): Promise<any>;
|
|
182
186
|
searchByPhone(tenantId: string, phoneNumber: string, size?: number): Promise<any>;
|
|
183
187
|
searchEntities(tenantId: string, query: string, size?: number, from?: number): Promise<any>;
|
|
184
188
|
getCachedName(tenantId: string, phoneNumber: string): string | null;
|
|
185
189
|
lookupNameByPhone(tenantId: string, phoneNumber: string, size?: number): Promise<string | null>;
|
|
190
|
+
/** Resolve the entity (id + name) matching a phone number; both are cached per tenant+number. */
|
|
191
|
+
lookupEntityByPhone(tenantId: string, phoneNumber: string, size?: number): Promise<{
|
|
192
|
+
id: string | null;
|
|
193
|
+
name: string | null;
|
|
194
|
+
}>;
|
|
186
195
|
private postEntities;
|
|
187
196
|
private cacheKey;
|
|
188
197
|
private ensureWildcard;
|
|
@@ -212,6 +221,9 @@ declare class AvayaIPOWidgetComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
212
221
|
*/
|
|
213
222
|
displayMode: 'popup' | 'standalone';
|
|
214
223
|
configurationMode?: string;
|
|
224
|
+
/** Recording upload strategy: 'complete' (one upload at call end) or 'chunked' (live-streamed
|
|
225
|
+
* over the recording WebSocket, survives a dead tab). Defaults to APP_CONFIG.RECORDING_UPLOAD_MODE. */
|
|
226
|
+
recordingUploadMode?: 'complete' | 'chunked';
|
|
215
227
|
avayaIPOServerIP?: string;
|
|
216
228
|
avayaIPOServerPort?: number;
|
|
217
229
|
avayaIPOServerStunServerIP?: string;
|
|
@@ -248,8 +260,7 @@ declare class AvayaIPOWidgetComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
248
260
|
number: string;
|
|
249
261
|
name: string | null;
|
|
250
262
|
}>;
|
|
251
|
-
readonly
|
|
252
|
-
readonly widgetVersion: "0.2.3";
|
|
263
|
+
readonly widgetVersion: "0.2.4";
|
|
253
264
|
isReconnectingInProgress: boolean;
|
|
254
265
|
isFailoverInProgress: boolean;
|
|
255
266
|
isFailbackInProgress: boolean;
|
|
@@ -270,6 +281,9 @@ declare class AvayaIPOWidgetComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
270
281
|
hideTabs: boolean;
|
|
271
282
|
darkModeEnabled: boolean;
|
|
272
283
|
activeCallNumber: string | null;
|
|
284
|
+
/** Entity id of the current call's counterpart (resolved via OpenSearch); sent with the
|
|
285
|
+
* chunked-recording socket so chunks land under <tenantId>/<entityId>/avaya-ipo-chunks/. */
|
|
286
|
+
activeCallEntityId: string | null;
|
|
273
287
|
incomingCallName: string | null;
|
|
274
288
|
incomingNameResolved: boolean;
|
|
275
289
|
activeCallName: string | null;
|
|
@@ -337,7 +351,7 @@ declare class AvayaIPOWidgetComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
337
351
|
private clearSession;
|
|
338
352
|
private loadAwlScript;
|
|
339
353
|
static ɵfac: i0.ɵɵFactoryDeclaration<AvayaIPOWidgetComponent, never>;
|
|
340
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<AvayaIPOWidgetComponent, "snugdesk-avaya-ipo-widget", never, { "isVisible": { "alias": "isVisible"; "required": false; }; "displayMode": { "alias": "displayMode"; "required": false; }; "configurationMode": { "alias": "configurationMode"; "required": false; }; "avayaIPOServerIP": { "alias": "avayaIPOServerIP"; "required": false; }; "avayaIPOServerPort": { "alias": "avayaIPOServerPort"; "required": false; }; "avayaIPOServerStunServerIP": { "alias": "avayaIPOServerStunServerIP"; "required": false; }; "avayaIPOServerStunServerPort": { "alias": "avayaIPOServerStunServerPort"; "required": false; }; "avayaIPOServerTurnServerIP": { "alias": "avayaIPOServerTurnServerIP"; "required": false; }; "avayaIPOServerTurnServerPort": { "alias": "avayaIPOServerTurnServerPort"; "required": false; }; "token": { "alias": "token"; "required": false; }; "tenantId": { "alias": "tenantId"; "required": false; }; "userId": { "alias": "userId"; "required": false; }; "extension": { "alias": "extension"; "required": false; }; "password": { "alias": "password"; "required": false; }; "showHistory": { "alias": "showHistory"; "required": false; }; "showContacts": { "alias": "showContacts"; "required": false; }; }, { "notificationEvent": "notificationEvent"; "incomingCall": "incomingCall"; }, never, never, false, never>;
|
|
354
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AvayaIPOWidgetComponent, "snugdesk-avaya-ipo-widget", never, { "isVisible": { "alias": "isVisible"; "required": false; }; "displayMode": { "alias": "displayMode"; "required": false; }; "configurationMode": { "alias": "configurationMode"; "required": false; }; "recordingUploadMode": { "alias": "recordingUploadMode"; "required": false; }; "avayaIPOServerIP": { "alias": "avayaIPOServerIP"; "required": false; }; "avayaIPOServerPort": { "alias": "avayaIPOServerPort"; "required": false; }; "avayaIPOServerStunServerIP": { "alias": "avayaIPOServerStunServerIP"; "required": false; }; "avayaIPOServerStunServerPort": { "alias": "avayaIPOServerStunServerPort"; "required": false; }; "avayaIPOServerTurnServerIP": { "alias": "avayaIPOServerTurnServerIP"; "required": false; }; "avayaIPOServerTurnServerPort": { "alias": "avayaIPOServerTurnServerPort"; "required": false; }; "token": { "alias": "token"; "required": false; }; "tenantId": { "alias": "tenantId"; "required": false; }; "userId": { "alias": "userId"; "required": false; }; "extension": { "alias": "extension"; "required": false; }; "password": { "alias": "password"; "required": false; }; "showHistory": { "alias": "showHistory"; "required": false; }; "showContacts": { "alias": "showContacts"; "required": false; }; }, { "notificationEvent": "notificationEvent"; "incomingCall": "incomingCall"; }, never, never, false, never>;
|
|
341
355
|
}
|
|
342
356
|
|
|
343
357
|
declare class CallHistoryComponent implements OnInit {
|
|
@@ -382,9 +396,6 @@ declare class CallHistoryComponent implements OnInit {
|
|
|
382
396
|
selectFromHistory(item: any): void;
|
|
383
397
|
private resolveDialable;
|
|
384
398
|
private resolveName;
|
|
385
|
-
private formatDialOutFromInput;
|
|
386
|
-
private getTenantIdFromSession;
|
|
387
|
-
private getUserIdFromSession;
|
|
388
399
|
getPhoneDisplay(item: any): string;
|
|
389
400
|
getPhoneBadge(item: any): string;
|
|
390
401
|
private getInitials;
|
|
@@ -398,28 +409,47 @@ type TranscriptLine = {
|
|
|
398
409
|
speaker?: string;
|
|
399
410
|
text?: string;
|
|
400
411
|
};
|
|
401
|
-
|
|
402
|
-
|
|
412
|
+
/**
|
|
413
|
+
* Shows the same AI call analysis as snugdesk-app's conversation view: the data is read
|
|
414
|
+
* from the Interaction record (metadata.aiAnalysis), which the server-side pipeline fills
|
|
415
|
+
* after the recording is uploaded — no client-side transcription is run here.
|
|
416
|
+
*/
|
|
417
|
+
declare class CallDetailsComponent implements OnChanges {
|
|
418
|
+
private appSync;
|
|
403
419
|
call: any;
|
|
404
420
|
transcriptLines: TranscriptLine[];
|
|
421
|
+
conversationSummary: string[];
|
|
422
|
+
nextActions: string[];
|
|
423
|
+
keyConcerns: string[];
|
|
424
|
+
callType: string;
|
|
425
|
+
customerIntent: string;
|
|
426
|
+
customerSentiment: string;
|
|
427
|
+
aiConfidenceScore: number | null;
|
|
405
428
|
summaryText: string;
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
429
|
+
aiProcessingStatus: string;
|
|
430
|
+
hasAnalysis: boolean;
|
|
431
|
+
isRefreshing: boolean;
|
|
432
|
+
refreshError: string;
|
|
409
433
|
isTranscriptFullscreen: boolean;
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
434
|
+
private readonly GET_INTERACTION_QUERY;
|
|
435
|
+
constructor(appSync: AppSyncHelperService);
|
|
436
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
437
|
+
get isAnalysisPending(): boolean;
|
|
413
438
|
getBadge(): string;
|
|
414
439
|
getDisplayName(): string;
|
|
415
440
|
getPhone(): string;
|
|
416
441
|
getTranscriptSpeaker(line: TranscriptLine): string;
|
|
417
|
-
|
|
442
|
+
getSentimentEmoji(): string;
|
|
443
|
+
/** Re-read the Interaction record (the AI pipeline fills metadata.aiAnalysis asynchronously). */
|
|
444
|
+
refreshAnalysis(): Promise<void>;
|
|
445
|
+
toggleTranscriptFullscreen(): void;
|
|
446
|
+
/** Pull the structured AI analysis off the interaction's metadata — same shape snugdesk-app reads. */
|
|
447
|
+
private parseAnalysisFromCall;
|
|
448
|
+
private normalizeText;
|
|
449
|
+
private normalizeBulletItems;
|
|
418
450
|
private normalizeTranscript;
|
|
419
|
-
getBehaviorEmoji(): string;
|
|
420
451
|
private parseSpeakerLine;
|
|
421
|
-
|
|
422
|
-
private getRecordingFilename;
|
|
452
|
+
private safeParse;
|
|
423
453
|
static ɵfac: i0.ɵɵFactoryDeclaration<CallDetailsComponent, never>;
|
|
424
454
|
static ɵcmp: i0.ɵɵComponentDeclaration<CallDetailsComponent, "app-call-details", never, { "call": { "alias": "call"; "required": false; }; }, {}, never, never, false, never>;
|
|
425
455
|
}
|
|
@@ -508,7 +538,7 @@ declare class SettingsComponent implements OnInit, OnDestroy {
|
|
|
508
538
|
logout: EventEmitter<void>;
|
|
509
539
|
audioInputs: MediaDeviceInfo[];
|
|
510
540
|
audioOutputs: MediaDeviceInfo[];
|
|
511
|
-
readonly widgetVersion: "0.2.
|
|
541
|
+
readonly widgetVersion: "0.2.4";
|
|
512
542
|
ngOnInit(): void;
|
|
513
543
|
onLogout(): void;
|
|
514
544
|
onToggleDarkMode(): void;
|
|
@@ -544,8 +574,12 @@ interface CallMetadata {
|
|
|
544
574
|
agentId: string;
|
|
545
575
|
phoneNumber: string;
|
|
546
576
|
callId: string;
|
|
577
|
+
/** Entity id of the call counterpart, when the widget has resolved one (chunked recordings
|
|
578
|
+
* use it so chunks land under <tenantId>/<entityId>/avaya-ipo-chunks/). */
|
|
579
|
+
entityId?: string | null;
|
|
547
580
|
}
|
|
548
581
|
|
|
582
|
+
type RecordingUploadMode = 'complete' | 'chunked';
|
|
549
583
|
interface RecordingSession {
|
|
550
584
|
audioContext: AudioContext;
|
|
551
585
|
recordingStream: MediaStreamAudioDestinationNode;
|
|
@@ -555,6 +589,19 @@ interface RecordingSession {
|
|
|
555
589
|
chunks: Blob[];
|
|
556
590
|
mimeType: string;
|
|
557
591
|
uploaded: boolean;
|
|
592
|
+
mode: RecordingUploadMode;
|
|
593
|
+
socket?: WebSocket | null;
|
|
594
|
+
seq: number;
|
|
595
|
+
pendingChunks: string[];
|
|
596
|
+
sentAny: boolean;
|
|
597
|
+
reconnectTimer?: any;
|
|
598
|
+
reconnectAttempts: number;
|
|
599
|
+
sourceNodes: AudioNode[];
|
|
600
|
+
/** Index into `chunks` up to which slices have been streamed (rewound to 0 on reconnect). */
|
|
601
|
+
streamCursor: number;
|
|
602
|
+
pumping: boolean;
|
|
603
|
+
everConnected: boolean;
|
|
604
|
+
completedSent: boolean;
|
|
558
605
|
}
|
|
559
606
|
declare class RecordingManagerService {
|
|
560
607
|
private http;
|
|
@@ -562,13 +609,34 @@ declare class RecordingManagerService {
|
|
|
562
609
|
private readonly MIME_TYPE_PREFERRED;
|
|
563
610
|
private readonly MIME_TYPE_FALLBACK;
|
|
564
611
|
private readonly TIMESLICE_MS;
|
|
612
|
+
private readonly CHUNKED_TIMESLICE_MS;
|
|
613
|
+
private readonly CHUNKED_AUDIO_BPS;
|
|
614
|
+
private readonly MAX_WS_DATA_CHARS;
|
|
565
615
|
private readonly AUDIO_CONTEXT_CLOSE_DELAY_MS;
|
|
616
|
+
private readonly SOCKET_RECONNECT_DELAY_MS;
|
|
617
|
+
private readonly CALL_COMPLETED_DELAY_MS;
|
|
618
|
+
private readonly SOCKET_MAX_RECONNECT_ATTEMPTS;
|
|
619
|
+
private readonly SOCKET_FINALIZE_GRACE_MS;
|
|
566
620
|
private readonly RECORDING_API_URL;
|
|
621
|
+
private readonly RECORDING_WS_URL;
|
|
567
622
|
constructor(http: HttpClient);
|
|
568
|
-
startRecording(localMediaStream: MediaStream, remoteMediaStream: MediaStream, metadata: CallMetadata): RecordingSession | undefined;
|
|
623
|
+
startRecording(localMediaStream: MediaStream, remoteMediaStream: MediaStream, metadata: CallMetadata, mode?: RecordingUploadMode): RecordingSession | undefined;
|
|
569
624
|
getSession(callId: string): RecordingSession | undefined;
|
|
570
625
|
stopRecording(callId: string): void;
|
|
571
626
|
private finalizeRecording;
|
|
627
|
+
/**
|
|
628
|
+
* Rewire fresh local/remote streams into the SAME recording destination. The MediaRecorder (and
|
|
629
|
+
* therefore the single WebM byte stream, the socket and the seq counter) continue uninterrupted —
|
|
630
|
+
* restarting the recorder would inject a second WebM header mid-file and break playback of the
|
|
631
|
+
* stitched recording.
|
|
632
|
+
*/
|
|
633
|
+
private rebindMedia;
|
|
634
|
+
private openRecordingSocket;
|
|
635
|
+
/** Stream session.chunks in strict order; safe to call repeatedly (single active pump). */
|
|
636
|
+
private pumpChunks;
|
|
637
|
+
private streamChunk;
|
|
638
|
+
private flushPendingChunks;
|
|
639
|
+
private finalizeChunked;
|
|
572
640
|
private uploadCallRecording;
|
|
573
641
|
private convertBlobToBase64;
|
|
574
642
|
private generateFilename;
|
|
@@ -618,7 +686,7 @@ declare class TranscriptionStreamService implements OnDestroy {
|
|
|
618
686
|
static ɵprov: i0.ɵɵInjectableDeclaration<TranscriptionStreamService>;
|
|
619
687
|
}
|
|
620
688
|
|
|
621
|
-
declare class PhoneComponent implements OnInit, AfterViewInit,
|
|
689
|
+
declare class PhoneComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
622
690
|
private cdr;
|
|
623
691
|
private formBuilder;
|
|
624
692
|
private avayaIpoService;
|
|
@@ -643,6 +711,9 @@ declare class PhoneComponent implements OnInit, AfterViewInit, OnChanges, OnDest
|
|
|
643
711
|
turnIp?: string;
|
|
644
712
|
turnPort?: number;
|
|
645
713
|
configurationMode?: string;
|
|
714
|
+
recordingUploadMode?: 'complete' | 'chunked';
|
|
715
|
+
/** Entity id of the call counterpart (resolved by the shell) — included in recording metadata. */
|
|
716
|
+
entityId?: string | null;
|
|
646
717
|
makeCallEv: EventEmitter<string>;
|
|
647
718
|
endCallEv: EventEmitter<void>;
|
|
648
719
|
audioElement: any;
|
|
@@ -662,7 +733,6 @@ declare class PhoneComponent implements OnInit, AfterViewInit, OnChanges, OnDest
|
|
|
662
733
|
private pendingTranscriptionCallId;
|
|
663
734
|
private pendingTranscriptionAllowBinary;
|
|
664
735
|
private lastPartialIndex;
|
|
665
|
-
private pendingIncomingCall;
|
|
666
736
|
dialForm: FormGroup;
|
|
667
737
|
directoryForm: FormGroup;
|
|
668
738
|
showDirectoryPhonebook: boolean;
|
|
@@ -709,7 +779,6 @@ declare class PhoneComponent implements OnInit, AfterViewInit, OnChanges, OnDest
|
|
|
709
779
|
get isConnecting(): boolean;
|
|
710
780
|
constructor(cdr: ChangeDetectorRef, formBuilder: FormBuilder, avayaIpoService: AvayaIPOService, authenticationService: AuthenticationService, recordingManagerService: RecordingManagerService, transcriptionStreamService: TranscriptionStreamService);
|
|
711
781
|
ngOnInit(): void;
|
|
712
|
-
ngOnChanges(changes: SimpleChanges): void;
|
|
713
782
|
ngAfterViewInit(): void;
|
|
714
783
|
ngOnDestroy(): void;
|
|
715
784
|
makeCall(): void;
|
|
@@ -780,8 +849,10 @@ declare class PhoneComponent implements OnInit, AfterViewInit, OnChanges, OnDest
|
|
|
780
849
|
private formatDialOutFromInput;
|
|
781
850
|
private formatTransferTargetFromInput;
|
|
782
851
|
private startRecordingForCall;
|
|
852
|
+
/** Per-embed [recordingUploadMode] wins; otherwise the APP_CONFIG default applies. */
|
|
853
|
+
private resolvedRecordingMode;
|
|
783
854
|
static ɵfac: i0.ɵɵFactoryDeclaration<PhoneComponent, never>;
|
|
784
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<PhoneComponent, "app-phone", never, { "contacts": { "alias": "contacts"; "required": false; }; "tenantId": { "alias": "tenantId"; "required": false; }; "agentId": { "alias": "agentId"; "required": false; }; "isActiveCall": { "alias": "isActiveCall"; "required": false; }; "activeCallNumber": { "alias": "activeCallNumber"; "required": false; }; "incomingCallName": { "alias": "incomingCallName"; "required": false; }; "incomingNameResolved": { "alias": "incomingNameResolved"; "required": false; }; "activeCallName": { "alias": "activeCallName"; "required": false; }; "serverIp": { "alias": "serverIp"; "required": false; }; "serverPort": { "alias": "serverPort"; "required": false; }; "stunIp": { "alias": "stunIp"; "required": false; }; "stunPort": { "alias": "stunPort"; "required": false; }; "turnIp": { "alias": "turnIp"; "required": false; }; "turnPort": { "alias": "turnPort"; "required": false; }; "configurationMode": { "alias": "configurationMode"; "required": false; }; }, { "callScreenChange": "callScreenChange"; "makeCallEv": "makeCallEv"; "endCallEv": "endCallEv"; }, never, never, false, never>;
|
|
855
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PhoneComponent, "app-phone", never, { "contacts": { "alias": "contacts"; "required": false; }; "tenantId": { "alias": "tenantId"; "required": false; }; "agentId": { "alias": "agentId"; "required": false; }; "isActiveCall": { "alias": "isActiveCall"; "required": false; }; "activeCallNumber": { "alias": "activeCallNumber"; "required": false; }; "incomingCallName": { "alias": "incomingCallName"; "required": false; }; "incomingNameResolved": { "alias": "incomingNameResolved"; "required": false; }; "activeCallName": { "alias": "activeCallName"; "required": false; }; "serverIp": { "alias": "serverIp"; "required": false; }; "serverPort": { "alias": "serverPort"; "required": false; }; "stunIp": { "alias": "stunIp"; "required": false; }; "stunPort": { "alias": "stunPort"; "required": false; }; "turnIp": { "alias": "turnIp"; "required": false; }; "turnPort": { "alias": "turnPort"; "required": false; }; "configurationMode": { "alias": "configurationMode"; "required": false; }; "recordingUploadMode": { "alias": "recordingUploadMode"; "required": false; }; "entityId": { "alias": "entityId"; "required": false; }; }, { "callScreenChange": "callScreenChange"; "makeCallEv": "makeCallEv"; "endCallEv": "endCallEv"; }, never, never, false, never>;
|
|
785
856
|
}
|
|
786
857
|
|
|
787
858
|
declare class PhoneIdleComponent {
|
package/package.json
CHANGED
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,20 +0,0 @@
|
|
|
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 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1080" height="1080" viewBox="0 0 1080 1080" xml:space="preserve">
|
|
4
|
-
<desc>Created with Fabric.js 5.2.4</desc>
|
|
5
|
-
<defs>
|
|
6
|
-
</defs>
|
|
7
|
-
<rect x="0" y="0" width="100%" height="100%" fill="transparent"></rect>
|
|
8
|
-
<g transform="matrix(1 0 0 1 540 540)" id="46946dc3-9491-43cb-8fe7-5b8ffbba78af" >
|
|
9
|
-
<rect style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1; visibility: hidden;" vector-effect="non-scaling-stroke" x="-540" y="-540" rx="0" ry="0" width="1080" height="1080" />
|
|
10
|
-
</g>
|
|
11
|
-
<g transform="matrix(1 0 0 1 540 540)" id="863c060c-d63b-4daf-a3bc-022136480777" >
|
|
12
|
-
</g>
|
|
13
|
-
<g transform="matrix(1 0 0 1 540 540)" id="facf6309-efdf-434e-a753-661bb2577e88" >
|
|
14
|
-
<polygon style="stroke: rgb(0,0,0); stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(218,40,28); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" points="-232.07,221.69 106.75,221.69 161.6,357.36 -295.67,357.36 -368.7,513.14 -570.6,513.14 -69.8,-513.14 69.88,-513.14 570.6,513.14 368.77,513.14 -0.04,-279.29 -232.07,221.69 -232.07,221.69 -232.07,221.69 " />
|
|
15
|
-
</g>
|
|
16
|
-
<g transform="matrix(NaN NaN NaN NaN 0 0)" >
|
|
17
|
-
<g style="" >
|
|
18
|
-
</g>
|
|
19
|
-
</g>
|
|
20
|
-
</svg>
|
|
@@ -1,16 +0,0 @@
|
|
|
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 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1080" height="1080" viewBox="0 0 1080 1080" xml:space="preserve">
|
|
4
|
-
<desc>Created with Fabric.js 5.2.4</desc>
|
|
5
|
-
<defs>
|
|
6
|
-
</defs>
|
|
7
|
-
<rect x="0" y="0" width="100%" height="100%" fill="transparent"></rect>
|
|
8
|
-
<g transform="matrix(1 0 0 1 540 540)" id="46946dc3-9491-43cb-8fe7-5b8ffbba78af" >
|
|
9
|
-
<rect style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1; visibility: hidden;" vector-effect="non-scaling-stroke" x="-540" y="-540" rx="0" ry="0" width="1080" height="1080" />
|
|
10
|
-
</g>
|
|
11
|
-
<g transform="matrix(1 0 0 1 540 540)" id="863c060c-d63b-4daf-a3bc-022136480777" >
|
|
12
|
-
</g>
|
|
13
|
-
<g transform="matrix(1 0 0 1 540 540)" id="facf6309-efdf-434e-a753-661bb2577e88" >
|
|
14
|
-
<polygon style="stroke: rgb(0,0,0); stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(136,136,136); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" points="-232.07,221.69 106.75,221.69 161.6,357.36 -295.67,357.36 -368.7,513.14 -570.6,513.14 -69.8,-513.14 69.88,-513.14 570.6,513.14 368.77,513.14 -0.04,-279.29 -232.07,221.69 -232.07,221.69 -232.07,221.69 " />
|
|
15
|
-
</g>
|
|
16
|
-
</svg>
|