{"version":3,"file":"../checkout-300.min.js","sources":["checkout-300.js"],"sourcesContent":["/**\n * Checkout Script\n * \n * Replaces the original WooCommerce `checkout.js`.\n */\n\n/* global wc_checkout_params */\njQuery( function( $ ) {\n\n\t// wc_checkout_params is required to continue, ensure the object exists\n\tif ( typeof wc_checkout_params === 'undefined' ) {\n\t\treturn false;\n\t}\n\n\t// CHANGE: Create flag to allow or block updating the checkout\n\twindow.can_update_checkout = true;\n\n\t// CHANGE: Add flag to up prevent users from leaving the page when there is unsaved data\n\tvar _updateBeforeUnload = false;\n\n\t// CHANGE: Add default settings object\n\tvar _settings = {\n\t\tformRowSelector: '.form-row',\n\t\tcheckoutPlaceOrderSelector: '#place_order, .fc-place-order-button',\n\t\tcheckoutTermsSelector: '.fc-terms-checkbox',\n\t\tcheckoutUpdateFieldsSelector: '.address-field input.input-text, .update_totals_on_change input.input-text',\n\t\tcheckoutLoadingInputSelector: '.loading_indicator_on_change input.input-text',\n\t\tfocusedFieldSkipFragmentReplaceSelector: 'input[type=\"text\"], input[type=\"color\"], input[type=\"date\"], input[type=\"datetime\"], input[type=\"datetime-local\"], input[type=\"email\"], input[type=\"file\"], input[type=\"image\"], input[type=\"month\"], input[type=\"number\"], input[type=\"password\"], input[type=\"search\"], input[type=\"tel\"], input[type=\"time\"], input[type=\"url\"], input[type=\"week\"], select, textarea, .fc-select2-field',\n\t\tphoneFieldSelector: 'input[type=\"tel\"], [data-phone-field], input.js-phone-field, .js-phone-field input',\n\t\tloginButtonSelector: '.fc-contact-login__action',\n\t\temailFieldSelector: 'form.woocommerce-checkout input[name=\"billing_email\"]',\n\t\tusernameFieldSelector: '.fc-login-form__inner input[name=\"username\"]',\n\n\t\tloadingClass: 'fc-loading',\n\t\tcheckoutBlockUISelector: '.woocommerce-checkout-payment, .woocommerce-checkout-review-order-table .fc-shipping-method__packages',\n\n\t\tcheckoutPlaceOrderApplyLoadingClass: 'yes',\n\t\tcheckoutUpdateBeforeUnload: 'yes',\n\t\tcheckoutUpdateOnVisibilityChange: 'yes',\n\t};\n\t// CHANGE: END - Add default settings object\n\n\t$.blockUI.defaults.overlayCSS.cursor = 'default';\n\n\tvar wc_checkout_form = {\n\t\tupdateTimer: false,\n\t\tdirtyInput: false,\n\t\tselectedPaymentMethod: false,\n\t\txhr: false,\n\t\t$order_review: $( '#order_review' ),\n\t\t$checkout_form: $( 'form.checkout' ),\n\t\tinit: function() {\n\t\t\t// CHANGE: Merge default settings object with values from the server settings object\n\t\t\t_settings = FCUtils.extendObject( true, _settings, window.fcSettings );\n\n\t\t\t$( document.body ).on( 'update_checkout', this.update_checkout );\n\t\t\t$( document.body ).on( 'init_checkout', this.init_checkout );\n\n\t\t\t// CHANGE: Add event handlers to autocomplete attributes\n\t\t\t$( document.body ).on( 'init_checkout', this.set_autocomplete_attribute_from_data );\n\t\t\t$( document.body ).on( 'updated_checkout', this.set_autocomplete_attribute_from_data );\n\n\t\t\t// Payment methods\n\t\t\tthis.$checkout_form.on( 'click', 'input[name=\"payment_method\"]', this.payment_method_selected );\n\n\t\t\tif ( $( document.body ).hasClass( 'woocommerce-order-pay' ) ) {\n\t\t\t\tthis.$order_review.on( 'click', 'input[name=\"payment_method\"]', this.payment_method_selected );\n\t\t\t\tthis.$order_review.on( 'submit', this.submitOrder );\n\t\t\t\tthis.$order_review.attr( 'novalidate', 'novalidate' );\n\t\t\t}\n\n\t\t\t// Prevent HTML5 validation which can conflict.\n\t\t\tthis.$checkout_form.attr( 'novalidate', 'novalidate' );\n\n\t\t\t// Form submission\n\t\t\tthis.$checkout_form.on( 'submit', this.submit );\n\n\t\t\t// CHANGE: Maybe disable inline validation from default WooCommerce checkout script when Fluid Checkout inline validation is enabled\n\t\t\tif ( ! window.CheckoutValidation ) {\n\t\t\t\t// Inline validation\n\t\t\t\tthis.$checkout_form.on( 'input validate change', '.input-text, select, input:checkbox', this.validate_field );\n\t\t\t}\n\n\t\t\t// Manual trigger\n\t\t\tthis.$checkout_form.on( 'update', this.trigger_update_checkout );\n\n\t\t\t// Inputs/selects which update totals\n\t\t\t// CHANGE: Removed selector `#ship-to-different-address input`\n\t\t\tthis.$checkout_form.on( 'change', 'select.shipping_method, input[name^=\"shipping_method\"], .update_totals_on_change select, .update_totals_on_change input[type=\"radio\"], .update_totals_on_change input[type=\"checkbox\"]', this.trigger_update_checkout ); // eslint-disable-line max-len\n\t\t\tthis.$checkout_form.on( 'change', '.address-field select', this.input_changed );\n\n\t\t\t// CHANGE: Move CSS selector for fields that trigger update checkout when value is changed\n\t\t\tthis.$checkout_form.on( 'change', _settings.checkoutUpdateFieldsSelector, this.maybe_input_changed ); // eslint-disable-line max-len\n\t\t\tthis.$checkout_form.on( 'keydown', _settings.checkoutUpdateFieldsSelector, this.queue_update_checkout ); // eslint-disable-line max-len\n\n\t\t\t// Address fields\n\t\t\t// CHANGE: Removed shipping to different address checkout `change` listener\n\n\t\t\t// CHANGE: Update checkout totals to save data to session when user switches tabs, apps, goes to homescreen, etc.\n\t\t\tdocument.addEventListener( 'visibilitychange', this.maybe_update_checkout_visibility_change );\n\n\t\t\t// CHANGE: Maybe prevent leaving the page if there are unsaved changes, and trigger `update_checkout` to save the data.\n\t\t\tif ( 'yes' === _settings.checkoutUpdateBeforeUnload ) {\n\t\t\t\tthis.$checkout_form.on( 'change, input', 'select, input, textarea', this.maybe_prevent_unload );\n\t\t\t}\n\n\t\t\t// CHANGE: Update checkout when \"billing same as shipping\" checked state changes\n\t\t\tthis.$checkout_form.on( 'change', '#billing_same_as_shipping', this.billing_same_shipping_changed );\n\n\t\t\t// CHANGE: Trigger reinitialization functions after checkout is updated\n\t\t\t$( document.body ).on( 'updated_checkout', this.maybe_reinitialize_collapsible_blocks );\n\t\t\t$( document.body ).on( 'updated_checkout', this.maybe_reinitialize_flyout_blocks );\n\n\t\t\t// CHANGE: Add event listener to sync terms checkbox state\n\t\t\tthis.$checkout_form.on( 'change', _settings.checkoutTermsSelector, this.terms_checked_changed );\n\n\t\t\t// Trigger events\n\t\t\t// CHANGE: Removed shipping to different address checkout `change` trigger\n\t\t\tthis.init_payment_methods();\n\n\t\t\t// Update on page load\n\t\t\tif ( wc_checkout_params.is_checkout === '1' ) {\n\t\t\t\t$( document.body ).trigger( 'init_checkout' );\n\t\t\t}\n\t\t\tif ( wc_checkout_params.option_guest_checkout === 'yes' ) {\n\t\t\t\t// CHANGE: Use native `change` event instead jQuery to handle create account checkbox toggle\n\t\t\t\tdocument.addEventListener( 'change', this.toggle_create_account, true );\n\t\t\t}\n\n\t\t\t// CHANGE: Add handler for login form modal initialization\n\t\t\tdocument.addEventListener( 'click', this.maybe_copy_email_to_login_form, true );\n\t\t},\n\t\t// CHANGE: Update checkout when \"billing same as shipping\" checked state changes\n\t\tbilling_same_shipping_changed: function( e ) {\n\t\t\tif ( window.CollapsibleBlock ) {\n\t\t\t\tvar checkbox = document.querySelector( '#billing_same_as_shipping' );\n\t\t\t\tvar fieldsWrapper = document.querySelector( '#woocommerce-billing-fields__field-wrapper' );\n\n\t\t\t\t// Toggle state\n\t\t\t\tif ( ! checkbox.checked ) {\n\t\t\t\t\tCollapsibleBlock.expand( fieldsWrapper );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tCollapsibleBlock.collapse( fieldsWrapper );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$( document.body ).trigger( 'update_checkout' );\n\t\t},\n\t\t// CHANGE: Reinitialize collapsible blocks after checkout update\n\t\tmaybe_reinitialize_collapsible_blocks: function() {\n\t\t\t// Bail if collapsible blocks are not available\n\t\t\tif ( ! window.CollapsibleBlock ) { return; }\n\n\t\t\t// Try to initialize collapsible blocks if not yet initialized\n\t\t\tCollapsibleBlock.init( window.fcSettings ? fcSettings.collapsibleBlock : null );\n\n\t\t\tvar collapsibleBlocks = document.querySelectorAll( '[data-collapsible]' );\n\t\t\tfor ( var i = 0; i < collapsibleBlocks.length; i++ ) {\n\t\t\t\tvar collapsibleBlock = collapsibleBlocks[i];\n\n\t\t\t\t// Maybe initialize the collapsible block\n\t\t\t\tif ( ! CollapsibleBlock.getInstance( collapsibleBlock ) ) {\n\t\t\t\t\tCollapsibleBlock.initializeElement( collapsibleBlock );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// CHANGE: Reinitialize flyout blocks after checkout update\n\t\tmaybe_reinitialize_flyout_blocks: function() {\n\t\t\t// Bail if flyout blocks are not available\n\t\t\tif ( ! window.FlyoutBlock ) { return; }\n\n\t\t\tFlyoutBlock.initTriggers();\n\t\t},\n\t\t// CHANGE: Update checkout when page gets hidden or visible again\n\t\tmaybe_update_checkout_visibility_change: function() {\n\t\t\t// Bail if update on visibility change is disabled\n\t\t\tif ( 'yes' !== _settings.checkoutUpdateOnVisibilityChange ) { return; }\n\n\t\t\t// Trigger update if visibility state is changed to `hidden` or `visible`\n\t\t\tif ( 'hidden' == document.visibilityState || 'visible' == document.visibilityState ) {\n\t\t\t\t$( document.body ).trigger( 'update_checkout', { refresh_payment_methods: false } );\n\t\t\t}\n\t\t},\n\t\t// CHANGE: Prompt user that they might lose data when closing tab or leaving the current page after they change some values in the checkout form\n\t\tmaybe_prevent_unload: function( e ) {\n\t\t\t// Ignore some fields\n\t\t\tif ( e && e.target.closest( '.payment_box, input#createaccount' ) ) { return; }\n\n\t\t\tif ( ! _updateBeforeUnload ) {\n\n\t\t\t\tvar preventUnload = function( e ) {\n\t\t\t\t\t// Prompt user if there is unsaved data\n\t\t\t\t\tif ( _updateBeforeUnload ) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\te.returnValue = '';\n\n\t\t\t\t\t\t// Proceed to update the checkout totals if the user cancel the event\n\t\t\t\t\t\t$( document.body ).trigger( 'update_checkout' );\n\n\t\t\t\t\t\t// Reset flag to update on `beforeunload`\n\t\t\t\t\t\t_updateBeforeUnload = false;\n\t\t\t\t\t\twindow.removeEventListener( 'beforeunload', preventUnload );\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\twindow.addEventListener( 'beforeunload', preventUnload );\n\t\t\t\t_updateBeforeUnload = true;\n\t\t\t}\n\t\t},\n\t\tinit_payment_methods: function() {\n\t\t\tvar $payment_methods = $( '.woocommerce-checkout' ).find( 'input[name=\"payment_method\"]' );\n\n\t\t\t// If there is one method, we can hide the radio input\n\t\t\tif ( 1 === $payment_methods.length ) {\n\t\t\t\t$payment_methods.eq(0).hide();\n\t\t\t}\n\n\t\t\t// If there was a previously selected method, check that one.\n\t\t\tif ( wc_checkout_form.selectedPaymentMethod ) {\n\t\t\t\t$( '#' + wc_checkout_form.selectedPaymentMethod ).prop( 'checked', true );\n\t\t\t}\n\n\t\t\t// If there are none selected, select the first.\n\t\t\tif ( 0 === $payment_methods.filter( ':checked' ).length ) {\n\t\t\t\t$payment_methods.eq(0).prop( 'checked', true );\n\t\t\t}\n\n\t\t\t// Get name of new selected method.\n\t\t\tvar checkedPaymentMethod = $payment_methods.filter( ':checked' ).eq(0).prop( 'id' );\n\n\t\t\tif ( $payment_methods.length > 1 ) {\n\t\t\t\t// Hide open descriptions.\n\t\t\t\t$( 'div.payment_box:not(\".' + checkedPaymentMethod + '\")' ).filter( ':visible' ).slideUp( 0 );\n\t\t\t}\n\n\t\t\t// Trigger click event for selected method\n\t\t\t$payment_methods.filter( ':checked' ).eq(0).trigger( 'click' );\n\t\t},\n\t\tget_payment_method: function() {\n\t\t\treturn wc_checkout_form.$checkout_form.find( 'input[name=\"payment_method\"]:checked' ).val();\n\t\t},\n\t\tpayment_method_selected: function( e ) {\n\t\t\te.stopPropagation();\n\n\t\t\tif ( $( '.payment_methods input.input-radio' ).length > 1 ) {\n\t\t\t\tvar target_payment_box = $( 'div.payment_box.' + $( this ).attr( 'ID' ) ),\n\t\t\t\t\tis_checked = $( this ).is( ':checked' );\n\n\t\t\t\tif ( is_checked && ! target_payment_box.is( ':visible' ) ) {\n\t\t\t\t\t$( 'div.payment_box' ).filter( ':visible' ).slideUp( 230 );\n\n\t\t\t\t\tif ( is_checked ) {\n\t\t\t\t\t\ttarget_payment_box.slideDown( 230 );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$( 'div.payment_box' ).show();\n\t\t\t}\n\n\t\t\tif ( $( this ).data( 'order_button_text' ) ) {\n\t\t\t\t// CHANGE: replaced the place order button css selector with an extended custom selector\n\t\t\t\t$( _settings.checkoutPlaceOrderSelector ).text( $( this ).data( 'order_button_text' ) );\n\t\t\t} else {\n\t\t\t\t// CHANGE: replaced the place order button css selector with an extended custom selector\n\t\t\t\t$( _settings.checkoutPlaceOrderSelector ).text( $( _settings.checkoutPlaceOrderSelector ).data( 'value' ) );\n\t\t\t}\n\n\t\t\tvar selectedPaymentMethod = $( '.woocommerce-checkout input[name=\"payment_method\"]:checked' ).attr( 'id' );\n\n\t\t\tif ( selectedPaymentMethod !== wc_checkout_form.selectedPaymentMethod ) {\n\t\t\t\t$( document.body ).trigger( 'payment_method_selected' );\n\t\t\t}\n\n\t\t\t// CHANGE: Add body class for selected payment method\n\t\t\tdocument.body.classList.remove( 'has-payment-method-selected--' + wc_checkout_form.selectedPaymentMethod );\n\t\t\tdocument.body.classList.add( 'has-payment-method-selected--' + selectedPaymentMethod );\n\n\t\t\twc_checkout_form.selectedPaymentMethod = selectedPaymentMethod;\n\t\t},\n\t\t// CHANGE: Add `e` parameter needed for checking target element\n\t\ttoggle_create_account: function( e ) {\n\t\t\t// CHANGE: Use collapsible block instead of jQuery to show/hide accoung fields section\n\t\t\t// Bail if not target element\n\t\t\tif ( ! e.target || ! e.target.matches( 'input#createaccount' ) ) { return; }\n\n\t\t\t// Bail if collapsible block not available\n\t\t\tif ( ! window.CollapsibleBlock ) { return; }\n\n\t\t\tvar checkbox = document.querySelector( 'input#createaccount' );\n\t\t\tvar createAccountBlock = document.querySelector( 'div.create-account' );\n\n\t\t\t// Toggle state\n\t\t\tif ( checkbox.checked ) {\n\t\t\t\tCollapsibleBlock.expand( createAccountBlock );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tCollapsibleBlock.collapse( createAccountBlock );\n\t\t\t}\n\t\t\t// CHANGE: END - Use collapsible block instead of jQuery to show/hide accoung fields section\n\t\t},\n\t\t// CHANGE: Add function to copy email field value to the login form username field\n\t\tmaybe_copy_email_to_login_form: function( e ) {\n\t\t\t// CHANGE: Use collapsible block instead of jQuery to show/hide accoung fields section\n\t\t\t// Bail if not target element\n\t\t\tif ( ! e.target || ! e.target.closest( _settings.loginButtonSelector ) ) { return; }\n\n\t\t\tvar billingEmailField = document.querySelector( _settings.emailFieldSelector );\n\t\t\tvar usernameField = document.querySelector( _settings.usernameFieldSelector );\n\t\t\t\n\t\t\t// Maybe copy email to username field\n\t\t\tif ( billingEmailField && usernameField ) {\n\t\t\t\tusernameField.value = billingEmailField.value;\n\t\t\t}\n\t\t},\n\t\t// CHANGE: END - Add function to copy email field value to the login form username field\n\t\tinit_checkout: function() {\n\t\t\t$( document.body ).trigger( 'update_checkout' );\n\t\t},\n\t\tmaybe_input_changed: function( e ) {\n\t\t\tif ( wc_checkout_form.dirtyInput ) {\n\t\t\t\twc_checkout_form.input_changed( e );\n\t\t\t}\n\t\t},\n\t\t// CHANGE: Add function to set the autocomplete attribute values form data attributes. This fixes issue with lost user data when refreshing the page while using the Firefox Browser.\n\t\tset_autocomplete_attribute_from_data: function( e ) {\n\t\t\tvar $fields = $( 'form.checkout' ).find( 'input, select, textarea' );\n\t\t\t$fields.each( function() {\n\t\t\t\tif ( $( this ).attr( 'data-autocomplete' ) ) {\n\t\t\t\t\t$( this ).attr( 'autocomplete', $( this ).attr( 'data-autocomplete' ) );\n\t\t\t\t}\n\t\t\t} );\n\t\t},\n\t\t// CHANGE: Add function to sync the terms checkbox state\n\t\tterms_checked_changed: function( e ) {\n\t\t\tvar termsCheckBoxChecked = $( e.target ).prop( 'checked' );\n\t\t\t$( _settings.checkoutTermsSelector ).prop( 'checked', termsCheckBoxChecked );\n\t\t},\n\t\t// CHANGE: Maybe add loading class to the form row\n\t\tmaybe_set_form_row_loading: function( e ) {\n\t\t\tif ( e.target && e.target.matches( _settings.checkoutLoadingInputSelector ) ) {\n\t\t\t\tvar formRow = e.target.closest( _settings.formRowSelector );\n\t\t\t\tif ( formRow ) {\n\t\t\t\t\tformRow.classList.add( _settings.loadingClass );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// CHANGE: Add function to remove loading classes from elements after updating the checkout fragments\n\t\tmaybe_stop_form_row_loading_indicators: function() {\n\t\t\tvar maybeLoadingFields = document.querySelectorAll( _settings.checkoutLoadingInputSelector );\n\t\t\tfor ( var i = 0; i < maybeLoadingFields.length; i++ ) {\n\t\t\t\tvar input = maybeLoadingFields[ i ];\n\t\t\t\tvar formRow = input.closest( _settings.formRowSelector );\n\t\t\t\tif ( formRow ) {\n\t\t\t\t\tformRow.classList.remove( _settings.loadingClass );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tinput_changed: function( e ) {\n\t\t\twc_checkout_form.dirtyInput = e.target;\n\t\t\twc_checkout_form.maybe_update_checkout();\n\t\t\t// CHANGE: Maybe add loading class to the form row\n\t\t\twc_checkout_form.maybe_set_form_row_loading( e );\n\t\t},\n\t\tqueue_update_checkout: function( e ) {\n\t\t\t// CHANGE: Add key detection to use the `event.key` property which is more reliable than `event.keyCode` or `event.which`.\n\t\t\tvar code = e.key;\n\n\t\t\t// CHANGE: Also skip `update_checkout` when pressing other controls keys such as \"Shift\", \"Control\", \"Command\", \"Alt\" and \"Arrows\"\n\t\t\tif ( FCUtils.keyboardKeys.TAB === code || FCUtils.keyboardKeys.SHIFT === code || FCUtils.keyboardKeys.CONTROL === code || FCUtils.keyboardKeys.ALT === code || FCUtils.keyboardKeys.COMMAND_OR_WINDOWS === code || FCUtils.keyboardKeys.ARROW_LEFT === code || FCUtils.keyboardKeys.ARROW_RIGHT === code || FCUtils.keyboardKeys.ARROW_UP === code || FCUtils.keyboardKeys.ARROW_DOWN === code ) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\twc_checkout_form.dirtyInput = this;\n\t\t\twc_checkout_form.reset_update_checkout_timer();\n\t\t\twc_checkout_form.updateTimer = setTimeout( wc_checkout_form.maybe_update_checkout, '1000' );\n\t\t\t// CHANGE: Maybe add loading class to the form row\n\t\t\twc_checkout_form.maybe_set_form_row_loading( e );\n\t\t},\n\t\ttrigger_update_checkout: function() {\n\t\t\twc_checkout_form.reset_update_checkout_timer();\n\t\t\twc_checkout_form.dirtyInput = false;\n\t\t\t$( document.body ).trigger( 'update_checkout' );\n\t\t},\n\t\tmaybe_update_checkout: function() {\n\t\t\tvar update_totals = true;\n\n\t\t\tif ( $( wc_checkout_form.dirtyInput ).length ) {\n\t\t\t\tvar $required_inputs = $( wc_checkout_form.dirtyInput ).closest( 'div' ).find( '.address-field.validate-required' );\n\n\t\t\t\tif ( $required_inputs.length ) {\n\t\t\t\t\t$required_inputs.each( function() {\n\t\t\t\t\t\tif ( $( this ).find( 'input.input-text' ).val() === '' ) {\n\t\t\t\t\t\t\tupdate_totals = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( update_totals ) {\n\t\t\t\twc_checkout_form.trigger_update_checkout();\n\t\t\t}\n\t\t},\n\t\t// CHANGE: Removed shipping to different address checkout `change` listener handler function\n\t\treset_update_checkout_timer: function() {\n\t\t\tclearTimeout( wc_checkout_form.updateTimer );\n\t\t},\n\t\tis_valid_json: function( raw_json ) {\n\t\t\ttry {\n\t\t\t\tvar json = JSON.parse( raw_json );\n\n\t\t\t\treturn ( json && 'object' === typeof json );\n\t\t\t} catch ( e ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tvalidate_field: function( e ) {\n\t\t\tvar $this = $( this ),\n\t\t\t\t$parent = $this.closest( '.form-row' ),\n\t\t\t\tvalidated = true,\n\t\t\t\tvalidate_required = $parent.is( '.validate-required' ),\n\t\t\t\tvalidate_email = $parent.is( '.validate-email' ),\n\t\t\t\tvalidate_phone = $parent.is( '.validate-phone' ),\n\t\t\t\tpattern = '',\n\t\t\t\tevent_type = e.type;\n\n\t\t\tif ( 'input' === event_type ) {\n\t\t\t\t$parent.removeClass( 'woocommerce-invalid woocommerce-invalid-required-field woocommerce-invalid-email woocommerce-invalid-phone woocommerce-validated' ); // eslint-disable-line max-len\n\t\t\t}\n\n\t\t\tif ( 'validate' === event_type || 'change' === event_type ) {\n\n\t\t\t\tif ( validate_required ) {\n\t\t\t\t\tif ( 'checkbox' === $this.attr( 'type' ) && ! $this.is( ':checked' ) ) {\n\t\t\t\t\t\t$parent.removeClass( 'woocommerce-validated' ).addClass( 'woocommerce-invalid woocommerce-invalid-required-field' );\n\t\t\t\t\t\tvalidated = false;\n\t\t\t\t\t} else if ( $this.val() === '' ) {\n\t\t\t\t\t\t$parent.removeClass( 'woocommerce-validated' ).addClass( 'woocommerce-invalid woocommerce-invalid-required-field' );\n\t\t\t\t\t\tvalidated = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( validate_email ) {\n\t\t\t\t\tif ( $this.val() ) {\n\t\t\t\t\t\t/* https://stackoverflow.com/questions/2855865/jquery-validate-e-mail-address-regex */\n\t\t\t\t\t\tpattern = new RegExp( /^([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]*[0-9a-z\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])\\.?$/i ); // eslint-disable-line max-len\n\n\t\t\t\t\t\tif ( ! pattern.test( $this.val() ) ) {\n\t\t\t\t\t\t\t$parent.removeClass( 'woocommerce-validated' ).addClass( 'woocommerce-invalid woocommerce-invalid-email woocommerce-invalid-phone' ); // eslint-disable-line max-len\n\t\t\t\t\t\t\tvalidated = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( validate_phone ) {\n\t\t\t\t\tpattern = new RegExp( /[\\s\\#0-9_\\-\\+\\/\\(\\)\\.]/g );\n\n\t\t\t\t\tif ( 0 < $this.val().replace( pattern, '' ).length ) {\n\t\t\t\t\t\t$parent.removeClass( 'woocommerce-validated' ).addClass( 'woocommerce-invalid woocommerce-invalid-phone' );\n\t\t\t\t\t\tvalidated = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( validated ) {\n\t\t\t\t\t$parent.removeClass( 'woocommerce-invalid woocommerce-invalid-required-field woocommerce-invalid-email woocommerce-invalid-phone' ).addClass( 'woocommerce-validated' ); // eslint-disable-line max-len\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tupdate_checkout: function( event, args ) {\n\t\t\t// Small timeout to prevent multiple requests when several fields update at the same time\n\t\t\twc_checkout_form.reset_update_checkout_timer();\n\t\t\twc_checkout_form.updateTimer = setTimeout( wc_checkout_form.update_checkout_action, '5', args );\n\t\t},\n\t\tupdate_checkout_action: function( args ) {\n\t\t\t// CHANGE: Check flag that allows or block updating the checkout\n\t\t\tif ( ! window.can_update_checkout ) { return; }\n\n\t\t\tif ( wc_checkout_form.xhr ) {\n\t\t\t\twc_checkout_form.xhr.abort();\n\t\t\t}\n\n\t\t\tvar $form = $( 'form.checkout' );\n\t\t\tif ( $form.length === 0 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\targs = typeof args !== 'undefined' ? args : {\n\t\t\t\tupdate_shipping_method: true\n\t\t\t};\n\n\t\t\tvar country\t\t\t = $( '#billing_country' ).val(),\n\t\t\t\tstate\t\t\t = $( '#billing_state' ).val(),\n\t\t\t\tpostcode\t\t = $( ':input#billing_postcode' ).val(),\n\t\t\t\tcity\t\t\t = $( '#billing_city' ).val(),\n\t\t\t\taddress\t\t\t = $( ':input#billing_address_1' ).val(),\n\t\t\t\taddress_2\t\t = $( ':input#billing_address_2' ).val(),\n\t\t\t\t// CHANGE: Always get shipping address values from shipping fields\n\t\t\t\ts_country\t\t = $( '#shipping_country' ).val(),\n\t\t\t\ts_state\t\t\t = $( '#shipping_state' ).val(),\n\t\t\t\ts_postcode\t\t = $( ':input#shipping_postcode' ).val(),\n\t\t\t\ts_city\t\t\t = $( '#shipping_city' ).val(),\n\t\t\t\ts_address\t\t = $( ':input#shipping_address_1' ).val(),\n\t\t\t\ts_address_2\t\t = $( ':input#shipping_address_2' ).val(),\n\t\t\t\t// END - CHANGE: Always get shipping address values from shipping fields\n\t\t\t\t$required_inputs = $( wc_checkout_form.$checkout_form ).find( '.address-field.validate-required:visible' ),\n\t\t\t\thas_full_address = true;\n\n\t\t\tif ( $required_inputs.length ) {\n\t\t\t\t$required_inputs.each( function() {\n\t\t\t\t\tif ( $( this ).find( ':input' ).val() === '' ) {\n\t\t\t\t\t\thas_full_address = false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// CHANGE: Removed if handling of different shipping address checkbox, always get shipping address values from shipping fields (see above)\n\n\t\t\tvar data = {\n\t\t\t\tsecurity : wc_checkout_params.update_order_review_nonce,\n\t\t\t\tpayment_method : wc_checkout_form.get_payment_method(),\n\t\t\t\tcountry : country,\n\t\t\t\tstate : state,\n\t\t\t\tpostcode : postcode,\n\t\t\t\tcity : city,\n\t\t\t\taddress : address,\n\t\t\t\taddress_2 : address_2,\n\t\t\t\ts_country : s_country,\n\t\t\t\ts_state : s_state,\n\t\t\t\ts_postcode : s_postcode,\n\t\t\t\ts_city : s_city,\n\t\t\t\ts_address : s_address,\n\t\t\t\ts_address_2 : s_address_2,\n\t\t\t\thas_full_address: has_full_address,\n\t\t\t\tpost_data : $( 'form.checkout' ).serialize()\n\t\t\t};\n\n\t\t\tif ( false !== args.update_shipping_method ) {\n\t\t\t\tvar shipping_methods = {};\n\n\t\t\t\t// eslint-disable-next-line max-len\n\t\t\t\t$( 'select.shipping_method, input[name^=\"shipping_method\"][type=\"radio\"]:checked, input[name^=\"shipping_method\"][type=\"hidden\"]' ).each( function() {\n\t\t\t\t\tshipping_methods[ $( this ).data( 'index' ) ] = $( this ).val();\n\t\t\t\t} );\n\n\t\t\t\tdata.shipping_method = shipping_methods;\n\t\t\t}\n\n\t\t\t// CHANGE: Define selector for blocking UI of sections as a variable, also block the shipping methods section when updating\n\t\t\tvar blockui_selector = _settings.checkoutBlockUISelector;\n\n\t\t\t// CHANGE: Add flag to indicate whether payment methods fragment should be refreshed\n\t\t\tif ( false === args.refresh_payment_methods ) {\n\t\t\t\tblockui_selector = blockui_selector.replace( '.woocommerce-checkout-payment, ', '' );\n\t\t\t\tdata.refresh_payment_methods = 'false';\n\t\t\t}\n\n\t\t\t// CHANGE: Use selector from settings to Block UI elements\n\t\t\t$( blockui_selector ).block({\n\t\t\t\tmessage: null,\n\t\t\t\toverlayCSS: {\n\t\t\t\t\tbackground: '#fff',\n\t\t\t\t\topacity: 0.6\n\t\t\t\t}\n\t\t\t});\n\n\t\t\twc_checkout_form.xhr = $.ajax({\n\t\t\t\ttype:\t\t'POST',\n\t\t\t\turl:\t\twc_checkout_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'update_order_review' ),\n\t\t\t\tdata:\t\tdata,\n\t\t\t\tsuccess:\tfunction( data ) {\n\n\t\t\t\t\t// Reload the page if requested\n\t\t\t\t\tif ( data && true === data.reload ) {\n\t\t\t\t\t\twindow.location.reload();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove any notices added previously\n\t\t\t\t\t$( '.woocommerce-NoticeGroup-updateOrderReview' ).remove();\n\n\t\t\t\t\t// CHANGE: replaced the terms checkbox css selector\n\t\t\t\t\tvar termsCheckBoxChecked = $( _settings.checkoutTermsSelector ).prop( 'checked' );\n\n\t\t\t\t\t// Save payment details to a temporary object\n\t\t\t\t\tvar paymentDetails = {};\n\t\t\t\t\t$( '.payment_box :input' ).each( function() {\n\t\t\t\t\t\tvar ID = $( this ).attr( 'id' );\n\n\t\t\t\t\t\tif ( ID ) {\n\t\t\t\t\t\t\tif ( $.inArray( $( this ).attr( 'type' ), [ 'checkbox', 'radio' ] ) !== -1 ) {\n\t\t\t\t\t\t\t\tpaymentDetails[ ID ] = $( this ).prop( 'checked' );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tpaymentDetails[ ID ] = $( this ).val();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\t// CHANGE: Get current element with focus, will re-set focus after updating the fragments\n\t\t\t\t\tvar currentFocusedElement = document.activeElement;\n\t\t\t\t\tvar currentValue = document.activeElement.value;\n\n\t\t\t\t\t// Maybe set current element with focus to the form row for `select2` fields\n\t\t\t\t\tvar currentFocusedFormRow = currentFocusedElement.closest( '.fc-select2-field' );\n\t\t\t\t\tif ( currentFocusedFormRow ) {\n\t\t\t\t\t\t// Remove focus from current element as it will be replaced\n\t\t\t\t\t\t// This fixes an issue where `select2` fields would not work properly\n\t\t\t\t\t\t// after checkout is updated while focus is on a `select2` field\n\t\t\t\t\t\tif ( currentFocusedElement ) { currentFocusedElement.blur(); }\n\n\t\t\t\t\t\tcurrentFocusedElement = currentFocusedFormRow;\n\t\t\t\t\t}\n\t\t\t\t\t// CHANGE: END - Get current element with focus, will re-set focus after updating the fragments\n\n\t\t\t\t\t// Always update the fragments\n\t\t\t\t\tif ( data && data.fragments ) {\n\t\t\t\t\t\t// CHANGE: Trigger custom event before fragments are replaced.\n\t\t\t\t\t\t$( document.body ).trigger( 'fc_checkout_fragments_replace_before', [ data ] );\n\n\t\t\t\t\t\t// CHANGE: Try to remove select2 components from existing fields before replacing fragments\n\t\t\t\t\t\t$( 'select.country_select, select.state_select' ).each( function() {\n\t\t\t\t\t\t\tvar field = $( this );\n\t\t\t\t\t\t\tif ( field.hasClass( 'select2-hidden-accessible' ) ) { // Field has `select2` initialized\n\t\t\t\t\t\t\t\tif ( typeof field.selectWoo === 'function' ) { field.selectWoo( 'destroy' ); }\n\t\t\t\t\t\t\t\telse if ( typeof field.select2 === 'function' ) { field.select2( 'destroy' ); }\n\t\t\t\t\t\t\t\tfield.off( 'select2:select' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t\t// CHANGE: END - Try to remove select2 components from existing fields before replacing fragments\n\n\t\t\t\t\t\t// CHANGE: Try to remove intl-tel-input components from existing fields before replacing fragments\n\t\t\t\t\t\tif ( window.intlTelInput && window.intlTelInputGlobals ) {\n\t\t\t\t\t\t\tvar allPhoneFields = document.querySelectorAll( _settings.phoneFieldSelector );\n\t\t\t\t\t\t\tfor ( var i = 0; i < allPhoneFields.length; i++ ) {\n\t\t\t\t\t\t\t\tvar field = allPhoneFields[i];\n\t\t\t\t\t\t\t\tvar phoneField = window.intlTelInputGlobals.getInstance( field );\n\t\t\t\t\t\t\t\tif ( phoneField ) {\n\t\t\t\t\t\t\t\t\tvar preservedValue = phoneField.getNumber();\n\t\t\t\t\t\t\t\t\tphoneField.destroy();\n\t\t\t\t\t\t\t\t\tfield.value = preservedValue;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// CHANGE: END - Try to remove intl-tel-input components from existing fields before replacing fragments\n\n\t\t\t\t\t\t$.each( data.fragments, function ( key, value ) {\n\t\t\t\t\t\t\t// CHANGE: Declare local variables needed for some checks before replacing the fragment\n\t\t\t\t\t\t\tvar fragmentToReplace = document.querySelector( key );\n\t\t\t\t\t\t\tvar replaceFragment = true;\n\n\t\t\t\t\t\t\t// CHANGE: Maybe set to skip fragment with the focus within it. This avoids unexpected closing of mobile keyboard and lost of focus when updating fragments.\n\t\t\t\t\t\t\tif ( fragmentToReplace && currentFocusedElement.closest( key ) && currentFocusedElement.closest( _settings.focusedFieldSkipFragmentReplaceSelector ) ) {\n\t\t\t\t\t\t\t\treplaceFragment = false;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// CHANGE: Allow fragments to be replaced every time even when their contents are equal the existing elements in the DOM, this overseeds the check for focus within the fragment.\n\t\t\t\t\t\t\tif ( value && -1 !== value.toString().indexOf( 'fc-fragment-always-replace' ) ) {\n\t\t\t\t\t\t\t\treplaceFragment = true;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( replaceFragment && ( ! wc_checkout_form.fragments || wc_checkout_form.fragments[ key ] !== value ) ) {\n\t\t\t\t\t\t\t\t// CHANGE: Log replaced fragment to console if debug mode is enabled.\n\t\t\t\t\t\t\t\tif ( fcSettings.debugMode ) {\n\t\t\t\t\t\t\t\t\tconsole.log( 'Replacing fragment: ' + key );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t$( key ).replaceWith( value );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t$( key ).unblock();\n\t\t\t\t\t\t} );\n\t\t\t\t\t\twc_checkout_form.fragments = data.fragments;\n\n\t\t\t\t\t\t// CHANGE: Trigger custom event after fragments are replaced.\n\t\t\t\t\t\t$( document.body ).trigger( 'fc_checkout_fragments_replace_after', [ data ] );\n\t\t\t\t\t}\n\n\t\t\t\t\t// CHANGE: Unblock remaining blocked fragments after updating.\n\t\t\t\t\t$( _settings.checkoutBlockUISelector ).unblock();\n\n\t\t\t\t\t// CHANGE: Re-set focus to the element with focus previously to updating fragments\n\t\t\t\t\tFCUtils.maybeRefocusElement( currentFocusedElement, currentValue );\n\n\t\t\t\t\t// Recheck the terms and conditions box, if needed\n\t\t\t\t\tif ( termsCheckBoxChecked ) {\n\t\t\t\t\t\t// CHANGE: replaced the terms checkbox css selector\n\t\t\t\t\t\t$( _settings.checkoutTermsSelector ).prop( 'checked', true );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fill in the payment details if possible without overwriting data if set.\n\t\t\t\t\tif ( ! $.isEmptyObject( paymentDetails ) ) {\n\t\t\t\t\t\t$( '.payment_box :input' ).each( function() {\n\t\t\t\t\t\t\tvar ID = $( this ).attr( 'id' );\n\t\t\t\t\t\t\tif ( ID ) {\n\t\t\t\t\t\t\t\tif ( $.inArray( $( this ).attr( 'type' ), [ 'checkbox', 'radio' ] ) !== -1 ) {\n\t\t\t\t\t\t\t\t\t$( this ).prop( 'checked', paymentDetails[ ID ] ).trigger( 'change' );\n\t\t\t\t\t\t\t\t} else if ( $.inArray( $( this ).attr( 'type' ), [ 'select' ] ) !== -1 ) {\n\t\t\t\t\t\t\t\t\t$( this ).val( paymentDetails[ ID ] ).trigger( 'change' );\n\t\t\t\t\t\t\t\t} else if ( null !== $( this ).val() && 0 === $( this ).val().length ) {\n\t\t\t\t\t\t\t\t\t$( this ).val( paymentDetails[ ID ] ).trigger( 'change' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check for error\n\t\t\t\t\tif ( data && 'failure' === data.result ) {\n\n\t\t\t\t\t\tvar $form = $( 'form.checkout' );\n\n\t\t\t\t\t\t// Remove notices from all sources\n\t\t\t\t\t\t$( '.woocommerce-error, .woocommerce-message' ).remove();\n\n\t\t\t\t\t\t// Add new errors returned by this event\n\t\t\t\t\t\tif ( data.messages ) {\n\t\t\t\t\t\t\t$form.prepend( '