PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 1.6.5
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v1.6.5
2.7.0 2.6.0 trunk 1.1.0 1.1.4 1.2.1 1.2.2 1.2.3 1.2.5 1.2.9 1.3.1 1.3.2 1.5.0 1.5.1 1.5.4 1.5.7 1.5.8 1.5.9 1.6.2 1.6.5 1.6.8 1.7.2 1.7.4 1.7.5 1.7.9 All 43 releases
sellkit / assets / dist / js / elementor-init.js

elementor-init.js in SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster 1.6.5, at assets/dist/js/elementor-init.js

4,922 lines 194.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2 "use strict";
3
4 Object.defineProperty(exports, "__esModule", {
5 value: true
6 });
7 exports["default"] = _default;
8
9 var _i18n = require("@wordpress/i18n");
10
11 /* eslint no-undef: 0 */
12 // Temporary turned off no undefined variable for localStorage
13 var $ = jQuery;
14 var wcCountries = JSON.parse(wc_country_select_params.countries);
15
16 function _default() {
17 $('body').addClass('contains-sellkit-checkout'); // General class to handle compatibility with other themes.
18
19 var parent = $('#sellkit-checkout-multistep-inner-wrap');
20 var sidebar = $('.sellkit-checkout-right-column');
21 var first = $('.sellkit-multistep-checkout-first');
22 var second = $('.sellkit-multistep-checkout-second');
23 var third = $('.sellkit-multistep-checkout-third');
24 var breadcrumb = $('.sellkit-checkout-widget-breadcrumb-desktop, .sellkit-checkout-widget-breadcrumb-mobile');
25 var billingMethodA = $('[name="billing-method"].sellkit-billing-method-a');
26
27 if (billingMethodA.length > 0 && billingMethodA[0].checked) {
28 billingMethodA[0].click();
29 }
30
31 if ('1' !== sellkit_elementor.wcNeedShipping || typeof sellkitCheckoutShipping !== 'undefined' && true === sellkitCheckoutShipping) {
32 third.show();
33 $('.sellkit-one-page-checkout-place-order').css('justify-content', 'flex-end');
34 }
35
36 $('.go-to-shipping').on('click', function () {
37 // Checks if required fields are filled.
38 var requiredFieldsError = checkRequiredFields();
39
40 if (true === requiredFieldsError) {
41 return;
42 }
43
44 secondStepHeader();
45 first.hide();
46
47 if ($('.sellkit-one-page-shipping-methods').children().length > 0) {
48 second.show();
49 } else {
50 third.show();
51 } //Fix Header & wrapper height.
52
53
54 parent.css('height', 'auto');
55 second.css('height', 'auto');
56 second.css('min-height', $('.sellkit-checkout-left-column').height());
57 $('.multistep-headers').css('height', 'auto'); // Manage Breadcrumb.
58
59 breadcrumb.find('.information').removeClass('current').addClass('blue-line');
60 breadcrumb.find('.shipping').addClass('current').removeClass('inactive');
61 });
62 $('.go-to-first').on('click', function () {
63 first.show();
64 third.hide();
65 second.hide();
66 parent.css('height', 'auto');
67 first.css('height', 'auto');
68 sidebar.css('background-color', 'transparent'); // Manage Breadcrumb.
69
70 breadcrumb.find('.information').removeClass('blue-line').addClass('current');
71 breadcrumb.find('.shipping, .payment').removeClass('current').removeClass('blue-line').addClass('inactive');
72 });
73 $('.go-to-payment').on('click', function () {
74 // Checks if required fields are filled.
75 var requiredFieldsError = checkRequiredFields();
76
77 if (true === requiredFieldsError) {
78 return;
79 }
80
81 secondStepHeader();
82 second.hide();
83 first.hide();
84 third.show();
85 $('.sellkit-one-page-checkout-payment-heading').css('margin-top', '0px');
86 sidebar.css('background-color', 'transparent'); //Fix Header & wrapper height.
87
88 parent.css('height', 'auto');
89 third.css('height', 'auto');
90 $('.multistep-headers').css('height', 'auto'); // Manage Breadcrumb.
91
92 breadcrumb.find('.shipping').addClass('blue-line').removeClass('current');
93 breadcrumb.find('.payment').addClass('current').removeClass('inactive');
94 });
95 $('.go-to-second , .go-to-second-header').on('click', function () {
96 // Checks if required fields are filled.
97 var requiredFieldsError = checkRequiredFields();
98
99 if (true === requiredFieldsError) {
100 return;
101 }
102
103 if ($('.sellkit-one-page-shipping-methods').children().length > 0) {
104 second.show();
105 first.hide();
106 } else {
107 second.hide();
108 first.show();
109 }
110
111 third.hide();
112 parent.css('height', 'auto');
113 second.css('height', 'auto');
114 second.css('height', $('.sellkit-checkout-left-column').height());
115 $('.multistep-headers').css('height', 'auto'); // Manage Breadcrumb.
116
117 breadcrumb.find('.shipping').addClass('current').removeClass('blue-line');
118 breadcrumb.find('.payment').removeClass('current').addClass('inactive');
119 }); //Inject login wrapper & functionality.
120
121 emailProcess();
122 LoginProcess(); // Billing method toggle.
123
124 manageBillingMethod(); // Mobile summary.
125
126 mobileSummary(); // Breadcrumb click management.
127
128 breadcrumbLinks(); // Fix shipping & billing fields space issue.
129
130 fixFieldSpaceIssue(); // Fields focus.
131
132 organizeFieldsonLoad();
133 fieldFocus();
134 jQuery(document).ajaxComplete(function () {
135 // Run after ajax
136 sellkitCheckoutUpdateCartItem();
137 applyCoupon();
138 couponToggle();
139 fixGatewayListUi();
140 }); // Fix the payment gateways divider issue.
141
142 fixGatewayListUi(); //Run when page loads.
143
144 sellkitCheckoutUpdateCartItem(); // Apply coupon.
145
146 applyCoupon(); // Coupon toggle.
147
148 couponToggle(); // Postal code autocomplete.
149
150 sellkitPostalCodeAutocomplete(); // Klarma checkout integration.
151
152 sellkitKlarmaIntegration(); // Fix state change issue on load.
153
154 fixStateIssueOnLoad(); // Shipping & billing country & state update on change
155
156 fixClientCountryOnReload(); // Configure bundled products.
157
158 sellkitCheckoutConfigureBundleProducts(); // Order bump.
159
160 sellkitCheckoutOrderBump(); // Sellkit after ajax call is completed.
161
162 sellkitAfterAjaxComplete(); // Load upsell steps with popup.
163
164 sellkitLoadUpsellSteps();
165 }
166
167 var emailProcess = function emailProcess() {
168 var emailField = $('#billing_email');
169 var searchIcon = $('.jupiter-checkout-widget-email-search');
170 var errorText = $('.sellkit-checkout-widget-email-error');
171 var emptyError = $('.sellkit-checkout-widget-email-empty');
172 var passwordWrap = $('.sellkit-checkout-widget-password-field');
173 var passwordField = passwordWrap.find('#register_pass');
174 var usernameWrap = $('.sellkit-checkout-widget-username-field');
175 var usernameField = usernameWrap.find('input');
176 var loginBtn = $('.login-wrapper');
177 var createBox = $('.create-desc');
178 var createCheck = $('#createaccount');
179 emailField.on('keyup', function () {
180 var _this = this;
181
182 setTimeout(function () {
183 var emailAddress = $(_this).val();
184
185 if (_.isEmpty(emailAddress)) {
186 emptyError.show().css('display', 'inline-block');
187 errorText.hide();
188 createBox.css('display', 'none');
189 passwordWrap.addClass('login_hidden_section');
190 usernameWrap.addClass('login_hidden_section');
191 loginBtn.addClass('login_hidden_section');
192 searchIcon.hide();
193 return;
194 }
195
196 var check = validateEmailAddress(emailAddress);
197 $('#createaccount').prop('checked', false);
198
199 if (false === check) {
200 errorText.show().css('display', 'inline-block');
201 emptyError.hide();
202 createBox.css('display', 'none');
203 passwordWrap.addClass('login_hidden_section');
204 usernameWrap.addClass('login_hidden_section');
205 loginBtn.addClass('login_hidden_section');
206 searchIcon.hide();
207 return;
208 }
209
210 emptyError.hide();
211 errorText.hide();
212 searchIcon.show().css('display', 'inline-block');
213 wp.ajax.post({
214 action: 'sellkit_checkout_ajax_handler',
215 sub_action: 'search_for_email',
216 email: emailAddress,
217 dataType: 'json',
218 nonce: sellkit_elementor.nonce
219 }).done(function () {
220 successResultEmailCheck();
221 }).fail(function () {
222 errorResultEmailCheck();
223 });
224 }, 500);
225 });
226 usernameField.on('keyup', function () {
227 var _this2 = this;
228
229 setTimeout(function () {
230 var userValue = $(_this2).val();
231 wp.ajax.post({
232 action: 'sellkit_checkout_ajax_handler',
233 sub_action: 'search_for_username',
234 user: userValue,
235 dataType: 'json',
236 nonce: sellkit_elementor.nonce
237 }).done(function () {
238 $('.sellkit-checkout-widget-username-error').hide();
239 }).fail(function () {
240 $('.sellkit-checkout-widget-username-error').show();
241 });
242 }, 500);
243 }); // If user is going to create account show password and username fields if exists.
244
245 createCheck.on('click', function () {
246 if ($(this).is(':checked')) {
247 if (passwordField.length > 0) {
248 passwordWrap.removeClass('login_hidden_section');
249 }
250
251 if (usernameField.length > 0) {
252 usernameWrap.removeClass('login_hidden_section');
253 }
254 } else {
255 usernameWrap.addClass('login_hidden_section');
256 passwordWrap.addClass('login_hidden_section');
257 }
258 });
259
260 var successResultEmailCheck = function successResultEmailCheck() {
261 createBox.css('display', 'none');
262 passwordWrap.removeClass('login_hidden_section');
263 usernameWrap.addClass('login_hidden_section');
264 loginBtn.removeClass('login_hidden_section');
265 searchIcon.hide();
266 };
267
268 var errorResultEmailCheck = function errorResultEmailCheck() {
269 createBox.css('display', 'flex');
270 passwordWrap.addClass('login_hidden_section');
271 usernameWrap.addClass('login_hidden_section');
272 loginBtn.addClass('login_hidden_section');
273 searchIcon.hide();
274 };
275 };
276
277 var validateEmailAddress = function validateEmailAddress(emailAddress) {
278 var pattern = /^([a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+(\.[a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)*|"((([ \t]*\r\n)?[ \t]+)?([\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*(([ \t]*\r\n)?[ \t]+)?")@(([a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.)+([a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.?$/i;
279 return pattern.test(emailAddress);
280 };
281
282 var LoginProcess = function LoginProcess() {
283 var submitBtn = $('.login-submit');
284 var email = $('.login-mail');
285 var pass = $('.login-pass');
286 var result = $('.login-result');
287 submitBtn.on('click', function () {
288 if ('' === email.val() || '' === pass.val()) {
289 result.text((0, _i18n.__)('Both Field required.', 'sellkit')).css({
290 color: 'red'
291 });
292 return;
293 }
294
295 wp.ajax.post({
296 beforeSend: function beforeSend() {
297 $('.login-submit').css('opacity', '0.5');
298 },
299 action: 'sellkit_checkout_ajax_handler',
300 sub_action: 'auth_user',
301 email: email.val(),
302 pass: pass.val(),
303 nonce: sellkit_elementor.nonce
304 }).done(function () {
305 location.reload();
306 }).fail(function (response) {
307 $('.login-submit').css('opacity', '1');
308 $('.login-result').html(response).css({
309 color: 'red'
310 });
311 });
312 });
313 };
314
315 var secondStepHeader = function secondStepHeader() {
316 var email = $('#billing_email');
317 $('.multistep-headers > .info-a > div > .mail').text(email.val());
318 var countryValue = $('#shipping_country option:selected').text();
319 var state = $('#sellkit-shipping_state');
320 var postcode = $('#shipping_postcode');
321 var city = $('#shipping_city');
322 var addressA = $('#shipping_address_1');
323 var addressB = $('#shipping_address_2');
324 var finalAddress = postcode.val() ? ', ' + postcode.val() : '';
325 finalAddress += addressB.val() ? ', ' + addressB.val() : '';
326 finalAddress += addressA.val() ? ', ' + addressA.val() : '';
327 finalAddress += city.val() ? ', ' + city.val() : '';
328 finalAddress += state.val() ? ', ' + state.val() : '';
329 finalAddress += countryValue && !countryValue.includes('/') ? ', ' + countryValue : '';
330
331 if (',' === finalAddress.charAt(0)) {
332 finalAddress = finalAddress.substring(1);
333 }
334
335 $('.multistep-headers > .info-b > div > .address').text(finalAddress);
336 var method = $('#shipping_method').find('input[type=radio]:checked');
337 var methodTxt = method.siblings('.labels').text();
338 $('.multistep-headers > .info-c > div > .method').text(methodTxt);
339 };
340
341 var manageBillingMethod = function manageBillingMethod() {
342 var billingWrap = $('.sellkit-one-page-checkout-billing');
343 var methodA = billingWrap.find('.method-a');
344 var methodB = billingWrap.find('.method-b'); // Get shipping values.
345
346 var name = $('#shipping_first_name');
347 var last = $('#shipping_last_name');
348 var addressA = $('#shipping_address_1');
349 var addressB = $('#shipping_address_2');
350 var country = $('#shipping_country');
351 var state = $('#sellkit-shipping_state');
352 var postcode = $('#shipping_postcode');
353 var city = $('#shipping_city');
354 methodA.on('click', function () {
355 billingWrap.find('.woocommerce-billing-fields__field-wrapper').hide();
356 $('#billing_first_name').val(name.val());
357 $('#billing_last_name').val(last.val());
358 $('#billing_address_1').val(addressA.val());
359 $('#billing_address_2').val(addressB.val());
360 $('#billing_country').val(country.val()).trigger('change');
361 $('#sellkit-billing_state').val(state.val()).trigger('change');
362 $('#billing_postcode').val(postcode.val());
363 $('#billing_city').val(city.val());
364 });
365 methodB.on('click', function () {
366 $('.inner_wrapper').css('height', 'auto');
367 billingWrap.find('.woocommerce-billing-fields__field-wrapper').show();
368 });
369 };
370
371 var mobileSummary = function mobileSummary() {
372 if ($(window).width() < 600) {
373 $('#order_review').addClass('sellkit-mobile-multistep-order-summary');
374 }
375
376 var toggleBtn = $('.summary_toggle > .title, .summary_toggle > i, .summary_toggle > .icon');
377 var wrap = $('.summary_toggle');
378 toggleBtn.on('click', function () {
379 $('#order_review').toggle();
380
381 if ('Hide order summary' === toggleBtn.text()) {
382 wrap.find('.title').text((0, _i18n.__)('Show order summary', 'sellkit'));
383 wrap.find('i').addClass('fa-chevron-down').removeClass('fa-chevron-up');
384 wrap.css('border-bottom-width', '0px');
385 } else {
386 wrap.find('.title').text((0, _i18n.__)('Hide order summary', 'sellkit'));
387 wrap.find('i').addClass('fa-chevron-up').removeClass('fa-chevron-down');
388 wrap.css('border-bottom-width', '1px');
389 }
390
391 var parent = $('#sellkit-checkout-multistep-inner-wrap');
392 parent.css('height', 'auto');
393 });
394 };
395
396 var fieldFocus = function fieldFocus() {
397 var $fields = $('.sellkit-checkout-local-fields').find('input, select, hidden, textarea, #sellkit-billing_state ,#sellkit-shipping_state, .validate-email');
398 $fields.each(function () {
399 var _this3 = this;
400
401 var miniTitle = $(this).parent().parent().parent().find('.mini-title');
402 var $thisValue = $(this).val(); // On load.
403
404 if (!_.isEmpty($thisValue)) {
405 $(this).addClass('filled').removeClass('empty');
406 miniTitle.css({
407 display: 'flex'
408 });
409 } // On change/focusOut
410
411
412 $(this).on('change input focusout', function (e) {
413 var changedValue = $(_this3).val();
414
415 if (changedValue || $(_this3).find('option').length) {
416 $(_this3).addClass('filled');
417 $(_this3).removeClass('empty');
418 $(_this3).parents('.sellkit-widget-checkout-fields').find('.mini-title').css('display', 'flex');
419 } else {
420 $(_this3).addClass('empty');
421 $(_this3).removeClass('filled');
422 $(_this3).parents('.sellkit-widget-checkout-fields').find('.mini-title').hide();
423 } // On focusout validate fields.
424
425
426 if ('focusout' === e.type) {
427 FieldsMiniTitles($(_this3), 'focusout');
428 var parent = $(_this3).parent().parent().parent(); // Required validation. return if required field rule is not followed.
429
430 if (parent.hasClass('validate-required')) {
431 if ('INPUT' === _this3.nodeName && 'checkbox' === $(_this3).attr('type')) {
432 if (!_this3.checked) {
433 parent.find('.sellkit-required-validation').css('display', 'inline-flex');
434 return;
435 }
436 }
437
438 if (_.isEmpty($(_this3).val())) {
439 parent.find('.sellkit-required-validation').css('display', 'inline-flex');
440 return;
441 }
442
443 parent.find('.sellkit-required-validation').css('display', 'none');
444 } // Required validation of this field if exists, passed successfully. now postcode validation.
445
446
447 if (parent.hasClass('sellkit-checkout-fields-validation-postcode')) {
448 var postcodeVal = $(_this3).val();
449
450 if (_.isEmpty(postcodeVal)) {
451 return;
452 } // Check field type to get related country value. we can't validate without country code.
453
454
455 var postcodeName = $(_this3).attr('name');
456 var postcodeCountry = $('#billing_country');
457
458 if (postcodeName.includes('shipping')) {
459 postcodeCountry = $('#shipping_country');
460 } // Keep validating only if country field is present.
461
462
463 if (!postcodeCountry.length) {
464 return;
465 }
466
467 var countryCode = postcodeCountry.val();
468
469 if (_.isEmpty(countryCode)) {
470 parent.find('.sellkit-checkout-field-global-errors').show().text((0, _i18n.__)('Please select a country.', 'sellkit'));
471 return;
472 } else {
473 // eslint-disable-line
474 parent.find('.sellkit-checkout-field-global-errors').hide().text('');
475 }
476
477 parent.find('.sellkit-checkout-field-global-errors').hide().text('');
478 postcodeValidation(postcodeVal, countryCode, $(_this3));
479 } // Phone validation using woocommerce way.
480
481
482 if (parent.hasClass('sellkit-checkout-fields-validation-phone')) {
483 var phone = $(_this3).val();
484
485 if (_.isEmpty(phone)) {
486 return;
487 }
488
489 phoneNumberValidation(phone, $(_this3));
490 }
491 }
492
493 if ('change' === e.type && ('billing_country' === $(_this3).attr('id') || 'shipping_country' === $(_this3).attr('id'))) {
494 var _countryCode = $(_this3).val();
495
496 var states = wcCountries[_countryCode];
497 var state = 'sellkit-shipping_state';
498
499 if ('billing_country' === $(_this3).attr('id')) {
500 state = 'sellkit-billing_state';
501 }
502
503 var stateField = document.getElementById(state);
504
505 if (_.isNull(stateField)) {
506 return;
507 }
508
509 $(stateField).empty();
510
511 for (var keys in states) {
512 var option = document.createElement('option');
513 option.value = keys;
514 option.innerHTML = states[keys];
515 stateField.appendChild(option);
516 }
517 }
518 });
519 });
520 };
521
522 var breadcrumbLinks = function breadcrumbLinks() {
523 var $parent = $('.sellkit-checkout-widget-breadcrumb-mobile, .sellkit-checkout-widget-breadcrumb-desktop');
524 var detector = $('.sellkit-multistep-checkout-first');
525 $parent.find('.information').on('click', function () {
526 $('.go-to-first').click();
527 });
528 $parent.find('.shipping').on('click', function () {
529 var display = detector.css('display');
530
531 if ('none' === display) {
532 $('.go-to-second').click();
533 } else {
534 $('.go-to-shipping').click();
535 }
536 });
537 $parent.find('.payment').on('click', function () {
538 $('.go-to-payment').click();
539 $('.information').removeClass('current').addClass('inactive, blue-line');
540 });
541 };
542
543 var fixFieldSpaceIssue = function fixFieldSpaceIssue() {
544 $(function () {
545 var shippingFields = $('#customer_details .sellkit-widget-checkout-fields');
546 shippingFields.each(function (index) {
547 if ($(shippingFields[index + 1]).length) {
548 var next = $(shippingFields[index + 1]).offset().top;
549 var current = $(shippingFields[index]).offset().top;
550
551 if (next > current) {
552 $(shippingFields[index]).addClass('sellkit-checkout-excluded-wrapper-fields');
553 }
554 } else {
555 $(shippingFields[index]).addClass('sellkit-checkout-excluded-wrapper-fields');
556 }
557 });
558 });
559 };
560
561 var organizeFieldsonLoad = function organizeFieldsonLoad() {
562 $(function () {
563 var fields = $('.sellkit-widget-checkout-fields').find('input, select, textarea');
564 fields.each(function () {
565 var tag = this.nodeName;
566
567 if ('SELECT' === tag) {
568 $(this).parent().parent().parent().addClass('sellkit-checkout-field-select');
569 }
570
571 FieldsMiniTitles($(this), 'load');
572 });
573 });
574 $(document).on('mousemove change', function (e) {
575 var fields = $('.sellkit-widget-checkout-fields').find('input, select, textarea');
576 fields.each(function () {
577 var tag = this.nodeName;
578
579 if ('SELECT' === tag) {
580 $(this).parent().parent().parent().addClass('sellkit-checkout-field-select');
581 }
582
583 FieldsMiniTitles($(this), e.type);
584 });
585 });
586 };
587
588 var FieldsMiniTitles = function FieldsMiniTitles(field, event) {
589 if (field.attr('multiple')) {
590 field.addClass('filled');
591 field.removeClass('empty');
592 field.parents('.sellkit-widget-checkout-fields').find('.mini-title').css('display', 'flex');
593 return;
594 }
595
596 if (_.isEmpty(field.val())) {
597 field.addClass('empty');
598 field.removeClass('filled');
599 field.parents('.sellkit-widget-checkout-fields').find('.mini-title').css('display', 'none');
600 } else {
601 field.addClass('filled');
602 field.removeClass('empty');
603 field.parents('.sellkit-widget-checkout-fields').find('.mini-title').css('display', 'flex');
604 } // Hide wrapper if field is hidden
605
606
607 if ('hidden' === field.attr('type')) {
608 field.parents('.sellkit-widget-checkout-fields').addClass('sellkit-hide-completely');
609 }
610
611 if ('change' !== event) {
612 return;
613 } // Hide Billing state wrapper when these fields are hidden.
614
615
616 if ('billing_country' === field.attr('id')) {
617 var $state = document.getElementById('sellkit-billing_state');
618
619 if (!_.isNull($state) && 'SELECT' === $state.nodeName && $('#sellkit-billing_state option').length < 1) {
620 var stateField = $('#sellkit-billing_state');
621 var parent = stateField.parent().parent().parent();
622 parent.removeClass('sellkit-checkout-field-select');
623 var placeholder = stateField.attr('placeholder');
624 var stateInput = document.createElement('input');
625 stateInput.setAttribute('type', 'text');
626 stateInput.setAttribute('id', 'sellkit-billing_state');
627 stateInput.setAttribute('name', 'billing_state');
628 stateInput.setAttribute('placeholder', placeholder); // Replace select field with text.
629
630 stateField.remove();
631 parent.find('.woocommerce-input-wrapper').append(stateInput);
632 }
633
634 var countryCode = field.val();
635 var states = wcCountries[countryCode];
636
637 if (!_.isNull($state) && 'INPUT' === $state.nodeName && !_.isEmpty(states)) {
638 var _stateField = $('#sellkit-billing_state');
639
640 var _placeholder = _stateField.attr('placeholder');
641
642 var _parent = _stateField.parent().parent().parent();
643
644 _parent.addClass('sellkit-checkout-field-select');
645
646 if (_.isUndefined(_placeholder) || _.isEmpty(_placeholder)) {
647 _placeholder = (0, _i18n.__)('State', 'sellkit');
648 } // Replace text field with select field.
649
650
651 _stateField.remove();
652
653 var stateSelect = document.createElement('select');
654 stateSelect.setAttribute('name', 'billing_state');
655 stateSelect.setAttribute('id', 'sellkit-billing_state');
656 stateSelect.setAttribute('placeholder', _placeholder);
657 stateSelect.addEventListener('change', function () {
658 sellkitSetAddressDetails();
659 });
660
661 for (var keys in states) {
662 var option = document.createElement('option');
663 option.value = keys;
664 option.innerHTML = states[keys];
665 stateSelect.appendChild(option);
666 }
667
668 _parent.find('.woocommerce-input-wrapper').append(stateSelect);
669 }
670 } // Remove select icon when field is text for the shipping/billing state fields.
671
672
673 if ('shipping_country' === field.attr('id')) {
674 var _$state = document.getElementById('sellkit-shipping_state');
675
676 if (!_.isNull(_$state) && 'SELECT' === _$state.nodeName && $('#sellkit-shipping_state option').length < 1) {
677 var _stateField2 = $('#sellkit-shipping_state');
678
679 var _parent2 = _stateField2.parent().parent().parent();
680
681 _parent2.removeClass('sellkit-checkout-field-select');
682
683 var _placeholder2 = _stateField2.attr('placeholder');
684
685 var _stateInput = document.createElement('input');
686
687 _stateInput.setAttribute('type', 'text');
688
689 _stateInput.setAttribute('id', 'sellkit-shipping_state');
690
691 _stateInput.setAttribute('name', 'shipping_state');
692
693 _stateInput.setAttribute('placeholder', _placeholder2); // Replace select field with text.
694
695
696 _stateField2.remove();
697
698 _parent2.find('.woocommerce-input-wrapper').append(_stateInput);
699 }
700
701 var _countryCode2 = field.val();
702
703 var _states = wcCountries[_countryCode2];
704
705 if (!_.isNull(_$state) && 'INPUT' === _$state.nodeName && !_.isEmpty(_states)) {
706 var _stateField3 = $('#sellkit-shipping_state');
707
708 var _placeholder3 = _stateField3.attr('placeholder');
709
710 var _parent3 = _stateField3.parent().parent().parent();
711
712 _parent3.addClass('sellkit-checkout-field-select');
713
714 if (_.isUndefined(_placeholder3) || _.isEmpty(_placeholder3)) {
715 _placeholder3 = (0, _i18n.__)('State', 'sellkit');
716 } // Replace text field with select field.
717
718
719 _stateField3.remove();
720
721 var _stateSelect = document.createElement('select');
722
723 _stateSelect.setAttribute('name', 'shipping_state');
724
725 _stateSelect.setAttribute('id', 'sellkit-shipping_state');
726
727 _stateSelect.setAttribute('placeholder', _placeholder3);
728
729 _stateSelect.addEventListener('change', function () {
730 sellkitSetAddressDetails();
731 });
732
733 for (var _keys in _states) {
734 var _option = document.createElement('option');
735
736 _option.value = _keys;
737 _option.innerHTML = _states[_keys];
738
739 _stateSelect.appendChild(_option);
740 }
741
742 _parent3.find('.woocommerce-input-wrapper').append(_stateSelect);
743 }
744 }
745 };
746 /**
747 * Change cart item quantity.
748 *
749 * @since 1.2.5
750 */
751
752
753 var sellkitCheckoutUpdateCartItem = function sellkitCheckoutUpdateCartItem() {
754 $('.sellkit-one-page-checkout-product-qty').off('change').on('change', function () {
755 $(this).attr('readonly', true);
756 wp.ajax.post({
757 action: 'sellkit_checkout_ajax_handler',
758 sub_action: 'change_cart_item_qty',
759 qty: $(this).val(),
760 id: $(this).attr('data-id'),
761 mode: 'edit',
762 related_checkout: $('#sellkit_current_page_id').val(),
763 nonce: sellkit_elementor.nonce
764 }).always(function () {
765 $(document.body).trigger('update_checkout');
766 $('.sellkit-one-page-checkout-product-qty').attr('readonly', false);
767 });
768 });
769 var paymentMethod = $('.sellkit-one-page-checkout-payment-methods').find('input[name=payment_method]:checked');
770 paymentMethod.parent().parent().next().show();
771 $('.sellkit-one-page-pay-method').on('click', function () {
772 $('.sellkit_payment_box').hide();
773 $(this).parent().parent().next().show();
774 });
775 var count = $('.sellkit-checkout-widget-order-summary-tfoot').children().length;
776
777 if (count <= 3) {
778 $('.cart-subtotal td').css('padding-bottom', '8px');
779 $('.cart-subtotal th').css('padding-bottom', '8px');
780 }
781 };
782 /**
783 * Apply a coupon.
784 *
785 * @since 1.2.5
786 */
787
788
789 var applyCoupon = function applyCoupon() {
790 $('.sellkit-apply-coupon').off('click').on('click', function () {
791 wp.ajax.post({
792 beforeSend: function beforeSend() {
793 $('.jx-apply-coupon').css('opacity', 0.5);
794 },
795 action: 'sellkit_checkout_ajax_handler',
796 sub_action: 'apply_coupon',
797 code: jQuery('.sellkit-custom-coupon-form').find('.jx-coupon').val(),
798 nonce: sellkit_elementor.nonce
799 }).done(function () {
800 $(document.body).trigger('update_checkout');
801 $('.jx-apply-coupon').css('opacity', 1);
802 }).fail(function () {
803 $('.jx-apply-coupon').css('opacity', 1);
804 });
805 });
806 };
807 /**
808 * Toggle coupon form on click event.
809 *
810 * @since 1.2.5
811 */
812
813
814 var couponToggle = function couponToggle() {
815 if ($('.sellkit-coupon-toggle').length) {
816 $('.sellkit-custom-coupon-form').css('display', 'none');
817 }
818
819 $('.sellkit-coupon-toggle').off('click').on('click', function () {
820 var direction = 'row';
821 var status = $('.sellkit-custom-coupon-form').css('display');
822 var displayValue = '';
823
824 if ($(window).width() < 600) {
825 direction = 'column';
826 }
827
828 if ('none' === status) {
829 displayValue = 'inline-flex';
830 } else {
831 displayValue = 'none';
832 }
833
834 $('.sellkit-custom-coupon-form').css({
835 display: displayValue,
836 flexDirection: direction
837 });
838 });
839 };
840 /**
841 * Validate postcode in WooCommerce way.
842 *
843 * @param {string} postcode
844 * @param {string} country
845 * @param {Object} element
846 */
847
848
849 var postcodeValidation = function postcodeValidation(postcode, country, element) {
850 var parentElement = element.attr('id');
851 wp.ajax.post({
852 action: 'sellkit_checkout_ajax_handler',
853 sub_action: 'validate_postcode',
854 post_code: postcode,
855 country_code: country,
856 parent: parentElement,
857 nonce: sellkit_elementor.nonce
858 }).done(function (response) {
859 var field = $('#' + response);
860 var parent = field.parent().parent().parent();
861 parent.find('.sellkit-checkout-field-global-errors').hide().text('');
862 }).fail(function (response) {
863 var field = $('#' + response);
864 var parent = field.parent().parent().parent();
865 parent.find('.sellkit-checkout-field-global-errors').show().text((0, _i18n.__)('Postcode is not valid.', 'sellkit'));
866 });
867 };
868 /**
869 * Validate phone number in WooCommerce way.
870 *
871 * @param {string} phone
872 * @param {Object} element
873 */
874
875
876 var phoneNumberValidation = function phoneNumberValidation(phone, element) {
877 var parentElement = element.attr('id');
878 wp.ajax.post({
879 action: 'sellkit_checkout_ajax_handler',
880 sub_action: 'validate_phone_number',
881 phone_number: phone,
882 parent: parentElement,
883 nonce: sellkit_elementor.nonce
884 }).done(function (response) {
885 var field = $('#' + response);
886 var parent = field.parent().parent().parent();
887 parent.find('.sellkit-checkout-field-global-errors').hide().text('');
888 }).fail(function (response) {
889 var field = $('#' + response);
890 var parent = field.parent().parent().parent();
891 parent.find('.sellkit-checkout-field-global-errors').show().text((0, _i18n.__)('Phone number is not valid.', 'sellkit'));
892 });
893 };
894 /**
895 * Auto populate city and state fields using postcode by getting information from third api : https://api.zippopotam.us/.
896 *
897 * @since 1.2.5
898 */
899
900
901 var sellkitPostalCodeAutocomplete = function sellkitPostalCodeAutocomplete() {
902 $('.post_code_autocomplete').find('input').on('paste focusout', function () {
903 var postcode = $(this).val();
904 var country = $('#shipping_country').val();
905 var state = $('#sellkit-shipping_state');
906 var city = $('#shipping_city');
907 var parent = $(this).parent().parent().parent();
908
909 if ('billing_postcode' === $(this).attr('id')) {
910 country = $('#billing_country').val();
911 state = $('#sellkit-billing_state');
912 city = $('#billing_city');
913 }
914
915 if (_.isEmpty(postcode) || _.isEmpty(country)) {
916 return;
917 }
918
919 wp.ajax.post({
920 action: 'sellkit_checkout_ajax_handler',
921 sub_action: 'sellkit_state_lookup_by_postcode',
922 country_value: country,
923 postcode_value: postcode,
924 nonce: sellkit_elementor.nonce
925 }).done(function (response) {
926 setError('');
927 var body = response;
928 var placeCity = body.places[0]['place name'];
929 var placeState = body.places[0]['state abbreviation'];
930 var countryResponse = body['country abbreviation'];
931
932 if (_.isEmpty(placeState)) {
933 placeState = body.places[0].state;
934 }
935
936 var countries = ['DE', 'TR', 'BD', 'DO', 'GB', 'GT', 'JP', 'TH', 'ZA'];
937
938 if (countries.includes(countryResponse)) {
939 placeState = fixConflictWooCommerceStatesWithApi(countryResponse, placeState, body);
940 }
941
942 setFields(placeCity, placeState);
943 }).fail(function (response) {
944 setError(response);
945 });
946
947 var setFields = function setFields(placeCity, placeState) {
948 state.val(placeState).addClass('filled');
949 city.val(placeCity).addClass('filled');
950
951 if (null === state.val() && 'SELECT' === state[0].nodeName) {
952 state.prop('selectedIndex', 0);
953 }
954 };
955
956 var setError = function setError(response) {
957 parent.find('.sellkit-checkout-field-global-errors').text(response);
958 };
959 });
960 };
961 /**
962 * Fix some countries states conflict between WooCommerce and https://api.zippopotam.us/.
963 *
964 * @param {string} country response country.
965 * @param {string} state response state.
966 * @param {Object} body response body.
967 * @return {string} state.
968 */
969
970
971 var fixConflictWooCommerceStatesWithApi = function fixConflictWooCommerceStatesWithApi(country, state, body) {
972 switch (country) {
973 case 'TR':
974 // Turkey.
975 state = 'TR' + state;
976 break;
977
978 case 'DE':
979 // Germany.
980 state = 'DE-' + state;
981 break;
982
983 case 'BD':
984 // Bangladesh.
985 state = sellkitCheckoutCountryFixAutoPopulate(state, country, body);
986 break;
987
988 case 'DO':
989 // Dominican Republic. Api has no proper response. we select first option
990 state = 'DO-01';
991 break;
992
993 case 'GB':
994 // United kingdom.
995 state = body.places[0].state;
996 break;
997
998 case 'GT':
999 // Guatemala.
1000 state = 'GT-AV';
1001 break;
1002
1003 case 'JP':
1004 // Japan.
1005 state = sellkitCheckoutCountryFixAutoPopulate(state, country, body);
1006 break;
1007
1008 case 'TH':
1009 // Thailand.
1010 state = sellkitCheckoutCountryFixAutoPopulate(state, country, body);
1011 break;
1012
1013 case 'ZA':
1014 // South Africa. API has no proper response. we select first option.
1015 state = 'EC';
1016 break;
1017
1018 default:
1019 return state;
1020 }
1021
1022 return state;
1023 };
1024 /**
1025 * Integration with Klarma checkout gateway.
1026 *
1027 * @since 1.2.5
1028 */
1029
1030
1031 var sellkitKlarmaIntegration = function sellkitKlarmaIntegration() {
1032 $(document).ready(function () {
1033 $('#sellkit-klarna-pay-button').on('click', function () {
1034 $('#payment_method_kco').trigger('click');
1035 });
1036 });
1037 };
1038 /**
1039 * Save client state and country on change event.
1040 *
1041 * @since 1.2.5
1042 */
1043
1044
1045 var fixClientCountryOnReload = function fixClientCountryOnReload() {
1046 $('#shipping_country, #billing_country, #sellkit-shipping_state, #sellkit-billing_state').on('change', function () {
1047 sellkitSetAddressDetails();
1048 });
1049 };
1050 /**
1051 * Ajax to save user state and country for both shipping and billing section if those fields are present.
1052 *
1053 * @since 1.2.5
1054 */
1055
1056
1057 var sellkitSetAddressDetails = function sellkitSetAddressDetails() {
1058 wp.ajax.post({
1059 action: 'sellkit_checkout_ajax_handler',
1060 sub_action: 'set_customer_details_ajax',
1061 country: document.querySelector('#billing_country') ? document.getElementById('billing_country').value : '',
1062 state: document.querySelector('#sellkit-billing_state') ? document.getElementById('sellkit-billing_state').value : '',
1063 shipping_country: document.querySelector('#shipping_country') ? document.getElementById('shipping_country').value : '',
1064 shipping_state: document.querySelector('#sellkit-shipping_state') ? document.getElementById('sellkit-shipping_state').value : '',
1065 nonce: sellkit_elementor.nonce
1066 }).always(function () {
1067 $(document.body).trigger('update_checkout');
1068 });
1069 };
1070 /**
1071 * On page load set shipping and billing state & country values.
1072 *
1073 * @since 1.2.5
1074 */
1075
1076
1077 var fixStateIssueOnLoad = function fixStateIssueOnLoad() {
1078 var primaryValue = '';
1079
1080 if (document.querySelector('#shipping_country')) {
1081 primaryValue = $('#shipping_country').val();
1082 $('#shipping_country').val($('#shipping_country option:eq(1)').val());
1083 $('#shipping_country').val(primaryValue).trigger('change');
1084 }
1085
1086 if (document.querySelector('#billing_country')) {
1087 primaryValue = $('#billing_country').val();
1088 $('#billing_country').val($('#billing_country option:eq(1)').val());
1089 $('#billing_country').val(primaryValue).trigger('change');
1090 }
1091 };
1092 /**
1093 * Modify cart items when bundle products are present.
1094 *
1095 * @since 1.2.5
1096 */
1097
1098
1099 var sellkitCheckoutConfigureBundleProducts = function sellkitCheckoutConfigureBundleProducts() {
1100 bundleProductOnQuantityChange();
1101 var radioProducts = $('.sellkit-checkout-bundle-item');
1102 radioProducts.off('change').on('change', function () {
1103 var addType = $(this).attr('type'); // On bundle product change, modify bump too.
1104
1105 $('.sellkit-checkout-bump-order-products').each(function () {
1106 if ($(this).is(':checked') && 'radio' === addType) {
1107 $(this).trigger('click');
1108 }
1109 });
1110 var product = $(this).val();
1111 var quantity = $(this).parent().parent().find('.sellkit-checkout-single-bundle-item-quantity').val();
1112 var checkout = $('#sellkit_current_page_id').val();
1113 var modifyType = 'add';
1114
1115 if (false === $(this).is(':checked')) {
1116 modifyType = 'remove';
1117 }
1118
1119 wp.ajax.post({
1120 action: 'sellkit_checkout_ajax_handler',
1121 sub_action: 'sellkit_checkout_modify_cart_by_bundle_products',
1122 id: product,
1123 qty: quantity,
1124 checkout_id: checkout,
1125 type: addType,
1126 modify: modifyType,
1127 nonce: sellkit_elementor.nonce
1128 }).always(function () {
1129 $(document.body).trigger('update_checkout');
1130 });
1131 });
1132 };
1133 /**
1134 * Change cart item quantity on bundle product quantity change.
1135 *
1136 * @since 1.3.1
1137 */
1138
1139
1140 var bundleProductOnQuantityChange = function bundleProductOnQuantityChange() {
1141 $('.sellkit-checkout-single-bundle-item-quantity').on('change', function () {
1142 var productCartKey = $(this).attr('data-id');
1143 var quantity = $(this).val();
1144
1145 if (false === $(this).parent().parent().find('.sellkit-checkout-bundle-item').is(':checked')) {
1146 return;
1147 }
1148
1149 wp.ajax.post({
1150 action: 'sellkit_checkout_ajax_handler',
1151 sub_action: 'sellkit_checkout_modify_cart_by_bundle_products',
1152 key: productCartKey,
1153 qty: quantity,
1154 nonce: sellkit_elementor.nonce
1155 }).always(function () {
1156 $(document.body).trigger('update_checkout');
1157 });
1158 });
1159 };
1160 /**
1161 * Manage to add or remove a bump product from cart.
1162 *
1163 * @since 1.2.5
1164 */
1165
1166
1167 var sellkitCheckoutOrderBump = function sellkitCheckoutOrderBump() {
1168 $('.sellkit-checkout-bump-order-products').on('click', function () {
1169 var subAction;
1170
1171 if ($(this).is(':checked')) {
1172 subAction = 'add';
1173 } else {
1174 subAction = 'remove';
1175 }
1176
1177 wp.ajax.post({
1178 action: 'sellkit_checkout_ajax_handler',
1179 sub_action: 'change_cart_item_qty',
1180 qty: $(this).attr('data-qty'),
1181 id: $(this).val(),
1182 mode: subAction,
1183 related_checkout: $('#sellkit_current_page_id').val(),
1184 nonce: sellkit_elementor.nonce
1185 }).always(function () {
1186 $(document.body).trigger('update_checkout');
1187 });
1188 });
1189 };
1190 /**
1191 * Checks if a required field is not filled.
1192 *
1193 * @return {boolean} state of error.
1194 * @since 1.2.5
1195 */
1196
1197
1198 var checkRequiredFields = function checkRequiredFields() {
1199 var fields = document.querySelectorAll('#sellkit-checkout-widget-shipping-fields > .validate-required');
1200 var error = false; // Let's check email field first.
1201
1202 if (_.isEmpty($('#billing_email').val())) {
1203 $('.sellkit-checkout-widget-email-empty').css('display', 'block');
1204 return true;
1205 } // Hide warning after filling email field.
1206
1207
1208 $('.sellkit-checkout-widget-email-empty').css('display', 'none');
1209
1210 if (fields.length < 1) {
1211 return error;
1212 }
1213
1214 fields.forEach(function (item) {
1215 var target = $(item).find('input, select, textarea').val();
1216
1217 if ('' === target) {
1218 error = true;
1219 $(item).find('.sellkit-required-validation').css('display', 'inline-flex');
1220 }
1221 });
1222 return error;
1223 };
1224 /**
1225 * Loop through WooCommerce states and replace api returned value.
1226 *
1227 * @param {string} state
1228 * @param {string} countryAbbreviated
1229 * @param {Object} body
1230 * @return {string} state value.
1231 * @since 1.2.5
1232 */
1233
1234
1235 var sellkitCheckoutCountryFixAutoPopulate = function sellkitCheckoutCountryFixAutoPopulate(state, countryAbbreviated, body) {
1236 var value = '';
1237 var country = '';
1238
1239 if ('BD' === countryAbbreviated) {
1240 country = wcCountries.BD;
1241 }
1242
1243 if ('JP' === countryAbbreviated) {
1244 country = wcCountries.JP;
1245 state = state.substring(0, state.length - 3);
1246 }
1247
1248 if ('TH' === countryAbbreviated) {
1249 value = 'TH-37';
1250 country = wcCountries.TH;
1251 state = body.places[0].state;
1252 }
1253
1254 for (var key in country) {
1255 if (state === country[key]) {
1256 value = key;
1257 }
1258 }
1259
1260 return value;
1261 };
1262
1263 var sellkitAfterAjaxComplete = function sellkitAfterAjaxComplete() {
1264 $('#place_order').on('click', function () {
1265 var count = 0;
1266 var transfer = setInterval(function () {
1267 count += 1;
1268
1269 if ($('.wc_payment_method > .woocommerce-NoticeGroup-checkout').length > 0) {
1270 // Remove notice from payment area and move it to top of page( default error area ).
1271 var notice = $('.wc_payment_method').find('.woocommerce-NoticeGroup-checkout').html();
1272 $('.wc_payment_method').find('.woocommerce-NoticeGroup-checkout').remove();
1273 $('.woocommerce-notices-wrapper').first().append(notice);
1274 $(document.body).animate({
1275 scrollTop: $('.woocommerce-notices-wrapper').offset().top - 100
1276 }, 500); // Stop interval.
1277
1278 clearInterval(transfer);
1279 }
1280
1281 if (count > 20) {
1282 clearInterval(transfer);
1283 }
1284 }, 500);
1285 });
1286 };
1287 /**
1288 * Hide payment gateways <hr> divider properly after ajax calls.
1289 * This could not be done with css.
1290 *
1291 * @since 1.5.4
1292 */
1293
1294
1295 var fixGatewayListUi = function fixGatewayListUi() {
1296 $('.wc_payment_methods hr.sellkit-checkout-widget-divider').each(function (index, item) {
1297 $(item).css('display', $(item).prevAll('li').first().css('display'));
1298 });
1299 };
1300 /**
1301 * Prevents checkout form from being submitted before checking upsell offers.
1302 *
1303 * @since 1.6.2
1304 */
1305
1306
1307 var sellkitLoadUpsellSteps = function sellkitLoadUpsellSteps() {
1308 $('form.checkout').on('checkout_place_order', function () {
1309 if ($('#sellkit_funnel_has_upsell').length > 0 && 'upsell' === $('#sellkit_funnel_has_upsell').val()) {
1310 sellkitCallUpsell();
1311 return false;
1312 }
1313
1314 return true;
1315 });
1316 };
1317 /**
1318 * After press place order button, call ajax to make decision for popups.
1319 *
1320 * @since 1.6.2
1321 */
1322
1323
1324 var sellkitCallUpsell = function sellkitCallUpsell() {
1325 var loadingIcon = function loadingIcon() {
1326 var icon = sellkit_elementor.url.assets + 'img/spinner.png',
1327 img = document.createElement('img');
1328 img.setAttribute('src', icon);
1329 img.setAttribute('width', '35px');
1330 img.setAttribute('class', 'sellkit-upsell-downsell-preloader');
1331 return img;
1332 };
1333
1334 var onEmpty = function onEmpty() {
1335 $('body').css('overflow', 'auto');
1336 $('.sellkit_funnel_upsell_popup').css('display', 'none');
1337 $('#sellkit_funnel_has_upsell').val('done');
1338 $('#place_order').trigger('click');
1339 };
1340
1341 var loadNew = function loadNew(data) {
1342 $('body').css('overflow', 'hidden');
1343 $('.sellkit-upsell-popup').css('display', 'none');
1344 $('#sellkit_funnel_popup_step_id').val(data.next_id);
1345 $('.sellkit_funnel_upsell_popup').css({
1346 'z-index': '100',
1347 display: 'none'
1348 });
1349 $('.sellkit_funnel_upsell_popup_' + data.next_id).css({
1350 'z-index': 101,
1351 display: 'block'
1352 });
1353 };
1354
1355 var onSuccess = function onSuccess(data) {
1356 setTimeout(function () {
1357 if ('thankyou' === data.next_type) {
1358 onEmpty();
1359 }
1360
1361 if ('upsell' === data.next_type || 'downsell' === data.next_type) {
1362 loadNew(data);
1363 sellkitUpsellOperation();
1364 }
1365 }, 1000);
1366 };
1367
1368 var sellkitUpsellOperation = function sellkitUpsellOperation() {
1369 $('.sellkit_funnel_upsell_popup .sellkit-upsell-accept-button').off().on('click', function () {
1370 var parent = $(this).parents('.sellkit_funnel_upsell_popup'),
1371 upsellId = parent.find('.identify').val(),
1372 checkoutId = $('#sellkit_current_page_id').val();
1373 $('.sellkit-upsell-popup').css('display', 'flex');
1374 parent.find('.sellkit-upsell-updating').addClass('active');
1375 wp.ajax.post({
1376 action: 'sellkit_checkout_ajax_handler',
1377 sub_action: 'perform_upsell_accept_button',
1378 upsell_id: upsellId,
1379 checkout_id: checkoutId,
1380 nonce: sellkit_elementor.nonce
1381 }).done(function (data) {
1382 $(document.body).trigger('update_checkout');
1383 parent.find('.sellkit-upsell-updating').removeClass('active');
1384 parent.find('.sellkit-upsell-accepted').addClass('active');
1385 onSuccess(data);
1386 }).fail(function (data) {
1387 // eslint-disable-next-line no-console
1388 console.error(data);
1389 });
1390 });
1391 $('.sellkit_funnel_upsell_popup .sellkit-upsell-reject-button').off().on('click', function () {
1392 var parent = $(this).parents('.sellkit_funnel_upsell_popup'),
1393 upsellId = parent.find('.identify').val(),
1394 icon = loadingIcon();
1395 parent.find('.sellkit-upsell-downsell-preloader').remove();
1396 $(icon).insertAfter(parent.find('.sellkit-accept-reject-button-widget .sellkit-upsell-reject-button'));
1397 wp.ajax.post({
1398 action: 'sellkit_checkout_ajax_handler',
1399 sub_action: 'perform_upsell_reject_button',
1400 upsell_id: upsellId,
1401 nonce: sellkit_elementor.nonce
1402 }).done(function (data) {
1403 onSuccess(data);
1404 }).fail(function (data) {
1405 // eslint-disable-next-line no-console
1406 console.error(data);
1407 });
1408 });
1409 };
1410
1411 var stepId = $('#sellkit_current_page_id').val(),
1412 img = loadingIcon();
1413 $('button[type=submit]').find('img').remove();
1414 $('button[type=submit]').append(img);
1415 wp.ajax.post({
1416 action: 'sellkit_checkout_ajax_handler',
1417 sub_action: 'call_funnel_popups',
1418 step: stepId,
1419 nonce: sellkit_elementor.nonce
1420 }).done(function (data) {
1421 onSuccess(data);
1422 $('button[type=submit]').find('img').remove();
1423 }).fail(function (data) {
1424 // eslint-disable-next-line no-console
1425 console.error(data);
1426 $('button[type=submit]').find('img').remove();
1427 });
1428 };
1429
1430 },{"@wordpress/i18n":15}],2:[function(require,module,exports){
1431 "use strict";
1432
1433 (function ($) {
1434 var SellkitFrontend = function SellkitFrontend() {
1435 var widgets = {
1436 'sellkit-product-images.default': require('./product-images')["default"],
1437 'sellkit-checkout.default': require('./checkout')["default"],
1438 'sellkit-optin.default': require('./optin/optin')["default"]
1439 };
1440
1441 function elementorInit() {
1442 for (var widget in widgets) {
1443 elementorFrontend.hooks.addAction("frontend/element_ready/".concat(widget), widgets[widget]);
1444 }
1445 }
1446
1447 this.init = function () {
1448 $(window).on('elementor/frontend/init', elementorInit);
1449 };
1450
1451 this.init();
1452 };
1453
1454 window.sellkitFrontend = new SellkitFrontend();
1455 })(jQuery);
1456
1457 },{"./checkout":1,"./optin/optin":3,"./product-images":6}],3:[function(require,module,exports){
1458 "use strict";
1459
1460 var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
1461
1462 Object.defineProperty(exports, "__esModule", {
1463 value: true
1464 });
1465 exports["default"] = _default;
1466
1467 var _intelligentTel = _interopRequireDefault(require("./submodules/intelligent-tel"));
1468
1469 var _fieldValidation = _interopRequireDefault(require("./submodules/field-validation"));
1470
1471 var _i18n = require("@wordpress/i18n");
1472
1473 var Optin = elementorModules.frontend.handlers.Base.extend({
1474 form: null,
1475 onInit: function onInit() {
1476 this.form = this.$element.find('form.sellkit-optin'); // Register submit listener.
1477
1478 this.form.on('submit', this.onSubmit.bind(this)); // Initialize ITI for tel fields.
1479
1480 _intelligentTel["default"].initializeITI(this.form); // AutoComplete address fields.
1481
1482
1483 jQuery(document).ready(this.autoCompleteAddress.bind(this)); // Initialize flatpickr for data and time fields.
1484
1485 this.initializeFlatpickr();
1486 },
1487 onSubmit: function onSubmit(event) {
1488 var _this = this;
1489
1490 event.preventDefault();
1491
1492 if (!this.checkSaveState()) {
1493 return;
1494 }
1495
1496 this.clearAllNotices();
1497 this.form.css('opacity', 0.5);
1498
1499 var validated = _fieldValidation["default"].validateFormFields(this.form);
1500
1501 if (!validated) {
1502 this.form.css('opacity', 1);
1503 return;
1504 }
1505
1506 wp.ajax.send('sellkit_optin_frontend', {
1507 data: this.prepareFormData(),
1508 type: 'POST',
1509 dataType: 'json',
1510 processData: false,
1511 contentType: false,
1512 success: this.onSuccess,
1513 error: this.onFailure,
1514 complete: function complete() {
1515 return _this.form.css('opacity', 1);
1516 }
1517 });
1518 },
1519 checkSaveState: function checkSaveState() {
1520 if (!this.isEdit) {
1521 return true;
1522 }
1523
1524 var btn = jQuery(elementor.panel.el).find('button#elementor-panel-saver-button-publish');
1525
1526 if (!btn.length || btn.hasClass('elementor-disabled')) {
1527 return true;
1528 }
1529
1530 var adminErrorsNode = "\n\t\t\t<div class=\"sellkit-optin-admin-alert\" role=\"alert\">\n\t\t\t\t<span class=\"title\">\n\t\t\t\t\tPlease first update/publish the changes.\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t";
1531 this.form.before(adminErrorsNode);
1532 return false;
1533 },
1534 clearAllNotices: function clearAllNotices() {
1535 var form = this.form; // Reset everything.
1536
1537 form.parent().find('.sellkit-optin-response').remove();
1538 form.parent().find('.sellkit-optin-admin-alert').remove();
1539 form.parent().removeClass('sellkit-optin-error');
1540 form.parent().removeClass('sellkit-optin-success');
1541 },
1542 prepareFormData: function prepareFormData() {
1543 _intelligentTel["default"].fixTelBeforeSubmit(this.form);
1544
1545 var formData = new FormData(this.form[0]);
1546 var entries = Array.from(formData.entries()); // Unify nonsingular formData entries ( happens for checkbox or multiselection select fields ) .
1547
1548 entries.forEach(function (entry, i) {
1549 var value = entry[1];
1550 entries.forEach(function (_entry, _i) {
1551 if (_i !== i && _entry[0] === entry[0]) {
1552 value += ", ".concat(_entry[1]);
1553 formData["delete"](_entry[0]);
1554 }
1555 });
1556 formData.set(entry[0], value);
1557 });
1558 formData.append('referrer', location.toString());
1559 formData.append('action', 'sellkit_optin_frontend');
1560 formData.append('nonce', window.sellkit_elementor.nonce); // To make _POST content compatible with sellkit_funnel() functionality and let it find the funnel data.
1561
1562 formData.append('sellkit_current_page_id', formData.get('post_id'));
1563 return formData;
1564 },
1565 onSuccess: function onSuccess(response) {
1566 var form = this.form; // Success Message.
1567
1568 form.trigger('reset');
1569 form.parent().addClass('sellkit-optin-success');
1570 form.after("<div class=\"sellkit-optin-response\">".concat(response.message, "</div>")); // Admin Error Messages.
1571
1572 this.printAdminErrors(response.admin_errors); // Download.
1573
1574 if (response.downloadURL) {
1575 window.open(response.downloadURL, '_blank');
1576 } // Redirect.
1577
1578
1579 if (!jQuery.isEmptyObject(response.redirectURL)) {
1580 window.location.href = response.redirectURL;
1581 }
1582 },
1583 onFailure: function onFailure(response) {
1584 var form = this.form;
1585 form.parent().removeClass('sellkit-optin-success');
1586 form.parent().addClass('sellkit-optin-error'); // Handle user error messages.
1587
1588 if (!_.isEmpty(response.errors)) {
1589 _.each(response.errors, function (error) {
1590 form.after("<div class=\"sellkit-optin-response\">".concat(error, "</div>"));
1591 });
1592 } // Admin Error Messages.
1593
1594
1595 this.printAdminErrors(response.admin_errors);
1596 },
1597 printAdminErrors: function printAdminErrors(errors) {
1598 if (_.isEmpty(errors)) {
1599 return;
1600 }
1601
1602 var errorList = '';
1603
1604 _.each(errors, function (error) {
1605 errorList += "<li>".concat(error, "</li>");
1606 });
1607
1608 var adminErrorsNode = "\n\t\t\t<div class=\"sellkit-optin-admin-alert\" role=\"alert\">\n\t\t\t\t<span class=\"title\">\n\t\t\t\t\t".concat((0, _i18n.__)('Following messages are visible only for admin users.', 'sellkit'), "\n\t\t\t\t</span>\n\t\t\t\t<div class=\"description\">\n\t\t\t\t\t<ul> ").concat(errorList, " </ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t");
1609 this.form.before(adminErrorsNode);
1610 },
1611 initializeFlatpickr: function initializeFlatpickr() {
1612 var dateField = this.form.find('.flatpickr[type=text]');
1613 var customLocale = dateField.data('locale');
1614 var locale = {
1615 firstDayOfWeek: 1
1616 };
1617
1618 if (!_.isUndefined(customLocale) && 'default' !== customLocale) {
1619 locale = customLocale;
1620 }
1621
1622 dateField.flatpickr({
1623 locale: locale,
1624 minuteIncrement: 1
1625 });
1626 },
1627 autoCompleteAddress: function autoCompleteAddress() {
1628 var addressFields = this.form.find('input[data-type="address"]');
1629 var google = this.isEdit ? window.parent.google : window.google;
1630
1631 if (!addressFields.length || !google) {
1632 return;
1633 }
1634
1635 _.each(addressFields, function (input) {
1636 new google.maps.places.Autocomplete(input, {
1637 types: ['geocode'],
1638 fields: ['address_components']
1639 });
1640 });
1641 }
1642 });
1643
1644 function _default($scope) {
1645 new Optin({
1646 $element: $scope
1647 });
1648 }
1649
1650 },{"./submodules/field-validation":4,"./submodules/intelligent-tel":5,"@babel/runtime/helpers/interopRequireDefault":8,"@wordpress/i18n":15}],4:[function(require,module,exports){
1651 "use strict";
1652
1653 Object.defineProperty(exports, "__esModule", {
1654 value: true
1655 });
1656 exports["default"] = void 0;
1657 var _default = {
1658 messageRequired: '',
1659 messageError: '',
1660 validateFormFields: function validateFormFields(form) {
1661 var _this = this;
1662
1663 this.getCustomMessages(form);
1664 var formData = form.find('[name^="fields"]');
1665 var result = true;
1666
1667 _.each(formData, function (field) {
1668 var message = _this.getValidationMessage(field);
1669
1670 if (!_.isEmpty(message)) {
1671 result = false;
1672 }
1673
1674 _this.toggleFieldMessage(field, message);
1675 });
1676
1677 this.toggleFinalMessage(form, result);
1678 return result;
1679 },
1680 getValidationMessage: function getValidationMessage(target) {
1681 var type = target.dataset.type;
1682 var validity = target.validity;
1683 var i18n = window.sellkitOptinValidationsTranslations;
1684 var message = '';
1685
1686 if (validity.valueMissing || target.required && _.isEmpty(target.value)) {
1687 message = this.messageRequired;
1688 return message;
1689 }
1690
1691 switch (type) {
1692 case 'email':
1693 if (validity.typeMismatch || validity.patternMismatch) {
1694 message = i18n.general.invalidEmail;
1695 }
1696
1697 break;
1698
1699 case 'tel':
1700 var isITI = target.hasAttribute('data-iti-tel');
1701
1702 if (isITI) {
1703 var validationMessages = i18n.itiValidation;
1704 var inputItiInstance = window.intlTelInputGlobals.getInstance(target);
1705 var itiValidationCode = inputItiInstance.getValidationError();
1706 var areaCodeRequired = target.hasAttribute('data-iti-area-required');
1707 var mustBeTelType = target.getAttribute('data-iti-tel-type');
1708 var telType = "".concat(inputItiInstance.getNumberType());
1709
1710 switch (itiValidationCode) {
1711 case 1:
1712 message = validationMessages.invalidCountryCode;
1713 break;
1714
1715 case 2:
1716 message = validationMessages.tooShort;
1717 break;
1718
1719 case 3:
1720 message = validationMessages.tooLong;
1721 break;
1722
1723 case 4:
1724 message = areaCodeRequired ? validationMessages.areaCodeMissing : '';
1725 break;
1726
1727 case 5:
1728 message = validationMessages.invalidLength;
1729 break;
1730
1731 case -99:
1732 message = validationMessages.invalidGeneral;
1733 break;
1734
1735 case 0:
1736 default:
1737 if ('all' !== mustBeTelType && telType !== mustBeTelType) {
1738 message = validationMessages.typeMismatch[mustBeTelType];
1739 }
1740
1741 }
1742
1743 break;
1744 }
1745
1746 if (validity.typeMismatch || validity.patternMismatch) {
1747 message = i18n.general.invalidPhone;
1748 }
1749
1750 break;
1751
1752 case 'number':
1753 if (validity.typeMismatch || validity.patternMismatch) {
1754 message = i18n.general.invalidNumber;
1755 break;
1756 }
1757
1758 if (validity.rangeOverflow) {
1759 message = i18n.general.invalidMaxValue.replace('MAX_VALUE', target.max);
1760 break;
1761 }
1762
1763 if (validity.rangeUnderflow) {
1764 message = i18n.general.invalidMinValue.replace('MIN_VALUE', target.min);
1765 }
1766
1767 break;
1768 }
1769
1770 return message;
1771 },
1772 toggleFieldMessage: function toggleFieldMessage(field, message) {
1773 var fieldGroup = jQuery(field).closest('.sellkit-field-group');
1774 fieldGroup.removeClass('sellkit-field-invalid');
1775 fieldGroup.find('small').remove();
1776
1777 if (!_.isEmpty(message)) {
1778 fieldGroup.addClass('sellkit-field-invalid');
1779 fieldGroup.append("<small class=\"sellkit-optin-text\">".concat(message, "</small>"));
1780 }
1781 },
1782 toggleFinalMessage: function toggleFinalMessage(form, validationResult) {
1783 form.parent().toggleClass('sellkit-optin-error', !validationResult);
1784 form.parent().toggleClass('sellkit-optin-success', validationResult);
1785 form.parent().find('.sellkit-optin-response').remove();
1786
1787 if (true === validationResult) {
1788 return;
1789 }
1790
1791 form.after("<div class=\"sellkit-optin-response\">".concat(this.messageError, "</div>"));
1792 },
1793 getCustomMessages: function getCustomMessages(form) {
1794 var messagesRaw = form.attr('data-messages');
1795
1796 if (!_.isEmpty(messagesRaw)) {
1797 var messages = JSON.parse(messagesRaw);
1798 this.messageError = messages.error;
1799 this.messageRequired = messages.required;
1800 return;
1801 }
1802
1803 this.messageError = window.sellkitOptinValidationsTranslations.general.errorExists;
1804 this.messageRequired = window.sellkitOptinValidationsTranslations.general.required;
1805 }
1806 };
1807 exports["default"] = _default;
1808
1809 },{}],5:[function(require,module,exports){
1810 "use strict";
1811
1812 Object.defineProperty(exports, "__esModule", {
1813 value: true
1814 });
1815 exports["default"] = void 0;
1816 var _default = {
1817 initializeITI: function initializeITI(form) {
1818 var _this = this;
1819
1820 var itiTelFields = form.find('input[data-iti-tel]');
1821
1822 if (!itiTelFields.length) {
1823 return;
1824 }
1825
1826 if (!window.itiCountry) {
1827 jQuery.get('https://ipwho.is/', function () {}, 'json').always(function (response) {
1828 window.itiCountry = response && response.country_code ? response.country_code.toLowerCase() : 'us';
1829
1830 _this.setupTelFields(itiTelFields);
1831 });
1832 } else {
1833 this.setupTelFields(itiTelFields);
1834 }
1835 },
1836 setupTelFields: function setupTelFields(itiTelFields) {
1837 var iti = require('intl-tel-input');
1838
1839 if (!iti) {
1840 return;
1841 }
1842
1843 var allCountries = window.intlTelInputGlobals.getCountryData().map(function (item) {
1844 return item.iso2;
1845 });
1846 var numberTypes = ['FIXED_LINE', 'MOBILE', 'FIXED_LINE_OR_MOBILE', 'TOLL_FREE', 'PREMIUM_RATE', 'SHARED_COST', 'VOIP', 'PERSONAL_NUMBER', 'PAGER', 'UAN', 'VOICEMAIL'];
1847
1848 _.each(itiTelFields, function (input) {
1849 var allowDropdown = input.hasAttribute('data-iti-allow-dropdown');
1850 var countriesAttr = input.getAttribute('data-iti-country-include');
1851 var countries = countriesAttr ? countriesAttr.split(' ') : null;
1852 var isCountriesSet = countries && countries.length;
1853 var ipDetect = input.hasAttribute('data-iti-ip-detect');
1854 var placeHolderAttr = input.getAttribute('data-iti-tel-type');
1855 var args = {
1856 allowDropdown: allowDropdown,
1857 utilsScript: 'https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.16/js/utils.min.js',
1858 separateDialCode: true,
1859 placeholderNumberType: 'all' === placeHolderAttr ? 'MOBILE' : numberTypes[+placeHolderAttr],
1860 onlyCountries: isCountriesSet ? countries : allCountries,
1861 initialCountry: '',
1862 geoIpLookup: null
1863 };
1864
1865 if (ipDetect) {
1866 args.initialCountry = isCountriesSet && !countries.includes(window.itiCountry) ? countries[0] : 'auto';
1867
1868 args.geoIpLookup = function (success) {
1869 return success(window.itiCountry);
1870 };
1871 }
1872
1873 iti(input, args);
1874 });
1875 },
1876 fixTelBeforeSubmit: function fixTelBeforeSubmit(form) {
1877 var itiTelFields = form.find('input[data-iti-tel]');
1878
1879 _.each(itiTelFields, function (input) {
1880 var internationalize = input.hasAttribute('data-iti-internationalize');
1881
1882 if (internationalize) {
1883 var itiInstance = window.intlTelInputGlobals.getInstance(input);
1884 input.value = itiInstance.getNumber();
1885 }
1886 });
1887 }
1888 };
1889 exports["default"] = _default;
1890
1891 },{"intl-tel-input":19}],6:[function(require,module,exports){
1892 "use strict";
1893
1894 Object.defineProperty(exports, "__esModule", {
1895 value: true
1896 });
1897 exports["default"] = _default;
1898 var ProductImages = elementorModules.frontend.handlers.Base.extend({
1899 onInit: function onInit() {
1900 elementorModules.frontend.handlers.Base.prototype.onInit.apply(this, arguments);
1901
1902 if (document.body.classList.contains('elementor-editor-active')) {
1903 this.$element.find('.woocommerce-product-gallery').wc_product_gallery();
1904 }
1905
1906 var self = this;
1907
1908 if (typeof window.elementor === 'undefined') {
1909 return;
1910 }
1911
1912 window.elementor.channels.editor.on('change', function (controlView) {
1913 self.onElementChange(controlView.model.get('name'), controlView);
1914 });
1915 this.handleThumbnailBorderRadius(this.getElementSettings('thumbnail_border_radius'));
1916 },
1917 onElementChange: function onElementChange(propertyName, controlView) {
1918 if ('thumbnail_border_radius' === propertyName) {
1919 var borderRadius = controlView.container.settings.get('thumbnail_border_radius');
1920 this.handleThumbnailBorderRadius(borderRadius);
1921 }
1922 },
1923 handleThumbnailBorderRadius: function handleThumbnailBorderRadius(borderRadius) {
1924 var unit = borderRadius.unit;
1925 this.$element.find('.flex-control-nav li').css({
1926 'border-radius': borderRadius.top + unit + ' ' + borderRadius.right + unit + ' ' + borderRadius.bottom + unit + ' ' + borderRadius.left + unit
1927 });
1928 },
1929 bindEvents: function bindEvents() {
1930 this.$element.find('.woocommerce-product-gallery__image a').on('click', function (e) {
1931 e.stopImmediatePropagation();
1932 e.preventDefault();
1933 });
1934 }
1935 });
1936
1937 function _default($scope) {
1938 new ProductImages({
1939 $element: $scope
1940 });
1941 }
1942
1943 },{}],7:[function(require,module,exports){
1944 function _defineProperty(obj, key, value) {
1945 if (key in obj) {
1946 Object.defineProperty(obj, key, {
1947 value: value,
1948 enumerable: true,
1949 configurable: true,
1950 writable: true
1951 });
1952 } else {
1953 obj[key] = value;
1954 }
1955
1956 return obj;
1957 }
1958
1959 module.exports = _defineProperty;
1960 },{}],8:[function(require,module,exports){
1961 function _interopRequireDefault(obj) {
1962 return obj && obj.__esModule ? obj : {
1963 "default": obj
1964 };
1965 }
1966
1967 module.exports = _interopRequireDefault;
1968 },{}],9:[function(require,module,exports){
1969 'use strict';
1970
1971 function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
1972
1973 var postfix = _interopDefault(require('@tannin/postfix'));
1974 var evaluate = _interopDefault(require('@tannin/evaluate'));
1975
1976 /**
1977 * Given a C expression, returns a function which can be called to evaluate its
1978 * result.
1979 *
1980 * @example
1981 *
1982 * ```js
1983 * import compile from '@tannin/compile';
1984 *
1985 * const evaluate = compile( 'n > 1' );
1986 *
1987 * evaluate( { n: 2 } );
1988 * // ⇒ true
1989 * ```
1990 *
1991 * @param {string} expression C expression.
1992 *
1993 * @return {(variables?:{[variable:string]:*})=>*} Compiled evaluator.
1994 */
1995 function compile( expression ) {
1996 var terms = postfix( expression );
1997
1998 return function( variables ) {
1999 return evaluate( terms, variables );
2000 };
2001 }
2002
2003 module.exports = compile;
2004
2005 },{"@tannin/evaluate":10,"@tannin/postfix":12}],10:[function(require,module,exports){
2006 'use strict';
2007
2008 /**
2009 * Operator callback functions.
2010 *
2011 * @type {Object}
2012 */
2013 var OPERATORS = {
2014 '!': function( a ) {
2015 return ! a;
2016 },
2017 '*': function( a, b ) {
2018 return a * b;
2019 },
2020 '/': function( a, b ) {
2021 return a / b;
2022 },
2023 '%': function( a, b ) {
2024 return a % b;
2025 },
2026 '+': function( a, b ) {
2027 return a + b;
2028 },
2029 '-': function( a, b ) {
2030 return a - b;
2031 },
2032 '<': function( a, b ) {
2033 return a < b;
2034 },
2035 '<=': function( a, b ) {
2036 return a <= b;
2037 },
2038 '>': function( a, b ) {
2039 return a > b;
2040 },
2041 '>=': function( a, b ) {
2042 return a >= b;
2043 },
2044 '==': function( a, b ) {
2045 return a === b;
2046 },
2047 '!=': function( a, b ) {
2048 return a !== b;
2049 },
2050 '&&': function( a, b ) {
2051 return a && b;
2052 },
2053 '||': function( a, b ) {
2054 return a || b;
2055 },
2056 '?:': function( a, b, c ) {
2057 if ( a ) {
2058 throw b;
2059 }
2060
2061 return c;
2062 },
2063 };
2064
2065 /**
2066 * Given an array of postfix terms and operand variables, returns the result of
2067 * the postfix evaluation.
2068 *
2069 * @example
2070 *
2071 * ```js
2072 * import evaluate from '@tannin/evaluate';
2073 *
2074 * // 3 + 4 * 5 / 6 ⇒ '3 4 5 * 6 / +'
2075 * const terms = [ '3', '4', '5', '*', '6', '/', '+' ];
2076 *
2077 * evaluate( terms, {} );
2078 * // ⇒ 6.333333333333334
2079 * ```
2080 *
2081 * @param {string[]} postfix Postfix terms.
2082 * @param {Object} variables Operand variables.
2083 *
2084 * @return {*} Result of evaluation.
2085 */
2086 function evaluate( postfix, variables ) {
2087 var stack = [],
2088 i, j, args, getOperatorResult, term, value;
2089
2090 for ( i = 0; i < postfix.length; i++ ) {
2091 term = postfix[ i ];
2092
2093 getOperatorResult = OPERATORS[ term ];
2094 if ( getOperatorResult ) {
2095 // Pop from stack by number of function arguments.
2096 j = getOperatorResult.length;
2097 args = Array( j );
2098 while ( j-- ) {
2099 args[ j ] = stack.pop();
2100 }
2101
2102 try {
2103 value = getOperatorResult.apply( null, args );
2104 } catch ( earlyReturn ) {
2105 return earlyReturn;
2106 }
2107 } else if ( variables.hasOwnProperty( term ) ) {
2108 value = variables[ term ];
2109 } else {
2110 value = +term;
2111 }
2112
2113 stack.push( value );
2114 }
2115
2116 return stack[ 0 ];
2117 }
2118
2119 module.exports = evaluate;
2120
2121 },{}],11:[function(require,module,exports){
2122 'use strict';
2123
2124 function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
2125
2126 var compile = _interopDefault(require('@tannin/compile'));
2127
2128 /**
2129 * Given a C expression, returns a function which, when called with a value,
2130 * evaluates the result with the value assumed to be the "n" variable of the
2131 * expression. The result will be coerced to its numeric equivalent.
2132 *
2133 * @param {string} expression C expression.
2134 *
2135 * @return {Function} Evaluator function.
2136 */
2137 function pluralForms( expression ) {
2138 var evaluate = compile( expression );
2139
2140 return function( n ) {
2141 return +evaluate( { n: n } );
2142 };
2143 }
2144
2145 module.exports = pluralForms;
2146
2147 },{"@tannin/compile":9}],12:[function(require,module,exports){
2148 'use strict';
2149
2150 var PRECEDENCE, OPENERS, TERMINATORS, PATTERN;
2151
2152 /**
2153 * Operator precedence mapping.
2154 *
2155 * @type {Object}
2156 */
2157 PRECEDENCE = {
2158 '(': 9,
2159 '!': 8,
2160 '*': 7,
2161 '/': 7,
2162 '%': 7,
2163 '+': 6,
2164 '-': 6,
2165 '<': 5,
2166 '<=': 5,
2167 '>': 5,
2168 '>=': 5,
2169 '==': 4,
2170 '!=': 4,
2171 '&&': 3,
2172 '||': 2,
2173 '?': 1,
2174 '?:': 1,
2175 };
2176
2177 /**
2178 * Characters which signal pair opening, to be terminated by terminators.
2179 *
2180 * @type {string[]}
2181 */
2182 OPENERS = [ '(', '?' ];
2183
2184 /**
2185 * Characters which signal pair termination, the value an array with the
2186 * opener as its first member. The second member is an optional operator
2187 * replacement to push to the stack.
2188 *
2189 * @type {string[]}
2190 */
2191 TERMINATORS = {
2192 ')': [ '(' ],
2193 ':': [ '?', '?:' ],
2194 };
2195
2196 /**
2197 * Pattern matching operators and openers.
2198 *
2199 * @type {RegExp}
2200 */
2201 PATTERN = /<=|>=|==|!=|&&|\|\||\?:|\(|!|\*|\/|%|\+|-|<|>|\?|\)|:/;
2202
2203 /**
2204 * Given a C expression, returns the equivalent postfix (Reverse Polish)
2205 * notation terms as an array.
2206 *
2207 * If a postfix string is desired, simply `.join( ' ' )` the result.
2208 *
2209 * @example
2210 *
2211 * ```js
2212 * import postfix from '@tannin/postfix';
2213 *
2214 * postfix( 'n > 1' );
2215 * // ⇒ [ 'n', '1', '>' ]
2216 * ```
2217 *
2218 * @param {string} expression C expression.
2219 *
2220 * @return {string[]} Postfix terms.
2221 */
2222 function postfix( expression ) {
2223 var terms = [],
2224 stack = [],
2225 match, operator, term, element;
2226
2227 while ( ( match = expression.match( PATTERN ) ) ) {
2228 operator = match[ 0 ];
2229
2230 // Term is the string preceding the operator match. It may contain
2231 // whitespace, and may be empty (if operator is at beginning).
2232 term = expression.substr( 0, match.index ).trim();
2233 if ( term ) {
2234 terms.push( term );
2235 }
2236
2237 while ( ( element = stack.pop() ) ) {
2238 if ( TERMINATORS[ operator ] ) {
2239 if ( TERMINATORS[ operator ][ 0 ] === element ) {
2240 // Substitution works here under assumption that because
2241 // the assigned operator will no longer be a terminator, it
2242 // will be pushed to the stack during the condition below.
2243 operator = TERMINATORS[ operator ][ 1 ] || operator;
2244 break;
2245 }
2246 } else if ( OPENERS.indexOf( element ) >= 0 || PRECEDENCE[ element ] < PRECEDENCE[ operator ] ) {
2247 // Push to stack if either an opener or when pop reveals an
2248 // element of lower precedence.
2249 stack.push( element );
2250 break;
2251 }
2252
2253 // For each popped from stack, push to terms.
2254 terms.push( element );
2255 }
2256
2257 if ( ! TERMINATORS[ operator ] ) {
2258 stack.push( operator );
2259 }
2260
2261 // Slice matched fragment from expression to continue match.
2262 expression = expression.substr( match.index + operator.length );
2263 }
2264
2265 // Push remainder of operand, if exists, to terms.
2266 expression = expression.trim();
2267 if ( expression ) {
2268 terms.push( expression );
2269 }
2270
2271 // Pop remaining items from stack into terms.
2272 return terms.concat( stack.reverse() );
2273 }
2274
2275 module.exports = postfix;
2276
2277 },{}],13:[function(require,module,exports){
2278 "use strict";
2279
2280 var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
2281
2282 Object.defineProperty(exports, "__esModule", {
2283 value: true
2284 });
2285 exports.createI18n = void 0;
2286
2287 var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
2288
2289 var _tannin = _interopRequireDefault(require("tannin"));
2290
2291 function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
2292
2293 function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
2294
2295 /**
2296 * @typedef {Record<string,any>} LocaleData
2297 */
2298
2299 /**
2300 * Default locale data to use for Tannin domain when not otherwise provided.
2301 * Assumes an English plural forms expression.
2302 *
2303 * @type {LocaleData}
2304 */
2305 var DEFAULT_LOCALE_DATA = {
2306 '': {
2307 /** @param {number} n */
2308 plural_forms: function plural_forms(n) {
2309 return n === 1 ? 0 : 1;
2310 }
2311 }
2312 };
2313 /**
2314 * An i18n instance
2315 *
2316 * @typedef {Object} I18n
2317 * @property {Function} setLocaleData Merges locale data into the Tannin instance by domain. Accepts data in a
2318 * Jed-formatted JSON object shape.
2319 * @property {Function} __ Retrieve the translation of text.
2320 * @property {Function} _x Retrieve translated string with gettext context.
2321 * @property {Function} _n Translates and retrieves the singular or plural form based on the supplied
2322 * number.
2323 * @property {Function} _nx Translates and retrieves the singular or plural form based on the supplied
2324 * number, with gettext context.
2325 * @property {Function} isRTL Check if current locale is RTL.
2326 */
2327
2328 /**
2329 * Create an i18n instance
2330 *
2331 * @param {LocaleData} [initialData] Locale data configuration.
2332 * @param {string} [initialDomain] Domain for which configuration applies.
2333 * @return {I18n} I18n instance
2334 */
2335
2336 var createI18n = function createI18n(initialData, initialDomain) {
2337 /**
2338 * The underlying instance of Tannin to which exported functions interface.
2339 *
2340 * @type {Tannin}
2341 */
2342 var tannin = new _tannin.default({});
2343 /**
2344 * Merges locale data into the Tannin instance by domain. Accepts data in a
2345 * Jed-formatted JSON object shape.
2346 *
2347 * @see http://messageformat.github.io/Jed/
2348 *
2349 * @param {LocaleData} [data] Locale data configuration.
2350 * @param {string} [domain] Domain for which configuration applies.
2351 */
2352
2353 var setLocaleData = function setLocaleData(data) {
2354 var domain = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'default';
2355 tannin.data[domain] = _objectSpread({}, DEFAULT_LOCALE_DATA, {}, tannin.data[domain], {}, data); // Populate default domain configuration (supported locale date which omits
2356 // a plural forms expression).
2357
2358 tannin.data[domain][''] = _objectSpread({}, DEFAULT_LOCALE_DATA[''], {}, tannin.data[domain]['']);
2359 };
2360 /**
2361 * Wrapper for Tannin's `dcnpgettext`. Populates default locale data if not
2362 * otherwise previously assigned.
2363 *
2364 * @param {string|undefined} domain Domain to retrieve the translated text.
2365 * @param {string|undefined} context Context information for the translators.
2366 * @param {string} single Text to translate if non-plural. Used as
2367 * fallback return value on a caught error.
2368 * @param {string} [plural] The text to be used if the number is
2369 * plural.
2370 * @param {number} [number] The number to compare against to use
2371 * either the singular or plural form.
2372 *
2373 * @return {string} The translated string.
2374 */
2375
2376
2377 var dcnpgettext = function dcnpgettext() {
2378 var domain = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'default';
2379 var context = arguments.length > 1 ? arguments[1] : undefined;
2380 var single = arguments.length > 2 ? arguments[2] : undefined;
2381 var plural = arguments.length > 3 ? arguments[3] : undefined;
2382 var number = arguments.length > 4 ? arguments[4] : undefined;
2383
2384 if (!tannin.data[domain]) {
2385 setLocaleData(undefined, domain);
2386 }
2387
2388 return tannin.dcnpgettext(domain, context, single, plural, number);
2389 };
2390 /**
2391 * Retrieve the translation of text.
2392 *
2393 * @see https://developer.wordpress.org/reference/functions/__/
2394 *
2395 * @param {string} text Text to translate.
2396 * @param {string} [domain] Domain to retrieve the translated text.
2397 *
2398 * @return {string} Translated text.
2399 */
2400
2401
2402 var __ = function __(text, domain) {
2403 return dcnpgettext(domain, undefined, text);
2404 };
2405 /**
2406 * Retrieve translated string with gettext context.
2407 *
2408 * @see https://developer.wordpress.org/reference/functions/_x/
2409 *
2410 * @param {string} text Text to translate.
2411 * @param {string} context Context information for the translators.
2412 * @param {string} [domain] Domain to retrieve the translated text.
2413 *
2414 * @return {string} Translated context string without pipe.
2415 */
2416
2417
2418 var _x = function _x(text, context, domain) {
2419 return dcnpgettext(domain, context, text);
2420 };
2421 /**
2422 * Translates and retrieves the singular or plural form based on the supplied
2423 * number.
2424 *
2425 * @see https://developer.wordpress.org/reference/functions/_n/
2426 *
2427 * @param {string} single The text to be used if the number is singular.
2428 * @param {string} plural The text to be used if the number is plural.
2429 * @param {number} number The number to compare against to use either the
2430 * singular or plural form.
2431 * @param {string} [domain] Domain to retrieve the translated text.
2432 *
2433 * @return {string} The translated singular or plural form.
2434 */
2435
2436
2437 var _n = function _n(single, plural, number, domain) {
2438 return dcnpgettext(domain, undefined, single, plural, number);
2439 };
2440 /**
2441 * Translates and retrieves the singular or plural form based on the supplied
2442 * number, with gettext context.
2443 *
2444 * @see https://developer.wordpress.org/reference/functions/_nx/
2445 *
2446 * @param {string} single The text to be used if the number is singular.
2447 * @param {string} plural The text to be used if the number is plural.
2448 * @param {number} number The number to compare against to use either the
2449 * singular or plural form.
2450 * @param {string} context Context information for the translators.
2451 * @param {string} [domain] Domain to retrieve the translated text.
2452 *
2453 * @return {string} The translated singular or plural form.
2454 */
2455
2456
2457 var _nx = function _nx(single, plural, number, context, domain) {
2458 return dcnpgettext(domain, context, single, plural, number);
2459 };
2460 /**
2461 * Check if current locale is RTL.
2462 *
2463 * **RTL (Right To Left)** is a locale property indicating that text is written from right to left.
2464 * For example, the `he` locale (for Hebrew) specifies right-to-left. Arabic (ar) is another common
2465 * language written RTL. The opposite of RTL, LTR (Left To Right) is used in other languages,
2466 * including English (`en`, `en-US`, `en-GB`, etc.), Spanish (`es`), and French (`fr`).
2467 *
2468 * @return {boolean} Whether locale is RTL.
2469 */
2470
2471
2472 var isRTL = function isRTL() {
2473 return 'rtl' === _x('ltr', 'text direction');
2474 };
2475
2476 if (initialData) {
2477 setLocaleData(initialData, initialDomain);
2478 }
2479
2480 return {
2481 setLocaleData: setLocaleData,
2482 __: __,
2483 _x: _x,
2484 _n: _n,
2485 _nx: _nx,
2486 isRTL: isRTL
2487 };
2488 };
2489
2490 exports.createI18n = createI18n;
2491
2492 },{"@babel/runtime/helpers/defineProperty":7,"@babel/runtime/helpers/interopRequireDefault":8,"tannin":22}],14:[function(require,module,exports){
2493 "use strict";
2494
2495 Object.defineProperty(exports, "__esModule", {
2496 value: true
2497 });
2498 exports.isRTL = exports._nx = exports._n = exports._x = exports.__ = exports.setLocaleData = void 0;
2499
2500 var _createI18n = require("./create-i18n");
2501
2502 /**
2503 * Internal dependencies
2504 */
2505 var i18n = (0, _createI18n.createI18n)();
2506 /*
2507 * Comments in this file are duplicated from ./i18n due to
2508 * https://github.com/WordPress/gutenberg/pull/20318#issuecomment-590837722
2509 */
2510
2511 /**
2512 * @typedef {import('./create-i18n').LocaleData} LocaleData
2513 */
2514
2515 /**
2516 * Merges locale data into the Tannin instance by domain. Accepts data in a
2517 * Jed-formatted JSON object shape.
2518 *
2519 * @see http://messageformat.github.io/Jed/
2520 *
2521 * @param {LocaleData} [data] Locale data configuration.
2522 * @param {string} [domain] Domain for which configuration applies.
2523 */
2524
2525 var setLocaleData = i18n.setLocaleData.bind(i18n);
2526 /**
2527 * Retrieve the translation of text.
2528 *
2529 * @see https://developer.wordpress.org/reference/functions/__/
2530 *
2531 * @param {string} text Text to translate.
2532 * @param {string} [domain] Domain to retrieve the translated text.
2533 *
2534 * @return {string} Translated text.
2535 */
2536
2537 exports.setLocaleData = setLocaleData;
2538
2539 var __ = i18n.__.bind(i18n);
2540 /**
2541 * Retrieve translated string with gettext context.
2542 *
2543 * @see https://developer.wordpress.org/reference/functions/_x/
2544 *
2545 * @param {string} text Text to translate.
2546 * @param {string} context Context information for the translators.
2547 * @param {string} [domain] Domain to retrieve the translated text.
2548 *
2549 * @return {string} Translated context string without pipe.
2550 */
2551
2552
2553 exports.__ = __;
2554
2555 var _x = i18n._x.bind(i18n);
2556 /**
2557 * Translates and retrieves the singular or plural form based on the supplied
2558 * number.
2559 *
2560 * @see https://developer.wordpress.org/reference/functions/_n/
2561 *
2562 * @param {string} single The text to be used if the number is singular.
2563 * @param {string} plural The text to be used if the number is plural.
2564 * @param {number} number The number to compare against to use either the
2565 * singular or plural form.
2566 * @param {string} [domain] Domain to retrieve the translated text.
2567 *
2568 * @return {string} The translated singular or plural form.
2569 */
2570
2571
2572 exports._x = _x;
2573
2574 var _n = i18n._n.bind(i18n);
2575 /**
2576 * Translates and retrieves the singular or plural form based on the supplied
2577 * number, with gettext context.
2578 *
2579 * @see https://developer.wordpress.org/reference/functions/_nx/
2580 *
2581 * @param {string} single The text to be used if the number is singular.
2582 * @param {string} plural The text to be used if the number is plural.
2583 * @param {number} number The number to compare against to use either the
2584 * singular or plural form.
2585 * @param {string} context Context information for the translators.
2586 * @param {string} [domain] Domain to retrieve the translated text.
2587 *
2588 * @return {string} The translated singular or plural form.
2589 */
2590
2591
2592 exports._n = _n;
2593
2594 var _nx = i18n._nx.bind(i18n);
2595 /**
2596 * Check if current locale is RTL.
2597 *
2598 * **RTL (Right To Left)** is a locale property indicating that text is written from right to left.
2599 * For example, the `he` locale (for Hebrew) specifies right-to-left. Arabic (ar) is another common
2600 * language written RTL. The opposite of RTL, LTR (Left To Right) is used in other languages,
2601 * including English (`en`, `en-US`, `en-GB`, etc.), Spanish (`es`), and French (`fr`).
2602 *
2603 * @return {boolean} Whether locale is RTL.
2604 */
2605
2606
2607 exports._nx = _nx;
2608 var isRTL = i18n.isRTL.bind(i18n);
2609 exports.isRTL = isRTL;
2610
2611 },{"./create-i18n":13}],15:[function(require,module,exports){
2612 "use strict";
2613
2614 Object.defineProperty(exports, "__esModule", {
2615 value: true
2616 });
2617 var _exportNames = {
2618 sprintf: true,
2619 setLocaleData: true,
2620 __: true,
2621 _x: true,
2622 _n: true,
2623 _nx: true,
2624 isRTL: true
2625 };
2626 Object.defineProperty(exports, "sprintf", {
2627 enumerable: true,
2628 get: function get() {
2629 return _sprintf.sprintf;
2630 }
2631 });
2632 Object.defineProperty(exports, "setLocaleData", {
2633 enumerable: true,
2634 get: function get() {
2635 return _defaultI18n.setLocaleData;
2636 }
2637 });
2638 Object.defineProperty(exports, "__", {
2639 enumerable: true,
2640 get: function get() {
2641 return _defaultI18n.__;
2642 }
2643 });
2644 Object.defineProperty(exports, "_x", {
2645 enumerable: true,
2646 get: function get() {
2647 return _defaultI18n._x;
2648 }
2649 });
2650 Object.defineProperty(exports, "_n", {
2651 enumerable: true,
2652 get: function get() {
2653 return _defaultI18n._n;
2654 }
2655 });
2656 Object.defineProperty(exports, "_nx", {
2657 enumerable: true,
2658 get: function get() {
2659 return _defaultI18n._nx;
2660 }
2661 });
2662 Object.defineProperty(exports, "isRTL", {
2663 enumerable: true,
2664 get: function get() {
2665 return _defaultI18n.isRTL;
2666 }
2667 });
2668
2669 var _sprintf = require("./sprintf");
2670
2671 var _createI18n = require("./create-i18n");
2672
2673 Object.keys(_createI18n).forEach(function (key) {
2674 if (key === "default" || key === "__esModule") return;
2675 if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
2676 Object.defineProperty(exports, key, {
2677 enumerable: true,
2678 get: function get() {
2679 return _createI18n[key];
2680 }
2681 });
2682 });
2683
2684 var _defaultI18n = require("./default-i18n");
2685
2686 },{"./create-i18n":13,"./default-i18n":14,"./sprintf":16}],16:[function(require,module,exports){
2687 "use strict";
2688
2689 var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
2690
2691 Object.defineProperty(exports, "__esModule", {
2692 value: true
2693 });
2694 exports.sprintf = sprintf;
2695
2696 var _memize = _interopRequireDefault(require("memize"));
2697
2698 var _sprintfJs = _interopRequireDefault(require("sprintf-js"));
2699
2700 /**
2701 * External dependencies
2702 */
2703
2704 /**
2705 * Log to console, once per message; or more precisely, per referentially equal
2706 * argument set. Because Jed throws errors, we log these to the console instead
2707 * to avoid crashing the application.
2708 *
2709 * @param {...*} args Arguments to pass to `console.error`
2710 */
2711 var logErrorOnce = (0, _memize.default)(console.error); // eslint-disable-line no-console
2712
2713 /**
2714 * Returns a formatted string. If an error occurs in applying the format, the
2715 * original format string is returned.
2716 *
2717 * @param {string} format The format of the string to generate.
2718 * @param {...*} args Arguments to apply to the format.
2719 *
2720 * @see http://www.diveintojavascript.com/projects/javascript-sprintf
2721 *
2722 * @return {string} The formatted string.
2723 */
2724
2725 function sprintf(format) {
2726 try {
2727 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2728 args[_key - 1] = arguments[_key];
2729 }
2730
2731 return _sprintfJs.default.sprintf.apply(_sprintfJs.default, [format].concat(args));
2732 } catch (error) {
2733 logErrorOnce('sprintf error: \n\n' + error.toString());
2734 return format;
2735 }
2736 }
2737
2738 },{"@babel/runtime/helpers/interopRequireDefault":8,"memize":20,"sprintf-js":17}],17:[function(require,module,exports){
2739 /* global window, exports, define */
2740
2741 !function() {
2742 'use strict'
2743
2744 var re = {
2745 not_string: /[^s]/,
2746 not_bool: /[^t]/,
2747 not_type: /[^T]/,
2748 not_primitive: /[^v]/,
2749 number: /[diefg]/,
2750 numeric_arg: /[bcdiefguxX]/,
2751 json: /[j]/,
2752 not_json: /[^j]/,
2753 text: /^[^\x25]+/,
2754 modulo: /^\x25{2}/,
2755 placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
2756 key: /^([a-z_][a-z_\d]*)/i,
2757 key_access: /^\.([a-z_][a-z_\d]*)/i,
2758 index_access: /^\[(\d+)\]/,
2759 sign: /^[+-]/
2760 }
2761
2762 function sprintf(key) {
2763 // `arguments` is not an array, but should be fine for this call
2764 return sprintf_format(sprintf_parse(key), arguments)
2765 }
2766
2767 function vsprintf(fmt, argv) {
2768 return sprintf.apply(null, [fmt].concat(argv || []))
2769 }
2770
2771 function sprintf_format(parse_tree, argv) {
2772 var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign
2773 for (i = 0; i < tree_length; i++) {
2774 if (typeof parse_tree[i] === 'string') {
2775 output += parse_tree[i]
2776 }
2777 else if (typeof parse_tree[i] === 'object') {
2778 ph = parse_tree[i] // convenience purposes only
2779 if (ph.keys) { // keyword argument
2780 arg = argv[cursor]
2781 for (k = 0; k < ph.keys.length; k++) {
2782 if (arg == undefined) {
2783 throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k-1]))
2784 }
2785 arg = arg[ph.keys[k]]
2786 }
2787 }
2788 else if (ph.param_no) { // positional argument (explicit)
2789 arg = argv[ph.param_no]
2790 }
2791 else { // positional argument (implicit)
2792 arg = argv[cursor++]
2793 }
2794
2795 if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {
2796 arg = arg()
2797 }
2798
2799 if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {
2800 throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))
2801 }
2802
2803 if (re.number.test(ph.type)) {
2804 is_positive = arg >= 0
2805 }
2806
2807 switch (ph.type) {
2808 case 'b':
2809 arg = parseInt(arg, 10).toString(2)
2810 break
2811 case 'c':
2812 arg = String.fromCharCode(parseInt(arg, 10))
2813 break
2814 case 'd':
2815 case 'i':
2816 arg = parseInt(arg, 10)
2817 break
2818 case 'j':
2819 arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)
2820 break
2821 case 'e':
2822 arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()
2823 break
2824 case 'f':
2825 arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)
2826 break
2827 case 'g':
2828 arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)
2829 break
2830 case 'o':
2831 arg = (parseInt(arg, 10) >>> 0).toString(8)
2832 break
2833 case 's':
2834 arg = String(arg)
2835 arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
2836 break
2837 case 't':
2838 arg = String(!!arg)
2839 arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
2840 break
2841 case 'T':
2842 arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()
2843 arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
2844 break
2845 case 'u':
2846 arg = parseInt(arg, 10) >>> 0
2847 break
2848 case 'v':
2849 arg = arg.valueOf()
2850 arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
2851 break
2852 case 'x':
2853 arg = (parseInt(arg, 10) >>> 0).toString(16)
2854 break
2855 case 'X':
2856 arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()
2857 break
2858 }
2859 if (re.json.test(ph.type)) {
2860 output += arg
2861 }
2862 else {
2863 if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
2864 sign = is_positive ? '+' : '-'
2865 arg = arg.toString().replace(re.sign, '')
2866 }
2867 else {
2868 sign = ''
2869 }
2870 pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '
2871 pad_length = ph.width - (sign + arg).length
2872 pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''
2873 output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)
2874 }
2875 }
2876 }
2877 return output
2878 }
2879
2880 var sprintf_cache = Object.create(null)
2881
2882 function sprintf_parse(fmt) {
2883 if (sprintf_cache[fmt]) {
2884 return sprintf_cache[fmt]
2885 }
2886
2887 var _fmt = fmt, match, parse_tree = [], arg_names = 0
2888 while (_fmt) {
2889 if ((match = re.text.exec(_fmt)) !== null) {
2890 parse_tree.push(match[0])
2891 }
2892 else if ((match = re.modulo.exec(_fmt)) !== null) {
2893 parse_tree.push('%')
2894 }
2895 else if ((match = re.placeholder.exec(_fmt)) !== null) {
2896 if (match[2]) {
2897 arg_names |= 1
2898 var field_list = [], replacement_field = match[2], field_match = []
2899 if ((field_match = re.key.exec(replacement_field)) !== null) {
2900 field_list.push(field_match[1])
2901 while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
2902 if ((field_match = re.key_access.exec(replacement_field)) !== null) {
2903 field_list.push(field_match[1])
2904 }
2905 else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
2906 field_list.push(field_match[1])
2907 }
2908 else {
2909 throw new SyntaxError('[sprintf] failed to parse named argument key')
2910 }
2911 }
2912 }
2913 else {
2914 throw new SyntaxError('[sprintf] failed to parse named argument key')
2915 }
2916 match[2] = field_list
2917 }
2918 else {
2919 arg_names |= 2
2920 }
2921 if (arg_names === 3) {
2922 throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')
2923 }
2924
2925 parse_tree.push(
2926 {
2927 placeholder: match[0],
2928 param_no: match[1],
2929 keys: match[2],
2930 sign: match[3],
2931 pad_char: match[4],
2932 align: match[5],
2933 width: match[6],
2934 precision: match[7],
2935 type: match[8]
2936 }
2937 )
2938 }
2939 else {
2940 throw new SyntaxError('[sprintf] unexpected placeholder')
2941 }
2942 _fmt = _fmt.substring(match[0].length)
2943 }
2944 return sprintf_cache[fmt] = parse_tree
2945 }
2946
2947 /**
2948 * export to either browser or node.js
2949 */
2950 /* eslint-disable quote-props */
2951 if (typeof exports !== 'undefined') {
2952 exports['sprintf'] = sprintf
2953 exports['vsprintf'] = vsprintf
2954 }
2955 if (typeof window !== 'undefined') {
2956 window['sprintf'] = sprintf
2957 window['vsprintf'] = vsprintf
2958
2959 if (typeof define === 'function' && define['amd']) {
2960 define(function() {
2961 return {
2962 'sprintf': sprintf,
2963 'vsprintf': vsprintf
2964 }
2965 })
2966 }
2967 }
2968 /* eslint-enable quote-props */
2969 }(); // eslint-disable-line
2970
2971 },{}],18:[function(require,module,exports){
2972 /*
2973 * International Telephone Input v17.0.16
2974 * https://github.com/jackocnr/intl-tel-input.git
2975 * Licensed under the MIT license
2976 */
2977
2978 // wrap in UMD
2979 (function(factory) {
2980 if (typeof module === "object" && module.exports) module.exports = factory(); else window.intlTelInput = factory();
2981 })(function(undefined) {
2982 "use strict";
2983 return function() {
2984 // Array of country objects for the flag dropdown.
2985 // Here is the criteria for the plugin to support a given country/territory
2986 // - It has an iso2 code: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
2987 // - It has it's own country calling code (it is not a sub-region of another country): https://en.wikipedia.org/wiki/List_of_country_calling_codes
2988 // - It has a flag in the region-flags project: https://github.com/behdad/region-flags/tree/gh-pages/png
2989 // - It is supported by libphonenumber (it must be listed on this page): https://github.com/googlei18n/libphonenumber/blob/master/resources/ShortNumberMetadata.xml
2990 // Each country array has the following information:
2991 // [
2992 // Country name,
2993 // iso2 code,
2994 // International dial code,
2995 // Order (if >1 country with same dial code),
2996 // Area codes
2997 // ]
2998 var allCountries = [ [ "Afghanistan (‫افغانستان‬‎)", "af", "93" ], [ "Albania (Shqipëri)", "al", "355" ], [ "Algeria (‫الجزائر‬‎)", "dz", "213" ], [ "American Samoa", "as", "1", 5, [ "684" ] ], [ "Andorra", "ad", "376" ], [ "Angola", "ao", "244" ], [ "Anguilla", "ai", "1", 6, [ "264" ] ], [ "Antigua and Barbuda", "ag", "1", 7, [ "268" ] ], [ "Argentina", "ar", "54" ], [ "Armenia (Հայաստան)", "am", "374" ], [ "Aruba", "aw", "297" ], [ "Ascension Island", "ac", "247" ], [ "Australia", "au", "61", 0 ], [ "Austria (Österreich)", "at", "43" ], [ "Azerbaijan (Azərbaycan)", "az", "994" ], [ "Bahamas", "bs", "1", 8, [ "242" ] ], [ "Bahrain (‫البحرين‬‎)", "bh", "973" ], [ "Bangladesh (বাংলাদেশ)", "bd", "880" ], [ "Barbados", "bb", "1", 9, [ "246" ] ], [ "Belarus (Беларусь)", "by", "375" ], [ "Belgium (België)", "be", "32" ], [ "Belize", "bz", "501" ], [ "Benin (Bénin)", "bj", "229" ], [ "Bermuda", "bm", "1", 10, [ "441" ] ], [ "Bhutan (འབྲུག)", "bt", "975" ], [ "Bolivia", "bo", "591" ], [ "Bosnia and Herzegovina (Босна и Херцеговина)", "ba", "387" ], [ "Botswana", "bw", "267" ], [ "Brazil (Brasil)", "br", "55" ], [ "British Indian Ocean Territory", "io", "246" ], [ "British Virgin Islands", "vg", "1", 11, [ "284" ] ], [ "Brunei", "bn", "673" ], [ "Bulgaria (България)", "bg", "359" ], [ "Burkina Faso", "bf", "226" ], [ "Burundi (Uburundi)", "bi", "257" ], [ "Cambodia (កម្ពុជា)", "kh", "855" ], [ "Cameroon (Cameroun)", "cm", "237" ], [ "Canada", "ca", "1", 1, [ "204", "226", "236", "249", "250", "289", "306", "343", "365", "387", "403", "416", "418", "431", "437", "438", "450", "506", "514", "519", "548", "579", "581", "587", "604", "613", "639", "647", "672", "705", "709", "742", "778", "780", "782", "807", "819", "825", "867", "873", "902", "905" ] ], [ "Cape Verde (Kabu Verdi)", "cv", "238" ], [ "Caribbean Netherlands", "bq", "599", 1, [ "3", "4", "7" ] ], [ "Cayman Islands", "ky", "1", 12, [ "345" ] ], [ "Central African Republic (République centrafricaine)", "cf", "236" ], [ "Chad (Tchad)", "td", "235" ], [ "Chile", "cl", "56" ], [ "China (中国)", "cn", "86" ], [ "Christmas Island", "cx", "61", 2, [ "89164" ] ], [ "Cocos (Keeling) Islands", "cc", "61", 1, [ "89162" ] ], [ "Colombia", "co", "57" ], [ "Comoros (‫جزر الق�
2999 ر‬‎)", "km", "269" ], [ "Congo (DRC) (Jamhuri ya Kidemokrasia ya Kongo)", "cd", "243" ], [ "Congo (Republic) (Congo-Brazzaville)", "cg", "242" ], [ "Cook Islands", "ck", "682" ], [ "Costa Rica", "cr", "506" ], [ "Côte d’Ivoire", "ci", "225" ], [ "Croatia (Hrvatska)", "hr", "385" ], [ "Cuba", "cu", "53" ], [ "Curaçao", "cw", "599", 0 ], [ "Cyprus (Κύπρος)", "cy", "357" ], [ "Czech Republic (Česká republika)", "cz", "420" ], [ "Denmark (Danmark)", "dk", "45" ], [ "Djibouti", "dj", "253" ], [ "Dominica", "dm", "1", 13, [ "767" ] ], [ "Dominican Republic (República Dominicana)", "do", "1", 2, [ "809", "829", "849" ] ], [ "Ecuador", "ec", "593" ], [ "Egypt (‫�
3000 صر‬‎)", "eg", "20" ], [ "El Salvador", "sv", "503" ], [ "Equatorial Guinea (Guinea Ecuatorial)", "gq", "240" ], [ "Eritrea", "er", "291" ], [ "Estonia (Eesti)", "ee", "372" ], [ "Eswatini", "sz", "268" ], [ "Ethiopia", "et", "251" ], [ "Falkland Islands (Islas Malvinas)", "fk", "500" ], [ "Faroe Islands (Føroyar)", "fo", "298" ], [ "Fiji", "fj", "679" ], [ "Finland (Suomi)", "fi", "358", 0 ], [ "France", "fr", "33" ], [ "French Guiana (Guyane française)", "gf", "594" ], [ "French Polynesia (Polynésie française)", "pf", "689" ], [ "Gabon", "ga", "241" ], [ "Gambia", "gm", "220" ], [ "Georgia (საქართველო)", "ge", "995" ], [ "Germany (Deutschland)", "de", "49" ], [ "Ghana (Gaana)", "gh", "233" ], [ "Gibraltar", "gi", "350" ], [ "Greece (Ελλάδα)", "gr", "30" ], [ "Greenland (Kalaallit Nunaat)", "gl", "299" ], [ "Grenada", "gd", "1", 14, [ "473" ] ], [ "Guadeloupe", "gp", "590", 0 ], [ "Guam", "gu", "1", 15, [ "671" ] ], [ "Guatemala", "gt", "502" ], [ "Guernsey", "gg", "44", 1, [ "1481", "7781", "7839", "7911" ] ], [ "Guinea (Guinée)", "gn", "224" ], [ "Guinea-Bissau (Guiné Bissau)", "gw", "245" ], [ "Guyana", "gy", "592" ], [ "Haiti", "ht", "509" ], [ "Honduras", "hn", "504" ], [ "Hong Kong (香港)", "hk", "852" ], [ "Hungary (Magyarország)", "hu", "36" ], [ "Iceland (Ísland)", "is", "354" ], [ "India (भारत)", "in", "91" ], [ "Indonesia", "id", "62" ], [ "Iran (‫ایران‬‎)", "ir", "98" ], [ "Iraq (‫العراق‬‎)", "iq", "964" ], [ "Ireland", "ie", "353" ], [ "Isle of Man", "im", "44", 2, [ "1624", "74576", "7524", "7924", "7624" ] ], [ "Israel (‫ישראל‬‎)", "il", "972" ], [ "Italy (Italia)", "it", "39", 0 ], [ "Jamaica", "jm", "1", 4, [ "876", "658" ] ], [ "Japan (日本)", "jp", "81" ], [ "Jersey", "je", "44", 3, [ "1534", "7509", "7700", "7797", "7829", "7937" ] ], [ "Jordan (‫الأردن‬‎)", "jo", "962" ], [ "Kazakhstan (Каза�
3001 стан)", "kz", "7", 1, [ "33", "7" ] ], [ "Kenya", "ke", "254" ], [ "Kiribati", "ki", "686" ], [ "Kosovo", "xk", "383" ], [ "Kuwait (‫الكويت‬‎)", "kw", "965" ], [ "Kyrgyzstan (Кыргызстан)", "kg", "996" ], [ "Laos (ລາວ)", "la", "856" ], [ "Latvia (Latvija)", "lv", "371" ], [ "Lebanon (‫لبنان‬‎)", "lb", "961" ], [ "Lesotho", "ls", "266" ], [ "Liberia", "lr", "231" ], [ "Libya (‫ليبيا‬‎)", "ly", "218" ], [ "Liechtenstein", "li", "423" ], [ "Lithuania (Lietuva)", "lt", "370" ], [ "Luxembourg", "lu", "352" ], [ "Macau (澳門)", "mo", "853" ], [ "North Macedonia (Македонија)", "mk", "389" ], [ "Madagascar (Madagasikara)", "mg", "261" ], [ "Malawi", "mw", "265" ], [ "Malaysia", "my", "60" ], [ "Maldives", "mv", "960" ], [ "Mali", "ml", "223" ], [ "Malta", "mt", "356" ], [ "Marshall Islands", "mh", "692" ], [ "Martinique", "mq", "596" ], [ "Mauritania (‫�
3002 وريتانيا‬‎)", "mr", "222" ], [ "Mauritius (Moris)", "mu", "230" ], [ "Mayotte", "yt", "262", 1, [ "269", "639" ] ], [ "Mexico (México)", "mx", "52" ], [ "Micronesia", "fm", "691" ], [ "Moldova (Republica Moldova)", "md", "373" ], [ "Monaco", "mc", "377" ], [ "Mongolia (Монгол)", "mn", "976" ], [ "Montenegro (Crna Gora)", "me", "382" ], [ "Montserrat", "ms", "1", 16, [ "664" ] ], [ "Morocco (‫ال�
3003 غرب‬‎)", "ma", "212", 0 ], [ "Mozambique (Moçambique)", "mz", "258" ], [ "Myanmar (Burma) (မြန်မာ)", "mm", "95" ], [ "Namibia (Namibië)", "na", "264" ], [ "Nauru", "nr", "674" ], [ "Nepal (नेपाल)", "np", "977" ], [ "Netherlands (Nederland)", "nl", "31" ], [ "New Caledonia (Nouvelle-Calédonie)", "nc", "687" ], [ "New Zealand", "nz", "64" ], [ "Nicaragua", "ni", "505" ], [ "Niger (Nijar)", "ne", "227" ], [ "Nigeria", "ng", "234" ], [ "Niue", "nu", "683" ], [ "Norfolk Island", "nf", "672" ], [ "North Korea (조선 민주주의 인민 공화국)", "kp", "850" ], [ "Northern Mariana Islands", "mp", "1", 17, [ "670" ] ], [ "Norway (Norge)", "no", "47", 0 ], [ "Oman (‫عُ�
3004 ان‬‎)", "om", "968" ], [ "Pakistan (‫پاکستان‬‎)", "pk", "92" ], [ "Palau", "pw", "680" ], [ "Palestine (‫فلسطين‬‎)", "ps", "970" ], [ "Panama (Panamá)", "pa", "507" ], [ "Papua New Guinea", "pg", "675" ], [ "Paraguay", "py", "595" ], [ "Peru (Perú)", "pe", "51" ], [ "Philippines", "ph", "63" ], [ "Poland (Polska)", "pl", "48" ], [ "Portugal", "pt", "351" ], [ "Puerto Rico", "pr", "1", 3, [ "787", "939" ] ], [ "Qatar (‫قطر‬‎)", "qa", "974" ], [ "Réunion (La Réunion)", "re", "262", 0 ], [ "Romania (România)", "ro", "40" ], [ "Russia (Россия)", "ru", "7", 0 ], [ "Rwanda", "rw", "250" ], [ "Saint Barthélemy", "bl", "590", 1 ], [ "Saint Helena", "sh", "290" ], [ "Saint Kitts and Nevis", "kn", "1", 18, [ "869" ] ], [ "Saint Lucia", "lc", "1", 19, [ "758" ] ], [ "Saint Martin (Saint-Martin (partie française))", "mf", "590", 2 ], [ "Saint Pierre and Miquelon (Saint-Pierre-et-Miquelon)", "pm", "508" ], [ "Saint Vincent and the Grenadines", "vc", "1", 20, [ "784" ] ], [ "Samoa", "ws", "685" ], [ "San Marino", "sm", "378" ], [ "São Tomé and Príncipe (São Tomé e Príncipe)", "st", "239" ], [ "Saudi Arabia (‫ال�
3005
3006 لكة العربية السعودية‬‎)", "sa", "966" ], [ "Senegal (Sénégal)", "sn", "221" ], [ "Serbia (Србија)", "rs", "381" ], [ "Seychelles", "sc", "248" ], [ "Sierra Leone", "sl", "232" ], [ "Singapore", "sg", "65" ], [ "Sint Maarten", "sx", "1", 21, [ "721" ] ], [ "Slovakia (Slovensko)", "sk", "421" ], [ "Slovenia (Slovenija)", "si", "386" ], [ "Solomon Islands", "sb", "677" ], [ "Somalia (Soomaaliya)", "so", "252" ], [ "South Africa", "za", "27" ], [ "South Korea (대한민국)", "kr", "82" ], [ "South Sudan (‫جنوب السودان‬‎)", "ss", "211" ], [ "Spain (España)", "es", "34" ], [ "Sri Lanka (ශ්‍රී ලංකාව)", "lk", "94" ], [ "Sudan (‫السودان‬‎)", "sd", "249" ], [ "Suriname", "sr", "597" ], [ "Svalbard and Jan Mayen", "sj", "47", 1, [ "79" ] ], [ "Sweden (Sverige)", "se", "46" ], [ "Switzerland (Schweiz)", "ch", "41" ], [ "Syria (‫سوريا‬‎)", "sy", "963" ], [ "Taiwan (台灣)", "tw", "886" ], [ "Tajikistan", "tj", "992" ], [ "Tanzania", "tz", "255" ], [ "Thailand (ไทย)", "th", "66" ], [ "Timor-Leste", "tl", "670" ], [ "Togo", "tg", "228" ], [ "Tokelau", "tk", "690" ], [ "Tonga", "to", "676" ], [ "Trinidad and Tobago", "tt", "1", 22, [ "868" ] ], [ "Tunisia (‫تونس‬‎)", "tn", "216" ], [ "Turkey (Türkiye)", "tr", "90" ], [ "Turkmenistan", "tm", "993" ], [ "Turks and Caicos Islands", "tc", "1", 23, [ "649" ] ], [ "Tuvalu", "tv", "688" ], [ "U.S. Virgin Islands", "vi", "1", 24, [ "340" ] ], [ "Uganda", "ug", "256" ], [ "Ukraine (Україна)", "ua", "380" ], [ "United Arab Emirates (‫الإ�
3007 ارات العربية ال�
3008 تحدة‬‎)", "ae", "971" ], [ "United Kingdom", "gb", "44", 0 ], [ "United States", "us", "1", 0 ], [ "Uruguay", "uy", "598" ], [ "Uzbekistan (Oʻzbekiston)", "uz", "998" ], [ "Vanuatu", "vu", "678" ], [ "Vatican City (Città del Vaticano)", "va", "39", 1, [ "06698" ] ], [ "Venezuela", "ve", "58" ], [ "Vietnam (Việt Nam)", "vn", "84" ], [ "Wallis and Futuna (Wallis-et-Futuna)", "wf", "681" ], [ "Western Sahara (‫الصحراء الغربية‬‎)", "eh", "212", 1, [ "5288", "5289" ] ], [ "Yemen (‫الي�
3009 ن‬‎)", "ye", "967" ], [ "Zambia", "zm", "260" ], [ "Zimbabwe", "zw", "263" ], [ "�
3010 land Islands", "ax", "358", 1, [ "18" ] ] ];
3011 // loop over all of the countries above, restructuring the data to be objects with named keys
3012 for (var i = 0; i < allCountries.length; i++) {
3013 var c = allCountries[i];
3014 allCountries[i] = {
3015 name: c[0],
3016 iso2: c[1],
3017 dialCode: c[2],
3018 priority: c[3] || 0,
3019 areaCodes: c[4] || null
3020 };
3021 }
3022 "use strict";
3023 function _classCallCheck(instance, Constructor) {
3024 if (!(instance instanceof Constructor)) {
3025 throw new TypeError("Cannot call a class as a function");
3026 }
3027 }
3028 function _defineProperties(target, props) {
3029 for (var i = 0; i < props.length; i++) {
3030 var descriptor = props[i];
3031 descriptor.enumerable = descriptor.enumerable || false;
3032 descriptor.configurable = true;
3033 if ("value" in descriptor) descriptor.writable = true;
3034 Object.defineProperty(target, descriptor.key, descriptor);
3035 }
3036 }
3037 function _createClass(Constructor, protoProps, staticProps) {
3038 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
3039 if (staticProps) _defineProperties(Constructor, staticProps);
3040 return Constructor;
3041 }
3042 var intlTelInputGlobals = {
3043 getInstance: function getInstance(input) {
3044 var id = input.getAttribute("data-intl-tel-input-id");
3045 return window.intlTelInputGlobals.instances[id];
3046 },
3047 instances: {},
3048 // using a global like this allows us to mock it in the tests
3049 documentReady: function documentReady() {
3050 return document.readyState === "complete";
3051 }
3052 };
3053 if (typeof window === "object") window.intlTelInputGlobals = intlTelInputGlobals;
3054 // these vars persist through all instances of the plugin
3055 var id = 0;
3056 var defaults = {
3057 // whether or not to allow the dropdown
3058 allowDropdown: true,
3059 // if there is just a dial code in the input: remove it on blur
3060 autoHideDialCode: true,
3061 // add a placeholder in the input with an example number for the selected country
3062 autoPlaceholder: "polite",
3063 // modify the parentClass
3064 customContainer: "",
3065 // modify the auto placeholder
3066 customPlaceholder: null,
3067 // append menu to specified element
3068 dropdownContainer: null,
3069 // don't display these countries
3070 excludeCountries: [],
3071 // format the input value during initialisation and on setNumber
3072 formatOnDisplay: true,
3073 // geoIp lookup function
3074 geoIpLookup: null,
3075 // inject a hidden input with this name, and on submit, populate it with the result of getNumber
3076 hiddenInput: "",
3077 // initial country
3078 initialCountry: "",
3079 // localized country names e.g. { 'de': 'Deutschland' }
3080 localizedCountries: null,
3081 // don't insert international dial codes
3082 nationalMode: true,
3083 // display only these countries
3084 onlyCountries: [],
3085 // number type to use for placeholders
3086 placeholderNumberType: "MOBILE",
3087 // the countries at the top of the list. defaults to united states and united kingdom
3088 preferredCountries: [ "us", "gb" ],
3089 // display the country dial code next to the selected flag so it's not part of the typed number
3090 separateDialCode: false,
3091 // specify the path to the libphonenumber script to enable validation/formatting
3092 utilsScript: ""
3093 };
3094 // https://en.wikipedia.org/wiki/List_of_North_American_Numbering_Plan_area_codes#Non-geographic_area_codes
3095 var regionlessNanpNumbers = [ "800", "822", "833", "844", "855", "866", "877", "880", "881", "882", "883", "884", "885", "886", "887", "888", "889" ];
3096 // utility function to iterate over an object. can't use Object.entries or native forEach because
3097 // of IE11
3098 var forEachProp = function forEachProp(obj, callback) {
3099 var keys = Object.keys(obj);
3100 for (var i = 0; i < keys.length; i++) {
3101 callback(keys[i], obj[keys[i]]);
3102 }
3103 };
3104 // run a method on each instance of the plugin
3105 var forEachInstance = function forEachInstance(method) {
3106 forEachProp(window.intlTelInputGlobals.instances, function(key) {
3107 window.intlTelInputGlobals.instances[key][method]();
3108 });
3109 };
3110 // this is our plugin class that we will create an instance of
3111 // eslint-disable-next-line no-unused-vars
3112 var Iti = /*#__PURE__*/
3113 function() {
3114 function Iti(input, options) {
3115 var _this = this;
3116 _classCallCheck(this, Iti);
3117 this.id = id++;
3118 this.telInput = input;
3119 this.activeItem = null;
3120 this.highlightedItem = null;
3121 // process specified options / defaults
3122 // alternative to Object.assign, which isn't supported by IE11
3123 var customOptions = options || {};
3124 this.options = {};
3125 forEachProp(defaults, function(key, value) {
3126 _this.options[key] = customOptions.hasOwnProperty(key) ? customOptions[key] : value;
3127 });
3128 this.hadInitialPlaceholder = Boolean(input.getAttribute("placeholder"));
3129 }
3130 _createClass(Iti, [ {
3131 key: "_init",
3132 value: function _init() {
3133 var _this2 = this;
3134 // if in nationalMode, disable options relating to dial codes
3135 if (this.options.nationalMode) this.options.autoHideDialCode = false;
3136 // if separateDialCode then doesn't make sense to A) insert dial code into input
3137 // (autoHideDialCode), and B) display national numbers (because we're displaying the country
3138 // dial code next to them)
3139 if (this.options.separateDialCode) {
3140 this.options.autoHideDialCode = this.options.nationalMode = false;
3141 }
3142 // we cannot just test screen size as some smartphones/website meta tags will report desktop
3143 // resolutions
3144 // Note: for some reason jasmine breaks if you put this in the main Plugin function with the
3145 // rest of these declarations
3146 // Note: to target Android Mobiles (and not Tablets), we must find 'Android' and 'Mobile'
3147 this.isMobile = /Android.+Mobile|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
3148 if (this.isMobile) {
3149 // trigger the mobile dropdown css
3150 document.body.classList.add("iti-mobile");
3151 // on mobile, we want a full screen dropdown, so we must append it to the body
3152 if (!this.options.dropdownContainer) this.options.dropdownContainer = document.body;
3153 }
3154 // these promises get resolved when their individual requests complete
3155 // this way the dev can do something like iti.promise.then(...) to know when all requests are
3156 // complete
3157 if (typeof Promise !== "undefined") {
3158 var autoCountryPromise = new Promise(function(resolve, reject) {
3159 _this2.resolveAutoCountryPromise = resolve;
3160 _this2.rejectAutoCountryPromise = reject;
3161 });
3162 var utilsScriptPromise = new Promise(function(resolve, reject) {
3163 _this2.resolveUtilsScriptPromise = resolve;
3164 _this2.rejectUtilsScriptPromise = reject;
3165 });
3166 this.promise = Promise.all([ autoCountryPromise, utilsScriptPromise ]);
3167 } else {
3168 // prevent errors when Promise doesn't exist
3169 this.resolveAutoCountryPromise = this.rejectAutoCountryPromise = function() {};
3170 this.resolveUtilsScriptPromise = this.rejectUtilsScriptPromise = function() {};
3171 }
3172 // in various situations there could be no country selected initially, but we need to be able
3173 // to assume this variable exists
3174 this.selectedCountryData = {};
3175 // process all the data: onlyCountries, excludeCountries, preferredCountries etc
3176 this._processCountryData();
3177 // generate the markup
3178 this._generateMarkup();
3179 // set the initial state of the input value and the selected flag
3180 this._setInitialState();
3181 // start all of the event listeners: autoHideDialCode, input keydown, selectedFlag click
3182 this._initListeners();
3183 // utils script, and auto country
3184 this._initRequests();
3185 }
3186 }, {
3187 key: "_processCountryData",
3188 value: function _processCountryData() {
3189 // process onlyCountries or excludeCountries array if present
3190 this._processAllCountries();
3191 // process the countryCodes map
3192 this._processCountryCodes();
3193 // process the preferredCountries
3194 this._processPreferredCountries();
3195 // translate countries according to localizedCountries option
3196 if (this.options.localizedCountries) this._translateCountriesByLocale();
3197 // sort countries by name
3198 if (this.options.onlyCountries.length || this.options.localizedCountries) {
3199 this.countries.sort(this._countryNameSort);
3200 }
3201 }
3202 }, {
3203 key: "_addCountryCode",
3204 value: function _addCountryCode(iso2, countryCode, priority) {
3205 if (countryCode.length > this.countryCodeMaxLen) {
3206 this.countryCodeMaxLen = countryCode.length;
3207 }
3208 if (!this.countryCodes.hasOwnProperty(countryCode)) {
3209 this.countryCodes[countryCode] = [];
3210 }
3211 // bail if we already have this country for this countryCode
3212 for (var i = 0; i < this.countryCodes[countryCode].length; i++) {
3213 if (this.countryCodes[countryCode][i] === iso2) return;
3214 }
3215 // check for undefined as 0 is falsy
3216 var index = priority !== undefined ? priority : this.countryCodes[countryCode].length;
3217 this.countryCodes[countryCode][index] = iso2;
3218 }
3219 }, {
3220 key: "_processAllCountries",
3221 value: function _processAllCountries() {
3222 if (this.options.onlyCountries.length) {
3223 var lowerCaseOnlyCountries = this.options.onlyCountries.map(function(country) {
3224 return country.toLowerCase();
3225 });
3226 this.countries = allCountries.filter(function(country) {
3227 return lowerCaseOnlyCountries.indexOf(country.iso2) > -1;
3228 });
3229 } else if (this.options.excludeCountries.length) {
3230 var lowerCaseExcludeCountries = this.options.excludeCountries.map(function(country) {
3231 return country.toLowerCase();
3232 });
3233 this.countries = allCountries.filter(function(country) {
3234 return lowerCaseExcludeCountries.indexOf(country.iso2) === -1;
3235 });
3236 } else {
3237 this.countries = allCountries;
3238 }
3239 }
3240 }, {
3241 key: "_translateCountriesByLocale",
3242 value: function _translateCountriesByLocale() {
3243 for (var i = 0; i < this.countries.length; i++) {
3244 var iso = this.countries[i].iso2.toLowerCase();
3245 if (this.options.localizedCountries.hasOwnProperty(iso)) {
3246 this.countries[i].name = this.options.localizedCountries[iso];
3247 }
3248 }
3249 }
3250 }, {
3251 key: "_countryNameSort",
3252 value: function _countryNameSort(a, b) {
3253 return a.name.localeCompare(b.name);
3254 }
3255 }, {
3256 key: "_processCountryCodes",
3257 value: function _processCountryCodes() {
3258 this.countryCodeMaxLen = 0;
3259 // here we store just dial codes
3260 this.dialCodes = {};
3261 // here we store "country codes" (both dial codes and their area codes)
3262 this.countryCodes = {};
3263 // first: add dial codes
3264 for (var i = 0; i < this.countries.length; i++) {
3265 var c = this.countries[i];
3266 if (!this.dialCodes[c.dialCode]) this.dialCodes[c.dialCode] = true;
3267 this._addCountryCode(c.iso2, c.dialCode, c.priority);
3268 }
3269 // next: add area codes
3270 // this is a second loop over countries, to make sure we have all of the "root" countries
3271 // already in the map, so that we can access them, as each time we add an area code substring
3272 // to the map, we also need to include the "root" country's code, as that also matches
3273 for (var _i = 0; _i < this.countries.length; _i++) {
3274 var _c = this.countries[_i];
3275 // area codes
3276 if (_c.areaCodes) {
3277 var rootCountryCode = this.countryCodes[_c.dialCode][0];
3278 // for each area code
3279 for (var j = 0; j < _c.areaCodes.length; j++) {
3280 var areaCode = _c.areaCodes[j];
3281 // for each digit in the area code to add all partial matches as well
3282 for (var k = 1; k < areaCode.length; k++) {
3283 var partialDialCode = _c.dialCode + areaCode.substr(0, k);
3284 // start with the root country, as that also matches this dial code
3285 this._addCountryCode(rootCountryCode, partialDialCode);
3286 this._addCountryCode(_c.iso2, partialDialCode);
3287 }
3288 // add the full area code
3289 this._addCountryCode(_c.iso2, _c.dialCode + areaCode);
3290 }
3291 }
3292 }
3293 }
3294 }, {
3295 key: "_processPreferredCountries",
3296 value: function _processPreferredCountries() {
3297 this.preferredCountries = [];
3298 for (var i = 0; i < this.options.preferredCountries.length; i++) {
3299 var countryCode = this.options.preferredCountries[i].toLowerCase();
3300 var countryData = this._getCountryData(countryCode, false, true);
3301 if (countryData) this.preferredCountries.push(countryData);
3302 }
3303 }
3304 }, {
3305 key: "_createEl",
3306 value: function _createEl(name, attrs, container) {
3307 var el = document.createElement(name);
3308 if (attrs) forEachProp(attrs, function(key, value) {
3309 return el.setAttribute(key, value);
3310 });
3311 if (container) container.appendChild(el);
3312 return el;
3313 }
3314 }, {
3315 key: "_generateMarkup",
3316 value: function _generateMarkup() {
3317 // if autocomplete does not exist on the element and its form, then
3318 // prevent autocomplete as there's no safe, cross-browser event we can react to, so it can
3319 // easily put the plugin in an inconsistent state e.g. the wrong flag selected for the
3320 // autocompleted number, which on submit could mean wrong number is saved (esp in nationalMode)
3321 if (!this.telInput.hasAttribute("autocomplete") && !(this.telInput.form && this.telInput.form.hasAttribute("autocomplete"))) {
3322 this.telInput.setAttribute("autocomplete", "off");
3323 }
3324 // containers (mostly for positioning)
3325 var parentClass = "iti";
3326 if (this.options.allowDropdown) parentClass += " iti--allow-dropdown";
3327 if (this.options.separateDialCode) parentClass += " iti--separate-dial-code";
3328 if (this.options.customContainer) {
3329 parentClass += " ";
3330 parentClass += this.options.customContainer;
3331 }
3332 var wrapper = this._createEl("div", {
3333 "class": parentClass
3334 });
3335 this.telInput.parentNode.insertBefore(wrapper, this.telInput);
3336 this.flagsContainer = this._createEl("div", {
3337 "class": "iti__flag-container"
3338 }, wrapper);
3339 wrapper.appendChild(this.telInput);
3340 // selected flag (displayed to left of input)
3341 this.selectedFlag = this._createEl("div", {
3342 "class": "iti__selected-flag",
3343 role: "combobox",
3344 "aria-controls": "iti-".concat(this.id, "__country-listbox"),
3345 "aria-owns": "iti-".concat(this.id, "__country-listbox"),
3346 "aria-expanded": "false"
3347 }, this.flagsContainer);
3348 this.selectedFlagInner = this._createEl("div", {
3349 "class": "iti__flag"
3350 }, this.selectedFlag);
3351 if (this.options.separateDialCode) {
3352 this.selectedDialCode = this._createEl("div", {
3353 "class": "iti__selected-dial-code"
3354 }, this.selectedFlag);
3355 }
3356 if (this.options.allowDropdown) {
3357 // make element focusable and tab navigable
3358 this.selectedFlag.setAttribute("tabindex", "0");
3359 this.dropdownArrow = this._createEl("div", {
3360 "class": "iti__arrow"
3361 }, this.selectedFlag);
3362 // country dropdown: preferred countries, then divider, then all countries
3363 this.countryList = this._createEl("ul", {
3364 "class": "iti__country-list iti__hide",
3365 id: "iti-".concat(this.id, "__country-listbox"),
3366 role: "listbox",
3367 "aria-label": "List of countries"
3368 });
3369 if (this.preferredCountries.length) {
3370 this._appendListItems(this.preferredCountries, "iti__preferred", true);
3371 this._createEl("li", {
3372 "class": "iti__divider",
3373 role: "separator",
3374 "aria-disabled": "true"
3375 }, this.countryList);
3376 }
3377 this._appendListItems(this.countries, "iti__standard");
3378 // create dropdownContainer markup
3379 if (this.options.dropdownContainer) {
3380 this.dropdown = this._createEl("div", {
3381 "class": "iti iti--container"
3382 });
3383 this.dropdown.appendChild(this.countryList);
3384 } else {
3385 this.flagsContainer.appendChild(this.countryList);
3386 }
3387 }
3388 if (this.options.hiddenInput) {
3389 var hiddenInputName = this.options.hiddenInput;
3390 var name = this.telInput.getAttribute("name");
3391 if (name) {
3392 var i = name.lastIndexOf("[");
3393 // if input name contains square brackets, then give the hidden input the same name,
3394 // replacing the contents of the last set of brackets with the given hiddenInput name
3395 if (i !== -1) hiddenInputName = "".concat(name.substr(0, i), "[").concat(hiddenInputName, "]");
3396 }
3397 this.hiddenInput = this._createEl("input", {
3398 type: "hidden",
3399 name: hiddenInputName
3400 });
3401 wrapper.appendChild(this.hiddenInput);
3402 }
3403 }
3404 }, {
3405 key: "_appendListItems",
3406 value: function _appendListItems(countries, className, preferred) {
3407 // we create so many DOM elements, it is faster to build a temp string
3408 // and then add everything to the DOM in one go at the end
3409 var tmp = "";
3410 // for each country
3411 for (var i = 0; i < countries.length; i++) {
3412 var c = countries[i];
3413 var idSuffix = preferred ? "-preferred" : "";
3414 // open the list item
3415 tmp += "<li class='iti__country ".concat(className, "' tabIndex='-1' id='iti-").concat(this.id, "__item-").concat(c.iso2).concat(idSuffix, "' role='option' data-dial-code='").concat(c.dialCode, "' data-country-code='").concat(c.iso2, "' aria-selected='false'>");
3416 // add the flag
3417 tmp += "<div class='iti__flag-box'><div class='iti__flag iti__".concat(c.iso2, "'></div></div>");
3418 // and the country name and dial code
3419 tmp += "<span class='iti__country-name'>".concat(c.name, "</span>");
3420 tmp += "<span class='iti__dial-code'>+".concat(c.dialCode, "</span>");
3421 // close the list item
3422 tmp += "</li>";
3423 }
3424 this.countryList.insertAdjacentHTML("beforeend", tmp);
3425 }
3426 }, {
3427 key: "_setInitialState",
3428 value: function _setInitialState() {
3429 // fix firefox bug: when first load page (with input with value set to number with intl dial
3430 // code) and initialising plugin removes the dial code from the input, then refresh page,
3431 // and we try to init plugin again but this time on number without dial code so get grey flag
3432 var attributeValue = this.telInput.getAttribute("value");
3433 var inputValue = this.telInput.value;
3434 var useAttribute = attributeValue && attributeValue.charAt(0) === "+" && (!inputValue || inputValue.charAt(0) !== "+");
3435 var val = useAttribute ? attributeValue : inputValue;
3436 var dialCode = this._getDialCode(val);
3437 var isRegionlessNanp = this._isRegionlessNanp(val);
3438 var _this$options = this.options, initialCountry = _this$options.initialCountry, nationalMode = _this$options.nationalMode, autoHideDialCode = _this$options.autoHideDialCode, separateDialCode = _this$options.separateDialCode;
3439 // if we already have a dial code, and it's not a regionlessNanp, we can go ahead and set the
3440 // flag, else fall back to the default country
3441 if (dialCode && !isRegionlessNanp) {
3442 this._updateFlagFromNumber(val);
3443 } else if (initialCountry !== "auto") {
3444 // see if we should select a flag
3445 if (initialCountry) {
3446 this._setFlag(initialCountry.toLowerCase());
3447 } else {
3448 if (dialCode && isRegionlessNanp) {
3449 // has intl dial code, is regionless nanp, and no initialCountry, so default to US
3450 this._setFlag("us");
3451 } else {
3452 // no dial code and no initialCountry, so default to first in list
3453 this.defaultCountry = this.preferredCountries.length ? this.preferredCountries[0].iso2 : this.countries[0].iso2;
3454 if (!val) {
3455 this._setFlag(this.defaultCountry);
3456 }
3457 }
3458 }
3459 // if empty and no nationalMode and no autoHideDialCode then insert the default dial code
3460 if (!val && !nationalMode && !autoHideDialCode && !separateDialCode) {
3461 this.telInput.value = "+".concat(this.selectedCountryData.dialCode);
3462 }
3463 }
3464 // NOTE: if initialCountry is set to auto, that will be handled separately
3465 // format - note this wont be run after _updateDialCode as that's only called if no val
3466 if (val) this._updateValFromNumber(val);
3467 }
3468 }, {
3469 key: "_initListeners",
3470 value: function _initListeners() {
3471 this._initKeyListeners();
3472 if (this.options.autoHideDialCode) this._initBlurListeners();
3473 if (this.options.allowDropdown) this._initDropdownListeners();
3474 if (this.hiddenInput) this._initHiddenInputListener();
3475 }
3476 }, {
3477 key: "_initHiddenInputListener",
3478 value: function _initHiddenInputListener() {
3479 var _this3 = this;
3480 this._handleHiddenInputSubmit = function() {
3481 _this3.hiddenInput.value = _this3.getNumber();
3482 };
3483 if (this.telInput.form) this.telInput.form.addEventListener("submit", this._handleHiddenInputSubmit);
3484 }
3485 }, {
3486 key: "_getClosestLabel",
3487 value: function _getClosestLabel() {
3488 var el = this.telInput;
3489 while (el && el.tagName !== "LABEL") {
3490 el = el.parentNode;
3491 }
3492 return el;
3493 }
3494 }, {
3495 key: "_initDropdownListeners",
3496 value: function _initDropdownListeners() {
3497 var _this4 = this;
3498 // hack for input nested inside label (which is valid markup): clicking the selected-flag to
3499 // open the dropdown would then automatically trigger a 2nd click on the input which would
3500 // close it again
3501 this._handleLabelClick = function(e) {
3502 // if the dropdown is closed, then focus the input, else ignore the click
3503 if (_this4.countryList.classList.contains("iti__hide")) _this4.telInput.focus(); else e.preventDefault();
3504 };
3505 var label = this._getClosestLabel();
3506 if (label) label.addEventListener("click", this._handleLabelClick);
3507 // toggle country dropdown on click
3508 this._handleClickSelectedFlag = function() {
3509 // only intercept this event if we're opening the dropdown
3510 // else let it bubble up to the top ("click-off-to-close" listener)
3511 // we cannot just stopPropagation as it may be needed to close another instance
3512 if (_this4.countryList.classList.contains("iti__hide") && !_this4.telInput.disabled && !_this4.telInput.readOnly) {
3513 _this4._showDropdown();
3514 }
3515 };
3516 this.selectedFlag.addEventListener("click", this._handleClickSelectedFlag);
3517 // open dropdown list if currently focused
3518 this._handleFlagsContainerKeydown = function(e) {
3519 var isDropdownHidden = _this4.countryList.classList.contains("iti__hide");
3520 if (isDropdownHidden && [ "ArrowUp", "Up", "ArrowDown", "Down", " ", "Enter" ].indexOf(e.key) !== -1) {
3521 // prevent form from being submitted if "ENTER" was pressed
3522 e.preventDefault();
3523 // prevent event from being handled again by document
3524 e.stopPropagation();
3525 _this4._showDropdown();
3526 }
3527 // allow navigation from dropdown to input on TAB
3528 if (e.key === "Tab") _this4._closeDropdown();
3529 };
3530 this.flagsContainer.addEventListener("keydown", this._handleFlagsContainerKeydown);
3531 }
3532 }, {
3533 key: "_initRequests",
3534 value: function _initRequests() {
3535 var _this5 = this;
3536 // if the user has specified the path to the utils script, fetch it on window.load, else resolve
3537 if (this.options.utilsScript && !window.intlTelInputUtils) {
3538 // if the plugin is being initialised after the window.load event has already been fired
3539 if (window.intlTelInputGlobals.documentReady()) {
3540 window.intlTelInputGlobals.loadUtils(this.options.utilsScript);
3541 } else {
3542 // wait until the load event so we don't block any other requests e.g. the flags image
3543 window.addEventListener("load", function() {
3544 window.intlTelInputGlobals.loadUtils(_this5.options.utilsScript);
3545 });
3546 }
3547 } else this.resolveUtilsScriptPromise();
3548 if (this.options.initialCountry === "auto") this._loadAutoCountry(); else this.resolveAutoCountryPromise();
3549 }
3550 }, {
3551 key: "_loadAutoCountry",
3552 value: function _loadAutoCountry() {
3553 // 3 options:
3554 // 1) already loaded (we're done)
3555 // 2) not already started loading (start)
3556 // 3) already started loading (do nothing - just wait for loading callback to fire)
3557 if (window.intlTelInputGlobals.autoCountry) {
3558 this.handleAutoCountry();
3559 } else if (!window.intlTelInputGlobals.startedLoadingAutoCountry) {
3560 // don't do this twice!
3561 window.intlTelInputGlobals.startedLoadingAutoCountry = true;
3562 if (typeof this.options.geoIpLookup === "function") {
3563 this.options.geoIpLookup(function(countryCode) {
3564 window.intlTelInputGlobals.autoCountry = countryCode.toLowerCase();
3565 // tell all instances the auto country is ready
3566 // TODO: this should just be the current instances
3567 // UPDATE: use setTimeout in case their geoIpLookup function calls this callback straight
3568 // away (e.g. if they have already done the geo ip lookup somewhere else). Using
3569 // setTimeout means that the current thread of execution will finish before executing
3570 // this, which allows the plugin to finish initialising.
3571 setTimeout(function() {
3572 return forEachInstance("handleAutoCountry");
3573 });
3574 }, function() {
3575 return forEachInstance("rejectAutoCountryPromise");
3576 });
3577 }
3578 }
3579 }
3580 }, {
3581 key: "_initKeyListeners",
3582 value: function _initKeyListeners() {
3583 var _this6 = this;
3584 // update flag on keyup
3585 this._handleKeyupEvent = function() {
3586 if (_this6._updateFlagFromNumber(_this6.telInput.value)) {
3587 _this6._triggerCountryChange();
3588 }
3589 };
3590 this.telInput.addEventListener("keyup", this._handleKeyupEvent);
3591 // update flag on cut/paste events (now supported in all major browsers)
3592 this._handleClipboardEvent = function() {
3593 // hack because "paste" event is fired before input is updated
3594 setTimeout(_this6._handleKeyupEvent);
3595 };
3596 this.telInput.addEventListener("cut", this._handleClipboardEvent);
3597 this.telInput.addEventListener("paste", this._handleClipboardEvent);
3598 }
3599 }, {
3600 key: "_cap",
3601 value: function _cap(number) {
3602 var max = this.telInput.getAttribute("maxlength");
3603 return max && number.length > max ? number.substr(0, max) : number;
3604 }
3605 }, {
3606 key: "_initBlurListeners",
3607 value: function _initBlurListeners() {
3608 var _this7 = this;
3609 // on blur or form submit: if just a dial code then remove it
3610 this._handleSubmitOrBlurEvent = function() {
3611 _this7._removeEmptyDialCode();
3612 };
3613 if (this.telInput.form) this.telInput.form.addEventListener("submit", this._handleSubmitOrBlurEvent);
3614 this.telInput.addEventListener("blur", this._handleSubmitOrBlurEvent);
3615 }
3616 }, {
3617 key: "_removeEmptyDialCode",
3618 value: function _removeEmptyDialCode() {
3619 if (this.telInput.value.charAt(0) === "+") {
3620 var numeric = this._getNumeric(this.telInput.value);
3621 // if just a plus, or if just a dial code
3622 if (!numeric || this.selectedCountryData.dialCode === numeric) {
3623 this.telInput.value = "";
3624 }
3625 }
3626 }
3627 }, {
3628 key: "_getNumeric",
3629 value: function _getNumeric(s) {
3630 return s.replace(/\D/g, "");
3631 }
3632 }, {
3633 key: "_trigger",
3634 value: function _trigger(name) {
3635 // have to use old school document.createEvent as IE11 doesn't support `new Event()` syntax
3636 var e = document.createEvent("Event");
3637 e.initEvent(name, true, true);
3638 // can bubble, and is cancellable
3639 this.telInput.dispatchEvent(e);
3640 }
3641 }, {
3642 key: "_showDropdown",
3643 value: function _showDropdown() {
3644 this.countryList.classList.remove("iti__hide");
3645 this.selectedFlag.setAttribute("aria-expanded", "true");
3646 this._setDropdownPosition();
3647 // update highlighting and scroll to active list item
3648 if (this.activeItem) {
3649 this._highlightListItem(this.activeItem, false);
3650 this._scrollTo(this.activeItem, true);
3651 }
3652 // bind all the dropdown-related listeners: mouseover, click, click-off, keydown
3653 this._bindDropdownListeners();
3654 // update the arrow
3655 this.dropdownArrow.classList.add("iti__arrow--up");
3656 this._trigger("open:countrydropdown");
3657 }
3658 }, {
3659 key: "_toggleClass",
3660 value: function _toggleClass(el, className, shouldHaveClass) {
3661 if (shouldHaveClass && !el.classList.contains(className)) el.classList.add(className); else if (!shouldHaveClass && el.classList.contains(className)) el.classList.remove(className);
3662 }
3663 }, {
3664 key: "_setDropdownPosition",
3665 value: function _setDropdownPosition() {
3666 var _this8 = this;
3667 if (this.options.dropdownContainer) {
3668 this.options.dropdownContainer.appendChild(this.dropdown);
3669 }
3670 if (!this.isMobile) {
3671 var pos = this.telInput.getBoundingClientRect();
3672 // windowTop from https://stackoverflow.com/a/14384091/217866
3673 var windowTop = window.pageYOffset || document.documentElement.scrollTop;
3674 var inputTop = pos.top + windowTop;
3675 var dropdownHeight = this.countryList.offsetHeight;
3676 // dropdownFitsBelow = (dropdownBottom < windowBottom)
3677 var dropdownFitsBelow = inputTop + this.telInput.offsetHeight + dropdownHeight < windowTop + window.innerHeight;
3678 var dropdownFitsAbove = inputTop - dropdownHeight > windowTop;
3679 // by default, the dropdown will be below the input. If we want to position it above the
3680 // input, we add the dropup class.
3681 this._toggleClass(this.countryList, "iti__country-list--dropup", !dropdownFitsBelow && dropdownFitsAbove);
3682 // if dropdownContainer is enabled, calculate postion
3683 if (this.options.dropdownContainer) {
3684 // by default the dropdown will be directly over the input because it's not in the flow.
3685 // If we want to position it below, we need to add some extra top value.
3686 var extraTop = !dropdownFitsBelow && dropdownFitsAbove ? 0 : this.telInput.offsetHeight;
3687 // calculate placement
3688 this.dropdown.style.top = "".concat(inputTop + extraTop, "px");
3689 this.dropdown.style.left = "".concat(pos.left + document.body.scrollLeft, "px");
3690 // close menu on window scroll
3691 this._handleWindowScroll = function() {
3692 return _this8._closeDropdown();
3693 };
3694 window.addEventListener("scroll", this._handleWindowScroll);
3695 }
3696 }
3697 }
3698 }, {
3699 key: "_getClosestListItem",
3700 value: function _getClosestListItem(target) {
3701 var el = target;
3702 while (el && el !== this.countryList && !el.classList.contains("iti__country")) {
3703 el = el.parentNode;
3704 }
3705 // if we reached the countryList element, then return null
3706 return el === this.countryList ? null : el;
3707 }
3708 }, {
3709 key: "_bindDropdownListeners",
3710 value: function _bindDropdownListeners() {
3711 var _this9 = this;
3712 // when mouse over a list item, just highlight that one
3713 // we add the class "highlight", so if they hit "enter" we know which one to select
3714 this._handleMouseoverCountryList = function(e) {
3715 // handle event delegation, as we're listening for this event on the countryList
3716 var listItem = _this9._getClosestListItem(e.target);
3717 if (listItem) _this9._highlightListItem(listItem, false);
3718 };
3719 this.countryList.addEventListener("mouseover", this._handleMouseoverCountryList);
3720 // listen for country selection
3721 this._handleClickCountryList = function(e) {
3722 var listItem = _this9._getClosestListItem(e.target);
3723 if (listItem) _this9._selectListItem(listItem);
3724 };
3725 this.countryList.addEventListener("click", this._handleClickCountryList);
3726 // click off to close
3727 // (except when this initial opening click is bubbling up)
3728 // we cannot just stopPropagation as it may be needed to close another instance
3729 var isOpening = true;
3730 this._handleClickOffToClose = function() {
3731 if (!isOpening) _this9._closeDropdown();
3732 isOpening = false;
3733 };
3734 document.documentElement.addEventListener("click", this._handleClickOffToClose);
3735 // listen for up/down scrolling, enter to select, or letters to jump to country name.
3736 // use keydown as keypress doesn't fire for non-char keys and we want to catch if they
3737 // just hit down and hold it to scroll down (no keyup event).
3738 // listen on the document because that's where key events are triggered if no input has focus
3739 var query = "";
3740 var queryTimer = null;
3741 this._handleKeydownOnDropdown = function(e) {
3742 // prevent down key from scrolling the whole page,
3743 // and enter key from submitting a form etc
3744 e.preventDefault();
3745 // up and down to navigate
3746 if (e.key === "ArrowUp" || e.key === "Up" || e.key === "ArrowDown" || e.key === "Down") _this9._handleUpDownKey(e.key); else if (e.key === "Enter") _this9._handleEnterKey(); else if (e.key === "Escape") _this9._closeDropdown(); else if (/^[a-zA-ZÀ-ÿа-яА-Я ]$/.test(e.key)) {
3747 // jump to countries that start with the query string
3748 if (queryTimer) clearTimeout(queryTimer);
3749 query += e.key.toLowerCase();
3750 _this9._searchForCountry(query);
3751 // if the timer hits 1 second, reset the query
3752 queryTimer = setTimeout(function() {
3753 query = "";
3754 }, 1e3);
3755 }
3756 };
3757 document.addEventListener("keydown", this._handleKeydownOnDropdown);
3758 }
3759 }, {
3760 key: "_handleUpDownKey",
3761 value: function _handleUpDownKey(key) {
3762 var next = key === "ArrowUp" || key === "Up" ? this.highlightedItem.previousElementSibling : this.highlightedItem.nextElementSibling;
3763 if (next) {
3764 // skip the divider
3765 if (next.classList.contains("iti__divider")) {
3766 next = key === "ArrowUp" || key === "Up" ? next.previousElementSibling : next.nextElementSibling;
3767 }
3768 this._highlightListItem(next, true);
3769 }
3770 }
3771 }, {
3772 key: "_handleEnterKey",
3773 value: function _handleEnterKey() {
3774 if (this.highlightedItem) this._selectListItem(this.highlightedItem);
3775 }
3776 }, {
3777 key: "_searchForCountry",
3778 value: function _searchForCountry(query) {
3779 for (var i = 0; i < this.countries.length; i++) {
3780 if (this._startsWith(this.countries[i].name, query)) {
3781 var listItem = this.countryList.querySelector("#iti-".concat(this.id, "__item-").concat(this.countries[i].iso2));
3782 // update highlighting and scroll
3783 this._highlightListItem(listItem, false);
3784 this._scrollTo(listItem, true);
3785 break;
3786 }
3787 }
3788 }
3789 }, {
3790 key: "_startsWith",
3791 value: function _startsWith(a, b) {
3792 return a.substr(0, b.length).toLowerCase() === b;
3793 }
3794 }, {
3795 key: "_updateValFromNumber",
3796 value: function _updateValFromNumber(originalNumber) {
3797 var number = originalNumber;
3798 if (this.options.formatOnDisplay && window.intlTelInputUtils && this.selectedCountryData) {
3799 var useNational = !this.options.separateDialCode && (this.options.nationalMode || number.charAt(0) !== "+");
3800 var _intlTelInputUtils$nu = intlTelInputUtils.numberFormat, NATIONAL = _intlTelInputUtils$nu.NATIONAL, INTERNATIONAL = _intlTelInputUtils$nu.INTERNATIONAL;
3801 var format = useNational ? NATIONAL : INTERNATIONAL;
3802 number = intlTelInputUtils.formatNumber(number, this.selectedCountryData.iso2, format);
3803 }
3804 number = this._beforeSetNumber(number);
3805 this.telInput.value = number;
3806 }
3807 }, {
3808 key: "_updateFlagFromNumber",
3809 value: function _updateFlagFromNumber(originalNumber) {
3810 // if we're in nationalMode and we already have US/Canada selected, make sure the number starts
3811 // with a +1 so _getDialCode will be able to extract the area code
3812 // update: if we dont yet have selectedCountryData, but we're here (trying to update the flag
3813 // from the number), that means we're initialising the plugin with a number that already has a
3814 // dial code, so fine to ignore this bit
3815 var number = originalNumber;
3816 var selectedDialCode = this.selectedCountryData.dialCode;
3817 var isNanp = selectedDialCode === "1";
3818 if (number && this.options.nationalMode && isNanp && number.charAt(0) !== "+") {
3819 if (number.charAt(0) !== "1") number = "1".concat(number);
3820 number = "+".concat(number);
3821 }
3822 // update flag if user types area code for another country
3823 if (this.options.separateDialCode && selectedDialCode && number.charAt(0) !== "+") {
3824 number = "+".concat(selectedDialCode).concat(number);
3825 }
3826 // try and extract valid dial code from input
3827 var dialCode = this._getDialCode(number, true);
3828 var numeric = this._getNumeric(number);
3829 var countryCode = null;
3830 if (dialCode) {
3831 var countryCodes = this.countryCodes[this._getNumeric(dialCode)];
3832 // check if the right country is already selected. this should be false if the number is
3833 // longer than the matched dial code because in this case we need to make sure that if
3834 // there are multiple country matches, that the first one is selected (note: we could
3835 // just check that here, but it requires the same loop that we already have later)
3836 var alreadySelected = countryCodes.indexOf(this.selectedCountryData.iso2) !== -1 && numeric.length <= dialCode.length - 1;
3837 var isRegionlessNanpNumber = selectedDialCode === "1" && this._isRegionlessNanp(numeric);
3838 // only update the flag if:
3839 // A) NOT (we currently have a NANP flag selected, and the number is a regionlessNanp)
3840 // AND
3841 // B) the right country is not already selected
3842 if (!isRegionlessNanpNumber && !alreadySelected) {
3843 // if using onlyCountries option, countryCodes[0] may be empty, so we must find the first
3844 // non-empty index
3845 for (var j = 0; j < countryCodes.length; j++) {
3846 if (countryCodes[j]) {
3847 countryCode = countryCodes[j];
3848 break;
3849 }
3850 }
3851 }
3852 } else if (number.charAt(0) === "+" && numeric.length) {
3853 // invalid dial code, so empty
3854 // Note: use getNumeric here because the number has not been formatted yet, so could contain
3855 // bad chars
3856 countryCode = "";
3857 } else if (!number || number === "+") {
3858 // empty, or just a plus, so default
3859 countryCode = this.defaultCountry;
3860 }
3861 if (countryCode !== null) {
3862 return this._setFlag(countryCode);
3863 }
3864 return false;
3865 }
3866 }, {
3867 key: "_isRegionlessNanp",
3868 value: function _isRegionlessNanp(number) {
3869 var numeric = this._getNumeric(number);
3870 if (numeric.charAt(0) === "1") {
3871 var areaCode = numeric.substr(1, 3);
3872 return regionlessNanpNumbers.indexOf(areaCode) !== -1;
3873 }
3874 return false;
3875 }
3876 }, {
3877 key: "_highlightListItem",
3878 value: function _highlightListItem(listItem, shouldFocus) {
3879 var prevItem = this.highlightedItem;
3880 if (prevItem) prevItem.classList.remove("iti__highlight");
3881 this.highlightedItem = listItem;
3882 this.highlightedItem.classList.add("iti__highlight");
3883 if (shouldFocus) this.highlightedItem.focus();
3884 }
3885 }, {
3886 key: "_getCountryData",
3887 value: function _getCountryData(countryCode, ignoreOnlyCountriesOption, allowFail) {
3888 var countryList = ignoreOnlyCountriesOption ? allCountries : this.countries;
3889 for (var i = 0; i < countryList.length; i++) {
3890 if (countryList[i].iso2 === countryCode) {
3891 return countryList[i];
3892 }
3893 }
3894 if (allowFail) {
3895 return null;
3896 }
3897 throw new Error("No country data for '".concat(countryCode, "'"));
3898 }
3899 }, {
3900 key: "_setFlag",
3901 value: function _setFlag(countryCode) {
3902 var prevCountry = this.selectedCountryData.iso2 ? this.selectedCountryData : {};
3903 // do this first as it will throw an error and stop if countryCode is invalid
3904 this.selectedCountryData = countryCode ? this._getCountryData(countryCode, false, false) : {};
3905 // update the defaultCountry - we only need the iso2 from now on, so just store that
3906 if (this.selectedCountryData.iso2) {
3907 this.defaultCountry = this.selectedCountryData.iso2;
3908 }
3909 this.selectedFlagInner.setAttribute("class", "iti__flag iti__".concat(countryCode));
3910 // update the selected country's title attribute
3911 var title = countryCode ? "".concat(this.selectedCountryData.name, ": +").concat(this.selectedCountryData.dialCode) : "Unknown";
3912 this.selectedFlag.setAttribute("title", title);
3913 if (this.options.separateDialCode) {
3914 var dialCode = this.selectedCountryData.dialCode ? "+".concat(this.selectedCountryData.dialCode) : "";
3915 this.selectedDialCode.innerHTML = dialCode;
3916 // offsetWidth is zero if input is in a hidden container during initialisation
3917 var selectedFlagWidth = this.selectedFlag.offsetWidth || this._getHiddenSelectedFlagWidth();
3918 // add 6px of padding after the grey selected-dial-code box, as this is what we use in the css
3919 this.telInput.style.paddingLeft = "".concat(selectedFlagWidth + 6, "px");
3920 }
3921 // and the input's placeholder
3922 this._updatePlaceholder();
3923 // update the active list item
3924 if (this.options.allowDropdown) {
3925 var prevItem = this.activeItem;
3926 if (prevItem) {
3927 prevItem.classList.remove("iti__active");
3928 prevItem.setAttribute("aria-selected", "false");
3929 }
3930 if (countryCode) {
3931 // check if there is a preferred item first, else fall back to standard
3932 var nextItem = this.countryList.querySelector("#iti-".concat(this.id, "__item-").concat(countryCode, "-preferred")) || this.countryList.querySelector("#iti-".concat(this.id, "__item-").concat(countryCode));
3933 nextItem.setAttribute("aria-selected", "true");
3934 nextItem.classList.add("iti__active");
3935 this.activeItem = nextItem;
3936 this.selectedFlag.setAttribute("aria-activedescendant", nextItem.getAttribute("id"));
3937 }
3938 }
3939 // return if the flag has changed or not
3940 return prevCountry.iso2 !== countryCode;
3941 }
3942 }, {
3943 key: "_getHiddenSelectedFlagWidth",
3944 value: function _getHiddenSelectedFlagWidth() {
3945 // to get the right styling to apply, all we need is a shallow clone of the container,
3946 // and then to inject a deep clone of the selectedFlag element
3947 var containerClone = this.telInput.parentNode.cloneNode();
3948 containerClone.style.visibility = "hidden";
3949 document.body.appendChild(containerClone);
3950 var flagsContainerClone = this.flagsContainer.cloneNode();
3951 containerClone.appendChild(flagsContainerClone);
3952 var selectedFlagClone = this.selectedFlag.cloneNode(true);
3953 flagsContainerClone.appendChild(selectedFlagClone);
3954 var width = selectedFlagClone.offsetWidth;
3955 containerClone.parentNode.removeChild(containerClone);
3956 return width;
3957 }
3958 }, {
3959 key: "_updatePlaceholder",
3960 value: function _updatePlaceholder() {
3961 var shouldSetPlaceholder = this.options.autoPlaceholder === "aggressive" || !this.hadInitialPlaceholder && this.options.autoPlaceholder === "polite";
3962 if (window.intlTelInputUtils && shouldSetPlaceholder) {
3963 var numberType = intlTelInputUtils.numberType[this.options.placeholderNumberType];
3964 var placeholder = this.selectedCountryData.iso2 ? intlTelInputUtils.getExampleNumber(this.selectedCountryData.iso2, this.options.nationalMode, numberType) : "";
3965 placeholder = this._beforeSetNumber(placeholder);
3966 if (typeof this.options.customPlaceholder === "function") {
3967 placeholder = this.options.customPlaceholder(placeholder, this.selectedCountryData);
3968 }
3969 this.telInput.setAttribute("placeholder", placeholder);
3970 }
3971 }
3972 }, {
3973 key: "_selectListItem",
3974 value: function _selectListItem(listItem) {
3975 // update selected flag and active list item
3976 var flagChanged = this._setFlag(listItem.getAttribute("data-country-code"));
3977 this._closeDropdown();
3978 this._updateDialCode(listItem.getAttribute("data-dial-code"), true);
3979 // focus the input
3980 this.telInput.focus();
3981 // put cursor at end - this fix is required for FF and IE11 (with nationalMode=false i.e. auto
3982 // inserting dial code), who try to put the cursor at the beginning the first time
3983 var len = this.telInput.value.length;
3984 this.telInput.setSelectionRange(len, len);
3985 if (flagChanged) {
3986 this._triggerCountryChange();
3987 }
3988 }
3989 }, {
3990 key: "_closeDropdown",
3991 value: function _closeDropdown() {
3992 this.countryList.classList.add("iti__hide");
3993 this.selectedFlag.setAttribute("aria-expanded", "false");
3994 // update the arrow
3995 this.dropdownArrow.classList.remove("iti__arrow--up");
3996 // unbind key events
3997 document.removeEventListener("keydown", this._handleKeydownOnDropdown);
3998 document.documentElement.removeEventListener("click", this._handleClickOffToClose);
3999 this.countryList.removeEventListener("mouseover", this._handleMouseoverCountryList);
4000 this.countryList.removeEventListener("click", this._handleClickCountryList);
4001 // remove menu from container
4002 if (this.options.dropdownContainer) {
4003 if (!this.isMobile) window.removeEventListener("scroll", this._handleWindowScroll);
4004 if (this.dropdown.parentNode) this.dropdown.parentNode.removeChild(this.dropdown);
4005 }
4006 this._trigger("close:countrydropdown");
4007 }
4008 }, {
4009 key: "_scrollTo",
4010 value: function _scrollTo(element, middle) {
4011 var container = this.countryList;
4012 // windowTop from https://stackoverflow.com/a/14384091/217866
4013 var windowTop = window.pageYOffset || document.documentElement.scrollTop;
4014 var containerHeight = container.offsetHeight;
4015 var containerTop = container.getBoundingClientRect().top + windowTop;
4016 var containerBottom = containerTop + containerHeight;
4017 var elementHeight = element.offsetHeight;
4018 var elementTop = element.getBoundingClientRect().top + windowTop;
4019 var elementBottom = elementTop + elementHeight;
4020 var newScrollTop = elementTop - containerTop + container.scrollTop;
4021 var middleOffset = containerHeight / 2 - elementHeight / 2;
4022 if (elementTop < containerTop) {
4023 // scroll up
4024 if (middle) newScrollTop -= middleOffset;
4025 container.scrollTop = newScrollTop;
4026 } else if (elementBottom > containerBottom) {
4027 // scroll down
4028 if (middle) newScrollTop += middleOffset;
4029 var heightDifference = containerHeight - elementHeight;
4030 container.scrollTop = newScrollTop - heightDifference;
4031 }
4032 }
4033 }, {
4034 key: "_updateDialCode",
4035 value: function _updateDialCode(newDialCodeBare, hasSelectedListItem) {
4036 var inputVal = this.telInput.value;
4037 // save having to pass this every time
4038 var newDialCode = "+".concat(newDialCodeBare);
4039 var newNumber;
4040 if (inputVal.charAt(0) === "+") {
4041 // there's a plus so we're dealing with a replacement (doesn't matter if nationalMode or not)
4042 var prevDialCode = this._getDialCode(inputVal);
4043 if (prevDialCode) {
4044 // current number contains a valid dial code, so replace it
4045 newNumber = inputVal.replace(prevDialCode, newDialCode);
4046 } else {
4047 // current number contains an invalid dial code, so ditch it
4048 // (no way to determine where the invalid dial code ends and the rest of the number begins)
4049 newNumber = newDialCode;
4050 }
4051 } else if (this.options.nationalMode || this.options.separateDialCode) {
4052 // don't do anything
4053 return;
4054 } else {
4055 // nationalMode is disabled
4056 if (inputVal) {
4057 // there is an existing value with no dial code: prefix the new dial code
4058 newNumber = newDialCode + inputVal;
4059 } else if (hasSelectedListItem || !this.options.autoHideDialCode) {
4060 // no existing value and either they've just selected a list item, or autoHideDialCode is
4061 // disabled: insert new dial code
4062 newNumber = newDialCode;
4063 } else {
4064 return;
4065 }
4066 }
4067 this.telInput.value = newNumber;
4068 }
4069 }, {
4070 key: "_getDialCode",
4071 value: function _getDialCode(number, includeAreaCode) {
4072 var dialCode = "";
4073 // only interested in international numbers (starting with a plus)
4074 if (number.charAt(0) === "+") {
4075 var numericChars = "";
4076 // iterate over chars
4077 for (var i = 0; i < number.length; i++) {
4078 var c = number.charAt(i);
4079 // if char is number (https://stackoverflow.com/a/8935649/217866)
4080 if (!isNaN(parseInt(c, 10))) {
4081 numericChars += c;
4082 // if current numericChars make a valid dial code
4083 if (includeAreaCode) {
4084 if (this.countryCodes[numericChars]) {
4085 // store the actual raw string (useful for matching later)
4086 dialCode = number.substr(0, i + 1);
4087 }
4088 } else {
4089 if (this.dialCodes[numericChars]) {
4090 dialCode = number.substr(0, i + 1);
4091 // if we're just looking for a dial code, we can break as soon as we find one
4092 break;
4093 }
4094 }
4095 // stop searching as soon as we can - in this case when we hit max len
4096 if (numericChars.length === this.countryCodeMaxLen) {
4097 break;
4098 }
4099 }
4100 }
4101 }
4102 return dialCode;
4103 }
4104 }, {
4105 key: "_getFullNumber",
4106 value: function _getFullNumber() {
4107 var val = this.telInput.value.trim();
4108 var dialCode = this.selectedCountryData.dialCode;
4109 var prefix;
4110 var numericVal = this._getNumeric(val);
4111 if (this.options.separateDialCode && val.charAt(0) !== "+" && dialCode && numericVal) {
4112 // when using separateDialCode, it is visible so is effectively part of the typed number
4113 prefix = "+".concat(dialCode);
4114 } else {
4115 prefix = "";
4116 }
4117 return prefix + val;
4118 }
4119 }, {
4120 key: "_beforeSetNumber",
4121 value: function _beforeSetNumber(originalNumber) {
4122 var number = originalNumber;
4123 if (this.options.separateDialCode) {
4124 var dialCode = this._getDialCode(number);
4125 // if there is a valid dial code
4126 if (dialCode) {
4127 // in case _getDialCode returned an area code as well
4128 dialCode = "+".concat(this.selectedCountryData.dialCode);
4129 // a lot of numbers will have a space separating the dial code and the main number, and
4130 // some NANP numbers will have a hyphen e.g. +1 684-733-1234 - in both cases we want to get
4131 // rid of it
4132 // NOTE: don't just trim all non-numerics as may want to preserve an open parenthesis etc
4133 var start = number[dialCode.length] === " " || number[dialCode.length] === "-" ? dialCode.length + 1 : dialCode.length;
4134 number = number.substr(start);
4135 }
4136 }
4137 return this._cap(number);
4138 }
4139 }, {
4140 key: "_triggerCountryChange",
4141 value: function _triggerCountryChange() {
4142 this._trigger("countrychange");
4143 }
4144 }, {
4145 key: "handleAutoCountry",
4146 value: function handleAutoCountry() {
4147 if (this.options.initialCountry === "auto") {
4148 // we must set this even if there is an initial val in the input: in case the initial val is
4149 // invalid and they delete it - they should see their auto country
4150 this.defaultCountry = window.intlTelInputGlobals.autoCountry;
4151 // if there's no initial value in the input, then update the flag
4152 if (!this.telInput.value) {
4153 this.setCountry(this.defaultCountry);
4154 }
4155 this.resolveAutoCountryPromise();
4156 }
4157 }
4158 }, {
4159 key: "handleUtils",
4160 value: function handleUtils() {
4161 // if the request was successful
4162 if (window.intlTelInputUtils) {
4163 // if there's an initial value in the input, then format it
4164 if (this.telInput.value) {
4165 this._updateValFromNumber(this.telInput.value);
4166 }
4167 this._updatePlaceholder();
4168 }
4169 this.resolveUtilsScriptPromise();
4170 }
4171 }, {
4172 key: "destroy",
4173 value: function destroy() {
4174 var form = this.telInput.form;
4175 if (this.options.allowDropdown) {
4176 // make sure the dropdown is closed (and unbind listeners)
4177 this._closeDropdown();
4178 this.selectedFlag.removeEventListener("click", this._handleClickSelectedFlag);
4179 this.flagsContainer.removeEventListener("keydown", this._handleFlagsContainerKeydown);
4180 // label click hack
4181 var label = this._getClosestLabel();
4182 if (label) label.removeEventListener("click", this._handleLabelClick);
4183 }
4184 // unbind hiddenInput listeners
4185 if (this.hiddenInput && form) form.removeEventListener("submit", this._handleHiddenInputSubmit);
4186 // unbind autoHideDialCode listeners
4187 if (this.options.autoHideDialCode) {
4188 if (form) form.removeEventListener("submit", this._handleSubmitOrBlurEvent);
4189 this.telInput.removeEventListener("blur", this._handleSubmitOrBlurEvent);
4190 }
4191 // unbind key events, and cut/paste events
4192 this.telInput.removeEventListener("keyup", this._handleKeyupEvent);
4193 this.telInput.removeEventListener("cut", this._handleClipboardEvent);
4194 this.telInput.removeEventListener("paste", this._handleClipboardEvent);
4195 // remove attribute of id instance: data-intl-tel-input-id
4196 this.telInput.removeAttribute("data-intl-tel-input-id");
4197 // remove markup (but leave the original input)
4198 var wrapper = this.telInput.parentNode;
4199 wrapper.parentNode.insertBefore(this.telInput, wrapper);
4200 wrapper.parentNode.removeChild(wrapper);
4201 delete window.intlTelInputGlobals.instances[this.id];
4202 }
4203 }, {
4204 key: "getExtension",
4205 value: function getExtension() {
4206 if (window.intlTelInputUtils) {
4207 return intlTelInputUtils.getExtension(this._getFullNumber(), this.selectedCountryData.iso2);
4208 }
4209 return "";
4210 }
4211 }, {
4212 key: "getNumber",
4213 value: function getNumber(format) {
4214 if (window.intlTelInputUtils) {
4215 var iso2 = this.selectedCountryData.iso2;
4216 return intlTelInputUtils.formatNumber(this._getFullNumber(), iso2, format);
4217 }
4218 return "";
4219 }
4220 }, {
4221 key: "getNumberType",
4222 value: function getNumberType() {
4223 if (window.intlTelInputUtils) {
4224 return intlTelInputUtils.getNumberType(this._getFullNumber(), this.selectedCountryData.iso2);
4225 }
4226 return -99;
4227 }
4228 }, {
4229 key: "getSelectedCountryData",
4230 value: function getSelectedCountryData() {
4231 return this.selectedCountryData;
4232 }
4233 }, {
4234 key: "getValidationError",
4235 value: function getValidationError() {
4236 if (window.intlTelInputUtils) {
4237 var iso2 = this.selectedCountryData.iso2;
4238 return intlTelInputUtils.getValidationError(this._getFullNumber(), iso2);
4239 }
4240 return -99;
4241 }
4242 }, {
4243 key: "isValidNumber",
4244 value: function isValidNumber() {
4245 var val = this._getFullNumber().trim();
4246 var countryCode = this.options.nationalMode ? this.selectedCountryData.iso2 : "";
4247 return window.intlTelInputUtils ? intlTelInputUtils.isValidNumber(val, countryCode) : null;
4248 }
4249 }, {
4250 key: "setCountry",
4251 value: function setCountry(originalCountryCode) {
4252 var countryCode = originalCountryCode.toLowerCase();
4253 // check if already selected
4254 if (!this.selectedFlagInner.classList.contains("iti__".concat(countryCode))) {
4255 this._setFlag(countryCode);
4256 this._updateDialCode(this.selectedCountryData.dialCode, false);
4257 this._triggerCountryChange();
4258 }
4259 }
4260 }, {
4261 key: "setNumber",
4262 value: function setNumber(number) {
4263 // we must update the flag first, which updates this.selectedCountryData, which is used for
4264 // formatting the number before displaying it
4265 var flagChanged = this._updateFlagFromNumber(number);
4266 this._updateValFromNumber(number);
4267 if (flagChanged) {
4268 this._triggerCountryChange();
4269 }
4270 }
4271 }, {
4272 key: "setPlaceholderNumberType",
4273 value: function setPlaceholderNumberType(type) {
4274 this.options.placeholderNumberType = type;
4275 this._updatePlaceholder();
4276 }
4277 } ]);
4278 return Iti;
4279 }();
4280 /********************
4281 * STATIC METHODS
4282 ********************/
4283 // get the country data object
4284 intlTelInputGlobals.getCountryData = function() {
4285 return allCountries;
4286 };
4287 // inject a <script> element to load utils.js
4288 var injectScript = function injectScript(path, handleSuccess, handleFailure) {
4289 // inject a new script element into the page
4290 var script = document.createElement("script");
4291 script.onload = function() {
4292 forEachInstance("handleUtils");
4293 if (handleSuccess) handleSuccess();
4294 };
4295 script.onerror = function() {
4296 forEachInstance("rejectUtilsScriptPromise");
4297 if (handleFailure) handleFailure();
4298 };
4299 script.className = "iti-load-utils";
4300 script.async = true;
4301 script.src = path;
4302 document.body.appendChild(script);
4303 };
4304 // load the utils script
4305 intlTelInputGlobals.loadUtils = function(path) {
4306 // 2 options:
4307 // 1) not already started loading (start)
4308 // 2) already started loading (do nothing - just wait for the onload callback to fire, which will
4309 // trigger handleUtils on all instances, invoking their resolveUtilsScriptPromise functions)
4310 if (!window.intlTelInputUtils && !window.intlTelInputGlobals.startedLoadingUtilsScript) {
4311 // only do this once
4312 window.intlTelInputGlobals.startedLoadingUtilsScript = true;
4313 // if we have promises, then return a promise
4314 if (typeof Promise !== "undefined") {
4315 return new Promise(function(resolve, reject) {
4316 return injectScript(path, resolve, reject);
4317 });
4318 }
4319 injectScript(path);
4320 }
4321 return null;
4322 };
4323 // default options
4324 intlTelInputGlobals.defaults = defaults;
4325 // version
4326 intlTelInputGlobals.version = "17.0.16";
4327 // convenience wrapper
4328 return function(input, options) {
4329 var iti = new Iti(input, options);
4330 iti._init();
4331 input.setAttribute("data-intl-tel-input-id", iti.id);
4332 window.intlTelInputGlobals.instances[iti.id] = iti;
4333 return iti;
4334 };
4335 }();
4336 });
4337 },{}],19:[function(require,module,exports){
4338 /**
4339 * Exposing intl-tel-input as a component
4340 */
4341 module.exports = require("./build/js/intlTelInput");
4342
4343 },{"./build/js/intlTelInput":18}],20:[function(require,module,exports){
4344 (function (process){
4345 /**
4346 * Memize options object.
4347 *
4348 * @typedef MemizeOptions
4349 *
4350 * @property {number} [maxSize] Maximum size of the cache.
4351 */
4352
4353 /**
4354 * Internal cache entry.
4355 *
4356 * @typedef MemizeCacheNode
4357 *
4358 * @property {?MemizeCacheNode|undefined} [prev] Previous node.
4359 * @property {?MemizeCacheNode|undefined} [next] Next node.
4360 * @property {Array<*>} args Function arguments for cache
4361 * entry.
4362 * @property {*} val Function result.
4363 */
4364
4365 /**
4366 * Properties of the enhanced function for controlling cache.
4367 *
4368 * @typedef MemizeMemoizedFunction
4369 *
4370 * @property {()=>void} clear Clear the cache.
4371 */
4372
4373 /**
4374 * Accepts a function to be memoized, and returns a new memoized function, with
4375 * optional options.
4376 *
4377 * @template {Function} F
4378 *
4379 * @param {F} fn Function to memoize.
4380 * @param {MemizeOptions} [options] Options object.
4381 *
4382 * @return {F & MemizeMemoizedFunction} Memoized function.
4383 */
4384 function memize( fn, options ) {
4385 var size = 0;
4386
4387 /** @type {?MemizeCacheNode|undefined} */
4388 var head;
4389
4390 /** @type {?MemizeCacheNode|undefined} */
4391 var tail;
4392
4393 options = options || {};
4394
4395 function memoized( /* ...args */ ) {
4396 var node = head,
4397 len = arguments.length,
4398 args, i;
4399
4400 searchCache: while ( node ) {
4401 // Perform a shallow equality test to confirm that whether the node
4402 // under test is a candidate for the arguments passed. Two arrays
4403 // are shallowly equal if their length matches and each entry is
4404 // strictly equal between the two sets. Avoid abstracting to a
4405 // function which could incur an arguments leaking deoptimization.
4406
4407 // Check whether node arguments match arguments length
4408 if ( node.args.length !== arguments.length ) {
4409 node = node.next;
4410 continue;
4411 }
4412
4413 // Check whether node arguments match arguments values
4414 for ( i = 0; i < len; i++ ) {
4415 if ( node.args[ i ] !== arguments[ i ] ) {
4416 node = node.next;
4417 continue searchCache;
4418 }
4419 }
4420
4421 // At this point we can assume we've found a match
4422
4423 // Surface matched node to head if not already
4424 if ( node !== head ) {
4425 // As tail, shift to previous. Must only shift if not also
4426 // head, since if both head and tail, there is no previous.
4427 if ( node === tail ) {
4428 tail = node.prev;
4429 }
4430
4431 // Adjust siblings to point to each other. If node was tail,
4432 // this also handles new tail's empty `next` assignment.
4433 /** @type {MemizeCacheNode} */ ( node.prev ).next = node.next;
4434 if ( node.next ) {
4435 node.next.prev = node.prev;
4436 }
4437
4438 node.next = head;
4439 node.prev = null;
4440 /** @type {MemizeCacheNode} */ ( head ).prev = node;
4441 head = node;
4442 }
4443
4444 // Return immediately
4445 return node.val;
4446 }
4447
4448 // No cached value found. Continue to insertion phase:
4449
4450 // Create a copy of arguments (avoid leaking deoptimization)
4451 args = new Array( len );
4452 for ( i = 0; i < len; i++ ) {
4453 args[ i ] = arguments[ i ];
4454 }
4455
4456 node = {
4457 args: args,
4458
4459 // Generate the result from original function
4460 val: fn.apply( null, args ),
4461 };
4462
4463 // Don't need to check whether node is already head, since it would
4464 // have been returned above already if it was
4465
4466 // Shift existing head down list
4467 if ( head ) {
4468 head.prev = node;
4469 node.next = head;
4470 } else {
4471 // If no head, follows that there's no tail (at initial or reset)
4472 tail = node;
4473 }
4474
4475 // Trim tail if we're reached max size and are pending cache insertion
4476 if ( size === /** @type {MemizeOptions} */ ( options ).maxSize ) {
4477 tail = /** @type {MemizeCacheNode} */ ( tail ).prev;
4478 /** @type {MemizeCacheNode} */ ( tail ).next = null;
4479 } else {
4480 size++;
4481 }
4482
4483 head = node;
4484
4485 return node.val;
4486 }
4487
4488 memoized.clear = function() {
4489 head = null;
4490 tail = null;
4491 size = 0;
4492 };
4493
4494 if ( process.env.NODE_ENV === 'test' ) {
4495 // Cache is not exposed in the public API, but used in tests to ensure
4496 // expected list progression
4497 memoized.getCache = function() {
4498 return [ head, tail, size ];
4499 };
4500 }
4501
4502 // Ignore reason: There's not a clear solution to create an intersection of
4503 // the function with additional properties, where the goal is to retain the
4504 // function signature of the incoming argument and add control properties
4505 // on the return value.
4506
4507 // @ts-ignore
4508 return memoized;
4509 }
4510
4511 module.exports = memize;
4512
4513 }).call(this,require('_process'))
4514 },{"_process":21}],21:[function(require,module,exports){
4515 // shim for using process in browser
4516 var process = module.exports = {};
4517
4518 // cached from whatever global is present so that test runners that stub it
4519 // don't break things. But we need to wrap it in a try catch in case it is
4520 // wrapped in strict mode code which doesn't define any globals. It's inside a
4521 // function because try/catches deoptimize in certain engines.
4522
4523 var cachedSetTimeout;
4524 var cachedClearTimeout;
4525
4526 function defaultSetTimout() {
4527 throw new Error('setTimeout has not been defined');
4528 }
4529 function defaultClearTimeout () {
4530 throw new Error('clearTimeout has not been defined');
4531 }
4532 (function () {
4533 try {
4534 if (typeof setTimeout === 'function') {
4535 cachedSetTimeout = setTimeout;
4536 } else {
4537 cachedSetTimeout = defaultSetTimout;
4538 }
4539 } catch (e) {
4540 cachedSetTimeout = defaultSetTimout;
4541 }
4542 try {
4543 if (typeof clearTimeout === 'function') {
4544 cachedClearTimeout = clearTimeout;
4545 } else {
4546 cachedClearTimeout = defaultClearTimeout;
4547 }
4548 } catch (e) {
4549 cachedClearTimeout = defaultClearTimeout;
4550 }
4551 } ())
4552 function runTimeout(fun) {
4553 if (cachedSetTimeout === setTimeout) {
4554 //normal enviroments in sane situations
4555 return setTimeout(fun, 0);
4556 }
4557 // if setTimeout wasn't available but was latter defined
4558 if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
4559 cachedSetTimeout = setTimeout;
4560 return setTimeout(fun, 0);
4561 }
4562 try {
4563 // when when somebody has screwed with setTimeout but no I.E. maddness
4564 return cachedSetTimeout(fun, 0);
4565 } catch(e){
4566 try {
4567 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
4568 return cachedSetTimeout.call(null, fun, 0);
4569 } catch(e){
4570 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
4571 return cachedSetTimeout.call(this, fun, 0);
4572 }
4573 }
4574
4575
4576 }
4577 function runClearTimeout(marker) {
4578 if (cachedClearTimeout === clearTimeout) {
4579 //normal enviroments in sane situations
4580 return clearTimeout(marker);
4581 }
4582 // if clearTimeout wasn't available but was latter defined
4583 if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
4584 cachedClearTimeout = clearTimeout;
4585 return clearTimeout(marker);
4586 }
4587 try {
4588 // when when somebody has screwed with setTimeout but no I.E. maddness
4589 return cachedClearTimeout(marker);
4590 } catch (e){
4591 try {
4592 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
4593 return cachedClearTimeout.call(null, marker);
4594 } catch (e){
4595 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
4596 // Some versions of I.E. have different rules for clearTimeout vs setTimeout
4597 return cachedClearTimeout.call(this, marker);
4598 }
4599 }
4600
4601
4602
4603 }
4604 var queue = [];
4605 var draining = false;
4606 var currentQueue;
4607 var queueIndex = -1;
4608
4609 function cleanUpNextTick() {
4610 if (!draining || !currentQueue) {
4611 return;
4612 }
4613 draining = false;
4614 if (currentQueue.length) {
4615 queue = currentQueue.concat(queue);
4616 } else {
4617 queueIndex = -1;
4618 }
4619 if (queue.length) {
4620 drainQueue();
4621 }
4622 }
4623
4624 function drainQueue() {
4625 if (draining) {
4626 return;
4627 }
4628 var timeout = runTimeout(cleanUpNextTick);
4629 draining = true;
4630
4631 var len = queue.length;
4632 while(len) {
4633 currentQueue = queue;
4634 queue = [];
4635 while (++queueIndex < len) {
4636 if (currentQueue) {
4637 currentQueue[queueIndex].run();
4638 }
4639 }
4640 queueIndex = -1;
4641 len = queue.length;
4642 }
4643 currentQueue = null;
4644 draining = false;
4645 runClearTimeout(timeout);
4646 }
4647
4648 process.nextTick = function (fun) {
4649 var args = new Array(arguments.length - 1);
4650 if (arguments.length > 1) {
4651 for (var i = 1; i < arguments.length; i++) {
4652 args[i - 1] = arguments[i];
4653 }
4654 }
4655 queue.push(new Item(fun, args));
4656 if (queue.length === 1 && !draining) {
4657 runTimeout(drainQueue);
4658 }
4659 };
4660
4661 // v8 likes predictible objects
4662 function Item(fun, array) {
4663 this.fun = fun;
4664 this.array = array;
4665 }
4666 Item.prototype.run = function () {
4667 this.fun.apply(null, this.array);
4668 };
4669 process.title = 'browser';
4670 process.browser = true;
4671 process.env = {};
4672 process.argv = [];
4673 process.version = ''; // empty string to avoid regexp issues
4674 process.versions = {};
4675
4676 function noop() {}
4677
4678 process.on = noop;
4679 process.addListener = noop;
4680 process.once = noop;
4681 process.off = noop;
4682 process.removeListener = noop;
4683 process.removeAllListeners = noop;
4684 process.emit = noop;
4685 process.prependListener = noop;
4686 process.prependOnceListener = noop;
4687
4688 process.listeners = function (name) { return [] }
4689
4690 process.binding = function (name) {
4691 throw new Error('process.binding is not supported');
4692 };
4693
4694 process.cwd = function () { return '/' };
4695 process.chdir = function (dir) {
4696 throw new Error('process.chdir is not supported');
4697 };
4698 process.umask = function() { return 0; };
4699
4700 },{}],22:[function(require,module,exports){
4701 'use strict';
4702
4703 function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
4704
4705 var pluralForms = _interopDefault(require('@tannin/plural-forms'));
4706
4707 /**
4708 * Tannin constructor options.
4709 *
4710 * @typedef {Object} TanninOptions
4711 *
4712 * @property {string} [contextDelimiter] Joiner in string lookup with context.
4713 * @property {Function} [onMissingKey] Callback to invoke when key missing.
4714 */
4715
4716 /**
4717 * Domain metadata.
4718 *
4719 * @typedef {Object} TanninDomainMetadata
4720 *
4721 * @property {string} [domain] Domain name.
4722 * @property {string} [lang] Language code.
4723 * @property {(string|Function)} [plural_forms] Plural forms expression or
4724 * function evaluator.
4725 */
4726
4727 /**
4728 * Domain translation pair respectively representing the singular and plural
4729 * translation.
4730 *
4731 * @typedef {[string,string]} TanninTranslation
4732 */
4733
4734 /**
4735 * Locale data domain. The key is used as reference for lookup, the value an
4736 * array of two string entries respectively representing the singular and plural
4737 * translation.
4738 *
4739 * @typedef {{[key:string]:TanninDomainMetadata|TanninTranslation,'':TanninDomainMetadata|TanninTranslation}} TanninLocaleDomain
4740 */
4741
4742 /**
4743 * Jed-formatted locale data.
4744 *
4745 * @see http://messageformat.github.io/Jed/
4746 *
4747 * @typedef {{[domain:string]:TanninLocaleDomain}} TanninLocaleData
4748 */
4749
4750 /**
4751 * Default Tannin constructor options.
4752 *
4753 * @type {TanninOptions}
4754 */
4755 var DEFAULT_OPTIONS = {
4756 contextDelimiter: '\u0004',
4757 onMissingKey: null,
4758 };
4759
4760 /**
4761 * Given a specific locale data's config `plural_forms` value, returns the
4762 * expression.
4763 *
4764 * @example
4765 *
4766 * ```
4767 * getPluralExpression( 'nplurals=2; plural=(n != 1);' ) === '(n != 1)'
4768 * ```
4769 *
4770 * @param {string} pf Locale data plural forms.
4771 *
4772 * @return {string} Plural forms expression.
4773 */
4774 function getPluralExpression( pf ) {
4775 var parts, i, part;
4776
4777 parts = pf.split( ';' );
4778
4779 for ( i = 0; i < parts.length; i++ ) {
4780 part = parts[ i ].trim();
4781 if ( part.indexOf( 'plural=' ) === 0 ) {
4782 return part.substr( 7 );
4783 }
4784 }
4785 }
4786
4787 /**
4788 * Tannin constructor.
4789 *
4790 * @class
4791 *
4792 * @param {TanninLocaleData} data Jed-formatted locale data.
4793 * @param {TanninOptions} [options] Tannin options.
4794 */
4795 function Tannin( data, options ) {
4796 var key;
4797
4798 /**
4799 * Jed-formatted locale data.
4800 *
4801 * @name Tannin#data
4802 * @type {TanninLocaleData}
4803 */
4804 this.data = data;
4805
4806 /**
4807 * Plural forms function cache, keyed by plural forms string.
4808 *
4809 * @name Tannin#pluralForms
4810 * @type {Object<string,Function>}
4811 */
4812 this.pluralForms = {};
4813
4814 /**
4815 * Effective options for instance, including defaults.
4816 *
4817 * @name Tannin#options
4818 * @type {TanninOptions}
4819 */
4820 this.options = {};
4821
4822 for ( key in DEFAULT_OPTIONS ) {
4823 this.options[ key ] = options !== undefined && key in options
4824 ? options[ key ]
4825 : DEFAULT_OPTIONS[ key ];
4826 }
4827 }
4828
4829 /**
4830 * Returns the plural form index for the given domain and value.
4831 *
4832 * @param {string} domain Domain on which to calculate plural form.
4833 * @param {number} n Value for which plural form is to be calculated.
4834 *
4835 * @return {number} Plural form index.
4836 */
4837 Tannin.prototype.getPluralForm = function( domain, n ) {
4838 var getPluralForm = this.pluralForms[ domain ],
4839 config, plural, pf;
4840
4841 if ( ! getPluralForm ) {
4842 config = this.data[ domain ][ '' ];
4843
4844 pf = (
4845 config[ 'Plural-Forms' ] ||
4846 config[ 'plural-forms' ] ||
4847 // Ignore reason: As known, there's no way to document the empty
4848 // string property on a key to guarantee this as metadata.
4849 // @ts-ignore
4850 config.plural_forms
4851 );
4852
4853 if ( typeof pf !== 'function' ) {
4854 plural = getPluralExpression(
4855 config[ 'Plural-Forms' ] ||
4856 config[ 'plural-forms' ] ||
4857 // Ignore reason: As known, there's no way to document the empty
4858 // string property on a key to guarantee this as metadata.
4859 // @ts-ignore
4860 config.plural_forms
4861 );
4862
4863 pf = pluralForms( plural );
4864 }
4865
4866 getPluralForm = this.pluralForms[ domain ] = pf;
4867 }
4868
4869 return getPluralForm( n );
4870 };
4871
4872 /**
4873 * Translate a string.
4874 *
4875 * @param {string} domain Translation domain.
4876 * @param {string|void} context Context distinguishing terms of the same name.
4877 * @param {string} singular Primary key for translation lookup.
4878 * @param {string=} plural Fallback value used for non-zero plural
4879 * form index.
4880 * @param {number=} n Value to use in calculating plural form.
4881 *
4882 * @return {string} Translated string.
4883 */
4884 Tannin.prototype.dcnpgettext = function( domain, context, singular, plural, n ) {
4885 var index, key, entry;
4886
4887 if ( n === undefined ) {
4888 // Default to singular.
4889 index = 0;
4890 } else {
4891 // Find index by evaluating plural form for value.
4892 index = this.getPluralForm( domain, n );
4893 }
4894
4895 key = singular;
4896
4897 // If provided, context is prepended to key with delimiter.
4898 if ( context ) {
4899 key = context + this.options.contextDelimiter + singular;
4900 }
4901
4902 entry = this.data[ domain ][ key ];
4903
4904 // Verify not only that entry exists, but that the intended index is within
4905 // range and non-empty.
4906 if ( entry && entry[ index ] ) {
4907 return entry[ index ];
4908 }
4909
4910 if ( this.options.onMissingKey ) {
4911 this.options.onMissingKey( singular, domain );
4912 }
4913
4914 // If entry not found, fall back to singular vs. plural with zero index
4915 // representing the singular value.
4916 return index === 0 ? singular : plural;
4917 };
4918
4919 module.exports = Tannin;
4920
4921 },{"@tannin/plural-forms":11}]},{},[2]);
4922