PageSourceSearch

https://freakonomics.com/wp-content/themes/freakonomics_2021/lib/main.js?v=1.1.46

js freakonomics.com collected 2026-09-24 08:24:35 UTC 16,313 bytes, 579 lines download raw bytes

1///////////////////////////////////////////
2// utility functions
3///////////////////////////////////////////
4
5function console_log( msg )
6{
7	if( ( window['console'] !== undefined ) )
8		console.log( msg );
9}
10
11function is_touch_device()
12{
13	return 'ontouchstart' in window // works on most browsers
14		|| 'onmsgesturechange' in window; // works on ie10
15}
16
17function wkd_set_cookie(name, value, days)
18{
19    if (days) {
20        var date = new Date();
21        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
22        var expires = "; expires=" + date.toGMTString();
23    } else var expires = "";
24    document.cookie = escape(name) + "=" + escape(value) + expires + "; path=/";
25}
26
27function wkd_get_cookie(name)
28{
29    var nameEQ = escape(name) + "=";
30    var ca = document.cookie.split(';');
31    for (var i = 0; i < ca.length; i++)
32	{
33        var c = ca[i];
34        while (c.charAt(0) == ' ') c = c.substring(1, c.length);
35        if (c.indexOf(nameEQ) == 0) return unescape(c.substring(nameEQ.length, c.length));
36    }
37    return null;
38}
39
40function wkd_remove_cookie(name)
41{
42    wkd_set_cookie(name, "", -1);
43}
44
45function get_human_readable_time( seconds )
46{
47	var time_lengths	= [60, 1];
48	var output			= '';
49
50	for ( var s = 0; s < time_lengths.length; s++ )
51	{
52		var d = Math.floor( seconds / time_lengths[s] );
53		var readable = d;
54		if ( readable < 10 )
55			readable = '0' + readable;
56
57		if ( s > 0 )
58			output = output + ':';
59		output = output + readable;
60		seconds -= ( d * time_lengths[s] );
61	}
62
63	return output;
64}
65
66///////////////////////////////////////////
67// site functions
68///////////////////////////////////////////
69
70function wkd_toggle_menu()
71{
72	jQuery('body').toggleClass( 'menu_open' );
73}
74function wkd_close_menu()
75{
76	jQuery('body').removeClass( 'menu_open' );
77}
78
79function wkd_toggle_buy()
80{
81	$('body').toggleClass( 'buy_open' );
82}
83function wkd_close_buy()
84{
85	$('body').removeClass( 'buy_open' );
86}
87
88function wkd_toggle_search()
89{
90	$('body').toggleClass( 'search_open' );
91	if ( $('body').hasClass( 'search_open') )
92		$('#search_text').focus();
93}
94function wkd_close_search()
95{
96	$('body').removeClass( 'search_open' );
97}
98
99function wkd_do_search()
100{
101	var search_text = $('#search_text').val();
102	if ( search_text.match( /^\s*$/) )
103		return false;
104
105	document.location.href = '/?s=' + encodeURIComponent( search_text );
106	return false;
107}
108
109$(document).ready( function() {
110
111
112	$('.hero_slider').each( function() {
113		$(this).slick( {
114			infinite: false,
115			dots: true,
116			arrows: true,
117			adaptiveHeight: false,
118			autoplay: true,
119			autoplaySpeed: 3000,
120			speed: 1000,
121			slidesToShow: 1,
122			slidesToScroll: 1
123		} );
124	} );
125
126	$('.hero_slider_custom').each( function() {
127		$(this).slick( {
128			infinite: false,
129			dots: true,
130			arrows: true,
131			adaptiveHeight: false,
132			autoplay: true,
133			autoplaySpeed: 3000,
134			speed: 1000,
135			slidesToShow: 1,
136			slidesToScroll: 1
137		} );
138	} );
139	$('.hero_slider_custom .slick-next').each( function() {
140		console_log( "Overriding next button." );
141		$(this).click( function( evt ) {
142			var slide_num = $('.hero_slider_custom').slick('slickCurrentSlide');
143			// if this is the last slide, loop back to the start
144			if ( slide_num >= wkd_total_features - 1 )
145			{
146				console_log( "Looping to zero." );
147				$('.hero_slider_custom').slick( 'slickGoTo', 0 );
148			}
149		} );
150	} );
151	$('.hero_slider_custom .slick-prev').each( function() {
152		console_log( "Overriding previous button." );
153		$(this).click( function( evt ) {
154			var slide_num = $('.hero_slider_custom').slick('slickCurrentSlide');
155			// if this is the last slide, loop back to the start
156			if ( slide_num <= 0 )
157			{
158				console_log( "Looping to the end." );
159				$('.hero_slider_custom').slick( 'slickGoTo',  wkd_total_features - 1 );
160			}
161		} );
162	} );
163
164	// thumbnail sliders
165	$('.thumb_slider').each( function() {
166		console_log( "Initializing thumbnail slider." );
167		$(this).slick( {
168			infinite: false,
169			dots: false,
170			arrows: true,
171			adaptiveHeight: false,
172			autoplay: true,
173			autoplaySpeed: 3000,
174			speed: 1000,
175			slidesToShow: 5,
176			slidesToScroll: 5
177		} );
178	} );
179} );
180
181
182
183///////////////////////////////////////////
184// podcast player
185///////////////////////////////////////////
186var wkd_last_audio_time = 0;
187var wkd_last_audio_id	= '';
188var wkd_last_audio_src	= '';
189var wkd_audio_reboot	= false;
190var wkd_timeline_drag	= false;
191var wkd_timeline_drag_x	= 0;
192var wkd_audio_playing	= null;
193var wkd_audio_mouse_y	= 0;
194var wkd_audio_buffered	= 0;
195
196function wkd_render_player( audio_id )
197{
198	var audio = $('#' + audio_id);
199	if ( !audio )
200	{
201		throw new Error( "Invalid DOM ID passed to wkd_render_player: " + audio_id );
202		return;
203	}
204
205	var audio_obj = document.getElementById( audio_id );
206	audio_obj.onerror = function( e ) {
207
208		console_log( "Media error. Attempting to restart..." );
209
210		wkd_audio_reboot	= true;
211		wkd_last_audio_id	= this.id;
212		wkd_last_audio_src	= this.src;
213		wkd_last_audio_time	= this.currentTime;
214
215		$('#' + wkd_last_audio_id ).remove();
216		setTimeout( function() {
217			console_log( "Reloading audio object." );
218			$('#' + wkd_last_audio_id + '_player').before(
219				$( '<audio src="' + wkd_last_audio_src + '" id="' + wkd_last_audio_id + '" class="wkd_player_audio"></audio>' )
220			);
221			setTimeout( function() {
222				console_log( "Attempting to resume playing." );
223				var audio_obj = document.getElementById( wkd_last_audio_id );
224				audio_obj.currentTime = wkd_last_audio_time;
225				audio_obj.play();
226				wkd_audio_reboot = false;
227
228			}, 100 );
229		}, 200 );
230	};
231	audio_obj.onended = function() {
232		wkd_toggle_audio_play( this.id );
233	};
234
235	// build the player shell
236	var player_id = audio_id + '_player';
237	var player = $('<div></div>');
238	player.attr( 'id', player_id ).attr( 'aria-label', 'Podcast Player' ).attr( 'data-audio-id', audio_id ).addClass( 'wkd_player' );
239
240	// build the play/pause button
241	var play_button = $('<div></div>');
242	play_button.addClass( 'play_button mode_pause' );
243	play_button.attr( 'data-audio-id', audio_id ).attr( 'aria-controls', audio_id ).attr( 'role', 'button' ).attr( 'tabindex', '0' ).attr( 'aria-label', 'Play and pause' );
244	play_button.bind( 'click keypress', function( evt ) {
245		if ( evt.keyCode || evt.which )
246		{
247			var code = evt.keyCode || evt.which;
248			if ( evt.type != "click" && code != 1 && code != 13 && code != 32 )
249				return true;
250		}
251
252		var audio_id	= $(this).attr( 'data-audio-id' );
253		var audio_obj	= document.getElementById( audio_id );
254
255		// pause any already-playing players
256		$('.wkd_player_audio').each( function() {
257			var aid	= $(this).attr('id');
258			if ( aid && aid != audio_id )
259			{
260				wkd_toggle_audio_play( aid, -1 );
261			}
262		} );
263
264		// toggle the targeted player
265		wkd_toggle_audio_play( audio_id, audio_obj.paused );
266		wkd_audio_playing = audio_obj;
267	} );
268	player.append( play_button );
269
270	// add the time played text
271	var time_played	= $('<div></div>');
272	time_played.addClass( 'time_played' );
273	time_played.attr( 'data-audio-id', audio_id );
274	time_played.html('<span>00:00</span>');
275	player.append( time_played );
276
277	// add rewind button
278	var rewind = $('<div></div>');
279	rewind.addClass( 'rewind' );
280	rewind.attr( 'data-audio-id', audio_id ).attr( 'role', 'button').attr( 'tabindex', '0' ).attr( 'aria-label', 'Rewind ten seconds' );
281	rewind.bind( 'click keypress', function( evt ) {
282		if ( evt.keyCode || evt.which )
283		{
284			var code = evt.keyCode || evt.which;
285			if ( evt.type != "click" && code != 1 && code != 13 && code != 32 )
286				return true;
287		}
288
289		var audio = document.getElementById( audio_id );
290		if ( !audio.duration )
291			return;
292
293		var updated_time = audio_obj.currentTime - 10;
294		if ( updated_time < 0 )
295			updated_time = 0;
296		audio_obj.currentTime = updated_time;
297	} );
298	player.append( rewind );
299
300	// add the timeline
301	var timeline = $('<div></div>');
302	timeline.addClass( 'timeline' );
303	timeline.attr( 'data-audio-id', audio_id );
304	var timeline_track = $('<span class="timeline_outer"><span class="timeline_buffered"><span class="timeline_inner"></span></span></span>');
305	timeline_track.click( function( e ) {
306		if ( wkd_audio_reboot )
307			return;
308
309	} );
310	timeline_track.mousedown( function( e ) {
311		wkd_timeline_drag = $(this);
312		wkd_set_timeline( wkd_timeline_drag, e.pageX );
313		e.stopPropagation();
314
315	} );
316	timeline_track.mouseout( function( e ) {
317		if ( wkd_timeline_drag )
318		{
319			wkd_set_timeline( wkd_timeline_drag, e.pageX );
320		}
321	} );
322	timeline.append( timeline_track );
323	player.append( timeline );
324
325	// add total-time panel
326	var time_total = $('<div></div>' );
327	time_total.addClass( 'time_total' );
328	time_total.attr( 'data-audio-id', audio_id );
329	if ( audio.attr('data-audio-time') )
330	{
331		time_total.html('<span>' + audio.attr('data-audio-time') + '</span>' );
332	}
333	player.append( time_total );
334
335
336	// add the volume control
337	var volume_block = $('<div></div>' );
338	volume_block.addClass( 'volume_toggle volume_on' );
339	volume_block.attr( 'data-audio-id', audio_id ).attr( 'role', 'button').attr( 'tabindex', '0' ).attr( 'aria-label', 'Mute' );
340	volume_block.on( 'click keypress', function( evt ) {
341		if ( wkd_audio_reboot )
342			return;
343
344		if ( evt.keyCode || evt.which )
345		{
346			var code = evt.keyCode || evt.which;
347			if ( evt.type != "click" && code != 1 && code != 13 && code != 32 )
348				return true;
349		}
350
351		var audio = document.getElementById( audio_id );
352		if ( !audio.duration )
353			return;
354
355		if ( $(this).hasClass( 'volume_on' ) )
356		{
357			$(this).removeClass( 'volume_on' );
358			$(this).addClass( 'volume_off' );
359			audio.volume = 0;
360		} else {
361			$(this).removeClass( 'volume_off' );
362			$(this).addClass( 'volume_on' );
363			audio.volume = 1;
364		}
365	} );
366	player.append( volume_block );
367
368	// build the download button
369	var download_file	= audio.attr( 'data-filename' );
370	var download_url	= audio_obj.src;
371	var download_target	= ' target="_blank" ';
372	if ( download_url.match( /omny\.fm/i) )
373	{
374		download_target = '';
375		download_url += '?requestSource=Widget&utm_source=Embed&download=true';
376	}
377	player.append( $('<div class="download"><a ' + download_target + ' href="' + download_url + '" title="Download full audio" download="' + download_file + '"><span>Download</span></a></div>' ) );
378	audio.before( player );
379
380	// if this is a reboot, attempt to move back to where we were in time
381	if ( wkd_last_audio_time > 0 )
382	{
383		audio_obj.play();
384		audio_obj.currentTime = wkd_last_audio_time;
385	}
386}
387
388function wkd_set_timeline( timeline_block, mouse_x )
389{
390	var audio_id	= timeline_block.parent().attr( 'data-audio-id' );
391	var audio		= document.getElementById( audio_id );
392	var offset		= timeline_block.offset();
393	var rel_x		= mouse_x - offset.left;
394	var percent_clicked = rel_x / timeline_block.width();
395
396	if ( !audio.duration )
397		return;
398
399	// if they're clicking close enough to the start, start over
400	if ( 100 * percent_clicked < 1 )
401		percent_clicked = 0;
402	var new_time = Math.round( audio.duration * percent_clicked );
403	if ( new_time >= audio.duration )
404		new_time = audio.duration;
405
406	wkd_last_audio_time = new_time;
407	audio.currentTime = new_time;
408	if ( new_time >= audio.duration )
409		wkd_toggle_audio_play( audio_id );
410}
411
412function wkd_toggle_audio_play( audio_id, play )
413{
414	var audio_obj	= document.getElementById(audio_id);
415	var play_button	= $('#' + audio_id + '_player .play_button').first();
416	if ( audio_obj.volume < 0 )
417		audio_obj.volume = 1;
418
419	play_button.removeClass( 'mode_pause' );
420	play_button.removeClass( 'mode_play' );
421
422	if ( play && play != -1 && audio_obj.paused )
423	{
424		play_button.addClass( 'mode_play' );
425		audio_obj.play();
426	} else {
427		play_button.addClass( 'mode_pause' );
428		audio_obj.pause();
429	}
430}
431
432function wkd_update_audio_players()
433{
434	if ( wkd_audio_reboot )
435		return;
436
437	$('.wkd_player_audio').each( function() {
438		var audio_id	= $(this).attr('id');
439		var audio_obj	= document.getElementById( audio_id );
440		if ( audio_obj && audio_obj.duration )
441		{
442			var buffered	= audio_obj.buffered.end(audio_obj.buffered.length - 1);
443			var buffered_percent	= ( 100 * ( buffered / audio_obj.duration ) ).toFixed(2);
444
445//			var percent_complete	= ( 100 * ( audio_obj.currentTime / audio_obj.duration ) ).toFixed( 2 );
446			var percent_complete	= ( audio_obj.currentTime / audio_obj.duration );
447			var percent_width		= Math.floor( $('#' + audio_id + '_player .timeline_outer').width() * percent_complete );
448
449			$('#' + audio_id + '_player .timeline span.timeline_inner').css( {
450				'width' : '' + percent_width + 'px'
451			} );
452
453			$('#' + audio_id + '_player .timeline span.timeline_buffered').css( {
454				'width' : '' + buffered_percent + '%'
455			} );
456
457			var time_played	= get_human_readable_time( audio_obj.currentTime );
458			var time_total	= get_human_readable_time( audio_obj.duration );
459			$('#' + audio_id + '_player .time_played').html( '<span>' + time_played + '</span>' );
460			$('#' + audio_id + '_player .time_total').html( '<span>' + time_total + '</span>' );
461			if ( audio_obj.currentTime >= audio_obj.duration )
462				wkd_toggle_audio_play( audio_id );
463
464		}
465	} );
466}
467
468function wkd_bind_player_input()
469{
470	/*
471	$(document).keypress( function( e ) {
472		if ( e.charCode == KEY_CODE_SPACE && wkd_audio_playing != null )
473		{
474			wkd_toggle_audio_play( wkd_audio_playing.id, wkd_audio_playing.paused );
475		}
476	} );
477	*/
478	$(document).mousemove( function( e ) {
479		if ( wkd_timeline_drag )
480		{
481			wkd_set_timeline( wkd_timeline_drag, e.pageX );
482			e.stopPropagation();
483		}
484	} );
485	$(document).mouseup( function( e ) {
486		if ( wkd_timeline_drag )
487		{
488			wkd_set_timeline( wkd_timeline_drag, e.pageX );
489			wkd_timeline_drag = null;
490			e.stopPropagation();
491		}
492	} );
493
494}
495
496$(function() {
497
498	var player_found = false;
499	$('.wkd_player_audio').each( function() {
500//		console_log( "Found player: " + $(this).attr('id') );
501		player_found = true;
502		wkd_render_player( $(this).attr('id') );
503	} );
504
505	if ( player_found )
506		wkd_bind_player_input();
507} );
508
509var wkd_player_updates = setInterval( "wkd_update_audio_players()", 250 );
510
511function wkd_series_links( id )
512{
513	wkd_close_series_links();
514	var series_links = $('#series_links_' + id);
515	series_links.detach();
516	$('body').append( series_links );
517	$('body').addClass( 'series_open' );
518	series_links.addClass('series_links_open');
519}
520function wkd_close_series_links()
521{
522	$('.series_links').each( function() {
523		$(this).removeClass('series_links_open');
524	} );
525	$('body').removeClass( 'series_open' );
526}
527
528function wkd_expand_transcript(button)
529{
530	if ( $('#transcript_inner').hasClass( 'expanded' ) )
531	{
532		$('#transcript_inner').css( 'height', '650px' ).removeClass( 'expanded' );
533		$(button).html("Read full Transcript");
534	} else {
535		$('#transcript_inner').css( 'height', 'auto' ).addClass( 'expanded' );
536		$(button).html("Collapse Transcript");
537	}
538}
539
540// cookie notification pop-up
541function wkd_pop_cookie_note( force )
542{
543	var note_popped = wkd_get_cookie('fre_cookie_note_2023');
544	if ( note_popped && !force )
545	{
546		$('#fre_cookie_modal').hide();
547	} else {
548		$('#fre_cookie_modal').css( { display: "block" } );
549		setTimeout( function() {
550			$('body').addClass( 'cookie_note_popped' );
551		}, 100 );
552	}
553}
554function wkd_hide_cookie_note()
555{
556	$('body').removeClass( 'cookie_note_popped' );
557}
558function wkd_set_cookie_note()
559{
560	wkd_set_cookie( 'fre_cookie_note_2023', '1', 730 );
561	$('body').removeClass( 'cookie_note_popped' );
562}
563
564$(document).ready( function() {
565	$('.payment-form-plan-list .sc-plan-selector__mp-tier-label').each( function() {
566		// monthly
567		console.log( 'For: ' + $(this).attr('for') );
568		var plan = $(this).attr('for');
569		if ( plan == 'plan-8939' || plan == 'plan-9259' )
570		{
571			$(this).html('<img src="/wp-content/themes/freakonomics_2021/images/plus_button_monthlyb.png" alt="Monthly plan">');
572
573		// annually
574	} else if ( plan == 'plan-8938' || plan == 'plan-9258' ) {
575			$(this).html('<img src="/wp-content/themes/freakonomics_2021/images/plus_button_annualb.png" alt="Annual plan">');
576
577		}
578	} );
579} );

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.