PageSourceSearch

https://sargarmirooz.ir/wp-content/plugins/aikit/includes/js/chatbot.js?ver=4.17.5

js sargarmirooz.ir collected 2026-10-01 14:39:02 UTC 14,797 bytes, 423 lines download raw bytes

1"use strict";
2jQuery(function($) {
3
4    let mediaRecorder;
5    let silenceThreshold = 1; // Adjust this value based on your environment
6    let silenceCheckInterval;
7    let recordingStartTimestamp;
8    let mediaStream;
9    const minRecordingDuration = 4000;
10    const maxRecordingDuration = 30000;
11    let isRecording = false;
12
13    const startRecordingButton = $("#aikit-voice-button");
14    // const audioPlayer = document.getElementById('audioPlayer');
15
16    startRecordingButton.click(function (event) {
17        event.preventDefault();
18
19        if (mediaStream == null) {
20            navigator.mediaDevices.getUserMedia({audio: true})
21                .then((stream) => {
22                    mediaStream = stream;
23                    handleRecording();
24                })
25                .catch((error) => {
26                    // get data-validation-no-mic attribute on .aikit-chat-widget and show the error
27                    let message = $(".aikit-chat-widget").data('validation-no-mic');
28                    alert(message);
29                });
30        } else {
31            stopRecording();
32        }
33    });
34
35    const handleRecording = () => {
36
37        isRecording = true;
38
39        const audioContext = new AudioContext();
40        const mediaStreamSource = audioContext.createMediaStreamSource(mediaStream);
41        const analyser = audioContext.createAnalyser();
42        mediaStreamSource.connect(analyser);
43
44        // mediaRecorder = new MediaRecorder(mediaStream);
45        mediaRecorder = new RecordRTC(mediaStream, {
46            type: 'audio',
47            mimeType: 'audio/webm',
48            numberOfAudioChannels: 1,
49            recorderType: RecordRTC.StereoAudioRecorder,
50            checkForInactiveTracks: true,
51            desiredSampRate: 16000,
52        });
53
54        mediaRecorder.startRecording();
55
56        recordingStartTimestamp = Date.now();
57
58        // Delay the start of silence checking
59        setTimeout(() => {
60            silenceCheckInterval = setInterval(checkSilence, 180); // Adjust the interval as needed
61        }, minRecordingDuration);
62
63        startRecordingButton.attr('data-recording', '1');
64
65        const checkSilence = () => {
66            const dataArray = new Uint8Array(analyser.frequencyBinCount);
67            analyser.getByteFrequencyData(dataArray);
68
69            const average = dataArray.reduce((acc, val) => acc + val, 0) / dataArray.length;
70
71            if (
72                (average <= silenceThreshold && (Date.now() - recordingStartTimestamp) > minRecordingDuration) ||
73                ((Date.now() - recordingStartTimestamp) > maxRecordingDuration)
74            ) {
75                stopRecording();
76            }
77
78        };
79    };
80
81    const stopRecording = () => {
82        if (!isRecording) {
83            return;
84        }
85
86        clearInterval(silenceCheckInterval);
87        mediaRecorder.stopRecording(() => {
88            isRecording = false;
89            let audioBlob = mediaRecorder.getBlob();
90
91            sendAudioToServer(audioBlob);
92            mediaStream.getTracks().forEach(track => track.stop());
93
94            startRecordingButton.removeAttr('data-recording');
95
96            mediaStream = null;
97        });
98    }
99
100    const sendAudioToServer = (audioBlob) => {
101
102        $(".aikit-mic-icon").hide();
103        $(".aikit-voice-button .aikit-loading").attr('data-visible', '1');
104
105        let formData = new FormData();
106
107        let file = new File([audioBlob], "audio.webm", { type: 'audio/webm' });
108
109        formData.append('audio', file);
110
111        $.ajax({
112            url: aikitChatbot.siteUrl + '/?rest_route=/aikit/chatbot/v1/speech-to-text',
113            type: 'POST',
114            data: formData,
115            processData: false,
116            contentType: false,
117            success: function(response) {
118                $("#aikit-new-message-textarea").val($("#aikit-new-message-textarea").val() + response.message);
119                $(".aikit-mic-icon").show();
120                $(".aikit-voice-button .aikit-loading").attr('data-visible', '0');
121            },
122            error: function(error) {
123                alert(error);
124
125                $(".aikit-mic-icon").show();
126                $(".aikit-voice-button .aikit-loading").attr('data-visible', '0');
127            }
128        });
129    };
130
131
132    aikitChatbot.previousMessages = [];
133    let isLivePreview = false;
134
135    // deactivate all inputs inside .aikit-deactivated-form class
136    $(".aikit-deactivated-form *").prop('disabled', true);
137
138    $(".aikit-chatbot-send-button").click(function (event) {
139        event.preventDefault();
140
141        sendChatbotMessage();
142    });
143
144    // on enter key press, send the message
145    $("#aikit-new-message-textarea").keypress(function (event) {
146        // if shift key is pressed, do nothing
147        if (event.shiftKey) {
148            return;
149        }
150
151        if (event.keyCode === 13) {
152            event.preventDefault();
153            sendChatbotMessage();
154        }
155    });
156
157    $(".aikit-open-chat-button").click(function(){
158        $(".aikit-chat-container").fadeIn(100, function () {
159            $(".aikit-open-chat-button").fadeOut(100);
160            $(".aikit-chatbot-send-button").fadeIn(100);
161            $(".aikit-chat-widget").addClass('aikit-open');
162        });
163
164    });
165    $(".aikit-exit-chat").click(function(){
166        $(".aikit-chat-container").fadeOut(100, function () {
167            $(".aikit-open-chat-button").fadeIn(100);
168            $(".aikit-chatbot-send-button").fadeOut(100);
169            $(".aikit-chat-widget").removeClass('aikit-open');
170        });
171    });
172
173    if ($('.aikit-chat-widget').data('default-view') === 'collapsed') {
174        $(".aikit-chat-container").hide();
175    } else {
176        $(".aikit-open-chat-button").hide();
177        $(".aikit-chat-widget").addClass('aikit-open');
178    }
179
180    const sendChatbotMessage = () => {
181        let message = $("#aikit-new-message-textarea").val();
182
183        if (message === '') {
184            return;
185        }
186
187        if ($(".aikit-chatbot-send-button").prop('disabled')) {
188            return;
189        }
190
191        // deactivate the send button
192        $(".aikit-chatbot-send-button").prop('disabled', true);
193        $(".aikit-chatbot-send-button").css('opacity', '0.5');
194
195        addMessageToChat(message, "reply");
196
197        let loading = $('<div class="aikit-message aikit-message-bot">\n' +
198            '                                    <span class="aikit-message-content">\n' +
199            '                                        <span class="aikit-typing">\n' +
200            '                                            <span class="aikit-dot"></span>\n' +
201            '                                            <span class="aikit-dot"></span>\n' +
202            '                                            <span class="aikit-dot"></span>\n' +
203            '                                        </span>\n' +
204            '                                    </span>\n' +
205            '                                </div>');
206
207        $("#aikit-messages").append(loading);
208        loading.hide().fadeIn(300);
209
210        // scroll to bottom of the chat
211        $("#aikit-conversation").animate({ scrollTop: $("#aikit-conversation").prop("scrollHeight")}, 50);
212
213        if (isLivePreview) {
214            // add a test message
215            // wait 1 second
216            setTimeout(function () {
217                loading.remove();
218                addMessageToChat("This is a test message from the live preview.");
219                // reactivate the send button
220                $(".aikit-chatbot-send-button").prop('disabled', false);
221
222                $(".aikit-chatbot-send-button").css('opacity', '1');
223
224            }, 2000);
225
226            $("#aikit-new-message-textarea").val('');
227            return;
228        }
229
230        $.ajax({
231            type: "POST",
232            url: aikitChatbot.siteUrl + '/?rest_route=/aikit/chatbot/v1/chat',
233            data: JSON.stringify({
234                message: message,
235                // json previous messages
236                previous_messages: JSON.stringify(aikitChatbot.previousMessages),
237                page_content: aikitChatbot.pageContent,
238                chat_id: $(".aikit-chat-widget").data('chat-id'),
239            }),
240            dataType: "json",
241            encode: true,
242            headers: {
243                'Content-Type': 'application/json',
244                'X-WP-Nonce': aikitChatbot.nonce,
245            },
246        }).done(function (data) {
247            aikitChatbot.previousMessages.push({
248                message: message,
249                author: 'user',
250            });
251
252            aikitChatbot.previousMessages.push({
253                message: data.message,
254                author: 'assistant',
255            });
256
257            data.message = data.message.replace(/\n/g, '<br>');
258
259            data.message = data.message.replace(/(https?:\/\/[^\s]+)/g, '<a href="$1" target="_blank">$1</a>');
260
261            loading.remove();
262            addMessageToChat(data.message);
263
264            // reactivate the send button
265            $(".aikit-chatbot-send-button").prop('disabled', false);
266            $(".aikit-chatbot-send-button").css('opacity', '1');
267
268        }).fail(function (data) {
269            if (data.responseJSON) {
270                data = data.responseJSON;
271            }
272
273            if (data.show_in_alert === true) {
274                alert(data.message);
275            } else {
276                console.log(data);
277            }
278
279            addMessageToChat(data.chat_error, "error");
280
281            // reactivate the send button
282            $(".aikit-chatbot-send-button").prop('disabled', false);
283            $(".aikit-chatbot-send-button").css('opacity', '1');
284            loading.remove();
285        });
286
287        // clear the input
288        $("#aikit-new-message-textarea").val('');
289    }
290
291    const addMessageToChat = (message, type = "") => {
292        let className = "aikit-message-bot";
293        if (type === "reply") {
294            className = "aikit-message-user";
295        } else if (type === "error") {
296            className = "aikit-message-error";
297        }
298
299        let bubble = $('<div class="aikit-message  ' + className + '"><span className="aikit-message-content">' + message + '</span></div>');
300        $("#aikit-messages").append(bubble);
301        bubble.hide().fadeIn(100);
302        $("#aikit-conversation").animate({ scrollTop: $("#aikit-conversation").prop("scrollHeight")}, 50);
303    }
304
305    const generateBotStyles = () => {
306        let secondaryColor = hashColorToRgb(aikitChatbot.secondaryColor, 1);
307        let mainColor = hashColorToRgb(aikitChatbot.mainColor, 1);
308        let shadowColor = hashColorToRgb(aikitChatbot.mainColor, .6);
309        let loadingColor = hashColorToRgb(aikitChatbot.mainColor, .7);
310        let dot1 = hashColorToRgb(aikitChatbot.mainColor, .7);
311        let dot2 = hashColorToRgb(aikitChatbot.mainColor, .4);
312        let dot3 = hashColorToRgb(aikitChatbot.mainColor, .2);
313
314        let titleColor = hashColorToRgb(aikitChatbot.titleColor, 0.9);
315
316        // remove the style if it exists
317        $("#aikit-chatbot-style").remove();
318
319        // output bot style to the head
320        let style = '<style id="aikit-chatbot-style">';
321
322        style += '.aikit-message-bot {';
323        style += '    background-color: ' + aikitChatbot.aiMessageBubbleColor + ';';
324        style += '    color: ' + aikitChatbot.aiMessageTextColor + ';';
325        style += '}';
326
327        style += '.aikit-chat-bubble a {';
328        style += '    text-decoration: underline;';
329        style += '}';
330
331        style += '.aikit-message-user {';
332        style += '    background: linear-gradient(135deg, ' + aikitChatbot.userMessageBubbleColor + ',' + secondaryColor + ');';
333        style += '    color: ' + aikitChatbot.userMessageTextColor + ';';
334        style += '}';
335
336        style += '.aikit-chat-header {';
337        style += '    background: linear-gradient(135deg, ' + mainColor + ' 0%,' + secondaryColor + ' 100%);';
338        style += '    color: ' + aikitChatbot.titleColor + ';';
339        style += '}';
340
341        style += '.aikit-button-body {';
342        style += '    background: linear-gradient(135deg, ' + mainColor + ',' + secondaryColor + ');';
343        style += '    box-shadow: ' + shadowColor + ' 0px 4px 24px;;';
344        style += '}';
345
346        style += '.aikit-button i svg, .aikit-down-arrow {';
347        style += '    color: ' + titleColor + ';';
348        style += '}';
349
350
351        style += '.aikit-typing .aikit-dot {';
352        style += '    background-color: ' + loadingColor + ';';
353        style += '}';
354
355        style += ' @keyframes mercuryTypingAnimation {';
356        style += '    0% {';
357        style += '        transform: translateY(0px);';
358        style += '        background-color: ' + dot1 + ';';
359        style += '    }';
360        style += '    28% {';
361        style += '        transform: translateY(-7px);';
362        style += '        background-color: ' + dot2 + ';';
363        style += '    }';
364        style += '    44% {';
365        style += '        transform: translateY(0px);';
366        style += '        background-color: ' + dot3 + ';';
367        style += '    }';
368        style += '}';
369
370        style += '</style>';
371
372        $('head').append(style);
373    }
374
375    const activateLivePreview = () => {
376        isLivePreview = true;
377        // activate live editing
378        $("input").on('input', function() {
379            let setting = $(this).attr('data-setting');
380            if (aikitChatbot[setting] !== undefined) {
381                aikitChatbot[setting] = $(this).val();
382            }
383
384            updateLivePreview();
385        });
386
387        updateLivePreview();
388    }
389
390    const hashColorToRgb = (color, opacity) => {
391        // turn # color to rgb and add opacity
392        let colorRgb = color.replace('#', '');
393        colorRgb = colorRgb.match(/.{1,2}/g);
394        colorRgb = 'rgba(' + parseInt(colorRgb[0], 16) + ',' + parseInt(colorRgb[1], 16) + ',' + parseInt(colorRgb[2], 16) + ', ' + opacity + ')';
395
396        return colorRgb;
397    }
398
399    const updateLivePreview = () => {
400
401        generateBotStyles();
402
403        // update get value from #aikit-chatbot-appearance-title and set it to the title
404        let title = $("#aikit-chatbot-appearance-title").val();
405        $(".aikit-chat-welcome span").html(title);
406
407        // same for first message
408        let firstMessage = $("#aikit-chatbot-appearance-start-message").val();
409        $(".aikit-message:first").html(firstMessage);
410
411        let inputTextPlaceholder = $("#aikit-chatbot-appearance-input-placeholder").val();
412        $("#aikit-new-message-textarea").attr('placeholder', inputTextPlaceholder);
413    }
414
415    // on load, generate the bot styles
416    generateBotStyles();
417
418    $('.aikit-chat-widget').removeClass('d-none');
419
420    if (window.location.href.indexOf('page=aikit_chatbot') > -1) {
421        activateLivePreview();
422    }
423});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.