PageSourceSearch

https://fredeshiem.nl/wp-content/themes/Impreza/common/js/elements/counter.js?ver=8.39.2

js fredeshiem.nl collected 2026-10-08 15:11:11 UTC 9,164 bytes, 293 lines download raw bytes

1/**
2 * UpSolution Element: Counter
3 */
4! function( $, undefined ) {
5
6	var // Private variables that are used only in the context of this function, it is necessary to optimize the code
7		_parseFloat = parseFloat,
8		_parseInt = parseInt,
9		_undefined = undefined,
10		_window = window
11
12	/**
13	 * Counter Number part animations
14	 *
15	 * @param container
16	 * @constructor
17	 */
18	var USCounterNumber = function( container ) {
19		var self = this;
20
21		self.$container = $( container );
22		self.initialString = self.$container.html() + '';
23		self.finalString = self.$container.data( 'final' ) + '';
24		self.format = self.getFormat( self.initialString, self.finalString );
25		if ( self.format.decMark ) {
26			var pattern = new RegExp( '[^0-9\/' + self.format.decMark + ']+', 'g' );
27			self.initial = _parseFloat( self.initialString.replace( pattern, '' ).replace( self.format.decMark, '.' ) );
28			self.final = _parseFloat( self.finalString.replace( pattern, '' ).replace( self.format.decMark, '.' ) );
29		} else {
30			self.initial = _parseInt( self.initialString.replace( /[^0-9]+/g, '' ) );
31			self.final = _parseInt( self.finalString.replace( /[^0-9]+/g, '' ) );
32		}
33		if ( self.format.accounting ) {
34			if ( self.initialString.length > 0 && self.initialString[ 0 ] == '(' ) {
35				self.initial = - self.initial;
36			}
37			if ( self.finalString.length > 0 && self.finalString[ 0 ] == '(' ) {
38				self.final = - self.final;
39			}
40		}
41	};
42	/**
43	 * Export API
44	 */
45	USCounterNumber.prototype = {
46
47		/**
48		 * Function to be called at each animation frame
49		 * @param now float Relative state between 0 and 1
50		 */
51		step: function( now ) {
52			var self = this,
53				value = ( 1 - now ) * self.initial + self.final * now,
54				intPart = Math[ self.format.decMark ? 'floor' : 'round' ]( value ).toString(),
55				result = '';
56			if ( self.format.zerofill ) {
57				// Check how many zeros we need to add to this step value
58				var amountOfZeros = ( self.format.intDigits - intPart.length );
59				if ( amountOfZeros > 0 ) {
60					intPart = '0'.repeat( amountOfZeros ) + intPart;
61				}
62			}
63			if ( self.format.groupMark ) {
64				if ( self.format.indian ) {
65					result += intPart.replace( /(\d)(?=(\d\d)+\d$)/g, '$1' + self.format.groupMark );
66				} else {
67					result += intPart.replace( /\B(?=(\d{3})+(?!\d))/g, self.format.groupMark );
68				}
69			} else {
70				result += intPart;
71			}
72			if ( self.format.decMark ) {
73				var decimalPart = ( value % 1 ).toFixed( self.format.decDigits ).substring( 2 );
74				result += self.format.decMark + decimalPart;
75			}
76			if ( self.format.accounting && result.length > 0 && result[ 0 ] == '-' ) {
77				result = '(' + result.substring( 1 ) + ')';
78			}
79			self.$container.html( result );
80		},
81
82		/**
83		 * Get number format based on initial and final number strings
84		 * @param initial string
85		 * @param final string
86		 * @returns {{groupMark, decMark, accounting, zerofill, indian}}
87		 */
88		getFormat: function( initial, final ) {
89			var self = this,
90				iFormat = self._getFormat( initial ),
91				fFormat = self._getFormat( final ),
92				// Final format has more priority
93				format = $.extend( {}, iFormat, fFormat );
94			// Group marks detector is more precise, so using it in controversial cases
95			if ( format.groupMark == format.decMark ) {
96				delete format.groupMark;
97			}
98			return format;
99		},
100
101		/**
102		 * Get number format based on a single number string
103		 * @param str string
104		 * @returns {{groupMark, decMark, accounting, zerofill, indian}}
105		 */
106		_getFormat: function( str ) {
107			var marks = str.replace( /[0-9\(\)\-]+/g, '' ),
108				format = {};
109			if ( str.charAt( 0 ) == '(' ) {
110				format.accounting = true;
111			}
112			if ( /^0[0-9]/.test( str ) ) {
113				format.zerofill = true;
114			}
115			str = str.replace( /[\(\)\-]/g, '' );
116			if ( marks.length != 0 ) {
117				if ( marks.length > 1 ) {
118					format.groupMark = marks.charAt( 0 );
119					if ( marks.charAt( 0 ) != marks.charAt( marks.length - 1 ) ) {
120						format.decMark = marks.charAt( marks.length - 1 );
121					}
122					if ( str.split( format.groupMark ).length > 2 && str.split( format.groupMark )[ 1 ].length == 2 ) {
123						format.indian = true;
124					}
125				} else/*if (marks.length == 1)*/ {
126					format[ ( ( ( str.length - 1 ) - str.indexOf( marks ) ) == 3 && marks !== '.' ) ? 'groupMark' : 'decMark' ] = marks;
127				}
128				if ( format.decMark ) {
129					format.decDigits = str.length - str.indexOf( format.decMark ) - 1;
130				}
131			}
132			if ( format.zerofill ) {
133				format.intDigits = str.replace( /[^\d]+/g, '' ).length - ( format.decDigits || 0 );
134			}
135
136			return format;
137		}
138	};
139
140	/**
141	 * Counter Number part animations
142	 *
143	 * @param container
144	 * @constructor
145	 */
146	var USCounterText = function( container ) {
147		var self = this;
148		self.$container = $( container );
149		self.initial = self.$container.text() + '';
150		self.final = self.$container.data( 'final' ) + '';
151		self.partsStates = self.getStates( self.initial, self.final );
152		self.len = 1 / ( self.partsStates.length - 1 );
153		// Text value won't be changed on each frame, so we'll update it only on demand
154		self.curState = 0;
155	};
156	/**
157	 * Export API
158	 */
159	USCounterText.prototype = {
160
161		/**
162		 * Function to be called at each animation frame
163		 *
164		 * @param now float Relative state between 0 and 1
165		 */
166		step: function( now ) {
167			var self = this,
168				state = Math.round( Math.max( 0, now / self.len ) );
169			if ( state == self.curState ) {
170				return;
171			}
172			self.$container.html( self.partsStates[ state ] );
173			self.curState = state;
174		},
175
176		/**
177		 * Slightly modified Wagner-Fischer algorithm to obtain the shortest edit distance with intermediate states
178		 *
179		 * @param initial string The initial string
180		 * @param final string The final string
181		 * @returns {[]}
182		 */
183		getStates: function( initial, final ) {
184			var min = Math.min,
185				dist = [],
186				i, j;
187			for ( i = 0; i <= initial.length; i ++ ) {
188				dist[ i ] = [ i ];
189			}
190			for ( j = 1; j <= final.length; j ++ ) {
191				dist[ 0 ][ j ] = j;
192				for ( i = 1; i <= initial.length; i ++ ) {
193					dist[ i ][ j ] = ( initial[ i - 1 ] === final[ j - 1 ] ) ? dist[ i - 1 ][ j - 1 ] : ( Math.min( dist[ i - 1 ][ j ], dist[ i ][ j - 1 ], dist[ i - 1 ][ j - 1 ] ) + 1 );
194				}
195			}
196			// Obtaining the intermediate states
197			var states = [ final ];
198			for ( i = initial.length, j = final.length; i > 0 || j > 0; i --, j -- ) {
199				var min = dist[ i ][ j ];
200				if ( i > 0 ) {
201					min = Math.min( min, dist[ i - 1 ][ j ], ( j > 0 ) ? dist[ i - 1 ][ j - 1 ] : min );
202				}
203				if ( j > 0 ) {
204					min = Math.min( min, dist[ i ][ j - 1 ] );
205				}
206				if ( min >= dist[ i ][ j ] ) {
207					continue;
208				}
209				if ( min == dist[ i ][ j - 1 ] ) {
210					// Remove
211					states.unshift( states[ 0 ].substring( 0, j - 1 ) + states[ 0 ].substring( j ) );
212					i ++;
213				} else if ( min == dist[ i - 1 ][ j - 1 ] ) {
214					// Modify
215					states.unshift( states[ 0 ].substring( 0, j - 1 ) + initial[ i - 1 ] + states[ 0 ].substring( j ) );
216				} else if ( min == dist[ i - 1 ][ j ] ) {
217					// Insert
218					states.unshift( states[ 0 ].substring( 0, j ) + initial[ i - 1 ] + states[ 0 ].substring( j ) );
219					j ++;
220				}
221			}
222			return states;
223		}
224	};
225
226	/**
227	 * @param container
228	 * @constructor
229	 */
230	var USCounter = function( container ) {
231		var self = this;
232
233		// Commonly used DOM elements
234		self.$container = $( container );
235		self.parts = [];
236		self.duration = _parseFloat( self.$container.data( 'duration' ) || 2 ) * 1000;
237		self.$container.find( '.w-counter-value-part' ).each( function( index, part ) {
238			var $part = $( part );
239			// Skipping the ones that won't be changed
240			if ( $part.html() + '' == $part.data( 'final' ) + '' ) {
241				return;
242			}
243			var type = $part.usMod( 'type' );
244			if ( type == 'number' ) {
245				self.parts.push( new USCounterNumber( $part ) );
246			} else {
247				self.parts.push( new USCounterText( $part ) );
248			}
249		} );
250		if ( _window.$us !== _undefined && _window.$us.scroll !== _undefined ) {
251			// Animate element when it becomes visible
252			$us.waypoints.add( self.$container, /* offset */'15%', self.animate.bind( self ) );
253		} else {
254			// No waypoints available: animate right from the start
255			self.animate();
256		}
257	};
258	/**
259	 * Export API
260	 */
261	USCounter.prototype = {
262		animate: function( duration ) {
263			var self = this;
264			self.$container.css( 'w-counter', 0 ).animate( { 'w-counter': 1 }, {
265				duration: self.duration,
266				step: self.step.bind( self )
267			} );
268		},
269
270		/**
271		 * Function to be called at each animation frame
272		 *
273		 * @param now float Relative state between 0 and 1
274		 */
275		step: function( now ) {
276			var self = this;
277			for ( var i = 0; i < self.parts.length; i ++ ) {
278				self.parts[ i ].step( now );
279			}
280		}
281	};
282
283	$.fn.wCounter = function( options ) {
284		return this.each( function() {
285			var self = this;
286			$( self ).data( 'wCounter', new USCounter( self, options ) );
287		} );
288	};
289
290	$( function() {
291		$( '.w-counter' ).wCounter();
292	} );
293}( 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.