PageSourceSearch

https://bellacom.com.pk/js/custom.260109195345.js

js bellacom.com.pk collected 2026-10-08 17:30:18 UTC 11,567 bytes, 405 lines download raw bytes

1/* JS for preset "Menu V2" */
2(function() {
3	$(function() {
4		$('.menu-wrapper').each(function() {
5			initMenu($(this))
6		});
7	});
8
9	// Make :active pseudo classes work on iOS
10	document.addEventListener("touchstart", function() {}, false);
11
12	const initMenu = function($menuWrapper) {
13		const $body = $('body');
14		const $menu = $('.ed-menu', $menuWrapper);
15		const $menuLinks = $('a', $menu);
16		const $menuTrigger = $('.menu-trigger', $menuWrapper);
17		const $banner = $('.banner').first();
18
19		const smoothScrollOffset = 20;
20		
21		// Set aria attributes
22		$menuTrigger.attr({
23				'aria-expanded': 'false',
24				'aria-controls': $menu.attr('id'),
25		});
26
27		toggleClassOnClick($body.add($menu), $menuTrigger, null, 'open open-menu'); // Keep open on $menu for backward compatibility
28		activateSmoothScroll($menuLinks.add($('.scroll a')), smoothScrollOffset);
29		addClassOnVisibleLinkTargets($menuLinks, 'active', 2 / 3);
30		handleSticky($menuWrapper, 'sticky', $banner);
31	};
32
33	/**
34	 * Observe element's height changes and reload the initMenu() function
35	 *
36	 * @param {HTMLElement} elm Element to observe
37	 * @param {function} callback to call when elmement's height changed
38	 */
39	const observeHeightChange = function(elm, callback) {
40		if (!('ResizeObserver' in window) || elm == null) return;
41
42		const ro = new ResizeObserver(callback);
43		ro.observe(elm);
44	}
45
46	/**
47	 * Toggles class on a target when a trigger is clicked
48	 * 
49	 * @param {jQuery} $target The target to apply the CSS class to
50	 * @param {jQuery} $trigger The Trigger
51	 * @param {jQuery} $closeTrigger Optional close trigger
52	 * @param {string} cssClass CSS Class to toggle on the target
53	 */
54	const toggleClassOnClick = function($target, $trigger, $closeTrigger, cssClass) {
55
56		// Reset in case class "open" was saved accidentally
57		$target.removeClass(cssClass);
58		$trigger.removeClass(cssClass).attr('aria-expanded', 'false');
59
60		// Click on trigger toggles class "open"
61		$trigger.off('.toggle').on('click.toggle', function() {
62			const isExpanded = $(this).attr('aria-expanded') === 'true';
63			const $menu = $target.filter('.ed-menu');
64			$(this).toggleClass(cssClass).attr('aria-expanded', !isExpanded);
65			$target.toggleClass(cssClass);
66
67			// Set focus to menu on open
68			if (!isExpanded) {
69				$menu.attr('tabindex', '0');
70				const focusMenu = () => {
71					$menu.focus();
72					$menu.off('transitionend', focusMenu);
73				};
74				$menu.on('transitionend', focusMenu);
75			}
76
77			$menu[0].addEventListener(
78				'blur',
79				function() {
80					$menu[0].removeAttribute('tabindex');
81				}, {
82					once: true
83				}
84			);
85		});
86
87		// Close target when link inside is clicked
88		$target.find('a').click(function() {
89			$target.removeClass(cssClass);
90			$trigger.removeClass(cssClass).attr('aria-expanded', 'false');
91		});
92
93		if (!$closeTrigger || !$closeTrigger.length) {
94			return;
95		}
96
97		$closeTrigger.click(function() {
98			$target.removeClass(cssClass);
99			$trigger.removeClass(cssClass).attr('aria-expanded', 'false');
100		});
101	};
102
103	/**
104	 * Smooth scroll to link targets
105	 * 
106	 * @param {jQuery} $scrollLinks The links
107	 * @param {jQuery} scrollOffset Offset to subtract from the scroll target position (e.g. for fixed positioned elements like a menu)
108	 */
109	const activateSmoothScroll = function($scrollLinks, scrollOffset) {
110		if (typeof scrollOffset === 'undefined') {
111			scrollOffset = 0;
112		}
113
114		const determineTarget = function($trigger, hash) {
115			if (hash == '#!next') {
116				return $trigger.closest('.ed-element').next();
117			}
118			// Prevent invalid selectors
119			try {
120				return $(hash);
121			} catch (e) {
122				return $();
123			}
124		}
125
126		$scrollLinks.click(function(e) {
127			const $target = determineTarget($(this), this.hash);
128			if (!$target.length) return;
129			e.preventDefault();
130
131			viewport.scrollTo($target, 'top', 500, 0);
132
133		});
134	};
135
136	/**
137	 * We are using the fill property on an element to pass user's choices from CSS to JavaScript
138	 * 
139	 * @param {jQuery} $element
140	 */
141	const getStickyMode = function($element) {
142		const fillValue = getComputedStyle($element[0]).fill;
143
144		return fillValue === 'rgb(255, 0, 0)' ?
145			'sticky_banner' :
146			fillValue === 'rgb(0, 255, 0)' ?
147			'sticky_menu' :
148			fillValue === 'rgb(0, 0, 255)' ?
149			'sticky_instant' :
150			fillValue === 'rgb(255, 255, 255)' ?
151			'sticky_reverse' :
152			'sticky_none';
153	};
154
155	/**
156	 * Adds a class to an element when not currently visible
157	 * 
158	 * @param {jQuery} $element The element to handle stickyness for
159	 * @param {string} cssClass The actual CSS class to be applied to the element when it's above a certain scroll position
160	 * @param {jQuery} $banner A banner to reference the scroll position to
161	 */
162	const handleSticky = function($element, cssClass, $banner) {
163		let triggerPos = 0,
164			offset = 0;
165		let menuWrapperHeight = $element.outerHeight();
166		let mode;
167		let prevScroll = 0;
168		$element.removeClass(cssClass);
169		
170		const toggleSpacer = function(toggle) {
171			document.body.style.setProperty('--spacer-height', toggle ? menuWrapperHeight + 'px' : '');
172		};
173
174		const handleScroll = function() {
175			if (!$element.length || mode === 'sticky_none') return;
176			//if (!$element.length || mode === 'sticky_none' || mode === 'sticky_instant') return;
177
178			const isReverse = mode === 'sticky_reverse',
179				curScroll = viewport.getScrollTop();
180
181			if (triggerPos <= curScroll && (!isReverse || prevScroll > curScroll)) {
182				$element.addClass(cssClass);
183				toggleSpacer(true);
184			} else {
185				$element.removeClass(cssClass);
186				toggleSpacer(false);
187			}
188
189			prevScroll = curScroll;
190		};
191		
192		const updateOffset = function() {
193			mode = getStickyMode($element);
194			menuWrapperHeight = $element.outerHeight();
195			if (!$element.hasClass(cssClass)) {
196				offset = $element.offset().top;
197			}
198			if (mode === 'sticky_banner' && !$banner.length) {
199				mode = 'sticky_menu';
200			}
201			if (mode === 'sticky_banner') {
202				triggerPos = $banner.offset().top + ($banner.length ? $banner.outerHeight() : $element.outerHeight());
203			}
204			if (mode === 'sticky_menu' || mode === 'sticky_reverse') {
205				triggerPos = offset + $element.outerHeight();
206			}
207			if (mode === 'sticky_instant') {
208				triggerPos = offset;
209			}
210			
211			handleScroll();
212		}
213		
214		viewport.observe('resize', updateOffset);
215		viewport.observe('animation.end', updateOffset);
216		observeHeightChange($element[0], updateOffset);
217		updateOffset();
218		
219		viewport.observe('scroll', handleScroll);
220		handleScroll();
221	};
222
223	/**
224	 * Adds a class to links whose target is currently inside the viewport
225	 * 
226	 * @param {jQuery} $links Link(s) to be observed
227	 * @param {string} cssClass CSS Class to be applied
228	 * @param {float} sectionViewportRatio Ratio by which the target should be within the viewport
229	 */
230	const addClassOnVisibleLinkTargets = function($links, cssClass, sectionViewportRatio) {
231		if (typeof sectionViewportRatio === 'undefined') {
232			sectionViewportRatio = 1 / 2;
233		}
234
235		const menuTargets = [];
236		const activeLink = $links.filter('.active');
237
238		const links = $links.filter(function() {
239			// Prevent invalid selectors
240			let $target;
241			try {
242				$target = $(this.hash);
243			} catch (e) {
244				return false;
245			}
246			if (!this.hash || !$target.length) {
247				return false;
248			}
249
250			// Cache offset position to improve performance (update on resize)		
251			const updateOffset = function() {
252				$target.data('offset', $target.offset().top);
253			};
254
255			viewport.observe('resize', updateOffset);
256			viewport.observe('animation.end', updateOffset);
257			updateOffset();
258
259			menuTargets.push($target);
260			return true;
261		});
262
263		// No hash links found, so don't handle it at all
264		if (!links.length) {
265			return;
266		}
267
268		const checkVisibility = function() {
269			$links.removeClass('active');
270
271			// Check section position reversely
272			for (let i = menuTargets.length - 1; i >= 0; i--) {
273				const desiredScrollPosition = menuTargets[i].data('offset') - viewport.getHeight() * (1 - sectionViewportRatio);
274				if (viewport.getScrollTop() >= desiredScrollPosition && menuTargets[i][0].offsetParent !== null) {
275					links.eq(i).addClass(cssClass);
276					return;
277				}
278			}
279
280			// Fallback to originally active item
281			activeLink.addClass(cssClass);
282		};
283
284		viewport.observe('scroll', checkVisibility);
285		checkVisibility();
286	};
287})();
288/* End JS for preset "Menu V2" */
289
290/* ---- particles.js config ---- */
291
292/*
293The MIT License (MIT)
294
295Copyright (c) 2015, Vincent Garreau
296
297Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
298
299The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
300
301THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
302*/
303
304$(function() {
305	if (document.body.classList.contains('edit') || document.body.classList.contains('preview')) {
306		return;
307	}		
308
309    particlesJS("particles-js", {
310      "particles": {
311        "number": {
312          "value": 100,
313          "density": {
314            "enable": true,
315            "value_area":1000
316          }
317        },
318        "color": {
319          "value": ["#fff"]
320        },
321        
322        "shape": {
323          "type": "circle",
324          "stroke": {
325            "width": 0,
326            "color": "#fff"
327          },
328          "polygon": {
329            "nb_sides": 5
330          },
331          "image": {
332            "src": "img/github.svg",
333            "width": 100,
334            "height": 100
335          }
336        },
337        "opacity": {
338          "value": 0.6,
339          "random": false,
340          "anim": {
341            "enable": false,
342            "speed": 1,
343            "opacity_min": 0.1,
344            "sync": false
345          }
346        },
347        "size": {
348          "value": 2,
349          "random": true,
350          "anim": {
351            "enable": false,
352            "speed": 40,
353            "size_min": 0.1,
354            "sync": false
355          }
356        },
357        "line_linked": {
358          "enable": true,
359          "distance": 120,
360          "color": "#ffffff",
361          "opacity": 0.4,
362          "width": 1
363        },
364      },
365      "interactivity": {
366        "detect_on": "canvas",
367        "events": {
368          "onhover": {
369            "enable": true,
370            "mode": "grab"
371          },
372          "onclick": {
373            "enable": false
374          },
375          "resize": true
376        },
377        "modes": {
378          "grab": {
379            "distance": 140,
380            "line_linked": {
381              "opacity": 1
382            }
383          },
384          "bubble": {
385            "distance": 400,
386            "size": 40,
387            "duration": 2,
388            "opacity": 8,
389            "speed": 3
390          },
391          "repulse": {
392            "distance": 200,
393            "duration": 0.4
394          },
395          "push": {
396            "particles_nb": 4
397          },
398          "remove": {
399            "particles_nb": 2
400          }
401        }
402      },
403      "retina_detect": true
404    });
405});

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.