PluginProbe
Easy Elements for Elementor – Addons & Website Templates / 1.3.0
Easy Elements for Elementor – Addons & Website Templates v1.3.0
1.5.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.6 1.4.7 1.4.8 1.4.5 1.4.4 1.4.3 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 All 47 releases
easy-elements / assets / js / custom.js

custom.js in Easy Elements for Elementor – Addons & Website Templates 1.3.0, at assets/js/custom.js

667 lines 23.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function($) {
2 "use strict";
3 function initBackPostSlider($scope) {
4 var $slider = $scope.find('.eel-all-slider');
5 if (!$slider.length) {
6 return;
7 }
8 var loop = $slider.data('loop') === true || $slider.data('loop') === 'true';
9 var autoplay = $slider.data('autoplay') === true || $slider.data('autoplay') === 'true';
10 var autoplayDelay = parseInt($slider.data('autoplay-delay'), 10) || 3000;
11 var slidesPerView = parseInt($slider.data('slides-per-view'), 10) || 3;
12 var speed = parseInt($slider.data('speed'), 10) || 600;
13 var centeredSlides = $slider.data('centered-slides') === true || $slider.data('centered-slides') === 'true';
14 var freeMode = $slider.data('free-mode') === true || $slider.data('free-mode') === 'true';
15 var spaceBetween = parseInt($slider.data('space-between'), 10) || 0;
16 var slidesPerViewTablet = parseInt($slider.data('slides-per-view-tablet'), 10) || 2;
17 var slidesPerViewMobile = parseInt($slider.data('slides-per-view-mobile'), 10) || 1;
18 var paginationType = $slider.data('pagination') !== 'none' ? $slider.data('pagination') : false;
19 var navigation = $slider.data('navigation') === true || $slider.data('navigation') === 'true';
20 var effect = $slider.data('effect') || 'slide';
21 var cubeShadow = $slider.data('cube-shadow') === true || $slider.data('cube-shadow') === 'true';
22 var coverflowRotate = parseInt($slider.data('coverflow-rotate'), 10) || 50;
23 var coverflowStretch = parseInt($slider.data('coverflow-stretch'), 10) || 0;
24
25 // Find navigation elements within the scope
26 var $nextButton = $scope.find('.swiper-next');
27 var $prevButton = $scope.find('.swiper-prev');
28 var $pagination = $scope.find('.swiper-pagination');
29
30 // Prevent multiple instances and duplicated handlers if Elementor re-runs init
31 if ($slider[0] && $slider[0].swiper) {
32 try { $slider[0].swiper.destroy(true, true); } catch (e) {}
33 }
34 if ($nextButton.length) { $nextButton.off('click.easyStopAuto click.easyFadeNav'); }
35 if ($prevButton.length) { $prevButton.off('click.easyStopAuto click.easyFadeNav'); }
36
37 var hasProgressBar = $pagination.hasClass('swiper-pagination-progressbar');
38
39 var effectOptions = {};
40
41 if (effect === 'cube') {
42 effectOptions = {
43 cubeEffect: {
44 shadow: cubeShadow,
45 slideShadows: cubeShadow,
46 shadowOffset: 20,
47 shadowScale: 0.94,
48 }
49 };
50 } else if (effect === 'coverflow') {
51 effectOptions = {
52 coverflowEffect: {
53 rotate: coverflowRotate,
54 stretch: coverflowStretch,
55 depth: 100,
56 modifier: 1,
57 slideShadows: true,
58 }
59 };
60 } else if (effect === 'flip') {
61 effectOptions = {
62 flipEffect: {
63 slideShadows: true,
64 limitRotation: true,
65 }
66 };
67 } else if (effect === 'cards') {
68 effectOptions = {
69 cardsEffect: {
70 slideShadows: true,
71 rotate: true,
72 perSlideOffset: 8,
73 }
74 };
75 } else if (effect === 'creative') {
76 var creativeStyle = $slider.data('creative-style') || 'default';
77 if (creativeStyle === 'zoom') {
78 effectOptions = {
79 creativeEffect: {
80 limitProgress: true,
81 prev: { scale: 1.1, opacity: 0, translate: [0, 0, 0] },
82 next: { scale: 1.6, opacity: 0, translate: [0, 0, 0] },
83 },
84 };
85 } else {
86 effectOptions = {
87 creativeEffect: {
88 limitProgress: true,
89 prev: { shadow: true, translate: [0, 0, -400] },
90 next: { translate: ['100%', 0, 0] },
91 },
92 };
93 }
94 } else if (effect === 'fade') {
95 effectOptions = {
96 fadeEffect: { crossFade: true }
97 };
98 }
99
100 // Loop handling tuned to avoid double-advance on loop edges
101 var totalSlides = $slider.find('.swiper-slide').length;
102 var isFade = effect === 'fade';
103 var visibleSlides = isFade ? 1 : slidesPerView;
104 var canLoop = totalSlides > visibleSlides;
105 var loopConfig = {};
106 if (loop && (canLoop || isFade)) {
107 loopConfig = {
108 loop: true,
109 loopAdditionalSlides: isFade ? totalSlides : 20,
110 loopedSlides: isFade ? totalSlides : Math.max(Math.ceil(visibleSlides), Math.min(totalSlides, 10))
111 };
112 } else {
113 loopConfig = { loop: false, rewind: !!loop };
114 }
115
116 var swiper = new Swiper($slider[0], {
117 ...loopConfig,
118 speed: speed,
119 effect: effect,
120 normalizeSlideIndex: true,
121 preventInteractionOnTransition: true,
122 simulateTouch: true,
123 touchRatio: 1,
124 grabCursor: true,
125 mousewheel: hasProgressBar ? {
126 enabled: true,
127 sensitivity: 1,
128 thresholdDelta: 50,
129 thresholdTime: 200,
130 releaseOnEdges: true,
131 invert: false,
132 forceToAxis: false,
133 eventsTarget: 'container'
134 } : false,
135 autoplay: autoplay ? {
136 delay: autoplayDelay,
137 disableOnInteraction: isFade ? true : false,
138 } : false,
139 slidesPerView: visibleSlides,
140 spaceBetween: isFade ? 0 : spaceBetween,
141 centeredSlides: isFade ? false : centeredSlides,
142 freeMode: freeMode,
143 pagination: paginationType && $pagination.length ? {
144 el: $pagination[0],
145 clickable: true,
146 type: paginationType,
147 renderBullet: function (index, className) {
148 let num = (index + 1).toString().padStart(2, '0');
149 return `<span class="${className}">${num}</span>`;
150 }
151 } : false,
152
153 // Progress bar for mouse scroll - only when swiper-pagination-progressbar class is present
154 progressbar: hasProgressBar ? {
155 el: '.swiper-progressbar',
156 type: 'progressbar',
157 } : false,
158
159 navigation: (!isFade) && navigation && ($nextButton.length || $prevButton.length) ? {
160 nextEl: $nextButton.length ? $nextButton[0] : null,
161 prevEl: $prevButton.length ? $prevButton[0] : null,
162 } : false,
163 breakpoints: {
164 0: {
165 slidesPerView: isFade ? 1 : slidesPerViewMobile,
166 },
167 768: {
168 slidesPerView: isFade ? 1 : slidesPerViewTablet,
169 },
170 1024: {
171 slidesPerView: isFade ? 1 : slidesPerView,
172 },
173 },
174 ...effectOptions,
175 });
176
177 // Fade: attach custom navigation so Next/Prev work
178 if (isFade && ($nextButton.length || $prevButton.length)) {
179 var isTransitioning = false;
180 swiper.on('transitionStart', function () { isTransitioning = true; });
181 swiper.on('transitionEnd', function () { isTransitioning = false; });
182 if ($nextButton.length) {
183 $nextButton.off('click.easyFadeNav').on('click.easyFadeNav', function (e) {
184 e.preventDefault();
185 e.stopPropagation();
186 if (swiper && swiper.autoplay && swiper.autoplay.stop) { swiper.autoplay.stop(); }
187 if (isTransitioning || (swiper && swiper.animating)) return;
188 swiper.slideNext();
189 });
190 }
191 if ($prevButton.length) {
192 $prevButton.off('click.easyFadeNav').on('click.easyFadeNav', function (e) {
193 e.preventDefault();
194 e.stopPropagation();
195 if (swiper && swiper.autoplay && swiper.autoplay.stop) { swiper.autoplay.stop(); }
196 if (isTransitioning || (swiper && swiper.animating)) return;
197 swiper.slidePrev();
198 });
199 }
200 }
201
202 // Non-fade: if loop+autoplay, stop autoplay on manual nav to avoid double-advance
203 if (!isFade && loop && autoplay) {
204 if ($nextButton.length) {
205 $nextButton.on('click.easyStopAuto', function () {
206 if (swiper && swiper.autoplay && swiper.autoplay.stop) {
207 swiper.autoplay.stop();
208 }
209 });
210 }
211 if ($prevButton.length) {
212 $prevButton.on('click.easyStopAuto', function () {
213 if (swiper && swiper.autoplay && swiper.autoplay.stop) {
214 swiper.autoplay.stop();
215 }
216 });
217 }
218 }
219 }
220
221 function addWidgetTypeToBody($scope) {
222 var widgetType = $scope.data('widget_type');
223 if (widgetType) {
224 var className = 'easy-eel-has-widget-' + widgetType.replace(/[^a-z0-9_-]/gi, '-').toLowerCase();
225 document.body.classList.add(className);
226 }
227 }
228
229 $(window).on('elementor/frontend/init', function () {
230
231 function checkStickySection() {
232 const stickySection = document.querySelector('.eel-sticky-section');
233 if (stickySection) {
234 document.body.classList.add('sticky-enabled-overlap');
235 } else {
236 document.body.classList.remove('sticky-enabled-overlap');
237 }
238 }
239
240 checkStickySection();
241
242 const observer = new MutationObserver(checkStickySection);
243 observer.observe(document.body, { childList: true, subtree: true });
244 });
245
246
247 function initReveal() {
248 const revealElements = document.querySelectorAll(".eel-img-reveal-wrap, .eel-img-advance-wrap");
249
250 const revealAnimate = (el) => {
251 const target = el.querySelector(".eel-reveal-img-main, .eel-advance-img-main");
252 if(target) target.classList.add("el-reveal-animate");
253 };
254
255 const isEditor = window.elementorFrontend && elementorFrontend.isEditMode && elementorFrontend.isEditMode();
256
257 if(isEditor){
258
259 revealElements.forEach(el => revealAnimate(el));
260 } else {
261
262 const observer = new IntersectionObserver((entries, obs) => {
263 entries.forEach(entry => {
264 if(entry.isIntersecting){
265 revealAnimate(entry.target);
266 obs.unobserve(entry.target);
267 }
268 });
269 }, { threshold: 0.3 });
270
271 revealElements.forEach(el => observer.observe(el));
272 }
273 }
274
275 $(window).on('elementor/frontend/init', function () {
276 elementorFrontend.hooks.addAction('frontend/element_ready/global', initBackPostSlider);
277 elementorFrontend.hooks.addAction('frontend/element_ready/global', addWidgetTypeToBody);
278 elementorFrontend.hooks.addAction('frontend/element_ready/global', initReveal);
279 });
280
281
282 $(window).on("elementor/frontend/init", function ($) {
283 var EasyJarallax = function ($scope, $) {
284 var $wrappers = $scope.hasClass('eele-has-jarallax') ? $scope : $scope.find('.eele-has-jarallax, .eele-inner-jarallax');
285 if (!$wrappers.length) return;
286 $wrappers.each(function () {
287 var $wrapper = $(this);
288 var bg = $wrapper.data('jarallax-bg');
289 var speed = $wrapper.data('jarallax-speed') || 0.5;
290 if (!bg) return;
291 // Check if jarallax div already exists
292 var $jarallaxDiv = $wrapper.find('.jarallax');
293 if ($jarallaxDiv.length === 0) {
294 var jarallaxMarkup = '<div class="jarallax eele-jarallax-bg" data-speed="' + speed + '">\
295 <img class="jarallax-img" src="' + bg + '" alt="">\
296 </div>';
297 $wrapper.append(jarallaxMarkup);
298 $jarallaxDiv = $wrapper.find('.jarallax');
299 }
300
301 // Initialize jarallax
302 $jarallaxDiv.each(function () {
303 jarallax(this, {
304 speed: $(this).data('speed')
305 });
306 });
307 });
308 };
309 elementorFrontend.hooks.addAction("frontend/element_ready/global", EasyJarallax);
310 });
311
312
313
314 jQuery(window).on('elementor/frontend/init', function() {
315
316 elementorFrontend.hooks.addAction('frontend/element_ready/eel-video-popup.default', function($scope, $) {
317
318 const wrapper = $scope.find('.eel-video-popup-wrapper');
319 const overlay = wrapper.find('.eel-video-overlay');
320 // Find video element (try with class first, then without)
321 let videoEl = wrapper.find('video.eel-normal-video');
322 if (!videoEl.length) {
323 videoEl = wrapper.find('video');
324 }
325 // Find iframe element (try with class first, then without)
326 let iframeEl = wrapper.find('iframe.eel-normal-video');
327 if (!iframeEl.length) {
328 iframeEl = wrapper.find('iframe');
329 }
330
331 // Helper function to get YouTube embed URL
332 function getYouTubeEmbedUrl(url) {
333 const regExp = /(?:v=|\/)([0-9A-Za-z_-]{11}).*/;
334 const match = url.match(regExp);
335 if (match && match[1]) {
336 return 'https://www.youtube.com/embed/' + match[1] + '?autoplay=1';
337 }
338 return null;
339 }
340
341 // Helper function to get Vimeo embed URL
342 function getVimeoEmbedUrl(url) {
343 const match = url.match(/(\d+)/);
344 if (match && match[1]) {
345 return 'https://player.vimeo.com/video/' + match[1] + '?autoplay=1';
346 }
347 return null;
348 }
349
350 // Helper function to open lightbox
351 function openLightbox(videoType, videoUrl, popupId, animation) {
352 const lightboxOverlay = $('#' + popupId);
353 const iframeWrapper = lightboxOverlay.find('.eel-video-popup-iframe-wrapper');
354 const lightboxContent = lightboxOverlay.find('.eel-video-popup-content');
355
356 if (!lightboxOverlay.length) return;
357
358 // Prevent duplicate opening if already active
359 if (lightboxOverlay.hasClass('active')) {
360 return;
361 }
362
363 let embedHtml = '';
364
365 if (videoType === 'youtube') {
366 const embedUrl = getYouTubeEmbedUrl(videoUrl);
367 if (embedUrl) {
368 embedHtml = '<iframe src="' + embedUrl + '" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe>';
369 }
370 } else if (videoType === 'vimeo') {
371 const embedUrl = getVimeoEmbedUrl(videoUrl);
372 if (embedUrl) {
373 embedHtml = '<iframe src="' + embedUrl + '" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe>';
374 }
375 } else if (videoType === 'self_hosted') {
376 embedHtml = '<video src="' + videoUrl + '" controls autoplay></video>';
377 }
378
379 if (embedHtml) {
380 iframeWrapper.html(embedHtml);
381
382 // Apply animation if set
383 if (animation && animation.trim() !== '') {
384 // Remove any existing animation classes
385 const currentClasses = lightboxContent.attr('class') || '';
386 const animationClasses = currentClasses.match(/\banimated\s+\S+/g);
387 if (animationClasses) {
388 lightboxContent.removeClass(animationClasses.join(' '));
389 }
390 // Add new animation classes
391 lightboxContent.addClass('animated ' + animation.trim());
392 } else {
393 // Remove animation classes if no animation
394 const currentClasses = lightboxContent.attr('class') || '';
395 const animationClasses = currentClasses.match(/\banimated\s+\S+/g);
396 if (animationClasses) {
397 lightboxContent.removeClass(animationClasses.join(' '));
398 }
399 }
400
401 lightboxOverlay.addClass('active');
402 $('body').css('overflow', 'hidden');
403 }
404 }
405
406 // Close lightbox handler
407 $(document).on('click', '.eel-video-popup-close', function(e) {
408 e.preventDefault();
409 const lightboxOverlay = $(this).closest('.eel-video-popup-overlay');
410 const lightboxContent = lightboxOverlay.find('.eel-video-popup-content');
411 lightboxOverlay.removeClass('active');
412 lightboxContent.removeClass('animated');
413 lightboxOverlay.find('.eel-video-popup-iframe-wrapper').html('');
414 $('body').css('overflow', '');
415 });
416
417 // Close lightbox on overlay click
418 $(document).on('click', '.eel-video-popup-overlay', function(e) {
419 if ($(e.target).hasClass('eel-video-popup-overlay')) {
420 const lightboxContent = $(this).find('.eel-video-popup-content');
421 $(this).removeClass('active');
422 lightboxContent.removeClass('animated');
423 $(this).find('.eel-video-popup-iframe-wrapper').html('');
424 $('body').css('overflow', '');
425 }
426 });
427
428 // Close lightbox on ESC key
429 $(document).on('keydown', function(e) {
430 if (e.keyCode === 27) { // ESC key
431 $('.eel-video-popup-overlay.active').each(function() {
432 const lightboxContent = $(this).find('.eel-video-popup-content');
433 $(this).removeClass('active');
434 lightboxContent.removeClass('animated');
435 $(this).find('.eel-video-popup-iframe-wrapper').html('');
436 $('body').css('overflow', '');
437 });
438 }
439 });
440
441 if (overlay.length) {
442 // Remove existing handler to prevent duplicate
443 overlay.off('click.eelVideoOverlay');
444 overlay.on('click.eelVideoOverlay', function(e) {
445 e.preventDefault();
446 e.stopPropagation();
447
448 const $overlay = $(this);
449 const useLightbox = $overlay.data('lightbox') === 'yes';
450 const videoType = $overlay.data('video-type');
451 const videoUrl = $overlay.data('video-url');
452 const popupId = $overlay.data('popup-id');
453 const animation = $overlay.data('animation') || '';
454
455 // If lightbox is enabled, open lightbox
456 if (useLightbox && videoType && videoUrl && popupId) {
457 // Check if lightbox is already open to prevent duplicate
458 const lightboxOverlay = $('#' + popupId);
459 if (lightboxOverlay.hasClass('active')) {
460 return;
461 }
462 openLightbox(videoType, videoUrl, popupId, animation);
463 return;
464 }
465
466 // Otherwise, play inline (original behavior)
467 // Self-hosted video play
468 if (videoEl.length) {
469 const video = videoEl.get(0);
470
471 // Function to play video
472 const playVideo = function() {
473 const playPromise = video.play();
474 if (playPromise !== undefined) {
475 playPromise.catch(function(error) {
476 console.log('Video play failed:', error);
477 // If play fails due to autoplay policy, try with muted
478 if (error.name === 'NotAllowedError' && !video.muted) {
479 video.muted = true;
480 video.play().then(function() {
481 // Unmute after play starts (if user wants sound)
482 setTimeout(function() {
483 video.muted = false;
484 }, 100);
485 }).catch(function(err) {
486 console.log('Video play with mute also failed:', err);
487 });
488 }
489 });
490 }
491 };
492
493 // Always try to load and play
494 if (video.readyState >= 2) {
495 // Video is already loaded, play immediately
496 playVideo();
497 } else {
498 // Video not loaded, load it first then play
499 video.load();
500 // Wait for video to be ready to play
501 const tryPlay = function() {
502 if (video.readyState >= 2) {
503 playVideo();
504 } else {
505 video.addEventListener('canplay', playVideo, { once: true });
506 video.addEventListener('loadeddata', playVideo, { once: true });
507 }
508 };
509 tryPlay();
510 }
511 }
512
513 // YouTube / Vimeo iframe autoplay
514 if (iframeEl.length) {
515 let src = iframeEl.attr('src');
516 if (src) {
517 // Check if it's YouTube or Vimeo
518 const isYouTube = src.indexOf('youtube.com') !== -1 || src.indexOf('youtu.be') !== -1;
519 const isVimeo = src.indexOf('vimeo.com') !== -1;
520
521 if (isYouTube || isVimeo) {
522 try {
523 // Use URL object for proper parsing
524 const url = new URL(src);
525
526 if (isYouTube) {
527 // YouTube: add autoplay, preserve original mute setting
528 url.searchParams.set('autoplay', '1');
529 // Only set mute=1 if it was already in the URL (preserve original setting)
530 // If mute was not in original URL, don't add it
531 if (!url.searchParams.has('mute')) {
532 // Don't add mute if it wasn't there originally
533 } else {
534 // Keep the original mute value
535 }
536 // Reload iframe with new src
537 iframeEl.attr('src', url.toString());
538 } else if (isVimeo) {
539 // Vimeo: add autoplay (Vimeo doesn't need mute for autoplay)
540 url.searchParams.set('autoplay', '1');
541 // Reload iframe with new src
542 iframeEl.attr('src', url.toString());
543 }
544 } catch (e) {
545 // Fallback for browsers that don't support URL constructor
546 // Remove existing autoplay parameter if present
547 src = src.replace(/[?&]autoplay=[^&]*/g, '');
548
549 if (isYouTube) {
550 // Check if mute parameter exists in original URL
551 const hasMute = /[?&]mute=/.test(src);
552 // Add autoplay=1
553 const separator = src.indexOf('?') === -1 ? '?' : '&';
554 src += separator + 'autoplay=1';
555 // Only add mute if it was already there (preserve original setting)
556 // Don't add mute if it wasn't in original URL
557 } else if (isVimeo) {
558 // Vimeo: just add autoplay=1
559 const separator = src.indexOf('?') === -1 ? '?' : '&';
560 src += separator + 'autoplay=1';
561 }
562
563 // Update src without clearing first
564 iframeEl.attr('src', src);
565 }
566 }
567 }
568 }
569
570 // Remove overlay after a small delay to ensure video starts
571 setTimeout(function() {
572 overlay.fadeOut(300, function() {
573 $(this).remove();
574 });
575 }, 200);
576 });
577 }
578
579 // Handle popup button clicks (for display_type = 'popup')
580 const popupBtn = wrapper.find('.entro-all-video-popup');
581 if (popupBtn.length) {
582 // Remove existing handler to prevent duplicate
583 popupBtn.off('click.eelVideoPopup');
584 popupBtn.on('click.eelVideoPopup', function(e) {
585 e.preventDefault();
586 e.stopPropagation();
587 const $btn = $(this);
588 const videoType = $btn.data('video-type');
589 const videoUrl = $btn.data('video-src');
590 const popupId = $btn.data('popup-id');
591 const lightboxOverlay = $('#' + popupId);
592 const animation = lightboxOverlay.data('animation') || '';
593
594 if (videoType && videoUrl && popupId) {
595 // Check if lightbox is already open to prevent duplicate
596 if (lightboxOverlay.hasClass('active')) {
597 return;
598 }
599 openLightbox(videoType, videoUrl, popupId, animation);
600 }
601 });
602 }
603 });
604
605 });
606
607
608 document.addEventListener('click', function (e) {
609 const link = e.target.closest('.eel-single-nav-list .eel-nav-item a');
610 if (!link) return;
611 const href = link.getAttribute('href');
612 if (href && href.startsWith('#') && href.length > 1) {
613 e.preventDefault();
614
615 const target = document.querySelector(href);
616 if (target) {
617 target.scrollIntoView({
618 behavior: 'smooth',
619 block: 'start'
620 });
621 }
622 }
623
624 document.querySelectorAll('.eel-single-nav-list .eel-nav-item').forEach(function (el) {
625 el.classList.remove('active');
626 });
627
628 link.closest('.eel-nav-item').classList.add('active');
629 });
630
631
632 // Sticky Navigation single page
633
634 function applyStickyToContainer($container) {
635 if ($container.find('.elementor-widget-eel-single-nav').length === 0) {
636 return;
637 }
638
639 $container.addClass('eel-single-nav-sticky-enabled');
640 }
641
642 /* ===== Frontend ===== */
643 $(window).on('elementor/frontend/init', function () {
644 elementorFrontend.hooks.addAction(
645 'frontend/element_ready/container',
646 function ($scope) {
647 applyStickyToContainer($scope);
648 }
649 );
650 });
651
652 /* ===== Editor ===== */
653 if (window.elementor && elementor.isEditMode()) {
654 elementor.hooks.addAction('editor:init', function () {
655 elementorFrontend.hooks.addAction(
656 'frontend/element_ready/container',
657 function ($scope) {
658 applyStickyToContainer($scope);
659 }
660 );
661 });
662 }
663
664 })(jQuery);
665
666
667