PageSourceSearch

https://www.lab4it.com/wp-content/plugins/bili-core/includes/elementor//assets/js/wgl_text_path.js?ver=1.0.0

js lab4it.com collected 2026-10-10 02:06:26 UTC 29,941 bytes, 644 lines download raw bytes

1(function ($) {
2    "use strict";
3
4    const WGLMathUtils = {
5        map: (x, a, b, c, d) => (x - a) * (d - c) / (b - a) + c,
6        lerp: (a, b, n) => (1 - n) * a + n * b,
7    };
8
9    const wglGetWinSize = () => {
10        return {
11            width: window.innerWidth,
12            height: window.innerHeight
13        };
14    };
15    let wglWinSize = wglGetWinSize();
16    window.addEventListener('resize', () => wglWinSize = wglGetWinSize());
17
18    class WGLTextPathHandlerClass extends elementorModules.frontend.handlers.Base {
19        getDefaultSettings() {
20            return {
21                selectors: {
22                    pathContainer: '.wgl-text-path',
23                    svg: '.wgl-text-path > svg',
24                    line: '.wgl-text-path > .simple_line',
25                }
26            };
27        }
28
29        getDefaultElements() {
30            var _this$getSettings = this.getSettings(),
31                selectors = _this$getSettings.selectors;
32            var element = this.$element[0];
33            return {
34                widgetWrapper: element,
35                pathContainer: element.querySelector(selectors.pathContainer),
36                svg: element.querySelector(selectors.svg),
37                line: element.querySelector(selectors.line),
38                textPath: element.querySelector(selectors.textPath)
39            };
40        }
41
42        fetchSVG() {
43            const {
44              url
45            } = this.elements.pathContainer.dataset;
46            
47            if (!url || !url.endsWith('.svg')) {
48              return Promise.reject(url);
49            }
50        
51            return fetch(url).then(res => res.text()).then(svg => {
52              this.elements.pathContainer.innerHTML = svg; // Re-initialize the elements, so the SVG tag will be added.
53        
54              this.elements = this.getDefaultElements();
55            });
56        }
57
58        onInit() {
59            this.elements = this.getDefaultElements(); // Generate unique IDs using the wrapper's `data-id`.
60            if(this.elements.pathContainer.dataset.url){
61                this.fetchSVG().then(() => {
62                    this.initSVG();
63                });                
64            }else{
65                this.initSVG();
66            }
67        }
68
69        initSVG(){
70            // Generate unique IDs using the wrapper's `data-id`.
71            this.pathId = `wgl-path-${this.elements.widgetWrapper.dataset.id}`;
72            this.textPathId = `wgl-text-path-${this.elements.widgetWrapper.dataset.id}`;
73    
74            if (!this.elements.svg && !this.elements.line) {
75            return;
76            }
77    
78            this.getPropertyPosition();
79            this.initTextPath();
80            this.initAnimation();
81        }
82
83        mobilecheck() {
84            var check = false;
85            (function(a){if(/(android|ipad|playbook|silk|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|
85sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
86            return check;
87        }
88
89        initAnimation() {
90            if(this.elements.pathContainer.classList.contains("loop_animation")){
91                window.addEventListener('resize', () => {
92                    this.getPropertyPosition();
93                    this.appendAnimate();
94                });
95
96                if(this.elements.pathContainer.classList.contains("clone_text")){
97                    window.addEventListener('resize', () => {
98                        this.cloneText();
99                    });
100                }
101
102                if(this.elements.line){
103                    this.animate_line();
104                    if(!this.mobilecheck()){
105                        window.addEventListener('resize', this.debounce(() => {
106                            this.createMarquee();
107                        }), false);                        
108                    }else{
109                        screen.orientation.addEventListener('change', this.debounce(() => {
110                            this.createMarquee();
111                        }), false);     
112                    }
113                }
114                if(
115                    this.elements.pathContainer.classList.contains("stop_on_hover")
116                    && this.elements.svg
117                ){
118                    this.elements.svg.addEventListener('mouseenter', e => {
119                        this.elements.svg.pauseAnimations();
120                    });
121
122                    this.elements.svg.addEventListener('touchstart', e => {
123                        this.elements.svg.pauseAnimations();
124                    });
125
126                    this.elements.svg.addEventListener('touchend', e => {
127                        this.elements.svg.unpauseAnimations();
128                    });
129
130                    this.elements.svg.addEventListener('mouseleave', e => {
131                        this.elements.svg.unpauseAnimations();
132                    });
133                }
134            }
135
136            if(this.elements.pathContainer.classList.contains("scroll_animation")){
137                this.svgRect = this.elements.svg ? this.elements.svg.getBoundingClientRect() : this.elements.line.getBoundingClientRect();
138                this.positionY = this.svgRect.top + window.pageYOffset;
139
140                window.addEventListener('resize', () => {
141                    this.getPropertyPosition();
142                    this.appendAnimate();
143                    this.svgRect = this.elements.svg ? this.elements.svg.getBoundingClientRect() : this.elements.line.getBoundingClientRect();
144                    this.positionY = this.svgRect.top + window.pageYOffset;
145                });
146
147                this.observer = new IntersectionObserver((entries) => {
148                    entries.forEach(entry => {
149                        this.isVisible = entry.intersectionRatio > 0;
150                        if (!this.isVisible) {
151                            this.update();
152                        }
153                    });
154                });
155
156                this.observer.observe(this.elements.svg ? this.elements.svg : this.elements.line);
157
158                requestAnimationFrame(() => this.render());
159            }
160
161            window.addEventListener('resize', () => {
162                this.textPosChange();
163            });
164        }
165
166        createMarquee() {
167            if ('animate' in this.marquee_el && typeof this.marquee_el.animate === 'function') {
168                if (typeof this.marquee !== 'undefined') this.marquee.cancel();
169                if (!this.elements.line.querySelector('.text--word')) return;
170                let vw = this.elements.line.querySelector('.text--word').clientWidth;
171                this.marquee = this.marquee_el.animate([
172                    { transform: 'translateX(0)', offset: 0 },
173                    { transform: 'translateX(-' + vw + 'px)', offset: 1 }
174                ],
175                    {
176                        duration: this.animation_speed,
177                        easing: 'linear',
178                        delay: 0,
179                        iterations: Infinity,
180                        fill: 'forwards'
181                    });
182            }
183        }
184
185        animate_line() {
186            this.marquee = undefined;
187            this.marquee_el = this.elements.line.querySelector('.simple_line--wrapper');
188
189            if ('animate' in this.marquee_el && typeof this.marquee_el.animate === 'function') {
190                this.createMarquee();
191                if(this.elements.pathContainer.classList.contains("stop_on_hover")){
192                    this.marquee_el.addEventListener('mouseenter', () => {this.pauseMarquee()});
193                    this.marquee_el.addEventListener('mouseleave', () => {this.playMarquee()});
194                }
195            }
196        }
197
198        playMarquee() {
199            if (this.marquee.playState === 'paused') this.marquee.play();
200        }
201
202        pauseMarquee() {
203            if (this.marquee.playState === 'running') this.marquee.pause();
204        }
205
206        debounce(func) {
207            var scheduled, context, args;
208            return function () {
209                context = this; args = [];
210                for (var i = 0; i < arguments.length; ++i) args[i] = arguments[i];
211                !!scheduled && window.cancelAnimationFrame(scheduled);
212                scheduled = window.requestAnimationFrame(function () {
213                    func.apply(context, args);
214                    scheduled = null;
215                });
216            }
217        }
218
219        textPosChange() {
220            document.querySelectorAll('tspan.text_divider').forEach(function(e){
221                if(e.closest('svg')){
222                    e.setAttribute("dy", -1 * getComputedStyle(e.closest('svg')).getPropertyValue('--top-offset'));
223                    e.setAttribute("dx", -1 * getComputedStyle(e.closest('svg')).getPropertyValue('--left-offset'));
224                }
225            });
226
227            document.querySelectorAll('tspan.divider').forEach(function(e){
228                if(e.closest('svg')){
229                    e.setAttribute("dy", getComputedStyle(e.closest('svg')).getPropertyValue('--top-offset'));
230                    e.setAttribute("dx", getComputedStyle(e.closest('svg')).getPropertyValue('--left-offset'));
231                }
232            });
233        }
234
235        setOffset(offset, endPoint) {
236            this.startOffset = {
237                value: parseInt(offset),
238                getDefaultStartPoint: offset || 0,
239                getDefaultEndPoint: endPoint || 0,
240                amt: 0.1
241            };
242
243            if (!this.elements.textPath) {
244                return;
245            }
246
247            this.elements.textPath.setAttribute('startOffset', this.elements.pathContainer.classList.contains("clone_text") ? 0 : offset + '');
248        }
249
250        appendAnimate() {
251            if (!this.elements.textPath) {
252                return;
253            }
254            if(
255                this.elements.pathContainer.classList.contains("loop_animation") && !this.elements.pathContainer.classList.contains("clone_text")
256            ){
257                if(this.elements.svg.querySelector('animate')){
258                    this.elements.svg.querySelector('animate').remove();
259                }
260                if(this.elements.pathContainer.dataset.typeSvg !== 'circle'){
261                    this.elements.textPath.insertAdjacentHTML('beforeend', '<animate attributeName="startOffset" from="'+this.startPoint +'" to ="'+ this.endPoint +'" begin="0s" dur="'+(this.animation_speed/1000)+'s" repeatCount="indefinite"/>');
262                }
263                if(this.elements.pathContainer.dataset.typeSvg === 'circle'){
264                    this.elements.pathContainer.classList.add('rotate_circle');
265                    this.elements.svg.style.animationDuration = this.animation_speed/1000 + 's';
266                }
267            }
268        }
269
270        cloneText() {
271            if (!this.elements.textPath && !this.elements.line) {
272                return;
273            }
274
275            let animation_speed = this.animation_speed;
276            let to = this.endPoint;
277            let from = this.startPoint;
278            let backspace = this.elements.pathContainer.dataset.backspaceCount;
279
280            if (this.elements.line) {
281                this.elements.line.querySelector('.simple_line--wrapper').innerHTML = '';
282            }
283
284            this.word.innerHTML = this.getDefautWord;
285            this.width = Math.ceil(this.elements.textPath ? this.elements.textPath.getBBox().width : this.word.querySelector('.text--word').getBoundingClientRect().width);
286            this.times = Math.ceil(window.innerWidth / this.width);
287
288            if (this.elements.textPath) {
289                this.elements.textPath.parentNode.style.width = `${(this.times + 1) * this.width}px`;
290            } else {
291                this.elements.line.querySelector('.simple_line--wrapper').style.width = `${(this.times + 1) * this.width}px`;
292            }
293
294            let countItem = 0;
295            let i;
296
297            if (this.times !== Infinity && this.times < 100) {
298                let times_item = this.elements.pathContainer.classList.contains("clone_text") && this.elements.pathContainer.classList.contains("scroll_animation") ? 2 * this.times : this.times;
299                for (i = 0; i < times_item; i++) {
300                    let space = '';
301                    for (let k = 0; k <= backspace; k++) {
302                        space += '\u00A0';
303                        countItem++;
304                    }
305                    if (this.elements.textPath) {
306                        this.word.insertAdjacentHTML('beforeend', space);
307                    } else {
308                        this.word.querySelectorAll('.text--word')[i].insertAdjacentHTML('beforeend', space);
309                    }
310
311                    if (
312                        this.elements.pathContainer.classList.contains("add_divider")
313                    ) {
314                        if (this.elements.textPath) {
315                            this.word.insertAdjacentHTML('beforeend', '<tspan class="divider" dy="' + getComputedStyle(this.elements.svg).getPropertyValue('--top-offset') + '" dx="' + getComputedStyle(this.elements.svg).getPropertyValue('--left-offset') + '">' + this.divider() + '</tspan>');
316                        } else {
317                            this.word.querySelectorAll(':scope > .text--word')[i].insertAdjacentHTML('beforeend', '<span class="divider">' + this.divider() + '</span>');
318                        }
319                    }
320
321                    this.word.insertAdjacentHTML('beforeend', this.getDefautWord);
322                }
323
324                if (
325                    !this.elements.pathContainer.classList.contains("scroll_animation")
326                ) {
327                    if (this.elements.textPath) {
328                        if(this.elements.pathContainer.dataset.typeSvg !== 'circle'){
329                            this.word.innerHTML += '<animate attributeName="startOffset" from="' + from + '" to ="' + to + '" begin="0s" dur="' + (animation_speed / 1000) + 's" repeatCount="indef
329inite"/>';
330                        }
331                        if(this.elements.pathContainer.dataset.typeSvg === 'circle'){
332                            this.elements.pathContainer.classList.add('rotate_circle');
333                            this.elements.svg.style.animationDuration = animation_speed / 1000 + 's';
334                        }
335                    }
336
337                }
338            }
339
340            this.textPosChange();
341        }
342
343        onElementChange(setting) {
344            var _this$getElementSetti = this.getElementSettings(),
345                startPoint =  this.elements.svg ? getComputedStyle(this.elements.svg).getPropertyValue('--start-point') : getComputedStyle(this.elements.line).getPropertyValue('--start-point'),
346                endPoint = this.elements.svg ? getComputedStyle(this.elements.svg).getPropertyValue('--end-point') : getComputedStyle(this.elements.line).getPropertyValue('--end-point') ,
347                text = _this$getElementSetti.text;
348
349            this.animation_speed = _this$getElementSetti.animation_speed;
350            switch (setting) {
351                case 'start_point':
352                case 'end_point':
353                case 'start_point_mobile':
354                case 'start_point_mobile_extra':
355                case 'start_point_tablet':
356                case 'start_point_tablet_extra':
357                case 'start_point_laptop':
358                case 'start_point_desktop':
359                case 'start_point_widescreen':
360                case 'end_point_mobile':
361                case 'end_point_mobile_extra':
362                case 'end_point_tablet':
363                case 'end_point_tablet_extra':
364                case 'end_point_laptop':
365                case 'end_point_desktop':
366                case 'end_point_widescreen':
367                    this.getPropertyPosition();
368                    this.setOffset(startPoint ? startPoint : 0, endPoint ? endPoint : 0);
369                    this.appendAnimate();
370                    break;
371
372                case 'top_offset':
373                case 'left_offset':
374                case 'top_offset_mobile':
375                case 'top_offset_mobile_extra':
376                case 'top_offset_tablet':
377                case 'top_offset_tablet_extra':
378                case 'top_offset_laptop':
379                case 'top_offset_desktop':
380                case 'top_offset_widescreen':
381                case 'left_offset_mobile':
382                case 'left_offset_mobile_extra':
383                case 'left_offset_tablet':
384                case 'left_offset_tablet_extra':
385                case 'left_offset_laptop':
386                case 'left_offset_desktop':
387                case 'left_offset_widescreen':
388                    this.textPosChange();
389                    break;
390
391                case 'text':
392                case 'animation_speed':
393                    this.getPropertyPosition();
394                    this.setText(text);
395                    this.appendAnimate();
396                    if(this.elements.pathContainer.classList.contains("clone_text")){
397                        this.cloneText();
398                    }
399                    if(this.elements.line){
400                        this.animate_line();
401                    }
402                    break;
403
404                default:
405                    break;
406            }
407        }
408
409        attachIdToPath() {
410            // Prioritize the custom `data` attribute over the `path` element, and fallback to the first `path`.
411            if (!this.elements.svg) {
412                return;
413            }
414
415            var path = this.elements.svg.querySelector('[data-path-anchor]') || this.elements.svg.querySelector('path');
416            if(!path){
417                return;
418            }
419            path.id = this.pathId;
420        }
421        getPropertyPosition(){
422            this.startPoint = this.elements.svg ? getComputedStyle(this.elements.svg).getPropertyValue('--start-point') : getComputedStyle(this.elements.line).getPropertyValue('--start-point');
423            this.endPoint = this.elements.svg ? getComputedStyle(this.elements.svg).getPropertyValue('--end-point') : getComputedStyle(this.elements.line).getPropertyValue('--end-point');
424        }
425
426        initTextPath() {
427            var _this$getElementSetti2 = this.getElementSettings();
428            this.animation_speed = _this$getElementSetti2.animation_speed;
429
430            var text = this.elements.pathContainer.dataset.text;
431            this.attachIdToPath(); // Generate the `textPath` element with its settings.
432
433            if(this.elements.svg){
434                this.elements.svg.innerHTML += "\n\t\t\t<text>\n\t\t\t\t<textPath id=\"".concat(this.textPathId, "\" href=\"#").concat(this.pathId, "\"></textPath>\n\t\t\t</text>\n\t\t"); // Regenerate the elements object to have access to `this.elements.textPath`.
435                this.elements.textPath = this.elements.svg.querySelector("#".concat(this.textPathId));
436            }else if(this.elements.line){
437                this.elements.line.innerHTML += "<div class=\"simple_line--wrapper\"></div>";
438            }
439            this.setOffset(this.startPoint ? this.startPoint : 0,  this.endPoint ?  this.endPoint : 0);
440            this.setText(text);
441        }
442
443        setText(newText) {
444
445            if(!newText){
446                return;
447            }
448            var _this$getElementSetti4;
449
450            var _this$getElementSetti3 = (_this$getElementSetti4 = this.getElementSettings()) === null || _this$getElementSetti4 === void 0 ? void 0 : _this$getElementSetti4.link,
451                url = _this$getElementSetti3.url,
452                isExternal = _this$getElementSetti3.is_external,
453                nofollow = _this$getElementSetti3.nofollow;
454
455            var target = isExternal ? '_blank' : '',
456                rel = nofollow ? 'nofollow' : ''; // Add link attributes.
457
458            if(
459                this.elements.pathContainer.classList.contains("add_divider")
460            ){
461                if(this.elements.svg){
462                    newText = '<tspan class="text_divider" dy="'+(-1 * getComputedStyle(this.elements.svg).getPropertyValue('--top-offset'))+'" dx="'+(-1 * getComputedStyle(this.elements.svg).getPropertyValue('--left-offset'))+'"> '.concat((0, newText), '</tspan>');
463                }else{
464                    newText = '<span class="text"> '.concat((0, newText), '</span>');
465                }
466            }
467
468            if (url) {
469                newText = "<a href=\"".concat((0, this.escapeHTML)(url), "\" rel=\"").concat(rel, "\" target=\"").concat(target, "\">").concat((0, newText), "</a>");
470            } // Set the text.
471
472            if(
473                this.elements.pathContainer.classList.contains("add_divider")
474                && !this.elements.pathContainer.classList.contains("clone_text")
475            ){
476
477                if(this.elements.svg){
478                    newText += '<tspan class="divider" dy="'+getComputedStyle(this.elements.svg).getPropertyValue('--top-offset')+'" dx="'+getComputedStyle(this.elements.svg).getPropertyValue('--left-offset')+'">'+ this.divider() +'</tspan>';
479                }else{
480                    newText += '<span class="divider_line">'+ this.divider() +'</span>';
481                }
482            }
483
484            if(this.elements.svg){
485                this.elements.textPath.innerHTML = '';
486                this.elements.textPath.innerHTML = newText; // Remove the cloned element if exists.
487            }else{
488                let newNode = document.createElement('span');
489                newNode.className = 'text--word';
490                newNode.innerHTML = newText;
491                this.elements.line.querySelector('.simple_line--wrapper').innerHTML = '';
492                this.elements.line.querySelector('.simple_line--wrapper').appendChild(newNode);
493            }
494
495            if(this.elements.pathContainer.classList.contains("clone_text")){
496                this.word = this.elements.svg ? this.elements.textPath : this.elements.line.querySelector('.simple_line--wrapper');
497                this.getDefautWord = this.word.innerHTML;
498                this.cloneText();
499            }
500
501            this.appendAnimate();
502
503            if(this.elements.svg){
504                var existingClone = this.elements.svg.querySelector("#".concat(this.textPathId, "-clone"));
505
506                if (existingClone) {
507                    existingClone.remove();
508                } // Reverse the text if needed.
509
510                if (this.shouldReverseText()) {
511                    // Keep an invisible selectable copy of original element for better a11y.
512                    var clone = this.elements.textPath.cloneNode();
513                    clone.id += '-clone';
514                    clone.classList.add('elementor-hidden');
515                    clone.textContent = newText;
516                    this.elements.textPath.parentNode.appendChild(clone);
517                    this.reverseToRTL();
518                }
519            }
520        }
521
522        isRTL() {
523            var _this$getElementSetti5 = this.getElementSettings(),
524                direction = _this$getElementSetti5.text_path_direction;
525
526            var isRTL = elementorFrontend.config.is_rtl;
527
528            if (direction) {
529                isRTL = 'rtl' === direction;
530            }
531
532            return isRTL;
533        }
534
535        shouldReverseText() {
536            return this.isRTL() && -1 === navigator.userAgent.indexOf('Firefox');
537        }
538
539        escapeHTML(str) {
540            var specialChars = {
541            '&': '&amp;',
542            '<': '&lt;',
543            '>': '&gt;',
544            "'": '&#39;',
545            '"': '&quot;'
546            };
547            return str.replace(/[&<>'"]/g, function (tag) {
548            return specialChars[tag] || tag;
549            });
550        }
551
552        reverseToRTL() {
553            // Make sure to use the inner `a` tag if exists.
554            var parentElement = this.elements.textPath;
555            parentElement = parentElement.querySelector('a') || parentElement; // Catch all RTL chars and reverse their order.
556
557            var pattern = /([\u0591-\u07FF\u200F\u202B\u202E\uFB1D-\uFDFD\uFE
55770-\uFEFC\s$&+,:;=?@#|'<>.^*()%!-]+)/ig; // Reverse the text.
558
559            parentElement.textContent = parentElement.textContent.replace(pattern, function (word) {
560                return word.split('').reverse().join('');
561            }); // Add a11y attributes.
562
563            parentElement.setAttribute('aria-hidden', true);
564        }
565
566        computeOffset() {
567            const fromValue = parseInt(this.startOffset.getDefaultStartPoint);
568            const toValue = parseInt(this.startOffset.getDefaultEndPoint);
569
570            const val =  WGLMathUtils.map(this.positionY - window.pageYOffset, wglWinSize.height, -1 * this.svgRect.height,  fromValue, toValue);
571            if(fromValue > toValue){
572                return Math.max(Math.min(val, fromValue), toValue);
573            }else{
574                return Math.min(Math.max(val, fromValue), toValue);
575            }
576        }
577
578        updateTextPathOffset() {
579            if (!this.elements.textPath && !this.elements.line) {
580                return;
581            }
582            if(this.elements.pathContainer.dataset.typeSvg === 'circle'){
583                let rotate = 360 * this.startOffset.value / 100;
584                this.elements.svg.style.transform = 'rotate(' + rotate + 'deg)';
585            }else if(this.elements.pathContainer.dataset.typeSvg === 'wgl_line_simple'){
586                this.elements.line.style.transform = 'translateX(' + this.startOffset.value + 'px)';
587            }else{
588                this.elements.textPath.setAttribute('startOffset', this.startOffset.value + '%');
589            }
590        }
591
592        divider() {
593            let divider;
594
595            switch (this.elements.pathContainer.dataset.dType) {
596                case 'star':
597                    divider = '*';
598                    break;
599
600                case 'line':
601                    divider = '//';
602                    break;
603                
604                case 'arrow':
605                    divider = '<svg viewBox="0 0 31 31" xmlns="http://www.w3.org/2000/svg"><path d="M18.6742 30.3182L13.2701 30.2776L13.1406 13.0492L13.1316 11.8549L12.287 12.6994L5.30318 19.6833L1.44794 15.828L15.7504 1.52543L30.2803 16.0555L26.4931 19.8426L19.3983 12.7477L18.5355 11.8849L18.5447 13.105L18.6742 30.3182Z"/></svg>';
606                    break;
607
608                case 'custom':
609                    divider = this.elements.pathContainer.dataset.dCustom;
610                    break;
611
612                default:
613                    break;
614            }
615
616            return divider
617        }
618
619        update() {
620            const currentOffset = this.computeOffset();
621            this.startOffset.value = WGLMathUtils.lerp(this.startOffset.value, currentOffset, this.startOffset.amt);
622            this.updateTextPathOffset();
623        }
624
625        render() {
626            if ( this.isVisible ) {
627                this.update();
628            }
629            requestAnimationFrame(() => this.render());
630        }
631    }
632
633    jQuery(window).on('elementor/frontend/init', function () {
634
635        const addHandler = ($element) => {
636            elementorFrontend.elementsHandler.addHandler(WGLTextPathHandlerClass, {
637                $element,
638            });
639        };
640
641        elementorFrontend.hooks.addAction('frontend/element_ready/wgl-text-path.default', addHandler);
642    });
643
644})(jQuery);

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.