PageSourceSearch

https://vicejazycnavychova.cz/wp-content/themes/mioweb3/modules/member/js/front.js?ver=1791165630

js vicejazycnavychova.cz collected 2026-10-05 22:14:59 UTC 29,294 bytes, 948 lines download raw bytes

1jQuery(function ($) {
2
3	$('.el_mem_checklist').mwMemberChecklist();
4
5	$('.mw_element_item_popup .mw_element_item_title a, .mw_element_item_popup .mw_element_item_image_hover').mwElementPopup();
6
7	$('#member_show_profile').mwMemberProfileAdmin();
8
9	var urlParams = new URLSearchParams(window.location.search);
10	if (urlParams.get('mw_discord') === 'connect') {
11		urlParams.delete('mw_discord');
12		var newSearch = urlParams.toString();
13		history.replaceState(null, null, window.location.pathname + (newSearch ? '?' + newSearch : ''));
14		var $profileEl = $('#member_show_profile');
15		if ($profileEl.length && $profileEl[0].MwMemberProfileAdmin) {
16			$profileEl[0].MwMemberProfileAdmin.openModal('integrations');
17		}
18	}
19
20	// TODO JQMIGRATE: jQuery.hover is deprecated, use "mouseenter" and "mouseleave" events (https://stackoverflow.com/a/13004732)
21	$("#member_user_avatar").hover(
22		function () {
23			$(this).addClass('member_user_menu_open');
24			$(this).removeClass('member_user_menu_close');
25		},
26		function () {
27			$(this).removeClass('member_user_menu_open');
28			$(this).addClass('member_user_menu_close');
29		});
30
31	// Close member user menu when user touches a link inside the menu (mobile fix)
32	$("#member_user_menu a").on('click', function () {
33		$("#member_user_avatar").removeClass('member_user_menu_open').addClass('member_user_menu_close');
34	});
35
36	//news
37	$(".member_new_show_text").click(function () {
38		$(this).closest(".mw_element_item_description").find(".member_new_short").toggle();
39		$(this).closest(".mw_element_item_description").find(".member_new_text").toggle();
40		return false;
41	});
42
43	mw_init_register_form('.mw_member_register_form');
44	mw_init_login_form('.member_login_form');
45});
46
47function mw_init_register_form(target) {
48	jQuery(target).mwForm({
49		onsubmit: function (self, $form) {
50			var form = $form.serialize();
51			var loading = self.$el.find("button");
52			loading.addClass('working');
53
54			jQuery.post(ajaxurl, 'action=send_registration_form&' + form, function (data) {
55
56				if (data.redirect) {
57					if (data.target) {
58						window.parent.location = data.redirect;
59					} else {
60						window.location = data.redirect;
61					}
62				}
63				else {
64					self.showMessage(data);
65					loading.removeClass('working');
66				}
67
68			}).fail(function (data) {
69				console.log(data);
70				self.showMessage({'sended': 'error', 'message': mem_front_texts.reg_nosended});
71				loading.removeClass('working');
72			});
73
74		}
75	});
76}
77
78function mw_init_login_form(target) {
79	jQuery(target).mwMemberLoginForm();
80}
81
82function mw_init_member_checklist(target) {
83	jQuery(target).mwMemberChecklist();
84}
85
86;(function (factory) {
87
88	if (typeof define === 'function' && define.amd) {
89		define(['jquery'], factory);
90	} else if (typeof exports !== 'undefined') {
91		module.exports = factory(require('jquery'));
92	} else {
93		factory(jQuery);
94	}
95
96})(function ($) {
97
98	// checklist
99	var MwMemberChecklist = (function (element) {
100
101		function _MwMemberChecklist(element) {
102			this.$el = $(element);
103			this.userId = this.$el.data('user_id');
104			this.checklistId = this.$el.data('checklist_id');
105			this.type = this.$el.data('type');
106			var obj = this;
107
108			this.$el.find('li').click(function() {
109
110				$(this).find('.mem_checklist_checkbox').toggleClass('mem_checklist_checkbox_checked');
111				var checkbox = $(this).find('input');
112
113				if($(this).find('.mem_checklist_checkbox').hasClass('mem_checklist_checkbox_checked')) {
114					checkbox.attr('checked', true);
115					var checked = 1;
116				} else {
117					checkbox.attr('checked', false);
118					var checked = 0;
119				}
120				var id = checkbox.val();
121
122				$.post(ajaxurl, {
123					"action": "mwmSaveMemberChecklist",
124					"taskId": id,
125					"checked": checked,
126					"type": obj.type,
127					"userId": obj.userId,
128					"checklistId": obj.checklistId,
129				}, function (data) {
130					//console.log(data);
131				})
132
133			});
134
135		}
136
137		return _MwMemberChecklist;
138
139	})();
140
141	$.fn.mwMemberChecklist = function (options) {
142		return this.each(function (index, el) {
143			el.MwMemberChecklist = new MwMemberChecklist(el, options);
144		});
145	};
146
147	// login form
148	var MwMemberLoginForm = (function (element) {
149
150		function _MwMemberLoginForm(element) {
151			this.$el = $(element);
152			var obj = this;
153
154			this.$el.find('.mw_password_input_container').mwPasswordInput();
155
156			this.$el.find('.ve_form_text').on('paste', function(e) {
157				let input = $(this);
158				e.preventDefault();
159				let pastedText = (e.originalEvent || e).clipboardData.getData('text');
160				let trimmedText = pastedText.trim();
161				input.val(trimmedText);
162			});
163
164			this.$el.find('.mw_send_two_factor_login').click(function (e) {
165				e.preventDefault();
166
167				let $but = $(this);
168				if ($but.hasClass('working')) {
169					return false;
170				}
171				$but.addClass('working');
172
173				let form = obj.$el.serialize();
174
175				$.post(ajaxurl, 'action=mw_send_login_form&' + form, function (response) {
176					obj.$el.find('.mw_login_form_message_container').html('');
177					obj.$el.find('.mw_login_code_message_container').html('');
178					if (response.success) {
179						obj.$el.find('.mw_login_code_container').show();
180						obj.$el.closest('.col').css('z-index', 3);
181						obj.$el.closest('.element_container').css('z-index', 3);
182					} else {
183						obj.$el.find('.mw_login_form_message_container').html(response.data.message);
184					}
185					$but.removeClass('working');
186				}).fail(function (data) {
187					console.log(data);
188					self.showMessage({'sended': 'error', 'message': 'test'});
189					$but.removeClass('working');
190				});
191			});
192
193			this.$el.find('.mw_check_two_factor_code').click(function (e) {
194				e.preventDefault();
195				obj.$el.find('.mw_login_code_message_container').html('');
196
197				let $but = $(this);
198				if ($but.hasClass('working')) {
199					return false;
200				}
201				$but.addClass('working');
202
203				let form = obj.$el.serialize();
204
205				$.post(ajaxurl, 'action=mw_check_login_code&' + form, function (response) {
206					if (response.success) {
207						window.location.href = response.data.redirect;
208					} else {
209						if (response.data.show_login) {
210							obj.$el.find('.mw_login_code_container').hide();
211							obj.$el.find('.mw_login_code_container input').val('');
212							obj.$el.find('.mw_login_form_message_container').html(response.data.message);
213						} else {
214							obj.$el.find('.mw_login_code_message_container').html(response.data.message);
215						}
216						$but.removeClass('working');
217					}
218				}).fail(function (data) {
219					console.log(data);
220					self.showMessage({'sended': 'error', 'message': 'Neznámá chyba'});
221					$but.removeClass('working');
222				});
223			});
224
225			this.$el.find('.mw_send_two_factor_code').click(function (e) {
226				e.preventDefault();
227				obj.$el.find('.mw_login_code_message_container').html('');
228
229				let $but = $(this);
230				if ($but.hasClass('working')) {
231					return false;
232				}
233				$but.addClass('working');
234
235				$.post(ajaxurl, 'action=mw_send_login_code', function (response) {
236					if (response.data.show_login) {
237						obj.$el.find('.mw_login_code_container').hide();
238						obj.$el.find('.mw_login_code_container input').val('');
239						obj.$el.find('.mw_login_form_message_container').html(response.data.message);
240					} else {
241						obj.$el.find('.mw_login_code_message_container').html(response.data.message);
242					}
243					$but.removeClass('working');
244				}).fail(function (data) {
245					console.log(data);
246					self.showMessage({'sended': 'error', 'message': 'Neznámá chyba'});
247					$but.removeClass('working');
248				});
249			});
250
251			this.$el.find('.mw_cancel_two_factor').click(function (e) {
252				e.preventDefault();
253				obj.$el.find('.mw_login_code_container').hide();
254				obj.$el.closest('.col').css('z-index', 2);
255				obj.$el.closest('.element_container').css('z-index', 2);
256			});
257
258			this.$el.find('.mw_set_password_ajax').click(function (e) {
259				e.preventDefault();
260
261				let $but = $(this);
262				if ($but.hasClass('working')) {
263					return false;
264				}
265				$but.addClass('working');
266
267				let password1 = obj.$el.find('input[name="new_password"]').val();
268				let password2 = obj.$el.find('input[name="confirm_password"]').val();
269				let userId = obj.$el.find('input[name="user_id"]').val();
270				let token = obj.$el.find('input[name="token"]').val();
271				let redirectTo = obj.$el.find('input[name="redirect_after_set_password"]').val();
272
273				$.post(ajaxurl, {
274					action: 'mw_set_password',
275					new_password: password1,
276					confirm_password: password2,
277					user_id: userId,
278					token: token,
279					redirect_to: redirectTo
280				}, function (response) {
281
282					obj.$el.find('.mw_set_password_message_container').html('');
283
284					if (response.success) {
285						if (response.data.redirect) {
286							window.location.href = response.data.redirect;
287						} else {
288							obj.$el.find('.mw_set_password_modal').hide();
289							obj.$el.find('.mw_set_password_modal input').val('');
290							obj.$el.find('.mw_login_form_message_container').html(response.data.message);
291						}
292					} else {
293						obj.$el.find('.mw_set_password_message_container').html(
294							'<div class="mw_message_error">' + response.data.message + '</div>'
295						);
296					}
297
298					$but.removeClass('working');
299				}).fail(function (data) {
300					console.log(data);
301					$but.removeClass('working');
302				});
303			});
304
305		}
306
307		return _MwMemberLoginForm;
308
309	})();
310
311	$.fn.mwMemberLoginForm = function (options) {
312		return this.each(function (index, el) {
313			el.MwMemberLoginForm = new MwMemberLoginForm(el, options);
314		});
315	};
316
317	// member profile admin
318	var MwMemberProfileAdmin = (function (element) {
319
320		function _MwMemberProfileAdmin(element) {
321			this.$el = $(element);
322
323			const modalContainerId = 'mw_member_profile_container';
324
325			// Create modal container
326			$('body').append('<div id="' + modalContainerId + '"></div>');
327
328			const selectors = {
329				container: '#' + modalContainerId,
330				overlay: '#mw_member_profile_overlay',
331				modal: '#mw_member_profile_modal',
332				content: '#mw_member_profile_modal .mw_member_profile_content',
333				menuItem: '#mw_member_profile_modal .mw_member_profile_menu li',
334				close: '#mw_member_close_profile_modal',
335				menuContainer: '#mw_member_profile_modal .mw_member_profile_menu_container'
336			};
337
338			this.openModal = function(section) {
339				this.createEmptyModal();
340				this.loadModal(section || 'profile');
341			};
342
343			this.showLoadingOverlay = function() {
344				$('body').append('<div id="mw_loading_indicator"><div class="mw_spinner"></div></div>');
345			};
346
347			this.hideLoadingOverlay = function() {
348				$('#mw_loading_indicator').fadeOut(150, function() {
349					$(this).remove();
350				});
351			};
352
353			this.createEmptyModal = function() {
354				$(selectors.container).empty();
355
356				// Create basic modal structure
357				const modalHtml = `
358					<div id="mw_member_profile_overlay" class="mw_member_profile_overlay"></div>
359					<div id="mw_member_profile_modal" class="mw_member_profile_modal">
360						<a href="#" id="mw_member_close_profile_modal"></a>
361						<div class="mw_member_profile_wrapper">
362							<div class="mw_member_profile_content loading">
363								<div class="mw_member_profile_content_inner"></div>
364							</div>
365						</div>
366					</div>
367				`;
368
369				$(selectors.container).html(modalHtml);
370
371				// Disable body scroll when modal is open
372				this.scrollPosition = window.pageYOffset;
373				$('body').addClass('mw_member_modal_open').css('top', -this.scrollPosition + 'px');
374
375				// Force browser reflow
376				$(selectors.modal)[0].offsetHeight;
377
378				requestAnimationFrame(function() {
379					$(selectors.overlay).addClass('visible');
380					$(selectors.modal).addClass('visible');
381				});
382			};
383
384			this.initializeOrdersSection = function(section) {
385				if (section !== 'orders') {
386					return;
387				}
388
389				const $content = $(selectors.content);
390
391				if (!$content[0].MwMemberOrders) {
392					$content.mwMemberOrders();
393				}
394			};
395
396			this.initializeIntegrationsSection = function(section) {
397				if (section !== 'integrations') {
398					return;
399				}
400
401				this.handleDiscordConnect();
402				this.handleDiscordDisconnect();
403			};
404
405			this.initializeSubscriptionsSection = function(section) {
406				if (section !== 'subscriptions') {
407					return;
408				}
409
410				this.handleSubscriptionApActivate();
411				this.handleSubscriptionApDeactivate();
412			};
413
414			this.handleSubscriptionApActivate = function() {
415				var self = this;
416
417				function openApPopup(uuid) {
418					var $popup = $('.mw_subscription_ap_popup');
419					$popup.data('uuid', uuid);
420					$popup.find('.mw_subscription_ap_checkbox').prop('checked', false);
421					$popup.find('.mw_subscription_ap_confirm_enable').addClass('mw_subscription_ap_enable_disabled');
422					$popup.fadeIn(150);
423				}
424
425				function closeApPopup() {
426					$('.mw_subscription_ap_popup').fadeOut(150);
427				}
428
429				$(document).off('click.mwAp').on('click.mwAp', '.mw_subscription_ap_activate_link', function(e) {
430					e.preventDefault();
431					openApPopup($(this).data('subscription-uuid'));
432				});
433
434				$(document).off('click.mwApCancel').on('click.mwApCancel', '.mw_subscription_ap_confirm_cancel', function(e) {
435					e.preventDefault();
436					closeApPopup();
437				});
438
439				$(document).off('click.mwApBackdrop').on('click.mwApBackdrop', '.mw_subscription_ap_popup_backdrop', function() {
440					closeApPopup();
441				});
442
443				$(document).off('change.mwApCheckbox').on('change.mwApCheckbox', '.mw_subscription_ap_checkbox', function() {
444					var $confirmBtn = $('.mw_subscription_ap_popup').find('.mw_subscription_ap_confirm_enable');
445					if ($(this).is(':checked')) {
446						$confirmBtn.removeClass('mw_subscription_ap_enable_disabled');
447					} else {
448						$confirmBtn.addClass('mw_subscription_ap_enable_disabled');
449					}
450				});
451
452				$(document).off('click.mwApEnable').on('click.mwApEnable', '.mw_subscription_ap_confirm_enable', function(e) {
453					e.preventDefault();
454					if ($(this).hasClass('mw_subscription_ap_enable_disabled')) {
455						return;
456					}
457
458					var $link = $(this);
459					var $popup = $('.mw_subscription_ap_popup');
460					var uuid = $popup.data('uuid');
461
462					if ($link.hasClass('working')) {
463						return;
464					}
465					$link.addClass('working');
466
467					$.post(mwMemberProfileData.ajaxurl, {
468						action: 'mwsEnableAutomaticPayments',
469						uuid: uuid
470					}).done(function() {
471						closeApPopup();
472						self.loadSection('subscriptions');
473					}).fail(function() {
474						console.error('AP enable failed');
475					}).always(function() {
476						$link.removeClass('working');
477					});
478				});
479			};
480
481			this.handleSubscriptionApDeactivate = function() {
482				var self = this;
483
484				$(document).off('click.mwApDeactivate').on('click.mwApDeactivate', '.mw_subscription_ap_deactivate_link', function(e) {
485					e.preventDefault();
486					var $link = $(this);
487					var uuid = $link.data('subscription-uuid');
488
489					if ($link.hasClass('working')) {
490						return;
491					}
492					$link.addClass('working');
493
494					$.post(mwMemberProfileData.ajaxurl, {
495						action: 'mwsDisableAutomaticPayments',
496						uuid: uuid
497					}).done(function() {
498						self.loadSection('subscriptions');
499					}).fail(function() {
500						console.error('AP disable failed');
501					}).always(function() {
502						$link.removeClass('working');
503					});
504				});
505			};
506
507			// Load modal content via AJAX
508			this.loadModal = function(section) {
509				$.post(mwMemberProfileData.ajaxurl, {
510					action: 'mw_member_profile_get_modal',
511					section: section
512				}).done(function(response) {
513					if (response.success && response.data.html) {
514						const $wrapper = $(selectors.modal).find('.mw_member_profile_wrapper');
515						const $tempContainer = $('<div>').html(response.data.html);
516
517						$wrapper.empty();
518
519						const $menuContainer = $tempContainer.find('.mw_member_profile_menu_container');
520						const $contentContainer = $tempContainer.find('.mw_member_profile_content');
521
522						// Append the extracted content to wrapper
523						if ($menuContainer.length && $contentContainer.length) {
524							$menuContainer.addClass('mw_member_fade_in');
525							$contentContainer.addClass('mw_member_fade_in');
526
527							$wrapper.append($menuContainer);
528							$wrapper.append($contentContainer);
529
530							// Trigger reflow to make transition work
531							$menuContainer[0].offsetHeight;
532							$contentContainer[0].offsetHeight;
533
534							$menuContainer.addClass('mw_member_fade_in_visible');
535							$contentContainer.addClass('mw_member_fade_in_visible');
536						} else {
537							// Fallback - just append all the HTML from response
538							const $content = $('<div>').html(response.data.html).addClass('mw_member_fade_in');
539							$wrapper.append($content);
540
541							// Trigger reflow
542							$content[0].offsetHeight;
543
544							// Fade in
545							$content.addClass('mw_member_fade_in_visible');
546						}
547
548						this.handleLoadingClass(false);
549						this.initializeOrdersSection(section);
550						this.initializeIntegrationsSection(section);
551						this.initializeSubscriptionsSection(section);
552						this.hideLoadingOverlay();
553
554						// Add a small horizontal bump animation on mobile to indicate menu is scrollable
555						if (window.innerWidth <= 767) {
556							// Check if the animation has already been shown
557							if (!document.cookie.match(/mw_member_menu_bump=1/)) {
558								// Use requestAnimationFrame to ensure DOM is updated
559								requestAnimationFrame(function() {
560									const $menu = $('#mw_member_profile_modal .mw_member_profile_menu');
561									const startPos = $menu.scrollLeft();
562
563									// If the menu has enough width to scroll, animate a small horizontal bump
564									if ($menu[0].scrollWidth > $menu.outerWidth()) {
565										$menu.animate({ scrollLeft: startPos + 50 }, 200, function() {
566											$menu.animate({ scrollLeft: startPos }, 200);
567										});
568
569										// Set cookie so the animation doesn't show again
570										const expiry = new Date();
571										expiry.setFullYear(expiry.getFullYear() + 1);
572										document.cookie = 'mw_member_menu_bump=1; expires=' + expiry.toUTCString() + '; path=/';
573									}
574								});
575							}
576						}
577					} else {
578						console.error('Failed to load profile modal');
579						this.hideLoadingOverlay();
580						this.closeModal();
581					}
582				}.bind(this)).fail(function() {
583					console.error('AJAX request failed');
584					this.hideLoadingOverlay();
585					this.closeModal();
586				}.bind(this));
587			};
588
589			this.handleDiscordConnect = function() {
590				$(document).on('click', '.mw_integration_discord_connect_link', function (e) {
591					e.preventDefault();
592
593					const url = $(this).data('url');
594					const width = 600;
595					const height = 700;
596					const left = (screen.width/2)-(width/2);
597					const top = (screen.height/2)-(height/2);
598
599					const popup = window.open(
600						url,
601						"discord_oauth_popup",
602						`width=${width},height=${height},top=${top},left=${left},resizable=yes,scrollbars=yes`
603					);
604
605					const profileEl = $('#member_show_profile')[0];
606					const timer = setInterval(function () {
607						if (!popup || popup.closed) {
608							clearInterval(timer);
609
610							if (profileEl && profileEl.MwMemberProfileAdmin) {
611								profileEl.MwMemberProfileAdmin.loadSection('integrations');
612							} else {
613								window.location.reload();
614							}
615						}
616					}, 500);
617				});
618			}
619
620			this.handleDiscordDisconnect = function() {
621				$(document).on('click', '.mw_integration_disconnect_link', function (e) {
622					e.preventDefault();
623
624					$.post(mwMemberProfileData.ajaxurl, {
625						action: 'mw_member_profile_disconnect_discord',
626					}).done(function(response) {
627						const profileEl = $('#member_show_profile')[0];
628						if (profileEl && profileEl.MwMemberProfileAdmin) {
629							profileEl.MwMemberProfileAdmin.loadSection('integrations');
630						} else {
631							window.location.reload();
632						}
633					}.bind(this)).fail(function() {
634						console.error('AJAX request failed');
635					}.bind(this));
636				});
637			}
638
639			// Function to update spinner and overlay position based on scroll
640			this.updateSpinnerPosition = function() {
641				const $content = $(selectors.content);
642
643				if (!$content.hasClass('loading')) return;
644
645				const scrollTop = $content.scrollTop();
646				const contentHeight = $content.outerHeight();
647				const spinnerTop = scrollTop + (contentHeight / 2);
648
649				// Set spinner position (centered in visible area)
650				$content[0].style.setProperty('--mw-spinner-top', spinnerTop + 'px');
651
652				// Set overlay position and height to cover visible area
653				$content[0].style.setProperty('--mw-overlay-top', scrollTop + 'px');
654				$content[0].style.setProperty('--mw-overlay-height', contentHeight + 'px');
655			};
656
657			// Helper function to handle loading class
658			this.handleLoadingClass = function(isLoading) {
659				const $content = $(selectors.content);
660
661				if (isLoading) {
662					$content.addClass('loading');
663					$(selectors.menuContainer).addClass('loading');
664					this.updateSpinnerPosition();
665
666					// Add scroll listener to handle inertia scrolling during loading
667					$content.on('scroll.loadingSpinner', this.updateSpinnerPosition.bind(this));
668				} else {
669					$content.removeClass('loading');
670					$(selectors.menuContainer).removeClass('loading');
671
672					// Remove scroll listener when loading is complete
673					$content.off('scroll.loadingSpinner');
674				}
675			};
676
677			this.closeModal = function() {
678				const $overlay = $(selectors.overlay);
679				const $modal = $(selectors.modal);
680				const $container = $(selectors.container);
681
682				// Re-enable body scroll when modal closes
683				$('body').removeClass('mw_member_modal_open').css('top', '');
684				window.scrollTo(0, this.scrollPosition);
685
686				// Remove visible class to trigger the transition
687				$overlay.removeClass('visible');
688				$modal.removeClass('visible');
689
690				// Clear hash
691				window.location.hash = '';
692
693				// Detect when the fade-out is complete
694				$overlay.one('transitionend', function() {
695					// Remove modal content
696					$container.empty();
697				});
698			};
699
700			this.setActive = function(section) {
701				// Find all menu items and remove active class
702				$(selectors.menuItem).removeClass('active');
703				// Add active class to the current section
704				$(selectors.menuItem + '[data-section="' + section + '"]').addClass('active');
705			};
706
707			this.loadSection = function(section, page) {
708				this.setActive(section);
709				this.handleLoadingClass(true);
710
711				var data = {
712					action: 'mw_member_profile_get',
713					section: section
714				};
715
716				if (page) {
717					data.page = page;
718				}
719
720				$.post(mwMemberProfileData.ajaxurl, data).done(function (resp) {
721					if (resp.success) {
722						const $newContent = $('<div>').html(resp.data.html).addClass('mw_member_fade_in');
723
724						if (!page) {
725							$(selectors.content).scrollTop(0);
726						}
727
728						$(selectors.content).html($newContent);
729
730						// Trigger reflow
731						$newContent[0].offsetHeight;
732
733						// Apply fade-in class
734						$newContent.addClass('mw_member_fade_in_visible');
735						this.initializeOrdersSection(section);
736						this.initializeIntegrationsSection(section);
737						this.initializeSubscriptionsSection(section);
738
739						// Scroll to top after content is loaded after changing page
740						if (page) {
741							$(selectors.content).animate({ scrollTop: 0 }, 300);
742						}
743					} else {
744						$(selectors.content).html('<p class="mw_member_error">' + (resp.data.message || 'Error') + '</p>');
745					}
746				}.bind(this)).fail(function () {
747					$(selectors.content).html('<p class="mw_member_error">' + mwMemberProfileData.ajaxError + '</p>');
748				}.bind(this)).always(function () {
749					this.handleLoadingClass(false);
750				}.bind(this));
751			};
752
753			this.displayMessage = function(container, message, isError) {
754				const messageClass = isError ? 'mw_member_error' : 'mw_member_success';
755				const messageHtml = '<div class="' + messageClass + '">' + message + '</div>';
756
757				container.empty();
758				container.html(messageHtml);
759
760				const scrollPos = container.offset().top - 20;
761				const currentScroll = $(selectors.content).scrollTop();
762
763				// Scroll if there is need to scroll up (message is above current viewport)
764				if (currentScroll > scrollPos) {
765					$(selectors.content).animate({ scrollTop: scrollPos }, 200);
766				}
767			};
768
769			this.handleFormSubmit = function(form) {
770				const $form = $(form);
771				const $submitButton = $form.find('button[type="submit"], input[type="submit"]');
772
773				// Blur any focused input elements
774				document.activeElement && document.activeElement.blur && document.activeElement.blur();
775
776				// Find message container or create one if not found
777				let $messageContainer = $form.prev('.mw_member_message_container');
778				if ($messageContainer.length === 0) {
779					$messageContainer = $form.closest('div').find('.mw_member_message_container');
780				}
781				if ($messageContainer.length === 0) {
782					$messageContainer = $form.parent().find('.mw_member_message_container');
783				}
784				if ($messageContainer.length === 0) {
785					$messageContainer = $('<div class="mw_member_message_container"></div>');
786					$form.before($messageContainer);
787				}
788
789				if ($submitButton.length) {
790					$submitButton.prop('disabled', true);
791				}
792
793				this.handleLoadingClass(true);
794
795				$.ajax({
796					url: mwMemberProfileData.ajaxurl,
797					type: 'POST',
798					data: $form.serialize() + '&action=mw_member_profile_save',
799					dataType: 'json',
800					success: function(response) {
801						let errorMessage = '';
802						let isError = false;
803
804						// Set default values based on success/failure state
805						isError = !response.success;
806						errorMessage = isError ? mwMemberProfileData.errorSaving : mwMemberProfileData.changesSaved;
807
808						// Override with response message if available
809						if (response.data && typeof response.data.message === 'string') {
810							errorMessage = response.data.message;
811						}
812
813						// For password form, clear the fields on form submission
814						if ($form.find('input[name="user[user_pass]"]').length) {
815							$form.find('input[type="password"]').val('');
816						}
817
818						// Handle nonce updates
819						if (response.success && response.data) {
820							// If server signals to refresh nonce (for password changes)
821							if (response.data.refresh_nonce) {
822								// Make an AJAX call to get a fresh nonce
823								$.post(mwMemberProfileData.ajaxurl, {
824									action: 'mw_member_refresh_nonce'
825								}).done(function(nonceResp) {
826									if (nonceResp.success && nonceResp.data && nonceResp.data.nonce) {
827										// Update the form with the fresh nonce
828										$form.find('input[name="mw_member_profile_save"]').val(nonceResp.data.nonce);
829									}
830								});
831							}
832							// If nonce is directly provided in response (regular profile updates)
833							else if (response.data.nonce) {
834								$form.find('input[name="mw_member_profile_save"]').val(response.data.nonce);
835							}
836						}
837
838						this.displayMessage($messageContainer, errorMessage, isError);
839					}.bind(this),
840					error: function() {
841						this.displayMessage($messageContainer, mwMemberProfileData.communicationError, true);
842					}.bind(this),
843					complete: function() {
844						this.handleLoadingClass(false);
845
846						if ($submitButton.length) {
847							$submitButton.prop('disabled', false);
848						}
849					}.bind(this)
850				});
851
852				return false; // prevent default form submission
853			};
854
855			// Bindings
856			var self = this;
857
858			this.$el.on('click', function(e) {
859				e.preventDefault();
860				self.openModal('profile');
861			});
862
863			$(document).on('click', selectors.menuItem + ' a', function (e) {
864				e.preventDefault();
865				const section = $(this).parent().data('section');
866				if (section) {
867					self.loadSection(section);
868				}
869			});
870
871			$(document).on('click', selectors.close + ',' + selectors.overlay, function (e) {
872				e.preventDefault();
873				self.closeModal();
874			});
875
876			// Intercept form submissions and handle via AJAX
877			$(document).on('submit', '.mw_member_profile_form', function(e) {
878				e.preventDefault();
879				return self.handleFormSubmit(this);
880			});
881
882			$(window).on('keyup', function (e) {
883				if (e.key === 'Escape') {
884					self.closeModal();
885				}
886			});
887		}
888
889		return _MwMemberProfileAdmin;
890
891	})();
892
893	$.fn.mwMemberProfileAdmin = function (options) {
894		return this.each(function (index, el) {
895			el.MwMemberProfileAdmin = new MwMemberProfileAdmin(el, options);
896		});
897	};
898
899	// member orders
900	var MwMemberOrders = (function (element) {
901
902		function _MwMemberOrders(element) {
903			this.$el = $(element);
904
905			// Handle order details toggle
906			this.$el.on('click', '.mw_member_order_main', function(e) {
907				// Don't toggle if clicking on invoice link
908				if ($(e.target).closest('.mw_order_invoice_icon').length) {
909					return;
910				}
911
912				const $orderRow = $(this).closest('.mw_member_order_row');
913				const $details = $orderRow.find('.mw_member_order_details');
914				const $main = $(this);
915
916				$details.slideToggle(300);
917				$main.toggleClass('mw_toggle_group_open');
918			});
919
920			// Handle orders pagination
921			this.$el.on('click', '.mw_page_navigation a.page-numbers', function(e) {
922				e.preventDefault();
923
924				// Extract page number from href like "#page-3"
925				const href = $(this).attr('href');
926				const match = href.match(/#page-(\d+)/);
927
928				if (!match) return;
929
930				const page = parseInt(match[1], 10);
931				const $profileAdmin = $('#member_show_profile')[0];
932
933				if ($profileAdmin && $profileAdmin.MwMemberProfileAdmin) {
934					$profileAdmin.MwMemberProfileAdmin.loadSection('orders', page);
935				}
936			});
937		}
938
939		return _MwMemberOrders;
940
941	})();
942
943	$.fn.mwMemberOrders = function (options) {
944		return this.each(function (index, el) {
945			el.MwMemberOrders = new MwMemberOrders(el, options);
946		});
947	};
948});

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.