1!function(){var e={117:function(e,t,n){"use strict";var o=n(1354),i=n.n(o),a=n(6314),s=n.n(a)()(i());s.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]),t.A=s},3541:function(e,t,n){"use strict";var o=n(1354),i=n.n(o),a=n(6314),s=n.n(a)()(i());s.push([e.id,"// extracted by mini-css-extract-plugin\nexport {};","",{version:3,sources:["webpack://./src/components/comments/styles/comments.css"],names:[],mappings:"AAAA;QACS,CAAA",sourcesContent:["// extracted by mini-css-extract-plugin\nexport {};"],sourceRoot:""}]),t.A=s},9051:function(e,t,n){"use strict";var o=n(1354),i=n.n(o),a=n(6314),s=n.n(a)()(i());s.push([e.id,"// extracted by mini-css-extract-plugin\nexport {};","",{version:3,sources:["webpack://./src/styles/tailwind.css"],names:[],mappings:"AAAA;QACS,CAAA",sourcesContent:["// extracted by mini-css-extract-plugin\nexport {};"],sourceRoot:""}]),t.A=s},6314:function(e){"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n="",o=void 0!==t[5];return t[4]&&(n+="@supports (".concat(t[4],") {")),t[2]&&(n+="@media ".concat(t[2]," {")),o&&(n+="@layer".concat(t[5].length>0?" ".concat(t[5]):""," {")),n+=e(t),o&&(n+="}"),t[2]&&(n+="}"),t[4]&&(n+="}"),n})).join("")},t.i=function(e,n,o,i,a){"string"==typeof e&&(e=[[null,e,void 0]]);var s={};if(o)for(var r=0;r<this.length;r++){var d=this[r][0];null!=d&&(s[d]=!0)}for(var l=0;l<e.length;l++){var c=[].concat(e[l]);o&&s[c[0]]||(void 0!==a&&(void 0===c[5]||(c[1]="@layer".concat(c[5].length>0?" ".concat(c[5]):""," {").concat(c[1],"}")),c[5]=a),n&&(c[2]?(c[1]="@media ".concat(c[2]," {").concat(c[1],"}"),c[2]=n):c[2]=n),i&&(c[4]?(c[1]="@supports (".concat(c[4],") {").concat(c[1],"}"),c[4]=i):c[4]="".concat(i)),t.push(c))}},t}},1354:function(e){"use strict";e.exports=function(e){var t=e[1],n=e[3];if(!n)return t;if("function"==typeof btoa){var o=btoa(unescape(encodeURIComponent(JSON.stringify(n)))),i="sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(o),a="/*# ".concat(i," */");return[t].concat([a]).join("\n")}return[t].join("\n")}},2551:function(e,t,n){var o=n(3633);e.exports=(o.default||o).template({1:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" <img\n class='h-12 w-12 rounded-full object-cover'\n src='"+e.escapeExpression(e.lambda(null!=(a=null!=t?s(t,"profile"):t)?s(a,"avatarImgSrc"):a,t))+"'\n alt='Profile'\n />\n"},3:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return null!=(a=s(n,"if").call(null!=t?t:e.nullContext||{},null!=(a=null!=t?s(t,"profile"):t)?s(a,"firstName"):a,{name:"if",hash:{},fn:e.program(4,i,0),inverse:e.program(7,i,0),data:i,loc:{start:{line:65,column:10},end:{line:78,column:10}}}))?a:""},4:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" <img\n class='h-12 w-12 rounded-full'\n src='https://ui-avatars.com/api/?name="+e.escapeExpression(e.lambda(null!=(a=null!=t?s(t,"profile"):t)?s(a,"firstName"):a,t))+(null!=(a=s(n,"if").call(null!=t?t:e.nullContext||{},null!=(a=null!=t?s(t,"profile"):t)?s(a,"lastName"):a,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i,loc:{start:{line:68,column:73},end:{line:68,column:125}}}))?a:"")+"&background=6366f1&color=ffffff&size=128'\n alt='Profile'\n />\n"},5:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return"+"+e.escapeExpression(e.lambda(null!=(a=null!=t?s(t,"profile"):t)?s(a,"lastName"):a,t))},7:function(e,t,n,o,i){return" <div class='h-12 w-12 rounded-full bg-gradient-to-br from-primary-500 to-primary-600 flex items-center justify-center'>\n <svg class='w-6 h-6 text-white' fill='none' stroke='currentColor' stroke-width='2' viewBox='0 0 24 24'>\n <path d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'/>
1\n <circle cx='12' cy='7' r='4'/>\n </svg>\n </div>\n "},9:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" "+e.escapeExpression(e.lambda(null!=(a=null!=t?s(t,"profile"):t)?s(a,"firstName"):a,t))+(null!=(a=s(n,"if").call(null!=t?t:e.nullContext||{},null!=(a=null!=t?s(t,"profile"):t)?s(a,"lastName"):a,{name:"if",hash:{},fn:e.program(10,i,0),inverse:e.noop,data:i,loc:{start:{line:82,column:37},end:{line:82,column:89}}}))?a:"")+"\n"},10:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" "+e.escapeExpression(e.lambda(null!=(a=null!=t?s(t,"profile"):t)?s(a,"lastName"):a,t))},12:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return null!=(a=s(n,"if").call(null!=t?t:e.nullContext||{},null!=(a=null!=t?s(t,"profile"):t)?s(a,"displayName"):a,{name:"if",hash:{},fn:e.program(13,i,0),inverse:e.program(15,i,0),data:i,loc:{start:{line:83,column:14},end:{line:87,column:14}}}))?a:""},13:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" "+e.escapeExpression(e.lambda(null!=(a=null!=t?s(t,"profile"):t)?s(a,"displayName"):a,t))+"\n"},15:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" "+e.escapeExpression(e.lambda(null!=(a=null!=t?s(t,"profile"):t)?s(a,"email"):a,t))+"\n "},17:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" <span class='ml-auto text-xs bg-gray-100 text-gray-600 px-2 py-0.5 rounded-full'>\n "+e.escapeExpression(e.lambda(null!=(a=null!=(a=null!=t?s(t,"profile"):t)?s(a,"stats"):a)?s(a,"affinityCount"):a,t))+"\n </span>\n"},19:function(e,t,n,o,i){return" <li class='border-t border-gray-200 mt-2 pt-2'>\n <a\n href='#activity'\n class='mobile-nav-item sidebar-item flex items-center px-3 py-2.5 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewB
1ox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z'\n />\n </svg>\n Activity Log\n </a>\n </li>\n"},21:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" "+e.escapeExpression(e.lambda(null!=(a=null!=t?s(t,"profile"):t)?s(a,"firstName"):a,t))+(null!=(a=s(n,"if").call(null!=t?t:e.nullContext||{},null!=(a=null!=t?s(t,"profile"):t)?s(a,"lastName"):a,{name:"if",hash:{},fn:e.program(10,i,0),inverse:e.noop,data:i,loc:{start:{line:342,column:35},end:{line:342,column:87}}}))?a:"")+"\n"},23:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return null!=(a=s(n,"if").call(null!=t?t:e.nullContext||{},null!=(a=null!=t?s(t,"profile"):t)?s(a,"displayName"):a,{name:"if",hash:{},fn:e.program(24,i,0),inverse:e.program(26,i,0),data:i,loc:{start:{line:343,column:12},end:{line:347,column:12}}}))?a:""},24:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" "+e.escapeExpression(e.lambda(null!=(a=null!=t?s(t,"profile"):t)?s(a,"displayName"):a,t))+"\n"},26:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" "+e.escapeExpression(e.lambda(null!=(a=null!=t?s(t,"profile"):t)?s(a,"email"):a,t))+"\n "},28:function(e,t,n,o,i){return" <span\n class='inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800'\n title='Verified Account'\n >\n <svg class='w-3 h-3 mr-1' fill='currentColor' viewBox='0 0 20 20'>\n <path\n fill-rule='evenodd'\n d='M6.267 3.455a3.066 3.066 0 001.745-.723 3.066 3.066 0 013.976 0 3.066 3.066 0 001.745.723 3.066 3.066 0 012.812 2.812c.051.643.304 1.254.723 1.745a3.066 3.066 0 010 3.976 3.066 3.066 0 00-.723 1.745 3.066 3.066 0 01-2.812 2.812 3.066 3.066 0 00-1.745.723 3.066 3.066 0 01-3.976 0 3.066 3.066 0 00-1.745-.723 3.066 3.066 0 01-2.812-2.812 3.066 3.066 0 00-.723-1.745 3.066 3.066 0 010-3.976 3.066 3.066 0 00.723-1.745 3.066 3.066 0 012.812-2.812zm7.44 5.252a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z'\n clip-rule='evenodd'\n />\n </svg>\n Verified\n </span>\n"},30:function(e,t,n,o,i){return" <button\n type='button'\n data-profile-completion-info>\n <span\n class='inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-700'\n title='Unverified Account'\n >\n <svg class='w-3 h-3 mr-1' fill='currentColor' viewBox='0 0 20 20'>\n <path\n fill-rule='evenodd'\n d='M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z'\n clip-rule='evenodd'\n />\n </svg>\n Not Verified\n </span>\n </button>\n"},32:function(e,t,n,o,i){return" <li class='border-t border-gray-200 mt-2 pt-2'>\n <a\n href='#activity'\n class='sidebar-item flex items-center px-4 py-3 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg mx-2 transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewB
1ox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z'\n />\n </svg>\n Activity Log\n </a>\n </li>\n"},34:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" \x3c!-- Avatar in header --\x3e\n <div class='relative flex-shrink-0 w-16 h-16 sm:w-20 sm:h-20 lg:w-24 lg:h-24'>\n"+(null!=(a=s(n,"if").call(null!=t?t:e.nullContext||{},null!=(a=null!=t?s(t,"profile"):t)?s(a,"avatarImgSrc"):a,{name:"if",hash:{},fn:e.program(35,i,0),inverse:e.program(37,i,0),data:i,loc:{start:{line:659,column:14},end:{line:680,column:21}}}))?a:"")+" \x3c!-- Edit Avatar Button on header avatar --\x3e\n <button\n type='button'\n class='absolute -bottom-1 -right-1 bg-white text-primary-600 rounded-full p-1.5 lg:p-2 hover:bg-gray-100 transition-colors shadow-md'\n id='header-avatar-edit'\n title='Change profile picture'\n >\n <svg class='w-3 h-3 lg:w-4 lg:h-4' fill='none' stroke='currentColor' viewBox='0 0 24 24'>\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z'\n >\n </path>\n </svg>\n </button>\n </div>\n"},35:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" <img\n class='h-16 w-16 sm:h-20 sm:w-20 lg:h-24 lg:w-24 rounded-full object-cover ring-4 ring-white/30 shadow-xl'\n src='"+e.escapeExpression(e.lambda(null!=(a=null!=t?s(t,"profile"):t)?s(a,"avatarImgSrc"):a,t))+"'\n alt='Profile'\n id='header-avatar'\n />\n"},37:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return null!=(a=s(n,"if").call(null!=t?t:e.nullContext||{},null!=(a=null!=t?s(t,"profile"):t)?s(a,"firstName"):a,{name:"if",hash:{},fn:e.program(38,i,0),inverse:e.program(40,i,0),data:i,loc:{start:{line:666,column:14},end:{line:680,column:14}}}))?a:""},38:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" <img\n class='h-16 w-16 sm:h-20 sm:w-20 lg:h-24 lg:w-24 rounded-full ring-4 ring-white/30 shadow-xl'\n src='https://ui-avatars.com/api/?name="+e.escapeExpression(e.lambda(null!=(a=null!=t?s(t,"profile"):t)?s(a,"firstName"):a,t))+(null!=(a=s(n,"if").call(null!=t?t:e.nullContext||{},null!=(a=null!=t?s(t,"profile"):t)?s(a,"lastName"):a,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i,loc:{start:{line:669,column:77},end:{line:669,column:129}}}))?a:"")+"&background=ffffff&color=6366f1&size=256'\n alt='Profile'\n id='header-avatar'\n />\n"},40:function(e,t,n,o,i){return" <div class='h-16 w-16 sm:h-20 sm:w-20 lg:h-24 lg:w-24 rounded-full ring-4 ring-white/30 shadow-xl bg-white flex items-center justify-center' id='header-avatar'>\n <svg class='w-8 h-8 sm:w-10 sm:h-10 lg:w-12 lg:h-12 text-primary-600' fill='none' stroke='currentColor' stroke-width='2' viewBox='0 0 24 24'>\n <path d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'/>\n <circle cx='12' cy='7' r='4'/>\n </svg>\n </div>\n "},42:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};
vendor: 2,113 bytes, line 1
1return",\n <span id='header-profile-name'>\n "+e.escapeExpression(e.lambda(null!=(a=null!=t?s(t,"profile"):t)?s(a,"firstName"):a,t))+"\n </span>"},44:function(e,t,n,o,i){return"3"},46:function(e,t,n,o,i){return"4"},48:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" "+e.escapeExpression(e.lambda(null!=(a=null!=(a=null!=t?s(t,"profile"):t)?s(a,"stats"):a)?s(a,"activeSubscriptions"):a,t))+"\n"},50:function(e,t,n,o,i){return" 0\n"},52:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" "+e.escapeExpression(e.lambda(null!=(a=null!=(a=null!=t?s(t,"profile"):t)?s(a,"stats"):a)?s(a,"paymentMethodsCount"):a,t))+"\n"},54:function(e,t,n,o,i){return" col-span-2 lg:col-span-1"},56:function(e,t,n,o,i){var a,s=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return" \x3c!-- Member Since --\x3e\n <div\n class='bg-white/20 backdrop-blur rounded-lg p-3 lg:p-4 cursor-pointer hover:bg-white/30 transition-all quick-stat-card'\n data-target-section='profile'\n >\n <div class='flex items-center justify-between'>\n <div>\n <p class='text-primary-100 text-xs lg:text-sm'>\n Member Since\n </p>\n <p class='text-xl lg:text-2xl font-bold' data-stat='memberYear'>\n "+e.escapeExpression("function"==typeof(a=null!=(a=s(n,"memberYear")||(null!=t?s(t,"memberYear"):t))?a:e.hooks.helperMissing)?a.call(null!=t?t:e.nullContext||{},{name:"memberYear",hash:{},data:i,loc:{start:{line:826,column:20},end:{line:826,column:34}}}):a)+"\n </p>\n </div>\n <svg\n class='w-6 h-6 lg:w-8 lg:h-8 text-primary-200'\n fill='none'\n stroke='currentColor'\n viewB
1ox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z'\n />\n </svg>\n </div>\n </div>\n"},compiler:[8,">= 4.3.0"],main:function(e,t,n,o,i){var a,s=null!=t?t:e.nullContext||{},r=e.lambda,d=e.escapeExpression,l=e.lookupProperty||function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]};return"\x3c!-- src/components/profile/templates/profile.hbs --\x3e\n\x3c!-- Main Dashboard Container --\x3e\n<div class='max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 lg:py-8'>\n \x3c!-- Mobile Header --\x3e\n <div class='lg:hidden mb-4'>\n <div class='flex items-center justify-between'>\n <h1 class='text-2xl font-bold text-gray-900'>My Profile</h1>\n <button\n id='mobile-menu-toggle'\n class='p-2 rounded-lg bg-gray-100 hover:bg-gray-200 transition-colors'\n aria-label='Toggle menu'\n >\n <svg class='w-6 h-6' fill='none' stroke='currentColor' viewBox='0 0 24 24'>\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M4 6h16M4 12h16M4 18h16'\n />\n </svg>\n </button>\n </div>\n </div>\n\n \x3c!-- Mobile Menu Overlay --\x3e\n <div\n id='mobile-menu-overlay'\n class='fixed inset-0 z-40 bg-black bg-opacity-50 hidden lg:hidden'\n ></div>\n\n \x3c!-- Mobile Sidebar --\x3e\n <aside\n id='mobile-sidebar'\n class='fixed inset-y-0 left-0 z-50 w-full bg-white transform -translate-x-full transition-transform duration-300 ease-in-out lg:hidden'\n >\n <div class='h-full overflow-y-auto'>\n \x3c!-- Mobile Menu Header --\x3e\n <div class='flex items-center justify-between p-4 border-b border-gray-200'>\n <h2 class='text-lg font-semibold text-gray-900'>Menu</h2>\n <button\n id='mobile-menu-close'\n class='p-2 rounded-lg hover:bg-gray-100 transition-colors'\n aria-label='Close menu'\n >\n <svg class='w-5 h-5' fill='none' stroke='currentColor' viewBox='0 0 24 24'>\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M6 18L18 6M6 6l12 12'\n />\n </svg>\n </button>\n </div>\n\n \x3c!-- Mobile Profile Summary --\x3e\n <div class='p-4 border-b border-gray-200'>\n <div class='flex items-center gap-3 mb-3'>\n"+(null!=(a=l(n,"if").call(s,null!=(a=null!=t?l(t,"profile"):t)?l(a,"avatarImgSrc"):a,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(3,i,0),data:i,loc:{start:{line:59,column:10},end:{line:78,column:17}}}))?a:"")+" <div>\n <p class='font-semibold text-gray-900'>\n"+(null!=(a=l(n,"if").call(s,null!=(a=null!=t?l(t,"profile"):t)?l(a,"firstName"):a,{name:"if",hash:{},fn:e.program(9,i,0),inverse:e.program(12,i,0),data:i,loc:{start:{line:81,column:14},end:{line:87,column:21}}}))?a:"")+" </p>\n <p class='text-sm text-gray-600'>"+d(r(null!=(a=null!=t?l(t,"profile"):t)?l(a,"email"):a,t))+"</p>\n </div>\n </div>\n\n \x3c!-- Profile Completion Mobile --\x3e\n <div class='space-y-1'>\n <div class='flex items-center justify-between'>\n <span class='text-xs text-gray-600'>Profile Completion</span>\n <span class='text-xs font-semibold text-primary-600'>75%</span>\n </div>\n <div class='w-full bg-gray-200 rounded-full h-1.5'>\n <div\n class='bg-primary-600 h-1.5 rounded-full transition-all duration-500'\n style='width: 75%'\n ></div>\n </div>\n </div>\n </div>\n\n \x3c!-- Mobile Navigation --\x3e\n <nav class='p-2'>\n <ul class='space-y-1'>\n <li>\n <a\n href='#profile'\n class='mobile-nav-item sidebar-item active flex items-center px-3 py-2.5 text-sm font-medium text-gray-900 hover:bg-gray-50 rounded-lg transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewB
1ox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z'\n />\n </svg>\n Profile Information\n </a>\n </li>\n <li>\n <a\n href='#addresses'\n class='mobile-nav-item sidebar-item flex items-center px-3 py-2.5 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewBox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z'\n />\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M15 11a3 3 0 11-6 0 3 3 0 016 0z'\n />\n </svg>\n Addresses\n </a>\n </li>\n <li>\n <a\n href='#payment'\n class='mobile-nav-item sidebar-item flex items-center px-3 py-2.5 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewB
1ox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z'\n />\n </svg>\n Payment Methods\n </a>\n </li>\n <li>\n <a\n href='#subscriptions'\n class='mobile-nav-item sidebar-item flex items-center px-3 py-2.5 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewBox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z'\n />\n </svg>\n Subscriptions\n </a>\n </li>\n <li>\n <a\n href='#invoices'\n class='mobile-nav-item sidebar-item flex items-center px-3 py-2.5 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewB
1ox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z'\n />\n </svg>\n Invoices\n </a>\n </li>\n <li>\n <a\n href='#affinity'\n class='mobile-nav-item sidebar-item flex items-center px-3 py-2.5 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewBox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z'\n />\n </svg>\n Liked & Followed\n"+(null!=(a=l(n,"if").call(s,null!=(a=null!=(a=null!=t?l(t,"profile"):t)?l(a,"stats"):a)?l(a,"affinityCount"):a,{name:"if",hash:{},fn:e.program(17,i,0),inverse:e.noop,data:i,loc:{start:{line:241,column:14},end:{line:245,column:21}}}))?a:"")+" </a>\n </li>\n <li>\n <a\n href='#newsletters'\n class='mobile-nav-item sidebar-item flex items-center px-3 py-2.5 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewB
1ox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z'\n />\n </svg>\n Email Preferences\n </a>\n </li>\n <li>\n <a\n href='#security'\n class='mobile-nav-item sidebar-item flex items-center px-3 py-2.5 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewBox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z'\n />\n </svg>\n Security\n </a>\n </li>\n"+(null!=(a=l(n,"unless").call(s,null!=(a=null!=t?l(t,"profile"):t)?l(a,"hideActivity"):a,{name:"unless",hash:{},fn:e.program(19,i,0),inverse:e.noop,data:i,loc:{start:{line:290,column:10},end:{line:312,column:21}}}))?a:"")+" <li class='border-t border-gray-200 mt-2 pt-2'>\n <button\n data-logout-trigger\n class='w-full flex items-center px-3 py-2.5 text-sm font-medium text-red-600 hover:bg-red-50 rounded-lg transition-colors'\n >\n <svg class='w-5 h-5 mr-3' fill='none' stroke='currentColor' viewBox='0 0 24 24'>\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1'\n />\n </svg>\n Logout\n </button>\n </li>\n </ul>\n </nav>\n </div>\n </aside>\n\n <div class='lg:flex lg:gap-8'>\n \x3c!-- Desktop Sidebar --\x3e\n <aside class='desktop-sidebar w-64 flex-shrink-0'>\n \x3c!-- Profile Summary Card --\x3e\n <div class='bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-6'>\n <h2 class='text-lg font-semibold text-gray-900 mb-2'>\n <span id='sidebar-profile-name'>\n"+(null!=(a=l(n,"if").call(s,null!=(a=null!=t?l(t,"profile"):t)?l(a,"firstName"):a,{name:"if",hash:{},fn:e.program(21,i,0),inverse:e.program(23,i,0),data:i,loc:{start:{line:341,column:12},end:{line:347,column:19}}}))?a:"")+" </span>\n </h2>\n <div class='flex items-center gap-2'>\n"+(null!=(a=l(n,"if").call(s,null!=(a=null!=t?l(t,"profile"):t)?l(a,"isVerified"):a,{name:"if",hash:{},fn:e.program(28,i,0),inverse:e.program(30,i,0),data:i,loc:{start:{line:351,column:10},end:{line:383,column:17}}}))?a:"")+" </div>\n\n \x3c!-- Profile Completion --\x3e\n <div class='mt-6'>\n <div class='flex items-center justify-between mb-2'>\n <span class='text-sm text-gray-600 flex items-center'>\n Profile Completion\n <button\n type='button'\n data-profile-completion-info\n class='ml-1.5 text-gray-400 hover:text-gray-600 transition-colors'\n title='View completion details'\n >\n <svg class='w-4 h-4' fill='none' stroke='currentColor' viewBox='0 0 24 24'>\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z'\n />\n </svg>\n </button>\n </span>\n <span class='text-sm font-semibold text-primary-600' id='profile-completion'>\n 75%\n </span>\n </div>\n <div class='w-full bg-gray-200 rounded-full h-2'>\n <div\n class='bg-primary-600 h-2 rounded-full transition-all duration-500'\n id='profile-completion-bar'\n style='width: 75%'\n ></div>\n </div>\n <p class='text-xs text-gray-500 mt-2'>\n Complete your profile to unlock all features\n </p>\n </div>\n </div>\n\n \x3c!-- Desktop Navigation Menu --\x3e\n <nav class='bg-white rounded-lg shadow-sm border border-gray-200'>\n <ul class='py-2'>\n <li>\n <a\n href='#profile'\n class='sidebar-item active flex items-center px-4 py-3 text-sm font-medium text-gray-900 hover:bg-gray-50 rounded-lg mx-2 transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewB
1ox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z'\n />\n </svg>\n Profile Information\n </a>\n </li>\n <li>\n <a\n href='#addresses'\n class='sidebar-item flex items-center px-4 py-3 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg mx-2 transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewBox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z'\n />\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M15 11a3 3 0 11-6 0 3 3 0 016 0z'\n />\n </svg>\n Addresses\n </a>\n </li>\n <li>\n <a\n href='#payment'\n class='sidebar-item flex items-center px-4 py-3 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg mx-2 transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewB
1ox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z'\n />\n </svg>\n Payment Methods\n </a>\n </li>\n <li>\n <a\n href='#subscriptions'\n class='sidebar-item flex items-center px-4 py-3 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg mx-2 transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewBox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z'\n />\n </svg>\n Subscriptions\n </a>\n </li>\n <li>\n <a\n href='#invoices'\n class='sidebar-item flex items-center px-4 py-3 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg mx-2 transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewB
1ox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z'\n />\n </svg>\n Invoices\n </a>\n </li>\n <li>\n <a\n href='#affinity'\n class='sidebar-item flex items-center px-4 py-3 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg mx-2 transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewBox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z'\n />\n </svg>\n Liked & Followed\n"+(null!=(a=l(n,"if").call(s,null!=(a=null!=(a=null!=t?l(t,"profile"):t)?l(a,"stats"):a)?l(a,"affinityCount"):a,{name:"if",hash:{},fn:e.program(17,i,0),inverse:e.noop,data:i,loc:{start:{line:557,column:14},end:{line:561,column:21}}}))?a:"")+" </a>\n </li>\n <li>\n <a\n href='#newsletters'\n class='sidebar-item flex items-center px-4 py-3 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg mx-2 transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewB
1ox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z'\n />\n </svg>\n Email Preferences\n </a>\n </li>\n <li>\n <a\n href='#security'\n class='sidebar-item flex items-center px-4 py-3 text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg mx-2 transition-colors'\n >\n <svg\n class='w-5 h-5 mr-3 text-gray-400'\n fill='none'\n stroke='currentColor'\n viewBox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z'\n />\n </svg>\n Security\n </a>\n </li>\n\n"+(null!=(a=l(n,"unless").call(s,null!=(a=null!=t?l(t,"profile"):t)?l(a,"hideActivity"):a,{name:"unless",hash:{},fn:e.program(32,i,0),inverse:e.noop,data:i,loc:{start:{line:607,column:10},end:{line:629,column:21}}}))?a:"")+" </ul>\n </nav>\n </aside>\n\n \x3c!-- Main Content Area --\x3e\n <main class='flex-1 min-w-0'>\n \x3c!-- Welcome Section --\x3e\n <div\n class='bg-gradient-to-r from-primary-500 to-secondary-600 rounded-lg p-4 sm:p-6 lg:p-8 mb-6 lg:mb-8 text-white relative overflow-hidden'\n >\n <button\n data-logout-trigger\n class='flex absolute top-4 right-4 lg:top-8 lg:right-8 items-center px-3 py-1.5 lg:px-4 lg:py-2 bg-white/20 backdrop-blur text-white rounded-lg hover:bg-white/30 transition-colors text-sm lg:text-base'\n >\n <svg class='w-4 h-4 mr-1.5 lg:mr-2' fill='none' stroke='currentColor' viewBox='0 0 24 24'>\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1'\n />\n </svg>\n Logout\n </button>\n\n <div class='flex flex-col sm:flex-row sm:items-center gap-4 sm:gap-6'>\n"+(null!=(a=l(n,"unless").call(s,null!=(a=null!=t?l(t,"profile"):t)?l(a,"hideAvatar"):a,{name:"unless",hash:{},fn:e.program(34,i,0),inverse:e.noop,data:i,loc:{start:{line:656,column:10},end:{line:699,column:21}}}))?a:"")+"\n <div class='flex-1'>\n <h1 class='text-xl sm:text-2xl lg:text-3xl font-bold mb-1 lg:mb-2'>\n Welcome back"+(null!=(a=l(n,"if").call(s,null!=(a=null!=t?l(t,"profile"):t)?l(a,"firstName"):a,{name:"if",hash:{},fn:e.program(42,i,0),inverse:e.noop,data:i,loc:{start:{line:703,column:26},end:{line:706,column:28}}}))?a:"")+"!\n </h1>\n <p class='text-sm sm:text-base text-primary-100'>\n Manage your account settings and preferences\n </p>\n </div>\n </div>\n\n \x3c!-- Quick Stats - Responsive Grid --\x3e\n <div class='grid grid-cols-2 lg:grid-cols-"+(null!=(a=l(n,"if").call(s,null!=(a=null!=t?l(t,"profile"):t)?l(a,"hideMemberSince"):a,{name:"if",hash:{},fn:e.program(44,i,0),inverse:e.program(46,i,0),data:i,loc:{start:{line:715,column:50},end:{line:715,column:98}}}))?a:"")+" gap-3 lg:gap-4 mt-6 lg:mt-8'>\n \x3c!-- Active Subscriptions --\x3e\n <div\n class='bg-white/20 backdrop-blur rounded-lg p-3 lg:p-4 cursor-pointer hover:bg-white/30 transition-all quick-stat-card'\n data-target-section='subscriptions'\n >\n <div class='flex items-center justify-between'>\n <div>\n <p class='text-primary-100 text-xs lg:text-sm'>\n Active Plans\n </p>\n <p class='text-xl lg:text-2xl font-bold' data-stat='activeSubscriptions'>\n"+(null!=(a=l(n,"if").call(s,null!=(a=null!=(a=null!=t?l(t,"profile"):t)?l(a,"stats"):a)?l(a,"activeSubscriptions"):a,{name:"if",hash:{},fn:e.program(48,i,0),inverse:e.program(50,i,0),data:i,loc:{start:{line:727,column:18},end:{line:731,column:25}}}))?a:"")+" </p>\n </div>\n <svg\n class='w-6 h-6 lg:w-8 lg:h-8 text-primary-200'\n fill='none'\n stroke='currentColor'\n viewB
1ox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z'\n />\n </svg>\n </div>\n </div>\n\n \x3c!-- Payment Methods --\x3e\n <div\n class='bg-white/20 backdrop-blur rounded-lg p-3 lg:p-4 cursor-pointer hover:bg-white/30 transition-all quick-stat-card'\n data-target-section='payment'\n >\n <div class='flex items-center justify-between'>\n <div>\n <p class='text-primary-100 text-xs lg:text-sm'>\n Payment Cards\n </p>\n <p class='text-xl lg:text-2xl font-bold' data-stat='paymentMethods'>\n"+(null!=(a=l(n,"if").call(s,null!=(a=null!=(a=null!=t?l(t,"profile"):t)?l(a,"stats"):a)?l(a,"paymentMethodsCount"):a,{name:"if",hash:{},fn:e.program(52,i,0),inverse:e.program(50,i,0),data:i,loc:{start:{line:761,column:18},end:{line:765,column:25}}}))?a:"")+" </p>\n </div>\n <svg\n class='w-6 h-6 lg:w-8 lg:h-8 text-primary-200'\n fill='none'\n stroke='currentColor'\n viewB
1ox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z'\n />\n </svg>\n </div>\n </div>\n\n \x3c!-- Saved Addresses --\x3e\n <div\n class='bg-white/20 backdrop-blur rounded-lg p-3 lg:p-4 cursor-pointer hover:bg-white/30 transition-all quick-stat-card"+(null!=(a=l(n,"if").call(s,null!=(a=null!=t?l(t,"profile"):t)?l(a,"hideMemberSince"):a,{name:"if",hash:{},fn:e.program(54,i,0),inverse:e.noop,data:i,loc:{start:{line:786,column:130},end:{line:786,column:193}}}))?a:"")+"'\n data-target-section='addresses'\n >\n <div class='flex items-center justify-between'>\n <div>\n <p class='text-primary-100 text-xs lg:text-sm'>\n Addresses\n </p>\n <p class='text-xl lg:text-2xl font-bold' data-stat='savedAddresses'>\n "+d(r(null!=(a=null!=(a=null!=t?l(t,"profile"):t)?l(a,"stats"):a)?l(a,"addressCount"):a,t))+"\n </p>\n </div>\n <svg\n class='w-6 h-6 lg:w-8 lg:h-8 text-primary-200'\n fill='none'\n stroke='currentColor'\n viewB
1ox='0 0 24 24'\n >\n <path\n stroke-linecap='round'\n stroke-linejoin='round'\n stroke-width='2'\n d='M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6'\n />\n </svg>\n </div>\n </div>\n\n"+(null!=(a=l(n,"unless").call(s,null!=(a=null!=t?l(t,"profile"):t)?l(a,"hideMemberSince"):a,{name:"unless",hash:{},fn:e.program(56,i,0),inverse:e.noop,data:i,loc:{start:{line:814,column:10},end:{line:844,column:21}}}))?a:"")+" </div>\n </div>\n\n \x3c!-- Content Sections --\x3e\n <div class='space-y-6 lg:space-y-8'>\n \x3c!-- All Profile Sections Pre-rendered --\x3e\n <div id='profile-sections'>\n \x3c!-- Profile Information Section --\x3e\n <section\n id='profile-section'\n class='hg-section'\n data-section='profile'\n >\n \x3c!-- Profile content will be rendered here by ProfileInfo component --\x3e\n </section>\n\n \x3c!-- Addresses Section --\x3e\n <section\n id='addresses-section'\n class='hg-section hidden'\n data-section='addresses'\n >\n <div class='hg-section-loading p-8 lg:p-12 text-center'>\n <div\n class='animate-spin h-8 w-8 border-4 border-primary-600 border-t-transparent rounded-full mx-auto mb-4'\n >\n </div>\n <p class='text-gray-600'>\n Loading addresses...\n </p>\n </div>\n </section>\n\n \x3c!-- Payment Methods Section --\x3e\n <section\n id='payment-section'\n class='hg-section hidden'\n data-section='payment'\n >\n <div class='hg-section-loading p-8 lg:p-12 text-center'>\n <div\n class='animate-spin h-8 w-8 border-4 border-primary-600 border-t-transparent rounded-full mx-auto mb-4'\n >\n </div>\n <p class='text-gray-600'>\n Loading payment methods...\n </p>\n </div>\n </section>\n\n \x3c!-- Subscriptions Section --\x3e\n <section\n id='subscriptions-section'\n class='hg-section hidden'\n data-section='subscriptions'\n >\n <div class='hg-section-loading p-8 lg:p-12 text-center'>\n <div\n class='animate-spin h-8 w-8 border-4 border-primary-600 border-t-transparent rounded-full mx-auto mb-4'\n >\n </div>\n <p class='text-gray-600'>\n Loading subscriptions...\n </p>\n </div>\n </section>\n\n \x3c!-- Invoices Section --\x3e\n <section\n id='invoices-section'\n class='hg-section hidden'\n data-section='invoices'\n >\n <div class='hg-section-loading p-8 lg:p-12 text-center'>\n <div\n class='animate-spin h-8 w-8 border-4 border-primary-600 border-t-transparent rounded-full mx-auto mb-4'\n >\n </div>\n <p class='text-gray-600'>\n Loading invoices...\n </p>\n </div>\n </section>\n\n \x3c!-- Activity Section --\x3e\n <section\n id='activity-section'\n class='hg-section hidden'\n data-section='activity'\n >\n <div class='hg-section-loading p-8 lg:p-12 text-center'>\n <div\n class='animate-spin h-8 w-8 border-4 border-primary-600 border-t-transparent rounded-full mx-auto mb-4'\n >\n </div>\n <p class='text-gray-600'>\n Loading activity...\n </p>\n </div>\n </section>\n\n \x3c!-- Affinity Section --\x3e\n <section\n id='affinity-section'\n class='hg-section hidden'\n data-section='affinity'\n >\n <div class='hg-section-loading p-8 lg:p-12 text-center'>\n <div\n class='animate-spin h-8 w-8 border-4 border-primary-600 border-t-transparent roun
1ded-full mx-auto mb-4'\n >\n </div>\n <p class='text-gray-600'>\n Loading affinity items...\n </p>\n </div>\n </section>\n\n \x3c!-- Other sections with placeholder content --\x3e\n <section\n id='security-section'\n class='hg-section hidden'\n data-section='security'\n >\n <div class='hg-section-loading p-8 lg:p-12 text-center'>\n <div\n class='animate-spin h-8 w-8 border-4 border-primary-600 border-t-transparent rounded-full mx-auto mb-4'\n >\n </div>\n <p class='text-gray-600'>\n Loading security settings...\n </p>\n </div>\n </section>\n\n <section\n id='newsletters-section'\n class='hg-section hidden'\n data-section='newsletters'\n >\n \x3c!-- Newsletter preferences placeholder --\x3e\n </section>\n\n <section\n id='rewards-section'\n class='hg-section hidden'\n data-section='rewards'\n >\n \x3c!-- Rewards placeholder --\x3e\n </section>\n </div>\n </div>\n </main>\n </div>\n</div>\n\n\x3c!-- Placeholder for modals --\x3e\n<div id='profile-modal'></div>\n\n\x3c!-- Responsive styles for sidebar --\x3e\n<style>\n /* Hide desktop sidebar on mobile */\n .desktop-sidebar {\n display: none;\n }\n\n /* Show desktop sidebar on large screens */\n @media (min-width: 1024px) {\n .desktop-sidebar {\n display: block;\n }\n }\n\n /* Minimum height for content sections to prevent jumping */\n .hg-section {\n min-height: 400px;\n position: relative;\n }\n\n /* Larger min-height on desktop */\n @media (min-width: 1024px) {\n .hg-section {\n min-height: 500px;\n }\n }\n\n /* Loading state centered in min-height container */\n .hg-section-loading {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 100%;\n }\n\n /* Smooth transitions for section visibility */\n .hg-section {\n transition: opacity 0.2s ease-in-out;\n }\n\n /* Ensure content containers maintain layout during loading */\n .hg-section > div:not(.hg-section-loading) {\n min-height: inherit;\n }\n\n /* Special handling for profile section which shows by default */\n #profile-section {\n min-height: 400px;\n }\n\n @media (min-width: 1024px) {\n #profile-section {\n min-height: 500px;\n }\n }\n\n /* Ensure mobile sidebar stays hidden on desktop */\n @media (min-width: 1024px) {\n #mobile-sidebar {\n display: none !important;\n }\n #mobile-menu-overlay {\n display: none !important;\n }\n }\n</style>"},useData:!0})},261:function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}function i(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}t.__esModule=!0;var a=i(n(2871)),s=o(n(9613)),r=o(n(3769)),d=i(n(2849)),l=i(n(7624)),c=o(n(1148));function u(){var e=new a.HandlebarsEnvironment;return d.extend(e,a),e.SafeString=s.default,e.Exception=r.default,e.Utils=d,e.escapeExpression=d.escapeExpression,e.VM=l,e.template=function(t){return l.template(t,e)},e}var m=u();m.create=u,c.default(m),m.default=m,t.default=m,e.exports=t.default},2871:function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0,t.HandlebarsEnvironment=u;var i=n(2849),a=o(n(3769)),s=n(2277),r=n(3559),d=o(n(566)),l=n(3865);t.VERSION="4.7.8";t.COMPILER_REVISION=8;t.LAST_COMPATIBLE_COMPILER_REVISION=7;t.REVISION_CHANGES={1:"<= 1.0.rc.2",2:"== 1.0.0-rc.3",3:"== 1.0.0-rc.4",4:"== 1.x.x",5:"== 2.0.0-alpha.x",6:">= 2.0.0-beta.1",7:">= 4.0.0 <4.3.0",8:">= 4.3.0"};var c="[object Object]";function u(e,t,n){this.helpers=e||{},this.partials=t||{},this.decorators=n||{},s.registerDefaultHelpers(this),r.registerDefaultDecorators(this)}u.prototype={constructor:u,logger:d.default,log:d.default.log,registerHelper:function(e,t){if(i.toString.call(e)===c){if(t)throw new a.default("Arg not supported with multiple helpers");i.extend(this.helpers,e)}else this.helpers[e]=t},unregisterHelper:function(e){delete this.helpers[e]},registerPartial:function(e,t){if(i.toString.call(e)===c)i.extend(this.partials,e);else{if(void 0===t)throw new a.default('Attempting to register a partial called "'+e+'" as undefined');this.partials[e]=t}},unregisterPartial:function(e){delete this.partials[e]},registerDecorator:function(e,t){if(i.toString.call(e)===c){if(t)throw new a.default("Arg not supported with multiple decorators");i.extend(this.decorators,e)}else this.decorators[e]=t},unregisterDecorator:function(e){delete this.decorators[e]},resetLoggedPropertyAccesses:function(){l.resetLoggedProperties()}};var m=d.default.log;t.log=m,t.createFrame=i.createFrame,t.logger=d.default},3559:function(e,t,n){"use strict";t.__esModule=!0,t.registerDefaultDecorators=function(e){a.default(e)};var o,i=n(7430),a=(o=i)&&o.__esModule?o:{default:o}},7430:function(e,t,n){"use strict";t.__esModule=!0;var o=n(2849);t.default=function(e){e.registerDecorator("inline",(function(e,t,n,i){var a=e;return t.partials||(t.partials={},a=function(i,a){var s=n.partials;n.partials=o.extend({},s,t.partials);var r=e(i,a);return n.partials=s,r}),t.partials[i.args[0]]=i.fn,a}))},e.exports=t.default},3769:function(e,t){"use strict";t.__esModule=!0;var n=["description","fileName","lineNumber","endLineNumber","message","name","number","stack"];function o(e,t){var i=t&&t.loc,a=void 0,s=void 0,r=void 0,d=void 0;i&&(a=i.start.line,s=i.end.line,r=i.start.column,d=i.end.column,e
vendor: 9,742 bytes, line 1
1+=" - "+a+":"+r);for(var l=Error.prototype.constructor.call(this,e),c=0;c<n.length;c++)this[n[c]]=l[n[c]];Error.captureStackTrace&&Error.captureStackTrace(this,o);try{i&&(this.lineNumber=a,this.endLineNumber=s,Object.defineProperty?(Object.defineProperty(this,"column",{value:r,enumerable:!0}),Object.defineProperty(this,"endColumn",{value:d,enumerable:!0})):(this.column=r,this.endColumn=d))}catch(e){}}o.prototype=new Error,t.default=o,e.exports=t.default},2277:function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0,t.registerDefaultHelpers=function(e){i.default(e),a.default(e),s.default(e),r.default(e),d.default(e),l.default(e),c.default(e)},t.moveHelperToHooks=function(e,t,n){e.helpers[t]&&(e.hooks[t]=e.helpers[t],n||delete e.helpers[t])};var i=o(n(6097)),a=o(n(6785)),s=o(n(4353)),r=o(n(2355)),d=o(n(5300)),l=o(n(7466)),c=o(n(908))},6097:function(e,t,n){"use strict";t.__esModule=!0;var o=n(2849);t.default=function(e){e.registerHelper("blockHelperMissing",(function(t,n){var i=n.inverse,a=n.fn;if(!0===t)return a(this);if(!1===t||null==t)return i(this);if(o.isArray(t))return t.length>0?(n.ids&&(n.ids=[n.name]),e.helpers.each(t,n)):i(this);if(n.data&&n.ids){var s=o.createFrame(n.data);s.contextPath=o.appendContextPath(n.data.contextPath,n.name),n={data:s}}return a(t,n)}))},e.exports=t.default},6785:function(e,t,n){"use strict";t.__esModule=!0;var o,i=n(2849),a=n(3769),s=(o=a)&&o.__esModule?o:{default:o};t.default=function(e){e.registerHelper("each",(function(e,t){if(!t)throw new s.default("Must pass iterator to #each");var n,o=t.fn,a=t.inverse,r=0,d="",l=void 0,c=void 0;function u(t,n,a){l&&(l.key=t,l.index=n,l.first=0===n,l.last=!!a,c&&(l.contextPath=c+t)),d+=o(e[t],{data:l,blockParams:i.blockParams([e[t],t],[c+t,null])})}if(t.data&&t.ids&&(c=i.appendContextPath(t.data.contextPath,t.ids[0])+"."),i.isFunction(e)&&(e=e.call(this)),t.data&&(l=i.createFrame(t.data)),e&&"object"==typeof e)if(i.isArray(e))for(var m=e.length;r<m;r++)r in e&&u(r,r,r===e.length-1);else if("function"==typeof Symbol&&e[Symbol.iterator]){for(var g=[],h=e[Symbol.iterator](),p=h.next();!p.done;p=h.next())g.push(p.value);for(m=(e=g).length;r<m;r++)u(r,r,r===e.length-1)}else n=void 0,Object.keys(e).forEach((function(e){void 0!==n&&u(n,r-1),n=e,r++})),void 0!==n&&u(n,r-1,!0);return 0===r&&(d=a(this)),d}))},e.exports=t.default},4353:function(e,t,n){"use strict";t.__esModule=!0;var o,i=n(3769),a=(o=i)&&o.__esModule?o:{default:o};t.default=function(e){e.registerHelper("helperMissing",(function(){if(1!==arguments.length)throw new a.default('Missing helper: "'+arguments[arguments.length-1].name+'"')}))},e.exports=t.default},2355:function(e,t,n){"use strict";t.__esModule=!0;var o,i=n(2849),a=n(3769),s=(o=a)&&o.__esModule?o:{default:o};t.default=function(e){e.registerHelper("if",(function(e,t){if(2!=arguments.length)throw new s.default("#if requires exactly one argument");return i.isFunction(e)&&(e=e.call(this)),!t.hash.includeZero&&!e||i.isEmpty(e)?t.inverse(this):t.fn(this)})),e.registerHelper("unless",(function(t,n){if(2!=arguments.length)throw new s.default("#unless requires exactly one argument");return e.helpers.if.call(this,t,{fn:n.inverse,inverse:n.fn,hash:n.hash})}))},e.exports=t.default},5300:function(e,t){"use strict";t.__esModule=!0,t.default=function(e){e.registerHelper("log",(function(){for(var t=[void 0],n=arguments[arguments.length-1],o=0;o<arguments.length-1;o++)t.push(arguments[o]);var i=1;null!=n.hash.level?i=n.hash.level:n.data&&null!=n.data.level&&(i=n.data.level),t[0]=i,e.log.apply(e,t)}))},e.exports=t.default},7466:function(e,t){"use strict";t.__esModule=!0,t.default=function(e){e.registerHelper("lookup",(function(e,t,n){return e?n.lookupProperty(e,t):e}))},e.exports=t.default},908:function(e,t,n){"use strict";t.__esModule=!0;var o,i=n(2849),a=n(3769),s=(o=a)&&o.__esModule?o:{default:o};t.default=function(e){e.registerHelper("with",(function(e,t){if(2!=arguments.length)throw new s.default("#with requires exactly one argument");i.isFunction(e)&&(e=e.call(this));var n=t.fn;if(i.isEmpty(e))return t.inverse(this);var o=t.data;return t.data&&t.ids&&((o=i.createFrame(t.data)).contextPath=i.appendContextPath(t.data.contextPath,t.ids[0])),n(e,{data:o,blockParams:i.blockParams([e],[o&&o.contextPath])})}))},e.exports=t.default},9726:function(e,t,n){"use strict";t.__esModule=!0,t.createNewLookupObject=function(){for(var e=arguments.length,t=Array(e),n=0;n<e;n++)t[n]=arguments[n];return o.extend.apply(void 0,[Object.create(null)].concat(t))};var o=n(2849)},3865:function(e,t,n){"use strict";t.__esModule=!0,t.createProtoAccessControl=function(e){var t=Object.create(null);t.constructor=!1,t.__defineGetter__=!1,t.__defineSetter__=!1,t.__lookupGetter__=!1;var n=Object.create(null);return n.__proto__=!1,{properties:{whitelist:i.createNewLookupObject(n,e.allowedProtoProperties),defaultValue:e.allowProtoPropertiesByDefault},methods:{whitelist:i.createNewLookupObject(t,e.allowedProtoMethods),defaultValue:e.allowProtoMethodsByDefault}}},t.resultIsAllowed=function(e,t,n){return d("function"==typeof e?t.methods:t.properties,n)},t.resetLoggedProperties=function(){Object.keys(r).forEach((function(e){delete r[e]}))};var o,i=n(9726),a=n(566),s=(o=a)&&o.__esModule?o:{default:o},r=Object.create(null);function d(e,t){return void 0!==e.whitelist[t]?!0===e.whitelist[t]:void 0!==e.defaultValue?e.defaultValue:(function(e){!0!==r[e]&&(r[e]=!0,s.default.log("error",'Handlebars: Access has been denied to resolve the property "'+e+'" because it is not an "own property" of its parent.\nYou can add a runtime option to disable the check or this warning:\nSee https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details'))}(t),!1)}},2614:function(e,t){"use strict";t.__esModule=!0,t.wrapHelper=function(e,t){if("function"!=typeof e)return e;return function(){return arguments[arguments.length-1]=t(arguments[arguments.length-1]),e.apply(this,arguments)}}},566:function(e,t,n){"use strict";t.__esModule=!0;var o=n(2849),i={methodMap:["debug","info","warn","error"],level:"info",lookupLevel:function(e){if("string"==typeof e){var t=o.indexOf(i.methodMap,e.toLowerCase());e=t>=0?t:parseInt(e,10)}return e},log:function(e){if(e=i.lookupLevel(e),"undefined"!=typeof console&&i.lookupLevel(i.level)<=e){var t=i.methodMap[e];console[t]||(t="log");for(var n=arguments.length,o=Array(n>1?n-1:0),a=1;a<n;a++)o[a-1]=arguments[a];console[t].apply(console,o)}}};t.default=i,e.exports=t.default},1148:function(e,t){"use strict";t.__esModule=!0,t.default=function(e){"object"!=typeof globalThis&&(Object.prototype.__defineGetter__("__magic__",(function(){return this})),__magic__.globalThis=__magic__,delete Object.prototype.__magic__);var t=globalThis.Handlebars;e.noConflict=function(){return globalThis.Handlebars===e&&(globalThis.Handlebars=t),e}},e.exports=t.default},7624:function(e,t,n){"use strict";t.__esModule=!0,t.checkRevision=function(e){var t=e&&e[0]||1,n=r.COMPILER_REVISION;if(t>=r.LAST_COMPATIBLE_COMPILER_REVISION&&t<=r.COMPILER_REVISION)return;if(t<r.LAST_COMPATIBLE_COMPILER_REVISION){var o=r.REVISION_CHANGES[n],i=r.REVISION_CHANGES[t];throw new s.default("Template was precompiled with an older version of Handlebars than the current runtime. Please update your precompiler to a newer version ("+o+") or downgrade your runtime to an older version ("+i+").")}throw new s.default("Template was precompiled with a newer version of Handlebars than the current runtime. Please update your runtime to a newer version ("+e[1]+").")},t.template=function(e,t){if(!t)throw new s.default("No environment passed to template");if(!e||!e.main)throw new s.default("Unknown template object: "+typeof e);e.main.decorator=e.main_d,t.VM.checkRevision(e.compiler);var n=e.compiler&&7===e.compiler[0];var o={strict:function(e,t,n){if(!e||!(t in e))throw new s.default('"'+t+'" not defined in '+e,{loc:n});return o.lookupProperty(e,t)},lookupProperty:function(e,t){var n=e[t];return null==n||Object.prototype.hasOwnProperty.call(e,t)||c.resultIsAllowed(n,o.protoAccessControl,t)?n:void 0},lookup:function(e,t){for(var n=e.length,i=0;i<n;i++){if(null!=(e[i]&&o.lookupProperty(e[i],t)))return e[i][t]}},lambda:function(e,t){return"function"==typeof e?e.call(t):e},escapeExpression:i.escapeExpression,invokePartial:function(n,o,a){a.hash&&(o=i.extend({},o,a.hash),a.ids&&(a.ids[0]=!0)),n=t.VM.resolvePartial.call(this,n,o,a);var r=i.extend({},a,{hooks:this.hooks,protoAccessControl:this.protoAccessControl}),d=t.VM.invokePartial.call(this,n,o,r);if(null==d&&t.compile&&(a.partials[a.name]=t.compile(n,e.compilerOptions,t),d=a.partials[a.name](o,r)),null!=d){if(a.indent){for(var l=d.split("\n"),c=0,u=l.length;c<u&&(l[c]||c+1!==u);c++)l[c]=a.indent+l[c];d=l.join("\n")}return d}throw new s.default("The partial "+a.name+" could not be compiled when running in runtime-only mode")},fn:function(t){var n=e[t];return n.decorator=e[t+"_d"],n},programs:[],program:function(e,t,n,o,i){var a=this.programs[e],s=this.fn(e);return t||i||o||n?a=u(this,e,s,t,n,o,i):a||(a=this.programs[e]=u(this,e,s)),a},data:function(e,t){for(;e&&t--;)e=e._parent;return e},mergeIfNeeded:function(e,t){var n=e||t;return e&&t&&e!==t&&(n=i.extend({},t,e)),n},nullContext:Object.seal({}),noop:t.VM.noop,compilerInfo:e.compiler};function a(t){var n=arguments.length<=1||void 0===arguments[1]?{}:arguments[1],i=n.data;a._setup(n),!n.partial&&e.useData&&(i=function(e,t){t&&"root"in t||((t=t?r.createFrame(t):{}).root=e);return t}(t,i));var s=void 0,d=e.useBlockParams?[]:void 0;function l(t){return""+e.main(o,t,o.helpers,o.partials,i,d,s)}return e.useDepths&&(s=n.depths?t!=n.depths[0]?[t].concat(n.depths):n.depths:[t]),(l=g(e.main,l,o,n.depths||[],i,d))(t,n)}
1return a.isTop=!0,a._setup=function(a){if(a.partial)o.protoAccessControl=a.protoAccessControl,o.helpers=a.helpers,o.partials=a.partials,o.decorators=a.decorators,o.hooks=a.hooks;else{var s=i.extend({},t.helpers,a.helpers);!function(e,t){Object.keys(e).forEach((function(n){var o=e[n];e[n]=function(e,t){var n=t.lookupProperty;return l.wrapHelper(e,(function(e){return i.extend({lookupProperty:n},e)}))}(o,t)}))}(s,o),o.helpers=s,e.usePartial&&(o.partials=o.mergeIfNeeded(a.partials,t.partials)),(e.usePartial||e.useDecorators)&&(o.decorators=i.extend({},t.decorators,a.decorators)),o.hooks={},o.protoAccessControl=c.createProtoAccessControl(a);var r=a.allowCallsToHelperMissing||n;d.moveHelperToHooks(o,"helperMissing",r),d.moveHelperToHooks(o,"blockHelperMissing",r)}},a._child=function(t,n,i,a){if(e.useBlockParams&&!i)throw new s.default("must pass block params");if(e.useDepths&&!a)throw new s.default("must pass parent depths");return u(o,t,e[t],n,0,i,a)},a},t.wrapProgram=u,t.resolvePartial=function(e,t,n){e?e.call||n.name||(n.name=e,e=n.partials[e]):e="@partial-block"===n.name?n.data["partial-block"]:n.partials[n.name];return e},t.invokePartial=function(e,t,n){var o=n.data&&n.data["partial-block"];n.partial=!0,n.ids&&(n.data.contextPath=n.ids[0]||n.data.contextPath);var a=void 0;n.fn&&n.fn!==m&&function(){n.data=r.createFrame(n.data);var e=n.fn;a=n.data["partial-block"]=function(t){var n=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];return n.data=r.createFrame(n.data),n.data["partial-block"]=o,e(t,n)},e.partials&&(n.partials=i.extend({},n.partials,e.partials))}();void 0===e&&a&&(e=a);if(void 0===e)throw new s.default("The partial "+n.name+" could not be found");if(e instanceof Function)return e(t,n)},t.noop=m;var o,i=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}(n(2849)),a=n(3769),s=(o=a)&&o.__esModule?o:{default:o},r=n(2871),d=n(2277),l=n(2614),c=n(3865);function u(e,t,n,o,i,a,s){function r(t){var i=arguments.length<=1||void 0===arguments[1]?{}:arguments[1],r=s;return!s||t==s[0]||t===e.nullContext&&null===s[0]||(r=[t].concat(s)),n(e,t,e.helpers,e.partials,i.data||o,a&&[i.blockParams].concat(a),r)}return(r=g(n,r,e,s,o,a)).program=t,r.depth=s?s.length:0,r.blockParams=i||0,r}function m(){return""}
1function g(e,t,n,o,a,s){if(e.decorator){var r={};t=e.decorator(t,r,n,o&&o[0],a,s,o),i.extend(t,r)}return t}},9613:function(e,t){"use strict";function n(e){this.string=e}t.__esModule=!0,n.prototype.toString=n.prototype.toHTML=function(){return""+this.string},t.default=n,e.exports=t.default},2849:function(e,t){"use strict";t.__esModule=!0,t.extend=s,t.indexOf=function(e,t){for(var n=0,o=e.length;n<o;n++)if(e[n]===t)return n;return-1},t.escapeExpression=function(e){if("string"!=typeof e){if(e&&e.toHTML)return e.toHTML();if(null==e)return"";if(!e)return e+"";e=""+e}if(!i.test(e))return e;return e.replace(o,a)},t.isEmpty=function(e){return!e&&0!==e||!(!l(e)||0!==e.length)},t.createFrame=function(e){var t=s({},e);return t._parent=e,t},t.blockParams=function(e,t){return e.path=t,e},t.appendContextPath=function(e,t){return(e?e+".":"")+t};var n={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`","=":"="},o=/[&<>"'`=]/g,i=/[&<>"'`=]/;function a(e){return n[e]}function s(e){for(var t=1;t<arguments.length;t++)for(var n in arguments[t])Object.prototype.hasOwnProperty.call(arguments[t],n)&&(e[n]=arguments[t][n]);return e}var r=Object.prototype.toString;t.toString=r;var d=function(e){return"function"==typeof e};d(/x/)&&(t.isFunction=d=function(e){return"function"==typeof e&&"[object Function]"===r.call(e)}),t.isFunction=d;var l=Array.isArray||function(e){return!(!e||"object"!=typeof e)&&"[object Array]"===r.call(e)};t.isArray=l},3633:function(e,t,n){e.exports=n(261).default},5606:function(e){var t,n,o=e.exports={};function i(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function s(e){if(t===setTimeout)return setTimeout(e,0);if((t===i||!t)&&setTimeout)return t=setTimeout,setTimeout(e,0);try{return t(e,0)}catch(n){try{return t.call(null,e,0)}catch(n){return t.call(this,e,0)}}}!function(){try{t="function"==typeof setTimeout?setTimeout:i}catch(e){t=i}try{n="function"==typeof clearTimeout?clearTimeout:a}catch(e){n=a}}();var r,d=[],l=!1,c=-1;function u(){l&&r&&(l=!1,r.length?d=r.concat(d):c=-1,d.length&&m())}function m(){if(!l){var e=s(u);l=!0;for(var t=d.length;t;){for(r=d,d=[];++c<t;)r&&r[c].run();c=-1,t=d.length}r=null,l=!1,function(e){if(n===clearTimeout)return clearTimeout(e);if((n===a||!n)&&clearTimeout)return n=clearTimeout,clearTimeout(e);try{return n(e)}catch(t){try{return n.call(null,e)}catch(t){return n.call(this,e)}}}(e)}}function g(e,t){this.fun=e,this.array=t}function h(){}o.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];d.push(new g(e,t)),1!==d.length||l||s(m)},g.prototype.run=function(){this.fun.apply(null,this.array)},o.title="browser",o.browser=!0,o.env={},o.argv=[],o.version="",o.versions={},o.on=h,o.addListener=h,o.once=h,o.off=h,o.removeListener=h,o.removeAllListeners=h,o.emit=h,o.prependListener=h,o.prependOnceListener=h,o.listeners=function(e){return[]},o.binding=function(e){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(e){throw new Error("process.chdir is not supported")},o.umask=function(){return 0}},5072:function(e){"use strict";var t=[];function n(e){for(var n=-1,o=0;o<t.length;o++)if(t[o].identifier===e){n=o;break}return n}function o(e,o){for(var a={},s=[],r=0;r<e.length;r++){var d=e[r],l=o.base?d[0]+o.base:d[0],c=a[l]||0,u="".concat(l," ").concat(c);a[l]=c+1;var m=n(u),g={css:d[1],media:d[2],sourceMap:d[3],supports:d[4],layer:d[5]};if(-1!==m)t[m].references++,t[m].updater(g);else{var h=i(g,o);o.byIndex=r,t.splice(r,0,{identifier:u,updater:h,references:1})}s.push(u)}return s}function i(e,t){var n=t.domAPI(t);n.update(e);return function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap&&t.supports===e.supports&&t.layer===e.layer)return;n.update(e=t)}else n.remove()}}e.exports=function(e,i){var a=o(e=e||[],i=i||{});return function(e){e=e||[];for(var s=0;s<a.length;s++){var r=n(a[s]);t[r].references--}for(var d=o(e,i),l=0;l<a.length;l++){var c=n(a[l]);0===t[c].references&&(t[c].updater(),t.splice(c,1))}a=d}}},7659:function(e){"use strict";var t={};e.exports=function(e,n){var o=function(e){if(void 0===t[e]){var n=document.querySelector(e);
1if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}t[e]=n}return t[e]}(e);if(!o)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");o.appendChild(n)}},540:function(e){"use strict";e.exports=function(e){var t=document.createElement("style");return e.setAttributes(t,e.attributes),e.insert(t,e.options),t}},5056:function(e,t,n){"use strict";e.exports=function(e){var t=n.nc;t&&e.setAttribute("nonce",t)}},7825:function(e){"use strict";e.exports=function(e){if("undefined"==typeof document)return{update:function(){},remove:function(){}};var t=e.insertStyleElement(e);return{update:function(n){!function(e,t,n){var o="";n.supports&&(o+="@supports (".concat(n.supports,") {")),n.media&&(o+="@media ".concat(n.media," {"));var i=void 0!==n.layer;i&&(o+="@layer".concat(n.layer.length>0?" ".concat(n.layer):""," {")),o+=n.css,i&&(o+="}"),n.media&&(o+="}"),n.supports&&(o+="}");var a=n.sourceMap;a&&"undefined"!=typeof btoa&&(o+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a))))," */")),t.styleTagTransform(o,e,t.options)}(t,e,n)},remove:function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(t)}}}},1113:function(e){"use strict";e.exports=function(e,t){if(t.styleSheet)t.styleSheet.cssText=e;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(e))}}},8200:function(e,t,n){"use strict";n.d(t,{fl:function(){return d}});var o=n(2910),i=n(7450),a=n(8520),s=n(1916);class r{constructor(){this.heimguardConfig=null,this.templateData=null,this.recurlyPublicKey=null,this.profileUIConfig=null,this.passwordlessLoginLinkExpirationHours=null,this.isLoaded=!1}async load(){if(this.isLoaded)return{success:!0};try{const e=await a.initService.getInitData();return this.setConfig(e),this.isLoaded=!0,{success:!0}}catch(e){const t={url:o.A.apiHeimguardSettingsUrl,timestamp:(new Date).toISOString(),errorType:"unknown"};return e instanceof Error&&("AbortError"===e.name?(e.message="Request timeout - server took too long to respond",t.errorType="timeout"):e.message.includes("fetch")&&(t.errorType="network")),i.Ak.logError("AuthConfig.load",e,t),s.vF.warn("Failed to load config, using fallback:","auth",e instanceof Error?e.message:"Unknown error"),this.loadDemoConfig(),this.isLoaded=!0,{success:!1,error:e,usedFallback:!0}}}setConfig(e){s.vF.debug("Setting config with initData:","auth",e);const t=e.generalConfig||{},n=e.authConfig||{};this.heimguardConfig={login:e.login||{...r.DEFAULT_COMPONENT_CONFIG,url:"/login"},register:e.register||{...r.DEFAULT_COMPONENT_CONFIG,url:"/register"},profile:e.profile||{...r.DEFAULT_COMPONENT_CONFIG,url:"/profile",useModal:!1},forgotPassword:e.forgotPassword||{...r.DEFAULT_COMPONENT_CONFIG,url:"/forgot-password"},terms:t.terms||e.terms||"",privacyPolicy:t.privacyPolicy||e.privacyPolicy||"",companyName:t.companyName||e.companyName,companyImgSrc:t.companyImgSrc||e.companyImgSrc,companySupportEmail:t.companySupportEmail,recurlyPublicKey:n.recurlyPublicKey||e.recurlyPublicKey||e.recurly_public_key,isFacebookLoginSetup:n.isFacebookLoginSetup,isGoogleLoginSetup:n.isGoogleLoginSetup,isMagicLinkSetup:n.isMagicLinkSetup,registerLinkText:e.registerLinkText,...e},this.templateData={companyName:t.companyName||e.companyName||e.templateData?.companyName||r.DEFAULT_TEMPLATE_DATA.companyName,companyImgSrc:t.companyImgSrc||e.companyImgSrc||e.templateData?.companyImgSrc||r.DEFAULT_TEMPLATE_DATA.companyImgSrc},s.vF.debug("Template data set to:","auth",this.templateData),this.recurlyPublicKey=n.recurlyPublicKey||e.recurlyPublicKey||e.recurly_public_key||null,this.passwordlessLoginLinkExpirationHours=n.passwordlessLoginLinkExpirationHours||e.passwordlessLoginLinkExpirationHours||null,this.profileUIConfig=e.profileUIConfig||{allowSubscriptionCancellation:!1,showSubscriptionFilters:!0,enableSmsOptInField:!1,smsOptInAgreementMessage:void 0,defaultCountry:"US",excludedCountries:[]},s.vF.debug("Profile UI Config:","auth",this.profileUIConfig)}
1loadDemoConfig(){this.heimguardConfig={login:{url:"/login",useModal:!0},register:{url:"/register",useModal:!0},profile:{url:"/profile",useModal:!1},forgotPassword:{url:"/forgot-password",useModal:!0},terms:"",privacyPolicy:"",...o.A.demoData?.heimguardConfig||{}},this.templateData={companyName:o.A.demoData?.companyName||r.DEFAULT_TEMPLATE_DATA.companyName,companyImgSrc:o.A.demoData?.companyImgSrc||r.DEFAULT_TEMPLATE_DATA.companyImgSrc},this.recurlyPublicKey="demo-recurly-public-key",s.vF.debug("Demo config loaded","auth")}getRecurlyPublicKey(){return this.recurlyPublicKey}getProfileUIConfig(){return this.profileUIConfig||{allowSubscriptionCancellation:!1,showSubscriptionFilters:!0,enableSmsOptInField:!1,smsOptInAgreementMessage:void 0,defaultCountry:"US",excludedCountries:[]}}getPasswordlessLoginLinkExpirationHours(){return this.passwordlessLoginLinkExpirationHours||"24"}getComponentConfig(e){if(!this.heimguardConfig)return null;const t=this.heimguardConfig[e];return["login","register","profile","forgotPassword"].includes(e)?t:null}shouldUseModal(e){const t=this.getComponentConfig(e);return!1!==t?.useModal}getRedirectUrl(e){const t=this.getComponentConfig(e);return t?.url||`/${e}`}setDisplayMode(e,t){if(!this.heimguardConfig)return;const n=this.heimguardConfig[e];n&&"object"==typeof n&&"useModal"in n&&(n.useModal=t,s.vF.debug(`Display mode changed: ${e} useModal = ${t}`,"auth"))}getTemplateData(){return{...this.templateData||r.DEFAULT_TEMPLATE_DATA}}getConfig(){return{heimguardConfig:this.heimguardConfig?{...this.heimguardConfig}:null,templateData:this.getTemplateData()}}hasTermsOrPrivacy(){const e=!!this.heimguardConfig?.terms?.trim(),t=!!this.heimguardConfig?.privacyPolicy?.trim();return{hasTerms:e,hasPrivacy:t,hasAny:e||t}}isConfigLoaded(){return this.isLoaded}reset(){this.heimguardConfig=null,this.templateData=null,this.recurlyPublicKey=null,this.isLoaded=!1}}r.DEFAULT_COMPONENT_CONFIG={url:"",useModal:!0},r.DEFAULT_TEMPLATE_DATA={companyName:"Your Company",companyImgSrc:""};const d=new r},7140:function(e,t,n){"use strict";n.d(t,{KM:function(){return i},QU:function(){return o},sQ:function(){return a}});const o={LOGIN_START:"auth:login:start",LOGIN_SUCCESS:"auth:login:success",LOGIN_ERROR:"auth:login:error",LOGIN_CANCELLED:"auth:login:cancelled",LOGOUT_START:"auth:logout:start",LOGOUT_SUCCESS:"auth:logout:success",LOGOUT_ERROR:"auth:logout:error",REGISTER_START:"auth:register:start",REGISTER_SUCCESS:"auth:register:success",REGISTER_ERROR:"auth:register:error",REGISTER_CANCELLED:"auth:register:cancelled",SESSION_CHECK:"auth:session:check",SESSION_VALID:"auth:session:valid",SESSION_INVALID:"auth:session:invalid",SESSION_EXPIRED:"auth:session:expired",SESSION_REFRESHED:"auth:session:refreshed",SESSION_REFRESH_ERROR:"auth:session:refresh-error",TWO_FACTOR_REQUIRED:"auth:2fa:required",TWO_FACTOR_START:"auth:2fa:start",TWO_FACTOR_SUCCESS:"auth:2fa:success",TWO_FACTOR_ERROR:"auth:2fa:error",TWO_FACTOR_CANCELLED:"auth:2fa:cancelled",PASSWORD_RESET_REQUEST:"auth:password:reset-request",PASSWORD_RESET_SENT:"auth:password:reset-sent",PASSWORD_RESET_ERROR:"auth:password:reset-error",PASSWORD_CHANGE_START:"auth:password:change-start",PASSWORD_CHANGE_SUCCESS:"auth:password:change-success",PASSWORD_CHANGE_ERROR:"auth:password:change-error",EMAIL_VERIFY_REQUEST:"auth:email:verify-request",EMAIL_VERIFY_SUCCESS:"auth:email:verify-success",EMAIL_VERIFY_ERROR:"auth:email:verify-error",EMAIL_RESEND_REQUEST:"auth:email:resend-request",EMAIL_RESEND_SUCCESS:"auth:email:resend-success",EMAIL_RESEND_ERROR:"auth:email:resend-error",MAGIC_LINK_SENT:"auth:magic:sent",MAGIC_LINK_VERIFIED:"auth:magic:verified",MAGIC_LINK_EXPIRED:"auth:magic:expired",SOCIAL_LOGIN_START:"auth:social:login-start",SOCIAL_LOGIN_SUCCESS:"auth:social:login-success",SOCIAL_LOGIN_ERROR:"auth:social:login-error",SOCIAL_LINK_START:"auth:social:link-start",SOCIAL_LINK_SUCCESS:"auth:social:link-success",SOCIAL_LINK_ERROR:"auth:social:link-error",SOCIAL_UNLINK_START:"auth:social:unlink-start",SOCIAL_UNLINK_SUCCESS:"auth:social:unlink-success",SOCIAL_UNLINK_ERROR:"auth:social:unlink-error",UI_SHOW_LOGIN:"auth:ui:show-login",UI_SHOW_REGISTER:"auth:ui:show-register",UI_SHOW_FORGOT_PASSWORD:"auth:ui:show-forgot-password",UI_SHOW_RESET_PASSWORD:"auth:ui:show-reset-password",UI_SHOW_TWO_FACTOR:"auth:ui:show-2fa",UI_SHOW_MAGIC_LINK:"auth:ui:show-magic-link",UI_LOGOUT:"auth:ui:logout",UI_HIDE_ALL:"auth:ui:hide-all",UI_SWITCH_MODE:"auth:ui:switch-mode",STATE_CHANGED:"auth:state:changed",USER_UPDATED:"auth:user:updated",USER_VERIFIED:"auth:user:verified",PROVIDER_CHANGED:"auth:provider:changed",ERROR_NETWORK:"auth:error:network",ERROR_VALIDATION:"auth:error:validation",ERROR_UNAUTHORIZED:"auth:error:unauthorized",ERROR_FORBIDDEN:"auth:error:forbidden",ERROR_SERVER:"auth:error:server",ERROR_UNKNOWN:"auth:error:unknown",SHOW_LOGIN:"auth:show:login",SHOW_REGISTER:"auth:show:register",SHOW_FORGOT_PASSWORD:"auth:show:forgot-password",HIDE:"auth:hide"};function i(e,t={}){const n={timestamp:Date.now(),eventName:e,...t},o=new CustomEvent(e,{detail:n,bubbles:!0});window.dispatchEvent(o),"undefined"!=typeof window&&window.eventBus&&window.eventBus.emit(e,n)}function a(e,t){const n=e=>{t(e.detail)};window.addEventListener(e,n);let o=null;return"undefined"!=typeof window&&window.eventBus&&(o=window.eventBus.on(e,t)),()=>{window.removeEventListener(e,n),o&&o()}}t.Ay=o},2554:function(e,t,n){"use strict";n.d(t,{A:function(){return l}});var o=n(2972),i=n(2910),a=n(7140);class s{static getCurrentEnvironment(){const e=window.location.hostname,t=window.location.port;return t?`${e}:${t}`:e}static areCookiesFromCurrentEnvironment(){const e=localStorage.getItem(this.ENV_KEY),t=this.getCurrentEnvironment();return e?e===t:(localStorage.setItem(this.ENV_KEY,t),!0)}static clearCookiesIfEnvironmentChanged(){const e=this.getCurrentEnvironment(),t=localStorage.getItem(this.ENV_KEY);t&&t!==e&&(console.log(`[EnvironmentCookieHelper] Environment changed from ${t} to ${e}`),console.log("[EnvironmentCookieHelper] Clearing auth cookies..."),this.clearAllAuthCookies(),localStorage.setItem(this.ENV_KEY,e),sessionStorage.removeItem("heimguard_auth_state"),sessionStorage.removeItem("heimguard_user_data"))}static clearAllAuthCookies(){["heimguard.authStatus","heimguard.user","heimguard.token","heimguard.session","heimguard.remember","heimguard.provider"].forEach((e=>{document.cookie=`${e}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`,document.cookie=`${e}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${window.location.hostname};`;const t=window.location.hostname.split(".");if(t.length>2){const n=t.slice(-2).join(".");document.cookie=`${e}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.${n};`}document.cookie=`${e}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.${window.location.hostname};`})),console.log("[EnvironmentCookieHelper] Cleared all auth cookies")}static initialize(){this.clearCookiesIfEnvironmentChanged(),window.addEventListener("focus",(()=>{this.clearCookiesIfEnvironmentChanged()}))}}s.COOKIE_PREFIX="heimguard",s.ENV_KEY="heimguard_env","undefined"!=typeof window&&s.initialize();var r=n(1916);class d{static get CONFIG(){return{cookies:{AUTH_STATUS:"heimguard.authStatus",USER_DATA:"heimguard.user",AUTH_TOKEN:"heimguard.token",SESSION:"heimguard.session"},selectors:{NAV_ITEM:".Navigation-items-item",NAV_TEXT:".NavigationItem-text span",LOGOUT:'[data-logout-trigger], [data-nav-role="logout"]',LOGIN:'[data-nav-role="login"]',REGIST
1ER:'[data-nav-role="register"]',PROFILE:'[data-nav-role="profile"]'},navMapping:{Login:"data-login-trigger",Logout:"data-logout-trigger",Profile:"data-profile-trigger",Register:"data-register-trigger",Dashboard:"data-dashboard-trigger",Settings:"data-settings-trigger"}}}static async init(){if(this.state.initialized)return r.vF.warn("auth","AuthStateManager already initialized"),this.getState();try{return r.vF.info("auth","Initializing AuthStateManager..."),await this.loadAuthState(),this.updateUI(),this.setupEventListeners(),this.state.initialized=!0,(0,a.KM)(a.QU.SESSION_VALID,{...this.getState(),source:"AuthStateManager"}),"undefined"!=typeof window&&(window.HeimGuard=window.HeimGuard||{},window.HeimGuard.AuthStateManager=d),r.vF.info("auth","AuthStateManager initialized:",{isAuthenticated:this.state.isAuthenticated,user:this.state.user?.email,provider:this.state.provider}),this.getState()}catch(e){return r.vF.error("auth","Failed to initialize AuthStateManager:",e),this.clearState(),this.state.initialized=!0,this.getState()}}static async loadAuthState(){if(!s.areCookiesFromCurrentEnvironment())return r.vF.warn("auth","Cookies from different environment detected, clearing auth state"),s.clearAllAuthCookies(),void this.clearState();const e=o.c.getCookie(this.CONFIG.cookies.AUTH_STATUS);if(e)try{const t=this.decodeAuthCookie(e);t?(this.state.isAuthenticated=!0,this.state.user=t.user||t,this.state.provider=t.provider||t.loginMethod||"basic",i.A.validateSessionOnInit?await this.validateSession():this.state.sessionValidated=!0):this.clearState()}catch(e){r.vF.error("auth","Error loading auth state:",e),this.clearState()}else this.clearState()}static async validateSession(){try{const e=await fetch(i.A.apiValidateSessionUrl,{method:"GET",credentials:"include",headers:{Accept:"application/json"}});if(!e.ok)throw new Error("Session validation failed");const t=await e.json();t.valid?(t.user&&(this.state.user={...this.state.user,...t.user}),this.state.sessionValidated=!0,r.vF.info("auth","Session validated successfully")):(r.vF.warn("auth","Session invalid, clearing auth state"),this.clearState(),(0,a.KM)(a.QU.SESSION_INVALID,{reason:"Server validation failed",source:"AuthStateManager"}))}catch(e){r.vF.error("auth","Session validation error:",e),this.state.sessionValidated=!1}}static decodeAuthCookie(e){try{const t=atob(e);return JSON.parse(t)}catch(e){return r.vF.error("auth","Failed to decode auth cookie:",e),null}}static updateAuthState(e){const t=this.getState();this.state.isAuthenticated=!0,this.state.user=e.user,this.state.provider=e.provider||"basic",this.state.sessionValidated=!0,this.updateUI(),(0,a.KM)(a.QU.STATE_CHANGED,{oldState:t,newState:this.getState(),action:"login",source:"AuthStateManager"}),r.vF.info("auth","Auth state updated:",{user:this.state.user?.email,provider:this.state.provider}),"undefined"!=typeof window&&setTimeout((()=>{window.dispatchEvent(new CustomEvent("heimguard:navigation:refresh")),window.dispatchEvent(new CustomEvent("heimguard:login",{detail:{user:this.state.user,provider:this.state.provider},bubbles:!0}))}),100)}static clearAuthState(){const e=this.getState();this.clearState(),this.updateUI(),(0,a.KM)(a.QU.STATE_CHANGED,{oldState:e,newState:this.getState(),action:"logout",source:"AuthStateManager"}),r.vF.info("auth","Auth state cleared"),"undefined"!=typeof window&&setTimeout((()=>{window.dispatchEvent(new CustomEvent("heimguard:navigation:refresh")),window.dispatchEvent(new CustomEvent("heimguard:logout",{detail:{reason:"logout"},bubbles:!0}))}),100)}static clearState(){this.state.isAuthenticated=!1,this.state.user=null,this.state.provider=null,this.state.sessionValidated=!1,this.state.error=null,this.state.sessionExpiry=null,this.state.requiresTwoFactor=!1,this.state.tempToken=null,this.state.rememberMe=!1}static getState(){return{isAuthenticated:this.state.isAuthenticated,user:this.state.user?{...this.state.user}:null,provider:this.state.provider,isLoading:this.state.isLoading,error:this.state.error,sessionExpiry:this.state.sessionExpiry,requiresTwoFactor:this.state.requiresTwoFactor,tempToken:this.state.tempToken,rememberMe:this.state.rememberMe}}static updateUI(){this.updateNavAttributes(),this.updateNavVisibility(),this.updateBodyClasses()}static updateNavAttributes(){document.querySelectorAll(this.CONFIG.selectors.NAV_ITEM
1).forEach((e=>{const t=e.querySelector(this.CONFIG.selectors.NAV_TEXT);if(!t)return;const n=t.textContent?.trim()||"",o=this.CONFIG.navMapping[n];o&&(e.hasAttribute(o)||e.setAttribute(o,""),e.hasAttribute("data-nav-item")||e.setAttribute("data-nav-item",n.toLowerCase()))}))}static updateNavVisibility(){const e={logout:document.querySelectorAll(this.CONFIG.selectors.LOGOUT),login:document.querySelectorAll(this.CONFIG.selectors.LOGIN),register:document.querySelectorAll(this.CONFIG.selectors.REGISTER),profile:document.querySelectorAll(this.CONFIG.selectors.PROFILE)};this.state.isAuthenticated?(this.toggleElements(e.logout,!0),this.toggleElements(e.profile,!0),this.toggleElements(e.login,!1),this.toggleElements(e.register,!1)):(this.toggleElements(e.logout,!1),this.toggleElements(e.profile,!1),this.toggleElements(e.login,!0),this.toggleElements(e.register,!0))}static updateBodyClasses(){document.body.classList.remove("user-authenticated","user-guest","user-role-admin","user-role-user","user-role-premium","auth-provider-basic","auth-provider-google","auth-provider-facebook","auth-provider-magic"),document.body.classList.add(this.state.isAuthenticated?"user-authenticated":"user-guest"),this.state.user?.role&&document.body.classList.add(`user-role-${this.state.user.role}
1`),this.state.provider&&document.body.classList.add(`auth-provider-${this.state.provider}`)}static toggleElements(e,t){e&&0!==e.length&&e.forEach((e=>{const n=e.closest(this.CONFIG.selectors.NAV_ITEM)||e;t?(n.classList.remove("hidden"),n.style.display=""):(n.classList.add("hidden"),n.style.display="none"),n.setAttribute("aria-hidden",(!t).toString())}))}static setupEventListeners(){window.addEventListener(a.QU.LOGIN_SUCCESS,(e=>{r.vF.info("auth","AuthStateManager received login success");const t=e;this.updateAuthState(t.detail),r.vF.info("auth","Removing all data-login-trigger attributes after login");document.querySelectorAll("[data-login-trigger]").forEach((e=>{r.vF.debug("auth","Removing data-login-trigger from:",e),e.removeAttribute("data-login-trigger")})),setTimeout((()=>{if(sessionStorage.getItem("pendingSubscriptionPlan"))return void r.vF.info("auth","Subscription flow in progress - skipping reload after login");if(document.querySelector(".access-wall-inline"))return void r.vF.info("auth","Access wall inline subscription - skipping reload after login");document.querySelector("#subscription-flow-modal")?r.vF.info("auth","Subscription modal active - skipping reload after login"):(r.vF.info("auth","Reloading page to update audience variations..."),window.location.reload())}),500)})),window.addEventListener(a.QU.REGISTER_SUCCESS,(e=>{r.vF.info("auth","AuthStateManager received register success");const t=e;t.detail?.requiresVerification||(r.vF.info("auth","Removing all data-login-trigger attributes after registration with auto-login"),setTimeout((()=>{document.querySelectorAll("[data-login-trigger]").forEach((e=>{r.vF.debug("auth","Removing data-login-trigger from:",e),e.removeAttribute("data-login-trigger")}));if("true"===sessionStorage.getItem("showingRegistrationModal"))return void r.vF.info("auth","Registration modal is showing - skipping reload");if(sessionStorage.getItem("pendingSubscriptionPlan"))return void r.vF.info("auth","Subscription flow in progress - skipping reload");document.querySelector(".access-wall-inline")?r.vF.info("auth","Access wall inline subscription - skipping reload"):(r.vF.info("auth","Reloading page to update audience variations..."),window.location.reload())}),500))})),window.addEventListener(a.QU.LOGOUT_SUCCESS,(()=>{r.vF.info("auth","AuthStateManager received logout success"),this.clearAuthState()})),window.addEventListener(a.QU.SESSION_INVALID,(()=>{r.vF.warn("auth","AuthStateManager received session invalid"),this.clearAuthState()})),window.addEventListener(a.QU.STATE_CHANGED,(e=>{const t=e;if(t.detail?.newState?.isAuthenticated){r.vF.info("auth","Auth state changed to authenticated - removing login triggers");document.querySelectorAll("[data-login-trigger]").forEach((e=>{e.removeAttribute("data-login-trigger")}))}}))}static async reinitialize(){return r.vF.info("auth","Reinitializing AuthStateManager..."),this.state.initialized=!1,await this.init()}static hasRole(e){return this.state.user?.role===e}static usedProvider(e){return this.state.provider===e}static isInitialized(){return this.state.initialized}static isSessionValidated(){return this.state.sessionValidated}static isAuthenticated(){return this.state.isAuthenticated}static getUser(){return this.state.user?{...this.state.user}:null}static getProvider(){return this.state.provider}}d.state={isAuthenticated:!1,user:null,provider:null,isLoading:!1,error:null,sessionExpiry:null,requiresTwoFactor:!1,tempToken:null,rememberMe:!1,initialized:!1,sessionValidated:!1};var l=d},1363:function(e,t,n){"use strict";n.d(t,{A:function(){return p}});var o=n(6730),i=n(8243),a=n(3716);class s{static render({icon:e="",title:t="No data",message:n="",action:o="",variant:i="default",size:a="medium",className:s=""}){const r=this.getSizeClasses(a);return`\n <div class="${this.getVariantClasses(i)} ${r.container} ${s}">\n ${e?this.renderIcon(e,a):this.renderDefaultIcon(a)}\n ${this.renderContent(t,n,r)}\n ${o?this.renderAction(o):""}\n </div>\n `}static getSizeClasses(e){const t={small:{container:"py-8 px-6",icon:"h-8 w-8",title:"text-base",message:"text-sm",spacing:"space-y-2"},medium:{container:"py-12 px-6",icon:"h-12 w-12",title:"text-lg",message:"text-base",spacing:"space-y-3"},large:{container:"py-16 px-6",icon:"h-16 w-16",title:"text-xl",message:"text-lg",spacing:"space-y-4"}};return t[e]||t.medium}static getVariantClasses(e){const t={default:"text-center",dashed:"text-center border-2 border-dashed border-gray-300 rounded-lg hover:border-gray-400 transition-colors",simple:"text-center"};return t[e]||t.default}static renderDefaultIcon(e){const t=this.getSizeClasses(e);return`\n <div class="mx-auto ${t.icon} text-gray-400">\n ${a.Hj.render("inbox",{class:t.icon})}\n </div>\n `}static renderIcon(e,t){return`\n <div class="mx-auto ${this.get
1SizeClasses(t).icon} text-gray-400">\n ${e}\n </div>\n `}static renderContent(e,t,n){return`\n <div class="${n.spacing}">\n <h3 class="${n.title} font-medium text-gray-900">\n ${this.escapeHtml(e)}\n </h3>\n ${t?`\n <p class="${n.message} text-gray-500">\n ${this.escapeHtml(t)}\n </p>\n `:""}\n </div>\n `}static renderAction(e){return`\n <div class="mt-6">\n ${e}\n </div>\n `}static escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}static renderNoResults({searchTerm:e="",suggestions:t=[],onClear:n="",...o}){const i=e?`No results found for "${e}"`:"No results found";let s="";e&&n&&(s=`\n <button type="button" onclick="${n}" class="text-primary-600 hover:text-primary-500">\n Clear search\n </button>\n `);const r=a.Hj.render("search",{class:"w-full h-full"});return this.render({icon:r,title:"No results",message:i,action:s,...o})}static renderNoItems({itemType:e="items",onAdd:t="",...n}){const o=t?`\n <button type="button" onclick="${t}" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700">\n ${a.Hj.render("plus",{class:"-ml-1 mr-2 h-5 w-5"})}\n Add ${e}\n </button>\n `:"";return this.render({title:`No ${e} yet`,message:`Get started by adding your first ${e.slice(0,-1)}.`,action:o,...n})}static renderError({error:e="Something went wrong",onRetry:t="",...n}){const o=a.Hj.render("alert-circle",{class:"w-full h-full"}),i=t?`\n <button type="button" onclick="${t}" class="text-primary-600 hover:text-primary-500">\n Try again\n </button>\n `:"";return this.render({icon:o,title:"Error loading data",message:e,action:i,...n})}static renderComingSoon({feature:e="This feature",...t}){const n=a.Hj.render("clock",{class:"w-full h-full"});return this.render({icon:n,title:"Coming soon",message:`${e} is not available yet, but we're working on it!`,...t})}static renderUnauthorized({onLogin:e="",...t}){const n=a.Hj.render("lock",{class:"w-full h-full"}),o=e?`\n <button type="button" onclick="${e}" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700">\n Sign in\n </button>\n `:"";return this.render({icon:n,title:"Access denied",message:"You need to be signed in to view this content.",action:o,...t})}}var r=n(8050),d=n(1678),l=n(3960),c=n(7411),u=n(1964),m=n(1916),g=n(8689);m.vF.debug("Imported activityAPI:","profile",u.A),m.vF.debug("activityAPI type:","profile",typeof u.A),m.vF.debug("activityAPI methods:","profile",u.A?Object.getOwnPropertyNames(Object.getPrototypeOf(u.A)):"null");class h extends o.${transformActivity(e){return{activityTime:e.createdAt||e.activityTime,activityType:e.type||e.activityType,activityTypeDisplay:e.activityTypeDisplay,description:e.description,ipAddress:e.ipAddress,userAgent:e.userAgent,details:e.metadata||e.details,success:e.success}}transformResponse(e){if(!e.success||!e.data)return{activities:[],hasMore:!1,page:1,pageSize:this.pageSize,totalCount:0,totalPages:0};const t=e.data;return{activities:t.items?.map((e=>this.transformActivity(e)))||[],hasMore:t.page<t.totalPages,page:t.page,pageSize:t.pageSize,totalCount:t.total,totalPages:t.totalPages}}constructor(e,t={}){super(e,t),this.api=t.api||u.A,this.pageSize=t.pageSize||20,this.showHeader=!1!==t.showHeader,console.log("[ActivityDashboard] Constructor - API:",this.api),console.log("[ActivityDashboard] API methods:",{getAllActivities:typeof this.api?.getAllActivities,getActivitySummary:typeof this.api?.getActivitySummary}),this.store.setState({currentFilter:"all",currentPage:1,activities:[],hasMore:!0,isLoading:!1,statistics:null,data:null})}getDefaultOptions(){return{autoInit:!0,debug:!1}}async onInit(){this.store.subscribe(((e,t,n)=>{this.container.querySelector("#activity-content-area")&&((n.includes("activities")||n.includes("statistics"))&&this.updateContent(),(n.includes("hasMore")||n.includes("activities"))&&this.updateLoadMoreButton())}))}async fetchData(){console.log("[ActivityDashboard] Fetching data...");try{await this.loadActivities(),console.log("[ActivityDashboard] Data fetching complete")}catch(e){console.error("[ActivityDashboard] Error in fetchData:",e)}}async render(){console.log("[ActivityDashboard] Rendering..."),this.container.innerHTML=this.getTemplate(),this.attachEventListeners(),console.log("[ActivityDashboard] About to fetch data..."),await this.fetchData()}updateContent(){this.store.getState();this.renderActivities()}getTemplate(){return this.showHeader?`\n <div class="space-y-6">\n ${this.renderTimelineCard()}\n </div>\n `:`\n <div class="space-y-6">\n ${this.renderTimelineContent()}\n </div>\n `}renderTimelineCard(){return l.Z.render({content:`\n <h3 class="text-lg font-semibold text-gray-900 mb-4">Activity Timeline</h3>\n ${this.renderTimelineContent()}\n `})}renderTimelineContent(){return`\n <div id="activity-content-area" style="min-height: 400px; position: relative;">\n \x3c!-- Loading State --\x3e\n <div id="activity-loading" class="hidden">\n \x3c!-- LoadingSpinner will be rendered here --\x3e\n </div>\n\n \x3c!-- Activity List --\x3e\n <div id="activity-list" class="space-y-4">\n \x3c!-- Activities will be rendered here --\x3e\n </div>\n\n \x3c!-- Empty State --\x3e\n <div id="activity-empty" class="hidden">\n \x3c!-- EmptyState will be rendered here --\x3e\n </div>\n\n \x3c!-- Load More --\x3e\n <div id="load-more-container" class="mt-6 text-center hidden">\n ${d.$.render({id:"load-more-btn",variant:"secondary",size:"small",icon:c.A.render("chevron-down",{class:"ml-2 -mr-0.5 h-4 w-4"}),text:"Load More Activities"})}\n </div>\n </div>\n `}attachEventListeners(){this.cleanup.addEventListener(this.container,"click",this.handleClick.bind(this))}handleClick(e){const t=e.target;t.matches("#refresh-activities")?this.refresh():t.matches("#load-more-btn")&&this.loadMore()}async loadActivities(e=!1){const t=this.store.getState();if(!t.isLoading){console.log("[ActivityDashboard] Loading activities...",{filter:t.currentFilter,page:t.currentPage,pageSize:this.pageSize}),this.store.setState({isLoading:!0}),this.showActivityLoading(e);try{let t;const n=this.store.getState();if(console.log("[ActivityDashboard] Loading all activities..."),console.log("[ActivityDashboard] API type:",this.api.constructor.name),"ProfileAPI"===this.api.constructor.name&&"function"==typeof this.api.getActivities){console.log("[ActivityDashboard] Using ProfileAPI.getActivities for all activities");const e=await this.api.getActivities({page:n.currentPage,pageSize:this.pageSize});if(console.log("[ActivityDashboard] ProfileAPI response:",e),e.success&&e.activities){const o={items:e.activities.map((e=>({...e,type:e.activityType,createdAt:e.activityTime,metadata:e.details}))),total:e.totalCount||0,page:e.page||n.currentPage,pageSize:e.pageSize||this.pageSize,totalPages:e.totalPages||1};t=this.transformResponse({success:!0,data:o})}}else{if("function"!=typeof this.api.getAllActivities)throw console.error("[ActivityDashboard] No suitable method found for loading all activities"),new Error("No suitable API method found for loading activities");{console.log("[ActivityDashboard] Using getAllActivities");const e=await this.api.getAllActivities({page:n.currentPage,pageSize:this.pageSize});if(console.log("[ActivityDashboard] getAllActivities response:",e),console.log("[ActivityDashboard] Response data structure:",e.data),e.success&&e.data)if("activities"in e.data&&!("items"in e.data)){console.log("[ActivityDashboard] Found activities in non-standard format");const o=e.data,i={items:o.activities.map((e=>({...e,type:e.activityType,createdAt:e.activityTime,metadata:e.details}))),total:o.totalCount||0,page:o.page||n.currentPage,pageSize:o.pageSize||this.pageSize,totalPages:o.totalPages||1};t=this.transformResponse({success:!0,data:i})}else t=this.transformResponse(e)}}if(t){const o=t.activities||[];console.log("[ActivityDashboard] Transformed activities:",o),console.log("[ActivityDashboard] Activities count:",o.length);const i=e?[...n.activities,...o]:o,a=t.hasMore||(t.totalPages?t.page<t.totalPages:t.page*t.pageSize<t.totalCount);console.log("[ActivityDashboard] Setting state with activities:",i.length),this.store.setState({activities:i,hasMore:a}),console.log("[ActivityDashboard] State updated, forcing render"),this.renderActivities()}else console.log("[ActivityDashboard] No response received")}catch(e){console.error("Error loading activities:",e),this.showActivityError("Failed to load activities")}finally{this.store.setState({isLoading:!1}),this.hideLoading()}}}renderActivities(){const e=this.store.getState();console.log("[ActivityDashboard] renderActivities - state:",e),console.log("[ActivityDashboard] renderActivities - activities count:",e.activities?.length);const t=this.container.querySelector("#activity-list"),n=this.container.querySelector("#activity-empty");e.activities&&0!==e.activities.length?(console.log("[ActivityDashboard] Rendering",e.activities.length,"activities"),n?.classList.add("hidden"),t?.classList.remove("hidden"),t&&(t.innerHTML=this.renderActivityTimeline(e.activities))):(console.log("[ActivityDashboard] No activities, showing empty state"),this.showEmpty())}renderActivityTimeline(e){const t=this.groupActivitiesByDate(e);return Object.entries(t).map((([e,t])=>`\n <div class="activity-day">\n <div class="text-sm font-medium text-gray-500 mb-3">${e}</div>\n <div class="space-y-3 relative">\n ${t.map(((e,t)=>this.renderActivityItem(e,0===t))).join("")}\n </div>\n </div>\n `)).join("")}groupActivitiesByDate(e){const t={};return e.forEach((e=>{const n=(0,g.Yq)(new Date(e.activityTime));t[n]||(t[n]=[]),t[n].push(e)})),t}renderActivityItem(e,t){const n=this.getActivityIcon(e.activityType),o=this.getActivityColor(e.activityType),i=(0,g.fU)(new Date(e.activityTime));return`\n <div class="flex items-start space-x-3 relative">\n ${t?"":'<div class="absolute -top-3 left-5 w-0.5 h-3 bg-gray-200"></div>'}\n\n <div class="flex-shrink-0">\n <div class="w-10 h-10 rounded-full ${o} flex items-center justify-center">\n ${n}\n </div>\n </div>\n\n <div class="flex-grow min-w-0">\n <div class="flex items-center justify-between">\n <p class="text-sm font-medium text-gray-900">\n ${e.activityTypeDisplay||e.description}\n </p>
1\n <span class="text-xs text-gray-500">${i}</span>\n </div>\n\n ${e.description&&e.description!==e.activityTypeDisplay?`\n <p class="text-sm text-gray-600 mt-1">${e.description}</p>\n `:""}\n\n ${this.renderActivityDetails(e)}\n ${this.renderActivityMetadata(e)}\n\n ${!1===e.success?`\n <div class="mt-2 text-xs text-red-600 bg-red-50 rounded p-2">\n ${c.A.render("alert-circle",{class:"w-3 h-3 inline mr-1"})}\n Failed activity\n </div>\n `:""}\n\n ${e.relatedContent?`\n <div class="mt-2 text-xs text-gray-500">\n <span class="flex items-center">\n ${c.A.render("link",{class:"w-3 h-3 mr-1"})}\n Related: ${e.relatedContent.type}\n </span>\n </div>\n `:""}\n </div>\n </div>\n `}renderActivityDetails(e){if(!e.details)return"";const t=[];switch(e.activityType){case"ADDRESS_ADDED":case"ADDRESS_UPDATED":(e.details.city||e.details.country)&&t.push(`${e.details.city||""}, ${e.details.country||""}`);break;case"PAYMENT_METHOD_ADDED":case"PAYMENT_METHOD_UPDATED":e.details.lastFour&&t.push(`Card ending in ${e.details.lastFour}`);break;case"SUBSCRIPTION_CREATED":case"SUBSCRIPTION_UPDATED":e.details.planName&&t.push(`Plan: ${e.details.planName}`);break;case"CONTENT_LIKED":case"CONTENT_FOLLOWED":e.details.contentTitle&&t.push(`"${e.details.contentTitle}"`)}return t.length>0?`<p class="text-sm text-gray-600 mt-1">${t.join(" ⢠")}</p>`:""}renderActivityMetadata(e){const t=[];if(e.ipAddress&&t.push(`\n <div class="text-xs text-gray-500 flex items-center mt-2">\n ${c.A.render("globe",{class:"w-3 h-3 mr-1"})}\n IP: ${e.ipAddress}\n </div>\n `),e.userAgent){const n=this.parseUserAgent(e.userAgent);t.push(`\n <div class="text-xs text-gray-500 flex items-center mt-1">\n ${c.A.render("monitor",{class:"w-3 h-3 mr-1"})}\n ${n}\n </div>\n `)}return t.join("")}getActivityIcon(e){return{LOGIN:c.A.render("log-in",{class:"w-5 h-5 text-white"}),LOGOUT:c.A.render("log-out",{class:"w-5 h-5 text-white"}),LOGIN_FAILED:c.A.render("alert-circle",{class:"w-5 h-5 text-white"}),REGISTRATION:c.A.render("user-plus",{class:"w-5 h-5 text-white"}),PASSWORD_CHANGE:c.A.render("key",{class:"w-5 h-5 text-white"}),PASSWORD_RESET:c.A.render("key",{class:"w-5 h-5 text-white"}),GOOGLE_LOGIN:c.A.social.google,FACEBOOK_LOGIN:c.A.social.facebook,PASSWORDLESS_LOGIN:c.A.render("mail",{class:"w-5 h-5 text-white"}),PROFILE_UPDATE:c.A.render("user",{class:"w-5 h-5 text-white"}),PROFILE_PICTURE_UPDATE:c.A.render("camera",{class:"w-5 h-5 text-white"}),EMAIL_VERIFIED:c.A.render("check-circle",{class:"w-5 h-5 text-white"}),ADDRESS_ADDED:c.A.render("map-pin",{class:"w-5 h-5 text-white"}),ADDRESS_UPDATED:c.A.render("map-pin",{class:"w-5 h-5 text-white"}),ADDRESS_DELETED:c.A.render("map-pin",{class:"w-5 h-5 text-white"}),PAYMENT_METHOD_ADDED:c.A.render("credit-card",{class:"w-5 h-5 text-white"}),PAYMENT_METHOD_UPDATED:c.A.render("credit-card",{class:"w-5 h-5 text-white"}),PAYMENT_METHOD_DELETED:c.A.render("credit-card",{class:"w-5 h-5 text-white"}),SUBSCRIPTION_CREATED:c.A.render("refresh-cw",{class:"w-5 h-5 text-white"}),SUBSCRIPTION_UPDATED:c.A.render("refresh-cw",{class:"w-5 h-5 text-white"}),SUBSCRIPTION_CANCELLED:c.A.render("x-circle",{class:"w-5 h-5 text-white"}),INVOICE_GENERATED:c.A.render("receipt",{class:"w-5 h-5 text-white"}),INVOICE_PAID:c.A.render("check-circle",{class:"w-5 h-5 text-white"}),CONTENT_LIKED:c.A.render("heart",{class:"w-5 h-5 text-white"}),CONTENT_UNLIKED:c.A.render("heart",{class:"w-5 h-5 text-white"}),CONTENT_FOLLOWED:c.A.render("bookmark",{class:"w-5 h-5 text-white"}),USER_FOLLOWED:c.A.render("users",{class:"w-5 h-5 text-white"}),COMMENT_POSTED:c.A.render("message-circle",{class:"w-5 h-5 text-white"}),TWO_FACTOR_ENABLED:c.A.render("shield-check",{class:"w-5 h-5 text-white"}),TWO_FACTOR_DISABLED:c.A.render("shield-off",{class:"w-5 h-5 text-white"})}[e]||c.A.render("info",{class:"w-5 h-5 text-white"})}getActivityColor(e){return{LOGIN:"bg-green-500",LOGOUT:"bg-gray-500",LOGIN_FAILED:"bg-red-500",REGISTRATION:"bg-blue-500",EMAIL_VERIFIED:"bg-green-600",PROFILE_UPDATE:"bg-blue-500",PAYMENT_METHOD_ADDED:"bg-primary-500",SUBSCRIPTION_CREATED:"bg-secondary-500",CONTENT_LIKED:"bg-secondary-500",COMMENT_POSTED:"bg-yellow-500",TWO_FACTOR_ENABLED:"bg-green-600",ACCOUNT_LOCKED:"bg-red-600"}[e]||"bg-gray-400"}parseUserAgent(e){return e?e.includes("Chrome")?"Chrome":e.includes("Firefox")?"Firefox":e.includes("Safari")?"Safari":e.includes("Edge")?"Edge":"Unknown Browser":""}async loadMore(){const e=this.store.getState();e.hasMore&&!e.isLoading&&(this.store.setState({currentPage:e.currentPage+1}),await this.loadActivities(!0))}async refresh(){this.store.setState({currentPage:1,activities:[]}),await this.loadActivities()}updateLoadMoreButton(){const e=this.store.getState(),t=this.container.querySelector("#load-more-container");t&&(e.hasMore&&e.activities.length>0?t.classList.remove("hidden"):t.classList.add("hidden"))}showActivityLoading(e=!1){const t=this.container.querySelector("#activity-loading"),n=this.container.querySelector("#activity-list"),o=this.container.querySelector("#activity-empty");e||(n.classList.add("hidden"),o.classList.add("hidden"),t.classList.remove("hidden"),t.innerHTML=`\n <div class="absolute inset-0 flex items-center justify-center">\n ${i.k.render({text:"Loading activities...",size:"medium"})}\n </div>\n `)}hideLoading(){const e=this.container.querySelector("#activity-loading"),t=this.container.querySelector("#activity-list");e.classList.add("hidden"),t.classList.remove("hidden")}showEmpty(){const e=this.container.querySelector("#activity-list"),t=this.container.querySelector("#activity-empty");if(!e||!t)return void console.warn("[ActivityDashboard] showEmpty called but DOM elements not found");e.classList.add("hidden"),t.classList.remove("hidden");const n=c.A.render("clipboard",{class:"w-16 h-16 text-gray-400"});t.innerHTML=`\n <div class="bg-gray-50 rounded-lg border border-gray-200 p-12">\n ${s.render({icon:n,title:"No activities found",message:"Your activity history will appear here",variant:"simple",size:"small"})}\n </div>\n `}showActivityError(e){const t=this.container.querySelector("#activity-list"),n=this.container.querySelector("#activity-empty");t.classList.add("hidden"),n.classList.remove("hidden"),n.innerHTML=r.Alert.render({variant:"error",title:"Failed to load activities",message:e,dismissible:!1})}}var p=h},7051:function(e,t,n){"use strict";var o=n(1363),i=n(1964);class a{constructor(e,t={}){this.dashboard=null,this.refreshTimer=null,this.container=e,this.options={apiBaseUrl:t.apiBaseUrl||"/api/heimguard",pageSize:t.pageSize||20,autoRefresh:t.autoRefresh||!1,refreshInterval:t.refreshInterval||3e4},this.api=i.A}async initialize(){try{if(!this.container)throw new Error("Container element not provided");this.dashboard=new o.A(this.container,{api:this.api,pageSize:this.options.pageSize}),await this.dashboard.render(),this.options.autoRefresh&&this.startAutoRefresh(),this.setupEventListeners()}catch(e){throw console.error("Failed to initialize activity system:",e),e}}async render(){await this.initialize()}setupEventListeners(){document.addEventListener("heimguard:activity:new",(async()=>{this.dashboard&&await this.dashboard.refresh()})),document.addEventListener("heimguard:profile:sectionChange",(e=>{"activity"===e.detail.section&&this.dashboard?.refresh()}))}startAutoRefresh(){this.stopAutoRefresh(),this.refreshTimer=window.setInterval((async()=>{this.dashboard&&await this.dashboard.refresh()}),this.options.refreshInterval)}stopAutoRefresh(){this.refreshTimer&&(clearInterval(this.refreshTimer),this.refreshTimer=null)}cleanup(){this.stopAutoRefresh(),this.dashboard&&this.dashboard.destroy()}static create(e,t){return new a(e,t)}}t.default=a},4047:function(e,t,n){"use strict";t.A=new class{constructor(){this.addressTypes={SHIPPING:"shipping",BILLING:"billing",BOTH:"both"},this.validationRules={firstName:{required:!0,minLength:2,maxLength:50},lastName:{required:!0,minLength:2,maxLength:50},street1:{required:!0,minLength:5,maxLength:100},street2:{maxLength:100},city:{required:!0,minLength:2,maxLength:50},region:{required:!0,minLength:2,maxLength:50},postalCode:{required:!0,pattern:/^[A-Za-z0-9\s-]{3,10}$/},country:{required:!0},phone:{pattern:/^[\d\s\-\(\)\+]+$/,minLength:10,maxLength:20}},this.defaultCountry="US",this.messages={loading:"Loading your addresses...",empty:{title:"No addresses yet",message:"Add your billing addresses for faster checkout"},success:{add:"Address added successfully",update:"Address updated successfully",delete:"Address deleted successfully",setDefault:"Default address updated"},error:{load:"Failed to load addresses",save:"Failed to save address",delete:"Failed to delete address",validation:"Please correct the errors below"},confirm:{delete:"Are you sure you want to delete this address?",deleteDefault:"This is a default address. Are you sure you want to delete it?"}}}getValidationRule(e){return this.validationRules[e]||{}}getMessage(e,t){const n=this.messages[e];return"string"==typeof n?n:"object"==typeof n&&t&&t in n?n[t]:t?`${e}.${String(t)}`:String(e)}}},3593:function(e,t,n){"use strict";n.d(t,{Ge:function(){return a},i$:function(){return o},id:function(){return i}});const o={ADDRESS_ADDED:"address:added",ADDRESS_UPDATED:"address:updated",ADDRESS_DELETED:"address:deleted",ADDRESS_LIST_UPDATED:"address:list:updated",DEFAULT_SHIPPING_SET:"address:default:shipping:set",DEFAULT_BILLING_SET:"address:default:billing:set",ADD_ADDRESS_CLICKED:"address:add:clicked",EDIT_ADDRESS_CLICKED:"address:edit:clicked",DELETE_ADDRESS_CLICKED:"address:delete:clicked",ADDRESS_MODAL_OPENED:"address:modal:opened",ADDRESS_MODAL_CLOSED:"address:modal:closed",ADDRESS_MODAL_SAVED:"address:modal:saved",ADDRESS_COUNT_CHANGED:"address:count:changed",ADDRESS_VALIDATION_FAILED:"address:validation:failed",ADDRESS_COMPONENT_READY:"address:component:ready",ADDRESS_COMPONENT_ERROR:"address:component:error"};function i(e,t={}){const n=new CustomEvent(`heimguard:${e}`,{detail:t,bubbles:!0});document.dispatchEvent(n)}function a(e,t){const n=e=>t(e.detail);return document.addEventListener(`heimguard:${e}`,n),()=>{document.removeEventListener(`heimguard:${e}`,n)}}},4849:function(e,t,n){"use strict";var o=n(5856),i=n(3593),a=n(4047);t.default=new class{constructor(){this.addresses=[],this.isLoaded=!1,this.api=o.A}async loadAddresses(e=!1){if(this.isLoaded&&!e)return this.addresses;try{const e=await this.api.getAddresses();let t=[];return e&&e.addresses?t=Object.values(e.addresses):Array.isArray(e)&&(t=e),this.addresses=t,this.isLoaded=!0,(0,i.id)(i.i$.ADDRESS_LIST_UPDATED,{addresses:t}),t}catch(e){throw console.error("Failed to load addresses:",e),e}}getAddresses(){return[...this.addresses]}getAddressById(e){return this.addresses.find((t=>t.id===e))}getDefaultAddresses(){return{shipping:this.addresses.find((e=>e.isDefaultShipping)),billing:this.addresses.find((e=>e.isDefaultBilling)),account:this.addresses.find((e=>e.isAccount))}}async addAddress(e){try{await this.api.addAddress(e);await this.loadAddresses(!0);const t=this.addresses[this.addresses.length-1];return(0,i.id)(i.i$.ADDRESS_ADDED,{address:t,count:this.addresses.length}),t}catch(e){throw console.error("Failed to add address:",e),e}}async updateAddress(e,t){try{console.log("[AddressManager] Updating address with data:",t);const n=!0===t.isDefaultShipping,o=!0===t.isDefaultBilling;await this.api.updateAddress(e,t);await this.loadAddresses(!0);const a=this.addresses.find((t=>t.id===e));return console.log("[AddressManager] Emitting ADDRESS_UPDATED event for address:",e),(0,i.id)(i.i$.ADDRESS_UPDATED,{address:a,addressId:e}),n&&a&&(console.log("[AddressManager] Emitting DEFAULT_SHIPPING_SET event"),(0,i.id)(i.i$.DEFAULT_SHIPPING_SET,{address:a,addressId:e})),o&&a&&(console.log("[AddressManager] Emitting DEFAULT_BILLING_SET event"),(0,i.id)(i.i$.DEFAULT_BILLING_SET,{address:a,addressId:e})),a}catch(e){throw console.error("Failed to update address:",e),e}}async deleteAddress(e){try{return await this.api.deleteAddress(e),this.addresses=this.addresses.filter((t=>
1t.id!==e)),(0,i.id)(i.i$.ADDRESS_DELETED,{addressId:e,count:this.addresses.length}),!0}catch(e){throw console.error("Failed to delete address:",e),e}}async setDefaultShipping(e){try{console.log("[AddressManager] Setting default shipping for:",e),this.addresses.forEach((e=>{e.isDefaultShipping&&(e.isDefaultShipping=!1)}));const t=this.addresses.find((t=>t.id===e));t&&(t.isDefaultShipping=!0,await this.updateAddress(e,{isDefaultShipping:!0}),(0,i.id)(i.i$.DEFAULT_SHIPPING_SET,{address:t,addressId:e}))}catch(e){throw console.error("Failed to set default shipping:",e),e}}async setDefaultBilling(e){try{console.log("[AddressManager] Setting default billing for:",e),this.addresses.forEach((e=>{e.isDefaultBilling&&(e.isDefaultBilling=!1)}));const t=this.addresses.find((t=>t.id===e));t&&(t.isDefaultBilling=!0,await this.updateAddress(e,{isDefaultBilling:!0}),(0,i.id)(i.i$.DEFAULT_BILLING_SET,{address:t,addressId:e}))}catch(e){throw console.error("Failed to set default billing:",e),e}}validateAddress(e){const t={},n=a.A.validationRules;return Object.keys(n).forEach((o=>{const i=n[o],a=e[o];!i.required||a&&""!==a.trim()?a&&(i.minLength&&a.length<i.minLength&&(t[o]=`Must be at least ${i.minLength} characters`),i.maxLength&&a.length>i.maxLength&&(t[o]=`Must not exceed ${i.maxLength} characters`),i.pattern&&!i.pattern.test(a)&&(t[o]="Invalid format")):t[o]=`${o} is required`})),{isValid:0===Object.keys(t).length,errors:t}}getCount(){return this.addresses.length}clear(){this.addresses=[],this.isLoaded=!1}}},6957:function(e,t,n){"use strict";n.d(t,{A:function(){return a}});var o=n(6833),i=n(8520);class a{constructor(e,t={}){this.hasMultipleCards=!1,this.container=e,this.options={paymentMethod:null,onRemove:void 0,onEdit:void 0,...t}}setHasMultipleCards(e){this.hasMultipleCards=e}render(){const e=this.options.paymentMethod;if(!e)return;const t=this.isExpired(e.expiryMonth,e.expiryYear),n=this.isExpiringSoon(e.expiryMonth,e.expiryYear),o=this.getExpirationStatus(e.expiryMonth,e.expiryYear);this.container.innerHTML=`\n <div class="payment-method-card group relative overflow-hidden rounded-2xl transition-all duration-300 ${e.isDefault?"bg-gradient-to-br from-blue-50 to-indigo-50 shadow-lg hover:shadow-xl ring-2 ring-blue-200":"bg-white shadow-md hover:shadow-lg"}">\n\n\n <div class="relative p-4 sm:p-6">\n \x3c!-- Main Content Area --\x3e\n <div class="flex flex-col sm:flex-row sm:items-start sm:justify-between">\n \x3c!-- Left Side: Card Details --\x3e\n <div class="flex items-start space-x-3 sm:space-x-4 mb-4 sm:mb-0">\n \x3c!-- Card Brand Icon --\x3e\n <div class="flex-shrink-0">\n <div class="w-14 h-9 sm:w-16 sm:h-10 bg-gradient-to-br ${this.getCardGradient(e.cardType)} rounded-lg flex items-center justify-center shadow-sm">\n <span class="text-white font-bold text-xs">${this.getCardBrandShort(e.cardType)}</span>\n </div>\n </div>\n\n \x3c!-- Card Details --\x3e\n <div class="flex-1">\n <div class="flex flex-col sm:flex-row sm:items-baseline sm:space-x-3">\n <span class="font-mono text-base sm:text-lg font-medium text-gray-900">â¢â¢â¢â¢ ${e.lastFour}</span>\n ${(t||n)&&o.label?`\n <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium mt-1 sm:mt-0 ${t?"bg-red-100 text-red-800":"bg-amber-100 text-amber-800"}">\n ${o.label}\n </span>\n `:""}\n </div>\n ${e.cardholderName?`<p class="text-sm text-gray-700 mt-1">${e.cardholderName}</p>`:""}\n <p class="text-xs sm:text-sm text-gray-500 mt-1">Expires ${e.expiryMonth.toString().padStart(2,"0")}/${e.expiryYear}</p>\n </div>\n </div>\n\n \x3c!-- Right Side (Desktop) / Bottom (Mobile): Actions --\x3e\n <div class="flex flex-col items-stretch sm:items-end space-y-2">\n \x3c!-- Action Buttons --\x3e\n <div class="flex items-center space-x-2 justify-end">\n <button class="inline-flex items-center justify-center px-3 py-1.5 bg-white text-blue-600 text-xs font-medium rounded-lg hover:bg-blue-50 transition-colors border border-blue-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 flex-1 sm:flex-initial" data-action="edit">\n <svg class="w-3.5 h-3.5 mr-1.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />\n </svg>\n Update\n </button>\n <button class="inline-flex items-center justify-center px-3 py-1.5 bg-white text-red-600 text-xs font-medium rounded-lg hover:bg-red-50 transition-colors border border-red-200 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 flex-1 sm:flex-initial" data-action="remove">\n <svg class="w-3.5 h-3.5 mr-1.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />\n </svg>\n Remove\n </button>\n </div>\n </div>\n </div>\n\n \x3c!-- Expiration Warning (More Subtle) --\x3e\n ${t||n?`\n <div class="mt-4 flex items-center space-x-2 text-xs ${t?"text-red-600":"text-amber-600"}">\n <svg class="w-4 h-4 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">\n <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />\n </svg>
1\n <span>\n ${t?"This card has expired. Please add a new card.":"Consider adding a new card to avoid payment interruptions."}\n </span>\n </div>\n `:""}\n\n \x3c!-- Bottom Metadata --\x3e\n <div class="mt-4 pt-4 border-t border-gray-100">\n <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between space-y-2 sm:space-y-0">\n <div class="flex flex-col sm:flex-row sm:items-center sm:space-x-3 text-xs text-gray-500 space-y-1 sm:space-y-0">\n <div class="flex items-center">\n <svg class="w-3.5 h-3.5 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />\n </svg>\n Added ${this.formatDate(e.createdAt)}\n </div>\n ${e.billingAddress&&e.billingAddress.city&&e.billingAddress.region?`\n <div class="flex items-center">\n <svg class="w-3.5 h-3.5 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />\n </svg>\n ${e.billingAddress.city}, ${e.billingAddress.region}\n </div>\n `:""}\n </div>\n </div>\n </div>\n </div>\n </div>\n `,this.attachEventListeners()}getCardBrandShort(e){return{visa:"VISA",mastercard:"MC",master:"MC",amex:"AMEX",american_express:"AMEX",discover:"DISC",diners:"DC",jcb:"JCB"}[e?.toLowerCase()]||e?.toUpperCase()||"CARD"}getCardGradient(e){return{visa:"from-blue-600 to-blue-700",mastercard:"from-red-500 to-orange-500",master:"from-red-500 to-orange-500",amex:"from-green-600 to-green-700",american_express:"from-green-600 to-green-700",discover:"from-orange-500 to-orange-600",diners:"from-slate-700 to-slate-800",jcb:"from-purple-600 to-purple-700"}[e?.toLowerCase()]||"from-gray-600 to-gray-700"}isExpired(e,t){const n=new Date,o=n.getFullYear(),i=n.getMonth()+1,a=t<100?2e3+t:t;return a<o||a===o&&e<i}isExpiringSoon(e,t){const n=new Date,o=12*((t<100?2e3+t:t)-n.getFullYear())+(e-(n.getMonth()+1));return o>0&&o<=3}getExpirationStatus(e,t){if(!e||!t||e<1||e>12)return{label:"Invalid Date",textColor:"text-gray-500",bgColor:null,borderColor:null,daysRemaining:null,friendlyDate:"Unknown"};const n=new Date,o=(n.getFullYear(),t<100?2e3+t:t),i=new Date(o,e,0).getDate(),a=new Date(o,e-1,i,23,59,59).getTime()-n.getTime(),s=Math.ceil(a/864e5);if(s<0)return{label:"Expired",textColor:"text-red-600",bgColor:"bg-red-100",borderColor:"border-red-200",daysRemaining:null,friendlyDate:null};if(0===s)return{label:"Expires Today",textColor:"text-red-600",bgColor:"bg-red-100",borderColor:"border-red-200",daysRemaining:0,friendlyDate:"today"};if(s<=30)return{label:`Expires in ${s} days`,textColor:"text-red-600",bgColor:"bg-red-100",borderColor:"border-red-200",daysRemaining:s,friendlyDate:`in ${s} day${s>1?"s":""}`};if(s<=90){const e=Math.floor(s/30);return{label:"Expiring Soon",textColor:"text-yellow-600",bgColor:"bg-yellow-100",borderColor:"border-yellow-200",daysRemaining:s,friendlyDate:`in ${e} month${e>1?"s":""}`}}return{label:null,textColor:"text-gray-500",bgColor:null,borderColor:null,daysRemaining:null,friendlyDate:`${["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"][e-1]} ${o.toString()}`}}formatDate(e){if(!e)return"Unknown";const t=new Date(e),n=new Date,o=new Date(t.getFullYear(),t.getMonth(),t.getDate()),i=new Date(n.getFullYear(),n.getMonth(),n.getDate()).getTime()-o.getTime(),a=Math.floor(i/864e5);return 0===a?"Today":1===a?"Yesterday":a<7?`${a} days ago`:a<30?`${Math.floor(a/7)} weeks ago`:a<365?`${Math.floor(a/30)} months ago`:t.toLocaleDateString("en-US",{month:"short",year:"numeric"})}attachEventListeners(){this.container.querySelectorAll('[data-action="edit"]').forEach((e=>{e&&this.options.paymentMethod&&e.addEventListener("click",(e=>{e.stopPropagation(),this.options.onEdit&&this.options.paymentMethod&&this.options.onEdit(this.options.paymentMethod)}))}));this.container.querySelectorAll('[data-action="remove"]').forEach((e=>{e&&this.options.paymentMethod&&e.addEventListener("click",(async e=>{e.stopPropagation(),await this.showRemoveComingSoonModal()}))}))}async showRemoveComingSoonModal(){let e="[email protected]";try{const t=await i.initService.getInitData();t?.generalConfig?.companySupportEmail&&(e=t.generalConfig.companySupportEmail)}catch(e){console.error("Failed to get support email:",e)}const t=`\n <div class="text-center py-4">\n <div class="inline-flex items-center justify-center w-16 h-16 bg-blue-100 rounded-full mb-4">\n <svg class="w-8 h-8 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n </div>\n <h3 class="text-lg font-semibold text-gray-900 mb-4">Remove Payment Method</h3>\n <p class="text-gray-700 mb-4">\n To remove a payment method, please contact our customer support team. They will assist you with removing this payment method from your account.\n </p>\n <p class="text-sm text-gray-500 mb-2">\n Please contact our customer support team at \n <a href="mailto:${e}" class="text-blue-600 hover:text-blue-700 font-medium">\n ${e}\n </a>\n </p>\n <p class="text-sm text-gray-500">\n If this is urgent, you can also call our customer service team directly for immediate assistance.\n </p>\n </div>\n `,n=new o.Modal({title:"Remove Payment Method",content:t,footer
1:'\n <div class="flex justify-end">\n <button id="coming-soon-close-btn" class="px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">\n Got it\n </button>\n </div>\n ',size:"small",closeButton:!0,closeOnOverlay:!0,closeOnEscape:!0});n.open(),setTimeout((()=>{const e=document.getElementById("coming-soon-close-btn");e&&e.addEventListener("click",(()=>{n.close()}))}),100)}destroy(){}}},8886:function(e,t,n){"use strict";var o=n(2910),i=n(7876),a=n(2404),s=n(6833),r=n(8050),d=n(8354),l=n(4140),c=n(5856),u=n(6957),m=n(4081),g=n(7310),h=n(1458),p=n(8520);class y extends i.A{constructor(e,t={}){super(e,t),this.paymentApi=l.paymentMethodsAPI,this.addressApi=c.A,this.paymentCardInstances=[],this.mainButtonListenerAttached=!1,this.activePaymentModal=null,this.isShowingModal=!1,this.lastModalCallTime=0,this.MODAL_DEBOUNCE_TIME=500,this.newlyAddedCardId=null,console.log("[PaymentMethodsList] Constructor called",{container:e,containerId:e.id,containerClass:e.className}),this.showAddPaymentModal=this.showAddPaymentModal.bind(this)}getDefaultOptions(){return{autoInit:!0,debug:!1}}getInitialState(){return{isLoading:!0,error:null,data:null,profileData:this.options.profileData,paymentMethods:[],addresses:[],recurlyPublicKey:null,enableAddCard:!0}}async onInit(){this.store.subscribe(((e,t,n)=>{n.includes("data")&&!e.isLoading&&this.updateContent()}))}getComponentClassName(){return"hg-payment-methods"}getComponentName(){return"payment methods"}getHeaderConfig(){const e=this.getState(),t=e.data&&e.data.paymentMethods?e.data.paymentMethods.length:0,n=e.enableAddCard||!e.enableAddCard&&0===t;return{icon:a.b.icons.payment,title:"Payment Methods",subtitle:"Manage your cards and billing information",actions:()=>n?'\n <button id="add-payment-btn" class="inline-flex items-center px-4 py-2 bg-white/20 backdrop-blur text-white rounded-lg hover:bg-white/30 transition-all border border-white/30 text-sm font-medium">\n <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />\n </svg>\n Add Card\n </button>\n ':""}}getLoadingMessage(){return"Loading your payment methods..."}async loadData(){const[e,t]=await Promise.all([this.getRecurlyKey(),p.initService.getInitData().catch((()=>null))]),o=t?.generalConfig?.enableAddCard??!0;if(this.setState({recurlyPublicKey:e,enableAddCard:o}),!e)throw new Error("Payment configuration not available. Please contact support.");const[i,a]=await Promise.all([this.paymentApi.getPaymentMethods().catch((e=>(console.error("Payment methods fetch error:",e),console.error("Error details:",{status:e.status,message:e.message,data:e.data}),{success:!0,data:{paymentMethods:{}}}))),(async()=>{try{const{default:e}=await Promise.resolve().then(n.bind(n,4849));return await e.loadAddresses()}catch(e){return console.warn("Addresses fetch error:",e),[]}})()]);console.log("[PaymentMethodsList] Raw payment methods response:",i);const s=this.parsePaymentMethods(i);return this.notifyPaymentMethodCountChange(s.length),{paymentMethods:s,addresses:a}}async fetchData(){const e=await this.loadData();return{paymentMethods:e.paymentMethods,addresses:e.addresses}}parsePaymentMethods(e){console.log("[PaymentMethodsList] ========== PARSING PAYMENT METHODS =========="),console.log("[PaymentMethodsList] Raw response:",JSON.stringify(e,null,2));const t=e?.data?.paymentMethods||e?.paymentMethods,n=e?.data?.userActiveAccountsIds||[];if(console.log("[PaymentMethodsList] Extracted paymentMethods:",JSON.stringify(t,null,2)),console.log("[PaymentMethodsList] User active accounts IDs:",JSON.stringify(n)),this.setState({userActiveAccountsIds:n}),t&&"object"==typeof t){if(0===Object.keys(t).length)return console.log("[PaymentMethodsList] No payment methods found - empty object"),[];console.log(`[PaymentMethodsList] Processing ${Object.keys(t).length} payment methods`);const e=Object.entries(t).map((([e,t])=>{console.log(`[PaymentMethodsList] ========== Processing method ${e} ==========`),console.log("[PaymentMethodsList] Raw method data:",JSON.stringify(t,null,2));const n={id:t.billingInfoId||t.id||`payment_method_${e}`,billingInfoId:t.billingInfoId,type:t.type||"credit_card",cardType:(t.cardType||"card").toLowerCase(),lastFour:t.maskedCardNumber?t.maskedCardNumber.slice(-4):"****",expiryMonth:t.expiryMonth||0,expiryYear:t.expiryYear||0,cardholderName:t.cardholderName||(t.billingAddress?`${t.billingAddress.firstName||""} ${t.billingAddress.lastName||""}`.trim():"")||"",isDefault:!1,isExpired:this.isCardExpired(t),billingAddress:t.billingAddress||{},billingAddressId:t.billingAddressId||"",maskedCardNumber:t.maskedCardNumber,createdAt:t.createdAt||(new Date).toISOString(),updatedAt:t.updatedAt};return console.log(`[PaymentMethodsList] Processed method ${e}:`,JSON.stringify(n,null,2)),n}));return e.sort(((e,t)=>{const n=e.createdAt?new Date(e.createdAt).getTime():0;return(t.createdAt?new Date(t.createdAt).getTime():0)-n})),console.log("[PaymentMethodsList] ========== FINAL PROCESSED METHODS =========="),console.log(`[PaymentMethodsList] Total methods after processing: ${e.length}`),e.forEach(((e,t)=>{console.log(`[PaymentMethodsList] Method ${t}: id=${e.id}, billingInfoId=${e.billingInfoId}`)})),console.log("[PaymentMethodsList] ========== END PROCESSING =========="),e}return[]}isCardExpired(e){const t=(new Date).getFullYear(),n=(new Date).getMonth()+1,o=e.expiryYear||e.year,i=e.expiryMonth||e.month;return o<t||o===t&&i<n}async getRecurlyKey(){let e=null;try{if(await g.default.load(),e=g.default.getRecurlyPublicKey(),e)return e}catch(e){console.warn("Failed to load from HeimguardSettings:",e)}if(window.HeimGuard?.authSystem?.authConfig&&(e=window.HeimGuard.authSystem.authConfig.getRecurlyPublicKey(),e))return e;try{const t=await fetch(o.A.apiHeimguardInitUrl,{credentials:"include"});if(t.ok){const n=await t.json();if(e=n.recurlyPublicKey||n.recurly_public_key,e)return e}}
1catch(e){console.warn("Failed to fetch Recurly key directly:",e)}return null}isEmptyState(e){return!e||!e.paymentMethods||0===e.paymentMethods.length}getEmptyStateConfig(){this.getState();return{icon:'<svg class="w-16 h-16 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" />\n </svg>',title:"No payment methods yet",message:"Add a payment method to make purchases and manage your subscriptions",action:'\n <button id="add-first-payment-btn" class="inline-flex items-center px-6 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-all font-medium shadow-md hover:shadow-lg transform hover:-translate-y-0.5">\n <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />\n </svg>\n Add Your First Card\n </button>\n '}}renderMainContent(){const e=this.getState();if(!e.data||!e.data.paymentMethods||0===e.data.paymentMethods.length)return"";return`\n \n <style>\n @keyframes pulseGlow {\n 0% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.7); }\n 70% { box-shadow: 0 0 0 10px rgba(59, 130, 246, 0); }\n 100% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0); }\n }\n .new-card-highlight {\n animation: pulseGlow 2s ease-out 3;\n border: 2px solid #3b82f6 !important;\n position: relative;\n }\n .new-badge {\n position: absolute;\n top: -10px;\n right: 20px;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n padding: 4px 12px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n z-index: 10;\n animation: fadeInOut 5s ease-out forwards;\n }\n @keyframes fadeInOut {\n 0% { opacity: 0; transform: scale(0.8); }\n 10% { opacity: 1; transform: scale(1.05); }\n 20% { opacity: 1; transform: scale(1); }\n 80% { opacity: 1; transform: scale(1); }\n 100% { opacity: 0; transform: scale(0.9); }\n }\n </style>\n \n <div class="p-6">\n <div class="space-y-4">\n ${e.data.paymentMethods.map(((e,t)=>{const n=0===t&&"newly-added"===this.newlyAddedCardId,o=n?"new-card-highlight":"";return`\n <div data-payment-method="${e.id}" class="payment-method-container ${o}">\n ${n?'<span class="new-badge">⨠NEW</span>':""}\n </div>\n `})).join("")}\n </div>\n\n ${this.renderSecurityBadges()}\n </div>\n `}renderSecurityBadges(){return'\n <div class="mt-8 pt-6 border-t border-gray-200">\n <div class="flex items-center justify-center space-x-6 text-sm text-gray-500">\n <div class="flex items-center">\n <svg class="w-5 h-5 mr-2 text-green-500" fill="currentColor" viewBox="0 0 20 20">\n <path fill-rule="evenodd" d="M2.166 4.999A11.954 11.954 0 0010 1.944 11.954 11.954 0 0017.834 5c.11.65.166 1.32.166 2.001 0 5.225-3.34 9.67-8 11.317C5.34 16.67 2 12.225 2 7c0-.682.057-1.35.166-2.001zm11.541 3.708a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />\n </svg>\n <span>PCI Compliant</span>\n </div>\n <div class="flex items-center">\n <svg class="w-5 h-5 mr-2 text-green-500" fill="currentColor" viewBox="0 0 20 20">\n <path fill-rule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clip-rule="evenodd" />\n </svg>\n <span>Secure Encryption</span>\n </div>\n <div class="flex items-center">\n <svg class="w-5 h-5 mr-2 text-green-500" fill="currentColor" viewBox="0 0 20 20">\n <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />\n </svg>
1\n <span>Verified Merchant</span>\n </div>\n </div>\n </div>\n '}attachEventListeners(){this.mainButtonListenerAttached?console.log("[PaymentMethodsList] Main button listener already attached, skipping"):(console.log("[PaymentMethodsList] Attaching main button listener"),this.addDelegatedListener("#add-payment-btn, #add-first-payment-btn","click",this.showAddPaymentModal),this.mainButtonListenerAttached=!0);const e=this.getState();if(this.cleanupCardInstances(),e.data&&e.data.paymentMethods){const t=e.data.paymentMethods.length>1;e.data.paymentMethods.forEach((e=>{const n=this.container.querySelector(`[data-payment-method="${e.id}"]`);if(n){const o=new u.A(n,{paymentMethod:e,onRemove:e=>this.confirmRemovePaymentMethod(e),onEdit:e=>this.showEditPaymentModal(e)});o.setHasMultipleCards(t),o.render(),this.paymentCardInstances.push(o)}}))}}cleanupCardInstances(){this.paymentCardInstances.forEach((e=>{e.destroy&&e.destroy()})),this.paymentCardInstances=[]}async showAddPaymentModal(){const e=Date.now();if(e-this.lastModalCallTime<this.MODAL_DEBOUNCE_TIME)return void console.log("[PaymentMethodsList] Debouncing rapid click");if(this.lastModalCallTime=e,this.isShowingModal||this.activePaymentModal)return void console.log("[PaymentMethodsList] Modal already showing, preventing duplicate");const t=this.getState();if(!t.recurlyPublicKey)return void r.Alert.error(h.UU.RECURLY_LOAD_FAILED);this.isShowingModal=!0;if(0!==(t.data&&t.data.addresses?t.data.addresses.filter((e=>e.isBilling||e.isDefaultBilling||e.isAccount)):[]).length)try{new m.default({addresses:t.data&&t.data.addresses?t.data.addresses:[],recurlyPublicKey:t.recurlyPublicKey,editMode:!1,onSuccess:async e=>{console.log("[PaymentMethodsList] ========== ADD MODAL SUCCESS =========="),console.log("[PaymentMethodsList] Token data received:",JSON.stringify(e,null,2));try{await this.handlePaymentMethodAdded(e)}catch(e){throw console.error("[PaymentMethodsList] Add modal success handler error:",e),e}},onCancel:()=>{console.log("Add payment modal cancelled"),this.isShowingModal=!1},onAddressNeeded:async()=>{const e=await this.addressApi.getAddresses();let t=[];return e?.addresses&&(t=Array.isArray(e.addresses)?e.addresses:Object.values(e.addresses)),t}}).show(),this.isShowingModal=!1}catch(e){console.error("Failed to open payment modal:",e),r.Alert.error("Failed to open payment modal. Please try again."),this.isShowingModal=!1}else s.Modal.confirm({title:"Billing Address Required",message:'\n <div class="space-y-4">\n <div class="flex items-start">\n <svg class="w-6 h-6 text-amber-500 mr-3 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />\n </svg>\n <div>\n <p class="text-gray-700 font-medium mb-2">You need a billing address to add a payment method.</p>\n <p class="text-gray-600 text-sm">Payment cards require a billing address for verification and security purposes.</p>\n </div>\n </div>\n\n <div class="bg-blue-50 border border-blue-200 rounded-lg p-4">\n <p class="text-sm text-blue-800">\n <strong>Why is this required?</strong><br>\n Your billing address helps verify your identity and prevent fraud when processing payments.\n </p>\n </div>\n </div>\n ',confirmText:"Add Billing Address",cancelText:"Cancel",confirmClass:"bg-primary-600 hover:bg-primary-700 text-white"}).then((e=>{this.isShowingModal=!1,e&&(window.location.hash="addresses")}))}async showEditPaymentModal(e){console.log("[PaymentMethodsList] ========== EDIT PAYMENT METHOD TRIGGERED =========="),console.log("[PaymentMethodsList] Edit payment method:",JSON.stringify(e,null,2));const t=this.getState();if(!t.recurlyPublicKey)return void r.Alert.error(h.UU.RECURLY_LOAD_FAILED);const n=e.billingInfoId||e.id;console.log("[PaymentMethodsList] Selected billing info for edit:",n);try{new m.default({addresses:t.data&&t.data.addresses?t.data.addresses:[],recurlyPublicKey:t.recurlyPublicKey,editMode:!0,selectedBillingInfoId:n,existingPaymentMethod:{id:e.id,billingInfoId:e.billingInfoId||e.id,cardType:e.cardType,lastFour:e.lastFour,expiryMonth:e.expiryMonth,expiryYear:e.expiryYear,cardholderName:e.cardholderName,billingAddressId:e.billingAddressId},onSuccess:async e=>{console.log("[PaymentMethodsList] ========== EDIT MODAL SUCCESS =========="),console.log("[PaymentMethodsList] Token data received:",JSON.stringify(e,null,2));try{await this.handlePaymentMethodEdit(e,n)}catch(e){throw console.error("[PaymentMethodsList] Edit modal success handler error:",e),e}},onCancel:()=>{console.log("Edit payment modal cancelled")},onAddressNeeded:async()=>{const e=await this.addressApi.getAddresses();let t=[];return e?.addresses&&(t=Array.isArray(e.addresses)?e.addresses:Object.values(e.addresses)),t}}).show()}catch(e){console.error("Failed to open edit payment modal:",e),r.Alert.error("Failed to open edit payment modal. Please try again.")}}async handlePaymentMethodEdit(e,t){try{console.log("[PaymentMethodsList] ========== UPDATING PAYMENT METHOD =========="),console.log("[PaymentMethodsList] Selected billing info:",t),console.log("[PaymentMethodsList] Token data:",JSON.stringify(e,null,2));const n={recurlyToken:e.tokenId,billingInfoId:t,billingAddressId:e.billingAddress.id,default:!1};console.log("[PaymentMethodsList] ð¤ API Payload:",JSON.stringify(n,null,2)),console.log("[PaymentMethodsList] ð¤ API URL:",o.A.apiUpdatePaymentMethodUrl);const i=await fetch(o.A.apiUpdatePaymentMethodUrl,{method:"POST",credentials:"include",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(n)});if(console.log("[PaymentMethodsList] ð¥ Response Status:",i.status,i.statusText),!i.ok){const e=await i.text();throw console.error("[PaymentMethodsList] â Update failed:",e),new Error(`Failed to update payment method: ${i.status} ${i.statusText}`)}const a=await i.json();console.log("[PaymentMethodsList] ð Response result:",JSON.stringify(a,null,2)),console.log("[PaymentMethodsList] ========== RELOADING DATA =========="),this.setState({isLoading:!0}),console.log("[PaymentMethodsList] â³ Waiting 500ms for backend processing..."),await new Promise((e=>setTimeout(e,500))),console.log("[PaymentMethodsList] ð Loading fresh data...");const s=await this.loadData();console.log("[PaymentMethodsList] ð Fresh data loaded:",JSON.stringify(s,null,2)),console.log("[PaymentMethodsList] ð Updating component state..."),this.setState({isLoading:!1,data:s,paymentMethods:s.paymentMethods,addresses:s.addresses}
1),console.log("[PaymentMethodsList] â
State updated - subscription will trigger re-render"),console.log("[PaymentMethodsList] ð Showing success flyout for edit..."),this.showPaymentMethodSuccess(!0),console.log("[PaymentMethodsList] ========== EDIT PAYMENT METHOD COMPLETE ==========")}catch(e){throw console.error("[PaymentMethodsList] â EDIT PAYMENT METHOD FAILED:",e),console.error("[PaymentMethodsList] Error details:",{name:e.name,message:e.message,stack:e.stack}),e}}async handlePaymentMethodAdded(e){this.getState();try{const t={recurlyToken:e.tokenId,cardholderName:e.cardholderName,firstName:e.billingAddress.firstName,lastName:e.billingAddress.lastName,billingAddressId:e.billingAddress.id,saveCard:!0};console.log("Adding payment method:",t);await this.paymentApi.addPaymentMethod(t);this.newlyAddedCardId="newly-added",await this.refresh(),this.showPaymentMethodSuccess(!1),setTimeout((()=>{this.scrollToNewCard()}),300),this.notifyPaymentMethodCountChange()}catch(e){throw console.error("Failed to save payment method:",e),r.Alert.error(e.getUserMessage?e.getUserMessage():h.UU.ADD_FAILED),e}}async confirmRemovePaymentMethod(e){const t=this.getState(),n=t.data&&t.data.paymentMethods?t.data.paymentMethods.find((t=>t.id===e)):null;if(!n)return;await s.Modal.confirm({title:"Remove Payment Method?",message:`\n <div class="space-y-4">\n <p class="text-gray-600">Are you sure you want to remove this payment method?</p>\n\n <div class="bg-gray-50 rounded-lg p-4">\n <div class="flex items-center space-x-3">\n <div class="w-12 h-12 bg-gradient-to-br ${this.getCardGradient(n.cardType)} rounded-lg flex items-center justify-center">\n <span class="text-white text-xs font-bold">****</span>\n </div>\n <div>\n <div class="font-medium text-gray-900">${this.formatCardBrand(n.cardType)} ****${n.lastFour}</div>\n <div class="text-sm text-gray-600">Expires ${n.expiryMonth}/${n.expiryYear}</div>\n </div>\n </div>\n </div>\n\n <div class="bg-amber-50 border border-amber-200 rounded-lg p-3">\n <div class="flex">\n <svg class="w-5 h-5 text-amber-600 mr-2 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />\n </svg>\n <p class="text-sm text-amber-800">This action cannot be undone.</p>\n </div>\n </div>\n </div>\n `,confirmText:"Remove Card",cancelText:"Cancel",confirmClass:"bg-red-600 hover:bg-red-700 text-white"})&&await this.removePaymentMethod(e)}async removePaymentMethod(e){try{await this.paymentApi.deletePaymentMethod(e),await this.refresh(),r.Alert.success(h.PL.METHOD_REMOVED),this.notifyPaymentMethodCountChange()}catch(e){console.error("Failed to remove payment method:",e);let t="[email protected]";try{const{initService:e}=await Promise.resolve().then(n.bind(n,8520)),o=await e.getInitData();o?.generalConfig?.companySupportEmail&&(t=o.generalConfig.companySupportEmail)}catch(e){console.error("Failed to get support email:",e)}await s.Modal.confirm({title:"Remove Payment Method",message:`\n <div class="text-center space-y-6">\n <div class="flex justify-center">\n <div class="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center">\n <svg class="w-8 h-8 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n </div>\n </div>\n\n <p class="text-gray-700">\n To remove a payment method, please contact our customer support team. They will assist you with removing this payment method from your account. Please contact our customer support team at <
1a href="mailto:${t}" class="text-blue-600 hover:text-blue-700 font-medium">${t}</a>\n </p>\n\n <p class="text-sm text-gray-500">\n If this is urgent, you can also call our customer service team directly for immediate assistance.\n </p>\n </div>\n `,confirmText:"Got it",cancelText:"",confirmClass:"bg-blue-600 hover:bg-blue-700 text-white"})}}notifyPaymentMethodCountChange(e=null){const t=this.getState(),n=null!==e?e:t.data&&t.data.paymentMethods?t.data.paymentMethods.length:0;d.ProfileEvents.emit("STATS_UPDATED",{stats:{paymentMethods:n}});const o=new CustomEvent(h.Rt.METHODS_UPDATED,{detail:{count:t.data&&t.data.paymentMethods?t.data.paymentMethods.length:0,methods:t.data&&t.data.paymentMethods?t.data.paymentMethods:[]},bubbles:!0});document.dispatchEvent(o)}getCardGradient(e){const t={visa:"from-blue-600 to-blue-700",mastercard:"from-red-500 to-orange-600",amex:"from-green-600 to-teal-600",discover:"from-orange-500 to-yellow-600",card:"from-gray-600 to-gray-700"};return t[e]||t.card}formatCardBrand(e){return{visa:"Visa",mastercard:"Mastercard",master:"Mastercard",amex:"American Express",american_express:"American Express",discover:"Discover",card:"Card"}[e?.toLowerCase()]||"Card"}scrollToNewCard(){const e=this.container.querySelector(".new-card-highlight");e&&(e.scrollIntoView({behavior:"smooth",block:"center"}),setTimeout((()=>{e.classList.remove("new-card-highlight");const t=e.querySelector(".new-badge");t&&t.remove(),this.newlyAddedCardId=null}),5e3))}async showPaymentMethodSuccess(e=!1){let t="[email protected]";try{const{initService:e}=await Promise.resolve().then(n.bind(n,8520)),o=await e.getInitData();o?.generalConfig?.companySupportEmail&&(t=o.generalConfig.companySupportEmail)}catch(e){console.error("Failed to get support email:",e)}const o=e?"Updated":"Added",i=e?"card has been updated successfully":"new card has been saved successfully",a=document.createElement("div");a.className="payment-success-notification",a.style.cssText="\n position: fixed;\n top: 20px;\n right: 20px;\n max-width: 480px;\n z-index: 10000;\n animation: slideIn 0.3s ease-out;\n ",a.innerHTML=`\n <style>\n @keyframes slideIn {\n from {\n transform: translateX(100%);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n }\n </style>\n <div class="bg-white rounded-lg shadow-xl border border-gray-200 overflow-hidden cursor-pointer hover:shadow-2xl transition-shadow" onclick="\n this.closest('.payment-success-notification').style.animation = 'slideOut 0.3s ease-in forwards';\n setTimeout(() => this.closest('.payment-success-notification').remove(), 300);\n ">\n \x3c!-- Success Header --\x3e\n <div class="bg-gradient-to-r from-green-500 to-green-600 p-4">\n <div class="flex items-center">\n <div class="flex-shrink-0 bg-white/20 backdrop-blur rounded-full p-2 mr-3">\n <svg class="h-6 w-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>\n </svg>\n </div>\n <div class="flex-1">\n <h3 class="text-white font-semibold text-lg">Payment Method ${o}!</h3>\n <p class="text-green-100 text-sm">Your ${i}</p>\n </div>\n <button\n onclick="\n const notification = this.closest('.payment-success-notification');\n notification.style.animation = 'slideOut 0.3s ease-in forwards';\n setTimeout(() => notification.remove(), 300);\n "\n class="text-white/80 hover:text-white transition-colors ml-4"\n >\n <svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>\n </svg>\n </button>\n </div>\n </div>\n\n \x3c!-- Important Information --\x3e\n <div class="p-4 space-y-3">\n \x3c!-- Next Steps --\x3e\n <div class="flex items-start">\n <svg class="h-5 w-5 text-blue-500 mr-2 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>\n </svg>\n <div class="text-sm">\n <p class="font-semibold text-gray-900 mb-1">What's Next?</p>\n <ul class="text-gray-600 space-y-1">\n <li class="flex items-start">
1\n <span class="text-blue-500 mr-1">â¢</span>\n <span>Check your <a href="#invoices" class="text-blue-600 hover:text-blue-700 font-medium">Invoices tab</a> for any outstanding payments</span>\n </li>\n <li class="flex items-start">\n <span class="text-blue-500 mr-1">â¢</span>\n <span>${e?"Your updated card information is now active":"This card can now be used for new subscriptions and purchases"}</span>\n </li>\n </ul>\n </div>\n </div>\n\n \x3c!-- Managing Cards --\x3e\n <div class="flex items-start bg-gray-50 border border-gray-200 rounded-lg p-3">\n <svg class="h-5 w-5 text-gray-600 mr-2 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"></path>\n </svg>\n <div class="text-sm">\n <p class="font-semibold text-gray-800 mb-1">${e?"Need to Remove a Card?":"Need to Update or Remove a Card?"}</p>\n <p class="text-gray-600">${e?"To remove a payment method, please contact our support team at":"To update card details or remove a payment method, please contact our support team at"} <a href="mailto:${t}" class="text-blue-600 hover:text-blue-700 font-medium">${t}</a></p>\n </div>\n </div>\n </div>\n </div>\n `,document.body.appendChild(a);const s=document.createElement("style");s.textContent="\n @keyframes slideOut {\n from {\n transform: translateX(0);\n opacity: 1;\n }\n to {\n transform: translateX(100%);\n opacity: 0;\n }\n }\n ",a.appendChild(s)}async showPaymentMethodAddedSuccess(){return this.showPaymentMethodSuccess(!1)}async onDestroy(){this.cleanupCardInstances(),this.activePaymentModal&&(this.activePaymentModal.hide(),this.activePaymentModal=null),this.isShowingModal=!1}async refresh(){this.activePaymentModal&&(this.activePaymentModal.hide(),this.activePaymentModal=null),this.isShowingModal=!1,await super.refresh()}}t.A=y},3583:function(e,t,n){"use strict";var o=n(8886);t.default=class{constructor(e,t={}){this.impl=new o.A(e,t)}async render(){return this.impl.render()}cleanup(){this.impl.destroy()}destroy(){this.impl.destroy()}async refresh(){return this.impl.refresh()}}},4081:function(e,t,n){"use strict";n.r(t),n.d(t,{default:function(){return l}});var o=n(9935),i=n(7411),a=n(3649),s=n(9632),r=n(5856),d=n(7310);class l{constructor(e){if(this.modalElement=null,this.inlineContainer=null,this.recurlyService=null,this.recurlyElements=null,this.cardElements=null,this.fieldsState={},this.addressModal=null,this.addressesApi=r.A,this.options={addresses:e.addresses||[],recurlyPublicKey:e.recurlyPublicKey||null,onSuccess:e.onSuccess||(()=>Promise.resolve()),onCancel:e.onCancel||(()=>{}),onAddressNeeded:e.onAddressNeeded,inline:e.inline||!1,editMode:e.editMode||!1,isOutstandingInvoiceFlow:e.isOutstandingInvoiceFlow||!1,selectedBillingInfoId:e.selectedBillingInfoId,existingPaymentMethod:e.existingPaymentMethod}
1,console.log("ð PaymentModal received addresses:",this.options.addresses),this.state={currentStep:1,totalSteps:this.options.isOutstandingInvoiceFlow||this.options.editMode?2:3,selectedAddress:null,cardData:{},cardholderName:"",isProcessing:!1,errors:{},isValid:{address:!1,card:!1,review:!1}},this.options.editMode&&this.options.existingPaymentMethod?.billingInfoId){const e=this.options.addresses.find((e=>e.id===this.options.existingPaymentMethod?.billingInfoId));e&&(this.state.selectedAddress=e,this.state.isValid.address=!0)}this.options.editMode&&!this.state.selectedAddress&&this.options.addresses.length>0&&(this.state.selectedAddress=this.options.addresses[0],this.state.isValid.address=!0),this.initializeRecurly()}async initializeRecurly(){if(this.options.recurlyPublicKey)try{this.recurlyService=new o.A({publicKey:this.options.recurlyPublicKey}),await this.recurlyService.initialize(),console.log("â
Recurly initialized")}catch(e){console.error("â Failed to initialize Recurly:",e)}}async show(){if(this.options.inline)throw new Error("Use renderInline() method for inline rendering");if(this.modalElement&&this.modalElement.parentNode)return void console.warn("[PaymentModal] Modal already showing, preventing duplicate");if(!a.J.canOpenModal("payment-modal"))return void console.log("[PaymentModal] Cannot open modal - another modal is active or debouncing");if(this.options.onAddressNeeded&&0===this.options.addresses.length)try{this.options.addresses=await this.options.onAddressNeeded()}catch(e){console.error("Failed to fetch addresses:",e)}if(0===this.options.addresses.filter((e=>e.isBilling||e.isDefaultBilling||e.isAccount)).length&&0===this.options.addresses.length)return console.error("No addresses available for payment method"),void(this.options.onCancel&&this.options.onCancel());if(!this.state.selectedAddress&&this.options.addresses.length>0){const e=this.options.addresses.find((e=>e.isDefaultBilling));e?(this.state.selectedAddress=e,this.state.isValid.address=!0):1===this.options.addresses.length&&(this.state.selectedAddress=this.options.addresses[0],this.state.isValid.address=!0)}a.J.registerModal(this,"payment-modal")?(this.createModal(),this.attachEventListeners(),document.body.classList.add("overflow-hidden")):console.log("[PaymentModal] Failed to register modal")}hide(){if(this.recurlyElements)try{this.recurlyElements=null}catch(e){console.warn("Error cleaning up Recurly elements:",e)}if(this.options.inline&&this.inlineContainer)return this.inlineContainer.innerHTML="",void(this.inlineContainer=null);a.J.unregisterModal(this),this.modalElement&&this.modalElement.parentNode&&this.modalElement.remove(),this.modalElement=null,document.body.classList.remove("overflow-hidden")}async renderInline(e){if(!this.options.inline)throw new Error("Set inline: true in options to use renderInline() method");if(this.inlineContainer=e,this.options.onAddressNeeded&&0===this.options.addresses.length)try{this.options.addresses=await this.options.onAddressNeeded()}catch(e){console.error("Failed to fetch addresses:",e)}if(0===this.options.addresses.filter((e=>e.isBilling||e.isDefaultBilling||e.isAccount)).length&&0===this.options.addresses.length)return console.error("No addresses available for payment method"),void(e.innerHTML='\n <div class="text-center py-8 text-gray-600">\n <p>Please add a billing address first.</p>\n </div>\n ');if(!this.state.selectedAddress&&this.options.addresses.length>0){const e=this.options.addresses.find((e=>e.isDefaultBilling));e?(this.state.selectedAddress=e,this.state.isValid.address=!0):1===this.options.addresses.length&&(this.state.selectedAddress=this.options.addresses[0],this.state.isValid.address=!0)}this.state.currentStep=2,this.state.totalSteps=2,e.innerHTML=`\n <div class="payment-modal-inline">\n \x3c!-- Header --\x3e\n \x3c!-- Header removed for cleaner UI --\x3e\n <div class="mb-4"></div>\n\n \x3c!-- Content --\x3e\n <div id="step-content" class="transition-opacity duration-200">\n ${this.renderCurrentStep()}\n </div>\n\n \x3c!-- Actions - Hidden in inline mode, parent handles navigation --\x3e\n <div id="modal-actions" class="hidden">\n </div>\n </div>\n `,document.querySelector("style[data-recurly-styles]")||this.addRecurlyStyles(),setTimeout((()=>this.initializeRecurlyElements()),100),this.attachInlineEventListeners()}createModal(){this.modalElement=document.createElement("div"),this.modalElement.className="fixed inset-0 z-50 flex items-center justify-center p-4",this.modalElement.innerHTML=`\n \x3c!-- Backdrop --\x3e\n <div class="absolute inset-0 bg-black/50 backdrop-blur-sm transition-opacity duration-300" data-action="backdrop"></div>\n\n \x3c!-- Modal --\x3e\n <div class="relative bg-white rounded-2xl shadow-2xl w-full max-w-2xl max-h-[90vh] flex flex-col transform transition-all duration-300 scale-95 opacity-0">\n \x3c!-- Header with Progress --\x3e\n <div class="px-6 pt-6 pb-4 border-b border-gray-200">\n <div class="flex items-center justify-between mb-4">\n <h2 class="text-xl font-bold text-gray-900">${this.options.editMode?"Update Payment Method":"Add Payment Method"}</h2>\n <button class="p-2 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg transition-colors" data-action="close">\n ${i.H.render("x",{class:"w-5 h-5"})}\n </button>\n </div>\n\n \x3c!-- Progress Bar Container --\x3e\n <div class="progress-bar-container">\n <div class="flex items-center justify-between">\n ${this.renderProgressBar()}\n </div>\n </div>\n </div>\n\n \x3c!-- Content --\x3e\n <div class="flex-1 overflow-y-auto overflow-x-hidden p-6">
1\n <div id="step-content" class="transition-opacity duration-200">\n ${this.renderCurrentStep()}\n </div>\n </div>\n\n \x3c!-- Footer --\x3e\n <div id="modal-actions" class="px-6 py-4 bg-gray-50 border-t border-gray-200 rounded-b-2xl">\n <div class="flex justify-between items-center">\n <button\n id="back-button"\n class="flex items-center px-4 py-2 text-gray-700 hover:text-gray-900 transition-colors ${1===this.state.currentStep?"invisible":""}"\n data-action="back"\n >\n ${i.H.render("chevron-left",{class:"w-4 h-4 mr-2"})}\n Back\n </button>\n\n <div class="flex items-center space-x-3">\n <button class="px-4 py-2 text-gray-700 hover:text-gray-900 hover:bg-gray-100 rounded-lg transition-colors" data-action="cancel">\n Cancel\n </button>\n <button\n id="continue-button"\n class="relative px-6 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 flex items-center"\n data-action="continue"\n ${this.canContinue()?"":"disabled"}\n >\n <span class="continue-text">${this.getContinueButtonText()}</span>\n ${i.H.render("chevron-right",{class:"w-4 h-4 ml-2 continue-arrow"})}\n <div class="continue-spinner hidden items-center">\n ${i.H.render("loader",{class:"animate-spin h-5 w-5 mr-2"})}\n <span>${this.options.editMode?"Updating Payment Method...":"Adding Payment Method..."}</span>\n </div>\n </button>\n </div>\n </div>\n </div>\n </div>\n `,document.body.appendChild(this.modalElement),requestAnimationFrame((()=>{const e=this.modalElement.querySelector(".relative");this.modalElement.querySelector('[data-action="backdrop"]').classList.add("opacity-100"),e.classList.remove("scale-95","opacity-0"),e.classList.add("scale-100","opacity-100")})),2===this.state.currentStep&&setTimeout((()=>this.initializeRecurlyElements()),100)}renderProgressBar(){const e=this.options.isOutstandingInvoiceFlow||this.options.editMode?[{number:1,title:"Billing Address"},{number:2,title:this.options.editMode?"Card Details":"Payment & Settlement"}]:[{number:1,title:"Billing Address"},{number:2,title:"Card Details"},{number:3,title:"Review"}];return e.map(((t,n)=>{const o=t.number===this.state.currentStep,a=t.number<this.state.currentStep,s=n===e.length-1;return`\n <div class="flex items-center ${s?"":"flex-1"}" key="step-${t.number}">\n <div class="flex items-center relative">\n <div class="flex items-center justify-center w-10 h-10 rounded-full border-2 transition-all duration-300\n ${o?"bg-primary-600 border-primary-600 text-white shadow-lg shadow-primary-600/30":a?"bg-green-500 border-green-500 text-white":"bg-white border-gray-300 text-gray-600"}">\n ${a?i.H.render("check",{class:"w-5 h-5"}):`\n <span class="text-sm font-bold">${t.number}</span>\n `}\n </div>\n <span class="ml-3 text-sm font-medium whitespace-nowrap\n ${o?"text-gray-900":a?"text-green-600":"text-gray-500"}">\n ${t.title}\n </span>\n </div>\n ${s?"":`\n <div class="mx-4 flex-1">\n <div class="h-1 bg-gray-200 rounded-full relative">\n <div class="absolute inset-0 h-full bg-green-500 rounded-full transition-all duration-500 ease-out"\n style="width: ${a?"100%":"0%"}"></div>\n </div>\n </div>\n `}\n </div>\n `})).join("")}renderCurrentStep(){switch(this.state.currentStep){case 1:return this.renderAddressStep();case 2:return this.options.editMode,this.renderCardStep();case 3:return this.renderReviewStep();default:return""}}renderAddressStep(){const e=this.options.addresses||[],t=d.default.isCabotWealth();if(!this.state.selectedAddress&&e.length>0){const t=e.find((e=>e.isDefaultBilling));t?(this.state.selectedAddress=t,this.state.isValid.address=!0):1===e.length&&(this.state.selectedAddress=e[0],this.state.isValid.address=!0)}if(0===e.length)return`\n <div class="text-center py-12">\n <div class="mx-auto w-24 h-24 bg-gray-100 rounded-full flex items-center justify-center mb-4">\n ${i.H.render("map-pin",{class:"w-12 h-12 text-gray-400"})}\n </div>\n <h3 class="text-lg font-medium text-gray-900 mb-2">No Billing Address Found</h3>\n <p class="text-gray-600 mb-6">You need a billing address to add a payment method. Create one now to continue.</p>\n\n <div class="flex flex-col sm:flex-row gap-3 justify-center">\n <button id="add-address-btn" class="inline-flex items-center px-6 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors font-medium shadow-md hover:shadow-lg"\n data-action="add-address">\n ${i.H.render("plus",{class:"w-5 h-5 mr-2"})}\n Add Billing Address\n </button>\n\n <button class="inline-flex items-center px-4 py-3 text-gray-700 hover:text-gray-900 transition-colors font-medium"\n onclick="window.location.href='/profile/addresses'">\n ${i.H.render("clipboard",{class:"w-5 h-5 mr-2"})}\n Manage in Profile\n </button>\n </div>\n\n \x3c!-- Inline Address Form (Initially Hidden) --\x3e\n <div id="inline-address-form" class="hidden mt-8 max-w-md mx-auto text-left">\n <div class="bg-gray-50 rounded-lg p-6 border border-gray-200">\n <h4 class="text-lg font-medium text-gray-900 mb-4">Add Billing Address</h4>\n\n <form class="space-y-4">\n <div class="grid grid-cols-2 gap-4">\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-1">First Name</label>\n <input type="text" id="addr-first-name" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500" required>\n </div>\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-1">Last Name</label>\n <input type="text" id="addr-last-name" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500" required>\n </div>\n </div>\n\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-1">Street Address</label>\n <input type="text" id="addr-street1" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500" required>\n </div>\n\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-1">Apartment, suite, etc. (optional)</label>\n <input type="text" id="addr-street2" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500">\n </div>\n\n <div class="grid grid-cols-2 gap-4">\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-1">City</label>\n <input type="text" id="addr-city" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500" required>\n </div>\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-1">State/Province</label>\n <input type="text" id="addr-region" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500" required>\n </div>\n </div>\n\n <div class="grid grid-cols-2 gap-4">\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-1">Postal Code</label>\n <input type="text" id="addr-postal-code" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500" required>\n </div>\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-1">Country</label>\n <select id="addr-country" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500" required>\n <option value="US">United States</option>\n <option value="CA">Canada</option>\n <option value="GB">United Kingdom</option>\n <option value="IE">Ireland</option>\n <option value="AU">Australia</option>\n <option value="NZ">New Zealand</option>\n </select>\n </div>\n </div>\n\n <div class="flex items-center">\n <input type="checkbox" id="addr-set-default" class="h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300 rounded" checked>\n <label for="addr-set-default" class="ml-2 block text-sm text-gray-700">Set as default billing address</label>\n </div>\n\n <div class="flex items-center pt-4 space-x-3">\n <button type="button" id="save-address-btn" class="flex-1 bg-primary-600 text-white px-4 py-2 rounded-lg hover:bg-primary-700 transition-colors font-medium disabled:opacity-50" disabled>\n Save Address\n </button>\n <button type="button" class="px-4 py-2 text-gray-700 hover:text-gray-900 transition-colors" data-action="cancel-add-address">\n Cancel\n </button>\n </div>\n </form>\n </div>\n </div>\n </div>\n `;return`\n <div>\n <div class="mb-6">\n <h3 class="text-lg font-semibold text-gray-900 mb-2">Select Billing Address</h3>\n <p class="text-sm text-gray-600">
1${t?"Fill in the information below":"Choose the billing address for your payment method"}</p>\n </div>\n\n <div class="space-y-3 mb-6">\n ${this.sortAddresses(e).map((e=>this.renderAddressCard(e))).join("")}\n\n \x3c!-- Add New Address Option --\x3e\n <div class="border-2 border-dashed border-gray-300 rounded-lg p-4 hover:border-primary-400 transition-colors cursor-pointer group"\n id="add-new-address-card" data-action="add-address">\n <div class="flex items-center space-x-3">\n <div class="w-10 h-10 bg-gray-100 rounded-full flex items-center justify-center group-hover:bg-primary-100 transition-colors">\n ${i.H.render("plus",{class:"w-5 h-5 text-gray-600 group-hover:text-primary-600"})}\n </div>\n <div>\n <h4 class="font-medium text-gray-900 group-hover:text-primary-700 transition-colors">Add New Address</h4>\n <p class="text-sm text-gray-500">Create a new billing address for this payment method</p>\n </div>\n </div>\n </div>\n </div>\n\n \x3c!-- Inline Address Form Container --\x3e\n <div id="inline-address-form-container" class="hidden mb-6"></div>\n\n \x3c!-- Security Note --\x3e\n <div class="bg-blue-50 border border-blue-200 rounded-lg p-4 flex items-start">\n ${i.H.render("lock",{class:"w-5 h-5 text-blue-600 mt-0.5 mr-3 flex-shrink-0"})}\n <div class="flex-1">\n <h4 class="text-sm font-medium text-blue-900">Secure Payment</h4>\n <p class="text-sm text-blue-700 mt-1">Your payment information is encrypted and secure. We never store your full card details.</p>\n </div>\n </div>\n </div>\n `}renderAddressCard(e){const t=this.state.selectedAddress?.id===e.id;return`\n <label class="block cursor-pointer" data-address-id="${e.id}">\n <input type="radio" name="billing-address" value="${e.id}" ${t?"checked":""} class="sr-only">\n\n <div class="relative border-2 rounded-lg p-4 transition-all duration-200\n ${t?"border-primary-600 bg-primary-50 shadow-md":"border-gray-200 hover:border-gray-300 hover:shadow-sm"}">\n\n \x3c!-- Selection Indicator --\x3e\n <div class="absolute top-4 right-4">\n <div class="w-6 h-6 rounded-full border-2 transition-all duration-200 flex items-center justify-center\n ${t?"border-primary-600 bg-primary-600":"border-gray-300 bg-white"}">\n ${t?i.H.render("check",{class:"w-4 h-4 text-white"}):""}\n </div>\n </div>\n\n <div class="pr-10">\n <div class="flex items-center mb-2">\n <h4 class="font-semibold text-gray-900">${e.firstName} ${e.lastName}</h4>\n ${this.renderAddressBadges(e)}\n </div>\n\n <div class="text-sm text-gray-600 space-y-1">\n <p>${e.street1}${e.street2?`, ${e.street2}`:""}</p>\n <p>${e.city}, ${e.region} ${e.postalCode}</p>\n <p>${this.getCountryName(e.country)}</p>\n </div>\n </div>\n </div>\n </label>\n `}renderAddressBadges(e){const t=[];return e.isDefaultBilling?t.push('<span class="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">Default Billing</span>'):e.isBilling&&t.push('<span class="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">Billing</span>'),e.isAccount&&t.push('<span class="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-secondary-100 text-secondary-800">Primary</span>'),t.join("")}renderCardStep(){return this.state.selectedAddress?`\n <div>\n \x3c!-- Payment details header hidden for cleaner UI --\x3e\n <div class="mb-4"></div>\n\n \x3c!-- Selected Address Summary --\x3e\n <div class="bg-gradient-to-r from-gray-50 to-gray-100 rounded-lg p-4 mb-6 border border-gray-200">\n <div class="flex items-start justify-between">\n <div class="flex items-start">\n <div class="p-2 bg-white rounded-lg shadow-sm mr-3">\n ${i.H.render("map-pin",{class:"w-5 h-5 text-gray-600"})}\n </div>\n <div>\n <h4 class="text-sm font-medium text-gray-700 mb-1">Billing Address</h4>\n <p class="text-sm text-gray-600">
1\n <span class="font-medium">${this.state.selectedAddress.firstName} ${this.state.selectedAddress.lastName}</span><br>\n ${this.state.selectedAddress.street1}${this.state.selectedAddress.street2?`, ${this.state.selectedAddress.street2}`:""}<br>\n ${this.state.selectedAddress.city}, ${this.state.selectedAddress.region} ${this.state.selectedAddress.postalCode}\n </p>\n </div>\n </div>\n <div class="bg-green-100 rounded-full p-1">\n ${i.H.render("check",{class:"w-5 h-5 text-green-600"})}\n </div>\n </div>\n </div>\n\n \x3c!-- Card Form --\x3e\n <form class="space-y-4">\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-2">Card Number</label>\n <div id="recurly-card-number" class="recurly-element w-full border border-gray-300 rounded-lg overflow-hidden bg-white" style="min-height: 44px;"></div>\n <p class="mt-1 text-sm text-red-600 hidden" data-error="number"></p>\n </div>\n\n <div class="grid grid-cols-2 gap-4">\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-2">Expiration Date</label>\n <div class="flex items-center gap-1 border border-gray-300 rounded-lg bg-white px-1" style="min-height: 44px;">\n <div class="flex-1">\n <div id="recurly-card-month" class="recurly-element w-full" style="min-height: 42px; border: none !important;"></div>\n </div>\n <span class="text-gray-400 text-lg font-medium px-1">/</span>\n <div class="flex-1">\n <div id="recurly-card-year" class="recurly-element w-full" style="min-height: 42px; border: none !important;"></div>\n </div>\n </div>\n <p class="mt-1 text-sm text-red-600 hidden" data-error="month"></p>\n <p class="mt-1 text-sm text-red-600 hidden" data-error="year"></p>\n <p class="mt-1 text-xs text-gray-500">Format: MM / YY (e.g., 12 / 25)</p>\n </div>\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-2">Security Code</label>\n <div id="recurly-card-cvv" class="recurly-element w-full border border-gray-300 rounded-lg overflow-hidden bg-white relative" style="min-height: 44px;">\n <div class="absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none text-gray-400">\n ${i.H.render("info",{class:"w-4 h-4"})}\n </div>\n </div>\n <p class="mt-1 text-sm text-red-600 hidden" data-error="cvv"></p>\n <p class="mt-1 text-xs text-gray-500">3 or 4 digits on back of card</p>\n </div>\n </div>\n\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-2">Cardholder Name</label>\n <input\n type="text"\n id="cardholder-name"\n class="w-full px-3 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500 transition-all"\n value="${this.state.selectedAddress.firstName} ${this.state.selectedAddress.lastName}"\n placeholder="Name on card"\n >\n <p class="mt-1 text-sm text-red-600 hidden" data-error="cardholder"></p>\n </div>\n </form>\n\n \x3c!-- Security Features --\x3e\n <div class="mt-6 flex items-center justify-center space-x-6 text-gray-500">\n <div class="flex items-center text-sm">\n ${i.H.render("shield-check",{class:"w-5 h-5 mr-2"})}\n PCI Compliant\n </div>\n <div class="flex items-center text-sm">\n ${i.H.render("lock",{class:"w-5 h-5 mr-2"})}\n 256-bit SSL Encryption\n </div>\n </div>\n\n \x3c!-- Accepted Cards --\x3e\n <div class="mt-6 pt-6 border-t border-gray-200">\n <p class="text-xs text-gray-500 text-center mb-3">We accept</p>\n <div class="flex items-center justify-center space-x-3">\n ${this.renderCardBrands()}\n </div>\n </div>\n </div>\n `:'<p class="text-red-600">No address selected</p>'}renderCardBrands(){return[{name:"Visa",logo:'<svg class="h-6 w-auto" viewB
1ox="0 0 40 24" xmlns="http://www.w3.org/2000/svg">\n <rect width="40" height="24" rx="4" fill="#1434CB"/>\n <text x="20" y="16" text-anchor="middle" fill="white" font-family="Arial, sans-serif" font-size="10" font-weight="bold">VISA</text>\n </svg>'},{name:"Mastercard",logo:'<svg class="h-6 w-auto" viewBox="0 0 40 24" xmlns="http://www.w3.org/2000/svg">\n <rect width="40" height="24" rx="4" fill="#EB001B"/>\n <circle cx="15" cy="12" r="7" fill="#FF5F00"/>\n <circle cx="25" cy="12" r="7" fill="#F79E1B"/>\n <circle cx="20" cy="12" r="7" fill="#FF5F00" fill-opacity="0.8"/>\n </svg>'},{name:"Amex",logo:'<svg class="h-6 w-auto" viewBox="0 0 40 24" xmlns="http://www.w3.org/2000/svg">\n <rect width="40" height="24" rx="4" fill="#006FCF"/>\n <text x="20" y="16" text-anchor="middle" fill="white" font-family="Arial, sans-serif" font-size="8" font-weight="bold">AMEX</text>\n </svg>'}].map((e=>`\n <div class="h-12 w-20 bg-white border border-gray-200 rounded-lg flex items-center justify-center shadow-sm"\n data-brand="${e.name.toLowerCase()}">\n ${e.logo}\n </div>\n `)).join("")}renderReviewStep(){if(!this.state.selectedAddress)return'<p class="text-red-600">No address selected</p>';const e=d.default.isCabotWealth();return`\n <div>\n <div class="mb-6">\n <h3 class="text-lg font-semibold text-gray-900 mb-2">${e?"Review and Submit":"Review & Confirm"}</h3>\n ${e?"":'<p class="text-sm text-gray-600">Please review your payment information before confirming</p>'}\n </div>\n\n \x3c!-- Billing Address Review --\x3e\n <div class="bg-gray-50 rounded-lg p-4 mb-4">\n <div class="flex items-center justify-between mb-3">\n <h4 class="text-sm font-medium text-gray-700 flex items-center">\n ${i.H.render("map-pin",{class:"w-4 h-4 mr-2 text-gray-400"})}\n Billing Address\n </h4>\n <button type="button" class="text-primary-600 hover:text-primary-700 text-sm font-medium" data-action="edit-address">\n Edit\n </button>\n </div>\n <div class="bg-white rounded-lg p-4 border border-gray-200">\n <p class="font-medium text-gray-900">${this.state.selectedAddress.firstName} ${this.state.selectedAddress.lastName}</p>\n <p class="text-sm text-gray-600 mt-1">\n ${this.state.selectedAddress.street1}${this.state.selectedAddress.street2?`, ${this.state.selectedAddress.street2}`:""}<br>\n ${this.state.selectedAddress.city}, ${this.state.selectedAddress.region} ${this.state.selectedAddress.postalCode}<br>\n ${this.getCountryName(this.state.selectedAddress.country)}\n </p>\n </div>\n </div>\n\n \x3c!-- Payment Method Review --\x3e\n <div class="bg-gray-50 rounded-lg p-4 mb-6">\n <div class="flex items-center justify-between mb-3">\n <h4 class="text-sm font-medium text-gray-700 flex items-center">\n ${i.H.render("credit-card",{class:"w-4 h-4 mr-2 text-gray-400"})}\n Payment Method\n </h4>\n <button type="button" class="text-primary-600 hover:text-primary-700 text-sm font-medium" data-action="edit-card">\n Edit\n </button>\n </div>\n <div class="bg-white rounded-lg p-4 border border-gray-200">\n <div class="flex items-center justify-between">\n <div class="flex items-center">\n <div class="w-12 h-8 bg-gradient-to-br ${this.getCardGradient(this.state.cardData.type)} rounded flex items-center justify-center text-white text-xs font-bold mr-3">\n ${this.getCardBrandShort(this.state.cardData.type)}\n </div>\n <div>\n <p class="font-medium text-gray-900">\n ${this.getCardBrandName(this.state.cardData.type)} ending in ${this.state.cardData.last4||"****"}\n </p>\n <p class="text-sm text-gray-600">\n ${this.state.cardholderName||`${this.state.selectedAddress.firstName} ${this.state.selectedAddress.lastName}`}\n </p>\n </div>\n </div>\n <div class="text-right">\n <p class="text-sm text-gray-600">Expires</p>\n <p class="font-medium text-gray-900">\n ${this.state.cardData.month||"**"}/${this.state.cardData.year||"**"}\n </p>\n </div>\n </div>\n </div>\n </div>\n\n \x3c!-- Terms and Conditions --\x3e\n <div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">\n <label class="flex items-start">\n <input type="checkbox" id="agree-terms" class="mt-1 h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300 rounded">
1\n <span class="ml-3 text-sm">\n <span class="text-blue-900 font-medium">I agree to the terms and conditions</span>\n <p class="text-blue-700 mt-1">\n By confirming, you authorize us to charge your payment method for any applicable fees.\n You can update or remove your payment method at any time.\n </p>\n </span>\n </label>\n </div>\n\n \x3c!-- Security Notes --\x3e\n <div class="grid grid-cols-1 md:grid-cols-3 gap-4 text-center text-sm text-gray-500">\n <div class="flex flex-col items-center">\n ${i.H.render("shield-check",{class:"w-8 h-8 text-green-500 mb-2"})}\n <span>Secure Payment</span>\n </div>\n <div class="flex flex-col items-center">\n ${i.H.render("lock",{class:"w-8 h-8 text-green-500 mb-2"})}\n <span>PCI Compliant</span>\n </div>\n <div class="flex flex-col items-center">\n ${i.H.render("zap",{class:"w-8 h-8 text-green-500 mb-2"})}\n <span>Instant Processing</span>\n </div>\n </div>\n </div>\n `}attachEventListeners(){console.log("ð Attaching event listeners to modal"),this.modalElement.addEventListener("click",(e=>{const t=e.target,n=t.dataset.action||t.closest("[data-action]")?.getAttribute("data-action");switch(console.log("ð±ï¸ Click event, action:",n),n){case"close":case"cancel":case"backdrop":this.handleCancel();break;case"back":this.goBack();break;case"continue":console.log("ð Continue button clicked!"),this.handleContinue();break;case"edit-address":console.log("Edit address clicked from step",this.state.currentStep,", moving to step 1"),this.state.previousStep=this.state.currentStep,this.state.currentStep=1,this.updateModal();break;case"edit-card":console.log("Edit card clicked from step",this.state.currentStep,", moving to step 2"),this.state.previousStep=this.state.currentStep,this.state.currentStep=2,this.updateModal();break;case"add-address":this.showAddressForm();break;case"cancel-add-address":this.hideAddressForm()}})),this.modalElement.addEventListener("change",(e=>{const t=e.target;if("billing-address"===t.name){const e=t.value;this.state.selectedAddress=this.options.addresses.find((t=>t.id===e))||null,this.state.isValid.address=!0,this.updateContinueButton(!0);this.modalElement.querySelectorAll("[data-address-id]").forEach((t=>{const n=t,o=n.dataset.addressId===e,i=n.querySelector(".relative.border-2"),a=n.querySelector(".absolute.top-4.right-4 > div"),s=a.querySelector("svg");o?(i.classList.remove("border-gray-200","hover:border-gray-300","hover:shadow-sm"),i.classList.add("border-primary-600","bg-primary-50","shadow-md"),a.classList.remove("border-gray-300","bg-white"),a.classList.add("border-primary-600","bg-primary-600"),s&&(s.style.display="block")):(i.classList.remove("border-primary-600","bg-primary-50","shadow-md"),i.classList.add("border-gray-200","hover:border-gray-300","hover:shadow-sm"),a.classList.remove("border-primary-600","bg-primary-600"),a.classList.add("border-gray-300","bg-white"),s&&(s.style.display="none"))}))}"agree-terms"===t.id&&this.updateContinueButton(t.checked)}));const e=this.modalElement.querySelector("#cardholder-name");e&&e.addEventListener("input",(()=>{const t=e.value.trim().length>2,n=this.modalElement.querySelector('[data-error="cardholder"]');n&&(t?n.classList.add("hidden"):(n.classList.remove("hidden"),n.textContent="Please enter cardholder name"))}))}updateInline(){if(!this.inlineContainer)return;const e=this.inlineContainer.querySelector("#step-content");e&&(this.updateInlineButtons(),e.style.opacity="0",setTimeout((()=>{if(e.innerHTML=this.renderCurrentStep(),e.style.opacity="1",2===this.state.currentStep&&setTimeout((()=>this.initializeRecurlyElements()),100),2===this.state.currentStep){const e=this.inlineContainer.querySelector("#cardholder-name");e&&(this.state.cardholderName&&(e.value=this.state.cardholderName),e.addEventListener("input",(()=>{const t=e.value.trim().length>2,n=this.inlineContainer.querySelector('[data-error="cardholder"]');
1n&&(t||0===e.value.trim().length?n.classList.add("hidden"):(n.classList.remove("hidden"),n.textContent="Please enter cardholder name")),this.cardElements&&this.checkCardValidity()})))}else if(3===this.state.currentStep){const e=this.inlineContainer.querySelector("#agree-terms");e&&(e.checked=!1)}}),200))}updateInlineButtons(){const e=this.inlineContainer.querySelector("#back-button"),t=this.inlineContainer.querySelector("#continue-button"),n=t?.querySelector(".continue-text");if(console.log("ð§ updateInlineButtons called, current step:",this.state.currentStep),e&&e.classList.toggle("invisible",2===this.state.currentStep),t&&(t.disabled=!this.canContinue(),n)){const e=this.getContinueButtonText();console.log("ð Setting button text to:",e),n.textContent=e}}attachInlineEventListeners(){if(console.log("ð Attaching inline event listeners"),!this.inlineContainer)return;this.inlineContainer.addEventListener("click",(e=>{const t=e.target,n=t.dataset.action||t.closest("[data-action]")?.getAttribute("data-action");switch(console.log("ð±ï¸ Inline click event, action:",n),n){case"cancel":this.options.onCancel&&this.options.onCancel(),this.hide();break;case"back":this.goBack();break;case"continue":console.log("ð Continue button clicked in inline mode!"),this.handleContinue();break;case"edit-address":console.log("Edit address clicked from step",this.state.currentStep,", moving to step 1"),this.state.previousStep=this.state.currentStep,this.state.currentStep=1,this.updateInline();break;case"edit-card":console.log("Edit card clicked from step",this.state.currentStep,", moving to step 2"),this.state.previousStep=this.state.currentStep,this.state.currentStep=2,this.updateInline()}})),this.inlineContainer.addEventListener("change",(e=>{const t=e.target;"agree-terms"===t.id&&this.updateContinueButton(t.checked)}));const e=this.inlineContainer.querySelector("#cardholder-name");e&&e.addEventListener("input",(()=>{const t=e.value.trim().length>2,n=this.inlineContainer.querySelector('[data-error="cardholder"]');n&&(t?n.classList.add("hidden"):(n.classList.remove("hidden"),n.textContent="Please enter cardholder name")),this.cardElements&&this.checkCardValidity()}))}initializeRecurlyElements(){if(this.recurlyService&&this.recurlyService.isInitialized)try{this.recurlyElements=this.recurlyService.recurly.Elements();const e={fontSize:"16px",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',padding:"12px",color:"#1f2937",fontWeight:"400",lineHeight:"1.5",backgroundColor:"transparent"},t=this.recurlyElements.CardNumberElement({style:e,placeholder:"1234 5678 9012 3456"}),n=this.recurlyElements.CardMonthElement({style:e,placeholder:"MM"}),o=this.recurlyElements.CardYearElement({style:e,placeholder:"YY"}),i=this.recurlyElements.CardCvvElement({style:e,placeholder:"123"});t.attach("#recurly-card-number"),n.attach("#recurly-card-month"),o.attach("#recurly-card-year"),i.attach("#recurly-card-cvv");let a={};const s=()=>{const e=Object.values(a).every((e=>e.valid||e.empty)),t=a.number&&!a.number.empty&&a.month&&!a.month.empty&&a.year&&!a.year.empty&&a.cvv&&!a.cvv.empty,n=this.modalElement||this.inlineContainer,o=n?.querySelector("#cardholder-name"),i=o&&o.value.trim().length>=3;this.state.isValid.card=e&&t&&i,this.updateContinueButton(this.state.isValid.card),console.log("Current card data:",this.state.cardData)};t.on("change",(e=>{console.log("Card number state:",e),a.number=e,e.brand?this.state.cardData.type=e.brand.id||e.brand:e.card&&e.card.type&&(this.state.cardData.type=e.card.type),e.lastFour?this.state.cardData.last4=e.lastFour:e.last_four&&(this.state.cardData.last4=e.last_four),this.state.cardData.type&&this.highlightCardBrand(this.state.cardData.type),this.updateFieldError("number",e),s()})),n.on("change",(e=>{console.log("Month state:",e),a.month=e,e.valid&&!e.empty&&(this.state.cardData.monthEntered=!0,this.state.cardData.month="MM",console.log("â
Month field is valid")),this.updateFieldError("month",e),s()})),o.on("change",(e=>{console.log("Year state:",e),a.year=e,e.valid&&!e.empty&&(this.state.cardData.yearEntered=!0,this.state.cardData.year="YY",console.log("â
Year field is valid")),this.updateFieldError("year",e),s()})),i.on("change",(e=>{a.cvv=e,this.updateFieldError("cvv",e),s()})),this.cardElements={cardNumber:t,cardMonth:n,cardYear:o,cardCvv:i},this.fieldsState=a,this.addRecurlyStyles()}catch(e){console.error("Failed to initialize Recurly elements:",e)}else console.error("Recurly service not initialized")}checkCardValidity(){if(!this.fieldsState)return;const e=Object.values(this.fieldsState).every((e=>e.valid||e.empty)),t=this.fieldsState.number&&!this.fieldsState.number.empty&&this.fieldsState.month&&!this.fieldsState.month.empty&&this.fieldsState.year&&!this.fieldsState.year.empty&&this.fieldsState.cvv&&!this.fieldsState.cvv.empty,n=this.modalElement||this.inlineContainer,o=n?.querySelector("#cardholder-name"),i=o&&o.value.trim().length>=3;this.state.isValid.card=e&&t&&i,this.updateContinueButton(this.state.isValid.card)}updateFieldError(e,t){const n=this.modalElement||this.inlineContainer,o=n?.querySelector(`[data-error="${e}"]`),i=n?.querySelector(`#recurly-card-${"number"===e?"number":e}`);o&&(t.valid||t.empty?(o.classList.add("hidden"),o.textContent="",i&&(i.classList.remove("border-red-500","focus-within:ring-red-500"),i.classList.add("border-gray-300"))):(o.classList.remove("hidden"),o.textContent=this.getFieldErrorMessage(e),i&&(i.classList.remove("border-gray-300"),i.classList.add("border-red-500","focus-within:ring-red-500"))))}highlightCardBrand(e){const t=this.modalElement||this.inlineContainer;
1(t?.querySelectorAll("[data-brand]")||[]).forEach((t=>{const n=t;n.dataset.brand===e?(n.classList.remove("opacity-50"),n.classList.add("opacity-100","scale-110")):(n.classList.add("opacity-50"),n.classList.remove("opacity-100","scale-110"))}))}updateModal(){const e=this.modalElement.querySelector("#step-content"),t=this.modalElement.querySelector(".progress-bar-container > div");t&&(t.innerHTML=this.renderProgressBar()),this.updateButtons();const n=e.innerHTML.includes("recurly-card-number");console.log("UpdateModal - Current step:",this.state.currentStep,"Has Recurly:",n);const o=2===this.state.currentStep&&3===this.state.previousStep;if(n&&2!==this.state.currentStep&&!o){console.log("Branch 1: Preserving Recurly elements"),e.querySelectorAll("[data-step]").forEach((e=>{e.style.display="none"})),e.querySelectorAll(":scope > div:not([data-step])").forEach((e=>{e.style.display="none"}));const t=e.querySelector(`[data-step="${this.state.currentStep}"]`);if(t)t.style.display="block";else{const t=document.createElement("div");t.setAttribute("data-step",String(this.state.currentStep)),t.innerHTML=this.renderCurrentStep(),t.style.display="block",e.appendChild(t)}}else console.log("Branch 2: Normal flow"),e.style.opacity="0",setTimeout((()=>{o&&(console.log("Force re-rendering step 2 for editing"),e.innerHTML="",this.cardElements=null,this.fieldsState={});const t=e.querySelector(`[data-step="${this.state.currentStep}"]`);if(console.log("Looking for hidden step:",this.state.currentStep,"Found:",!!t),t&&!o?(console.log("Showing existing hidden step"),e.querySelectorAll("[data-step]").forEach((e=>{const t=e;t.style.display=t.getAttribute("data-step")===String(this.state.currentStep)?"block":"none"}))):e.innerHTML=this.renderCurrentStep(),e.style.opacity="1",2!==this.state.currentStep||n&&!o||setTimeout((()=>this.initializeRecurlyElements()),100),1===this.state.currentStep){if(this.state.selectedAddress){const e=this.modalElement.querySelector(`input[name="billing-address"][value="${this.state.selectedAddress.id}"]`);e&&(e.checked=!0,e.dispatchEvent(new Event("change",{bubbles:!0})))}}else if(2===this.state.currentStep){const e=this.modalElement.querySelector("#cardholder-name");e&&(this.state.cardholderName&&(e.value=this.state.cardholderName),e.addEventListener("input",(()=>{const t=e.value.trim().length>2,n=this.modalElement.querySelector('[data-error="cardholder"]');n&&(t||0===e.value.trim().length?n.classList.add("hidden"):(n.classList.remove("hidden"),n.textContent="Please enter cardholder name")),this.cardElements&&this.checkCardValidity()})))}else if(3===this.state.currentStep){const e=this.modalElement.querySelector("#agree-terms");e&&(e.checked=!1)}}),200)}updateButtons(){const e=this.modalElement.querySelector("#back-button"),t=this.modalElement.querySelector("#continue-button"),n=t?.querySelector(".continue-text");if(console.log("ð§ updateButtons called, current step:",this.state.currentStep),e&&e.classList.toggle("invisible",1===this.state.currentStep),t&&(t.disabled=!this.canContinue(),n)){const e=this.getContinueButtonText();console.log("ð Setting button text to:",e),n.textContent=e}}updateContinueButton(e){const t=this.modalElement||this.inlineContainer,n=t?.querySelector("#continue-button");if(n)n.disabled=!e;else if(this.options.inline){const t=new CustomEvent("paymentmodal:validation:changed",{detail:{canProceed:e},bubbles:!0});this.inlineContainer&&this.inlineContainer.dispatchEvent(t)}}async processPayment(){console.log("ð PaymentModal: processPayment() called"),window.PaymentDebugger&&window.PaymentDebugger.logPaymentFlow("ProcessPayment Started",{selectedAddress:this.state.selectedAddress,cardData:this.state.cardData,cardholderName:this.state.cardholderName}),this.state.isProcessing=!0;const e=this.modalElement||this.inlineContainer,t=e?.querySelector("#continue-button"),n=t?.querySelector(".continue-text"),o=t?.querySelector(".continue-arrow"),i=t?.querySelector(".continue-spinner");try{t&&(t.disabled=!0,n&&n.classList.add("hidden"),o&&o.classList.add("hidden"),i&&(i.classList.remove("hidden"),i.classList.add("flex"))),console.log("ð Loading state set"),console.log("ð Using stored cardholder name:",this.state.cardholderName),!this.state.cardholderName&&this.state.selectedAddress&&(this.state.cardholderName=`${this.state.selectedAddress.firstName} ${this.state.selectedAddress.lastName}`,console.log("ð Using billing address name as fallback:",this.state.cardholderName));const e={first_name:this.state.selectedAddress.firstName,last_name:this.state.selectedAddress.lastName,address1:this.state.selectedAddress.street1,address2:this.state.selectedAddress.street2||"",city:this.state.selectedAddress.city,state:this.state.selectedAddress.region,postal_code:this.state.selectedAddress.postalCode,country:this.state.selectedAddress.country};if(!this.recurlyService||!this.recurlyService.isInitialized)throw new Error("Recurly service not initialized");if(!this.recurlyElements)throw new Error("Recurly elements not found. Card form may not be properly initialized.");const a=await new Promise(((t,n)=>{if(!this.recurlyService.recurly.token)return console.error("â Recurly token method not available!"),void n(new Error("Recurly token method not available"));const o=setTimeout((()=>{console.error("â Tokenization timeout - no response after 30 seconds"),n(new Error("Tokenization timeout - please check your card details"))}),3e4);try{this.recurlyService.recurly.token(this.recurlyElements,e,((e,i)=>{if(clearTimeout(o),e)console.error("â Tokenization error:",e),console.error("Error details:",{code:e.code,message:e.message,fields:e.fields,details:e.details}),n(e);else{const e={last4:i.details?.lastFour||i.last_four||this.state.cardData.last4,type:i.details?.type||i.type||this.state.cardData.type,month:i.details?.month||i.month,year:i.details?.year||i.year};if(e.last4&&(this.state.cardData.last4=e.last4),e.type&&(this.state.cardData.type=e.type),e.month&&(this.state.cardData.month=String(e.month).padStart(2,"0")),e.year){const t=String(e.year);this.state.cardData.year=4===t.length?t.slice(-2):t}t(i)}}))}catch(e){clearTimeout(o),console.error("â Synchronous error calling recurly.token:",e),n(e)}}));if(window.PaymentDebugger&&window.PaymentDebugger.logPaymentFlow("Token Created",{tokenId:a.id,tokenType:a.type}),this.options.onSuccess){const e={tokenId:a.id,cardType:this.state.cardData.type||a.type||"card",last4:this.state.cardData.last4||a.lastFour||"****",expMonth:this.state.cardData.month||"**",expYear:this.state.cardData.year||"**",cardholderName:this.state.cardholderName,billingAddress:this.state.selectedAddress};console.log("ð¦ Success callback data:",e),await this.options.onSuccess(e),console.log("â
onSuccess callback completed")}else console.warn("â ï¸ No onSuccess callback provided");this.state.isProcessing=!1,t&&(t.disabled=!1,n&&n.classList.remove("hidden"),o&&o.classList.remove("hidden"),i&&(i.classList.add("hidden"),i.classList.remove("flex"))),console.log("[PaymentModal] Processing complete. Inline mode?",this.options.inline),this.options.inline?console.log("â
Payment tokenized successfully (inline mode - parent handles UI)"):(console.log("ð Showing success animation (modal mode)"),this.showSuccessAnimation())}catch(e){console.error("â Payment processing failed:",e),console.error("Error details:",{message:e.message,code:e.code,stack:e.stack}),window.PaymentDebugger&&window.PaymentDebugger.logError("ProcessPayment Failed",e),this.state.isProcessing=!1,t&&(t.disabled=!1,n&&n.classList.remove("hidden"),o&&o.classList.remove("hidden"),i&&(i.classList.add("hidden"),i.classList.remove("flex"))),this.options.inline?(e.code||e.fields)&&this.showError(e.message||"Failed to process payment. Please check your card details."):this.showError(e.message||"Failed to process payment. Please try again.")}}showSuccessAnimation(){const e=this.modalElement||this.inlineContainer,t=e?.querySelector("#step-content");
1if(!t)return;const n=e?.querySelector("#modal-actions");n&&(n.style.display="none"),t.innerHTML=`\n <div class="text-center py-12">\n <div class="mx-auto flex items-center justify-center h-24 w-24 rounded-full bg-green-100 mb-4">\n ${i.H.render("check",{class:"h-12 w-12 text-green-600"})}\n </div>\n <h3 class="text-lg font-medium text-gray-900 mb-2">Payment Method ${this.options.editMode?"Updated":"Added"}!</h3>\n <p class="text-gray-600">Your payment method has been successfully ${this.options.editMode?"updated":"saved"}.</p>\n <button data-action="close" class="mt-6 inline-flex items-center px-6 py-3 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-all font-medium shadow-md hover:shadow-lg">\n Close\n </button>\n </div>\n `}showError(e){const t=this.modalElement||this.inlineContainer,n=t?.querySelector("#step-content");if(!n)return;const o=document.createElement("div");o.className="mb-4 bg-red-50 border border-red-200 text-red-800 px-4 py-3 rounded-lg flex items-start",o.innerHTML=`\n ${i.H.render("x-circle",{class:"w-5 h-5 text-red-400 mt-0.5 mr-3"})}\n <span>${e}</span>\n `,n.insertBefore(o,n.firstChild),setTimeout((()=>o.remove()),5e3)}canContinue(){switch(console.log("ð Checking canContinue for step:",this.state.currentStep),this.state.currentStep){case 1:const e=null!==this.state.selectedAddress;return console.log("Step 1 can continue:",e,"selectedAddress:",this.state.selectedAddress),e;case 2:const t=this.state.isValid.card;return console.log("Step 2 can continue:",t,"card valid:",this.state.isValid.card),t;case 3:const n=this.modalElement||this.inlineContainer,o=n?.querySelector("#agree-terms"),i=o&&o.checked;return console.log("Step 3 can continue:",i,"checkbox element:",o,"checked:",o?.checked),i;default:return console.log("Unknown step, cannot continue"),!1}}getContinueButtonText(){console.log("ð getContinueButtonText called for step:",this.state.currentStep);const e=this.options.editMode,t=this.options.isOutstandingInvoiceFlow;switch(this.state.currentStep){case 1:default:return"Continue";case 2:return e?"Update Payment Method":t?"Settle Invoice":"Review";case 3:return t?"Settle Invoice":e?"Update Payment Method":"Add Payment Method"}}goBack(){const e=this.options.inline?2:1;this.state.currentStep>e&&(this.state.currentStep--,this.options.inline?this.updateInline():this.updateModal())}async handleContinue(){if(console.log("ð¯ handleContinue called, current step:",this.state.currentStep),this.canContinue()){if(2===this.state.currentStep){console.log("ð Leaving card details step, storing data...");const e=this.modalElement||this.inlineContainer,t=e?.querySelector("#cardholder-name");t&&(this.state.cardholderName=t.value.trim(),console.log("ð Stored cardholder name:",this.state.cardholderName)),this.state.cardData.last4||(this.state.cardData.last4="****"),console.log("Final card data for review:",this.state.cardData)}
1if(this.state.previousStep&&3===this.state.previousStep){if(1===this.state.currentStep)return console.log("â¡ï¸ Returning to step 3 after address edit"),this.state.currentStep=3,this.state.previousStep=void 0,void(this.options.inline?this.updateInline():this.updateModal());if(2===this.state.currentStep){console.log("â¡ï¸ Returning to step 3 after card edit");const e=this.modalElement||this.inlineContainer,t=e?.querySelector("#cardholder-name");return t&&(this.state.cardholderName=t.value.trim(),console.log("ð Stored cardholder name before returning to step 3:",this.state.cardholderName)),this.state.currentStep=3,this.state.previousStep=void 0,void(this.options.inline?this.updateInline():this.updateModal())}}this.state.currentStep<this.state.totalSteps?(console.log("â¡ï¸ Moving to next step:",this.state.currentStep+1),this.state.currentStep++,console.log("ð New current step:",this.state.currentStep),(this.options.isOutstandingInvoiceFlow||this.options.editMode)&&2===this.state.currentStep?(console.log("ð Moving to step 2 for edit/outstanding invoice mode..."),this.options.inline?this.updateInline():this.updateModal()):this.options.inline?this.updateInline():this.updateModal()):(console.log("ð³ Final step - processing payment..."),await this.processPayment())}else console.warn("â Cannot continue - validation failed")}handleCancel(){this.options.onCancel&&this.options.onCancel(),this.hide()}sortAddresses(e){return[...e].sort(((e,t)=>e.isDefaultBilling&&!t.isDefaultBilling?-1:!e.isDefaultBilling&&t.isDefaultBilling?1:e.isBilling&&!t.isBilling?-1:!e.isBilling&&t.isBilling?1:e.isAccount&&!t.isAccount?-1:!e.isAccount&&t.isAccount?1:0))}getCountryName(e){return{US:"United States",CA:"Canada",GB:"United Kingdom",IE:"Ireland",AU:"Australia",NZ:"New Zealand"}[e]||e}getCardBrandName(e){return{visa:"Visa",mastercard:"Mastercard",amex:"American Express",discover:"Discover"}[e?.toLowerCase()||""]||"Card"}getCardBrandShort(e){return{visa:"VISA",mastercard:"MC",amex:"AMEX",discover:"DISC"}[e?.toLowerCase()||""]||"CARD"}getCardGradient(e){return{visa:"from-blue-600 to-blue-700",mastercard:"from-red-500 to-yellow-500",amex:"from-green-600 to-green-700",discover:"from-orange-500 to-orange-600"}[e?.toLowerCase()||""]||"from-gray-600 to-gray-700"}getFieldErrorMessage(e){return{number:"Please enter a valid card number",month:"Please enter a valid month",year:"Please enter a valid year",cvv:"Please enter a valid CVV"}[e]||"Invalid value"}addRecurlyStyles(){const e=document.createElement("style");e.textContent="\n /* Recurly Element Container Styles */\n .recurly-element {\n position: relative;\n display: block;\n width: 100%;\n min-height: 44px;\n }\n\n /* Ensure iframe fills container */\n .recurly-element iframe {\n position: absolute !important;\n top: 0 !important;\n left: 0 !important;\n width: 100% !important;\n height: 100% !important;\n border: none !important;\n background: transparent !important;\n }\n\n\n /* Focus states */\n .recurly-element:focus-within {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n }\n\n /* Error states */\n .recurly-element.error {\n border-color: #ef4444;\n background-color: #fef2f2;\n }\n\n /* Animation for card brand highlighting */\n [data-brand] {\n transition: all 0.2s ease;\n }\n\n /* Smooth transitions */\n #step-content {\n transition: opacity 0.2s ease-in-out;\n }\n\n /* Progress bar animation */\n .progress-bar > div {\n transition: all 0.3s ease;\n }\n\n /* Ensure Recurly hosted fields are visible */\n [data-recurly-element] {\n display: block !important;\n visibility: visible !important;\n }\n\n /* Dropdown icon styling */\n .recurly-element .absolute {\n z-index: 10;\n }\n ",document.head.appendChild(e)}async showAddressForm(){const e=this.modalElement.querySelector("#add-address-btn"),t=this.modalElement.querySelector("#add-new-address-card"),n=this.modalElement.querySelector("#inline-address-form-container");n&&(e&&(e.style.display="none"),t&&(t.style.display="none"),n.classList.remove("hidden"),this.addressModal=new s.W({inline:!0,forceBillingOnly:!0,hideAddressType:!0,hideBackButton:!1,isFirstAddress:0===this.options.addresses.length,title:"Add Billing Address",submitText:"Save Address",onSave:async e=>{try{const t=await this.addressesApi.addAddress(e);if(t&&t.addresses){const n=Array.isArray(t.addresses)?t.addresses:Object.values(t.addresses),o=n.find((t=>t.firstName===e.firstName&&t.lastName===e.lastName&&t.street1===e.street1));if(!o)throw new Error("Failed to find the newly created address");this.options.addresses=n,this.state.selectedAddress=o,this.state.isValid.address=!0,this.hideAddressForm(),this.updateModal(),this.options.onAddressNeeded&&await this.options.onAddressNeeded()}else{if(!this.options.onAddressNeeded)throw new Error("Failed to get updated addresses after save");{const t=await this.options.onAddressNeeded();this.options.addresses=t;const n=t.find((t=>t.firstName===e.firstName&&t.lastName===e.lastName&&t.street1===e.street1));if(!n)throw new Error("Failed to find the newly created address after refresh");this.state.selectedAddress=n,this.state.isValid.address=!0,this.hideAddressForm(),this.updateModal()}}}catch(e){throw console.error("Failed to save address:",e),e}},onCancel:()=>{this.hideAddressForm()}}),await this.addressModal.renderInline(n))}hideAddressForm(){const e=this.modalElement.querySelector("#add-address-btn"),t=this.modalElement.querySelector("#add-new-address-card"),n=this.modalElement.querySelector("#inline-address-form-container");this.addressModal&&(this.addressModal=null),e&&(e.style.display="inline-flex"),t&&(t.style.display="block"),n&&(n.classList.add("hidden"),n.innerHTML="")}canProceed(){return this.canContinue()}getCurrentStep(){return this.state.currentStep}getTotalSteps(){return this.state.totalSteps}isOnFirstStep(){const e=this.options.inline?2:1;return this.state.currentStep<=e}async navigateBack(){this.goBack()}async navigateContinue(){await this.handleContinue()}getContinueText(){return this.getContinueButtonText()}isProcessing(){return this.state.isProcessing}}},2046:function(e,t,n){"use strict";const o=new class{constructor(){this.paymentTypes={CREDIT_CARD:"credit_card",DEBIT_CARD:"debit_card",PAYPAL:"paypal",BANK_ACCOUNT:"bank_account"},this.cardBrands={visa:{name:"Visa",short:"VISA",color:"bg-blue-600",icon:"visa"},mastercard:{name:"Mastercard",short:"MC",color:"bg-red-600",icon:"mastercard"},american_express:{name:"American Express",short:"AMEX",color:"bg-blue-500",icon:"amex"},discover:{name:"Discover",short:"DISC",color:"bg-orange-600",icon:"discover"},diners_club:{name:"Diners Club",short:"DC",color:"bg-gray-700",icon:"diners"},jcb:{name:"JCB",short:"JCB",color:"bg-green-600",icon:"jcb"},unknown:{name:"Card",short:"CARD",color:"bg-gray-500",icon:"card"}},this.status={ACTIVE:"active",EXPIRED:"expired",PENDING:"pending",FAILED:"failed"},this.validationRules={cardNumber:{required:!0,pattern:/^\d{13,19}$/,message:"Card number must be 13-19 digits"},cvv:{required:!0,pattern:/^\d{3,4}$/,message:"CVV must be 3-4 digits"},expiryMonth:{required:!0,min:1,max:12,message:"Invalid month"},expiryYear:{required:!0,min:(new Date).getFullYear(),message:"Card is expired"},cardholderName:{required:!0,minLength:2,maxLength:100,message:"Cardholder name is required"}},this.messages={loading:"Loading payment methods...",empty:{title:"No payment methods",message:"Add a payment method to make purchases and manage subscriptions"},success:{add:"Payment method added successfully",update:"Payment method updated successfully",remove:"Payment method removed successfully",setDefault:"Default payment method updated"},error:{load:"Failed to load payment methods",add:"Failed to add payment method",update:"Failed to update payment method",remove:"Failed to remove payment method",recurlyLoad:"Failed to load payment processor",invalidCard:"Invalid card information",network:"Network error. Please try again.",validation:"Please correct the errors below"},confirm:{remove:"Are you sure you want to remove this payment method?",removeDefault:"This is your default payment method. Are you sure you want to remove it?",removeLastCard:"This is your only payment method. Removing it may affect your active subscriptions."}},this.features={enablePayPal:!1,enableBankAccount:!1,enableMultipleDefaults:!1,requireAddress:!0,autoDetectCardBrand:!0},this.recurly={timeout:1e4,fields:{number:{selector:"#card-number",placeholder:"â¢â¢â¢â¢ â¢â¢â¢â¢ â¢â¢â¢â¢ â¢â¢â¢â¢"},cvv:{selector:"#card-cvv",placeholder:"CVV"},month:{selector:"#card-month",placeholder:"MM"},year:{selector:"#card-year",placeholder:"YYYY"}}
1,style:{base:{fontSize:"14px",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',color:"#1F2937","::placeholder":{color:"#9CA3AF"}},focus:{borderColor:"#4F46E5"},invalid:{borderColor:"#EF4444",color:"#EF4444"}}},this.api={timeout:3e4,retryAttempts:3,retryDelay:1e3}}getCardBrand(e){return this.cardBrands[e]||this.cardBrands.unknown}getValidationRule(e){return this.validationRules[e]||{}}getMessage(e,t){const n=this.messages[e];return"string"==typeof n?n:"object"==typeof n&&t in n?n[t]:`${e}.${t}`}isFeatureEnabled(e){return this.features[e]||!1}getRecurlyField(e){return this.recurly.fields[e]||{}}update(e){Object.assign(this,e)}};t.Ay=o},1458:function(e,t,n){"use strict";n.d(t,{PL:function(){return a},Rt:function(){return o.aC},UU:function(){return i}});var o=n(6532);const i={LOAD_FAILED:"Failed to load payment methods. Please try again.",ADD_FAILED:"Failed to add payment method. Please check your information and try again.",REMOVE_FAILED:"Failed to remove payment method. Please try again.",UPDATE_FAILED:"Failed to update payment method. Please try again.",RECURLY_LOAD_FAILED:"Failed to load payment processor. Please refresh the page.",INVALID_CARD:"Invalid card information. Please check and try again.",NETWORK_ERROR:"Network error. Please check your connection and try again."},a={METHOD_ADDED:"Payment method added successfully",METHOD_REMOVED:"Payment method removed successfully",METHOD_UPDATED:"Payment method updated successfully",DEFAULT_SET:"Default payment method updated"}},6532:function(e,t,n){"use strict";n.d(t,{Ac:function(){return d},aC:function(){return i},wJ:function(){return s},yH:function(){return r}});var o=n(6534);const i={SYSTEM_READY:"payment:system:ready",SYSTEM_ERROR:"payment:system:error",METHODS_LOADING:"payment:methods:loading",METHODS_LOADED:"payment:methods:loaded",METHODS_UPDATED:"payment:methods:updated",METHODS_ERROR:"payment:methods:error",METHOD_ADDING:"payment:method:adding",METHOD_ADDED:"payment:method:added",METHOD_UPDATING:"payment:method:updating",METHOD_UPDATED:"payment:method:updated",METHOD_REMOVING:"payment:method:removing",METHOD_REMOVED:"payment:method:removed",METHOD_ERROR:"payment:method:error",DEFAULT_CHANGING:"payment:default:changing",DEFAULT_CHANGED:"payment:default:changed",DEFAULT_ERROR:"payment:default:error",MODAL_OPENING:"payment:modal:opening",MODAL_OPENED:"payment:modal:opened",MODAL_CLOSING:"payment:modal:closing",MODAL_CLOSED:"payment:modal:closed",MODAL_SUCCESS:"payment:modal:success",MODAL_ERROR:"payment:modal:error",FORM_VALIDATING:"payment:form:validating",FORM_VALID:"payment:form:valid",FORM_INVALID:"payment:form:invalid",FORM_SUBMITTING:"payment:form:submitting",FORM_SUBMITTED:"payment:form:submitted",FORM_ERROR:"payment:form:error",RECURLY_LOADING:"payment:recurly:loading",RECURLY_READY:"payment:recurly:ready",RECURLY_ERROR:"payment:recurly:error",RECURLY_TOKEN_REQUESTED:"payment:recurly:token:requested",RECURLY_TOKEN_RECEIVED:"payment:recurly:token:received",RECURLY_TOKEN_ERROR:"payment:recurly:token:error",ADD_BUTTON_CLICKED:"payment:ui:add:clicked",EDIT_BUTTON_CLICKED:"payment:ui:edit:clicked",REMOVE_BUTTON_CLICKED:"payment:ui:remove:clicked",SET_DEFAULT_CLICKED:"payment:ui:setdefault:clicked",STATE_INITIALIZED:"payment:state:initialized",STATE_CHANGED:"payment:state:changed",STATE_CLEARED:"payment:state:cleared",STATE_ERROR:"payment:state:error"},a=new o.b({namespace:"payment",debug:!1});function s(e,t={}){const n={timestamp:Date.now(),source:"payment-methods",...t};a.emit(e,n)}function r(e,t,n){return a.on(e,t,n)}function d(){return a.createHandlers()}},2512:function(e,t,n){"use strict";n.d(t,{Ay:function(){return l}});var o=n(4140),i=n(6532),a=n(2046);var s=class{constructor(e={}){this.isInitialized=!1,this.config=e}isReady(){return this.isInitialized}getName(){return this.constructor.name}destroy(){this.isInitialized=!1}},r=n(9935);var d=class extends s{constructor(e={}){super(e),this.recurly=null,this.publicKey=e.publicKey||null}async initialize(){if(this.publicKey)try{(0,i.wJ)(i.aC.RECURLY_LOADING);const e=new r.A({publicKey:this.publicKey});await e.initialize(),this.recurly=window.recurly,this.recurly.configure(this.publicKey),this.isInitialized=!0,(0,i.wJ)(i.aC.RECURLY_READY,{publicKey:this.publicKey})}catch(e){throw console.error("Failed to initialize Recurly:",e),(0,i.wJ)(i.aC.RECURLY_ERROR,{error:e}),e}}async setPublicKey(e){this.publicKey!==e&&(this.publicKey=e,this.isInitialized&&await this.initialize())}async tokenize(e){if(!this.isReady())throw new Error("Recurly provider not initialized");if(!this.recurly)throw new Error("Recurly not loaded");try{(0,i.wJ)(i.aC.RECURLY_TOKEN_REQUESTED,{paymentData:e});const t={number:e.cardNumber||"",month:e.expiryMonth||0,year:e.expiryYear||0,cvv:e.cvv||"",first_name:e.firstName||e.billingAddress?.firstName,last_name:e.lastName||e.billingAddress?.lastName,address1:e.billingAddress?.street1,address2:e.billingAddress?.street2,city:e.b
1illingAddress?.city,state:e.billingAddress?.region,postal_code:e.billingAddress?.postalCode,country:e.billingAddress?.country};return new Promise(((n,o)=>{this.recurly.token(t,((t,a)=>{t?(console.error("Recurly tokenization error:",t),(0,i.wJ)(i.aC.RECURLY_TOKEN_ERROR,{error:t}),o(t)):((0,i.wJ)(i.aC.RECURLY_TOKEN_RECEIVED,{token:a}),n({tokenId:a.id,cardType:a.card?.type,lastFour:a.card?.last_four,...e}))}))}))}catch(e){throw(0,i.wJ)(i.aC.RECURLY_TOKEN_ERROR,{error:e}),e}}validate(e){const t={};e.cardNumber&&this.isValidCardNumber(e.cardNumber)||(t.cardNumber="Invalid card number");const n=(new Date).getFullYear(),o=(new Date).getMonth()+1;return(!e.expiryMonth||e.expiryMonth<1||e.expiryMonth>12)&&(t.expiryMonth="Invalid expiry month"),!e.expiryYear||e.expiryYear<n?t.expiryYear="Invalid expiry year":e.expiryYear===n&&e.expiryMonth&&e.expiryMonth<o&&(t.expiryMonth="Card is expired"),e.cvv&&this.isValidCVV(e.cvv)||(t.cvv="Invalid CVV"),e.firstName?.trim()||(t.firstName="First name is required"),e.lastName?.trim()||(t.lastName="Last name is required"),{isValid:0===Object.keys(t).length,errors:t}}isValidCardNumber(e){const t=e.replace(/\D/g,"");if(t.length<13||t.length>19)return!1;let n=0,o=!1;for(let e=t.length-1;e>=0;e--){let i=parseInt(t[e],10);o&&(i*=2,i>9&&(i-=9)),n+=i,o=!o}return n%10==0}isValidCVV(e){const t=e.replace(/\D/g,"");return t.length>=3&&t.length<=4}getRecurly(){return this.recurly}destroy(){super.destroy(),this.recurly=null}};var l=new class{constructor(){this.paymentMethods=[],this.isLoaded=!1,this.isLoading=!1,this.api=o.paymentMethodsAPI,this.config=a.Ay,this.recurlyReady=!1,this.provider=null,this.providers={recurly:d}}async initialize(){try{return await this.initializeProvider("recurly"),(0,i.wJ)(i.aC.SYSTEM_READY),!0}catch(e){return console.error("Failed to initialize payment manager:",e),(0,i.wJ)(i.aC.SYSTEM_ERROR,{error:e}),!1}}async initializeProvider(e,t={}){const n=this.providers[e];if(!n)throw new Error(`Unknown payment provider: ${e}`);const o={publicKey:t.publicKey||this.config.getRecurlyPublicKey?.(),...t};return this.provider=new n(o),await this.provider.initialize(),"recurly"===e&&this.setRecurlyReady(!0),this.provider}getProvider(){return this.provider}async loadPaymentMethods(e=!1){if(this.isLoaded&&!e)return this.paymentMethods;if(this.isLoading)return console.log("Already loading payment methods..."),this.paymentMethods;try{this.isLoading=!0,(0,i.wJ)(i.aC.METHODS_LOADING);const e=await this.api.getPaymentMethods();let t=[];const n=e?.data?.paymentMethods;return n?"object"!=typeof n||Array.isArray(n)?Array.isArray(n)&&(t=n):t=Object.values(n):Array.isArray(e)&&(t=e),this.paymentMethods=t.map((e=>this.normalizePaymentMethod(e))),this.isLoaded=!0,(0,i.wJ)(i.aC.METHODS_LOADED,{methods:this.paymentMethods,count:this.paymentMethods.length}),this.paymentMethods}catch(e){throw console.error("Failed to load payment methods:",e),(0,i.wJ)(i.aC.METHODS_ERROR,{error:e}),e}finally{this.isLoading=!1}}getPaymentMethods(){return[...this.paymentMethods]}getPaymentMethodById(e){return this.paymentMethods.find((t=>t.id===e))}getDefaultPaymentMethod(){return this.paymentMethods.find((e=>e.isDefault))}async addPaymentMethod(e){try{(0,i.wJ)(i.aC.METHOD_ADDING,{paymentData:e});const t=await this.api.addPaymentMethod(e);console.log("[PaymentManager] Add payment method response:",t),await this.loadPaymentMethods(!0);const n="data"in t&&t.data?t.data:t;console.log("[PaymentManager] Response data:",n),console.log("[PaymentManager] Current payment methods:",this.paymentMethods);let o=this.paymentMethods.find((e=>{const t=e.billingInfoId===n.billingInfoId||e.id===n.billingInfoId||e.id===n.id||e.billingInfoId===n.id||n.token&&e.token===n.token;return t&&console.log("[PaymentManager] Found matching method:",e),t}));return!o&&this.paymentMethods.length>0&&(console.warn("[PaymentManager] Could not find method by ID match, using last added method"),o=this.paymentMethods[this.paymentMethods.length-1]),(0,i.wJ)(i.aC.METHOD_ADDED,{method:o,count:this.paymentMethods.length}),o}catch(e){throw console.error("Failed to add payment method:",e),(0,i.wJ)(i.aC.METHOD_ERROR,{error:e,action:"add"}),e}}async updatePaymentMethod(e,t){console.log("[PaymentManager] updatePaymentMethod called with:",{methodId:e,updateData:t,timestamp:(new Date).toISOString()});try{(0,i.wJ)(i.aC.METHOD_UPDATING,{methodId:e,updateData:t});if(!this.getPaymentMethodById(e))throw new Error(`Payment method not found: ${e}`);const n={billingAddressId:t.billingInfoId,isDefault:t.isDefault,expirationMonth:t.expiryMonth?.toString(),expirationYear:t.expiryYear?.toString()};console.log("[PaymentManager] Updating payment method:",{methodId:e,request:n});const o=await this.api.updatePaymentMethod(e,n);await this.loadPaymentMethods(!0);const a=this.getPaymentMethodById(e)||this.normalizePaymentMethod(o);return(0,i.wJ)(i.aC.METHOD_UPDATED,{method:a,methodId:e}),a}catch(t){throw console.error("Failed to update payment method:",t),(0,i.wJ)(i.aC.METHOD_ERROR,{error:t,action:"update",methodId:e}),t}}async removePaymentMethod(e){try{return(0,i.wJ)(i.aC.METHOD_REMOVING,{methodId:e}),await this.api.deletePaymentMethod(e),this.paymentMethods=this.paymentMethods.filter((t=>
1t.id!==e)),(0,i.wJ)(i.aC.METHOD_REMOVED,{methodId:e,count:this.paymentMethods.length}),!0}catch(t){throw console.error("Failed to remove payment method:",t),(0,i.wJ)(i.aC.METHOD_ERROR,{error:t,action:"remove",methodId:e}),t}}async setDefaultPaymentMethod(e){try{(0,i.wJ)(i.aC.DEFAULT_CHANGING,{methodId:e}),this.paymentMethods.forEach((e=>{e.isDefault&&(e.isDefault=!1)}));const t=this.paymentMethods.find((t=>t.id===e));return t&&(t.isDefault=!0,await this.updatePaymentMethod(e,{isDefault:!0}),(0,i.wJ)(i.aC.DEFAULT_CHANGED,{methodId:e,method:t})),t}catch(t){throw console.error("Failed to set default payment method:",t),(0,i.wJ)(i.aC.DEFAULT_ERROR,{error:t,methodId:e}),t}}validatePaymentMethod(e){const t={},n=this.config.validationRules;e.cardholderName?.trim()||(t.cardholderName=n.cardholderName.message);const o=(new Date).getFullYear(),i=(new Date).getMonth()+1;return(!e.expiryMonth||e.expiryMonth<1||e.expiryMonth>12)&&(t.expiryMonth=n.expiryMonth.message),!e.expiryYear||e.expiryYear<o?t.expiryYear=n.expiryYear.message:e.expiryYear===o&&e.expiryMonth<i&&(t.expiryMonth="Card is expired"),this.config.isFeatureEnabled("requireAddress")&&(e.billingAddressId||e.billingAddress||(t.billingAddress="Billing address is required")),{isValid:0===Object.keys(t).length,errors:t}}normalizePaymentMethod(e){return{id:e.billingInfoId||e.id,billingInfoId:e.billingInfoId,type:e.type||this.config.paymentTypes.CREDIT_CARD,cardType:e.cardType||e.brand||"unknown",lastFour:e.lastFour||e.lastFourDigits||e.maskedCardNumber?.slice(-4)||"****",expiryMonth:parseInt(e.expiryMonth||e.month||"0"),expiryYear:parseInt(e.expiryYear||e.year||"0"),cardholderName:e.cardholderName||e.nameOnCard||"",isDefault:e.isDefault||e.default||!1,isExpired:this.isCardExpired(e),billingAddress:e.billingAddress,billingAddressId:e.billingAddressId,maskedCardNumber:e.maskedCardNumber,createdAt:e.createdAt||e.created||(new Date).toISOString(),updatedAt:e.updatedAt||e.updated}}isCardExpired(e){const t=(new Date).getFullYear(),n=(new Date).getMonth()+1,o=e.expiryYear||e.year,i=e.expiryMonth||e.month;return o<t||o===t&&i<n}getCount(){return this.paymentMethods.length}hasPaymentMethods(){return this.paymentMethods.length>0}setRecurlyReady(e){this.recurlyReady=e,e&&(0,i.wJ)(i.aC.RECURLY_READY)}isRecurlyReady(){return this.recurlyReady}clear(){this.paymentMethods=[],this.isLoaded=!1,this.isLoading=!1,this.recurlyReady=!1}}},9948:function(e,t,n){"use strict";var o=n(4081),i=n(6833),a=n(5762),s=n(6532),r=n(2512),d=n(2046),l=n(5856),c=n(7310),u=n(8520);const m=new class{constructor(){this.activeModal=null,this.manager=r.Ay,this.config=d.Ay,this.addressesAPI=l.A,this.recurlyPublicKey=null,this.isInlineMode=!1,this.currentAccountId=null}async initialize(e){return this.recurlyPublicKey=e,!0}async openAddModal(e={}){if(this.activeModal)console.warn("Payment modal already open");else{this.isInlineMode=e.inline||!1,this.currentAccountId=e.accountId||null,this.currentAccountId&&console.log("[PaymentModalHandler] Invoice payment mode - accountId:",this.currentAccountId),(0,s.wJ)(s.aC.ADD_BUTTON_CLICKED);try{if(e.bypassLimitCheck)console.log("[PaymentModalHandler] Bypassing payment method limit check for invoice payment");else{const e=await u.initService.getInitData();if(!(e.generalConfig?.enableAddCard??!0)){await this.manager.loadPaymentMethods(!0);if(this.manager.getPaymentMethods().length>0)return void await this.showPaymentLimitModal()}}(0,s.wJ)(s.aC.MODAL_OPENING,{mode:"add"});const t=await this.fetchAddresses(),n=new o.default({addresses:t,recurlyPublicKey:this.recurlyPublicKey,onSuccess:async e=>{await this.handleAddSuccess(e)},onCancel:()=>{this.handleCancel()},onAddressNeeded:async()=>await this.fetchAddresses()});await n.show(),this.activeModal=n,(0,s.wJ)(s.aC.MODAL_OPENED,{mode:"add"})}catch(e){console.error("Failed to open payment modal:",e),(0,s.wJ)(s.aC.MODAL_ERROR,{error:e,mode:"add"}),a.AlertUtils.error(this.config.getMessage("error","add"))}}}async showPaymentLimitModal(){try{const e=await c.default.load(),t=e.companySupportEmail||"[email protected]",n=`\n <div class="text-center">\n <div class="mx-auto w-16 h-16 bg-yellow-100 rounded-full flex items-center justify-center mb-4">\n <svg class="w-8 h-8 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.664-.833-2.464 0L3.34 16.5c-.77.833.192 2.5 1.732 2.5z"></path>\n </svg>\n </div>\n \n <h3 class="text-lg font-medium text-gray-900 mb-3">Payment Method Limit Reached</h3>\n \n <p class="text-sm text-gray-600 mb-6">\n You can only have one payment method on your account. To add a new card, you'll need to remove your existing payment method first.\n </p>\n \n <div class="bg-gray-50 rounded-lg p-4 mb-6">\n <p class="text-sm text-gray-700 mb-2">Need help? Contact customer support:</p>\n <div class="space-y-2">\n <div class="flex items-center justify-center space-x-2 text-sm">\n <svg class="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 4.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>\n </svg>
1\n <span class="text-blue-600">${t}</span>\n </div>\n <div class="flex items-center justify-center space-x-2 text-sm">\n <svg class="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"></path>\n </svg>\n <span class="text-blue-600">${e.companySupportPhone||"N/A"}</span>\n </div>\n </div>\n </div>\n \n <button id="payment-limit-ok-btn" class="w-full px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors font-medium">\n Understood\n </button>\n </div>\n `,o=new i.Modal({content:n,size:"small",title:"",closeButton:!1,onClose:()=>{this.activeModal=null}});o.open(),this.activeModal=o;const a=document.getElementById("payment-limit-ok-btn");a&&a.addEventListener("click",(()=>{o.close(),this.activeModal=null}))}catch(e){console.error("Failed to show payment limit modal:",e),a.AlertUtils.error("You can only have one payment method on your account. Please remove your existing payment method before adding a new one.")}}async handleAddSuccess(e){try{(0,s.wJ)(s.aC.FORM_SUBMITTED,{paymentData:e}),this.currentAccountId&&(console.log("[PaymentModalHandler] Adding accountId to payment data for invoice payment:",this.currentAccountId),e.accountId=this.currentAccountId);const t=await this.manager.addPaymentMethod(e);return(0,s.wJ)(s.aC.MODAL_SUCCESS,{method:t,mode:"add"}),this.closeModal(),this.isInlineMode?await i.Modal.alert({title:"Payment Method Added",message:`\n <div class="text-center">\n <div class="mx-auto w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mb-4">\n <svg class="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>\n </svg>\n </div>\n <p class="text-gray-600">${this.config.getMessage("success","add")}</p>\n </div>\n `,buttonText:"Continue",buttonClass:"bg-primary-600 hover:bg-primary-700 text-white"}):a.AlertUtils.success(this.config.getMessage("success","add")),this.isInlineMode=!1,document.dispatchEvent(new CustomEvent("paymentMethodAdded")),t}catch(e){throw console.error("Failed to add payment method:",e),(0,s.wJ)(s.aC.FORM_ERROR,{error:e}),e}}handleCancel(){(0,s.wJ)(s.aC.MODAL_CLOSING,{reason:"user_cancelled"}),this.closeModal()}closeModal(){this.activeModal&&(this.activeModal.hide&&this.activeModal.hide(),this.activeModal=null,(0,s.wJ)(s.aC.MODAL_CLOSED)),this.isInlineMode=!1,this.currentAccountId=null}async fetchAddresses(){try{const e=await this.addressesAPI.getAddresses();let t=[];return e&&e.addresses?"object"!=typeof e.addresses||Array.isArray(e.addresses)?Array.isArray(e.addresses)&&(t=e.addresses):t=Object.values(e.addresses):Array.isArray(e)&&(t=e),t.filter((e=>e.isBilling))}catch(e){return console.error("Failed to fetch addresses:",e),[]}}async confirmRemove(e){const t=this.manager.getPaymentMethodById(e);if(!t)return;const n=t.isDefault,o=1===this.manager.getCount();let r=this.config.getMessage("confirm","remove");n?r=this.config.getMessage("confirm","removeDefault"):o&&(r=this.config.getMessage("confirm","removeLastCard")),(0,s.wJ)(s.aC.REMOVE_BUTTON_CLICKED,{methodId:e});const d=`\n <div class="-mt-4 -mx-2">\n <div class="flex items-center justify-center w-12 h-12 mx-auto bg-red-100 rounded-full mb-3">\n <svg class="w-6 h-6 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />\n </svg>\n </div>\n \n <h3 class="text-lg font-medium text-gray-900 text-center mb-2">Remove Payment Method</h3>\n <p class="text-sm text-gray-600 text-center mb-4">${r}</p>\n \n <div class="bg-gray-50 rounded-lg p-3 mb-4">\n <div class="flex items-center space-x-3">\n <div class="flex-shrink-0">\n <div class="w-12 h-8 bg-gray-200 rounded flex items-center justify-center text-xs font-medium">\n ${t.cardType.toUpperCase()}\n </div>\n </div>\n <div class="text-sm">\n <p class="font-medium text-gray-900">â¢â¢â¢â¢ ${t.lastFour}</p>\n <p class="text-gray-500">Expires ${t.expiryMonth}/${t.expiryYear}</p>\n </div>\n </div>\n </div>\n \n <div class="flex gap-3">\n <button id="cancel-remove-btn" class="flex-1 px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 transition-colors font-medium">\n Cancel\n </button>\n <button id="confirm-remove-btn" class="flex-1 px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors font-medium">\n Remove Card\n </button>\n </div>\n </div>\n `,l=new i.Modal({content:d,size:"small",title:"",closeButton:!1,onClose:()=>{this.activeModal=null}});l.open(),this.activeModal=l;const c=document.getElementById("cancel-remove-btn"),u=document.getElementById("confirm-remove-btn");c&&c.addEventListener("click",(()=>{l.close(),this.activeModal=null})),u&&u.addEventListener("click",(async()=>{try{u.disabled=!0,u.innerHTML='\n <svg class="animate-spin h-4 w-4 mx-auto" fill="none" viewBox="0 0 24 24">\n <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>\n <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>\n </svg>\n ',await this.manager.removePaymentMethod(e),l.close(),this.activeModal=null,a.AlertUtils.success(this.config.getMessage("success","remove"))}catch(e){console.error("Failed to remove payment method:",e),a.AlertUtils.error(this.config.getMessage("error","remove")),u.disabled=!1,u.innerHTML="Remove Card"}}))}async setDefault(e){try{(0,s.wJ)(s.aC.SET_DEFAULT_CLICKED,{methodId:e}),await this.manager.setDefaultPaymentMethod(e),a.AlertUtils.success(this.config.getMessage("success","setDefault"))}catch(e){console.error("Failed to set default payment method:",e),a.AlertUtils.error(this.config.getMessage("error","update"))}}isModalOpen(){return null!==this.activeModal}cleanup(){this.closeModal(),this.recurlyPublicKey=null}};t.Ay=m},4140:function(e,t,n){"use strict";n.d(t,{paymentMethodsAPI:function(){return s}});var o=n(8231),i=n(2910);class a extends o.pZ{async getPaymentMethods(){const e=i.A.apiGetPaymentMethodsUrl.replace(this.baseURL,"");return this.get(e)}async addPaymentMethod(e){console.log("Adding payment method with data:",e);const t=i.A.apiAddPaymentMethodUrl.replace(this.baseURL,"");console.log("Using endpoint:",t);let n=e;const o=e;("recurlyToken"in o||"tokenId"in o)&&(n={recurlyToken:o.recurlyToken||o.tokenId,billingAddressId:o.billingAddressId||o.billingAddress?.id,accountId:o.accountId,firstName:o.firstName||o.billingAddress?.firstName||"",lastName:o.lastName||o.billingAddress?.lastName||"",cardholderName:o.cardholderName||"",default:o.isDefault||o.default||!1,saveCard:!1!==o.saveCard}),console.log("Transformed request data:",n),console.log("Making POST request to:",this.baseURL+t);try{const e=await this.post(t,n);return console.log("Add payment method response:",e),e}catch(e){throw console.error("Add payment method error details:",e),e}}async updatePaymentMethod(e,t){const n=i.A.apiUpdatePaymentMethodUrl.replace(this.baseURL,""),o={billingInfoId:e,default:t.isDefault,billingAddressId:t.billingAddressId,expirationMonth:t.expirationMonth,expirationYear:t.expirationYear};return console.log("Update payment method request:",{paymentMethodId:e,updateData:t,requestData:o}),this.post(n,o)}async deletePaymentMethod(e){const t=i.A.apiDeletePaymentMethodUrl.replace(this.baseURL,"");return this.post(t,{billingInfoId:e})}async setDefaultPaymentMethod(e){return this.post("/profile/payment-methods/set-default",{id:e})}}const s=new a},3039:function(e,t,n){"use strict";n.d(t,{default:function(){return P}});var o=n(7310),i=n(8200),a=n(8243),s=n(7411),r=n(1175),d=n(7663),l=n(2554),c=n(7140);class u{constructor(e,t={}){this.container=e,this.options={planCode:"",onCouponApplied:()=>{},onCouponRemoved:()=>{},initialCouponCode:"",...t},this.state={inputValue:this.options.initialCouponCode,isValidating:!1,isValid:!1,errorMessage:null,appliedCoupon:null}}
1render(){if(!this.container)return;const e=!!this.state.appliedCoupon;this.container.innerHTML=`\n <div class="coupon-input-container">\n ${e?this.renderAppliedCoupon():this.renderCouponForm()}\n </div>\n `,this.attachEventListeners()}renderCouponForm(){return`\n <div class="bg-gray-50 rounded-lg p-4">\n <div class="flex items-center justify-between mb-3">\n <label class="text-sm font-medium text-gray-700 flex items-center">\n ${s.H.getIcon("general","tag","w-4 h-4 mr-2")}\n Have a coupon code?\n </label>\n ${this.state.errorMessage?`\n <span class="text-sm text-red-600">${this.state.errorMessage}</span>\n `:""}\n </div>\n \n <div class="flex space-x-2">\n <input\n type="text"\n id="coupon-input"\n value="${this.state.inputValue}"\n placeholder="Enter coupon code"\n class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500 ${this.state.errorMessage?"border-red-300":""}"\n ${this.state.isValidating?"disabled":""}\n />\n <button\n type="button"\n id="apply-coupon-btn"\n class="px-4 py-2 bg-primary-600 text-white rounded-md hover:bg-primary-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center"\n ${this.state.isValidating||!this.state.inputValue.trim()?"disabled":""}\n >\n ${this.state.isValidating?'\n <div class="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>\n ':"Apply"}\n </button>\n </div>\n </div>\n `}renderAppliedCoupon(){const e=this.state.appliedCoupon;return`\n <div class="bg-green-50 border border-green-200 rounded-lg p-4">\n <div class="flex items-center justify-between">\n <div class="flex items-center gap-2">\n <div class="flex-shrink-0">\n ${s.H.getIcon("general","checkCircle","w-5 h-5 text-green-600")}\n </div>\n <div class="flex items-center gap-2 text-sm text-green-800">\n <span class="font-medium">Coupon Applied: ${e.code}</span>\n <span class="text-green-700">â¢</span>\n <span class="text-green-700">${this.formatDiscount(e)}</span>\n ${e.description?`<span class="text-green-700">â¢</span><span class="text-green-700">${e.description}</span>`:""}\n </div>\n </div>\n <button\n type="button"\n id="remove-coupon-btn"\n class="ml-4 text-green-600 hover:text-green-700 flex-shrink-0"\n title="Remove coupon"\n >\n ${s.H.getIcon("general","x","w-5 h-5")}\n </button>\n </div>\n </div>\n `}formatDiscount(e){return"percent"===e.discountType?`${e.discountPercent}% discount`:"fixed"===e.discountType?`$${e.discountAmount?.toFixed(2)} discount`:"Discount applied"}attachEventListeners(){if(!this.container)return;const e=this.container.querySelector("#coupon-input"),t=this.container.querySelector("#apply-coupon-btn"),n=this.container.querySelector("#remove-coupon-btn");e&&t&&(e.addEventListener("input",(n=>{if(this.state.inputValue=n.target.value,this.state.inputValue.trim()&&!this.state.isValidating?t.disabled=!1:t.disabled=!0,this.state.errorMessage){this.state.errorMessage=null;const t=this.container.querySelector(".text-red-600");t&&(t.textContent=""),e.classList.remove("border-red-300")}})),e.addEventListener("keypress",(e=>{"Enter"===e.key&&(e.preventDefault(),this.applyCoupon())})),t.addEventListener("click",(()=>this.applyCoupon()))),n&&n.addEventListener("click",(()=>this.removeCoupon()))}async applyCoupon(){const e=this.state.inputValue.trim().toUpperCase();if(!e)return;if(!l.A.isAuthenticated())return this.state.errorMessage="Please sign in to apply a coupon code.",this.state.isValid=!1,this.render(),void setTimeout((()=>{window.dispatchEvent(new CustomEvent(c.Ay.UI_SHOW_LOGIN,{detail:{returnUrl:window.location.href,message:"Please sign in to apply your coupon code."}}))}),1500);const t=null!==this.state.appliedCoupon;this.state.isValidating=!0,this.state.errorMessage=null,t||this.render();try{const t=await d.G.validateCoupon(e,this.options.planCode);if(t.success&&t.data?.valid){const n=t.data.coupon,o=t.data.discountType||n?.type||n?.discountType||"fixed";this.state.appliedCoupon={code:e,discountType:o,discountAmount:t.data.discountAmount||n?.discountAmount,discountPercent:t.data.discountPercent||n?.discountPercent,description:t.data.description||n?.description||n?.name},this.state.isValid=!0,this.options.onCouponApplied(e,this.state.appliedCoupon)}else this.state.appliedCoupon=null,this.state.errorMessage=t.data?.message||"Invalid coupon code",this.state.isValid=!1}catch(e){console.error("[CouponInput] Error validating coupon:",e),this.state.appliedCoupon=null,this.state.errorMessage="Failed to validate coupon. Please try again.",this.state.isValid=!1}finally{this.state.isValidating=!1,this.render()}}
1removeCoupon(){this.state.appliedCoupon=null,this.state.inputValue="",this.state.isValid=!1,this.state.errorMessage=null,this.options.onCouponRemoved(),this.render()}getAppliedCouponCode(){return this.state.appliedCoupon?.code||null}setCouponCode(e,t=!1){this.state.inputValue=e.trim(),this.state.errorMessage=null,t&&this.state.inputValue?this.applyCoupon():this.render()}setPlanCode(e){if(this.options.planCode=e,this.state.appliedCoupon){const e=this.state.appliedCoupon.code;this.state.inputValue=e,this.applyCoupon()}}reset(){this.state={inputValue:"",isValidating:!1,isValid:!1,errorMessage:null,appliedCoupon:null},this.render()}setContainer(e){this.container=e,this.render()}cleanup(){}}class m{constructor(e,t={}){this.container=e,this.options={onGiftCardCodeChanged:()=>{},initialGiftCardCode:"",...t},this.state={inputValue:this.options.initialGiftCardCode,isApplied:!!this.options.initialGiftCardCode}}render(){this.container&&(this.container.innerHTML=`\n <div class="gift-card-input-container">\n ${this.state.isApplied?this.renderAppliedGiftCard():this.renderGiftCardForm()}\n </div>\n `,this.attachEventListeners())}renderGiftCardForm(){return`\n <div class="bg-gray-50 rounded-lg p-4">\n <div class="flex items-center justify-between mb-3">\n <label class="text-sm font-medium text-gray-700 flex items-center">\n ${s.H.getIcon("payment","creditCardSolid","w-4 h-4 mr-2")}\n Have a gift card?\n </label>\n </div>\n\n <div class="flex space-x-2">\n <input\n type="text"\n id="gift-card-input"\n value="${this.state.inputValue}"\n placeholder="Enter gift card redemption code"\n class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500"\n />\n <button\n type="button"\n id="apply-gift-card-btn"\n class="px-4 py-2 bg-primary-600 text-white rounded-md hover:bg-primary-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center"\n ${this.state.inputValue.trim()?"":"disabled"}\n >\n Apply\n </button>\n </div>\n <p class="mt-2 text-xs text-gray-500">Gift card will be validated during checkout.</p>\n </div>\n `}renderAppliedGiftCard(){return`\n <div class="bg-purple-50 border border-purple-200 rounded-lg p-4">\n <div class="flex items-center justify-between">\n <div class="flex items-center gap-2">\n <div class="flex-shrink-0">\n ${s.H.getIcon("general","checkCircle","w-5 h-5 text-purple-600")}\n </div>\n <div class="flex items-center gap-2 text-sm text-purple-800">\n <span class="font-medium">Gift Card Code: ${this.state.inputValue}</span>\n </div>\n </div>\n <button\n type="button"\n id="remove-gift-card-btn"\n class="ml-4 text-purple-600 hover:text-purple-700 flex-shrink-0"\n title="Remove gift card"\n >\n ${s.H.getIcon("general","x","w-5 h-5")}\n </button>\n </div>\n </div>\n `}attachEventListeners(){if(!this.container)return;const e=this.container.querySelector("#gift-card-input"),t=this.container.querySelector("#apply-gift-card-btn"),n=this.container.querySelector("#remove-gift-card-btn");e&&t&&(e.addEventListener("input",(e=>{this.state.inputValue=e.target.value,this.state.inputValue.trim()?t.disabled=!1:t.disabled=!0})),e.addEventListener("keypress",(e=>{"Enter"===e.key&&(e.preventDefault(),this.applyGiftCard())})),t.addEventListener("click",(()=>this.applyGiftCard()))),n&&n.addEventListener("click",(()=>this.removeGiftCard()))}applyGiftCard(){const e=this.state.inputValue.trim();e&&(this.state.isApplied=!0,this.options.onGiftCardCodeChanged(e),this.render())}removeGiftCard(){this.state.inputValue="",this.state.isApplied=!1,this.options.onGiftCardCodeChanged(null),this.render()}getAppliedGiftCardCode(){return this.state.isApplied?this.state.inputValue:null}setGiftCardCode(e){this.state.inputValue=e.trim(),this.state.inputValue&&(this.state.isApplied=!0,this.options.onGiftCardCodeChanged(this.state.inputValue)),this.render()}reset(){this.state={inputValue:"",isApplied:!1},this.render()}setContainer(e){this.container=e,this.render()}cleanup(){}}class g{constructor(e,t={}){this.isCabotWealth=!1,this.container=e,this.options={plans:[],userPlans:{},selectedPlan:null,onPlanSelected:()=>{},onCouponApplied:()=>{},onCouponRemoved:()=>{},onGiftCardCodeChanged:()=>{},onCampaignCodeDetected:()=>{},onLoad:()=>{},defaultBillingFilter:"all",displaySettings:{showFilters:!0,showSort:!0,showLegend:!0,showProgress:!0,showCoupon:!0,showGiftCard:!0},...t};i.fl.getProfileUIConfig().defaultCountry;this.state={currentSlide:0,plansPerView:1,isLoading:!1,filters:{billing:"all",trialOnly:!1,sort:"",group:"all"},filteredPlans:[],appliedCoupon:null,couponValidationCache:{}},console.log("PlanSelectionStep initialized:",{currentSlide:this.state.currentSlide,plansPerView:this.state.plansPerView}),this.state.filteredPlans=[...this.options.plans],this.state.plansPerView=this.getPlansPerView(),this.handleResize=this.handleResizeBound.bind(this),window.addEventListener("resize",this.handleResize)}get plansToRender(){return this.state.filteredPlans.length>0?this.state.filteredPlans:this.options.plans}
1async render(){if(!this.container)return;await o.default.load(),this.isCabotWealth=o.default.isCabotWealth(),"all"===this.state.filters.billing&&(this.options.defaultBillingFilter?this.state.filters.billing=this.options.defaultBillingFilter:this.isCabotWealth&&(this.state.filters.billing="year"));const e=new URLSearchParams(window.location.search).has("coupon_code"),t=o.default.isShowCouponField()||e||!0===this.options.displaySettings?.showCoupon;this.container.innerHTML=`\n <div class="plan-selection-step">\n \x3c!-- Header --\x3e\n <div class="mb-6">\n <h3 class="text-xl font-semibold text-gray-900 mb-2">Choose Your Plan</h3>\n ${this.isCabotWealth?"":'<p class="text-gray-600">Select the subscription plan that works best for you</p>'}\n </div>\n\n \x3c!-- Filter Controls --\x3e\n <div id="plan-filters" class="${this.isCabotWealth?"":"mb-6"}${0!==this.options.plans.length&&this.options.displaySettings?.showFilters?"":"hidden"}">\n <div class="bg-gray-50 rounded-lg p-4">\n <div class="flex flex-wrap items-center gap-4">\n \x3c!-- Billing Period Toggle --\x3e\n <div class="flex items-center space-x-3">\n <span class="text-sm font-medium text-gray-700">Billing:</span>\n <div class="inline-flex rounded-lg border border-gray-300 bg-white p-1">\n ${this.isCabotWealth?"":`\n <button \n data-filter="billing" \n data-value="all" \n class="filter-btn px-4 py-1.5 text-sm font-medium rounded-md transition-all duration-200 ${"all"===this.state.filters.billing?"bg-primary-600 text-white shadow-sm":"text-gray-600 hover:text-gray-900"}"\n >\n All\n </button>\n `}\n <button \n data-filter="billing" \n data-value="year" \n class="filter-btn px-4 py-1.5 text-sm font-medium rounded-md transition-all duration-200 ${"year"===this.state.filters.billing?"bg-primary-600 text-white shadow-sm":"text-gray-600 hover:text-gray-900"}"\n >\n ${this.isCabotWealth?"Annual":"Yearly"}\n </button>\n <button \n data-filter="billing" \n data-value="month" \n class="filter-btn px-4 py-1.5 text-sm font-medium rounded-md transition-all duration-200 ${"month"===this.state.filters.billing?"bg-primary-600 text-white shadow-sm":"text-gray-600 hover:text-gray-900"}"\n >\n Monthly\n </button>\n </div>\n </div>\n\n ${this.isCabotWealth?"":`\n \x3c!-- Trial Toggle --\x3e\n <div class="flex items-center space-x-2">\n <label class="relative inline-flex items-center cursor-pointer">\n <input \n type="checkbox" \n id="trial-filter" \n class="sr-only peer" \n ${this.state.filters.trialOnly?"checked":""}\n >\n <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-primary-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary-600"></div>\n <span class="ml-2 text-sm font-medium text-gray-700">Free trial only</span>\n </label>\n </div> \n `}\n\n \n ${this.isCabotWealth?`\n \x3c!-- Group By Dropdown --\x3e\n <div class="flex items-center space-x-2 ml-auto">\n <span class="text-sm font-medium text-gray-700">Group by:</span>\n <select \n id="group-filter" \n class="block w-36 px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:ring-primary-500 focus:border-primary-500"\n >\n <option value="all" ${"all"===this.state.filters.group?"selected":""}>All</option>\n <option value="Growth" ${"Growth"===this.state.filters.group?"selected":""}>Growth</option>\n <option value="Dividend" ${"Dividend"===this.state.filters.group?"selected":""}>Dividend</option>\n <option value="Income" ${"Income"===this.state.filters.group?"selected":""}>Income</option>\n <option value="Options" ${"Options"===this.state.filters.group?"selected":""}>Options</option>\n <option value="Other" ${"Other"===this.state.filters.group?"selected":""}>Other</option>\n </select>\n </div>\n `:!1!==this.options.displaySettings?.showSort?`\n \x3c!-- Sort Dropdown --\x3e\n <div class="flex items-center space-x-2 ml-auto">
1\n <span class="text-sm font-medium text-gray-700">Sort by:</span>\n <select \n id="sort-filter" \n class="block w-32 px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:ring-primary-500 focus:border-primary-500"\n >\n <option value="" ${""===this.state.filters.sort?"selected":""}>Sort by...</option>\n <option value="price-asc" ${"price-asc"===this.state.filters.sort?"selected":""}>Price: Low</option>\n <option value="price-desc" ${"price-desc"===this.state.filters.sort?"selected":""}>Price: High</option>\n <option value="popular" ${"popular"===this.state.filters.sort?"selected":""}>Most Popular</option>\n </select>\n </div>\n `:""}\n </div>\n </div>\n </div>\n\n \x3c!-- Coupon Section --\x3e\n ${t?`\n <div id="coupon-section" class="mb-6 ${0===this.options.plans.length?"hidden":""}">\n <div id="coupon-container"></div>\n </div>\n `:""}\n\n \x3c!-- Gift Card Section --\x3e\n ${this.options.displaySettings?.showGiftCard?`\n <div id="gift-card-section" class="mb-6 ${0===this.options.plans.length?"hidden":""}">\n <div id="gift-card-container"></div>\n </div>\n `:""}
1\n\n \x3c!-- Plans Loading State --\x3e\n <div id="plans-loading" class="hidden py-12">\n ${a.k.render({size:"large",color:"primary",text:"Loading plans...",className:"py-6"})}\n </div>\n\n \x3c!-- Plans Carousel --\x3e\n <div id="plans-carousel-container" class="relative ${0===this.options.plans.length?"hidden":""}">\n\n ${this.isCabotWealth?"":`\n \x3c!-- Plans Count Info --\x3e\n <div id="active-filters-info" class="mb-4 text-sm text-gray-600 ${this.options.displaySettings?.showLegend?"":"hidden"}">\n Showing <span id="filtered-count">0</span> <span id="filtered-text">of <span id="total-count">0</span></span> plans\n </div>\n `}\n\n \x3c!-- Carousel Wrapper --\x3e\n <div class="relative py-4" id="carousel-viewport">\n \x3c!-- Plans carousel --\x3e\n <div class="${1===this.plansToRender.length?"w-full sm:w-2/3 md:w-1/2 lg:w-1/3 mx-auto":`grid grid-flow-col ${this.getGridColumnsClass()}`} transition-transform duration-300 ease-out" id="plans-carousel">\n ${this.renderPlans()}\n </div>\n </div>\n\n \x3c!-- Navigation Controls --\x3e\n ${this.renderNavigationControls()}\n \n \x3c!-- Dots Indicator --\x3e\n <div class="flex justify-center space-x-2 mt-6" id="carousel-dots">\n ${this.renderDots()}\n </div>\n </div>\n\n \x3c!-- Empty State --\x3e\n <div id="plans-empty" class="hidden text-center py-12">\n <div class="mx-auto w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mb-4">\n ${s.H.render("clipboard",{class:"w-8 h-8 text-gray-400"})}\n </div>\n <h3 class="text-lg font-medium text-gray-900 mb-2">No Plans Available</h3>\n <p class="text-gray-600">Please try again later or contact support.</p>\n </div>\n\n \x3c!-- No Results State --\x3e\n <div id="no-results" class="hidden text-center py-12">\n <div class="mx-auto w-16 h-16 bg-yellow-100 rounded-full flex items-center justify-center mb-4">\n ${s.H.render("alert-circle",{class:"w-8 h-8 text-yellow-600"})}\n </div>\n <h3 class="text-lg font-medium text-gray-900 mb-2">No Matching Plans</h3>\n <p class="text-gray-600 mb-4">Try adjusting your filters to see more options.</p>\n <button \n id="clear-filters-btn" \n class="inline-flex items-center px-4 py-2 text-sm font-medium text-primary-600 hover:text-primary-700"\n >\n ${s.H.render("x",{class:"w-4 h-4 mr-2"})}\n Clear filters\n </button>\n </div>\n </div>\n `,this.attachEventListeners(),this.updateDisplay()}renderPlans(){return this.plansToRender&&0!==this.plansToRender.length?this.plansToRender.map(((e,t)=>this.renderPlanCard(e,t))).join(""):""}renderPlanCard(e,t){const n=this.options.selectedPlan?.id===e.id,o=e.isPopular||e.popular||e.featured||e.recommended,i=this.options.userPlans&&e.code&&this.options.userPlans[e.code],a=e.price;let d=a,l=0;if(this.state.appliedCoupon&&!i)if("percent"===this.state.appliedCoupon.discountType){l=a*((this.state.appliedCoupon.discountPercent||0)/100),d=a-l}else"fixed"===this.state.appliedCoupon.discountType&&(l=this.state.appliedCoupon.discountAmount||0,d=Math.max(0,a-l));const c=this.state.appliedCoupon&&!i&&l>0;return`\n <div class="${1===this.plansToRender.length?"px-0":"px-2"}" data-plan-id="${e.id}">\n <div class="plan-card relative rounded-xl border-2 transition-all duration-200 h-full flex flex-col\n ${i?"bg-gray-50 border-gray-300 cursor-not-allowed opacity-60":n?"bg-gradient-to-br from-primary-50 to-secondary-50 border-primary-600 shadow-2xl cursor-pointer transform scale-105":o?"bg-gradient-to-br from-secondary-50 to-primary-50 border-primary-400 shadow-lg hover:shadow-xl hover:scale-102 cursor-pointer":"bg-white border-gray-200 shadow-md hover:shadow-lg hover:border-primary-300 cursor-pointer"}"\n ${i?"":'data-action="select-plan"'}>\n \n \x3c!-- Popular Badge --\x3e\n ${o&&!i?`\n <div class="absolute -top-3 left-1/2 transform -translate-x-1/2 bg-gradient-to-r from-primary-600 to-secondary-600 text-white px-3 py-1 rounded-full text-xs font-semibold shadow-md z-10">
1\n <span class="flex items-center space-x-1">\n ${s.H.render("star",{class:"w-3 h-3"})}\n <span>Popular</span>\n </span>\n </div>\n `:""}\n \n \x3c!-- Subscribed Badge --\x3e\n ${i?`\n <div class="absolute -top-3 left-1/2 transform -translate-x-1/2 bg-gray-500 text-white px-3 py-1 rounded-full text-xs font-medium shadow-sm z-10">\n <span class="flex items-center space-x-1">\n ${s.H.render("check",{class:"w-3 h-3"})}\n <span>Current</span>\n </span>\n </div>\n `:""}\n\n <div class="p-4 flex-1 flex flex-col">\n \x3c!-- Plan Header --\x3e\n <div class="mb-3 text-center">\n <h4 class="${i?"text-lg font-medium text-gray-600":"text-xl font-bold text-gray-900"}">${e.name}</h4>\n ${e.description?`<p class="${i?"text-sm text-gray-500":"text-sm text-gray-600"} mt-1">${this.sanitizeDescription(e.description)}</p>`:""}\n </div>\n\n \x3c!-- Pricing --\x3e\n <div class="mb-3 text-center">\n ${c?`\n \x3c!-- Original Price (strikethrough) --\x3e\n <div class="flex items-end justify-center mb-1">\n <span class="text-xl font-medium text-gray-400 line-through">\n $${a.toFixed(2)}\n </span>\n ${r.U.formatPriceInterval(e.interval,e.intervalLength)?`<span class="text-gray-400 ml-1 text-sm mb-0.5">${r.U.formatPriceInterval(e.interval,e.intervalLength)}</span>`:""}\n </div>\n \x3c!-- Discounted Price --\x3e\n <div class="flex items-end justify-center">\n <span class="text-4xl font-bold bg-gradient-to-r from-green-600 to-emerald-600 bg-clip-text text-transparent">\n $${d.toFixed(2)}\n </span>\n ${r.U.formatPriceInterval(e.interval,e.intervalLength)?`<span class="text-gray-700 ml-1 text-base mb-1 font-medium">${r.U.formatPriceInterval(e.interval,e.intervalLength)}</span>`:""}\n </div>\n \x3c!-- Savings Badge --\x3e\n <div class="mt-2">\n <span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800">\n ${s.H.render("tag",{class:"w-3 h-3 mr-1"})}\n Save $${l.toFixed(2)}${"percent"===this.state.appliedCoupon?.discountType?` (${this.state.appliedCoupon?.discountPercent}% off)`:""}\n </span>\n </div>\n `:`\n \x3c!-- Regular Price --\x3e\n <div class="flex items-end justify-center">\n <span class="${i?"text-2xl font-medium text-gray-500":"text-4xl font-bold bg-gradient-to-r from-primary-600 to-secondary-600 bg-clip-text text-transparent"}">\n $${e.price}\n </span>\n ${r.U.formatPriceInterval(e.interval,e.intervalLength)?`<span class="${i?"text-gray-500":"text-gray-700"} ml-1 text-base mb-1 font-medium">${r.U.formatPriceInterval(e.interval,e.intervalLength)}</span>`:""}\n </div>\n `}\n \x3c!-- Auto-renews tag --\x3e\n ${e.auto_renew&&!e.hideAutoRenewBadge?`\n <div class="mt-2">\n <span class="inline-flex items-center ${i?"text-gray-500":"text-primary-600"} text-xs">\n ${s.H.render("refresh-cw",{class:"w-3 h-3 mr-1"})}\n Auto-renews\n </span>\n </div>\n `:""}\n ${e.setupFee&&e.setupFee>0&&!e.hideSetupFeeBadge?`\n <div class="mt-1">\n <span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">\n $${e.setupFee} setup fee\n </span>\n </div>\n `:""}\n ${e.trialDays>0&&!e.hideFreeTrialBadge?`\n <div class="mt-1">
1\n <span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">\n ${e.trialDays} days free trial\n </span>\n </div>\n `:""}\n </div>\n\n \x3c!-- Features --\x3e\n <div class="space-y-2 mb-4 flex-1">\n ${this.renderPlanFeatures(e)}\n </div>\n\n \x3c!-- Selection Button --\x3e\n <button class="w-full py-3 px-4 rounded-lg font-semibold text-sm transition-all duration-200 transform\n ${i?"bg-gray-200 text-gray-500 cursor-not-allowed":n?"bg-gradient-to-r from-primary-600 to-secondary-600 hover:from-primary-700 hover:to-secondary-700 text-white shadow-lg hover:shadow-xl hover:-translate-y-0.5":"bg-gradient-to-r from-primary-500 to-secondary-600 hover:from-primary-600 hover:to-secondary-700 text-white shadow-md hover:shadow-lg hover:-translate-y-0.5"}"\n ${i?"disabled":""}>\n ${i?"Already Subscribed":n?"â Selected":"Choose This Plan"}\n </button>\n </div>\n </div>\n </div>\n `}renderPlanFeatures(e){const t=["Full access","Email support","Mobile app access","Cancel anytime"];let n;n=e.featured_points&&e.featured_points.length>0?e.featured_points:e.features&&e.features.length>0?e.features:t;const o=this.options.userPlans&&e.code&&this.options.userPlans[e.code];return n.slice(0,4).map((e=>`\n <div class="flex items-start">\n ${s.H.render("check",{class:`w-4 h-4 ${o?"text-gray-400":"text-green-500"} mr-2 flex-shrink-0 mt-0.5`})}\n <span class="text-sm ${o?"text-gray-500":"text-gray-700"}">${e}</span>\n </div>\n `)).join("")}renderNavigationControls(){return this.needsNavigation()?`\n <button id="carousel-prev" class="absolute left-0 top-1/2 -translate-y-1/2 -translate-x-4 bg-white rounded-full shadow-lg p-3 text-gray-600 hover:text-gray-900 transition-all hover:scale-110 disabled:opacity-50 disabled:cursor-not-allowed z-10">\n ${s.H.render("chevron-left",{class:"w-5 h-5"})}\n </button>\n <button id="carousel-next" class="absolute right-0 top-1/2 -translate-y-1/2 translate-x-4 bg-white rounded-full shadow-lg p-3 text-gray-600 hover:text-gray-900 transition-all hover:scale-110 disabled:opacity-50 disabled:cursor-not-allowed z-10">\n ${s.H.render("chevron-right",{class:"w-5 h-5"})}\n </button>\n `:""}renderDots(){if(!this.needsNavigation())return"";const e=this.plansToRender.length,t=Math.max(1,Math.ceil(e/Math.max(1,this.state.plansPerView)));return!isFinite(t)||t<0||t>100?"":Array.from({length:t},((e,t)=>`\n <button class="w-3 h-3 rounded-full transition-all duration-200 ${t===this.state.currentSlide?"bg-primary-600":"bg-gray-300 hover:bg-gray-400"}" data-slide="${t}"></button>\n `)).join("")}attachEventListeners(){if(!this.container)return;const e=new URLSearchParams(window.location.search),t=e.get("coupon_code")||"",n=(e.get("plan_id"),e.get("campaign_key")||"");n&&this.options.onCampaignCodeDetected&&(console.log("[PlanSelectionStep] Campaign code detected from URL:",n),this.options.onCampaignCodeDetected(n)),this.clickHandler&&this.container.removeEventListener("click",this.clickHandler),this.clickHandler=e=>{if(e.defaultPrevented)return;const t=e.target,n=t.closest('[data-action="select-plan"]');if(n){const e=n.closest("[data-plan-id]")?.getAttribute("data-plan-id");return void(e&&this.selectPlan(e))}const o=t.closest(".filter-btn");if(o){const e=o.getAttribute("data-filter"),t=o.getAttribute("data-value");return void(e&&t&&this.updateFilter(e,t))}if(t.closest("#clear-filters-btn"))return void this.clearFilters();if(t.closest("#carousel-prev"))return e.preventDefault(),e.stopPropagation(),console.log("Previous button clicked"),void this.previousSlide();if(t.closest("#carousel-next"))return e.preventDefault(),e.stopPropagation(),console.log("Next button clicked"),void this.nextSlide();const i=t.closest("[data-slide]");
1if(i){const e=parseInt(i.getAttribute("data-slide")||"0");this.goToSlide(e)}else;},this.container.addEventListener("click",this.clickHandler);const o=this.container.querySelector("#trial-filter");o&&o.addEventListener("change",(e=>{const t=e.target;this.updateFilter("trialOnly",t.checked)}));const i=this.container.querySelector("#sort-filter");i&&i.addEventListener("change",(e=>{const t=e.target;this.updateFilter("sort",t.value)}));const a=this.container.querySelector("#group-filter");a&&a.addEventListener("change",(e=>{const t=e.target;this.updateFilter("group",t.value)})),this.addTouchSupport();const s=this.container.querySelector("#coupon-container");if(s&&(!0===this.options.displaySettings?.showCoupon||t)){const e=this.state.appliedCoupon;this.couponInput=new u(s,{planCode:this.options.selectedPlan?.code,initialCouponCode:t||e?.code||"",onCouponApplied:(e,t)=>{this.state.appliedCoupon&&this.state.appliedCoupon.code!==e&&(this.state.couponValidationCache={}),this.state.appliedCoupon=t,this.updatePlanCardPrices(),this.options.onCouponApplied(e,t)},onCouponRemoved:()=>{this.state.appliedCoupon=null,this.state.couponValidationCache={},this.updatePlanCardPrices(),this.options.onCouponRemoved()}}),this.couponInput.render(),e?setTimeout((()=>{this.couponInput&&this.couponInput.setCouponCode(e.code,!0)}),100):t&&setTimeout((()=>{this.couponInput&&this.couponInput.setCouponCode(t,!0)}),100)}const r=this.container.querySelector("#gift-card-container");r&&this.options.displaySettings?.showGiftCard&&(this.giftCardInput=new m(r,{onGiftCardCodeChanged:e=>{this.options.onGiftCardCodeChanged(e)}}),this.giftCardInput.render())}async updatePlanCardPrices(){if(!this.state.appliedCoupon)return void this.renderPlanCardsWithoutDiscount();const e=this.container.querySelectorAll("[data-plan-id]"),t=this.state.appliedCoupon.code,n=Array.from(e).map((async e=>{const n=e.getAttribute("data-plan-id"),o=this.plansToRender.find((e=>e.id===n));if(!o)return;if(this.options.userPlans&&o.code&&this.options.userPlans[o.code])return;const i=`${t}:${o.code}`;let a=this.state.couponValidationCache[i];if(void 0===a)try{const e=await d.G.validateCoupon(t,o.code);if(e.success&&e.data?.valid){const n=e.data.coupon,o=e.data.discountType||n?.type||n?.discountType||"fixed";a={code:t,discountType:o,discountAmount:e.data.discountAmount||n?.discountAmount,discountPercent:e.data.discountPercent||n?.discountPercent,description:e.data.description||n?.description||n?.name}}else a=null;this.state.couponValidationCache[i]=a}catch(e){console.error(`[PlanSelectionStep] Error validating coupon for plan ${o.code}:`,e),a=null,this.state.couponValidationCache[i]=null}this.updateSinglePlanCardPrice(e,o,a)}));await Promise.all(n)}updateSinglePlanCardPrice(e,t,n){const o=e.querySelector(".plan-card");if(!o)return;const i=o.querySelectorAll("div.mb-3.text-center")[1];if(!i)return;const a=t.price;let d=a,l=0;if(n)if("percent"===n.discountType){l=a*((n.discountPercent||0)/100),d=a-l}else"fixed"===n.discountType&&(l=n.discountAmount||0,d=Math.max(0,a-l));const c=n&&l>0;let u="";const m=r.U.formatPriceInterval(t.interval,t.intervalLength);u=c?`\n \x3c!-- Original Price (strikethrough) --\x3e\n <div class="flex items-end justify-center mb-1">\n <span class="text-xl font-medium text-gray-400 line-through">\n $${a.toFixed(2)}\n </span>\n ${m?`<span class="text-gray-400 ml-1 text-sm mb-0.5">${m}</span>`:""}\n </div>\n \x3c!-- Discounted Price --\x3e\n <div class="flex items-end justify-center">\n <span class="text-4xl font-bold bg-gradient-to-r from-green-600 to-emerald-600 bg-clip-text text-transparent">\n $${d.toFixed(2)}\n </span>\n ${m?`<span class="text-gray-700 ml-1 text-base mb-1 font-medium">${m}</span>`:""}\n </div>\n \x3c!-- Savings Badge --\x3e\n <div class="mt-2">\n <span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800">\n ${s.H.render("tag",{class:"w-3 h-3 mr-1"})}\n Save $${l.toFixed(2)}${"percent"===n?.discountType?` (${n?.discountPercent}% off)`:""}\n </span>\n </div>\n `:`\n \x3c!-- Regular Price --\x3e\n <div class="flex items-end justify-center">
1\n <span class="text-4xl font-bold bg-gradient-to-r from-primary-600 to-secondary-600 bg-clip-text text-transparent">\n $${t.price}\n </span>\n ${m?`<span class="text-gray-700 ml-1 text-base mb-1 font-medium">${m}</span>`:""}\n </div>\n `,i.innerHTML=u}renderPlanCardsWithoutDiscount(){this.container.querySelectorAll("[data-plan-id]").forEach((e=>{const t=e.getAttribute("data-plan-id"),n=this.plansToRender.find((e=>e.id===t));if(!n)return;this.options.userPlans&&n.code&&this.options.userPlans[n.code]||this.updateSinglePlanCardPrice(e,n,null)}))}selectPlan(e){let t=this.state.filteredPlans.find((t=>t.id===e));if(t||(t=this.options.plans.find((t=>t.id===e))),!t)return;this.options.userPlans&&t.code&&this.options.userPlans[t.code]||(this.container.querySelectorAll(".plan-card").forEach((t=>{const n=t.closest("[data-plan-id]")?.getAttribute("data-plan-id"),o=this.options.plans.find((e=>e.id===n)),i=o&&this.options.userPlans&&o.code&&this.options.userPlans[o.code],a=n===e;if(i)return;if(a)t.classList.remove("border-gray-200","hover:border-primary-300","bg-white","shadow-md","hover:shadow-lg","border-primary-400","bg-gradient-to-br","from-secondary-50","to-primary-50","scale-100"),t.classList.add("border-primary-600","shadow-2xl","bg-gradient-to-br","from-primary-50","to-secondary-50","transform","scale-105");else{t.classList.remove("border-primary-600","shadow-2xl","bg-gradient-to-br","from-primary-50","to-secondary-50","transform","scale-105");const e=this.options.plans.find((e=>e.id===n));e?.isPopular?t.classList.add("bg-gradient-to-br","from-secondary-50","to-primary-50","border-primary-400","shadow-lg"):t.classList.add("bg-white","border-gray-200","shadow-md","hover:shadow-lg","hover:border-primary-300")}const s=t.querySelector("button");s&&!s.disabled&&(s.textContent=a?"â Selected":"Choose This Plan")})),this.couponInput&&t.code&&this.couponInput.setPlanCode(t.code),this.options.onPlanSelected&&this.options.onPlanSelected(t))}needsNavigation(){return(this.state.filteredPlans.length>0?this.state.filteredPlans.length:this.options.plans.length)>this.state.plansPerView}previousSlide(){this.state.currentSlide>0&&(this.state.currentSlide--,this.updateCarousel())}nextSlide(){const e=this.state.filteredPlans.length>0?this.state.filteredPlans.length:this.options.plans.length,t=Math.ceil(e/this.state.plansPerView),n=t-1;console.log("NextSlide:",{currentSlide:this.state.currentSlide,planCount:e,plansPerView:this.state.plansPerView,totalSlides:t,maxSlide:n}),this.state.currentSlide<n&&(this.state.currentSlide++,console.log("Moving to slide:",this.state.currentSlide),this.updateCarousel())}goToSlide(e){this.state.currentSlide=e,this.updateCarousel()}updateCarousel(){const e=this.container.querySelector("#plans-carousel");if(e){if(1===this.plansToRender.length)e.className="w-full sm:w-2/3 md:w-1/2 lg:w-1/3 mx-auto",e.style.transform="translateX(0)";else{e.className=`grid grid-flow-col ${this.getGridColumnsClass()} transition-transform duration-300 ease-out`;const t=this.getPlansPerView();if(t!==this.state.plansPerView){this.state.plansPerView=t;const e=this.state.filteredPlans.length>0?this.state.filteredPlans.length:this.options.plans.length,n=Math.ceil(e/this.state.plansPerView)-1;this.state.currentSlide>n&&(this.state.currentSlide=n)}const n=-100*this.state.currentSlide;e.style.transform=`translateX(${n}%)`,console.log("UpdateCarousel:",{currentSlide:this.state.currentSlide,translateX:`${n}%`,plansPerView:this.state.plansPerView})}this.updateNavigationButtons(),this.updateDots(),setTimeout((()=>{this.setupCarouselObserver()}),350)}}updateNavigationButtons(){const e=this.container.querySelector("#carousel-prev"),t=this.container.querySelector("#carousel-next");if(e&&(e.disabled=0===this.state.currentSlide),t){const e=this.state.filteredPlans.length>0?this.state.filteredPlans.length:this.options.plans.length,n=Math.ceil(e/this.state.plansPerView)-1;t.disabled=this.state.currentSlide>=n}}updateDots(){this.container.querySelectorAll("[data-slide]").forEach(((e,t)=>{t===this.state.currentSlide?(e.classList.remove("bg-gray-300","hover:bg-gray-400"),e.classList.add("bg-primary-600")):(e.classList.remove("bg-primary-600"),e.classList.add("bg-gray-300","hover:bg-gray-400"))}))}setupCarouselObserver(){if(this.carouselObserver&&this.carouselObserver.disconnect(),this.plansToRender.length<=1)return;const e=this.container.querySelector("#carousel-viewport");if(!e)return;this.carouselObserver=new IntersectionObserver((e=>{e.forEach((e=>{const t=e.target.closest("[data-plan-id]");if(!t)return;const n=e.intersectionRatio;t.classList.contains("transition-opacity")||t.classList.add("transition-opacity","duration-300","ease-in-out"),n<.2?(t.style.opacity="0",t.style.pointerEvents="none"):n<.5?(t.style.opacity=String(2*n),t.style.pointerEvents="auto"):(t.style.opacity="1",t.style.pointerEvents="auto")}))}
1),{root:e,rootMargin:"-10% 0px -10% 0px",threshold:[0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1]});this.container.querySelectorAll(".plan-card").forEach((e=>{this.carouselObserver&&this.carouselObserver.observe(e)}))}addTouchSupport(){let e=0,t=0,n=!1;const o=this.container.querySelector("#plans-carousel");o&&(o.addEventListener("touchstart",(t=>{e=t.touches[0].clientX,n=!0})),o.addEventListener("touchmove",(e=>{n&&(t=e.touches[0].clientX)})),o.addEventListener("touchend",(()=>{if(!n)return;n=!1;const o=e-t;Math.abs(o)>50&&(o>0?this.nextSlide():this.previousSlide())})))}showLoading(){const e=this.container?.querySelector("#plans-loading"),t=this.container?.querySelector("#plans-carousel-container");e&&e.classList.remove("hidden"),t&&t.classList.add("hidden")}hideLoading(){const e=this.container?.querySelector("#plans-loading");e&&e.classList.add("hidden")}showEmpty(){const e=this.container?.querySelector("#plans-empty");e&&e.classList.remove("hidden")}showError(e){this.container&&(this.container.innerHTML=`\n <div class="plan-selection-step">\n <div class="mb-6">\n <h3 class="text-xl font-semibold text-gray-900 mb-2">Choose Your Plan</h3>\n ${this.isCabotWealth?"":'<p class="text-gray-600">Select the subscription plan that works best for you</p>'}\n </div>\n\n <div class="text-center py-12">\n <div class="mx-auto w-16 h-16 bg-red-100 rounded-full flex items-center justify-center mb-4">\n ${s.H.render("alert-circle",{class:"w-8 h-8 text-red-500"})}\n </div>\n <h3 class="text-lg font-medium text-gray-900 mb-2">Unable to Load Plans</h3>\n <p class="text-gray-600 mb-4">${e}</p>\n <button onclick="location.reload()" class="inline-flex items-center px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors font-medium">\n ${s.H.render("refresh-cw",{class:"w-4 h-4 mr-2"})}\n Refresh Page\n </button>\n </div>\n </div>\n `)}updateDisplay(){if(0===this.options.plans.length)this.showEmpty();else{const e=this.container?.querySelector("#plans-carousel-container"),t=this.container?.querySelector("#plan-filters");e&&e.classList.remove("hidden"),t&&t.classList.remove("hidden"),setTimeout((()=>{this.updateCarousel(),this.updateNavigationButtons(),this.updateDots(),this.updateFilterInfo()}),0)}}updatePlans(e,t={}){this.options.plans=e,this.options.userPlans=t,this.state.filteredPlans=[...e],this.state.currentSlide=0,this.isCabotWealth&&this.applyFilters()}updateSelectedPlan(e){this.options.selectedPlan=e,this.updatePlanCardSelection()}updatePlanCardSelection(){if(!this.container)return;this.container.querySelectorAll("[data-plan-id]").forEach((e=>{const t=e.getAttribute("data-plan-id"),n=this.options.selectedPlan?.id===t,o=this.plansToRender.find((e=>e.id===t));if(!o)return;if(this.options.userPlans&&o.code&&this.options.userPlans[o.code])return;const i=e.querySelector(".plan-card"),a=e.querySelector("button");if(i&&a)if(n)i.className="plan-card relative rounded-xl border-2 transition-all duration-200 h-full flex flex-col bg-gradient-to-br from-primary-50 to-secondary-50 border-primary-600 shadow-2xl cursor-pointer transform scale-105",a.textContent="â Selected";else{const e=o.isPopular||o.popular||o.featured||o.recommended;i.className="plan-card relative rounded-xl border-2 transition-all duration-200 h-full flex flex-col "+(e?"bg-gradient-to-br from-secondary-50 to-primary-50 border-primary-400 shadow-lg hover:shadow-xl hover:scale-102 cursor-pointer":"bg-white border-gray-200 shadow-md hover:shadow-lg hover:border-primary-300 cursor-pointer"),a.textContent="Choose This Plan"}}))}updateFilter(e,t){this.state.filters[e]=t,this.applyFilters()}clearFilters(){this.state.filters={billing:this.isCabotWealth?"month":"all",trialOnly:!1,sort:"",group:this.isCabotWealth?"all":void 0},this.applyFilters()}applyFilters(){let e=[...this.options.plans];if("all"!==this.state.filters.billing&&(e=e.filter((e=>e.interval===this.state.filters.billing))),this.state.filters.trialOnly&&(e=e.filter((e=>e.trialDays>0))),this.isCabotWealth&&this.state.filters.group&&"all"!==this.state.filters.group){const t=this.state.filters.group;e=e.filter((e=>{const n=e.name?.toLowerCase()||"";return"Growth"===t?n.includes("growth"):"Dividend"===t?n.includes("dividend"):"Income"===t?n.includes("income"):"Options"===t?n.includes("options"):"Other"!==t||!(n.includes("growth")||n.includes("dividend")||n.includes("income")||n.includes("options"))}))}if(this.state.filters.sort)switch(this.state.filters.sort){case"price-asc":e.sort(((e,t)=>e.price-t.price));break;case"price-desc":e.sort(((e,t)=>t.price-e.price));break;case"popular":e.sort(((e,t)=>{const n=e.isPopular||e.popular||e.featured||e.recommended?1:0,o=t.isPopular||t.popular||t.featured||t.recommended?1:0;return o!==n?o-n:e.price-t.price}))}this.state.filteredPlans=e,this.state.currentSlide=0,this.render(),setTimeout((()=>this.updateFilterInfo()),0)}updateFilterInfo(){const e=this.container.querySelector("#active-filters-info"),t=this.container.querySelector("#filtered-count"),n=this.container.querySelector("#filtered-text"),o=this.container.querySelector("#total-count"),i=this.container.querySelector("#no-results"),a=this.container.querySelector("#plans-carousel-container"),s=this.container.querySelector("#plans-empty"),r=this.plansToRender.length;0===this.state.filteredPlans.length&&this.options.plans.length>0?(i&&i.classList.remove("hidden"),a&&a.classList.add("hidden"),s&&s.classList.add("hidden")):(i&&i.classList.add("hidden"),a&&a.classList.remove("hidden"),e&&t&&(e.classList.remove("hidden"),t.textContent=r.toString(),n&&o&&(this.state.filteredPlans.length>0&&this.state.filteredPlans.length<this.options.plans.length?(n.classList.remove("hidden"),o.textContent=this.options.plans.length.toString()):n.
1classList.add("hidden"))))}getPlansPerView(){const e=this.plansToRender.length;return window.innerWidth<768?1:window.innerWidth<1024?Math.min(2,e):2===e?2:3}getGridColumnsClass(){const e=this.plansToRender.length;let t;return t=1===e?"lg:auto-cols-[50%] lg:justify-items-center":2===e?"lg:auto-cols-[50%]":"lg:auto-cols-[33.333%]",`auto-cols-[100%] ${e>=2?"md:auto-cols-[50%]":"md:auto-cols-[100%]"} ${t}`}handleResizeBound(){const e=this.getPlansPerView();if(e!==this.state.plansPerView){this.state.plansPerView=e;const t=this.plansToRender.length,n=Math.ceil(t/this.state.plansPerView)-1;this.state.currentSlide>n&&(this.state.currentSlide=n),this.render()}}sanitizeDescription(e){return e?e.replace(/<[^>]*>/g,"").trim():""}cleanup(){this.carouselObserver&&(this.carouselObserver.disconnect(),this.carouselObserver=void 0),window.removeEventListener("resize",this.handleResize),this.clickHandler&&this.container&&this.container.removeEventListener("click",this.clickHandler),this.couponInput&&this.couponInput.cleanup(),this.giftCardInput&&this.giftCardInput.cleanup()}}var h=n(4140),p=n(8050),y=n(5856),C=n(9632),f=n(9948),v=n(6532),b=n(4148),w=n(8215),S=n(8520);class x{constructor(e,t={}){this.activePaymentModal=null,this.container=e,this.options={selectedPlan:null,selectedPaymentMethod:null,appliedCoupon:null,onPaymentMethodSelected:()=>{},...t},this.state={paymentMethods:[],isLoading:!1}}async render(){this.container&&(this.container.innerHTML=`\n <div class="payment-method-step">\n \x3c!-- Header with action button --\x3e\n <div class="mb-6">\n <div class="flex items-start justify-between">\n <div>\n <h3 class="text-xl font-semibold text-gray-900 mb-2">Select Payment Method</h3>\n <p class="text-gray-600">Choose how you'd like to pay for your subscription</p>\n </div>\n <button type="button" \n id="add-payment-method-btn"\n data-action="add-payment-inline" \n class="hidden text-primary-600 hover:text-primary-700 font-medium text-sm flex items-center">\n ${s.H.render("plus",{class:"w-4 h-4 mr-1"})}\n Add Payment Method\n </button>\n </div>\n </div>\n\n \x3c!-- Selected Plan Summary --\x3e\n ${this.renderPlanSummary()}\n\n \x3c!-- Payment Methods Loading --\x3e\n <div id="payment-methods-loading" class="hidden py-8">\n ${a.k.render({size:"medium",color:"indigo",text:"Loading payment methods...",className:"py-4"})}\n </div>\n\n \x3c!-- Payment Methods List --\x3e\n <div id="payment-methods-container" class="space-y-4">\n ${this.renderPaymentMethods()}\n </div>\n </div>\n `,await this.loadPaymentMethods(),this.attachEventListeners())}renderPlanSummary(){if(!this.options.selectedPlan)return"";const e=this.options.selectedPlan,t=this.options.appliedCoupon;let n=e.price,o=!1,i=0;return t&&(o=!0,"percent"===t.discountType&&t.discountPercent?(i=e.price*t.discountPercent/100,n=e.price-i):"fixed"===t.discountType&&t.discountAmount&&(i=t.discountAmount,n=Math.max(0,e.price-t.discountAmount))),`\n <div class="bg-gradient-to-r from-primary-50 to-secondary-50 rounded-lg p-4 mb-6 border border-primary-200">\n <div class="flex items-center justify-between">\n <div class="flex items-center">\n <div class="p-2 bg-white rounded-lg shadow-sm mr-4">\n ${s.H.render("clipboard",{class:"w-6 h-6 text-primary-600"})}\n </div>\n <div>\n <h4 class="font-semibold text-gray-900">${e.name} Plan</h4>\n <p class="text-sm text-gray-600">${this.sanitizeDescription(e.description||"")}</p>\n ${e.trialDays&&e.trialDays>0?`\n <p class="text-sm text-green-700 font-medium mt-1">\n ${e.trialDays} days free trial included\n </p>\n `:""}\n ${o&&t?`\n <div class="flex items-center gap-2 mt-1">\n <div class="flex items-center gap-1 text-sm text-green-700">\n ${s.H.render("tag",{class:"w-4 h-4"})}
1\n <span class="font-medium">Coupon Applied: ${t.code}</span>\n </div>\n </div>\n `:""}\n </div>\n </div>\n <div class="text-right">\n ${o?`\n <div class="text-sm text-gray-500 line-through">$${e.price.toFixed(2)}</div>\n <div class="text-2xl font-bold bg-gradient-to-r from-green-600 to-green-700 bg-clip-text text-transparent">\n $${n.toFixed(2)}\n </div>\n <div class="text-xs text-green-600 font-medium">Save $${i.toFixed(2)}</div>\n `:`\n <div class="text-2xl font-bold text-gray-900">$${e.price}</div>\n `}\n ${r.U.formatPriceInterval(e.interval,e.intervalLength)?`<div class="text-sm text-gray-600">${r.U.formatPriceInterval(e.interval,e.intervalLength).replace("/","per")}</div>`:""}\n </div>\n </div>\n </div>\n `}sanitizeDescription(e){return e?e.replace(/<[^>]*>/g,"").trim():""}renderPaymentMethods(){return this.state.isLoading?"":0===this.state.paymentMethods.length?`\n <div class="payment-method-step-empty">\n \x3c!-- Inline payment form container --\x3e\n <div id="inline-payment-form">\n \x3c!-- This will be automatically populated with either address or payment form --\x3e\n <div class="text-center py-8">\n ${a.k.render({size:"medium",text:"Loading...",className:""})}\n </div>\n </div>\n </div>\n `:this.state.paymentMethods.map((e=>this.renderPaymentMethodCard(e))).join("")}renderPaymentMethodCard(e){const t=this.options.selectedPaymentMethod?.id===e.id,n=e.isDefault;return`\n <div class="payment-method-card border-2 rounded-lg p-4 cursor-pointer transition-all duration-200 hover:shadow-md\n ${t?"border-primary-600 bg-primary-50 shadow-md":"border-gray-200 hover:border-gray-300"}"\n data-payment-method-id="${e.id}"\n data-action="select-payment-method">\n\n \x3c!-- Selection Indicator --\x3e\n <div class="flex items-center justify-between">\n <div class="flex items-center flex-1">\n \x3c!-- Card Icon --\x3e\n <div class="p-3 rounded-lg mr-4 ${this.getCardBackgroundClass(e.brand)}">\n ${s.H.render("credit-card",{class:"w-6 h-6 text-white"})}\n </div>\n\n \x3c!-- Card Details --\x3e\n <div class="flex-1">\n <div class="flex items-center">\n <span class="font-medium text-gray-900 capitalize">${e.brand}</span>\n <span class="mx-2 text-gray-400">â¢â¢â¢â¢</span>\n <span class="font-medium text-gray-900">${e.last4}</span>\n ${n?'\n <span class="ml-3 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">\n Default\n </span>\n ':""}\n </div>\n <div class="text-sm text-gray-600 mt-1">\n Expires ${e.expMonth}/${e.expYear}\n ${e.cardholderName?` ⢠${e.cardholderName}`:""}\n </div>\n </div>\n </div>\n\n \x3c!-- Selection Radio --\x3e\n <div class="ml-4">\n <div class="w-6 h-6 rounded-full border-2 transition-all duration-200 flex items-center justify-center\n ${t?"border-primary-600 bg-primary-600":"border-gray-300"}">\n ${s.H.render("check",{class:"w-4 h-4 text-white "+(t?"":"hidden")})}\n </div>\n </div>\n </div>\n </div>\n `}getCardBackgroundClass(e){const t={visa:"bg-gradient-to-br from-blue-600 to-blue-700",mastercard:"bg-gradient-to-br from-red-500 to-yellow-500",amex:"bg-gradient-to-br from-green-600 to-green-700",discover:"bg-gradient-to-br from-orange-500 to-orange-600",card:"bg-gradient-to-br from-gray-600 to-gray-700"};return t[e?.toLowerCase()]||t.card}async loadPaymentMethods(){this.showLoading();try{const e=await h.paymentMethodsAPI.getPaymentMethods();let t=e?.data?.paymentMethods||e?.data;if(t&&"object"==typeof t&&"message"in t)this.state.paymentMethods=[];else if(t&&(Array.isArray(t)||"object"==typeof t&&Object.keys(t).length>0)){const e=Array.isArray(t)?t:Object.values(t),n=e.filter((e=>e&&(e.id||e.maskedCardNumber||e.cardType||e.last4))).map(((e,t)=>({id:e.id||`method_${t}`,billingInfoId:e.billingInfoId||e.id,last4:e.maskedCardNumber?e.maskedCardNumber.slice(-4):"****",brand:e.cardType?e.cardType.toLowerCase():"card",expMonth:e.expiryMonth||"**",expYear:e.expiryYear?String(e.expiryYear).slice(-2):"**",cardholderName:e.cardholderName,isDefault:e.isDefault||!1,_original:e})));this.state.paymentMethods=n,this.methodToAutoSelect=null;const o=n.find((e=>e.isDefault));o&&!this.options.selectedPaymentMethod?this.methodToAutoSelect=o:1!==n.length||this.options.selectedPaymentMethod||(this.methodToAutoSelect=n[0])}else this.state.paymentMethods=[]}catch(e){console.error("[PaymentMethodStep] Error loading payment methods:",e),this.state.paymentMethods=[]}this.hideLoading(),await this.updateDisplay()}selectPaymentMethod(e){this.container.querySelectorAll(".payment-method-card").forEach((t=>{const n=t.dataset.paymentMethodId===e.id;n?(t.classList.remove("border-gray-200","hover:border-gray-300"),t.classList.add("border-primary-600","bg-primary-50","shadow-md")):(t.classList.remove("border-primary-600","bg-primary-50","shadow-md"),t.classList.add("border-gray-200","hover:border-gray-300"));const o=t.querySelector(".w-6.h-6.rounded-full"),i=o?.querySelector("svg");o&&(n?(o.classList.remove("border-gray-300"),o.classList.add("border-primary-600","bg-primary-600"),i&&i.classList.remove("hidden")):(o.classList.remove("border-primary-600","bg-primary-600"),o.classList.add("border-gray-300"),i&&i.classList.add("hidden")))})),this.options.onPaymentMethodSelected&&this.options.onPaymentMethodSelected(e)}async handleManagePaymentMethods(){try{if(!window.location.pathname.includes("/profile")){const e=await this.fetchAddresses();if(!e.some((e=>e.isBilling||e.isDefaultBilling)))return void await this.showAddBillingAddressModal()}await this.showAddPaymentMethodModal()}catch(e){console.error("Error handling manage payment methods:",e),window.location.href="/profile#payment"}}async fetchAddresses(){try{const e=await y.A.getAddresses();let t=[];return e&&e.addresses?"object"!=typeof e.addresses||Array.isArray(e.addresses)?Array.isArray(e.addresses)&&(t=e.addresses):t=Object.values(e.addresses):Array.isArray(e)&&(t=e),t}catch(e){return console.error("Failed to fetch addresses:",e),[]}}async showAddBillingAddressModal(){const e=new C.W({title:"Add Billing Address",submitText:"Save & Continue",hideAddressType:!0,forceBillingOnly:!0,showDefaults:!0,showAccountAddress:!0,address:{firstName:"",lastName:"",street1:"",street2:"",city:"",region:"",postalCode:"",country:o.default.getDefaultCountry()||"US",phone:"",isShipping:!1,isBilling:!0,isDefaultBilling:!0},onSave:async e=>{try{await y.A.addAddress(e);try{const{default:e}=await Promise.resolve().then(n.bind(n,4849));await e.loadAddresses(!0),document.dispatchEvent(new CustomEvent("profile:addresses:refresh",{detail:{source:"subscription-payment-step-modal"},bubbles:!0}))}catch(e){console.error("Failed to refresh AddressManager cache:",e)}if(e.isDefaultBilling&&e.firstName&&e.lastName)try{const t=await b._.getProfile();if(t.success&&t.data?.profile){const n=t.data.profile;if(!n.firstName&&!n.lastName){const t=await b._.updateProfile({firstName:e.firstName,lastName:e.lastName,mobileNumber:e.mobileNumber,otherPhone:e.otherPhone||e.phone,smsAgreementOptIn:e.smsAgreementOptIn});if(t.success&&t.data){const o={...n,...t.data,firstName:e.firstName,lastName:e.lastName,mobileNumber:e.mobileNumber,otherPhone:e.otherPhone||e.phone,smsAgreementOptIn:e.smsAgreementOptIn};w.nU.emit("UPDATED",{data:o})}}}}catch(e){console.error("[PaymentMethodStep] Failed to update profile with names:",e)}await this.loadPaymentMethods();const t=this.container?.querySelector("#payment-container");t&&(t.innerHTML=this.renderPaymentMethods())}catch(e){if(console.error("Failed to save address:",e),e instanceof Error&&"status"in e&&401===e.status){const e=document.createElement("button");throw e.setAttribute("data-login-trigger","true"),e.style.display="none",document.body.appendChild(e),e.click(),e.remove(),new Error("Your session has expired. Please log in again to continue.")}throw e}},onCancel:()=>{}});await e.render()}async showInlineBillingAddressForm(){const e=this.container?.querySelector("#inline-payment-form");if(!e)return;const t=await this.fetchAddresses();t.length>0?await this.showAddressSelection(t):await this.showAddAddressForm()}async showAddressSelection(e){const t=this.container?.querySelector("#inline-payment-form");if(!t)return;const n=[...e.filter((e=>e.isBilling||e.isDefaultBilling)),...e.filter((e=>!e.isBilling&&!e.isDefaultBilling))];t.innerHTML=`\n <div class="space-y-4">\n \x3c!-- Header with action --\x3e\n <div class="flex items-center justify-between mb-4">\n <div>\n <h4 class="text-lg font-medium text-gray-900">Select Billing Address</h4>\n <p class="text-sm text-gray-600 mt-1">Choose where we'll send your bills</p>\n </div>\n <button type="button" \n data-action="add-new-address" \n class="text-primary-600 hover:text-primary-700 font-medium text-sm flex items-center">\n ${s.H.render("plus",{class:"w-4 h-4 mr-1"})}\n Add New\n </button>\n </div>
1\n \n \x3c!-- Address options --\x3e\n <div class="space-y-3">\n ${n.map(((e,t)=>`\n <div class="address-option border-2 rounded-lg p-4 cursor-pointer transition-all hover:border-primary-300 hover:shadow-sm ${0===t?"border-primary-500 bg-primary-50":"border-gray-200"}"\n data-address-id="${e.id}"\n data-action="select-address">\n <div class="flex items-start justify-between">\n <div class="flex-1">\n <div class="flex items-center mb-1">\n <span class="font-medium text-gray-900">${e.firstName} ${e.lastName}</span>\n ${e.isDefaultBilling?'<span class="ml-2 text-xs bg-green-100 text-green-800 px-2 py-0.5 rounded-full">Default</span>':""}\n </div>\n <div class="text-sm text-gray-600">\n <div>${e.street1}${e.street2?", "+e.street2:""}</div>\n <div>${e.city}, ${e.region} ${e.postalCode}</div>\n </div>\n </div>\n <div class="ml-4">\n <div class="w-5 h-5 rounded-full border-2 flex items-center justify-center ${0===t?"border-primary-600 bg-primary-600":"border-gray-300"}">\n ${0===t?s.H.render("check",{class:"w-3 h-3 text-white"}):""}\n </div>\n </div>\n </div>\n </div>\n `)).join("")}\n </div>\n \n \x3c!-- Continue button --\x3e\n <div class="pt-2">\n <button type="button"\n data-action="continue-with-address"\n data-selected-address-id="${n[0]?.id}"\n class="w-full px-4 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors font-medium">\n Continue to Payment\n </button>\n </div>\n </div>\n `,this.selectedBillingAddressId=n[0]?.id}async showAddAddressForm(){const e=this.container?.querySelector("#inline-payment-form");if(!e)return;const t=await this.fetchAddresses(),n=0===t.length;let o="",i="";try{const e=await b._.getProfile();e.success&&e.data?.profile&&(o=e.data.profile.firstName||"",i=e.data.profile.lastName||"")}catch(e){console.error("Failed to get profile for defaults:",e)}const a=new C.W({inline:!0,isFirstAddress:n,hideAddressType:!0,forceBillingOnly:!0,showDefaults:!0,showAccountAddress:!0,hideBackButton:!0,defaultFirstName:o,defaultLastName:i,onSave:async e=>{await this.handleAddressSaved(e)},onCancel:()=>{t.length>0?this.showAddressSelection(t):e.innerHTML=""}});await a.renderInline(e)}async handleAddressSaved(e){try{await y.A.addAddress(e);try{const{default:e}=await Promise.resolve().then(n.bind(n,4849));await e.loadAddresses(!0),document.dispatchEvent(new CustomEvent("profile:addresses:refresh",{detail:{source:"subscription-payment-step-inline"},bubbles:!0}))}catch(e){console.error("Failed to refresh AddressManager cache:",e)}if(e.isAccount&&e.firstName&&e.lastName)try{const t=await b._.getProfile();if(t.success&&t.data?.profile){const n=t.data.profile;n.firstName||n.lastName||(await b._.updateProfile({firstName:e.firstName,lastName:e.lastName,mobileNumber:e.mobileNumber,otherPhone:e.otherPhone||e.phone,smsAgreementOptIn:e.smsAgreementOptIn}),w.nU.emit("UPDATED",{data:{...n,firstName:e.firstName,lastName:e.lastName,mobileNumber:e.mobileNumber,otherPhone:e.otherPhone||e.phone,smsAgreementOptIn:e.smsAgreementOptIn}}))}}catch(e){console.error("[PaymentMethodStep] Failed to update profile with names:",e)}const t=await this.fetchAddresses();let o;t.length>0&&(o=t.find((t=>t.firstName===e.firstName&&t.lastName===e.lastName&&t.street1===e.street1&&t.city===e.city))||t[t.length-1]),o?.id&&(this.selectedBillingAddressId=o.id),p.Alert.flash({message:"Billing address saved successfully!",variant:"success",duration:3e3}),this.updateStepIndicator(2),await this.renderInlinePaymentMethodForm()}catch(e){if(console.error("Failed to save address:",e),e instanceof Error&&"status"in e&&401===e.status){const e=document.createElement("button");throw e.setAttribute("data-login-trigger","true"),e.style.display="none",document.body.appendChild(e),e.click(),e.remove(),new Error("Your session has expired. Please log in again to continue.")}throw e}}selectAddress(e){this.container.querySelectorAll(".address-option").forEach((t=>{const n=t.getAttribute("data-address-id")===e;n?(t.classList.add("border-primary-500","bg-primary-50"),t.classList.remove("border-gray-200")):(t.classList.remove("border-primary-500","bg-primary-50"),t.classList.add("border-gray-200"));const o=t.querySelector(".w-5.h-5");o&&(n?(o.classList.add("border-primary-600","bg-primary-600"),o.classList.remove("border-gray-300"),o.innerHTML=s.H.render("check",{class:"w-3 h-3 text-white"})):(o.classList.remove("border-primary-600","bg-primary-600"),o.classList.add("border-gray-300"),o.innerHTML=""))}));const t=this.container.querySelector('[data-action="continue-with-address"]');t&&t.setAttribute("data-selected-address-id",e),this.selectedBillingAddressId=e}async handleAddressFormSubmit(e){const t=new FormData(e),o=e.querySelector('button[type="submit"]');o&&(o.disabled=!0,o.textContent="Saving...");try{const o={firstName:t.get("firstName"),lastName:t.get("lastName"),street1:t.get("street1"),street2:t.get("street2")||"",city:t.get("city"),region:t.get("region"),postalCode:t.get("postalCode"),country:t.get("country"),phone:t.get("phone")||"",isShipping:!1,isBilling:!0,isDefaultBilling:!0,isAccount:e.querySelector("#isAccount")?.checked||!1};o.isAccount&&(o.isDefaultBilling=!0);await y.A.addAddress(o);try{const{default:e}=await Promise.resolve().then(n.bind(n,4849));await e.loadAddresses(!0),document.dispatchEvent(new CustomEvent("profile:addresses:refresh",{detail:{source:"subscription-payment-step"},bubbles:!0}))}catch(e){console.error("Failed to refresh AddressManager cache:",e)}if(o.isAccount&&o.firstName&&o.lastName)try{const e=await b._.getProfile();if(e.success&&e.data?.profile){const t=e.data.profile;t.firstName||t.lastName||(await b._.updateProfile({firstName:o.firstName,lastName:o.lastName,mobileNumber:o.mobileNumber,otherPhone:o.otherPhone||o.phone,smsAgreementOptIn:o.smsAgreementOptIn}),w.nU.emit("UPDATED",{data:{...t,firstName:o.firstName,lastName:o.lastName,mobileNumber:o.mobileNumber,otherPhone:o.otherPhone||o.phone,smsAgreementOptIn:o.smsAgreementOptIn}}))}}catch(e){console.error("[PaymentMethodStep] Failed to update profile with names:",e)}const i=await this.fetchAddresses();let a;i.length>0&&(a=i.find((e=>e.firstName===o.firstName&&e.lastName===o.lastName&&e.street1===o.street1&&e.city===o.city))||i[i.length-1]),a?.id&&
1(this.selectedBillingAddressId=a.id),await this.renderInlinePaymentMethodForm()}catch(t){console.error("Failed to save address:",t),o&&(o.disabled=!1,o.textContent="Save & Continue");const n=document.createElement("div");n.className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg mb-4",n.textContent="Failed to save address. Please try again.",e.insertBefore(n,e.firstChild),setTimeout((()=>n.remove()),5e3)}}getCountryName(e){return{US:"United States",CA:"Canada",GB:"United Kingdom",IE:"Ireland",AU:"Australia",NZ:"New Zealand"}[e]||e}async renderInlinePaymentMethodForm(){const e=this.container?.querySelector("#inline-payment-form");e&&await this.showInlinePaymentModal(e)}async showInlinePaymentForm(){const e=this.container?.querySelector("#payment-methods-container");if(!e)return;0===(await this.fetchAddresses()).filter((e=>e.isBilling||e.isDefaultBilling||e.isAccount)).length?(e.innerHTML='\n <div id="inline-payment-form">\n \x3c!-- Will be populated with address form --\x3e\n </div>\n ',await this.showAddAddressForm()):(e.innerHTML='\n <div id="inline-payment-form">\n \x3c!-- Will be populated with payment form --\x3e\n </div>\n ',await this.renderInlinePaymentMethodForm());const t=this.container?.querySelector("#add-payment-method-btn");t&&t.classList.add("hidden")}async showInlinePaymentModal(e){try{const t=(await o.default.load()).recurlyPublicKey;if(!t)return console.warn("[PaymentMethodStep] No Recurly public key found"),void(e.innerHTML='\n <div class="text-center py-8 text-gray-600">\n <p>Payment configuration is not available. Please contact support.</p>\n </div>\n ');let i;try{i=(await Promise.resolve().then(n.bind(n,4081))).default}catch(e){if(console.error("[PaymentMethodStep] Failed to import PaymentModal:",e),!window.HeimGuard?.PaymentModal)throw new Error("PaymentModal not available");i=window.HeimGuard.PaymentModal}const a=new i({addresses:await this.fetchAddresses(),recurlyPublicKey:t,inline:!0,onSuccess:async t=>{try{const e=t.last4,o=t.cardType;console.log("[PaymentMethodStep] Storing card details for matching:",{cardLast4:e,cardType:o});const{paymentMethodsAPI:i}=await Promise.resolve().then(n.bind(n,4140)),a={recurlyToken:t.tokenId,billingAddressId:t.billingAddress.id,firstName:t.billingAddress.firstName,lastName:t.billingAddress.lastName,cardholderName:t.cardholderName,default:0===this.state.paymentMethods.length,saveCard:!0},s=await i.addPaymentMethod(a);if(!s.success)throw new Error("Failed to save payment method");{console.log("[PaymentMethodStep] Backend response:",s.data),this.activePaymentModal=null,await this.loadPaymentMethods(),console.log("[PaymentMethodStep] Looking for newly added method by card details. Last4:",e),console.log("[PaymentMethodStep] Available payment methods:",this.state.paymentMethods);const t=this.state.paymentMethods.find((t=>{const n=t.last4===e;return console.log("[PaymentMethodStep] Comparing:",t.last4,"with",e,"=",n),n}));t?(console.log("[PaymentMethodStep] â
Found newly added method by last4, setting for auto-selection:",t),this.methodToAutoSelect=t,console.log("[PaymentMethodStep] Calling updateDisplay to apply selection..."),await this.updateDisplay(),console.log("[PaymentMethodStep] updateDisplay complete")):console.warn("[PaymentMethodStep] â Could not find newly added payment method by card details",{searchLast4:e,availableCards:this.state.paymentMethods.map((e=>({last4:e.last4,brand:e.brand})))}),p.Alert.flash({message:"Payment method added successfully!",variant:"success",duration:3e3});const n=this.container?.querySelector("#add-payment-method-btn");n&&(n.classList.remove("hidden"),n.classList.add("flex"))}}catch(t){console.error("[PaymentMethodStep] Error saving payment method:",t),p.Alert.flash({message:"Failed to save payment method. Please try again.",variant:"error",duration:5e3}),await this.showInlinePaymentModal(e)}},onCancel:()=>{this.activePaymentModal=null,this.updateDisplay();const e=this.container?.querySelector("#add-payment-method-btn");e&&(e.classList.remove("hidden"),e.classList.add("flex"))},onAddressNeeded:async()=>await this.fetchAddresses()});this.activePaymentModal=a,e.innerHTML="",await a.renderInline(e)}catch(t){console.error("[PaymentMethodStep] Error showing inline payment modal:",t),console.error("[PaymentMethodStep] Error details:",{message:t.message,stack:t.stack,name:t.name}),e.innerHTML=`\n <div class="bg-red-50 border border-red-200 rounded-lg p-4">\n <div class="flex items-start">\n ${s.H.render("x-circle",{class:"w-5 h-5 text-red-400 mt-0.5 mr-3"})}\n <div>
1\n <h4 class="text-sm font-medium text-red-800 mb-1">Failed to load payment form</h4>\n <p class="text-sm text-red-700">${t.message||"An unexpected error occurred"}</p>\n <button \n type="button" \n data-action="retry-payment-form"\n class="mt-3 text-sm text-red-700 hover:text-red-800 underline font-medium"\n >\n Try again\n </button>\n </div>\n </div>\n </div>\n `;const n=e.querySelector('[data-action="retry-payment-form"]');n&&n.addEventListener("click",(async()=>{await this.showInlinePaymentModal(e)}))}}async showAddPaymentMethodModal(){try{if(!f.Ay.recurlyPublicKey){const e=(await o.default.load()).recurlyPublicKey;if(!e)return console.warn("No Recurly public key found in settings"),void(window.location.href="/profile#payment");await f.Ay.initialize(e)}let e=null,t=null;const n=async n=>{e&&(e(),e=null),t&&(t(),t=null),await this.loadPaymentMethods()},i=()=>{e&&(e(),e=null),t&&(t(),t=null)};e=(0,v.yH)(v.aC.MODAL_SUCCESS,n),t=(0,v.yH)(v.aC.MODAL_CLOSED,i),await f.Ay.openAddModal({inline:!0})}catch(e){console.error("Failed to show payment method modal:",e),window.location.href="/profile#payment"}}attachEventListeners(){this.container&&this.container.addEventListener("click",(async e=>{const t=e.target;if(t.closest('[data-action="manage-payment-methods"]'))return e.preventDefault(),void await this.handleManagePaymentMethods();if(t.closest('[data-action="add-payment-inline"]'))return e.preventDefault(),void await this.showInlinePaymentForm();const n=t.closest('[data-action="select-address"]');if(n){e.preventDefault();const t=n.getAttribute("data-address-id");return void(t&&this.selectAddress(t))}if(t.closest('[data-action="add-new-address"]'))return e.preventDefault(),void await this.showAddAddressForm();const o=t.closest('[data-action="continue-with-address"]');if(o){e.preventDefault();const t=o.getAttribute("data-selected-address-id");return void(t&&(this.selectedBillingAddressId=t,await this.renderInlinePaymentMethodForm()))}if(t.closest('[data-action="cancel-address"]'))return e.preventDefault(),void await this.updateDisplay();if(t.closest('[data-action="back-to-addresses"]')){e.preventDefault();const t=await this.fetchAddresses();return void await this.showAddressSelection(t)}const i=t.closest('[data-action="select-payment-method"]');if(i){const e=i.getAttribute("data-payment-method-id");if(e){const t=this.state.paymentMethods.find((t=>t.id===e));t&&this.selectPaymentMethod(t)}}else;}))}showLoading(){const e=this.container?.querySelector("#payment-methods-loading");e&&e.classList.remove("hidden")}hideLoading(){const e=this.container?.querySelector("#payment-methods-loading");e&&e.classList.add("hidden")}async updateDisplay(){const e=this.container?.querySelector("#payment-methods-container");if(e){e.innerHTML=this.renderPaymentMethods();const t=this.container?.querySelector("#add-payment-method-btn");if(t)try{const e=await S.initService.getInitData();(e.generalConfig?.enableAddCard??!0)&&this.state.paymentMethods.length>0?(t.classList.remove("hidden"),t.classList.add("flex")):(t.classList.add("hidden"),t.classList.remove("flex"))}catch(e){console.error("[PaymentMethodStep] Failed to check enableAddCard flag:",e),this.state.paymentMethods.length>0?(t.classList.remove("hidden"),t.classList.add("flex")):(t.classList.add("hidden"),t.classList.remove("flex"))}console.log("[PaymentMethodStep] updateDisplay - checking methodToAutoSelect:",this.methodToAutoSelect),this.methodToAutoSelect?(console.log("[PaymentMethodStep] methodToAutoSelect is set, scheduling auto-selection in 50ms"),setTimeout((()=>{console.log("[PaymentMethodStep] setTimeout fired, selecting method:",this.methodToAutoSelect),this.methodToAutoSelect&&(this.selectPaymentMethod(this.methodToAutoSelect),this.methodToAutoSelect=null,console.log("[PaymentMethodStep] Auto-selection complete, methodToAutoSelect cleared"))}),50)):console.log("[PaymentMethodStep] No methodToAutoSelect, skipping auto-selection"),0===this.state.paymentMethods.length&&await this.checkAndShowAddressForm()}}updateStepIndicator(e){const t=this.container?.querySelector('[data-step="1"]'),n=this.container?.querySelector('[data-step="2"]');2===e&&t&&n&&(t.classList.remove("bg-primary-100","text-primary-600"),t.classList.add("bg-green-100","text-green-600"),t.innerHTML=s.H.render("check",{class:"w-4 h-4"}),n.classList.remove("bg-gray-100","text-gray-400"),n.classList.add("bg-primary-100","text-primary-600"))}async checkAndShowAddressForm(){try{0===(await this.fetchAddresses()).length?await this.showAddAddressForm():await this.showInlineBillingAddressForm()}catch(e){console.error("[PaymentMethodStep] Error checking addresses:",e)}}getSelectedPaymentMethod(){return this.options.selectedPaymentMethod}getActivePaymentModal(){return this.activePaymentModal}cleanup(){this.activePaymentModal=null}}class A{constructor(e,t={}){this.isCabotWealth=!1,this.lastCouponCode=null,this.container=e,this.options={selectedPlan:null,selectedPaymentMethod:null,
1selectedBillingInfoId:null,couponCode:null,appliedCoupon:null,onConfirm:()=>{},onEdit:()=>{},...t},this.state={termsAccepted:!1,isProcessing:!1,settings:null,previewData:null,previewLoading:!1,previewError:null}}async render(){if(!this.container)return;try{this.state.settings=await o.default.load(),this.isCabotWealth=o.default.isCabotWealth()}catch(e){this.state.settings={terms:"",privacyPolicy:""}}const e=o.default.isEnableTaxPreview();this.lastCouponCode!==this.options.couponCode&&(this.state.previewData=null,this.state.previewError=null,this.lastCouponCode=this.options.couponCode),e&&this.options.selectedPlan&&this.options.selectedBillingInfoId&&!this.state.previewData&&!this.state.previewLoading&&!this.state.previewError&&await this.loadPreviewData(),this.container.innerHTML=`\n <div class="review-step">\n \x3c!-- Header --\x3e\n <div class="mb-6">\n <h3 class="text-xl font-semibold text-gray-900 mb-2">${this.isCabotWealth?"Review and Submit":"Review & Confirm"}</h3>\n ${this.isCabotWealth?"":'<p class="text-gray-600">Please review your subscription details before confirming</p>'}\n </div>\n\n \x3c!-- Plan Review --\x3e\n <div class="bg-white rounded-lg border border-gray-200 mb-6">\n <div class="px-6 py-4 border-b border-gray-200">\n <div class="flex items-center justify-between">\n <h4 class="text-lg font-medium text-gray-900 flex items-center">\n ${s.H.getIcon("general","clipboard","w-5 h-5 text-gray-400 mr-2")}\n Subscription Plan\n </h4>\n <button class="text-primary-600 hover:text-primary-700 text-sm font-medium" data-action="edit-plan">\n Edit\n </button>\n </div>\n </div>\n <div class="px-6 py-4">\n ${this.renderPlanDetails()}\n </div>\n </div>\n\n \x3c!-- Payment Method Review --\x3e\n <div class="bg-white rounded-lg border border-gray-200 mb-6">\n <div class="px-6 py-4 border-b border-gray-200">\n <div class="flex items-center justify-between">\n <h4 class="text-lg font-medium text-gray-900 flex items-center">\n ${s.H.getIcon("payment","creditCard","w-5 h-5 text-gray-400 mr-2")}\n Payment Method\n </h4>\n <button class="text-primary-600 hover:text-primary-700 text-sm font-medium" data-action="edit-payment">\n Edit\n </button>\n </div>\n </div>\n <div class="px-6 py-4">\n ${this.renderPaymentMethodDetails()}\n </div>\n </div>\n\n \x3c!-- Billing Summary --\x3e\n <div class="bg-gradient-to-br from-gray-50 to-gray-100 rounded-lg p-6 mb-6">\n <h4 class="text-lg font-medium text-gray-900 mb-4">Billing Summary</h4>\n ${this.renderBillingSummary()}\n </div>\n\n \x3c!-- Terms and Conditions --\x3e\n <div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">\n <label class="flex items-start cursor-pointer">\n <input\n type="checkbox"\n id="terms-checkbox"\n class="mt-1 h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300 rounded"\n ${this.state.termsAccepted?"checked":""}\n >\n <span class="ml-3 text-sm">\n <span class="text-blue-900 font-medium">I agree to the terms and conditions</span>\n <p class="text-blue-700 mt-1">\n By confirming your subscription, you authorize us to charge your payment method for the subscription fee.\n You can cancel your subscription at any time by contacting our <a href="mailto:${this.state.settings?.companySupportEmail||"[email protected]"}" class="text-blue-600 underline hover:text-blue-800">customer service team</a>.\n </p>\n <p class="text-blue-700 mt-2">\n ${this.renderTermsLinks()}\n </p>\n </span>\n </label>\n </div>\n\n \x3c!-- Security & Features --\x3e\n <div class="grid grid-cols-1 md:grid-cols-3 gap-4 text-center text-sm text-gray-500 mb-6">\n <div class="flex flex-col items-center">\n ${s.H.getIcon("general","shieldCheck","w-8 h-8 text-green-500 mb-2")}
1\n <span>Secure Payment</span>\n </div>\n <div class="flex flex-col items-center">\n ${s.H.getIcon("ui","refresh","w-8 h-8 text-green-500 mb-2")}\n <span>Cancel Anytime</span>\n </div>\n <div class="flex flex-col items-center">\n ${s.H.getIcon("general","lightning","w-8 h-8 text-green-500 mb-2")}\n <span>Instant Access</span>\n </div>\n </div>\n </div>\n `,this.attachEventListeners()}renderPlanDetails(){if(!this.options.selectedPlan)return'<p class="text-gray-500">No plan selected</p>';const e=this.options.selectedPlan,t=this.options.appliedCoupon;let n=e.price,o=!1,i=0;return t&&(o=!0,"percent"===t.discountType&&t.discountPercent?(i=e.price*t.discountPercent/100,n=e.price-i):"fixed"===t.discountType&&t.discountAmount&&(i=t.discountAmount,n=Math.max(0,e.price-t.discountAmount))),`\n <div class="flex items-center justify-between">\n <div class="flex items-center">\n ${this.isCabotWealth?"":`\n <div class="p-3 bg-primary-100 rounded-lg mr-4">\n ${s.H.getIcon("general","clipboard","w-6 h-6 text-primary-600")}\n </div>\n `}\n\n <div>\n <h5 class="font-semibold text-gray-900">${e.name} Plan</h5>\n <p class="text-sm text-gray-600">${e.description||""}</p>\n ${e.trialDays>0?`\n <div class="mt-2">\n <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">\n ${e.trialDays} days free trial\n </span>\n </div>\n `:""}\n ${o&&t?`\n <div class="mt-2">\n <div class="flex items-center gap-1 text-sm text-green-700">\n ${s.H.getIcon("general","tag","w-4 h-4")}\n <span class="font-medium">Coupon Applied: ${t.code}</span>\n </div>\n </div>\n `:""}\n </div>\n </div>\n <div class="text-right">\n ${o?`\n <div class="text-sm text-gray-500 line-through">$${e.price.toFixed(2)}</div>\n <div class="text-2xl font-bold bg-gradient-to-r from-green-600 to-green-700 bg-clip-text text-transparent">\n $${n.toFixed(2)}\n </div>\n <div class="text-xs text-green-600 font-medium">Save $${i.toFixed(2)}</div>\n `:`\n <div class="text-2xl font-bold text-gray-900">$${e.price}</div>\n `}\n ${r.U.formatPriceInterval(e.interval,e.intervalLength)?`<div class="text-sm text-gray-600">${r.U.formatPriceInterval(e.interval,e.intervalLength).replace("/","per")}</div>`:""}\n </div>\n </div>\n `}renderPaymentMethodDetails(){if(!this.options.selectedPaymentMethod)return'<p class="text-gray-500">No payment method selected</p>';const e=this.options.selectedPaymentMethod;return`\n <div class="flex items-center justify-between">\n <div class="flex items-center">\n ${this.isCabotWealth?"":`\n <div class="p-3 ${r.U.getCardBackgroundClass(e.brand)} rounded-lg mr-4">\n ${s.H.getIcon("payment","creditCardSolid","w-6 h-6 text-white")}\n </div>\n `}\n <div>\n <h5 class="font-semibold text-gray-900 capitalize">\n ${e.brand} â¢â¢â¢â¢ ${e.last4}\n </h5>\n <p class="text-sm text-gray-600">\n Expires ${e.expMonth}/${e.expYear}\n ${e.cardholderName?` ⢠${e.cardholderName}`:""}\n </p>\n ${e.isDefault?'\n <div class="mt-1">\n <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">\n Default payment method\n </span>\n </div>\n ':""}\n </div>\n </div>\n </div>\n `}renderBillingSummary(){if(!this.options.selectedPlan)return'<p class="text-gray-500">No plan selected</p>';
1const e=this.options.selectedPlan,t=this.options.appliedCoupon,n=new Date,i=new Date(n);e.trialDays>0?i.setDate(n.getDate()+e.trialDays):i.setMonth(n.getMonth()+1);let a=e.price,s=0;t&&("percent"===t.discountType&&t.discountPercent?s=a*t.discountPercent/100:"fixed"===t.discountType&&t.discountAmount&&(s=t.discountAmount));let r=a-s,d=0,l=0,c=r,u=s;const m="Sales Tax",g=a-s;let h=0,p=0,y=g;const C=o.default.isEnableTaxPreview(),f=C&&this.state.previewData&&!this.state.previewLoading;return f&&this.state.previewData&&(0===e.trialDays?(r=this.state.previewData.subtotal,d=this.state.previewData.tax,c=this.state.previewData.total,u=this.state.previewData.discount||0,l=parseFloat(this.state.previewData.taxRate)/100):(p=parseFloat(this.state.previewData.taxRate)/100,h=g*p,y=g+h)),`\n <div class="space-y-3">\n ${this.state.previewLoading?'\n <div class="flex items-center justify-center py-8">\n <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary-600"></div>\n <span class="ml-3 text-gray-600">Calculating taxes...</span>\n </div>\n ':`\n \x3c!-- Current Charge --\x3e\n <div class="flex justify-between items-center">\n <span class="text-gray-700">${e.name} Plan (${e.intervalLength&&e.intervalLength>1?`Every ${e.intervalLength} ${e.interval}s`:`${e.interval.charAt(0).toUpperCase()+e.interval.slice(1)}ly`})</span>\n <span class="font-semibold text-gray-900">\n ${e.trialDays>0?"Free Trial":`$${r.toFixed(2)}`}\n </span>\n </div>\n\n ${e.trialDays>0?`\n \x3c!-- Trial Info --\x3e\n <div class="flex justify-between items-center text-sm">\n <span class="text-gray-600">Trial ends on</span>\n <span class="text-gray-700">${i.toLocaleDateString()}</span>\n </div>\n `:""}\n\n ${u>0&&t?`\n \x3c!-- Coupon Discount --\x3e\n <div class="flex justify-between items-center">\n <span class="text-gray-700">Coupon Discount (${t.code})</span>\n <span class="font-semibold text-green-600">-$${u.toFixed(2)}</span>\n </div>\n `:""}\n\n ${!e.trialDays&&C?`\n \x3c!-- Tax --\x3e\n <div class="flex justify-between items-center">\n <span class="text-gray-700">${f?`${m} (${(100*l).toFixed(2)}%)`:"Tax (calculated at checkout)"}</span>\n <span class="font-semibold text-gray-900">${f?`$${d.toFixed(2)}`:"TBD"}</span>\n </div>\n `:""}\n `}\n\n \x3c!-- Divider --\x3e\n <div class="border-t border-gray-300 pt-3">\n <div class="flex justify-between items-center">\n <span class="text-lg font-medium text-gray-900">\n ${e.trialDays>0?"Total Today":"Total"}\n </span>\n <span class="text-2xl font-bold text-gray-900">\n ${e.trialDays>0?"$0.00":`$${c.toFixed(2)}`}\n </span>\n </div>\n </div>\n\n ${e.trialDays>0?`\n \x3c!-- Next Billing --\x3e\n <div class="bg-white rounded-lg p-3 border border-gray-200">\n <div class="flex justify-between items-center text-sm">\n <span class="text-gray-600">First charge on</span>\n <span class="font-medium text-gray-900">${i.toLocaleDateString()}</span>\n </div>\n <div class="flex justify-between items-center text-sm mt-1">\n <span class="text-gray-600">Subtotal</span>\n <span class="font-medium text-gray-900">$${g.toFixed(2)}</span>\n </div>\n ${C&&f&&p>0?`\n <div class="flex justify-between items-center text-sm mt-1">\n <span class="text-gray-600">${m} (${(100*p).toFixed(2)}%)</span>\n <span class="font-medium text-gray-900">$${h.toFixed(2)}</span>\n </div>`:""}\n <div class="flex justify-between items-center text-sm mt-1 pt-1 border-t border-gray-200">\n <span class="text-gray-600 font-medium">Total Amount</span>
1\n <span class="font-medium text-gray-900">$${y.toFixed(2)}</span>\n </div>\n </div>\n `:""}\n </div>\n `}renderTermsLinks(){const e=this.state.settings||{},t=e.terms||"#",n=e.privacyPolicy||"#",o=[];return t&&"#"!==t&&o.push(`<a href="${t}" target="_blank" rel="noopener noreferrer" class="underline hover:no-underline">View Terms of Service</a>`),n&&"#"!==n&&o.push(`<a href="${n}" target="_blank" rel="noopener noreferrer" class="underline hover:no-underline">Privacy Policy</a>`),0===o.length?"Please review our terms of service and privacy policy.":o.join(" ⢠")}attachEventListeners(){if(!this.container)return;this.container.addEventListener("click",(e=>{const t=e.target;t.closest('[data-action="edit-plan"]')?this.options.onEdit&&this.options.onEdit("plan"):t.closest('[data-action="edit-payment"]')&&this.options.onEdit&&this.options.onEdit("payment")}));const e=this.container.querySelector("#terms-checkbox");e&&e.addEventListener("change",(e=>{const t=e.target;this.state.termsAccepted=t.checked,this.options.onConfirm&&this.options.onConfirm(this.state.termsAccepted)}))}isValid(){return this.state.termsAccepted&&!!this.options.selectedPlan&&!!this.options.selectedPaymentMethod}getConfirmationData(){const e=o.default.isEnableTaxPreview();return{plan:this.options.selectedPlan,paymentMethod:this.options.selectedPaymentMethod,termsAccepted:this.state.termsAccepted,previewData:e?this.state.previewData:null}}setProcessing(e){this.state.isProcessing=e;const t=this.container?.querySelector("#terms-checkbox");t&&(t.disabled=e)}async loadPreviewData(){if(this.options.selectedPlan&&this.options.selectedBillingInfoId){this.state.previewLoading=!0,this.state.previewError=null;try{const e=this.options.selectedPlan.code||this.options.selectedPlan.name.toLowerCase().replace(/\s+/g,"_"),t=await d.G.previewSubscription(e,this.options.selectedBillingInfoId,this.options.couponCode||void 0);if(t.success&&t.data){const e=t.data.data||t.data;this.state.previewData=e,this.state.previewLoading=!1,await this.render()}else this.state.previewError="string"==typeof t.error?t.error:t.error?.message||"Failed to load tax preview",console.error("[ReviewStep] Preview subscription failed:",t.error),this.state.previewLoading=!1,await this.render()}catch(e){this.state.previewError="Failed to load tax preview",console.error("[ReviewStep] Error loading preview data:",e),this.state.previewLoading=!1,await this.render()}}}cleanup(){}}var T=n(6833),M=n(3649),E=n(1916);class P{constructor(e={}){this.modalElement=null,this.currentStepComponent=null,this.authenticationCache=null,this.authSuccessHandler=null,E.vF.info("[SubscriptionFlow] Constructor called","init"),this.isCabotWealth=!1,this.options={onSuccess:e.onSuccess||(()=>{}),onCancel:e.onCancel||(()=>{}),shortCode:e.shortCode||null,inline:e.inline||!1,container:e.container||null,preSelectedPlanId:e.preSelectedPlanId||null,couponCode:e.couponCode||null,giftCardCode:e.giftCardCode||null,campaignCode:e.campaignCode||null,displaySettings:e.displaySettings||{showFilters:!0,showSort:!0,showLegend:!0,showProgress:!0,showGiftCard:!0},accessWallData:e.accessWallData||{}},this.state={currentStep:1,totalSteps:3,selectedPlan:null,selectedPaymentMethod:null,availablePlans:[],userPlans:{},isProcessing:!1,couponCode:e.couponCode||null,giftCardCode:e.giftCardCode||null,campaignCode:e.campaignCode||null},this.steps={1:{component:g,title:"Choose Plan"},2:{component:x,title:"Payment Method"},3:{component:A,title:"Review & Confirm"}},this.setupAuthEventListeners()}async show(){try{await o.default.load(),this.isCabotWealth=o.default.isCabotWealth(),this.steps[3].title=this.isCabotWealth?"Review and Submit":"Review & Confirm";const e=o.default.isShowCouponField();E.vF.debug("[SubscriptionFlow] heimguardSettings.isShowCouponField()","init",{showCouponField:e,options:this.options});const t=new URLSearchParams(window.location.search).has("coupon_code");this.options.displaySettings||(this.options.displaySettings={}),void 0===this.options.displaySettings.showCoupon&&(this.options.displaySettings.showCoupon=e||t,console.log("[
1SubscriptionFlow] Set displaySettings.showCoupon:",{fromSettings:e,hasCouponCodeInUrl:t,final:this.options.displaySettings.showCoupon}))}catch(e){E.vF.error("[SubscriptionFlow] Failed to load settings","init",e)}if(this.options.inline)await this.showInline();else if(this.modalElement&&this.modalElement.parentNode)E.vF.warn("Subscription modal is already open","ui");else{if(!M.J.canOpenModal("subscription-flow"))return E.vF.info("[SubscriptionFlow] Cannot open modal - another modal is active or debouncing","ui"),void(this.options.onCancel&&this.options.onCancel());if(!M.J.registerModal(this,"subscription-flow"))return console.log("[SubscriptionFlow] Failed to register modal"),void(this.options.onCancel&&this.options.onCancel());this.createModal(),this.attachEventListeners(),document.body.classList.add("overflow-hidden"),requestAnimationFrame((()=>{if(!this.modalElement)return;const e=this.modalElement.querySelector(".relative"),t=this.modalElement.querySelector('[data-action="backdrop"]');t&&t.classList.add("opacity-100"),e&&(e.classList.remove("scale-95","opacity-0"),e.classList.add("scale-100","opacity-100"))})),this.renderCurrentStep(),await this.loadPlans()}}async showMissingRequirementsMessage(e){const t=document.getElementById("step-content");if(!t)return;let n="",o="",i="both";e.needsAddress&&e.needsPayment?(n="To continue with your subscription, you need to add a billing address and payment method.",o="Add Billing Address",i="both"):e.needsAddress?(n="To continue with your subscription, you need to add a billing address.",o="Add Billing Address",i="address"):e.needsPayment&&(n="To continue with your subscription, you need to add a payment method.",o="Add Payment Method",i="payment");const a=`\n <div class="requirements-alert mb-6 p-4 bg-amber-50 border border-amber-200 rounded-lg">\n <div class="flex">\n <div class="flex-shrink-0">\n ${s.H.render("alert-triangle",{class:"h-5 w-5 text-amber-400"})}\n </div>\n <div class="ml-3 flex-1">\n <p class="text-sm text-amber-800">${n}</p>\n <div class="mt-3">\n <button\n data-requirements-action="${i}"\n class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"\n >\n ${o}\n ${s.H.render("chevron-right",{class:"ml-2 h-4 w-4"})}\n </button>\n </div>\n </div>\n </div>\n </div>\n `,r=t.querySelector(".requirements-alert");r&&r.remove(),t.insertAdjacentHTML("afterbegin",a);const d=t.querySelector("[data-requirements-action]");d&&d.addEventListener("click",(async e=>{e.preventDefault();const t=d.getAttribute("data-requirements-action");e.preventDefault(),this.options.onCancel&&this.options.onCancel(),this.hide(),await new Promise((e=>setTimeout(e,300)));const n=window.HeimGuard,o=n?.AuthConfig?.getConfig?.(),i=o?.heimguardConfig?.profile?.url||"/profile",a="address"===t||"both"===t?"addresses":"payment";if(window.location.pathname.includes(i.replace("/",""))||window.location.hash.startsWith("#"))if(n?.switchProfileTab){await n.switchProfileTab(a)||(window.location.hash=a)}else window.location.hash=a;else window.location.href=`${i}#${a}`}));const l=this.modalElement?.querySelector(".overflow-y-auto");l&&(l.scrollTop=0)}async showAddBillingAddressModal(){return new Promise(((e,t)=>{new C.W({title:"Add Billing Address",submitText:"Save & Continue",showDefaults:!0,address:{firstName:"",lastName:"",street1:"",street2:"",city:"",region:"",postalCode:"",country:i.fl.getProfileUIConfig().defaultCountry||"US",phone:"",isShipping:!1,isBilling:!0,isDefaultBilling:!0},onSave:async n=>{try{await y.A.addAddress(n),e()}catch(e){E.vF.error("Failed to save address","profile",e),t(e)}},onCancel:()=>{t(new Error("User cancelled address addition"))}}).render()}))}async showAddPaymentMethodModal(){return new Promise((async(e,t)=>{try{if(!f.Ay.recurlyPublicKey){const e=(await o.default.load()).recurlyPublicKey;if(!e)return E.vF.warn("No Recurly public key found in settings","payment"),void t(new Error("Payment system not configured"));await f.Ay.initialize(e)}let n=null,i=null;const a=async t=>{E.vF.info("[SubscriptionFlow] Payment success event received","payment"),n&&(n(),n=null),i&&(i(),i=null),e()},s=()=>{E.vF.info("[SubscriptionFlow] Payment modal closed","ui"),n&&(n(),n=null),i&&(i(),i=null),t(new Error("User cancelled payment method addition"))};n=(0,v.yH)(v.aC.MODAL_SUCCESS,a),i=(0,v.yH)(v.aC.MODAL_CLOSED,s),await f.Ay.openAddModal({inline:!0})}catch(e){E.vF.error("Failed to show payment method modal","payment",e),t(e)}}))}async checkMissingRequirements(){if(this.options.inline)return{needsAddress:!1,needsPayment:!1};try{let e=!1,t=!1;try{const t=await y.A.getAddresses();let n=[],o=!1;t&&t.addresses?"object"!=typeof t.addresses||Array.isArray(t.addresses)?Array.isArray(t.addresses)&&(n=t.addresses):n=Object.values(t.addresses):Array.isArray(t)&&(n=t),o=n.some((e=>e.isBilling||e.isDefaultBilling)),e=0===n.length||!o}catch(t){E.vF.warn("[SubscriptionFlow] Error fetching addresses","profile",t),e=!0}try{const e=await h.paymentMethodsAPI.getPaymentMethods(),n=e?.data;let o=[];if("error"===n?.status&&n?.message?.includes("No payment methods found"))o=[];else if(n?.paymentMethods){const e=n.paymentMethods;
1Array.isArray(e)?o=e:"object"==typeof e&&Object.keys(e).length>0&&(o=Object.values(e))}t=0===o.length}catch(e){E.vF.warn("[SubscriptionFlow] Error fetching payment methods","payment",e),t=!0}return{needsAddress:e,needsPayment:t}}catch(e){return E.vF.error("[SubscriptionFlow] Unexpected error checking requirements","init",e),{needsAddress:!1,needsPayment:!1}}}async checkUserSetup(){if(this.options.inline)return!1;try{let e=[],t=!1;try{const n=await y.A.getAddresses();n&&n.addresses?"object"!=typeof n.addresses||Array.isArray(n.addresses)?Array.isArray(n.addresses)&&(e=n.addresses):e=Object.values(n.addresses):Array.isArray(n)&&(e=n),t=e.some((e=>e.isBilling||e.isDefaultBilling))}catch(n){E.vF.warn("[SubscriptionFlow] Error fetching addresses","profile",n),e=[],t=!1}if(0===e.length||!t)return await this.showAddressSetupPrompt(),!0;let n=[];try{const e=await h.paymentMethodsAPI.getPaymentMethods(),t=e?.data;if("error"===t?.status&&t?.message?.includes("No payment methods found"))n=[];else if(t?.paymentMethods){const e=t.paymentMethods;Array.isArray(e)?n=e:"object"==typeof e&&(n=0===Object.keys(e).length?[]:Object.values(e))}}catch(e){E.vF.warn("[SubscriptionFlow] Error fetching payment methods","payment",e),n=[]}return E.vF.debug("[SubscriptionFlow] Payment methods check","payment",{paymentMethodsCount:n.length,paymentMethods:n}),0===n.length&&(await this.showPaymentMethodSetupPrompt(),!0)}catch(e){return E.vF.error("[SubscriptionFlow] Unexpected error in checkUserSetup","init",e),!1}}async showAddressSetupPrompt(){return new Promise((e=>{const t=new T.Modal({id:"subscription-address-required",title:"Billing Address Required",content:`\n <div class="text-center py-4">\n <div class="mx-auto flex items-center justify-center h-16 w-16 rounded-full bg-yellow-100 mb-4">\n ${s.H.render("alert-triangle",{class:"h-8 w-8 text-yellow-600"})}\n </div>\n <h3 class="text-lg font-medium text-gray-900 mb-2">Billing Address Required</h3>\n <p class="text-gray-600 mb-6">You need to add a billing address before subscribing to a plan.</p>\n <div class="flex gap-3 justify-center">\n <button id="cancel-address-setup" class="px-4 py-2 text-gray-700 hover:text-gray-900 hover:bg-gray-100 rounded-lg transition-colors">\n Cancel\n </button>\n <button id="add-address-btn" class="px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors">\n Go to Addresses\n </button>\n </div>\n </div>\n `,closeButton:!0,closeOnOverlay:!0,closeOnEscape:!0,size:"small",onClose:()=>{e()}});t.open();const n=document.getElementById("cancel-address-setup"),o=document.getElementById("add-address-btn"),i=()=>{n?.removeEventListener("click",a),o?.removeEventListener("click",r)},a=()=>{i(),t.close()},r=async()=>{i(),t.close(),await new Promise((e=>setTimeout(e,300)));const e=window.HeimGuard,n=e?.AuthConfig?.getConfig?.(),o=n?.heimguardConfig?.profile?.url||"/profile";if(window.location.pathname.includes(o.replace("/",""))||window.location.hash.startsWith("#"))if(e?.switchProfileTab){await e.switchProfileTab("addresses")||(window.location.hash="addresses")}else window.location.hash="addresses";else window.location.href=o+"#addresses"};n&&n.addEventListener("click",a),o&&o.addEventListener("click",r)}))}async showPaymentMethodSetupPrompt(){return new Promise((e=>{let t=!1;const n=`subscription-payment-required-${Date.now()}`,o=new T.Modal({id:n,title:"Payment Method Required",content:`\n <div class="text-center py-4">\n <div class="mx-auto flex items-center justify-center h-16 w-16 rounded-full bg-yellow-100 mb-4">\n ${s.H.render("credit-card",{class:"h-8 w-8 text-yellow-600"})}\n </div>\n <h3 class="text-lg font-medium text-gray-900 mb-2">Payment Method Required</h3>\n <p class="text-gray-600 mb-6">You need to add at least one payment method to subscribe to a plan.</p>\n <div class="flex gap-3 justify-center">\n <button id="cancel-payment-setup" class="px-4 py-2 text-gray-700 hover:text-gray-900 hover:bg-gray-100 rounded-lg transition-colors">\n Cancel\n </button>\n <button id="add-payment-btn" class="px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors">\n Add Payment Method\n </button>\n </div>\n </div>\n `,closeButton:!0,closeOnOverlay:!0,closeOnEscape:!0,size:"small",onClose:()=>{t||(t=!0,e())}});o.open(),E.vF.info("[SubscriptionFlow] Payment method required modal opened","ui",{modalId:n}),requestAnimationFrame((()=>{requestAnimationFrame((()=>{const i=document.getElementById(n);if(!i)return E.vF.error("[SubscriptionFlow] Modal container not found!","ui"),void e();
1console.log("[SubscriptionFlow] Attaching event listeners to modal");const a=async n=>{const s=n.target.closest("button");if(s)if(console.log("[SubscriptionFlow] Button clicked:",s.id),"cancel-payment-setup"===s.id)console.log("[SubscriptionFlow] Cancel clicked"),i.removeEventListener("click",a),t=!0,o.close(),e();else if("add-payment-btn"===s.id){console.log("[SubscriptionFlow] Add payment clicked"),n.preventDefault(),n.stopPropagation(),i.removeEventListener("click",a),t=!0,o.close(),await new Promise((e=>setTimeout(e,300)));const s=window.HeimGuard,r=s?.AuthConfig?.getConfig?.(),d=r?.heimguardConfig?.profile?.url||"/profile";if(window.location.pathname.includes(d.replace("/",""))||window.location.hash.startsWith("#"))if(s?.switchProfileTab){await s.switchProfileTab("payment")||(window.location.hash="payment")}else window.location.hash="payment";else window.location.href=d+"#payment";e()}};i.addEventListener("click",a),console.log("[SubscriptionFlow] Event listener attached successfully")}))}))}))}async loadPlans(){try{this.currentStepComponent&&this.currentStepComponent.showLoading&&this.currentStepComponent.showLoading();const e=await d.G.getAvailablePlans(this.options.shortCode||void 0);if(!e?.success||!e?.data){throw new Error(e?.error?.message||"Unable to load subscription plans. Please try again later.")}this.state.availablePlans=e.data.plans||[],this.state.userPlans=e.data.userPlans||{},this.state.startExploringPageUrl=e.data.startExploringPageUrl||null;const t=new URLSearchParams(window.location.search).get("plan_id");if(t){console.log("[SubscriptionFlow] Filtering plans for plan_id:",t);const e=this.state.availablePlans.filter((e=>e.id===t));e.length>0?(this.state.availablePlans=e,this.state.selectedPlan=e[0],console.log("[SubscriptionFlow] Filtered to single plan and auto-selected:",e[0])):console.warn("[SubscriptionFlow] No plan found with id:",t)}const n=sessionStorage.getItem("pendingSubscriptionPlan");if(n)try{const e=JSON.parse(n),t=this.state.availablePlans.find((t=>t.code===e.code));if(t)return this.state.selectedPlan=t,sessionStorage.removeItem("pendingSubscriptionPlan"),this.state.currentStep=2,this.renderCurrentStep(),this.updateProgressBar(),this.updateButtons(),void p.Alert.flash({message:"Welcome back! Let's continue with your subscription.",variant:"success",duration:3e3})}catch(e){console.error("Failed to restore pending subscription plan:",e),sessionStorage.removeItem("pendingSubscriptionPlan")}1===this.state.currentStep&&this.currentStepComponent&&(this.currentStepComponent.hideLoading&&this.currentStepComponent.hideLoading(),this.currentStepComponent.updatePlans&&this.currentStepComponent.updatePlans(this.state.availablePlans,this.state.userPlans),this.state.selectedPlan&&this.currentStepComponent.updateSelectedPlan&&this.currentStepComponent.updateSelectedPlan(this.state.selectedPlan))}catch(e){console.error("[SubscriptionFlow] Error loading plans:",e);const t=e instanceof Error?e.message:"Unable to load subscription plans. Please try again later.";this.currentStepComponent&&this.currentStepComponent.showError?this.currentStepComponent.showError(t):this.showError(t)}}async showInline(){if(this.options.container)try{this.modalElement=this.options.container,this.createInlineStructure(),this.options.inline&&await this.updateButtonForAuthentication(),this.renderCurrentStep(),await this.loadPlans()}catch(e){console.error("[SubscriptionFlow] Error in showInline:",e),this.options.container&&(this.options.container.innerHTML='\n <div class="bg-red-50 border border-red-200 rounded-lg p-4 text-center">\n <p class="text-red-800">Unable to load subscription options. Please try again later.</p>\n </div>\n '),this.options.onCancel&&this.options.onCancel()}else console.error("[SubscriptionFlow] No container provided for inline mode")}createInlineStructure(){this.modalElement&&(this.modalElement.innerHTML=`\n <div class="bg-white rounded-2xl shadow-lg w-full max-w-4xl mx-auto">\n \x3c!-- Header with Progress --\x3e\n <div class="px-6 pt-6 pb-4 border-b border-gray-200">\n <div class="flex items-center justify-between mb-4">\n <div>\n <h2 class="text-2xl font-bold text-gray-900">${this.isCabotWealth?"Subscribe":this.options.accessWallData?.title||"Subscribe to Plan"}</h2>\n <p class="text-gray-600 mt-1">${this.options.accessWallData?.description||`Complete your subscription in ${this.state.totalSteps} easy steps ${this.isCabotWealth?"for immediate access":""}`}</p>\n </div>\n </div>\n\n \x3c!-- Progress Bar --\x3e\n ${!1!==this.options.displaySettings?.showProgress?`\n <div class="progress-bar-container flex items-center">\n ${this.renderProgressBar()}\n </div>\n `:""}\n </div>\n\n \x3c!-- Content --\x3e\n <div class="p-6">
1\n <div id="step-content" class="transition-opacity duration-200">\n \x3c!-- Step content will be rendered here --\x3e\n </div>\n </div>\n\n \x3c!-- Footer --\x3e\n <div class="px-6 py-4 bg-gray-50 border-t border-gray-200 rounded-b-2xl">\n <div class="flex justify-between items-center">\n <button\n id="back-button"\n type="button"\n class="flex items-center px-4 py-2 text-gray-700 hover:text-gray-900 transition-colors ${1===this.state.currentStep?"invisible":""}"\n data-action="back"\n >\n ${s.H.render("chevron-left",{class:"w-4 h-4 mr-2"})}\n Back\n </button>\n\n <div class="flex items-center space-x-3">\n <button\n id="continue-button"\n type="button"\n class="relative px-6 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 flex items-center"\n data-action="continue"\n disabled\n >\n <span class="continue-text">${this.getContinueButtonText()}</span>\n ${s.H.render("chevron-right",{class:"w-4 h-4 ml-2 continue-arrow"})}\n <div class="continue-spinner hidden absolute inset-0 flex items-center justify-center">\n ${s.H.render("loader",{class:"animate-spin h-5 w-5 text-white"})}\n </div>\n </button>\n </div>\n </div>\n </div>\n </div>\n `,this.attachInlineEventListeners())}attachInlineEventListeners(){this.modalElement&&this.modalElement.addEventListener("click",(async e=>{const t=e.target.closest("[data-action]"),n=t?.getAttribute("data-action");if("back"===n)e.preventDefault(),e.stopPropagation(),this.goBack();else if("continue"===n){if(t?.hasAttribute("data-login-trigger"))return void(this.state.selectedPlan&&sessionStorage.setItem("pendingSubscriptionPlan",JSON.stringify(this.state.selectedPlan)));e.preventDefault(),e.stopPropagation(),await this.handleContinue()}}))}hide(){this.options.inline||M.J.unregisterModal(this),this.currentStepComponent&&this.currentStepComponent.cleanup&&this.currentStepComponent.cleanup(),this.options.inline?this.modalElement&&(this.modalElement.innerHTML=""):(this.modalElement&&this.modalElement.parentNode&&this.modalElement.remove(),document.body.classList.remove("overflow-hidden")),this.authSuccessHandler&&(document.removeEventListener("auth:login:success",this.authSuccessHandler),document.removeEventListener("auth:register:success",this.authSuccessHandler),this.authSuccessHandler=null),this.modalElement=null}createModal(){this.modalElement=document.createElement("div"),this.modalElement.className="fixed inset-0 z-50 flex items-center justify-center p-4",this.modalElement.innerHTML=`\n \x3c!-- Backdrop --\x3e\n <div class="absolute inset-0 bg-black/50 backdrop-blur-sm transition-opacity duration-300" data-action="backdrop"></div>\n\n \x3c!-- Modal --\x3e\n <div class="relative bg-white rounded-2xl shadow-2xl w-full max-w-4xl max-h-[90vh] flex flex-col transform transition-all duration-300 scale-95 opacity-0">\n \x3c!-- Header with Progress --\x3e\n <div class="px-6 pt-6 pb-4 border-b border-gray-200">\n <div class="flex items-center justify-between mb-4">\n <div>\n <h2 class="text-2xl font-bold text-gray-900">${o.default.isCabotWealth()?"Subscribe":this.options.accessWallData?.title||"Subscribe to Plan"}</h2>\n <p class="text-gray-600 mt-1">${this.options.accessWallData?.description||`Complete your subscription in ${this.state.totalSteps} easy steps${o.default.isCabotWealth()?" for immediate access.":""}`}</p>\n </div>\n <button class="p-2 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg transition-colors" data-action="close">\n ${s.H.render("x",{class:"w-5 h-5"})}\n </button>\n </div>\n\n \x3c!-- Progress Bar --\x3e\n ${!1!==this.options.displaySettings?.showProgress?`\n <div class="progress-bar-container flex items-center">\n ${this.renderProgressBar()}\n </div>\n `:""}\n </div>\n\n \x3c!-- Content --\x3e\n <div class="flex-1 overflow-y-auto overflow-x-hidden p-6">
1\n <div id="step-content" class="transition-opacity duration-200">\n \x3c!-- Step content will be rendered here --\x3e\n </div>\n </div>\n\n \x3c!-- Footer --\x3e\n <div class="px-6 py-4 bg-gray-50 border-t border-gray-200 rounded-b-2xl">\n <div class="flex justify-between items-center">\n <button\n id="back-button"\n type="button"\n class="flex items-center px-4 py-2 text-gray-700 hover:text-gray-900 transition-colors ${1===this.state.currentStep?"invisible":""}"\n data-action="back"\n >\n ${s.H.render("chevron-left",{class:"w-4 h-4 mr-2"})}\n Back\n </button>\n\n <div class="flex items-center space-x-3">\n <button class="px-4 py-2 text-gray-700 hover:text-gray-900 hover:bg-gray-100 rounded-lg transition-colors" data-action="cancel">\n Cancel\n </button>\n <button\n id="continue-button"\n type="button"\n class="relative px-6 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 flex items-center"\n data-action="continue"\n disabled\n >\n <span class="continue-text">${this.getContinueButtonText()}</span>\n ${s.H.render("chevron-right",{class:"w-4 h-4 ml-2 continue-arrow"})}\n <div class="continue-spinner hidden absolute inset-0 flex items-center justify-center">\n ${s.H.render("loader",{class:"animate-spin h-5 w-5 text-white"})}\n </div>\n </button>\n </div>\n </div>\n </div>\n </div>\n `,document.body.appendChild(this.modalElement)}renderProgressBar(){const e=[{number:1,title:"Choose Plan"},{number:2,title:"Payment Method"},{number:3,title:this.isCabotWealth?"Review and Submit":"Review & Confirm"}];return e.map(((t,n)=>{const o=t.number===this.state.currentStep,i=t.number<this.state.currentStep,a=n===e.length-1;return`\n <div class="flex items-center ${a?"":"flex-1"}">\n \x3c!-- Step Circle and Label --\x3e\n <div class="flex items-center flex-shrink-0">\n <div class="flex items-center justify-center w-10 h-10 rounded-full border-2 transition-all duration-300 ${o?"bg-primary-600 border-primary-600 text-white shadow-lg shadow-primary-600/30":i?"bg-green-500 border-green-500 text-white":"bg-white border-gray-300 text-gray-600"}">\n ${i?`\n ${s.H.render("check",{class:"w-5 h-5"})}\n `:`\n <span class="text-sm font-bold">${t.number}</span>\n `}\n </div>\n <div class="ml-3">\n <span class="text-sm font-medium whitespace-nowrap ${o?"text-gray-900":i?"text-green-600":"text-gray-500"}">\n ${t.title}\n </span>\n </div>\n </div>\n\n \x3c!-- Connector Line --\x3e\n ${a?"":`\n <div class="flex-1 mx-4">\n <div class="h-1 bg-gray-200 rounded-full relative">\n <div class="absolute inset-0 h-full bg-green-500 rounded-full transition-all duration-500 ease-out"\n style="width: ${i?"100%":"0%"}"></div>\n </div>\n </div>\n `}\n </div>\n `})).join("")}renderCurrentStep(){if(!this.modalElement)return;const e=this.modalElement.querySelector("#step-content");if(!e)return;this.currentStepComponent&&this.currentStepComponent.cleanup&&this.currentStepComponent.cleanup(),e.innerHTML="";const t=this.steps[this.state.currentStep].component;switch(this.state.currentStep){case 1:console.log("[SubscriptionFlow] Creating PlanSelectionStep with displaySettings:",this.options.displaySettings),this.currentStepComponent=new t(e,{plans:this.state.availablePlans,userPlans:this.state.userPlans,selectedPlan:this.state.selectedPlan,onPlanSelected:e=>this.handlePlanSelected(e),onCouponApplied:(e,t)=>this.handleCouponApplied(e,t),onCouponRemoved:()=>this.handleCouponRemoved(),onGiftCardCodeChanged:e=>this.handleGiftCardCodeChanged(e),onCampaignCodeDetected:e=>this.handleCampaignCodeDetected(e),displaySettings:this.options.displaySettings,defaultBillingFilter:this.options.inline?"all":void 0});break;case 2:this.currentStepComponent=new t(e,{selectedPlan:this.state.selectedPlan,selectedPaymentMethod:this.state.selectedPaymentMethod,appliedCoupon:this.state.appliedCoupon,onPaymentMethodSelected:e=>this.handlePaymentMethodSelected(e),onAddPaymentMethod:e=>this.handlePaymentMethodAdded(e)}),e.addEventListener("paymentmodal:validation:changed",(e=>
1{console.log("[SubscriptionFlow] PaymentModal validation changed:",e.detail),this.updateButtons()}));break;case 3:this.currentStepComponent=new t(e,{selectedPlan:this.state.selectedPlan,selectedPaymentMethod:this.state.selectedPaymentMethod,selectedBillingInfoId:this.state.selectedPaymentMethod?.billingInfoId||this.state.selectedPaymentMethod?.id,couponCode:this.state.couponCode,appliedCoupon:this.state.appliedCoupon,onConfirm:e=>this.handleConfirmationChange(e),onEdit:e=>this.handleEdit(e)})}if(this.currentStepComponent.render){const e=this.currentStepComponent.render();e&&"function"==typeof e.then?e.then((()=>{this.updateButtons()})).catch((e=>{this.updateButtons()})):this.updateButtons()}else this.updateButtons()}handlePlanSelected(e){this.state.selectedPlan=e,this.updateButtons()}handleCouponApplied(e,t){this.state.couponCode=e,this.state.appliedCoupon=t}handleCouponRemoved(){this.state.couponCode=null,this.state.appliedCoupon=null}handleGiftCardCodeChanged(e){this.state.giftCardCode=e}handleCampaignCodeDetected(e){this.state.campaignCode=e,console.log("[SubscriptionFlow] Campaign code detected:",e)}handlePaymentMethodSelected(e){this.state.selectedPaymentMethod=e,this.updateButtons()}handlePaymentMethodAdded(e){this.state.selectedPaymentMethod=e,this.updateButtons()}handleConfirmationChange(e){this.updateContinueButton(e)}handleEdit(e){"plan"===e?this.state.currentStep=1:"payment"===e&&(this.state.currentStep=2),this.renderCurrentStep(),this.updateProgressBar()}attachEventListeners(){this.modalElement&&this.modalElement.addEventListener("click",(async e=>{const t=e.target,n=t.closest("[data-action]"),o=t.dataset.action||n?.getAttribute("data-action");switch(!o||"continue"===o&&n?.hasAttribute("data-login-trigger")||(e.preventDefault(),e.stopPropagation()),o){case"close":case"cancel":case"backdrop":this.handleCancel();break;case"back":this.goBack();break;case"continue":n?.hasAttribute("data-login-trigger")?this.state.selectedPlan&&sessionStorage.setItem("pendingSubscriptionPlan",JSON.stringify(this.state.selectedPlan)):await this.handleContinue()}}))}async handleContinue(){if(2===this.state.currentStep&&this.currentStepComponent){const e=this.currentStepComponent.getActivePaymentModal?.();if(e)return await e.navigateContinue(),void this.updateButtons()}if(this.canContinue()){if(1===this.state.currentStep&&this.options.inline){const e=this.modalElement?.querySelector("#continue-button");if(e?.hasAttribute("data-login-trigger")&&this.state.selectedPlan)return sessionStorage.setItem("pendingSubscriptionPlan",JSON.stringify(this.state.selectedPlan)),void p.Alert.flash({message:"Please login or create an account to continue with your subscription",variant:"info",duration:5e3})}if(this.state.currentStep<this.state.totalSteps){if(1===this.state.currentStep){const e=this.modalElement?.querySelector("#continue-button");e?.hasAttribute("data-login-trigger")&&(console.log("[SubscriptionFlow] Button has login trigger, clearing auth cache for fresh check"),this.authenticationCache=null);const t=await this.checkAuthentication();if(console.log("[SubscriptionFlow] handleContinue auth check:",t),!t){if(p.Alert.flash({message:"Please login or create an account to continue with your subscription",variant:"info",duration:5e3}),e){e.setAttribute("data-login-trigger","true");const t=e.querySelector(".continue-text");t&&(t.textContent="Login to Continue")}return}}this.state.currentStep++,this.renderCurrentStep(),this.updateProgressBar(),this.updateButtons()}else await this.processSubscription()}}async processSubscription(){if(!this.state.selectedPlan||!this.state.selectedPaymentMethod||!this.modalElement)return;const e=this.modalElement.querySelector("#continue-button"),t=e?.querySelector(".continue-text"),n=e?.querySelector(".continue-arrow"),o=e?.querySelector(".continue-spinner");try{this.state.isProcessing=!0,e&&(e.disabled=!0),t&&t.classList.add("hidden"),n&&n.classList.add("hidden"),o&&o.classList.remove("hidden"),this.currentStepComponent&&this.currentStepComponent.setProcessing&&this.currentStepComponent.setProcessing(!0);const i=this.state.selectedPaymentMethod.billingInfoId||this.state.selectedPaymentMethod.id,a=this.state.selectedPlan.code;if(!a)throw new Error("Plan code is missing. Please select a valid plan.");if(!i)throw new Error("Payment method billing info is missing. Please select a valid payment method.");console.log("Creating subscription with:",{planCode:a,billingInfoId:i,selectedPlan:this.state.selectedPlan,paymentMethod:this.state.selectedPaymentMethod});const s=await d.G.createSubscription({planCode:a,billingInfoId:i,couponCode:this.state.couponCode||void 0,giftCardRedemptionCode:this.state.giftCardCode||void 0,campaignCode:this.state.campaignCode||void 0});let r=null;if(this.currentStepComponent&&"getConfirmationData"in this.currentStepComponent){r=this.currentStepComponent.getConfirmationData().previewData}const l={...this.state.selectedPlan,...r?{tax:r.tax,taxRate:parseFloat(r.taxRate)/100,totalWithTax:r.total,subtotal:r.subtotal}:{tax:void 0,taxRate:void 0,taxType:void 0,totalWithTax:this.state.selectedPlan.price}};await this.showSuccessState({subscription:s,plan:l,paymentMethod:this.state.selectedPaymentMethod,appliedCoupon:this.state.appliedCoupon})}catch(i){this.state.isProcessing=!1,e&&(e.disabled=!1),t&&(t.classList.remove("hidden"),t.textContent=this.getContinueButtonText()),n&&n.classList.remove("hidden"),o&&o.classList.add("hidden"),this.currentStepComponent&&this.currentStepComponent.setProcessing&&this.currentStepComponent.setProcessing(!1),this.showDetailedError(i)}}async checkAuthentication(){if(this.authenticationCache?.checked)return this.authenticationCache.isAuthenticated;if(!l.A.isInitialized())try{await l.A.init()}catch(e){E.vF.error("[SubscriptionFlow] Failed to initialize AuthStateManager","subscription",e)}if(!l.A.isAuthenticated())return this.authenticationCache={checked:!0,isAuthenticated:!1},!1;try{const e=(await fetch("/api/heimguard/profile/get-profile",{credentials:"include",headers:{"X-Requested-With":"XMLHttpRequest"}})).ok;return this.authenticationCache={checked:!0,isAuthenticated:e},e}catch(e){return E.vF.error("[SubscriptionFlow] Authentication check failed","
1subscription",e),this.authenticationCache={checked:!0,isAuthenticated:!1},!1}}async updateButtonForAuthentication(){if(1===this.state.currentStep&&this.options.inline&&this.modalElement){const e=await this.checkAuthentication(),t=this.modalElement.querySelector("#continue-button");if(!t)return;if(console.log("[SubscriptionFlow] updateButtonForAuthentication - isAuthenticated:",e),e){t.removeAttribute("data-login-trigger");const e=t.querySelector(".continue-text");e&&(e.textContent=this.getContinueButtonText())}else{t.setAttribute("data-login-trigger","true");const e=t.querySelector(".continue-text");e&&(e.textContent="Login to Continue")}}}setupAuthEventListeners(){this.cleanupAuthEventListeners(),this.authSuccessHandler=this.handleAuthSuccess.bind(this),document.addEventListener("auth:login:success",this.authSuccessHandler),document.addEventListener("auth:register:success",this.authSuccessHandler),document.addEventListener("auth:state:changed",(async e=>{const t=e;t.detail?.newState?.isAuthenticated&&this.options.inline&&(console.log("[SubscriptionFlow] Auth state changed to authenticated"),this.authenticationCache=null,1===this.state.currentStep&&this.modalElement&&await this.updateButtonForAuthentication())}))}cleanupAuthEventListeners(){this.authSuccessHandler&&(document.removeEventListener("auth:login:success",this.authSuccessHandler),document.removeEventListener("auth:register:success",this.authSuccessHandler),this.authSuccessHandler=null)}async handleAuthSuccess(e){console.log("[SubscriptionFlow] Auth success event received:",e?.type),this.authenticationCache=null;const t=e,n=e?.type;if("auth:register:success"===n){const e=t?.detail?.requiresVerification;return console.log("[SubscriptionFlow] Registration event - requires verification:",e),e?void console.log("[SubscriptionFlow] Registration requires email verification - not reloading plans"):(console.log("[SubscriptionFlow] Registration with auto-login - updating after short delay"),void setTimeout((async()=>{this.authenticationCache=null;const e=await this.checkAuthentication();if(console.log("[SubscriptionFlow] Post-registration auth check:",e),e){if(console.log("[SubscriptionFlow] User authenticated after registration, updating UI"),this.options.inline&&1===this.state.currentStep&&this.modalElement){this.authenticationCache=null,await this.updateButtonForAuthentication();const e=this.modalElement.querySelector("#continue-button");e&&this.state.selectedPlan&&(e.disabled=!1)}}else console.log("[SubscriptionFlow] User still not authenticated after registration, clearing cache"),this.authenticationCache=null}),1e3))}if(console.log("[SubscriptionFlow] User authenticated, updating UI without reload"),this.authenticationCache=null,this.options.inline&&1===this.state.currentStep&&this.modalElement){console.log("[SubscriptionFlow] Updating button after authentication");const e=this.modalElement.querySelector("#continue-button");if(console.log("[SubscriptionFlow] Continue button found:",!!e),e){console.log("[SubscriptionFlow] Removing data-login-trigger attribute"),e.removeAttribute("data-login-trigger");const t=e.querySelector(".continue-text");t&&(t.textContent=this.getContinueButtonText()),this.state.selectedPlan&&(e.disabled=!1),this.updateButtons()}}}goBack(){if(2===this.state.currentStep&&this.currentStepComponent){const e=this.currentStepComponent.getActivePaymentModal?.();if(e&&!e.isOnFirstStep())return e.navigateBack(),void this.updateButtons()}this.state.currentStep>1&&!this.state.isProcessing&&(this.state.currentStep--,this.renderCurrentStep(),this.updateProgressBar(),this.updateButtons())}handleCancel(){this.options.onCancel&&this.options.onCancel(),this.hide()}canContinue(){if(2===this.state.currentStep&&this.currentStepComponent){const e=this.currentStepComponent.getActivePaymentModal?.();if(e)return e.canProceed()&&!e.isProcessing()}switch(this.state.currentStep){case 1:return!!this.state.selectedPlan;case 2:return!!this.state.selectedPaymentMethod;case 3:return this.currentStepComponent&&this.currentStepComponent.isValid&&this.currentStepComponent.isValid();default:return!1}}getContinueButtonText(){if(2===this.state.currentStep&&this.currentStepComponent){const e=this.currentStepComponent.getActivePaymentModal?.();if(e)return e.getContinueText()}switch(this.state.currentStep){case 1:default:return"Continue";case 2:return this.isCabotWealth?"Review":"Review Subscription";case 3:return this.isCabotWealth?"Start Subscription":"Complete Subscription"}}updateButtons(){if(!this.modalElement)return;const e=this.modalElement.querySelector("#back-button"),t=this.modalElement.querySelector("#continue-button"),n=t?.querySelector(".continue-text");if(e&&e.classList.toggle("invisible",1===this.state.currentStep||this.state.isProcessing),t&&(t.disabled=!this.canContinue()||this.state.isProcessing,n&&(n.textContent=this.getContinueButtonText())),this.options.inline&&1===this.state.currentStep&&t){const e=t.hasAttribute("data-login-trigger");(!this.authenticationCache?.checked||this.authenticationCache?.isAuthenticated&&e)&&this.updateButtonForAuthentication()}}updateContinueButton(e){if(!this.modalElement)return;const t=this.modalElement.querySelector("#continue-button");t&&!this.state.isProcessing&&(t.disabled=!e)}updateProgressBar(){if(!this.modalElement)return;const e=this.modalElement.querySelector(".progress-bar-container");e&&(e.innerHTML=this.renderProgressBar())}showError(e){if(!this.modalElement)return;const t=this.modalElement.querySelector("#step-content");
1if(!t)return;const n=p.Alert.render({message:e,variant:"error",dismissible:!0,autoHide:5e3,className:"mb-4"});t.insertAdjacentHTML("afterbegin",n),p.Alert.attachHandlers(t)}showDetailedError(e){if(!this.modalElement)return;const t=e.message||e.toString();let n="",i="",a=!1;if(t.includes("Recurly")||t.includes("500"))n="Payment Processing Temporarily Unavailable",i="Our payment system is experiencing issues. This is usually temporary.",a=!0;else if(t.includes("card")||t.includes("payment"))n="Payment Method Issue",i="There was a problem processing your payment method. Please verify your card details.";else if(t.includes("network")||t.includes("fetch"))n="Connection Problem",i="Please check your internet connection and try again.";else if(t.includes("subscription already exists"))n="Subscription Already Active",i="You already have an active subscription. Check your subscription tab.";else if(t.includes("Failed to create subscription")){if(n="Unable to Complete Subscription",o.default.isCabotWealth()&&this.state.selectedPlan){i=`Unable to create subscription for <strong>${this.state.selectedPlan.titleOverride||this.state.selectedPlan.name||this.state.selectedPlan.code}</strong>. Please try again or contact support.`}else i=t;a=!0}else n="Unable to Complete Subscription",i=t,a=!0;const r=this.modalElement.querySelector("#step-content");if(!r)return;r.innerHTML=`\n <div class="text-center py-8">\n \x3c!-- Error Icon --\x3e\n <div class="mx-auto flex items-center justify-center h-20 w-20 rounded-full bg-red-100 mb-6">\n ${s.H.render("alert-circle",{class:"h-10 w-10 text-red-600"})}\n </div>\n\n \x3c!-- Error Message --\x3e\n <h3 class="text-xl font-semibold text-gray-900 mb-2">${n}</h3>\n <p class="text-gray-600 mb-8 max-w-md mx-auto">${i}</p>\n\n \x3c!-- Helpful Actions --\x3e\n <div class="bg-gray-50 rounded-lg p-6 mb-6 max-w-md mx-auto">\n <h4 class="font-medium text-gray-900 mb-3">What you can try:</h4>\n <ul class="space-y-2 text-left text-sm text-gray-600">\n <li class="flex items-start">\n ${s.H.render("check-circle",{class:"w-5 h-5 text-gray-400 mr-2 mt-0.5 flex-shrink-0"})}\n <span>Wait a few moments and try again</span>\n </li>\n <li class="flex items-start">\n ${s.H.render("check-circle",{class:"w-5 h-5 text-gray-400 mr-2 mt-0.5 flex-shrink-0"})}\n <span>Verify your payment information is correct</span>\n </li>\n <li class="flex items-start">\n ${s.H.render("check-circle",{class:"w-5 h-5 text-gray-400 mr-2 mt-0.5 flex-shrink-0"})}\n <span>Try a different payment method</span>\n </li>\n ${a?`\n <li class="flex items-start">\n ${s.H.render("check-circle",{class:"w-5 h-5 text-gray-400 mr-2 mt-0.5 flex-shrink-0"})}\n <span>Contact support if the issue persists</span>\n </li>\n `:""}\n </ul>\n </div>\n\n \x3c!-- Action Buttons --\x3e\n <div class="flex flex-col sm:flex-row gap-3 justify-center">\n <button\n class="px-6 py-2 bg-primary-600 text-white font-medium rounded-lg hover:bg-primary-700 transition-colors"\n onclick="window.location.reload()"\n >\n Refresh & Try Again\n </button>\n <button\n class="px-6 py-2 text-gray-700 font-medium hover:text-gray-900 transition-colors"\n data-action="back"\n >\n Go Back\n </button>\n </div>\n\n \x3c!-- Error Details (collapsible) --\x3e\n <details class="mt-6 max-w-md mx-auto text-left">\n <summary class="cursor-pointer text-sm text-gray-500 hover:text-gray-700">\n Technical details\n </summary>\n <pre class="mt-2 text-xs bg-gray-100 p-3 rounded overflow-x-auto">${this.escapeHtml(t)}</pre>\n </details>\n </div>\n `;const d=this.modalElement.querySelector("#continue-button"),l=this.modalElement.querySelector("#back-button");d&&(d.style.display="none"),l&&(l.classList.remove("invisible"),l.disabled=!1)}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}async showSuccessState(e){if(!this.modalElement)return;const t=this.state.startExploringPageUrl&&"/"!==this.state.startExploringPageUrl?this.state.startExploringPageUrl:o.default.getLibraryPageUrl();if(this.options.inline){this.modalElement&&(this.modalElement.remove(),this.modalElement=null);return new T.Modal({id:"subscription-success-modal",title:"",content:`\n <div class="text-center py-6 px-4">\n \x3c!-- Success Animation - Fixed centering --\x3e\n <div class="mb-8 flex justify-center">\n <div class="relative inline-block">\n <div class="success-circle-bg absolute inset-0 rounded-full bg-green-100 animate-ping"></div>\n <div class="success-circle relative w-32 h-32 rounded-full bg-gradient-to-r from-green-400 to-emerald-500 flex items-center justify-center shadow-lg">\n <svg class="success-checkmark w-16 h-16 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"></path>\n </svg>\n </div>\n </div>\n </div>\n\n \x3c!-- Success Message --\x3e\n <h2 class="text-3xl font-bold text-gray-900 mb-4">\n ð Welcome to ${e.plan.name}!\n </h2>\n\n <p class="text-lg text-gray-600 mb-8 max-w-md mx-auto">\n Your subscription has been activated successfully. You now have full access to all premium features.\n </p>\n\n \x3c!-- Subscription Details --\x3e\n <div class="bg-gradient-to-r from-gray-50 to-gray-100 rounded-xl p-6 mb-8 max-w-md mx-auto">\n <div class="space-y-3">\n <div class="flex justify-between items-center">
1\n <span class="text-gray-600">Plan</span>\n <span class="font-semibold text-gray-900">${e.plan.name}</span>\n </div>\n <div class="flex justify-between items-center">\n <span class="text-gray-600">Subtotal</span>\n <span class="font-semibold text-gray-900">$${e.plan.price}${r.U.formatPriceInterval(e.plan.interval,e.plan.intervalLength)}</span>\n </div>\n ${e.appliedCoupon?`<div class="flex justify-between items-center">\n <span class="text-gray-600">Coupon Discount (${e.appliedCoupon.code})</span>\n <span class="font-semibold text-green-600">-$${"percent"===e.appliedCoupon.discountType?(e.plan.price*e.appliedCoupon.discountPercent/100).toFixed(2):(e.appliedCoupon.discountAmount||0).toFixed(2)}</span>\n </div>`:""}\n ${void 0!==e.plan.tax&&null!==e.plan.tax?`<div class="flex justify-between items-center">\n <span class="text-gray-600">${e.plan.taxType||"Sales Tax"} (${(100*(e.plan.taxRate||0)).toFixed(2)}%)</span>\n <span class="font-semibold text-gray-900">$${e.plan.tax.toFixed(2)}</span>\n </div>`:""}\n <div class="flex justify-between items-center pt-2 border-t border-gray-200">\n <span class="text-gray-700 font-medium">Total</span>\n <span class="font-bold text-gray-900">$${(()=>{const t=e.appliedCoupon?"percent"===e.appliedCoupon.discountType?e.plan.price*e.appliedCoupon.discountPercent/100:e.appliedCoupon.discountAmount||0:0;return((e.plan.totalWithTax||e.plan.price)-t).toFixed(2)})()}${r.U.formatPriceInterval(e.plan.interval,e.plan.intervalLength)}</span>\n </div>\n ${e.plan.trialDays>0?`\n <div class="flex justify-between items-center">\n <span class="text-gray-600">Trial Period</span>\n <span class="font-semibold text-green-600">${e.plan.trialDays} days free</span>\n </div>\n `:""}\n <div class="flex justify-between items-center">\n <span class="text-gray-600">Payment Method</span>\n <span class="font-semibold text-gray-900 capitalize">\n ${e.paymentMethod.brand} â¢â¢â¢â¢ ${e.paymentMethod.last4}\n </span>\n </div>\n </div>\n </div>\n\n \x3c!-- Action Button --\x3e\n <a\n href="${t}"\n class="inline-block w-full max-w-md px-6 py-3 bg-primary-600 text-white font-medium rounded-lg hover:bg-primary-700 transition-colors text-center"\n >\n Start Exploring\n </a>\n\n \x3c!-- Confetti Container --\x3e\n <div class="confetti-container fixed inset-0 pointer-events-none overflow-hidden" style="z-index: 9999;">\n ${this.generateConfetti()}\n </div>\n </div>\n\n <style>\n @keyframes checkmark-stroke {\n to {\n stroke-dashoffset: 0;\n }\n }\n\n .success-checkmark path {\n stroke-dasharray: 60;\n stroke-dashoffset: 60;\n animation: checkmark-stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) 0.3s forwards;\n }\n\n .success-circle {\n animation: scale-in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);\n }\n\n @keyframes scale-in {\n from {\n transform: scale(0);\n opacity: 0;\n }\n to {\n transform: scale(1);\n opacity: 1;\n }\n }\n\n @keyframes confetti-fall {\n 0% {\n transform: translateY(-100vh) rotate(0deg);\n opacity: 1;\n }\n 100% {\n transform: translateY(100vh) rotate(720deg);\n opacity: 0;\n }\n }\n\n .confetti {\n position: fixed;\n animation: confetti-fall 3s linear;\n animation-delay: calc(var(--delay) * 1s);\n left: calc(var(--left) * 1%);\n }\n </style>\n `,size:"medium",closeButton:!0,closeOnOverlay:!1,closeOnEscape:!1}).open(),void setTimeout((()=>{document.querySelectorAll(".confetti").forEach(((e,t)=>{const n=e;n.style.setProperty("--delay",(2*Math.random()).toString()),n.style.setProperty("--left",(100*Math.random()).toString())}))}),100)}const n=this.modalElement.querySelector(".relative");n&&(n.innerHTML=`\n <div class="text-center py-6 px-4">\n \x3c!-- Success Icon - Fixed centering --\x3e\n <div class="mb-8 flex justify-center">\n <div class="relative inline-block">\n <div class="success-circle-bg absolute inset-0 rounded-full bg-green-100 animate-ping"></div>\n <div class="success-circle relative w-32 h-32 rounded-full bg-gradient-to-r from-green-400 to-emerald-500 flex items-center justify-center shadow-lg">\n ${s.H.render("check",{class:"success-checkmark w-16 h-16 text-white"})}\n </div>\n </div>\n </div>\n\n \x3c!-- Success Message --\x3e\n <h2 class="text-3xl font-bold text-gray-900 mb-4">\n ð Welcome to ${e.plan.name}!\n </h2>\n\n <p class="text-lg text-gray-600 mb-8 max-w-md mx-auto">\n Your subscription has been activated successfully. You now have full access to all premium features.\n </p>\n\n \x3c!-- Subscription Details --\x3e\n <div class="bg-gradient-to-r from-gray-50 to-gray-100 rounded-xl p-6 mb-8 max-w-md mx-auto">\n <div class="space-y-3">\n <div class="flex justify-between items-center">
1\n <span class="text-gray-600">Plan</span>\n <span class="font-semibold text-gray-900">${e.plan.name}</span>\n </div>\n <div class="flex justify-between items-center">\n <span class="text-gray-600">Subtotal</span>\n <span class="font-semibold text-gray-900">$${e.plan.price}${r.U.formatPriceInterval(e.plan.interval,e.plan.intervalLength)}</span>\n </div>\n ${e.appliedCoupon?`<div class="flex justify-between items-center">\n <span class="text-gray-600">Coupon Discount (${e.appliedCoupon.code})</span>\n <span class="font-semibold text-green-600">-$${"percent"===e.appliedCoupon.discountType?(e.plan.price*e.appliedCoupon.discountPercent/100).toFixed(2):(e.appliedCoupon.discountAmount||0).toFixed(2)}</span>\n </div>`:""}\n ${void 0!==e.plan.tax&&null!==e.plan.tax?`<div class="flex justify-between items-center">\n <span class="text-gray-600">${e.plan.taxType||"Sales Tax"} (${(100*(e.plan.taxRate||0)).toFixed(2)}%)</span>\n <span class="font-semibold text-gray-900">$${e.plan.tax.toFixed(2)}</span>\n </div>`:""}\n <div class="flex justify-between items-center pt-2 border-t border-gray-200">\n <span class="text-gray-700 font-medium">Total</span>\n <span class="font-bold text-gray-900">$${(()=>{const t=e.appliedCoupon?"percent"===e.appliedCoupon.discountType?e.plan.price*e.appliedCoupon.discountPercent/100:e.appliedCoupon.discountAmount||0:0;return((e.plan.totalWithTax||e.plan.price)-t).toFixed(2)})()}${r.U.formatPriceInterval(e.plan.interval,e.plan.intervalLength)}</span>\n </div>\n ${e.plan.trialDays>0?`\n <div class="flex justify-between items-center">\n <span class="text-gray-600">Trial Period</span>\n <span class="font-semibold text-green-600">${e.plan.trialDays} days free</span>\n </div>\n `:""}\n <div class="flex justify-between items-center">\n <span class="text-gray-600">Payment Method</span>\n <span class="font-semibold text-gray-900 capitalize">\n ${e.paymentMethod.brand} â¢â¢â¢â¢ ${e.paymentMethod.last4}\n </span>\n </div>\n </div>\n </div>\n\n \x3c!-- Quick Actions --\x3e\n <div class="space-y-3">\n <a\n href="${t}"\n class="block w-full max-w-md mx-auto px-6 py-3 bg-primary-600 text-white font-medium rounded-lg hover:bg-primary-700 transition-colors text-center"\n >\n Start Exploring\n </a>\n <button\n class="w-full max-w-md px-6 py-3 text-gray-700 font-medium hover:text-gray-900 transition-colors"\n data-action="close"\n >\n Close\n </button>\n </div>\n\n \x3c!-- Confetti Container --\x3e\n <div class="confetti-container fixed inset-0 pointer-events-none overflow-hidden">\n ${this.generateConfetti()}\n </div>\n </div>\n\n <style>\n @keyframes checkmark-stroke {\n to {\n stroke-dashoffset: 0;\n }\n }\n\n .success-checkmark path {\n stroke-dasharray: 60;\n stroke-dashoffset: 60;\n animation: checkmark-stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) 0.3s forwards;\n }\n\n .success-circle {\n animation: scale-in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);\n }\n\n @keyframes scale-in {\n from {\n transform: scale(0);\n opacity: 0;\n }\n to {\n transform: scale(1);\n opacity: 1;\n }\n }\n\n @keyframes confetti-fall {\n to {\n transform: translateY(100vh) rotate(360deg);\n }\n }\n\n .confetti {\n position: absolute;\n animation: confetti-fall 3s linear forwards;\n }\n </style>\n `,setTimeout((()=>{n.querySelectorAll(".confetti").forEach(((e,t)=>{e.style.animationDelay=.5*Math.random()+"s",e.style.left=100*Math.random()+"%"}))}),100),this.options.onSuccess&&this.options.onSuccess(e))}generateConfetti(){const e=["#FF6B6B","#4ECDC4","#45B7D1","#FFA07A","#98D8C8","#F7DC6F","#BB8FCE"],t=["square","circle"];let n="";for(let o=0;o<50;o++){const o=e[Math.floor(Math.random()*e.length)],i=t[Math.floor(Math.random()*t.length)],a=10*Math.random()+5;n+=`\n <div class="confetti ${i}" style="\n width: ${a}px;\n height: ${a}px;\n background-color: ${o};\n transform: rotate(${360*Math.random()}deg);\n top: -20px;\n ${"circle"===i?"border-radius: 50%;":""}\n "></div>\n `}return n}async trackPendingPurchase(e){try{await fetch("/api/heimguard/pending-purchase",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({planId:e}),credentials:"include"}),console.log("[PlanSelectionStep] Pending purchase tracked:",e)}catch(e){console.error("[PlanSelectionStep] Failed to track pending purchase:",e)}}cleanup(){this.currentStepComponent&&this.currentStepComponent.cleanup&&this.currentStepComponent.cleanup()}}},8231:function(e,t,n){"use strict";n.d(t,{LG:function(){return o},pZ:function(){return i}});
1class o extends Error{constructor(e,t,n,o){super(e),this.name="APIError",this.code=t,this.status=n,this.details=o}getUserMessage(){return this.message||"An unexpected error occurred. Please try again."}toJSON(){return{code:this.code,message:this.message,details:this.details}}}class i{constructor(e={}){this.abortControllers=new Map,this.baseURL=e.baseURL||"/api/heimguard",this.config={timeout:3e4,credentials:"include",headers:{"Content-Type":"application/json"},...e}}async get(e,t={}){return this.request("GET",e,void 0,t)}async post(e,t,n={}){return this.request("POST",e,t,n)}async put(e,t,n={}){return this.request("PUT",e,t,n)}async delete(e,t={}){return this.request("DELETE",e,void 0,t)}async request(e,t,n,i={}){const a=this.buildURL(t,i.params),s=new AbortController,r=`${e}-${t}-${Date.now()}`;this.abortControllers.set(r,s);const d=setTimeout((()=>{s.abort()}),i.timeout||this.config.timeout);try{const t={method:e,headers:{...this.config.headers,...i.headers},credentials:i.credentials||this.config.credentials,signal:s.signal,...i};n&&["POST","PUT","PATCH"].includes(e)&&(n instanceof FormData?(t.body=n,delete t.headers["Content-Type"]):t.body=JSON.stringify(n)),console.log("[BaseAPIService] Making request to:",a);const o=await fetch(a,t);return console.log("[BaseAPIService] Response status:",o.status),clearTimeout(d),await this.handleResponse(o)}catch(e){if(clearTimeout(d),e instanceof o)throw e;if(e instanceof Error){if("AbortError"===e.name)throw new o("Request timeout","TIMEOUT",0);throw console.error("[BaseAPIService] Request error:",e),new o(e.message,"NETWORK_ERROR",0)}throw e}finally{this.abortControllers.delete(r)}}async handleResponse(e){if(401===e.status)throw this.config.onUnauthorized&&this.config.onUnauthorized(),new o("Unauthorized","UNAUTHORIZED",401);let t;const n=e.headers.get("content-type");if(n?.includes("application/json"))try{t=await e.json()}catch{t=null}else t=await e.text();if(!e.ok){const n=this.parseError(t,e.status);throw this.config.onError&&this.config.onError(n.toJSON()),n}return t&&"object"==typeof t&&"error"===t.status&&console.log("[BaseAPIService] Backend returned error status in 200 response:",t),{success:!0,data:t}}parseError(e,t){return console.log("[BaseAPIService] Parsing error - Status:",t,"Data:",e),e&&"object"==typeof e?new o(e.message||e.error||`Request failed with status ${t}`,e.code||"API_ERROR",t,e.details||e):new o(`Request failed with status ${t}`,"API_ERROR",t)}buildURL(e,t){const n=e.startsWith("/")?e.slice(1):e;if(this.baseURL.startsWith("/")){const e=window.location.origin+this.baseURL,o=e.endsWith("/")?e:e+"/",i=new URL(n,o);return t&&Object.entries(t).forEach((([e,t])=>{null!=t&&i.searchParams.append(e,String(t))})),i.toString()}const o=this.baseURL.endsWith("/")?this.baseURL:this.baseURL+"/",i=new URL(n,o);return t&&Object.entries(t).forEach((([e,t])=>{null!=t&&i.searchParams.append(e,String(t))})),i.toString()}cancelAllRequests(){this.abortControllers.forEach((e=>{e.abort()})),this.abortControllers.clear()}updateConfig(e){this.config={...this.config,...e}}}},7310:function(e,t,n){"use strict";n.r(t);var o=n(2910),i=n(1916);const a=new class{loadFromStorage(){const e=localStorage.getItem(this.STORAGE_KEY);if(!e)return null;try{const t=JSON.parse(e),n=Date.now();return t._ts&&n-t._ts>36e5?(i.vF.debug("Settings expired in localStorage","init"),localStorage.removeItem(this.STORAGE_KEY),null):t.companyName&&"Company"!==t.companyName?(i.vF.debug("Valid settings found in localStorage:","init",t),t):(i.vF.debug("Invalid or default settings found in localStorage","init"),null)}catch(e){return i.vF.error("Failed to parse saved settings:","init",e),null}}saveToStorage(e){try{const t={...e,_ts:Date.now()};localStorage.setItem(this.STORAGE_KEY,JSON.stringify(t)),i.vF.debug("Saved settings to localStorage:","init",t)}catch(e){i.vF.error("Failed to save settings to localStorage:","init",e)}}constructor(){this.settings=null,this.isLoaded=!1,this.loadPromise=null,this.STORAGE_KEY="heimguard-settings";const e=this.loadFromStorage();e&&(this.settings=e,this.isLoaded=!0)}async load(){if(0!==new URLSearchParams(window.location.search).size&&this.reset(),this.loadPromise)return this.loadPromise;if(this.isLoaded&&this.settings)return this.settings;this.loadPromise=this._loadSettings();try{return this.settings=await this.loadPromise,this.isLoaded=!0,this.settings}finally{this.loadPromise=null}}async _loadSettings(){try{const e=this.loadFromStorage();if(e)return e;const t=await fetch(o.A.apiHeimguardSettingsUrl,{method:"GET",credentials:"include",headers:{Accept:"application/json","Content-Type":"application/json"}});if(!t.ok)throw new Error(`Failed to load settings: ${t.status}`);const n=await t.json();i.vF.debug("Heimguard settings loaded from API","init",n),i.vF.debug("Raw authConfig:","init",n.authConfig);const a=n.generalConfig||{},s=n.authConfig||{},r={companyName:a.companyName||n.companyName||"Company",companyImgSrc:a.companyImgSrc||n.companyImgSrc||n.templateData?.companyImgSrc,companySupportEmail:a.companySupportEmail,companySupportPhone:a.companySupportPhone,recurlyPublicKey:s.recurlyPublicKey||n.recurlyPublicKey||n.recurly_public_key,login:n.login||{url:"/login",useModal:!0},register:n.register||{url:"/register",useModal:!0},profile:n.profile||{url:"/profile",useModal:!1},forgotPassword:n.forgotPassword||{url:"/forgot-password",useModal:!0},terms:a.terms||n.terms||"",privacyPolicy:a.privacyPolicy||n.privacyPolicy||"",libraryPageUrl:a.libraryPageUrl||"/my-library",hideNewsLetterThumbnail:n.profileUIConfig?.hideNewsLetterThumbnail??n.hideNewsLetterThumbnail??!1,...n};return r.companyName&&"Company"!==r.companyName&&this.saveToStorage(r),void 0!==s.enableTaxPreview&&(r.enableTaxPreview=s.enableTaxPreview),void 0!==s.showCouponField&&(r.showCouponField=s.showCouponField),void 0!==a.enableInvoiceSettlement?r.enableInvoiceSettlement=a.enableInvoiceSettlement:void 0!==n.enableInvoiceSettlement?r.enableInvoiceSettlement=n.enableInvoiceSettlement:r.enableInvoiceSettlement=!0,r}catch(e){return i.vF.error("Failed to load Heimguard settings:","init",e),{companyName:o.A.demoData?.companyName||"Company",companyImgSrc:o.A.demoData?.companyImgSrc,recurlyPublicKey:"demo-recurly-key",login:{url:"/login",useModal:!0},register:{url:"/register",useModal:!0},profile:{url:"/profile",useModal:!1},forgotPassword:{url:"/forgot-password",useModal:!0},terms:"",privacyPolicy:""}}}getRecurlyPublicKey(){return this.settings?.recurlyPublicKey||null}getCompanyName(){return this.settings?.companyName||"Company"}getSettings(){return this.settings}isEnableTaxPreview(){return!1!==this.settings?.enableTaxPreview}isShowCouponField(){return console.log("isShowCouponField called, settings value:","init",this.settings?.authConfig?.showCouponField),!0===this.settings?.authConfig?.showCouponField}isInvoiceSettlementEnabled(){return!1!==this.settings?.enableInvoiceSettlement}getLibraryPageUrl(){return this.settings?.libraryPageUrl||"/my-library"}isCabotWealth(){return"Cabot Wealth"===this.getCompanyName()}hideNewsLetterThumbnail(){return this.settings?.hideNewsLetterThumbnail||!1}getDefaultCountry(){return this.settings?.profileUIConfig?.defaultCountry||"US"}getExcludedCountries(){return this.settings?.profileUIConfig?.excludedCountries||[]}reset(){this.settings=null,this.isLoaded=!1,this.loadPromise=null,localStorage.removeItem(this.STORAGE_KEY),i.vF.debug("Settings reset and cleared from localStorage","init")}};t.default=a},1964:function(e,t,n){"use strict";n.d(t,{A:function(){return s}});var o=n(2910),i=n(8231);class a extends i.pZ{constructor(e){super({baseURL:e||o.A.apiBaseUrl+"/profile"})}async getAllActivities(e){const t=o.A.apiGetActivitiesUrl?o.A.apiGetActivitiesUrl.replace(this.baseURL,""):"/activities/all";return this.get(t,{params:e})}async getRecentActivities(e){const t={page:e?.page||1,pageSize:e?.pageSize||20,...e};return this.get("/activities/recent",{params:t})}async getActivitiesByType(e,t){const n={type:e,page:t?.page||1,pageSize:t?.pageSize||20,...t};return this.get("/activities/by-type",{params:n})}async getActivitySummary(){return this.get("/activities/summary")}
1async getActivitiesByCategory(e,t){const n=a.CATEGORY_MAPPINGS[e];if(!n||0===n.length)throw new Error(`Unknown category: ${e}`);const o=t?.page||1,i=t?.pageSize||20,s=await this.getAllActivities({page:o,pageSize:2*i,...t});if(s.success&&s.data?.items){const e=s.data.items.filter((e=>n.includes(e.type)));return{success:!0,data:{items:e.slice(0,i),total:e.length,page:o,pageSize:i,totalPages:Math.ceil(e.length/i)}}}return s}async getActivityTimeline(e,t){return this.get("/activities/timeline",{params:{startDate:e.toISOString(),endDate:t.toISOString()}})}}a.CATEGORY_MAPPINGS={auth:["LOGIN","LOGOUT","LOGIN_FAILED","REGISTRATION","EMAIL_VERIFIED","PASSWORD_CHANGE","PASSWORD_RESET","GOOGLE_LOGIN","FACEBOOK_LOGIN","PASSWORDLESS_LOGIN"],profile:["PROFILE_UPDATE","EMAIL_VERIFIED","PROFILE_PICTURE_UPDATE","ADDRESS_ADDED","ADDRESS_UPDATED","ADDRESS_DELETED"],payment:["PAYMENT_METHOD_ADDED","PAYMENT_METHOD_UPDATED","PAYMENT_METHOD_DELETED","BILLING_INFO_ADDED","BILLING_INFO_UPDATED","BILLING_INFO_DELETED","SUBSCRIPTION_CREATED","SUBSCRIPTION_UPDATED","SUBSCRIPTION_CANCELLED","INVOICE_GENERATED","INVOICE_PAID"],social:["CONTENT_LIKED","CONTENT_UNLIKED","CONTENT_FOLLOWED","CONTENT_UNFOLLOWED","USER_FOLLOWED","USER_UNFOLLOWED","COMMENT_POSTED","COMMENT_EDITED"],security:["TWO_FACTOR_ENABLED","TWO_FACTOR_DISABLED","SESSION_EXPIRED","ACCOUNT_LOCKED","ACCOUNT_UNLOCKED","BACKUP_CODES_GENERATED"]};const s=new a},5856:function(e,t,n){"use strict";var o=n(2910),i=n(8231);class a extends i.pZ{async getAddresses(){const e=o.A.apiGetAllAddresses.replace(o.A.apiBaseUrl,""),t=await this.get(e);if(!t.success)throw new Error(t.message||"Failed to get addresses");return t.data}async addAddress(e){console.log("Adding address with data:",e),console.log("Address data JSON:",JSON.stringify(e,null,2));try{const t=o.A.apiAddAddress.replace(o.A.apiBaseUrl,""),n=await this.post(t,e);if(console.log("Add address response:",n),!n.success)throw new Error(n.message||"Failed to add address");return n.data}catch(e){throw console.error("Add address error:",e),e instanceof Error&&"response"in e&&console.error("Error response:",e.response),e}}async updateAddress(e,t){const n={...t,id:e};console.log("[AddressesAPI.updateAddress] Sending payload:",JSON.stringify(n,null,2));const i=o.A.apiUpdateAddress.replace(o.A.apiBaseUrl,"");try{const e=await this.post(i,n);if(console.log("[AddressesAPI.updateAddress] Response:",e),!e.success)throw new Error(e.message||"Failed to update address");return e.data}catch(e){throw console.error("[AddressesAPI.updateAddress] Error:",e),e instanceof Error&&"response"in e&&console.error("[AddressesAPI.updateAddress] Error response:",e.response),e}}async deleteAddress(e){const t=o.A.apiDeleteAddress.replace(o.A.apiBaseUrl,""),n=await this.post(t,{id:e});if(!n.success)throw new Error(n.message||"Failed to delete address");return n.data}async getAddressCount(){try{const e=await this.getAddresses();if(e&&e.addresses){if("object"==typeof e.addresses&&!Array.isArray(e.addresses))return Object.keys(e.addresses).length;if(Array.isArray(e.addresses))return e.addresses.length}return 0}catch(e){return console.error("Failed to get address count:",e),0}}}t.A=new a},9935:function(e,t,n){"use strict";n.d(t,{A:function(){return i}});var o=n(1916);class i{constructor(e={}){this.options={publicKey:null,...e},this.recurly=null,this.isInitialized=!1,this.elements=null}async initialize(){if(!this.isInitialized)if(this.options.publicKey)try{window.recurly||await this.loadRecurlyScript(),window.recurly.configure(this.options.publicKey),this.recurly=window.recurly,this.isInitialized=!0,o.vF.debug("Recurly initialized","payment")}catch(e){throw o.vF.error("Failed to initialize Recurly:","payment",e),e}else o.vF.debug("Recurly initialize skipped: no public key configured","payment")}async loadRecurlyScript(){return new Promise(((e,t)=>{if(window.recurly)return void e(window.recurly);const n=document.createElement("script");n.src="https://js.recurly.com/v4/recurly.js",n.async=!0,n.onload=()=>e(window.recurly),n.onerror=()=>t(new Error("Failed to load Recurly script")),document.head.appendChild(n)}))}createElements(e={}){if(!this.isInitialized||!this.recurly)throw new Error("Recurly not initialized. Call initialize() first.");const t={style:{fontSize:"16px",fontFamily:"system-ui, -apple-system, sans-serif",fontColor:"#374151",placeholder:{fontColor:"#9
1CA3AF"},invalid:{fontColor:"#EF4444"}},...e};return this.elements=this.recurly.Elements(t),{cardNumber:this.elements.CardNumberElement(),cardMonth:this.elements.CardMonthElement(),cardYear:this.elements.CardYearElement(),cardCvv:this.elements.CardCvvElement()}}async tokenize(e,t={}){if(!this.recurly)throw new Error("Recurly not initialized");return new Promise(((n,o)=>{const i={...t};this.recurly.token(e.cardNumber,i,((e,t)=>{e?o(new Error(e.message||"Tokenization failed")):n(t)}))}))}attachElement(e,t){const n=document.querySelector(t);n?e.attach(n):console.error(`Container not found: ${t}`)}validateElements(e){const t={};return Object.keys(e).forEach((n=>{const o=e[n];o&&o.state&&o.state.empty&&(t[n]="This field is required")})),{isValid:0===Object.keys(t).length,errors:t}}}},4148:function(e,t,n){"use strict";n.d(t,{_:function(){return s},q:function(){return a}});var o=n(8231),i=n(2910);class a extends o.pZ{constructor(){super({baseURL:i.A.apiBaseUrl})}async getProfile(){const e=i.A.apiGetProfileUrl.replace(i.A.apiBaseUrl,""),t=await this.get(e);if(t.success&&t.data){if(t.data.profile)return t;if(t.data.email||t.data.id||t.data.userId)return{...t,data:{profile:t.data,stats:t.data.stats}}}return t}async updateProfile(e){const t=i.A.apiEditProfileUrl.replace(i.A.apiBaseUrl,"");return this.post(t,e)}async uploadAvatar(e){const t=new FormData;t.append("avatar",e.file),e.cropData&&t.append("cropData",JSON.stringify(e.cropData));const n=i.A.apiProfileAvatarUrl.replace(i.A.apiBaseUrl,"");return this.post(n,t)}async deleteAvatar(){const e=i.A.apiProfileAvatarDeleteUrl.replace(i.A.apiBaseUrl,"");return this.delete(e)}async getAddresses(){const e=i.A.apiGetAllAddresses.replace(i.A.apiBaseUrl,"");return this.get(e)}async getAddress(e){const t=i.A.apiGetAllAddresses.replace(i.A.apiBaseUrl,""),n=await this.get(t);if(n.success&&n.data&&n.data.addresses){let t;if(t=Array.isArray(n.data.addresses)?n.data.addresses.find((t=>t.id===e)):n.data.addresses[e],t)return{success:!0,data:t}}throw new o.LG("Address not found","NOT_FOUND",404)}async createAddress(e){const t=i.A.apiAddAddress.replace(i.A.apiBaseUrl,"");return this.post(t,e)}async updateAddress(e,t){const n=i.A.apiUpdateAddress.replace(i.A.apiBaseUrl,"");return this.post(n,{...t,id:e})}async deleteAddress(e){const t=i.A.apiDeleteAddress.replace(i.A.apiBaseUrl,"");return this.post(t,{id:e})}async setDefaultShippingAddress(e,t){const n=i.A.apiUpdateAddress.replace(i.A.apiBaseUrl,""),o={...t,id:e,isDefaultShipping:!0};return this.post(n,o)}async setDefaultBillingAddress(e,t){const n=i.A.apiUpdateAddress.replace(i.A.apiBaseUrl,""),o={...t,id:e,isDefaultBilling:!0};return this.post(n,o)}async getPaymentMethods(){const e=i.A.apiGetPaymentMethodsUrl.replace(i.A.apiBaseUrl,"");return this.get(e)}async addPaymentMethod(e){const t=i.A.apiAddPaymentMethodUrl.replace(i.A.apiBaseUrl,"");return this.post(t,e)}async deletePaymentMethod(e){const t=i.A.apiDeletePaymentMethodUrl.replace(i.A.apiBaseUrl,"");return this.post(t,{id:e})}async setDefaultPaymentMethod(e){throw new o.LG("Setting default payment method requires backend API support","NOT_IMPLEMENTED",501)}async getSubscriptions(){const e=i.A.apiGetSubscriptionsUrl.replace(i.A.apiBaseUrl,"");return this.get(e)}async getSubscription(e){const t=i.A.apiGetSubscriptionsUrl.replace(i.A.apiBaseUrl,""),n=await this.get(t);if(n.success&&n.data&&n.data.subscriptions){let t;if(t=Array.isArray(n.data.subscriptions)?n.data.subscriptions.find((t=>t.id===e)):n.data.subscriptions[e],t)return{success:!0,data:t}}throw new o.LG("Subscription not found","NOT_FOUND",404)}async cancelSubscription(e,t){const n=i.A.apiDeleteSubscriptionUrl.replace(i.A.apiBaseUrl,""),o={id:e,reason:t};return this.post(n,o)}async reactivateSubscription(e){const t=i.A.apiUpdateSubscriptionUrl.replace(i.A.apiBaseUrl,"");return this.post(t,{id:e,status:"active"})}async updateSubscriptionPaymentMethod(e,t){const n=i.A.apiUpdateSubscriptionUrl.replace(i.A.apiBaseUrl,"");return this.post(n,{id:e,paymentMethodId:t})}async getInvoices(e){const t=i.A.apiGetInvoicesUrl.replace(i.A.apiBaseUrl,"");return this.get(t,{params:e})}async downloadInvoice(e){const t=i.A.apiGetInvoicePdfUrl.replace(i.A.apiBaseUrl,"");return(await this.get(`${t}/${e}`,{headers:{Accept:"application/pdf"}})).data}async getActivities(e){const t=i.A.apiGetActivitiesUrl.replace(i.A.apiBaseUrl,"");return this.get(t,{params:e})}static isProfileResponse(e){return e&&"object"==typeof e&&"profile"in e}static isAddressesResponse(e){return e&&"object"==typeof e&&"addresses"in e}static isPaymentMethodsResponse(e){return e&&"object"==typeof e&&"paymentMethods"in e}}const s=new a},7663:function(e,t,n){"use strict";n.d(t,{G:function(){return s}});var o=n(2910),i=n(8231);class a extends i.pZ{async getSubscriptions(e=1,t=10){const n=new URLSearchParams({pageNumber:e.toString(),pageSize:t.toString()}
1),i=o.A.apiGetSubscriptionsUrl.replace(this.baseURL,"")+"?"+n.toString(),a=await this.get(i);return console.log("[SubscriptionAPI] getSubscriptions response:",a),a}async getSubscriptionsArray(){try{const e=await this.getSubscriptions();if(e.success&&e.data?.subscriptions){const t=e.data.subscriptions;return Array.isArray(t)?t:Object.values(t)}return[]}catch(e){return[]}}async createSubscription(e){if(console.log("SubscriptionAPI.createSubscription called with:",e),!e.planCode||"undefined"===e.planCode||"null"===e.planCode)throw new Error(`Invalid plan code: ${e.planCode}`);if(!e.billingInfoId||"undefined"===e.billingInfoId||"null"===e.billingInfoId)throw new Error(`Invalid billing info ID: ${e.billingInfoId}`);const t=o.A.apiAddSubscriptionUrl.replace(this.baseURL,"");return this.post(t,e)}async cancelSubscription(e){const t=o.A.apiCancelSubscriptionUrl.replace(this.baseURL,"");return this.post(t,{subscriptionId:e})}async deleteSubscription(e){const t=o.A.apiDeleteSubscriptionUrl.replace(this.baseURL,"");return this.post(t,e)}async updateSubscription(e){const t=o.A.apiUpdateSubscriptionUrl.replace(this.baseURL,"");return this.post(t,e)}async updateSubscriptionPaymentMethod(e,t){const n={id:e,paymentMethodId:t};return this.updateSubscription(n)}async previewSubscription(e,t,n){const o={planCode:e,billingInfoId:t,couponCode:n};return this.post("/profile/subscriptions/preview",o)}async validateCoupon(e,t){const n={couponCode:e,planCode:t};return this.post("/profile/coupons/validate",n)}async getAvailablePlans(e="global"){try{const t=e||"global",n=await fetch(`${o.A.apiAccessWall}?shortCode=${t}`,{method:"GET",credentials:"include",headers:{"Content-Type":"application/json"}});if(!n.ok)throw new Error(`Failed to fetch plans: ${n.status}`);const i=await n.json();return{success:!0,data:this.transformPlansFromTemplate(i)}}catch(e){return console.error("[SubscriptionAPI] Error fetching plans:",e),{success:!1,error:{message:"Unable to load subscription plans. Please check your connection and try again.",code:"NETWORK_ERROR"}}}}transformPlansFromTemplate(e){console.log("Full template data received:",e);let t=[],n={};e.userPlans&&"object"==typeof e.userPlans&&(n=e.userPlans,console.log("Found userPlans:",n)),e.plans&&Array.isArray(e.plans)?(t=e.plans,console.log("Found plans in templateData.plans:",t)):e.accessWall&&e.accessWall.plans&&Array.isArray(e.accessWall.plans)?(t=e.accessWall.plans,console.log("Found plans in templateData.accessWall.plans:",t)):e.subscriptionPlans&&(t=Array.isArray(e.subscriptionPlans)?e.subscriptionPlans:Object.values(e.subscriptionPlans||{}),console.log("Found plans in templateData.subscriptionPlans:",t));return{plans:t.map(((e,t)=>{console.log("Transforming plan:",e);const n=e.currencies&&e.currencies[0],o=n?n.unit_amount:0,i=n&&n.setup_fee||0,a=n?n.currency:"CAD";console.log(`[SubscriptionAPI] Plan ${e.name} - Raw unit_amount: ${o}, setup_fee: ${i}, currency: ${a}`);const s=e.code||e.plan_code||e.planCode||e.id,{interval:r,length:d}=this.parseIntervalFromPlan(e);return{id:s||`plan_${t}`,code:s||"",name:e.title_override||this.cleanPlanName(e.name),description:e.description_override||this.cleanPlanDescription(e.description),amount:100*o,price:o,setupFee:i,interval:r,intervalLength:d,currency:a,trialPeriodDays:e.trial_length||0,trialDays:this.parseTrial(e.trial_unit,e.trial_length)||0,intervalCount:1,features:[...this.addAnnualFeatures(e),...this.extractFeaturesFromDescription(e.description)],featured_points:e.featured_points||void 0,hideAutoRenewBadge:e.hide_auto_renew_badge||!1,hideSetupFeeBadge:e.hide_setup_fee_badge||!1,hideFreeTrialBadge:e.hide_free_trial_badge||!1,tax:e.tax||0,taxRate:e.taxRate||0,taxType:e.taxType||"Sales Tax",totalWithTax:e.totalWithTax||o+(e.tax||0),cardType:e.cardType||void 0,lastFour:e.lastFour||void 0}})),userPlans:n,startExploringPageUrl:e.startExploringPageUrl}}parsePrice(e){if("number"==typeof e)return e;if("string"==typeof e){const t=parseFloat(e.replace(/[^0-9.]/g,""));return isNaN(t)?0:t}return 0}parseInterval(e){if(!e)return"month";const t=e.toString().toLowerCase();return t.includes("year")||t.includes("annual")?"year":t.includes("month")||t.includes("monthly")?"month":t.includes("week")||t.includes("weekly")?"week":t.includes("day")||t.includes("daily")?"day":"month"}parseTrial(e,t){switch(e){case"days":return t||0;case"months":return 30*(t||1);default:return console.warn(`[trialPeriodToDays] Unknown trial unit: '${e}'. Defaulting to 0 days.`),0}}parseIntervalFromPlan(e){if(e.interval_unit&&e.interval_length){const t=e.interval_unit.toLowerCase(),n=e.interval_length;if("months"===t)return n>=12&&n%12==0?{interval:"year",length:n/12}:{interval:"month",length:n};if("days"===t)return{interval:"day",length:n}}return{interval:"month",length:1}}cleanPlanName(e){if(!e)return"Subscription Plan";let t=e.replace(/^TSI\s+/i,"").replace(/\s+-\s+\[DEFAULT\]/i,"").replace(/\s+-\s+\$[\d.]+(?:\.\d{2})?\s+.*$/i,"").trim();if(t.length>50){const e=t.split(" - ");e.length>1&&(t=e[0].trim())}return t||"Subscription Plan"}cleanPlanDescription(e){if(!e)return"Premium subscription access";let t=e.split("\n")[0].replace(/\s+/g," ").trim();if(t.length>120){const e=t.split(". ");t=e[0],t.length<50&&e.length>1&&(t+=". "+e[1]),t.endsWith(".")||t.endsWith("!")||t.endsWith("?")||(t+="...")}return t||"Premium subscription access"}extractFeaturesFromDescription(e){if(!e)return this.getDefaultFeatures();const t=[];if((e.includes("digital")||e.includes("online"))&&t.push("Digital access included"),e.includes("print")&&t.push("Print delivery included"),(e.includes("weekly")||e.includes("Hotline"))&&t.push("Weekly updates and hotlines"),(e.includes("back issues")||e.includes("library"))&&t.push("Full archive access"),(e.includes("No-Risk Guarantee")||e.includes("cancel"))&&t.push("Cancel anytime guarantee"),(e.includes("save")||e.includes("Save"))&&t.push("Special savings offer"),0===t.length)return this.getDefaultFeatures();for(;t.length<3;){const e=this.getDefaultFeatures().find((e=>!t.includes(e)));if(!e)break;t.push(e)}return t.slice(0,4)}addAnnualFeatures(e){const t=[],{interval:n}=this.parseIntervalFromPlan(e);
1return"year"===n&&(t.push("Best value"),t.push("30-day money-back guarantee")),t}determinePlanPopularity(e,t,n){if(n>=3&&t===Math.floor(n/2))return!0;const o=(e.name||"").toLowerCase();return!!(o.includes("best")||o.includes("savings")||o.includes("save"))}getDefaultFeatures(e){const t=(e||"").toLowerCase();return t.includes("basic")?["Access to basic content","Email support","Mobile app access","Cancel anytime"]:t.includes("premium")||t.includes("pro")?["Access to all content","Premium content library","Priority support","Mobile app access","Advanced features","Cancel anytime"]:["Premium subscription access","Support included","Cancel anytime"]}getStatusInfo(e){return{active:{label:"Active",color:"green",icon:"check-circle"},trialing:{label:"Trial",color:"blue",icon:"clock"},past_due:{label:"Past Due",color:"yellow",icon:"exclamation-triangle"},canceled:{label:"Cancelled",color:"red",icon:"x-circle"},unpaid:{label:"Unpaid",color:"red",icon:"exclamation-circle"},pending:{label:"Pending",color:"gray",icon:"clock"}}[e]||{label:e||"Unknown",color:"gray",icon:"question-mark-circle"}}getBillingDateInfo(e){if(!e)return{display:"N/A",isUpcoming:!1,daysDiff:null};const t=new Date(e),n=new Date,o=t.getTime()-n.getTime(),i=Math.ceil(o/864e5);return{display:t.toLocaleDateString(),isUpcoming:i<=7&&i>=0,daysDiff:i,formatted:this.formatBillingDate(i)}}formatBillingDate(e){return e<0?"Overdue":0===e?"Today":1===e?"Tomorrow":e<=7?`In ${e} days`:"Upcoming"}}const s=new a},9632:function(e,t,n){"use strict";n.d(t,{W:function(){return c}});var o=n(6833),i=n(6894),a=n(744),s=n(8380),r=n(4436),d=n(7310),l=n(8520);class c{constructor(e={}){this.modal=null,this.inlineContainer=null,this.errors={},this.enableSmsOptInField=!1,this.smsConsentText=null,this.isCabotWealth=!1,this.options={address:null,onSave:null,onCancel:null,title:null,submitText:null,showDefaults:!0,showAccountAddress:!1,defaultFirstName:"",defaultLastName:"",countries:null,validator:this.defaultValidator,isFirstAddress:!1,hideAddressType:!1,forceBillingOnly:!1,inline:!1,hideBackButton:!1,...e},this.isEdit=!!this.options.address,this.formData=this.initializeFormData(),this.loadConfigSettings()}initializeFormData(){if(this.options.address){const e={...this.options.address};return e.isAccount&&(e.isDefaultBilling=!0),e}const e=this.options.isFirstAddress||!1;return{firstName:this.options.defaultFirstName||"",lastName:this.options.defaultLastName||"",street1:"",street2:"",city:"",region:"",postalCode:"",country:d.default.getDefaultCountry()||"US",phone:"",mobileNumber:"",otherPhone:"",smsAgreementOptIn:!1,isShipping:!this.options.forceBillingOnly,isBilling:!0,isDefaultShipping:!1,isDefaultBilling:e,isAccount:e}}getAddressType(){return this.formData.isShipping&&this.formData.isBilling?"both":this.formData.isShipping?"shipping":this.formData.isBilling?"billing":"both"}async render(){if(this.options.inline)throw new Error("Use renderInline() method for inline rendering");await this.loadConfigSettings(),this.options.countries||(this.options.countries=s.A.getAllCountries());const e=this.options.title||(this.isEdit?"Edit Address":"Add New Address"),t=this.options.submitText||(this.isEdit?"Upd
1ate Address":"Add Address"),n=`\n <form id="address-form" class="space-y-5">\n \x3c!-- Contact Information Section --\x3e\n <div>\n <h3 class="text-sm font-semibold text-gray-900 mb-3">Contact Information</h3>\n ${this.renderNameFields()}\n </div>\n\n \x3c!-- Address Section --\x3e\n <div>\n <h3 class="text-sm font-semibold text-gray-900 mb-3">Address Details</h3>\n ${this.renderAddressFields()}\n ${this.renderLocationFields()}\n </div>\n\n \x3c!-- Address Type Section --\x3e\n <div>\n ${this.renderAddressTypes()}\n <div id="default-options-container" class="mt-4">\n ${this.renderDefaultOptions()}\n </div>\n </div>\n </form>\n `,i=`\n <div class="flex justify-end space-x-3">\n <button id="cancel-address-btn" class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">\n Cancel\n </button>\n <button id="save-address-btn" class="px-4 py-2 text-sm font-medium text-white bg-primary-600 border border-transparent rounded-md hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">\n ${t}\n </button>\n </div>\n `,a={id:this.isEdit?`address-edit-${Date.now()}`:`address-add-${Date.now()}`,title:e,content:n,footer:i,size:"large",onClose:()=>{this.options.onCancel&&this.options.onCancel()}};this.modal=new o.Modal(a),this.modal.open(),this.attachEventListeners()}async renderInline(e){if(!this.options.inline)throw new Error("Set inline: true in options to use renderInline() method");this.inlineContainer=e,await this.loadConfigSettings(),this.options.countries||(this.options.countries=s.A.getAllCountries());const t=this.options.title||(this.isEdit?"Edit Address":"Add Billing Address"),n=this.options.submitText||(this.isEdit?"Upd
1ate Address":"Save & Continue"),o=`\n <div class="address-form-container">\n \x3c!-- Header for inline mode --\x3e\n <div class="mb-6">\n <h3 class="text-lg font-semibold text-gray-900 mb-2">${t}</h3>\n <p class="text-gray-600">Enter your address details below</p>\n </div>\n\n <form id="address-form" class="space-y-5">\n \x3c!-- Contact Information Section --\x3e\n <div>\n <h4 class="text-sm font-semibold text-gray-900 mb-3">Contact Information</h4>\n ${this.renderNameFields()}\n </div>\n\n \x3c!-- Address Section --\x3e\n <div>\n <h4 class="text-sm font-semibold text-gray-900 mb-3">Address Details</h4>\n ${this.renderAddressFields()}\n ${this.renderLocationFields()}\n </div>\n\n \x3c!-- Address Type Section --\x3e\n <div>\n ${this.renderAddressTypes()}\n <div id="default-options-container" class="mt-4">\n ${this.renderDefaultOptions()}\n </div>\n </div>\n\n \x3c!-- Action Buttons --\x3e\n <div class="flex ${this.options.hideBackButton?"justify-end":"justify-between"} pt-4 border-t">\n ${this.options.hideBackButton?"":'\n <button id="cancel-address-btn" type="button" class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">\n Back\n </button>\n '}\n <button id="save-address-btn" type="submit" class="px-6 py-2 text-sm font-medium text-white bg-primary-600 border border-transparent rounded-md hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">\n ${n}\n </button>\n </div>\n </form>\n </div>\n `;e.innerHTML=o,this.attachEventListeners()}renderNameFields(){return`\n <div class="grid grid-cols-2 gap-4">\n <div>\n <label for="firstName" class="block text-sm font-medium text-gray-700 mb-1">\n First Name <span class="text-red-500">*</span>\n </label>\n <input\n type="text"\n id="firstName"\n name="firstName"\n value="${this.escapeHtml(this.formData.firstName)}"\n class="w-full px-3 py-2 border ${this.errors.firstName?"border-red-300 focus:ring-red-500 focus:border-red-500":"border-gray-300 focus:ring-primary-500 focus:border-primary-500"} rounded-md text-sm"\n ${this.isCabotWealth?"":'placeholder="John"'}\n />\n ${this.errors.firstName?`<p class="mt-1 text-sm text-red-600">${this.errors.firstName}</p>`:""}\n </div>\n <div>\n <label for="lastName" class="block text-sm font-medium text-gray-700 mb-1">\n Last Name <span class="text-red-500">*</span>\n </label>\n <input\n type="text"\n id="lastName"\n name="lastName"\n value="${this.escapeHtml(this.formData.lastName)}"\n class="w-full px-3 py-2 border ${this.errors.lastName?"border-red-300 focus:ring-red-500 focus:border-red-500":"border-gray-300 focus:ring-primary-500 focus:border-primary-500"} rounded-md text-sm"\n ${this.isCabotWealth?"":'placeholder="Doe"'}\n />\n ${this.errors.lastName?`<p class="mt-1 text-sm text-red-600">${this.errors.lastName}</p>`:""}\n </div>\n </div>\n `}renderAddressFields(){return`\n <div class="grid grid-cols-2 gap-4">\n <div>\n <label for="street1" class="block text-sm font-medium text-gray-700 mb-1">\n Street Address <span class="text-red-500">*</span>\n </label>\n <input\n type="text"\n id="street1"\n name="street1"\n value="${this.formData.street1}"\n class="w-full px-3 py-2 border ${this.errors.street1?"border-red-300 focus:ring-red-500 focus:border-red-500":"border-gray-300 focus:ring-primary-500 focus:border-primary-500"} rounded-md text-sm"\n ${this.isCabotWealth?"":'placeholder="123 Main Street"'}\n />\n ${this.errors.street1?`<p class="mt-1 text-sm text-red-600">${this.errors.street1}</p>`:""}\n </div>\n <div>\n <label for="street2" class="block text-sm font-medium text-gray-700 mb-1">\n Apartment, Suite, etc. <span class="text-gray-500">(Optional)</span>\n </label>\n <input\n type="text"\n id="street2"\n name="street2"\n value="${this.formData.street2||""}"\n class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-primary-500 focus:border-primary-500 text-sm"\n ${this.isCabotWealth?"":'placeholder="Apt 4B"'}\n />\n ${this.errors.street2?`<p class="mt-1 text-sm text-red-600">${this.errors.street2}</p>`:""}\n </div>\n </div>\n `}renderLocationFields(){return`\n <div class="grid grid-cols-2 gap-4 mt-4">\n <div>\n <label for="city" class="block text-sm font-medium text-gray-700 mb-1">\n City\n </label>\n <input\n type="text"\n id="city"\n name="city"\n value="${this.formData.city}"\n class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-primary-500 focus:border-primary-500 text-sm"\n />\n ${this.errors.city?`<p class="mt-1 text-sm text-red-600">${this.errors.city}</p>`:""}\n </div>\n <div>\n <label for="region" class="block text-sm font-medium text-gray-700 mb-1">\n State/Region\n </label>\n ${this.renderRegionField()}\n ${this.errors.region?`<p class="mt-1 text-sm text-red-600">${this.errors.region}</p>`:""}\n </div>\n </div>\n\n <div class="grid grid-cols-2 gap-4 mt-4">\n <div>\n ${r.W.renderPostalCodeField({name:"postalCode",label:"Postal Code",value:this.formData.postalCode,countryCode:this.formData.country,required:!1,className:""})}\n \x3c!-- Postal code errors are handled by AddressFields component --\x3e\n </div>\n <div>\n ${r.W.renderCountryField({name:"country",label:"Country",value:this.formData.country,required:!1,className:""})}\n </div>\n </div>\n <div class="mt-6">\n <h3 class="text-sm font-semibold text-gray-900 mb-3">Contact Details</h3>\n </div>\n <div class="grid grid-cols-2 gap-4 mt-4">\n <div>\n ${i.I.render({name:"mobileNumber",label:"Mobile Number",value:this.formData.mobileNumber||"",required:!1,defaultCountry:this.formData.country.toLowerCase()||"ca",preferredCountries:["ca","us"],separateDialCode:!0,autoPlaceholder:this.isCabotWealth?"off":"aggressive",className:""+(this.errors.mobileNumber?"error":""),hint:"optional"})}\n ${this.errors.mobileNumber?`<p class="mt-1 text-sm text-red-600">${this.errors.mobileNumber}</p>`:""}\n </div>\n <div>\n ${i.I.render({name:"phone",label:"Phone Number",value:this.formData.phone||"",required:!1,defaultCountry:this.formData.country.toLowerCase()||"ca",preferredCountries:["ca","us"],separateDialCode:!0,autoPlaceholder:this.isCabotWealth?"off":"aggressive",className:""+(this.errors.phone?"error":""),hint:"optional"})}\n ${this.errors.phone?`<p class="mt-1 text-sm text-red-600">${this.errors.phone}</p>`:""}\n </div>\n </div>\n\n ${this.renderSmsOptIn()}\n `}renderRegionField(){const e=s.A.getStatesByCountry(this.formData.country);return e&&e.length>0?`\n <select\n id="region"\n name="region"\n class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-primary-500 focus:border-primary-500 text-sm"\n >\n <option value="">Select a state</option>\n ${e.map((e=>`\n <option value="${e.code}" ${this.formData.region===e.code?"selected":""}>\n ${e.name}\n </option>\n `)).join("")}\n </select>\n `:`\n <input\n type="text"\n id="region"\n name="region"\n value="${this.formData.region}"\n class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-primary-500 focus:border-primary-500 text-sm"\n placeholder="State/Province/Region"\n />\n `}renderSmsOptIn(){if(!this.enableSmsOptInField)return"";const e=this.smsConsentText||"By checking this box, you consent to receive text messages at the mobile number provided that may be sent via an automated system (only US and Canadian customers will receive messages at this time). Consent is not a condition of purchase. Text STOP to cancel at any time. Message & data rates may apply. By continuing, you agree to Cabot Wealth Network's Terms of Service and Privacy Policy.";return`\n <div class="mt-4">\n <label class="flex items-start cursor-pointer">\n <div class="flex items-center h-5">\n <input\n type="checkbox"\n name="smsAgreementOptIn"\n id="smsAgreementOptIn"\n ${this.formData.smsAgreementOptIn?"checked":""}\n class="h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300 rounded"\n />\n </div>\n <div class="ml-3">
1\n <span class="text-sm font-medium text-gray-700 block mb-1">SMS Notifications</span>\n <p class="text-xs text-gray-600 leading-relaxed">\n ${e}\n </p>\n </div>\n </label>\n </div>\n `}async loadConfigSettings(){try{const e=await l.initService.getInitData();this.enableSmsOptInField=e.profileUIConfig?.enableSmsOptInField??!1,this.smsConsentText=e.profileUIConfig?.smsOptInAgreementMessage||null,this.isCabotWealth=d.default.isCabotWealth()}catch(e){console.error("[AddressModal] Failed to load config settings:",e)}}renderAddressTypes(){if(this.options.hideAddressType)return"";const e=this.getAddressType();return`\n <div class="space-y-3 pt-4 border-t">\n <label class="block text-sm font-medium text-gray-900">\n Address Type\n </label>\n <div class="grid grid-cols-3 gap-3">\n <button\n type="button"\n id="type-both"\n class="address-type-btn flex items-center justify-center gap-2 py-2 px-4 border rounded-md text-sm font-medium transition-all ${"both"===e?"border-primary-600 bg-primary-50 text-primary-700":"border-gray-300 bg-white text-gray-700 hover:bg-gray-50"}"\n >\n <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />\n </svg>\n Both\n </button>\n\n <button\n type="button"\n id="type-shipping"\n class="address-type-btn flex items-center justify-center gap-2 py-2 px-4 border rounded-md text-sm font-medium transition-all ${"shipping"===e?"border-primary-600 bg-primary-50 text-primary-700":"border-gray-300 bg-white text-gray-700 hover:bg-gray-50"}"\n >\n <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4" />\n </svg>\n Shipping\n </button>\n\n <button\n type="button"\n id="type-billing"\n class="address-type-btn flex items-center justify-center gap-2 py-2 px-4 border rounded-md text-sm font-medium transition-all ${"billing"===e?"border-primary-600 bg-primary-50 text-primary-700":"border-gray-300 bg-white text-gray-700 hover:bg-gray-50"}"\n >\n <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" />\n </svg>\n Billing\n </button>\n </div>\n </div>\n `}renderDefaultOptions(){if(!this.options.showDefaults)return"";if(this.options.hideAddressType)return`\n <div class="border-t pt-4 space-y-3">\n ${this.options.showAccountAddress?`\n <label class="flex items-center justify-between ${this.options.isFirstAddress||this.isEdit&&this.formData.isAccount?"cursor-not-allowed":"cursor-pointer"}">\n <span class="text-sm ${this.options.isFirstAddress||this.isEdit&&this.formData.isAccount?"text-gray-500":"text-gray-700"}">\n Default address\n ${this.options.isFirstAddress?'<span class="text-xs text-gray-500 ml-2">(Required for first address)</span>':""}\n ${this.isEdit&&this.formData.isAccount?'<span class="text-xs text-gray-500 ml-2">(Set another address as default to change)</span>':""}\n </span>\n <div class="relative">\n <input\n type="checkbox"\n id="isAccount"\n name="isAccount"\n ${this.formData.isAccount?"checked":""}\n ${this.options.isFirstAddress||this.isEdit&&this.formData.isAccount?"disabled":""}\n class="sr-only peer"\n >\n <div class="w-11 h-6 ${this.options.isFirstAddress||this.isEdit&&this.formData.isAccount?"bg-gray-100":"bg-gray-200"} rounded-full peer peer-focus:ring-4 peer-focus:ring-primary-300 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary-600 ${this.options.isFirstAddress||this.isEdit&&this.formData.isAccount?"opacity-75":""}"></div>\n </div>\n </label>\n `:""}\n </div>\n `;return this.formData.isShipping||this.formData.isBilling?`\n <div class="border-t pt-4 space-y-3">\n ${this.formData.isShipping?`\n <label class="flex items-center justify-between cursor-pointer">
1\n <span class="text-sm text-gray-700">Default shipping address</span>\n <div class="relative">\n <input\n type="checkbox"\n id="isDefaultShipping"\n name="isDefaultShipping"\n ${this.formData.isDefaultShipping?"checked":""}\n class="sr-only peer"\n >\n <div class="w-11 h-6 bg-gray-200 rounded-full peer peer-focus:ring-4 peer-focus:ring-primary-300 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary-600"></div>\n </div>\n </label>\n `:""}\n\n ${this.formData.isBilling?`\n <label class="flex items-center justify-between cursor-pointer">\n <span class="text-sm text-gray-700">Default billing address</span>\n <div class="relative">\n <input\n type="checkbox"\n id="isDefaultBilling"\n name="isDefaultBilling"\n ${this.formData.isDefaultBilling?"checked":""}\n class="sr-only peer"\n >\n <div class="w-11 h-6 bg-gray-200 rounded-full peer peer-focus:ring-4 peer-focus:ring-primary-300 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary-600"></div>\n </div>\n </label>\n `:""}\n\n <label class="flex items-center justify-between ${this.options.isFirstAddress||this.isEdit&&this.formData.isAccount?"cursor-not-allowed":"cursor-pointer"}">\n <span class="text-sm ${this.options.isFirstAddress||this.isEdit&&this.formData.isAccount?"text-gray-500":"text-gray-700"}">\n Default address\n ${this.options.isFirstAddress?'<span class="text-xs text-gray-500 ml-2">(Required for first address)</span>':""}\n ${this.isEdit&&this.formData.isAccount?'<span class="text-xs text-gray-500 ml-2">(Set another address as default to change)</span>':""}\n </span>\n <div class="relative">\n <input\n type="checkbox"\n id="isAccount"\n name="isAccount"\n ${this.formData.isAccount?"checked":""}\n ${this.options.isFirstAddress||this.isEdit&&this.formData.isAccount?"disabled":""}\n class="sr-only peer"\n >\n <div class="w-11 h-6 ${this.options.isFirstAddress||this.isEdit&&this.formData.isAccount?"bg-gray-100":"bg-gray-200"} rounded-full peer peer-focus:ring-4 peer-focus:ring-primary-300 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary-600 ${this.options.isFirstAddress||this.isEdit&&this.formData.isAccount?"opacity-75":""}"></div>\n </div>\n </label>\n </div>\n `:""}updateProgress(){}attachEventListeners(){const e=document.getElementById("address-form");if(!e)return;r.W.attachEventHandlers(e),e.addEventListener("input",(e=>{const t=e.target;if(t.name||t.id){const n=t.name||t.id;if("checkbox"===t.type){if("isAccount"===n&&(this.options.isFirstAddress||this.isEdit&&this.formData.isAccount))return e.preventDefault(),void(t.checked=!!this.formData.isAccount);this.formData[n]=t.checked,"isAccount"===n&&t.checked&&(this.formData.isDefaultBilling=!0)}else this.formData[n]=t.value;this.errors[n]&&(delete this.errors[n],this.updateFieldError(n))}}));["firstName","lastName","street1","city","region","postalCode"].forEach((e=>{const t=document.getElementById(e);t&&t.addEventListener("blur",(()=>{this.validateField(e)}))}));const t=e.querySelector('input[name="phone"]'),n=e.querySelector('input[name="mobileNumber"]'),o=e.querySelector('input[name="otherPhone"]');t&&i.I.initialize(t),n&&i.I.initialize(n),o&&i.I.initialize(o);const a=document.getElementById("country");a&&a.addEventListener("change",(()=>{this.formData.country=a.value,this.formData.region="",this.updateRegionField();const e=a.value.toLowerCase();t&&i.I.setCountry(t,e),n&&i.I.setCountry(n,e),o&&i.I.setCountry(o,e)}));e.querySelectorAll(".address-type-btn").forEach((e=>{e.addEventListener("click",(t=>{t.preventDefault();const n=e.id.replace("type-",""),o=this.formData.isShipping,i=this.formData.isBilling;"both"===n?(this.formData.isShipping=!0,this.formData.isBilling=!0):"shipping"===n?(this.formData.isShipping=!0,this.formData.isBilling=!1,i&&!this.formData.isBilling&&(this.formData.isDefaultBilling=!1)):"billing"===n&&(this.formData.isShipping=!1,this.formData.isBilling=!0,o&&!this.formData.isShipping&&(this.formData.isDefaultShipping=!1)),this.updateAddressTypeButtons(),this.updateDefaultOptions()}))}));const s=document.getElementById("save-address-btn");s&&s.addEventListener("click",(e=>{e.preventDefault(),this.handleSave()}));const d=document.getElementById("cancel-address-btn");d&&d.addEventListener("click",(e=>{e.preventDefault(),this.handleCancel()}))}
1updateRegionField(){const e=document.querySelector("#region")?.parentElement;if(!e)return;const t=e.querySelector("label"),n=this.renderRegionField();t&&(e.innerHTML=t.outerHTML+n);const o=document.getElementById("region");o&&o.addEventListener("input",(e=>{const t=e.target;this.formData.region=t.value}))}updateAddressTypeButtons(){const e=this.getAddressType();document.querySelectorAll(".address-type-btn").forEach((t=>{const n=t,o=n.id.replace("type-","");n.className=o===e?"address-type-btn flex items-center justify-center gap-2 py-2 px-4 border rounded-md text-sm font-medium transition-all border-primary-600 bg-primary-50 text-primary-700":"address-type-btn flex items-center justify-center gap-2 py-2 px-4 border rounded-md text-sm font-medium transition-all border-gray-300 bg-white text-gray-700 hover:bg-gray-50"}))}updateDefaultOptions(){const e=document.getElementById("default-options-container");e&&this.options.showDefaults&&(e.innerHTML=this.renderDefaultOptions(),e.querySelectorAll('input[type="checkbox"]').forEach((e=>{e.addEventListener("change",(e=>{const t=e.target;if("isAccount"===t.id&&(this.options.isFirstAddress||this.isEdit&&this.formData.isAccount))return e.preventDefault(),void(t.checked=!!this.formData.isAccount);this.formData[t.id]=t.checked,"isAccount"===t.id&&t.checked&&(this.formData.isDefaultBilling=!0)}))})))}validateField(e){const t=document.getElementById(e);if(!t)return;const n="postalCode"===e?t.value.replace(/^\s+|\s+$/g,""):t.value.trim();let o=null;switch(e){case"firstName":n||(o="First name is required");break;case"lastName":n||(o="Last name is required");break;case"street1":n||(o="Street address is required");break;case"city":n||(o="City is required");break;case"region":n||(o="State/Region is required");break;case"postalCode":if(n){const e=s.A.getPostalCodeFormat(this.formData.country);if(!e.pattern.test(n)){o=`Invalid postal code format (e.g., ${e.example})`;const t=document.querySelector(".postal-code-feedback");t&&(t.innerHTML=`\n <span class="text-red-600 flex items-center">\n <svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20">\n <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />\n </svg>\n ${o}\n </span>\n `)}}else o="Postal code is required"}if(o)this.errors[e]=o;else if(delete this.errors[e],"postalCode"===e){const e=document.querySelector(".postal-code-feedback");e&&(e.innerHTML="")}this.updateFieldError(e)}updateFieldError(e){const t=document.getElementById(e);if(!t)return;if("postalCode"===e)return void(this.errors[e]?(t.classList.remove("border-gray-300","focus:border-primary-500","focus:ring-primary-500"),t.classList.add("border-red-300","focus:border-red-500","focus:ring-red-500")):(t.classList.remove("border-red-300","focus:border-red-500","focus:ring-red-500"),t.classList.add("border-gray-300","focus:border-primary-500","focus:ring-primary-500")));const n=t.parentElement?.querySelector(".text-red-600");if(n&&n.remove(),this.errors[e]){t.classList.remove("border-gray-300","focus:border-primary-500","focus:ring-primary-500"),t.classList.add("border-red-300","focus:border-red-500","focus:ring-red-500");const n=document.createElement("p");n.className="mt-1 text-sm text-red-600",n.textContent=this.errors[e],t.parentElement?.appendChild(n)}else t.classList.remove("border-red-300","focus:border-red-500","focus:ring-red-500"),t.classList.add("border-gray-300","focus:border-primary-500","focus:ring-primary-500")}async handleSave(){const e=document.querySelector('input[name="phone"]'),t=document.querySelector('input[name="mobileNumber"]'),n=document.querySelector('input[name="otherPhone"]'),o=document.querySelector('input[name="smsAgreementOptIn"]');e&&(this.formData.phone=i.I.getNumber(e)),t&&(this.formData.mobileNumber=i.I.getNumber(t)),n&&(this.formData.otherPhone=i.I.getNumber(n)),o&&(this.formData.smsAgreementOptIn=o.checked);const s=this.validateForm();if(!s.isValid){this.errors=s.errors,Object.keys(this.errors).forEac
1h((e=>{"addressType"!==e&&this.updateFieldError(e)}));Object.keys(this.errors).length>1?this.showError("Please correct the errors below and try again."):this.errors.addressType&&this.showError(this.errors.addressType);const e=Object.keys(this.errors).find((e=>"addressType"!==e));if(e){const t=document.getElementById(e);t&&(t.focus(),t.scrollIntoView({behavior:"smooth",block:"center"}))}return}const r=a.A.setSubmitting("save-address-btn","Saving");try{this.options.onSave&&await this.options.onSave(this.formData),this.options.inline||this.close()}catch(e){console.error("Failed to save address:",e),r?.restore();const t=e instanceof Error?e.message:"Failed to save address";this.showError(t)}}handleCancel(){this.options.onCancel&&this.options.onCancel(),this.options.inline||this.close()}validateForm(){const e={};if([{field:"firstName",message:"First name is required"},{field:"lastName",message:"Last name is required"},{field:"street1",message:"Street address is required"},{field:"city",message:"City is required"},{field:"region",message:"State/Region is required"},{field:"postalCode",message:"Postal code is required"}].forEach((({field:t,message:n})=>{const o=this.formData[t];o?.trim()||(e[t]=n)})),this.formData.postalCode){const t=this.formData.postalCode.replace(/^\s+|\s+$/g,""),n=s.A.getPostalCodeFormat(this.formData.country);n.pattern.test(t)||(e.postalCode=`Invalid postal code format (e.g., ${n.example})`)}if(this.formData.isShipping||this.formData.isBilling||(e.addressType="Please select at least one address type",setTimeout((()=>{const e=document.getElementById("type-both");e&&(e.focus(),e.scrollIntoView({behavior:"smooth",block:"center"}))}),100)),this.options.validator){const t=this.options.validator(this.formData);Object.assign(e,t)}return{isValid:0===Object.keys(e).length,errors:e}}showError(e){const t=document.getElementById("address-form");if(!t)return;const n=t.querySelector(".bg-red-50");n&&n.remove();const o=document.createElement("div");o.className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg mb-4 flex items-start",o.innerHTML=`\n <svg class="w-5 h-5 mr-2 flex-shrink-0 mt-0.5" fill="currentColor" viewBox="0 0 20 20">\n <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />\n </svg>
1\n <span>${e}</span>\n `,t.insertBefore(o,t.firstChild),setTimeout((()=>{o.remove()}),5e3)}close(){const e=document.querySelector('input[name="phone"]');e&&i.I.destroy(e);const t=document.querySelector('input[name="mobileNumber"]');t&&i.I.destroy(t);const n=document.querySelector('input[name="otherPhone"]');n&&i.I.destroy(n),this.options.inline&&this.inlineContainer?(this.inlineContainer.innerHTML="",this.inlineContainer=null):this.modal&&this.modal.close()}escapeHtml(e){const t=document.createElement("div");return t.textContent=e||"",t.innerHTML}defaultValidator(e){return{}}}},6730:function(e,t,n){"use strict";n.d(t,{$:function(){return l}});class o{constructor(){this.cleanupTasks=new Set,this.eventListeners=[],this.timers=new Set,this.observers=new Set,this.abortControllers=new Set,this.isDestroyed=!1}addCleanupTask(e){return this.isDestroyed?(console.warn("CleanupManager: Trying to add task after destroy"),()=>{}):(this.cleanupTasks.add(e),()=>this.cleanupTasks.delete(e))}addEventListener(e,t,n,o={}){if(this.isDestroyed||!e)return()=>{};const i=e=>{this.isDestroyed||n(e)};e.addEventListener(t,i,o);const a={target:e,event:t,handler:i,options:o};return this.eventListeners.push(a),()=>this.removeEventListener(a)}removeEventListener(e){const t=this.eventListeners.indexOf(e);t>-1&&(this.eventListeners.splice(t,1),e.target.removeEventListener(e.event,e.handler,e.options))}setTimeout(e,t){if(this.isDestroyed)return 0;const n=window.setTimeout((()=>{this.timers.delete(n),this.isDestroyed||e()}),t);return this.timers.add(n),n}setInterval(e,t){if(this.isDestroyed)return 0;const n=window.setInterval((()=>{this.isDestroyed?this.clearInterval(n):e()}),t);return this.timers.add(n),n}clearTimeout(e){e&&this.timers.has(e)&&(clearTimeout(e),this.timers.delete(e))}clearInterval(e){e&&this.timers.has(e)&&(clearInterval(e),this.timers.delete(e))}observeMutations(e,t,n){if(this.isDestroyed||!t)return null;const o=new MutationObserver(((...t)=>{this.isDestroyed||e(...t)}));return o.observe(t,n),this.observers.add(o),o}observeIntersection(e,t){if(this.isDestroyed)return null;const n=new IntersectionObserver(((...t)=>{this.isDestroyed||e(...t)}),t);return this.observers.add(n),n}observeResize(e){if(this.isDestroyed||"undefined"==typeof ResizeObserver)return null;const t=new ResizeObserver(((...t)=>{this.isDestroyed||e(...t)}));return this.observers.add(t),t}createAbortController(){if(this.isDestroyed)return null;const e=new AbortController;return this.abortControllers.add(e),e}requestAnimationFrame(e){if(this.isDestroyed)return 0;let t;return t=requestAnimationFrame((()=>{this.timers.delete(t),this.isDestroyed||e(performance.now())})),this.timers.add(t),t}addDelegatedListener(e,t,n,o=document){return this.addEventListener(o,t,(t=>{const i=t.target?.closest(e);i&&o.contains&&o.contains(i)&&n.call(i,t,i)}))}cleanup(){this.isDestroyed||(this.isDestroyed=!0,this.eventListeners.forEach((e=>{e.target.removeEventListener(e.event,e.handler,e.options)})),this.eventListeners=[],this.timers.forEach((e=>{clearTimeout(e),clearInterval(e),"undefined"!=typeof cancelAnimationFrame&&cancelAnimationFrame(e)})),this.timers.clear(),this.observers.forEach((e=>{e.disconnect()})),this.observers.clear(),this.abortControllers.forEach((e=>{e.signal.aborted||e.abort()})),this.abortControllers.clear(),this.cleanupTasks.forEach((e=>{try{e()}catch(e){console.error("Error in cleanup task:",e)}})),this.cleanupTasks.clear())}destroy(){this.cleanup()}get destroyed(){return this.isDestroyed}}var i=o,a=n(9088);class s{static setText(e,t){e&&(e.textContent=t)}static setHTML(e,t,n={}){if(!e)return;if(!/<[^>]*>/.test(t))return void(e.textContent=t);const o=this.sanitizeHTML(t,n);e.innerHTML=o}static sanitizeHTML(e,t={}){const{allowedTags:n=["b","i","em","strong","a","p","br","span","div","ul","ol","li"],allowedAttributes:o={a:["href","title","target"],span:["class"],div:["class","id"]},allowedProtocols:i=["http:","https:","mailto:"]}=t,a=document.createElement("div");return a.innerHTML=e,this.cleanNode(a,n,o,i),a.innerHTML}
1static cleanNode(e,t,n,o){Array.from(e.childNodes).forEach((i=>{if(i.nodeType===Node.ELEMENT_NODE){const a=i,s=a.tagName.toLowerCase();if(!t.includes(s)){for(;a.firstChild;)e.insertBefore(a.firstChild,a);return void e.removeChild(a)}Array.from(a.attributes).forEach((e=>{const t=e.name.toLowerCase();if((n[s]||[]).includes(t)){if("href"===t||"src"===t){const t=e.value.trim(),n=o.some((e=>t.toLowerCase().startsWith(e)));(t.toLowerCase().startsWith("javascript:")||t.toLowerCase().startsWith("data:")||!n&&t.includes(":"))&&a.removeAttribute(e.name)}t.startsWith("on")&&a.removeAttribute(e.name)}else a.removeAttribute(e.name)})),this.cleanNode(a,t,n,o)}}))}static createElement(e,t={}){const n=document.createElement(e);return t.attributes&&Object.entries(t.attributes).forEach((([e,t])=>{e.toLowerCase().startsWith("on")||n.setAttribute(e,t)})),t.text?this.setText(n,t.text):t.html&&this.setHTML(n,t.html,t.sanitizeOptions),t.className&&(n.className=t.className),t.children&&t.children.forEach((e=>{"string"==typeof e?n.appendChild(document.createTextNode(e)):n.appendChild(e)})),n}static query(e,t=document){try{return t.querySelector(e)}catch(t){return console.error("Invalid selector:",e),null}}static queryAll(e,t=document){try{return Array.from(t.querySelectorAll(e))}catch(t){return console.error("Invalid selector:",e),[]}}static escapeHTML(e){const t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(e).replace(/[&<>"'/]/g,(e=>t[e]))}static createTextNode(e){return document.createTextNode(e)}static setAttributes(e,t){e&&Object.entries(t).forEach((([t,n])=>{t.toLowerCase().startsWith("on")||"srcdoc"===t.toLowerCase()||"srcset"===t.toLowerCase()||("href"!==t&&"src"!==t||!n.toLowerCase().startsWith("javascript:")&&!n.toLowerCase().startsWith("data:"))&&e.setAttribute(t,n)}))}}var r=s;"undefined"!=typeof window&&(window.HeimGuard=window.HeimGuard||{},window.HeimGuard.SafeDOM=s);var d=n(7450);class l{constructor(e,t={}){if(this.isInitialized=!1,this.isRendered=!1,this.isDestroyed=!1,!(e&&e instanceof HTMLElement))throw new Error("Valid container element required");this.container=e,this.options={...this.getDefaultOptions(),...t},this.cleanup=new i,this.store=new a.A(this.getInitialState(),{enableLogging:this.options.debug||!1}),this.componentId=this.generateId(),this.setupErrorBoundary(),this.options.autoInit&&this.init().catch((e=>{this.handleError("Initialization failed",e)}))}getDefaultOptions(){return{autoInit:!0,debug:!1,errorHandler:null}}getInitialState(){return{isLoading:!1,error:null,data:null}}
1async init(){if(!this.isInitialized&&!this.isDestroyed)try{this.emit("beforeInit"),this.setupStateSubscriptions(),await this.onInit(),this.isInitialized=!0,this.emit("afterInit"),this.isVisible()?await this.render():this.setupVisibilityObserver()}catch(e){throw this.handleError("Failed to initialize component",e),e}}async render(){if(this.isInitialized&&!this.isDestroyed)try{this.emit("beforeRender"),this.setState({isLoading:!0});const e=await this.fetchData();void 0!==e?this.setState({data:e,isLoading:!1,error:null}):this.setState({isLoading:!1}),this.renderContent(),this.attachEventListeners(),this.isRendered=!0,this.emit("afterRender")}catch(e){this.setState({isLoading:!1,error:e}),this.handleError("Failed to render component",e)}}renderContent(){const e=this.store.getState();e.isLoading?this.renderLoading():e.error?this.renderError(e.error):this.renderMain()}renderLoading(){r.setHTML(this.container,'\n <div class="component-loading">\n <div class="spinner"></div>\n <p>Loading...</p>\n </div>\n ')}renderError(e){r.setHTML(this.container,`\n <div class="component-error">\n <div class="error-icon">â ï¸</div>\n <h3>Something went wrong</h3>\n <p>${r.escapeHTML(e.message||"An unexpected error occurred")}</p>\n <button class="retry-button">Try Again</button>\n </div>\n `);const t=this.container.querySelector(".retry-button");t&&this.cleanup.addEventListener(t,"click",(()=>this.render()))}renderMain(){r.setText(this.container,"Component content")}async onInit(){}async fetchData(){}attachEventListeners(){}onStateChange(e,t,n){}onDestroy(){}setState(e){this.store.setState(e)}getState(e){return this.store.getState(e)}subscribe(e,t){return this.store.subscribe(e,t)}setupStateSubscriptions(){this.cleanup.addCleanupTask(this.store.subscribe(((e,t,n)=>{this.isRendered&&n.length>0&&this.renderContent(),t&&this.onStateChange(e,t,n)})))}addEventListener(e,t,n,o){return this.cleanup.addEventListener(e,t,n,o)}addDelegatedListener(e,t,n){return this.cleanup.addDelegatedListener(e,t,n,this.container)}setTimeout(e,t){return this.cleanup.setTimeout(e,t)}setInterval(e,t){return this.cleanup.setInterval(e,t)}$(e){return r.query(e,this.container)}$$(e){return r.queryAll(e,this.container)}isVisible(){return null!==this.container.offsetParent}setupVisibilityObserver(){const e=this.cleanup.observeIntersection((t=>{t[0].isIntersecting&&!this.isRendered&&(this.render(),e?.disconnect())}),{threshold:.1});e&&e.observe(this.container)}setupErrorBoundary(){Object.getOwnPropertyNames(Object.getPrototypeOf(this)).forEach((e=>{if("constructor"===e||"handleError"===e)return;const t=this[e];"function"==typeof t&&(this[e]=(...n)=>{try{const o=t.apply(this,n);return o instanceof Promise?o.catch((t=>{throw this.handleError(`Error in ${e}`,t),t})):o}catch(t){throw this.handleError(`Error in ${e}`,t),t}})}))}handleError(e,t){console.error(`[${this.constructor.name}] ${e}:`,t),this.options.errorHandler?this.options.errorHandler(t,{component:this,message:e}):d.Ay.log(this.constructor.name,t,{componentId:this.componentId,message:e}),this.emit("error",{message:e,error:t})}emit(e,t={}){const n=new CustomEvent(`component:${e}`,{detail:{component:this,componentId:this.componentId,...t},bubbles:!0});this.container.dispatchEvent(n)}async refresh(){this.isInitialized&&!this.isDestroyed&&await this.render()}async reset(){this.store.reset(),await this.render()}destroy(){if(!this.isDestroyed)try{this.emit("beforeDestroy"),this.onDestroy(),this.cleanup.destroy(),this.container.innerHTML="",this.isDestroyed=!0,this.isInitialized=!1,this.isRendered=!1,this.emit("afterDestroy")}catch(e){console.error("Error during component destroy:",e)}}generateId(){return`${this.constructor.name}-${Date.now()}-${Math.random().toString(36).substr(2,9)}`}debounce(e,t){let n;return(...o)=>{this.cleanup.clearTimeout(n),n=this.cleanup.setTimeout((()=>e.apply(this,o)),t)}}throttle(e,t){let n;return(...o)=>{n||(e.apply(this,o),n=!0,this.cleanup.setTimeout((()=>n=!1),t))}}}},7876:function(e,t,n){"use strict";n.d(t,{A:function(){return s}});var o=n(6730),i=n(2404),a=n(7310);class s extends o.${constructor(e,t={}){super(e,t)}getDefaultOptions(){return{autoInit:!0,debug:!1}}getInitialState(){return{isLoading:!0,error:null,data:null,profileData:this.options.profileData}}async onInit(){this.store.subscribe(((e,t,n)=>{!n.includes("data")||e.isLoading||e.error||this.updateContent()}))}renderShell({icon:e,title:t,subtitle:n,actions:o=""}){this.headerConfig={icon:e,title:t,subtitle:n,actions:o};const a="function"==typeof o?o():o;this.container.innerHTML=`\n <div class="${this.getComponentClassName()}-container">\n <div class="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden">\n ${i.b.render({icon:e,title:t,subtitle:n,actions:a})}\n\n \x3c!-- Content Area --\x3e\n <div class="${this.getComponentClassName()}-content-area">\n \x3c!-- Content will be inserted here --\x3e\n </div>\n </div>\n </div>\n `}updateContentArea(e){const t=this.container.querySelector(`.${this.getComponentClassName()}-content-area`);t&&(t.style.opacity="0.5",t.style.transition="opacity 0.2s ease-out",this.setTimeout((()=>
1{t.innerHTML=e,t.style.opacity="1",this.emit(`${this.getComponentName()}:content-updated`),this.setTimeout((()=>{t.style.transition=""}),200)}),100))}updateHeaderActions(e){const t="function"==typeof e?e():e,n=this.container.querySelector(".heimguard-component-header");if(n){const e=n.querySelector(".heimguard-header-actions");e&&(e.innerHTML=t)}}renderLoadingState(e="Loading..."){return`\n <div class="p-6">\n <div class="text-center mb-4">\n <div class="inline-flex items-center px-4 py-2 bg-blue-50 text-blue-700 rounded-full text-sm font-medium">\n <svg class="animate-spin h-4 w-4 mr-2" fill="none" viewBox="0 0 24 24">\n <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>\n <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>\n </svg>\n ${e}\n </div>\n </div>\n \n \x3c!-- Skeleton loader --\x3e\n <div class="animate-pulse space-y-4">\n ${this.renderSkeletonRows(5)}\n </div>\n </div>\n `}renderSkeletonRows(e=3){return Array(e).fill(0).map((()=>'\n <div class="border border-gray-200 rounded-lg p-4">\n <div class="flex items-center space-x-4">\n <div class="h-12 w-12 bg-gray-200 rounded"></div>\n <div class="flex-1 space-y-2">\n <div class="h-4 bg-gray-200 rounded w-3/4"></div>\n <div class="h-3 bg-gray-100 rounded w-1/2"></div>\n </div>\n <div class="h-8 w-20 bg-gray-200 rounded"></div>\n </div>\n </div>\n ')).join("")}renderErrorState({title:e="Failed to load data",message:t="An error occurred",retryButton:n=!0,retryText:o="Try Again"}={}){return`\n <div class="p-6">\n <div class="text-center py-16">\n <div class="mx-auto w-24 h-24 bg-red-100 rounded-full flex items-center justify-center mb-6">\n <svg class="w-12 h-12 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n </div>\n <h3 class="text-lg font-semibold text-gray-900 mb-2">${e}</h3>\n <p class="text-gray-600 mb-6 max-w-md mx-auto">${t}</p>\n ${n?`\n <button class="${this.getComponentClassName()}-retry inline-flex items-center px-6 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors font-medium">\n <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />\n </svg>\n ${o}\n </button>\n `:""}\n </div>\n </div>\n `}showDollarIcon(){return"Cabot Wealth"!==a.default.getCompanyName()}renderEmptyState({icon:e='<svg class="w-16 h-16 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4" />\n </svg>',title:t="No data found",message:n="",action:o=null}={}){return`\n <div class="p-6">\n <div class="text-center py-16">\n ${this.showDollarIcon()?`\n <div class="mx-auto w-32 h-32 bg-gray-100 rounded-full flex items-center justify-center mb-6">\n ${e}\n </div>\n `:""}\n <h3 class="text-xl font-semibold text-gray-900 mb-3">${t}</h3>\n ${n?`<p class="text-gray-600 mb-8 max-w-md mx-auto">${n}</p>`:""}\n ${o?`\n <div class="flex flex-col sm:flex-row gap-3 justify-center">\n ${o}\n </div>\n `:""}\n </div>\n </div>\n `}renderMain(){this.container.querySelector(".heimguard-component-header")||this.renderShell(this.getHeaderConfig()),this.updateContent()}
1renderLoading(){this.container.querySelector(".heimguard-component-header")||this.renderShell(this.getHeaderConfig()),this.updateContentArea(this.renderLoadingState(this.getLoadingMessage()))}async fetchData(){try{return await this.loadData()}catch(e){throw console.error(`Failed to load ${this.getComponentName()}:`,e),e}}renderError(e){this.container.querySelector(".heimguard-component-header")||this.renderShell(this.getHeaderConfig()),this.updateContentArea(this.renderErrorState({title:`Failed to load ${this.getComponentName()}`,message:e.message||"An error occurred"})),this.addDelegatedListener(`.${this.getComponentClassName()}-retry`,"click",(()=>this.render()))}updateContent(){const e=this.getState();if(e.isLoading)this.updateContentArea(this.renderLoadingState(this.getLoadingMessage()));else if(e.error)this.updateContentArea(this.renderErrorState({title:`Failed to load ${this.getComponentName()}`,message:e.error.message||"An error occurred"}));else if(this.isEmptyState(e.data))this.updateContentArea(this.renderEmptyState(this.getEmptyStateConfig()));else{const e=this.renderMainContent();this.updateContentArea(e),this.setTimeout((()=>{this.attachEventListeners()}),150)}}getComponentClassName(){return"profile-component"}getComponentName(){return"data"}getLoadingMessage(){return`Loading ${this.getComponentName()}...`}isEmptyState(e){return!e||Array.isArray(e)&&0===e.length}getEmptyStateConfig(){return{}}shouldUpdateHeaderActions(){return!1}}},4436:function(e,t,n){"use strict";n.d(t,{W:function(){return a}});var o=n(7310),i=n(8380);class a{static renderCountryField({name:e="country",label:t="Country",value:n="",required:a=!1,className:s="",onChange:r=""}){const d=o.default.getExcludedCountries();return`\n <div class="address-field-country ${s}">\n <label for="${e}" class="block text-sm font-medium text-gray-700 mb-1">\n ${t}${a?' <span class="text-red-500">*</span>':""}\n </label>\n <select\n id="${e}"\n name="${e}"\n class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-primary-500 focus:border-primary-500 text-sm"\n ${a?"required":""}\n ${r?`onchange="${r}"`:""}\n >\n <option value="">Select a country</option>\n ${i.A.getAllCountries(d).map((e=>`\n <option value="${e.code}" ${n===e.code?"selected":""}>\n ${e.name}\n </option>\n `)).join("")}\n </select>\n </div>\n `}static renderStateField({name:e="state",label:t="State/Province",value:n="",countryCode:o="",required:a=!1,className:s=""}){const r=o?i.A.getStatesByCountry(o):[];return r.length>0?`\n <div class="address-field-state ${s}">\n <label for="${e}" class="block text-sm font-medium text-gray-700 mb-1">\n ${t}${a?' <span class="text-red-500">*</span>':""}\n </label>\n <select\n id="${e}"\n name="${e}"\n class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-primary-500 focus:border-primary-500 text-sm"\n ${a?"required":""}\n ${o?"":"disabled"}\n >\n <option value="">Select a state</option>\n ${r.map((e=>`\n <option value="${e.code}" ${n===e.code?"selected":""}>\n ${e.name}\n </option>\n `)).join("")}\n </select>\n </div>\n `:`\n <div class="address-field-state ${s}">\n <label for="${e}" class="block text-sm font-medium text-gray-700 mb-1">\n ${t}${a?' <span class="text-red-500">*</span>':""}\n </label>\n <input\n type="text"\n id="${e}"\n name="${e}"\n value="${n}"\n class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-primary-500 focus:border-primary-500 text-sm"\n placeholder="Enter state/province"\n ${a?"required":""}\n />\n </div>\n `}static renderPostalCodeField({name:e="postalCode",label:t="Postal Code",value:n="",countryCode:a="",required:s=!1,className:r="",onBlur:d=""}){const l=i.A.getPostalCodeFormat(a);return`\n <div class="address-field-postal ${r}">\n <label for="${e}" class="block text-sm font-medium text-gray-700 mb-1">\n ${t}${s?' <span class="text-red-500">*</span>':""}\n </label>\n <input\n type="text"\n id="${e}"\n name="${e}"\n value="${n}"\n class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-primary-500 focus:border-primary-500 text-sm"\n ${o.default.isCabotWealth()?"":`placeholder="${l.example}"`}\n maxlength="${l.maxLength}"\n ${s?"required":""}
1\n ${d?`onblur="${d}"`:""}\n data-country="${a}"\n />\n <div class="postal-code-feedback mt-1 text-sm"></div>\n </div>\n `}static attachEventHandlers(e){const t=e.querySelector('[name="country"]'),n=e.querySelector(".address-field-state"),o=e.querySelector('[name="postalCode"]');t&&t.addEventListener("change",(t=>{const a=t.target.value;if(n){const t=e.querySelector('[name="state"]')?.value||"";n.innerHTML=this.renderStateField({name:"state",label:"State/Province",value:t,countryCode:a,required:null!==n.querySelector("[required]")})}if(o){const e=i.A.getPostalCodeFormat(a);o.placeholder=e.example,o.maxLength=e.maxLength,o.dataset.country=a}})),o&&(o.addEventListener("input",(e=>{const t=e.target,n=t.dataset.country;n&&(t.value=i.A.formatPostalCode(n,t.value))})),o.addEventListener("blur",(async t=>{const n=t.target,o=n.dataset.country||"CA",a=n.value,s=e.querySelector(".postal-code-feedback");if(!a)return void(s&&(s.innerHTML=""));s&&(s.innerHTML='<span class="text-gray-500">Validating...</span>');const r=await i.A.validatePostalCode(o,a);if(s)if(r.valid){const e=r.places?.[0];let t="Valid postal code";e?t=`Valid - ${e.name}, ${e.state}`:r.validatedByFormat&&(t="Format looks correct"),s.innerHTML=`\n <span class="text-green-600 flex items-center">\n <svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20">\n <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />\n </svg>\n ${t}\n </span>\n `}else s.innerHTML=`\n <span class="text-red-600 flex items-center">\n <svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20">\n <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />\n </svg>\n ${r.error||"Invalid postal code"}\n </span>\n `})))}static renderAddressForm({values:e={},required:t=!1,className:n=""}){return`\n <div class="address-form ${n}">\n <div class="grid grid-cols-1 md:grid-cols-2 gap-4">\n <div class="md:col-span-2">\n <input\n type="text"\n name="street1"\n placeholder="Street Address"\n value="${e.street1||""}"\n class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500"\n ${t?"required":""}\n />\n </div>\n\n <div class="md:col-span-2">\n <input\n type="text"\n name="street2"\n placeholder="Apartment, suite, etc. (optional)"\n value="${e.street2||""}"\n class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500"\n />\n </div>\n\n <div>\n <input\n type="text"\n name="city"\n placeholder="City"\n value="${e.city||""}"\n class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500"\n ${t?"required":""}\n />\n </div>\n\n ${this.renderStateField({name:"state",label:"",value:e.state||e.region||"",countryCode:e.country||o.default.getDefaultCountry()||"US",required:t})}\n\n ${this.renderPostalCodeField({name:"postalCode",label:"",value:e.postalCode||"",countryCode:e.country||o.default.getDefaultCountry()||"US",required:t})}\n\n ${this.renderCountryField({name:"country",label:"",value:e.country||o.default.getDefaultCountry()||"US",required:t})}\n </div>\n </div>\n `}}},7147:function(e,t,n){"use strict";n.d(t,{z:function(){return o}});class o{static render({id:e,name:t,label:n,type:o="text",value:i="",placeholder:a="",required:s=!1,disabled:r=!1,readonly:d=!1,error:l="",hint:c="",helperText:u="",icon:m=null,className:g="",inputClassName:h="",labelClassName:p="",containerClassName:y="",...C}){const f=e||`field-${t}`,v=!!l,b={id:f,name:t,type:o,value:i,placeholder:a,required:s,disabled:r,readonly:d,"aria-invalid":v,"aria-describedby":v?`${f}-error`:c?`${f}-hint`:void 0,...C},w=Object.entries(b).filter((([e,t])=>!1!==t&&void 0!==t&&""!==t)).map((([e,t])=>!0===t?e:`${e}="${this.escapeAttr(String(t))}"`)).join(" "),S="optional"===c?.toLowerCase()||"optional"===u?.toLowerCase(),x=S&&!s,A=S?"":c||u;return`\n <div class="form-field ${y}">\n ${n?this.renderLabel(f,n,s,p,x):""}\n <div class="mt-1">\n ${m?`\n <div class="relative flex rounded-lg shadow-sm border ${v?"border-red-500":"border-gray-300"} focus-within:ring-2 focus-within:ring-primary-500 focus-within:ring-opacity-20 focu
1s-within:border-primary-500 transition-all duration-200">\n <span class="inline-flex items-center pl-3 pr-2 text-gray-400">\n ${m}\n </span>\n <input \n ${w}\n class="${this.getInputClasses(v,h,!0)}"\n />\n </div>\n `:`\n <input \n ${w}\n class="${this.getInputClasses(v,h)}"\n />\n `}\n ${A?this.renderHint(f,A):""}\n ${l?this.renderError(f,l):""}\n </div>\n </div>\n `}static renderLabel(e,t,n,o="",i=!1){return`\n <label for="${e}" class="block text-sm font-medium text-gray-700 ${o}">\n ${this.escapeHtml(t)}\n ${n?'<span class="text-red-500 ml-1">*</span>':""}\n ${!n&&i?'<span class="text-gray-400 font-normal ml-1">(optional)</span>':""}\n </label>\n `}static renderHint(e,t){return`\n <p id="${e}-hint" class="mt-1 text-sm text-gray-500">\n ${this.escapeHtml(t)}\n </p>\n `}static renderError(e,t){return`\n <p id="${e}-error" class="mt-1 text-sm text-red-600" role="alert">\n ${this.escapeHtml(t)}\n </p>\n `}static getInputClasses(e,t="",n=!1){return`${n?"flex-1 min-w-0 border-0 bg-transparent pl-1 pr-3 py-2 text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-0 sm:text-sm":"block w-full rounded-md shadow-sm sm:text-sm"} ${n?"":e?"border-red-300 text-red-900 placeholder-red-300 focus:border-red-500 focus:ring-red-500":"border-gray-300 focus:border-primary-500 focus:ring-primary-500"} ${t}`.trim()}static escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}static escapeAttr(e){return String(e).replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}static validate(e,t={}){const n=[],o=String(e||"");if(t.required&&!e&&n.push("This field is required"),t.minLength&&o.length<t.minLength&&n.push(`Must be at least ${t.minLength} characters`),t.maxLength&&o.length>t.maxLength&&n.push(`Must be no more than ${t.maxLength} characters`),t.pattern&&e&&!t.pattern.test(o)&&n.push(t.patternMessage||"Invalid format"),t.custom){const o=t.custom(e);o&&n.push(o)}return n}static getValue(e){if(!e)return"";if("checkbox"===e.type)return e.checked;if("radio"===e.type){const t=e.form;if(!t)return"";const n=t.querySelector(`input[name="${e.name}"]:checked`);return n?n.value:""}return e.value}static setValue(e,t){if(e)if("checkbox"===e.type)e.checked=!!t;else if("radio"===e.type){const n=e.form;if(!n)return;const o=n.querySelector(`input[name="${e.name}"][value="${t}"]`);o&&(o.checked=!0)}else e.value=String(t||"")}static clearError(e){if(!e)return;const t=e.closest(".form-field");if(!t)return;const n=t.querySelector('[role="alert"]');n&&n.remove(),e.classList.remove("border-red-300","text-red-900","placeholder-red-300","focus:border-red-500","focus:ring-red-500"),e.classList.add("border-gray-300","focus:border-primary-500","focus:ring-primary-500"),e.removeAttribute("aria-invalid"),e.removeAttribute("aria-describedby")}static showError(e,t){if(!e)return;if(!e.closest(".form-field"))return;this.clearError(e),e.classList.remove("border-gray-300","focus:border-primary-500","focus:ring-primary-500"),e.classList.add("border-red-300","text-red-900","placeholder-red-300","focus:border-red-500","focus:ring-red-500"),e.setAttribute("aria-invalid","true");const n=`${e.id}-error`,o=this.renderError(n,t),i=e.parentElement;i&&(i.insertAdjacentHTML("beforeend",o),e.setAttribute("aria-describedby",n))}static hasError(e){return"true"===e?.getAttribute("aria-invalid")}static getError(e){if(!e)return null;const t=e.getAttribute("aria-describedby");if(!t)return null;const n=document.getElementById(t);return n?.textContent||null}static focus(e){e&&e.focus()}static blur(e){e&&e.blur()}static enable(e){e&&(e.disabled=!1,e.removeAttribute("disabled"))}static disable(e){e&&(e.disabled=!0,e.setAttribute("disabled","true"))}static isDisabled(e){return e?.disabled||!1}static isRequired(e){return e?.required||!1}static setRequired(e,t){e&&(e.required=t,t?e.setAttribute("required","true"):e.removeAttribute("required"))}}},6894:function(e,t,n){"use strict";n.d(t,{I:function(){return i}});var o=n(7147);class i extends o.z{static async loadAssets(){return this.loadPromise||(this.loadPromise=(async()=>
1{if(!this.cssLoaded){const e=document.createElement("link");e.rel="stylesheet",e.href="https://cdn.jsdelivr.net/npm/[email protected]/build/css/intlTelInput.css",document.head.appendChild(e),this.cssLoaded=!0}this.jsLoaded||window.intlTelInput||await new Promise(((e,t)=>{const n=document.createElement("script");n.src="https://cdn.jsdelivr.net/npm/[email protected]/build/js/intlTelInput.min.js",n.async=!0,n.onload=()=>{this.jsLoaded=!0,e()},n.onerror=()=>t(new Error("Failed to load intl-tel-input")),document.head.appendChild(n)}))})()),this.loadPromise}static render(e){const{defaultCountry:t="ca",preferredCountries:n=["ca","us"],separateDialCode:o=!0,nationalMode:i=!1,autoHideDialCode:a=!0,autoPlaceholder:s="aggressive",utilsScript:r="https://cdn.jsdelivr.net/npm/[email protected]/build/js/utils.js",placeholder:d,...l}=e,c=l.className||"",u=`${l.inputClassName||""} intl-phone-field`.trim(),m={"data-default-country":t,"data-preferred-countries":JSON.stringify(n),"data-separate-dial-code":o,"data-national-mode":i,"data-auto-hide-dial-code":a,"data-auto-placeholder":s,"data-utils-script":r};return e.onlyCountries&&(m["data-only-countries"]=JSON.stringify(e.onlyCountries)),e.excludeCountries&&(m["data-exclude-countries"]=JSON.stringify(e.excludeCountries)),super.render({type:"tel",autocomplete:"tel",...l,className:c,inputClassName:u,...m,placeholder:void 0})}static async initialize(e){if(!e||this.instances.has(e))return this.instances.get(e)||null;try{await this.loadAssets(),e.hasAttribute("placeholder")&&e.removeAttribute("placeholder");const t={initialCountry:e.dataset.defaultCountry||"ca",preferredCountries:JSON.parse(e.dataset.preferredCountries||'["ca", "us"]'),separateDialCode:"true"===e.dataset.separateDialCode,nationalMode:"true"===e.dataset.nationalMode,autoHideDialCode:"true"===e.dataset.autoHideDialCode,autoPlaceholder:e.dataset.autoPlaceholder||"aggressive",utilsScript:e.dataset.utilsScript||"https://cdn.jsdelivr.net/npm/[email protected]/build/js/utils.js",formatOnDisplay:!0,placeholderNumberType:"MOBILE",dropdownContainer:document.body,showFlags:!0,countrySearch:!0,i18n:{searchPlaceholder:"Search countries..."}};e.dataset.onlyCountries&&(t.onlyCountries=JSON.parse(e.dataset.onlyCountries)),e.dataset.excludeCountries&&(t.excludeCountries=JSON.parse(e.dataset.excludeCountries));const n=window.intlTelInput(e,t);this.instances.set(e,n);const o=e.closest(".iti");o&&o.classList.add("w-full");const i=()=>{n.getNumber();const t=n.isValidNumber(),o=n.getValidationError();if(e.value){if(e.value.length>1&&t)e.classList.remove("!border-red-300","focus:!border-red-500","focus:!ring-red-500"),e.classList.add("!border-green-300","focus:!border-green-500","focus:!ring-green-500"),this.clearValidationMessage(e);else if(e.value.length>0){e.classList.remove("!border-green-300","focus:!border-green-500","focus:!ring-green-500"),e.classList.add("!border-red-300","focus:!border-red-500","focus:!ring-red-500");const t=0===o?"Please enter a valid phone number":this.getErrorMessage(o);this.showValidationMessage(e,t)}}else e.classList.remove("!border-red-300","focus:!border-red-500","focus:!ring-red-500","!border-green-300","focus:!border-green-500","focus:!ring-green-500"),this.clearValidationMessage(e)};e.addEventListener("blur",i),e.addEventListener("input",(()=>{clearTimeout(e._validationTimeout),e._validationTimeout=setTimeout(i,500)}));const a=e.closest("form");if(a){const t=t=>{if(!n.isValidNumber()&&e.value)return t.preventDefault(),i(),e.focus(),!1;const o=n.getNumber();o&&(e.value=o)};a.addEventListener("submit",t),e.dataset.itiSubmitHandler="true"}return n}catch(e){return console.error("Failed to initialize intl-tel-input:",e),null}}static destroy(e){const t=this.instances.get(e);t&&(t.destroy(),this.instances.delete(e))}static getNumber(e){const t=this.instances.get(e);return t?t.getNumber():e.value}static isValid(e){const t=this.instances.get(e);if(!t)return!1;const n=t.isValidNumber();if(!n&&e.value){const n=t.getValidationError(),o=this.getErrorMessage(n);this.showValidationMessage(e,o),e.classList.add("!border-red-300","focus:!border-red-500","focus:!ring-red-500")}return n}static setNumber(e,t){const n=this.instances.get(e);n?n.setNumber(t):e.value=t}static setCountry(e,t){const n=this.instances.get(e);n&&n.setCountry(t)}static validate(e,t={}){const n=super.validate(e,t);if(e&&!1!==t.required){const t=String(e).replace(/\s+/g,"").replace(/[^\d+]/g,"");(t.length<7||t.length>15)&&n.push("Please enter a valid phone number")}return n}static async autoInitialize(){const e=document.querySelectorAll("input.intl-phone-field"),t=Array.from(e).map((e=>this.initialize(e)));await Promise.all(t)}static getErrorMessage(e){return{1:"Please enter a valid country code",2:"Phone number is too short",3:"Phone number is too long",4:"Please enter a valid phone number",5:"Please enter a valid phone number"}[e]||"Please enter a valid phone number"}static showValidationMessage(e,t){this.clearValidationMessage(e);const n=document.createElement("div");n.className="iti-error-msg text-sm text-red-600 mt-1",n.textContent=t;
1const o=e.closest(".iti");o&&o.parentNode&&o.parentNode.insertBefore(n,o.nextSibling)}static clearValidationMessage(e){const t=e.closest(".iti");if(t){const e=t.parentNode?.querySelector(".iti-error-msg");e&&e.remove()}}}i.instances=new WeakMap,i.cssLoaded=!1,i.jsLoaded=!1,i.loadPromise=null;const a=document.createElement("style");a.textContent="\n /* Custom styles for intl-tel-input integration */\n .iti {\n width: 100%;\n }\n\n .iti__flag-container {\n background-color: transparent;\n }\n\n .iti__selected-flag {\n padding-right: 8px;\n }\n\n .iti__country-list {\n max-height: 300px;\n border-radius: 0.5rem;\n box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);\n font-size: 0.875rem; /* 14px - matches text-sm */\n background-color: white !important;\n color: #1f2937 !important; /* Force dark gray text */\n }\n \n .iti__country {\n padding: 8px 10px;\n font-size: 0.875rem; /* 14px */\n color: #1f2937 !important; /* Force dark gray text */\n }\n \n .iti__country:hover,\n .iti__country--highlight {\n background-color: #f3f4f6 !important; /* Light gray background on hover */\n color: #1f2937 !important; /* Keep dark text on hover */\n }\n \n .iti__dial-code {\n font-size: 0.875rem; /* 14px */\n color: #6b7280 !important; /* Medium gray for dial codes */\n }\n \n .iti__selected-flag {\n font-size: 0.875rem; /* 14px */\n }\n \n .iti__country-name {\n font-size: 0.875rem; /* 14px */\n color: #1f2937 !important; /* Force dark gray text */\n }\n \n /* Search box in dropdown */\n .iti__search-input {\n font-size: 0.875rem; /* 14px */\n padding: 8px 10px;\n background-color: white !important;\n color: #1f2937 !important; /* Force dark gray text */\n border-color: #e5e7eb !important;\n }\n \n .iti__search-input::placeholder {\n color: #9ca3af !important; /* Light gray for placeholder */\n }\n \n /* Divider between countries */\n .iti__divider {\n border-bottom-color: #e5e7eb !important;\n }\n\n .iti__input {\n width: 100%;\n padding-left: 52px !important;\n }\n\n .iti--separate-dial-code .iti__input {\n padding-left: 80px !important;\n }\n\n /* Validation states */\n .iti__input.!border-red-300 {\n border-color: #fca5a5 !important;\n }\n\n .iti__input.!border-green-300 {\n border-color: #86efac !important;\n }\n\n .iti__input.focus\\:!border-red-500:focus {\n border-color: #ef4444 !important;\n }\n\n .iti__input.focus\\:!border-green-500:focus {\n border-color: #22c55e !important;\n }\n\n .iti__input.focus\\:!ring-red-500:focus {\n --tw-ring-color: #ef4444 !important;\n }\n\n .iti__input.focus\\:!ring-green-500:focus {\n --tw-ring-color: #22c55e !important;\n }\n\n .iti-error-msg {\n color: #dc2626;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n }\n\n /* Dark mode support - Removed to ensure consistent appearance\n The dropdown now always shows with white background and dark text\n regardless of system color scheme for better readability */\n",document.head.appendChild(a)},8050:function(e,t,n){"use strict";n.r(t),n.d(t,{Alert:function(){return i}});var o=n(3716);class i{static render({id:e="",title:t="",message:n="",variant:o="info",dismissible:i=!1,icon:a=!0,actions:s="",className:r="",autoHide:d=5e3}){return`\n <div ${e?`id="${e}"`:""} class="${this.getBaseClasses(o)} ${r} toast-alert" role="alert" ${d>0?`data-auto-hide="${d}"`:""}>\n <div class="flex">\n ${a?this.renderIcon(o):""}\n <div class="flex-1 ${a?"ml-3":""}">\n ${t?this.renderTitle(t,o):""}\n ${n?this.renderMessage(n,o,!t):""}\n ${s?this.renderActions(s,o):""}\n </div>\n </div>\n </div>\n `}static getBaseClasses(e){const t={info:"bg-blue-50 border-blue-200",success:"bg-green-50 border-green-200",warning:"bg-yellow-50 border-yellow-200",error:"bg-red-50 border-red-200"};return`rounded-md p-4 border shadow-lg ${t[e]||t.info}`}static renderIcon(e){const t={info:{name:"info",class:"h-5 w-5 text-blue-400"},success:{name:"check-circle",class:"h-5 w-5 text-green-400"},warning:{name:"alert-triangle",class:"h-5 w-5 text-yellow-400"},error:{name:"x-circle",class:"h-5 w-5 text-red-400"}},n=t[e]||t.info;return`\n <div class="flex-shrink-0">\n ${o.Hj.render(n.name,{class:n.class})}\n </div>\n `}static renderTitle(e,t){const n={info:"text-blue-800",success:"text-green-800",warning:"text-yellow-800",error:"text-red-800"};return`<h3 class="text-sm font-medium ${n[t]||n.info}">${this.escapeHtml(e)}</h3>`}static renderMessage(e,t,n=!1){const o={info:"text-blue-700",success:"text-green-700",warning:"text-yellow-700",error:"text-red-700"};return`<div class="${n?"":"mt-2"} text-sm ${o[t]||o.info}">${this.escapeHtml(e)}</div>`}static renderActions(e,t){return`\n <div class="mt-4">\n <div class="-mx-2 -my-1.5 flex">\n ${e}\n </div>\n </div>\n `}static renderDismissButton(){return`\n <div class="ml-auto pl-3">\n <div class="-mx-1.5 -my-1.5">\n <button type="button" class="alert-dismiss inline-flex rounded-md p-1.5 focus:outline-none focus:ring-2 focus:ring-offset-2" aria-label="Dismiss">\n ${o.Hj.render("x",{class:"h-5 w-5"})}\n </button>\n </div>\n </div>\n `}static escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}static show(e){const t=document.getElementById(e);t&&(t.classList.remove("hidden"),this.setupAutoHide(t))}static hide(e){const t="string"==typeof e?document.getElementById(e):e;t&&(t.classList.add("hidden"),t.dispatchEvent(new CustomEvent("alert:hidden")))}static attachHandlers(e=document){e.querySelectorAll(".alert-dismiss").forEach((e=>{e.addEventListener("click",(e=>{const t=e.target.closest('[role="alert"]');t&&this.hide(t)}))}
1));e.querySelectorAll("[data-auto-hide]").forEach((e=>{this.setupAutoHide(e)}))}static setupAutoHide(e){const t=parseInt(e.dataset.autoHide||"0");t>0&&setTimeout((()=>{this.hide(e)}),t)}static flash({message:e,variant:t="info",duration:n=5e3,container:o=document.body}){const i=`${t}:${e}`,a=this.recentMessages.get(i),s=Date.now();if(a&&s-a<this.MESSAGE_DEBOUNCE_TIME)return console.log("[Alert] Duplicate message prevented:",e),"";this.recentMessages.set(i,s),setTimeout((()=>{this.recentMessages.delete(i)}),this.MESSAGE_DEBOUNCE_TIME);const r=`alert-${s}`,d=this.render({id:r,message:e,variant:t,dismissible:!1,autoHide:n});let l=document.getElementById("flash-alerts");l||(l=document.createElement("div"),l.id="flash-alerts",l.className="fixed top-4 right-4 z-[9999] space-y-2 max-w-sm",o.appendChild(l),this.addToastStyles()),l.insertAdjacentHTML("beforeend",d);const c=document.getElementById(r);return c.offsetHeight,requestAnimationFrame((()=>{c.classList.add("toast-show")})),this.setupAutoHide(c),c.addEventListener("alert:hidden",(()=>{c.classList.remove("toast-show"),c.classList.add("toast-hide"),setTimeout((()=>c.remove()),300)})),r}static renderInline({message:e,variant:t="error",className:n=""}){const o={info:"text-blue-600",success:"text-green-600",warning:"text-yellow-600",error:"text-red-600"};return`\n <p class="mt-1 text-sm ${o[t]||o.error} ${n}" role="alert">\n ${this.escapeHtml(e)}\n </p>\n `}static addToastStyles(){if(document.getElementById("toast-styles"))return;const e=document.createElement("style");e.id="toast-styles",e.textContent="\n .toast-alert {\n transform: translateX(100%);\n opacity: 0;\n transition: all 0.3s ease-out;\n }\n \n .toast-alert.toast-show {\n transform: translateX(0);\n opacity: 1;\n }\n \n .toast-alert.toast-hide {\n transform: translateX(100%);\n opacity: 0;\n transition: all 0.3s ease-in;\n }\n ",document.head.appendChild(e)}static success(e,t={}){return this.flash({message:e,variant:"success",...t})}static error(e,t={}){return this.flash({message:e,variant:"error",...t})}static warning(e,t={}){return this.flash({message:e,variant:"warning",...t})}static info(e,t={}){return this.flash({message:e,variant:"info",...t})}}i.recentMessages=new Map,i.MESSAGE_DEBOUNCE_TIME=1e3,t.default=i},1678:function(e,t,n){"use strict";n.d(t,{$:function(){return i}});var o=n(3716);class i{static render({id:e="",text:t="",type:n="button",variant:o="primary",size:i="medium",fullWidth:a=!1,disabled:s=!1,loading:r=!1,icon:d="",iconPosition:l="left",className:c="",onClick:u="",ariaLabel:m="",...g}){return`\n <button\n ${e?`id="${e}"`:""}\n type="${n}"\n class="${this.getBaseClasses(o,i,a,s,r)} ${c}"\n ${s?"disabled":""}\n ${u?`onclick="${this.escapeAttr(u)}"`:""}\n ${m?`aria-label="${this.escapeAttr(m)}"`:""}\n ${Object.entries(g).map((([e,t])=>`${e}="${this.escapeAttr(String(t))}"`)).join(" ")}\n >\n ${this.renderContent(t,d,l,r,i)}\n </button>\n `}static getBaseClasses(e,t,n,o,i){const a="inline-flex items-center justify-center font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 transition-all duration-200",s={small:"px-3 py-1.5 text-sm",medium:"px-4 py-2 text-sm",large:"px-6 py-3 text-base"},r={primary:"text-white bg-primary-600 hover:bg-primary-700 focus:ring-primary-500",secondary:"text-secondary-700 bg-secondary-100 hover:bg-secondary-200 focus:ring-primary-500",white:"text-gray-700 bg-white hover:bg-gray-50 border border-gray-300 focus:ring-primary-500",danger:"text-white bg-red-600 hover:bg-red-700 focus:ring-red-500",success:"text-white bg-green-600 hover:bg-green-700 focus:ring-green-500",warning:"text-white bg-yellow-600 hover:bg-yellow-700 focus:ring-yellow-500",link:"text-primary-600 hover:text-primary-700 underline focus:ring-primary-500 p-0"},d=o||i?"opacity-50 cursor-not-allowed pointer-events-none":"cursor-pointer",l=n?"w-full":"",c=s[t]||s.medium,u=r[e]||r.primary;return"link"===e?`${a} ${u} ${d} ${l}`.trim():`${a} ${c} ${u} ${d} ${l}`.trim()}static renderContent(e,t,n,o,i){if(o)return this.renderLoadingSpinner(i);const a=!!e;if(!!!t)return this.escapeHtml(e);const s=`<span class="${a?"left"===n?"mr-2":"ml-2":""} ${this.getIconSizeClass(i)}">${t}</span>`;return"left"===n?`${s}${a?this.escapeHtml(e):""}`:`${a?this.escapeHtml(e):""}${s}`}static renderLoadingSpinner(e){const t={small:"h-3 w-3",medium:"h-4 w-4",large:"h-5 w-5"},n=t[e]||t.medium;return o.Hj.render("loader",{class:`animate-spin ${n}`})}static getIconSizeClass(e){const t={small:"[&>svg]:h-3 [&>svg]:w-3",medium:"[&>svg]:h-4 [&>svg]:w-4",large:"[&>svg]:h-5 [&>svg]:w-5"};return t[e]||t.medium}static escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}static escapeAttr(e){return String(e).replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}static renderGroup({buttons:e=[],size:t="medium",fullWidth:n=!1,className:o=""}){return`\n <div class="${n?"flex w-full":"inline-flex"} ${o}">\n ${e.map(((n,o)=>{const i=0===o,a=o===e.length-1;let s="";
1return i||(s+=" -ml-px"),i||a||(s+=" rounded-none"),i&&e.length>1&&(s+=" rounded-r-none"),a&&e.length>1&&(s+=" rounded-l-none"),this.render({...n,size:t,className:`${n.className||""} ${s}`.trim()})})).join("")}\n </div>\n `}static primary(e,t={}){return this.render({text:e,variant:"primary",...t})}static secondary(e,t={}){return this.render({text:e,variant:"secondary",...t})}static danger(e,t={}){return this.render({text:e,variant:"danger",...t})}static cancel(e="Cancel",t={}){return this.render({text:e,variant:"white",...t})}static save(e="Save",t={}){return this.render({text:e,variant:"primary",type:"submit",...t})}static delete(e="Delete",t={}){return this.render({text:e,variant:"danger",...t})}}},3960:function(e,t,n){"use strict";n.d(t,{Z:function(){return i}});var o=n(3716);class i{static render({id:e="",title:t="",subtitle:n="",content:o="",footer:i="",actions:a="",variant:s="default",padding:r="normal",highlighted:d=!1,className:l="",headerClassName:c="",contentClassName:u="",footerClassName:m=""}){return`\n <div ${e?`id="${e}"`:""} class="${this.getBaseClasses(s,r,d)} ${l}">\n ${this.renderHeader(t,n,c,r)}\n ${this.renderContent(o,u,r)}\n ${this.renderFooter(i,a,m,r)}\n </div>\n `}static getBaseClasses(e,t,n){const o={default:"bg-white",bordered:"bg-white border border-gray-200",shadow:"bg-white shadow-sm",elevated:"bg-white shadow-lg"};return`${o[e]||o.default} rounded-lg ${n?"ring-2 ring-primary-500":""}`.trim()}static renderHeader(e,t,n,o){if(!e&&!t)return"";return`\n <div class="${this.getPaddingClass(o,"header")} ${n}">\n ${e?`<h3 class="text-lg font-medium leading-6 text-gray-900">${this.escapeHtml(e)}</h3>`:""}\n ${t?`<p class="mt-1 text-sm text-gray-500">${this.escapeHtml(t)}</p>`:""}\n </div>\n `}static renderContent(e,t,n){if(!e)return"";return`\n <div class="${this.getPaddingClass(n,"content")} ${t}">\n ${e}\n </div>\n `}static renderFooter(e,t,n,o){if(!e&&!t)return"";return`\n <div class="${this.getPaddingClass(o,"footer")} border-t border-gray-200 ${n}">\n ${e||""}\n ${t?`\n <div class="flex justify-end space-x-3">\n ${t}\n </div>\n `:""}\n </div>\n `}static getPaddingClass(e,t){const n={none:"",small:{header:"px-3 py-2",content:"px-3 py-2",footer:"px-3 py-2"},normal:{header:"px-4 py-4 sm:px-6",content:"px-4 py-4 sm:px-6",footer:"px-4 py-3 sm:px-6"},large:{header:"px-6 py-6 sm:px-8",content:"px-6 py-6 sm:px-8",footer:"px-6 py-4 sm:px-8"}};if("none"===e)return"";const o=n[e]||n.normal;return"string"==typeof o?o:o[t]||""}static escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}static renderList({title:e,items:t=[],emptyMessage:n="No items",divided:o=!0,...i}){if(0===t.length)return this.render({title:e,content:`<p class="text-gray-500">${this.escapeHtml(n)}</p>`,...i});const a=o?"py-3 first:pt-0 last:pb-0":"py-2",s=`\n <ul class="${o?"divide-y divide-gray-200":""}">\n ${t.map((e=>`\n <li class="${a}">\n ${e}\n </li>\n `)).join("")}\n </ul>\n `;return this.render({title:e,content:s,padding:"none",contentClassName:"px-4 py-4 sm:px-6",...i})}static renderStats({title:e,value:t,description:n,icon:i,trend:a,trendDirection:s="up",...r}){const d="up"===s?"text-green-600":"text-red-600",l="up"===s?o.Hj.render("trending-up",{class:"w-4 h-4"}):o.Hj.render("trending-down",{class:"w-4 h-4"}),c=`\n <div class="flex items-center">\n ${i?`\n <div class="flex-shrink-0 p-3 bg-primary-500 text-white rounded-lg">\n ${i}\n </div>\n `:""}\n <div class="${i?"ml-5":""} w-0 flex-1">\n <dl>\n <dt class="text-sm font-medium text-gray-500 truncate">\n ${this.escapeHtml(e||"")}\n </dt>\n <dd class="flex items-baseline">\n <div class="text-2xl font-semibold text-gray-900">\n ${this.escapeHtml(t)}\n </div>\n ${a?`\n <div class="ml-2 flex items-baseline text-sm font-semibold ${d}">\n ${l}
1\n <span class="sr-only">${"up"===s?"Increased":"Decreased"} by</span>\n ${this.escapeHtml(a)}\n </div>\n `:""}\n </dd>\n ${n?`\n <dd class="mt-1 text-sm text-gray-500">\n ${this.escapeHtml(n)}\n </dd>\n `:""}\n </dl>\n </div>\n </div>\n `;return this.render({content:c,variant:"shadow",...r})}}},8243:function(e,t,n){"use strict";n.d(t,{k:function(){return o}});class o{static render({size:e="medium",color:t="indigo",text:n="",fullScreen:o=!1,overlay:i=!1,className:a=""}){return o?this.renderFullScreen(e,t,n,a):i?this.renderOverlay(e,t,n,a):this.renderInline(e,t,n,a)}static renderInline(e,t,n,o){return`\n <div class="flex flex-col items-center justify-center ${o}">\n <div class="animate-spin rounded-full ${this.getSizeClasses(e)} border-b-2 ${`border-${t}-600`}"></div>\n ${n?`<p class="mt-4 text-sm text-gray-600">${this.escapeHtml(n)}</p>`:""}\n </div>\n `}static renderOverlay(e,t,n,o){return`\n <div class="absolute inset-0 z-50 flex items-center justify-center bg-white bg-opacity-75 ${o}">\n <div class="flex flex-col items-center">\n <div class="animate-spin rounded-full ${this.getSizeClasses(e)} border-b-2 ${`border-${t}-600`}"></div>\n ${n?`<p class="mt-4 text-sm text-gray-600">${this.escapeHtml(n)}</p>`:""}\n </div>\n </div>\n `}static renderFullScreen(e,t,n,o){return`\n <div class="fixed inset-0 z-50 flex items-center justify-center bg-white bg-opacity-90 ${o}">\n <div class="flex flex-col items-center">\n <div class="animate-spin rounded-full ${this.getSizeClasses("small"===e?"medium":e)} border-b-2 ${`border-${t}-600`}"></div>\n ${n?`<p class="mt-4 text-lg text-gray-700">${this.escapeHtml(n)}</p>`:""}\n </div>\n </div>\n `}static getSizeClasses(e){const t={small:"h-6 w-6",medium:"h-12 w-12",large:"h-16 w-16"};return t[e]||t.medium}static escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}static renderWithIcon({icon:e="",size:t="medium",color:n="indigo",text:o="",className:i=""}){const a={small:"h-4 w-4",medium:"h-8 w-8",large:"h-12 w-12"};return`\n <div class="flex flex-col items-center justify-center ${i}">\n <div class="relative">\n <div class="animate-spin rounded-full ${this.getSizeClasses(t)} border-b-2 border-${n}-600"></div>\n <div class="absolute inset-0 flex items-center justify-center">\n <div class="text-${n}-600 ${a[t]||a.medium}">\n ${e}\n </div>\n </div>\n </div>\n ${o?`<p class="mt-4 text-sm text-gray-600">${this.escapeHtml(o)}</p>`:""}\n </div>\n `}static renderProgress({progress:e=0,size:t="medium",color:n="indigo",text:o="",showPercentage:i=!0,className:a=""}){const s={small:{size:60,stroke:4},medium:{size:100,stroke:6},large:{size:140,stroke:8}},r=s[t]||s.medium,d=(r.size-r.stroke)/2,l=2*d*Math.PI,c=l-e/100*l;return`\n <div class="flex flex-col items-center justify-center ${a}">\n <div class="relative">\n <svg class="transform -rotate-90" width="${r.size}" height="${r.size}">\n <circle\n cx="${r.size/2}"\n cy="${r.size/2}"\n r="${d}"\n stroke="currentColor"\n stroke-width="${r.stroke}"\n fill="none"\n class="text-gray-300"\n />\n <circle\n cx="${r.size/2}"\n cy="${r.size/2}"\n r="${d}"\n stroke="currentColor"\n stroke-width="${r.stroke}"\n fill="none"\n stroke-dasharray="${l}"\n stroke-dashoffset="${c}"\n class="text-${n}-600 transition-all duration-300"\n />\n </svg>\n ${i?`\n <div class="absolute inset-0 flex items-center justify-center">\n <span class="text-${"small"===t?"xs":"large"===t?"lg":"sm"} font-medium text-gray-700">\n ${Math.round(e)}%\n </span>\n </div>\n `:""}\n </div>\n ${o?`<p class="mt-4 text-sm text-gray-600">${this.escapeHtml(o)}</p>`:""}\n </div>\n `}
1static renderSkeleton({lines:e=3,showAvatar:t=!1,className:n=""}){return`\n <div class="space-y-3 ${n}">\n ${t?'\n <div class="flex items-center space-x-3">\n <div class="h-10 w-10 bg-gray-300 rounded-full animate-pulse"></div>\n <div class="flex-1 space-y-2">\n <div class="h-4 bg-gray-300 rounded w-1/2 animate-pulse"></div>\n <div class="h-3 bg-gray-300 rounded w-1/3 animate-pulse"></div>\n </div>\n </div>\n ':""}\n <div class="space-y-2">\n ${Array(e).fill(null).map(((t,n)=>`<div class="h-4 bg-gray-300 rounded ${n===e-1?"w-3/4":"w-full"} animate-pulse"></div>`)).join("")}\n </div>\n </div>\n `}static showOverlay(e,t={}){if(!e)return"";"static"===window.getComputedStyle(e).position&&(e.style.position="relative");const n=`spinner-${Date.now()}`,o=document.createElement("div");o.id=n,o.innerHTML=this.renderOverlay(t.size||"medium",t.color||"indigo",t.text||"",t.className||"");const i=o.firstElementChild;return i&&e.appendChild(i),n}static hideOverlay(e,t){if(!e)return;const n=t?e.querySelector(`#${t}`):e.querySelector(".absolute.inset-0");n&&n.remove()}}},6833:function(e,t,n){"use strict";n.r(t),n.d(t,{Modal:function(){return a}});var o=n(3716),i=n(3649);class a{constructor(e={}){this.isOpen=!1,this.modalElement=null,this.escapeHandler=null,this.overlayHandler=null,this.options={id:`modal-${Date.now()}`,title:"",content:"",footer:"",size:"medium",closeButton:!0,closeOnOverlay:!0,closeOnEscape:!0,className:"",onClose:null,onOpen:null,...e}}open(){if(this.isOpen)return;if(!i.J.canOpenModal(this.options.id))return void console.log(`[Modal] Cannot open modal ${this.options.id} - another modal is active or debouncing`);if(!i.J.registerModal(this,this.options.id))return void console.log(`[Modal] Failed to register modal ${this.options.id}`);const e=a.render({...this.options,open:!0}),t=document.createElement("div");t.innerHTML=e,this.modalElement=t.firstElementChild,document.body.appendChild(this.modalElement),document.body.style.overflow="hidden",this.attachEventListeners(),this.options.onOpen&&this.options.onOpen(),requestAnimationFrame((()=>{if(!this.modalElement)return;this.modalElement.classList.remove("hidden");const e=this.modalElement.querySelector(".modal-overlay"),t=this.modalElement.querySelector(".modal-content");e&&e.classList.add("animate-fade-in"),t&&t.classList.add("animate-slide-up")})),this.isOpen=!0}close(){if(!this.isOpen||!this.modalElement)return;i.J.unregisterModal(this);const e=this.modalElement.querySelector(".modal-overlay"),t=this.modalElement.querySelector(".modal-content");e&&e.classList.add("animate-fade-out"),t&&t.classList.add("animate-slide-down"),setTimeout((()=>{this.removeEventListeners(),this.modalElement&&this.modalElement.parentNode&&this.modalElement.remove(),document.body.style.overflow="",this.options.onClose&&this.options.onClose(),this.modalElement=null,this.isOpen=!1}),200)}updateContent(e){if(!this.modalElement)return;const t=this.modalElement.querySelector(".modal-body");t&&(t.innerHTML=e)}updateFooter(e){if(!this.modalElement)return;const t=this.modalElement.querySelector(".modal-footer");t&&(t.innerHTML=e)}attachEventListeners(){if(this.modalElement){if(this.options.closeButton){const e=this.modalElement.querySelector(".modal-close-btn");e&&e.addEventListener("click",(()=>this.close()))}this.options.closeOnOverlay&&(this.overlayHandler=e=>{e.target.classList.contains("modal-overlay")&&this.close()},this.modalElement.addEventListener("click",this.overlayHandler)),this.options.closeOnEscape&&(this.escapeHandler=e=>{"Escape"===e.key&&this.isOpen&&this.close()},document.addEventListener("keydown",this.escapeHandler))}}removeEventListeners(){this.overlayHandler&&this.modalElement&&this.modalElement.removeEventListener("click",this.overlayHandler),this.escapeHandler&&document.removeEventListener("keydown",this.escapeHandler)}static render({id:e="modal",title:t="",content:n="",footer:o="",size:i="medium",closeButton:a=!0,closeOnOverlay:s=!0,closeOnEscape:r=!0,className:d="",open:l=!1}){return`\n <div \n id="${e}" \n class="modal fixed inset-0 z-50 overflow-y-auto ${l?"":"hidden"}"\n aria-labelledby="${e}-title"\n aria-modal="true"\n role="dialog"\n ${s?'data-close-on-overlay="true"':""}\n ${r?'data-close-on-escape="true"':""}\n >
1\n \x3c!-- Background overlay with blur --\x3e\n <div class="modal-overlay fixed inset-0 bg-gray-900 bg-opacity-50 backdrop-blur-sm transition-opacity" aria-hidden="true"></div>\n\n \x3c!-- Center modal container --\x3e\n <div class="flex min-h-screen items-start justify-center p-4 text-center sm:p-6 lg:p-8">\n \x3c!-- Modal panel --\x3e\n <div class="modal-content relative inline-block w-full transform overflow-hidden rounded-lg bg-white text-left shadow-2xl transition-all ${this.getSizeClasses(i)} ${d} max-h-[calc(100vh-10px)] overflow-y-auto">\n ${this.renderHeader(e,t,a)}\n ${this.renderContent(n)}\n ${this.renderFooter(o)}\n </div>\n </div>\n </div>\n `}static getSizeClasses(e){const t={small:"sm:max-w-sm sm:w-full",medium:"sm:max-w-lg sm:w-full",large:"sm:max-w-xl sm:w-full",full:"sm:max-w-4xl sm:w-full"};return t[e]||t.medium}static renderHeader(e,t,n){return t||n?`\n <div class="modal-header bg-gray-50 px-4 py-3 sm:px-6">\n <div class="flex items-center justify-between">\n <h3 class="text-lg font-medium leading-6 text-gray-900" id="${e}-title">\n ${t}\n </h3>\n ${n?`\n <button \n type="button" \n class="modal-close-btn rounded-md bg-gray-50 text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-primary-500"\n >\n <span class="sr-only">Close</span>\n ${o.Hj.render("x",{class:"h-6 w-6"})}\n </button>\n `:""}\n </div>\n </div>\n `:""}static renderContent(e){return e?`\n <div class="modal-body px-4 py-5 sm:p-6">\n ${e}\n </div>\n `:""}static renderFooter(e){return e?`\n <div class="modal-footer bg-gray-50 px-4 py-3 sm:px-6">\n ${e}\n </div>\n `:""}static async confirm({title:e="Confirm",message:t="Are you sure?",confirmText:n="Confirm",cancelText:o="Cancel",confirmClass:i="bg-primary-600 hover:bg-primary-700 text-white",cancelClass:s="bg-gray-200 hover:bg-gray-300 text-gray-800"}){return new Promise((r=>{const d=new a({title:e,content:`<div class="text-gray-600">${t}</div>`,footer:`\n <div class="flex justify-end space-x-3">\n <button id="modal-cancel" class="${s} px-4 py-2 rounded-lg transition-colors font-medium">\n ${o}\n </button>\n <button id="modal-confirm" class="${i} px-4 py-2 rounded-lg transition-colors font-medium">\n ${n}\n </button>\n </div>\n `,size:"small",onClose:()=>r(!1)});d.open(),setTimeout((()=>{const e=document.getElementById("modal-cancel"),t=document.getElementById("modal-confirm");e?.addEventListener("click",(()=>{d.close(),r(!1)})),t?.addEventListener("click",(()=>{d.close(),r(!0)}))}),0)}))}static alert({title:e="Alert",message:t="",buttonText:n="OK",buttonClass:o="bg-primary-600 hover:bg-primary-700 text-white"}){return new Promise((i=>{const s=new a({title:e,content:`<div class="text-gray-600">${t}</div>`,footer:`\n <div class="flex justify-end">\n <button id="modal-ok" class="${o} px-4 py-2 rounded-lg transition-colors font-medium">\n ${n}\n </button>\n </div>\n `,size:"small",onClose:()=>i()});s.open(),setTimeout((()=>{const e=document.getElementById("modal-ok");e?.addEventListener("click",(()=>{s.close(),i()}))}),0)}))}}if("undefined"!=typeof document&&!document.getElementById("modal-animations")){const e=document.createElement("style");e.id="modal-animations",e.textContent="\n @keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n \n @keyframes fadeOut {\n from { opacity: 1; }\n to { opacity: 0; }\n }\n \n @keyframes slideUp {\n from {\n opacity: 0;\n transform: translateY(1rem);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n \n @keyframes slideDown {\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(1rem);\n }\n }\n \n .animate-fade-in {\n animation: fadeIn 0.2s ease-out forwards;\n }\n \n .animate-fade-out {\n animation: fadeOut 0.2s ease-out forwards;\n }\n \n .animate-slide-up {\n animation: slideUp 0.2s ease-out forwards;\n }\n \n .animate-slide-down {\n animation: slideDown 0.2s ease-out forwards;\n }\n \n /* Ensure modal content is scrollable */\n .modal
1-content {\n display: flex;\n flex-direction: column;\n }\n \n .modal-body {\n flex: 1;\n overflow-y: auto;\n }\n ",document.head.appendChild(e)}t.default=a},2404:function(e,t,n){"use strict";n.d(t,{b:function(){return i}});var o=n(3716);class i{static render({icon:e="",title:t="",subtitle:n="",actions:o="",gradient:i="bg-gradient-to-r from-primary-500 to-secondary-600"}){return`\n <div class="heimguard-component-header ${i} p-4 sm:p-6">\n <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">\n <div class="flex items-center">\n ${e?`\n <div class="p-2 bg-white/20 rounded-lg mr-3 sm:mr-4 flex-shrink-0">\n ${e}\n </div>\n `:""}\n <div class="min-w-0">\n <h2 class="text-xl sm:text-2xl font-bold text-white truncate">${this.escapeHtml(t)}</h2>\n ${n?`<p class="text-primary-100 mt-0.5 sm:mt-1 text-sm sm:text-base truncate">${this.escapeHtml(n)}</p>`:""}\n </div>\n </div>\n <div class="heimguard-header-actions flex items-center gap-2 sm:gap-3 self-end sm:self-auto">\n ${o}\n </div>\n </div>\n </div>\n `}static renderButton({text:e,icon:t,onClick:n="",className:o=""}){return`\n <button class="inline-flex items-center px-3 sm:px-4 py-1.5 sm:py-2 text-white rounded-lg transition-all border border-white/30 text-xs sm:text-sm font-medium whitespace-nowrap ${o}" style="background-color: rgba(255, 255, 255, 0.2) !important; backdrop-filter: blur(8px) !important;" ${n?`onclick="${n}"`:""} onmouseover="this.style.backgroundColor='rgba(255, 255, 255, 0.3) !important'" onmouseout="this.style.backgroundColor='rgba(255, 255, 255, 0.2) !important'">\n ${t?`<span class="mr-1.5">${t}</span>`:""}\n <span>${e}</span>\n </button>\n `}static renderFilterDropdown({currentFilter:e="all",options:t=[],onFilterChange:n="",className:i=""}){return`\n <div class="relative ${i}" id="profile-filter-dropdown">\n <button class="profile-filter-toggle flex items-center px-3 sm:px-4 py-1.5 sm:py-2 bg-white/20 backdrop-blur text-white rounded-lg hover:bg-white/30 transition-all text-xs sm:text-sm">\n ${o.Hj.render("filter",{class:"w-3 h-3 sm:w-4 sm:h-4 mr-1.5 sm:mr-2"})}\n <span class="truncate max-w-[100px] sm:max-w-none">${e}</span>\n </button>\n\n <div class="profile-filter-menu hidden absolute right-0 mt-2 w-48 sm:w-56 bg-white rounded-lg shadow-xl border border-gray-200 py-1 z-20">\n ${t.map((e=>`\n <button class="profile-filter-option w-full px-3 sm:px-4 py-2 text-left text-xs sm:text-sm hover:bg-gray-50 transition-colors flex items-center justify-between text-gray-700" data-filter="${e.value}">\n <span class="flex items-center">\n ${e.icon?`<span class="mr-1.5 sm:mr-2">${e.icon}</span>`:""}\n <span>${e.label}</span>\n </span>\n ${e.count?`<span class="text-xs font-medium text-gray-500">${e.count}</span>`:""}\n </button>\n `)).join("")}\n </div>\n </div>\n `}static escapeHtml(e){if(!e)return"";const t=document.createElement("div");return t.textContent=e,t.innerHTML}}i.icons={user:o.Hj.render("user",{class:"w-6 h-6 text-white"}),invoice:o.Hj.render("file-text",{class:"w-6 h-6 text-white"}),subscription:o.Hj.render("clipboard-list",{class:"w-6 h-6 text-white"}),payment:o.Hj.render("credit-card",{class:"w-6 h-6 text-white"}),address:o.Hj.render("map-pin",{class:"w-6 h-6 text-white"}),security:o.Hj.render("lock",{class:"w-6 h-6 text-white"}),heart:o.Hj.render("heart",{class:"w-6 h-6 text-white"}),activity:o.Hj.render("clipboard-check",{class:"w-6 h-6 text-white"}),mail:o.Hj.render("mail",{class:"w-6 h-6 text-white"})}},8380:function(e,t,n){"use strict";n.d(t,{A:function(){return c}});var o=JSON.parse('[{"name":"Afghanistan","isoCode":"AF","flag":"ð¦ð«","phonecode":"93","currency":"AFN","latitude":"33.00000000","longitude":"65.00000000","timezones":[{"zoneName":"Asia/Kabul","gmtOffset":16200,"gmtOffsetName":"UTC+04:30","abbreviation":"AFT","tzName":"Afghanistan Time"}]}
1,{"name":"Aland Islands","isoCode":"AX","flag":"ð¦ð½","phonecode":"+358-18","currency":"EUR","latitude":"60.11666700","longitude":"19.90000000","timezones":[{"zoneName":"Europe/Mariehamn","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Albania","isoCode":"AL","flag":"ð¦ð±","phonecode":"355","currency":"ALL","latitude":"41.00000000","longitude":"20.00000000","timezones":[{"zoneName":"Europe/Tirane","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Algeria","isoCode":"DZ","flag":"ð©ð¿","phonecode":"213","currency":"DZD","latitude":"28.00000000","longitude":"3.00000000","timezones":[{"zoneName":"Africa/Algiers","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"American Samoa","isoCode":"AS","flag":"ð¦ð¸","phonecode":"+1-684","currency":"USD","latitude":"-14.33333333","longitude":"-170.00000000","timezones":[{"zoneName":"Pacific/Pago_Pago","gmtOffset":-39600,"gmtOffsetName":"UTC-11:00","abbreviation":"SST","tzName":"Samoa Standard Time"}]},{"name":"Andorra","isoCode":"AD","flag":"ð¦ð©","phonecode":"376","currency":"EUR","latitude":"42.50000000","longitude":"1.50000000","timezones":[{"zoneName":"Europe/Andorra","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Angola","isoCode":"AO","flag":"ð¦ð´","phonecode":"244","currency":"AOA","latitude":"-12.50000000","longitude":"18.50000000","timezones":[{"zoneName":"Africa/Luanda","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"WAT","tzName":"West Africa Time"}]},{"name":"Anguilla","isoCode":"AI","flag":"ð¦ð®","phonecode":"+1-264","currency":"XCD","latitude":"18.25000000","longitude":"-63.16666666","timezones":[{"zoneName":"America/Anguilla","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Antarctica","isoCode":"AQ","flag":"ð¦ð¶","phonecode":"672","currency":"AAD","latitude":"-74.65000000","longitude":"4.48000000","timezones":[{"zoneName":"Antarctica/Casey","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"AWST","tzName":"Australian Western Standard Time"},{"zoneName":"Antarctica/Davis","gmtOffset":25200,"gmtOffsetName":"UTC+07:00","abbreviation":"DAVT","tzName":"Davis Time"},{"zoneName":"Antarctica/DumontDUrville","gmtOffset":36000,"gmtOffsetName":"UTC+10:00","abbreviation":"DDUT","tzName":"Dumont d\'Urville Time"},{"zoneName":"Antarctica/Mawson","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"MAWT","tzName":"Mawson Station Time"},{"zoneName":"Antarctica/McMurdo","gmtOffset":46800,"gmtOffsetName":"UTC+13:00","abbreviation":"NZDT","tzName":"New Zealand Daylight Time"},{"zoneName":"Antarctica/Palmer","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"CLST","tzName":"Chile Summer Time"},{"zoneName":"Antarctica/Rothera","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"ROTT","tzName":"Rothera Research Station Time"},{"zoneName":"Antarctica/Syowa","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"SYOT","tzName":"Showa Station Time"},{"zoneName":"Antarctica/Troll","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"},{"zoneName":"Antarctica/Vostok","gmtOffset":21600,"gmtOffsetName":"UTC+06:00","abbreviation":"VOST","tzName":"Vostok Station Time"}]},{"name":"Antigua And Barbuda","isoCode":"AG","flag":"ð¦ð¬","phonecode":"+1-268","currency":"XCD","latitude":"17.05000000","longitude":"-61.80000000","timezones":[{"zoneName":"America/Antigua","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Argentina","isoCode":"AR","flag":"ð¦ð·","phonecode":"54","currency":"ARS","latitude":"-34.00000000","longitude":"-64.00000000","timezones":[{"zoneName":"America/Argentina/Buenos_Aires","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"ART","tzName":"Argentina Time"},{"zoneName":"America/Argentina/Catamarca","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"ART","tzName":"Argentina Time"},{"zoneName":"America/Argentina/Cordoba","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"ART","tzName":"Argentina Time"},{"zoneName":"America/Argentina/Jujuy","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"ART","tzName":"Argentina Time"},{"zoneName":"America/Argentina/La_Rioja","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"ART","tzName":"Argentina Time"},{"zoneName":"America/Argentina/Mendoza","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"ART","tzName":"Argentina Time"},{"zoneName":"America/Argentina/Rio_Gallegos","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"ART","tzName":"Argentina Time"},{"zoneName":"America/Argentina/Salta","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"ART","tzName":"Argentina Time"},{"zoneName":"America/Argentina/San_Juan","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"ART","tzName":"Argentina Time"},{"zoneName":"America/Argentina/San_Luis","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"ART","tzName":"Argentina Time"},{"zoneName":"America/Argentina/Tucuman","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"ART","tzName":"Argentina Time"},{"zoneName":"America/Argentina/Ushuaia","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"ART","tzName":"Argentina Time"}]}
1,{"name":"Armenia","isoCode":"AM","flag":"ð¦ð²","phonecode":"374","currency":"AMD","latitude":"40.00000000","longitude":"45.00000000","timezones":[{"zoneName":"Asia/Yerevan","gmtOffset":14400,"gmtOffsetName":"UTC+04:00","abbreviation":"AMT","tzName":"Armenia Time"}]},{"name":"Aruba","isoCode":"AW","flag":"ð¦ð¼","phonecode":"297","currency":"AWG","latitude":"12.50000000","longitude":"-69.96666666","timezones":[{"zoneName":"America/Aruba","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Australia","isoCode":"AU","flag":"ð¦ðº","phonecode":"61","currency":"AUD","latitude":"-27.00000000","longitude":"133.00000000","timezones":[{"zoneName":"Antarctica/Macquarie","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"MIST","tzName":"Macquarie Island Station Time"},{"zoneName":"Australia/Adelaide","gmtOffset":37800,"gmtOffsetName":"UTC+10:30","abbreviation":"ACDT","tzName":"Australian Central Daylight Saving Time"},{"zoneName":"Australia/Brisbane","gmtOffset":36000,"gmtOffsetName":"UTC+10:00","abbreviation":"AEST","tzName":"Australian Eastern Standard Time"},{"zoneName":"Australia/Broken_Hill","gmtOffset":37800,"gmtOffsetName":"UTC+10:30","abbreviation":"ACDT","tzName":"Australian Central Daylight Saving Time"},{"zoneName":"Australia/Currie","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"AEDT","tzName":"Australian Eastern Daylight Saving Time"},{"zoneName":"Australia/Darwin","gmtOffset":34200,"gmtOffsetName":"UTC+09:30","abbreviation":"ACST","tzName":"Australian Central Standard Time"},{"zoneName":"Australia/Eucla","gmtOffset":31500,"gmtOffsetName":"UTC+08:45","abbreviation":"ACWST","tzName":"Australian Central Western Standard Time (Unofficial)"},{"zoneName":"Australia/Hobart","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"AEDT","tzName":"Australian Eastern Daylight Saving Time"},{"zoneName":"Australia/Lindeman","gmtOffset":36000,"gmtOffsetName":"UTC+10:00","abbreviation":"AEST","tzName":"Australian Eastern Standard Time"},{"zoneName":"Australia/Lord_Howe","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"LHST","tzName":"Lord Howe Summer Time"},{"zoneName":"Australia/Melbourne","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"AEDT","tzName":"Australian Eastern Daylight Saving Time"},{"zoneName":"Australia/Perth","gmtOffset":28800,"gmtOffsetName":"UTC+08:00","abbreviation":"AWST","tzName":"Australian Western Standard Time"},{"zoneName":"Australia/Sydney","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"AEDT","tzName":"Australian Eastern Daylight Saving Time"}]},{"name":"Austria","isoCode":"AT","flag":"ð¦ð¹","phonecode":"43","currency":"EUR","latitude":"47.33333333","longitude":"13.33333333","timezones":[{"zoneName":"Europe/Vienna","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Azerbaijan","isoCode":"AZ","flag":"ð¦ð¿","phonecode":"994","currency":"AZN","latitude":"40.50000000","longitude":"47.50000000","timezones":[{"zoneName":"Asia/Baku","gmtOffset":14400,"gmtOffsetName":"UTC+04:00","abbreviation":"AZT","tzName":"Azerbaijan Time"}]},{"name":"The Bahamas","isoCode":"BS","flag":"ð§ð¸","phonecode":"+1-242","currency":"BSD","latitude":"24.25000000","longitude":"-76.00000000","timezones":[{"zoneName":"America/Nassau","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America)"}]},{"name":"Bahrain","isoCode":"BH","flag":"ð§ð","phonecode":"973","currency":"BHD","latitude":"26.00000000","longitude":"50.55000000","timezones":[{"zoneName":"Asia/Bahrain","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"AST","tzName":"Arabia Standard Time"}]},{"name":"Bangladesh","isoCode":"BD","flag":"ð§ð©","phonecode":"880","currency":"BDT","latitude":"24.00000000","longitude":"90.00000000","timezones":[{"zoneName":"Asia/Dhaka","gmtOffset":21600,"gmtOffsetName":"UTC+06:00","abbreviation":"BDT","tzName":"Bangladesh Standard Time"}]},{"name":"Barbados","isoCode":"BB","flag":"ð§ð§","phonecode":"+1-246","currency":"BBD","latitude":"13.16666666","longitude":"-59.53333333","t
1imezones":[{"zoneName":"America/Barbados","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Belarus","isoCode":"BY","flag":"ð§ð¾","phonecode":"375","currency":"BYN","latitude":"53.00000000","longitude":"28.00000000","timezones":[{"zoneName":"Europe/Minsk","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"MSK","tzName":"Moscow Time"}]},{"name":"Belgium","isoCode":"BE","flag":"ð§ðª","phonecode":"32","currency":"EUR","latitude":"50.83333333","longitude":"4.00000000","timezones":[{"zoneName":"Europe/Brussels","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Belize","isoCode":"BZ","flag":"ð§ð¿","phonecode":"501","currency":"BZD","latitude":"17.25000000","longitude":"-88.75000000","timezones":[{"zoneName":"America/Belize","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America)"}]},{"name":"Benin","isoCode":"BJ","flag":"ð§ð¯","phonecode":"229","currency":"XOF","latitude":"9.50000000","longitude":"2.25000000","timezones":[{"zoneName":"Africa/Porto-Novo","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"WAT","tzName":"West Africa Time"}]},{"name":"Bermuda","isoCode":"BM","flag":"ð§ð²","phonecode":"+1-441","currency":"BMD","latitude":"32.33333333","longitude":"-64.75000000","timezones":[{"zoneName":"Atlantic/Bermuda","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Bhutan","isoCode":"BT","flag":"ð§ð¹","phonecode":"975","currency":"BTN","latitude":"27.50000000","longitude":"90.50000000","timezones":[{"zoneName":"Asia/Thimphu","gmtOffset":21600,"gmtOffsetName":"UTC+06:00","abbreviation":"BTT","tzName":"Bhutan Time"}]},{"name":"Bolivia","isoCode":"BO","flag":"ð§ð´","phonecode":"591","currency":"BOB","latitude":"-17.00000000","longitude":"-65.00000000","timezones":[{"zoneName":"America/La_Paz","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"BOT","tzName":"Bolivia Time"}]},{"name":"Bosnia and Herzegovina","isoCode":"BA","flag":"ð§ð¦","phonecode":"387","currency":"BAM","latitude":"44.00000000","longitude":"18.00000000","timezones":[{"zoneName":"Europe/Sarajevo","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Botswana","isoCode":"BW","flag":"ð§ð¼","phonecode":"267","currency":"BWP","latitude":"-22.00000000","longitude":"24.00000000","timezones":[{"zoneName":"Africa/Gaborone","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"CAT","tzName":"Central Africa Time"}]},{"name":"Bouvet Island","isoCode":"BV","flag":"ð§ð»","phonecode":"0055","currency":"NOK","latitude":"-54.43333333","longitude":"3.40000000","timezones":[{"zoneName":"Europe/Oslo","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Brazil","isoCode":"BR","flag":"ð§ð·","phonecode":"55","currency":"BRL","latitude":"-10.00000000","longitude":"-55.00000000","timezones":[{"zoneName":"America/Araguaina","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"BRT","tzName":"BrasÃlia Time"},{"zoneName":"America/Bahia","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"BRT","tzName":"BrasÃlia Time"},{"zoneName":"America/Belem","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"BRT","tzName":"BrasÃlia Time"},{"zoneName":"America/Boa_Vista","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AMT","tzName":"Amazon Time (Brazil)[3"},{"zoneName":"America/Campo_Grande","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AMT","tzName":"Amazon Time (Brazil)[3"},{"zoneName":"America/Cuiaba","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"BRT","tzName":"Brasilia Time"},{"zoneName":"America/Eirunepe","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"ACT","tzName":"Acre Time"},{"zoneName":"America/Fortaleza","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"BRT","tzName":"BrasÃlia Time"},{"zoneName":"America/Maceio","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"BRT","tzName":"BrasÃlia Time"},{"zoneName":"America/Manaus","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AMT","tzName":"Amazon Time (Brazil)"},{"zoneName":"America/Noronha","gmtOffset":-7200,"gmtOffsetName":"UTC-02:00","abbreviation":"FNT","tzName":"Fernando de Noronha Time"},{"zoneName":"America/Porto_Velho","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AMT","tzName":"Amazon Time (Brazil)[3"},{"zoneName":"America/Recife","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"BRT","tzName":"BrasÃlia Time"},{"zoneName":"America/Rio_Branco","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"ACT","tzName":"Acre Time"},{"zoneName":"America/Santarem","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"BRT","tzName":"BrasÃlia Time"},{"zoneName":"America/Sao_Paulo","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"BRT","tzName":"BrasÃlia Time"}]}
1,{"name":"British Indian Ocean Territory","isoCode":"IO","flag":"ð®ð´","phonecode":"246","currency":"USD","latitude":"-6.00000000","longitude":"71.50000000","timezones":[{"zoneName":"Indian/Chagos","gmtOffset":21600,"gmtOffsetName":"UTC+06:00","abbreviation":"IOT","tzName":"Indian Ocean Time"}]},{"name":"Brunei","isoCode":"BN","flag":"ð§ð³","phonecode":"673","currency":"BND","latitude":"4.50000000","longitude":"114.66666666","timezones":[{"zoneName":"Asia/Brunei","gmtOffset":28800,"gmtOffsetName":"UTC+08:00","abbreviation":"BNT","tzName":"Brunei Darussalam Time"}]},{"name":"Bulgaria","isoCode":"BG","flag":"ð§ð¬","phonecode":"359","currency":"BGN","latitude":"43.00000000","longitude":"25.00000000","timezones":[{"zoneName":"Europe/Sofia","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Burkina Faso","isoCode":"BF","flag":"ð§ð«","phonecode":"226","currency":"XOF","latitude":"13.00000000","longitude":"-2.00000000","timezones":[{"zoneName":"Africa/Ouagadougou","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Burundi","isoCode":"BI","flag":"ð§ð®","phonecode":"257","currency":"BIF","latitude":"-3.50000000","longitude":"30.00000000","timezones":[{"zoneName":"Africa/Bujumbura","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"CAT","tzName":"Central Africa Time"}]},{"name":"Cambodia","isoCode":"KH","flag":"ð°ð","phonecode":"855","currency":"KHR","latitude":"13.00000000","longitude":"105.00000000","timezones":[{"zoneName":"Asia/Phnom_Penh","gmtOffset":25200,"gmtOffsetName":"UTC+07:00","abbreviation":"ICT","tzName":"Indochina Time"}]},{"name":"Cameroon","isoCode":"CM","flag":"ð¨ð²","phonecode":"237","currency":"XAF","latitude":"6.00000000","longitude":"12.00000000","timezones":[{"zoneName":"Africa/Douala","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"WAT","tzName":"West Africa Time"}]},{"name":"Canada","isoCode":"CA","flag":"ð¨ð¦","phonecode":"1","currency":"CAD","latitude":"60.00000000","longitude":"-95.00000000","timezones":[{"zoneName":"America/Atikokan","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America)"},{"zoneName":"America/Blanc-Sablon","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"},{"zoneName":"America/Cambridge_Bay","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America)"},{"zoneName":"America/Creston","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America)"},{"zoneName":"America/Dawson","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America)"},{"zoneName":"America/Dawson_Creek","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America)"},{"zoneName":"America/Edmonton","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America)"},{"zoneName":"America/Fort_Nelson","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America)"},{"zoneName":"America/Glace_Bay","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"},{"zoneName":"America/Goose_Bay","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"},{"zoneName":"America/Halifax","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"},{"zoneName":"America/Inuvik","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America"},{"zoneName":"America/Iqaluit","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Moncton","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"},{"zoneName":"America/Nipigon","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Pangnirtung","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Rainy_River","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Rankin_Inlet","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Regina","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Resolute","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/St_Johns","gmtOffset":-12600,"gmtOffsetName":"UTC-03:30","abbreviation":"NST","tzName":"Newfoundland Standard Time"},{"zoneName":"America/Swift_Current","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Thunder_Bay","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Toronto","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Vancouver","gmtOffset":-28800,"gmtOffsetName":"UTC-08:00","abbreviation":"PST","tzName":"Pacific Standard Time (North America"},{"zoneName":"America/Whitehorse","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America"},{"zoneName":"America/Winnipeg","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Yellowknife","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America"}]},{"name":"Cape Verde","isoCode":"CV","flag":"ð¨ð»","phonecode":"238","currency":"CVE","latitude":"16.00000000","longitude":"-24.00000000","timezones":[{"zoneName":"Atlantic/Cape_Verde","gmtOffset":-3600,"gmtOffsetName":"UTC-01:00","abbreviation":"CVT","tzName":"Cape Verde Time"}]}
1,{"name":"Cayman Islands","isoCode":"KY","flag":"ð°ð¾","phonecode":"+1-345","currency":"KYD","latitude":"19.50000000","longitude":"-80.50000000","timezones":[{"zoneName":"America/Cayman","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"}]},{"name":"Central African Republic","isoCode":"CF","flag":"ð¨ð«","phonecode":"236","currency":"XAF","latitude":"7.00000000","longitude":"21.00000000","timezones":[{"zoneName":"Africa/Bangui","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"WAT","tzName":"West Africa Time"}]},{"name":"Chad","isoCode":"TD","flag":"ð¹ð©","phonecode":"235","currency":"XAF","latitude":"15.00000000","longitude":"19.00000000","timezones":[{"zoneName":"Africa/Ndjamena","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"WAT","tzName":"West Africa Time"}]},{"name":"Chile","isoCode":"CL","flag":"ð¨ð±","phonecode":"56","currency":"CLP","latitude":"-30.00000000","longitude":"-71.00000000","timezones":[{"zoneName":"America/Punta_Arenas","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"CLST","tzName":"Chile Summer Time"},{"zoneName":"America/Santiago","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"CLST","tzName":"Chile Summer Time"},{"zoneName":"Pacific/Easter","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EASST","tzName":"Easter Island Summer Time"}]},{"name":"China","isoCode":"CN","flag":"ð¨ð³","phonecode":"86","currency":"CNY","latitude":"35.00000000","longitude":"105.00000000","timezones":[{"zoneName":"Asia/Shanghai","gmtOffset":28800,"gmtOffsetName":"UTC+08:00","abbreviation":"CST","tzName":"China Standard Time"},{"zoneName":"Asia/Urumqi","gmtOffset":21600,"gmtOffsetName":"UTC+06:00","abbreviation":"XJT","tzName":"China Standard Time"}]},{"name":"Christmas Island","isoCode":"CX","flag":"ð¨ð½","phonecode":"61","currency":"AUD","latitude":"-10.50000000","longitude":"105.66666666","timezones":[{"zoneName":"Indian/Christmas","gmtOffset":25200,"gmtOffsetName":"UTC+07:00","abbreviation":"CXT","tzName":"Christmas Island Time"}]},{"name":"Cocos (Keeling) Islands","isoCode":"CC","flag":"ð¨ð¨","phonecode":"61","currency":"AUD","latitude":"-12.50000000","longitude":"96.83333333","timezones":[{"zoneName":"Indian/Cocos","gmtOffset":23400,"gmtOffsetName":"UTC+06:30","abbreviation":"CCT","tzName":"Cocos Islands Time"}]},{"name":"Colombia","isoCode":"CO","flag":"ð¨ð´","phonecode":"57","currency":"COP","latitude":"4.00000000","longitude":"-72.00000000","timezones":[{"zoneName":"America/Bogota","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"COT","tzName":"Colombia Time"}]},{"name":"Comoros","isoCode":"KM","flag":"ð°ð²","phonecode":"269","currency":"KMF","latitude":"-12.16666666","longitude":"44.25000000","timezones":[{"zoneName":"Indian/Comoro","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"EAT","tzName":"East Africa Time"}]},{"name":"Congo","isoCode":"CG","flag":"ð¨ð¬","phonecode":"242","currency":"XAF","latitude":"-1.00000000","longitude":"15.00000000","timezones":[{"zoneName":"Africa/Brazzaville","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"WAT","tzName":"West Africa Time"}]},{"name":"Democratic Republic of the Congo","isoCode":"CD","flag":"ð¨ð©","phonecode":"243","currency":"CDF","latitude":"0.00000000","longitude":"25.00000000","timezones":[{"zoneName":"Africa/Kinshasa","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"WAT","tzName":"West Africa Time"},{"zoneName":"Africa/Lubumbashi","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"CAT","tzName":"Central Africa Time"}]},{"name":"Cook Islands","isoCode":"CK","flag":"ð¨ð°","phonecode":"682","currency":"NZD","latitude":"-21.23333333","longitude":"-159.76666666","timezones":[{"zoneName":"Pacific/Rarotonga","gmtOffset":-36000,"gmtOffsetName":"UTC-10:00","abbreviation":"CKT","tzName":"Cook Island Time"}]},{"name":"Costa Rica","isoCode":"CR","flag":"ð¨ð·","phonecode":"506","currency":"CRC","latitude":"10.00000000","longitude":"-84.00000000","timezones":[{"zoneName":"America/Costa_Rica","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"}]}
1,{"name":"Cote D\'Ivoire (Ivory Coast)","isoCode":"CI","flag":"ð¨ð®","phonecode":"225","currency":"XOF","latitude":"8.00000000","longitude":"-5.00000000","timezones":[{"zoneName":"Africa/Abidjan","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Croatia","isoCode":"HR","flag":"ðð·","phonecode":"385","currency":"HRK","latitude":"45.16666666","longitude":"15.50000000","timezones":[{"zoneName":"Europe/Zagreb","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Cuba","isoCode":"CU","flag":"ð¨ðº","phonecode":"53","currency":"CUP","latitude":"21.50000000","longitude":"-80.00000000","timezones":[{"zoneName":"America/Havana","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"CST","tzName":"Cuba Standard Time"}]},{"name":"Cyprus","isoCode":"CY","flag":"ð¨ð¾","phonecode":"357","currency":"EUR","latitude":"35.00000000","longitude":"33.00000000","timezones":[{"zoneName":"Asia/Famagusta","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"},{"zoneName":"Asia/Nicosia","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Czech Republic","isoCode":"CZ","flag":"ð¨ð¿","phonecode":"420","currency":"CZK","latitude":"49.75000000","longitude":"15.50000000","timezones":[{"zoneName":"Europe/Prague","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Denmark","isoCode":"DK","flag":"ð©ð°","phonecode":"45","currency":"DKK","latitude":"56.00000000","longitude":"10.00000000","timezones":[{"zoneName":"Europe/Copenhagen","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Djibouti","isoCode":"DJ","flag":"ð©ð¯","phonecode":"253","currency":"DJF","latitude":"11.50000000","longitude":"43.00000000","timezones":[{"zoneName":"Africa/Djibouti","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"EAT","tzName":"East Africa Time"}]},{"name":"Dominica","isoCode":"DM","flag":"ð©ð²","phonecode":"+1-767","currency":"XCD","latitude":"15.41666666","longitude":"-61.33333333","timezones":[{"zoneName":"America/Dominica","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Dominican Republic","isoCode":"DO","flag":"ð©ð´","phonecode":"+1-809 and 1-829","currency":"DOP","latitude":"19.00000000","longitude":"-70.66666666","timezones":[{"zoneName":"America/Santo_Domingo","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"East Timor","isoCode":"TL","flag":"ð¹ð±","phonecode":"670","currency":"USD","latitude":"-8.83333333","longitude":"125.91666666","timezones":[{"zoneName":"Asia/Dili","gmtOffset":32400,"gmtOffsetName":"UTC+09:00","abbreviation":"TLT","tzName":"Timor Leste Time"}]},{"name":"Ecuador","isoCode":"EC","flag":"ðªð¨","phonecode":"593","currency":"USD","latitude":"-2.00000000","longitude":"-77.50000000","timezones":[{"zoneName":"America/Guayaquil","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"ECT","tzName":"Ecuador Time"},{"zoneName":"Pacific/Galapagos","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"GALT","tzName":"Galápagos Time"}]},{"name":"Egypt","isoCode":"EG","flag":"ðªð¬","phonecode":"20","currency":"EGP","latitude":"27.00000000","longitude":"30.00000000","timezones":[{"zoneName":"Africa/Cairo","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"El Salvador","isoCode":"SV","flag":"ð¸ð»","phonecode":"503","currency":"USD","latitude":"13.83333333","longitude":"-88.91666666","timezones":[{"zoneName":"America/El_Salvador","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"}]},{"name":"Equatorial Guinea","isoCode":"GQ","flag":"ð¬ð¶","phonecode":"240","currency":"XAF","latitude":"2.00000000","longitude":"10.00000000","timezones":[{"zoneName":"Africa/Malabo","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"WAT","tzName":"West Africa Time"}]}
1,{"name":"Eritrea","isoCode":"ER","flag":"ðªð·","phonecode":"291","currency":"ERN","latitude":"15.00000000","longitude":"39.00000000","timezones":[{"zoneName":"Africa/Asmara","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"EAT","tzName":"East Africa Time"}]},{"name":"Estonia","isoCode":"EE","flag":"ðªðª","phonecode":"372","currency":"EUR","latitude":"59.00000000","longitude":"26.00000000","timezones":[{"zoneName":"Europe/Tallinn","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Ethiopia","isoCode":"ET","flag":"ðªð¹","phonecode":"251","currency":"ETB","latitude":"8.00000000","longitude":"38.00000000","timezones":[{"zoneName":"Africa/Addis_Ababa","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"EAT","tzName":"East Africa Time"}]},{"name":"Falkland Islands","isoCode":"FK","flag":"ð«ð°","phonecode":"500","currency":"FKP","latitude":"-51.75000000","longitude":"-59.00000000","timezones":[{"zoneName":"Atlantic/Stanley","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"FKST","tzName":"Falkland Islands Summer Time"}]},{"name":"Faroe Islands","isoCode":"FO","flag":"ð«ð´","phonecode":"298","currency":"DKK","latitude":"62.00000000","longitude":"-7.00000000","timezones":[{"zoneName":"Atlantic/Faroe","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"WET","tzName":"Western European Time"}]},{"name":"Fiji Islands","isoCode":"FJ","flag":"ð«ð¯","phonecode":"679","currency":"FJD","latitude":"-18.00000000","longitude":"175.00000000","timezones":[{"zoneName":"Pacific/Fiji","gmtOffset":43200,"gmtOffsetName":"UTC+12:00","abbreviation":"FJT","tzName":"Fiji Time"}]},{"name":"Finland","isoCode":"FI","flag":"ð«ð®","phonecode":"358","currency":"EUR","latitude":"64.00000000","longitude":"26.00000000","timezones":[{"zoneName":"Europe/Helsinki","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"France","isoCode":"FR","flag":"ð«ð·","phonecode":"33","currency":"EUR","latitude":"46.00000000","longitude":"2.00000000","timezones":[{"zoneName":"Europe/Paris","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"French Guiana","isoCode":"GF","flag":"ð¬ð«","phonecode":"594","currency":"EUR","latitude":"4.00000000","longitude":"-53.00000000","timezones":[{"zoneName":"America/Cayenne","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"GFT","tzName":"French Guiana Time"}]},{"name":"French Polynesia","isoCode":"PF","flag":"ðµð«","phonecode":"689","currency":"XPF","latitude":"-15.00000000","longitude":"-140.00000000","timezones":[{"zoneName":"Pacific/Gambier","gmtOffset":-32400,"gmtOffsetName":"UTC-09:00","abbreviation":"GAMT","tzName":"Gambier Islands Time"},{"zoneName":"Pacific/Marquesas","gmtOffset":-34200,"gmtOffsetName":"UTC-09:30","abbreviation":"MART","tzName":"Marquesas Islands Time"},{"zoneName":"Pacific/Tahiti","gmtOffset":-36000,"gmtOffsetName":"UTC-10:00","abbreviation":"TAHT","tzName":"Tahiti Time"}]},{"name":"French Southern Territories","isoCode":"TF","flag":"ð¹ð«","phonecode":"262","currency":"EUR","latitude":"-49.25000000","longitude":"69.16700000","timezones":[{"zoneName":"Indian/Kerguelen","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"TFT","tzName":"French Southern and Antarctic Time"}]},{"name":"Gabon","isoCode":"GA","flag":"ð¬ð¦","phonecode":"241","currency":"XAF","latitude":"-1.00000000","longitude":"11.75000000","timezones":[{"zoneName":"Africa/Libreville","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"WAT","tzName":"West Africa Time"}]},{"name":"The Gambia","isoCode":"GM","flag":"ð¬ð²","phonecode":"220","currency":"GMD","latitude":"13.46666666","longitude":"-16.56666666","timezones":[{"zoneName":"Africa/Banjul","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Georgia","isoCode":"GE","flag":"ð¬ðª","phonecode":"995","currency":"GEL","latitude":"42.00000000","longitude":"43.50000000","timezones":[{"zoneName":"Asia/Tbilisi","gmtOffset":14400,"gmtOffsetName":"UTC+04:00","abbreviation":"GET","tzName":"Georgia Standard Time"}]}
1,{"name":"Germany","isoCode":"DE","flag":"ð©ðª","phonecode":"49","currency":"EUR","latitude":"51.00000000","longitude":"9.00000000","timezones":[{"zoneName":"Europe/Berlin","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"},{"zoneName":"Europe/Busingen","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Ghana","isoCode":"GH","flag":"ð¬ð","phonecode":"233","currency":"GHS","latitude":"8.00000000","longitude":"-2.00000000","timezones":[{"zoneName":"Africa/Accra","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Gibraltar","isoCode":"GI","flag":"ð¬ð®","phonecode":"350","currency":"GIP","latitude":"36.13333333","longitude":"-5.35000000","timezones":[{"zoneName":"Europe/Gibraltar","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Greece","isoCode":"GR","flag":"ð¬ð·","phonecode":"30","currency":"EUR","latitude":"39.00000000","longitude":"22.00000000","timezones":[{"zoneName":"Europe/Athens","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Greenland","isoCode":"GL","flag":"ð¬ð±","phonecode":"299","currency":"DKK","latitude":"72.00000000","longitude":"-40.00000000","timezones":[{"zoneName":"America/Danmarkshavn","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"},{"zoneName":"America/Nuuk","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"WGT","tzName":"West Greenland Time"},{"zoneName":"America/Scoresbysund","gmtOffset":-3600,"gmtOffsetName":"UTC-01:00","abbreviation":"EGT","tzName":"Eastern Greenland Time"},{"zoneName":"America/Thule","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Grenada","isoCode":"GD","flag":"ð¬ð©","phonecode":"+1-473","currency":"XCD","latitude":"12.11666666","longitude":"-61.66666666","timezones":[{"zoneName":"America/Grenada","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Guadeloupe","isoCode":"GP","flag":"ð¬ðµ","phonecode":"590","currency":"EUR","latitude":"16.25000000","longitude":"-61.58333300","timezones":[{"zoneName":"America/Guadeloupe","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Guam","isoCode":"GU","flag":"ð¬ðº","phonecode":"+1-671","currency":"USD","latitude":"13.46666666","longitude":"144.78333333","timezones":[{"zoneName":"Pacific/Guam","gmtOffset":36000,"gmtOffsetName":"UTC+10:00","abbreviation":"CHST","tzName":"Chamorro Standard Time"}]},{"name":"Guatemala","isoCode":"GT","flag":"ð¬ð¹","phonecode":"502","currency":"GTQ","latitude":"15.50000000","longitude":"-90.25000000","timezones":[{"zoneName":"America/Guatemala","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"}]},{"name":"Guernsey and Alderney","isoCode":"GG","flag":"ð¬ð¬","phonecode":"+44-1481","currency":"GBP","latitude":"49.46666666","longitude":"-2.58333333","timezones":[{"zoneName":"Europe/Guernsey","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Guinea","isoCode":"GN","flag":"ð¬ð³","phonecode":"224","currency":"GNF","latitude":"11.00000000","longitude":"-10.00000000","timezones":[{"zoneName":"Africa/Conakry","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Guinea-Bissau","isoCode":"GW","flag":"ð¬ð¼","phonecode":"245","currency":"XOF","latitude":"12.00000000","longitude":"-15.00000000","timezones":[{"zoneName":"Africa/Bissau","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Guyana","isoCode":"GY","flag":"ð¬ð¾","phonecode":"592","currency":"GYD","latitude":"5.00000000","longitude":"-59.00000000","timezones":[{"zoneName":"America/Guyana","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"GYT","tzName":"Guyana Time"}]}
1,{"name":"Haiti","isoCode":"HT","flag":"ðð¹","phonecode":"509","currency":"HTG","latitude":"19.00000000","longitude":"-72.41666666","timezones":[{"zoneName":"America/Port-au-Prince","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"}]},{"name":"Heard Island and McDonald Islands","isoCode":"HM","flag":"ðð²","phonecode":"672","currency":"AUD","latitude":"-53.10000000","longitude":"72.51666666","timezones":[{"zoneName":"Indian/Kerguelen","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"TFT","tzName":"French Southern and Antarctic Time"}]},{"name":"Honduras","isoCode":"HN","flag":"ðð³","phonecode":"504","currency":"HNL","latitude":"15.00000000","longitude":"-86.50000000","timezones":[{"zoneName":"America/Tegucigalpa","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"}]},{"name":"Hong Kong S.A.R.","isoCode":"HK","flag":"ðð°","phonecode":"852","currency":"HKD","latitude":"22.25000000","longitude":"114.16666666","timezones":[{"zoneName":"Asia/Hong_Kong","gmtOffset":28800,"gmtOffsetName":"UTC+08:00","abbreviation":"HKT","tzName":"Hong Kong Time"}]},{"name":"Hungary","isoCode":"HU","flag":"ððº","phonecode":"36","currency":"HUF","latitude":"47.00000000","longitude":"20.00000000","timezones":[{"zoneName":"Europe/Budapest","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Iceland","isoCode":"IS","flag":"ð®ð¸","phonecode":"354","currency":"ISK","latitude":"65.00000000","longitude":"-18.00000000","timezones":[{"zoneName":"Atlantic/Reykjavik","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"India","isoCode":"IN","flag":"ð®ð³","phonecode":"91","currency":"INR","latitude":"20.00000000","longitude":"77.00000000","timezones":[{"zoneName":"Asia/Kolkata","gmtOffset":19800,"gmtOffsetName":"UTC+05:30","abbreviation":"IST","tzName":"Indian Standard Time"}]},{"name":"Indonesia","isoCode":"ID","flag":"ð®ð©","phonecode":"62","currency":"IDR","latitude":"-5.00000000","longitude":"120.00000000","timezones":[{"zoneName":"Asia/Jakarta","gmtOffset":25200,"gmtOffsetName":"UTC+07:00","abbreviation":"WIB","tzName":"Western Indonesian Time"},{"zoneName":"Asia/Jayapura","gmtOffset":32400,"gmtOffsetName":"UTC+09:00","abbreviation":"WIT","tzName":"Eastern Indonesian Time"},{"zoneName":"Asia/Makassar","gmtOffset":28800,"gmtOffsetName":"UTC+08:00","abbreviation":"WITA","tzName":"Central Indonesia Time"},{"zoneName":"Asia/Pontianak","gmtOffset":25200,"gmtOffsetName":"UTC+07:00","abbreviation":"WIB","tzName":"Western Indonesian Time"}]},{"name":"Iran","isoCode":"IR","flag":"ð®ð·","phonecode":"98","currency":"IRR","latitude":"32.00000000","longitude":"53.00000000","timezones":[{"zoneName":"Asia/Tehran","gmtOffset":12600,"gmtOffsetName":"UTC+03:30","abbreviation":"IRDT","tzName":"Iran Daylight Time"}]},{"name":"Iraq","isoCode":"IQ","flag":"ð®ð¶","phonecode":"964","currency":"IQD","latitude":"33.00000000","longitude":"44.00000000","timezones":[{"zoneName":"Asia/Baghdad","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"AST","tzName":"Arabia Standard Time"}]},{"name":"Ireland","isoCode":"IE","flag":"ð®ðª","phonecode":"353","currency":"EUR","latitude":"53.00000000","longitude":"-8.00000000","timezones":[{"zoneName":"Europe/Dublin","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Israel","isoCode":"IL","flag":"ð®ð±","phonecode":"972","currency":"ILS","latitude":"31.50000000","longitude":"34.75000000","timezones":[{"zoneName":"Asia/Jerusalem","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"IST","tzName":"Israel Standard Time"}]},{"name":"Italy","isoCode":"IT","flag":"ð®ð¹","phonecode":"39","currency":"EUR","latitude":"42.83333333","longitude":"12.83333333","timezones":[{"zoneName":"Europe/Rome","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]}
1,{"name":"Jamaica","isoCode":"JM","flag":"ð¯ð²","phonecode":"+1-876","currency":"JMD","latitude":"18.25000000","longitude":"-77.50000000","timezones":[{"zoneName":"America/Jamaica","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"}]},{"name":"Japan","isoCode":"JP","flag":"ð¯ðµ","phonecode":"81","currency":"JPY","latitude":"36.00000000","longitude":"138.00000000","timezones":[{"zoneName":"Asia/Tokyo","gmtOffset":32400,"gmtOffsetName":"UTC+09:00","abbreviation":"JST","tzName":"Japan Standard Time"}]},{"name":"Jersey","isoCode":"JE","flag":"ð¯ðª","phonecode":"+44-1534","currency":"GBP","latitude":"49.25000000","longitude":"-2.16666666","timezones":[{"zoneName":"Europe/Jersey","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Jordan","isoCode":"JO","flag":"ð¯ð´","phonecode":"962","currency":"JOD","latitude":"31.00000000","longitude":"36.00000000","timezones":[{"zoneName":"Asia/Amman","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Kazakhstan","isoCode":"KZ","flag":"ð°ð¿","phonecode":"7","currency":"KZT","latitude":"48.00000000","longitude":"68.00000000","timezones":[{"zoneName":"Asia/Almaty","gmtOffset":21600,"gmtOffsetName":"UTC+06:00","abbreviation":"ALMT","tzName":"Alma-Ata Time[1"},{"zoneName":"Asia/Aqtau","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"AQTT","tzName":"Aqtobe Time"},{"zoneName":"Asia/Aqtobe","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"AQTT","tzName":"Aqtobe Time"},{"zoneName":"Asia/Atyrau","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"MSD+1","tzName":"Moscow Daylight Time+1"},{"zoneName":"Asia/Oral","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"ORAT","tzName":"Oral Time"},{"zoneName":"Asia/Qostanay","gmtOffset":21600,"gmtOffsetName":"UTC+06:00","abbreviation":"QYZST","tzName":"Qyzylorda Summer Time"},{"zoneName":"Asia/Qyzylorda","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"QYZT","tzName":"Qyzylorda Summer Time"}]},{"name":"Kenya","isoCode":"KE","flag":"ð°ðª","phonecode":"254","currency":"KES","latitude":"1.00000000","longitude":"38.00000000","timezones":[{"zoneName":"Africa/Nairobi","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"EAT","tzName":"East Africa Time"}]},{"name":"Kiribati","isoCode":"KI","flag":"ð°ð®","phonecode":"686","currency":"AUD","latitude":"1.41666666","longitude":"173.00000000","timezones":[{"zoneName":"Pacific/Enderbury","gmtOffset":46800,"gmtOffsetName":"UTC+13:00","abbreviation":"PHOT","tzName":"Phoenix Island Time"},{"zoneName":"Pacific/Kiritimati","gmtOffset":50400,"gmtOffsetName":"UTC+14:00","abbreviation":"LINT","tzName":"Line Islands Time"},{"zoneName":"Pacific/Tarawa","gmtOffset":43200,"gmtOffsetName":"UTC+12:00","abbreviation":"GILT","tzName":"Gilbert Island Time"}]},{"name":"North Korea","isoCode":"KP","flag":"ð°ðµ","phonecode":"850","currency":"KPW","latitude":"40.00000000","longitude":"127.00000000","timezones":[{"zoneName":"Asia/Pyongyang","gmtOffset":32400,"gmtOffsetName":"UTC+09:00","abbreviation":"KST","tzName":"Korea Standard Time"}]},{"name":"South Korea","isoCode":"KR","flag":"ð°ð·","phonecode":"82","currency":"KRW","latitude":"37.00000000","longitude":"127.50000000","timezones":[{"zoneName":"Asia/Seoul","gmtOffset":32400,"gmtOffsetName":"UTC+09:00","abbreviation":"KST","tzName":"Korea Standard Time"}]},{"name":"Kuwait","isoCode":"KW","flag":"ð°ð¼","phonecode":"965","currency":"KWD","latitude":"29.50000000","longitude":"45.75000000","timezones":[{"zoneName":"Asia/Kuwait","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"AST","tzName":"Arabia Standard Time"}]},{"name":"Kyrgyzstan","isoCode":"KG","flag":"ð°ð¬","phonecode":"996","currency":"KGS","latitude":"41.00000000","longitude":"75.00000000","timezones":[{"zoneName":"Asia/Bishkek","gmtOffset":21600,"gmtOffsetName":"UTC+06:00","abbreviation":"KGT","tzName":"Kyrgyzstan Time"}]},{"name":"Laos","isoCode":"LA","flag":"ð±ð¦","phonecode":"856","currency":"LAK","latitude":"18.00000000","longitude":"105.00000000","timezones":[{"zoneName":"Asia/Vientiane","gmtOffset":25200,"gmtOffsetName":"UTC+07:00","abbreviation":"ICT","tzName":"Indochina Time"}]}
1,{"name":"Latvia","isoCode":"LV","flag":"ð±ð»","phonecode":"371","currency":"EUR","latitude":"57.00000000","longitude":"25.00000000","timezones":[{"zoneName":"Europe/Riga","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Lebanon","isoCode":"LB","flag":"ð±ð§","phonecode":"961","currency":"LBP","latitude":"33.83333333","longitude":"35.83333333","timezones":[{"zoneName":"Asia/Beirut","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Lesotho","isoCode":"LS","flag":"ð±ð¸","phonecode":"266","currency":"LSL","latitude":"-29.50000000","longitude":"28.50000000","timezones":[{"zoneName":"Africa/Maseru","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"SAST","tzName":"South African Standard Time"}]},{"name":"Liberia","isoCode":"LR","flag":"ð±ð·","phonecode":"231","currency":"LRD","latitude":"6.50000000","longitude":"-9.50000000","timezones":[{"zoneName":"Africa/Monrovia","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Libya","isoCode":"LY","flag":"ð±ð¾","phonecode":"218","currency":"LYD","latitude":"25.00000000","longitude":"17.00000000","timezones":[{"zoneName":"Africa/Tripoli","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Liechtenstein","isoCode":"LI","flag":"ð±ð®","phonecode":"423","currency":"CHF","latitude":"47.26666666","longitude":"9.53333333","timezones":[{"zoneName":"Europe/Vaduz","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Lithuania","isoCode":"LT","flag":"ð±ð¹","phonecode":"370","currency":"EUR","latitude":"56.00000000","longitude":"24.00000000","timezones":[{"zoneName":"Europe/Vilnius","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Luxembourg","isoCode":"LU","flag":"ð±ðº","phonecode":"352","currency":"EUR","latitude":"49.75000000","longitude":"6.16666666","timezones":[{"zoneName":"Europe/Luxembourg","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Macau S.A.R.","isoCode":"MO","flag":"ð²ð´","phonecode":"853","currency":"MOP","latitude":"22.16666666","longitude":"113.55000000","timezones":[{"zoneName":"Asia/Macau","gmtOffset":28800,"gmtOffsetName":"UTC+08:00","abbreviation":"CST","tzName":"China Standard Time"}]},{"name":"Macedonia","isoCode":"MK","flag":"ð²ð°","phonecode":"389","currency":"MKD","latitude":"41.83333333","longitude":"22.00000000","timezones":[{"zoneName":"Europe/Skopje","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Madagascar","isoCode":"MG","flag":"ð²ð¬","phonecode":"261","currency":"MGA","latitude":"-20.00000000","longitude":"47.00000000","timezones":[{"zoneName":"Indian/Antananarivo","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"EAT","tzName":"East Africa Time"}]},{"name":"Malawi","isoCode":"MW","flag":"ð²ð¼","phonecode":"265","currency":"MWK","latitude":"-13.50000000","longitude":"34.00000000","timezones":[{"zoneName":"Africa/Blantyre","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"CAT","tzName":"Central Africa Time"}]},{"name":"Malaysia","isoCode":"MY","flag":"ð²ð¾","phonecode":"60","currency":"MYR","latitude":"2.50000000","longitude":"112.50000000","timezones":[{"zoneName":"Asia/Kuala_Lumpur","gmtOffset":28800,"gmtOffsetName":"UTC+08:00","abbreviation":"MYT","tzName":"Malaysia Time"},{"zoneName":"Asia/Kuching","gmtOffset":28800,"gmtOffsetName":"UTC+08:00","abbreviation":"MYT","tzName":"Malaysia Time"}]},{"name":"Maldives","isoCode":"MV","flag":"ð²ð»","phonecode":"960","currency":"MVR","latitude":"3.25000000","longitude":"73.00000000","timezones":[{"zoneName":"Indian/Maldives","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"MVT","tzName":"Maldives Time"}]},{"name":"Mali","isoCode":"ML","flag":"ð²ð±","phonecode":"223","currency":"XOF","latitude":"17.00000000","longitude":"-4.00000000","timezones":[{"zoneName":"Africa/Bamako","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]}
1,{"name":"Malta","isoCode":"MT","flag":"ð²ð¹","phonecode":"356","currency":"EUR","latitude":"35.83333333","longitude":"14.58333333","timezones":[{"zoneName":"Europe/Malta","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Man (Isle of)","isoCode":"IM","flag":"ð®ð²","phonecode":"+44-1624","currency":"GBP","latitude":"54.25000000","longitude":"-4.50000000","timezones":[{"zoneName":"Europe/Isle_of_Man","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Marshall Islands","isoCode":"MH","flag":"ð²ð","phonecode":"692","currency":"USD","latitude":"9.00000000","longitude":"168.00000000","timezones":[{"zoneName":"Pacific/Kwajalein","gmtOffset":43200,"gmtOffsetName":"UTC+12:00","abbreviation":"MHT","tzName":"Marshall Islands Time"},{"zoneName":"Pacific/Majuro","gmtOffset":43200,"gmtOffsetName":"UTC+12:00","abbreviation":"MHT","tzName":"Marshall Islands Time"}]},{"name":"Martinique","isoCode":"MQ","flag":"ð²ð¶","phonecode":"596","currency":"EUR","latitude":"14.66666700","longitude":"-61.00000000","timezones":[{"zoneName":"America/Martinique","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Mauritania","isoCode":"MR","flag":"ð²ð·","phonecode":"222","currency":"MRO","latitude":"20.00000000","longitude":"-12.00000000","timezones":[{"zoneName":"Africa/Nouakchott","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Mauritius","isoCode":"MU","flag":"ð²ðº","phonecode":"230","currency":"MUR","latitude":"-20.28333333","longitude":"57.55000000","timezones":[{"zoneName":"Indian/Mauritius","gmtOffset":14400,"gmtOffsetName":"UTC+04:00","abbreviation":"MUT","tzName":"Mauritius Time"}]},{"name":"Mayotte","isoCode":"YT","flag":"ð¾ð¹","phonecode":"262","currency":"EUR","latitude":"-12.83333333","longitude":"45.16666666","timezones":[{"zoneName":"Indian/Mayotte","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"EAT","tzName":"East Africa Time"}]},{"name":"Mexico","isoCode":"MX","flag":"ð²ð½","phonecode":"52","currency":"MXN","latitude":"23.00000000","longitude":"-102.00000000","timezones":[{"zoneName":"America/Bahia_Banderas","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Cancun","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Chihuahua","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America"},{"zoneName":"America/Hermosillo","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America"},{"zoneName":"America/Matamoros","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Mazatlan","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America"},{"zoneName":"America/Merida","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Mexico_City","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Monterrey","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Ojinaga","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America"},{"zoneName":"America/Tijuana","gmtOffset":-28800,"gmtOffsetName":"UTC-08:00","abbreviation":"PST","tzName":"Pacific Standard Time (North America"}]},{"name":"Micronesia","isoCode":"FM","flag":"ð«ð²","phonecode":"691","currency":"USD","latitude":"6.91666666","longitude":"158.25000000","timezones":[{"zoneName":"Pacific/Chuuk","gmtOffset":36000,"gmtOffsetName":"UTC+10:00","abbreviation":"CHUT","tzName":"Chuuk Time"},{"zoneName":"Pacific/Kosrae","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"KOST","tzName":"Kosrae Time"},{"zoneName":"Pacific/Pohnpei","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"PONT","tzName":"Pohnpei Standard Time"}]}
1,{"name":"Moldova","isoCode":"MD","flag":"ð²ð©","phonecode":"373","currency":"MDL","latitude":"47.00000000","longitude":"29.00000000","timezones":[{"zoneName":"Europe/Chisinau","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Monaco","isoCode":"MC","flag":"ð²ð¨","phonecode":"377","currency":"EUR","latitude":"43.73333333","longitude":"7.40000000","timezones":[{"zoneName":"Europe/Monaco","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Mongolia","isoCode":"MN","flag":"ð²ð³","phonecode":"976","currency":"MNT","latitude":"46.00000000","longitude":"105.00000000","timezones":[{"zoneName":"Asia/Choibalsan","gmtOffset":28800,"gmtOffsetName":"UTC+08:00","abbreviation":"CHOT","tzName":"Choibalsan Standard Time"},{"zoneName":"Asia/Hovd","gmtOffset":25200,"gmtOffsetName":"UTC+07:00","abbreviation":"HOVT","tzName":"Hovd Time"},{"zoneName":"Asia/Ulaanbaatar","gmtOffset":28800,"gmtOffsetName":"UTC+08:00","abbreviation":"ULAT","tzName":"Ulaanbaatar Standard Time"}]},{"name":"Montenegro","isoCode":"ME","flag":"ð²ðª","phonecode":"382","currency":"EUR","latitude":"42.50000000","longitude":"19.30000000","timezones":[{"zoneName":"Europe/Podgorica","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Montserrat","isoCode":"MS","flag":"ð²ð¸","phonecode":"+1-664","currency":"XCD","latitude":"16.75000000","longitude":"-62.20000000","timezones":[{"zoneName":"America/Montserrat","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Morocco","isoCode":"MA","flag":"ð²ð¦","phonecode":"212","currency":"MAD","latitude":"32.00000000","longitude":"-5.00000000","timezones":[{"zoneName":"Africa/Casablanca","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"WEST","tzName":"Western European Summer Time"}]},{"name":"Mozambique","isoCode":"MZ","flag":"ð²ð¿","phonecode":"258","currency":"MZN","latitude":"-18.25000000","longitude":"35.00000000","timezones":[{"zoneName":"Africa/Maputo","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"CAT","tzName":"Central Africa Time"}]},{"name":"Myanmar","isoCode":"MM","flag":"ð²ð²","phonecode":"95","currency":"MMK","latitude":"22.00000000","longitude":"98.00000000","timezones":[{"zoneName":"Asia/Yangon","gmtOffset":23400,"gmtOffsetName":"UTC+06:30","abbreviation":"MMT","tzName":"Myanmar Standard Time"}]},{"name":"Namibia","isoCode":"NA","flag":"ð³ð¦","phonecode":"264","currency":"NAD","latitude":"-22.00000000","longitude":"17.00000000","timezones":[{"zoneName":"Africa/Windhoek","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"WAST","tzName":"West Africa Summer Time"}]},{"name":"Nauru","isoCode":"NR","flag":"ð³ð·","phonecode":"674","currency":"AUD","latitude":"-0.53333333","longitude":"166.91666666","timezones":[{"zoneName":"Pacific/Nauru","gmtOffset":43200,"gmtOffsetName":"UTC+12:00","abbreviation":"NRT","tzName":"Nauru Time"}]},{"name":"Nepal","isoCode":"NP","flag":"ð³ðµ","phonecode":"977","currency":"NPR","latitude":"28.00000000","longitude":"84.00000000","timezones":[{"zoneName":"Asia/Kathmandu","gmtOffset":20700,"gmtOffsetName":"UTC+05:45","abbreviation":"NPT","tzName":"Nepal Time"}]},{"name":"Bonaire, Sint Eustatius and Saba","isoCode":"BQ","flag":"ð§ð¶","phonecode":"599","currency":"USD","latitude":"12.15000000","longitude":"-68.26666700","timezones":[{"zoneName":"America/Anguilla","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Netherlands","isoCode":"NL","flag":"ð³ð±","phonecode":"31","currency":"EUR","latitude":"52.50000000","longitude":"5.75000000","timezones":[{"zoneName":"Europe/Amsterdam","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"New Caledonia","isoCode":"NC","flag":"ð³ð¨","phonecode":"687","currency":"XPF","latitude":"-21.50000000","longitude":"165.50000000","timezones":[{"zoneName":"Pacific/Noumea","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"NCT","tzName":"New Caledonia Time"}]}
1,{"name":"New Zealand","isoCode":"NZ","flag":"ð³ð¿","phonecode":"64","currency":"NZD","latitude":"-41.00000000","longitude":"174.00000000","timezones":[{"zoneName":"Pacific/Auckland","gmtOffset":46800,"gmtOffsetName":"UTC+13:00","abbreviation":"NZDT","tzName":"New Zealand Daylight Time"},{"zoneName":"Pacific/Chatham","gmtOffset":49500,"gmtOffsetName":"UTC+13:45","abbreviation":"CHAST","tzName":"Chatham Standard Time"}]},{"name":"Nicaragua","isoCode":"NI","flag":"ð³ð®","phonecode":"505","currency":"NIO","latitude":"13.00000000","longitude":"-85.00000000","timezones":[{"zoneName":"America/Managua","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"}]},{"name":"Niger","isoCode":"NE","flag":"ð³ðª","phonecode":"227","currency":"XOF","latitude":"16.00000000","longitude":"8.00000000","timezones":[{"zoneName":"Africa/Niamey","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"WAT","tzName":"West Africa Time"}]},{"name":"Nigeria","isoCode":"NG","flag":"ð³ð¬","phonecode":"234","currency":"NGN","latitude":"10.00000000","longitude":"8.00000000","timezones":[{"zoneName":"Africa/Lagos","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"WAT","tzName":"West Africa Time"}]},{"name":"Niue","isoCode":"NU","flag":"ð³ðº","phonecode":"683","currency":"NZD","latitude":"-19.03333333","longitude":"-169.86666666","timezones":[{"zoneName":"Pacific/Niue","gmtOffset":-39600,"gmtOffsetName":"UTC-11:00","abbreviation":"NUT","tzName":"Niue Time"}]},{"name":"Norfolk Island","isoCode":"NF","flag":"ð³ð«","phonecode":"672","currency":"AUD","latitude":"-29.03333333","longitude":"167.95000000","timezones":[{"zoneName":"Pacific/Norfolk","gmtOffset":43200,"gmtOffsetName":"UTC+12:00","abbreviation":"NFT","tzName":"Norfolk Time"}]},{"name":"Northern Mariana Islands","isoCode":"MP","flag":"ð²ðµ","phonecode":"+1-670","currency":"USD","latitude":"15.20000000","longitude":"145.75000000","timezones":[{"zoneName":"Pacific/Saipan","gmtOffset":36000,"gmtOffsetName":"UTC+10:00","abbreviation":"ChST","tzName":"Chamorro Standard Time"}]},{"name":"Norway","isoCode":"NO","flag":"ð³ð´","phonecode":"47","currency":"NOK","latitude":"62.00000000","longitude":"10.00000000","timezones":[{"zoneName":"Europe/Oslo","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Oman","isoCode":"OM","flag":"ð´ð²","phonecode":"968","currency":"OMR","latitude":"21.00000000","longitude":"57.00000000","timezones":[{"zoneName":"Asia/Muscat","gmtOffset":14400,"gmtOffsetName":"UTC+04:00","abbreviation":"GST","tzName":"Gulf Standard Time"}]},{"name":"Pakistan","isoCode":"PK","flag":"ðµð°","phonecode":"92","currency":"PKR","latitude":"30.00000000","longitude":"70.00000000","timezones":[{"zoneName":"Asia/Karachi","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"PKT","tzName":"Pakistan Standard Time"}]},{"name":"Palau","isoCode":"PW","flag":"ðµð¼","phonecode":"680","currency":"USD","latitude":"7.50000000","longitude":"134.50000000","timezones":[{"zoneName":"Pacific/Palau","gmtOffset":32400,"gmtOffsetName":"UTC+09:00","abbreviation":"PWT","tzName":"Palau Time"}]},{"name":"Palestinian Territory Occupied","isoCode":"PS","flag":"ðµð¸","phonecode":"970","currency":"ILS","latitude":"31.90000000","longitude":"35.20000000","timezones":[{"zoneName":"Asia/Gaza","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"},{"zoneName":"Asia/Hebron","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Panama","isoCode":"PA","flag":"ðµð¦","phonecode":"507","currency":"PAB","latitude":"9.00000000","longitude":"-80.00000000","timezones":[{"zoneName":"America/Panama","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"}]},{"name":"Papua new Guinea","isoCode":"PG","flag":"ðµð¬","phonecode":"675","currency":"PGK","latitude":"-6.00000000","longitude":"147.00000000","timezones":[{"zoneName":"Pacific/Bougainville","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"BST","tzName":"Bougainville Standard Time[6"},{"zoneName":"Pacific/Port_Moresby","gmtOffset":36000,"gmtOffsetName":"UTC+10:00","abbreviation":"PGT","tzName":"Papua New Guinea Time"}]}
1,{"name":"Paraguay","isoCode":"PY","flag":"ðµð¾","phonecode":"595","currency":"PYG","latitude":"-23.00000000","longitude":"-58.00000000","timezones":[{"zoneName":"America/Asuncion","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"PYST","tzName":"Paraguay Summer Time"}]},{"name":"Peru","isoCode":"PE","flag":"ðµðª","phonecode":"51","currency":"PEN","latitude":"-10.00000000","longitude":"-76.00000000","timezones":[{"zoneName":"America/Lima","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"PET","tzName":"Peru Time"}]},{"name":"Philippines","isoCode":"PH","flag":"ðµð","phonecode":"63","currency":"PHP","latitude":"13.00000000","longitude":"122.00000000","timezones":[{"zoneName":"Asia/Manila","gmtOffset":28800,"gmtOffsetName":"UTC+08:00","abbreviation":"PHT","tzName":"Philippine Time"}]},{"name":"Pitcairn Island","isoCode":"PN","flag":"ðµð³","phonecode":"870","currency":"NZD","latitude":"-25.06666666","longitude":"-130.10000000","timezones":[{"zoneName":"Pacific/Pitcairn","gmtOffset":-28800,"gmtOffsetName":"UTC-08:00","abbreviation":"PST","tzName":"Pacific Standard Time (North America"}]},{"name":"Poland","isoCode":"PL","flag":"ðµð±","phonecode":"48","currency":"PLN","latitude":"52.00000000","longitude":"20.00000000","timezones":[{"zoneName":"Europe/Warsaw","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Portugal","isoCode":"PT","flag":"ðµð¹","phonecode":"351","currency":"EUR","latitude":"39.50000000","longitude":"-8.00000000","timezones":[{"zoneName":"Atlantic/Azores","gmtOffset":-3600,"gmtOffsetName":"UTC-01:00","abbreviation":"AZOT","tzName":"Azores Standard Time"},{"zoneName":"Atlantic/Madeira","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"WET","tzName":"Western European Time"},{"zoneName":"Europe/Lisbon","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"WET","tzName":"Western European Time"}]},{"name":"Puerto Rico","isoCode":"PR","flag":"ðµð·","phonecode":"+1-787 and 1-939","currency":"USD","latitude":"18.25000000","longitude":"-66.50000000","timezones":[{"zoneName":"America/Puerto_Rico","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Qatar","isoCode":"QA","flag":"ð¶ð¦","phonecode":"974","currency":"QAR","latitude":"25.50000000","longitude":"51.25000000","timezones":[{"zoneName":"Asia/Qatar","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"AST","tzName":"Arabia Standard Time"}]},{"name":"Reunion","isoCode":"RE","flag":"ð·ðª","phonecode":"262","currency":"EUR","latitude":"-21.15000000","longitude":"55.50000000","timezones":[{"zoneName":"Indian/Reunion","gmtOffset":14400,"gmtOffsetName":"UTC+04:00","abbreviation":"RET","tzName":"Réunion Time"}]},{"name":"Romania","isoCode":"RO","flag":"ð·ð´","phonecode":"40","currency":"RON","latitude":"46.00000000","longitude":"25.00000000","timezones":[{"zoneName":"Europe/Bucharest","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Russia","isoCode":"RU","flag":"ð·ðº","phonecode":"7","currency":"RUB","latitude":"60.00000000","longitude":"100.00000000","timezones":[{"zoneName":"Asia/Anadyr","gmtOffset":43200,"gmtOffsetName":"UTC+12:00","abbreviation":"ANAT","tzName":"Anadyr Time[4"},{"zoneName":"Asia/Barnaul","gmtOffset":25200,"gmtOffsetName":"UTC+07:00","abbreviation":"KRAT","tzName":"Krasnoyarsk Time"},{"zoneName":"Asia/Chita","gmtOffset":32400,"gmtOffsetName":"UTC+09:00","abbreviation":"YAKT","tzName":"Yakutsk Time"},{"zoneName":"Asia/Irkutsk","gmtOffset":28800,"gmtOffsetName":"UTC+08:00","abbreviation":"IRKT","tzName":"Irkutsk Time"},{"zoneName":"Asia/Kamchatka","gmtOffset":43200,"gmtOffsetName":"UTC+12:00","abbreviation":"PETT","tzName":"Kamchatka Time"},{"zoneName":"Asia/Khandyga","gmtOffset":32400,"gmtOffsetName":"UTC+09:00","abbreviation":"YAKT","tzName":"Yakutsk Time"},{"zoneName":"Asia/Krasnoyarsk","gmtOffset":25200,"gmtOffsetName":"UTC+07:00","abbreviation":"KRAT","tzName":"Krasnoyarsk Time"},{"zoneName":"Asia/Magadan","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"MAGT","tzName":"Magadan Time"},{"zoneName":"Asia/Novokuznetsk","gmtOffset":25200,"gmtOffsetName":"UTC+07:00","abbreviation":"KRAT","tzName":"Krasnoyarsk Time"},{"zoneName":"Asia/Novosibirsk","gmtOffset":25200,"gmtOffsetName":"UTC+07:00","abbreviation":"NOVT","tzName":"Novosibirsk Time"},{"zoneName":"Asia/Omsk","gmtOffset":21600,"gmtOffsetName":"UTC+06:00","abbreviation":"OMST","tzName":"Omsk Time"},{"zoneName":"Asia/Sakhalin","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"SAKT","tzName":"Sakhalin Island Time"},{"zoneName":"Asia/Srednekolymsk","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"SRET","tzName":"Srednekolymsk Time"},{"zoneName":"Asia/Tomsk","gmtOffset":25200,"gmtOffsetName":"UTC+07:00","abbreviation":"MSD+3","tzName":"Moscow Daylight Time+3"},{"zoneName":"Asia/Ust-Nera","gmtOffset":36000,"gmtOffsetName":"UTC+10:00","abbreviation":"VLAT","tzName":"Vladivostok Time"},{"zoneName":"Asia/Vladivostok","gmtOffset":36000,"gmtOffsetName":"UTC+10:00","abbreviation":"VLAT","tzName":"Vladivostok Time"},{"zoneName":"Asia/Yakutsk","gmtOffset":32400,"gmtOffsetName":"UTC+09:00","abbreviation":"YAKT","tzName":"Yakutsk Time"},{"zoneName":"Asia/Yekaterinburg","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"YEKT","tzName":"Yekaterinburg Time"},{"zoneName":"Europe/Astrakhan","gmtOffset":14400,"gmtOffsetName":"UTC+04:00","abbreviation":"SAMT","tzName":"Samara Time"},{"zoneName":"Europe/Kaliningrad","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"},{"zoneName":"Europe/Kirov","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"MSK","tzName":"Moscow Time"},{"zoneName":"Europe/Moscow","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"MSK","tzName":"Moscow Time"},{"zoneName":"Europe/Samara","gmtOffset":14400,"gmtOffsetName":"UTC+04:00","abbreviation":"SAMT","tzName":"Samara Time"},{"zoneName":"Europe/Saratov","gmtOffset":14400,"gmtOffsetName":"UTC+04:00","abbreviation":"MSD","tzName":"Moscow Daylight Time+4"},{"zoneName":"Europe/Ulyanovsk","gmtOffset":14400,"gmtOffsetName":"UTC+04:00","abbreviation":"SAMT","tzName":"Samara Time"},{"zoneName":"Europe/Volgograd","gmtOffset":14400,"gmtOffsetName":"UTC+04:00","abbreviation":"MSK","tzName":"Moscow Standard Time"}]}
1,{"name":"Rwanda","isoCode":"RW","flag":"ð·ð¼","phonecode":"250","currency":"RWF","latitude":"-2.00000000","longitude":"30.00000000","timezones":[{"zoneName":"Africa/Kigali","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"CAT","tzName":"Central Africa Time"}]},{"name":"Saint Helena","isoCode":"SH","flag":"ð¸ð","phonecode":"290","currency":"SHP","latitude":"-15.95000000","longitude":"-5.70000000","timezones":[{"zoneName":"Atlantic/St_Helena","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Saint Kitts And Nevis","isoCode":"KN","flag":"ð°ð³","phonecode":"+1-869","currency":"XCD","latitude":"17.33333333","longitude":"-62.75000000","timezones":[{"zoneName":"America/St_Kitts","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Saint Lucia","isoCode":"LC","flag":"ð±ð¨","phonecode":"+1-758","currency":"XCD","latitude":"13.88333333","longitude":"-60.96666666","timezones":[{"zoneName":"America/St_Lucia","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Saint Pierre and Miquelon","isoCode":"PM","flag":"ðµð²","phonecode":"508","currency":"EUR","latitude":"46.83333333","longitude":"-56.33333333","timezones":[{"zoneName":"America/Miquelon","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"PMDT","tzName":"Pierre & Miquelon Daylight Time"}]},{"name":"Saint Vincent And The Grenadines","isoCode":"VC","flag":"ð»ð¨","phonecode":"+1-784","currency":"XCD","latitude":"13.25000000","longitude":"-61.20000000","timezones":[{"zoneName":"America/St_Vincent","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Saint-Barthelemy","isoCode":"BL","flag":"ð§ð±","phonecode":"590","currency":"EUR","latitude":"18.50000000","longitude":"-63.41666666","timezones":[{"zoneName":"America/St_Barthelemy","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Saint-Martin (French part)","isoCode":"MF","flag":"ð²ð«","phonecode":"590","currency":"EUR","latitude":"18.08333333","longitude":"-63.95000000","timezones":[{"zoneName":"America/Marigot","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Samoa","isoCode":"WS","flag":"ð¼ð¸","phonecode":"685","currency":"WST","latitude":"-13.58333333","longitude":"-172.33333333","timezones":[{"zoneName":"Pacific/Apia","gmtOffset":50400,"gmtOffsetName":"UTC+14:00","abbreviation":"WST","tzName":"West Samoa Time"}]},{"name":"San Marino","isoCode":"SM","flag":"ð¸ð²","phonecode":"378","currency":"EUR","latitude":"43.76666666","longitude":"12.41666666","timezones":[{"zoneName":"Europe/San_Marino","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Sao Tome and Principe","isoCode":"ST","flag":"ð¸ð¹","phonecode":"239","currency":"STD","latitude":"1.00000000","longitude":"7.00000000","timezones":[{"zoneName":"Africa/Sao_Tome","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Saudi Arabia","isoCode":"SA","flag":"ð¸ð¦","phonecode":"966","currency":"SAR","latitude":"25.00000000","longitude":"45.00000000","timezones":[{"zoneName":"Asia/Riyadh","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"AST","tzName":"Arabia Standard Time"}]},{"name":"Senegal","isoCode":"SN","flag":"ð¸ð³","phonecode":"221","currency":"XOF","latitude":"14.00000000","longitude":"-14.00000000","timezones":[{"zoneName":"Africa/Dakar","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Serbia","isoCode":"RS","flag":"ð·ð¸","phonecode":"381","currency":"RSD","latitude":"44.00000000","longitude":"21.00000000","timezones":[{"zoneName":"Europe/Belgrade","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Seychelles","isoCode":"SC","flag":"ð¸ð¨","phonecode":"248","currency":"SCR","latitude":"-4.58333333","longitude":"55.66666666","timezones":[{"zoneName":"Indian/Mahe","gmtOffset":14400,"gmtOffsetName":"UTC+04:00","abbreviation":"SCT","tzName":"Seychelles Time"}]}
1,{"name":"Sierra Leone","isoCode":"SL","flag":"ð¸ð±","phonecode":"232","currency":"SLL","latitude":"8.50000000","longitude":"-11.50000000","timezones":[{"zoneName":"Africa/Freetown","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Singapore","isoCode":"SG","flag":"ð¸ð¬","phonecode":"65","currency":"SGD","latitude":"1.36666666","longitude":"103.80000000","timezones":[{"zoneName":"Asia/Singapore","gmtOffset":28800,"gmtOffsetName":"UTC+08:00","abbreviation":"SGT","tzName":"Singapore Time"}]},{"name":"Slovakia","isoCode":"SK","flag":"ð¸ð°","phonecode":"421","currency":"EUR","latitude":"48.66666666","longitude":"19.50000000","timezones":[{"zoneName":"Europe/Bratislava","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Slovenia","isoCode":"SI","flag":"ð¸ð®","phonecode":"386","currency":"EUR","latitude":"46.11666666","longitude":"14.81666666","timezones":[{"zoneName":"Europe/Ljubljana","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Solomon Islands","isoCode":"SB","flag":"ð¸ð§","phonecode":"677","currency":"SBD","latitude":"-8.00000000","longitude":"159.00000000","timezones":[{"zoneName":"Pacific/Guadalcanal","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"SBT","tzName":"Solomon Islands Time"}]},{"name":"Somalia","isoCode":"SO","flag":"ð¸ð´","phonecode":"252","currency":"SOS","latitude":"10.00000000","longitude":"49.00000000","timezones":[{"zoneName":"Africa/Mogadishu","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"EAT","tzName":"East Africa Time"}]},{"name":"South Africa","isoCode":"ZA","flag":"ð¿ð¦","phonecode":"27","currency":"ZAR","latitude":"-29.00000000","longitude":"24.00000000","timezones":[{"zoneName":"Africa/Johannesburg","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"SAST","tzName":"South African Standard Time"}]},{"name":"South Georgia","isoCode":"GS","flag":"ð¬ð¸","phonecode":"500","currency":"GBP","latitude":"-54.50000000","longitude":"-37.00000000","timezones":[{"zoneName":"Atlantic/South_Georgia","gmtOffset":-7200,"gmtOffsetName":"UTC-02:00","abbreviation":"GST","tzName":"South Georgia and the South Sandwich Islands Time"}]},{"name":"South Sudan","isoCode":"SS","flag":"ð¸ð¸","phonecode":"211","currency":"SSP","latitude":"7.00000000","longitude":"30.00000000","timezones":[{"zoneName":"Africa/Juba","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"EAT","tzName":"East Africa Time"}]},{"name":"Spain","isoCode":"ES","flag":"ðªð¸","phonecode":"34","currency":"EUR","latitude":"40.00000000","longitude":"-4.00000000","timezones":[{"zoneName":"Africa/Ceuta","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"},{"zoneName":"Atlantic/Canary","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"WET","tzName":"Western European Time"},{"zoneName":"Europe/Madrid","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Sri Lanka","isoCode":"LK","flag":"ð±ð°","phonecode":"94","currency":"LKR","latitude":"7.00000000","longitude":"81.00000000","timezones":[{"zoneName":"Asia/Colombo","gmtOffset":19800,"gmtOffsetName":"UTC+05:30","abbreviation":"IST","tzName":"Indian Standard Time"}]},{"name":"Sudan","isoCode":"SD","flag":"ð¸ð©","phonecode":"249","currency":"SDG","latitude":"15.00000000","longitude":"30.00000000","timezones":[{"zoneName":"Africa/Khartoum","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EAT","tzName":"Eastern African Time"}]},{"name":"Suriname","isoCode":"SR","flag":"ð¸ð·","phonecode":"597","currency":"SRD","latitude":"4.00000000","longitude":"-56.00000000","timezones":[{"zoneName":"America/Paramaribo","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"SRT","tzName":"Suriname Time"}]},{"name":"Svalbard And Jan Mayen Islands","isoCode":"SJ","flag":"ð¸ð¯","phonecode":"47","currency":"NOK","latitude":"78.00000000","longitude":"20.00000000","timezones":[{"zoneName":"Arctic/Longyearbyen","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]}
1,{"name":"Swaziland","isoCode":"SZ","flag":"ð¸ð¿","phonecode":"268","currency":"SZL","latitude":"-26.50000000","longitude":"31.50000000","timezones":[{"zoneName":"Africa/Mbabane","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"SAST","tzName":"South African Standard Time"}]},{"name":"Sweden","isoCode":"SE","flag":"ð¸ðª","phonecode":"46","currency":"SEK","latitude":"62.00000000","longitude":"15.00000000","timezones":[{"zoneName":"Europe/Stockholm","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Switzerland","isoCode":"CH","flag":"ð¨ð","phonecode":"41","currency":"CHF","latitude":"47.00000000","longitude":"8.00000000","timezones":[{"zoneName":"Europe/Zurich","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Syria","isoCode":"SY","flag":"ð¸ð¾","phonecode":"963","currency":"SYP","latitude":"35.00000000","longitude":"38.00000000","timezones":[{"zoneName":"Asia/Damascus","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Taiwan","isoCode":"TW","flag":"ð¹ð¼","phonecode":"886","currency":"TWD","latitude":"23.50000000","longitude":"121.00000000","timezones":[{"zoneName":"Asia/Taipei","gmtOffset":28800,"gmtOffsetName":"UTC+08:00","abbreviation":"CST","tzName":"China Standard Time"}]},{"name":"Tajikistan","isoCode":"TJ","flag":"ð¹ð¯","phonecode":"992","currency":"TJS","latitude":"39.00000000","longitude":"71.00000000","timezones":[{"zoneName":"Asia/Dushanbe","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"TJT","tzName":"Tajikistan Time"}]},{"name":"Tanzania","isoCode":"TZ","flag":"ð¹ð¿","phonecode":"255","currency":"TZS","latitude":"-6.00000000","longitude":"35.00000000","timezones":[{"zoneName":"Africa/Dar_es_Salaam","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"EAT","tzName":"East Africa Time"}]},{"name":"Thailand","isoCode":"TH","flag":"ð¹ð","phonecode":"66","currency":"THB","latitude":"15.00000000","longitude":"100.00000000","timezones":[{"zoneName":"Asia/Bangkok","gmtOffset":25200,"gmtOffsetName":"UTC+07:00","abbreviation":"ICT","tzName":"Indochina Time"}]},{"name":"Togo","isoCode":"TG","flag":"ð¹ð¬","phonecode":"228","currency":"XOF","latitude":"8.00000000","longitude":"1.16666666","timezones":[{"zoneName":"Africa/Lome","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"Tokelau","isoCode":"TK","flag":"ð¹ð°","phonecode":"690","currency":"NZD","latitude":"-9.00000000","longitude":"-172.00000000","timezones":[{"zoneName":"Pacific/Fakaofo","gmtOffset":46800,"gmtOffsetName":"UTC+13:00","abbreviation":"TKT","tzName":"Tokelau Time"}]},{"name":"Tonga","isoCode":"TO","flag":"ð¹ð´","phonecode":"676","currency":"TOP","latitude":"-20.00000000","longitude":"-175.00000000","timezones":[{"zoneName":"Pacific/Tongatapu","gmtOffset":46800,"gmtOffsetName":"UTC+13:00","abbreviation":"TOT","tzName":"Tonga Time"}]},{"name":"Trinidad And Tobago","isoCode":"TT","flag":"ð¹ð¹","phonecode":"+1-868","currency":"TTD","latitude":"11.00000000","longitude":"-61.00000000","timezones":[{"zoneName":"America/Port_of_Spain","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Tunisia","isoCode":"TN","flag":"ð¹ð³","phonecode":"216","currency":"TND","latitude":"34.00000000","longitude":"9.00000000","timezones":[{"zoneName":"Africa/Tunis","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Turkey","isoCode":"TR","flag":"ð¹ð·","phonecode":"90","currency":"TRY","latitude":"39.00000000","longitude":"35.00000000","timezones":[{"zoneName":"Europe/Istanbul","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"Turkmenistan","isoCode":"TM","flag":"ð¹ð²","phonecode":"993","currency":"TMT","latitude":"40.00000000","longitude":"60.00000000","timezones":[{"zoneName":"Asia/Ashgabat","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"TMT","tzName":"Turkmenistan Time"}]}
1,{"name":"Turks And Caicos Islands","isoCode":"TC","flag":"ð¹ð¨","phonecode":"+1-649","currency":"USD","latitude":"21.75000000","longitude":"-71.58333333","timezones":[{"zoneName":"America/Grand_Turk","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"}]},{"name":"Tuvalu","isoCode":"TV","flag":"ð¹ð»","phonecode":"688","currency":"AUD","latitude":"-8.00000000","longitude":"178.00000000","timezones":[{"zoneName":"Pacific/Funafuti","gmtOffset":43200,"gmtOffsetName":"UTC+12:00","abbreviation":"TVT","tzName":"Tuvalu Time"}]},{"name":"Uganda","isoCode":"UG","flag":"ðºð¬","phonecode":"256","currency":"UGX","latitude":"1.00000000","longitude":"32.00000000","timezones":[{"zoneName":"Africa/Kampala","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"EAT","tzName":"East Africa Time"}]},{"name":"Ukraine","isoCode":"UA","flag":"ðºð¦","phonecode":"380","currency":"UAH","latitude":"49.00000000","longitude":"32.00000000","timezones":[{"zoneName":"Europe/Kiev","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"},{"zoneName":"Europe/Simferopol","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"MSK","tzName":"Moscow Time"},{"zoneName":"Europe/Uzhgorod","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"},{"zoneName":"Europe/Zaporozhye","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"EET","tzName":"Eastern European Time"}]},{"name":"United Arab Emirates","isoCode":"AE","flag":"ð¦ðª","phonecode":"971","currency":"AED","latitude":"24.00000000","longitude":"54.00000000","timezones":[{"zoneName":"Asia/Dubai","gmtOffset":14400,"gmtOffsetName":"UTC+04:00","abbreviation":"GST","tzName":"Gulf Standard Time"}]},{"name":"United Kingdom","isoCode":"GB","flag":"ð¬ð§","phonecode":"44","currency":"GBP","latitude":"54.00000000","longitude":"-2.00000000","timezones":[{"zoneName":"Europe/London","gmtOffset":0,"gmtOffsetName":"UTC±00","abbreviation":"GMT","tzName":"Greenwich Mean Time"}]},{"name":"United States","isoCode":"US","flag":"ðºð¸","phonecode":"1","currency":"USD","latitude":"38.00000000","longitude":"-97.00000000","timezones":[{"zoneName":"America/Adak","gmtOffset":-36000,"gmtOffsetName":"UTC-10:00","abbreviation":"HST","tzName":"HawaiiâAleutian Standard Time"},{"zoneName":"America/Anchorage","gmtOffset":-32400,"gmtOffsetName":"UTC-09:00","abbreviation":"AKST","tzName":"Alaska Standard Time"},{"zoneName":"America/Boise","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America"},{"zoneName":"America/Chicago","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Denver","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America"},{"zoneName":"America/Detroit","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Indiana/Indianapolis","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Indiana/Knox","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Indiana/Marengo","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Indiana/Petersburg","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Indiana/Tell_City","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Indiana/Vevay","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Indiana/Vincennes","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Indiana/Winamac","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Juneau","gmtOffset":-32400,"gmtOffsetName":"UTC-09:00","abbreviation":"AKST","tzName":"Alaska Standard Time"},{"zoneName":"America/Kentucky/Louisville","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Kentucky/Monticello","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Los_Angeles","gmtOffset":-28800,"gmtOffsetName":"UTC-08:00","abbreviation":"PST","tzName":"Pacific Standard Time (North America"},{"zoneName":"America/Menominee","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Metlakatla","gmtOffset":-32400,"gmtOffsetName":"UTC-09:00","abbreviation":"AKST","tzName":"Alaska Standard Time"}
1,{"zoneName":"America/New_York","gmtOffset":-18000,"gmtOffsetName":"UTC-05:00","abbreviation":"EST","tzName":"Eastern Standard Time (North America"},{"zoneName":"America/Nome","gmtOffset":-32400,"gmtOffsetName":"UTC-09:00","abbreviation":"AKST","tzName":"Alaska Standard Time"},{"zoneName":"America/North_Dakota/Beulah","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/North_Dakota/Center","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/North_Dakota/New_Salem","gmtOffset":-21600,"gmtOffsetName":"UTC-06:00","abbreviation":"CST","tzName":"Central Standard Time (North America"},{"zoneName":"America/Phoenix","gmtOffset":-25200,"gmtOffsetName":"UTC-07:00","abbreviation":"MST","tzName":"Mountain Standard Time (North America"},{"zoneName":"America/Sitka","gmtOffset":-32400,"gmtOffsetName":"UTC-09:00","abbreviation":"AKST","tzName":"Alaska Standard Time"},{"zoneName":"America/Yakutat","gmtOffset":-32400,"gmtOffsetName":"UTC-09:00","abbreviation":"AKST","tzName":"Alaska Standard Time"},{"zoneName":"Pacific/Honolulu","gmtOffset":-36000,"gmtOffsetName":"UTC-10:00","abbreviation":"HST","tzName":"HawaiiâAleutian Standard Time"}]},{"name":"United States Minor Outlying Islands","isoCode":"UM","flag":"ðºð²","phonecode":"1","currency":"USD","latitude":"0.00000000","longitude":"0.00000000","timezones":[{"zoneName":"Pacific/Midway","gmtOffset":-39600,"gmtOffsetName":"UTC-11:00","abbreviation":"SST","tzName":"Samoa Standard Time"},{"zoneName":"Pacific/Wake","gmtOffset":43200,"gmtOffsetName":"UTC+12:00","abbreviation":"WAKT","tzName":"Wake Island Time"}]},{"name":"Uruguay","isoCode":"UY","flag":"ðºð¾","phonecode":"598","currency":"UYU","latitude":"-33.00000000","longitude":"-56.00000000","timezones":[{"zoneName":"America/Montevideo","gmtOffset":-10800,"gmtOffsetName":"UTC-03:00","abbreviation":"UYT","tzName":"Uruguay Standard Time"}]},{"name":"Uzbekistan","isoCode":"UZ","flag":"ðºð¿","phonecode":"998","currency":"UZS","latitude":"41.00000000","longitude":"64.00000000","timezones":[{"zoneName":"Asia/Samarkand","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"UZT","tzName":"Uzbekistan Time"},{"zoneName":"Asia/Tashkent","gmtOffset":18000,"gmtOffsetName":"UTC+05:00","abbreviation":"UZT","tzName":"Uzbekistan Time"}]},{"name":"Vanuatu","isoCode":"VU","flag":"ð»ðº","phonecode":"678","currency":"VUV","latitude":"-16.00000000","longitude":"167.00000000","timezones":[{"zoneName":"Pacific/Efate","gmtOffset":39600,"gmtOffsetName":"UTC+11:00","abbreviation":"VUT","tzName":"Vanuatu Time"}]},{"name":"Vatican City State (Holy See)","isoCode":"VA","flag":"ð»ð¦","phonecode":"379","currency":"EUR","latitude":"41.90000000","longitude":"12.45000000","timezones":[{"zoneName":"Europe/Vatican","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Venezuela","isoCode":"VE","flag":"ð»ðª","phonecode":"58","currency":"VEF","latitude":"8.00000000","longitude":"-66.00000000","timezones":[{"zoneName":"America/Caracas","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"VET","tzName":"Venezuelan Standard Time"}]},{"name":"Vietnam","isoCode":"VN","flag":"ð»ð³","phonecode":"84","currency":"VND","latitude":"16.16666666","longitude":"107.83333333","timezones":[{"zoneName":"Asia/Ho_Chi_Minh","gmtOffset":25200,"gmtOffsetName":"UTC+07:00","abbreviation":"ICT","tzName":"Indochina Time"}]},{"name":"Virgin Islands (British)","isoCode":"VG","flag":"ð»ð¬","phonecode":"+1-284","currency":"USD","latitude":"18.43138300","longitude":"-64.62305000","timezones":[{"zoneName":"America/Tortola","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Virgin Islands (US)","isoCode":"VI","flag":"ð»ð®","phonecode":"+1-340","currency":"USD","latitude":"18.34000000","longitude":"-64.93000000","timezones":[{"zoneName":"America/St_Thomas","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]}
1,{"name":"Wallis And Futuna Islands","isoCode":"WF","flag":"ð¼ð«","phonecode":"681","currency":"XPF","latitude":"-13.30000000","longitude":"-176.20000000","timezones":[{"zoneName":"Pacific/Wallis","gmtOffset":43200,"gmtOffsetName":"UTC+12:00","abbreviation":"WFT","tzName":"Wallis & Futuna Time"}]},{"name":"Western Sahara","isoCode":"EH","flag":"ðªð","phonecode":"212","currency":"MAD","latitude":"24.50000000","longitude":"-13.00000000","timezones":[{"zoneName":"Africa/El_Aaiun","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"WEST","tzName":"Western European Summer Time"}]},{"name":"Yemen","isoCode":"YE","flag":"ð¾ðª","phonecode":"967","currency":"YER","latitude":"15.00000000","longitude":"48.00000000","timezones":[{"zoneName":"Asia/Aden","gmtOffset":10800,"gmtOffsetName":"UTC+03:00","abbreviation":"AST","tzName":"Arabia Standard Time"}]},{"name":"Zambia","isoCode":"ZM","flag":"ð¿ð²","phonecode":"260","currency":"ZMW","latitude":"-15.00000000","longitude":"30.00000000","timezones":[{"zoneName":"Africa/Lusaka","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"CAT","tzName":"Central Africa Time"}]},{"name":"Zimbabwe","isoCode":"ZW","flag":"ð¿ð¼","phonecode":"263","currency":"ZWL","latitude":"-20.00000000","longitude":"30.00000000","timezones":[{"zoneName":"Africa/Harare","gmtOffset":7200,"gmtOffsetName":"UTC+02:00","abbreviation":"CAT","tzName":"Central Africa Time"}]},{"name":"Kosovo","isoCode":"XK","flag":"ð½ð°","phonecode":"383","currency":"EUR","latitude":"42.56129090","longitude":"20.34030350","timezones":[{"zoneName":"Europe/Belgrade","gmtOffset":3600,"gmtOffsetName":"UTC+01:00","abbreviation":"CET","tzName":"Central European Time"}]},{"name":"Curaçao","isoCode":"CW","flag":"ð¨ð¼","phonecode":"599","currency":"ANG","latitude":"12.11666700","longitude":"-68.93333300","timezones":[{"zoneName":"America/Curacao","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]},{"name":"Sint Maarten (Dutch part)","isoCode":"SX","flag":"ð¸ð½","phonecode":"1721","currency":"ANG","latitude":"18.03333300","longitude":"-63.05000000","timezones":[{"zoneName":"America/Anguilla","gmtOffset":-14400,"gmtOffsetName":"UTC-04:00","abbreviation":"AST","tzName":"Atlantic Standard Time"}]}]');const i=(e,t)=>{if(t&&null!=e){const n=e.findIndex((e=>e.isoCode===t));return-1!==n?e[n]:void 0}};function a(e){return e.name}const s=(e,t,n=a)=>n(e)<n(t)?-1:n(e)>n(t)?1:0;var r={getCountryByCode:function(e){if(e)return i(o,e)},getAllCountries:function(){return o},sortByIsoCode:function(e){return e.sort(((e,t)=>s(e,t,(e=>e.isoCode))))}},d=JSON.parse('[{"name":"Canillo","isoCode":"02","countryCode":"AD","latitude":"42.59782490","longitude":"1.65663770"},{"name":"Encamp","isoCode":"03","countryCode":"AD","latitude":"42.53597640","longitude":"1.58367730"},{"name":"La Massana","isoCode":"04","countryCode":"AD","latitude":"42.54562500","longitude":"1.51473920"},{"name":"Ordino","isoCode":"05","countryCode":"AD","latitude":"42.59944330","longitude":"1.54023270"},{"name":"Sant Julià de Lòria","isoCode":"06","countryCode":"AD","latitude":"42.45296310","longitude":"1.49182350"},{"name":"Andorra la Vella","isoCode":"07","countryCode":"AD","latitude":"42.50631740","longitude":"1.52183550"},{"name":"Escaldes-Engordany","isoCode":"08","countryCode":"AD","latitude":"42.49093790","longitude":"1.58869660"},{"name":"Ajman Emirate","isoCode":"AJ","countryCode":"AE","latitude":"25.40521650","longitude":"55.51364330"},{"name":"Abu Dhabi Emirate","isoCode":"AZ","countryCode":"AE","latitude":"24.45388400","longitude":"54.37734380"},{"name":"Dubai","isoCode":"DU","countryCode":"AE","latitude":"25.20484930","longitude":"55.27078280"},{"name":"Fujairah","isoCode":"FU","countryCode":"AE","latitude":"25.12880990","longitude":"56.32648490"},{"name":"Ras al-Khaimah","isoCode":"RK","countryCode":"AE","latitude":"25.67413430","longitude":"55.98041730"},{"name":"Sharjah Emirate","isoCode":"SH","countryCode":"AE","latitude":"25.07539740","longitude":"55.75784030"},{"name":"Umm al-Quwain","isoCode":"UQ","countryCode":"AE","latitude":"25.54263240","longitude":"55.54753480"},{"name":"Balkh","isoCode":"BAL","countryCode":"AF","latitude":"36.75506030","longitude":"66.89753720"},{"name":"Bamyan","isoCode":"BAM","countryCode":"AF","latitude":"34.81000670","longitude":"67.82121040"},{"name":"Badghis","isoCode":"BDG","countryCode":"AF","latitude":"35.16713390","longitude":"63.76953840"},{"name":"Badakhshan","isoCode":"BDS","countryCode":"AF","latitude":"36.73477250","longitude":"70.81199530"},{"name":"Baghlan","isoCode":"BGL","countryCode":"AF","latitude":"36.17890260","longitude":"68.74530640"},{"name":"Daykundi","isoCode":"DAY","countryCode":"AF","latitude":"33.66949500","longitude":"66.
104635340"},{"name":"Farah","isoCode":"FRA","countryCode":"AF","latitude":"32.49532800","longitude":"62.26266270"},{"name":"Faryab","isoCode":"FYB","countryCode":"AF","latitude":"36.07956130","longitude":"64.90595500"},{"name":"Ghazni","isoCode":"GHA","countryCode":"AF","latitude":"33.54505870","longitude":"68.41739720"},{"name":"GhÅr","isoCode":"GHO","countryCode":"AF","latitude":"34.09957760","longitude":"64.90595500"},{"name":"Helmand","isoCode":"HEL","countryCode":"AF","latitude":"39.29893610","longitude":"-76.61604720"},{"name":"Herat","isoCode":"HER","countryCode":"AF","latitude":"34.35286500","longitude":"62.20402870"},{"name":"Jowzjan","isoCode":"JOW","countryCode":"AF","latitude":"36.89696920","longitude":"65.66585680"},{"name":"Kabul","isoCode":"KAB","countryCode":"AF","latitude":"34.55534940","longitude":"69.20748600"},{"name":"Kandahar","isoCode":"KAN","countryCode":"AF","latitude":"31.62887100","longitude":"65.73717490"},{"name":"Kapisa","isoCode":"KAP","countryCode":"AF","latitude":"34.98105720","longitude":"69.62145620"},{"name":"Kunduz Province","isoCode":"KDZ","countryCode":"AF","latitude":"36.72855110","longitude":"68.86789820"},{"name":"Khost","isoCode":"KHO","countryCode":"AF","latitude":"33.33384720","longitude":"69.93716730"},{"name":"Kunar","isoCode":"KNR","countryCode":"AF","latitude":"34.84658930","longitude":"71.09731700"},{"name":"Laghman","isoCode":"LAG","countryCode":"AF","latitude":"34.68976870","longitude":"70.14558050"},{"name":"Logar","isoCode":"LOG","countryCode":"AF","latitude":"34.01455180","longitude":"69.19239160"},{"name":"Nangarhar","isoCode":"NAN","countryCode":"AF","latitude":"34.17183130","longitude":"70.62167940"},{"name":"Nimruz","isoCode":"NIM","countryCode":"AF","latitude":"31.02614880","longitude":"62.45041540"},{"name":"Nuristan","isoCode":"NUR","countryCode":"AF","latitude":"35.32502230","longitude":"70.90712360"},{"name":"Panjshir","isoCode":"PAN","countryCode":"AF","latitude":"38.88023910","longitude":"-77.17172380"},{"name":"Parwan","isoCode":"PAR","countryCode":"AF","latitude":"34.96309770","longitude":"68.81088490"},{"name":"Paktia","isoCode":"PIA","countryCode":"AF","latitude":"33.70619900","longitude":"69.38310790"},{"name":"Paktika","isoCode":"PKA","countryCode":"AF","latitude":"32.26453860","longitude":"68.52471490"},{"name":"Samangan","isoCode":"SAM","countryCode":"AF","latitude":"36.31555060","longitude":"67.96428630"},{"name":"Sar-e Pol","isoCode":"SAR","countryCode":"AF","latitude":"36.21662800","longitude":"65.93336000"},{"name":"Takhar","isoCode":"TAK","countryCode":"AF","latitude":"36.66980130","longitude":"69.47845410"},{"name":"Urozgan","isoCode":"URU","countryCode":"AF","latitude":"32.92712870","longitude":"66.14152630"},{"name":"Zabul","isoCode":"ZAB","countryCode":"AF","latitude":"32.19187820","longitude":"67.18944880"},{"name":"Saint George Parish","isoCode":"03","countryCode":"AG","latitude":null,"longitude":null},{"name":"Saint John Parish","isoCode":"04","countryCode":"AG","latitude":null,"longitude":null},{"name":"Saint Mary Parish","isoCode":"05","countryCode":"AG","latitude":null,"longitude":null},{"name":"Saint Paul Parish","isoCode":"06","countryCode":"AG","latitude":null,"longitude":null},{"name":"Saint Peter Parish","isoCode":"07","countryCode":"AG","latitude":null,"longitude":null},{"name":"Saint Philip Parish","isoCode":"08","countryCode":"AG","latitude":"40.43682580","longitude":"-80.06855320"},{"name":"Barbuda","isoCode":"10","countryCode":"AG","latitude":"17.62662420","longitude":"-61.77130280"},{"name":"Redonda","isoCode":"11","countryCode":"AG","latitude":"16.93841600","longitude":"-62.34551480"},{"name":"Berat County","isoCode":"01","countryCode":"AL","latitude":"40.69530120","longitude":"20.04496620"},{"name":"Durrës County","isoCode":"02","countryCode":"AL","latitude":"41.50809720","longitude":"19.61631850"},{"name":"Elbasan County","isoCode":"03","countryCode":"AL","latitude":"41.12666720","longitude":"20.23556470"},{"name":"Fier County","isoCode":"04","countryCode":"AL","latitude":"40.91913920","longitude":"19.66393090"},{"name":"Gjirokastër County","isoCode":"05","countryCode":"AL","latitude":"40.06728740","longitude":"20.10452290"},{"name":"Korçë County","isoCode":"06","countryCode":"AL","latitude":"40.59056700","longitude":"20.61689210"},{"name":"Kukës County","isoCode":"07","countryCode":"AL","latitude":"42.08074640","longitude":"20.41429230"},{"name":"Lezhë County","isoCode":"08","countryCode":"AL","latitude":"41.78137
1590","longitude":"19.80679160"},{"name":"Dibër County","isoCode":"09","countryCode":"AL","latitude":"41.58881630","longitude":"20.23556470"},{"name":"Shkodër County","isoCode":"10","countryCode":"AL","latitude":"42.15037100","longitude":"19.66393090"},{"name":"Tirana County","isoCode":"11","countryCode":"AL","latitude":"41.24275980","longitude":"19.80679160"},{"name":"Vlorë County","isoCode":"12","countryCode":"AL","latitude":"40.15009600","longitude":"19.80679160"},{"name":"Berat District","isoCode":"BR","countryCode":"AL","latitude":"40.70863770","longitude":"19.94373140"},{"name":"Bulqizë District","isoCode":"BU","countryCode":"AL","latitude":"41.49425870","longitude":"20.21471570"},{"name":"Dibër District","isoCode":"DI","countryCode":"AL","latitude":"41.58881630","longitude":"20.23556470"},{"name":"Delvinë District","isoCode":"DL","countryCode":"AL","latitude":"39.94813640","longitude":"20.09558910"},{"name":"Durrës District","isoCode":"DR","countryCode":"AL","latitude":"41.37065170","longitude":"19.52110630"},{"name":"Devoll District","isoCode":"DV","countryCode":"AL","latitude":"40.64473470","longitude":"20.95066360"},{"name":"Kolonjë District","isoCode":"ER","countryCode":"AL","latitude":"40.33732620","longitude":"20.67946760"},{"name":"Fier District","isoCode":"FR","countryCode":"AL","latitude":"40.72750400","longitude":"19.56275960"},{"name":"Gjirokastër District","isoCode":"GJ","countryCode":"AL","latitude":"40.06728740","longitude":"20.10452290"},{"name":"Gramsh District","isoCode":"GR","countryCode":"AL","latitude":"40.86698730","longitude":"20.18493230"},{"name":"Has District","isoCode":"HA","countryCode":"AL","latitude":"42.79013360","longitude":"-83.61220120"},{"name":"Kavajë District","isoCode":"KA","countryCode":"AL","latitude":"41.18445290","longitude":"19.56275960"},{"name":"Kurbin District","isoCode":"KB","countryCode":"AL","latitude":"41.64126440","longitude":"19.70559500"},{"name":"Kuçovë District","isoCode":"KC","countryCode":"AL","latitude":"40.78370630","longitude":"19.87823480"},{"name":"Korçë District","isoCode":"KO","countryCode":"AL","latitude":"40.59056700","longitude":"20.61689210"},{"name":"Krujë District","isoCode":"KR","countryCode":"AL","latitude":"41.50947650","longitude":"19.77107320"},{"name":"Kukës District","isoCode":"KU","countryCode":"AL","latitude":"42.08074640","longitude":"20.41429230"},{"name":"Librazhd District","isoCode":"LB","countryCode":"AL","latitude":"41.18292320","longitude":"20.31747690"},{"name":"Lezhë District","isoCode":"LE","countryCode":"AL","latitude":"41.78607300","longitude":"19.64607580"},{"name":"Lushnjë District","isoCode":"LU","countryCode":"AL","latitude":"40.94198300","longitude":"19.69964280"},{"name":"Mallakastër District","isoCode":"MK","countryCode":"AL","latitude":"40.52733760","longitude":"19.78297910"},{"name":"Malësi e Madhe District","isoCode":"MM","countryCode":"AL","latitude":"42.42451730","longitude":"19.61631850"},{"name":"Mirditë District","isoCode":"MR","countryCode":"AL","latitude":"41.76428600","longitude":"19.90205090"},{"name":"Mat District","isoCode":"MT","countryCode":"AL","latitude":"41.59376750","longitude":"19.99732440"},{"name":"Pogradec District","isoCode":"PG","countryCode":"AL","latitude":"40.90153140","longitude":"20.65562890"},{"name":"Peqin District","isoCode":"PQ","countryCode":"AL","latitude":"41.04709020","longitude":"19.75023840"},{"name":"Përmet District","isoCode":"PR","countryCode":"AL","latitude":"40.23618370","longitude":"20.35173340"},{"name":"Pukë District","isoCode":"PU","countryCode":"AL","latitude":"42.04697720","longitude":"19.89609680"},{"name":"Shkodër District","isoCode":"SH","countryCode":"AL","latitude":"42.06929850","longitude":"19.50325590"},{"name":"Skrapar District","isoCode":"SK","countryCode":"AL","latitude":"40.53499460","longitude":"20.28322170"},{"name":"Sarandë District","isoCode":"SR","countryCode":"AL","latitude":"39.85921190","longitude":"20.02710010"},{"name":"Tepelenë District","isoCode":"TE","countryCode":"AL","latitude":"40.29666320","longitude":"20.01816730"},{"name":"Tropojë District","isoCode":"TP","countryCode":"AL","latitude":"42.39821510","longitude":"20.16259550"},{"name":"Tirana District","isoCode":"TR","countryCode":"AL","latitude":"41.32754590","longitude":"19.81869820"}
1,{"name":"Vlorë District","isoCode":"VL","countryCode":"AL","latitude":"40.46606680","longitude":"19.49135600"},{"name":"Aragatsotn Region","isoCode":"AG","countryCode":"AM","latitude":"40.33473010","longitude":"44.37482960"},{"name":"Ararat Province","isoCode":"AR","countryCode":"AM","latitude":"39.91394150","longitude":"44.72000040"},{"name":"Armavir Region","isoCode":"AV","countryCode":"AM","latitude":"40.15546310","longitude":"44.03724460"},{"name":"Yerevan","isoCode":"ER","countryCode":"AM","latitude":"40.18720230","longitude":"44.51520900"},{"name":"Gegharkunik Province","isoCode":"GR","countryCode":"AM","latitude":"40.35264260","longitude":"45.12604140"},{"name":"Kotayk Region","isoCode":"KT","countryCode":"AM","latitude":"40.54102140","longitude":"44.76901480"},{"name":"Lori Region","isoCode":"LO","countryCode":"AM","latitude":"40.96984520","longitude":"44.49001380"},{"name":"Shirak Region","isoCode":"SH","countryCode":"AM","latitude":"40.96308140","longitude":"43.81024610"},{"name":"Syunik Province","isoCode":"SU","countryCode":"AM","latitude":"39.51331120","longitude":"46.33932340"},{"name":"Tavush Region","isoCode":"TV","countryCode":"AM","latitude":"40.88662960","longitude":"45.33934900"},{"name":"Vayots Dzor Region","isoCode":"VD","countryCode":"AM","latitude":"39.76419960","longitude":"45.33375280"},{"name":"Bengo Province","isoCode":"BGO","countryCode":"AO","latitude":"-9.10422570","longitude":"13.72891670"},{"name":"Benguela Province","isoCode":"BGU","countryCode":"AO","latitude":"-12.80037440","longitude":"13.91439900"},{"name":"Bié Province","isoCode":"BIE","countryCode":"AO","latitude":"-12.57279070","longitude":"17.66888700"},{"name":"Cabinda Province","isoCode":"CAB","countryCode":"AO","latitude":"-5.02487490","longitude":"12.34638750"},{"name":"Cuando Cubango Province","isoCode":"CCU","countryCode":"AO","latitude":"-16.41808240","longitude":"18.80761950"},{"name":"Cunene Province","isoCode":"CNN","countryCode":"AO","latitude":"-16.28022210","longitude":"16.15809370"},{"name":"Cuanza Norte Province","isoCode":"CNO","countryCode":"AO","latitude":"-9.23985130","longitude":"14.65878210"},{"name":"Cuanza Sul","isoCode":"CUS","countryCode":"AO","latitude":"-10.59519100","longitude":"15.40680790"},{"name":"Huambo Province","isoCode":"HUA","countryCode":"AO","latitude":"-12.52682210","longitude":"15.59433880"},{"name":"HuÃla Province","isoCode":"HUI","countryCode":"AO","latitude":"-14.92805530","longitude":"14.65878210"},{"name":"Lunda Norte Province","isoCode":"LNO","countryCode":"AO","latitude":"-8.35250220","longitude":"19.18800470"},{"name":"Lunda Sul Province","isoCode":"LSU","countryCode":"AO","latitude":"-10.28665780","longitude":"20.71224650"},{"name":"Luanda Province","isoCode":"LUA","countryCode":"AO","latitude":"-9.03508800","longitude":"13.26634790"},{"name":"Malanje Province","isoCode":"MAL","countryCode":"AO","latitude":"-9.82511830","longitude":"16.91225100"},{"name":"Moxico Province","isoCode":"MOX","countryCode":"AO","latitude":"-13.42935790","longitude":"20.33088140"},{"name":"UÃge Province","isoCode":"UIG","countryCode":"AO","latitude":"-7.17367320","longitude":"15.40680790"},{"name":"Zaire Province","isoCode":"ZAI","countryCode":"AO","latitude":"-6.57334580","longitude":"13.17403480"},{"name":"Salta","isoCode":"A","countryCode":"AR","latitude":"-24.79976880","longitude":"-65.41503670"},{"name":"Buenos Aires","isoCode":"B","countryCode":"AR","latitude":"-37.20172850","longitude":"-59.84106970"},{"name":"Ciudad Autónoma de Buenos Aires","isoCode":"C","countryCode":"AR","latitude":"-34.60368440","longitude":"-58.38155910"},{"name":"San Luis","isoCode":"D","countryCode":"AR","latitude":"-33.29620420","longitude":"-66.32949480"},{"name":"Entre RÃos","isoCode":"E","countryCode":"AR","latitude":"-31.77466540","longitude":"-60.49564610"},{"name":"La Rioja","isoCode":"F","countryCode":"AR","latitude":"-29.41937930","longitude":"-66.85599320"},{"name":"Santiago del Estero","isoCode":"G","countryCode":"AR","latitude":"-27.78335740","longitude":"-64.26416700"},{"name":"Chaco","isoCode":"H","countryCode":"AR","latitude":"-27.42571750","longitude":"-59.02437840"},{"name":"San Juan","isoCode":"J","countryCode":"AR","latitude":"-31.53169760","longitude":"-68.56769620"},{"name":"Catamarca","isoCode":"K","countryCode":"AR","latitude":"-28.47158770","longitude":"-65.78772090"},{"name":"La Pampa","isoCode":"L","countryCode":"AR","latitude":"-36.61475730","longitude":"-64.28392090"},{"name":"Mendoza","isoCode":"M","countryCode":"AR","latitude":"-32.88945870","longitude":"-68.84583860"},{"name":"Misiones","isoCode":"N","countryCode":"AR","latitude":"-27.42692550","longitude":"-55.94670760"},{"name":"Formosa","isoCode":"P","countryCode":"AR","latitude":"-26.18948040","longitude":"-58.22428060"},{"name":"Neuquén","isoCode":"Q","countryCode":"AR","latitude":"-38.94587000","longitude":"-68.07309250"},{"name":"RÃo Negro","isoCode":"R","countryCode":"AR","latitude":"-40.82614340","longitude":"-63.02663390"},{"name":"Santa Fe","isoCode":"S","countryCode":"AR","latitude":"-31.58551090","longitude":"-60.72380160"},{"name":"Tucumán","isoCode":"T","countryCode":"AR","latitude":"-26.82211270","longitude":"-65.21929030"},{"name":"Chubut","isoCode":"U","countryCode":"AR","latitude":"-43.29342460","longitude":"-65.11148180"}
1,{"name":"Tierra del Fuego","isoCode":"V","countryCode":"AR","latitude":"-54.80539980","longitude":"-68.32420610"},{"name":"Corrientes","isoCode":"W","countryCode":"AR","latitude":"-27.46921310","longitude":"-58.83063490"},{"name":"Córdoba","isoCode":"X","countryCode":"AR","latitude":"-31.39928760","longitude":"-64.26438420"},{"name":"Jujuy","isoCode":"Y","countryCode":"AR","latitude":"-24.18433970","longitude":"-65.30217700"},{"name":"Santa Cruz","isoCode":"Z","countryCode":"AR","latitude":"-51.63528210","longitude":"-69.24743530"},{"name":"Burgenland","isoCode":"1","countryCode":"AT","latitude":"47.15371650","longitude":"16.26887970"},{"name":"Carinthia","isoCode":"2","countryCode":"AT","latitude":"46.72220300","longitude":"14.18058820"},{"name":"Lower Austria","isoCode":"3","countryCode":"AT","latitude":"48.10807700","longitude":"15.80495580"},{"name":"Upper Austria","isoCode":"4","countryCode":"AT","latitude":"48.02585400","longitude":"13.97236650"},{"name":"Salzburg","isoCode":"5","countryCode":"AT","latitude":"47.80949000","longitude":"13.05501000"},{"name":"Styria","isoCode":"6","countryCode":"AT","latitude":"47.35934420","longitude":"14.46998270"},{"name":"Tyrol","isoCode":"7","countryCode":"AT","latitude":"47.25374140","longitude":"11.60148700"},{"name":"Vorarlberg","isoCode":"8","countryCode":"AT","latitude":"47.24974270","longitude":"9.97973730"},{"name":"Vienna","isoCode":"9","countryCode":"AT","latitude":"48.20817430","longitude":"16.37381890"},{"name":"Australian Capital Territory","isoCode":"ACT","countryCode":"AU","latitude":"-35.47346790","longitude":"149.01236790"},{"name":"New South Wales","isoCode":"NSW","countryCode":"AU","latitude":"-31.25321830","longitude":"146.92109900"},{"name":"Northern Territory","isoCode":"NT","countryCode":"AU","latitude":"-19.49141080","longitude":"132.55096030"},{"name":"Queensland","isoCode":"QLD","countryCode":"AU","latitude":"-20.91757380","longitude":"142.70279560"},{"name":"South Australia","isoCode":"SA","countryCode":"AU","latitude":"-30.00023150","longitude":"136.20915470"},{"name":"Tasmania","isoCode":"TAS","countryCode":"AU","latitude":"-41.45451960","longitude":"145.97066470"},{"name":"Victoria","isoCode":"VIC","countryCode":"AU","latitude":"-36.48564230","longitude":"140.97794250"},{"name":"Western Australia","isoCode":"WA","countryCode":"AU","latitude":"-27.67281680","longitude":"121.62830980"},{"name":"Absheron District","isoCode":"ABS","countryCode":"AZ","latitude":"40.36296930","longitude":"49.27368150"},{"name":"Agstafa District","isoCode":"AGA","countryCode":"AZ","latitude":"41.26559330","longitude":"45.51342910"},{"name":"Aghjabadi District","isoCode":"AGC","countryCode":"AZ","latitude":"28.78918410","longitude":"77.51607880"},{"name":"Agdam District","isoCode":"AGM","countryCode":"AZ","latitude":"39.99318530","longitude":"46.99495620"},{"name":"Agdash District","isoCode":"AGS","countryCode":"AZ","latitude":"40.63354270","longitude":"47.46743100"},{"name":"Agsu District","isoCode":"AGU","countryCode":"AZ","latitude":"40.52833390","longitude":"48.36508350"},{"name":"Astara District","isoCode":"AST","countryCode":"AZ","latitude":"38.49378450","longitude":"48.69443650"},{"name":"Baku","isoCode":"BA","countryCode":"AZ","latitude":"40.40926170","longitude":"49.86709240"},{"name":"Babek District","isoCode":"BAB","countryCode":"AZ","latitude":"39.15076130","longitude":"45.44853680"},{"name":"Balakan District","isoCode":"BAL","countryCode":"AZ","latitude":"41.70375090","longitude":"46.40442130"},{"name":"Barda District","isoCode":"BAR","countryCode":"AZ","latitude":"40.37065550","longitude":"47.13789090"},{"name":"Beylagan District","isoCode":"BEY","countryCode":"AZ","latitude":"39.77230730","longitude":"47.61541660"},{"name":"Bilasuvar District","isoCode":"BIL","countryCode":"AZ","latitude":"39.45988330","longitude":"48.55098130"},{"name":"Jabrayil District","isoCode":"CAB","countryCode":"AZ","latitude":"39.26455440","longitude":"46.96215620"},{"name":"Jalilabad District","isoCode":"CAL","countryCode":"AZ","latitude":"39.20516320","longitude":"48.51006040"},{"name":"Julfa District","isoCode":"CUL","countryCode":"AZ","latitude":"38.96049830","longitude":"45.62929390"},{"name":"Dashkasan District","isoCode":"DAS","countryCode":"AZ","latitude":"40.52022570","longitude":"46.07793040"},{"name":"Fizuli District","isoCode":"FUZ","countryCode":"AZ","latitude":"39.53786050","longitude":"47.30338770"},{"name":"Ganja","isoCode":"GA","countryCode":"AZ","latitude":"36.36873380","longitude":"-95.99857670"},{"name":"GÉdÉbÉy","isoCode":"GAD","countryCode":"AZ","latitude":"40.56996390","longitude":"45.81068830"},{"name":"Goranboy District","isoCode":"GOR","countryCode":"AZ","latitude":"40.53805060","longitude":"46.59908910"},{"name":"Goychay","isoCode":"GOY","countryCode":"AZ","latitude":"40.62361680","longitude":"47.74030340"},{"name":"Goygol District","isoCode":"GYG","countryCode":"AZ","latitude":"40.55953780","longitude":"46.33149530"},{"name":"Hajigabul District","isoCode":"HAC","countryCode":"AZ","latitude":"40.03937700","longitude":"48.92025330"},{"name":"Imishli District","isoCode":"IMI","countryCode":"AZ","latitude":"39.86946860","longitude":"48.06652180"},{"name":"Ismailli District","isoCode":"ISM","countryCode":"AZ","latitude":"40.74299360","longitude":"48.21255560"},{"name":"Kalbajar District","isoCode":"KAL","countryCode":"AZ","latitude":"40.10243290","longitude":"46.03648720"},{"name":"Kangarli District","isoCode":"KAN","countryCode":"AZ","latitude":"39.38719400","longitude":"45.16398520"},{"name":"Kurdamir District","isoCode":"KUR","countryCode":"AZ","latitude":"40.36986510","longitude":"48.16446260"},{"name":"Lankaran District","isoCode":"LA","countryCode":"AZ","latitude":"38.75286690","longitude":"48.84750150"},{"name":"Lachin District","isoCode":"LAC","countryCode":"AZ","latitude":"39.63834140","longitude":"46.54608530"},{"name":"Lankaran","isoCode":"LAN","countryCode":"AZ","latitude":"38.75286690","longitude":"48.84750150"},{"name":"Lerik District","isoCode":"LER","countryCode":"AZ","latitude":"38.77361920","longitude":"48.41514830"},{"name":"Masally District","isoCode":"MAS","countryCode":"AZ","latitude":"39.03407220","longitude":"48.65893540"},{"name":"Mingachevir","isoCode":"MI","countryCode":"AZ","latitude":"40.77025630","longitude":"47.04960150"},{"name":"Neftchala District","isoCode":"NEF","countryCode":"AZ","latitude":"39.38810520","longitude":"49.24137430"},{"name":"Nakhchivan Autonomous Republic","isoCode":"NX","countryCode":"AZ","latitude":"39.32568140","longitude":"45.49126480"},{"name":"Oghuz District","isoCode":"OGU","countryCode":"AZ","latitude":"41.07279240","longitude":"47.46506720"},{"name":"Ordubad District","isoCode":"ORD","countryCode":"AZ","latitude":"38.90216220","longitude":"46.02376250"},{"name":"Qabala District","isoCode":"QAB","countryCode":"AZ","latitude":"40.92539250","longitude":"47.80161060"},{"name":"Qakh District","isoCode":"QAX","countryCode":"AZ","latitude":"41.42068270","longitude":"46.93201840"},{"name":"Qazakh District","isoCode":"QAZ","countryCode":"AZ","latitude":"41.09710740","longitude":"45.35163310"},{"name":"Quba District","isoCode":"QBA","countryCode":"AZ","latitude":"41.15642420","longitude":"48.41350210"},{"name":"Qubadli District","isoCode":"QBI","countryCode":"AZ","latitude":"39.27139960","longitude":"46.63543120"},{"name":"Gobustan District","isoCode":"QOB","countryCode":"AZ","latitude":"40.53261040","longitude":"48.92737500"},{"name":"Qusar District","isoCode":"QUS","countryCode":"AZ","latitude":"41.42668860","longitude":"48.43455770"},{"name":"Shaki","isoCode":"SA","countryCode":"AZ","latitude":"41.19747530","longitude":"47.15712410"},{"name":"Sabirabad District","isoCode":"SAB","countryCode":"AZ","latitude":"39.98706630","longitude":"48.46925450"},{"name":"Sadarak District","isoCode":"SAD","countryCode":"AZ","latitude":"39.71051140","longitude":"44.88642770"},{"name":"Shahbuz District","isoCode":"SAH","countryCode":"AZ","latitude":"39.44521030","longitude":"45.65680090"},{"name":"Shaki District","isoCode":"SAK","countryCode":"AZ","latitude":"41.11346620","longitude":"47.13169270"},{"name":"Salyan District","isoCode":"SAL","countryCode":"AZ","latitude":"28.35248110","longitude":"82.12784000"},{"name":"Sharur District","isoCode":"SAR","countryCode":"AZ","latitude":"39.55363320","longitude":"44.98456800"},{"name":"Saatly District","isoCode":"SAT","countryCode":"AZ","latitude":"39.9095
15030","longitude":"48.35951220"},{"name":"Shabran District","isoCode":"SBN","countryCode":"AZ","latitude":"41.22283760","longitude":"48.84573040"},{"name":"Siazan District","isoCode":"SIY","countryCode":"AZ","latitude":"41.07838330","longitude":"49.11184770"},{"name":"Shamkir District","isoCode":"SKR","countryCode":"AZ","latitude":"40.82881440","longitude":"46.01668790"},{"name":"Sumqayit","isoCode":"SM","countryCode":"AZ","latitude":"40.58547650","longitude":"49.63174110"},{"name":"Shamakhi District","isoCode":"SMI","countryCode":"AZ","latitude":"40.63187310","longitude":"48.63638010"},{"name":"Samukh District","isoCode":"SMX","countryCode":"AZ","latitude":"40.76046310","longitude":"46.40631810"},{"name":"Shirvan","isoCode":"SR","countryCode":"AZ","latitude":"39.94697070","longitude":"48.92239190"},{"name":"Shusha District","isoCode":"SUS","countryCode":"AZ","latitude":"39.75374380","longitude":"46.74647550"},{"name":"Tartar District","isoCode":"TAR","countryCode":"AZ","latitude":"40.34438750","longitude":"46.93765190"},{"name":"Tovuz District","isoCode":"TOV","countryCode":"AZ","latitude":"40.99545230","longitude":"45.61659070"},{"name":"Ujar District","isoCode":"UCA","countryCode":"AZ","latitude":"40.50675250","longitude":"47.64896410"},{"name":"Khachmaz District","isoCode":"XAC","countryCode":"AZ","latitude":"41.45911680","longitude":"48.80206260"},{"name":"Khojali District","isoCode":"XCI","countryCode":"AZ","latitude":"39.91325530","longitude":"46.79430500"},{"name":"Khizi District","isoCode":"XIZ","countryCode":"AZ","latitude":"40.91094890","longitude":"49.07292640"},{"name":"Martuni","isoCode":"XVD","countryCode":"AZ","latitude":"39.79146930","longitude":"47.11008140"},{"name":"Yardymli District","isoCode":"YAR","countryCode":"AZ","latitude":"38.90589170","longitude":"48.24961270"},{"name":"Yevlakh","isoCode":"YE","countryCode":"AZ","latitude":"40.61966380","longitude":"47.15003240"},{"name":"Yevlakh District","isoCode":"YEV","countryCode":"AZ","latitude":"40.61966380","longitude":"47.15003240"},{"name":"Zangilan District","isoCode":"ZAN","countryCode":"AZ","latitude":"39.08568990","longitude":"46.65247280"},{"name":"Zaqatala District","isoCode":"ZAQ","countryCode":"AZ","latitude":"41.59068890","longitude":"46.72403730"},{"name":"Zardab District","isoCode":"ZAR","countryCode":"AZ","latitude":"40.21481140","longitude":"47.71494400"},{"name":"Una-Sana Canton","isoCode":"01","countryCode":"BA","latitude":"44.65031160","longitude":"16.31716290"},{"name":"Posavina Canton","isoCode":"02","countryCode":"BA","latitude":"45.07520940","longitude":"18.37763040"},{"name":"Tuzla Canton","isoCode":"03","countryCode":"BA","latitude":"44.53434630","longitude":"18.69727970"},{"name":"Zenica-Doboj Canton","isoCode":"04","countryCode":"BA","latitude":"44.21271090","longitude":"18.16046250"},{"name":"Bosnian Podrinje Canton","isoCode":"05","countryCode":"BA","latitude":"43.68749000","longitude":"18.82443940"},{"name":"Central Bosnia Canton","isoCode":"06","countryCode":"BA","latitude":"44.13818560","longitude":"17.68667140"},{"name":"Herzegovina-Neretva Canton","isoCode":"07","countryCode":"BA","latitude":"43.52651590","longitude":"17.76362100"},{"name":"West Herzegovina Canton","isoCode":"08","countryCode":"BA","latitude":"43.43692440","longitude":"17.38488310"},{"name":"Sarajevo Canton","isoCode":"09","countryCode":"BA","latitude":"43.85125640","longitude":"18.29534420"},{"name":"Canton 10","isoCode":"10","countryCode":"BA","latitude":"43.95341550","longitude":"16.94251870"},{"name":"Federation of Bosnia and Herzegovina","isoCode":"BIH","countryCode":"BA","latitude":"43.88748970","longitude":"17.84279300"},{"name":"BrÄko District","isoCode":"BRC","countryCode":"BA","latitude":"44.84059440","longitude":"18.74215300"},{"name":"Republika Srpska","isoCode":"SRP","countryCode":"BA","latitude":"44.72801860","longitude":"17.31481360"},{"name":"Christ Church","isoCode":"01","countryCode":"BB","latitude":"36.00604070","longitude":"-95.92112100"},{"name":"Saint Andrew","isoCode":"02","countryCode":"BB","latitude":null,"longitude":null},{"name":"Saint George","isoCode":"03","countryCode":"BB","latitude":"37.09652780","longitude":"-113.56841640"},{"name":"Saint James","isoCode":"04","countryCode":"BB","latitude":"48.52356600","longitude":"-1.32378850"},{"name":"Saint John","isoCode":"05","countryCode":"BB","latitude":"45.27331530","longitude":"-66.06330800"},{"name":"Saint Joseph","isoCode":"06","countryCode":"BB","latitude":"39.76745780","longitude":"-94.84668100"},{"name":"Saint Lucy","isoCode":"07","countryCode":"BB","latitude":"38.76146250","longitude":"-77.44914390"},{"name":"Saint Michael","isoCode":"08","countryCode":"BB","latitude":"36.03597700","longitude":"-95.84905200"},{"name":"Saint Peter","isoCode":"09","countryCode":"BB","latitude":"37.08271190","longitude":"-94.51712500"},{"name":"Saint Philip","isoCode":"10","countryCode":"BB","latitude":"35.23311400","longitude":"-89.43640420"},{"name":"Saint Thomas","isoCode":"11","countryCode":"BB","latitude":"18.33809650","longitude":"-64.89409460"},{"name":"Bandarban District","isoCode":"01","countryCode":"BD","latitude":"21.83110020","longitude":"92.36863210"},{"name":"Barguna District","isoCode":"02","countryCode":"BD","latitude":"22.09529150","longitude":"90.11206960"},{"name":"Bogra District","isoCode":"03","countryCode":"BD","latitude":"24.85104020","longitude":"89.36972250"},{"name":"Brahmanbaria District","isoCode":"04","countryCode":"BD","latitude":"23.96081810","longitude":"91.11150140"},{"name":"Bagerhat District","isoCode":"05","countryCode":"BD","latitude":"22.66024360","longitude":"89.78954780"},{"name":"Barisal District","isoCode":"06","countryCode":"BD","latitude":"22.70220980","longitude":"90.36963160"},{"name":"Bhola District","isoCode":"07","countryCode":"BD","latitude":"22.17853150","longitude":"90.71010230"},{"name":"Comilla District","isoCode":"08","countryCode":"BD","latitude":"23.45756670","longitude":"91.18089960"},{"name":"Chandpur District","isoCode":"09","countryCode":"BD","latitude":"23.25131480","longitude":"90.85178460"},{"name":"Chittagong District","isoCode":"10","countryCode":"BD","latitude":"22.51501050","longitude":"91.75388170"},{"name":"Cox\'s Bazar District","isoCode":"11","countryCode":"BD","latitude":"21.56406260","longitude":"92.02821290"},{"name":"Chuadanga District","isoCode":"12","countryCode":"BD","latitude":"23.61605120","longitude":"88.82630060"},{"name":"Dhaka District","isoCode":"13","countryCode":"BD","latitude":"23.81051400","longitude":"90.33718890"},{"name":"Dinajpur District","isoCode":"14","countryCode":"BD","latitude":"25.62791230","longitude":"88.63317580"},{"name":"Faridpur District","isoCode":"15","countryCode":"BD","latitude":"23.54239190","longitude":"89.63089210"},{"name":"Feni District","isoCode":"16","countryCode":"BD","latitude":"22.94087840","longitude":"91.40666460"},{"name":"Gopalganj District","isoCode":"17","countryCode":"BD","latitude":"26.48315840","longitude":"84.43655000"},{"name":"Gazipur District","isoCode":"18","countryCode":"BD","latitude":"24.09581710","longitude":"90.41251810"},{"name":"Gaibandha District","isoCode":"19","countryCode":"BD","latitude":"25.32969280","longitude":"89.54296520"},{"name":"Habiganj District","isoCode":"20","countryCode":"BD","latitude":"24.47712360","longitude":"91.45065650"},{"name":"Jamalpur District","isoCode":"21","countryCode":"BD","latitude":"25.08309260","longitude":"89.78532180"},{"name":"Jessore District","isoCode":"22","countryCode":"BD","latitude":"23.16340140","longitude":"89.21816640"},{"name":"Jhenaidah District","isoCode":"23","countryCode":"BD","latitude":"23.54498730","longitude":"89.17260310"},{"name":"Joypurhat District","isoCode":"24","countryCode":"BD","latitude":"25.09473490","longitude":"89.09449370"},{"name":"Jhalokati District","isoCode":"25","countryCode":"BD","latitude":"22.57208000","longitude":"90.18696440"},{"name":"Kishoreganj District","isoCode":"26","countryCode":"BD","latitude":"24.42604570","longitude":"90.98206680"},{"name":"Khulna District","isoCode":"27","countryCode":"BD","latitude":"22.67377350","longitude":"89.39665810"},{"name":"Kurigram District","isoCode":"28","countryCode":"BD","latitude":"25.80724140","longitude":"89.62947460"},{"name":"Khagrachari District","isoCode":"29","countryCode":"BD","latitude":"23.13217510","longitude":"91.94902100"},{"name":"Kushtia District","isoCode":"30","countryCode":"BD","latitude":"23.89069950","longitude":"89.10993680"},{"name":"Lakshmipur District","isoCode":"31","countryCode":"BD","latitude":"22.94467440","longitude":"90.82819070"},{"name":"Lalmonirhat District","isoCode":"32","countryCode":"BD","latitude":"25.99233980","longitude":"89.28472510"},{"name":"Bahadia","isoCode":"33","countryCode":"BD","latitude":"23.78987120","longitude":"90.16714830"},{"name":"Mymensingh District","isoCode":"34","countryCode":"BD","latitude":"24.75385750","longitude":"90.40729190"},{"name":"Munshiganj District","isoCode":"35","countryCode":"BD","latitude":"23.49809310","longitude":"90.41266210"},{"name":"Madaripur District","isoCode":"36","countryCode":"BD","latitude":"23.23933460","longitude":"90.18696440"},{"name":"Moulvibazar District","isoCode":"38","countryCode":"BD","latitude":"24.30953440","longitude":"91.73149030"},{"name":"Meherpur District","isoCode":"39","countryCode":"BD","latitude":"23.80519910","longitude":"88.67235780"},{"name":"Narayanganj District","isoCode":"40","countryCode":"BD","latitude":"23.71466010","longitude":"90.56360900"},{"name":"Netrokona District","isoCode":"41","countryCode":"BD","latitude":"24.81032840","longitude":"90.86564150"},{"name":"Narail District","isoCode":"43","countryCode":"BD","latitude":"23.11629290","longitude":"89.58404040"},{"name":"Natore District","isoCode":"44","countryCode":"BD","latitude":"24.41024300","longitude":"89.00761770"}
1,{"name":"Chapai Nawabganj District","isoCode":"45","countryCode":"BD","latitude":"24.74131110","longitude":"88.29120690"},{"name":"Nilphamari District","isoCode":"46","countryCode":"BD","latitude":"25.84827980","longitude":"88.94141340"},{"name":"Noakhali District","isoCode":"47","countryCode":"BD","latitude":"22.87237890","longitude":"91.09731840"},{"name":"Naogaon District","isoCode":"48","countryCode":"BD","latitude":"24.91315970","longitude":"88.75309520"},{"name":"Pabna District","isoCode":"49","countryCode":"BD","latitude":"24.15850500","longitude":"89.44807180"},{"name":"Pirojpur District","isoCode":"50","countryCode":"BD","latitude":"22.57907440","longitude":"89.97592640"},{"name":"Patuakhali District","isoCode":"51","countryCode":"BD","latitude":"22.22486320","longitude":"90.45475030"},{"name":"Panchagarh District","isoCode":"52","countryCode":"BD","latitude":"26.27087050","longitude":"88.59517510"},{"name":"Rajbari District","isoCode":"53","countryCode":"BD","latitude":"23.71513400","longitude":"89.58748190"},{"name":"Rajshahi District","isoCode":"54","countryCode":"BD","latitude":"24.37330870","longitude":"88.60487160"},{"name":"Rangpur District","isoCode":"55","countryCode":"BD","latitude":"25.74679250","longitude":"89.25083350"},{"name":"Rangamati Hill District","isoCode":"56","countryCode":"BD","latitude":"22.73241730","longitude":"92.29851340"},{"name":"Sherpur District","isoCode":"57","countryCode":"BD","latitude":"25.07462350","longitude":"90.14949040"},{"name":"Satkhira District","isoCode":"58","countryCode":"BD","latitude":"22.31548120","longitude":"89.11145250"},{"name":"Sirajganj District","isoCode":"59","countryCode":"BD","latitude":"24.31411150","longitude":"89.56996150"},{"name":"Sylhet District","isoCode":"60","countryCode":"BD","latitude":"24.89933570","longitude":"91.87004730"},{"name":"Sunamganj District","isoCode":"61","countryCode":"BD","latitude":"25.07145350","longitude":"91.39916270"},{"name":"Shariatpur District","isoCode":"62","countryCode":"BD","latitude":"23.24232140","longitude":"90.43477110"},{"name":"Tangail District","isoCode":"63","countryCode":"BD","latitude":"24.39174270","longitude":"89.99482570"},{"name":"Thakurgaon District","isoCode":"64","countryCode":"BD","latitude":"26.04183920","longitude":"88.42826160"},{"name":"Barisal Division","isoCode":"A","countryCode":"BD","latitude":"22.38111310","longitude":"90.33718890"},{"name":"Chittagong Division","isoCode":"B","countryCode":"BD","latitude":"23.17931570","longitude":"91.98815270"},{"name":"Dhaka Division","isoCode":"C","countryCode":"BD","latitude":"23.95357420","longitude":"90.14949880"},{"name":"Khulna Division","isoCode":"D","countryCode":"BD","latitude":"22.80878160","longitude":"89.24671910"},{"name":"Rajshahi Division","isoCode":"E","countryCode":"BD","latitude":"24.71057760","longitude":"88.94138650"},{"name":"Rangpur Division","isoCode":"F","countryCode":"BD","latitude":"25.84833880","longitude":"88.94138650"},{"name":"Sylhet Division","isoCode":"G","countryCode":"BD","latitude":"24.70498110","longitude":"91.67606910"},{"name":"Mymensingh Division","isoCode":"H","countryCode":"BD","latitude":"24.71362000","longitude":"90.45023680"},{"name":"Brussels-Capital Region","isoCode":"BRU","countryCode":"BE","latitude":"50.85034630","longitude":"4.35172110"},{"name":"Antwerp","isoCode":"VAN","countryCode":"BE","latitude":"51.21944750","longitude":"4.40246430"},{"name":"Flemish Brabant","isoCode":"VBR","countryCode":"BE","latitude":"50.88154340","longitude":"4.56459700"},{"name":"Flanders","isoCode":"VLG","countryCode":"BE","latitude":"51.01087060","longitude":"3.72646130"},{"name":"Limburg","isoCode":"VLI","countryCode":"BE","latitude":null,"longitude":null},{"name":"East Flanders","isoCode":"VOV","countryCode":"BE","latitude":"51.03621010","longitude":"3.73731240"},{"name":"West Flanders","isoCode":"VWV","countryCode":"BE","latitude":"40.01793340","longitude":"-105.28067330"},{"name":"Wallonia","isoCode":"WAL","countryCode":"BE","latitude":"50.41756370","longitude":"4.45100660"},{"name":"Walloon Brabant","isoCode":"WBR","countryCode":"BE","latitude":"50.63324100","longitude":"4.52431500"},{"name":"Hainaut","isoCode":"WHT","countryCode":"BE","latitude":"50.52570760","longitude":"4.06210170"},{"name":"Liège","isoCode":"WLG","countryCode":"BE","latitude":"50.63255740","longitude":"5.57966620"},{"name":"Luxembourg","isoCode":"WLX","countryCode":"BE","latitude":"49.81527300","longitude":"6.12958300"},{"name":"Namur","isoCode":"WNA","countryCode":"BE","latitude":"50.46738830","longitude":"4.87198540"},{"name":"Boucle du Mouhoun Region","isoCode":"01","countryCode":"BF","latitude":"12.41660000","longitude":"-3.41955270"},{"name":"Cascades Region","isoCode":"02","countryCode":"BF","latitude":"10.40729920","longitude":"-4.56244260"},{"name":"Centre","isoCode":"03","countryCode":"BF","latitude":null,"longitude":null},{"name":"Centre-Est Region","isoCode":"04","countryCode":"BF","latitude":"11.52476740","longitude":"-0.14949880"},{"name":"Centre-Nord Region","isoCode":"05","countryCode":"BF","latitude":"13.17244640","longitude":"-0.90566230"},{"name":"Centre-Ouest Region","isoCode":"06","countryCode":"BF","latitude":"11.87984660","longitude":"-2.30244600"},{"name":"Centre-Sud Region","isoCode":"07","countryCode":"BF","latitude":"11.52289110","longitude":"-1.05861350"},{"name":"Est Region","isoCode":"08","countryCode":"BF","latitude":"12.43655260","longitude":"0.90566230"},{"name":"Hauts-Bassins Region","isoCode":"09","countryCode":"BF","latitude":"11.49420030","longitude":"-4.23333550"},{"name":"Nord Region, Burkina Faso","isoCode":"10","countryCode":"BF","latitude":"13.71825200","longitude":"-2.30244600"},{"name":"Plateau-Central Region","isoCode":"11","countryCode":"BF","latitude":"12.25376480","longitude":"-0.75328090"},{"name":"Sahel Region","isoCode":"12","countryCode":"BF","latitude":"14.10008650","longitude":"-0.14949880"},{"name":"Sud-Ouest Region","isoCode":"13","countryCode":"BF","latitude":"10.42314930","longitude":"-3.25836260"},{"name":"Balé Province","isoCode":"BAL","countryCode":"BF","latitude":"11.78206020","longitude":"-3.01757120"},{"name":"Bam Province","isoCode":"BAM","countryCode":"BF","latitude":"13.44613300","longitude":"-1.59839590"},{"name":"Banwa Province","isoCode":"BAN","countryCode":"BF","latitude":"12.13230530","longitude":"-4.15137640"},{"name":"Bazèga Province","isoCode":"BAZ","countryCode":"BF","latitude":"11.97676920","longitude":"-1.44346900"},{"name":"Bougouriba Province","isoCode":"BGR","countryCode":"BF","latitude":"10.87226460","longitude":"-3.33889170"},{"name":"Boulgou","isoCode":"BLG","countryCode":"BF","latitude":"11.43367660","longitude":"-0.37483540"},{"name":"Comoé Province","isoCode":"COM","countryCode":"BF","latitude":"10.40729920","longitude":"-4.56244260"},{"name":"Ganzourgou Province","isoCode":"GAN","countryCode":"BF","latitude":"12.25376480","longitude":"-0.75328090"},{"name":"Gnagna Province","isoCode":"GNA","countryCode":"BF","latitude":"12.89749920","longitude":"0.07467670"},{"name":"Gourma Province","isoCode":"GOU","countryCode":"BF","latitude":"12.16244730","longitude":"0.67730460"},{"name":"Houet Province","isoCode":"HOU","countryCode":"BF","latitude":"11.13204470","longitude":"-4.23333550"},{"name":"Ioba Province","isoCode":"IOB","countryCode":"BF","latitude":"11.05620340","longitude":"-3.01757120"},{"name":"Kadiogo Province","isoCode":"KAD","countryCode":"BF","latitude":"12.34258970","longitude":"-1.44346900"},{"name":"Kénédougou Province","isoCode":"KEN","countryCode":"BF","latitude":"11.39193950","longitude":"-4.97665400"},{"name":"Komondjari Province","isoCode":"KMD","countryCode":"BF","latitude":"12.71265270","longitude":"0.67730460"},{"name":"Kompienga Province","isoCode":"KMP","countryCode":"BF","latitude":"11.52383620","longitude":"0.75328090"},{"name":"Koulpélogo Province","isoCode":"KOP","countryCode":"BF","latitude":"11.52476740","longitude":"0.14949880"},{"name":"Kossi Province","isoCode":"KOS","countryCode":"BF","latitude":"12.96045800","longitude":"-3.90626880"},{"name":"Kouritenga Province","isoCode":"KOT","countryCode":"BF","latitude":"12.16318130","longitude":"-0.22446620"},{"name":"Kourwéogo Province","isoCode":"KOW","countryCode":"BF","latitude":"12.70774950","longitude":"-1.75388170"},{"name":"Léraba Province","isoCode":"LER","countryCode":"BF","latitude":"10.66487850","longitude":"-5.31025050"},{"name":"Loroum Province","isoCode":"LOR","countryCode":"BF","latitude":"13.81298140","longitude":"-2.06651970"},{"name":"Mouhoun","isoCode":"MOU","countryCode":"BF","latitude":"12.14323810","longitude":"-3.33889170"},{"name":"Namentenga Province","isoCode":"NAM","countryCode":"BF","latitude":"13.08125840","longitude":"-0.52578230"},{"name":"Nahouri Province","isoCode":"NAO","countryCode":"BF","latitude":"11.25022670","longitude":"-1.13530200"},{"name":"Nayala Province","isoCode":"NAY","countryCode":"BF","latitude":"12.69645580","longitude":"-3.01757120"},{"name":"Noumbiel Province","isoCode":"NOU","countryCode":"BF","latitude":"9.84409460","longitude":"-2.97755580"},{"name":"Oubritenga Province","isoCode":"OUB","countryCode":"BF","latitude":"12.70960870","longitude":"-1.44346900"},{"name":"Oudalan Province","isoCode":"OUD","countryCode":"BF","latitude":"14.47190200","longitude":"-0.45023680"},{"name":"Passoré Province","isoCode":"PAS","countryCode":"BF","latitude":"12.88812210","longitude":"-2.22366670"},{"name":"Poni Province","isoCode":"PON","countryCode":"BF","latitude":"10.33259960","longitude":"-3.33889170"},{"name":"Séno Province","isoCode":"SEN","countryCode":"BF","latitude":"14.00722340","longitude":"-0.07467670"},{"name":"Sissili Province","isoCode":"SIS","countryCode":"BF","latitude":"11.24412190","longitude":"-2.22366670"},{"name":"Sanmatenga Province","isoCode":"SMT","countryCode":"BF","latitude":"13.35653040","longitude":"-1.05861350"},{"name":"Sanguié Province","isoCode":"SNG","countryCode":"BF","latitude":"12.15018610","longitude":"-2.69838680"},{"name":"Soum Province","isoCode":"SOM","countryCode":"BF","latitude":"14.09628410","longitude":"-1.36621600"},{"name":"Sourou Province","isoCode":"SOR","countryCode":"BF","latitude":"13.34180300","longitude":"-2.93757390"},{"name":"Tapoa Province","isoCode":"TAP","countryCode":"BF","latitude":"12.24970720","longitude":"1.67606910"},{"name":"Tuy Province","isoCode":"TUI","countryCode":"BF","latitude":"38.88868400","longitude":"-77.00471900"},{"name":"Yagha Province","isoCode":"YAG","countryCode":"BF","latitude":"13.35761570","longitude":"0.75328090"},{"name":"Yatenga Province","isoCode":"YAT","countryCode":"BF","latitude":"13.62493440","longitude":"-2.38136210"},{"name":"Ziro Province","isoCode":"ZIR","countryCode":"BF","latitude":"11.60949950","longitude":"-1.90992380"},{"name":"Zondoma Province","isoCode":"ZON","countryCode":"BF","latitude":"13.11659260","longitude":"-2.42087130"},{"name":"Zoundwéogo Province","isoCode":"ZOU","countryCode":"BF","latitude":"11.61411740","longitude":"-0.98206680"},{"name":"Blagoevgrad Province","isoCode":"01","countryCode":"BG","latitude":"42.0208614
10","longitude":"23.09433560"},{"name":"Burgas Province","isoCode":"02","countryCode":"BG","latitude":"42.50480000","longitude":"27.46260790"},{"name":"Varna Province","isoCode":"03","countryCode":"BG","latitude":"43.20464770","longitude":"27.91054880"},{"name":"Veliko Tarnovo Province","isoCode":"04","countryCode":"BG","latitude":"43.07565390","longitude":"25.61715000"},{"name":"Vidin Province","isoCode":"05","countryCode":"BG","latitude":"43.99617390","longitude":"22.86795150"},{"name":"Vratsa Province","isoCode":"06","countryCode":"BG","latitude":"43.21018060","longitude":"23.55292100"},{"name":"Gabrovo Province","isoCode":"07","countryCode":"BG","latitude":"42.86847000","longitude":"25.31688900"},{"name":"Dobrich Province","isoCode":"08","countryCode":"BG","latitude":"43.57278600","longitude":"27.82728020"},{"name":"Kardzhali Province","isoCode":"09","countryCode":"BG","latitude":"41.63384160","longitude":"25.37766870"},{"name":"Kyustendil Province","isoCode":"10","countryCode":"BG","latitude":"42.28687990","longitude":"22.69396350"},{"name":"Lovech Province","isoCode":"11","countryCode":"BG","latitude":"43.13677980","longitude":"24.71393350"},{"name":"Montana Province","isoCode":"12","countryCode":"BG","latitude":"43.40851480","longitude":"23.22575890"},{"name":"Pazardzhik Province","isoCode":"13","countryCode":"BG","latitude":"42.19275670","longitude":"24.33362260"},{"name":"Pernik Province","isoCode":"14","countryCode":"BG","latitude":"42.60519900","longitude":"23.03779160"},{"name":"Pleven Province","isoCode":"15","countryCode":"BG","latitude":"43.41701690","longitude":"24.60667080"},{"name":"Plovdiv Province","isoCode":"16","countryCode":"BG","latitude":"42.13540790","longitude":"24.74529040"},{"name":"Razgrad Province","isoCode":"17","countryCode":"BG","latitude":"43.52717050","longitude":"26.52412280"},{"name":"Ruse Province","isoCode":"18","countryCode":"BG","latitude":"43.83559640","longitude":"25.96561440"},{"name":"Silistra Province","isoCode":"19","countryCode":"BG","latitude":"44.11471010","longitude":"27.26714540"},{"name":"Sliven Province","isoCode":"20","countryCode":"BG","latitude":"42.68167020","longitude":"26.32285690"},{"name":"Smolyan Province","isoCode":"21","countryCode":"BG","latitude":"41.57741480","longitude":"24.70108710"},{"name":"Sofia City Province","isoCode":"22","countryCode":"BG","latitude":"42.75701090","longitude":"23.45046830"},{"name":"Sofia Province","isoCode":"23","countryCode":"BG","latitude":"42.67344000","longitude":"23.83349370"},{"name":"Stara Zagora Province","isoCode":"24","countryCode":"BG","latitude":"42.42577090","longitude":"25.63448550"},{"name":"Targovishte Province","isoCode":"25","countryCode":"BG","latitude":"43.24623490","longitude":"26.56912510"},{"name":"Haskovo Province","isoCode":"26","countryCode":"BG","latitude":"41.93441780","longitude":"25.55546720"},{"name":"Shumen","isoCode":"27","countryCode":"BG","latitude":"43.27123980","longitude":"26.93612860"},{"name":"Yambol Province","isoCode":"28","countryCode":"BG","latitude":"42.48414940","longitude":"26.50352960"},{"name":"Capital Governorate","isoCode":"13","countryCode":"BH","latitude":null,"longitude":null},{"name":"Southern Governorate","isoCode":"14","countryCode":"BH","latitude":"25.93810180","longitude":"50.57568870"},{"name":"Muharraq Governorate","isoCode":"15","countryCode":"BH","latitude":"26.26856530","longitude":"50.64825170"},{"name":"Central Governorate","isoCode":"16","countryCode":"BH","latitude":"26.14260930","longitude":"50.56532940"},{"name":"Northern Governorate","isoCode":"17","countryCode":"BH","latitude":"26.15519140","longitude":"50.48251730"},{"name":"Bubanza Province","isoCode":"BB","countryCode":"BI","latitude":"-3.15724030","longitude":"29.37149090"},{"name":"Bujumbura Rural Province","isoCode":"BL","countryCode":"BI","latitude":"-3.50901440","longitude":"29.46435900"},{"name":"Bujumbura Mairie Province","isoCode":"BM","countryCode":"BI","latitude":"-3.38841410","longitude":"29.34826460"},{"name":"Bururi Province","isoCode":"BR","countryCode":"BI","latitude":"-3.90068510","longitude":"29.51077080"},{"name":"Cankuzo Province","isoCode":"CA","countryCode":"BI","latitude":"-3.15277880","longitude":"30.61998950"},{"name":"Cibitoke Province","isoCode":"CI","countryCode":"BI","latitude":"-2.81028970","longitude":"29.18557850"},{"name":"Gitega Province","isoCode":"GI","countryCode":"BI","latitude":"-3.49290510","longitude":"29.92779470"},{"name":"Kirundo Province","isoCode":"KI","countryCode":"BI","latitude":"-2.57628820","longitude":"30.11273500"},{"name":"Karuzi Province","isoCode":"KR","countryCode":"BI","latitude":"-3.13403470","longitude":"30.11273500"},{"name":"Kayanza Province","isoCode":"KY","countryCode":"BI","latitude":"-3.00779810","longitude":"29.64991620"},{"name":"Makamba Province","isoCode":"MA","countryCode":"BI","latitude":"-4.32570620","longitude":"29.69626770"},{"name":"Muramvya Province","isoCode":"MU","countryCode":"BI","latitude":"-3.28983980","longitude":"29.64991620"},{"name":"Mwaro Province","isoCode":"MW","countryCode":"BI","latitude":"-3.50259180","longitude":"29.64991620"},{"name":"Muyinga Province","isoCode":"MY","countryCode":"BI","latitude":"-2.77935110","longitude":"30.29741990"},{"name":"Ngozi Province","isoCode":"NG","countryCode":"BI","latitude":"-2.89582430","longitude":"29.88152030"},{"name":"Rumonge Province","isoCode":"RM","countryCode":"BI","latitude":"-3.97540490","longitude":"29.43880140"},{"name":"Rutana Province","isoCode":"RT","countryCode":"BI","latitude":"-3.87915230","longitude":"30.06652360"},{"name":"Ruyigi Province","isoCode":"RY","countryCode":"BI","latitude":"-3.44620700","longitude":"30.25127280"},{"name":"Atakora Department","isoCode":"AK","countryCode":"BJ","latitude":"10.79549310","longitude":"1.67606910"},{"name":"Alibori Department","isoCode":"AL","countryCode":"BJ","latitude":"10.96810930","longitude":"2.77798130"},{"name":"Atlantique Department","isoCode":"AQ","countryCode":"BJ","latitude":"6.65883910","longitude":"2.22366670"},{"name":"Borgou Department","isoCode":"BO","countryCode":"BJ","latitude":"9.53408640","longitude":"2.77798130"},{"name":"Collines Department","isoCode":"CO","countryCode":"BJ","latitude":"8.30222970","longitude":"2.30244600"},{"name":"Donga Department","isoCode":"DO","countryCode":"BJ","latitude":"9.71918670","longitude":"1.67606910"},{"name":"Kouffo Department","isoCode":"KO","countryCode":"BJ","latitude":"7.00358940","longitude":"1.75388170"},{"name":"Littoral Department","isoCode":"LI","countryCode":"BJ","latitude":"6.38069730","longitude":"2.44063870"},{"name":"Mono Department","isoCode":"MO","countryCode":"BJ","latitude":"37.92186080","longitude":"-118.95286450"},{"name":"Ouémé Department","isoCode":"OU","countryCode":"BJ","latitude":"6.61481520","longitude":"2.49999180"},{"name":"Plateau Department","isoCode":"PL","countryCode":"BJ","latitude":"7.34451410","longitude":"2.53960300"},{"name":"Zou Department","isoCode":"ZO","countryCode":"BJ","latitude":"7.34692680","longitude":"2.06651970"},{"name":"Devonshire Parish","isoCode":"DEV","countryCode":"BM","latitude":"32.30380620","longitude":"-64.76069540"},{"name":"Hamilton Parish","isoCode":"HA","countryCode":"BM","latitude":"32.34494320","longitude":"-64.72365000"},{"name":"Paget Parish","isoCode":"PAG","countryCode":"BM","latitude":"32.28107400","longitude":"-64.77847870"},{"name":"Pembroke Parish","isoCode":"PEM","countryCode":"BM","latitude":"32.30076720","longitude":"-64.79626300"},{"name":"Sandys Parish","isoCode":"SAN","countryCode":"BM","latitude":"32.29995280","longitude":"-64.86741030"},{"name":"Saint George\'s Parish","isoCode":"SGE","countryCode":"BM","latitude":"17.12577590","longitude":"-62.56198110"},{"name":"Smith\'s Parish,","isoCode":"SMI","countryCode":"BM","latitude":"32.31339660","longitude":"-64.73105880"},{"name":"Southampton Parish","isoCode":"SOU","countryCode":"BM","latitude":"32.25400950","longitude":"-64.82590580"},{"name":"Warwick Parish","isoCode":"WAR","countryCode":"BM","latitude":"32.26615340","longitude":"-64.80811980"},{"name":"Belait District","isoCode":"BE","countryCode":"BN","latitude":"4.37507490","longitude":"114.61928990"},{"name":"Brunei-Muara District","isoCode":"BM","countryCode":"BN","latitude":"4.93112060","longitude":"114.95168690"},{"name":"Temburong District","isoCode":"TE","countryCode":"BN","latitude":"4.62041280","longitude":"115.14148400"},{"name":"Tutong District","isoCode":"TU","countryCode":"BN","latitude":"4.71403730","longitude":"114.66679390"},{"name":"Beni Department","isoCode":"B","countryCode":"BO","latitude":"-14.37827470","longitude":"-65.09577920"},{"name":"Cochabamba Department","isoCode":"C","countryCode":"BO","latitude":"-17.56816750","longitude":"-65.47573600"},{"name":"Chuquisaca Department","isoCode":"H","countryCode":"BO","latitude":"-20.02491440","longitude":"-64.14782360"},{"name":"La Paz Department","isoCode":"L","countryCode":"BO","latitude":null,"longitude":null},{"name":"Pando Department","isoCode":"N","countryCode":"BO","latitude":"-10.79889010","longitude":"-66.99880110"},{"name":"Oruro Department","isoCode":"O","countryCode":"BO","latitude":"-18.57115790","longitude":"-67.76159830"},{"name":"Potosà Department","isoCode":"P","countryCode":"BO","latitude":"-20.62471300","longitude":"-66.99880110"},{"name":"Santa Cruz Department","isoCode":"S","countryCode":"BO","latitude":"-16.74760370","longitude":"-62.07509980"},{"name":"Tarija Department","isoCode":"T","countryCode":"BO","latitude":"-21.58315950","longitude":"-63.95861110"},{"name":"Acre","isoCode":"AC","countryCode":"BR","latitude":"-9.02379600","longitude":"-70.81199500"},{"name":"Alagoas","isoCode":"AL","countryCode":"BR","latitude":"-9.57130580","longitude":"-36.78195050"},{"name":"Amazonas","isoCode":"AM","countryCode":"BR","latitude":"-3.07000000","longitude":"-61.
166000000"},{"name":"Amapá","isoCode":"AP","countryCode":"BR","latitude":"0.90199250","longitude":"-52.00295650"},{"name":"Bahia","isoCode":"BA","countryCode":"BR","latitude":"-11.40987400","longitude":"-41.28085700"},{"name":"Ceará","isoCode":"CE","countryCode":"BR","latitude":"-5.49839770","longitude":"-39.32062410"},{"name":"Distrito Federal","isoCode":"DF","countryCode":"BR","latitude":"-15.79976540","longitude":"-47.86447150"},{"name":"EspÃrito Santo","isoCode":"ES","countryCode":"BR","latitude":"-19.18342290","longitude":"-40.30886260"},{"name":"Goiás","isoCode":"GO","countryCode":"BR","latitude":"-15.82703690","longitude":"-49.83622370"},{"name":"Maranhão","isoCode":"MA","countryCode":"BR","latitude":"-4.96094980","longitude":"-45.27441590"},{"name":"Minas Gerais","isoCode":"MG","countryCode":"BR","latitude":"-18.51217800","longitude":"-44.55503080"},{"name":"Mato Grosso do Sul","isoCode":"MS","countryCode":"BR","latitude":"-20.77222950","longitude":"-54.78515310"},{"name":"Mato Grosso","isoCode":"MT","countryCode":"BR","latitude":"-12.68187120","longitude":"-56.92109900"},{"name":"Pará","isoCode":"PA","countryCode":"BR","latitude":"-1.99812710","longitude":"-54.93061520"},{"name":"ParaÃba","isoCode":"PB","countryCode":"BR","latitude":"-7.23996090","longitude":"-36.78195050"},{"name":"Pernambuco","isoCode":"PE","countryCode":"BR","latitude":"-8.81371730","longitude":"-36.95410700"},{"name":"PiauÃ","isoCode":"PI","countryCode":"BR","latitude":"-7.71834010","longitude":"-42.72892360"},{"name":"Paraná","isoCode":"PR","countryCode":"BR","latitude":"-25.25208880","longitude":"-52.02154150"},{"name":"Rio de Janeiro","isoCode":"RJ","countryCode":"BR","latitude":"-22.90684670","longitude":"-43.17289650"},{"name":"Rio Grande do Norte","isoCode":"RN","countryCode":"BR","latitude":"-5.40258030","longitude":"-36.95410700"},{"name":"Rondônia","isoCode":"RO","countryCode":"BR","latitude":"-11.50573410","longitude":"-63.58061100"},{"name":"Roraima","isoCode":"RR","countryCode":"BR","latitude":"2.73759710","longitude":"-62.07509980"},{"name":"Rio Grande do Sul","isoCode":"RS","countryCode":"BR","latitude":"-30.03463160","longitude":"-51.21769860"},{"name":"Santa Catarina","isoCode":"SC","countryCode":"BR","latitude":"-27.33000000","longitude":"-49.44000000"},{"name":"Sergipe","isoCode":"SE","countryCode":"BR","latitude":"-10.57409340","longitude":"-37.38565810"},{"name":"São Paulo","isoCode":"SP","countryCode":"BR","latitude":"-23.55051990","longitude":"-46.63330940"},{"name":"Tocantins","isoCode":"TO","countryCode":"BR","latitude":"-10.17528000","longitude":"-48.29824740"},{"name":"Acklins and Crooked Islands","isoCode":"AC","countryCode":"BS","latitude":"22.36577080","longitude":"-74.05351260"},{"name":"Acklins","isoCode":"AK","countryCode":"BS","latitude":"22.36577080","longitude":"-74.05351260"},{"name":"Bimini","isoCode":"BI","countryCode":"BS","latitude":"24.64153250","longitude":"-79.85062260"},{"name":"Black Point","isoCode":"BP","countryCode":"BS","latitude":"41.39510240","longitude":"-71.46505560"},{"name":"Berry Islands","isoCode":"BY","countryCode":"BS","latitude":"25.62500420","longitude":"-77.82522030"},{"name":"Central Eleuthera","isoCode":"CE","countryCode":"BS","latitude":"25.13620370","longitude":"-76.14359150"},{"name":"Cat Island","isoCode":"CI","countryCode":"BS","latitude":"30.22801360","longitude":"-89.10149330"},{"name":"Crooked Island","isoCode":"CK","countryCode":"BS","latitude":"22.63909820","longitude":"-74.00650900"},{"name":"Central Abaco","isoCode":"CO","countryCode":"BS","latitude":"26.35550290","longitude":"-77.14851630"},{"name":"Central Andros","isoCode":"CS","countryCode":"BS","latitude":"24.46884820","longitude":"-77.97386500"},{"name":"East Grand Bahama","isoCode":"EG","countryCode":"BS","latitude":"26.65828230","longitude":"-78.22482910"},{"name":"Exuma","isoCode":"EX","countryCode":"BS","latitude":"23.61925980","longitude":"-75.96954650"},{"name":"Fresh Creek","isoCode":"FC","countryCode":"BS","latitude":"40.65437560","longitude":"-73.89479390"},{"name":"Freeport","isoCode":"FP","countryCode":"BS","latitude":"42.29668610","longitude":"-89.62122710"},{"name":"Grand Cay","isoCode":"GC","countryCode":"BS","latitude":"27.21626150","longitude":"-78.32305590"},{"name":"Governor\'s Harbour","isoCode":"GH","countryCode":"BS","latitude":"25.19480960","longitude":"-76.24396220"},{"name":"Green Turtle Cay","isoCode":"GT","countryCode":"BS","latitude":"26.77471070","longitude":"-77.32957080"},{"name":"Harbour Island","isoCode":"HI","countryCode":"BS","latitude":"25.50011000","longitude":"-76.63405110"},{"name":"High Rock","isoCode":"HR","countryCode":"BS","latitude":"46.68434150","longitude":"-121.90174610"},{"name":"Hope Town","isoCode":"HT","countryCode":"BS","latitude":"26.50095040","longitude":"-76.99598720"},{"name":"Inagua","isoCode":"IN","countryCode":"BS","latitude":"21.06560660","longitude":"-73.32370800"},{"name":"Kemps Bay","isoCode":"KB","countryCode":"BS","latitude":"24.02364000","longitude":"-77.54534900"},{"name":"Long Island","isoCode":"LI","countryCode":"BS","latitude":"40.78914200","longitude":"-73.13496100"},{"name":"Mangrove Cay","isoCode":"MC","countryCode":"BS","latitude":"24.14814250","longitude":"-77.76809520"},{"name":"Mayaguana District","isoCode":"MG","countryCode":"BS","latitude":"22.40177140","longitude":"-73.06413960"},{"name":"Marsh Harbour","isoCode":"MH","countryCode":"BS","latitude":"26.52416530","longitude":"-77.09098090"},{"name":"Nichollstown and Berry Islands","isoCode":"NB","countryCode":"BS","latitude":"25.72362340","longitude":"-77.83101040"},{"name":"North Eleuthera","isoCode":"NE","countryCode":"BS","latitude":"25.46475170","longitude":"-76.67592200"},{"name":"North Abaco","isoCode":"NO","countryCode":"BS","latitude":"26.78716970","longitude":"-77.43577390"},{"name":"New Providence","isoCode":"NP","countryCode":"BS","latitude":"40.69843480","longitude":"-74.40154050"},{"name":"North Andros","isoCode":"NS","countryCode":"BS","latitude":"24.70638050","longitude":"-78.01953870"},{"name":"Rum Cay District","isoCode":"RC","countryCode":"BS","latitude":"23.68546760","longitude":"-74.83901620"},{"name":"Ragged Island","isoCode":"RI","countryCode":"BS","latitude":"41.59743100","longitude":"-71.26020200"},{"name":"Rock Sound","isoCode":"RS","countryCode":"BS","latitude":"39.01424430","longitude":"-95.67089890"},{"name":"South Andros","isoCode":"SA","countryCode":"BS","latitude":"23.97135560","longitude":"-77.60778650"},{"name":"South Eleuthera","isoCode":"SE","countryCode":"BS","latitude":"24.77085620","longitude":"-76.21314740"},{"name":"South Abaco","isoCode":"SO","countryCode":"BS","latitude":"26.06405910","longitude":"-77.26350380"},{"name":"Sandy Point","isoCode":"SP","countryCode":"BS","latitude":"39.01454640","longitude":"-76.39989250"},{"name":"San Salvador and Rum Cay","isoCode":"SR","countryCode":"BS","latitude":"23.68546760","longitude":"-74.83901620"},{"name":"San Salvador Island","isoCode":"SS","countryCode":"BS","latitude":"24.07755460","longitude":"-74.47600880"},{"name":"Spanish Wells","isoCode":"SW","countryCode":"BS","latitude":"26.32505990","longitude":"-81.79803280"},{"name":"West Grand Bahama","isoCode":"WG","countryCode":"BS","latitude":"26.65944700","longitude":"-78.52065000"},{"name":"Paro District","isoCode":"11","countryCode":"BT","latitude":"27.42859490","longitude":"89.41665160"},{"name":"Chukha District","isoCode":"12","countryCode":"BT","latitude":"27.07843040","longitude":"89.47421770"},{"name":"Haa District","isoCode":"13","countryCode":"BT","latitude":"27.26516690","longitude":"89.17059980"},{"name":"Samtse District","isoCode":"14","countryCode":"BT","latitude":"27.02918320","longitude":"89.05615320"},{"name":"Thimphu District","isoCode":"15","countryCode":"BT","latitude":"27.47122160","longitude":"89.63390410"},{"name":"Tsirang District","isoCode":"21","countryCode":"BT","latitude":"27.03220700","longitude":"90.18696440"},{"name":"Dagana District","isoCode":"22","countryCode":"BT","latitude":"27.03228610","longitude":"89.88793040"},{"name":"Punakha District","isoCode":"23","countryCode":"BT","latitude":"27.69037160","longitude":"89.88793040"},{"name":"Wangdue Phodrang District","isoCode":"24","countryCode":"BT","latitude":"27.45260460","longitude":"90.06749280"},{"name":"Sarpang District","isoCode":"31","countryCode":"BT","latitude":"26.93730410","longitude":"90.48799160"},{"name":"Trongsa District","isoCode":"32","countryCode":"BT","latitude":"27.50022690","longitude":"90.50806340"},{"name":"Bumthang District","isoCode":"33","countryCode":"BT","latitude":"27.64183900","longitude":"90.67730460"},{"name":"Zhemgang District","isoCode":"34","countryCode":"BT","latitude":"27.07697500","longitude":"90.82940020"},{"name":"Trashigang District","isoCode":"41","countryCode":"BT","latitude":"27.25667950","longitude":"91.75388170"},{"name":"Mongar District","isoCode":"42","countryCode":"BT","latitude":"27.26170590","longitude":"91.289
110360"},{"name":"Pemagatshel District","isoCode":"43","countryCode":"BT","latitude":"27.00238200","longitude":"91.34692470"},{"name":"Lhuntse District","isoCode":"44","countryCode":"BT","latitude":"27.82649890","longitude":"91.13530200"},{"name":"Samdrup Jongkhar District","isoCode":"45","countryCode":"BT","latitude":"26.80356820","longitude":"91.50392070"},{"name":"Gasa District","isoCode":"GA","countryCode":"BT","latitude":"28.01858860","longitude":"89.92532330"},{"name":"Central District","isoCode":"CE","countryCode":"BW","latitude":null,"longitude":null},{"name":"Ghanzi District","isoCode":"GH","countryCode":"BW","latitude":"-21.86523140","longitude":"21.85685860"},{"name":"Kgalagadi District","isoCode":"KG","countryCode":"BW","latitude":"-24.75502850","longitude":"21.85685860"},{"name":"Kgatleng District","isoCode":"KL","countryCode":"BW","latitude":"-24.19704450","longitude":"26.23046160"},{"name":"Kweneng District","isoCode":"KW","countryCode":"BW","latitude":"-23.83672490","longitude":"25.28375850"},{"name":"North-East District","isoCode":"NE","countryCode":"BW","latitude":"37.58844610","longitude":"-94.68637820"},{"name":"Ngamiland","isoCode":"NG","countryCode":"BW","latitude":"-19.19053210","longitude":"23.00119890"},{"name":"North-West District","isoCode":"NW","countryCode":"BW","latitude":"39.34463070","longitude":"-76.68542830"},{"name":"South-East District","isoCode":"SE","countryCode":"BW","latitude":"31.21637980","longitude":"-82.35270440"},{"name":"Southern District","isoCode":"SO","countryCode":"BW","latitude":null,"longitude":null},{"name":"Brest Region","isoCode":"BR","countryCode":"BY","latitude":"52.52966410","longitude":"25.46064800"},{"name":"Minsk","isoCode":"HM","countryCode":"BY","latitude":"53.90060110","longitude":"27.55897200"},{"name":"Gomel Region","isoCode":"HO","countryCode":"BY","latitude":"52.16487540","longitude":"29.13332510"},{"name":"Grodno Region","isoCode":"HR","countryCode":"BY","latitude":"53.65999450","longitude":"25.34485710"},{"name":"Mogilev Region","isoCode":"MA","countryCode":"BY","latitude":"53.51017910","longitude":"30.40064440"},{"name":"Minsk Region","isoCode":"MI","countryCode":"BY","latitude":"54.10678890","longitude":"27.41292450"},{"name":"Vitebsk Region","isoCode":"VI","countryCode":"BY","latitude":"55.29598330","longitude":"28.75836270"},{"name":"Belize District","isoCode":"BZ","countryCode":"BZ","latitude":"17.56776790","longitude":"-88.40160410"},{"name":"Cayo District","isoCode":"CY","countryCode":"BZ","latitude":"17.09844450","longitude":"-88.94138650"},{"name":"Corozal District","isoCode":"CZL","countryCode":"BZ","latitude":"18.13492380","longitude":"-88.24611830"},{"name":"Orange Walk District","isoCode":"OW","countryCode":"BZ","latitude":"17.76035300","longitude":"-88.86469800"},{"name":"Stann Creek District","isoCode":"SC","countryCode":"BZ","latitude":"16.81166310","longitude":"-88.40160410"},{"name":"Toledo District","isoCode":"TOL","countryCode":"BZ","latitude":"16.24919230","longitude":"-88.86469800"},{"name":"Alberta","isoCode":"AB","countryCode":"CA","latitude":"53.93327060","longitude":"-116.57650350"},{"name":"British Columbia","isoCode":"BC","countryCode":"CA","latitude":"53.72666830","longitude":"-127.64762050"},{"name":"Manitoba","isoCode":"MB","countryCode":"CA","latitude":"53.76086080","longitude":"-98.81387620"},{"name":"New Brunswick","isoCode":"NB","countryCode":"CA","latitude":"46.56531630","longitude":"-66.46191640"},{"name":"Newfoundland and Labrador","isoCode":"NL","countryCode":"CA","latitude":"53.13550910","longitude":"-57.66043640"},{"name":"Nova Scotia","isoCode":"NS","countryCode":"CA","latitude":"44.68198660","longitude":"-63.74431100"},{"name":"Northwest Territories","isoCode":"NT","countryCode":"CA","latitude":"64.82554410","longitude":"-124.84573340"},{"name":"Nunavut","isoCode":"NU","countryCode":"CA","latitude":"70.29977110","longitude":"-83.10757700"},{"name":"Ontario","isoCode":"ON","countryCode":"CA","latitude":"51.25377500","longitude":"-85.32321400"},{"name":"Prince Edward Island","isoCode":"PE","countryCode":"CA","latitude":"46.51071200","longitude":"-63.41681360"},{"name":"Quebec","isoCode":"QC","countryCode":"CA","latitude":"52.93991590","longitude":"-73.54913610"},{"name":"Saskatchewan","isoCode":"SK","countryCode":"CA","latitude":"52.93991590","longitude":"-106.45086390"},{"name":"Yukon","isoCode":"YT","countryCode":"CA","latitude":"35.50672150","longitude":"-97.76254410"},{"name":"Kongo Central","isoCode":"BC","countryCode":"CD","latitude":"-5.23656850","longitude":"13.91439900"},{"name":"Bas-Uélé","isoCode":"BU","countryCode":"CD","latitude":"3.99010090","longitude":"24.90422080"},{"name":"Ãquateur","isoCode":"EQ","countryCode":"CD","latitude":"-1.83123900","longitude":"-78.18340600"},{"name":"Haut-Katanga","isoCode":"HK","countryCode":"CD","latitude":"-10.41020750","longitude":"27.54958460"},{"name":"Haut-Lomami","isoCode":"HL","countryCode":"CD","latitude":"-7.70527520","longitude":"24.90422080"},{"name":"Haut-Uélé","isoCode":"HU","countryCode":"CD","latitude":"3.58451540","longitude":"28.29943500"},{"name":"Ituri","isoCode":"IT","countryCode":"CD","latitude":"1.59576820","longitude":"29.41793240"},{"name":"Kasaï Central","isoCode":"KC","countryCode":"CD","latitude":"-8.44045910","longitude":"20.41659340"},{"name":"Kasaï Oriental","isoCode":"KE","countryCode":"CD","latitude":"-6.03362300","longitude":"23.57285010"},{"name":"Kwango","isoCode":"KG","countryCode":"CD","latitude":"-6.43374090","longitude":"17.66888700"},{"name":"Kwilu","isoCode":"KL","countryCode":"CD","latitude":"-5.11888250","longitude":"18.42760470"},{"name":"Kinshasa","isoCode":"KN","countryCode":"CD","latitude":"-4.44193110","longitude":"15.26629310"},{"name":"Kasaï","isoCode":"KS","countryCode":"CD","latitude":"-5.04719790","longitude":"20.71224650"},{"name":"Lomami","isoCode":"LO","countryCode":"CD","latitude":"-6.14539310","longitude":"24.52426400"},{"name":"Lualaba","isoCode":"LU","countryCode":"CD","latitude":"-10.4808698
10","longitude":"25.62978160"},{"name":"Maniema","isoCode":"MA","countryCode":"CD","latitude":"-3.07309290","longitude":"26.04138890"},{"name":"Mai-Ndombe","isoCode":"MN","countryCode":"CD","latitude":"-2.63574340","longitude":"18.42760470"},{"name":"Mongala","isoCode":"MO","countryCode":"CD","latitude":"1.99623240","longitude":"21.47528510"},{"name":"Nord-Kivu","isoCode":"NK","countryCode":"CD","latitude":"-0.79177290","longitude":"29.04599270"},{"name":"Nord-Ubangi","isoCode":"NU","countryCode":"CD","latitude":"3.78787260","longitude":"21.47528510"},{"name":"Sankuru","isoCode":"SA","countryCode":"CD","latitude":"-2.84374530","longitude":"23.38235450"},{"name":"Sud-Kivu","isoCode":"SK","countryCode":"CD","latitude":"-3.01165800","longitude":"28.29943500"},{"name":"Sud-Ubangi","isoCode":"SU","countryCode":"CD","latitude":"3.22999420","longitude":"19.18800470"},{"name":"Tanganyika","isoCode":"TA","countryCode":"CD","latitude":"-6.27401180","longitude":"27.92490020"},{"name":"Tshopo","isoCode":"TO","countryCode":"CD","latitude":"0.54554620","longitude":"24.90422080"},{"name":"Tshuapa","isoCode":"TU","countryCode":"CD","latitude":"-0.99030230","longitude":"23.02888440"},{"name":"Ouham Prefecture","isoCode":"AC","countryCode":"CF","latitude":"7.09091100","longitude":"17.66888700"},{"name":"Bamingui-Bangoran Prefecture","isoCode":"BB","countryCode":"CF","latitude":"8.27334550","longitude":"20.71224650"},{"name":"Bangui","isoCode":"BGF","countryCode":"CF","latitude":"4.39467350","longitude":"18.55818990"},{"name":"Basse-Kotto Prefecture","isoCode":"BK","countryCode":"CF","latitude":"4.87193190","longitude":"21.28450250"},{"name":"Haute-Kotto Prefecture","isoCode":"HK","countryCode":"CF","latitude":"7.79643790","longitude":"23.38235450"},{"name":"Haut-Mbomou Prefecture","isoCode":"HM","countryCode":"CF","latitude":"6.25371340","longitude":"25.47335540"},{"name":"Mambéré-Kadéï","isoCode":"HS","countryCode":"CF","latitude":"4.70556530","longitude":"15.96998780"},{"name":"Nana-Grébizi Economic Prefecture","isoCode":"KB","countryCode":"CF","latitude":"7.18486070","longitude":"19.37832060"},{"name":"Kémo Prefecture","isoCode":"KG","countryCode":"CF","latitude":"5.88677940","longitude":"19.37832060"},{"name":"Lobaye Prefecture","isoCode":"LB","countryCode":"CF","latitude":"4.35259810","longitude":"17.47951730"},{"name":"Mbomou Prefecture","isoCode":"MB","countryCode":"CF","latitude":"5.55683700","longitude":"23.76328280"},{"name":"Ombella-M\'Poko Prefecture","isoCode":"MP","countryCode":"CF","latitude":"5.11888250","longitude":"18.42760470"},{"name":"Nana-Mambéré Prefecture","isoCode":"NM","countryCode":"CF","latitude":"5.69321350","longitude":"15.21948080"},{"name":"Ouham-Pendé Prefecture","isoCode":"OP","countryCode":"CF","latitude":"6.48509840","longitude":"16.15809370"},{"name":"Sangha-Mbaéré","isoCode":"SE","countryCode":"CF","latitude":"3.43686070","longitude":"16.34637910"},{"name":"Ouaka Prefecture","isoCode":"UK","countryCode":"CF","latitude":"6.31682160","longitude":"20.71224650"},{"name":"Vakaga Prefecture","isoCode":"VK","countryCode":"CF","latitude":"9.51132960","longitude":"22.23840170"},{"name":"Bouenza Department","isoCode":"11","countryCode":"CG","latitude":"-4.11280790","longitude":"13.72891670"},{"name":"Pool Department","isoCode":"12","countryCode":"CG","latitude":"-3.77626280","longitude":"14.84546190"},{"name":"Sangha Department","isoCode":"13","countryCode":"CG","latitude":"1.46623280","longitude":"15.40680790"},{"name":"Plateaux Department","isoCode":"14","countryCode":"CG","latitude":"-2.06800880","longitude":"15.40680790"},{"name":"Cuvette-Ouest Department","isoCode":"15","countryCode":"CG","latitude":"0.14475500","longitude":"14.47233010"},{"name":"Pointe-Noire","isoCode":"16","countryCode":"CG","latitude":"-4.76916230","longitude":"11.86636200"},{"name":"Lékoumou Department","isoCode":"2","countryCode":"CG","latitude":"-3.17038200","longitude":"13.35872880"},{"name":"Kouilou Department","isoCode":"5","countryCode":"CG","latitude":"-4.14284130","longitude":"11.88917210"},{"name":"Likouala Department","isoCode":"7","countryCode":"CG","latitude":"2.04392400","longitude":"17.66888700"},{"name":"Cuvette Department","isoCode":"8","countryCode":"CG","latitude":"-0.28774460","longitude":"16.15809370"},{"name":"Niari Department","isoCode":"9","countryCode":"CG","latitude":"-3.18427000","longitude":"12.25479190"},{"name":"Brazzaville","isoCode":"BZV","countryCode":"CG","latitude":"-4.26335970","longitude":"15.24288530"},{"name":"Aargau","isoCode":"AG","countryCode":"CH","latitude":"47.38766640","longitude":"8.25542950"},{"name":"Appenzell Innerrhoden","isoCode":"AI","countryCode":"CH","latitude":"47.31619250","longitude":"9.43165730"},{"name":"Appenzell Ausserrhoden","isoCode":"AR","countryCode":"CH","latitude":"47.36648100","longitude":"9.30009160"},{"name":"Bern","isoCode":"BE","countryCode":"CH","latitude":"46.798862
110","longitude":"7.70807010"},{"name":"Basel-Land","isoCode":"BL","countryCode":"CH","latitude":"47.44181220","longitude":"7.76440020"},{"name":"Basel-Stadt","isoCode":"BS","countryCode":"CH","latitude":"47.56666700","longitude":"7.60000000"},{"name":"Fribourg","isoCode":"FR","countryCode":"CH","latitude":"46.68167480","longitude":"7.11726350"},{"name":"Geneva","isoCode":"GE","countryCode":"CH","latitude":"46.21800730","longitude":"6.12169250"},{"name":"Glarus","isoCode":"GL","countryCode":"CH","latitude":"47.04112320","longitude":"9.06790000"},{"name":"Graubünden","isoCode":"GR","countryCode":"CH","latitude":"46.65698710","longitude":"9.57802570"},{"name":"Jura","isoCode":"JU","countryCode":"CH","latitude":"47.34444740","longitude":"7.14306080"},{"name":"Lucerne","isoCode":"LU","countryCode":"CH","latitude":"47.07956710","longitude":"8.16624450"},{"name":"Neuchâtel","isoCode":"NE","countryCode":"CH","latitude":"46.98998740","longitude":"6.92927320"},{"name":"Nidwalden","isoCode":"NW","countryCode":"CH","latitude":"46.92670160","longitude":"8.38499820"},{"name":"Obwalden","isoCode":"OW","countryCode":"CH","latitude":"46.87785800","longitude":"8.25124900"},{"name":"St. Gallen","isoCode":"SG","countryCode":"CH","latitude":"47.14562540","longitude":"9.35043320"},{"name":"Schaffhausen","isoCode":"SH","countryCode":"CH","latitude":"47.70093640","longitude":"8.56800400"},{"name":"Solothurn","isoCode":"SO","countryCode":"CH","latitude":"47.33207170","longitude":"7.63883850"},{"name":"Schwyz","isoCode":"SZ","countryCode":"CH","latitude":"47.02071380","longitude":"8.65298840"},{"name":"Thurgau","isoCode":"TG","countryCode":"CH","latitude":"47.60378560","longitude":"9.05573710"},{"name":"Ticino","isoCode":"TI","countryCode":"CH","latitude":"46.33173400","longitude":"8.80045290"},{"name":"Uri","isoCode":"UR","countryCode":"CH","latitude":"41.48606470","longitude":"-71.53085370"},{"name":"Vaud","isoCode":"VD","countryCode":"CH","latitude":"46.56131350","longitude":"6.53676500"},{"name":"Valais","isoCode":"VS","countryCode":"CH","latitude":"46.19046140","longitude":"7.54492260"},{"name":"Zug","isoCode":"ZG","countryCode":"CH","latitude":"47.16615050","longitude":"8.51547490"},{"name":"Zürich","isoCode":"ZH","countryCode":"CH","latitude":"47.35953600","longitude":"8.63564520"},{"name":"Lagunes region","isoCode":"01","countryCode":"CI","latitude":"5.88273340","longitude":"-4.23333550"},{"name":"Haut-Sassandra","isoCode":"02","countryCode":"CI","latitude":"6.87578480","longitude":"-6.57833870"},{"name":"Savanes Region","isoCode":"03","countryCode":"CI","latitude":null,"longitude":null},{"name":"Vallée du Bandama Region","isoCode":"04","countryCode":"CI","latitude":"8.27897800","longitude":"-4.89356270"},{"name":"Moyen-Comoé","isoCode":"05","countryCode":"CI","latitude":"6.65149170","longitude":"-3.50034540"},{"name":"Dix-Huit Montagnes","isoCode":"06","countryCode":"CI","latitude":"7.37623730","longitude":"-7.43813550"},{"name":"Lacs Region","isoCode":"07","countryCode":"CI","latitude":"47.73958660","longitude":"-70.41866520"},{"name":"Bas-Sassandra Region","isoCode":"09","countryCode":"CI","latitude":"5.35679160","longitude":"-6.74939930"},{"name":"Denguélé Region","isoCode":"10","countryCode":"CI","latitude":"9.46623720","longitude":"-7.43813550"},{"name":"N\'zi-Comoé","isoCode":"11","countryCode":"CI","latitude":"7.24567490","longitude":"-4.23333550"},{"name":"Marahoué Region","isoCode":"12","countryCode":"CI","latitude":"6.88462070","longitude":"-5.89871390"},{"name":"Sud-Comoé","isoCode":"13","countryCode":"CI","latitude":"5.55279300","longitude":"-3.25836260"},{"name":"Worodougou","isoCode":"14","countryCode":"CI","latitude":"8.25489620","longitude":"-6.57833870"},{"name":"Sud-Bandama","isoCode":"15","countryCode":"CI","latitude":"5.53570830","longitude":"-5.56172790"},{"name":"Agnéby","isoCode":"16","countryCode":"CI","latitude":"5.32245030","longitude":"-4.34495290"},{"name":"Bafing Region","isoCode":"17","countryCode":"CI","latitude":"8.32520470","longitude":"-7.52472430"},{"name":"Fromager","isoCode":"18","countryCode":"CI","latitude":"45.54502130","longitude":"-73.60462230"},{"name":"Moyen-Cavally","isoCode":"19","countryCode":"CI","latitude":"6.52087930","longitude":"-7.61142170"},{"name":"Abidjan","isoCode":"AB","countryCode":"CI","latitude":"5.35995170","longitude":"-4.00825630"},{"name":"Bas-Sassandra District","isoCode":"BS","countryCode":"CI","latitude":"5.27983560","longitude":"-6.15269850"},{"name":"Comoé District","isoCode":"CM","countryCode":"CI","latitude":"5.55279300","longitude":"-3.25836260"},{"name":"Denguélé District","isoCode":"DN","countryCode":"CI","latitude":"48.07077630","longitude":"-68.56093410"},{"name":"Gôh-Djiboua District","isoCode":"GD","countryCode":"CI","latitude":"5.87113930","longitude":"-5.56172790"},{"name":"Lacs District","isoCode":"LC","countryCode":"CI","latitude":"48.19801690","longitude":"-80.45644120"},{"name":"Lagunes District","isoCode":"LG","countryCode":"CI","latitude":"5.88273340","longitude":"-4.23333550"},{"name":"Montagnes District","isoCode":"MG","countryCode":"CI","latitude":"7.37623730","longitude":"-7.43813550"},{"name":"Sassandra-Marahoué District","isoCode":"SM","countryCode":"CI","latitude":"6.88033480","longitude":"-6.23759470"}
1,{"name":"Vallée du Bandama District","isoCode":"VB","countryCode":"CI","latitude":"8.27897800","longitude":"-4.89356270"},{"name":"Woroba District","isoCode":"WR","countryCode":"CI","latitude":"8.24913720","longitude":"-6.92091350"},{"name":"Yamoussoukro","isoCode":"YM","countryCode":"CI","latitude":"6.82762280","longitude":"-5.28934330"},{"name":"Zanzan Region","isoCode":"ZZ","countryCode":"CI","latitude":"8.82079040","longitude":"-3.41955270"},{"name":"Aisén del General Carlos Ibañez del Campo","isoCode":"AI","countryCode":"CL","latitude":"-46.37834500","longitude":"-72.30076230"},{"name":"Antofagasta","isoCode":"AN","countryCode":"CL","latitude":"-23.83691040","longitude":"-69.28775350"},{"name":"Arica y Parinacota","isoCode":"AP","countryCode":"CL","latitude":"-18.59404850","longitude":"-69.47845410"},{"name":"La AraucanÃa","isoCode":"AR","countryCode":"CL","latitude":"-38.94892100","longitude":"-72.33111300"},{"name":"Atacama","isoCode":"AT","countryCode":"CL","latitude":"-27.56605580","longitude":"-70.05031400"},{"name":"BiobÃo","isoCode":"BI","countryCode":"CL","latitude":"-37.44644280","longitude":"-72.14161320"},{"name":"Coquimbo","isoCode":"CO","countryCode":"CL","latitude":"-30.54018100","longitude":"-70.81199530"},{"name":"Libertador General Bernardo O\'Higgins","isoCode":"LI","countryCode":"CL","latitude":"-34.57553740","longitude":"-71.00223110"},{"name":"Los Lagos","isoCode":"LL","countryCode":"CL","latitude":"-41.91977790","longitude":"-72.14161320"},{"name":"Los RÃos","isoCode":"LR","countryCode":"CL","latitude":"-40.23102170","longitude":"-72.33111300"},{"name":"Magallanes y de la Antártica Chilena","isoCode":"MA","countryCode":"CL","latitude":"-52.20643160","longitude":"-72.16850010"},{"name":"Maule","isoCode":"ML","countryCode":"CL","latitude":"-35.51636030","longitude":"-71.57239530"},{"name":"Ãuble","isoCode":"NB","countryCode":"CL","latitude":"-36.72257430","longitude":"-71.76224810"},{"name":"Región Metropolitana de Santiago","isoCode":"RM","countryCode":"CL","latitude":"-33.43755450","longitude":"-70.65048960"},{"name":"Tarapacá","isoCode":"TA","countryCode":"CL","latitude":"-20.20287990","longitude":"-69.28775350"},{"name":"ValparaÃso","isoCode":"VS","countryCode":"CL","latitude":"-33.04723800","longitude":"-71.61268850"},{"name":"Adamawa","isoCode":"AD","countryCode":"CM","latitude":"9.32647510","longitude":"12.39838530"},{"name":"Centre","isoCode":"CE","countryCode":"CM","latitude":null,"longitude":null},{"name":"Far North","isoCode":"EN","countryCode":"CM","latitude":"66.76134510","longitude":"124.12375300"},{"name":"East","isoCode":"ES","countryCode":"CM","latitude":"39.01853360","longitude":"-94.27924110"},{"name":"Littoral","isoCode":"LT","countryCode":"CM","latitude":"48.46227570","longitude":"-68.51780710"},{"name":"North","isoCode":"NO","countryCode":"CM","latitude":"37.09024000","longitude":"-95.71289100"},{"name":"Northwest","isoCode":"NW","countryCode":"CM","latitude":"36.37118570","longitude":"-94.19346060"},{"name":"West","isoCode":"OU","countryCode":"CM","latitude":"37.03649890","longitude":"-95.67059870"},{"name":"South","isoCode":"SU","countryCode":"CM","latitude":"37.63159500","longitude":"-97.34584090"},{"name":"Southwest","isoCode":"SW","countryCode":"CM","latitude":"36.19088130","longitude":"-95.88974480"},{"name":"Anhui","isoCode":"AH","countryCode":"CN","latitude":"30.60067730","longitude":"117.92490020"},{"name":"Beijing","isoCode":"BJ","countryCode":"CN","latitude":"39.90419990","longitude":"116.40739630"},{"name":"Chongqing","isoCode":"CQ","countryCode":"CN","latitude":"29.43158610","longitude":"106.91225100"},{"name":"Fujian","isoCode":"FJ","countryCode":"CN","latitude":"26.48368420","longitude":"117.92490020"},{"name":"Guangdong","isoCode":"GD","countryCode":"CN","latitude":"23.37903330","longitude":"113.76328280"},{"name":"Gansu","isoCode":"GS","countryCode":"CN","latitude":"35.75183260","longitude":"104.28611160"},{"name":"Guangxi Zhuang","isoCode":"GX","countryCode":"CN","latitude":"23.72475990","longitude":"108.80761950"},{"name":"Guizhou","isoCode":"GZ","countryCode":"CN","latitude":"26.84296450","longitude":"107.29028390"},{"name":"Henan","isoCode":"HA","countryCode":"CN","latitude":"34.29043020","longitude":"113.38235450"},{"name":"Hubei","isoCode":"HB","countryCode":"CN","latitude":"30.73781180","longitude":"112.23840170"},{"name":"Hebei","isoCode":"HE","countryCode":"CN","latitude":"37.89565940","longitude":"114.90422080"},{"name":"Hainan","isoCode":"HI","countryCode":"CN","latitude":"19.56639470","longitude":"109.94968600"},{"name":"Hong Kong SAR","isoCode":"HK","countryCode":"CN","latitude":"22.31930390","longitude":"114.16936110"},{"name":"Heilongjiang","isoCode":"HL","countryCode":"CN","latitude":"47.12164720","longitude":"128.73823100"},{"name":"Hunan","isoCode":"HN","countryCode":"CN","latitude":"36.73412940","longitude":"-95.93449020"},{"name":"Jilin","isoCode":"JL","countryCode":"CN","latitude":"43.83788300","longitude":"126.54957200"},{"name":"Jiangsu","isoCode":"JS","countryCode":"CN","latitude":"33.14017150","longitude":"119.78892480"},{"name":"Jiangxi","isoCode":"JX","countryCode":"CN","latitude":"27.08745640","longitude":"114.90422080"},{"name":"Liaoning","isoCode":"LN","countryCode":"CN","latitude":"41.94365430","longitude":"122.52903760"},{"name":"Macau SAR","isoCode":"MO","countryCode":"CN","latitude":"22.19874500","longitude":"113.54387300"},{"name":"Inner Mongolia","isoCode":"NM","countryCode":"CN","latitude":"43.37822000","longitude":"115.05948150"},{"name":"Ningxia Huizu","isoCode":"NX","countryCode":"CN","latitude":"37.19873100","longitude":"106.15809370"},{"name":"Qinghai","isoCode":"QH","countryCode":"CN","latitude":"35.74479800","longitude":"96.40773580"},{"name":"Sichuan","isoCode":"SC","countryCode":"CN","latitude":"30.26380320","longitude":"102.80547530"},{"name":"Shandong","isoCode":"SD","countryCode":"CN","latitude":"37.80060640","longitude":"-122.26999180"},{"name":"Shanghai","isoCode":"SH","countryCode":"CN","latitude":"31.23041600","longitude":"121.47370100"},{"name":"Shaanxi","isoCode":"SN","countryCode":"CN","latitude":"35.39399080","longitude":"109.18800470"},{"name":"Shanxi","isoCode":"SX","countryCode":"CN","latitude":"37.24256490","longitude":"111.85685860"},{"name":"Tianjin","isoCode":"TJ","countryCode":"CN","latitude":"39.12522910","longitude":"117.01534350"},{"name":"Taiwan","isoCode":"TW","countryCode":"CN","latitude":"23.69781000","longitude":"120.96051500"},{"name":"Xinjiang","isoCode":"XJ","countryCode":"CN","latitude":"42.52463570","longitude":"87.53958550"},{"name":"Xizang","isoCode":"XZ","countryCode":"CN","latitude":"30.15336050","longitude":"88.78786780"},{"name":"Yunnan","isoCode":"YN","countryCode":"CN","latitude":"24.47528470","longitude":"101.34310580"},{"name":"Zhejiang","isoCode":"ZJ","countryCode":"CN","latitude":"29.14164320","longitude":"119.78892480"},{"name":"Amazonas","isoCode":"AMA","countryCode":"CO","latitude":"-1.44291230","longitude":"-71.57239530"},{"name":"Antioquia","isoCode":"ANT","countryCode":"CO","latitude":"7.19860640","longitude":"-75.34121790"},{"name":"Arauca","isoCode":"ARA","countryCode":"CO","latitude":"6.54730600","longitude":"-71.00223110"},{"name":"Atlántico","isoCode":"ATL","countryCode":"CO","latitude":"10.69661590","longitude":"-74.87410450"},{"name":"BolÃvar","isoCode":"BOL","countryCode":"CO","latitude":"8.67043820","longitude":"-74.03001220"},{"name":"Boyacá","isoCode":"BOY","countryCode":"CO","latitude":"5.45451100","longitude":"-73.36200300"},{"name":"Caldas","isoCode":"CAL","countryCode":"CO","latitude":"5.29826000","longitude":"-75.24790610"},{"name":"Caquetá","isoCode":"CAQ","countryCode":"CO","latitude":"0.86989200","longitude":"-73.84190630"}
1,{"name":"Casanare","isoCode":"CAS","countryCode":"CO","latitude":"5.75892690","longitude":"-71.57239530"},{"name":"Cauca","isoCode":"CAU","countryCode":"CO","latitude":"2.70498130","longitude":"-76.82596520"},{"name":"Cesar","isoCode":"CES","countryCode":"CO","latitude":"9.33729480","longitude":"-73.65362090"},{"name":"Chocó","isoCode":"CHO","countryCode":"CO","latitude":"5.25280330","longitude":"-76.82596520"},{"name":"Córdoba","isoCode":"COR","countryCode":"CO","latitude":"8.04929300","longitude":"-75.57405000"},{"name":"Cundinamarca","isoCode":"CUN","countryCode":"CO","latitude":"5.02600300","longitude":"-74.03001220"},{"name":"Bogotá D.C.","isoCode":"DC","countryCode":"CO","latitude":"4.28204150","longitude":"-74.50270420"},{"name":"GuainÃa","isoCode":"GUA","countryCode":"CO","latitude":"2.58539300","longitude":"-68.52471490"},{"name":"Guaviare","isoCode":"GUV","countryCode":"CO","latitude":"2.04392400","longitude":"-72.33111300"},{"name":"Huila","isoCode":"HUI","countryCode":"CO","latitude":"2.53593490","longitude":"-75.52766990"},{"name":"La Guajira","isoCode":"LAG","countryCode":"CO","latitude":"11.35477430","longitude":"-72.52048270"},{"name":"Magdalena","isoCode":"MAG","countryCode":"CO","latitude":"10.41130140","longitude":"-74.40566120"},{"name":"Meta","isoCode":"MET","countryCode":"CO","latitude":"39.76732580","longitude":"-104.97535950"},{"name":"Nariño","isoCode":"NAR","countryCode":"CO","latitude":"1.28915100","longitude":"-77.35794000"},{"name":"Norte de Santander","isoCode":"NSA","countryCode":"CO","latitude":"7.94628310","longitude":"-72.89880690"},{"name":"Putumayo","isoCode":"PUT","countryCode":"CO","latitude":"0.43595060","longitude":"-75.52766990"},{"name":"QuindÃo","isoCode":"QUI","countryCode":"CO","latitude":"4.46101910","longitude":"-75.66735600"},{"name":"Risaralda","isoCode":"RIS","countryCode":"CO","latitude":"5.31584750","longitude":"-75.99276520"},{"name":"Santander","isoCode":"SAN","countryCode":"CO","latitude":"6.64370760","longitude":"-73.65362090"},{"name":"Archipiélago de San Andrés, Providencia y Santa Catalina","isoCode":"SAP","countryCode":"CO","latitude":"12.55673240","longitude":"-81.71852530"},{"name":"Sucre","isoCode":"SUC","countryCode":"CO","latitude":"8.81397700","longitude":"-74.72328300"},{"name":"Tolima","isoCode":"TOL","countryCode":"CO","latitude":"4.09251680","longitude":"-75.15453810"},{"name":"Valle del Cauca","isoCode":"VAC","countryCode":"CO","latitude":"3.80088930","longitude":"-76.64127120"},{"name":"Vaupés","isoCode":"VAU","countryCode":"CO","latitude":"0.85535610","longitude":"-70.81199530"},{"name":"Vichada","isoCode":"VID","countryCode":"CO","latitude":"4.42344520","longitude":"-69.28775350"},{"name":"Alajuela Province","isoCode":"A","countryCode":"CR","latitude":"10.39158300","longitude":"-84.43827210"},{"name":"Provincia de Cartago","isoCode":"C","countryCode":"CR","latitude":"9.86223110","longitude":"-83.92141870"},{"name":"Guanacaste Province","isoCode":"G","countryCode":"CR","latitude":"10.62673990","longitude":"-85.44367060"},{"name":"Heredia Province","isoCode":"H","countryCode":"CR","latitude":"10.47352300","longitude":"-84.01674230"},{"name":"Limón Province","isoCode":"L","countryCode":"CR","latitude":"9.98963980","longitude":"-83.03324170"},{"name":"Puntarenas Province","isoCode":"P","countryCode":"CR","latitude":"9.21695310","longitude":"-83.33618800"},{"name":"San José Province","isoCode":"SJ","countryCode":"CR","latitude":"9.91297270","longitude":"-84.07682940"},{"name":"Pinar del RÃo Province","isoCode":"01","countryCode":"CU","latitude":"22.40762560","longitude":"-83.84730150"},{"name":"Havana Province","isoCode":"03","countryCode":"CU","latitude":"23.05406980","longitude":"-82.34518900"},{"name":"Matanzas Province","isoCode":"04","countryCode":"CU","latitude":"22.57671230","longitude":"-81.33994140"},{"name":"Villa Clara Province","isoCode":"05","countryCode":"CU","latitude":"22.49372040","longitude":"-79.91927020"},{"name":"Cienfuegos Province","isoCode":"06","countryCode":"CU","latitude":"22.23797830","longitude":"-80.36586500"},{"name":"Sancti SpÃritus Province","isoCode":"07","countryCode":"CU","latitude":"21.99382140","longitude":"-79.47038850"},{"name":"Ciego de Ãvila Province","isoCode":"08","countryCode":"CU","latitude":"21.93295150","longitude":"-78.56608520"},{"name":"Camagüey Province","isoCode":"09","countryCode":"CU","latitude":"21.21672470","longitude":"-77.74520810"},{"name":"Las Tunas Province","isoCode":"10","countryCode":"CU","latitude":"21.06051620","longitude":"-76.91820970"},{"name":"HolguÃn Province","isoCode":"11","countryCode":"CU","latitude":"20.78378930","longitude":"-75.80690820"},{"name":"Granma Province","isoCode":"12","countryCode":"CU","latitude":"20.38449020","longitude":"-76.64127120"},{"name":"Santiago de Cuba Province","isoCode":"13","countryCode":"CU","latitude":"20.23976820","longitude":"-75.99276520"},{"name":"Guantánamo Province","isoCode":"14","countryCode":"CU","latitude":"20.14559170","longitude":"-74.87410450"},{"name":"Artemisa Province","isoCode":"15","countryCode":"CU","latitude":"22.7
15229030","longitude":"-82.99316070"},{"name":"Mayabeque Province","isoCode":"16","countryCode":"CU","latitude":"22.89265290","longitude":"-81.95348150"},{"name":"Isla de la Juventud","isoCode":"99","countryCode":"CU","latitude":"21.70847370","longitude":"-82.82202320"},{"name":"Barlavento Islands","isoCode":"B","countryCode":"CV","latitude":"16.82368450","longitude":"-23.99348810"},{"name":"Brava","isoCode":"BR","countryCode":"CV","latitude":"40.98977780","longitude":"-73.68357150"},{"name":"Boa Vista","isoCode":"BV","countryCode":"CV","latitude":"38.74346600","longitude":"-120.73042970"},{"name":"Santa Catarina","isoCode":"CA","countryCode":"CV","latitude":"-27.24233920","longitude":"-50.21885560"},{"name":"Santa Catarina do Fogo","isoCode":"CF","countryCode":"CV","latitude":"14.93091040","longitude":"-24.32225770"},{"name":"Santa Cruz","isoCode":"CR","countryCode":"CV","latitude":"36.97411710","longitude":"-122.03079630"},{"name":"Maio Municipality","isoCode":"MA","countryCode":"CV","latitude":"15.20030980","longitude":"-23.16797930"},{"name":"Mosteiros","isoCode":"MO","countryCode":"CV","latitude":"37.89043480","longitude":"-25.82075560"},{"name":"Paul","isoCode":"PA","countryCode":"CV","latitude":"37.06250000","longitude":"-95.67706800"},{"name":"Porto Novo","isoCode":"PN","countryCode":"CV","latitude":"6.49685740","longitude":"2.62885230"},{"name":"Praia","isoCode":"PR","countryCode":"CV","latitude":"14.93305000","longitude":"-23.51332670"},{"name":"Ribeira Brava Municipality","isoCode":"RB","countryCode":"CV","latitude":"16.60707390","longitude":"-24.20338430"},{"name":"Ribeira Grande","isoCode":"RG","countryCode":"CV","latitude":"37.82103690","longitude":"-25.51481370"},{"name":"Ribeira Grande de Santiago","isoCode":"RS","countryCode":"CV","latitude":"14.98302980","longitude":"-23.65617250"},{"name":"Sotavento Islands","isoCode":"S","countryCode":"CV","latitude":"15.00000000","longitude":"-24.00000000"},{"name":"São Domingos","isoCode":"SD","countryCode":"CV","latitude":"15.02861650","longitude":"-23.56392200"},{"name":"São Filipe","isoCode":"SF","countryCode":"CV","latitude":"14.89516790","longitude":"-24.49456360"},{"name":"Sal","isoCode":"SL","countryCode":"CV","latitude":"26.59581220","longitude":"-80.20450830"},{"name":"São Miguel","isoCode":"SM","countryCode":"CV","latitude":"37.78041100","longitude":"-25.49704660"},{"name":"São Lourenço dos Ãrgãos","isoCode":"SO","countryCode":"CV","latitude":"15.05378410","longitude":"-23.60856120"},{"name":"São Vicente","isoCode":"SV","countryCode":"CV","latitude":"-23.96071570","longitude":"-46.39620220"},{"name":"Tarrafal","isoCode":"TA","countryCode":"CV","latitude":"15.27605780","longitude":"-23.74840770"},{"name":"Tarrafal de São Nicolau","isoCode":"TS","countryCode":"CV","latitude":"16.56364980","longitude":"-24.35494200"},{"name":"Nicosia District (LefkoÅa)","isoCode":"01","countryCode":"CY","latitude":"35.18556590","longitude":"33.38227640"},{"name":"Limassol District (Leymasun)","isoCode":"02","countryCode":"CY","latitude":"34.70713010","longitude":"33.02261740"},{"name":"Larnaca District (Larnaka)","isoCode":"03","countryCode":"CY","latitude":"34.85072060","longitude":"33.48319060"},{"name":"Famagusta District (MaÄusa)","isoCode":"04","countryCode":"CY","latitude":"35.28570230","longitude":"33.84112880"},{"name":"Paphos District (Pafos)","isoCode":"05","countryCode":"CY","latitude":"34.91645940","longitude":"32.49200880"},{"name":"Kyrenia District (Keryneia)","isoCode":"06","countryCode":"CY","latitude":"35.29919400","longitude":"33.23632460"},{"name":"Praha, Hlavnà mÄsto","isoCode":"10","countryCode":"CZ","latitude":"50.07553810","longitude":"14.43780050"},{"name":"StÅedoÄeský kraj","isoCode":"20","countryCode":"CZ","latitude":"49.87822230","longitude":"14.93629550"},{"name":"BeneÅ¡ov","isoCode":"201","countryCode":"CZ","latitude":"49.69008280","longitude":"14.77643990"},{"name":"Beroun","isoCode":"202","countryCode":"CZ","latitude":"49.95734280","longitude":"13.98407150"},{"name":"Kladno","isoCode":"203","countryCode":"CZ","latitude":"50.19402580","longitude":"14.10436570"},{"name":"KolÃn","isoCode":"204","countryCode":"CZ","latitude":"49.98832930","longitude":"15.05519770"},{"name":"Kutná Hora","isoCode":"205","countryCode":"CZ","latitude":"49.94920890","longitude":"15.24704400"},{"name":"MÄlnÃk","isoCode":"206","countryCode":"CZ","latitude":"50.31044150","longitude":"14.51792230"},{"name":"Mladá Boleslav","isoCode":"207","countryCode":"CZ","latitude":"50.42523170","longitude":"14.93624770"},{"name":"Nymburk","isoCode":"208","countryCode":"CZ","latitude":"50.18558160","longitude":"15.04366040"},{"name":"Praha-východ","isoCode":"209","countryCode":"CZ","latitude":"49.93893070","longitude":"14.79244720"},{"name":"Praha-západ","isoCode":"20A","countryCode":"CZ","latitude":"49.89352350","longitude":"14.32937790"},{"name":"PÅÃbram","isoCode":"20B","countryCode":"CZ","latitude":"49.69479590","longitude":"14.08238100"},{"name":"RakovnÃk","isoCode":"20C","countryCode":"CZ","latitude":"50.10612300","longitude":"13.73966230"},{"name":"JihoÄeský kraj","isoCode":"31","countryCode":"CZ","latitude":"48.94577890","longitude":"14.44160550"}
1,{"name":"Äeské BudÄjovice","isoCode":"311","countryCode":"CZ","latitude":"48.97755530","longitude":"14.51507470"},{"name":"Äeský Krumlov","isoCode":"312","countryCode":"CZ","latitude":"48.81273540","longitude":"14.31746570"},{"name":"JindÅichův Hradec","isoCode":"313","countryCode":"CZ","latitude":"49.14448230","longitude":"15.00613890"},{"name":"PÃsek","isoCode":"314","countryCode":"CZ","latitude":"49.34199380","longitude":"14.24697600"},{"name":"Prachatice","isoCode":"315","countryCode":"CZ","latitude":"49.01091000","longitude":"14.00000050"},{"name":"Strakonice","isoCode":"316","countryCode":"CZ","latitude":"49.26040430","longitude":"13.91030850"},{"name":"Tábor","isoCode":"317","countryCode":"CZ","latitude":"49.36462930","longitude":"14.71912930"},{"name":"PlzeÅský kraj","isoCode":"32","countryCode":"CZ","latitude":"49.41348120","longitude":"13.31572460"},{"name":"Domažlice","isoCode":"321","countryCode":"CZ","latitude":"49.43970270","longitude":"12.93114350"},{"name":"Klatovy","isoCode":"322","countryCode":"CZ","latitude":"49.39555490","longitude":"13.29509370"},{"name":"PlzeÅ-mÄsto","isoCode":"323","countryCode":"CZ","latitude":"49.73843140","longitude":"13.37363710"},{"name":"PlzeÅ-jih","isoCode":"324","countryCode":"CZ","latitude":"49.59048850","longitude":"13.57158610"},{"name":"PlzeÅ-sever","isoCode":"325","countryCode":"CZ","latitude":"49.87748930","longitude":"13.25374280"},{"name":"Rokycany","isoCode":"326","countryCode":"CZ","latitude":"49.82628270","longitude":"13.68749430"},{"name":"Tachov","isoCode":"327","countryCode":"CZ","latitude":"49.79878030","longitude":"12.63619210"},{"name":"Karlovarský kraj","isoCode":"41","countryCode":"CZ","latitude":"50.14350000","longitude":"12.75018990"},{"name":"Cheb","isoCode":"411","countryCode":"CZ","latitude":"50.07953340","longitude":"12.36986360"},{"name":"Karlovy Vary","isoCode":"412","countryCode":"CZ","latitude":"50.14350000","longitude":"12.75018990"},{"name":"Sokolov","isoCode":"413","countryCode":"CZ","latitude":"50.20134340","longitude":"12.60546360"},{"name":"Ãstecký kraj","isoCode":"42","countryCode":"CZ","latitude":"50.61190370","longitude":"13.78700860"},{"name":"DÄÄÃn","isoCode":"421","countryCode":"CZ","latitude":"50.77255630","longitude":"14.21276120"},{"name":"Chomutov","isoCode":"422","countryCode":"CZ","latitude":"50.45838720","longitude":"13.30179100"},{"name":"LitomÄÅice","isoCode":"423","countryCode":"CZ","latitude":"50.53841970","longitude":"14.13054580"},{"name":"Louny","isoCode":"424","countryCode":"CZ","latitude":"50.35398120","longitude":"13.80335510"},{"name":"Most","isoCode":"425","countryCode":"CZ","latitude":"37.15540830","longitude":"-94.29488840"},{"name":"Teplice","isoCode":"426","countryCode":"CZ","latitude":"50.65846050","longitude":"13.75132270"},{"name":"Ãstà nad Labem","isoCode":"427","countryCode":"CZ","latitude":"50.61190370","longitude":"13.78700860"},{"name":"Liberecký kraj","isoCode":"51","countryCode":"CZ","latitude":"50.65942400","longitude":"14.76324240"},{"name":"Äeská LÃpa","isoCode":"511","countryCode":"CZ","latitude":"50.67852010","longitude":"14.53969910"},{"name":"Jablonec nad Nisou","isoCode":"512","countryCode":"CZ","latitude":"50.72205280","longitude":"15.17031350"},{"name":"Liberec","isoCode":"513","countryCode":"CZ","latitude":"50.75641010","longitude":"14.99650410"},{"name":"Semily","isoCode":"514","countryCode":"CZ","latitude":"50.60515760","longitude":"15.32814090"},{"name":"Královéhradecký kraj","isoCode":"52","countryCode":"CZ","latitude":"50.35124840","longitude":"15.79764590"},{"name":"Hradec Králové","isoCode":"521","countryCode":"CZ","latitude":"50.24148050","longitude":"15.67430000"},{"name":"JiÄÃn","isoCode":"522","countryCode":"CZ","latitude":"50.43533250","longitude":"15.36104400"},{"name":"Náchod","isoCode":"523","countryCode":"CZ","latitude":"50.41457220","longitude":"16.16563470"},{"name":"Rychnov nad KnÄžnou","isoCode":"524","countryCode":"CZ","latitude":"50.16596510","longitude":"16.27768420"},{"name":"Trutnov","isoCode":"525","countryCode":"CZ","latitude":"50.56538380","longitude":"15.90909230"},{"name":"Pardubický kraj","isoCode":"53","countryCode":"CZ","latitude":"49.94444790","longitude":"16.28569160"},{"name":"Chrudim","isoCode":"531","countryCode":"CZ","latitude":"49.88302160","longitude":"15.82908660"},{"name":"Pardubice","isoCode":"532","countryCode":"CZ","latitude":"49.94444790","longitude":"16.28569160"},{"name":"Svitavy","isoCode":"533","countryCode":"CZ","latitude":"49.75516290","longitude":"16.46918610"},{"name":"Ãstà nad OrlicÃ","isoCode":"534","countryCode":"CZ","latitude":"49.97218010","longitude":"16.39966170"},{"name":"Kraj VysoÄina","isoCode":"63","countryCode":"CZ","latitude":"49.44900520","longitude":"15.64059340"},{"name":"HavlÃÄkův Brod","isoCode":"631","countryCode":"CZ","latitude":"49.60433640","longitude":"15.57965520"},{"name":"Jihlava","isoCode":"632","countryCode":"CZ","latitude":"49.39837820","longitude":"15.58704150"},{"name":"PelhÅimov","isoCode":"633","countryCode":"CZ","latitude":"49.43062070","longitude":"15.22298300"},{"name":"TÅebÃÄ","isoCode":"634","countryCode":"CZ","latitude":"49.21478690","longitude":"15.87955160"},{"name":"ŽÄár nad Sázavou","isoCode":"635","countryCode":"CZ","latitude":"49.56430120","longitude":"15.93910300"},{"name":"Jihomoravský kraj","isoCode":"64","countryCode":"CZ","latitude":"48.95445280","longitude":"16.76768990"},{"name":"Blansko","isoCode":"641","countryCode":"CZ","latitude":"49.36485020","longitude":"16.64775520"},{"name":"Brno-mÄsto","isoCode":"642","countryCode":"CZ","latitude":"49.19506020","longitude":"16.60683710"},{"name":"Brno-venkov","isoCode":"643","countryCode":"CZ","latitude":"49.12501380","longitude":"16.45588240"},{"name":"BÅeclav","isoCode":"644","countryCode":"CZ","latitude":"48.75314000","longitude":"16.88251690"},{"name":"HodonÃn","isoCode":"645","countryCode":"CZ","latitude":"48.85293910","longitude":"17.12600250"},{"name":"VyÅ¡kov","isoCode":"646","countryCode":"CZ","latitude":"49.21274450","longitude":"16.98559270"},{"name":"Znojmo","isoCode":"647","countryCode":"CZ","latitude":"48.92723270","longitude":"16.10378080"},{"name":"Olomoucký kraj","isoCode":"71","countryCode":"CZ","latitude":"49.65865490","longitude":"17.08114060"},{"name":"JesenÃk","isoCode":"711","countryCode":"CZ","latitude":"50.22462490","longitude":"17.19804710"},{"name":"Olomouc","isoCode":"712","countryCode":"CZ","latitude":"49.59377800","longitude":"17.25087870"},{"name":"ProstÄjov","isoCode":"713","countryCode":"CZ","latitude":"49.44184010","longitude":"17.12779040"},{"name":"PÅerov","isoCode":"714","countryCode":"CZ","latitude":"49.46713560","longitude":"17.50773320"},{"name":"Å umperk","isoCode":"715","countryCode":"CZ","latitude":"49.97784070","longitude":"16.97177540"},{"name":"ZlÃnský kraj","isoCode":"72","countryCode":"CZ","latitude":"49.21622960","longitude":"17.77203530"},{"name":"KromÄÅÞ","isoCode":"721","countryCode":"CZ","latitude":"49.29165820","longitude":"17.39938000"},{"name":"Uherské HradiÅ¡tÄ","isoCode":"722","countryCode":"CZ","latitude":"49.05979690","longitude":"17.49585010"},{"name":"VsetÃn","isoCode":"723","countryCode":"CZ","latitude":"49.37932500","longitude":"18.06181620"},{"name":"ZlÃn","isoCode":"724","countryCode":"CZ","latitude":"49.16960520","longitude":"17.80252200"},{"name":"Moravskoslezský kraj","isoCode":"80","countryCode":"CZ","latitude":"49.73053270","longitude":"18.23326370"},{"name":"Bruntál","isoCode":"801","countryCode":"CZ","latitude":"49.98817670","longitude":"17.46369410"},{"name":"Frýdek-MÃstek","isoCode":"802","countryCode":"CZ","latitude":"49.68193050","longitude":"18.36732160"},{"name":"Karviná","isoCode":"803","countryCode":"CZ","latitude":"49.85665240","longitude":"18.54321860"},{"name":"Nový JiÄÃn","isoCode":"804","countryCode":"CZ","latitude":"49.59432510","longitude":"18.01353560"},{"name":"Opava","isoCode":"805","countryCode":"CZ","latitude":"49.90837570","longitude":"17.91633800"},{"name":"Ostrava-mÄsto","isoCode":"806","countryCode":"CZ","latitude":"49.82092260","longitude":"18.26252430"},{"name":"Brandenburg","isoCode":"BB","countryCode":"DE","latitude":"52.41252870","longitude":"12.53164440"},{"name":"Berlin","isoCode":"BE","countryCode":"DE","latitude":"52.52000660","longitude":"13.40495400"},{"name":"Baden-Württemberg","isoCode":"BW","countryCode":"DE","latitude":"48.66160370","longitude":"9.35013360"},{"name":"Bavaria","isoCode":"BY","countryCode":"DE","latitude":"48.79044720","longitude":"11.49788950"},{"name":"Bremen","isoCode":"HB","countryCode":"DE","latitude":"53.07929620","longitude":"8.80169360"},{"name":"Hesse","isoCode":"HE","countryCode":"DE","latitude":"50.65205150","longitude":"9.16243760"},{"name":"Hamburg","isoCode":"HH","countryCode":"DE","latitude":"53.55108460","longitude":"9.99368190"},{"name":"Mecklenburg-Vorpommern","isoCode":"MV","countryCode":"DE","latitude":"53.61265050","longitude":"12.42959530"},{"name":"Lower Saxony","isoCode":"NI","countryCode":"DE","latitude":"52.63670360","longitude":"9.84507660"},{"name":"North Rhine-Westphalia","isoCode":"NW","countryCode":"DE","latitude":"51.43323670","longitude":"7.66159380"},{"name":"Rhineland-Palatinate","isoCode":"RP","countryCode":"DE","latitude":"50.11834600","longitude":"7.30895270"},{"name":"Schleswig-Holstein","isoCode":"SH","countryCode":"DE","latitude":"54.21936720","longitude":"9.69611670"},{"name":"Saarland","isoCode":"SL","countryCode":"DE","latitude":"49.39642340","longitude":"7.02296070"},{"name":"Saxony","isoCode":"SN","countryCode":"DE","latitude":"51.10454070","longitude":"13.20173840"},{"name":"Saxony-Anhalt","isoCode":"ST","countryCode":"DE","latitude":"51.95026490","longitude":"11.69227340"},{"name":"Thuringia","isoCode":"TH","countryCode":"DE","latitude":"51.01098920","longitude":"10.84534600"},{"name":"Arta Region","isoCode":"AR","countryCode":"DJ","latitude":"11.52555280","longitude":"42.84794740"},{"name":"Ali Sabieh Region","isoCode":"AS","countryCode":"DJ","latitude":"11.19289730","longitude":"42.94169800"},{"name":"Dikhil Region","isoCode":"DI","countryCode":"DJ","latitude":"11.10543360","longitude":"42.37047440"},{"name":"Djibouti","isoCode":"DJ","countryCode":"DJ","latitude":"11.82513800","longitude":"42.59027500"},{"name":"Obock Region","isoCode":"OB","countryCode":"DJ","latitude":"12.38956910","longitude":"43.01948970"},{"name":"Tadjourah Region","isoCode":"TA","countryCode":"DJ","latitude":"11.93388850","longitude":"42.39383750"},{"name":"North Denmark Region","isoCode":"81","countryCode":"DK","latitude":"56.83074160","longitude":"9.49305270"},{"name":"Central Denmark Region","isoCode":"82","countryCode":"DK","latitude":"56.30213900","longitude":"9.30277700"},{"name":"Region of Southern Denmark","isoCode":"83","countryCode":"DK","latitude":"55.33077140","longitude":"9.09249030"},{"name":"Capital Region of Denmark","isoCode":"84","countryCode":"DK","latitude":"55.67518120","longitude":"12.54932610"},{"name":"Region Zealand","isoCode":"85","countryCode":"DK","latitude":"55.46325180","longitude":"11.72149790"},{"name":"Saint Andrew Parish","isoCode":"02","countryCode":"DM","latitude":null,"longitude":null},{"name":"Saint David Parish","isoCode":"03","countryCode":"DM","latitude":null,"longitude":null},{"name":"Saint George Parish","isoCode":"04","countryCode":"DM","latitude":null,"longitude":null},{"name":"Saint John Parish","isoCode":"05","countryCode":"DM","latitude":null,"longitude":null},{"name":"Saint Joseph Parish","isoCode":"06","countryCode":"DM","latitude":"39.02227120","longitude":"-94.71765040"},{"name":"Saint Luke Parish","isoCode":"07","countryCode":"DM","latitude":"42.10513630","longitude":"-80.05707220"},{"name":"Saint Mark Parish","isoCode":"08","countryCode":"DM","latitude":null,"longitude":null},{"name":"Saint Patrick Parish","isoCode":"09","countryCode":"DM","latitude":null,"longitude":null},{"name":"Saint Paul Parish","isoCode":"10","countryCode":"DM","latitude":"38.86146000","longitude":"-90.74356190"},{"name":"Saint Peter Parish","isoCode":"11","countryCode":"DM","latitude":"40.45241940","longitude":"-80.00850560"},{"name":"Distrito Nacional","isoCode":"01","countryCode":"DO","latitude":"18.48605750","longitude":"-69.93121170"},{"name":"Azua Province","isoCode":"02","countryCode":"DO","latitude":"18.45527090","longitude":"-70.73809280"},{"name":"Baoruco Province","isoCode":"03","countryCode":"DO","latitude":"18.48798980","longitude":"-71.41822490"},{"name":"Barahona Province","isoCode":"04","countryCode":"DO","latitude":"18.21390660","longitude":"-71.10437590"},{"name":"Dajabón Province","isoCode":"05","countryCode":"DO","latitude":"19.54992410","longitude":"-71.70865140"},{"name":"Duarte Province","isoCode":"06","countryCode":"DO","latitude":"19.20908230","longitude":"-70.02700040"},{"name":"El Seibo Province","isoCode":"08","countryCode":"DO","latitude":"18.76584960","longitude":"-69.04066800"},{"name":"Espaillat Province","isoCode":"09","countryCode":"DO","latitude":"19.62776580","longitude":"-70.27867750"},{"name":"Independencia","isoCode":"10","countryCode":"DO","latitude":"32.63357480","longitude":"-115.42892940"},{"name":"La Altagracia Province","isoCode":"11","countryCode":"DO","latitude":"18.58502360","longitude":"-68.62010720"},{"name":"La Romana Province","isoCode":"12","countryCode":"DO","latitude":"18.43102710","longitude":"-68.98373730"},{"name":"La Vega Province","isoCode":"13","countryCode":"DO","latitude":"19.22115540","longitude":"-70.52887530"},{"name":"MarÃa Trinidad Sánchez Province","isoCode":"14","countryCode":"DO","latitude":"19.37345970","longitude":"-69.85144390"},{"name":"Monte Cristi Province","isoCode":"15","countryCode":"DO","latitude":"19.73968990","longitude":"-71.44339840"},{"name":"Pedernales Province","isoCode":"16","countryCode":"DO","latitude":"17.85376260","longitude":"-71.33032090"},{"name":"Peravia Province","isoCode":"17","countryCode":"DO","latitude":"18.27865940","longitude":"-70.33358870"},{"name":"Puerto Plata Province","isoCode":"18","countryCode":"DO","latitude":"19.75432250","longitude":"-70.83328470"},{"name":"Hermanas Mirabal Province","isoCode":"19","countryCode":"DO","latitude":"19.37475590","longitude":"-70.35132350"},{"name":"Samaná Province","isoCode":"20","countryCode":"DO","latitude":"19.20583710","longitude":"-69.33629490"},{"name":"San Cristóbal Province","isoCode":"21","countryCode":"DO","latitude":"18.41804140","longitude":"-70.106
158490"},{"name":"San Juan Province","isoCode":"22","countryCode":"DO","latitude":"-31.52871270","longitude":"-68.53604030"},{"name":"San Pedro de MacorÃs","isoCode":"23","countryCode":"DO","latitude":"18.46266000","longitude":"-69.30512340"},{"name":"Sánchez RamÃrez Province","isoCode":"24","countryCode":"DO","latitude":"19.05270600","longitude":"-70.14922640"},{"name":"Santiago Province","isoCode":"25","countryCode":"DO","latitude":"-33.45000000","longitude":"-70.66670000"},{"name":"Santiago RodrÃguez Province","isoCode":"26","countryCode":"DO","latitude":"19.47131810","longitude":"-71.33958010"},{"name":"Valverde Province","isoCode":"27","countryCode":"DO","latitude":"19.58812210","longitude":"-70.98033100"},{"name":"Monseñor Nouel Province","isoCode":"28","countryCode":"DO","latitude":"18.92152340","longitude":"-70.38368150"},{"name":"Monte Plata Province","isoCode":"29","countryCode":"DO","latitude":"18.80808780","longitude":"-69.78691460"},{"name":"Hato Mayor Province","isoCode":"30","countryCode":"DO","latitude":"18.76357990","longitude":"-69.25576370"},{"name":"San José de Ocoa Province","isoCode":"31","countryCode":"DO","latitude":"18.54385800","longitude":"-70.50418160"},{"name":"Santo Domingo Province","isoCode":"32","countryCode":"DO","latitude":"18.51042530","longitude":"-69.84040540"},{"name":"Adrar","isoCode":"01","countryCode":"DZ","latitude":"26.41813100","longitude":"-0.60147170"},{"name":"Chlef","isoCode":"02","countryCode":"DZ","latitude":"36.16935150","longitude":"1.28910360"},{"name":"Laghouat","isoCode":"03","countryCode":"DZ","latitude":"33.80783410","longitude":"2.86282940"},{"name":"Oum El Bouaghi","isoCode":"04","countryCode":"DZ","latitude":"35.86887890","longitude":"7.11082660"},{"name":"Batna","isoCode":"05","countryCode":"DZ","latitude":"35.59659540","longitude":"5.89871390"},{"name":"Béjaïa","isoCode":"06","countryCode":"DZ","latitude":"36.75152580","longitude":"5.05568370"},{"name":"Biskra","isoCode":"07","countryCode":"DZ","latitude":"34.84494370","longitude":"5.72485670"},{"name":"Béchar","isoCode":"08","countryCode":"DZ","latitude":"31.62380980","longitude":"-2.21624430"},{"name":"Blida","isoCode":"09","countryCode":"DZ","latitude":"36.53112300","longitude":"2.89762540"},{"name":"Bouïra","isoCode":"10","countryCode":"DZ","latitude":"36.36918460","longitude":"3.90061940"},{"name":"Tamanghasset","isoCode":"11","countryCode":"DZ","latitude":"22.79029720","longitude":"5.51932680"},{"name":"Tébessa","isoCode":"12","countryCode":"DZ","latitude":"35.12906910","longitude":"7.95928630"},{"name":"Tlemcen","isoCode":"13","countryCode":"DZ","latitude":"34.67802840","longitude":"-1.36621600"},{"name":"Tiaret","isoCode":"14","countryCode":"DZ","latitude":"35.37086890","longitude":"1.32178520"},{"name":"Tizi Ouzou","isoCode":"15","countryCode":"DZ","latitude":"36.70691100","longitude":"4.23333550"},{"name":"Algiers","isoCode":"16","countryCode":"DZ","latitude":"36.69972940","longitude":"3.05761990"},{"name":"Djelfa","isoCode":"17","countryCode":"DZ","latitude":"34.67039560","longitude":"3.25037610"},{"name":"Jijel","isoCode":"18","countryCode":"DZ","latitude":"36.71796810","longitude":"5.98325770"},{"name":"Sétif","isoCode":"19","countryCode":"DZ","latitude":"36.30733890","longitude":"5.56172790"},{"name":"Saïda","isoCode":"20","countryCode":"DZ","latitude":"34.84152070","longitude":"0.14560550"},{"name":"Skikda","isoCode":"21","countryCode":"DZ","latitude":"36.67211980","longitude":"6.83509990"},{"name":"Sidi Bel Abbès","isoCode":"22","countryCode":"DZ","latitude":"34.68060240","longitude":"-1.09994950"},{"name":"Annaba","isoCode":"23","countryCode":"DZ","latitude":"36.80205080","longitude":"7.52472430"},{"name":"Guelma","isoCode":"24","countryCode":"DZ","latitude":"36.46274440","longitude":"7.43308330"},{"name":"Constantine","isoCode":"25","countryCode":"DZ","latitude":"36.33739110","longitude":"6.66381200"},{"name":"Médéa","isoCode":"26","countryCode":"DZ","latitude":"36.26370780","longitude":"2.75878570"},{"name":"Mostaganem","isoCode":"27","countryCode":"DZ","latitude":"35.95830540","longitude":"0.33718890"},{"name":"M\'Sila","isoCode":"28","countryCode":"DZ","latitude":"35.71866460","longitude":"4.52334230"},{"name":"Mascara","isoCode":"29","countryCode":"DZ","latitude":"35.39041250","longitude":"0.14949880"},{"name":"Ouargla","isoCode":"30","countryCode":"DZ","latitude":"32.22648630","longitude":"5.72998210"},{"name":"Oran","isoCode":"31","countryCode":"DZ","latitude":"35.60823510","longitude":"-0.56360900"},{"name":"El Bayadh","isoCode":"32","countryCode":"DZ","latitude":"32.71488240","longitude":"0.90566230"},{"name":"Illizi","isoCode":"33","countryCode":"DZ","latitude":"26.16900050","longitude":"8.48424650"},{"name":"Bordj Bou Arréridj","isoCode":"34","countryCode":"DZ","latitude":"36.07399250","longitude":"4.76302710"},{"name":"Boumerdès","isoCode":"35","countryCode":"DZ","latitude":"36.68395590","longitude":"3.62178020"},{"name":"El Tarf","isoCode":"36","countryCode":"DZ","latitude":"36.75766780","longitude":"8.30763430"},{"name":"Tindouf","isoCode":"37","countryCode":"DZ","latitude":"27.80631190","longitude":"-5.72998210"},{"name":"Tissemsilt","isoCode":"38","countryCode":"DZ","latitude":"35.60537810","longitude":"1.81309800"},{"name":"El Oued","isoCode":"39","countryCode":"DZ","latitude":"33.36781100","longitude":"6.85165110"},{"name":"Khenchela","isoCode":"40","countryCode":"DZ","latitude":"35.42694040","longitude":"7.14601550"},{"name":"Souk Ahras","isoCode":"41","countryCode":"DZ","latitude":"36.28010620","longitude":"7.93840330"},{"name":"Tipasa","isoCode":"42","countryCode":"DZ","latitude":"36.54626500","longitude":"2.18432850"},{"name":"Mila","isoCode":"43","countryCode":"DZ","latitude":"36.36479570","longitude":"6.15269850"},{"name":"Aïn Defla","isoCode":"44","countryCode":"DZ","latitude":"36.25094290","longitude":"1.93938150"},{"name":"Naama","isoCode":"45","countryCode":"DZ","latitude":"33.26673170","longitude":"-0.31286590"},{"name":"Aïn Témouchent","isoCode":"46","countryCode":"DZ","latitude":"35.29926980","longitude":"-1.13927920"},{"name":"Ghardaïa","isoCode":"47","countryCode":"DZ","latitude":"32.49437410","longitude":"3.64446000"},{"name":"Relizane","isoCode":"48","countryCode":"DZ","latitude":"35.73834050","longitude":"0.75328090"},{"name":"El M\'ghair","isoCode":"49","countryCode":"DZ","latitude":"33.95405610","longitude":"5.13464180"},{"name":"El Menia","isoCode":"50","countryCode":"DZ","latitude":"31.36422500","longitude":"2.57844950"},{"name":"Ouled Djellal","isoCode":"51","countryCode":"DZ","latitude":"34.41782210","longitude":"4.96858430"},{"name":"Bordj Baji Mokhtar","isoCode":"52","countryCode":"DZ","latitude":"22.96633500","longitude":"-3.94727320"},{"name":"Béni Abbès","isoCode":"53","countryCode":"DZ","latitude":"30.08310420","longitude":"-2.83450520"},{"name":"Timimoun","isoCode":"54","countryCode":"DZ","latitude":"29.67890600","longitude":"0.50046080"},{"name":"Touggourt","isoCode":"55","countryCode":"DZ","latitude":"33.12484760","longitude":"5.78327150"},{"name":"Djanet","isoCode":"56","countryCode":"DZ","latitude":"23.83108720","longitude":"8.70046720"},{"name":"In Salah","isoCode":"57","countryCode":"DZ","latitude":"27.21492290","longitude":"1.84843960"},{"name":"In Guezzam","isoCode":"58","countryCode":"DZ","latitude":"20.38643230","longitude":"4.77893940"},{"name":"Azuay","isoCode":"A","countryCode":"EC","latitude":"-2.89430680","longitude":"-78.99683440"},{"name":"BolÃvar","isoCode":"B","countryCode":"EC","latitude":"-1.70958280","longitude":"-79.04504290"},{"name":"Carchi","isoCode":"C","countryCode":"EC","latitude":"0.50269120","longitude":"-77.90425210"},{"name":"Orellana","isoCode":"D","countryCode":"EC","latitude":"-0.45451630","longitude":"-76.99502860"},{"name":"Esmeraldas","isoCode":"E","countryCode":"EC","latitude":"0.96817890","longitude":"-79.65172020"},{"name":"Cañar","isoCode":"F","countryCode":"EC","latitude":"-2.55893150","longitude":"-78.93881910"},{"name":"Guayas","isoCode":"G","countryCode":"EC","latitude":"-1.95748390","longitude":"-79.91927020"},{"name":"Chimborazo","isoCode":"H","countryCode":"EC","latitude":"-1.66479950","longitude":"-78.65432550"},{"name":"Imbabura","isoCode":"I","countryCode":"EC","latitude":"0.34997680","longitude":"-78.12601290"},{"name":"Loja","isoCode":"L","countryCode":"EC","latitude":"-3.99313000","longitude":"-79.20422000"},{"name":"ManabÃ","isoCode":"M","countryCode":"EC","latitude":"-1.05434340","longitude":"-80.45264400"},{"name":"Napo","isoCode":"N","countryCode":"EC","latitude":"-0.99559640","longitude":"-77.81296840"},{"name":"El Oro","isoCode":"O","countryCode":"EC","latitude":"-3.25924130","longitude":"-79.95835410"},{"name":"Pichincha","isoCode":"P","countryCode":"EC","latitude":"-0.14648470","longitude":"-78.47519450"},{"name":"Los RÃos","isoCode":"R","countryCode":"EC","latitude":"-1.02306070","longitude":"-79.46088970"},{"name":"Morona-Santiago","isoCode":"S","countryCode":"EC","latitude":"-2.30510620","longitude":"-78.11468660"},{"name":"Santo Domingo de los Tsáchilas","isoCode":"SD","countryCode":"EC","latitude":"-0.25218820","longitude":"-79.18793830"},{"name":"Santa Elena","isoCode":"SE","countryCode":"EC","latitude":"-2.22671050","longitude":"-80.85949900"},{"name":"Tungurahua","isoCode":"T","countryCode":"EC","latitude":"-1.26352840","longitude":"-78.56608520"},{"name":"SucumbÃos","isoCode":"U","countryCode":"EC","latitude":"0.08892310","longitude":"-76.88975570"},{"name":"Galápagos","isoCode":"W","countryCode":"EC","latitude":"-0.95376910","longitude":"-90.96560190"},{"name":"Cotopaxi","isoCode":"X","countryCode":"EC","latitude":"-0.83842060","longitude":"-78.66626780"},{"name":"Pastaza","isoCode":"Y","countryCode":"EC","latitude":"-1.48822650","longitude":"-78.00310570"},{"name":"Zamora Chinchipe","isoCode":"Z","countryCode":"EC","latitude":"-4.06558920","longitude":"-78.95035250"},{"name":"Harju County","isoCode":"37","countryCode":"EE","latitude":"59.33342390","longitude":"25.24669740"}
1,{"name":"Hiiu County","isoCode":"39","countryCode":"EE","latitude":"58.92395530","longitude":"22.59194680"},{"name":"Ida-Viru County","isoCode":"44","countryCode":"EE","latitude":"59.25926630","longitude":"27.41365350"},{"name":"Jõgeva County","isoCode":"49","countryCode":"EE","latitude":"58.75061430","longitude":"26.36048780"},{"name":"Järva County","isoCode":"51","countryCode":"EE","latitude":"58.88667130","longitude":"25.50006240"},{"name":"Lääne County","isoCode":"57","countryCode":"EE","latitude":"58.97227420","longitude":"23.87408340"},{"name":"Lääne-Viru County","isoCode":"59","countryCode":"EE","latitude":"59.30188160","longitude":"26.32803120"},{"name":"Põlva County","isoCode":"65","countryCode":"EE","latitude":"58.11606220","longitude":"27.20663940"},{"name":"Pärnu County","isoCode":"67","countryCode":"EE","latitude":"58.52619520","longitude":"24.40201590"},{"name":"Rapla County","isoCode":"70","countryCode":"EE","latitude":"58.84926250","longitude":"24.73465690"},{"name":"Saare County","isoCode":"74","countryCode":"EE","latitude":"58.48497210","longitude":"22.61364080"},{"name":"Tartu County","isoCode":"78","countryCode":"EE","latitude":"58.40571280","longitude":"26.80157600"},{"name":"Valga County","isoCode":"82","countryCode":"EE","latitude":"57.91034410","longitude":"26.16018190"},{"name":"Viljandi County","isoCode":"84","countryCode":"EE","latitude":"58.28217460","longitude":"25.57522330"},{"name":"Võru County","isoCode":"86","countryCode":"EE","latitude":"57.73773720","longitude":"27.13989380"},{"name":"Alexandria","isoCode":"ALX","countryCode":"EG","latitude":"30.87605680","longitude":"29.74260400"},{"name":"Aswan","isoCode":"ASN","countryCode":"EG","latitude":"23.69664980","longitude":"32.71813750"},{"name":"Asyut","isoCode":"AST","countryCode":"EG","latitude":"27.21338310","longitude":"31.44561790"},{"name":"Red Sea","isoCode":"BA","countryCode":"EG","latitude":"24.68263160","longitude":"34.15319470"},{"name":"Beheira","isoCode":"BH","countryCode":"EG","latitude":"30.84809860","longitude":"30.34355060"},{"name":"Beni Suef","isoCode":"BNS","countryCode":"EG","latitude":"28.89388370","longitude":"31.44561790"},{"name":"Cairo","isoCode":"C","countryCode":"EG","latitude":"29.95375640","longitude":"31.53700030"},{"name":"Dakahlia","isoCode":"DK","countryCode":"EG","latitude":"31.16560440","longitude":"31.49131820"},{"name":"Damietta","isoCode":"DT","countryCode":"EG","latitude":"31.36257990","longitude":"31.67393710"},{"name":"Faiyum","isoCode":"FYM","countryCode":"EG","latitude":"29.30840210","longitude":"30.84284970"},{"name":"Gharbia","isoCode":"GH","countryCode":"EG","latitude":"30.87535560","longitude":"31.03351000"},{"name":"Giza","isoCode":"GZ","countryCode":"EG","latitude":"28.76662160","longitude":"29.23207840"},{"name":"Ismailia","isoCode":"IS","countryCode":"EG","latitude":"30.58309340","longitude":"32.26538870"},{"name":"South Sinai","isoCode":"JS","countryCode":"EG","latitude":"29.31018280","longitude":"34.15319470"},{"name":"Qalyubia","isoCode":"KB","countryCode":"EG","latitude":"30.32923680","longitude":"31.21684660"},{"name":"Kafr el-Sheikh","isoCode":"KFS","countryCode":"EG","latitude":"31.30854440","longitude":"30.80394740"},{"name":"Qena","isoCode":"KN","countryCode":"EG","latitude":"26.23460330","longitude":"32.98883190"},{"name":"Luxor","isoCode":"LX","countryCode":"EG","latitude":"25.39444440","longitude":"32.49200880"},{"name":"Minya","isoCode":"MN","countryCode":"EG","latitude":"28.28472900","longitude":"30.52790960"},{"name":"Monufia","isoCode":"MNF","countryCode":"EG","latitude":"30.59724550","longitude":"30.98763210"},{"name":"Matrouh","isoCode":"MT","countryCode":"EG","latitude":"29.56963500","longitude":"26.41938900"},{"name":"Port Said","isoCode":"PTS","countryCode":"EG","latitude":"31.07586060","longitude":"32.26538870"},{"name":"Sohag","isoCode":"SHG","countryCode":"EG","latitude":"26.69383400","longitude":"32.17460500"},{"name":"Sharqia","isoCode":"SHR","countryCode":"EG","latitude":"30.67305450","longitude":"31.15932470"},{"name":"North Sinai","isoCode":"SIN","countryCode":"EG","latitude":"30.28236500","longitude":"33.61757700"},{"name":"Suez","isoCode":"SUZ","countryCode":"EG","latitude":"29.36822550","longitude":"32.17460500"},{"name":"New Valley","isoCode":"WAD","countryCode":"EG","latitude":"24.54556380","longitude":"27.17353160"},{"name":"Anseba Region","isoCode":"AN","countryCode":"ER","latitude":"16.47455310","longitude":"37.80876930"},{"name":"Southern Red Sea Region","isoCode":"DK","countryCode":"ER","latitude":"13.51371030","longitude":"41.76064720"},{"name":"Debub Region","isoCode":"DU","countryCode":"ER","latitude":"14.94786920","longitude":"39.15436770"},{"name":"Gash-Barka Region","isoCode":"GB","countryCode":"ER","latitude":"15.40688250","longitude":"37.63866220"},{"name":"Maekel Region","isoCode":"MA","countryCode":"ER","latitude":"15.35514090","longitude":"38.86236830"},{"name":"Northern Red Sea Region","isoCode":"SK","countryCode":"ER","latitude":"16.25839970","longitude":"38.82054540"},{"name":"Andalusia","isoCode":"AN","countryCode":"ES","latitude":"37.54427060","longitude":"-4.72775280"},{"name":"Aragon","isoCode":"AR","countryCode":"ES","latitude":"41.59762750","longitude":"-0.90566230"},{"name":"Asturias","isoCode":"AS","countryCode":"ES","latitude":"43.36139530","longitude":"-5.85932670"},{"name":"Ãvila","isoCode":"AV","countryCode":"ES","latitude":"40.69345110","longitude":"-4.89356270"},{"name":"Burgos Province","isoCode":"BU","countryCode":"ES","latitude":"42.33807580","longitude":"-3.58126920"},{"name":"Cantabria","isoCode":"CB","countryCode":"ES","latitude":"43.18283960","longitude":"-3.98784270"},{"name":"Ceuta","isoCode":"CE","countryCode":"ES","latitude":"35.88938740","longitude":"-5.32134550"},{"name":"Castile and León","isoCode":"CL","countryCode":"ES","latitude":"41.83568210","longitude":"-4.39763570"},{"name":"Castilla La Mancha","isoCode":"CM","countryCode":"ES","latitude":"39.27956070","longitude":"-3.09770200"},{"name":"Canary Islands","isoCode":"CN","countryCode":"ES","latitude":"28.29156370","longitude":"-16.62913040"},{"name":"Catalonia","isoCode":"CT","countryCode":"ES","latitude":"41.59115890","longitude":"1.52086240"},{"name":"Extremadura","isoCode":"EX","countryCode":"ES","latitude":"39.49373920","longitude":"-6.06791940"},{"name":"Galicia","isoCode":"GA","countryCode":"ES","latitude":"42.57505540","longitude":"-8.13385580"},{"name":"Léon","isoCode":"LE","countryCode":"ES","latitude":"42.59870410","longitude":"-5.56708390"},{"name":"Murcia","isoCode":"MC","countryCode":"ES","latitude":"38.13981410","longitude":"-1.36621600"},{"name":"Madrid","isoCode":"MD","countryCode":"ES","latitude":"40.41675150","longitude":"-3.70383220"},{"name":"Melilla","isoCode":"ML","countryCode":"ES","latitude":"35.29227750","longitude":"-2.93809730"},{"name":"Navarra","isoCode":"NC","countryCode":"ES","latitude":"42.69539090","longitude":"-1.67606910"},{"name":"Palencia Province","isoCode":"P","countryCode":"ES","latitude":"42.00968320","longitude":"-4.52879490"},{"name":"Balearic Islands","isoCode":"PM","countryCode":"ES","latitude":"39.35877590","longitude":"2.73563280"},{"name":"Basque Country","isoCode":"PV","countryCode":"ES","latitude":"42.98962480","longitude":"-2.61892730"},{"name":"La Rioja","isoCode":"RI","countryCode":"ES","latitude":"42.28707330","longitude":"-2.53960300"},{"name":"Salamanca Province","isoCode":"SA","countryCode":"ES","latitude":"40.95152630","longitude":"-6.23759470"},{"name":"Segovia Province","isoCode":"SG","countryCode":"ES","latitude":"40.94292960","longitude":"-4.10889420"},{"name":"Soria Province","isoCode":"SO","countryCode":"ES","latitude":"41.76654640","longitude":"-2.47903060"}
1,{"name":"Valladolid Province","isoCode":"VA","countryCode":"ES","latitude":"41.65173750","longitude":"-4.72449500"},{"name":"Valencia","isoCode":"VC","countryCode":"ES","latitude":"39.48401080","longitude":"-0.75328090"},{"name":"Zamora Province","isoCode":"ZA","countryCode":"ES","latitude":"41.60957440","longitude":"-5.89871390"},{"name":"Addis Ababa","isoCode":"AA","countryCode":"ET","latitude":"8.98060340","longitude":"38.75776050"},{"name":"Afar Region","isoCode":"AF","countryCode":"ET","latitude":"11.75593880","longitude":"40.95868800"},{"name":"Amhara Region","isoCode":"AM","countryCode":"ET","latitude":"11.34942470","longitude":"37.97845850"},{"name":"Benishangul-Gumuz Region","isoCode":"BE","countryCode":"ET","latitude":"10.78028890","longitude":"35.56578620"},{"name":"Dire Dawa","isoCode":"DD","countryCode":"ET","latitude":"9.60087470","longitude":"41.85014200"},{"name":"Gambela Region","isoCode":"GA","countryCode":"ET","latitude":"7.92196870","longitude":"34.15319470"},{"name":"Harari Region","isoCode":"HA","countryCode":"ET","latitude":"9.31486600","longitude":"42.19677160"},{"name":"Oromia Region","isoCode":"OR","countryCode":"ET","latitude":"7.54603770","longitude":"40.63468510"},{"name":"Southern Nations, Nationalities, and Peoples\' Region","isoCode":"SN","countryCode":"ET","latitude":"6.51569110","longitude":"36.95410700"},{"name":"Somali Region","isoCode":"SO","countryCode":"ET","latitude":"6.66122930","longitude":"43.79084530"},{"name":"Tigray Region","isoCode":"TI","countryCode":"ET","latitude":"14.03233360","longitude":"38.31657250"},{"name":"Ã
land Islands","isoCode":"01","countryCode":"FI","latitude":"60.17852470","longitude":"19.91561050"},{"name":"South Karelia","isoCode":"02","countryCode":"FI","latitude":"61.11819490","longitude":"28.10243720"},{"name":"Southern Ostrobothnia","isoCode":"03","countryCode":"FI","latitude":"62.94330990","longitude":"23.52852670"},{"name":"Southern Savonia","isoCode":"04","countryCode":"FI","latitude":"61.69451480","longitude":"27.80050150"},{"name":"Kainuu","isoCode":"05","countryCode":"FI","latitude":"64.37365640","longitude":"28.74374750"},{"name":"Tavastia Proper","isoCode":"06","countryCode":"FI","latitude":"60.90701500","longitude":"24.30054980"},{"name":"Central Ostrobothnia","isoCode":"07","countryCode":"FI","latitude":"63.56217350","longitude":"24.00136310"},{"name":"Central Finland","isoCode":"08","countryCode":"FI","latitude":"62.56667430","longitude":"25.55494450"},{"name":"Kymenlaakso","isoCode":"09","countryCode":"FI","latitude":"60.78051200","longitude":"26.88293360"},{"name":"Pirkanmaa","isoCode":"11","countryCode":"FI","latitude":"61.69869180","longitude":"23.78955980"},{"name":"Ostrobothnia","isoCode":"12","countryCode":"FI","latitude":"63.11817570","longitude":"21.90610620"},{"name":"North Karelia","isoCode":"13","countryCode":"FI","latitude":"62.80620780","longitude":"30.15538870"},{"name":"Northern Ostrobothnia","isoCode":"14","countryCode":"FI","latitude":"65.27949300","longitude":"26.28904170"},{"name":"Northern Savonia","isoCode":"15","countryCode":"FI","latitude":"63.08448000","longitude":"27.02535040"},{"name":"Päijänne Tavastia","isoCode":"16","countryCode":"FI","latitude":"61.32300410","longitude":"25.73224960"},{"name":"Satakunta","isoCode":"17","countryCode":"FI","latitude":"61.59327580","longitude":"22.14830810"},{"name":"Uusimaa","isoCode":"18","countryCode":"FI","latitude":"60.21872000","longitude":"25.27162100"},{"name":"Finland Proper","isoCode":"19","countryCode":"FI","latitude":"60.36279140","longitude":"22.44393690"},{"name":"Eastern Finland Province","isoCode":"IS","countryCode":"FI","latitude":"62.56338910","longitude":"28.50240420"},{"name":"Lapland","isoCode":"LL","countryCode":"FI","latitude":"67.92223040","longitude":"26.50464380"},{"name":"Oulu Province","isoCode":"OL","countryCode":"FI","latitude":"65.01207480","longitude":"25.46504960"},{"name":"Ba","isoCode":"01","countryCode":"FJ","latitude":"36.06138930","longitude":"-95.80058720"},{"name":"Bua","isoCode":"02","countryCode":"FJ","latitude":"43.09645840","longitude":"-89.50088000"},{"name":"Cakaudrove","isoCode":"03","countryCode":"FJ","latitude":"-16.58141050","longitude":"179.51200840"},{"name":"Kadavu","isoCode":"04","countryCode":"FJ","latitude":"-19.01271220","longitude":"178.18766760"},{"name":"Lau","isoCode":"05","countryCode":"FJ","latitude":"31.66870150","longitude":"-106.39557630"},{"name":"Lomaiviti","isoCode":"06","countryCode":"FJ","latitude":"-17.70900000","longitude":"179.09100000"},{"name":"Macuata","isoCode":"07","countryCode":"FJ","latitude":"-16.48649220","longitude":"179.28472510"},{"name":"Nadroga-Navosa","isoCode":"08","countryCode":"FJ","latitude":"-17.98652780","longitude":"177.65811300"},{"name":"Naitasiri","isoCode":"09","countryCode":"FJ","latitude":"-17.89757540","longitude":"178.20715980"},{"name":"Namosi","isoCode":"10","countryCode":"FJ","latitude":"-18.08641760","longitude":"178.12913870"},{"name":"Ra","isoCode":"11","countryCode":"FJ","latitude":"37.10031530","longitude":"-95.67442460"},{"name":"Rewa","isoCode":"12","countryCode":"FJ","latitude":"34.79235170","longitude":"-82.36092640"},{"name":"Serua","isoCode":"13","countryCode":"FJ","latitude":"-18.18047490","longitude":"178.05097900"},{"name":"Tailevu","isoCode":"14","countryCode":"FJ","latitude":"-17.82691110","longitude":"178.29324800"},{"name":"Central Division","isoCode":"C","countryCode":"FJ","latitude":"34.04400660","longitude":"-118.24727380"},{"name":"Eastern Division","isoCode":"E","countryCode":"FJ","latitude":"32.80943050","longitude":"-117.12899370"},{"name":"Northern Division","isoCode":"N","countryCode":"FJ","latitude":"32.87687660","longitude":"-117.21563450"},{"name":"Rotuma","isoCode":"R","countryCode":"FJ","latitude":"-12.50250690","longitude":"177.07241640"},{"name":"Western Division","isoCode":"W","countryCode":"FJ","latitude":"42.96621980","longitude":"-78.70211340"},{"name":"Kosrae State","isoCode":"KSA","countryCode":"FM","latitude":"5.30956180","longitude":"162.98148770"},{"name":"Pohnpei State","isoCode":"PNI","countryCode":"FM","latitude":"6.85412540","longitude":"158.26238220"},{"name":"Chuuk State","isoCode":"TRK","countryCode":"FM","latitude":"7.13867590","longitude":"151.55930650"},{"name":"Yap State","isoCode":"YAP","countryCode":"FM","latitude":"8.67164900","longitude":"142.84393350"},{"name":"Ain","isoCode":"01","countryCode":"FR","latitude":"46.06508600","longitude":"4.88861500"},{"name":"Aisne","isoCode":"02","countryCode":"FR","latitude":"49.45289210","longitude":"3.04651110"},{"name":"Allier","isoCode":"03","countryCode":"FR","latitude":"46.36708630","longitude":"2.58082770"}
1,{"name":"Alpes-de-Haute-Provence","isoCode":"04","countryCode":"FR","latitude":"44.16377520","longitude":"5.67247800"},{"name":"Hautes-Alpes","isoCode":"05","countryCode":"FR","latitude":"44.65626820","longitude":"5.68732110"},{"name":"Alpes-Maritimes","isoCode":"06","countryCode":"FR","latitude":"43.92041700","longitude":"6.61678220"},{"name":"Ardèche","isoCode":"07","countryCode":"FR","latitude":"44.81486950","longitude":"3.81334830"},{"name":"Ardennes","isoCode":"08","countryCode":"FR","latitude":"49.69759510","longitude":"4.14895760"},{"name":"Ariège","isoCode":"09","countryCode":"FR","latitude":"42.94347830","longitude":"0.94048640"},{"name":"Aube","isoCode":"10","countryCode":"FR","latitude":"48.31975470","longitude":"3.56371040"},{"name":"Aude","isoCode":"11","countryCode":"FR","latitude":"43.05411400","longitude":"1.90384760"},{"name":"Aveyron","isoCode":"12","countryCode":"FR","latitude":"44.31563620","longitude":"2.08523790"},{"name":"Bouches-du-Rhône","isoCode":"13","countryCode":"FR","latitude":"43.54038650","longitude":"4.46138290"},{"name":"Calvados","isoCode":"14","countryCode":"FR","latitude":"49.09035140","longitude":"-0.91706480"},{"name":"Cantal","isoCode":"15","countryCode":"FR","latitude":"45.04921770","longitude":"2.15672720"},{"name":"Charente","isoCode":"16","countryCode":"FR","latitude":"45.66584790","longitude":"-0.31845770"},{"name":"Charente-Maritime","isoCode":"17","countryCode":"FR","latitude":"45.72968280","longitude":"-1.33881160"},{"name":"Cher","isoCode":"18","countryCode":"FR","latitude":"47.02436280","longitude":"1.86627320"},{"name":"Corrèze","isoCode":"19","countryCode":"FR","latitude":"45.34237070","longitude":"1.31717330"},{"name":"Corse","isoCode":"20R","countryCode":"FR","latitude":"42.03960420","longitude":"9.01289260"},{"name":"Côte-d\'Or","isoCode":"21","countryCode":"FR","latitude":"47.46513020","longitude":"4.23154950"},{"name":"Côtes-d\'Armor","isoCode":"22","countryCode":"FR","latitude":"48.46633360","longitude":"-3.34789610"},{"name":"Creuse","isoCode":"23","countryCode":"FR","latitude":"46.05903940","longitude":"1.43150500"},{"name":"Dordogne","isoCode":"24","countryCode":"FR","latitude":"45.14234160","longitude":"0.14274080"},{"name":"Doubs","isoCode":"25","countryCode":"FR","latitude":"46.93217740","longitude":"6.34762140"},{"name":"Drôme","isoCode":"26","countryCode":"FR","latitude":"44.72933570","longitude":"4.67821580"},{"name":"Eure","isoCode":"27","countryCode":"FR","latitude":"49.07540350","longitude":"0.48937320"},{"name":"Eure-et-Loir","isoCode":"28","countryCode":"FR","latitude":"48.44697840","longitude":"0.81470250"},{"name":"Finistère","isoCode":"29","countryCode":"FR","latitude":"48.22696100","longitude":"-4.82437330"},{"name":"Corse-du-Sud","isoCode":"2A","countryCode":"FR","latitude":"41.85720550","longitude":"8.41091830"},{"name":"Haute-Corse","isoCode":"2B","countryCode":"FR","latitude":"42.42958660","longitude":"8.50625610"},{"name":"Gard","isoCode":"30","countryCode":"FR","latitude":"43.95952760","longitude":"3.49356810"},{"name":"Haute-Garonne","isoCode":"31","countryCode":"FR","latitude":"43.30505550","longitude":"0.68455150"},{"name":"Gers","isoCode":"32","countryCode":"FR","latitude":"43.69505340","longitude":"-0.09997280"},{"name":"Gironde","isoCode":"33","countryCode":"FR","latitude":"44.89584690","longitude":"-1.59405320"},{"name":"Hérault","isoCode":"34","countryCode":"FR","latitude":"43.59111200","longitude":"2.80661080"},{"name":"Ille-et-Vilaine","isoCode":"35","countryCode":"FR","latitude":"48.17624840","longitude":"-2.21304010"},{"name":"Indre","isoCode":"36","countryCode":"FR","latitude":"46.81175500","longitude":"0.97555230"},{"name":"Indre-et-Loire","isoCode":"37","countryCode":"FR","latitude":"47.22285820","longitude":"0.14896190"},{"name":"Isère","isoCode":"38","countryCode":"FR","latitude":"45.28922710","longitude":"4.99023550"},{"name":"Jura","isoCode":"39","countryCode":"FR","latitude":"46.78287410","longitude":"5.16918440"},{"name":"Landes","isoCode":"40","countryCode":"FR","latitude":"44.00950800","longitude":"-1.25385790"},{"name":"Loir-et-Cher","isoCode":"41","countryCode":"FR","latitude":"47.65937600","longitude":"0.85376310"},{"name":"Loire","isoCode":"42","countryCode":"FR","latitude":"46.35228120","longitude":"-1.17563390"},{"name":"Haute-Loire","isoCode":"43","countryCode":"FR","latitude":"45.08538060","longitude":"3.22607070"},{"name":"Loire-Atlantique","isoCode":"44","countryCode":"FR","latitude":"47.34757210","longitude":"-2.34663120"},{"name":"Loiret","isoCode":"45","countryCode":"FR","latitude":"47.91354310","longitude":"1.76009900"},{"name":"Lot","isoCode":"46","countryCode":"FR","latitude":"44.62460700","longitude":"1.03576310"},{"name":"Lot-et-Garonne","isoCode":"47","countryCode":"FR","latitude":"44.36873140","longitude":"-0.09161690"}
1,{"name":"Lozère","isoCode":"48","countryCode":"FR","latitude":"44.54227790","longitude":"2.92934590"},{"name":"Maine-et-Loire","isoCode":"49","countryCode":"FR","latitude":"47.38900340","longitude":"-1.12025270"},{"name":"Manche","isoCode":"50","countryCode":"FR","latitude":"49.08817340","longitude":"-2.46272090"},{"name":"Marne","isoCode":"51","countryCode":"FR","latitude":"48.96107450","longitude":"3.65737670"},{"name":"Haute-Marne","isoCode":"52","countryCode":"FR","latitude":"48.13248210","longitude":"4.69834990"},{"name":"Mayenne","isoCode":"53","countryCode":"FR","latitude":"48.30668420","longitude":"-0.64901820"},{"name":"Meurthe-et-Moselle","isoCode":"54","countryCode":"FR","latitude":"48.95566150","longitude":"5.71423500"},{"name":"Meuse","isoCode":"55","countryCode":"FR","latitude":"49.01246200","longitude":"4.81087340"},{"name":"Morbihan","isoCode":"56","countryCode":"FR","latitude":"47.74395180","longitude":"-3.44555240"},{"name":"Moselle","isoCode":"57","countryCode":"FR","latitude":"49.02045660","longitude":"6.20553220"},{"name":"Nièvre","isoCode":"58","countryCode":"FR","latitude":"47.11921640","longitude":"2.97797130"},{"name":"Nord","isoCode":"59","countryCode":"FR","latitude":"50.52854770","longitude":"2.60007760"},{"name":"Oise","isoCode":"60","countryCode":"FR","latitude":"49.41173350","longitude":"1.86688250"},{"name":"Orne","isoCode":"61","countryCode":"FR","latitude":"48.57576440","longitude":"-0.50242950"},{"name":"Pas-de-Calais","isoCode":"62","countryCode":"FR","latitude":"50.51446990","longitude":"1.81149800"},{"name":"Puy-de-Dôme","isoCode":"63","countryCode":"FR","latitude":"45.77141850","longitude":"2.62626760"},{"name":"Pyrénées-Atlantiques","isoCode":"64","countryCode":"FR","latitude":"43.18681700","longitude":"-1.44170710"},{"name":"Hautes-Pyrénées","isoCode":"65","countryCode":"FR","latitude":"43.14294620","longitude":"-0.40097360"},{"name":"Pyrénées-Orientales","isoCode":"66","countryCode":"FR","latitude":"42.62541790","longitude":"1.88929580"},{"name":"Bas-Rhin","isoCode":"67","countryCode":"FR","latitude":"48.59864440","longitude":"7.02666760"},{"name":"Haut-Rhin","isoCode":"68","countryCode":"FR","latitude":"47.86537740","longitude":"6.67113810"},{"name":"Rhône","isoCode":"69","countryCode":"FR","latitude":"44.93433000","longitude":"4.24093290"},{"name":"Métropole de Lyon","isoCode":"69M","countryCode":"FR","latitude":"45.74826290","longitude":"4.59584040"},{"name":"Alsace","isoCode":"6AE","countryCode":"FR","latitude":"48.31817950","longitude":"7.44162410"},{"name":"Haute-Saône","isoCode":"70","countryCode":"FR","latitude":"47.63789960","longitude":"5.53550550"},{"name":"Saône-et-Loire","isoCode":"71","countryCode":"FR","latitude":"46.65548830","longitude":"3.98350500"},{"name":"Sarthe","isoCode":"72","countryCode":"FR","latitude":"48.02627330","longitude":"-0.32613170"},{"name":"Savoie","isoCode":"73","countryCode":"FR","latitude":"45.49469900","longitude":"5.84329840"},{"name":"Haute-Savoie","isoCode":"74","countryCode":"FR","latitude":"46.04452770","longitude":"5.86413800"},{"name":"Paris","isoCode":"75C","countryCode":"FR","latitude":"48.85661400","longitude":"2.35222190"},{"name":"Seine-Maritime","isoCode":"76","countryCode":"FR","latitude":"49.66096810","longitude":"0.36775610"},{"name":"Seine-et-Marne","isoCode":"77","countryCode":"FR","latitude":"48.61853940","longitude":"2.41525610"},{"name":"Yvelines","isoCode":"78","countryCode":"FR","latitude":"48.76153010","longitude":"1.27729490"},{"name":"Deux-Sèvres","isoCode":"79","countryCode":"FR","latitude":"46.53868170","longitude":"-0.90199480"},{"name":"Somme","isoCode":"80","countryCode":"FR","latitude":"49.96859220","longitude":"1.73106960"},{"name":"Tarn","isoCode":"81","countryCode":"FR","latitude":"43.79149770","longitude":"1.67588930"},{"name":"Tarn-et-Garonne","isoCode":"82","countryCode":"FR","latitude":"44.08089500","longitude":"1.08916570"},{"name":"Var","isoCode":"83","countryCode":"FR","latitude":"43.39507300","longitude":"5.73424170"},{"name":"Vaucluse","isoCode":"84","countryCode":"FR","latitude":"44.04475000","longitude":"4.64277180"},{"name":"Vendée","isoCode":"85","countryCode":"FR","latitude":"46.67541030","longitude":"-2.02983920"},{"name":"Vienne","isoCode":"86","countryCode":"FR","latitude":"45.52213140","longitude":"4.84531360"},{"name":"Haute-Vienne","isoCode":"87","countryCode":"FR","latitude":"45.91868780","longitude":"0.70972060"},{"name":"Vosges","isoCode":"88","countryCode":"FR","latitude":"48.16301730","longitude":"5.73556000"},{"name":"Yonne","isoCode":"89","countryCode":"FR","latitude":"47.85476140","longitude":"3.03394040"},{"name":"Territoire de Belfort","isoCode":"90","countryCode":"FR","latitude":"47.62930720","longitude":"6.66962000"},{"name":"Essonne","isoCode":"91","countryCode":"FR","latitude":"48.53046150","longitude":"1.96990560"},{"name":"Hauts-de-Seine","isoCode":"92","countryCode":"FR","latitude":"48.84030080","longitude":"2.10125590"},{"name":"Seine-Saint-Denis","isoCode":"93","countryCode":"FR","latitude":"48.90993180","longitude":"2.30573790"}
1,{"name":"Val-de-Marne","isoCode":"94","countryCode":"FR","latitude":"48.77470040","longitude":"2.32210390"},{"name":"Val-d\'Oise","isoCode":"95","countryCode":"FR","latitude":"49.07518180","longitude":"1.82169140"},{"name":"Guadeloupe","isoCode":"971","countryCode":"FR","latitude":"16.26500000","longitude":"-61.55100000"},{"name":"Martinique","isoCode":"972","countryCode":"FR","latitude":"14.64152800","longitude":"-61.02417400"},{"name":"French Guiana","isoCode":"973","countryCode":"FR","latitude":"3.93388900","longitude":"-53.12578200"},{"name":"La Réunion","isoCode":"974","countryCode":"FR","latitude":"-21.11514100","longitude":"55.53638400"},{"name":"Mayotte","isoCode":"976","countryCode":"FR","latitude":"-12.82750000","longitude":"45.16624400"},{"name":"Auvergne-Rhône-Alpes","isoCode":"ARA","countryCode":"FR","latitude":"45.44714310","longitude":"4.38525070"},{"name":"Bourgogne-Franche-Comté","isoCode":"BFC","countryCode":"FR","latitude":"47.28051270","longitude":"4.99943720"},{"name":"Saint-Barthélemy","isoCode":"BL","countryCode":"FR","latitude":"17.90051340","longitude":"-62.82058710"},{"name":"Bretagne","isoCode":"BRE","countryCode":"FR","latitude":"48.20204710","longitude":"-2.93264350"},{"name":"Clipperton","isoCode":"CP","countryCode":"FR","latitude":"10.28335410","longitude":"-109.22542150"},{"name":"Centre-Val de Loire","isoCode":"CVL","countryCode":"FR","latitude":"47.75156860","longitude":"1.67506310"},{"name":"Grand-Est","isoCode":"GES","countryCode":"FR","latitude":"48.69980300","longitude":"6.18780740"},{"name":"Hauts-de-France","isoCode":"HDF","countryCode":"FR","latitude":"50.48011530","longitude":"2.79372650"},{"name":"Ãle-de-France","isoCode":"IDF","countryCode":"FR","latitude":"48.84991980","longitude":"2.63704110"},{"name":"Saint-Martin","isoCode":"MF","countryCode":"FR","latitude":"18.07082980","longitude":"-63.05008090"},{"name":"Nouvelle-Aquitaine","isoCode":"NAQ","countryCode":"FR","latitude":"45.70871820","longitude":"0.62689100"},{"name":"Normandie","isoCode":"NOR","countryCode":"FR","latitude":"48.87987040","longitude":"0.17125290"},{"name":"Occitanie","isoCode":"OCC","countryCode":"FR","latitude":"43.89272320","longitude":"3.28276250"},{"name":"Provence-Alpes-Côte-dâAzur","isoCode":"PAC","countryCode":"FR","latitude":"43.93516910","longitude":"6.06791940"},{"name":"Pays-de-la-Loire","isoCode":"PDL","countryCode":"FR","latitude":"47.76328360","longitude":"-0.32996870"},{"name":"French Polynesia","isoCode":"PF","countryCode":"FR","latitude":"-17.67974200","longitude":"-149.40684300"},{"name":"Saint Pierre and Miquelon","isoCode":"PM","countryCode":"FR","latitude":"46.88520000","longitude":"-56.31590000"},{"name":"French Southern and Antarctic Lands","isoCode":"TF","countryCode":"FR","latitude":"-47.54466040","longitude":"51.28375420"},{"name":"Wallis and Futuna","isoCode":"WF","countryCode":"FR","latitude":"-14.29380000","longitude":"-178.11650000"},{"name":"Estuaire Province","isoCode":"1","countryCode":"GA","latitude":"0.44328640","longitude":"10.08072980"},{"name":"Haut-Ogooué Province","isoCode":"2","countryCode":"GA","latitude":"-1.47625440","longitude":"13.91439900"},{"name":"Moyen-Ogooué Province","isoCode":"3","countryCode":"GA","latitude":"-0.44278400","longitude":"10.43965600"},{"name":"Ngounié Province","isoCode":"4","countryCode":"GA","latitude":"-1.49303030","longitude":"10.98070030"},{"name":"Nyanga Province","isoCode":"5","countryCode":"GA","latitude":"-2.88210330","longitude":"11.16173560"},{"name":"Ogooué-Ivindo Province","isoCode":"6","countryCode":"GA","latitude":"0.88183110","longitude":"13.17403480"},{"name":"Ogooué-Lolo Province","isoCode":"7","countryCode":"GA","latitude":"-0.88440930","longitude":"12.43805810"},{"name":"Ogooué-Maritime Province","isoCode":"8","countryCode":"GA","latitude":"-1.34659750","longitude":"9.72326730"},{"name":"Woleu-Ntem Province","isoCode":"9","countryCode":"GA","latitude":"2.29898270","longitude":"11.44669140"},{"name":"Armagh, Banbridge and Craigavon","isoCode":"ABC","countryCode":"GB","latitude":"54.39325920","longitude":"-6.45634010"},{"name":"Aberdeenshire","isoCode":"ABD","countryCode":"GB","latitude":"57.28687230","longitude":"-2.38156840"},{"name":"Aberdeen","isoCode":"ABE","countryCode":"GB","latitude":"57.14971700","longitude":"-2.09427800"},{"name":"Argyll and Bute","isoCode":"AGB","countryCode":"GB","latitude":"56.40062140","longitude":"-5.48074800"},{"name":"Ards and North Down","isoCode":"AND","countryCode":"GB","latitude":"54.58996450","longitude":"-5.59849720"},{"name":"Antrim and Newtownabbey","isoCode":"ANN","countryCode":"GB","latitude":"54.69568870","longitude":"-5.94810690"},{"name":"Angus","isoCode":"ANS","countryCode":"GB","latitude":"37.27578860","longitude":"-95.65010330"},{"name":"Antrim","isoCode":"ANT","countryCode":"GB","latitude":"54.71953380","longitude":"-6.20724980"},{"name":"Ards","isoCode":"ARD","countryCode":"GB","latitude":"42.13918510","longitude":"-87.86149720"},{"name":"Armagh City and District Council","isoCode":"ARM","countryCode":"GB","latitude":"54.39325920","longitude":"-6.45634010"},{"name":"Bath and North East Somerset","isoCode":"BAS","countryCode":"GB","latitude":"51.32501020","longitude":"-2.47662410"},{"name":"Blackburn with Darwen","isoCode":"BBD","countryCode":"GB","latitude":"53.69575220","longitude":"-2.46829850"},{"name":"Bedford","isoCode":"BDF","countryCode":"GB","latitude":"32.84401700","longitude":"-97.14306710"},{"name":"London Borough of Barking and Dagenham","isoCode":"BDG","countryCode":"GB","latitude":"51.55406660","longitude":"0.13401700"},{"name":"London Borough of Brent","isoCode":"BEN","countryCode":"GB","latitude":"51.56728080","longitude":"-0.27105680"},{"name":"London Borough of Bexley","isoCode":"BEX","countryCode":"GB","latitude":"51.45190210","longitude":"0.11
1717860"},{"name":"Belfast district","isoCode":"BFS","countryCode":"GB","latitude":"54.61703660","longitude":"-5.95318610"},{"name":"Bridgend County Borough","isoCode":"BGE","countryCode":"GB","latitude":"51.50831990","longitude":"-3.58120750"},{"name":"Blaenau Gwent County Borough","isoCode":"BGW","countryCode":"GB","latitude":"51.78757790","longitude":"-3.20439310"},{"name":"Birmingham","isoCode":"BIR","countryCode":"GB","latitude":"33.51858920","longitude":"-86.81035670"},{"name":"Buckinghamshire","isoCode":"BKM","countryCode":"GB","latitude":"51.80722040","longitude":"-0.81276640"},{"name":"Ballymena Borough","isoCode":"BLA","countryCode":"GB","latitude":"54.86426000","longitude":"-6.27910740"},{"name":"Ballymoney","isoCode":"BLY","countryCode":"GB","latitude":"55.07048880","longitude":"-6.51737080"},{"name":"Bournemouth","isoCode":"BMH","countryCode":"GB","latitude":"50.71916400","longitude":"-1.88076900"},{"name":"Banbridge","isoCode":"BNB","countryCode":"GB","latitude":"54.34872900","longitude":"-6.27048030"},{"name":"London Borough of Barnet","isoCode":"BNE","countryCode":"GB","latitude":"51.60496730","longitude":"-0.20762950"},{"name":"Brighton and Hove","isoCode":"BNH","countryCode":"GB","latitude":"50.82262880","longitude":"-0.13704700"},{"name":"Barnsley","isoCode":"BNS","countryCode":"GB","latitude":"34.29949560","longitude":"-84.98458090"},{"name":"Bolton","isoCode":"BOL","countryCode":"GB","latitude":"44.37264760","longitude":"-72.87876250"},{"name":"Blackpool","isoCode":"BPL","countryCode":"GB","latitude":"53.81750530","longitude":"-3.03567480"},{"name":"Bracknell Forest","isoCode":"BRC","countryCode":"GB","latitude":"51.41538280","longitude":"-0.75364950"},{"name":"Bradford","isoCode":"BRD","countryCode":"GB","latitude":"53.79598400","longitude":"-1.75939800"},{"name":"London Borough of Bromley","isoCode":"BRY","countryCode":"GB","latitude":"51.36797050","longitude":"0.07006200"},{"name":"City of Bristol","isoCode":"BST","countryCode":"GB","latitude":"41.67352200","longitude":"-72.94653750"},{"name":"Bury","isoCode":"BUR","countryCode":"GB","latitude":"53.59334980","longitude":"-2.29660540"},{"name":"Cambridgeshire","isoCode":"CAM","countryCode":"GB","latitude":"52.20529730","longitude":"0.12181950"},{"name":"Caerphilly County Borough","isoCode":"CAY","countryCode":"GB","latitude":"51.66044650","longitude":"-3.21787240"},{"name":"Central Bedfordshire","isoCode":"CBF","countryCode":"GB","latitude":"52.00297440","longitude":"-0.46513890"},{"name":"Causeway Coast and Glens","isoCode":"CCG","countryCode":"GB","latitude":"55.04318300","longitude":"-6.67412880"},{"name":"Ceredigion","isoCode":"CGN","countryCode":"GB","latitude":"52.21914290","longitude":"-3.93212560"},{"name":"Craigavon Borough Council","isoCode":"CGV","countryCode":"GB","latitude":"54.39325920","longitude":"-6.45634010"},{"name":"Cheshire East","isoCode":"CHE","countryCode":"GB","latitude":"53.16104460","longitude":"-2.21859320"},{"name":"Cheshire West and Chester","isoCode":"CHW","countryCode":"GB","latitude":"53.23029740","longitude":"-2.71511170"},{"name":"Carrickfergus Borough Council","isoCode":"CKF","countryCode":"GB","latitude":"54.72568430","longitude":"-5.80937190"},{"name":"Cookstown District Council","isoCode":"CKT","countryCode":"GB","latitude":"54.64181580","longitude":"-6.74438950"},{"name":"Calderdale","isoCode":"CLD","countryCode":"GB","latitude":"53.72478450","longitude":"-1.86583570"},{"name":"Clackmannanshire","isoCode":"CLK","countryCode":"GB","latitude":"56.10753510","longitude":"-3.75294090"},{"name":"Coleraine Borough Council","isoCode":"CLR","countryCode":"GB","latitude":"55.14515700","longitude":"-6.67598140"},{"name":"Cumbria","isoCode":"CMA","countryCode":"GB","latitude":"54.57723230","longitude":"-2.79748350"},{"name":"London Borough of Camden","isoCode":"CMD","countryCode":"GB","latitude":"51.54547360","longitude":"-0.16279020"},{"name":"Carmarthenshire","isoCode":"CMN","countryCode":"GB","latitude":"51.85723090","longitude":"-4.31159590"},{"name":"Cornwall","isoCode":"CON","countryCode":"GB","latitude":"50.26604710","longitude":"-5.05271250"},{"name":"Coventry","isoCode":"COV","countryCode":"GB","latitude":"52.40682200","longitude":"-1.51969300"},{"name":"City and County of Cardiff","isoCode":"CRF","countryCode":"GB","latitude":"51.48158100","longitude":"-3.17909000"},{"name":"London Borough of Croydon","isoCode":"CRY","countryCode":"GB","latitude":"51.38274460","longitude":"-0.09851630"},{"name":"Castlereagh","isoCode":"CSR","countryCode":"GB","latitude":"54.57567900","longitude":"-5.88840280"},{"name":"Conwy County Borough","isoCode":"CWY","countryCode":"GB","latitude":"53.29350130","longitude":"-3.72651610"},{"name":"Darlington","isoCode":"DAL","countryCode":"GB","latitude":"34.29987620","longitude":"-79.87617410"},{"name":"Derbyshire","isoCode":"DBY","countryCode":"GB","latitude":"53.10467820","longitude":"-1.56238850"},{"name":"Denbighshire","isoCode":"DEN","countryCode":"GB","latitude":"53.18422880","longitude":"-3.42249850"},{"name":"City of Derby","isoCode":"DER","countryCode":"GB","latitude":"37.54837550","longitude":"-97.24851910"},{"name":"Devon","isoCode":"DEV","countryCode":"GB","latitude":"50.71555910","longitude":"-3.53087500"},{"name":"Dungannon and South Tyrone Borough Council","isoCode":"DGN","countryCode":"GB","latitude":"54.50826840","longitude":"-6.76658910"},{"name":"Dumfries and Galloway","isoCode":"DGY","countryCode":"GB","latitude":"55.07010730","longitude":"-3.60525810"},{"name":"Doncaster","isoCode":"DNC","countryCode":"GB","latitude":"53.52282000","longitude":"-1.12846200"},{"name":"Dundee","isoCode":"DND","countryCode":"GB","latitude":"56.46201800","longitude":"-2.97072
1100"},{"name":"Dorset","isoCode":"DOR","countryCode":"GB","latitude":"50.74876350","longitude":"-2.34447860"},{"name":"Down District Council","isoCode":"DOW","countryCode":"GB","latitude":"54.24342870","longitude":"-5.95779590"},{"name":"Derry City and Strabane","isoCode":"DRS","countryCode":"GB","latitude":"55.00474430","longitude":"-7.32092220"},{"name":"Derry City Council","isoCode":"DRY","countryCode":"GB","latitude":"54.96907780","longitude":"-7.19583510"},{"name":"Dudley","isoCode":"DUD","countryCode":"GB","latitude":"42.04336610","longitude":"-71.92760330"},{"name":"County Durham","isoCode":"DUR","countryCode":"GB","latitude":"54.72940990","longitude":"-1.88115980"},{"name":"London Borough of Ealing","isoCode":"EAL","countryCode":"GB","latitude":"51.52503660","longitude":"-0.34139650"},{"name":"East Ayrshire","isoCode":"EAY","countryCode":"GB","latitude":"55.45184960","longitude":"-4.26444780"},{"name":"Edinburgh","isoCode":"EDH","countryCode":"GB","latitude":"55.95325200","longitude":"-3.18826700"},{"name":"East Dunbartonshire","isoCode":"EDU","countryCode":"GB","latitude":"55.97431620","longitude":"-4.20229800"},{"name":"East Lothian","isoCode":"ELN","countryCode":"GB","latitude":"55.94933830","longitude":"-2.77044640"},{"name":"Outer Hebrides","isoCode":"ELS","countryCode":"GB","latitude":"57.75989180","longitude":"-7.01940340"},{"name":"London Borough of Enfield","isoCode":"ENF","countryCode":"GB","latitude":"51.66229090","longitude":"-0.11806510"},{"name":"England","isoCode":"ENG","countryCode":"GB","latitude":"52.35551770","longitude":"-1.17431970"},{"name":"East Renfrewshire","isoCode":"ERW","countryCode":"GB","latitude":"55.77047350","longitude":"-4.33598210"},{"name":"East Riding of Yorkshire","isoCode":"ERY","countryCode":"GB","latitude":"53.84161680","longitude":"-0.43441060"},{"name":"Essex","isoCode":"ESS","countryCode":"GB","latitude":"51.57424470","longitude":"0.48567810"},{"name":"East Sussex","isoCode":"ESX","countryCode":"GB","latitude":"50.90859550","longitude":"0.24941660"},{"name":"Falkirk","isoCode":"FAL","countryCode":"GB","latitude":"56.00187750","longitude":"-3.78391310"},{"name":"Fermanagh District Council","isoCode":"FER","countryCode":"GB","latitude":"54.34479780","longitude":"-7.63842180"},{"name":"Fife","isoCode":"FIF","countryCode":"GB","latitude":"56.20820780","longitude":"-3.14951750"},{"name":"Flintshire","isoCode":"FLN","countryCode":"GB","latitude":"53.16686580","longitude":"-3.14189080"},{"name":"Fermanagh and Omagh","isoCode":"FMO","countryCode":"GB","latitude":"54.45135240","longitude":"-7.71250180"},{"name":"Gateshead","isoCode":"GAT","countryCode":"GB","latitude":"54.95268000","longitude":"-1.60341100"},{"name":"Glasgow","isoCode":"GLG","countryCode":"GB","latitude":"55.86423700","longitude":"-4.25180600"},{"name":"Gloucestershire","isoCode":"GLS","countryCode":"GB","latitude":"51.86421120","longitude":"-2.23803350"},{"name":"Royal Borough of Greenwich","isoCode":"GRE","countryCode":"GB","latitude":"51.48346270","longitude":"0.05862020"},{"name":"Gwynedd","isoCode":"GWN","countryCode":"GB","latitude":"52.92772660","longitude":"-4.13348360"},{"name":"Halton","isoCode":"HAL","countryCode":"GB","latitude":"43.53253720","longitude":"-79.87448360"},{"name":"Hampshire","isoCode":"HAM","countryCode":"GB","latitude":"51.05769480","longitude":"-1.30806290"},{"name":"London Borough of Havering","isoCode":"HAV","countryCode":"GB","latitude":"51.57792400","longitude":"0.21208290"},{"name":"London Borough of Hackney","isoCode":"HCK","countryCode":"GB","latitude":"51.57344500","longitude":"-0.07243760"},{"name":"Herefordshire","isoCode":"HEF","countryCode":"GB","latitude":"52.07651640","longitude":"-2.65441820"},{"name":"London Borough of Hillingdon","isoCode":"HIL","countryCode":"GB","latitude":"51.53518320","longitude":"-0.44813780"},{"name":"Highland","isoCode":"HLD","countryCode":"GB","latitude":"36.29675080","longitude":"-95.83803660"},{"name":"London Borough of Hammersmith and Fulham","isoCode":"HMF","countryCode":"GB","latitude":"51.49901560","longitude":"-0.22915000"},{"name":"London Borough of Hounslow","isoCode":"HNS","countryCode":"GB","latitude":"51.48283580","longitude":"-0.38820620"},{"name":"Hartlepool","isoCode":"HPL","countryCode":"GB","latitude":"54.69174500","longitude":"-1.21292600"},{"name":"Hertfordshire","isoCode":"HRT","countryCode":"GB","latitude":"51.80978230","longitude":"-0.23767440"},{"name":"London Borough of Harrow","isoCode":"HRW","countryCode":"GB","latitude":"51.58816270","longitude":"-0.34228510"},{"name":"London Borough of Haringey","isoCode":"HRY","countryCode":"GB","latitude":"51.59061130","longitude":"-0.11097090"},{"name":"Isles of Scilly","isoCode":"IOS","countryCode":"GB","latitude":"49.92772610","longitude":"-6.32749660"},{"name":"Isle of Wight","isoCode":"IOW","countryCode":"GB","latitude":"50.69384790","longitude":"-1.30473400"},{"name":"London Borough of Islington","isoCode":"ISL","countryCode":"GB","latitude":"51.54650630","longitude":"-0.10580580"},{"name":"Inverclyde","isoCode":"IVC","countryCode":"GB","latitude":"55.93165690","longitude":"-4.68001580"},{"name":"Royal Borough of Kensington and Chelsea","isoCode":"KEC","countryCode":"GB","latitude":"51.49908050","longitude":"-0.19382530"},{"name":"Kent","isoCode":"KEN","countryCode":"GB","latitude":"41.15366740","longitude":"-81.35788590"},{"name":"City of Kingston upon Hull","isoCode":"KHL","countryCode":"GB","latitude":"53.76762360","longitude":"-0.32741980"},{"name":"Kirklees","isoCode":"KIR","countryCode":"GB","latitude":"53.59334320","longitude":"-1.80095090"},{"name":"Royal Borough of Kingston upon Thames","isoCode":"KTT","countryCode":"GB","latitude":"51.37811700","longitude":"-0.29270900"},{"name":"Knowsley","isoCode":"KWL","countryCode":"GB","latitude":"53.45459400","longitude":"-2.85290700"},{"name":"Lancashire","isoCode":"LAN","countryCode":"GB","latitude":"53.76322540","longitude":"-2.70440520"},{"name":"Lisburn and Castlereagh","isoCode":"LBC","countryCode":"GB","latitude":"54.49815840","longitude":"-6.13067910"},{"name":"London Borough of Lambeth","isoCode":"LBH","countryCode":"GB","latitude":"51.45714770","longitude":"-0.12306810"},{"name":"City of Leicester","isoCode":"LCE","countryCode":"GB","latitude":"52.63687780","longitude":"-1.13975920"},{"name":"Leeds","isoCode":"LDS","countryCode":"GB","latitude":"53.80075540","longitude":"-1.54907740"}
1,{"name":"Leicestershire","isoCode":"LEC","countryCode":"GB","latitude":"52.77257100","longitude":"-1.20521260"},{"name":"London Borough of Lewisham","isoCode":"LEW","countryCode":"GB","latitude":"51.44145790","longitude":"-0.01170060"},{"name":"Lincolnshire","isoCode":"LIN","countryCode":"GB","latitude":"52.94518890","longitude":"-0.16012460"},{"name":"Liverpool","isoCode":"LIV","countryCode":"GB","latitude":"32.65649810","longitude":"-115.47632410"},{"name":"Limavady Borough Council","isoCode":"LMV","countryCode":"GB","latitude":"55.05168200","longitude":"-6.94919440"},{"name":"City of London","isoCode":"LND","countryCode":"GB","latitude":"51.51234430","longitude":"-0.09098520"},{"name":"Larne Borough Council","isoCode":"LRN","countryCode":"GB","latitude":"54.85780030","longitude":"-5.82362240"},{"name":"Lisburn City Council","isoCode":"LSB","countryCode":"GB","latitude":"54.49815840","longitude":"-6.13067910"},{"name":"Manchester","isoCode":"MAN","countryCode":"GB","latitude":"53.48075930","longitude":"-2.24263050"},{"name":"Middlesbrough","isoCode":"MDB","countryCode":"GB","latitude":"54.57422700","longitude":"-1.23495600"},{"name":"Medway","isoCode":"MDW","countryCode":"GB","latitude":"42.14176410","longitude":"-71.39672560"},{"name":"Mid and East Antrim","isoCode":"MEA","countryCode":"GB","latitude":"54.93993410","longitude":"-6.11374230"},{"name":"Magherafelt District Council","isoCode":"MFT","countryCode":"GB","latitude":"54.75532790","longitude":"-6.60774870"},{"name":"Milton Keynes","isoCode":"MIK","countryCode":"GB","latitude":"52.08520380","longitude":"-0.73331330"},{"name":"Midlothian","isoCode":"MLN","countryCode":"GB","latitude":"32.47533500","longitude":"-97.01031810"},{"name":"Monmouthshire","isoCode":"MON","countryCode":"GB","latitude":"51.81161000","longitude":"-2.71634170"},{"name":"London Borough of Merton","isoCode":"MRT","countryCode":"GB","latitude":"51.40977420","longitude":"-0.21080840"},{"name":"Moray","isoCode":"MRY","countryCode":"GB","latitude":"57.64984760","longitude":"-3.31680390"},{"name":"Merthyr Tydfil County Borough","isoCode":"MTY","countryCode":"GB","latitude":"51.74674740","longitude":"-3.38132750"},{"name":"Mid Ulster","isoCode":"MUL","countryCode":"GB","latitude":"54.64113010","longitude":"-6.75225490"},{"name":"Moyle District Council","isoCode":"MYL","countryCode":"GB","latitude":"55.20473270","longitude":"-6.25317400"},{"name":"North Ayrshire","isoCode":"NAY","countryCode":"GB","latitude":"55.64167310","longitude":"-4.75946000"},{"name":"Northumberland","isoCode":"NBL","countryCode":"GB","latitude":"55.20825420","longitude":"-2.07841380"},{"name":"North Down Borough Council","isoCode":"NDN","countryCode":"GB","latitude":"54.65362970","longitude":"-5.67249250"},{"name":"North East Lincolnshire","isoCode":"NEL","countryCode":"GB","latitude":"53.56682010","longitude":"-0.08150660"},{"name":"Newcastle upon Tyne","isoCode":"NET","countryCode":"GB","latitude":"54.97825200","longitude":"-1.61778000"},{"name":"Norfolk","isoCode":"NFK","countryCode":"GB","latitude":"36.85076890","longitude":"-76.28587260"},{"name":"City of Nottingham","isoCode":"NGM","countryCode":"GB","latitude":"52.95478320","longitude":"-1.15810860"},{"name":"Northern Ireland","isoCode":"NIR","countryCode":"GB","latitude":"54.78771490","longitude":"-6.49231450"},{"name":"North Lanarkshire","isoCode":"NLK","countryCode":"GB","latitude":"55.86624320","longitude":"-3.96131440"},{"name":"North Lincolnshire","isoCode":"NLN","countryCode":"GB","latitude":"53.60555920","longitude":"-0.55965820"},{"name":"Newry, Mourne and Down","isoCode":"NMD","countryCode":"GB","latitude":"54.24342870","longitude":"-5.95779590"}
1,{"name":"North Somerset","isoCode":"NSM","countryCode":"GB","latitude":"51.38790280","longitude":"-2.77810910"},{"name":"Newtownabbey Borough Council","isoCode":"NTA","countryCode":"GB","latitude":"54.67924220","longitude":"-5.95911020"},{"name":"Northamptonshire","isoCode":"NTH","countryCode":"GB","latitude":"52.27299440","longitude":"-0.87555150"},{"name":"Neath Port Talbot County Borough","isoCode":"NTL","countryCode":"GB","latitude":"51.59785190","longitude":"-3.78396680"},{"name":"Nottinghamshire","isoCode":"NTT","countryCode":"GB","latitude":"53.10031900","longitude":"-0.99363060"},{"name":"North Tyneside","isoCode":"NTY","countryCode":"GB","latitude":"55.01823990","longitude":"-1.48584360"},{"name":"London Borough of Newham","isoCode":"NWM","countryCode":"GB","latitude":"51.52551620","longitude":"0.03521630"},{"name":"Newport","isoCode":"NWP","countryCode":"GB","latitude":"37.52782340","longitude":"-94.10438760"},{"name":"North Yorkshire","isoCode":"NYK","countryCode":"GB","latitude":"53.99150280","longitude":"-1.54120150"},{"name":"Newry and Mourne District Council","isoCode":"NYM","countryCode":"GB","latitude":"54.17425050","longitude":"-6.33919920"},{"name":"Oldham","isoCode":"OLD","countryCode":"GB","latitude":"42.20405980","longitude":"-71.20481190"},{"name":"Omagh District Council","isoCode":"OMH","countryCode":"GB","latitude":"54.45135240","longitude":"-7.71250180"},{"name":"Orkney Islands","isoCode":"ORK","countryCode":"GB","latitude":"58.98094010","longitude":"-2.96052060"},{"name":"Oxfordshire","isoCode":"OXF","countryCode":"GB","latitude":"51.76120560","longitude":"-1.24646740"},{"name":"Pembrokeshire","isoCode":"PEM","countryCode":"GB","latitude":"51.67407800","longitude":"-4.90887850"},{"name":"Perth and Kinross","isoCode":"PKN","countryCode":"GB","latitude":"56.39538170","longitude":"-3.42835470"},{"name":"City of Plymouth","isoCode":"PLY","countryCode":"GB","latitude":"42.37089410","longitude":"-83.46971410"},{"name":"Poole","isoCode":"POL","countryCode":"GB","latitude":"50.71505000","longitude":"-1.98724800"},{"name":"City of Portsmouth","isoCode":"POR","countryCode":"GB","latitude":"36.83291500","longitude":"-76.29755490"},{"name":"Powys","isoCode":"POW","countryCode":"GB","latitude":"52.64642490","longitude":"-3.32609040"},{"name":"City of Peterborough","isoCode":"PTE","countryCode":"GB","latitude":"44.30936360","longitude":"-78.32015300"},{"name":"Redcar and Cleveland","isoCode":"RCC","countryCode":"GB","latitude":"54.59713440","longitude":"-1.07759970"},{"name":"Rochdale","isoCode":"RCH","countryCode":"GB","latitude":"53.60971360","longitude":"-2.15610000"},{"name":"Rhondda Cynon Taf","isoCode":"RCT","countryCode":"GB","latitude":"51.64902070","longitude":"-3.42886920"},{"name":"London Borough of Redbridge","isoCode":"RDB","countryCode":"GB","latitude":"51.58861210","longitude":"0.08239820"},{"name":"Reading","isoCode":"RDG","countryCode":"GB","latitude":"36.14866590","longitude":"-95.98400120"},{"name":"Renfrewshire","isoCode":"RFW","countryCode":"GB","latitude":"55.84665400","longitude":"-4.53312590"},{"name":"London Borough of Richmond upon Thames","isoCode":"RIC","countryCode":"GB","latitude":"51.46130540","longitude":"-0.30377090"},{"name":"Rotherham","isoCode":"ROT","countryCode":"GB","latitude":"53.43260350","longitude":"-1.36350090"},{"name":"Rutland","isoCode":"RUT","countryCode":"GB","latitude":"43.61062370","longitude":"-72.97260650"},{"name":"Sandwell","isoCode":"SAW","countryCode":"GB","latitude":"52.53616740","longitude":"-2.01079300"},{"name":"South Ayrshire","isoCode":"SAY","countryCode":"GB","latitude":"55.45889880","longitude":"-4.62919940"},{"name":"Scottish Borders","isoCode":"SCB","countryCode":"GB","latitude":"55.54856970","longitude":"-2.78613880"},{"name":"Scotland","isoCode":"SCT","countryCode":"GB","latitude":"56.49067120","longitude":"-4.20264580"},{"name":"Suffolk","isoCode":"SFK","countryCode":"GB","latitude":"52.18724720","longitude":"0.97078010"},{"name":"Sefton","isoCode":"SFT","countryCode":"GB","latitude":"53.50344490","longitude":"-2.97035900"},{"name":"South Gloucestershire","isoCode":"SGC","countryCode":"GB","latitude":"51.52643610","longitude":"-2.47284870"},{"name":"Ascension Island","isoCode":"SH-AC","countryCode":"GB","latitude":"-7.94671660","longitude":"-14.35591580"},{"name":"Saint Helena","isoCode":"SH-HL","countryCode":"GB","latitude":"-15.96501040","longitude":"-5.70892410"},{"name":"Sheffield","isoCode":"SHF","countryCode":"GB","latitude":"36.09507430","longitude":"-80.27884660"},{"name":"St Helens","isoCode":"SHN","countryCode":"GB","latitude":"45.85896100","longitude":"-122.82123560"},{"name":"Shropshire","isoCode":"SHR","countryCode":"GB","latitude":"52.70636570","longitude":"-2.74178490"},{"name":"Stockport","isoCode":"SKP","countryCode":"GB","latitude":"53.41063160","longitude":"-2.15753320"},{"name":"Salford","isoCode":"SLF","countryCode":"GB","latitude":"53.48752350","longitude":"-2.29012640"},{"name":"Slough","isoCode":"SLG","countryCode":"GB","latitude":"51.51053840","longitude":"-0.59504060"},{"name":"South Lanarkshire","isoCode":"SLK","countryCode":"GB","latitude":"55.67359090","longitude":"-3.78196610"},{"name":"City of Sunderland","isoCode":"SND","countryCode":"GB","latitude":"54.88614890","longitude":"-1.47857970"},{"name":"Solihull","isoCode":"SOL","countryCode":"GB","latitude":"52.41181100","longitude":"-1.77761000"},{"name":"Somerset","isoCode":"SOM","countryCode":"GB","latitude":"51.10509700","longitude":"-2.92623070"},{"name":"Southend-on-Sea","isoCode":"SOS","countryCode":"GB","latitude":"51.54592690","longitude":"0.70771230"},{"name":"Surrey","isoCode":"SRY","countryCode":"GB","latitude":"51.31475930","longitude":"-0.55995010"},{"name":"Strabane District Council","isoCode":"STB","countryCode":"GB","latitude":"54.82738650","longitude":"-7.46331030"},{"name":"City of Stoke-on-Trent","isoCode":"STE","countryCode":"GB","latitude":"53.00266800","longitude":"-2.17940400"},{"name":"Stirling","isoCode":"STG","countryCode":"GB","latitude":"56.11652270","longitude":"-3.93690290"},{"name":"City of Southampton","isoCode":"STH","countryCode":"GB","latitude":"50.90970040","longitude":"-1.40435090"},{"name":"London Borough of Sutton","isoCode":"STN","countryCode":"GB","latitude":"51.35737620","longitude":"-0.17527960"},{"name":"Staffordshire","isoCode":"STS","countryCode":"GB","latitude":"52.87927450","longitude":"-2.05718680"},{"name":"Stockton-on-Tees","isoCode":"STT","countryCode":"GB","latitude":"54.57045510","longitude":"-1.32898210"},{"name":"South Tyneside","isoCode":"STY","countryCode":"GB","latitude":"54.96366930","longitude":"-1.44186340"},{"name":"City and County of Swansea","isoCode":"SWA","countryCode":"GB","latitude":"51.62144000","longitude":"-3.94364600"},{"name":"Swindon","isoCode":"SWD","countryCode":"GB","latitude":"51.55577390","longitude":"-1.77971760"},{"name":"London Borough of Southwark","isoCode":"SWK","countryCode":"GB","latitude":"51.48805720","longitude":"-0.07628380"},{"name":"Tameside","isoCode":"TAM","countryCode":"GB","latitude":"53.48058280","longitude":"-2.08098910"},{"name":"Telford and Wrekin","isoCode":"TFW","countryCode":"GB","latitude":"52.74099160","longitude":"-2.48685860"},{"name":"Thurrock","isoCode":"THR","countryCode":"GB","latitude":"51.49345570","longitude":"0.35291970"},{"name":"Torbay","isoCode":"TOB","countryCode":"GB","latitude":"50.43923290","longitude":"-3.53698990"},{"name":"Torfaen","isoCode":"TOF","countryCode":"GB","latitude":"51.70022530","longitude":"-3.04460150"},{"name":"Trafford","isoCode":"TRF","countryCode":"GB","latitude":"40.38562460","longitude":"-79.75893470"},{"name":"London Borough of Tower Hamlets","isoCode":"TWH","countryCode":"GB","latitude":"51.52026070","longitude":"-0.02933960"},{"name":"United Kingdom","isoCode":"UKM","countryCode":"GB","latitude":"55.37805100","longitude":"-3.43597300"}
1,{"name":"Vale of Glamorgan","isoCode":"VGL","countryCode":"GB","latitude":"51.40959580","longitude":"-3.48481670"},{"name":"Warwickshire","isoCode":"WAR","countryCode":"GB","latitude":"52.26713530","longitude":"-1.46752160"},{"name":"West Berkshire","isoCode":"WBK","countryCode":"GB","latitude":"51.43082550","longitude":"-1.14449270"},{"name":"West Dunbartonshire","isoCode":"WDU","countryCode":"GB","latitude":"55.94509250","longitude":"-4.56462590"},{"name":"London Borough of Waltham Forest","isoCode":"WFT","countryCode":"GB","latitude":"51.58863830","longitude":"-0.01176250"},{"name":"Metropolitan Borough of Wigan","isoCode":"WGN","countryCode":"GB","latitude":"53.51348120","longitude":"-2.61069990"},{"name":"Wiltshire","isoCode":"WIL","countryCode":"GB","latitude":"51.34919960","longitude":"-1.99271050"},{"name":"Wakefield","isoCode":"WKF","countryCode":"GB","latitude":"42.50393950","longitude":"-71.07233910"},{"name":"Walsall","isoCode":"WLL","countryCode":"GB","latitude":"52.58621400","longitude":"-1.98291900"},{"name":"West Lothian","isoCode":"WLN","countryCode":"GB","latitude":"55.90701980","longitude":"-3.55171670"},{"name":"Wales","isoCode":"WLS","countryCode":"GB","latitude":"52.13066070","longitude":"-3.78371170"},{"name":"City of Wolverhampton","isoCode":"WLV","countryCode":"GB","latitude":"52.58891200","longitude":"-2.15646300"},{"name":"London Borough of Wandsworth","isoCode":"WND","countryCode":"GB","latitude":"51.45682740","longitude":"-0.18966380"},{"name":"Windsor and Maidenhead","isoCode":"WNM","countryCode":"GB","latitude":"51.47997120","longitude":"-0.62425650"},{"name":"Wokingham","isoCode":"WOK","countryCode":"GB","latitude":"51.41045700","longitude":"-0.83386100"},{"name":"Worcestershire","isoCode":"WOR","countryCode":"GB","latitude":"52.25452250","longitude":"-2.26683820"},{"name":"Wirral","isoCode":"WRL","countryCode":"GB","latitude":"53.37271810","longitude":"-3.07375400"},{"name":"Warrington","isoCode":"WRT","countryCode":"GB","latitude":"40.24927410","longitude":"-75.13406040"},{"name":"Wrexham County Borough","isoCode":"WRX","countryCode":"GB","latitude":"53.03013780","longitude":"-3.02614870"},{"name":"City of Westminster","isoCode":"WSM","countryCode":"GB","latitude":"39.57659770","longitude":"-76.99721260"},{"name":"West Sussex","isoCode":"WSX","countryCode":"GB","latitude":"50.92801430","longitude":"-0.46170750"},{"name":"City of York","isoCode":"YOR","countryCode":"GB","latitude":"53.95996510","longitude":"-1.08729790"},{"name":"Shetland Islands","isoCode":"ZET","countryCode":"GB","latitude":"60.52965070","longitude":"-1.26594090"},{"name":"Saint Andrew Parish","isoCode":"01","countryCode":"GD","latitude":null,"longitude":null},{"name":"Saint David Parish","isoCode":"02","countryCode":"GD","latitude":null,"longitude":null},{"name":"Saint George Parish","isoCode":"03","countryCode":"GD","latitude":null,"longitude":null},{"name":"Saint John Parish","isoCode":"04","countryCode":"GD","latitude":"30.11183310","longitude":"-90.48799160"},{"name":"Saint Mark Parish","isoCode":"05","countryCode":"GD","latitude":"40.58818630","longitude":"-73.94957010"},{"name":"Saint Patrick Parish","isoCode":"06","countryCode":"GD","latitude":null,"longitude":null},{"name":"Carriacou and Petite Martinique","isoCode":"10","countryCode":"GD","latitude":"12.47858880","longitude":"-61.44938420"},{"name":"Khelvachauri Municipality","isoCode":"29","countryCode":"GE","latitude":"41.58019260","longitude":"41.66107420"},{"name":"Senaki Municipality","isoCode":"50","countryCode":"GE","latitude":"42.26963600","longitude":"42.06568960"},{"name":"Autonomous Republic of Abkhazia","isoCode":"AB","countryCode":"GE","latitude":"43.00155440","longitude":"41.02340700"},{"name":"Adjara","isoCode":"AJ","countryCode":"GE","latitude":"41.60056260","longitude":"42.06883830"},{"name":"Guria","isoCode":"GU","countryCode":"GE","latitude":"41.94427360","longitude":"42.04580910"},{"name":"Imereti","isoCode":"IM","countryCode":"GE","latitude":"42.23010800","longitude":"42.90086640"},{"name":"Kakheti","isoCode":"KA","countryCode":"GE","latitude":"41.64816020","longitude":"45.69055540"},{"name":"Kvemo Kartli","isoCode":"KK","countryCode":"GE","latitude":"41.47918330","longitude":"44.65604510"},{"name":"Mtskheta-Mtianeti","isoCode":"MM","countryCode":"GE","latitude":"42.16821850","longitude":"44.65060580"},{"name":"Racha-Lechkhumi and Kvemo Svaneti","isoCode":"RL","countryCode":"GE","latitude":"42.67188730","longitude":"43.05628360"},{"name":"Samtskhe-Javakheti","isoCode":"SJ","countryCode":"GE","latitude":"41.54792960","longitude":"43.27764000"},{"name":"Shida Kartli","isoCode":"SK","countryCode":"GE","latitude":"42.07569440","longitude":"43.954
104620"},{"name":"Samegrelo-Zemo Svaneti","isoCode":"SZ","countryCode":"GE","latitude":"42.73522470","longitude":"42.16893620"},{"name":"Tbilisi","isoCode":"TB","countryCode":"GE","latitude":"41.71513770","longitude":"44.82709600"},{"name":"Greater Accra","isoCode":"AA","countryCode":"GH","latitude":"5.81428360","longitude":"0.07467670"},{"name":"Ahafo","isoCode":"AF","countryCode":"GH","latitude":"7.58213720","longitude":"-2.54974630"},{"name":"Ashanti","isoCode":"AH","countryCode":"GH","latitude":"6.74704360","longitude":"-1.52086240"},{"name":"Bono East","isoCode":"BE","countryCode":"GH","latitude":"7.75000000","longitude":"-1.05000000"},{"name":"Bono","isoCode":"BO","countryCode":"GH","latitude":"7.65000000","longitude":"-2.50000000"},{"name":"Central","isoCode":"CP","countryCode":"GH","latitude":"5.50000000","longitude":"-1.00000000"},{"name":"Eastern","isoCode":"EP","countryCode":"GH","latitude":"6.50000000","longitude":"-0.50000000"},{"name":"North East","isoCode":"NE","countryCode":"GH","latitude":"10.51666700","longitude":"-0.36666700"},{"name":"Northern","isoCode":"NP","countryCode":"GH","latitude":"9.50000000","longitude":"-1.00000000"},{"name":"Oti","isoCode":"OT","countryCode":"GH","latitude":"7.90000000","longitude":"0.30000000"},{"name":"Savannah","isoCode":"SV","countryCode":"GH","latitude":"9.08333300","longitude":"-1.81666700"},{"name":"Volta","isoCode":"TV","countryCode":"GH","latitude":"6.57813730","longitude":"0.45023680"},{"name":"Upper East","isoCode":"UE","countryCode":"GH","latitude":"10.70824990","longitude":"-0.98206680"},{"name":"Upper West","isoCode":"UW","countryCode":"GH","latitude":"10.25297570","longitude":"-2.14502450"},{"name":"Western North","isoCode":"WN","countryCode":"GH","latitude":"6.30000000","longitude":"-2.80000000"},{"name":"Western","isoCode":"WP","countryCode":"GH","latitude":"5.50000000","longitude":"-2.50000000"},{"name":"Banjul","isoCode":"B","countryCode":"GM","latitude":"13.45487610","longitude":"-16.57903230"},{"name":"Lower River Division","isoCode":"L","countryCode":"GM","latitude":"13.35533060","longitude":"-15.92299000"},{"name":"Central River Division","isoCode":"M","countryCode":"GM","latitude":"13.59944690","longitude":"-14.89216680"},{"name":"North Bank Division","isoCode":"N","countryCode":"GM","latitude":"13.52854360","longitude":"-16.01699710"},{"name":"Upper River Division","isoCode":"U","countryCode":"GM","latitude":"13.42573660","longitude":"-14.00723480"},{"name":"West Coast Division","isoCode":"W","countryCode":"GM","latitude":"5.97727980","longitude":"116.07542880"},{"name":"Boké Region","isoCode":"B","countryCode":"GN","latitude":"11.18646720","longitude":"-14.10013260"},{"name":"Beyla Prefecture","isoCode":"BE","countryCode":"GN","latitude":"8.91981780","longitude":"-8.30884410"},{"name":"Boffa Prefecture","isoCode":"BF","countryCode":"GN","latitude":"10.18082540","longitude":"-14.03916150"},{"name":"Boké Prefecture","isoCode":"BK","countryCode":"GN","latitude":"11.08473790","longitude":"-14.37919120"},{"name":"Conakry","isoCode":"C","countryCode":"GN","latitude":"9.64118550","longitude":"-13.57840120"},{"name":"Coyah Prefecture","isoCode":"CO","countryCode":"GN","latitude":"9.77155350","longitude":"-13.31252990"},{"name":"Kindia Region","isoCode":"D","countryCode":"GN","latitude":"10.17816940","longitude":"-12.98961500"},{"name":"Dabola Prefecture","isoCode":"DB","countryCode":"GN","latitude":"10.72978060","longitude":"-11.11078540"},{"name":"Dinguiraye Prefecture","isoCode":"DI","countryCode":"GN","latitude":"11.68442220","longitude":"-10.80000510"},{"name":"Dalaba Prefecture","isoCode":"DL","countryCode":"GN","latitude":"10.68681760","longitude":"-12.24906970"},{"name":"Dubréka Prefecture","isoCode":"DU","countryCode":"GN","latitude":"9.79073480","longitude":"-13.51477350"},{"name":"Faranah Prefecture","isoCode":"FA","countryCode":"GN","latitude":"9.90573990","longitude":"-10.80000510"},{"name":"Forécariah Prefecture","isoCode":"FO","countryCode":"GN","latitude":"9.38861870","longitude":"-13.08179030"},{"name":"Fria Prefecture","isoCode":"FR","countryCode":"GN","latitude":"10.36745430","longitude":"-13.58418710"},{"name":"Gaoual Prefecture","isoCode":"GA","countryCode":"GN","latitude":"11.57628040","longitude":"-13.35872880"},{"name":"Guéckédou Prefecture","isoCode":"GU","countryCode":"GN","latitude":"8.56496880","longitude":"-10.13111630"},{"name":"Kankan Region","isoCode":"K","countryCode":"GN","latitude":"10.12092300","longitude":"-9.54509740"},{"name":"Kankan Prefecture","isoCode":"KA","countryCode":"GN","latitude":"10.30344650","longitude":"-9.36730840"},{"name":"Koubia Prefecture","isoCode":"KB","countryCode":"GN","latitude":"11.58235400","longitude":"-11.89202370"},{"name":"Kindia Prefecture","isoCode":"KD","countryCode":"GN","latitude":"10.10132920","longitude":"-12.71351210"},{"name":"Kérouané Prefecture","isoCode":"KE","countryCode":"GN","latitude":"9.25366430","longitude":"-9.01289260"},{"name":"Koundara Prefecture","isoCode":"KN","countryCode":"GN","latitude":"12.48940210","longitude":"-13.30675620"},{"name":"Kouroussa Prefecture","isoCode":"KO","countryCode":"GN","latitude":"10.64892290","longitude":"-9.88505860"},{"name":"Kissidougou Prefecture","isoCode":"KS","countryCode":"GN","latitude":"9.22520220","longitude":"-10.08072980"},{"name":"Labé Region","isoCode":"L","countryCode":"GN","latitude":"11.32320420","longitude":"-12.28913140"},{"name":"Labé Prefecture","isoCode":"LA","countryCode":"GN","latitude":"11.35419390","longitude":"-12.34638750"},{"name":"Lélouma Prefecture","isoCode":"LE","countryCode":"GN","latitude":"11.18333300","longitude":"-12.93333300"},{"name":"Lola Prefecture","isoCode":"LO","countryCode":"GN","latitude":"7.96138180","longitude":"-8.39649380"},{"name":"Mamou Region","isoCode":"M","countryCode":"GN","latitude":"10.57360240","longitude":"-11.88917210"},{"name":"Macenta Prefecture","isoCode":"MC","countryCode":"GN","latitude":"8.46157950","longitude":"-9.27855830"},{"name":"Mandiana Prefecture","isoCode":"MD","countryCode":"GN","latitude":"10.61728270","longitude":"-8.69857160"},{"name":"Mali Prefecture","isoCode":"ML","countryCode":"GN","latitude":"11.98370900","longitude":"-12.25479190"},{"name":"Mamou Prefecture","isoCode":"MM","countryCode":"GN","latitude":"10.57360240","longitude":"-11.88917210"},{"name":"Nzérékoré Region","isoCode":"N","countryCode":"GN","latitude":"8.03858700","longitude":"-8.83627550"},{"name":"Nzérékoré Prefecture","isoCode":"NZ","countryCode":"GN","latitude":"7.74783590","longitude":"-8.82525020"},{"name":"Pita Prefecture","isoCode":"PI","countryCode":"GN","latitude":"10.80620860","longitude":"-12.71351210"},{"name":"Siguiri Prefecture","isoCode":"SI","countryCode":"GN","latitude":"11.41481130","longitude":"-9.17883040"},{"name":"Télimélé Prefecture","isoCode":"TE","countryCode":"GN","latitude":"10.90893640","longitude":"-13.02993310"},{"name":"Tougué Prefecture","isoCode":"TO","countryCode":"GN","latitude":"11.38415830","longitude":"-11.61577730"},{"name":"Yomou Prefecture","isoCode":"YO","countryCode":"GN","latitude":"7.56962790","longitude":"-9.25915710"},{"name":"Annobón Province","isoCode":"AN","countryCode":"GQ","latitude":"-1.42687820","longitude":"5.63528010"},{"name":"Bioko Norte Province","isoCode":"BN","countryCode":"GQ","latitude":"3.65950720","longitude":"8.79218360"},{"name":"Bioko Sur Province","isoCode":"BS","countryCode":"GQ","latitude":"3.42097850","longitude":"8.61606740"},{"name":"RÃo Muni","isoCode":"C","countryCode":"GQ","latitude":"1.46106060","longitude":"9.67868940"},{"name":"Centro Sur Province","isoCode":"CS","countryCode":"GQ","latitude":"1.343
160840","longitude":"10.43965600"},{"name":"Insular Region","isoCode":"I","countryCode":"GQ","latitude":"37.09024000","longitude":"-95.71289100"},{"name":"Kié-Ntem Province","isoCode":"KN","countryCode":"GQ","latitude":"2.02809300","longitude":"11.07117580"},{"name":"Litoral Province","isoCode":"LI","countryCode":"GQ","latitude":"1.57502440","longitude":"9.81249350"},{"name":"Wele-Nzas Province","isoCode":"WN","countryCode":"GQ","latitude":"1.41661620","longitude":"11.07117580"},{"name":"Aetolia-Acarnania Regional Unit","isoCode":"01","countryCode":"GR","latitude":"38.70843860","longitude":"21.37989280"},{"name":"Boeotia Regional Unit","isoCode":"03","countryCode":"GR","latitude":"38.36636640","longitude":"23.09650640"},{"name":"Euboea","isoCode":"04","countryCode":"GR","latitude":"38.52360360","longitude":"23.85847370"},{"name":"Phthiotis Prefecture","isoCode":"06","countryCode":"GR","latitude":"38.99978500","longitude":"22.33377690"},{"name":"Argolis Regional Unit","isoCode":"11","countryCode":"GR","latitude":null,"longitude":null},{"name":"Arcadia Prefecture","isoCode":"12","countryCode":"GR","latitude":"37.55578250","longitude":"22.33377690"},{"name":"Achaea Regional Unit","isoCode":"13","countryCode":"GR","latitude":"38.11587290","longitude":"21.95224910"},{"name":"Corinthia Regional Unit","isoCode":"15","countryCode":"GR","latitude":null,"longitude":null},{"name":"Laconia","isoCode":"16","countryCode":"GR","latitude":"43.52785460","longitude":"-71.47035090"},{"name":"Corfu Prefecture","isoCode":"22","countryCode":"GR","latitude":"39.62498380","longitude":"19.92234610"},{"name":"Kefalonia Prefecture","isoCode":"23","countryCode":"GR","latitude":"38.17536750","longitude":"20.56921790"},{"name":"Lefkada Regional Unit","isoCode":"24","countryCode":"GR","latitude":"38.83336630","longitude":"20.70691080"},{"name":"Ioannina Regional Unit","isoCode":"33","countryCode":"GR","latitude":"39.66502880","longitude":"20.85374660"},{"name":"Preveza Prefecture","isoCode":"34","countryCode":"GR","latitude":"38.95926490","longitude":"20.75171550"},{"name":"Karditsa Regional Unit","isoCode":"41","countryCode":"GR","latitude":"39.36402580","longitude":"21.92140490"},{"name":"Larissa Prefecture","isoCode":"42","countryCode":"GR","latitude":"39.63902240","longitude":"22.41912540"},{"name":"Grevena Prefecture","isoCode":"51","countryCode":"GR","latitude":"40.08376260","longitude":"21.42732990"},{"name":"Drama Regional Unit","isoCode":"52","countryCode":"GR","latitude":"41.23400230","longitude":"24.23904980"},{"name":"Imathia Regional Unit","isoCode":"53","countryCode":"GR","latitude":"40.60600670","longitude":"22.14302150"},{"name":"Thessaloniki Regional Unit","isoCode":"54","countryCode":"GR","latitude":"40.64006290","longitude":"22.94441910"},{"name":"Kastoria Regional Unit","isoCode":"56","countryCode":"GR","latitude":"40.51926910","longitude":"21.26871710"},{"name":"Kilkis Regional Unit","isoCode":"57","countryCode":"GR","latitude":"40.99370710","longitude":"22.87536740"},{"name":"Kozani Prefecture","isoCode":"58","countryCode":"GR","latitude":"40.30055860","longitude":"21.78877370"},{"name":"Pella Regional Unit","isoCode":"59","countryCode":"GR","latitude":"40.91480390","longitude":"22.14302150"},{"name":"Serres Prefecture","isoCode":"62","countryCode":"GR","latitude":"41.08638540","longitude":"23.54838190"},{"name":"Chania Regional Unit","isoCode":"94","countryCode":"GR","latitude":"35.51382980","longitude":"24.01803670"},{"name":"East Macedonia and Thrace","isoCode":"A","countryCode":"GR","latitude":"41.12951260","longitude":"24.88771910"},{"name":"East Attica Regional Unit","isoCode":"A2","countryCode":"GR","latitude":"38.20540930","longitude":"23.85847370"},{"name":"Central Macedonia","isoCode":"B","countryCode":"GR","latitude":"40.62117300","longitude":"23.19180210"},{"name":"West Macedonia Region","isoCode":"C","countryCode":"GR","latitude":"40.30040580","longitude":"21.79035590"},{"name":"Epirus Region","isoCode":"D","countryCode":"GR","latitude":"39.57064130","longitude":"20.76428430"},{"name":"Ionian Islands Region","isoCode":"F","countryCode":"GR","latitude":"37.96948980","longitude":"21.38023720"},{"name":"West Greece Region","isoCode":"G","countryCode":"GR","latitude":"38.51154960","longitude":"21.57067860"},{"name":"Central Greece Region","isoCode":"H","countryCode":"GR","latitude":"38.60439840","longitude":"22.71521310"},{"name":"Attica Region","isoCode":"I","countryCode":"GR","latitude":"38.04575680","longitude":"23.85847370"},{"name":"Peloponnese Region","isoCode":"J","countryCode":"GR","latitude":"37.50794720","longitude":"22.37349000"},{"name":"South Aegean","isoCode":"L","countryCode":"GR","latitude":"37.08553020","longitude":"25.14892150"},{"name":"Crete Region","isoCode":"M","countryCode":"GR","latitude":"35.24011700","longitude":"24.80926910"},{"name":"Alta Verapaz Department","isoCode":"AV","countryCode":"GT","latitude":"15.59428830","longitude":"-90.14949880"},{"name":"Baja Verapaz Department","isoCode":"BV","countryCode":"GT","latitude":"15.12558670","longitude":"-90.37483540"},{"name":"Chimaltenango Department","isoCode":"CM","countryCode":"GT","latitude":"14.56347870","longitude":"-90.98206680"},{"name":"Chiquimula Department","isoCode":"CQ","countryCode":"GT","latitude":"14.75149990","longitude":"-89.47421770"},{"name":"Escuintla Department","isoCode":"ES","countryCode":"GT","latitude":"14.19109120","longitude":"-90.98206680"},{"name":"Guatemala Department","isoCode":"GU","countryCode":"GT","latitude":"14.56494010","longitude":"-90.52578230"},{"name":"Huehuetenango Department","isoCode":"HU","countryCode":"GT","latitude":"15.58799140","longitude":"-91.67606910"},{"name":"Izabal Department","isoCode":"IZ","countryCode":"GT","latitude":"15.49765170","longitude":"-88.86469800"},{"name":"Jalapa Department","isoCode":"JA","countryCode":"GT","latitude":"14.61214460","longitude":"-89.96267990"},{"name":"Jutiapa Department","isoCode":"JU","countryCode":"GT","latitude":"14.19308020","longitude":"-89.92532330"},{"name":"Petén Department","isoCode":"PE","countryCode":"GT","latitude":"16.91203300","longitude":"-90.29957850"},{"name":"El Progreso Department","isoCode":"PR","countryCode":"GT","latitude":"14.93887320","longitude":"-90.07467670"},{"name":"Quiché Department","isoCode":"QC","countryCode":"GT","latitude":"15.49838080","longitude":"-90.98206680"},{"name":"Quetzaltenango Department","isoCode":"QZ","countryCode":"GT","latitude":"14.79243300","longitude":"-91.71495800"},{"name":"Retalhuleu Department","isoCode":"RE","countryCode":"GT","latitude":"14.52454850","longitude":"-91.68578800"},{"name":"Sacatepéquez Department","isoCode":"SA","countryCode":"GT","latitude":"14.51783790","longitude":"-90.71527490"},{"name":"San Marcos Department","isoCode":"SM","countryCode":"GT","latitude":"14.93095690","longitude":"-91.90992380"},{"name":"Sololá Department","isoCode":"SO","countryCode":"GT","latitude":"14.74852300","longitude":"-91.28910360"},{"name":"Santa Rosa Department","isoCode":"SR","countryCode":"GT","latitude":"38.44057590","longitude":"-122.70375430"},{"name":"Suchitepéquez Department","isoCode":"SU","countryCode":"GT","latitude":"14.42159820","longitude":"-91.40482490"},{"name":"Totonicapán Department","isoCode":"TO","countryCode":"GT","latitude":"14.91734020","longitude":"-91.36139230"},{"name":"Bafatá","isoCode":"BA","countryCode":"GW","latitude":"12.17352430","longitude":"-14.65295200"},{"name":"Bolama Region","isoCode":"BL","countryCode":"GW","latitude":"11.14805910","longitude":"-16.13457050"},{"name":"Biombo Region","isoCode":"BM","countryCode":"GW","latitude":"11.85290610","longitude":"-15.73511710"},{"name":"Cacheu Region","isoCode":"CA","countryCode":"GW","latitude":"12.05514160","longitude":"-16.06401790"},{"name":"Gabú Region","isoCode":"GA","countryCode":"GW","latitude":"11.89624880","longitude":"-14.10013260"},{"name":"Leste Province","isoCode":"L","countryCode":"GW","latitude":null,"longitude":null},{"name":"Norte Province","isoCode":"N","countryCode":"GW","latitude":"7.87218110","longitude":"123.88577470"},{"name":"Oio Region","isoCode":"OI","countryCode":"GW","latitude":"12.27607090","longitude":"-15.31311850"},{"name":"Quinara Region","isoCode":"QU","countryCode":"GW","latitude":"11.79556200","longitude":"-15.17268160"},{"name":"Sul Province","isoCode":"S","countryCode":"GW","latitude":"-10.28665780","longitude":"20.71224650"},{"name":"Tombali Region","isoCode":"TO","countryCode":"GW","latitude":"11.36326960","longitude":"-14.98561760"},{"name":"Barima-Waini","isoCode":"BA","countryCode":"GY","latitude":"7.48824190","longitude":"-59.65644940"},{"name":"Cuyuni-Mazaruni","isoCode":"CU","countryCode":"GY","latitude":"6.46421410","longitude":"-60.21107520"},{"name":"Demerara-Mahaica","isoCode":"DE","countryCode":"GY","latitude":"6.54642600","longitude":"-58.09820460"},{"name":"East Berbice-Corentyne","isoCode":"EB","countryCode":"GY","latitude":"2.74779220","longitude":"-57.46272590"},{"name":"Essequibo Islands-West Demerara","isoCode":"ES","countryCode":"GY","latitude":"6.57201320","longitude":"-58.46299970"},{"name":"Mahaica-Berbice","isoCode":"MA","countryCode":"GY","latitude":"6.23849600","longitude":"-57.91625550"},{"name":"Pomeroon-Supenaam","isoCode":"PM","countryCode":"GY","latitude":"7.12941660","longitude":"-58.92062950"},{"name":"Potaro-Siparuni","isoCode":"PT","countryCode":"GY","latitude":"4.78558530","longitude":"-59.28799770"},{"name":"Upper Demerara-Berbice","isoCode":"UD","countryCode":"GY","latitude":"5.30648790","longitude":"-58.18929210"},{"name":"Upper Takutu-Upper Essequibo","isoCode":"UT","countryCode":"GY","latitude":"2.92395950","longitude":"-58.73736340"},{"name":"Central and Western District","isoCode":"HCW","countryCode":"HK","latitude":"22.28666000","longitude":"114.15497000"},{"name":"Eastern","isoCode":"HEA","countryCode":"HK","latitude":"22.28411000","longitude":"114.22414000"},{"name":"Southern","isoCode":"HSO","countryCode":"HK","latitude":"22.24725000","longitude":"114.15884000"},{"name":"Wan Chai","isoCode":"HWC","countryCode":"HK","latitude":"22.27968000","longitude":"114.17168000"},{"name":"Kowloon City","isoCode":"KKC","countryCode":"HK","latitude":"22.32820000","longitude":"114.19155000"},{"name":"Kwun Tong","isoCode":"KKT","countryCode":"HK","latitude":"22.31326000","longitude":"114.22581000"},{"name":"Sham Shui Po","isoCode":"KSS","countryCode":"HK","latitude":"22.33074000","longitude":"114.16220000"},{"name":"Wong Tai Sin","isoCode":"KWT","countryCode":"HK","latitude":"22.33353000","longitude":"114.19686000"},{"name":"Yau Tsim Mong","isoCode":"KYT","countryCode":"HK","latitude":"22.32138000","longitude":"114.17260000"},{"name":"Islands District","isoCode":"NIS","countryCode":"HK","latitude":"22.26114000","longitude":"113.94608000"},{"name":"Kwai Tsing","isoCode":"NKT","countryCode":"HK","latitude":"22.35488000","longitude":"114.08401000"},{"name":"North","isoCode":"NNO","countryCode":"HK","latitude":"22.49471000","longitude":"114.13812000"},{"name":"Sai Kung District","isoCode":"NSK","countryCode":"HK","latitude":"22.38143000","longitude":"114.27052000"},{"name":"Sha Tin","isoCode":"NST","countryCode":"HK","latitude":"22.38715000","longitude":"114.19534000"},{"name":"Tuen Mun","isoCode":"NTM","countryCode":"HK","latitude":"22.39163000","longitude":"113.97708850"},{"name":"Tsuen Wan District","isoCode":"NTW","countryCode":"HK","latitude":"22.36281000","longitude":"114.12907000"}
1,{"name":"Yuen Long District","isoCode":"NYL","countryCode":"HK","latitude":"22.44559000","longitude":"114.02218000"},{"name":"Atlántida Department","isoCode":"AT","countryCode":"HN","latitude":"15.66962830","longitude":"-87.14228950"},{"name":"Choluteca Department","isoCode":"CH","countryCode":"HN","latitude":"13.25043250","longitude":"-87.14228950"},{"name":"Colón Department","isoCode":"CL","countryCode":"HN","latitude":"15.64259650","longitude":"-85.52002400"},{"name":"Comayagua Department","isoCode":"CM","countryCode":"HN","latitude":"14.55348280","longitude":"-87.61863790"},{"name":"Copán Department","isoCode":"CP","countryCode":"HN","latitude":"14.93608380","longitude":"-88.86469800"},{"name":"Cortés Department","isoCode":"CR","countryCode":"HN","latitude":"15.49235080","longitude":"-88.09007620"},{"name":"El ParaÃso Department","isoCode":"EP","countryCode":"HN","latitude":"13.98212940","longitude":"-86.49965460"},{"name":"Francisco Morazán Department","isoCode":"FM","countryCode":"HN","latitude":"14.45411000","longitude":"-87.06242610"},{"name":"Gracias a Dios Department","isoCode":"GD","countryCode":"HN","latitude":"15.34180600","longitude":"-84.60604490"},{"name":"Bay Islands Department","isoCode":"IB","countryCode":"HN","latitude":"16.48266140","longitude":"-85.87932520"},{"name":"Intibucá Department","isoCode":"IN","countryCode":"HN","latitude":"14.37273400","longitude":"-88.24611830"},{"name":"Lempira Department","isoCode":"LE","countryCode":"HN","latitude":"14.18876980","longitude":"-88.55653100"},{"name":"La Paz Department","isoCode":"LP","countryCode":"HN","latitude":"-15.08924160","longitude":"-68.52471490"},{"name":"Ocotepeque Department","isoCode":"OC","countryCode":"HN","latitude":"14.51703470","longitude":"-89.05615320"},{"name":"Olancho Department","isoCode":"OL","countryCode":"HN","latitude":"14.80674060","longitude":"-85.76666450"},{"name":"Santa Bárbara Department","isoCode":"SB","countryCode":"HN","latitude":"15.12027950","longitude":"-88.40160410"},{"name":"Valle Department","isoCode":"VA","countryCode":"HN","latitude":"13.57829360","longitude":"-87.57912870"},{"name":"Yoro Department","isoCode":"YO","countryCode":"HN","latitude":"15.29496790","longitude":"-87.14228950"},{"name":"Zagreb County","isoCode":"01","countryCode":"HR","latitude":"45.87066120","longitude":"16.39549100"},{"name":"Krapina-Zagorje County","isoCode":"02","countryCode":"HR","latitude":"46.10133930","longitude":"15.88096930"},{"name":"Sisak-Moslavina County","isoCode":"03","countryCode":"HR","latitude":"45.38379260","longitude":"16.53809940"},{"name":"Karlovac County","isoCode":"05","countryCode":"HR","latitude":"45.26133520","longitude":"15.52542016"},{"name":"Koprivnica-Križevci County","isoCode":"06","countryCode":"HR","latitude":"46.15689190","longitude":"16.83908260"},{"name":"Bjelovar-Bilogora County","isoCode":"07","countryCode":"HR","latitude":"45.89879720","longitude":"16.84230930"},{"name":"Primorje-Gorski Kotar County","isoCode":"08","countryCode":"HR","latitude":"45.31739960","longitude":"14.81674660"},{"name":"Lika-Senj County","isoCode":"09","countryCode":"HR","latitude":"44.61922180","longitude":"15.47016080"},{"name":"Virovitica-Podravina County","isoCode":"10","countryCode":"HR","latitude":"45.65579850","longitude":"17.79324720"},{"name":"Požega-Slavonia County","isoCode":"11","countryCode":"HR","latitude":"45.34178680","longitude":"17.81143590"},{"name":"Brod-Posavina County","isoCode":"12","countryCode":"HR","latitude":"45.26379510","longitude":"17.32645620"},{"name":"Zadar County","isoCode":"13","countryCode":"HR","latitude":"44.14693900","longitude":"15.61649430"},{"name":"Osijek-Baranja County","isoCode":"14","countryCode":"HR","latitude":"45.55764280","longitude":"18.39421410"},{"name":"Å ibenik-Knin County","isoCode":"15","countryCode":"HR","latitude":"43.92814850","longitude":"16.10376940"},{"name":"Vukovar-Syrmia County","isoCode":"16","countryCode":"HR","latitude":"45.17735520","longitude":"18.80535270"},{"name":"Split-Dalmatia County","isoCode":"17","countryCode":"HR","latitude":"43.52403280","longitude":"16.81783770"},{"name":"Istria County","isoCode":"18","countryCode":"HR","latitude":"45.12864550","longitude":"13.90154200"},{"name":"Dubrovnik-Neretva County","isoCode":"19","countryCode":"HR","latitude":"43.07665880","longitude":"17.52684710"},{"name":"MeÄimurje County","isoCode":"20","countryCode":"HR","latitude":"46.37666440","longitude":"16.42132980"},{"name":"Zagreb","isoCode":"21","countryCode":"HR","latitude":"45.81501080","longitude":"15.98191890"},{"name":"Artibonite","isoCode":"AR","countryCode":"HT","latitude":"19.36290200","longitude":"-72.42581450"},{"name":"Centre","isoCode":"CE","countryCode":"HT","latitude":"32.83702510","longitude":"-96.77738820"},{"name":"Grand\'Anse","isoCode":"GA","countryCode":"HT","latitude":"12.01666670","longitude":"-61.76666670"},{"name":"Nord","isoCode":"ND","countryCode":"HT","latitude":"43.19052600","longitude":"-89.43792100"},{"name":"Nord-Est","isoCode":"NE","countryCode":"HT","latitude":"19.48897230","longitude":"-71.85713310"},{"name":"Nippes","isoCode":"NI","countryCode":"HT","latitude":"18.39907350","longitude":"-73.41802110"},{"name":"Nord-Ouest","isoCode":"NO","countryCode":"HT","latitude":"19.83740090","longitude":"-73.04052770"},{"name":"Ouest","isoCode":"OU","countryCode":"HT","latitude":"45.45472490","longitude":"-73.65023650"},{"name":"Sud","isoCode":"SD","countryCode":"HT","latitude":"29.92132480","longitude":"-90.09737720"},{"name":"Sud-Est","isoCode":"SE","countryCode":"HT","latitude":"18.27835980","longitude":"-72.35479150"},{"name":"Baranya County","isoCode":"BA","countryCode":"HU","latitude":"46.04845850","longitude":"18.27191730"},{"name":"Békéscsaba","isoCode":"BC","countryCode":"HU","latitude":"46.67359390","longitude":"21.08773090"},{"name":"Békés County","isoCode":"BE","countryCode":"HU","latitude":"46.67048990","longitude":"21.04349960"},{"name":"Bács-Kiskun County","isoCode":"BK","countryCode":"HU","latitude":"46.56614370","longitude":"19.42724640"},{"name":"Budapest","isoCode":"BU","countryCode":"HU","latitude":"47.49791200","longitude":"19.04023500"},{"name":"Borsod-Abaúj-Zemplén County","isoCode":"BZ","countryCode":"HU","latitude":"48.29394010","longitude":"20.69341120"},{"name":"Csongrád County","isoCode":"CS","countryCode":"HU","latitude":"46.41670500","longitude":"20.25661610"},{"name":"Debrecen","isoCode":"DE","countryCode":"HU","latitude":"47.53160490","longitude":"21.62731240"},{"name":"Dunaújváros","isoCode":"DU","countryCode":"HU","latitude":"46.96190590","longitude":"18.93552270"},{"name":"Eger","isoCode":"EG","countryCode":"HU","latitude":"47.90253480","longitude":"20.37722840"},{"name":"Ãrd","isoCode":"ER","countryCode":"HU","latitude":"47.39197180","longitude":"18.90454400"},{"name":"Fejér County","isoCode":"FE","countryCode":"HU","latitude":"47.12179320","longitude":"18.52948150"},{"name":"GyÅr-Moson-Sopron County","isoCode":"GS","countryCode":"HU","latitude":"47.65092850","longitude":"17.25058830"},{"name":"GyÅr","isoCode":"GY","countryCode":"HU","latitude":"47.68745690","longitude":"17.65039740"},{"name":"Hajdú-Bihar County","isoCode":"HB","countryCode":"HU","latitude":"47.46883550","longitude":"21.54532270"},{"name":"Heves County","isoCode":"HE","countryCode":"HU","latitude":"47.80576170","longitude":"20.20385590"},{"name":"HódmezÅvásárhely","isoCode":"HV","countryCode":"HU","latitude":"46.41812620","longitude":"20.33003150"},{"name":"Jász-Nagykun-Szolnok County","isoCode":"JN","countryCode":"HU","latitude":"47.25555790","longitude":"20.52324560"},{"name":"Kecskemét","isoCode":"KM","countryCode":"HU","latitude":"46.89637110","longitude":"19.68968610"},{"name":"Kaposvár","isoCode":"KV","countryCode":"HU","latitude":"46.35936060","longitude":"17.79676390"},{"name":"Miskolc","isoCode":"MI","countryCode":"HU","latitude":"48.10347750","longitude":"20.77843840"},{"name":"Nagykanizsa","isoCode":"NK","countryCode":"HU","latitude":"46.45902180","longitude":"16.98967960"},{"name":"Nógrád County","isoCode":"NO","countryCode":"HU","latitude":"47.90410310","longitude":"19.04985040"},{"name":"NyÃregyháza","isoCode":"NY","countryCode":"HU","latitude":"47.94953240","longitude":"21.72440530"},{"name":"Pest County","isoCode":"PE","countryCode":"HU","latitude":"47.44800010","longitude":"19.46181280"},{"name":"Pécs","isoCode":"PS","countryCode":"HU","latitude":"46.07273450","longitude":"18.23226600"},{"name":"Szeged","isoCode":"SD","countryCode":"HU","latitude":"46.25301020","longitude":"20.14142530"},{"name":"Székesfehérvár","isoCode":"SF","countryCode":"HU","latitude":"47.18602620","longitude":"18.42213580"},{"name":"Szombathely","isoCode":"SH","countryCode":"HU","latitude":"47.23068510","longitude":"16.62184410"},{"name":"Szolnok","isoCode":"SK","countryCode":"HU","latitude":"47.16213550","longitude":"20.18247120"},{"name":"Sopron","isoCode":"SN","countryCode":"HU","latitude":"47.68166190","longitude":"16.58447950"},{"name":"Somogy County","isoCode":"SO","countryCode":"HU","latitude":"46.55485900","longitude":"17.58667320"},{"name":"Szekszárd","isoCode":"SS","countryCode":"HU","latitude":"46.34743260","longitude":"18.70622930"},{"name":"Salgótarján","isoCode":"ST","countryCode":"HU","latitude":"48.09352370","longitude":"19.79998130"},{"name":"Szabolcs-Szatmár-Bereg County","isoCode":"SZ","countryCode":"HU","latitude":"48.03949540","longitude":"22.00333000"},{"name":"Tatabánya","isoCode":"TB","countryCode":"HU","latitude":"47.56924600","longitude":"18.40481800"},{"name":"Tolna County","isoCode":"TO","countryCode":"HU","latitude":"46.47627540","longitude":"18.55706270"}
1,{"name":"Vas County","isoCode":"VA","countryCode":"HU","latitude":"47.09291110","longitude":"16.68121830"},{"name":"Veszprém County","isoCode":"VE","countryCode":"HU","latitude":"47.09309740","longitude":"17.91007630"},{"name":"Veszprém","isoCode":"VM","countryCode":"HU","latitude":"47.10280870","longitude":"17.90930190"},{"name":"Zala County","isoCode":"ZA","countryCode":"HU","latitude":"46.73844040","longitude":"16.91522520"},{"name":"Zalaegerszeg","isoCode":"ZE","countryCode":"HU","latitude":"46.84169360","longitude":"16.84163220"},{"name":"Aceh","isoCode":"AC","countryCode":"ID","latitude":"4.69513500","longitude":"96.74939930"},{"name":"Bali","isoCode":"BA","countryCode":"ID","latitude":"-8.34053890","longitude":"115.09195090"},{"name":"Kepulauan Bangka Belitung","isoCode":"BB","countryCode":"ID","latitude":"-2.74105130","longitude":"106.44058720"},{"name":"Bengkulu","isoCode":"BE","countryCode":"ID","latitude":"-3.79284510","longitude":"102.26076410"},{"name":"Banten","isoCode":"BT","countryCode":"ID","latitude":"-6.40581720","longitude":"106.06401790"},{"name":"Gorontalo","isoCode":"GO","countryCode":"ID","latitude":"0.54354420","longitude":"123.05676930"},{"name":"Jambi","isoCode":"JA","countryCode":"ID","latitude":"-1.61012290","longitude":"103.61312030"},{"name":"Jawa Barat","isoCode":"JB","countryCode":"ID","latitude":"-7.09091100","longitude":"107.66888700"},{"name":"Jawa Timur","isoCode":"JI","countryCode":"ID","latitude":"-7.53606390","longitude":"112.23840170"},{"name":"DKI Jakarta","isoCode":"JK","countryCode":"ID","latitude":"-6.20876340","longitude":"106.84559900"},{"name":"Jawa Tengah","isoCode":"JT","countryCode":"ID","latitude":"-7.15097500","longitude":"110.14025940"},{"name":"Kalimantan Barat","isoCode":"KA","countryCode":"ID","latitude":"0.96188340","longitude":"114.55484950"},{"name":"Kalimantan Timur","isoCode":"KI","countryCode":"ID","latitude":"0.53865860","longitude":"116.41938900"},{"name":"Kepulauan Riau","isoCode":"KR","countryCode":"ID","latitude":"3.94565140","longitude":"108.14286690"},{"name":"Kalimantan Selatan","isoCode":"KS","countryCode":"ID","latitude":"-3.09264150","longitude":"115.28375850"},{"name":"Kalimantan Tengah","isoCode":"KT","countryCode":"ID","latitude":"-1.68148780","longitude":"113.38235450"},{"name":"Kalimantan Utara","isoCode":"KU","countryCode":"ID","latitude":"3.07309290","longitude":"116.04138890"},{"name":"Lampung","isoCode":"LA","countryCode":"ID","latitude":"-4.55858490","longitude":"105.40680790"},{"name":"Maluku","isoCode":"MA","countryCode":"ID","latitude":"-3.23846160","longitude":"130.14527340"},{"name":"Maluku Utara","isoCode":"MU","countryCode":"ID","latitude":"1.57099930","longitude":"127.80876930"},{"name":"Nusa Tenggara Barat","isoCode":"NB","countryCode":"ID","latitude":"-8.65293340","longitude":"117.36164760"},{"name":"Nusa Tenggara Timur","isoCode":"NT","countryCode":"ID","latitude":"-8.65738190","longitude":"121.07937050"},{"name":"Papua","isoCode":"PA","countryCode":"ID","latitude":"-5.01222020","longitude":"141.34701590"},{"name":"Papua Barat","isoCode":"PB","countryCode":"ID","latitude":"-1.33611540","longitude":"133.17471620"},{"name":"Riau","isoCode":"RI","countryCode":"ID","latitude":"0.29334690","longitude":"101.70682940"},{"name":"Sulawesi Utara","isoCode":"SA","countryCode":"ID","latitude":"0.62469320","longitude":"123.97500180"},{"name":"Sumatera Barat","isoCode":"SB","countryCode":"ID","latitude":"-0.73993970","longitude":"100.80000510"},{"name":"Sulawesi Tenggara","isoCode":"SG","countryCode":"ID","latitude":"-4.14491000","longitude":"122.17460500"},{"name":"Sulawesi Selatan","isoCode":"SN","countryCode":"ID","latitude":"-3.66879940","longitude":"119.97405340"},{"name":"Sulawesi Barat","isoCode":"SR","countryCode":"ID","latitude":"-2.84413710","longitude":"119.23207840"},{"name":"Sumatera Selatan","isoCode":"SS","countryCode":"ID","latitude":"-3.31943740","longitude":"103.91439900"},{"name":"Sulawesi Tengah","isoCode":"ST","countryCode":"ID","latitude":"-1.43002540","longitude":"121.44561790"},{"name":"Sumatera Utara","isoCode":"SU","countryCode":"ID","latitude":"2.11535470","longitude":"99.54509740"},{"name":"DI Yogyakarta","isoCode":"YO","countryCode":"ID","latitude":"-7.87538490","longitude":"110.42620880"},{"name":"Connacht","isoCode":"C","countryCode":"IE","latitude":"53.83762430","longitude":"-8.95844810"},{"name":"Clare","isoCode":"CE","countryCode":"IE","latitude":"43.04664000","longitude":"-87.89958100"},{"name":"Cavan","isoCode":"CN","countryCode":"IE","latitude":"53.97654240","longitude":"-7.29966230"},{"name":"Cork","isoCode":"CO","countryCode":"IE","latitude":"51.89851430","longitude":"-8.47560350"},{"name":"Carlow","isoCode":"CW","countryCode":"IE","latitude":"52.72322170","longitude":"-6.81082950"},{"name":"Dublin","isoCode":"D","countryCode":"IE","latitude":"53.34980530","longitude":"-6.26030970"},{"name":"Donegal","isoCode":"DL","countryCode":"IE","latitude":"54.65489930","longitude":"-8.10409670"},{"name":"Galway","isoCode":"G","countryCode":"IE","latitude":"53.35645090","longitude":"-8.85341130"},{"name":"Kildare","isoCode":"KE","countryCode":"IE","latitude":"53.21204340","longitude":"-6.81947080"},{"name":"Kilkenny","isoCode":"KK","countryCode":"IE","latitude":"52.57769570","longitude":"-7.21800200"},{"name":"Kerry","isoCode":"KY","countryCode":"IE","latitude":"52.15446070","longitude":"-9.56686330"},{"name":"Leinster","isoCode":"L","countryCode":"IE","latitude":"53.32715380","longitude":"-7.51408410"},{"name":"Longford","isoCode":"LD","countryCode":"IE","latitude":"53.72749820","longitude":"-7.79315270"},{"name":"Louth","isoCode":"LH","countryCode":"IE","latitude":"53.92523240","longitude":"-6.48894230"},{"name":"Limerick","isoCode":"LK","countryCode":"IE","latitude":"52.50905170","longitude":"-8.74749550"},{"name":"Laois","isoCode":"LS","countryCode":"IE","latitude":"52.99429500","longitude":"-7.33230070"},{"name":"Munster","isoCode":"M","countryCode":"IE","latitude":"51.94711970","longitude":"7.58453200"},{"name":"Meath","isoCode":"MH","countryCode":"IE","latitude":"53.60554800","longitude":"-6.65641690"},{"name":"Monaghan","isoCode":"MN","countryCode":"IE","latitude":"54.24920460","longitude":"-6.96831320"},{"name":"Mayo","isoCode":"MO","countryCode":"IE","latitude":"54.01526040","longitude":"-9.42893690"},{"name":"Offaly","isoCode":"OY","countryCode":"IE","latitude":"53.23568710","longitude":"-7.71222290"},{"name":"Roscommon","isoCode":"RN","countryCode":"IE","latitude":"53.75926040","longitude":"-8.26816210"},{"name":"Sligo","isoCode":"SO","countryCode":"IE","latitude":"54.15532770","longitude":"-8.60645320"},{"name":"Tipperary","isoCode":"TA","countryCode":"IE","latitude":"52.47378940","longitude":"-8.16185140"},{"name":"Ulster","isoCode":"U","countryCode":"IE","latitude":"54.76165550","longitude":"-6.96122730"},{"name":"Waterford","isoCode":"WD","countryCode":"IE","latitude":"52.19435490","longitude":"-7.62275120"},{"name":"Westmeath","isoCode":"WH","countryCode":"IE","latitude":"53.53453080","longitude":"-7.46532170"},{"name":"Wicklow","isoCode":"WW","countryCode":"IE","latitude":"52.98623130","longitude":"-6.36725430"},{"name":"Wexford","isoCode":"WX","countryCode":"IE","latitude":"52.47936030","longitude":"-6.58399130"},{"name":"Southern District","isoCode":"D","countryCode":"IL","latitude":"40.71375860","longitude":"-74.00090590"},{"name":"Haifa District","isoCode":"HA","countryCode":"IL","latitude":"32.48141110","longitude":"34.99475100"},{"name":"Jerusalem District","isoCode":"JM","countryCode":"IL","latitude":"31.76482430","longitude":"34.99475100"},{"name":"Central District","isoCode":"M","countryCode":"IL","latitude":"47.60875830","longitude":"-122.29642350"},{"name":"Tel Aviv District","isoCode":"TA","countryCode":"IL","latitude":"32.09290750","longitude":"34.80721650"},{"name":"Northern District","isoCode":"Z","countryCode":"IL","latitude":"36.15118640","longitude":"-95.99517630"},{"name":"Andaman and Nicobar Islands","isoCode":"AN","countryCode":"IN","latitude":"11.74008670","longitude":"92.65864010"},{"name":"Andhra Pradesh","isoCode":"AP","countryCode":"IN","latitude":"15.91289980","longitude":"79.73998750"},{"name":"Arunachal Pradesh","isoCode":"AR","countryCode":"IN","latitude":"28.21799940","longitude":"94.72775280"},{"name":"Assam","isoCode":"AS","countryCode":"IN","latitude":"26.20060430","longitude":"92.93757390"},{"name":"Bihar","isoCode":"BR","countryCode":"IN","latitude":"25.09607420","longitude":"85.31311940"},{"name":"Chandigarh","isoCode":"CH","countryCode":"IN","latitude":"30.73331480","longitude":"76.77941790"},{"name":"Chhattisgarh","isoCode":"CT","countryCode":"IN","latitude":"21.27865670","longitude":"81.86614420"},{"name":"Dadra and Nagar Haveli and Daman and Diu","isoCode":"DH","countryCode":"IN","latitude":"20.39737360","longitude":"72.83279910"},{"name":"Delhi","isoCode":"DL","countryCode":"IN","latitude":"28.70405920","longitude":"77.10249020"},{"name":"Goa","isoCode":"GA","countryCode":"IN","latitude":"15.29932650","longitude":"74.12399600"},{"name":"Gujarat","isoCode":"GJ","countryCode":"IN","latitude":"22.25865200","longitude":"71.19238050"},{"name":"Himachal Pradesh","isoCode":"HP","countryCode":"IN","latitude":"31.10482940","longitude":"77.17339010"},{"name":"Haryana","isoCode":"HR","countryCode":"IN","latitude":"29.05877570","longitude":"76.08560100"},{"name":"Jharkhand","isoCode":"JH","countryCode":"IN","latitude":"23.61018080","longitude":"85.27993540"},{"name":"Jammu and Kashmir","isoCode":"JK","countryCode":"IN","latitude":"33.27783900","longitude":"75.34121790"},{"name":"Karnataka","isoCode":"KA","countryCode":"IN","latitude":"15.31727750","longitude":"75.71388840"},{"name":"Kerala","isoCode":"KL","countryCode":"IN","latitude":"10.85051590","longitude":"76.27108330"},{"name":"Ladakh","isoCode":"LA","countryCode":"IN","latitude":"34.22684750","longitude":"77.56194190"},{"name":"Lakshadweep","isoCode":"LD","countryCode":"IN","latitude":"10.32802650","longitude":"72.78463360"},{"name":"Maharashtra","isoCode":"MH","countryCode":"IN","latitude":"19.75147980","longitude":"75.71388840"},{"name":"Meghalaya","isoCode":"ML","countryCode":"IN","latitude":"25.46703080","longitude":"91.36621600"},{"name":"Manipur","isoCode":"MN","countryCode":"IN","latitude":"24.66371730","longitude":"93.90626880"},{"name":"Madhya Pradesh","isoCode":"MP","countryCode":"IN","latitude":"22.97342290","longitude":"78.65689420"},{"name":"Mizoram","isoCode":"MZ","countryCode":"IN","latitude":"23.16454300","longitude":"92.93757390"},{"name":"Nagaland","isoCode":"NL","countryCode":"IN","latitude":"26.15843540","longitude":"94.56244260"}
1,{"name":"Odisha","isoCode":"OR","countryCode":"IN","latitude":"20.95166580","longitude":"85.09852360"},{"name":"Punjab","isoCode":"PB","countryCode":"IN","latitude":"31.14713050","longitude":"75.34121790"},{"name":"Puducherry","isoCode":"PY","countryCode":"IN","latitude":"11.94159150","longitude":"79.80831330"},{"name":"Rajasthan","isoCode":"RJ","countryCode":"IN","latitude":"27.02380360","longitude":"74.21793260"},{"name":"Sikkim","isoCode":"SK","countryCode":"IN","latitude":"27.53297180","longitude":"88.51221780"},{"name":"Telangana","isoCode":"TG","countryCode":"IN","latitude":"18.11243720","longitude":"79.01929970"},{"name":"Tamil Nadu","isoCode":"TN","countryCode":"IN","latitude":"11.12712250","longitude":"78.65689420"},{"name":"Tripura","isoCode":"TR","countryCode":"IN","latitude":"23.94084820","longitude":"91.98815270"},{"name":"Uttar Pradesh","isoCode":"UP","countryCode":"IN","latitude":"26.84670880","longitude":"80.94615920"},{"name":"Uttarakhand","isoCode":"UT","countryCode":"IN","latitude":"30.06675300","longitude":"79.01929970"},{"name":"West Bengal","isoCode":"WB","countryCode":"IN","latitude":"22.98675690","longitude":"87.85497550"},{"name":"Al Anbar Governorate","isoCode":"AN","countryCode":"IQ","latitude":"32.55976140","longitude":"41.91964710"},{"name":"Erbil Governorate","isoCode":"AR","countryCode":"IQ","latitude":"36.55706280","longitude":"44.38512630"},{"name":"Basra Governorate","isoCode":"BA","countryCode":"IQ","latitude":"30.51142520","longitude":"47.82962530"},{"name":"Babylon Governorate","isoCode":"BB","countryCode":"IQ","latitude":"32.46819100","longitude":"44.55019350"},{"name":"Baghdad Governorate","isoCode":"BG","countryCode":"IQ","latitude":"33.31526180","longitude":"44.36606530"},{"name":"Dohuk Governorate","isoCode":"DA","countryCode":"IQ","latitude":"36.90772520","longitude":"43.06316890"},{"name":"Diyala Governorate","isoCode":"DI","countryCode":"IQ","latitude":"33.77334870","longitude":"45.14945050"},{"name":"Dhi Qar Governorate","isoCode":"DQ","countryCode":"IQ","latitude":"31.10422920","longitude":"46.36246860"},{"name":"Karbala Governorate","isoCode":"KA","countryCode":"IQ","latitude":"32.40454930","longitude":"43.86732220"},{"name":"Kirkuk Governorate","isoCode":"KI","countryCode":"IQ","latitude":"35.32920140","longitude":"43.94367880"},{"name":"Maysan Governorate","isoCode":"MA","countryCode":"IQ","latitude":"31.87340020","longitude":"47.13621250"},{"name":"Al Muthanna Governorate","isoCode":"MU","countryCode":"IQ","latitude":"29.91331710","longitude":"45.29938620"},{"name":"Najaf Governorate","isoCode":"NA","countryCode":"IQ","latitude":"31.35174860","longitude":"44.09603110"},{"name":"Nineveh Governorate","isoCode":"NI","countryCode":"IQ","latitude":"36.22957400","longitude":"42.23624350"},{"name":"Al-QÄdisiyyah Governorate","isoCode":"QA","countryCode":"IQ","latitude":"32.04369100","longitude":"45.14945050"},{"name":"Saladin Governorate","isoCode":"SD","countryCode":"IQ","latitude":"34.53375270","longitude":"43.48373800"},{"name":"Sulaymaniyah Governorate","isoCode":"SU","countryCode":"IQ","latitude":"35.54663480","longitude":"45.30036830"},{"name":"Wasit Governorate","isoCode":"WA","countryCode":"IQ","latitude":"32.60240940","longitude":"45.75209850"},{"name":"Markazi","isoCode":"00","countryCode":"IR","latitude":"34.61230500","longitude":"49.85472660"},{"name":"Gilan","isoCode":"01","countryCode":"IR","latitude":"37.28094550","longitude":"49.59241340"},{"name":"Mazandaran","isoCode":"02","countryCode":"IR","latitude":"36.22623930","longitude":"52.53186040"},{"name":"East Azerbaijan","isoCode":"03","countryCode":"IR","latitude":"37.90357330","longitude":"46.26821090"},{"name":"West Azarbaijan","isoCode":"04","countryCode":"IR","latitude":"37.45500620","longitude":"45.00000000"},{"name":"Kermanshah","isoCode":"05","countryCode":"IR","latitude":"34.45762330","longitude":"46.67053400"},{"name":"Khuzestan","isoCode":"06","countryCode":"IR","latitude":"31.43601490","longitude":"49.04131200"},{"name":"Fars","isoCode":"07","countryCode":"IR","latitude":"29.10438130","longitude":"53.04589300"},{"name":"Kerman","isoCode":"08","countryCode":"IR","latitude":"29.48500890","longitude":"57.64390480"},{"name":"Razavi Khorasan","isoCode":"09","countryCode":"IR","latitude":"35.10202530","longitude":"59.10417580"},{"name":"Isfahan","isoCode":"10","countryCode":"IR","latitude":"33.27710730","longitude":"52.36133780"},{"name":"Sistan and Baluchestan","isoCode":"11","countryCode":"IR","latitude":"27.52999060","longitude":"60.58206760"},{"name":"Kurdistan","isoCode":"12","countryCode":"IR","latitude":"35.95535790","longitude":"47.13621250"},{"name":"Hamadan","isoCode":"13","countryCode":"IR","latitude":"34.91936070","longitude":"47.48329250"},{"name":"Chaharmahal and Bakhtiari","isoCode":"14","countryCode":"IR","latitude":"31.99704190","longitude":"50.66138490"},{"name":"Lorestan","isoCode":"15","countryCode":"IR","latitude":"33.58183940","longitude":"48.39881860"},{"name":"Ilam","isoCode":"16","countryCode":"IR","latitude":"33.29576180","longitude":"46.67053400"},{"name":"Kohgiluyeh and Boyer-Ahmad","isoCode":"17","countryCode":"IR","latitude":"30.72458600","longitude":"50.84563230"},{"name":"Bushehr","isoCode":"18","countryCode":"IR","latitude":"28.76207390","longitude":"51.51500770"},{"name":"Zanjan","isoCode":"19","countryCode":"IR","latitude":"36.50181850","longitude":"48.39881860"},{"name":"Semnan","isoCode":"20","countryCode":"IR","latitude":"35.22555850","longitude":"54.43421380"},{"name":"Yazd","isoCode":"21","countryCode":"IR","latitude":"32.10063870","longitude":"54.43421380"},{"name":"Hormozgan","isoCode":"22","countryCode":"IR","latitude":"27.13872300","longitude":"55.13758340"},{"name":"Tehran","isoCode":"23","countryCode":"IR","latitude":"35.72484160","longitude":"51.38165300"},{"name":"Ardabil","isoCode":"24","countryCode":"IR","latitude":"38.48532760","longitude":"47.89112090"},{"name":"Qom","isoCode":"25","countryCode":"IR","latitude":"34.64157640","longitude":"50.87460350"},{"name":"Qazvin","isoCode":"26","countryCode":"IR","latitude":"36.08813170","longitude":"49.85472660"},{"name":"Golestan","isoCode":"27","countryCode":"IR","latitude":"37.28981230","longitude":"55.13758340"},{"name":"North Khorasan","isoCode":"28","countryCode":"IR","latitude":"37.47103530","longitude":"57.10131880"},{"name":"South Khorasan","isoCode":"29","countryCode":"IR","latitude":"32.51756430","longitude":"59.10417580"},{"name":"Alborz","isoCode":"30","countryCode":"IR","latitude":"35.99604670","longitude":"50.92892460"},{"name":"Capital Region","isoCode":"1","countryCode":"IS","latitude":"38.56569570","longitude":"-92.18169490"},{"name":"Southern Peninsula Region","isoCode":"2","countryCode":"IS","latitude":"63.91548030","longitude":"-22.36496670"},{"name":"Western Region","isoCode":"3","countryCode":"IS","latitude":null,"longitude":null},{"name":"Westfjords","isoCode":"4","countryCode":"IS","latitude":"65.91961500","longitude":"-21.88117640"},{"name":"Northwestern Region","isoCode":"5","countryCode":"IS","latitude":"41.91339320","longitude":"-73.04716880"},{"name":"Northeastern Region","isoCode":"6","countryCode":"IS","latitude":"43.29942850","longitude":"-74.21793260"},{"name":"Eastern Region","isoCode":"7","countryCode":"IS","latitude":null,"longitude":null},{"name":"Southern Region","isoCode":"8","countryCode":"IS","latitude":null,"longitude":null},{"name":"Piedmont","isoCode":"21","countryCode":"IT","latitude":"45.05223660","longitude":"7.51538850"},{"name":"Aosta Valley","isoCode":"23","countryCode":"IT","latitude":"45.73888780","longitude":"7.42618660"},{"name":"Lombardy","isoCode":"25","countryCode":"IT","latitude":"45.47906710","longitude":"9.84524330"},{"name":"Trentino-South Tyrol","isoCode":"32","countryCode":"IT","latitude":"46.43366620","longitude":"11.16932960"},{"name":"Veneto","isoCode":"34","countryCode":"IT","latitude":"45.44146620","longitude":"12.31525950"},{"name":"FriuliâVenezia Giulia","isoCode":"36","countryCode":"IT","latitude":"46.22591770","longitude":"13.10336460"},{"name":"Liguria","isoCode":"42","countryCode":"IT","latitude":"44.31679170","longitude":"8.39649380"},{"name":"Emilia-Romagna","isoCode":"45","countryCode":"IT","latitude":"44.59676070","longitude":"11.21863960"},{"name":"Tuscany","isoCode":"52","countryCode":"IT","latitude":"43.77105130","longitude":"11.24862080"},{"name":"Umbria","isoCode":"55","countryCode":"IT","latitude":"42.93800400","longitude":"12.62162110"},{"name":"Marche","isoCode":"57","countryCode":"IT","latitude":"30.55670700","longitude":"-81.44930300"},{"name":"Lazio","isoCode":"62","countryCode":"IT","latitude":"45.69916670","longitude":"-73.65583330"},{"name":"Abruzzo","isoCode":"65","countryCode":"IT","latitude":"42.19201190","longitude":"13.72891670"},{"name":"Molise","isoCode":"67","countryCode":"IT","latitude":"41.67388650","longitude":"14.75209390"},{"name":"Campania","isoCode":"72","countryCode":"IT","latitude":"40.66708870","longitude":"15.10681130"},{"name":"Apulia","isoCode":"75","countryCode":"IT","latitude":"40.79283930","longitude":"17.10119310"},{"name":"Basilicata","isoCode":"77","countryCode":"IT","latitude":"40.64307660","longitude":"15.96998780"},{"name":"Calabria","isoCode":"78","countryCode":"IT","latitude":"39.30877140","longitude":"16.34637910"},{"name":"Sicily","isoCode":"82","countryCode":"IT","latitude":"37.59999380","longitude":"14.01535570"},{"name":"Sardinia","isoCode":"88","countryCode":"IT","latitude":"40.12087
1520","longitude":"9.01289260"},{"name":"Libero consorzio comunale di Agrigento","isoCode":"AG","countryCode":"IT","latitude":"37.31052020","longitude":"13.58579780"},{"name":"Province of Alessandria","isoCode":"AL","countryCode":"IT","latitude":"44.81755870","longitude":"8.70466270"},{"name":"Province of Ancona","isoCode":"AN","countryCode":"IT","latitude":"43.54932450","longitude":"13.26634790"},{"name":"Province of Ascoli Piceno","isoCode":"AP","countryCode":"IT","latitude":"42.86389330","longitude":"13.58997330"},{"name":"Province of L\'Aquila","isoCode":"AQ","countryCode":"IT","latitude":"42.12563170","longitude":"13.63627150"},{"name":"Province of Asti","isoCode":"AT","countryCode":"IT","latitude":"44.90076520","longitude":"8.20643150"},{"name":"Province of Avellino","isoCode":"AV","countryCode":"IT","latitude":"40.99645100","longitude":"15.12589550"},{"name":"Metropolitan City of Bari","isoCode":"BA","countryCode":"IT","latitude":"41.11714320","longitude":"16.87187150"},{"name":"Province of Bergamo","isoCode":"BG","countryCode":"IT","latitude":"45.69826420","longitude":"9.67726980"},{"name":"Province of Biella","isoCode":"BI","countryCode":"IT","latitude":"45.56281760","longitude":"8.05827170"},{"name":"Province of Belluno","isoCode":"BL","countryCode":"IT","latitude":"46.24976590","longitude":"12.19695650"},{"name":"Benevento Province","isoCode":"BN","countryCode":"IT","latitude":"41.20350930","longitude":"14.75209390"},{"name":"Metropolitan City of Bologna","isoCode":"BO","countryCode":"IT","latitude":"44.49488700","longitude":"11.34261620"},{"name":"Province of Brindisi","isoCode":"BR","countryCode":"IT","latitude":"40.61126630","longitude":"17.76362100"},{"name":"Province of Brescia","isoCode":"BS","countryCode":"IT","latitude":"45.54155260","longitude":"10.21180190"},{"name":"Province of Barletta-Andria-Trani","isoCode":"BT","countryCode":"IT","latitude":"41.20045430","longitude":"16.20514840"},{"name":"South Tyrol","isoCode":"BZ","countryCode":"IT","latitude":"46.49494500","longitude":"11.34026570"},{"name":"Metropolitan City of Cagliari","isoCode":"CA","countryCode":"IT","latitude":"39.22384110","longitude":"9.12166130"},{"name":"Province of Campobasso","isoCode":"CB","countryCode":"IT","latitude":"41.67388650","longitude":"14.75209390"},{"name":"Province of Caserta","isoCode":"CE","countryCode":"IT","latitude":"41.20783540","longitude":"14.10013260"},{"name":"Province of Chieti","isoCode":"CH","countryCode":"IT","latitude":"42.03344280","longitude":"14.37919120"},{"name":"Province of Carbonia-Iglesias","isoCode":"CI","countryCode":"IT","latitude":"39.25346590","longitude":"8.57210160"},{"name":"Libero consorzio comunale di Caltanissetta","isoCode":"CL","countryCode":"IT","latitude":"37.48601300","longitude":"14.06149820"},{"name":"Province of Cuneo","isoCode":"CN","countryCode":"IT","latitude":"44.59703140","longitude":"7.61142170"},{"name":"Province of Como","isoCode":"CO","countryCode":"IT","latitude":"45.80804160","longitude":"9.08517930"},{"name":"Province of Cremona","isoCode":"CR","countryCode":"IT","latitude":"45.20143750","longitude":"9.98365820"},{"name":"Province of Cosenza","isoCode":"CS","countryCode":"IT","latitude":"39.56441050","longitude":"16.25221430"},{"name":"Metropolitan City of Catania","isoCode":"CT","countryCode":"IT","latitude":"37.45154380","longitude":"15.05574150"},{"name":"Province of Catanzaro","isoCode":"CZ","countryCode":"IT","latitude":"38.88963480","longitude":"16.44058720"},{"name":"Libero consorzio comunale di Enna","isoCode":"EN","countryCode":"IT","latitude":"37.56762160","longitude":"14.27953490"},{"name":"Province of Forlì-Cesena","isoCode":"FC","countryCode":"IT","latitude":"43.99476810","longitude":"11.98046130"},{"name":"Province of Ferrara","isoCode":"FE","countryCode":"IT","latitude":"44.76636800","longitude":"11.76440680"},{"name":"Province of Foggia","isoCode":"FG","countryCode":"IT","latitude":"41.63844800","longitude":"15.59433880"},{"name":"Metropolitan City of Florence","isoCode":"FI","countryCode":"IT","latitude":"43.76791780","longitude":"11.25237920"},{"name":"Province of Fermo","isoCode":"FM","countryCode":"IT","latitude":"43.09313670","longitude":"13.58997330"},{"name":"Province of Frosinone","isoCode":"FR","countryCode":"IT","latitude":"41.65765280","longitude":"13.63627150"},{"name":"Metropolitan City of Genoa","isoCode":"GE","countryCode":"IT","latitude":"44.40564930","longitude":"8.94625640"},{"name":"Province of Gorizia","isoCode":"GO","countryCode":"IT","latitude":"45.90538990","longitude":"13.51637250"},{"name":"Province of Grosseto","isoCode":"GR","countryCode":"IT","latitude":"42.85180070","longitude":"11.25237920"},{"name":"Province of Imperia","isoCode":"IM","countryCode":"IT","latitude":"43.94186600","longitude":"7.82863680"},{"name":"Province of Isernia","isoCode":"IS","countryCode":"IT","latitude":"41.58915550","longitude":"14.19309180"},{"name":"Province of Crotone","isoCode":"KR","countryCode":"IT","latitude":"39.13098560","longitude":"17.00670310"},{"name":"Province of Lecco","isoCode":"LC","countryCode":"IT","latitude":"45.93829410","longitude":"9.38572900"},{"name":"Province of Lecce","isoCode":"LE","countryCode":"IT","latitude":"40.23473930","longitude":"18.14286690"},{"name":"Province of Livorno","isoCode":"LI","countryCode":"IT","latitude":"43.02398480","longitude":"10.66471010"},{"name":"Province of Lodi","isoCode":"LO","countryCode":"IT","latitude":"45.24050360","longitude":"9.52925120"},{"name":"Province of Latina","isoCode":"LT","countryCode":"IT","latitude":"41.40874760","longitude":"13.08179030"},{"name":"Province of Lucca","isoCode":"LU","countryCode":"IT","latitude":"43.83767360","longitude":"10.49505300"},{"name":"Province of Monza and Brianza","isoCode":"MB","countryCode":"IT","latitude":"45.62359900","longitude":"9.2588
10150"},{"name":"Province of Macerata","isoCode":"MC","countryCode":"IT","latitude":"43.24593220","longitude":"13.26634790"},{"name":"Metropolitan City of Messina","isoCode":"ME","countryCode":"IT","latitude":"38.19373350","longitude":"15.55420570"},{"name":"Metropolitan City of Milan","isoCode":"MI","countryCode":"IT","latitude":"45.45862600","longitude":"9.18187300"},{"name":"Province of Mantua","isoCode":"MN","countryCode":"IT","latitude":"45.16677280","longitude":"10.77536130"},{"name":"Province of Modena","isoCode":"MO","countryCode":"IT","latitude":"44.55137990","longitude":"10.91804800"},{"name":"Province of Massa and Carrara","isoCode":"MS","countryCode":"IT","latitude":"44.22139980","longitude":"10.03596610"},{"name":"Province of Matera","isoCode":"MT","countryCode":"IT","latitude":"40.66634960","longitude":"16.60436360"},{"name":"Metropolitan City of Naples","isoCode":"NA","countryCode":"IT","latitude":"40.90197500","longitude":"14.33264400"},{"name":"Province of Novara","isoCode":"NO","countryCode":"IT","latitude":"45.54851330","longitude":"8.51507930"},{"name":"Province of Nuoro","isoCode":"NU","countryCode":"IT","latitude":"40.32869040","longitude":"9.45615500"},{"name":"Province of Ogliastra","isoCode":"OG","countryCode":"IT","latitude":"39.84105360","longitude":"9.45615500"},{"name":"Province of Oristano","isoCode":"OR","countryCode":"IT","latitude":"40.05990680","longitude":"8.74811670"},{"name":"Province of Olbia-Tempio","isoCode":"OT","countryCode":"IT","latitude":"40.82683830","longitude":"9.27855830"},{"name":"Metropolitan City of Palermo","isoCode":"PA","countryCode":"IT","latitude":"38.11569000","longitude":"13.36148680"},{"name":"Province of Piacenza","isoCode":"PC","countryCode":"IT","latitude":"44.82631120","longitude":"9.52914470"},{"name":"Province of Padua","isoCode":"PD","countryCode":"IT","latitude":"45.36618640","longitude":"11.82091390"},{"name":"Province of Pescara","isoCode":"PE","countryCode":"IT","latitude":"42.35706550","longitude":"13.96080910"},{"name":"Province of Perugia","isoCode":"PG","countryCode":"IT","latitude":"42.93800400","longitude":"12.62162110"},{"name":"Province of Pisa","isoCode":"PI","countryCode":"IT","latitude":"43.72283150","longitude":"10.40171940"},{"name":"Province of Pordenone","isoCode":"PN","countryCode":"IT","latitude":"46.03788620","longitude":"12.71083500"},{"name":"Province of Prato","isoCode":"PO","countryCode":"IT","latitude":"44.04539000","longitude":"11.11644520"},{"name":"Province of Parma","isoCode":"PR","countryCode":"IT","latitude":"44.80153220","longitude":"10.32793540"},{"name":"Province of Pistoia","isoCode":"PT","countryCode":"IT","latitude":"43.95437330","longitude":"10.89030990"},{"name":"Pesaro and Urbino Province","isoCode":"PU","countryCode":"IT","latitude":"43.61301180","longitude":"12.71351210"},{"name":"Province of Pavia","isoCode":"PV","countryCode":"IT","latitude":"45.32181660","longitude":"8.84662360"},{"name":"Province of Potenza","isoCode":"PZ","countryCode":"IT","latitude":"40.41821940","longitude":"15.87600400"},{"name":"Province of Ravenna","isoCode":"RA","countryCode":"IT","latitude":"44.41844430","longitude":"12.20359980"},{"name":"Metropolitan City of Reggio Calabria","isoCode":"RC","countryCode":"IT","latitude":"38.10843960","longitude":"15.64370480"},{"name":"Province of Reggio Emilia","isoCode":"RE","countryCode":"IT","latitude":"44.58565800","longitude":"10.55647360"},{"name":"Libero consorzio comunale di Ragusa","isoCode":"RG","countryCode":"IT","latitude":"36.92692730","longitude":"14.72551290"},{"name":"Province of Rieti","isoCode":"RI","countryCode":"IT","latitude":"42.36744050","longitude":"12.89750980"},{"name":"Metropolitan City of Rome","isoCode":"RM","countryCode":"IT","latitude":"41.90270080","longitude":"12.49623520"},{"name":"Province of Rimini","isoCode":"RN","countryCode":"IT","latitude":"44.06782880","longitude":"12.56951580"},{"name":"Province of Rovigo","isoCode":"RO","countryCode":"IT","latitude":"45.02418180","longitude":"11.82381620"},{"name":"Province of Salerno","isoCode":"SA","countryCode":"IT","latitude":"40.42878320","longitude":"15.21948080"},{"name":"Province of Siena","isoCode":"SI","countryCode":"IT","latitude":"43.29377320","longitude":"11.43391480"},{"name":"Province of Sondrio","isoCode":"SO","countryCode":"IT","latitude":"46.17276360","longitude":"9.79949170"},{"name":"Province of La Spezia","isoCode":"SP","countryCode":"IT","latitude":"44.24479130","longitude":"9.76786870"},{"name":"Libero consorzio comunale di Siracusa","isoCode":"SR","countryCode":"IT","latitude":"37.06569240","longitude":"15.28571090"},{"name":"Province of Sassari","isoCode":"SS","countryCode":"IT","latitude":"40.79679070","longitude":"8.57504070"},{"name":"Province of Savona","isoCode":"SV","countryCode":"IT","latitude":"44.28879950","longitude":"8.26505800"},{"name":"Province of Taranto","isoCode":"TA","countryCode":"IT","latitude":"40.57409010","longitude":"17.24299760"},{"name":"Province of Teramo","isoCode":"TE","countryCode":"IT","latitude":"42.58956080","longitude":"13.63627150"},{"name":"Trentino","isoCode":"TN","countryCode":"IT","latitude":"46.05120040","longitude":"11.11753920"},{"name":"Metropolitan City of Turin","isoCode":"TO","countryCode":"IT","latitude":"45.06329900","longitude":"7.66928900"},{"name":"Libero consorzio comunale di Trapani","isoCode":"TP","countryCode":"IT","latitude":"38.01831160","longitude":"12.51482650"},{"name":"Province of Terni","isoCode":"TR","countryCode":"IT","latitude":"42.56345340","longitude":"12.52980280"},{"name":"Province of Trieste","isoCode":"TS","countryCode":"IT","latitude":"45.68948230","longitude":"13.78330720"},{"name":"Province of Treviso","isoCode":"TV","countryCode":"IT","latitude":"45.66685170","longitude":"12.24306170"},{"name":"Province of Udine","isoCode":"UD","countryCode":"IT","latitude":"46.14079720","longitude":"13.16628960"}
1,{"name":"Province of Varese","isoCode":"VA","countryCode":"IT","latitude":"45.79902600","longitude":"8.73009450"},{"name":"Province of Verbano-Cusio-Ossola","isoCode":"VB","countryCode":"IT","latitude":"46.13996880","longitude":"8.27246490"},{"name":"Province of Vercelli","isoCode":"VC","countryCode":"IT","latitude":"45.32022040","longitude":"8.41850800"},{"name":"Metropolitan City of Venice","isoCode":"VE","countryCode":"IT","latitude":"45.44146850","longitude":"12.31526720"},{"name":"Province of Vicenza","isoCode":"VI","countryCode":"IT","latitude":"45.69839950","longitude":"11.56614650"},{"name":"Province of Verona","isoCode":"VR","countryCode":"IT","latitude":"45.44184980","longitude":"11.07353160"},{"name":"Province of Medio Campidano","isoCode":"VS","countryCode":"IT","latitude":"39.53173890","longitude":"8.70407500"},{"name":"Province of Viterbo","isoCode":"VT","countryCode":"IT","latitude":"42.40024200","longitude":"11.88917210"},{"name":"Province of Vibo Valentia","isoCode":"VV","countryCode":"IT","latitude":"38.63785650","longitude":"16.20514840"},{"name":"Kingston Parish","isoCode":"01","countryCode":"JM","latitude":"17.96832710","longitude":"-76.78270200"},{"name":"Saint Andrew","isoCode":"02","countryCode":"JM","latitude":"37.22451030","longitude":"-95.70211890"},{"name":"Saint Thomas Parish","isoCode":"03","countryCode":"JM","latitude":"41.44253890","longitude":"-81.74022180"},{"name":"Portland Parish","isoCode":"04","countryCode":"JM","latitude":"18.08442740","longitude":"-76.41002670"},{"name":"Saint Mary Parish","isoCode":"05","countryCode":"JM","latitude":"36.09252200","longitude":"-95.97384400"},{"name":"Saint Ann Parish","isoCode":"06","countryCode":"JM","latitude":"37.28714520","longitude":"-77.41035330"},{"name":"Trelawny Parish","isoCode":"07","countryCode":"JM","latitude":"18.35261430","longitude":"-77.60778650"},{"name":"Saint James Parish","isoCode":"08","countryCode":"JM","latitude":"30.01792920","longitude":"-90.79132270"},{"name":"Hanover Parish","isoCode":"09","countryCode":"JM","latitude":"18.40977070","longitude":"-78.13363800"},{"name":"Westmoreland Parish","isoCode":"10","countryCode":"JM","latitude":"18.29443780","longitude":"-78.15644320"},{"name":"Saint Elizabeth Parish","isoCode":"11","countryCode":"JM","latitude":"38.99253080","longitude":"-94.58992000"},{"name":"Manchester Parish","isoCode":"12","countryCode":"JM","latitude":"18.06696540","longitude":"-77.51607880"},{"name":"Clarendon Parish","isoCode":"13","countryCode":"JM","latitude":"17.95571830","longitude":"-77.24051530"},{"name":"Saint Catherine Parish","isoCode":"14","countryCode":"JM","latitude":"18.03641340","longitude":"-77.05644640"},{"name":"Ajloun Governorate","isoCode":"AJ","countryCode":"JO","latitude":"32.33255840","longitude":"35.75168440"},{"name":"Amman Governorate","isoCode":"AM","countryCode":"JO","latitude":"31.94536330","longitude":"35.92838950"},{"name":"Aqaba Governorate","isoCode":"AQ","countryCode":"JO","latitude":"29.53208600","longitude":"35.00628210"},{"name":"Tafilah Governorate","isoCode":"AT","countryCode":"JO","latitude":"30.83380630","longitude":"35.61605130"},{"name":"Zarqa Governorate","isoCode":"AZ","countryCode":"JO","latitude":"32.06085050","longitude":"36.09421210"},{"name":"Balqa Governorate","isoCode":"BA","countryCode":"JO","latitude":"32.03668060","longitude":"35.72884800"},{"name":"Irbid Governorate","isoCode":"IR","countryCode":"JO","latitude":"32.55696360","longitude":"35.84789650"},{"name":"Jerash Governorate","isoCode":"JA","countryCode":"JO","latitude":"32.27472370","longitude":"35.89609540"},{"name":"Karak Governorate","isoCode":"KA","countryCode":"JO","latitude":"31.18535270","longitude":"35.70476820"},{"name":"Mafraq Governorate","isoCode":"MA","countryCode":"JO","latitude":"32.34169230","longitude":"36.20201750"},{"name":"Madaba Governorate","isoCode":"MD","countryCode":"JO","latitude":"31.71960970","longitude":"35.79327540"},{"name":"Ma\'an Governorate","isoCode":"MN","countryCode":"JO","latitude":"30.19267890","longitude":"35.72493190"},{"name":"HokkaidÅ Prefecture","isoCode":"01","countryCode":"JP","latitude":"43.22032660","longitude":"142.86347370"},{"name":"Aomori Prefecture","isoCode":"02","countryCode":"JP","latitude":"40.76570770","longitude":"140.91758790"}
1,{"name":"Iwate Prefecture","isoCode":"03","countryCode":"JP","latitude":"39.58329890","longitude":"141.25345740"},{"name":"Miyagi Prefecture","isoCode":"04","countryCode":"JP","latitude":"38.63061200","longitude":"141.11930480"},{"name":"Akita Prefecture","isoCode":"05","countryCode":"JP","latitude":"40.13762930","longitude":"140.33434100"},{"name":"Yamagata Prefecture","isoCode":"06","countryCode":"JP","latitude":"38.53705640","longitude":"140.14351980"},{"name":"Fukushima Prefecture","isoCode":"07","countryCode":"JP","latitude":"37.38343730","longitude":"140.18325160"},{"name":"Ibaraki Prefecture","isoCode":"08","countryCode":"JP","latitude":"36.21935710","longitude":"140.18325160"},{"name":"Tochigi Prefecture","isoCode":"09","countryCode":"JP","latitude":"36.67147390","longitude":"139.85472660"},{"name":"Gunma Prefecture","isoCode":"10","countryCode":"JP","latitude":"36.56053880","longitude":"138.87999720"},{"name":"Saitama Prefecture","isoCode":"11","countryCode":"JP","latitude":"35.99625130","longitude":"139.44660050"},{"name":"Chiba Prefecture","isoCode":"12","countryCode":"JP","latitude":"35.33541550","longitude":"140.18325160"},{"name":"Tokyo","isoCode":"13","countryCode":"JP","latitude":"35.67619190","longitude":"139.65031060"},{"name":"Kanagawa Prefecture","isoCode":"14","countryCode":"JP","latitude":"35.49135350","longitude":"139.28414300"},{"name":"Niigata Prefecture","isoCode":"15","countryCode":"JP","latitude":"37.51783860","longitude":"138.92697940"},{"name":"Toyama Prefecture","isoCode":"16","countryCode":"JP","latitude":"36.69582660","longitude":"137.21370710"},{"name":"Ishikawa Prefecture","isoCode":"17","countryCode":"JP","latitude":"36.32603170","longitude":"136.52896530"},{"name":"Fukui Prefecture","isoCode":"18","countryCode":"JP","latitude":"35.89622700","longitude":"136.21115790"},{"name":"Yamanashi Prefecture","isoCode":"19","countryCode":"JP","latitude":"35.66351130","longitude":"138.63888790"},{"name":"Nagano Prefecture","isoCode":"20","countryCode":"JP","latitude":"36.15439410","longitude":"137.92182040"},{"name":"Gifu Prefecture","isoCode":"21","countryCode":"JP","latitude":"35.74374910","longitude":"136.98051030"},{"name":"Shizuoka Prefecture","isoCode":"22","countryCode":"JP","latitude":"35.09293970","longitude":"138.31902760"},{"name":"Aichi Prefecture","isoCode":"23","countryCode":"JP","latitude":"35.01825050","longitude":"137.29238930"},{"name":"Mie Prefecture","isoCode":"24","countryCode":"JP","latitude":"33.81439010","longitude":"136.04870470"},{"name":"Shiga Prefecture","isoCode":"25","countryCode":"JP","latitude":"35.32920140","longitude":"136.05632120"},{"name":"KyÅto Prefecture","isoCode":"26","countryCode":"JP","latitude":"35.15666090","longitude":"135.52519820"},{"name":"Åsaka Prefecture","isoCode":"27","countryCode":"JP","latitude":"34.64133150","longitude":"135.56293940"},{"name":"HyÅgo Prefecture","isoCode":"28","countryCode":"JP","latitude":"34.85795180","longitude":"134.54537870"},{"name":"Nara Prefecture","isoCode":"29","countryCode":"JP","latitude":"34.29755280","longitude":"135.82797340"},{"name":"Wakayama Prefecture","isoCode":"30","countryCode":"JP","latitude":"33.94809140","longitude":"135.37453580"},{"name":"Tottori Prefecture","isoCode":"31","countryCode":"JP","latitude":"35.35731610","longitude":"133.40666180"},{"name":"Shimane Prefecture","isoCode":"32","countryCode":"JP","latitude":"35.12440940","longitude":"132.62934460"},{"name":"Okayama Prefecture","isoCode":"33","countryCode":"JP","latitude":"34.89634070","longitude":"133.63753140"},{"name":"Hiroshima Prefecture","isoCode":"34","countryCode":"JP","latitude":"34.88234080","longitude":"133.01948970"},{"name":"Yamaguchi Prefecture","isoCode":"35","countryCode":"JP","latitude":"34.27967690","longitude":"131.52127420"},{"name":"Tokushima Prefecture","isoCode":"36","countryCode":"JP","latitude":"33.94196550","longitude":"134.32365570"},{"name":"Kagawa Prefecture","isoCode":"37","countryCode":"JP","latitude":"34.22259150","longitude":"134.01991520"},{"name":"Ehime Prefecture","isoCode":"38","countryCode":"JP","latitude":"33.60253060","longitude":"132.78575830"},{"name":"KÅchi Prefecture","isoCode":"39","countryCode":"JP","latitude":"33.28791610","longitude":"132.27592620"},{"name":"Fukuoka Prefecture","isoCode":"40","countryCode":"JP","latitude":"33.56625590","longitude":"130.71585700"},{"name":"Saga Prefecture","isoCode":"41","countryCode":"JP","latitude":"33.30783710","longitude":"130.22712430"},{"name":"Nagasaki Prefecture","isoCode":"42","countryCode":"JP","latitude":"33.24885250","longitude":"129.69309120"},{"name":"Kumamoto Prefecture","isoCode":"43","countryCode":"JP","latitude":"32.85944270","longitude":"130.79691490"},{"name":"Åita Prefecture","isoCode":"44","countryCode":"JP","latitude":"33.15892990","longitude":"131.36111210"},{"name":"Miyazaki Prefecture","isoCode":"45","countryCode":"JP","latitude":"32.60360220","longitude":"131.44125100"},{"name":"Kagoshima Prefecture","isoCode":"46","countryCode":"JP","latitude":"31.39119580","longitude":"130.87785860"},{"name":"Okinawa Prefecture","isoCode":"47","countryCode":"JP","latitude":"26.12019110","longitude":"127.70250120"},{"name":"Baringo","isoCode":"01","countryCode":"KE","latitude":"0.85549880","longitude":"36.08934060"},{"name":"Bomet","isoCode":"02","countryCode":"KE","latitude":"-0.80150090","longitude":"35.30272260"},{"name":"Bungoma","isoCode":"03","countryCode":"KE","latitude":"0.56952520","longitude":"34.55837660"},{"name":"Busia","isoCode":"04","countryCode":"KE","latitude":"0.43465060","longitude":"34.24215970"},{"name":"Elgeyo-Marakwet","isoCode":"05","countryCode":"KE","latitude":"1.04982370","longitude":"35.47819260"},{"name":"Embu","isoCode":"06","countryCode":"KE","latitude":"-0.65604770","longitude":"37.72376780"},{"name":"Garissa","isoCode":"07","countryCode":"KE","latitude":"-0.45322930","longitude":"39.64609880"},{"name":"Homa Bay","isoCode":"08","countryCode":"KE","latitude":"-0.62206550","longitude":"34.33103640"},{"name":"Isiolo","isoCode":"09","countryCode":"KE","latitude":"0.35243520","longitude":"38.48499230"},{"name":"Kajiado","isoCode":"10","countryCode":"KE","latitude":"-2.09807510","longitude":"36.78195050"},{"name":"Kakamega","isoCode":"11","countryCode":"KE","latitude":"0.30789400","longitude":"34.77407930"},{"name":"Kericho","isoCode":"12","countryCode":"KE","latitude":"-0.18279130","longitude":"35.47819260"},{"name":"Kiambu","isoCode":"13","countryCode":"KE","latitude":"-1.03137010","longitude":"36.86807910"},{"name":"Kilifi","isoCode":"14","countryCode":"KE","latitude":"-3.51065080","longitude":"39.90932690"},{"name":"Kirinyaga","isoCode":"15","countryCode":"KE","latitude":"-0.65905650","longitude":"37.38272340"},{"name":"Kisii","isoCode":"16","countryCode":"KE","latitude":"-0.67733400","longitude":"34.77960300"},{"name":"Kisumu","isoCode":"17","countryCode":"KE","latitude":"-0.09170160","longitude":"34.76795680"},{"name":"Kitui","isoCode":"18","countryCode":"KE","latitude":"-1.68328220","longitude":"38.31657250"}
1,{"name":"Kwale","isoCode":"19","countryCode":"KE","latitude":"-4.18161150","longitude":"39.46056120"},{"name":"Laikipia","isoCode":"20","countryCode":"KE","latitude":"0.36060630","longitude":"36.78195050"},{"name":"Lamu","isoCode":"21","countryCode":"KE","latitude":"-2.23550580","longitude":"40.47200040"},{"name":"Machakos","isoCode":"22","countryCode":"KE","latitude":"-1.51768370","longitude":"37.26341460"},{"name":"Makueni","isoCode":"23","countryCode":"KE","latitude":"-2.25587340","longitude":"37.89366630"},{"name":"Mandera","isoCode":"24","countryCode":"KE","latitude":"3.57379910","longitude":"40.95868800"},{"name":"Marsabit","isoCode":"25","countryCode":"KE","latitude":"2.44264030","longitude":"37.97845850"},{"name":"Meru","isoCode":"26","countryCode":"KE","latitude":"0.35571740","longitude":"37.80876930"},{"name":"Migori","isoCode":"27","countryCode":"KE","latitude":"-0.93657020","longitude":"34.41982430"},{"name":"Mombasa","isoCode":"28","countryCode":"KE","latitude":"-3.97682910","longitude":"39.71371810"},{"name":"Murang\'a","isoCode":"29","countryCode":"KE","latitude":"-0.78392810","longitude":"37.04003390"},{"name":"Nairobi City","isoCode":"30","countryCode":"KE","latitude":"-1.29206590","longitude":"36.82194620"},{"name":"Nakuru","isoCode":"31","countryCode":"KE","latitude":"-0.30309880","longitude":"36.08002600"},{"name":"Nandi","isoCode":"32","countryCode":"KE","latitude":"0.18358670","longitude":"35.12687810"},{"name":"Narok","isoCode":"33","countryCode":"KE","latitude":"-1.10411100","longitude":"36.08934060"},{"name":"Nyamira","isoCode":"34","countryCode":"KE","latitude":"-0.56694050","longitude":"34.93412340"},{"name":"Nyandarua","isoCode":"35","countryCode":"KE","latitude":"-0.18038550","longitude":"36.52296410"},{"name":"Nyeri","isoCode":"36","countryCode":"KE","latitude":"-0.41969150","longitude":"37.04003390"},{"name":"Samburu","isoCode":"37","countryCode":"KE","latitude":"1.21545060","longitude":"36.95410700"},{"name":"Siaya","isoCode":"38","countryCode":"KE","latitude":"-0.06173280","longitude":"34.24215970"},{"name":"TaitaâTaveta","isoCode":"39","countryCode":"KE","latitude":"-3.31606870","longitude":"38.48499230"},{"name":"Tana River","isoCode":"40","countryCode":"KE","latitude":"-1.65184680","longitude":"39.65181650"},{"name":"Tharaka-Nithi","isoCode":"41","countryCode":"KE","latitude":"-0.29648510","longitude":"37.72376780"},{"name":"Trans Nzoia","isoCode":"42","countryCode":"KE","latitude":"1.05666670","longitude":"34.95066250"},{"name":"Turkana","isoCode":"43","countryCode":"KE","latitude":"3.31224770","longitude":"35.56578620"},{"name":"Uasin Gishu","isoCode":"44","countryCode":"KE","latitude":"0.55276380","longitude":"35.30272260"},{"name":"Vihiga","isoCode":"45","countryCode":"KE","latitude":"0.07675530","longitude":"34.70776650"},{"name":"Wajir","isoCode":"46","countryCode":"KE","latitude":"1.63604750","longitude":"40.30886260"},{"name":"West Pokot","isoCode":"47","countryCode":"KE","latitude":"1.62100760","longitude":"35.39050460"},{"name":"Batken Region","isoCode":"B","countryCode":"KG","latitude":"39.97214250","longitude":"69.85974060"},{"name":"Chuy Region","isoCode":"C","countryCode":"KG","latitude":"42.56550000","longitude":"74.40566120"},{"name":"Bishkek","isoCode":"GB","countryCode":"KG","latitude":"42.87462120","longitude":"74.56976170"},{"name":"Osh","isoCode":"GO","countryCode":"KG","latitude":"36.06313990","longitude":"-95.91828950"},{"name":"Jalal-Abad Region","isoCode":"J","countryCode":"KG","latitude":"41.10680800","longitude":"72.89880690"},{"name":"Naryn Region","isoCode":"N","countryCode":"KG","latitude":"41.29432270","longitude":"75.34121790"},{"name":"Osh Region","isoCode":"O","countryCode":"KG","latitude":"39.84073660","longitude":"72.89880690"},{"name":"Talas Region","isoCode":"T","countryCode":"KG","latitude":"42.28673390","longitude":"72.52048270"},{"name":"Issyk-Kul Region","isoCode":"Y","countryCode":"KG","latitude":"42.18594280","longitude":"77.56194190"},{"name":"Banteay Meanchey","isoCode":"1","countryCode":"KH","latitude":"13.75319140","longitude":"102.98961500"},{"name":"Kratie","isoCode":"10","countryCode":"KH","latitude":"12.50436080","longitude":"105.96998780"},{"name":"Mondulkiri","isoCode":"11","countryCode":"KH","latitude":"12.78794270","longitude":"107.10119310"},{"name":"Phnom Penh","isoCode":"12","countryCode":"KH","latitude":"11.55637380","longitude":"104.92820990"},{"name":"Preah Vihear","isoCode":"13","countryCode":"KH","latitude":"14.00857970","longitude":"104.84546190"},{"name":"Prey Veng","isoCode":"14","countryCode":"KH","latitude":"11.38024420","longitude":"105.50054830"},{"name":"Pursat","isoCode":"15","countryCode":"KH","latitude":"12.27209560","longitude":"103.72891670"},{"name":"Ratanakiri","isoCode":"16","countryCode":"KH","latitude":"13.85766070","longitude":"107.10119310"},{"name":"Siem Reap","isoCode":"17","countryCode":"KH","latitude":"13.33026600","longitude":"104.10013260"},{"name":"Sihanoukville","isoCode":"18","countryCode":"KH","latitude":"10.75818990","longitude":"103.82162610"},{"name":"Stung Treng","isoCode":"19","countryCode":"KH","latitude":"13.57647300","longitude":"105.96998780"},{"name":"Battambang","isoCode":"2","countryCode":"KH","latitude":"13.02869710","longitude":"102.98961500"},{"name":"Svay Rieng","isoCode":"20","countryCode":"KH","latitude":"11.14272200","longitude":"105.82902980"},{"name":"Takeo","isoCode":"21","countryCode":"KH","latitude":"10.93215190","longitude":"104.79877100"},{"name":"Oddar Meanchey","isoCode":"22","countryCode":"KH","latitude":"14.16097380","longitude":"103.82162610"},{"name":"Kep","isoCode":"23","countryCode":"KH","latitude":"10.53608900","longitude":"104.35591580"},{"name":"Pailin","isoCode":"24","countryCode":"KH","latitude":"12.90929620","longitude":"102.66755750"},{"name":"Kampong Cham","isoCode":"3","countryCode":"KH","latitude":"12.09829180","longitude":"105.31311850"},{"name":"Kampong Chhnang","isoCode":"4","countryCode":"KH","latitude":"12.13923520","longitude":"104.56552730"},{"name":"Kampong Speu","isoCode":"5","countryCode":"KH","latitude":"11.61551090","longitude":"104.37919120"},{"name":"Kampong Thom","isoCode":"6","countryCode":"KH","latitude":"12.81674850","longitude":"103.84131040"},{"name":"Kampot","isoCode":"7","countryCode":"KH","latitude":"10.73253510","longitude":"104.37919120"},{"name":"Kandal","isoCode":"8","countryCode":"KH","latitude":"11.22373830","longitude":"105.12589550"},{"name":"Koh Kong","isoCode":"9","countryCode":"KH","latitude":"11.57628040","longitude":"103.35872880"},{"name":"Tai Po District","isoCode":"NTP","countryCode":"KH","latitude":"22.45085000","longitude":"114.16422000"},{"name":"Gilbert Islands","isoCode":"G","countryCode":"KI","latitude":"0.35242620","longitude":"174.75526340"},{"name":"Line Islands","isoCode":"L","countryCode":"KI","latitude":"1.74294390","longitude":"-157.21328260"},{"name":"Phoenix Islands","isoCode":"P","countryCode":"KI","latitude":"33.32843690","longitude":"-111.98247740"},{"name":"Anjouan","isoCode":"A","countryCode":"KM","latitude":"-12.21381450","longitude":"44.43706060"},{"name":"Grande Comore","isoCode":"G","countryCode":"KM","latitude":"-11.71673380","longitude":"43.36807880"},{"name":"Mohéli","isoCode":"M","countryCode":"KM","latitude":"-12.33773760","longitude":"43.73340890"},{"name":"Christ Church Nichola Town Parish","isoCode":"01","countryCode":"KN","latitude":"17.36048120","longitude":"-62.76178370"},{"name":"Saint Anne Sandy Point Parish","isoCode":"02","countryCode":"KN","latitude":"17.37253330","longitude":"-62.84411330"},{"name":"Saint George Gingerland Parish","isoCode":"04","countryCode":"KN","latitude":"17.12577590","longitude":"-62.56198110"},{"name":"Saint James Windward Parish","isoCode":"05","countryCode":"KN","latitude":"17.17696330","longitude":"-62.57960260"},{"name":"Saint John Capisterre Parish","isoCode":"06","countryCode":"KN","latitude":"17.38103410","longitude":"-62.79118330"},{"name":"Saint John Figtree Parish","isoCode":"07","countryCode":"KN","latitude":"17.11557480","longitude":"-62.60310040"},{"name":"Saint Mary Cayon Parish","isoCode":"08","countryCode":"KN","latitude":"17.34620710","longitude":"-62.73826710"},{"name":"Saint Paul Capisterre Parish","isoCode":"09","countryCode":"KN","latitude":"17.40166830","longitude":"-62.82573320"},{"name":"Saint Paul Charlestown Parish","isoCode":"10","countryCode":"KN","latitude":"17.13462970","longitude":"-62.61338160"},{"name":"Saint Peter Basseterre Parish","isoCode":"11","countryCode":"KN","latitude":"17.31029110","longitude":"-62.71475330"},{"name":"Saint Thomas Lowland Parish","isoCode":"12","countryCode":"KN","latitude":"17.16505130","longitude":"-62.60897530"},{"name":"Saint Thomas Middle Island Parish","isoCode":"13","countryCode":"KN","latitude":"17.33488130","longitude":"-62.80882510"},{"name":"Trinity Palmetto Point Parish","isoCode":"15","countryCode":"KN","latitude":"17.30635190","longitude":"-62.76178370"},{"name":"Saint Kitts","isoCode":"K","countryCode":"KN","latitude":"17.34337960","longitude":"-62.75590430"},{"name":"Nevis","isoCode":"N","countryCode":"KN","latitude":"17.15535580","longitude":"-62.57960260"},{"name":"Pyongyang","isoCode":"01","countryCode":"KP","latitude":"39.03921930","longitude":"125.76252410"},{"name":"South Pyongan Province","isoCode":"02","countryCode":"KP","latitude":"39.35391780","longitude":"126.16827100"},{"name":"North Pyongan Province","isoCode":"03","countryCode":"KP","latitude":"39.92556180","longitude":"125.39280250"},{"name":"Chagang Province","isoCode":"04","countryCode":"KP","latitude":"40.72028090","longitude":"126.56211370"},{"name":"South Hwanghae Province","isoCode":"05","countryCode":"KP","latitude":"38.20072150","longitude":"125.47819260"},{"name":"North Hwanghae Province","isoCode":"06","countryCode":"KP","latitude":"38.37860850","longitude":"126.43643630"},{"name":"Kangwon Province","isoCode":"07","countryCode":"KP","latitude":"38.84323930","longitude":"127.55970670"},{"name":"South Hamgyong Province","isoCode":"08","countryCode":"KP","latitude":"40.37253390","longitude":"128.29888400"},{"name":"North Hamgyong Province","isoCode":"09","countryCode":"KP","latitude":"41.81487580","longitude":"129.45819550"},{"name":"Ryanggang Province","isoCode":"10","countryCode":"KP","latitude":"41.23189210","longitude":"128.50763590"},{"name":"Rason","isoCode":"13","countryCode":"KP","latitude":"42.25690630","longitude":"130.29771860"},{"name":"Seoul","isoCode":"11","countryCode":"KR","latitude":"37.56653500","longitude":"126.97796920"},{"name":"Busan","isoCode":"26","countryCode":"KR","latitude":"35.17955430","longitude":"129.07564160"}
1,{"name":"Daegu","isoCode":"27","countryCode":"KR","latitude":"35.87143540","longitude":"128.60144500"},{"name":"Incheon","isoCode":"28","countryCode":"KR","latitude":"37.45625570","longitude":"126.70520620"},{"name":"Gwangju","isoCode":"29","countryCode":"KR","latitude":"35.15954540","longitude":"126.85260120"},{"name":"Daejeon","isoCode":"30","countryCode":"KR","latitude":"36.35041190","longitude":"127.38454750"},{"name":"Ulsan","isoCode":"31","countryCode":"KR","latitude":"35.53837730","longitude":"129.31135960"},{"name":"Gyeonggi Province","isoCode":"41","countryCode":"KR","latitude":"37.41380000","longitude":"127.51830000"},{"name":"Gangwon Province","isoCode":"42","countryCode":"KR","latitude":"37.82280000","longitude":"128.15550000"},{"name":"North Chungcheong Province","isoCode":"43","countryCode":"KR","latitude":"36.80000000","longitude":"127.70000000"},{"name":"South Chungcheong Province","isoCode":"44","countryCode":"KR","latitude":"36.51840000","longitude":"126.80000000"},{"name":"North Jeolla Province","isoCode":"45","countryCode":"KR","latitude":"35.71750000","longitude":"127.15300000"},{"name":"South Jeolla Province","isoCode":"46","countryCode":"KR","latitude":"34.86790000","longitude":"126.99100000"},{"name":"North Gyeongsang Province","isoCode":"47","countryCode":"KR","latitude":"36.49190000","longitude":"128.88890000"},{"name":"South Gyeongsang Province","isoCode":"48","countryCode":"KR","latitude":"35.46060000","longitude":"128.21320000"},{"name":"Jeju","isoCode":"49","countryCode":"KR","latitude":"33.95682780","longitude":"-84.13135000"},{"name":"Sejong City","isoCode":"50","countryCode":"KR","latitude":"34.05233230","longitude":"-118.30848970"},{"name":"Al Ahmadi Governorate","isoCode":"AH","countryCode":"KW","latitude":"28.57451250","longitude":"48.10247430"},{"name":"Al Farwaniyah Governorate","isoCode":"FA","countryCode":"KW","latitude":"29.27335700","longitude":"47.94001540"},{"name":"Hawalli Governorate","isoCode":"HA","countryCode":"KW","latitude":"29.30567160","longitude":"48.03076130"},{"name":"Al Jahra Governorate","isoCode":"JA","countryCode":"KW","latitude":"29.99318310","longitude":"47.76347310"},{"name":"Capital Governorate","isoCode":"KU","countryCode":"KW","latitude":"26.22851610","longitude":"50.58604970"},{"name":"Mubarak Al-Kabeer Governorate","isoCode":"MU","countryCode":"KW","latitude":"29.21224000","longitude":"48.06051080"},{"name":"Akmola Region","isoCode":"AKM","countryCode":"KZ","latitude":"51.91653200","longitude":"69.41104940"},{"name":"Aktobe Region","isoCode":"AKT","countryCode":"KZ","latitude":"48.77970780","longitude":"57.99743780"},{"name":"Almaty","isoCode":"ALA","countryCode":"KZ","latitude":"43.22201460","longitude":"76.85124850"},{"name":"Almaty Region","isoCode":"ALM","countryCode":"KZ","latitude":"45.01192270","longitude":"78.42293920"},{"name":"Nur-Sultan","isoCode":"AST","countryCode":"KZ","latitude":"51.16052270","longitude":"71.47035580"},{"name":"Atyrau Region","isoCode":"ATY","countryCode":"KZ","latitude":"47.10761880","longitude":"51.91413300"},{"name":"Baikonur","isoCode":"BAY","countryCode":"KZ","latitude":"45.96458510","longitude":"63.30524280"},{"name":"Karaganda Region","isoCode":"KAR","countryCode":"KZ","latitude":"47.90221820","longitude":"71.77068070"},{"name":"Kostanay Region","isoCode":"KUS","countryCode":"KZ","latitude":"51.50770960","longitude":"64.04790730"},{"name":"Kyzylorda Region","isoCode":"KZY","countryCode":"KZ","latitude":"44.69226130","longitude":"62.65718850"},{"name":"Mangystau Region","isoCode":"MAN","countryCode":"KZ","latitude":"44.59080200","longitude":"53.84995080"},{"name":"Pavlodar Region","isoCode":"PAV","countryCode":"KZ","latitude":"52.28784440","longitude":"76.97334530"},{"name":"North Kazakhstan Region","isoCode":"SEV","countryCode":"KZ","latitude":"54.16220660","longitude":"69.93870710"},{"name":"East Kazakhstan Region","isoCode":"VOS","countryCode":"KZ","latitude":"48.70626870","longitude":"80.79225340"},{"name":"Turkestan Region","isoCode":"YUZ","countryCode":"KZ","latitude":"43.36669580","longitude":"68.40944050"},{"name":"West Kazakhstan Province","isoCode":"ZAP","countryCode":"KZ","latitude":"49.56797270","longitude":"50.80666160"},{"name":"Jambyl Region","isoCode":"ZHA","countryCode":"KZ","latitude":"44.22203080","longitude":"72.36579670"},{"name":"Attapeu Province","isoCode":"AT","countryCode":"LA","latitude":"14.93634000","longitude":"107.10119310"},{"name":"Bokeo Province","isoCode":"BK","countryCode":"LA","latitude":"20.28726620","longitude":"100.70978670"},{"name":"Bolikhamsai Province","isoCode":"BL","countryCode":"LA","latitude":"18.43629240","longitude":"104.47233010"},{"name":"Champasak Province","isoCode":"CH","countryCode":"LA","latitude":"14.65786640","longitude":"105.96998780"},{"name":"Houaphanh Province","isoCode":"HO","countryCode":"LA","latitude":"20.32541750","longitude":"104.10013260"},{"name":"Khammouane Province","isoCode":"KH","countryCode":"LA","latitude":"17.63840660","longitude":"105.21948080"},{"name":"Luang Namtha Province","isoCode":"LM","countryCode":"LA","latitude":"20.91701870","longitude":"101.16173560"},{"name":"Luang Prabang Province","isoCode":"LP","countryCode":"LA","latitude":"20.06562290","longitude":"102.62162110"},{"name":"Oudomxay Province","isoCode":"OU","countryCode":"LA","latitude":"20.49219290","longitude":"101.88917210"},{"name":"Phongsaly Province","isoCode":"PH","countryCode":"LA","latitude":"21.59193770","longitude":"102.25479190"},{"name":"Salavan Province","isoCode":"SL","countryCode":"LA","latitude":"15.81710730","longitude":"106.25221430"},{"name":"Savannakhet Province","isoCode":"SV","countryCode":"LA","latitude":"16.50653810","longitude":"105.59433880"}
1,{"name":"Vientiane Province","isoCode":"VI","countryCode":"LA","latitude":"18.57050630","longitude":"102.62162110"},{"name":"Vientiane Prefecture","isoCode":"VT","countryCode":"LA","latitude":"18.11054100","longitude":"102.52980280"},{"name":"Sainyabuli Province","isoCode":"XA","countryCode":"LA","latitude":"19.39078860","longitude":"101.52480550"},{"name":"Sekong Province","isoCode":"XE","countryCode":"LA","latitude":"15.57674460","longitude":"107.00670310"},{"name":"Xiangkhouang Province","isoCode":"XI","countryCode":"LA","latitude":"19.60930030","longitude":"103.72891670"},{"name":"Xaisomboun","isoCode":"XN","countryCode":"LA","latitude":null,"longitude":null},{"name":"Xaisomboun Province","isoCode":"XS","countryCode":"LA","latitude":"18.43629240","longitude":"104.47233010"},{"name":"Akkar Governorate","isoCode":"AK","countryCode":"LB","latitude":"34.53287630","longitude":"36.13281320"},{"name":"North Governorate","isoCode":"AS","countryCode":"LB","latitude":"34.43806250","longitude":"35.83082330"},{"name":"Beirut Governorate","isoCode":"BA","countryCode":"LB","latitude":"33.88861060","longitude":"35.49547720"},{"name":"Baalbek-Hermel Governorate","isoCode":"BH","countryCode":"LB","latitude":"34.26585560","longitude":"36.34980970"},{"name":"Beqaa Governorate","isoCode":"BI","countryCode":"LB","latitude":"33.84626620","longitude":"35.90194890"},{"name":"South Governorate","isoCode":"JA","countryCode":"LB","latitude":"33.27214790","longitude":"35.20327780"},{"name":"Mount Lebanon Governorate","isoCode":"JL","countryCode":"LB","latitude":"33.81008580","longitude":"35.59731390"},{"name":"Nabatieh Governorate","isoCode":"NA","countryCode":"LB","latitude":"33.37716930","longitude":"35.48382930"},{"name":"Anse la Raye Quarter","isoCode":"01","countryCode":"LC","latitude":"13.94594240","longitude":"-61.03694680"},{"name":"Castries Quarter","isoCode":"02","countryCode":"LC","latitude":"14.01010940","longitude":"-60.98746870"},{"name":"Choiseul Quarter","isoCode":"03","countryCode":"LC","latitude":"13.77501540","longitude":"-61.04859100"},{"name":"Dauphin Quarter","isoCode":"04","countryCode":"LC","latitude":"14.01033960","longitude":"-60.91909880"},{"name":"Dennery Quarter","isoCode":"05","countryCode":"LC","latitude":"13.92673930","longitude":"-60.91909880"},{"name":"Gros Islet Quarter","isoCode":"06","countryCode":"LC","latitude":"14.08435780","longitude":"-60.94527940"},{"name":"Laborie Quarter","isoCode":"07","countryCode":"LC","latitude":"13.75227830","longitude":"-60.99328890"},{"name":"Micoud Quarter","isoCode":"08","countryCode":"LC","latitude":"13.82118710","longitude":"-60.90019340"},{"name":"Praslin Quarter","isoCode":"09","countryCode":"LC","latitude":"13.87523920","longitude":"-60.89946630"},{"name":"Soufrière Quarter","isoCode":"10","countryCode":"LC","latitude":"13.85709860","longitude":"-61.05732480"},{"name":"Vieux Fort Quarter","isoCode":"11","countryCode":"LC","latitude":"13.72060800","longitude":"-60.94964330"},{"name":"Canaries","isoCode":"12","countryCode":"LC","latitude":"28.29156370","longitude":"-16.62913040"},{"name":"Balzers","isoCode":"01","countryCode":"LI","latitude":"42.05283570","longitude":"-88.03668480"},{"name":"Eschen","isoCode":"02","countryCode":"LI","latitude":"40.76695740","longitude":"-73.95228210"},{"name":"Gamprin","isoCode":"03","countryCode":"LI","latitude":"47.21324900","longitude":"9.50251950"},{"name":"Mauren","isoCode":"04","countryCode":"LI","latitude":"47.21892850","longitude":"9.54173500"},{"name":"Planken","isoCode":"05","countryCode":"LI","latitude":"40.66505760","longitude":"-73.50479800"},{"name":"Ruggell","isoCode":"06","countryCode":"LI","latitude":"47.25292220","longitude":"9.54021270"},{"name":"Schaan","isoCode":"07","countryCode":"LI","latitude":"47.12043400","longitude":"9.59416020"},{"name":"Schellenberg","isoCode":"08","countryCode":"LI","latitude":"47.23096600","longitude":"9.54678430"},{"name":"Triesen","isoCode":"09","countryCode":"LI","latitude":"47.10979880","longitude":"9.52482960"},{"name":"Triesenberg","isoCode":"10","countryCode":"LI","latitude":"47.12245110","longitude":"9.57019850"},{"name":"Vaduz","isoCode":"11","countryCode":"LI","latitude":"47.14103030","longitude":"9.52092770"},{"name":"Western Province","isoCode":"1","countryCode":"LK","latitude":null,"longitude":null},{"name":"Colombo District","isoCode":"11","countryCode":"LK","latitude":"6.92695570","longitude":"79.86173060"},{"name":"Gampaha District","isoCode":"12","countryCode":"LK","latitude":"7.07126190","longitude":"80.00877460"},{"name":"Kalutara District","isoCode":"13","countryCode":"LK","latitude":"6.60846860","longitude":"80.14285840"},{"name":"Central Province","isoCode":"2","countryCode":"LK","latitude":null,"longitude":null},{"name":"Kandy District","isoCode":"21","countryCode":"LK","latitude":"7.29315880","longitude":"80.63501070"},{"name":"Matale District","isoCode":"22","countryCode":"LK","latitude":"7.46596460","longitude":"80.62342590"},{"name":"Nuwara Eliya District","isoCode":"23","countryCode":"LK","latitude":"6.96065320","longitude":"80.76927580"},{"name":"Southern Province","isoCode":"3","countryCode":"LK","latitude":null,"longitude":null},{"name":"Galle District","isoCode":"31","countryCode":"LK","latitude":"6.05774900","longitude":"80.21755720"},{"name":"Matara District","isoCode":"32","countryCode":"LK","latitude":"5.94493480","longitude":"80.54879970"},{"name":"Hambantota District","isoCode":"33","countryCode":"LK","latitude":"6.15358160","longitude":"81.12714900"},{"name":"Northern Province","isoCode":"4","countryCode":"LK","latitude":null,"longitude":null},{"name":"Jaffna District","isoCode":"41","countryCode":"LK","latitude":"9.69304680","longitude":"80.16518540"},{"name":"Kilinochchi District","isoCode":"42","countryCode":"LK","latitude":"9.36779710","longitude":"80.32131060"},{"name":"Mannar District","isoCode":"43","countryCode":"LK","latitude":"8.98095310","longitude":"79.90439750"},{"name":"Vavuniya District","isoCode":"44","countryCode":"LK","latitude":"8.75947390","longitude":"80.50003340"},{"name":"Mullaitivu District","isoCode":"45","countryCode":"LK","latitude":"9.26753880","longitude":"80.81282540"},{"name":"Eastern Province","isoCode":"5","countryCode":"LK","latitude":null,"longitude":null},{"name":"Batticaloa District","isoCode":"51","countryCode":"LK","latitude":"7.82927810","longitude":"81.47183870"},{"name":"Ampara District","isoCode":"52","countryCode":"LK","latitude":"7.29116850","longitude":"81.67237610"},{"name":"Trincomalee District","isoCode":"53","countryCode":"LK","latitude":"8.60130690","longitude":"81.11960750"},{"name":"North Western Province","isoCode":"6","countryCode":"LK","latitude":"7.75840910","longitude":"80.187506
150"},{"name":"Puttalam District","isoCode":"62","countryCode":"LK","latitude":"8.02599150","longitude":"79.84712720"},{"name":"North Central Province","isoCode":"7","countryCode":"LK","latitude":"8.19956380","longitude":"80.63269160"},{"name":"Anuradhapura District","isoCode":"71","countryCode":"LK","latitude":"8.33183050","longitude":"80.40290170"},{"name":"Polonnaruwa District","isoCode":"72","countryCode":"LK","latitude":"7.93955670","longitude":"81.00034030"},{"name":"Uva Province","isoCode":"8","countryCode":"LK","latitude":"6.84276120","longitude":"81.33994140"},{"name":"Badulla District","isoCode":"81","countryCode":"LK","latitude":"6.99340090","longitude":"81.05498150"},{"name":"Monaragala District","isoCode":"82","countryCode":"LK","latitude":"6.87277810","longitude":"81.35068320"},{"name":"Sabaragamuwa Province","isoCode":"9","countryCode":"LK","latitude":"6.73959410","longitude":"80.36586500"},{"name":"Ratnapura district","isoCode":"91","countryCode":"LK","latitude":"6.70551680","longitude":"80.38483890"},{"name":"Kegalle District","isoCode":"92","countryCode":"LK","latitude":"7.12040530","longitude":"80.32131060"},{"name":"Bong County","isoCode":"BG","countryCode":"LR","latitude":"6.82950190","longitude":"-9.36730840"},{"name":"Bomi County","isoCode":"BM","countryCode":"LR","latitude":"6.75629260","longitude":"-10.84514670"},{"name":"Grand Cape Mount County","isoCode":"CM","countryCode":"LR","latitude":"7.04677580","longitude":"-11.07117580"},{"name":"Grand Bassa County","isoCode":"GB","countryCode":"LR","latitude":"6.23084520","longitude":"-9.81249350"},{"name":"Grand Gedeh County","isoCode":"GG","countryCode":"LR","latitude":"5.92220780","longitude":"-8.22129790"},{"name":"Grand Kru County","isoCode":"GK","countryCode":"LR","latitude":"4.76138620","longitude":"-8.22129790"},{"name":"Gbarpolu County","isoCode":"GP","countryCode":"LR","latitude":"7.49526370","longitude":"-10.08072980"},{"name":"Lofa County","isoCode":"LO","countryCode":"LR","latitude":"8.19111840","longitude":"-9.72326730"},{"name":"Margibi County","isoCode":"MG","countryCode":"LR","latitude":"6.51518750","longitude":"-10.30488970"},{"name":"Montserrado County","isoCode":"MO","countryCode":"LR","latitude":"6.55258150","longitude":"-10.52961150"},{"name":"Maryland County","isoCode":"MY","countryCode":"LR","latitude":"39.04575490","longitude":"-76.64127120"},{"name":"Nimba","isoCode":"NI","countryCode":"LR","latitude":"7.61666670","longitude":"-8.41666670"},{"name":"River Gee County","isoCode":"RG","countryCode":"LR","latitude":"5.26048940","longitude":"-7.87216000"},{"name":"River Cess County","isoCode":"RI","countryCode":"LR","latitude":"5.90253280","longitude":"-9.45615500"},{"name":"Sinoe County","isoCode":"SI","countryCode":"LR","latitude":"5.49871000","longitude":"-8.66005860"},{"name":"Maseru District","isoCode":"A","countryCode":"LS","latitude":"-29.51656500","longitude":"27.83114280"},{"name":"Butha-Buthe District","isoCode":"B","countryCode":"LS","latitude":"-28.76537540","longitude":"28.24681480"},{"name":"Leribe District","isoCode":"C","countryCode":"LS","latitude":"-28.86380650","longitude":"28.04788260"},{"name":"Berea District","isoCode":"D","countryCode":"LS","latitude":"41.36616140","longitude":"-81.85430260"},{"name":"Mafeteng District","isoCode":"E","countryCode":"LS","latitude":"-29.80410080","longitude":"27.50261740"},{"name":"Mohale\'s Hoek District","isoCode":"F","countryCode":"LS","latitude":"-30.14259170","longitude":"27.46738450"},{"name":"Quthing District","isoCode":"G","countryCode":"LS","latitude":"-30.40156870","longitude":"27.70801330"},{"name":"Qacha\'s Nek District","isoCode":"H","countryCode":"LS","latitude":"-30.11145650","longitude":"28.67897900"},{"name":"Mokhotlong District","isoCode":"J","countryCode":"LS","latitude":"-29.25731930","longitude":"28.95286450"},{"name":"Thaba-Tseka District","isoCode":"K","countryCode":"LS","latitude":"-29.52389750","longitude":"28.60897520"},{"name":"AkmenÄ District Municipality","isoCode":"01","countryCode":"LT","latitude":"56.24550290","longitude":"22.74711690"},{"name":"Alytus City Municipality","isoCode":"02","countryCode":"LT","latitude":"54.39629380","longitude":"24.04587610"},{"name":"Alytus District Municipality","isoCode":"03","countryCode":"LT","latitude":"54.32974960","longitude":"24.19609310"},{"name":"BirÅ¡tonas Municipality","isoCode":"05","countryCode":"LT","latitude":"54.56696640","longitude":"24.00930980"},{"name":"Biržai District Municipality","isoCode":"06","countryCode":"LT","latitude":"56.20177190","longitude":"24.75601180"},{"name":"Druskininkai municipality","isoCode":"07","countryCode":"LT","latitude":"53.99336850","longitude":"24.03424380"},{"name":"ElektrÄnai municipality","isoCode":"08","countryCode":"LT","latitude":"54.76539340","longitude":"24.77405830"},{"name":"Ignalina District Municipality","isoCode":"09","countryCode":"LT","latitude":"55.40903420","longitude":"26.32848930"},{"name":"Jonava District Municipality","isoCode":"10","countryCode":"LT","latitude":"55.07272420","longitude":"24.27933370"},{"name":"JoniÅ¡kis District Municipality","isoCode":"11","countryCode":"LT","latitude":"56.23607300","longitude":"23.61365790"},{"name":"Jurbarkas District Municipality","isoCode":"12","countryCode":"LT","latitude":"55.07740700","longitude":"22.74195690"},{"name":"KaiÅ¡iadorys District Municipality","isoCode":"13","countryCode":"LT","latitude":"54.85886690","longitude":"24.42779290"},{"name":"Kalvarija municipality","isoCode":"14","countryCode":"LT","latitude":"54.37616740","longitude":"23.19203210"},{"name":"Kaunas City Municipality","isoCode":"15","countryCode":"LT","latitude":"54.91453260","longitude":"23.90535180"},{"name":"Kaunas District Municipality","isoCode":"16","countryCode":"LT","latitude":"54.99362360","longitude":"23.63249410"},{"name":"Kazlų RÅ«da municipality","isoCode":"17","countryCode":"LT","latitude":"54.78075260","longitude":"23.48402430"},{"name":"KÄdainiai District Municipality","isoCode":"18","countryCode":"LT","latitude":"55.35609470","longitude":"23.98326830"},{"name":"KelmÄ District Municipality","isoCode":"19","countryCode":"LT","latitude":"55.62663520","longitude":"22.87817200"},{"name":"Klaipeda City Municipality","isoCode":"20","countryCode":"LT","latitude":"55.70329480","longitude":"21.14427950"},{"name":"KlaipÄda District Municipality","isoCode":"21","countryCode":"LT","latitude":"55.68416150","longitude":"21.44164640"},{"name":"Kretinga District Municipality","isoCode":"22","countryCode":"LT","latitude":"55.88384200","longitude":"21.23509190"},{"name":"KupiÅ¡kis District Municipality","isoCode":"23","countryCode":"LT","latitude":"55.84287410","longitude":"25.02958160"},{"name":"Lazdijai District Municipality","isoCode":"24","countryCode":"LT","latitude":"54.23432670","longitude":"23.51565050"}
1,{"name":"MarijampolÄ Municipality","isoCode":"25","countryCode":"LT","latitude":"54.57110940","longitude":"23.48593710"},{"name":"Mažeikiai District Municipality","isoCode":"26","countryCode":"LT","latitude":"56.30924390","longitude":"22.34146800"},{"name":"MolÄtai District Municipality","isoCode":"27","countryCode":"LT","latitude":"55.22653090","longitude":"25.41800110"},{"name":"Neringa Municipality","isoCode":"28","countryCode":"LT","latitude":"55.45724030","longitude":"21.08390050"},{"name":"PagÄgiai municipality","isoCode":"29","countryCode":"LT","latitude":"55.17213200","longitude":"21.96836140"},{"name":"Pakruojis District Municipality","isoCode":"30","countryCode":"LT","latitude":"56.07326050","longitude":"23.93899060"},{"name":"Palanga City Municipality","isoCode":"31","countryCode":"LT","latitude":"55.92019800","longitude":"21.06776140"},{"name":"PanevÄžys City Municipality","isoCode":"32","countryCode":"LT","latitude":"55.73479150","longitude":"24.35747740"},{"name":"PanevÄžys District Municipality","isoCode":"33","countryCode":"LT","latitude":"55.61667280","longitude":"24.31422830"},{"name":"Pasvalys District Municipality","isoCode":"34","countryCode":"LT","latitude":"56.06046190","longitude":"24.39629100"},{"name":"PlungÄ District Municipality","isoCode":"35","countryCode":"LT","latitude":"55.91078400","longitude":"21.84540690"},{"name":"Prienai District Municipality","isoCode":"36","countryCode":"LT","latitude":"54.63835800","longitude":"23.94680090"},{"name":"RadviliÅ¡kis District Municipality","isoCode":"37","countryCode":"LT","latitude":"55.81083990","longitude":"23.54648700"},{"name":"Raseiniai District Municipality","isoCode":"38","countryCode":"LT","latitude":"55.38194990","longitude":"23.11561290"},{"name":"Rietavas municipality","isoCode":"39","countryCode":"LT","latitude":"55.70217190","longitude":"21.99865640"},{"name":"RokiÅ¡kis District Municipality","isoCode":"40","countryCode":"LT","latitude":"55.95550390","longitude":"25.58592490"},{"name":"Å akiai District Municipality","isoCode":"41","countryCode":"LT","latitude":"54.95267100","longitude":"23.04801990"},{"name":"Å alÄininkai District Municipality","isoCode":"42","countryCode":"LT","latitude":"54.30976700","longitude":"25.38756400"},{"name":"Å iauliai City Municipality","isoCode":"43","countryCode":"LT","latitude":"55.93490850","longitude":"23.31368230"},{"name":"Å iauliai District Municipality","isoCode":"44","countryCode":"LT","latitude":"55.97214560","longitude":"23.03323710"},{"name":"Å ilalÄ District Municipality","isoCode":"45","countryCode":"LT","latitude":"55.49268000","longitude":"22.18455590"},{"name":"Å ilutÄ District Municipality","isoCode":"46","countryCode":"LT","latitude":"55.35041400","longitude":"21.46598590"},{"name":"Å irvintos District Municipality","isoCode":"47","countryCode":"LT","latitude":"55.04310200","longitude":"24.95698100"},{"name":"Skuodas District Municipality","isoCode":"48","countryCode":"LT","latitude":"56.27021690","longitude":"21.52143310"},{"name":"Å venÄionys District Municipality","isoCode":"49","countryCode":"LT","latitude":"55.10280980","longitude":"26.00718550"},{"name":"TauragÄ District Municipality","isoCode":"50","countryCode":"LT","latitude":"55.25036600","longitude":"22.29095000"},{"name":"TelÅ¡iai District Municipality","isoCode":"51","countryCode":"LT","latitude":"55.91752150","longitude":"22.34518400"},{"name":"Trakai District Municipality","isoCode":"52","countryCode":"LT","latitude":"54.63791130","longitude":"24.93468940"},{"name":"UkmergÄ District Municipality","isoCode":"53","countryCode":"LT","latitude":"55.24526500","longitude":"24.77607490"},{"name":"Utena District Municipality","isoCode":"54","countryCode":"LT","latitude":"55.50846140","longitude":"25.68326420"},{"name":"VarÄna District Municipality","isoCode":"55","countryCode":"LT","latitude":"54.22033300","longitude":"24.57899700"},{"name":"VilkaviÅ¡kis District Municipality","isoCode":"56","countryCode":"LT","latitude":"54.65194500","longitude":"23.03515500"},{"name":"Vilnius City Municipality","isoCode":"57","countryCode":"LT","latitude":"54.67107610","longitude":"25.28787210"},{"name":"Vilnius District Municipality","isoCode":"58","countryCode":"LT","latitude":"54.77325780","longitude":"25.58671130"},{"name":"Visaginas Municipality","isoCode":"59","countryCode":"LT","latitude":"55.59411800","longitude":"26.43079540"},{"name":"Zarasai District Municipality","isoCode":"60","countryCode":"LT","latitude":"55.73096090","longitude":"26.24529500"},{"name":"Alytus County","isoCode":"AL","countryCode":"LT","latitude":"54.20002140","longitude":"24.15126340"},{"name":"KlaipÄda County","isoCode":"KL","countryCode":"LT","latitude":"55.65197440","longitude":"21.37439560"},{"name":"Kaunas County","isoCode":"KU","countryCode":"LT","latitude":"54.98728630","longitude":"23.95257360"},{"name":"MarijampolÄ County","isoCode":"MR","countryCode":"LT","latitude":"54.78199710","longitude":"23.13413650"},{"name":"PanevÄžys County","isoCode":"PN","countryCode":"LT","latitude":"55.97480490","longitude":"25.07947670"},{"name":"Å iauliai County","isoCode":"SA","countryCode":"LT","latitude":"55.99857510","longitude":"23.13800510"},{"name":"TauragÄ County","isoCode":"TA","countryCode":"LT","latitude":"55.30725860","longitude":"22.35729390"},{"name":"TelÅ¡iai County","isoCode":"TE","countryCode":"LT","latitude":"56.10266160","longitude":"22.11139150"},{"name":"Utena County","isoCode":"UT","countryCode":"LT","latitude":"55.53189690","longitude":"25.79046990"}
1,{"name":"Vilnius County","isoCode":"VL","countryCode":"LT","latitude":"54.80865020","longitude":"25.21821390"},{"name":"Canton of Capellen","isoCode":"CA","countryCode":"LU","latitude":"49.64039310","longitude":"5.95538460"},{"name":"Canton of Clervaux","isoCode":"CL","countryCode":"LU","latitude":"50.05463130","longitude":"6.02858750"},{"name":"Diekirch District","isoCode":"D","countryCode":"LU","latitude":"49.86717200","longitude":"6.15963620"},{"name":"Canton of Diekirch","isoCode":"DI","countryCode":"LU","latitude":"49.86717840","longitude":"6.15956330"},{"name":"Canton of Echternach","isoCode":"EC","countryCode":"LU","latitude":"49.81141330","longitude":"6.41756350"},{"name":"Canton of Esch-sur-Alzette","isoCode":"ES","countryCode":"LU","latitude":"49.50088050","longitude":"5.98609250"},{"name":"Grevenmacher District","isoCode":"G","countryCode":"LU","latitude":"49.68085100","longitude":"6.44075240"},{"name":"Canton of Grevenmacher","isoCode":"GR","countryCode":"LU","latitude":"49.68084100","longitude":"6.44075930"},{"name":"Luxembourg District","isoCode":"L","countryCode":"LU","latitude":"49.59537060","longitude":"6.13331780"},{"name":"Canton of Luxembourg","isoCode":"LU","countryCode":"LU","latitude":"49.63010250","longitude":"6.15201850"},{"name":"Canton of Mersch","isoCode":"ME","countryCode":"LU","latitude":"49.75429060","longitude":"6.12921850"},{"name":"Canton of Redange","isoCode":"RD","countryCode":"LU","latitude":"49.76455000","longitude":"5.88948000"},{"name":"Canton of Remich","isoCode":"RM","countryCode":"LU","latitude":"49.54501700","longitude":"6.36742220"},{"name":"Canton of Vianden","isoCode":"VD","countryCode":"LU","latitude":"49.93419240","longitude":"6.20199170"},{"name":"Canton of Wiltz","isoCode":"WI","countryCode":"LU","latitude":"49.96622000","longitude":"5.93243060"},{"name":"Aglona Municipality","isoCode":"001","countryCode":"LV","latitude":"56.10890060","longitude":"27.12862270"},{"name":"Aizkraukle Municipality","isoCode":"002","countryCode":"LV","latitude":"56.64610800","longitude":"25.23708540"},{"name":"Aizpute Municipality","isoCode":"003","countryCode":"LV","latitude":"56.71825960","longitude":"21.60727590"},{"name":"AknÄ«ste Municipality","isoCode":"004","countryCode":"LV","latitude":"56.16130370","longitude":"25.74848270"},{"name":"Aloja Municipality","isoCode":"005","countryCode":"LV","latitude":"57.76713600","longitude":"24.87708390"},{"name":"Alsunga Municipality","isoCode":"006","countryCode":"LV","latitude":"56.98285310","longitude":"21.55559190"},{"name":"AlÅ«ksne Municipality","isoCode":"007","countryCode":"LV","latitude":"57.42544850","longitude":"27.04249680"},{"name":"Amata Municipality","isoCode":"008","countryCode":"LV","latitude":"56.99387260","longitude":"25.26276750"},{"name":"Ape Municipality","isoCode":"009","countryCode":"LV","latitude":"57.53926970","longitude":"26.69416490"},{"name":"Auce Municipality","isoCode":"010","countryCode":"LV","latitude":"56.46016800","longitude":"22.90547810"},{"name":"BabÄ«te Municipality","isoCode":"012","countryCode":"LV","latitude":"56.95415500","longitude":"23.94539900"},{"name":"Baldone Municipality","isoCode":"013","countryCode":"LV","latitude":"56.74246000","longitude":"24.39115440"},{"name":"Baltinava Municipality","isoCode":"014","countryCode":"LV","latitude":"56.94584680","longitude":"27.64410660"},{"name":"Balvi Municipality","isoCode":"015","countryCode":"LV","latitude":"57.13262400","longitude":"27.26466850"},{"name":"Bauska Municipality","isoCode":"016","countryCode":"LV","latitude":"56.41018680","longitude":"24.20006890"},{"name":"BeverÄ«na Municipality","isoCode":"017","countryCode":"LV","latitude":"57.51971090","longitude":"25.60736540"},{"name":"BrocÄni Municipality","isoCode":"018","countryCode":"LV","latitude":"56.73475410","longitude":"22.63573710"},{"name":"Burtnieki Municipality","isoCode":"019","countryCode":"LV","latitude":"57.69490040","longitude":"25.27647770"},{"name":"Carnikava Municipality","isoCode":"020","countryCode":"LV","latitude":"57.10241210","longitude":"24.21086620"},{"name":"Cesvaine Municipality","isoCode":"021","countryCode":"LV","latitude":"56.96792640","longitude":"26.30831720"},{"name":"CÄsis Municipality","isoCode":"022","countryCode":"LV","latitude":"57.31028970","longitude":"25.26761250"},{"name":"Cibla Municipality","isoCode":"023","countryCode":"LV","latitude":"56.61023440","longitude":"27.86965980"},{"name":"Dagda Municipality","isoCode":"024","countryCode":"LV","latitude":"56.09560890","longitude":"27.53245900"},{"name":"Daugavpils Municipality","isoCode":"025","countryCode":"LV","latitude":"55.89917830","longitude":"26.61020120"},{"name":"Dobele Municipality","isoCode":"026","countryCode":"LV","latitude":"56.62630500","longitude":"23.28090660"},{"name":"Dundaga Municipality","isoCode":"027","countryCode":"LV","latitude":"57.50491670","longitude":"22.35051140"},{"name":"Durbe Municipality","isoCode":"028","countryCode":"LV","latitude":"56.62798570","longitude":"21.49162450"},{"name":"Engure Municipality","isoCode":"029","countryCode":"LV","latitude":"57.16235000","longitude":"23.21966340"},{"name":"Ärgļi Municipality","isoCode":"030","countryCode":"LV","latitude":"56.92370650","longitude":"25.67538520"},{"name":"Garkalne Municipality","isoCode":"031","countryCode":"LV","latitude":"57.01903870","longitude":"24.38261810"},{"name":"GrobiÅa Municipality","isoCode":"032","countryCode":"LV","latitude":"56.53963200","longitude":"21.16689200"}
1,{"name":"Gulbene Municipality","isoCode":"033","countryCode":"LV","latitude":"57.21556450","longitude":"26.64529550"},{"name":"Iecava Municipality","isoCode":"034","countryCode":"LV","latitude":"56.59867930","longitude":"24.19962720"},{"name":"Ikšķile Municipality","isoCode":"035","countryCode":"LV","latitude":"56.83736670","longitude":"24.49747450"},{"name":"IlÅ«kste Municipality","isoCode":"036","countryCode":"LV","latitude":"55.97825470","longitude":"26.29650880"},{"name":"InÄukalns Municipality","isoCode":"037","countryCode":"LV","latitude":"57.09943420","longitude":"24.68555700"},{"name":"Jaunjelgava Municipality","isoCode":"038","countryCode":"LV","latitude":"56.52836590","longitude":"25.39214430"},{"name":"Jaunpiebalga Municipality","isoCode":"039","countryCode":"LV","latitude":"57.14334710","longitude":"25.99518880"},{"name":"Jaunpils Municipality","isoCode":"040","countryCode":"LV","latitude":"56.73141940","longitude":"23.01256160"},{"name":"Jelgava Municipality","isoCode":"041","countryCode":"LV","latitude":"56.58956890","longitude":"23.66104810"},{"name":"JÄkabpils Municipality","isoCode":"042","countryCode":"LV","latitude":"56.29193200","longitude":"25.98120170"},{"name":"Kandava Municipality","isoCode":"043","countryCode":"LV","latitude":"57.03406730","longitude":"22.78018130"},{"name":"KÄrsava Municipality","isoCode":"044","countryCode":"LV","latitude":"56.76458420","longitude":"27.73582950"},{"name":"KocÄni Municipality","isoCode":"045","countryCode":"LV","latitude":"57.52262920","longitude":"25.33495070"},{"name":"Koknese Municipality","isoCode":"046","countryCode":"LV","latitude":"56.72055600","longitude":"25.48939090"},{"name":"KrÄslava Municipality","isoCode":"047","countryCode":"LV","latitude":"55.89514640","longitude":"27.18145770"},{"name":"Krimulda Municipality","isoCode":"048","countryCode":"LV","latitude":"57.17912730","longitude":"24.71401270"},{"name":"Krustpils Municipality","isoCode":"049","countryCode":"LV","latitude":"56.54155780","longitude":"26.24463970"},{"name":"KuldÄ«ga Municipality","isoCode":"050","countryCode":"LV","latitude":"56.96872570","longitude":"21.96137390"},{"name":"Ķegums Municipality","isoCode":"051","countryCode":"LV","latitude":"56.74753570","longitude":"24.71736450"},{"name":"Ķekava Municipality","isoCode":"052","countryCode":"LV","latitude":"56.80643510","longitude":"24.19394930"},{"name":"LielvÄrde Municipality","isoCode":"053","countryCode":"LV","latitude":"56.73929760","longitude":"24.97116180"},{"name":"Limbaži Municipality","isoCode":"054","countryCode":"LV","latitude":"57.54032270","longitude":"24.71344510"},{"name":"LÄ«gatne Municipality","isoCode":"055","countryCode":"LV","latitude":"57.19442040","longitude":"25.09406810"},{"name":"LÄ«vÄni Municipality","isoCode":"056","countryCode":"LV","latitude":"56.35509420","longitude":"26.17251900"},{"name":"LubÄna Municipality","isoCode":"057","countryCode":"LV","latitude":"56.89992690","longitude":"26.71987890"},{"name":"Ludza Municipality","isoCode":"058","countryCode":"LV","latitude":"56.54595900","longitude":"27.71431990"},{"name":"Madona Municipality","isoCode":"059","countryCode":"LV","latitude":"56.85989230","longitude":"26.22762010"},{"name":"Mazsalaca Municipality","isoCode":"060","countryCode":"LV","latitude":"57.92677490","longitude":"25.06698950"},{"name":"MÄlpils Municipality","isoCode":"061","countryCode":"LV","latitude":"57.00841190","longitude":"24.95742780"},{"name":"MÄrupe Municipality","isoCode":"062","countryCode":"LV","latitude":"56.89657170","longitude":"24.04600490"},{"name":"MÄrsrags Municipality","isoCode":"063","countryCode":"LV","latitude":"57.33068810","longitude":"23.10237070"},{"name":"NaukÅ¡Äni Municipality","isoCode":"064","countryCode":"LV","latitude":"57.92953610","longitude":"25.51192660"},{"name":"Nereta Municipality","isoCode":"065","countryCode":"LV","latitude":"56.19866550","longitude":"25.32529690"},{"name":"NÄ«ca Municipality","isoCode":"066","countryCode":"LV","latitude":"56.34649830","longitude":"21.06549300"},{"name":"Ogre Municipality","isoCode":"067","countryCode":"LV","latitude":"56.81473550","longitude":"24.60445550"},{"name":"Olaine Municipality","isoCode":"068","countryCode":"LV","latitude":"56.79523530","longitude":"24.01535890"},{"name":"Ozolnieki Municipality","isoCode":"069","countryCode":"LV","latitude":"56.67563050","longitude":"23.89948160"},{"name":"PÄrgauja Municipality","isoCode":"070","countryCode":"LV","latitude":"57.36481220","longitude":"24.98220450"},{"name":"PÄvilosta Municipality","isoCode":"071","countryCode":"LV","latitude":"56.88654240","longitude":"21.19468490"},{"name":"PļaviÅas Municipality","isoCode":"072","countryCode":"LV","latitude":"56.61773130","longitude":"25.71940430"},{"name":"Preiļi Municipality","isoCode":"073","countryCode":"LV","latitude":"56.15111570","longitude":"26.74397670"},{"name":"Priekule Municipality","isoCode":"074","countryCode":"LV","latitude":"56.41794130","longitude":"21.55033360"},{"name":"Priekuļi Municipality","isoCode":"075","countryCode":"LV","latitude":"57.36171380","longitude":"25.44104230"},{"name":"Rauna Municipality","isoCode":"076","countryCode":"LV","latitude":"57.33169300","longitude":"25.61003390"},{"name":"RÄzekne Municipality","isoCode":"077","countryCode":"LV","latitude":"56.32736380","longitude":"27.32843310"},{"name":"RiebiÅi Municipality","isoCode":"078","countryCode":"LV","latitude":"56.34361900","longitude":"26.80181380"},{"name":"Roja Municipality","isoCode":"079","countryCode":"LV","latitude":"57.50467130","longitude":"22.80121640"},{"name":"Ropaži Municipality","isoCode":"080","countryCode":"LV","latitude":"56.96157860","longitude":"24.60104760"},{"name":"Rucava Municipality","isoCode":"081","countryCode":"LV","latitude":"56.15931240","longitude":"21.16181210"},{"name":"RugÄji Municipality","isoCode":"082","countryCode":"LV","latitude":"57.00560230","longitude":"27.13172030"},{"name":"RundÄle Municipality","isoCode":"083","countryCode":"LV","latitude":"56.40972100","longitude":"24.01241390"},{"name":"RÅ«jiena Municipality","isoCode":"084","countryCode":"LV","latitude":"57.89372910","longitude":"25.33910080"},{"name":"Sala Municipality","isoCode":"085","countryCode":"LV","latitude":"59.96796130","longitude":"16.49782170"},{"name":"SalacgrÄ«va Municipality","isoCode":"086","countryCode":"LV","latitude":"57.75808830","longitude":"24.35431810"},{"name":"Salaspils Municipality","isoCode":"087","countryCode":"LV","latitude":"56.86081520","longitude":"24.34978810"},{"name":"Saldus Municipality","isoCode":"088","countryCode":"LV","latitude":"56.66650880","longitude":"22.49354930"},{"name":"Saulkrasti Municipality","isoCode":"089","countryCode":"LV","latitude":"57.25794180","longitude":"24.41831460"},{"name":"SÄja Municipality","isoCode":"090","countryCode":"LV","latitude":"57.20069950","longitude":"24.59228210"},{"name":"Sigulda Municipality","isoCode":"091","countryCode":"LV","latitude":"57.10550920","longitude":"24.83142590"},{"name":"SkrÄ«veri Municipality","isoCode":"092","countryCode":"LV","latitude":"56.67613910","longitude":"25.09788490"},{"name":"Skrunda Municipality","isoCode":"093","countryCode":"LV","latitude":"56.66434580","longitude":"22.00457290"},{"name":"Smiltene Municipality","isoCode":"094","countryCode":"LV","latitude":"57.42303320","longitude":"25.90027800"},{"name":"StopiÅi Municipality","isoCode":"095","countryCode":"LV","latitude":"56.93644900","longitude":"24.28729490"},{"name":"StrenÄi Municipality","isoCode":"096","countryCode":"LV","latitude":"57.62254710","longitude":"25.80480860"},{"name":"Talsi Municipality","isoCode":"097","countryCode":"LV","latitude":"57.34152080","longitude":"22.57131250"},{"name":"TÄrvete Municipality","isoCode":"098","countryCode":"LV","latitude":"56.41192010","longitude":"23.31883320"},{"name":"Tukums Municipality","isoCode":"099","countryCode":"LV","latitude":"56.96728680","longitude":"23.15243790"},{"name":"VaiÅode Municipality","isoCode":"100","countryCode":"LV","latitude":"56.41542710","longitude":"21.85139840"},{"name":"Valka Municipality","isoCode":"101","countryCode":"LV","latitude":"57.77439000","longitude":"26.01700500"},{"name":"VarakļÄni Municipality","isoCode":"102","countryCode":"LV","latitude":"56.66880060","longitude":"26.56364140"},{"name":"VÄrkava Municipality","isoCode":"103","countryCode":"LV","latitude":"56.24657440","longitude":"26.56643710"},{"name":"Vecpiebalga Municipality","isoCode":"104","countryCode":"LV","latitude":"57.06033560","longitude":"25.81615920"},{"name":"Vecumnieki Municipality","isoCode":"105","countryCode":"LV","latitude":"56.60623370","longitude":"24.52218910"},{"name":"Ventspils Municipality","isoCode":"106","countryCode":"LV","latitude":"57.28336820","longitude":"21.85875580"},{"name":"ViesÄ«te Municipality","isoCode":"107","countryCode":"LV","latitude":"56.31130850","longitude":"25.50704640"},{"name":"Viļaka Municipality","isoCode":"108","countryCode":"LV","latitude":"57.17222630","longitude":"27.66731880"},{"name":"ViļÄni Municipality","isoCode":"109","countryCode":"LV","latitude":"56.54561710","longitude":"26.91679270"},{"name":"Zilupe Municipality","isoCode":"110","countryCode":"LV","latitude":"56.30189850","longitude":"28.13395900"},{"name":"Daugavpils","isoCode":"DGV","countryCode":"LV","latitude":"55.87473600","longitude":"26.53617900"},{"name":"Jelgava","isoCode":"JEL","countryCode":"LV","latitude":"56.65110910","longitude":"23.72135410"},{"name":"JÄkabpils","isoCode":"JKB","countryCode":"LV","latitude":"56.50145500","longitude":"25.87829900"},{"name":"JÅ«rmala","isoCode":"JUR","countryCode":"LV","latitude":"56.94707900","longitude":"23.61684850"},{"name":"LiepÄja","isoCode":"LPX","countryCode":"LV","latitude":"56.50466780","longitude":"21.01080600"},{"name":"RÄzekne","isoCode":"REZ","countryCode":"LV","latitude":"56.50992230","longitude":"27.33313570"},{"name":"Riga","isoCode":"RIX","countryCode":"LV","latitude":"56.94964870","longitude":"24.10518650"}
1,{"name":"Ventspils","isoCode":"VEN","countryCode":"LV","latitude":"57.39372160","longitude":"21.56470660"},{"name":"Valmiera","isoCode":"VMR","countryCode":"LV","latitude":"57.53846590","longitude":"25.42636180"},{"name":"Benghazi","isoCode":"BA","countryCode":"LY","latitude":"32.11942420","longitude":"20.08679090"},{"name":"Derna District","isoCode":"DR","countryCode":"LY","latitude":"32.75561300","longitude":"22.63774320"},{"name":"Ghat District","isoCode":"GT","countryCode":"LY","latitude":"24.96403710","longitude":"10.17592850"},{"name":"Jabal al Akhdar","isoCode":"JA","countryCode":"LY","latitude":"23.18560810","longitude":"57.37138790"},{"name":"Jabal al Gharbi District","isoCode":"JG","countryCode":"LY","latitude":"30.26380320","longitude":"12.80547530"},{"name":"Jafara","isoCode":"JI","countryCode":"LY","latitude":"32.45259040","longitude":"12.94355360"},{"name":"Jufra","isoCode":"JU","countryCode":"LY","latitude":"27.98351350","longitude":"16.91225100"},{"name":"Kufra District","isoCode":"KF","countryCode":"LY","latitude":"23.31123890","longitude":"21.85685860"},{"name":"Murqub","isoCode":"MB","countryCode":"LY","latitude":"32.45996770","longitude":"14.10013260"},{"name":"Misrata District","isoCode":"MI","countryCode":"LY","latitude":"32.32558840","longitude":"15.09925560"},{"name":"Marj District","isoCode":"MJ","countryCode":"LY","latitude":"32.05503630","longitude":"21.18911510"},{"name":"Murzuq District","isoCode":"MQ","countryCode":"LY","latitude":"25.91822620","longitude":"13.92600010"},{"name":"Nalut District","isoCode":"NL","countryCode":"LY","latitude":"31.87423480","longitude":"10.97504840"},{"name":"Nuqat al Khams","isoCode":"NQ","countryCode":"LY","latitude":"32.69149090","longitude":"11.88917210"},{"name":"Sabha District","isoCode":"SB","countryCode":"LY","latitude":"27.03654060","longitude":"14.42902360"},{"name":"Sirte District","isoCode":"SR","countryCode":"LY","latitude":"31.18968900","longitude":"16.57019270"},{"name":"Tripoli District","isoCode":"TB","countryCode":"LY","latitude":"32.64080210","longitude":"13.26634790"},{"name":"Al Wahat District","isoCode":"WA","countryCode":"LY","latitude":"29.04668080","longitude":"21.85685860"},{"name":"Wadi al Hayaa District","isoCode":"WD","countryCode":"LY","latitude":"26.42259260","longitude":"12.62162110"},{"name":"Wadi al Shatii District","isoCode":"WS","countryCode":"LY","latitude":"27.73514680","longitude":"12.43805810"},{"name":"Zawiya District","isoCode":"ZA","countryCode":"LY","latitude":"32.76302820","longitude":"12.73649620"},{"name":"Tanger-Tétouan-Al Hoceïma","isoCode":"01","countryCode":"MA","latitude":"35.26295580","longitude":"-5.56172790"},{"name":"L\'Oriental","isoCode":"02","countryCode":"MA","latitude":"37.06968300","longitude":"-94.51227700"},{"name":"Fès-Meknès","isoCode":"03","countryCode":"MA","latitude":"34.06252900","longitude":"-4.72775280"},{"name":"Rabat-Salé-Kénitra","isoCode":"04","countryCode":"MA","latitude":"34.07686400","longitude":"-7.34544760"},{"name":"Béni Mellal-Khénifra","isoCode":"05","countryCode":"MA","latitude":"32.57191840","longitude":"-6.06791940"},{"name":"Casablanca-Settat","isoCode":"06","countryCode":"MA","latitude":"33.21608720","longitude":"-7.43813550"},{"name":"Marrakesh-Safi","isoCode":"07","countryCode":"MA","latitude":"31.73308330","longitude":"-8.13385580"},{"name":"Drâa-Tafilalet","isoCode":"08","countryCode":"MA","latitude":"31.14995380","longitude":"-5.39395510"},{"name":"Souss-Massa","isoCode":"09","countryCode":"MA","latitude":"30.27506110","longitude":"-8.13385580"},{"name":"Guelmim-Oued Noun (EH-partial)","isoCode":"10","countryCode":"MA","latitude":"28.48442810","longitude":"-10.08072980"},{"name":"Laâyoune-Sakia El Hamra (EH-partial)","isoCode":"11","countryCode":"MA","latitude":"27.86831940","longitude":"-11.98046130"},{"name":"Dakhla-Oued Ed-Dahab (EH)","isoCode":"12","countryCode":"MA","latitude":"22.73378920","longitude":"-14.28611160"},{"name":"Agadir-Ida-Ou-Tanane","isoCode":"AGD","countryCode":"MA","latitude":"30.64620910","longitude":"-9.83390610"},{"name":"Aousserd (EH)","isoCode":"AOU","countryCode":"MA","latitude":"22.55215380","longitude":"-14.32973530"},{"name":"Assa-Zag (EH-partial)","isoCode":"ASZ","countryCode":"MA","latitude":"28.14023950","longitude":"-9.72326730"},{"name":"Azilal","isoCode":"AZI","countryCode":"MA","latitude":"32.00426200","longitude":"-6.57833870"},{"name":"Béni Mellal","isoCode":"BEM","countryCode":"MA","latitude":"32.34244300","longitude":"-6.37579900"},{"name":"Berkane","isoCode":"BER","countryCode":"MA","latitude":"34.88408760","longitude":"-2.34188700"},{"name":"Benslimane","isoCode":"BES","countryCode":"MA","latitude":"33.61896980","longitude":"-7.13055360"},{"name":"Boujdour (EH)","isoCode":"BOD","countryCode":"MA","latitude":"26.12524930","longitude":"-14.48473470"},{"name":"Boulemane","isoCode":"BOM","countryCode":"MA","latitude":"33.36251590","longitude":"-4.73033970"},{"name":"Berrechid","isoCode":"BRR","countryCode":"MA","latitude":"33.26025230","longitude":"-7.59848370"}
1,{"name":"Casablanca","isoCode":"CAS","countryCode":"MA","latitude":"33.57226780","longitude":"-7.65703260"},{"name":"Chefchaouen","isoCode":"CHE","countryCode":"MA","latitude":"35.01817200","longitude":"-5.14320680"},{"name":"Chichaoua","isoCode":"CHI","countryCode":"MA","latitude":"31.53835810","longitude":"-8.76463880"},{"name":"Chtouka-Ait Baha","isoCode":"CHT","countryCode":"MA","latitude":"30.10724220","longitude":"-9.27855830"},{"name":"Driouch","isoCode":"DRI","countryCode":"MA","latitude":"34.97603200","longitude":"-3.39644930"},{"name":"Errachidia","isoCode":"ERR","countryCode":"MA","latitude":"31.90512750","longitude":"-4.72775280"},{"name":"Essaouira","isoCode":"ESI","countryCode":"MA","latitude":"31.50849260","longitude":"-9.75950410"},{"name":"Es-Semara (EH-partial)","isoCode":"ESM","countryCode":"MA","latitude":"26.74185600","longitude":"-11.67836710"},{"name":"Fahs-Anjra","isoCode":"FAH","countryCode":"MA","latitude":"35.76019920","longitude":"-5.66683060"},{"name":"Fès","isoCode":"FES","countryCode":"MA","latitude":"34.02395790","longitude":"-5.03675990"},{"name":"Figuig","isoCode":"FIG","countryCode":"MA","latitude":"32.10926130","longitude":"-1.22980600"},{"name":"Fquih Ben Salah","isoCode":"FQH","countryCode":"MA","latitude":"32.50016800","longitude":"-6.71007170"},{"name":"Guelmim","isoCode":"GUE","countryCode":"MA","latitude":"28.98836590","longitude":"-10.05274980"},{"name":"Guercif","isoCode":"GUF","countryCode":"MA","latitude":"34.23450360","longitude":"-3.38130050"},{"name":"El Hajeb","isoCode":"HAJ","countryCode":"MA","latitude":"33.68573500","longitude":"-5.36778440"},{"name":"Al Haouz","isoCode":"HAO","countryCode":"MA","latitude":"31.29567290","longitude":"-7.87216000"},{"name":"Al Hoceïma","isoCode":"HOC","countryCode":"MA","latitude":"35.24455890","longitude":"-3.93174680"},{"name":"Ifrane","isoCode":"IFR","countryCode":"MA","latitude":"33.52280620","longitude":"-5.11095520"},{"name":"Inezgane-Ait Melloul","isoCode":"INE","countryCode":"MA","latitude":"30.35090980","longitude":"-9.38951100"},{"name":"El Jadida","isoCode":"JDI","countryCode":"MA","latitude":"33.23163260","longitude":"-8.50071160"},{"name":"Jerada","isoCode":"JRA","countryCode":"MA","latitude":"34.30617910","longitude":"-2.17941360"},{"name":"Kénitra","isoCode":"KEN","countryCode":"MA","latitude":"34.25405030","longitude":"-6.58901660"},{"name":"El Kelâa des Sraghna","isoCode":"KES","countryCode":"MA","latitude":"32.05227670","longitude":"-7.35165580"},{"name":"Khémisset","isoCode":"KHE","countryCode":"MA","latitude":"33.81537040","longitude":"-6.05733020"},{"name":"Khénifra","isoCode":"KHN","countryCode":"MA","latitude":"32.93404710","longitude":"-5.66157100"},{"name":"Khouribga","isoCode":"KHO","countryCode":"MA","latitude":"32.88602300","longitude":"-6.92086550"},{"name":"Laâyoune (EH)","isoCode":"LAA","countryCode":"MA","latitude":"27.15003840","longitude":"-13.19907580"},{"name":"Larache","isoCode":"LAR","countryCode":"MA","latitude":"35.17442710","longitude":"-6.14739640"},{"name":"Marrakech","isoCode":"MAR","countryCode":"MA","latitude":"31.63460230","longitude":"-8.07789320"},{"name":"Mâdiq-Fnideq","isoCode":"MDF","countryCode":"MA","latitude":"35.77330190","longitude":"-5.51433000"},{"name":"Médiouna","isoCode":"MED","countryCode":"MA","latitude":"33.45409390","longitude":"-7.51660200"},{"name":"Meknès","isoCode":"MEK","countryCode":"MA","latitude":"33.88100000","longitude":"-5.57303970"},{"name":"Midelt","isoCode":"MID","countryCode":"MA","latitude":"32.68550790","longitude":"-4.75017090"},{"name":"Mohammadia","isoCode":"MOH","countryCode":"MA","latitude":"33.68737490","longitude":"-7.42391420"},{"name":"Moulay Yacoub","isoCode":"MOU","countryCode":"MA","latitude":"34.08744790","longitude":"-5.17840190"},{"name":"Nador","isoCode":"NAD","countryCode":"MA","latitude":"34.91719260","longitude":"-2.85771050"},{"name":"Nouaceur","isoCode":"NOU","countryCode":"MA","latitude":"33.36703930","longitude":"-7.57325370"},{"name":"Ouarzazate","isoCode":"OUA","countryCode":"MA","latitude":"30.93354360","longitude":"-6.93701600"},{"name":"Oued Ed-Dahab (EH)","isoCode":"OUD","countryCode":"MA","latitude":"22.73378920","longitude":"-14.28611160"},{"name":"Oujda-Angad","isoCode":"OUJ","countryCode":"MA","latitude":"34.68375040","longitude":"-2.2993239
10"},{"name":"Ouezzane","isoCode":"OUZ","countryCode":"MA","latitude":"34.80634500","longitude":"-5.59145050"},{"name":"Rabat","isoCode":"RAB","countryCode":"MA","latitude":"33.96919900","longitude":"-6.92730290"},{"name":"Rehamna","isoCode":"REH","countryCode":"MA","latitude":"32.20329050","longitude":"-8.56896710"},{"name":"Safi","isoCode":"SAF","countryCode":"MA","latitude":"32.29898720","longitude":"-9.10134980"},{"name":"Salé","isoCode":"SAL","countryCode":"MA","latitude":"34.03775700","longitude":"-6.84270730"},{"name":"Sefrou","isoCode":"SEF","countryCode":"MA","latitude":"33.83052440","longitude":"-4.83531540"},{"name":"Settat","isoCode":"SET","countryCode":"MA","latitude":"32.99242420","longitude":"-7.62226650"},{"name":"Sidi Bennour","isoCode":"SIB","countryCode":"MA","latitude":"32.64926020","longitude":"-8.44714530"},{"name":"Sidi Ifni","isoCode":"SIF","countryCode":"MA","latitude":"29.36657970","longitude":"-10.21084850"},{"name":"Sidi Kacem","isoCode":"SIK","countryCode":"MA","latitude":"34.22601720","longitude":"-5.71291640"},{"name":"Sidi Slimane","isoCode":"SIL","countryCode":"MA","latitude":"34.27378280","longitude":"-5.98059720"},{"name":"Skhirate-Témara","isoCode":"SKH","countryCode":"MA","latitude":"33.76224250","longitude":"-7.04190520"},{"name":"Tarfaya (EH-partial)","isoCode":"TAF","countryCode":"MA","latitude":"27.93777010","longitude":"-12.92940630"},{"name":"Taourirt","isoCode":"TAI","countryCode":"MA","latitude":"34.21259800","longitude":"-2.69838680"},{"name":"Taounate","isoCode":"TAO","countryCode":"MA","latitude":"34.53691700","longitude":"-4.63986930"},{"name":"Taroudannt","isoCode":"TAR","countryCode":"MA","latitude":"30.47271260","longitude":"-8.87487650"},{"name":"Tata","isoCode":"TAT","countryCode":"MA","latitude":"29.75087700","longitude":"-7.97563430"},{"name":"Taza","isoCode":"TAZ","countryCode":"MA","latitude":"34.27889530","longitude":"-3.58126920"},{"name":"Tétouan","isoCode":"TET","countryCode":"MA","latitude":"35.58889950","longitude":"-5.36255160"},{"name":"Tinghir","isoCode":"TIN","countryCode":"MA","latitude":"31.48507940","longitude":"-6.20192980"},{"name":"Tiznit","isoCode":"TIZ","countryCode":"MA","latitude":"29.69339200","longitude":"-9.73215700"},{"name":"Tanger-Assilah","isoCode":"TNG","countryCode":"MA","latitude":"35.76325390","longitude":"-5.90450980"},{"name":"Tan-Tan (EH-partial)","isoCode":"TNT","countryCode":"MA","latitude":"28.03012000","longitude":"-11.16173560"},{"name":"Youssoufia","isoCode":"YUS","countryCode":"MA","latitude":"32.02006790","longitude":"-8.86926480"},{"name":"Zagora","isoCode":"ZAG","countryCode":"MA","latitude":"30.57860930","longitude":"-5.89871390"},{"name":"La Colle","isoCode":"CL","countryCode":"MC","latitude":"43.73274650","longitude":"7.41372760"},{"name":"La Condamine","isoCode":"CO","countryCode":"MC","latitude":"43.73506650","longitude":"7.41990600"},{"name":"Moneghetti","isoCode":"MG","countryCode":"MC","latitude":"43.73649270","longitude":"7.41533830"},{"name":"Anenii Noi District","isoCode":"AN","countryCode":"MD","latitude":"46.87956630","longitude":"29.23121750"},{"name":"BÄlÈi Municipality","isoCode":"BA","countryCode":"MD","latitude":"47.75399470","longitude":"27.91841480"},{"name":"Bender Municipality","isoCode":"BD","countryCode":"MD","latitude":"46.82275510","longitude":"29.46201010"},{"name":"Briceni District","isoCode":"BR","countryCode":"MD","latitude":"48.36320220","longitude":"27.07503980"},{"name":"Basarabeasca District","isoCode":"BS","countryCode":"MD","latitude":"46.42370600","longitude":"28.89354920"},{"name":"Cahul District","isoCode":"CA","countryCode":"MD","latitude":"45.89394040","longitude":"28.18902750"},{"name":"CÄlÄraÈi District","isoCode":"CL","countryCode":"MD","latitude":"47.28694600","longitude":"28.27453100"},{"name":"CimiÈlia District","isoCode":"CM","countryCode":"MD","latitude":"46.52508510","longitude":"28.77218350"},{"name":"Criuleni District","isoCode":"CR","countryCode":"MD","latitude":"47.21361140","longitude":"29.15575190"},{"name":"CÄuÈeni District","isoCode":"CS","countryCode":"MD","latitude":"46.65547150","longitude":"29.40912220"},{"name":"Cantemir District","isoCode":"CT","countryCode":"MD","latitude":"46.27717420","longitude":"28.20096530"},{"name":"ChiÈinÄu Municipality","isoCode":"CU","countryCode":"MD","latitude":"47.01045290","longitude":"28.86381020"},{"name":"DonduÈeni District","isoCode":"DO","countryCode":"MD","latitude":"48.23383050","longitude":"27.59980870"},{"name":"Drochia District","isoCode":"DR","countryCode":"MD","latitude":"48.07977880","longitude":"27.86041140"},{"name":"DubÄsari District","isoCode":"DU","countryCode":"MD","latitude":"47.26439420","longitude":"29.15503480"},{"name":"EdineÈ District","isoCode":"ED","countryCode":"MD","latitude":"48.16789910","longitude":"27.29361430"},{"name":"FÄleÈti District","isoCode":"FA","countryCode":"MD","latitude":"47.56477250","longitude":"27.72655930"},{"name":"FloreÈti District","isoCode":"FL","countryCode":"MD","latitude":"47.86678490","longitude":"28.33918640"},{"name":"Gagauzia","isoCode":"GA","countryCode":"MD","latitude":"46.09794350","longitude":"28.63846450"},{"name":"Glodeni District","isoCode":"GL","countryCode":"MD","latitude":"47.77901560","longitude":"27.51680100"},{"name":"HînceÈti District","isoCode":"HI","countryCode":"MD","latitude":"46.82811470","longitude":"28.58508890"},{"name":"Ialoveni District","isoCode":"IA","countryCode":"MD","latitude":"46.86308600","longitude":"28.82342180"},{"name":"Nisporeni District","isoCode":"NI","countryCode":"MD","latitude":"47.07513490","longitude":"28.17681550"},{"name":"OcniÈa District","isoCode":"OC","countryCode":"MD","latitude":"48.41104350","longitude":"27.47680920"},{"name":"Orhei District","isoCode":"OR","countryCode":"MD","latitude":"47.38604000","longitude":"28.83030820"},{"name":"Rezina District","isoCode":"RE","countryCode":"MD","latitude":"47.71804470","longitude":"28.88710240"},{"name":"RîÈcani District","isoCode":"RI","countryCode":"MD","latitude":"47.90701530","longitude":"27.53749960"},{"name":"ÈoldÄneÈti District","isoCode":"SD","countryCode":"MD","latitude":"47.81473890","longitude":"28.78895860"},{"name":"Sîngerei District","isoCode":"SI","countryCode":"MD","latitude":"47.63891340","longitude":"28.13718160"},{"name":"Transnistria autonomous territorial unit","isoCode":"SN","countryCode":"MD","latitude":"47.21529720","longitude":"29.46380540"},{"name":"Soroca District","isoCode":"SO","countryCode":"MD","latitude":"48.15497430","longitude":"28.28707830"},{"name":"StrÄÈeni District","isoCode":"ST","countryCode":"MD","latitude":"47.14502670","longitude":"28.61367360"},{"name":"Ètefan VodÄ District","isoCode":"SV","countryCode":"MD","latitude":"46.55404880","longitude":"29.70224200"},{"name":"Taraclia District","isoCode":"TA","countryCode":"MD","latitude":"45.89865100","longitude":"28.66716440"},{"name":"TeleneÈti District","isoCode":"TE","countryCode":"MD","latitude":"47.49839620","longitude":"28.36760190"},{"name":"Ungheni District","isoCode":"UN","countryCode":"MD","latitude":"47.23057670","longitude":"27.78926610"},{"name":"Andrijevica Municipality","isoCode":"01","countryCode":"ME","latitude":"42.73624770","longitude":"19.78595560"},{"name":"Bar Municipality","isoCode":"02","countryCode":"ME","latitude":"42.12781190","longitude":"19.14043800"},{"name":"Berane Municipality","isoCode":"03","countryCode":"ME","latitude":"42.82572890","longitude":"19.90205090"},{"name":"Bijelo Polje Municipality","isoCode":"04","countryCode":"ME","latitude":"43.08465260","longitude":"19.71154720"},{"name":"Budva Municipality","isoCode":"05","countryCode":"ME","latitude":"42.31407200","longitude":"18.83138320"},{"name":"Old Royal Capital Cetinje","isoCode":"06","countryCode":"ME","latitude":"42.39309590","longitude":"18.91159640"},{"name":"Danilovgrad Municipality","isoCode":"07","countryCode":"ME","latitude":"42.58357000","longitude":"19.14043800"},{"name":"KolaÅ¡in Municipality","isoCode":"09","countryCode":"ME","latitude":"42.76019160","longitude":"19.42591140"},{"name":"Kotor Municipality","isoCode":"10","countryCode":"ME","latitude":"42.57402610","longitude":"18.64131450"},{"name":"Mojkovac Municipality","isoCode":"11","countryCode":"ME","latitude":"42.96880180","longitude":"19.52110630"},{"name":"NikÅ¡iÄ Municipality","isoCode":"12","countryCode":"ME","latitude":"42.79971840","longitude":"18.76009630"},{"name":"Plav Municipality","isoCode":"13","countryCode":"ME","latitude":"42.60013370","longitude":"19.94075410"},{"name":"Pljevlja Municipality","isoCode":"14","countryCode":"ME","latitude":"43.27233830","longitude":"19.28315310"},{"name":"Plužine Municipality","isoCode":"15","countryCode":"ME","latitude":"43.15933840","longitude":"18.85514840"},{"name":"Podgorica Municipality","isoCode":"16","countryCode":"ME","latitude":"42.36938340","longitude":"19.28315310"},{"name":"Rožaje Municipality","isoCode":"17","countryCode":"ME","latitude":"42.84083890","longitude":"20.16706280"},{"name":"Å avnik Municipality","isoCode":"18","countryCode":"ME","latitude":"42.96037560","longitude":"19.14043800"},{"name":"Tivat Municipality","isoCode":"19","countryCode":"ME","latitude":"42.42348000","longitude":"18.71851840"},{"name":"Ulcinj Municipality","isoCode":"20","countryCode":"ME","latitude":"41.96527950","longitude":"19.30694320"},{"name":"Žabljak Municipality","isoCode":"21","countryCode":"ME","latitude":"43.15551520","longitude":"19.12260180"},{"name":"Gusinje Municipality","isoCode":"22","countryCode":"ME","latitude":"42.55634550","longitude":"19.83060510"},{"name":"Petnjica Municipality","isoCode":"23","countryCode":"ME","latitude":"42.93534800","longitude":"20.02114490"},{"name":"Toamasina Province","isoCode":"A","countryCode":"MG","latitude":"-18.14428110","longitude":"49.39578360"},{"name":"Antsiranana Province","isoCode":"D","countryCode":"MG","latitude":"-13.77153900","longitude":"49.52799960"},{"name":"Fianarantsoa Province","isoCode":"F","countryCode":"MG","latitude":"-22.35362400","longitude":"46.82528380"},{"name":"Mahajanga Province","isoCode":"M","countryCode":"MG","latitude":"-16.52388300","longitude":"46.51626200"},{"name":"Antananarivo Province","isoCode":"T","countryCode":"MG","latitude":"-18.7051474
10","longitude":"46.82528380"},{"name":"Toliara Province","isoCode":"U","countryCode":"MG","latitude":"-23.35161910","longitude":"43.68549360"},{"name":"Ralik Chain","isoCode":"L","countryCode":"MH","latitude":"8.13614600","longitude":"164.88679560"},{"name":"Ratak Chain","isoCode":"T","countryCode":"MH","latitude":"10.27632760","longitude":"170.55009370"},{"name":"Aerodrom Municipality","isoCode":"01","countryCode":"MK","latitude":"41.94643630","longitude":"21.49317130"},{"name":"AraÄinovo Municipality","isoCode":"02","countryCode":"MK","latitude":"42.02473810","longitude":"21.57664070"},{"name":"Berovo Municipality","isoCode":"03","countryCode":"MK","latitude":"41.66619290","longitude":"22.76288300"},{"name":"Bitola Municipality","isoCode":"04","countryCode":"MK","latitude":"41.03633020","longitude":"21.33219740"},{"name":"Bogdanci Municipality","isoCode":"05","countryCode":"MK","latitude":"41.18696160","longitude":"22.59602680"},{"name":"Bogovinje Municipality","isoCode":"06","countryCode":"MK","latitude":"41.92363710","longitude":"20.91638870"},{"name":"Bosilovo Municipality","isoCode":"07","countryCode":"MK","latitude":"41.49048640","longitude":"22.78671740"},{"name":"Brvenica Municipality","isoCode":"08","countryCode":"MK","latitude":"41.96814820","longitude":"20.98195860"},{"name":"Butel Municipality","isoCode":"09","countryCode":"MK","latitude":"42.08950680","longitude":"21.46336100"},{"name":"Valandovo Municipality","isoCode":"10","countryCode":"MK","latitude":"41.32119090","longitude":"22.50066930"},{"name":"Vasilevo Municipality","isoCode":"11","countryCode":"MK","latitude":"41.47416990","longitude":"22.64221280"},{"name":"VevÄani Municipality","isoCode":"12","countryCode":"MK","latitude":"41.24075430","longitude":"20.59156490"},{"name":"Veles Municipality","isoCode":"13","countryCode":"MK","latitude":"41.72744260","longitude":"21.71376940"},{"name":"Vinica Municipality","isoCode":"14","countryCode":"MK","latitude":"41.85710200","longitude":"22.57218810"},{"name":"VraneÅ¡tica Municipality","isoCode":"15","countryCode":"MK","latitude":"41.48290870","longitude":"21.05796320"},{"name":"VrapÄiÅ¡te Municipality","isoCode":"16","countryCode":"MK","latitude":"41.87911600","longitude":"20.83145000"},{"name":"Gazi Baba Municipality","isoCode":"17","countryCode":"MK","latitude":"42.01629610","longitude":"21.49913340"},{"name":"Gevgelija Municipality","isoCode":"18","countryCode":"MK","latitude":"41.21186060","longitude":"22.38146240"},{"name":"Gostivar Municipality","isoCode":"19","countryCode":"MK","latitude":"41.80255410","longitude":"20.90893780"},{"name":"Gradsko Municipality","isoCode":"20","countryCode":"MK","latitude":"41.59916080","longitude":"21.88070640"},{"name":"Debarca Municipality","isoCode":"22","countryCode":"MK","latitude":"41.35840770","longitude":"20.85529190"},{"name":"DelÄevo Municipality","isoCode":"23","countryCode":"MK","latitude":"41.96843870","longitude":"22.76288300"},{"name":"Demir Kapija Municipality","isoCode":"24","countryCode":"MK","latitude":"41.37955380","longitude":"22.21455710"},{"name":"Demir Hisar Municipality","isoCode":"25","countryCode":"MK","latitude":"41.22708300","longitude":"21.14142260"},{"name":"Dojran Municipality","isoCode":"26","countryCode":"MK","latitude":"41.24366720","longitude":"22.69137640"},{"name":"Dolneni Municipality","isoCode":"27","countryCode":"MK","latitude":"41.46409350","longitude":"21.40374070"},{"name":"Drugovo Municipality","isoCode":"28","countryCode":"MK","latitude":"41.44081530","longitude":"20.92682010"},{"name":"GjorÄe Petrov Municipality","isoCode":"29","countryCode":"MK","latitude":"42.06063740","longitude":"21.32027360"},{"name":"Želino Municipality","isoCode":"30","countryCode":"MK","latitude":"41.90065310","longitude":"21.11757670"},{"name":"Zajas Municipality","isoCode":"31","countryCode":"MK","latitude":"41.60303280","longitude":"20.87913430"},{"name":"Zelenikovo Municipality","isoCode":"32","countryCode":"MK","latitude":"41.87338120","longitude":"21.60272500"},{"name":"Zrnovci Municipality","isoCode":"33","countryCode":"MK","latitude":"41.82282210","longitude":"22.41722560"}
1,{"name":"Ilinden Municipality","isoCode":"34","countryCode":"MK","latitude":"41.99574430","longitude":"21.56769750"},{"name":"Jegunovce Municipality","isoCode":"35","countryCode":"MK","latitude":"42.07407200","longitude":"21.12204780"},{"name":"Kavadarci Municipality","isoCode":"36","countryCode":"MK","latitude":"41.28900680","longitude":"21.99994350"},{"name":"Karbinci","isoCode":"37","countryCode":"MK","latitude":"41.81801590","longitude":"22.23247580"},{"name":"KarpoÅ¡ Municipality","isoCode":"38","countryCode":"MK","latitude":"41.97096610","longitude":"21.39181680"},{"name":"Kisela Voda Municipality","isoCode":"39","countryCode":"MK","latitude":"41.92748000","longitude":"21.49317130"},{"name":"KiÄevo Municipality","isoCode":"40","countryCode":"MK","latitude":"41.51291120","longitude":"20.95250650"},{"name":"KonÄe Municipality","isoCode":"41","countryCode":"MK","latitude":"41.51710110","longitude":"22.38146240"},{"name":"KoÄani Municipality","isoCode":"42","countryCode":"MK","latitude":"41.98583740","longitude":"22.40530460"},{"name":"Kratovo Municipality","isoCode":"43","countryCode":"MK","latitude":"42.05371410","longitude":"22.07148350"},{"name":"Kriva Palanka Municipality","isoCode":"44","countryCode":"MK","latitude":"42.20584540","longitude":"22.33079650"},{"name":"KrivogaÅ¡tani Municipality","isoCode":"45","countryCode":"MK","latitude":"41.30823060","longitude":"21.36796890"},{"name":"KruÅ¡evo Municipality","isoCode":"46","countryCode":"MK","latitude":"41.37693310","longitude":"21.26065540"},{"name":"Kumanovo Municipality","isoCode":"47","countryCode":"MK","latitude":"42.07326130","longitude":"21.78531430"},{"name":"Lipkovo Municipality","isoCode":"48","countryCode":"MK","latitude":"42.20066260","longitude":"21.61837550"},{"name":"Lozovo Municipality","isoCode":"49","countryCode":"MK","latitude":"41.78181390","longitude":"21.90008270"},{"name":"Mavrovo and RostuÅ¡a Municipality","isoCode":"50","countryCode":"MK","latitude":"41.60924270","longitude":"20.60124880"},{"name":"Makedonska Kamenica Municipality","isoCode":"51","countryCode":"MK","latitude":"42.06946040","longitude":"22.54834900"},{"name":"Makedonski Brod Municipality","isoCode":"52","countryCode":"MK","latitude":"41.51330880","longitude":"21.21743290"},{"name":"Mogila Municipality","isoCode":"53","countryCode":"MK","latitude":"41.14796450","longitude":"21.45143690"},{"name":"Negotino Municipality","isoCode":"54","countryCode":"MK","latitude":"41.49899850","longitude":"22.09532970"},{"name":"Novaci Municipality","isoCode":"55","countryCode":"MK","latitude":"41.04426610","longitude":"21.45888940"},{"name":"Novo Selo Municipality","isoCode":"56","countryCode":"MK","latitude":"41.43255800","longitude":"22.88204890"},{"name":"Oslomej Municipality","isoCode":"57","countryCode":"MK","latitude":"41.57583910","longitude":"21.02219600"},{"name":"Ohrid Municipality","isoCode":"58","countryCode":"MK","latitude":"41.06820880","longitude":"20.75992660"},{"name":"Petrovec Municipality","isoCode":"59","countryCode":"MK","latitude":"41.90298970","longitude":"21.68992100"},{"name":"PehÄevo Municipality","isoCode":"60","countryCode":"MK","latitude":"41.77371320","longitude":"22.88204890"},{"name":"Plasnica Municipality","isoCode":"61","countryCode":"MK","latitude":"41.45463490","longitude":"21.10565390"},{"name":"Prilep Municipality","isoCode":"62","countryCode":"MK","latitude":"41.26931420","longitude":"21.71376940"},{"name":"ProbiÅ¡tip Municipality","isoCode":"63","countryCode":"MK","latitude":"41.95891460","longitude":"22.16686700"},{"name":"RadoviÅ¡ Municipality","isoCode":"64","countryCode":"MK","latitude":"41.64955310","longitude":"22.47682870"},{"name":"Rankovce Municipality","isoCode":"65","countryCode":"MK","latitude":"42.18081410","longitude":"22.09532970"},{"name":"Resen Municipality","isoCode":"66","countryCode":"MK","latitude":"40.93680930","longitude":"21.04604070"},{"name":"Rosoman Municipality","isoCode":"67","countryCode":"MK","latitude":"41.48480060","longitude":"21.88070640"},{"name":"Saraj Municipality","isoCode":"68","countryCode":"MK","latitude":"41.98694960","longitude":"21.26065540"},{"name":"Sveti Nikole Municipality","isoCode":"69","countryCode":"MK","latitude":"41.89803120","longitude":"21.99994350"},{"name":"SopiÅ¡te Municipality","isoCode":"70","countryCode":"MK","latitude":"41.86384920","longitude":"21.30834990"}
1,{"name":"Staro NagoriÄane Municipality","isoCode":"71","countryCode":"MK","latitude":"42.21916920","longitude":"21.90455410"},{"name":"Struga Municipality","isoCode":"72","countryCode":"MK","latitude":"41.31737440","longitude":"20.66456830"},{"name":"Strumica Municipality","isoCode":"73","countryCode":"MK","latitude":"41.43780040","longitude":"22.64274280"},{"name":"StudeniÄani Municipality","isoCode":"74","countryCode":"MK","latitude":"41.92256390","longitude":"21.53639650"},{"name":"Tearce Municipality","isoCode":"75","countryCode":"MK","latitude":"42.07775110","longitude":"21.05349230"},{"name":"Tetovo Municipality","isoCode":"76","countryCode":"MK","latitude":"42.02748600","longitude":"20.95066360"},{"name":"Centar Municipality","isoCode":"77","countryCode":"MK","latitude":"41.96989340","longitude":"21.42162670"},{"name":"Centar Župa Municipality","isoCode":"78","countryCode":"MK","latitude":"41.46522590","longitude":"20.59305480"},{"name":"Äair Municipality","isoCode":"79","countryCode":"MK","latitude":"41.99303550","longitude":"21.43653180"},{"name":"ÄaÅ¡ka Municipality","isoCode":"80","countryCode":"MK","latitude":"41.64743800","longitude":"21.69141150"},{"name":"ÄeÅ¡inovo-ObleÅ¡evo Municipality","isoCode":"81","countryCode":"MK","latitude":"41.86393160","longitude":"22.26224600"},{"name":"ÄuÄer-Sandevo Municipality","isoCode":"82","countryCode":"MK","latitude":"42.14839460","longitude":"21.40374070"},{"name":"Å tip Municipality","isoCode":"83","countryCode":"MK","latitude":"41.70792970","longitude":"22.19071220"},{"name":"Å uto Orizari Municipality","isoCode":"84","countryCode":"MK","latitude":"42.02904160","longitude":"21.40970270"},{"name":"Greater Skopje","isoCode":"85","countryCode":"MK","latitude":"41.99812940","longitude":"21.42543550"},{"name":"Kayes Region","isoCode":"1","countryCode":"ML","latitude":"14.08183080","longitude":"-9.90181310"},{"name":"Taoudénit Region","isoCode":"10","countryCode":"ML","latitude":"22.67641320","longitude":"-3.97891430"},{"name":"Koulikoro Region","isoCode":"2","countryCode":"ML","latitude":"13.80180740","longitude":"-7.43813550"},{"name":"Sikasso Region","isoCode":"3","countryCode":"ML","latitude":"10.89051860","longitude":"-7.43813550"},{"name":"Ségou Region","isoCode":"4","countryCode":"ML","latitude":"13.83944560","longitude":"-6.06791940"},{"name":"Mopti Region","isoCode":"5","countryCode":"ML","latitude":"14.63380390","longitude":"-3.41955270"},{"name":"Tombouctou Region","isoCode":"6","countryCode":"ML","latitude":"21.05267060","longitude":"-3.74350900"},{"name":"Gao Region","isoCode":"7","countryCode":"ML","latitude":"16.90663320","longitude":"1.52086240"},{"name":"Kidal Region","isoCode":"8","countryCode":"ML","latitude":"18.79868320","longitude":"1.83183340"},{"name":"Ménaka Region","isoCode":"9","countryCode":"ML","latitude":"15.91564210","longitude":"2.39617400"},{"name":"Bamako","isoCode":"BKO","countryCode":"ML","latitude":"12.63923160","longitude":"-8.00288920"},{"name":"Sagaing Region","isoCode":"01","countryCode":"MM","latitude":"24.42838100","longitude":"95.39395510"},{"name":"Bago","isoCode":"02","countryCode":"MM","latitude":"17.32207110","longitude":"96.46632860"},{"name":"Magway Region","isoCode":"03","countryCode":"MM","latitude":"19.88713860","longitude":"94.72775280"},{"name":"Mandalay Region","isoCode":"04","countryCode":"MM","latitude":"21.56190580","longitude":"95.89871390"},{"name":"Tanintharyi Region","isoCode":"05","countryCode":"MM","latitude":"12.47068760","longitude":"99.01289260"},{"name":"Yangon Region","isoCode":"06","countryCode":"MM","latitude":"16.91434880","longitude":"96.15269850"},{"name":"Ayeyarwady Region","isoCode":"07","countryCode":"MM","latitude":"17.03421250","longitude":"95.22666750"},{"name":"Kachin State","isoCode":"11","countryCode":"MM","latitude":"25.85090400","longitude":"97.43813550"},{"name":"Kayah State","isoCode":"12","countryCode":"MM","latitude":"19.23420610","longitude":"97.26528580"},{"name":"Kayin State","isoCode":"13","countryCode":"MM","latitude":"16.94593460","longitude":"97.95928630"},{"name":"Chin State","isoCode":"14","countryCode":"MM","latitude":"22.00869780","longitude":"93.58126920"},{"name":"Mon State","isoCode":"15","countryCode":"MM","latitude":"16.30031330","longitude":"97.69822720"},{"name":"Rakhine State","isoCode":"16","countryCode":"MM","latitude":"20.10408180","longitude":"93.58126920"},{"name":"Shan State","isoCode":"17","countryCode":"MM","latitude":"22.03619850","longitude":"98.13385580"},{"name":"Naypyidaw Union Territory","isoCode":"18","countryCode":"MM","latitude":"19.93862450","longitude":"96.15269850"},{"name":"Orkhon Province","isoCode":"035","countryCode":"MN","latitude":"49.00470500","longitude":"104.30165270"},{"name":"Darkhan-Uul Province","isoCode":"037","countryCode":"MN","latitude":"49.46484340","longitude":"105.97459190"},{"name":"Khentii Province","isoCode":"039","countryCode":"MN","latitude":"47.60812090","longitude":"109.93728560"},{"name":"Khövsgöl Province","isoCode":"041","countryCode":"MN","latitude":"50.22044840","longitude":"100.32137680"},{"name":"Khovd Province","isoCode":"043","countryCode":"MN","latitude":"47.11296540","longitude":"92.31107520"},{"name":"Uvs Province","isoCode":"046","countryCode":"MN","latitude":"49.64497070","longitude":"93.27365760"},{"name":"Töv Province","isoCode":"047","countryCode":"MN","latitude":"47.21240560","longitude":"106.41541000"},{"name":"Selenge Province","isoCode":"049","countryCode":"MN","latitude":"50.00592730","longitude":"106.44341080"},{"name":"Sükhbaatar Province","isoCode":"051","countryCode":"MN","latitude":"46.56531630","longitude":"113.53808360"},{"name":"Ãmnögovi Province","isoCode":"053","countryCode":"MN","latitude":"43.50002400","longitude":"104.28611160"},{"name":"Ãvörkhangai Province","isoCode":"055","countryCode":"MN","latitude":"45.76243920","longitude":"103.09170320"},{"name":"Zavkhan Province","isoCode":"057","countryCode":"MN","latitude":"48.23881470","longitude":"96.07030190"},{"name":"Dundgovi Province","isoCode":"059","countryCode":"MN","latitude":"45.58227860","longitude":"106.76442090"},{"name":"Dornod Province","isoCode":"061","countryCode":"MN","latitude":"47.46581540","longitude":"115.39271200"},{"name":"Dornogovi Province","isoCode":"063","countryCode":"MN","latitude":"43.96538890","longitude":"109.17734590"},{"name":"Govisümber Province","isoCode":"064","countryCode":"MN","latitude":"46.47627540","longitude":"108.55706270"},{"name":"Govi-Altai Province","isoCode":"065","countryCode":"MN","latitude":"45.45112270","longitude":"95.85057660"},{"name":"Bulgan Province","isoCode":"067","countryCode":"MN","latitude":"48.96909130","longitude":"102.88317230"},{"name":"Bayankhongor Province","isoCode":"069","countryCode":"MN","latitude":"45.15267070","longitude":"100.10736670"},{"name":"Bayan-Ãlgii Province","isoCode":"071","countryCode":"MN","latitude":"48.39832540","longitude":"89.66259150"},{"name":"Arkhangai Province","isoCode":"073","countryCode":"MN","latitude":"47.89711010","longitude":"100.72401650"},{"name":"Hodh Ech Chargui Region","isoCode":"01","countryCode":"MR","latitude":"18.67370260","longitude":"-7.09287700"},{"name":"Hodh El Gharbi Region","isoCode":"02","countryCode":"MR","latitude":"16.69121490","longitude":"-9.54509740"},{"name":"Assaba Region","isoCode":"03","countryCode":"MR","latitude":"16.77595580","longitude":"-11.52480550"},{"name":"Gorgol Region","isoCode":"04","countryCode":"MR","latitude":"15.97173570","longitude":"-12.62162110"},{"name":"Brakna Region","isoCode":"05","countryCode":"MR","latitude":"17.23175610","longitude":"-13.17403480"},{"name":"Trarza Region","isoCode":"06","countryCode":"MR","latitude":"17.86649640","longitude":"-14.65878210"},{"name":"Adrar Region","isoCode":"07","countryCode":"MR","latitude":"19.8
16521760","longitude":"-12.80547530"},{"name":"Dakhlet Nouadhibou","isoCode":"08","countryCode":"MR","latitude":"20.59855880","longitude":"-16.25221430"},{"name":"Tagant Region","isoCode":"09","countryCode":"MR","latitude":"18.54675270","longitude":"-9.90181310"},{"name":"Guidimaka Region","isoCode":"10","countryCode":"MR","latitude":"15.25573310","longitude":"-12.25479190"},{"name":"Tiris Zemmour Region","isoCode":"11","countryCode":"MR","latitude":"24.57737640","longitude":"-9.90181310"},{"name":"Inchiri Region","isoCode":"12","countryCode":"MR","latitude":"20.02805610","longitude":"-15.40680790"},{"name":"Nouakchott-Ouest Region","isoCode":"13","countryCode":"MR","latitude":"18.15113570","longitude":"-15.99349100"},{"name":"Nouakchott-Nord Region","isoCode":"14","countryCode":"MR","latitude":"18.11302050","longitude":"-15.89949560"},{"name":"Nouakchott-Sud Region","isoCode":"15","countryCode":"MR","latitude":"17.97092880","longitude":"-15.94648740"},{"name":"Attard","isoCode":"01","countryCode":"MT","latitude":"35.89049670","longitude":"14.41993220"},{"name":"Balzan","isoCode":"02","countryCode":"MT","latitude":"35.89574140","longitude":"14.45340650"},{"name":"Birgu","isoCode":"03","countryCode":"MT","latitude":"35.88792140","longitude":"14.52256200"},{"name":"Birkirkara","isoCode":"04","countryCode":"MT","latitude":"35.89547060","longitude":"14.46650720"},{"name":"BirżebbuÄ¡a","isoCode":"05","countryCode":"MT","latitude":"35.81359890","longitude":"14.52474630"},{"name":"Cospicua","isoCode":"06","countryCode":"MT","latitude":"35.88067530","longitude":"14.52183380"},{"name":"Dingli","isoCode":"07","countryCode":"MT","latitude":"35.86273090","longitude":"14.38501070"},{"name":"Fgura","isoCode":"08","countryCode":"MT","latitude":"35.87382690","longitude":"14.52329010"},{"name":"Floriana","isoCode":"09","countryCode":"MT","latitude":"45.49521850","longitude":"-73.71395760"},{"name":"Fontana","isoCode":"10","countryCode":"MT","latitude":"34.09223350","longitude":"-117.43504800"},{"name":"Gudja","isoCode":"11","countryCode":"MT","latitude":"35.84698030","longitude":"14.50290400"},{"name":"Gżira","isoCode":"12","countryCode":"MT","latitude":"35.90589700","longitude":"14.49533380"},{"name":"Għajnsielem","isoCode":"13","countryCode":"MT","latitude":"36.02479660","longitude":"14.28029610"},{"name":"Għarb","isoCode":"14","countryCode":"MT","latitude":"36.06890900","longitude":"14.20180980"},{"name":"Għargħur","isoCode":"15","countryCode":"MT","latitude":"35.92205690","longitude":"14.45631760"},{"name":"Għasri","isoCode":"16","countryCode":"MT","latitude":"36.06680750","longitude":"14.21924750"},{"name":"Għaxaq","isoCode":"17","countryCode":"MT","latitude":"35.84403590","longitude":"14.51600900"},{"name":"Ħamrun","isoCode":"18","countryCode":"MT","latitude":"35.88612370","longitude":"14.48834420"},{"name":"Iklin","isoCode":"19","countryCode":"MT","latitude":"35.90987740","longitude":"14.45777320"},{"name":"Senglea","isoCode":"20","countryCode":"MT","latitude":"35.88730410","longitude":"14.51673710"},{"name":"Kalkara","isoCode":"21","countryCode":"MT","latitude":"35.89142420","longitude":"14.53202780"},{"name":"KerÄem","isoCode":"22","countryCode":"MT","latitude":"36.04479390","longitude":"14.22506050"},{"name":"Kirkop","isoCode":"23","countryCode":"MT","latitude":"35.84378620","longitude":"14.48543240"},{"name":"Lija","isoCode":"24","countryCode":"MT","latitude":"49.18007600","longitude":"-123.10331700"},{"name":"Luqa","isoCode":"25","countryCode":"MT","latitude":"35.85828650","longitude":"14.48688830"},{"name":"Marsa","isoCode":"26","countryCode":"MT","latitude":"34.03195870","longitude":"-118.44555350"},{"name":"Marsaskala","isoCode":"27","countryCode":"MT","latitude":"35.86036400","longitude":"14.55678760"},{"name":"Marsaxlokk","isoCode":"28","countryCode":"MT","latitude":"35.84116990","longitude":"14.53930970"},{"name":"Mdina","isoCode":"29","countryCode":"MT","latitude":"35.88809300","longitude":"14.40683570"},{"name":"Mellieħa","isoCode":"30","countryCode":"MT","latitude":"35.95235290","longitude":"14.35009750"},{"name":"MÄ¡arr","isoCode":"31","countryCode":"MT","latitude":"35.91893270","longitude":"14.36173430"},{"name":"Mosta","isoCode":"32","countryCode":"MT","latitude":"35.91415040","longitude":"14.42284270"},{"name":"Mqabba","isoCode":"33","countryCode":"MT","latitude":"35.84441430","longitude":"14.46941860"},{"name":"Msida","isoCode":"34","countryCode":"MT","latitude":"35.89563880","longitude":"14.48688830"},{"name":"Mtarfa","isoCode":"35","countryCode":"MT","latitude":"35.88951250","longitude":"14.39519530"},{"name":"Munxar","isoCode":"36","countryCode":"MT","latitude":"36.02880580","longitude":"14.22506050"},{"name":"Nadur","isoCode":"37","countryCode":"MT","latitude":"36.04470190","longitude":"14.29192730"},{"name":"Naxxar","isoCode":"38","countryCode":"MT","latitude":"35.93175180","longitude":"14.43157460"},{"name":"Paola","isoCode":"39","countryCode":"MT","latitude":"38.57223530","longitude":"-94.87912940"},{"name":"Pembroke","isoCode":"40","countryCode":"MT","latitude":"34.68016260","longitude":"-79.19503730"},{"name":"Pietà ","isoCode":"41","countryCode":"MT","latitude":"42.21862000","longitude":"-83.73464700"},{"name":"Qala","isoCode":"42","countryCode":"MT","latitude":"36.03886280","longitude":"14.31810100"},{"name":"Qormi","isoCode":"43","countryCode":"MT","latitude":"35.87643880","longitude":"14.46941860"},{"name":"Qrendi","isoCode":"44","countryCode":"MT","latitude":"35.83284880","longitude":"14.45486210"},{"name":"Victoria","isoCode":"45","countryCode":"MT","latitude":"28.80526740","longitude":"-97.00359820"},{"name":"Rabat","isoCode":"46","countryCode":"MT","latitude":"33.97159040","longitude":"-6.84981290"},{"name":"St. Julian\'s","isoCode":"48","countryCode":"MT","latitude":"42.21225130","longitude":"-85.89171270"},{"name":"San Ä wann","isoCode":"49","countryCode":"MT","latitude":"35.9
10773650","longitude":"14.47524160"},{"name":"Saint Lawrence","isoCode":"50","countryCode":"MT","latitude":"38.95780560","longitude":"-95.25656890"},{"name":"St. Paul\'s Bay","isoCode":"51","countryCode":"MT","latitude":"35.93601700","longitude":"14.39665030"},{"name":"Sannat","isoCode":"52","countryCode":"MT","latitude":"36.01926430","longitude":"14.25994370"},{"name":"Santa LuÄija","isoCode":"53","countryCode":"MT","latitude":"35.85614200","longitude":"14.50436000"},{"name":"Santa Venera","isoCode":"54","countryCode":"MT","latitude":"35.89022010","longitude":"14.47669740"},{"name":"Siġġiewi","isoCode":"55","countryCode":"MT","latitude":"35.84637420","longitude":"14.43157460"},{"name":"Sliema","isoCode":"56","countryCode":"MT","latitude":"35.91100810","longitude":"14.50290400"},{"name":"Swieqi","isoCode":"57","countryCode":"MT","latitude":"35.91911820","longitude":"14.46941860"},{"name":"Ta\' Xbiex","isoCode":"58","countryCode":"MT","latitude":"35.89914480","longitude":"14.49635190"},{"name":"Tarxien","isoCode":"59","countryCode":"MT","latitude":"35.86725520","longitude":"14.51164050"},{"name":"Valletta","isoCode":"60","countryCode":"MT","latitude":"35.89890850","longitude":"14.51455280"},{"name":"Xagħra","isoCode":"61","countryCode":"MT","latitude":"36.05084500","longitude":"14.26748200"},{"name":"Xewkija","isoCode":"62","countryCode":"MT","latitude":"36.02992360","longitude":"14.25994370"},{"name":"Xgħajra","isoCode":"63","countryCode":"MT","latitude":"35.88682820","longitude":"14.54723910"},{"name":"Å»abbar","isoCode":"64","countryCode":"MT","latitude":"35.87247150","longitude":"14.54513540"},{"name":"Å»ebbuÄ¡ Gozo","isoCode":"65","countryCode":"MT","latitude":"36.07164030","longitude":"14.24540800"},{"name":"Å»ebbuÄ¡ Malta","isoCode":"66","countryCode":"MT","latitude":"35.87646480","longitude":"14.43908400"},{"name":"Å»ejtun","isoCode":"67","countryCode":"MT","latitude":"35.85487140","longitude":"14.53639690"},{"name":"Å»urrieq","isoCode":"68","countryCode":"MT","latitude":"35.82163060","longitude":"14.48106480"},{"name":"Agaléga","isoCode":"AG","countryCode":"MU","latitude":"-10.40000000","longitude":"56.61666670"},{"name":"Rivière Noire District","isoCode":"BL","countryCode":"MU","latitude":"-20.37084920","longitude":"57.39486490"},{"name":"Beau Bassin-Rose Hill","isoCode":"BR","countryCode":"MU","latitude":"-20.22303050","longitude":"57.46838300"},{"name":"Cargados Carajos","isoCode":"CC","countryCode":"MU","latitude":"-16.58333300","longitude":"59.61666700"},{"name":"Curepipe","isoCode":"CU","countryCode":"MU","latitude":"-20.31708720","longitude":"57.52652890"},{"name":"Flacq District","isoCode":"FL","countryCode":"MU","latitude":"-20.22578360","longitude":"57.71192740"},{"name":"Grand Port District","isoCode":"GP","countryCode":"MU","latitude":"-20.38515460","longitude":"57.66657420"},{"name":"Moka District","isoCode":"MO","countryCode":"MU","latitude":"-20.23997820","longitude":"57.57592600"},{"name":"Pamplemousses District","isoCode":"PA","countryCode":"MU","latitude":"-20.11360080","longitude":"57.57592600"},{"name":"Port Louis District","isoCode":"PL","countryCode":"MU","latitude":"-20.16089120","longitude":"57.50122220"},{"name":"Port Louis","isoCode":"PU","countryCode":"MU","latitude":"-20.16089120","longitude":"57.50122220"},{"name":"Plaines Wilhems District","isoCode":"PW","countryCode":"MU","latitude":"-20.30548720","longitude":"57.48535610"},{"name":"Quatre Bornes","isoCode":"QB","countryCode":"MU","latitude":"-20.26747180","longitude":"57.47969810"},{"name":"Rodrigues","isoCode":"RO","countryCode":"MU","latitude":"-19.72453850","longitude":"63.42721850"},{"name":"Rivière du Rempart District","isoCode":"RR","countryCode":"MU","latitude":"-20.05609830","longitude":"57.65523890"},{"name":"Savanne District","isoCode":"SA","countryCode":"MU","latitude":"-20.47395300","longitude":"57.48535610"},{"name":"Vacoas-Phoenix","isoCode":"VP","countryCode":"MU","latitude":"-20.29840260","longitude":"57.49383550"},{"name":"Alif Dhaal Atoll","isoCode":"00","countryCode":"MV","latitude":"3.65433020","longitude":"72.80427970"},{"name":"Addu Atoll","isoCode":"01","countryCode":"MV","latitude":"-0.63009950","longitude":"73.15856260"},{"name":"Alif Alif Atoll","isoCode":"02","countryCode":"MV","latitude":"4.08500000","longitude":"72.85154790"},{"name":"Lhaviyani Atoll","isoCode":"03","countryCode":"MV","latitude":"5.37470210","longitude":"73.51229280"},{"name":"Vaavu Atoll","isoCode":"04","countryCode":"MV","latitude":"3.39554380","longitude":"73.51229280"},{"name":"Laamu Atoll","isoCode":"05","countryCode":"MV","latitude":"1.94307370","longitude":"73.41802110"},{"name":"Haa Alif Atoll","isoCode":"07","countryCode":"MV","latitude":"6.99034880","longitude":"72.94605660"},{"name":"Thaa Atoll","isoCode":"08","countryCode":"MV","latitude":"2.43111610","longitude":"73.18216230"},{"name":"Meemu Atoll","isoCode":"12","countryCode":"MV","latitude":"3.00903450","longitude":"73.51229280"},{"name":"Raa Atoll","isoCode":"13","countryCode":"MV","latitude":"5.60064570","longitude":"72.94605660"},{"name":"Faafu Atoll","isoCode":"14","countryCode":"MV","latitude":"3.23094090","longitude":"72.94605660"},{"name":"Dhaalu Atoll","isoCode":"17","countryCode":"MV","latitude":"2.84685020","longitude":"72.94605660"},{"name":"Haa Dhaalu Atoll","isoCode":"23","countryCode":"MV","latitude":"6.57827170","longitude":"72.94605660"},{"name":"Shaviyani Atoll","isoCode":"24","countryCode":"MV","latitude":"6.17511000","longitude":"73.13496050"},{"name":"Noonu Atoll","isoCode":"25","countryCode":"MV","latitude":"5.85512760","longitude":"73.32370800"},{"name":"Kaafu Atoll","isoCode":"26","countryCode":"MV","latitude":"4.45589790","longitude":"73.55941280"},{"name":"Gaafu Alif Atoll","isoCode":"27","countryCode":"MV","latitude":"0.61248130","longitude":"73.32370800"},{"name":"Gaafu Dhaalu Atoll","isoCode":"28","countryCode":"MV","latitude":"0.35880400","longitude":"73.18216230"},{"name":"Gnaviyani Atoll","isoCode":"29","countryCode":"MV","latitude":"-0.30064250","longitude":"73.42391430"},{"name":"Central Province","isoCode":"CE","countryCode":"MV","latitude":null,"longitude":null},{"name":"Malé","isoCode":"MLE","countryCode":"MV","latitude":"46.34888670","longitude":"10.90724890"},{"name":"North Central Province","isoCode":"NC","countryCode":"MV","latitude":null,"longitude":null},{"name":"North Province","isoCode":"NO","countryCode":"MV","latitude":"8.88550270","longitude":"80.27673270"},{"name":"South Central Province","isoCode":"SC","countryCode":"MV","latitude":"7.25649960","longitude":"80.72144170"},{"name":"South Province","isoCode":"SU","countryCode":"MV","latitude":"-21.74820060","longitude":"166.17837390"},{"name":"Upper South Province","isoCode":"US","countryCode":"MV","latitude":"0.23070000","longitude":"73.27948460"},{"name":"Balaka District","isoCode":"BA","countryCode":"MW","latitude":"-15.05065950","longitude":"35.08285880"},{"name":"Blantyre District","isoCode":"BL","countryCode":"MW","latitude":"-15.67785410","longitude":"34.95066250"},{"name":"Central Region","isoCode":"C","countryCode":"MW","latitude":null,"longitude":null},{"name":"Chikwawa District","isoCode":"CK","countryCode":"MW","latitude":"-16.19584460","longitude":"34.77407930"},{"name":"Chiradzulu District","isoCode":"CR","countryCode":"MW","latitude":"-15.74231510","longitude":"35.25879640"},{"name":"Chitipa district","isoCode":"CT","countryCode":"MW","latitude":"-9.70376550","longitude":"33.27002530"},{"name":"Dedza District","isoCode":"DE","countryCode":"MW","latitude":"-14.18945850","longitude":"34.24215970"},{"name":"Dowa District","isoCode":"DO","countryCode":"MW","latitude":"-13.60412560","longitude":"33.88577470"},{"name":"Karonga District","isoCode":"KR","countryCode":"MW","latitude":"-9.90363650","longitude":"33.97500180"},{"name":"Kasungu District","isoCode":"KS","countryCode":"MW","latitude":"-13.13670650","longitude":"33.25879300"},{"name":"Lilongwe District","isoCode":"LI","countryCode":"MW","latitude":"-14.04752280","longitude":"33.61757700"},{"name":"Likoma District","isoCode":"LK","countryCode":"MW","latitude":"-12.05840050","longitude":"34.73540310"},{"name":"Mchinji District","isoCode":"MC","countryCode":"MW","latitude":"-13.74015250","longitude":"32.98883190"},{"name":"Mangochi District","isoCode":"MG","countryCode":"MW","latitude":"-14.13882480","longitude":"35.03881640"},{"name":"Machinga District","isoCode":"MH","countryCode":"MW","latitude":"-14.94072
1630","longitude":"35.47819260"},{"name":"Mulanje District","isoCode":"MU","countryCode":"MW","latitude":"-15.93464340","longitude":"35.52200120"},{"name":"Mwanza District","isoCode":"MW","countryCode":"MW","latitude":"-2.46711970","longitude":"32.89868120"},{"name":"Mzimba District","isoCode":"MZ","countryCode":"MW","latitude":"-11.74754520","longitude":"33.52800720"},{"name":"Northern Region","isoCode":"N","countryCode":"MW","latitude":null,"longitude":null},{"name":"Nkhata Bay District","isoCode":"NB","countryCode":"MW","latitude":"-11.71850420","longitude":"34.33103640"},{"name":"Ntchisi District","isoCode":"NI","countryCode":"MW","latitude":"-13.28419920","longitude":"33.88577470"},{"name":"Nkhotakota District","isoCode":"NK","countryCode":"MW","latitude":"-12.75419610","longitude":"34.24215970"},{"name":"Nsanje District","isoCode":"NS","countryCode":"MW","latitude":"-16.72882020","longitude":"35.17087410"},{"name":"Ntcheu District","isoCode":"NU","countryCode":"MW","latitude":"-14.90375380","longitude":"34.77407930"},{"name":"Phalombe District","isoCode":"PH","countryCode":"MW","latitude":"-15.70920380","longitude":"35.65328480"},{"name":"Rumphi District","isoCode":"RU","countryCode":"MW","latitude":"-10.78515370","longitude":"34.33103640"},{"name":"Southern Region","isoCode":"S","countryCode":"MW","latitude":"32.75049570","longitude":"-97.33154760"},{"name":"Salima District","isoCode":"SA","countryCode":"MW","latitude":"-13.68095860","longitude":"34.41982430"},{"name":"Thyolo District","isoCode":"TH","countryCode":"MW","latitude":"-16.12991770","longitude":"35.12687810"},{"name":"Zomba District","isoCode":"ZO","countryCode":"MW","latitude":"-15.37658570","longitude":"35.33565180"},{"name":"Aguascalientes","isoCode":"AGU","countryCode":"MX","latitude":"21.88525620","longitude":"-102.29156770"},{"name":"Baja California","isoCode":"BCN","countryCode":"MX","latitude":"30.84063380","longitude":"-115.28375850"},{"name":"Baja California Sur","isoCode":"BCS","countryCode":"MX","latitude":"26.04444460","longitude":"-111.66607250"},{"name":"Campeche","isoCode":"CAM","countryCode":"MX","latitude":"19.83012510","longitude":"-90.53490870"},{"name":"Ciudad de México","isoCode":"CDMX","countryCode":"MX","latitude":"19.43260770","longitude":"-99.13320800"},{"name":"Chihuahua","isoCode":"CHH","countryCode":"MX","latitude":"28.63299570","longitude":"-106.06910040"},{"name":"Chiapas","isoCode":"CHP","countryCode":"MX","latitude":"16.75693180","longitude":"-93.12923530"},{"name":"Coahuila de Zaragoza","isoCode":"COA","countryCode":"MX","latitude":"27.05867600","longitude":"-101.70682940"},{"name":"Colima","isoCode":"COL","countryCode":"MX","latitude":"19.24523420","longitude":"-103.72408680"},{"name":"Durango","isoCode":"DUR","countryCode":"MX","latitude":"37.27528000","longitude":"-107.88006670"},{"name":"Guerrero","isoCode":"GRO","countryCode":"MX","latitude":"17.43919260","longitude":"-99.54509740"},{"name":"Guanajuato","isoCode":"GUA","countryCode":"MX","latitude":"21.01901450","longitude":"-101.25735860"},{"name":"Hidalgo","isoCode":"HID","countryCode":"MX","latitude":"26.10035470","longitude":"-98.26306840"},{"name":"Jalisco","isoCode":"JAL","countryCode":"MX","latitude":"20.65953820","longitude":"-103.34943760"},{"name":"Estado de México","isoCode":"MEX","countryCode":"MX","latitude":"23.63450100","longitude":"-102.55278400"},{"name":"Michoacán de Ocampo","isoCode":"MIC","countryCode":"MX","latitude":"19.56651920","longitude":"-101.70682940"},{"name":"Morelos","isoCode":"MOR","countryCode":"MX","latitude":"18.68130490","longitude":"-99.10134980"},{"name":"Nayarit","isoCode":"NAY","countryCode":"MX","latitude":"21.75138440","longitude":"-104.84546190"},{"name":"Nuevo León","isoCode":"NLE","countryCode":"MX","latitude":"25.59217200","longitude":"-99.99619470"},{"name":"Oaxaca","isoCode":"OAX","countryCode":"MX","latitude":"17.07318420","longitude":"-96.72658890"},{"name":"Puebla","isoCode":"PUE","countryCode":"MX","latitude":"19.04143980","longitude":"-98.20627270"},{"name":"Querétaro","isoCode":"QUE","countryCode":"MX","latitude":"20.58879320","longitude":"-100.38988810"},{"name":"Quintana Roo","isoCode":"ROO","countryCode":"MX","latitude":"19.18173930","longitude":"-88.47913760"},{"name":"Sinaloa","isoCode":"SIN","countryCode":"MX","latitude":"25.17210910","longitude":"-107.47951730"},{"name":"San Luis PotosÃ","isoCode":"SLP","countryCode":"MX","latitude":"22.15646990","longitude":"-100.98554090"},{"name":"Sonora","isoCode":"SON","countryCode":"MX","latitude":"37.98294960","longitude":"-120.38217240"},{"name":"Tabasco","isoCode":"TAB","countryCode":"MX","latitude":"17.84091730","longitude":"-92.61892730"},{"name":"Tamaulipas","isoCode":"TAM","countryCode":"MX","latitude":"24.26694000","longitude":"-98.83627550"},{"name":"Tlaxcala","isoCode":"TLA","countryCode":"MX","latitude":"19.31815400","longitude":"-98.23749540"}
1,{"name":"Veracruz de Ignacio de la Llave","isoCode":"VER","countryCode":"MX","latitude":"19.17377300","longitude":"-96.13422410"},{"name":"Yucatán","isoCode":"YUC","countryCode":"MX","latitude":"20.70987860","longitude":"-89.09433770"},{"name":"Zacatecas","isoCode":"ZAC","countryCode":"MX","latitude":"22.77085550","longitude":"-102.58324260"},{"name":"Johor","isoCode":"01","countryCode":"MY","latitude":"1.48536820","longitude":"103.76181540"},{"name":"Kedah","isoCode":"02","countryCode":"MY","latitude":"6.11839640","longitude":"100.36845950"},{"name":"Kelantan","isoCode":"03","countryCode":"MY","latitude":"6.12539690","longitude":"102.23807100"},{"name":"Malacca","isoCode":"04","countryCode":"MY","latitude":"2.18959400","longitude":"102.25008680"},{"name":"Negeri Sembilan","isoCode":"05","countryCode":"MY","latitude":"2.72580580","longitude":"101.94237820"},{"name":"Pahang","isoCode":"06","countryCode":"MY","latitude":"3.81263180","longitude":"103.32562040"},{"name":"Penang","isoCode":"07","countryCode":"MY","latitude":"5.41639350","longitude":"100.33267860"},{"name":"Perak","isoCode":"08","countryCode":"MY","latitude":"4.59211260","longitude":"101.09010900"},{"name":"Perlis","isoCode":"09","countryCode":"MY","latitude":"29.92270940","longitude":"-90.12285590"},{"name":"Selangor","isoCode":"10","countryCode":"MY","latitude":"3.07383790","longitude":"101.51834690"},{"name":"Terengganu","isoCode":"11","countryCode":"MY","latitude":"5.31169160","longitude":"103.13241540"},{"name":"Sabah","isoCode":"12","countryCode":"MY","latitude":"5.97883980","longitude":"116.07531990"},{"name":"Sarawak","isoCode":"13","countryCode":"MY","latitude":"1.55327830","longitude":"110.35921270"},{"name":"Kuala Lumpur","isoCode":"14","countryCode":"MY","latitude":"3.13900300","longitude":"101.68685500"},{"name":"Labuan","isoCode":"15","countryCode":"MY","latitude":"5.28314560","longitude":"115.23082500"},{"name":"Putrajaya","isoCode":"16","countryCode":"MY","latitude":"2.92636100","longitude":"101.69644500"},{"name":"Niassa Province","isoCode":"A","countryCode":"MZ","latitude":"-12.78262020","longitude":"36.60939260"},{"name":"Manica Province","isoCode":"B","countryCode":"MZ","latitude":"-19.50597870","longitude":"33.43835300"},{"name":"Gaza Province","isoCode":"G","countryCode":"MZ","latitude":"-23.02219280","longitude":"32.71813750"},{"name":"Inhambane Province","isoCode":"I","countryCode":"MZ","latitude":"-22.85279970","longitude":"34.55087580"},{"name":"Maputo Province","isoCode":"L","countryCode":"MZ","latitude":"-25.25698760","longitude":"32.53727410"},{"name":"Maputo","isoCode":"MPM","countryCode":"MZ","latitude":"-25.96924800","longitude":"32.57317460"},{"name":"Nampula Province","isoCode":"N","countryCode":"MZ","latitude":"-14.76049310","longitude":"39.32062410"},{"name":"Cabo Delgado Province","isoCode":"P","countryCode":"MZ","latitude":"-12.33354740","longitude":"39.32062410"},{"name":"Zambezia Province","isoCode":"Q","countryCode":"MZ","latitude":"-16.56389870","longitude":"36.60939260"},{"name":"Sofala Province","isoCode":"S","countryCode":"MZ","latitude":"-19.20390730","longitude":"34.86241660"},{"name":"Tete Province","isoCode":"T","countryCode":"MZ","latitude":"-15.65960560","longitude":"32.71813750"},{"name":"Zambezi Region","isoCode":"CA","countryCode":"NA","latitude":"-17.81934190","longitude":"23.95364660"},{"name":"Erongo Region","isoCode":"ER","countryCode":"NA","latitude":"-22.25656820","longitude":"15.40680790"},{"name":"Hardap Region","isoCode":"HA","countryCode":"NA","latitude":"-24.23101340","longitude":"17.66888700"},{"name":"Karas Region","isoCode":"KA","countryCode":"NA","latitude":"-26.84296450","longitude":"17.29028390"},{"name":"Kavango East Region","isoCode":"KE","countryCode":"NA","latitude":"-18.27104800","longitude":"18.42760470"},{"name":"Khomas Region","isoCode":"KH","countryCode":"NA","latitude":"-22.63778540","longitude":"17.10119310"},{"name":"Kunene Region","isoCode":"KU","countryCode":"NA","latitude":"-19.40863170","longitude":"13.91439900"},{"name":"Kavango West Region","isoCode":"KW","countryCode":"NA","latitude":"-18.27104800","longitude":"18.42760470"},{"name":"Otjozondjupa Region","isoCode":"OD","countryCode":"NA","latitude":"-20.54869160","longitude":"17.66888700"},{"name":"Omaheke Region","isoCode":"OH","countryCode":"NA","latitude":"-21.84666510","longitude":"19.18800470"},{"name":"Oshana Region","isoCode":"ON","countryCode":"NA","latitude":"-18.43050640","longitude":"15.68817880"},{"name":"Omusati Region","isoCode":"OS","countryCode":"NA","latitude":"-18.40702940","longitude":"14.84546190"},{"name":"Oshikoto Region","isoCode":"OT","countryCode":"NA","latitude":"-18.41525750","longitude":"16.91225100"},{"name":"Ohangwena Region","isoCode":"OW","countryCode":"NA","latitude":"-17.59792910","longitude":"16.81783770"},{"name":"Agadez Region","isoCode":"1","countryCode":"NE","latitude":"20.66707520","longitude":"12.07182810"},{"name":"Diffa Region","isoCode":"2","countryCode":"NE","latitude":"13.67686470","longitude":"12.71351210"},{"name":"Dosso Region","isoCode":"3","countryCode":"NE","latitude":"13.15139470","longitude":"3.41955270"},{"name":"Maradi Region","isoCode":"4","countryCode":"NE","latitude":"13.80180740","longitude":"7.43813550"},{"name":"Tahoua Region","isoCode":"5","countryCode":"NE","latitude":"16.09025430","longitude":"5.39395510"},{"name":"Tillabéri Region","isoCode":"6","countryCode":"NE","latitude":"14.64895250","longitude":"2.14502450"},{"name":"Zinder Region","isoCode":"7","countryCode":"NE","latitude":"15.17188810","longitude":"10.26001250"},{"name":"Abia","isoCode":"AB","countryCode":"NG","latitude":"5.45273540","longitude":"7.52484140"},{"name":"Adamawa","isoCode":"AD","countryCode":"NG","latitude":"9.32647510","longitude":"12.39838530"},{"name":"Akwa Ibom","isoCode":"AK","countryCode":"NG","latitude":"4.90573710","longitude":"7.85366750"},{"name":"Anambra","isoCode":"AN","countryCode":"NG","latitude":"6.22089970","longitude":"6.93695590"},{"name":"Bauchi","isoCode":"BA","countryCode":"NG","latitude":"10.77606240","longitude":"9.99919430"}
1,{"name":"Benue","isoCode":"BE","countryCode":"NG","latitude":"7.33690240","longitude":"8.74036870"},{"name":"Borno","isoCode":"BO","countryCode":"NG","latitude":"11.88463560","longitude":"13.15196650"},{"name":"Bayelsa","isoCode":"BY","countryCode":"NG","latitude":"4.77190710","longitude":"6.06985260"},{"name":"Cross River","isoCode":"CR","countryCode":"NG","latitude":"5.87017240","longitude":"8.59880140"},{"name":"Delta","isoCode":"DE","countryCode":"NG","latitude":"33.74537840","longitude":"-90.73545080"},{"name":"Ebonyi","isoCode":"EB","countryCode":"NG","latitude":"6.26492320","longitude":"8.01373020"},{"name":"Edo","isoCode":"ED","countryCode":"NG","latitude":"6.63418310","longitude":"5.93040560"},{"name":"Ekiti","isoCode":"EK","countryCode":"NG","latitude":"7.71898620","longitude":"5.31095050"},{"name":"Enugu","isoCode":"EN","countryCode":"NG","latitude":"6.53635300","longitude":"7.43561940"},{"name":"Abuja Federal Capital Territory","isoCode":"FC","countryCode":"NG","latitude":"8.89406910","longitude":"7.18604020"},{"name":"Gombe","isoCode":"GO","countryCode":"NG","latitude":"10.36377950","longitude":"11.19275870"},{"name":"Imo","isoCode":"IM","countryCode":"NG","latitude":"5.57201220","longitude":"7.05882190"},{"name":"Jigawa","isoCode":"JI","countryCode":"NG","latitude":"12.22801200","longitude":"9.56158670"},{"name":"Kaduna","isoCode":"KD","countryCode":"NG","latitude":"10.37640060","longitude":"7.70945370"},{"name":"Kebbi","isoCode":"KE","countryCode":"NG","latitude":"11.49420030","longitude":"4.23333550"},{"name":"Kano","isoCode":"KN","countryCode":"NG","latitude":"11.74706980","longitude":"8.52471070"},{"name":"Kogi","isoCode":"KO","countryCode":"NG","latitude":"7.73373250","longitude":"6.69058360"},{"name":"Katsina","isoCode":"KT","countryCode":"NG","latitude":"12.37967070","longitude":"7.63057480"},{"name":"Kwara","isoCode":"KW","countryCode":"NG","latitude":"8.96689610","longitude":"4.38740510"},{"name":"Lagos","isoCode":"LA","countryCode":"NG","latitude":"6.52437930","longitude":"3.37920570"},{"name":"Nasarawa","isoCode":"NA","countryCode":"NG","latitude":"8.49979080","longitude":"8.19969370"},{"name":"Niger","isoCode":"NI","countryCode":"NG","latitude":"9.93092240","longitude":"5.59832100"},{"name":"Ogun","isoCode":"OG","countryCode":"NG","latitude":"6.99797470","longitude":"3.47373780"},{"name":"Ondo","isoCode":"ON","countryCode":"NG","latitude":"6.91486820","longitude":"5.14781440"},{"name":"Osun","isoCode":"OS","countryCode":"NG","latitude":"7.56289640","longitude":"4.51995930"},{"name":"Oyo","isoCode":"OY","countryCode":"NG","latitude":"8.15738090","longitude":"3.61465340"},{"name":"Plateau","isoCode":"PL","countryCode":"NG","latitude":"9.21820930","longitude":"9.51794880"},{"name":"Rivers","isoCode":"RI","countryCode":"NG","latitude":"5.02134200","longitude":"6.43760220"},{"name":"Sokoto","isoCode":"SO","countryCode":"NG","latitude":"13.05331430","longitude":"5.32227220"},{"name":"Taraba","isoCode":"TA","countryCode":"NG","latitude":"7.99936160","longitude":"10.77398630"},{"name":"Yobe","isoCode":"YO","countryCode":"NG","latitude":"12.29387600","longitude":"11.43904110"},{"name":"Zamfara","isoCode":"ZA","countryCode":"NG","latitude":"12.12218050","longitude":"6.22358190"},{"name":"North Caribbean Coast","isoCode":"AN","countryCode":"NI","latitude":"13.83944560","longitude":"-83.93208060"},{"name":"South Caribbean Coast","isoCode":"AS","countryCode":"NI","latitude":"12.19185020","longitude":"-84.10128610"},{"name":"Boaco","isoCode":"BO","countryCode":"NI","latitude":"12.46928400","longitude":"-85.66146820"},{"name":"Carazo","isoCode":"CA","countryCode":"NI","latitude":"11.72747290","longitude":"-86.21584970"},{"name":"Chinandega","isoCode":"CI","countryCode":"NI","latitude":"12.88200620","longitude":"-87.14228950"},{"name":"Chontales","isoCode":"CO","countryCode":"NI","latitude":"11.93947170","longitude":"-85.18940450"},{"name":"EstelÃ","isoCode":"ES","countryCode":"NI","latitude":"13.08511390","longitude":"-86.36301970"},{"name":"Granada","isoCode":"GR","countryCode":"NI","latitude":"11.93440730","longitude":"-85.95600050"},{"name":"Jinotega","isoCode":"JI","countryCode":"NI","latitude":"13.08839070","longitude":"-85.99939970"},{"name":"León","isoCode":"LE","countryCode":"NI","latitude":"12.50920370","longitude":"-86.66110830"}
1,{"name":"Madriz","isoCode":"MD","countryCode":"NI","latitude":"13.47260050","longitude":"-86.45920910"},{"name":"Managua","isoCode":"MN","countryCode":"NI","latitude":"12.13916990","longitude":"-86.33767610"},{"name":"Masaya","isoCode":"MS","countryCode":"NI","latitude":"11.97593280","longitude":"-86.07334980"},{"name":"Matagalpa","isoCode":"MT","countryCode":"NI","latitude":"12.94984360","longitude":"-85.43755740"},{"name":"Nueva Segovia","isoCode":"NS","countryCode":"NI","latitude":"13.76570610","longitude":"-86.53700390"},{"name":"Rivas","isoCode":"RI","countryCode":"NI","latitude":"11.40234900","longitude":"-85.68457800"},{"name":"RÃo San Juan","isoCode":"SJ","countryCode":"NI","latitude":"11.47816100","longitude":"-84.77333250"},{"name":"Bonaire","isoCode":"BQ1","countryCode":"NL","latitude":"12.20189020","longitude":"-68.26238220"},{"name":"Saba","isoCode":"BQ2","countryCode":"NL","latitude":"17.63546420","longitude":"-63.23267630"},{"name":"Sint Eustatius","isoCode":"BQ3","countryCode":"NL","latitude":"17.48903060","longitude":"-62.97355500"},{"name":"Drenthe","isoCode":"DR","countryCode":"NL","latitude":"52.94760120","longitude":"6.62305860"},{"name":"Flevoland","isoCode":"FL","countryCode":"NL","latitude":"52.52797810","longitude":"5.59535080"},{"name":"Friesland","isoCode":"FR","countryCode":"NL","latitude":"53.16416420","longitude":"5.78175420"},{"name":"Gelderland","isoCode":"GE","countryCode":"NL","latitude":"52.04515500","longitude":"5.87182350"},{"name":"Groningen","isoCode":"GR","countryCode":"NL","latitude":"53.21938350","longitude":"6.56650170"},{"name":"Limburg","isoCode":"LI","countryCode":"NL","latitude":"51.44272380","longitude":"6.06087260"},{"name":"North Brabant","isoCode":"NB","countryCode":"NL","latitude":"51.48265370","longitude":"5.23216870"},{"name":"North Holland","isoCode":"NH","countryCode":"NL","latitude":"52.52058690","longitude":"4.78847400"},{"name":"Overijssel","isoCode":"OV","countryCode":"NL","latitude":"52.43878140","longitude":"6.50164110"},{"name":"Utrecht","isoCode":"UT","countryCode":"NL","latitude":"52.09073740","longitude":"5.12142010"},{"name":"Zeeland","isoCode":"ZE","countryCode":"NL","latitude":"51.49403090","longitude":"3.84968150"},{"name":"South Holland","isoCode":"ZH","countryCode":"NL","latitude":"41.60086810","longitude":"-87.60698940"},{"name":"Ãstfold","isoCode":"01","countryCode":"NO","latitude":"59.25582860","longitude":"11.32790060"},{"name":"Akershus","isoCode":"02","countryCode":"NO","latitude":"28.37042030","longitude":"-81.54680580"},{"name":"Oslo","isoCode":"03","countryCode":"NO","latitude":"59.91386880","longitude":"10.75224540"},{"name":"Hedmark","isoCode":"04","countryCode":"NO","latitude":"61.39673110","longitude":"11.56273690"},{"name":"Oppland","isoCode":"05","countryCode":"NO","latitude":"61.54227520","longitude":"9.71663150"},{"name":"Buskerud","isoCode":"06","countryCode":"NO","latitude":"60.48460250","longitude":"8.69837640"},{"name":"Vestfold","isoCode":"07","countryCode":"NO","latitude":"59.17078620","longitude":"10.11443550"},{"name":"Telemark","isoCode":"08","countryCode":"NO","latitude":"59.39139850","longitude":"8.32112090"},{"name":"Vest-Agder","isoCode":"10","countryCode":"NO","latitude":"58.09990810","longitude":"6.58698090"},{"name":"Rogaland","isoCode":"11","countryCode":"NO","latitude":"59.14895440","longitude":"6.01434320"},{"name":"Hordaland","isoCode":"12","countryCode":"NO","latitude":"60.27336740","longitude":"5.72201940"},{"name":"Sogn og Fjordane","isoCode":"14","countryCode":"NO","latitude":"61.55394350","longitude":"6.33258790"},{"name":"Møre og Romsdal","isoCode":"15","countryCode":"NO","latitude":"62.84068330","longitude":"7.00714300"},{"name":"Sør-Trøndelag","isoCode":"16","countryCode":"NO","latitude":"63.01368230","longitude":"10.34871360"},{"name":"Nord-Trøndelag","isoCode":"17","countryCode":"NO","latitude":"64.43707920","longitude":"11.74629500"},{"name":"Nordland","isoCode":"18","countryCode":"NO","latitude":"67.69305800","longitude":"12.70739360"},{"name":"Troms","isoCode":"19","countryCode":"NO","latitude":"69.81782420","longitude":"18.78193650"},{"name":"Finnmark","isoCode":"20","countryCode":"NO","latitude":"70.48303880","longitude":"26.01351070"},{"name":"Svalbard","isoCode":"21","countryCode":"NO","latitude":"77.87497250","longitude":"20.97518210"},{"name":"Jan Mayen","isoCode":"22","countryCode":"NO","latitude":"71.03181800","longitude":"-8.29203460"},{"name":"Trøndelag","isoCode":"50","countryCode":"NO","latitude":"63.54201250","longitude":"10.93692670"},{"name":"Central Region","isoCode":"1","countryCode":"NP","latitude":null,"longitude":null},{"name":"Mid-Western Region","isoCode":"2","countryCode":"NP","latitude":"38.41118410","longitude":"-90.38320980"},{"name":"Western Region","isoCode":"3","countryCode":"NP","latitude":null,"longitude":null},{"name":"Eastern Development Region","isoCode":"4","countryCode":"NP","latitude":"27.33090720","longitude":"87.06242610"},{"name":"Far-Western Development Region","isoCode":"5","countryCode":"NP","latitude":"29.29878710","longitude":"80.98710740"},{"name":"Bagmati Zone","isoCode":"BA","countryCode":"NP","latitude":"28.03675770","longitude":"85.43755740"},{"name":"Bheri Zone","isoCode":"BH","countryCode":"NP","latitude":"28.51745600","longitude":"81.77870210"},{"name":"Dhaulagiri Zone","isoCode":"DH","countryCode":"NP","latitude":"28.61117600","longitude":"83.50702030"},{"name":"Gandaki Zone","isoCode":"GA","countryCode":"NP","latitude":"28.37320370","longitude":"84.43827210"},{"name":"Janakpur Zone","isoCode":"JA","countryCode":"NP","latitude":"27.21108990","longitude":"86.01215730"},{"name":"Karnali Zone","isoCode":"KA","countryCode":"NP","latitude":"29.38625550","longitude":"82.38857830"},{"name":"Kosi Zone","isoCode":"KO","countryCode":"NP","latitude":"27.05365240","longitude":"87.30161320"},{"name":"Lumbini Zone","isoCode":"LU","countryCode":"NP","latitude":"27.45000000","longitude":"83.25000000"},{"name":"Mahakali Zone","isoCode":"MA","countryCode":"NP","latitude":"29.36010790","longitude":"80.54384500"},{"name":"Mechi Zone","isoCode":"ME","countryCode":"NP","latitude":"26.87600070","longitude":"87.93348030"},{"name":"Narayani Zone","isoCode":"NA","countryCode":"NP","latitude":"27.36117660","longitude":"84.85679320"},{"name":"Rapti Zone","isoCode":"RA","countryCode":"NP","latitude":"28.27434700","longitude":"82.38857830"},{"name":"Sagarmatha Zone","isoCode":"SA","countryCode":"NP","latitude":"27.32382630","longitude":"86.74163740"},{"name":"Seti Zone","isoCode":"SE","countryCode":"NP","latitude":"29.69054270","longitude":"81.33994140"},{"name":"Aiwo District","isoCode":"01","countryCode":"NR","latitude":"-0.53400120","longitude":"166.91388730"},{"name":"Anabar District","isoCode":"02","countryCode":"NR","latitude":"-0.51335170","longitude":"166.94846240"},{"name":"Anetan District","isoCode":"03","countryCode":"NR","latitude":"-0.50643430","longitude":"166.94270060"},{"name":"Anibare District","isoCode":"04","countryCode":"NR","latitude":"-0.52947580","longitude":"166.95134320"},{"name":"Baiti District","isoCode":"05","countryCode":"NR","latitude":"-0.51043100","longitude":"166.92757440"},{"name":"Boe District","isoCode":"06","countryCode":"NR","latitude":"39.07327760","longitude":"-94.57104980"},{"name":"Buada District","isoCode":"07","countryCode":"NR","latitude":"-0.53287770","longitude":"166.92685410"},{"name":"Denigomodu District","isoCode":"08","countryCode":"NR","latitude":"-0.52479640","longitude":"166.91676890"},{"name":"Ewa District","isoCode":"09","countryCode":"NR","latitude":"-0.50872410","longitude":"166.93693840"},{"name":"Ijuw District","isoCode":"10","countryCode":"NR","latitude":"-0.52027670","longitude":"166.95710460"},{"name":"Meneng District","isoCode":"11","countryCode":"NR","latitude":"-0.54672400","longitude":"166.93837900"},{"name":"Nibok District","isoCode":"12","countryCode":"NR","latitude":"-0.51962080","longitude":"166.91893010"},{"name":"Uaboe District","isoCode":"13","countryCode":"NR","latitude":"-0.52022220","longitude":"166.93117610"},{"name":"Yaren District","isoCode":"14","countryCode":"NR","latitude":"-0.54668570","longitude":"166.92109130"},{"name":"Auckland Region","isoCode":"AUK","countryCode":"NZ","latitude":"-36.66753280","longitude":"174.77333250"},{"name":"Bay of Plenty Region","isoCode":"BOP","countryCode":"NZ","latitude":"-37.42339170","longitude":"176.74163740"},{"name":"Canterbury Region","isoCode":"CAN","countryCode":"NZ","latitude":"-43.75422750","longitude":"171.16372450"},{"name":"Chatham Islands","isoCode":"CIT","countryCode":"NZ","latitude":"-44.00575230","longitude":"-176.54006740"},{"name":"Gisborne District","isoCode":"GIS","countryCode":"NZ","latitude":"-38.13581740","longitude":"178.32393090"},{"name":"Hawke\'s Bay Region","isoCode":"HKB","countryCode":"NZ","latitude":"-39.60165970","longitude":"176.58044730"},{"name":"Marlborough Region","isoCode":"MBH","countryCode":"NZ","latitude":"-41.59168830","longitude":"173.76240530"},{"name":"Manawatu-Wanganui Region","isoCode":"MWT","countryCode":"NZ","latitude":"-39.72733560","longitude":"175.43755740"},{"name":"Nelson Region","isoCode":"NSN","countryCode":"NZ","latitude":"-41.29853970","longitude":"173.24414910"},{"name":"Northland Region","isoCode":"NTL","countryCode":"NZ","latitude":"-35.41361720","longitude":"173.93208060"},{"name":"Otago Region","isoCode":"OTA","countryCode":"NZ","latitude":"-45.47906710","longitude":"170.15475670"},{"name":"Southland Region","isoCode":"STL","countryCode":"NZ","latitude":"-45.84891590","longitude":"167.67553870"},{"name":"Tasman District","isoCode":"TAS","countryCode":"NZ","latitude":"-41.45711840","longitude":"172.82097400"},{"name":"Taranaki Region","isoCode":"TKI","countryCode":"NZ","latitude":"-39.35381490","longitude":"174.43827210"},{"name":"Wellington Region","isoCode":"WGN","countryCode":"NZ","latitude":"-41.02993230","longitude":"175.43755740"},{"name":"Waikato Region","isoCode":"WKO","countryCode":"NZ","latitude":"-37.61908620","longitude":"175.02334600"},{"name":"West Coast Region","isoCode":"WTC","countryCode":"NZ","latitude":"62.41136340","longitude":"-149.07297140"},{"name":"Al Batinah Region","isoCode":"BA","countryCode":"OM","latitude":"24.34198460","longitude":"56.72989040"},{"name":"Al Batinah South Governorate","isoCode":"BJ","countryCode":"OM","latitude":"23.43149030","longitude":"57.42397960"},{"name":"Al Batinah North Governorate","isoCode":"BS","countryCode":"OM","latitude":"24.34198460","longitude":"56.72989040"},{"name":"Al Buraimi Governorate","isoCode":"BU","countryCode":"OM","latitude":"24.16714130","longitude":"56.11422530"}
1,{"name":"Ad Dakhiliyah Governorate","isoCode":"DA","countryCode":"OM","latitude":"22.85887580","longitude":"57.53943560"},{"name":"Muscat Governorate","isoCode":"MA","countryCode":"OM","latitude":"23.58803070","longitude":"58.38287170"},{"name":"Musandam Governorate","isoCode":"MU","countryCode":"OM","latitude":"26.19861440","longitude":"56.24609490"},{"name":"Ash Sharqiyah Region","isoCode":"SH","countryCode":"OM","latitude":"22.71411960","longitude":"58.53080640"},{"name":"Ash Sharqiyah South Governorate","isoCode":"SJ","countryCode":"OM","latitude":"22.01582490","longitude":"59.32519220"},{"name":"Ash Sharqiyah North Governorate","isoCode":"SS","countryCode":"OM","latitude":"22.71411960","longitude":"58.53080640"},{"name":"Al Wusta Governorate","isoCode":"WU","countryCode":"OM","latitude":"19.95710780","longitude":"56.27568460"},{"name":"Ad Dhahirah Governorate","isoCode":"ZA","countryCode":"OM","latitude":"23.21616740","longitude":"56.49074440"},{"name":"Dhofar Governorate","isoCode":"ZU","countryCode":"OM","latitude":"17.03221210","longitude":"54.14252140"},{"name":"Bocas del Toro Province","isoCode":"1","countryCode":"PA","latitude":"9.41655210","longitude":"-82.52077870"},{"name":"Panamá Oeste Province","isoCode":"10","countryCode":"PA","latitude":"9.11967510","longitude":"-79.29021330"},{"name":"Coclé Province","isoCode":"2","countryCode":"PA","latitude":"8.62660680","longitude":"-80.36586500"},{"name":"Colón Province","isoCode":"3","countryCode":"PA","latitude":"9.18519890","longitude":"-80.05349230"},{"name":"Chiriquà Province","isoCode":"4","countryCode":"PA","latitude":"8.58489800","longitude":"-82.38857830"},{"name":"Darién Province","isoCode":"5","countryCode":"PA","latitude":"7.86817130","longitude":"-77.83672820"},{"name":"Herrera Province","isoCode":"6","countryCode":"PA","latitude":"7.77042820","longitude":"-80.72144170"},{"name":"Los Santos Province","isoCode":"7","countryCode":"PA","latitude":"7.59093020","longitude":"-80.36586500"},{"name":"Panamá Province","isoCode":"8","countryCode":"PA","latitude":"9.11967510","longitude":"-79.29021330"},{"name":"Veraguas Province","isoCode":"9","countryCode":"PA","latitude":"8.12310330","longitude":"-81.07546570"},{"name":"Emberá-Wounaan Comarca","isoCode":"EM","countryCode":"PA","latitude":"8.37669830","longitude":"-77.65361250"},{"name":"Guna Yala","isoCode":"KY","countryCode":"PA","latitude":"9.23443950","longitude":"-78.19262500"},{"name":"Ngöbe-Buglé Comarca","isoCode":"NB","countryCode":"PA","latitude":"8.65958330","longitude":"-81.77870210"},{"name":"Amazonas","isoCode":"AMA","countryCode":"PE","latitude":null,"longitude":null},{"name":"Ãncash","isoCode":"ANC","countryCode":"PE","latitude":"-9.32504970","longitude":"-77.56194190"},{"name":"ApurÃmac","isoCode":"APU","countryCode":"PE","latitude":"-14.05045330","longitude":"-73.08774900"},{"name":"Arequipa","isoCode":"ARE","countryCode":"PE","latitude":"-16.40904740","longitude":"-71.53745100"},{"name":"Ayacucho","isoCode":"AYA","countryCode":"PE","latitude":"-13.16387370","longitude":"-74.22356410"},{"name":"Cajamarca","isoCode":"CAJ","countryCode":"PE","latitude":"-7.16174650","longitude":"-78.51278550"},{"name":"Callao","isoCode":"CAL","countryCode":"PE","latitude":"-12.05084910","longitude":"-77.12598430"},{"name":"Cusco","isoCode":"CUS","countryCode":"PE","latitude":"-13.53195000","longitude":"-71.96746260"},{"name":"Huanuco","isoCode":"HUC","countryCode":"PE","latitude":"-9.92076480","longitude":"-76.24108430"},{"name":"Huancavelica","isoCode":"HUV","countryCode":"PE","latitude":"-12.78619780","longitude":"-74.97640240"},{"name":"Ica","isoCode":"ICA","countryCode":"PE","latitude":"42.35288320","longitude":"-71.04300970"},{"name":"JunÃn","isoCode":"JUN","countryCode":"PE","latitude":"-11.15819250","longitude":"-75.99263060"},{"name":"La Libertad","isoCode":"LAL","countryCode":"PE","latitude":"13.49069700","longitude":"-89.30846070"},{"name":"Lambayeque","isoCode":"LAM","countryCode":"PE","latitude":"-6.71976660","longitude":"-79.90807570"},{"name":"Lima","isoCode":"LIM","countryCode":"PE","latitude":"-12.04637310","longitude":"-77.04275400"},{"name":"Loreto","isoCode":"LOR","countryCode":"PE","latitude":"-4.37416430","longitude":"-76.13042640"},{"name":"Madre de Dios","isoCode":"MDD","countryCode":"PE","latitude":"-11.76687050","longitude":"-70.81199530"},{"name":"Moquegua","isoCode":"MOQ","countryCode":"PE","latitude":"-17.19273610","longitude":"-70.93281380"},{"name":"Pasco","isoCode":"PAS","countryCode":"PE","latitude":"46.23050490","longitude":"-119.09223160"},{"name":"Piura","isoCode":"PIU","countryCode":"PE","latitude":"-5.17828840","longitude":"-80.65488820"},{"name":"Puno","isoCode":"PUN","countryCode":"PE","latitude":"-15.84022180","longitude":"-70.02188050"},{"name":"San MartÃn","isoCode":"SAM","countryCode":"PE","latitude":"37.08494640","longitude":"-121.61022160"},{"name":"Tacna","isoCode":"TAC","countryCode":"PE","latitude":"-18.00656790","longitude":"-70.24627410"},{"name":"Tumbes","isoCode":"TUM","countryCode":"PE","latitude":"-3.55649210","longitude":"-80.42708850"},{"name":"Ucayali","isoCode":"UCA","countryCode":"PE","latitude":"-9.82511830","longitude":"-73.08774900"},{"name":"Chimbu Province","isoCode":"CPK","countryCode":"PG","latitude":"-6.30876820","longitude":"144.87312190"},{"name":"Central Province","isoCode":"CPM","countryCode":"PG","latitude":null,"longitude":null},{"name":"East New Britain","isoCode":"EBR","countryCode":"PG","latitude":"-4.61289430","longitude":"151.88773210"},{"name":"Eastern Highlands Province","isoCode":"EHG","countryCode":"PG","latitude":"-6.58616740","longitude":"145.66896360"},{"name":"Enga Province","isoCode":"EPW","countryCode":"PG","latitude":"-5.30058490","longitude":"143.56356370"},{"name":"Gulf","isoCode":"GPK","countryCode":"PG","latitude":"37.05483150","longitude":"-94.43704190"},{"name":"Hela","isoCode":"HLA","countryCode":"PG","latitude":"42.33295160","longitude":"-83.04826180"},{"name":"Jiwaka Province","isoCode":"JWK","countryCode":"PG","latitude":"-5.86911540","longitude":"144.69727
1740"},{"name":"Milne Bay Province","isoCode":"MBA","countryCode":"PG","latitude":"-9.52214510","longitude":"150.67496530"},{"name":"Morobe Province","isoCode":"MPL","countryCode":"PG","latitude":"-6.80137370","longitude":"146.56164700"},{"name":"Madang Province","isoCode":"MPM","countryCode":"PG","latitude":"-4.98497330","longitude":"145.13758340"},{"name":"Manus Province","isoCode":"MRL","countryCode":"PG","latitude":"-2.09411690","longitude":"146.87609510"},{"name":"Port Moresby","isoCode":"NCD","countryCode":"PG","latitude":"-9.44380040","longitude":"147.18026710"},{"name":"New Ireland Province","isoCode":"NIK","countryCode":"PG","latitude":"-4.28532560","longitude":"152.92059180"},{"name":"Oro Province","isoCode":"NPP","countryCode":"PG","latitude":"-8.89880630","longitude":"148.18929210"},{"name":"Bougainville","isoCode":"NSB","countryCode":"PG","latitude":"-6.37539190","longitude":"155.38071010"},{"name":"Sandaun Province","isoCode":"SAN","countryCode":"PG","latitude":"-3.71261790","longitude":"141.68342750"},{"name":"Southern Highlands Province","isoCode":"SHM","countryCode":"PG","latitude":"-6.41790830","longitude":"143.56356370"},{"name":"West New Britain Province","isoCode":"WBK","countryCode":"PG","latitude":"-5.70474320","longitude":"150.02594660"},{"name":"Western Highlands Province","isoCode":"WHM","countryCode":"PG","latitude":"-5.62681280","longitude":"144.25931180"},{"name":"Western Province","isoCode":"WPD","countryCode":"PG","latitude":null,"longitude":null},{"name":"Ilocos Region","isoCode":"01","countryCode":"PH","latitude":"16.08321440","longitude":"120.61998950"},{"name":"Cagayan Valley","isoCode":"02","countryCode":"PH","latitude":"16.97537580","longitude":"121.81070790"},{"name":"Central Luzon","isoCode":"03","countryCode":"PH","latitude":"15.48277220","longitude":"120.71200230"},{"name":"Bicol Region","isoCode":"05","countryCode":"PH","latitude":"13.42098850","longitude":"123.41367360"},{"name":"Western Visayas","isoCode":"06","countryCode":"PH","latitude":"11.00498360","longitude":"122.53727410"},{"name":"Central Visayas","isoCode":"07","countryCode":"PH","latitude":"9.81687500","longitude":"124.06414190"},{"name":"Eastern Visayas","isoCode":"08","countryCode":"PH","latitude":"12.24455330","longitude":"125.03881640"},{"name":"Zamboanga Peninsula","isoCode":"09","countryCode":"PH","latitude":"8.15407700","longitude":"123.25879300"},{"name":"Northern Mindanao","isoCode":"10","countryCode":"PH","latitude":"8.02016350","longitude":"124.68565090"},{"name":"Davao Region","isoCode":"11","countryCode":"PH","latitude":"7.30416220","longitude":"126.08934060"},{"name":"Soccsksargen","isoCode":"12","countryCode":"PH","latitude":"6.27069180","longitude":"124.68565090"},{"name":"Caraga","isoCode":"13","countryCode":"PH","latitude":"8.80145620","longitude":"125.74068820"},{"name":"Autonomous Region in Muslim Mindanao","isoCode":"14","countryCode":"PH","latitude":"6.95683130","longitude":"124.24215970"},{"name":"Cordillera Administrative Region","isoCode":"15","countryCode":"PH","latitude":"17.35125420","longitude":"121.17188510"},{"name":"Calabarzon","isoCode":"40","countryCode":"PH","latitude":"14.10078030","longitude":"121.07937050"},{"name":"Mimaropa","isoCode":"41","countryCode":"PH","latitude":"9.84320650","longitude":"118.73647830"},{"name":"Abra","isoCode":"ABR","countryCode":"PH","latitude":"42.49708300","longitude":"-96.38441000"},{"name":"Agusan del Norte","isoCode":"AGN","countryCode":"PH","latitude":"8.94562590","longitude":"125.53192340"},{"name":"Agusan del Sur","isoCode":"AGS","countryCode":"PH","latitude":"8.04638880","longitude":"126.06153840"},{"name":"Aklan","isoCode":"AKL","countryCode":"PH","latitude":"11.81661090","longitude":"122.09415410"},{"name":"Albay","isoCode":"ALB","countryCode":"PH","latitude":"13.17748270","longitude":"123.52800720"},{"name":"Antique","isoCode":"ANT","countryCode":"PH","latitude":"37.03586950","longitude":"-95.63616940"},{"name":"Apayao","isoCode":"APA","countryCode":"PH","latitude":"18.01203040","longitude":"121.17103890"},{"name":"Aurora","isoCode":"AUR","countryCode":"PH","latitude":"36.97089100","longitude":"-93.71797900"},{"name":"Bataan","isoCode":"BAN","countryCode":"PH","latitude":"14.64168420","longitude":"120.48184460"},{"name":"Basilan","isoCode":"BAS","countryCode":"PH","latitude":"6.42963490","longitude":"121.98701650"},{"name":"Benguet","isoCode":"BEN","countryCode":"PH","latitude":"16.55772570","longitude":"120.80394740"},{"name":"Biliran","isoCode":"BIL","countryCode":"PH","latitude":"11.58331520","longitude":"124.46418480"},{"name":"Bohol","isoCode":"BOH","countryCode":"PH","latitude":"9.84999110","longitude":"124.14354270"},{"name":"Batangas","isoCode":"BTG","countryCode":"PH","latitude":"13.75646510","longitude":"121.05830760"},{"name":"Batanes","isoCode":"BTN","countryCode":"PH","latitude":"20.44850740","longitude":"121.97081290"},{"name":"Bukidnon","isoCode":"BUK","countryCode":"PH","latitude":"8.05150540","longitude":"124.92299460"},{"name":"Bulacan","isoCode":"BUL","countryCode":"PH","latitude":"14.79427350","longitude":"120.87990080"},{"name":"Cagayan","isoCode":"CAG","countryCode":"PH","latitude":"18.24896290","longitude":"121.87878330"},{"name":"Camiguin","isoCode":"CAM","countryCode":"PH","latitude":"9.17321640","longitude":"124.72987650"},{"name":"Camarines Norte","isoCode":"CAN","countryCode":"PH","latitude":"14.13902650","longitude":"122.76330360"},{"name":"Capiz","isoCode":"CAP","countryCode":"PH","latitude":"11.55288160","longitude":"122.74072300"}
1,{"name":"Camarines Sur","isoCode":"CAS","countryCode":"PH","latitude":"13.52501970","longitude":"123.34861470"},{"name":"Catanduanes","isoCode":"CAT","countryCode":"PH","latitude":"13.70886840","longitude":"124.24215970"},{"name":"Cavite","isoCode":"CAV","countryCode":"PH","latitude":"14.47912970","longitude":"120.89696340"},{"name":"Cebu","isoCode":"CEB","countryCode":"PH","latitude":"10.31569920","longitude":"123.88543660"},{"name":"Compostela Valley","isoCode":"COM","countryCode":"PH","latitude":"7.51251500","longitude":"126.17626150"},{"name":"Davao Oriental","isoCode":"DAO","countryCode":"PH","latitude":"7.31715850","longitude":"126.54198870"},{"name":"Davao del Sur","isoCode":"DAS","countryCode":"PH","latitude":"6.76626870","longitude":"125.32842690"},{"name":"Davao del Norte","isoCode":"DAV","countryCode":"PH","latitude":"7.56176990","longitude":"125.65328480"},{"name":"Dinagat Islands","isoCode":"DIN","countryCode":"PH","latitude":"10.12818160","longitude":"125.60954740"},{"name":"Davao Occidental","isoCode":"DVO","countryCode":"PH","latitude":"6.09413960","longitude":"125.60954740"},{"name":"Eastern Samar","isoCode":"EAS","countryCode":"PH","latitude":"11.50007310","longitude":"125.49999080"},{"name":"Guimaras","isoCode":"GUI","countryCode":"PH","latitude":"10.59286610","longitude":"122.63250810"},{"name":"Ifugao","isoCode":"IFU","countryCode":"PH","latitude":"16.83307920","longitude":"121.17103890"},{"name":"Iloilo","isoCode":"ILI","countryCode":"PH","latitude":"10.72015010","longitude":"122.56210630"},{"name":"Ilocos Norte","isoCode":"ILN","countryCode":"PH","latitude":"18.16472810","longitude":"120.71155920"},{"name":"Ilocos Sur","isoCode":"ILS","countryCode":"PH","latitude":"17.22786640","longitude":"120.57395790"},{"name":"Isabela","isoCode":"ISA","countryCode":"PH","latitude":"18.50077590","longitude":"-67.02434620"},{"name":"Kalinga","isoCode":"KAL","countryCode":"PH","latitude":"17.47404220","longitude":"121.35416310"},{"name":"Laguna","isoCode":"LAG","countryCode":"PH","latitude":"33.54271890","longitude":"-117.78535680"},{"name":"Lanao del Norte","isoCode":"LAN","countryCode":"PH","latitude":"7.87218110","longitude":"123.88577470"},{"name":"Lanao del Sur","isoCode":"LAS","countryCode":"PH","latitude":"7.82317600","longitude":"124.41982430"},{"name":"Leyte","isoCode":"LEY","countryCode":"PH","latitude":"10.86245360","longitude":"124.88111950"},{"name":"La Union","isoCode":"LUN","countryCode":"PH","latitude":"38.87668780","longitude":"-77.12809120"},{"name":"Marinduque","isoCode":"MAD","countryCode":"PH","latitude":"13.47671710","longitude":"121.90321920"},{"name":"Maguindanao","isoCode":"MAG","countryCode":"PH","latitude":"6.94225810","longitude":"124.41982430"},{"name":"Masbate","isoCode":"MAS","countryCode":"PH","latitude":"12.35743460","longitude":"123.55040760"},{"name":"Occidental Mindoro","isoCode":"MDC","countryCode":"PH","latitude":"13.10241110","longitude":"120.76512840"},{"name":"Oriental Mindoro","isoCode":"MDR","countryCode":"PH","latitude":"13.05645980","longitude":"121.40694170"},{"name":"Mountain Province","isoCode":"MOU","countryCode":"PH","latitude":"40.70754370","longitude":"-73.95010330"},{"name":"Misamis Occidental","isoCode":"MSC","countryCode":"PH","latitude":"8.33749030","longitude":"123.70706190"},{"name":"Misamis Oriental","isoCode":"MSR","countryCode":"PH","latitude":"8.50455580","longitude":"124.62195920"},{"name":"Cotabato","isoCode":"NCO","countryCode":"PH","latitude":"7.20466680","longitude":"124.23104390"},{"name":"Metro Manila","isoCode":"NCR","countryCode":"PH","latitude":"14.60905370","longitude":"121.02225650"},{"name":"Negros Occidental","isoCode":"NEC","countryCode":"PH","latitude":"10.29256090","longitude":"123.02465180"},{"name":"Negros Oriental","isoCode":"NER","countryCode":"PH","latitude":"9.62820830","longitude":"122.98883190"},{"name":"Northern Samar","isoCode":"NSA","countryCode":"PH","latitude":"12.36131990","longitude":"124.77407930"},{"name":"Nueva Ecija","isoCode":"NUE","countryCode":"PH","latitude":"15.57837500","longitude":"121.11126150"},{"name":"Nueva Vizcaya","isoCode":"NUV","countryCode":"PH","latitude":"16.33011070","longitude":"121.17103890"},{"name":"Pampanga","isoCode":"PAM","countryCode":"PH","latitude":"15.07940900","longitude":"120.61998950"},{"name":"Pangasinan","isoCode":"PAN","countryCode":"PH","latitude":"15.89490550","longitude":"120.28631830"},{"name":"Palawan","isoCode":"PLW","countryCode":"PH","latitude":"9.83494930","longitude":"118.73836150"},{"name":"Quezon","isoCode":"QUE","countryCode":"PH","latitude":"14.03139060","longitude":"122.11309090"},{"name":"Quirino","isoCode":"QUI","countryCode":"PH","latitude":"16.27004240","longitude":"121.53700030"},{"name":"Rizal","isoCode":"RIZ","countryCode":"PH","latitude":"14.60374460","longitude":"121.30840880"},{"name":"Romblon","isoCode":"ROM","countryCode":"PH","latitude":"12.57780160","longitude":"122.26914600"},{"name":"Sarangani","isoCode":"SAR","countryCode":"PH","latitude":"5.92671750","longitude":"124.99475100"},{"name":"South Cotabato","isoCode":"SCO","countryCode":"PH","latitude":"6.33575650","longitude":"124.77407930"},{"name":"Siquijor","isoCode":"SIG","countryCode":"PH","latitude":"9.19987790","longitude":"123.59519250"},{"name":"Southern Leyte","isoCode":"SLE","countryCode":"PH","latitude":"10.33462060","longitude":"125.17087410"},{"name":"Sulu","isoCode":"SLU","countryCode":"PH","latitude":"5.97490110","longitude":"121.03351000"},{"name":"Sorsogon","isoCode":"SOR","countryCode":"PH","latitude":"12.99270950","longitude":"124.01474640"},{"name":"Sultan Kudarat","isoCode":"SUK","countryCode":"PH","latitude":"6.50694010","longitude":"124.41982430"},{"name":"Surigao del Norte","isoCode":"SUN","countryCode":"PH","latitude":"9.51482800","longitude":"125.69699840"},{"name":"Surigao del Sur","isoCode":"SUR","countryCode":"PH","latitude":"8.54049060","longitude":"126.11447580"},{"name":"Tarlac","isoCode":"TAR","countryCode":"PH","latitude":"15.47547860","longitude":"120.59634920"},{"name":"Tawi-Tawi","isoCode":"TAW","countryCode":"PH","latitude":"5.13381100","longitude":"119.95092600"},{"name":"Zamboanga del Norte","isoCode":"ZAN","countryCode":"PH","latitude":"8.38862820","longitude":"123.16888830"},{"name":"Zamboanga del Sur","isoCode":"ZAS","countryCode":"PH","latitude":"7.83830540","longitude":"123.29666570"},{"name":"Zambales","isoCode":"ZMB","countryCode":"PH","latitude":"15.50817660","longitude":"119.96978080"},{"name":"Zamboanga Sibugay","isoCode":"ZSI","countryCode":"PH","latitude":"7.52252470","longitude":"122.31075170"},{"name":"Balochistan","isoCode":"BA","countryCode":"PK","latitude":"28.49073320","longitude":"65.09577920"},{"name":"Gilgit-Baltistan","isoCode":"GB","countryCode":"PK","latitude":"35.80256670","longitude":"74.98318080"},{"name":"Islamabad Capital Territory","isoCode":"IS","countryCode":"PK","latitude":"33.72049970","longitude":"73.04052770"},{"name":"Azad Kashmir","isoCode":"JK","countryCode":"PK","latitude":"33.92590550","longitude":"73.78103340"},{"name":"Khyber Pakhtunkhwa","isoCode":"KP","countryCode":"PK","latitude":"34.95262050","longitude":"72.33111300"},{"name":"Punjab","isoCode":"PB","countryCode":"PK","latitude":"31.14713050","longitude":"75.34121790"},{"name":"Sindh","isoCode":"SD","countryCode":"PK","latitude":"25.89430180","longitude":"68.52471490"},{"name":"Federally Administered Tribal Areas","isoCode":"TA","countryCode":"PK","latitude":"32.66747600","longitude":"69.85974060"},{"name":"Lower Silesian Voivodeship","isoCode":"DS","countryCode":"PL","latitude":"51.13398610","longitude":"16.88419610"},{"name":"Kuyavian-Pomeranian Voivodeship","isoCode":"KP","countryCode":"PL","latitude":"53.16483630","longitude":"18.48342240"},{"name":"Lubusz Voivodeship","isoCode":"LB","countryCode":"PL","latitude":"52.22746120","longitude":"15.25591030"},{"name":"Åódź Voivodeship","isoCode":"LD","countryCode":"PL","latitude":"51.46347710","longitude":"19.17269740"},{"name":"Lublin Voivodeship","isoCode":"LU","countryCode":"PL","latitude":"51.24935190","longitude":"23.10113920"},{"name":"Lesser Poland Voivodeship","isoCode":"MA","countryCode":"PL","latitude":"49.72253060","longitude":"20.25033580"},{"name":"Masovian Voivodeship","isoCode":"MZ","countryCode":"PL","latitude":"51.89271820","longitude":"21.00216790"},{"name":"Opole Voivodeship","isoCode":"OP","countryCode":"PL","latitude":"50.80037610","longitude":"17.93798900"},{"name":"Podlaskie Voivodeship","isoCode":"PD","countryCode":"PL","latitude":"53.06971590","longitude":"22.96746390"},{"name":"Podkarpackie Voivodeship","isoCode":"PK","countryCode":"PL","latitude":"50.05747490","longitude":"22.08956910"},{"name":"Pomeranian Voivodeship","isoCode":"PM","countryCode":"PL","latitude":"54.29442520","longitude":"18.15311640"},{"name":"ÅwiÄtokrzyskie Voivodeship","isoCode":"SK","countryCode":"PL","latitude":"50.62610410","longitude":"20.94062790"},{"name":"Silesian Voivodeship","isoCode":"SL","countryCode":"PL","latitude":"50.57165950","longitude":"19.32197680"},{"name":"Warmian-Masurian Voivodeship","isoCode":"WN","countryCode":"PL","latitude":"53.86711170","longitude":"20.70278610"},{"name":"Greater Poland Voivodeship","isoCode":"WP","countryCode":"PL","latitude":"52.27998600","longitude":"17.35229390"},{"name":"West Pomeranian Voivodeship","isoCode":"ZP","countryCode":"PL","latitude":"53.46578910","longitude":"15.18225810"},{"name":"Aveiro","isoCode":"01","countryCode":"PT","latitude":"40.72090230","longitude":"-8.57210160"},{"name":"Beja","isoCode":"02","countryCode":"PT","latitude":"37.96877860","longitude":"-7.87216000"},{"name":"Braga","isoCode":"03","countryCode":"PT","latitude":"41.55038800","longitude":"-8.42613010"},{"name":"Bragança","isoCode":"04","countryCode":"PT","latitude":"41.80616520","longitude":"-6.75674270"},{"name":"Castelo Branco","isoCode":"05","countryCode":"PT","latitude":"39.86313230","longitude":"-7.48141630"},{"name":"Coimbra","isoCode":"06","countryCode":"PT","latitude":"40.20579940","longitude":"-8.41369000"},{"name":"Ãvora","isoCode":"07","countryCode":"PT","latitude":"38.57444680","longitude":"-7.90765530"},{"name":"Faro","isoCode":"08","countryCode":"PT","latitude":"37.01935480","longitude":"-7.93043970"},{"name":"Guarda","isoCode":"09","countryCode":"PT","latitude":"40.53859720","longitude":"-7.26757720"},{"name":"Leiria","isoCode":"10","countryCode":"PT","latitude":"39.77095320","longitude":"-8.79218360"},{"name":"Lisbon","isoCode":"11","countryCode":"PT","latitude":"38.72232630","longitude":"-9.13927140"},{"name":"Portalegre","isoCode":"12","countryCode":"PT","latitude":"39.29670860","longitude":"-7.42847550"},{"name":"Porto","isoCode":"13","countryCode":"PT","latitude":"41.14766290","longitude":"-8.60789730"},{"name":"Santarém","isoCode":"14","countryCode":"PT","latitude":"39.23666870","longitude":"-8.68599440"},{"name":"Setúbal","isoCode":"15","countryCode":"PT","latitude":"38.52409330","longitude":"-8.89258760"},{"name":"Viana do Castelo","isoCode":"16","countryCode":"PT","latitude":"41.69180460","longitude":"-8.83445100"},{"name":"Vila Real","isoCode":"17","countryCode":"PT","latitude":"41.30035270","longitude":"-7.74572740"},{"name":"Viseu","isoCode":"18","countryCode":"PT","latitude":"40.65884240","longitude":"-7.91475600"},{"name":"Açores","isoCode":"20","countryCode":"PT","latitude":"37.74124880","longitude":"-25.67559440"},{"name":"Madeira","isoCode":"30","countryCode":"PT","latitude":"32.76070740","longitude":"-16.95947230"},{"name":"Aimeliik","isoCode":"002","countryCode":"PW","latitude":"7.44558590","longitude":"134.50308780"},{"name":"Airai","isoCode":"004","countryCode":"PW","latitude":"7.39661180","longitude":"134.56902250"},{"name":"Angaur","isoCode":"010","countryCode":"PW","latitude":"6.90922300","longitude":"134.13879340"},{"name":"Hatohobei","isoCode":"050","countryCode":"PW","latitude":"3.00706580","longitude":"131.12377810"},{"name":"Kayangel","isoCode":"100","countryCode":"PW","latitude":"8.07000000","longitude":"134.7027
17800"},{"name":"Koror","isoCode":"150","countryCode":"PW","latitude":"7.33756460","longitude":"134.48894690"},{"name":"Melekeok","isoCode":"212","countryCode":"PW","latitude":"7.51502860","longitude":"134.59725180"},{"name":"Ngaraard","isoCode":"214","countryCode":"PW","latitude":"7.60794000","longitude":"134.63486450"},{"name":"Ngarchelong","isoCode":"218","countryCode":"PW","latitude":"7.71054690","longitude":"134.63016460"},{"name":"Ngardmau","isoCode":"222","countryCode":"PW","latitude":"7.58504860","longitude":"134.55960890"},{"name":"Ngatpang","isoCode":"224","countryCode":"PW","latitude":"7.47109940","longitude":"134.52664660"},{"name":"Ngchesar","isoCode":"226","countryCode":"PW","latitude":"7.45232800","longitude":"134.57843420"},{"name":"Ngeremlengui","isoCode":"227","countryCode":"PW","latitude":"7.51983970","longitude":"134.55960890"},{"name":"Ngiwal","isoCode":"228","countryCode":"PW","latitude":"7.56147640","longitude":"134.61606190"},{"name":"Peleliu","isoCode":"350","countryCode":"PW","latitude":"7.00229060","longitude":"134.24316280"},{"name":"Sonsorol","isoCode":"370","countryCode":"PW","latitude":"5.32681190","longitude":"132.22391170"},{"name":"Concepción Department","isoCode":"1","countryCode":"PY","latitude":"-23.42142640","longitude":"-57.43444510"},{"name":"Alto Paraná Department","isoCode":"10","countryCode":"PY","latitude":"-25.60755460","longitude":"-54.96118360"},{"name":"Central Department","isoCode":"11","countryCode":"PY","latitude":"36.15592290","longitude":"-95.96620750"},{"name":"Ãeembucú Department","isoCode":"12","countryCode":"PY","latitude":"-27.02991140","longitude":"-57.82539500"},{"name":"Amambay Department","isoCode":"13","countryCode":"PY","latitude":"-22.55902720","longitude":"-56.02499820"},{"name":"Canindeyú","isoCode":"14","countryCode":"PY","latitude":"-24.13787350","longitude":"-55.66896360"},{"name":"Presidente Hayes Department","isoCode":"15","countryCode":"PY","latitude":"-23.35126050","longitude":"-58.73736340"},{"name":"Alto Paraguay Department","isoCode":"16","countryCode":"PY","latitude":"-20.08525080","longitude":"-59.47209040"},{"name":"Boquerón Department","isoCode":"19","countryCode":"PY","latitude":"-21.74492540","longitude":"-60.95400730"},{"name":"San Pedro Department","isoCode":"2","countryCode":"PY","latitude":"-24.19486680","longitude":"-56.56164700"},{"name":"Cordillera Department","isoCode":"3","countryCode":"PY","latitude":"-25.22894910","longitude":"-57.01116810"},{"name":"Guairá Department","isoCode":"4","countryCode":"PY","latitude":"-25.88109320","longitude":"-56.29293810"},{"name":"Caaguazú","isoCode":"5","countryCode":"PY","latitude":"-25.46458180","longitude":"-56.01385100"},{"name":"Caazapá","isoCode":"6","countryCode":"PY","latitude":"-26.18277130","longitude":"-56.37123270"},{"name":"Itapúa","isoCode":"7","countryCode":"PY","latitude":"-26.79236230","longitude":"-55.66896360"},{"name":"Misiones Department","isoCode":"8","countryCode":"PY","latitude":"-26.84335120","longitude":"-57.10131880"},{"name":"Paraguarà Department","isoCode":"9","countryCode":"PY","latitude":"-25.62621740","longitude":"-57.15206420"},{"name":"Doha","isoCode":"DA","countryCode":"QA","latitude":"25.28544730","longitude":"51.53103980"},{"name":"Al Khor","isoCode":"KH","countryCode":"QA","latitude":"25.68040780","longitude":"51.49685020"},{"name":"Madinat ash Shamal","isoCode":"MS","countryCode":"QA","latitude":"26.11827430","longitude":"51.21572650"},{"name":"Al Rayyan Municipality","isoCode":"RA","countryCode":"QA","latitude":"25.25225510","longitude":"51.43887130"},{"name":"Al-Shahaniya","isoCode":"SH","countryCode":"QA","latitude":"25.41063860","longitude":"51.18460250"},{"name":"Umm Salal Municipality","isoCode":"US","countryCode":"QA","latitude":"25.48752420","longitude":"51.39656800"},{"name":"Al Wakrah","isoCode":"WA","countryCode":"QA","latitude":"25.16593140","longitude":"51.59755240"},{"name":"Al Daayen","isoCode":"ZA","countryCode":"QA","latitude":"25.57845590","longitude":"51.48213870"},{"name":"Alba","isoCode":"AB","countryCode":"RO","latitude":"44.70091530","longitude":"8.03569110"},{"name":"Arges","isoCode":"AG","countryCode":"RO","latitude":"45.07225270","longitude":"24.81427260"},{"name":"Arad County","isoCode":"AR","countryCode":"RO","latitude":"46.22836510","longitude":"21.65978190"},{"name":"Bucharest","isoCode":"B","countryCode":"RO","latitude":"44.42676740","longitude":"26.10253840"},{"name":"BacÄu County","isoCode":"BC","countryCode":"RO","latitude":"46.32581840","longitude":"26.66237800"},{"name":"Bihor County","isoCode":"BH","countryCode":"RO","latitude":"47.01575160","longitude":"22.17226600"},{"name":"BistriÈa-NÄsÄud County","isoCode":"BN","countryCode":"RO","latitude":"47.24861070","longitude":"24.53228140"},{"name":"Braila","isoCode":"BR","countryCode":"RO","latitude":"45.26524630","longitude":"27.95947140"},{"name":"BotoÈani County","isoCode":"BT","countryCode":"RO","latitude":"47.89240420","longitude":"26.75917810"},{"name":"BraÈov County","isoCode":"BV","countryCode":"RO","latitude":"45.77818440","longitude":"25.22258000"},{"name":"BuzÄu County","isoCode":"BZ","countryCode":"RO","latitude":"45.33509120","longitude":"26.71075780"},{"name":"Cluj County","isoCode":"CJ","countryCode":"RO","latitude":"46.79417970","longitude":"23.61214920"},{"name":"CÄlÄraÈi County","isoCode":"CL","countryCode":"RO","latitude":"44.36587150","longitude":"26.75486070"},{"name":"CaraÈ-Severin County","isoCode":"CS","countryCode":"RO","latitude":"45.11396460","longitude":"22.07409930"},{"name":"ConstanÈa County","isoCode":"CT","countryCode":"RO","latitude":"44.21298700","longitude":"28.25500550"},{"name":"Covasna County","isoCode":"CV","countryCode":"RO","latitude":"45.94263470","longitude":"25.89189840"},{"name":"DâmboviÈa County","isoCode":"DB","countryCode":"RO","latitude":"44.92898930","longitude":"25.42538500"},{"name":"Dolj County","isoCode":"DJ","countryCode":"RO","latitude":"44.16230220","longitude":"23.63250540"},{"name":"Gorj County","isoCode":"GJ","countryCode":"RO","latitude":"44.94855950","longitude":"23.24270790"},{"name":"GalaÈi County","isoCode":"GL","countryCode":"RO","latitude":"45.78005690","longitude":"27.82515760"},{"name":"Giurgiu County","isoCode":"GR","countryCode":"RO","latitude":"43.90370760","longitude":"25.96992650"},{"name":"Hunedoara County","isoCode":"HD","countryCode":"RO","latitude":"45.79363800","longitude":"22.99759930"},{"name":"Harghita County","isoCode":"HR","countryCode":"RO","latitude":"46.49285070","longitude":"25.64566960"},{"name":"Ilfov County","isoCode":"IF","countryCode":"RO","latitude":"44.53554800","longitude":"26.23248860"},{"name":"IalomiÈa County","isoCode":"IL","countryCode":"RO","latitude":"44.60313300","longitude":"27.37899140"},{"name":"IaÈi County","isoCode":"IS","countryCode":"RO","latitude":"47.26796530","longitude":"27.21856620"},{"name":"MehedinÈi County","isoCode":"MH","countryCode":"RO","latitude":"44.55150530","longitude":"22.90441570"},{"name":"MaramureÈ County","isoCode":"MM","countryCode":"RO","latitude":"46.55699040","longitude":"24.67232150"},{"name":"MureÈ County","isoCode":"MS","countryCode":"RO","latitude":"46.55699040","longitude":"24.67232150"},{"name":"NeamÈ County","isoCode":"NT","countryCode":"RO","latitude":"46.97586850","longitude":"26.38187640"},{"name":"Olt County","isoCode":"OT","countryCode":"RO","latitude":"44.20079700","longitude":"24.50229810"},{"name":"Prahova County","isoCode":"PH","countryCode":"RO","latitude":"45.08919060","longitude":"26.08293130"},{"name":"Sibiu County","isoCode":"SB","countryCode":"RO","latitude":"45.92691060","longitude":"24.22548070"},{"name":"SÄlaj County","isoCode":"SJ","countryCode":"RO","latitude":"47.20908130","longitude":"23.21219010"},{"name":"Satu Mare County","isoCode":"SM","countryCode":"RO","latitude":"47.76689050","longitude":"22.92413770"},{"name":"Suceava County","isoCode":"SV","countryCode":"RO","latitude":"47.55055480","longitude":"25.74106200"},{"name":"Tulcea County","isoCode":"TL","countryCode":"RO","latitude":"45.04505650","longitude":"29.03249120"},{"name":"TimiÈ County","isoCode":"TM","countryCode":"RO","latitude":"45.81389020","longitude":"21.33310550"},{"name":"Teleorman County","isoCode":"TR","countryCode":"RO","latitude":"44.01604910","longitude":"25.29866280"}
1,{"name":"Vâlcea County","isoCode":"VL","countryCode":"RO","latitude":"45.07980510","longitude":"24.08352830"},{"name":"Vrancea County","isoCode":"VN","countryCode":"RO","latitude":"45.81348760","longitude":"27.06575310"},{"name":"Vaslui County","isoCode":"VS","countryCode":"RO","latitude":"46.46310590","longitude":"27.73980310"},{"name":"Belgrade","isoCode":"00","countryCode":"RS","latitude":"44.78656800","longitude":"20.44892160"},{"name":"North BaÄka District","isoCode":"01","countryCode":"RS","latitude":"45.98033940","longitude":"19.59070010"},{"name":"Central Banat District","isoCode":"02","countryCode":"RS","latitude":"45.47884850","longitude":"20.60825220"},{"name":"North Banat District","isoCode":"03","countryCode":"RS","latitude":"45.90683900","longitude":"19.99934170"},{"name":"South Banat District","isoCode":"04","countryCode":"RS","latitude":"45.00274570","longitude":"21.05425090"},{"name":"West BaÄka District","isoCode":"05","countryCode":"RS","latitude":"45.73553850","longitude":"19.18973640"},{"name":"South BaÄka District","isoCode":"06","countryCode":"RS","latitude":"45.48903440","longitude":"19.69761870"},{"name":"Srem District","isoCode":"07","countryCode":"RS","latitude":"45.00291710","longitude":"19.80137730"},{"name":"MaÄva District","isoCode":"08","countryCode":"RS","latitude":"44.59253140","longitude":"19.50822460"},{"name":"Kolubara District","isoCode":"09","countryCode":"RS","latitude":"44.35098110","longitude":"20.00043050"},{"name":"Podunavlje District","isoCode":"10","countryCode":"RS","latitude":"44.47291560","longitude":"20.99014260"},{"name":"BraniÄevo District","isoCode":"11","countryCode":"RS","latitude":"44.69822460","longitude":"21.54467750"},{"name":"Å umadija District","isoCode":"12","countryCode":"RS","latitude":"44.20506780","longitude":"20.78565650"},{"name":"Pomoravlje District","isoCode":"13","countryCode":"RS","latitude":"43.95913790","longitude":"21.27135300"},{"name":"Bor District","isoCode":"14","countryCode":"RS","latitude":"44.06989180","longitude":"22.09850860"},{"name":"ZajeÄar District","isoCode":"15","countryCode":"RS","latitude":"43.90150480","longitude":"22.27380110"},{"name":"Zlatibor District","isoCode":"16","countryCode":"RS","latitude":"43.64541700","longitude":"19.71014550"},{"name":"Moravica District","isoCode":"17","countryCode":"RS","latitude":"43.84147000","longitude":"20.29049870"},{"name":"RaÅ¡ka District","isoCode":"18","countryCode":"RS","latitude":"43.33734610","longitude":"20.57340050"},{"name":"Rasina District","isoCode":"19","countryCode":"RS","latitude":"43.52635250","longitude":"21.15881780"},{"name":"NiÅ¡ava District","isoCode":"20","countryCode":"RS","latitude":"43.37389020","longitude":"21.93223310"},{"name":"Toplica District","isoCode":"21","countryCode":"RS","latitude":"43.19065920","longitude":"21.34077620"},{"name":"Pirot District","isoCode":"22","countryCode":"RS","latitude":"43.08740360","longitude":"22.59830440"},{"name":"Jablanica District","isoCode":"23","countryCode":"RS","latitude":"42.94815600","longitude":"21.81293210"},{"name":"PÄinja District","isoCode":"24","countryCode":"RS","latitude":"42.58363620","longitude":"22.14302150"},{"name":"Vojvodina","isoCode":"VO","countryCode":"RS","latitude":"45.26086510","longitude":"19.83193380"},{"name":"Republic of Adygea","isoCode":"AD","countryCode":"RU","latitude":"44.82291550","longitude":"40.17544630"},{"name":"Altai Republic","isoCode":"AL","countryCode":"RU","latitude":"50.61819240","longitude":"86.21993080"},{"name":"Altai Krai","isoCode":"ALT","countryCode":"RU","latitude":"51.79362980","longitude":"82.67585960"},{"name":"Amur Oblast","isoCode":"AMU","countryCode":"RU","latitude":"54.60350650","longitude":"127.48017210"},{"name":"Arkhangelsk","isoCode":"ARK","countryCode":"RU","latitude":"64.54585490","longitude":"40.55057690"},{"name":"Astrakhan Oblast","isoCode":"AST","countryCode":"RU","latitude":"46.13211660","longitude":"48.06101150"},{"name":"Republic of Bashkortostan","isoCode":"BA","countryCode":"RU","latitude":"54.23121720","longitude":"56.16452570"},{"name":"Belgorod Oblast","isoCode":"BEL","countryCode":"RU","latitude":"50.71069260","longitude":"37.75333770"},{"name":"Bryansk Oblast","isoCode":"BRY","countryCode":"RU","latitude":"53.04085990","longitude":"33.26909000"},{"name":"Republic of Buryatia","isoCode":"BU","countryCode":"RU","latitude":"54.83311460","longitude":"112.40605300"},{"name":"Chechen Republic","isoCode":"CE","countryCode":"RU","latitude":"43.40233010","longitude":"45.71874680"},{"name":"Chelyabinsk Oblast","isoCode":"CHE","countryCode":"RU","latitude":"54.43194220","longitude":"60.87889630"},{"name":"Chukotka Autonomous Okrug","isoCode":"CHU","countryCode":"RU","latitude":"65.62983550","longitude":"171.69521590"},{"name":"Chuvash Republic","isoCode":"CU","countryCode":"RU","latitude":"55.55959920","longitude":"46.92835350"},{"name":"Republic of Dagestan","isoCode":"DA","countryCode":"RU","latitude":"42.14318860","longitude":"47.09497990"},{"name":"Republic of Ingushetia","isoCode":"IN","countryCode":"RU","latitude":"43.40516980","longitude":"44.82029990"},{"name":"Irkutsk","isoCode":"IRK","countryCode":"RU","latitude":"52.28548340","longitude":"104.28902220"},{"name":"Ivanovo Oblast","isoCode":"IVA","countryCode":"RU","latitude":"57.10568540","longitude":"41.48300840"},{"name":"Kamchatka Krai","isoCode":"KAM","countryCode":"RU","latitude":"61.43439810","longitude":"166.78841310"},{"name":"Kabardino-Balkar Republic","isoCode":"KB","countryCode":"RU","latitude":"43.39324690","longitude":"43.56284980"},{"name":"Karachay-Cherkess Republic","isoCode":"KC","countryCode":"RU","latitude":"43.88451430","longitude":"41.73039390"},{"name":"Krasnodar Krai","isoCode":"KDA","countryCode":"RU","latitude":"45.64152890","longitude":"39.70559770"},{"name":"Kemerovo Oblast","isoCode":"KEM","countryCode":"RU","latitude":"54.75746480","longitude":"87.40552880"},{"name":"Kaliningrad","isoCode":"KGD","countryCode":"RU","latitude":"54.71042640","longitude":"20.45221440"},{"name":"Kurgan Oblast","isoCode":"KGN","countryCode":"RU","latitude":"55.44815480","longitude":"65.11809750"},{"name":"Khabarovsk Krai","isoCode":"KHA","countryCode":"RU","latitude":"50.58884310","longitude":"135.00000000"},{"name":"Khanty-Mansi Autonomous Okrug","isoCode":"KHM","countryCode":"RU","latitude":"62.22870620","longitude":"70.64100570"},{"name":"Kirov Oblast","isoCode":"KIR","countryCode":"RU","latitude":"58.41985290","longitude":"50.20972480"},{"name":"Republic of Khakassia","isoCode":"KK","countryCode":"RU","latitude":"53.04522810","longitude":"90.39821450"},{"name":"Republic of Kalmykia","isoCode":"KL","countryCode":"RU","latitude":"46.18671760","longitude":"45.00000000"},{"name":"Kaluga Oblast","isoCode":"KLU","countryCode":"RU","latitude":"54.38726660","longitude":"35.18890940"},{"name":"Komi Republic","isoCode":"KO","countryCode":"RU","latitude":"63.86305390","longitude":"54.83126900"},{"name":"Kostroma Oblast","isoCode":"KOS","countryCode":"RU","latitude":"58.55010690","longitude":"43.95411020"},{"name":"Republic of Karelia","isoCode":"KR","countryCode":"RU","latitude":"63.15587020","longitude":"32.99055520"},{"name":"Kursk Oblast","isoCode":"KRS","countryCode":"RU","latitude":"51.76340260","longitude":"35.38118120"},{"name":"Krasnoyarsk Krai","isoCode":"KYA","countryCode":"RU","latitude":"64.24797580","longitude":"95.11041760"},{"name":"Leningrad Oblast","isoCode":"LEN","countryCode":"RU","latitude":"60.07932080","longitude":"31.89266450"},{"name":"Lipetsk Oblast","isoCode":"LIP","countryCode":"RU","latitude":"52.52647020","longitude":"39.20322690"},{"name":"Magadan Oblast","isoCode":"MAG","countryCode":"RU","latitude":"62.66434170","longitude":"153.91499100"},{"name":"Mari El Republic","isoCode":"ME","countryCode":"RU","latitude":"56.43845700","longitude":"47.96077580"},{"name":"Republic of Mordovia","isoCode":"MO","countryCode":"RU","latitude":"54.23694410","longitude":"44.06839700"},{"name":"Moscow Oblast","isoCode":"MOS","countryCode":"RU","latitude":"55.34039600","longitude":"38.29176510"},{"name":"Moscow","isoCode":"MOW","countryCode":"RU","latitude":"55.75582600","longitude":"37.61729990"},{"name":"Murmansk Oblast","isoCode":"MUR","countryCode":"RU","latitude":"67.84426740","longitude":"35.08841020"},{"name":"Nenets Autonomous Okrug","isoCode":"NEN","countryCode":"RU","latitude":"67.60783370","longitude":"57.63383310"},{"name":"Novgorod Oblast","isoCode":"NGR","countryCode":"RU","latitude":"58.24275520","longitude":"32.56651900"},{"name":"Nizhny Novgorod Oblast","isoCode":"NIZ","countryCode":"RU","latitude":"55.79951590","longitude":"44.02967690"},{"name":"Novosibirsk","isoCode":"NVS","countryCode":"RU","latitude":"54.98326930","longitude":"82.89638310"},{"name":"Omsk Oblast","isoCode":"OMS","countryCode":"RU","latitude":"55.05546690","longitude":"73.31673420"},{"name":"Orenburg Oblast","isoCode":"ORE","countryCode":"RU","latitude":"51.76340260","longitude":"54.61881880"},{"name":"Oryol Oblast","isoCode":"ORL","countryCode":"RU","latitude":"52.78564140","longitude":"36.92423440"},{"name":"Perm Krai","isoCode":"PER","countryCode":"RU","latitude":"58.82319290","longitude":"56.58724810"},{"name":"Penza Oblast","isoCode":"PNZ","countryCode":"RU","latitude":"53.14121050","longitude":"44.09400480"},{"name":"Primorsky Krai","isoCode":"PRI","countryCode":"RU","latitude":"45.05256410","longitude":"135.00000000"},{"name":"Pskov Oblast","isoCode":"PSK","countryCode":"RU","latitude":"56.77085990","longitude":"29.09400900"},{"name":"Rostov Oblast","isoCode":"ROS","countryCode":"RU","latitude":"47.68532470","longitude":"41.82589520"},{"name":"Ryazan Oblast","isoCode":"RYA","countryCode":"RU","latitude":"54.38759640","longitude":"41.25956610"},{"name":"Sakha Republic","isoCode":"SA","countryCode":"RU","latitude":"66.76134510","longitude":"124.12375300"},{"name":"Sakhalin","isoCode":"SAK","countryCode":"RU","latitude":"50.69098480","longitude":"142.95056890"},{"name":"Samara Oblast","isoCode":"SAM","countryCode":"RU","latitude":"53.41838390","longitude":"50.47255280"},{"name":"Saratov Oblast","isoCode":"SAR","countryCode":"RU","latitude":"51.83692630","longitude":"46.75393970"},{"name":"Republic of North Ossetia-Alania","isoCode":"SE","countryCode":"RU","latitude":"43.04513020","longitude":"44.28709720"},{"name":"Smolensk Oblast","isoCode":"SMO","countryCode":"RU","latitude":"54.98829940","longitude":"32.66773780"},{"name":"Saint Petersburg","isoCode":"SPE","countryCode":"RU","latitude":"59.93105840","longitude":"30.36090960"},{"name":"Stavropol Krai","isoCode":"STA","countryCode":"RU","latitude":"44.66809930","longitude":"43.52021400"},{"name":"Sverdlovsk","isoCode":"SVE","countryCode":"RU","latitude":"56.84309930","longitude":"60.64540860"},{"name":"Republic of Tatarstan","isoCode":"TA","countryCode":"RU","latitude":"55.18023640","longitude":"50.72639450"},{"name":"Tambov Oblast","isoCode":"TAM","countryCode":"RU","latitude":"52.64165890","longitude":"41.42164510"},{"name":"Tomsk Oblast","isoCode":"TOM","countryCode":"RU","latitude":"58.89698820","longitude":"82.67655000"},{"name":"Tula Oblast","isoCode":"TUL","countryCode":"RU","latitude":"54.16376800","longitude":"37.56495070"},{"name":"Tver Oblast","isoCode":"TVE","countryCode":"RU","latitude":"57.00216540","longitude":"33.98531420"},{"name":"Tuva Republic","isoCode":"TY","countryCode":"RU","latitude":"51.88726690","longitude":"95.62601720"},{"name":"Tyumen Oblast","isoCode":"TYU","countryCode":"RU","latitude":"56.96343870","longitude":"66.94827800"},{"name":"Sevastopol","isoCode":"UA-40","countryCode":"RU","latitude":"44.61665000","longitude":"33.52536710"},{"name":"Udmurt Republic","isoCode":"UD","countryCode":"RU","latitude":"57.06702180","longitude":"53.02779480"},{"name":"Ulyanovsk Oblast","isoCode":"ULY","countryCode":"RU","latitude":"53.97933570","longitude":"47.77624250"}
1,{"name":"Volgograd Oblast","isoCode":"VGG","countryCode":"RU","latitude":"49.25873930","longitude":"39.81544630"},{"name":"Vladimir Oblast","isoCode":"VLA","countryCode":"RU","latitude":"56.15534650","longitude":"40.59266850"},{"name":"Vologda Oblast","isoCode":"VLG","countryCode":"RU","latitude":"59.87067110","longitude":"40.65554110"},{"name":"Voronezh Oblast","isoCode":"VOR","countryCode":"RU","latitude":"50.85897130","longitude":"39.86443740"},{"name":"Yamalo-Nenets Autonomous Okrug","isoCode":"YAN","countryCode":"RU","latitude":"66.06530570","longitude":"76.93451930"},{"name":"Yaroslavl Oblast","isoCode":"YAR","countryCode":"RU","latitude":"57.89915230","longitude":"38.83886330"},{"name":"Jewish Autonomous Oblast","isoCode":"YEV","countryCode":"RU","latitude":"48.48081470","longitude":"131.76573670"},{"name":"Zabaykalsky Krai","isoCode":"ZAB","countryCode":"RU","latitude":"53.09287710","longitude":"116.96765610"},{"name":"Kigali district","isoCode":"01","countryCode":"RW","latitude":"-1.94407270","longitude":"30.06188510"},{"name":"Eastern Province","isoCode":"02","countryCode":"RW","latitude":null,"longitude":null},{"name":"Northern Province","isoCode":"03","countryCode":"RW","latitude":null,"longitude":null},{"name":"Western Province","isoCode":"04","countryCode":"RW","latitude":null,"longitude":null},{"name":"Southern Province","isoCode":"05","countryCode":"RW","latitude":null,"longitude":null},{"name":"Riyadh","isoCode":"01","countryCode":"SA","latitude":"22.75543850","longitude":"46.20915470"},{"name":"Makkah","isoCode":"02","countryCode":"SA","latitude":"21.52355840","longitude":"41.91964710"},{"name":"Al Madinah","isoCode":"03","countryCode":"SA","latitude":"24.84039770","longitude":"39.32062410"},{"name":"Eastern Province","isoCode":"04","countryCode":"SA","latitude":"24.04399320","longitude":"45.65892250"},{"name":"Al-Qassim","isoCode":"05","countryCode":"SA","latitude":"26.20782600","longitude":"43.48373800"},{"name":"Ha\'il","isoCode":"06","countryCode":"SA","latitude":"27.70761430","longitude":"41.91964710"},{"name":"Tabuk","isoCode":"07","countryCode":"SA","latitude":"28.24533350","longitude":"37.63866220"},{"name":"Northern Borders","isoCode":"08","countryCode":"SA","latitude":"30.07991620","longitude":"42.86378750"},{"name":"Jizan","isoCode":"09","countryCode":"SA","latitude":"17.17381760","longitude":"42.70761070"},{"name":"Najran","isoCode":"10","countryCode":"SA","latitude":"18.35146640","longitude":"45.60071080"},{"name":"Al Bahah","isoCode":"11","countryCode":"SA","latitude":"20.27227390","longitude":"41.44125100"},{"name":"Al Jawf","isoCode":"12","countryCode":"SA","latitude":"29.88735600","longitude":"39.32062410"},{"name":"\'Asir","isoCode":"14","countryCode":"SA","latitude":"19.09690620","longitude":"42.86378750"},{"name":"Central Province","isoCode":"CE","countryCode":"SB","latitude":null,"longitude":null},{"name":"Choiseul Province","isoCode":"CH","countryCode":"SB","latitude":"-7.05014940","longitude":"156.95114590"},{"name":"Honiara","isoCode":"CT","countryCode":"SB","latitude":"-9.44563810","longitude":"159.97289990"},{"name":"Guadalcanal Province","isoCode":"GU","countryCode":"SB","latitude":"-9.57732840","longitude":"160.14558050"},{"name":"Isabel Province","isoCode":"IS","countryCode":"SB","latitude":"-8.05923530","longitude":"159.14470810"},{"name":"Makira-Ulawa Province","isoCode":"MK","countryCode":"SB","latitude":"-10.57374470","longitude":"161.80969410"},{"name":"Malaita Province","isoCode":"ML","countryCode":"SB","latitude":"-8.94461680","longitude":"160.90712360"},{"name":"Rennell and Bellona Province","isoCode":"RB","countryCode":"SB","latitude":"-11.61314350","longitude":"160.16939490"},{"name":"Temotu Province","isoCode":"TE","countryCode":"SB","latitude":"-10.68692900","longitude":"166.06239790"},{"name":"Western Province","isoCode":"WE","countryCode":"SB","latitude":null,"longitude":null},{"name":"Anse-aux-Pins","isoCode":"01","countryCode":"SC","latitude":"-4.69004430","longitude":"55.51502890"},{"name":"Anse Boileau","isoCode":"02","countryCode":"SC","latitude":"-4.70472680","longitude":"55.48593630"},{"name":"Au Cap","isoCode":"04","countryCode":"SC","latitude":"-4.70597230","longitude":"55.50810120"}
1,{"name":"Anse Royale","isoCode":"05","countryCode":"SC","latitude":"-4.74079880","longitude":"55.50810120"},{"name":"Baie Lazare","isoCode":"06","countryCode":"SC","latitude":"-4.74825250","longitude":"55.48593630"},{"name":"Baie Sainte Anne","isoCode":"07","countryCode":"SC","latitude":"47.05259000","longitude":"-64.95245790"},{"name":"Beau Vallon","isoCode":"08","countryCode":"SC","latitude":"-4.62109670","longitude":"55.42778020"},{"name":"Bel Air","isoCode":"09","countryCode":"SC","latitude":"34.10024550","longitude":"-118.45946300"},{"name":"Bel Ombre","isoCode":"10","countryCode":"SC","latitude":"-20.50100950","longitude":"57.42596240"},{"name":"Cascade","isoCode":"11","countryCode":"SC","latitude":"44.51628210","longitude":"-116.04179830"},{"name":"Glacis","isoCode":"12","countryCode":"SC","latitude":"47.11573030","longitude":"-70.30281830"},{"name":"Grand\'Anse Mahé","isoCode":"13","countryCode":"SC","latitude":"-4.67739200","longitude":"55.46377700"},{"name":"Grand\'Anse Praslin","isoCode":"14","countryCode":"SC","latitude":"-4.31762190","longitude":"55.70783630"},{"name":"La Digue","isoCode":"15","countryCode":"SC","latitude":"49.76669220","longitude":"-97.15466290"},{"name":"La Rivière Anglaise","isoCode":"16","countryCode":"SC","latitude":"-4.61061500","longitude":"55.45408410"},{"name":"Mont Buxton","isoCode":"17","countryCode":"SC","latitude":"-4.61666670","longitude":"55.44577680"},{"name":"Mont Fleuri","isoCode":"18","countryCode":"SC","latitude":"-4.63565430","longitude":"55.45546880"},{"name":"Plaisance","isoCode":"19","countryCode":"SC","latitude":"45.60709500","longitude":"-75.11427450"},{"name":"Pointe La Rue","isoCode":"20","countryCode":"SC","latitude":"-4.68048900","longitude":"55.51918570"},{"name":"Port Glaud","isoCode":"21","countryCode":"SC","latitude":"-4.64885230","longitude":"55.41947530"},{"name":"Saint Louis","isoCode":"22","countryCode":"SC","latitude":"38.62700250","longitude":"-90.19940420"},{"name":"Takamaka","isoCode":"23","countryCode":"SC","latitude":"37.96459170","longitude":"-1.22177270"},{"name":"Les Mamelles","isoCode":"24","countryCode":"SC","latitude":"38.82505050","longitude":"-90.48345170"},{"name":"Roche Caiman","isoCode":"25","countryCode":"SC","latitude":"-4.63960280","longitude":"55.46793150"},{"name":"Central Darfur","isoCode":"DC","countryCode":"SD","latitude":"14.37827470","longitude":"24.90422080"},{"name":"East Darfur","isoCode":"DE","countryCode":"SD","latitude":"14.37827470","longitude":"24.90422080"},{"name":"North Darfur","isoCode":"DN","countryCode":"SD","latitude":"15.76619690","longitude":"24.90422080"},{"name":"South Darfur","isoCode":"DS","countryCode":"SD","latitude":"11.64886390","longitude":"24.90422080"},{"name":"West Darfur","isoCode":"DW","countryCode":"SD","latitude":"12.84635610","longitude":"23.00119890"},{"name":"Al Qadarif","isoCode":"GD","countryCode":"SD","latitude":"14.02430700","longitude":"35.36856790"},{"name":"West Kordofan","isoCode":"GK","countryCode":"SD","latitude":"11.19901920","longitude":"29.41793240"},{"name":"Al Jazirah","isoCode":"GZ","countryCode":"SD","latitude":"14.88596110","longitude":"33.43835300"},{"name":"Kassala","isoCode":"KA","countryCode":"SD","latitude":"15.45813320","longitude":"36.40396290"},{"name":"Khartoum","isoCode":"KH","countryCode":"SD","latitude":"15.50065440","longitude":"32.55989940"},{"name":"North Kordofan","isoCode":"KN","countryCode":"SD","latitude":"13.83064410","longitude":"29.41793240"},{"name":"South Kordofan","isoCode":"KS","countryCode":"SD","latitude":"11.19901920","longitude":"29.41793240"},{"name":"Blue Nile","isoCode":"NB","countryCode":"SD","latitude":"47.59867300","longitude":"-122.33441900"},{"name":"Northern","isoCode":"NO","countryCode":"SD","latitude":"38.06381700","longitude":"-84.46286480"},{"name":"River Nile","isoCode":"NR","countryCode":"SD","latitude":"23.97275950","longitude":"32.87492060"},{"name":"White Nile","isoCode":"NW","countryCode":"SD","latitude":"9.33215160","longitude":"31.46153000"},{"name":"Red Sea","isoCode":"RS","countryCode":"SD","latitude":"20.28023200","longitude":"38.51257300"},{"name":"Sennar","isoCode":"SI","countryCode":"SD","latitude":"13.56746900","longitude":"33.56720450"},{"name":"Stockholm County","isoCode":"AB","countryCode":"SE","latitude":"59.60249580","longitude":"18.13843830"},{"name":"Västerbotten County","isoCode":"AC","countryCode":"SE","latitude":"65.33373110","longitude":"16.51616940"},{"name":"Norrbotten County","isoCode":"BD","countryCode":"SE","latitude":"66.83092160","longitude":"20.39919660"},{"name":"Uppsala County","isoCode":"C","countryCode":"SE","latitude":"60.00922620","longitude":"17.27145880"},{"name":"Södermanland County","isoCode":"D","countryCode":"SE","latitude":"59.03363490","longitude":"16.75188990"},{"name":"Ãstergötland County","isoCode":"E","countryCode":"SE","latitude":"58.34536350","longitude":"15.51978440"},{"name":"Jönköping County","isoCode":"F","countryCode":"SE","latitude":"57.37084340","longitude":"14.34391740"},{"name":"Kronoberg County","isoCode":"G","countryCode":"SE","latitude":"56.71834030","longitude":"14.41146730"},{"name":"Kalmar County","isoCode":"H","countryCode":"SE","latitude":"57.23501560","longitude":"16.18493490"},{"name":"Gotland County","isoCode":"I","countryCode":"SE","latitude":"57.46841210","longitude":"18.48674470"},{"name":"Blekinge","isoCode":"K","countryCode":"SE","latitude":"56.27838370","longitude":"15.01800580"},{"name":"SkÃ¥ne County","isoCode":"M","countryCode":"SE","latitude":"55.9902572
10","longitude":"13.59576920"},{"name":"Halland County","isoCode":"N","countryCode":"SE","latitude":"56.89668050","longitude":"12.80339930"},{"name":"Västra Götaland County","isoCode":"O","countryCode":"SE","latitude":"58.25279260","longitude":"13.05964250"},{"name":"Värmland County","isoCode":"S","countryCode":"SE","latitude":"59.72940650","longitude":"13.23540240"},{"name":"Ãrebro County","isoCode":"T","countryCode":"SE","latitude":"59.53503600","longitude":"15.00657310"},{"name":"Västmanland County","isoCode":"U","countryCode":"SE","latitude":"59.67138790","longitude":"16.21589530"},{"name":"Dalarna County","isoCode":"W","countryCode":"SE","latitude":"61.09170120","longitude":"14.66636530"},{"name":"Gävleborg County","isoCode":"X","countryCode":"SE","latitude":"61.30119930","longitude":"16.15342140"},{"name":"Västernorrland County","isoCode":"Y","countryCode":"SE","latitude":"63.42764730","longitude":"17.72924440"},{"name":"Central Singapore Community Development Council","isoCode":"01","countryCode":"SG","latitude":"1.29868","longitude":"103.85367"},{"name":"North East Community Development Council","isoCode":"02","countryCode":"SG","latitude":"1.31421","longitude":"103.85822"},{"name":"North West Community Development Council","isoCode":"03","countryCode":"SG","latitude":"1.29868","longitude":"103.81986"},{"name":"South East Community Development Council","isoCode":"04","countryCode":"SG","latitude":"1.30683","longitude":"103.88698"},{"name":"South West Community Development Council","isoCode":"05","countryCode":"SG","latitude":"1.31464","longitude":"103.83007"},{"name":"AjdovÅ¡Äina Municipality","isoCode":"001","countryCode":"SI","latitude":"45.88707760","longitude":"13.90428180"},{"name":"Beltinci Municipality","isoCode":"002","countryCode":"SI","latitude":"46.60791530","longitude":"16.23651270"},{"name":"Bled Municipality","isoCode":"003","countryCode":"SI","latitude":"46.36832660","longitude":"14.11457980"},{"name":"Bohinj Municipality","isoCode":"004","countryCode":"SI","latitude":"46.30056520","longitude":"13.94271950"},{"name":"Borovnica Municipality","isoCode":"005","countryCode":"SI","latitude":"45.90445250","longitude":"14.38241890"},{"name":"Bovec Municipality","isoCode":"006","countryCode":"SI","latitude":"46.33804950","longitude":"13.55241740"},{"name":"Brda Municipality","isoCode":"007","countryCode":"SI","latitude":"45.99756520","longitude":"13.52704740"},{"name":"Brezovica Municipality","isoCode":"008","countryCode":"SI","latitude":"45.95593510","longitude":"14.43499520"},{"name":"Brežice Municipality","isoCode":"009","countryCode":"SI","latitude":"45.90410960","longitude":"15.59436390"},{"name":"TiÅ¡ina Municipality","isoCode":"010","countryCode":"SI","latitude":"46.65418840","longitude":"16.07547810"},{"name":"City Municipality of Celje","isoCode":"011","countryCode":"SI","latitude":"46.23974950","longitude":"15.26770630"},{"name":"Cerklje na Gorenjskem Municipality","isoCode":"012","countryCode":"SI","latitude":"46.25170540","longitude":"14.48579790"},{"name":"Cerknica Municipality","isoCode":"013","countryCode":"SI","latitude":"45.79662550","longitude":"14.39217700"},{"name":"Cerkno Municipality","isoCode":"014","countryCode":"SI","latitude":"46.12884140","longitude":"13.98940270"},{"name":"ÄrenÅ¡ovci Municipality","isoCode":"015","countryCode":"SI","latitude":"46.57200290","longitude":"16.28773460"},{"name":"Ärna na KoroÅ¡kem Municipality","isoCode":"016","countryCode":"SI","latitude":"46.47045290","longitude":"14.84999980"},{"name":"Ärnomelj Municipality","isoCode":"017","countryCode":"SI","latitude":"45.53612250","longitude":"15.19441430"},{"name":"Destrnik Municipality","isoCode":"018","countryCode":"SI","latitude":"46.49223680","longitude":"15.87779560"},{"name":"DivaÄa Municipality","isoCode":"019","countryCode":"SI","latitude":"45.68060690","longitude":"13.97203120"},{"name":"Dobrepolje Municipality","isoCode":"020","countryCode":"SI","latitude":"45.85249510","longitude":"14.70831090"},{"name":"DobrovaâPolhov Gradec Municipality","isoCode":"021","countryCode":"SI","latitude":"46.06488960","longitude":"14.31681950"},{"name":"Dol pri Ljubljani Municipality","isoCode":"022","countryCode":"SI","latitude":"46.08843860","longitude":"14.64247920"},{"name":"Domžale Municipality","isoCode":"023","countryCode":"SI","latitude":"46.14382690","longitude":"14.63752790"},{"name":"Dornava Municipality","isoCode":"024","countryCode":"SI","latitude":"46.44435130","longitude":"15.98891590"},{"name":"Dravograd Municipality","isoCode":"025","countryCode":"SI","latitude":"46.58921900","longitude":"15.02460210"},{"name":"Duplek Municipality","isoCode":"026","countryCode":"SI","latitude":"46.50100160","longitude":"15.75463070"},{"name":"Gorenja VasâPoljane Municipality","isoCode":"027","countryCode":"SI","latitude":"46.11165820","longitude":"14.11493480"},{"name":"GoriÅ¡nica Municipality","isoCode":"028","countryCode":"SI","latitude":"46.41202710","longitude":"16.01330890"},{"name":"Gornja Radgona Municipality","isoCode":"029","countryCode":"SI","latitude":"46.67670990","longitude":"15.99108470"},{"name":"Gornji Grad Municipality","isoCode":"030","countryCode":"SI","latitude":"46.29617120","longitude":"14.80623470"},{"name":"Gornji Petrovci Municipality","isoCode":"031","countryCode":"SI","latitude":"46.80371280","longitude":"16.21913790"},{"name":"Grosuplje Municipality","isoCode":"032","countryCode":"SI","latitude":"45.95576450","longitude":"14.65889900"},{"name":"Å alovci Municipality","isoCode":"033","countryCode":"SI","latitude":"46.85335680","longitude":"16.25917910"},{"name":"Hrastnik Municipality","isoCode":"034","countryCode":"SI","latitude":"46.14172880","longitude":"15.08448940"},{"name":"HrpeljeâKozina Municipality","isoCode":"035","countryCode":"SI","latitude":"45.60911920","longitude":"13.93791480"},{"name":"Idrija Municipality","isoCode":"036","countryCode":"SI","latitude":"46.00409390","longitude":"13.97754930"},{"name":"Ig Municipality","isoCode":"037","countryCode":"SI","latitude":"45.95888680","longitude":"14.52705280"},{"name":"Municipality of Ilirska Bistrica","isoCode":"038","countryCode":"SI","latitude":"45.57913230","longitude":"14.28097290"},{"name":"IvanÄna Gorica Municipality","isoCode":"039","countryCode":"SI","latitude":"45.93958410","longitude":"14.80476260"},{"name":"Izola Municipality","isoCode":"040","countryCode":"SI","latitude":"45.53135570","longitude":"13.66646490"},{"name":"Jesenice Municipality","isoCode":"041","countryCode":"SI","latitude":"46.43670470","longitude":"14.05260570"},{"name":"JurÅ¡inci Municipality","isoCode":"042","countryCode":"SI","latitude":"46.48986510","longitude":"15.98092300"},{"name":"Kamnik Municipality","isoCode":"043","countryCode":"SI","latitude":"46.22216660","longitude":"14.60707270"},{"name":"Kanal ob SoÄi Municipality","isoCode":"044","countryCode":"SI","latitude":"46.06735300","longitude":"13.62033500"},{"name":"KidriÄevo Municipality","isoCode":"045","countryCode":"SI","latitude":"46.39575720","longitude":"15.79259060"},{"name":"Kobarid Municipality","isoCode":"046","countryCode":"SI","latitude":"46.24569710","longitude":"13.57869490"},{"name":"Kobilje Municipality","isoCode":"047","countryCode":"SI","latitude":"46.68518000","longitude":"16.39367190"},{"name":"KoÄevje Municipality","isoCode":"048","countryCode":"SI","latitude":"45.64280000","longitude":"14.86158380"},{"name":"Komen Municipality","isoCode":"049","countryCode":"SI","latitude":"45.81752350","longitude":"13.74827110"},{"name":"Koper City Municipality","isoCode":"050","countryCode":"SI","latitude":"45.54805900","longitude":"13.73018770"},{"name":"Kozje Municipality","isoCode":"051","countryCode":"SI","latitude":"46.07332110","longitude":"15.55967190"},{"name":"Kranj City Municipality","isoCode":"052","countryCode":"SI","latitude":"46.25850210","longitude":"14.35435690"},{"name":"Kranjska Gora Municipality","isoCode":"053","countryCode":"SI","latitude":"46.48452930","longitude":"13.78571450"},{"name":"Municipality of KrÅ¡ko","isoCode":"054","countryCode":"SI","latitude":"45.95896090","longitude":"15.49235550"},{"name":"Kungota","isoCode":"055","countryCode":"SI","latitude":"46.64187930","longitude":"15.60362880"},{"name":"Kuzma Municipality","isoCode":"056","countryCode":"SI","latitude":"46.83510380","longitude":"16.08071000"},{"name":"LaÅ¡ko Municipality","isoCode":"057","countryCode":"SI","latitude":"46.15422360","longitude":"15.23614910"},{"name":"Lenart Municipality","isoCode":"058","countryCode":"SI","latitude":"46.58344240","longitude":"15.82621250"},{"name":"Lendava Municipality","isoCode":"059","countryCode":"SI","latitude":"46.55134830","longitude":"16.44198390"},{"name":"Litija Municipality","isoCode":"060","countryCode":"SI","latitude":"46.05732260","longitude":"14.83096360"},{"name":"Ljubljana City Municipality","isoCode":"061","countryCode":"SI","latitude":"46.05694650","longitude":"14.50575150"},{"name":"Ljubno Municipality","isoCode":"062","countryCode":"SI","latitude":"46.34431250","longitude":"14.83354920"},{"name":"Ljutomer Municipality","isoCode":"063","countryCode":"SI","latitude":"46.51908480","longitude":"16.18932160"},{"name":"Logatec Municipality","isoCode":"064","countryCode":"SI","latitude":"45.91761100","longitude":"14.23514510"},{"name":"LoÅ¡ka Dolina Municipality","isoCode":"065","countryCode":"SI","latitude":"45.64779080","longitude":"14.49731470"},{"name":"LoÅ¡ki Potok Municipality","isoCode":"066","countryCode":"SI","latitude":"45.69096370","longitude":"14.59859700"},{"name":"LuÄe Municipality","isoCode":"067","countryCode":"SI","latitude":"46.35449250","longitude":"14.74715040"},{"name":"Lukovica Municipality","isoCode":"068","countryCode":"SI","latitude":"46.16962930","longitude":"14.69072590"},{"name":"MajÅ¡perk Municipality","isoCode":"069","countryCode":"SI","latitude":"46.35030190","longitude":"15.73405950"},{"name":"Maribor City Municipality","isoCode":"070","countryCode":"SI","latitude":"46.55064960","longitude":"15.62054390"},{"name":"Medvode Municipality","isoCode":"071","countryCode":"SI","latitude":"46.14190800","longitude":"14.40325960"},{"name":"MengeÅ¡ Municipality","isoCode":"072","countryCode":"SI","latitude":"46.16591220","longitude":"14.57196940"},{"name":"Metlika Municipality","isoCode":"073","countryCode":"SI","latitude":"45.64807150","longitude":"15.31778380"},{"name":"Mežica Municipality","isoCode":"074","countryCode":"SI","latitude":"46.52150270","longitude":"14.85213400"},{"name":"MirenâKostanjevica Municipality","isoCode":"075","countryCode":"SI","latitude":"45.84360290","longitude":"13.62766470"},{"name":"Mislinja Municipality","isoCode":"076","countryCode":"SI","latitude":"46.44294030","longitude":"15.19876780"},{"name":"MoravÄe Municipality","isoCode":"077","countryCode":"SI","latitude":"46.13627810","longitude":"14.74600100"},{"name":"Moravske Toplice Municipality","isoCode":"078","countryCode":"SI","latitude":"46.68569320","longitude":"16.22245820"},{"name":"Mozirje Municipality","isoCode":"079","countryCode":"SI","latitude":"46.33943500","longitude":"14.96024130"}
1,{"name":"Murska Sobota City Municipality","isoCode":"080","countryCode":"SI","latitude":"46.64321470","longitude":"16.15157540"},{"name":"Muta Municipality","isoCode":"081","countryCode":"SI","latitude":"46.60973660","longitude":"15.16299950"},{"name":"Naklo Municipality","isoCode":"082","countryCode":"SI","latitude":"46.27186630","longitude":"14.31569320"},{"name":"Nazarje Municipality","isoCode":"083","countryCode":"SI","latitude":"46.28217410","longitude":"14.92256290"},{"name":"Nova Gorica City Municipality","isoCode":"084","countryCode":"SI","latitude":"45.97627600","longitude":"13.73088810"},{"name":"City Municipality of Novo Mesto","isoCode":"085","countryCode":"SI","latitude":"45.80108240","longitude":"15.17100890"},{"name":"Odranci Municipality","isoCode":"086","countryCode":"SI","latitude":"46.59010170","longitude":"16.27881650"},{"name":"Ormož Municipality","isoCode":"087","countryCode":"SI","latitude":"46.43533330","longitude":"16.15437400"},{"name":"Osilnica Municipality","isoCode":"088","countryCode":"SI","latitude":"45.54184670","longitude":"14.71563030"},{"name":"Pesnica Municipality","isoCode":"089","countryCode":"SI","latitude":"46.60887550","longitude":"15.67570510"},{"name":"Piran Municipality","isoCode":"090","countryCode":"SI","latitude":"45.52888560","longitude":"13.56807350"},{"name":"Pivka Municipality","isoCode":"091","countryCode":"SI","latitude":"45.67892960","longitude":"14.25426890"},{"name":"PodÄetrtek Municipality","isoCode":"092","countryCode":"SI","latitude":"46.17395420","longitude":"15.60138160"},{"name":"Podvelka Municipality","isoCode":"093","countryCode":"SI","latitude":"46.62219520","longitude":"15.38899220"},{"name":"Postojna Municipality","isoCode":"094","countryCode":"SI","latitude":"45.77493900","longitude":"14.21342630"},{"name":"Preddvor Municipality","isoCode":"095","countryCode":"SI","latitude":"46.30171390","longitude":"14.42181650"},{"name":"Ptuj City Municipality","isoCode":"096","countryCode":"SI","latitude":"46.41995350","longitude":"15.86968840"},{"name":"Puconci Municipality","isoCode":"097","countryCode":"SI","latitude":"46.72004180","longitude":"16.09977920"},{"name":"RaÄeâFram Municipality","isoCode":"098","countryCode":"SI","latitude":"46.45420830","longitude":"15.63294670"},{"name":"RadeÄe Municipality","isoCode":"099","countryCode":"SI","latitude":"46.06669540","longitude":"15.18204380"},{"name":"Radenci Municipality","isoCode":"100","countryCode":"SI","latitude":"46.62311210","longitude":"16.05069030"},{"name":"Radlje ob Dravi Municipality","isoCode":"101","countryCode":"SI","latitude":"46.61357320","longitude":"15.23544380"},{"name":"Radovljica Municipality","isoCode":"102","countryCode":"SI","latitude":"46.33558270","longitude":"14.20945340"},{"name":"Ravne na KoroÅ¡kem Municipality","isoCode":"103","countryCode":"SI","latitude":"46.55211940","longitude":"14.95990840"},{"name":"Ribnica Municipality","isoCode":"104","countryCode":"SI","latitude":"45.74003030","longitude":"14.72657820"},{"name":"RogaÅ¡ovci Municipality","isoCode":"105","countryCode":"SI","latitude":"46.80557850","longitude":"16.03452370"},{"name":"RogaÅ¡ka Slatina Municipality","isoCode":"106","countryCode":"SI","latitude":"46.24539730","longitude":"15.62650140"},{"name":"Rogatec Municipality","isoCode":"107","countryCode":"SI","latitude":"46.22866260","longitude":"15.69913380"},{"name":"RuÅ¡e Municipality","isoCode":"108","countryCode":"SI","latitude":"46.52062650","longitude":"15.48178690"},{"name":"SemiÄ Municipality","isoCode":"109","countryCode":"SI","latitude":"45.65205340","longitude":"15.18207010"},{"name":"Sevnica Municipality","isoCode":"110","countryCode":"SI","latitude":"46.00703170","longitude":"15.30456790"},{"name":"Sežana Municipality","isoCode":"111","countryCode":"SI","latitude":"45.72751090","longitude":"13.86619310"},{"name":"Slovenj Gradec City Municipality","isoCode":"112","countryCode":"SI","latitude":"46.48777180","longitude":"15.07294780"},{"name":"Slovenska Bistrica Municipality","isoCode":"113","countryCode":"SI","latitude":"46.39198130","longitude":"15.57278690"},{"name":"Slovenske Konjice Municipality","isoCode":"114","countryCode":"SI","latitude":"46.33691910","longitude":"15.42147080"},{"name":"StarÅ¡e Municipality","isoCode":"115","countryCode":"SI","latitude":"46.46743310","longitude":"15.76405460"},{"name":"Sveti Jurij ob Å Äavnici Municipality","isoCode":"116","countryCode":"SI","latitude":"46.56874520","longitude":"16.02225280"},{"name":"Å enÄur Municipality","isoCode":"117","countryCode":"SI","latitude":"46.24336990","longitude":"14.41922230"},{"name":"Å entilj Municipality","isoCode":"118","countryCode":"SI","latitude":"46.68628390","longitude":"15.71035670"},{"name":"Å entjernej Municipality","isoCode":"119","countryCode":"SI","latitude":"45.84341300","longitude":"15.33783120"},{"name":"Å entjur Municipality","isoCode":"120","countryCode":"SI","latitude":"46.26543390","longitude":"15.40800000"},{"name":"Å kocjan Municipality","isoCode":"121","countryCode":"SI","latitude":"45.91754540","longitude":"15.31017360"},{"name":"Å kofja Loka Municipality","isoCode":"122","countryCode":"SI","latitude":"46.14098440","longitude":"14.28
1118730"},{"name":"Municipality of Å kofljica","isoCode":"123","countryCode":"SI","latitude":"45.98409620","longitude":"14.57466260"},{"name":"Å marje pri JelÅ¡ah Municipality","isoCode":"124","countryCode":"SI","latitude":"46.22870250","longitude":"15.51903530"},{"name":"Å martno ob Paki Municipality","isoCode":"125","countryCode":"SI","latitude":"46.32903720","longitude":"15.03339370"},{"name":"Å oÅ¡tanj Municipality","isoCode":"126","countryCode":"SI","latitude":"46.37828360","longitude":"15.04613780"},{"name":"Å tore Municipality","isoCode":"127","countryCode":"SI","latitude":"46.22225140","longitude":"15.31261160"},{"name":"Tolmin Municipality","isoCode":"128","countryCode":"SI","latitude":"46.18571880","longitude":"13.73198380"},{"name":"Trbovlje Municipality","isoCode":"129","countryCode":"SI","latitude":"46.15035630","longitude":"15.04531370"},{"name":"Trebnje Municipality","isoCode":"130","countryCode":"SI","latitude":"45.90801630","longitude":"15.01319050"},{"name":"TržiÄ Municipality","isoCode":"131","countryCode":"SI","latitude":"46.35935140","longitude":"14.30066230"},{"name":"TurniÅ¡Äe Municipality","isoCode":"132","countryCode":"SI","latitude":"46.61375040","longitude":"16.32021000"},{"name":"Velike LaÅ¡Äe Municipality","isoCode":"134","countryCode":"SI","latitude":"45.83365910","longitude":"14.63623630"},{"name":"Videm Municipality","isoCode":"135","countryCode":"SI","latitude":"46.36383300","longitude":"15.87812120"},{"name":"Vipava Municipality","isoCode":"136","countryCode":"SI","latitude":"45.84126740","longitude":"13.96096130"},{"name":"Vitanje Municipality","isoCode":"137","countryCode":"SI","latitude":"46.38153230","longitude":"15.29506870"},{"name":"Vodice Municipality","isoCode":"138","countryCode":"SI","latitude":"46.18966430","longitude":"14.49385390"},{"name":"Vojnik Municipality","isoCode":"139","countryCode":"SI","latitude":"46.29205810","longitude":"15.30205800"},{"name":"Vrhnika Municipality","isoCode":"140","countryCode":"SI","latitude":"45.95027190","longitude":"14.32764220"},{"name":"Vuzenica Municipality","isoCode":"141","countryCode":"SI","latitude":"46.59808360","longitude":"15.16572370"},{"name":"Zagorje ob Savi Municipality","isoCode":"142","countryCode":"SI","latitude":"46.13452020","longitude":"14.99643840"},{"name":"ZavrÄ Municipality","isoCode":"143","countryCode":"SI","latitude":"46.35713000","longitude":"16.04777470"},{"name":"ZreÄe Municipality","isoCode":"144","countryCode":"SI","latitude":"46.41777860","longitude":"15.37094310"},{"name":"Železniki Municipality","isoCode":"146","countryCode":"SI","latitude":"46.22563770","longitude":"14.16936170"},{"name":"Žiri Municipality","isoCode":"147","countryCode":"SI","latitude":"46.04724990","longitude":"14.10984510"},{"name":"Benedikt Municipality","isoCode":"148","countryCode":"SI","latitude":"46.61558410","longitude":"15.89572810"},{"name":"Bistrica ob Sotli Municipality","isoCode":"149","countryCode":"SI","latitude":"46.05655790","longitude":"15.66259470"},{"name":"Bloke Municipality","isoCode":"150","countryCode":"SI","latitude":"45.77281410","longitude":"14.50634590"},{"name":"BraslovÄe Municipality","isoCode":"151","countryCode":"SI","latitude":"46.28361920","longitude":"15.04183200"},{"name":"Cankova Municipality","isoCode":"152","countryCode":"SI","latitude":"46.71823700","longitude":"16.01972220"},{"name":"Cerkvenjak Municipality","isoCode":"153","countryCode":"SI","latitude":"46.56707110","longitude":"15.94297530"},{"name":"Dobje Municipality","isoCode":"154","countryCode":"SI","latitude":"46.13700370","longitude":"15.39412900"},{"name":"Dobrna Municipality","isoCode":"155","countryCode":"SI","latitude":"46.33561410","longitude":"15.22597320"},{"name":"Dobrovnik Municipality","isoCode":"156","countryCode":"SI","latitude":"46.65386620","longitude":"16.35065940"},{"name":"Dolenjske Toplice Municipality","isoCode":"157","countryCode":"SI","latitude":"45.73457110","longitude":"15.01294930"},{"name":"Grad Municipality","isoCode":"158","countryCode":"SI","latitude":"46.80873200","longitude":"16.10920600"},{"name":"Hajdina Municipality","isoCode":"159","countryCode":"SI","latitude":"46.41850140","longitude":"15.82447220"},{"name":"HoÄeâSlivnica Municipality","isoCode":"160","countryCode":"SI","latitude":"46.47785800","longitude":"15.64760050"},{"name":"HodoÅ¡ Municipality","isoCode":"161","countryCode":"SI","latitude":"46.83141340","longitude":"16.32106800"},{"name":"Horjul Municipality","isoCode":"162","countryCode":"SI","latitude":"46.02253780","longitude":"14.29862690"},{"name":"Jezersko Municipality","isoCode":"163","countryCode":"SI","latitude":"46.39427940","longitude":"14.49855590"},{"name":"Komenda Municipality","isoCode":"164","countryCode":"SI","latitude":"46.20648800","longitude":"14.53824990"},{"name":"Kostel Municipality","isoCode":"165","countryCode":"SI","latitude":"45.49282550","longitude":"14.87082350"},{"name":"Križevci Municipality","isoCode":"166","countryCode":"SI","latitude":"46.57018210","longitude":"16.10926530"},{"name":"Lovrenc na Pohorju Municipality","isoCode":"167","countryCode":"SI","latitude":"46.54196380","longitude":"15.40004430"},{"name":"Markovci Municipality","isoCode":"168","countryCode":"SI","latitude":"46.38793090","longitude":"15.95860140"}
1,{"name":"Miklavž na Dravskem Polju Municipality","isoCode":"169","countryCode":"SI","latitude":"46.50826280","longitude":"15.69520650"},{"name":"Mirna PeÄ Municipality","isoCode":"170","countryCode":"SI","latitude":"45.84815740","longitude":"15.08794500"},{"name":"Oplotnica","isoCode":"171","countryCode":"SI","latitude":"46.38716300","longitude":"15.44581310"},{"name":"Podlehnik Municipality","isoCode":"172","countryCode":"SI","latitude":"46.33107820","longitude":"15.87858360"},{"name":"Polzela Municipality","isoCode":"173","countryCode":"SI","latitude":"46.28089700","longitude":"15.07373210"},{"name":"Prebold Municipality","isoCode":"174","countryCode":"SI","latitude":"46.23591360","longitude":"15.09369120"},{"name":"Prevalje Municipality","isoCode":"175","countryCode":"SI","latitude":"46.56211460","longitude":"14.88478610"},{"name":"Razkrižje Municipality","isoCode":"176","countryCode":"SI","latitude":"46.52263390","longitude":"16.26686380"},{"name":"Ribnica na Pohorju Municipality","isoCode":"177","countryCode":"SI","latitude":"46.53561450","longitude":"15.26745380"},{"name":"Selnica ob Dravi Municipality","isoCode":"178","countryCode":"SI","latitude":"46.55139180","longitude":"15.49294100"},{"name":"Sodražica Municipality","isoCode":"179","countryCode":"SI","latitude":"45.76165650","longitude":"14.63528530"},{"name":"SolÄava Municipality","isoCode":"180","countryCode":"SI","latitude":"46.40235260","longitude":"14.68023040"},{"name":"Sveta Ana Municipality","isoCode":"181","countryCode":"SI","latitude":"46.65000000","longitude":"15.84527800"},{"name":"Sveti Andraž v Slovenskih Goricah Municipality","isoCode":"182","countryCode":"SI","latitude":"46.51897470","longitude":"15.94982620"},{"name":"Å empeterâVrtojba Municipality","isoCode":"183","countryCode":"SI","latitude":"45.92900950","longitude":"13.64155940"},{"name":"Tabor Municipality","isoCode":"184","countryCode":"SI","latitude":"46.21079210","longitude":"15.01742490"},{"name":"Trnovska Vas Municipality","isoCode":"185","countryCode":"SI","latitude":"46.52940350","longitude":"15.88531180"},{"name":"Trzin Municipality","isoCode":"186","countryCode":"SI","latitude":"46.12982410","longitude":"14.55776370"},{"name":"Velika Polana Municipality","isoCode":"187","countryCode":"SI","latitude":"46.57317150","longitude":"16.34441260"},{"name":"Veržej Municipality","isoCode":"188","countryCode":"SI","latitude":"46.58411350","longitude":"16.16208000"},{"name":"Vransko Municipality","isoCode":"189","countryCode":"SI","latitude":"46.23900600","longitude":"14.95272490"},{"name":"Žalec Municipality","isoCode":"190","countryCode":"SI","latitude":"46.25197120","longitude":"15.16500720"},{"name":"Žetale Municipality","isoCode":"191","countryCode":"SI","latitude":"46.27428330","longitude":"15.79133590"},{"name":"Žirovnica Municipality","isoCode":"192","countryCode":"SI","latitude":"46.39544030","longitude":"14.15396320"},{"name":"Žužemberk Municipality","isoCode":"193","countryCode":"SI","latitude":"45.82003500","longitude":"14.95359190"},{"name":"Å martno pri Litiji Municipality","isoCode":"194","countryCode":"SI","latitude":"46.04549710","longitude":"14.84101330"},{"name":"Municipality of ApaÄe","isoCode":"195","countryCode":"SI","latitude":"46.69746790","longitude":"15.91025340"},{"name":"Municipality of Cirkulane","isoCode":"196","countryCode":"SI","latitude":"46.32983220","longitude":"15.99806660"},{"name":"Kostanjevica na Krki Municipality","isoCode":"197","countryCode":"SI","latitude":"45.83166380","longitude":"15.44119060"},{"name":"Makole Municipality","isoCode":"198","countryCode":"SI","latitude":"46.31686970","longitude":"15.66641260"},{"name":"MokronogâTrebelno Municipality","isoCode":"199","countryCode":"SI","latitude":"45.90885290","longitude":"15.15967360"},{"name":"PoljÄane Municipality","isoCode":"200","countryCode":"SI","latitude":"46.31398530","longitude":"15.57847910"},{"name":"RenÄeâVogrsko Municipality","isoCode":"201","countryCode":"SI","latitude":"45.89546170","longitude":"13.67856730"},{"name":"SrediÅ¡Äe ob Dravi","isoCode":"202","countryCode":"SI","latitude":"46.39592820","longitude":"16.27049150"},{"name":"Straža Municipality","isoCode":"203","countryCode":"SI","latitude":"45.77684280","longitude":"15.09486940"},{"name":"Sveta Trojica v Slovenskih Goricah Municipality","isoCode":"204","countryCode":"SI","latitude":"46.56808090","longitude":"15.88230640"},{"name":"Sveti Tomaž Municipality","isoCode":"205","countryCode":"SI","latitude":"46.48352830","longitude":"16.07944200"},{"name":"Å marjeÅ¡ke Toplice Municipality","isoCode":"206","countryCode":"SI","latitude":"45.86803770","longitude":"15.23474220"},{"name":"Gorje Municipality","isoCode":"207","countryCode":"SI","latitude":"46.38024580","longitude":"14.06853390"},{"name":"LogâDragomer Municipality","isoCode":"208","countryCode":"SI","latitude":"46.01787470","longitude":"14.36877670"},{"name":"ReÄica ob Savinji Municipality","isoCode":"209","countryCode":"SI","latitude":"46.32337900","longitude":"14.92236700"},{"name":"Sveti Jurij v Slovenskih Goricah Municipality","isoCode":"210","countryCode":"SI","latitude":"46.61707910","longitude":"15.78046770"},{"name":"Å entrupert Municipality","isoCode":"211","countryCode":"SI","latitude":"45.98731420","longitude":"15.08297830"},{"name":"Mirna Municipality","isoCode":"212","countryCode":"SI","latitude":"45.95156470","longitude":"15.06209770"},{"name":"Ankaran Municipality","isoCode":"213","countryCode":"SI","latitude":"45.57845100","longitude":"13.73691740"},{"name":"Banská Bystrica Region","isoCode":"BC","countryCode":"SK","latitude":"48.53124990","longitude":"19.38287400"},{"name":"Bratislava Region","isoCode":"BL","countryCode":"SK","latitude":"48.31183040","longitude":"17.19732990"},{"name":"KoÅ¡ice Region","isoCode":"KI","countryCode":"SK","latitude":"48.63757370","longitude":"21.08342250"},{"name":"Nitra Region","isoCode":"NI","countryCode":"SK","latitude":"48.01437650","longitude":"18.54165040"},{"name":"PreÅ¡ov Region","isoCode":"PV","countryCode":"SK","latitude":"49.17167730","longitude":"21.37420010"},{"name":"Trnava Region","isoCode":"TA","countryCode":"SK","latitude":"48.39438980","longitude":"17.72162050"},{"name":"TrenÄÃn Region","isoCode":"TC","countryCode":"SK","latitude":"48.80867580","longitude":"18.23240260"},{"name":"Žilina Region","isoCode":"ZI","countryCode":"SK","latitude":"49.20314350","longitude":"19.36457330"},{"name":"Eastern Province","isoCode":"E","countryCode":"SL","latitude":null,"longitude":null},{"name":"Northern Province","isoCode":"N","countryCode":"SL","latitude":null,"longitude":null},{"name":"Southern Province","isoCode":"S","countryCode":"SL","latitude":null,"longitude":null},{"name":"Western Area","isoCode":"W","countryCode":"SL","latitude":"40.25459690","longitude":"-80.24554440"},{"name":"Acquaviva","isoCode":"01","countryCode":"SM","latitude":"41.86715970","longitude":"14.74694790"},{"name":"Chiesanuova","isoCode":"02","countryCode":"SM","latitude":"45.42261720","longitude":"7.65038540"},{"name":"Domagnano","isoCode":"03","countryCode":"SM","latitude":"43.95019290","longitude":"12.46815370"},{"name":"Faetano","isoCode":"04","countryCode":"SM","latitude":"43.93489670","longitude":"12.48965540"},{"name":"Fiorentino","isoCode":"05","countryCode":"SM","latitude":"43.90783370","longitude":"12.45812090"},{"name":"Borgo Maggiore","isoCode":"06","countryCode":"SM","latitude":"43.95748820","longitude":"12.45525460"},{"name":"San Marino","isoCode":"07","countryCode":"SM","latitude":"43.94236000","longitude":"12.45777700"},{"name":"Montegiardino","isoCode":"08","countryCode":"SM","latitude":"43.90529990","longitude":"12.48105420"},{"name":"Serravalle","isoCode":"09","countryCode":"SM","latitude":"44.72320840","longitude":"8.85740050"},{"name":"Diourbel Region","isoCode":"DB","countryCode":"SN","latitude":"14.72830850","longitude":"-16.25221430"},{"name":"Dakar","isoCode":"DK","countryCode":"SN","latitude":"14.71667700","longitude":"-17.46768610"},{"name":"Fatick","isoCode":"FK","countryCode":"SN","latitude":"14.33901670","longitude":"-16.41114250"},{"name":"Kaffrine","isoCode":"KA","countryCode":"SN","latitude":"14.10520200","longitude":"-15.54157550"},{"name":"Kolda","isoCode":"KD","countryCode":"SN","latitude":"12.910
174950","longitude":"-14.95056710"},{"name":"Kédougou","isoCode":"KE","countryCode":"SN","latitude":"12.56046070","longitude":"-12.17470770"},{"name":"Kaolack","isoCode":"KL","countryCode":"SN","latitude":"14.16520830","longitude":"-16.07577490"},{"name":"Louga","isoCode":"LG","countryCode":"SN","latitude":"15.61417680","longitude":"-16.22868000"},{"name":"Matam","isoCode":"MT","countryCode":"SN","latitude":"15.66002250","longitude":"-13.25769060"},{"name":"Sédhiou","isoCode":"SE","countryCode":"SN","latitude":"12.70460400","longitude":"-15.55623040"},{"name":"Saint-Louis","isoCode":"SL","countryCode":"SN","latitude":"38.62700250","longitude":"-90.19940420"},{"name":"Tambacounda Region","isoCode":"TC","countryCode":"SN","latitude":"13.56190110","longitude":"-13.17403480"},{"name":"Thiès Region","isoCode":"TH","countryCode":"SN","latitude":"14.79100520","longitude":"-16.93586040"},{"name":"Ziguinchor","isoCode":"ZG","countryCode":"SN","latitude":"12.56414790","longitude":"-16.26398250"},{"name":"Awdal Region","isoCode":"AW","countryCode":"SO","latitude":"10.63342850","longitude":"43.32946600"},{"name":"Bakool","isoCode":"BK","countryCode":"SO","latitude":"4.36572210","longitude":"44.09603110"},{"name":"Banaadir","isoCode":"BN","countryCode":"SO","latitude":"2.11873750","longitude":"45.33694590"},{"name":"Bari","isoCode":"BR","countryCode":"SO","latitude":"41.11714320","longitude":"16.87187150"},{"name":"Bay","isoCode":"BY","countryCode":"SO","latitude":"37.03655340","longitude":"-95.61747670"},{"name":"Galguduud","isoCode":"GA","countryCode":"SO","latitude":"5.18501280","longitude":"46.82528380"},{"name":"Gedo","isoCode":"GE","countryCode":"SO","latitude":"3.50392270","longitude":"42.23624350"},{"name":"Hiran","isoCode":"HI","countryCode":"SO","latitude":"4.32101500","longitude":"45.29938620"},{"name":"Middle Juba","isoCode":"JD","countryCode":"SO","latitude":"2.07804880","longitude":"41.60118140"},{"name":"Lower Juba","isoCode":"JH","countryCode":"SO","latitude":"0.22402100","longitude":"41.60118140"},{"name":"Mudug","isoCode":"MU","countryCode":"SO","latitude":"6.56567260","longitude":"47.76375650"},{"name":"Nugal","isoCode":"NU","countryCode":"SO","latitude":"43.27938610","longitude":"17.03392050"},{"name":"Sanaag Region","isoCode":"SA","countryCode":"SO","latitude":"10.39382180","longitude":"47.76375650"},{"name":"Middle Shebelle","isoCode":"SD","countryCode":"SO","latitude":"2.92502470","longitude":"45.90396890"},{"name":"Lower Shebelle","isoCode":"SH","countryCode":"SO","latitude":"1.87664580","longitude":"44.24790150"},{"name":"Togdheer Region","isoCode":"TO","countryCode":"SO","latitude":"9.44605870","longitude":"45.29938620"},{"name":"Brokopondo District","isoCode":"BR","countryCode":"SR","latitude":"4.77102470","longitude":"-55.04933750"},{"name":"Commewijne District","isoCode":"CM","countryCode":"SR","latitude":"5.74021100","longitude":"-54.87312190"},{"name":"Coronie District","isoCode":"CR","countryCode":"SR","latitude":"5.69432710","longitude":"-56.29293810"},{"name":"Marowijne District","isoCode":"MA","countryCode":"SR","latitude":"5.62681280","longitude":"-54.25931180"},{"name":"Nickerie District","isoCode":"NI","countryCode":"SR","latitude":"5.58554690","longitude":"-56.83111170"},{"name":"Paramaribo District","isoCode":"PM","countryCode":"SR","latitude":"5.85203550","longitude":"-55.20382780"},{"name":"Para District","isoCode":"PR","countryCode":"SR","latitude":"5.48173180","longitude":"-55.22592070"},{"name":"Saramacca District","isoCode":"SA","countryCode":"SR","latitude":"5.72408130","longitude":"-55.66896360"},{"name":"Sipaliwini District","isoCode":"SI","countryCode":"SR","latitude":"3.65673820","longitude":"-56.20353870"},{"name":"Wanica District","isoCode":"WA","countryCode":"SR","latitude":"5.73237620","longitude":"-55.27012350"},{"name":"Northern Bahr el Ghazal","isoCode":"BN","countryCode":"SS","latitude":"8.53604490","longitude":"26.79678490"},{"name":"Western Bahr el Ghazal","isoCode":"BW","countryCode":"SS","latitude":"8.64523990","longitude":"25.28375850"},{"name":"Central Equatoria","isoCode":"EC","countryCode":"SS","latitude":"4.61440630","longitude":"31.26263660"},{"name":"Eastern Equatoria","isoCode":"EE","countryCode":"SS","latitude":"5.06929950","longitude":"33.43835300"},{"name":"Western Equatoria","isoCode":"EW","countryCode":"SS","latitude":"5.34717990","longitude":"28.29943500"},{"name":"Jonglei State","isoCode":"JG","countryCode":"SS","latitude":"7.18196190","longitude":"32.35609520"},{"name":"Lakes","isoCode":"LK","countryCode":"SS","latitude":"37.16282550","longitude":"-95.69116230"},{"name":"Upper Nile","isoCode":"NU","countryCode":"SS","latitude":"9.88942020","longitude":"32.71813750"},{"name":"Unity","isoCode":"UY","countryCode":"SS","latitude":"37.78712760","longitude":"-122.40340790"},{"name":"Warrap","isoCode":"WR","countryCode":"SS","latitude":"8.08862380","longitude":"28.64106410"},{"name":"PrÃncipe Province","isoCode":"P","countryCode":"ST","latitude":"1.61393810","longitude":"7.40569280"},{"name":"São Tomé Province","isoCode":"S","countryCode":"ST","latitude":"0.33019240","longitude":"6.73334300"},{"name":"Ahuachapán Department","isoCode":"AH","countryCode":"SV","latitude":"13.82161480","longitude":"-89.92532330"},{"name":"Cabañas Department","isoCode":"CA","countryCode":"SV","latitude":"13.86482880","longitude":"-88.74939980"},{"name":"Chalatenango Department","isoCode":"CH","countryCode":"SV","latitude":"14.19166480","longitude":"-89.17059980"},{"name":"Cuscatlán Department","isoCode":"CU","countryCode":"SV","latitude":"13.86619570","longitude":"-89.05615320"},{"name":"La Libertad Department","isoCode":"LI","countryCode":"SV","latitude":"13.68176610","longitude":"-89.36062980"},{"name":"Morazán Department","isoCode":"MO","countryCode":"SV","latitude":"13.76820000","longitude":"-88.12913870"},{"name":"La Paz Department","isoCode":"PA","countryCode":"SV","latitude":null,"longitude":null},{"name":"Santa Ana Department","isoCode":"SA","countryCode":"SV","latitude":"14.14611210","longitude":"-89.51200840"},{"name":"San Miguel Department","isoCode":"SM","countryCode":"SV","latitude":"13.44510410","longitude":"-88.24611830"},{"name":"Sonsonate Department","isoCode":"SO","countryCode":"SV","latitude":"13.68235800","longitude":"-89.66281110"},{"name":"San Salvador Department","isoCode":"SS","countryCode":"SV","latitude":"13.77399970","longitude":"-89.20867730"},{"name":"San Vicente Department","isoCode":"SV","countryCode":"SV","latitude":"13.58685610","longitude":"-88.74939980"},{"name":"La Unión Department","isoCode":"UN","countryCode":"SV","latitude":"13.48864430","longitude":"-87.89424510"},{"name":"Usulután Department","isoCode":"US","countryCode":"SV","latitude":"13.44706340","longitude":"-88.55653100"},{"name":"Damascus Governorate","isoCode":"DI","countryCode":"SY","latitude":"33.51514440","longitude":"36.39313540"},{"name":"Daraa Governorate","isoCode":"DR","countryCode":"SY","latitude":"32.92488130","longitude":"36.17626150"},{"name":"Deir ez-Zor Governorate","isoCode":"DY","countryCode":"SY","latitude":"35.28797980","longitude":"40.30886260"},{"name":"Al-Hasakah Governorate","isoCode":"HA","countryCode":"SY","latitude":"36.40551500","longitude":"40.79691490"},{"name":"Homs Governorate","isoCode":"HI","countryCode":"SY","latitude":"34.25671230","longitude":"38.31657250"},{"name":"Aleppo Governorate","isoCode":"HL","countryCode":"SY","latitude":"36.22623930","longitude":"37.46813960"},{"name":"Hama Governorate","isoCode":"HM","countryCode":"SY","latitude":"35.18878650","longitude":"37.21158290"},{"name":"Idlib Governorate","isoCode":"ID","countryCode":"SY","latitude":"35.82687980","longitude":"36.69572160"},{"name":"Latakia Governorate","isoCode":"LA","countryCode":"SY","latitude":"35.61297910","longitude":"36.00232250"},{"name":"Quneitra Governorate","isoCode":"QU","countryCode":"SY","latitude":"33.07763180","longitude":"35.89341360"},{"name":"Al-Raqqah Governorate","isoCode":"RA","countryCode":"SY","latitude":"35.95941060","longitude":"38.99810520"},{"name":"Rif Dimashq Governorate","isoCode":"RD","countryCode":"SY","latitude":"33.51672890","longitude":"36.95410700"},{"name":"As-Suwayda Governorate","isoCode":"SU","countryCode":"SY","latitude":"32.79891560","longitude":"36.78195050"},{"name":"Tartus Governorate","isoCode":"TA","countryCode":"SY","latitude":"35.00066520","longitude":"36.00232250"},{"name":"Hhohho District","isoCode":"HH","countryCode":"SZ","latitude":"-26.13656620","longitude":"31.35416310"},{"name":"Lubombo District","isoCode":"LU","countryCode":"SZ","latitude":"-26.78517730","longitude":"31.81070790"},{"name":"Manzini District","isoCode":"MA","countryCode":"SZ","latitude":"-26.50819990","longitude":"31.37131640"},{"name":"Shiselweni District","isoCode":"SH","countryCode":"SZ","latitude":"-26.98275770","longitude":"31.35416310"},{"name":"Batha Region","isoCode":"BA","countryCode":"TD","latitude":"13.93717750","longitude":"18.42760470"},{"name":"Bahr el Gazel","isoCode":"BG","countryCode":"TD","latitude":"14.77022660","longitude":"16.91225100"},{"name":"Borkou","isoCode":"BO","countryCode":"TD","latitude":"17.86888450","longitude":"18.80761950"},{"name":"Ennedi-Est","isoCode":"EE","countryCode":"TD","latitude":"16.34204960","longitude":"23.00119890"},{"name":"Ennedi Region","isoCode":"EN","countryCode":"TD","latitude":"17.54145780","longitude":"21.85685860"},{"name":"Ennedi-Ouest","isoCode":"EO","countryCode":"TD","latitude":"18.97756300","longitude":"21.85685860"},{"name":"Guéra Region","isoCode":"GR","countryCode":"TD","latitude":"11.12190150","longitude":"18.42760470"},{"name":"Hadjer-Lamis","isoCode":"HL","countryCode":"TD","latitude":"12.45772730","longitude":"16.72346390"},{"name":"Kanem Region","isoCode":"KA","countryCode":"TD","latitude":"14.8781262
10","longitude":"15.40680790"},{"name":"Lac Region","isoCode":"LC","countryCode":"TD","latitude":"13.69153770","longitude":"14.10013260"},{"name":"Logone Occidental Region","isoCode":"LO","countryCode":"TD","latitude":"8.75967600","longitude":"15.87600400"},{"name":"Logone Oriental Region","isoCode":"LR","countryCode":"TD","latitude":"8.31499490","longitude":"16.34637910"},{"name":"Mandoul Region","isoCode":"MA","countryCode":"TD","latitude":"8.60309100","longitude":"17.47951730"},{"name":"Moyen-Chari Region","isoCode":"MC","countryCode":"TD","latitude":"9.06399980","longitude":"18.42760470"},{"name":"Mayo-Kebbi Est Region","isoCode":"ME","countryCode":"TD","latitude":"9.40460390","longitude":"14.84546190"},{"name":"Mayo-Kebbi Ouest Region","isoCode":"MO","countryCode":"TD","latitude":"10.41130140","longitude":"15.59433880"},{"name":"N\'Djamena","isoCode":"ND","countryCode":"TD","latitude":"12.13484570","longitude":"15.05574150"},{"name":"Ouaddaï Region","isoCode":"OD","countryCode":"TD","latitude":"13.74847600","longitude":"20.71224650"},{"name":"Salamat Region","isoCode":"SA","countryCode":"TD","latitude":"10.96916010","longitude":"20.71224650"},{"name":"Sila Region","isoCode":"SI","countryCode":"TD","latitude":"12.13074000","longitude":"21.28450250"},{"name":"Tandjilé Region","isoCode":"TA","countryCode":"TD","latitude":"9.66257290","longitude":"16.72346390"},{"name":"Tibesti Region","isoCode":"TI","countryCode":"TD","latitude":"21.36500310","longitude":"16.91225100"},{"name":"Wadi Fira Region","isoCode":"WF","countryCode":"TD","latitude":"15.08924160","longitude":"21.47528510"},{"name":"Centrale Region","isoCode":"C","countryCode":"TG","latitude":"8.65860290","longitude":"1.05861350"},{"name":"Kara Region","isoCode":"K","countryCode":"TG","latitude":"9.72163930","longitude":"1.05861350"},{"name":"Maritime","isoCode":"M","countryCode":"TG","latitude":"41.65514930","longitude":"-83.52784670"},{"name":"Plateaux Region","isoCode":"P","countryCode":"TG","latitude":"7.61013780","longitude":"1.05861350"},{"name":"Savanes Region","isoCode":"S","countryCode":"TG","latitude":"10.52917810","longitude":"0.52578230"},{"name":"Bangkok","isoCode":"10","countryCode":"TH","latitude":"13.75633090","longitude":"100.50176510"},{"name":"Samut Prakan","isoCode":"11","countryCode":"TH","latitude":"13.59909610","longitude":"100.59983190"},{"name":"Nonthaburi","isoCode":"12","countryCode":"TH","latitude":"13.85910840","longitude":"100.52165080"},{"name":"Pathum Thani","isoCode":"13","countryCode":"TH","latitude":"14.02083910","longitude":"100.52502760"},{"name":"Phra Nakhon Si Ayutthaya","isoCode":"14","countryCode":"TH","latitude":"14.36923250","longitude":"100.58766340"},{"name":"Ang Thong","isoCode":"15","countryCode":"TH","latitude":"14.58960540","longitude":"100.45505200"},{"name":"Lop Buri","isoCode":"16","countryCode":"TH","latitude":"14.79950810","longitude":"100.65337060"},{"name":"Sing Buri","isoCode":"17","countryCode":"TH","latitude":"14.89362530","longitude":"100.39673140"},{"name":"Chai Nat","isoCode":"18","countryCode":"TH","latitude":"15.18519710","longitude":"100.12512500"},{"name":"Saraburi","isoCode":"19","countryCode":"TH","latitude":"14.52891540","longitude":"100.91014210"},{"name":"Chon Buri","isoCode":"20","countryCode":"TH","latitude":"13.36114310","longitude":"100.98467170"},{"name":"Rayong","isoCode":"21","countryCode":"TH","latitude":"12.68139570","longitude":"101.28162610"},{"name":"Chanthaburi","isoCode":"22","countryCode":"TH","latitude":"12.61124850","longitude":"102.10378060"},{"name":"Trat","isoCode":"23","countryCode":"TH","latitude":"12.24275630","longitude":"102.51747340"},{"name":"Chachoengsao","isoCode":"24","countryCode":"TH","latitude":"13.69041940","longitude":"101.07795960"},{"name":"Prachin Buri","isoCode":"25","countryCode":"TH","latitude":"14.04206990","longitude":"101.66008740"},{"name":"Nakhon Nayok","isoCode":"26","countryCode":"TH","latitude":"14.20694660","longitude":"101.21305110"},{"name":"Sa Kaeo","isoCode":"27","countryCode":"TH","latitude":"13.82403800","longitude":"102.06458390"},{"name":"Nakhon Ratchasima","isoCode":"30","countryCode":"TH","latitude":"14.97384930","longitude":"102.08365200"},{"name":"Buri Ram","isoCode":"31","countryCode":"TH","latitude":"14.99510030","longitude":"103.11159150"},{"name":"Surin","isoCode":"32","countryCode":"TH","latitude":"37.03582710","longitude":"-95.62763670"},{"name":"Si Sa Ket","isoCode":"33","countryCode":"TH","latitude":"15.11860090","longitude":"104.32200950"},{"name":"Ubon Ratchathani","isoCode":"34","countryCode":"TH","latitude":"15.24484530","longitude":"104.84729950"},{"name":"Yasothon","isoCode":"35","countryCode":"TH","latitude":"15.79264100","longitude":"104.14528270"},{"name":"Chaiyaphum","isoCode":"36","countryCode":"TH","latitude":"16.00749740","longitude":"101.61291720"},{"name":"Amnat Charoen","isoCode":"37","countryCode":"TH","latitude":"15.86567830","longitude":"104.62577740"},{"name":"Bueng Kan","isoCode":"38","countryCode":"TH","latitude":"18.36091040","longitude":"103.64644630"},{"name":"Nong Bua Lam Phu","isoCode":"39","countryCode":"TH","latitude":"17.22182470","longitude":"102.42603680"},{"name":"Khon Kaen","isoCode":"40","countryCode":"TH","latitude":"16.43219380","longitude":"102.82362140"},{"name":"Udon Thani","isoCode":"41","countryCode":"TH","latitude":"17.36469690","longitude":"102.81589240"},{"name":"Loei","isoCode":"42","countryCode":"TH","latitude":"17.48602320","longitude":"101.72230020"},{"name":"Nong Khai","isoCode":"43","countryCode":"TH","latitude":"17.87828030","longitude":"102.74126380"},{"name":"Maha Sarakham","isoCode":"44","countryCode":"TH","latitude":"16.01320150","longitude":"103.16151690"},{"name":"Roi Et","isoCode":"45","countryCode":"TH","latitude":"16.05381960","longitude":"103.65200360"},{"name":"Kalasin","isoCode":"46","countryCode":"TH","latitude":"16.43850800","longitude":"103.50609940"},{"name":"Sakon Nakhon","isoCode":"47","countryCode":"TH","latitude":"17.16642110","longitude":"104.14860550"},{"name":"Nakhon Phanom","isoCode":"48","countryCode":"TH","latitude":"17.39203900","longitude":"104.76955080"}
1,{"name":"Mukdahan","isoCode":"49","countryCode":"TH","latitude":"16.54359140","longitude":"104.70241210"},{"name":"Chiang Mai","isoCode":"50","countryCode":"TH","latitude":"18.78834390","longitude":"98.98530080"},{"name":"Lamphun","isoCode":"51","countryCode":"TH","latitude":"18.57446060","longitude":"99.00872210"},{"name":"Lampang","isoCode":"52","countryCode":"TH","latitude":"18.28553950","longitude":"99.51278950"},{"name":"Uttaradit","isoCode":"53","countryCode":"TH","latitude":"17.62008860","longitude":"100.09929420"},{"name":"Phrae","isoCode":"54","countryCode":"TH","latitude":"18.14457740","longitude":"100.14028310"},{"name":"Nan","isoCode":"55","countryCode":"TH","latitude":"45.52220800","longitude":"-122.98632810"},{"name":"Phayao","isoCode":"56","countryCode":"TH","latitude":"19.21543670","longitude":"100.20236920"},{"name":"Chiang Rai","isoCode":"57","countryCode":"TH","latitude":"19.91047980","longitude":"99.84057600"},{"name":"Mae Hong Son","isoCode":"58","countryCode":"TH","latitude":"19.30202960","longitude":"97.96543680"},{"name":"Nakhon Sawan","isoCode":"60","countryCode":"TH","latitude":"15.69873820","longitude":"100.11996000"},{"name":"Uthai Thani","isoCode":"61","countryCode":"TH","latitude":"15.38350010","longitude":"100.02455270"},{"name":"Kamphaeng Phet","isoCode":"62","countryCode":"TH","latitude":"16.48277980","longitude":"99.52266180"},{"name":"Tak","isoCode":"63","countryCode":"TH","latitude":"45.02996460","longitude":"-93.10498150"},{"name":"Sukhothai","isoCode":"64","countryCode":"TH","latitude":"43.64855560","longitude":"-79.37466390"},{"name":"Phitsanulok","isoCode":"65","countryCode":"TH","latitude":"16.82112380","longitude":"100.26585160"},{"name":"Phichit","isoCode":"66","countryCode":"TH","latitude":"16.27408760","longitude":"100.33469910"},{"name":"Phetchabun","isoCode":"67","countryCode":"TH","latitude":"16.30166900","longitude":"101.11928040"},{"name":"Ratchaburi","isoCode":"70","countryCode":"TH","latitude":"13.52828930","longitude":"99.81342110"},{"name":"Kanchanaburi","isoCode":"71","countryCode":"TH","latitude":"14.10113930","longitude":"99.41794310"},{"name":"Suphan Buri","isoCode":"72","countryCode":"TH","latitude":"14.47448920","longitude":"100.11771280"},{"name":"Nakhon Pathom","isoCode":"73","countryCode":"TH","latitude":"13.81402930","longitude":"100.03729290"},{"name":"Samut Sakhon","isoCode":"74","countryCode":"TH","latitude":"13.54752160","longitude":"100.27439560"},{"name":"Samut Songkhram","isoCode":"75","countryCode":"TH","latitude":"13.40982170","longitude":"100.00226450"},{"name":"Phetchaburi","isoCode":"76","countryCode":"TH","latitude":"12.96492150","longitude":"99.64258830"},{"name":"Prachuap Khiri Khan","isoCode":"77","countryCode":"TH","latitude":"11.79383890","longitude":"99.79575640"},{"name":"Nakhon Si Thammarat","isoCode":"80","countryCode":"TH","latitude":"8.43248310","longitude":"99.95990330"},{"name":"Krabi","isoCode":"81","countryCode":"TH","latitude":"8.08629970","longitude":"98.90628350"},{"name":"Phangnga","isoCode":"82","countryCode":"TH","latitude":"8.45014140","longitude":"98.52553170"},{"name":"Phuket","isoCode":"83","countryCode":"TH","latitude":"7.88044790","longitude":"98.39225040"},{"name":"Surat Thani","isoCode":"84","countryCode":"TH","latitude":"9.13419490","longitude":"99.33341980"},{"name":"Ranong","isoCode":"85","countryCode":"TH","latitude":"9.95287020","longitude":"98.60846410"},{"name":"Chumphon","isoCode":"86","countryCode":"TH","latitude":"10.49304960","longitude":"99.18001990"},{"name":"Songkhla","isoCode":"90","countryCode":"TH","latitude":"7.18976590","longitude":"100.59538130"},{"name":"Satun","isoCode":"91","countryCode":"TH","latitude":"6.62381580","longitude":"100.06737440"},{"name":"Trang","isoCode":"92","countryCode":"TH","latitude":"7.56448330","longitude":"99.62393340"},{"name":"Phatthalung","isoCode":"93","countryCode":"TH","latitude":"7.61668230","longitude":"100.07402310"},{"name":"Pattani","isoCode":"94","countryCode":"TH","latitude":"6.76183080","longitude":"101.32325490"},{"name":"Yala","isoCode":"95","countryCode":"TH","latitude":"44.05791170","longitude":"-123.16538480"},{"name":"Narathiwat","isoCode":"96","countryCode":"TH","latitude":"6.42546070","longitude":"101.82531430"},{"name":"Pattaya","isoCode":"S","countryCode":"TH","latitude":"12.92355570","longitude":"100.88245510"},{"name":"Gorno-Badakhshan Autonomous Province","isoCode":"GB","countryCode":"TJ","latitude":"38.41273200","longitude":"73.08774900"},{"name":"Khatlon Province","isoCode":"KT","countryCode":"TJ","latitude":"37.91135620","longitude":"69.09702300"},{"name":"districts of Republican Subordination","isoCode":"RA","countryCode":"TJ","latitude":"39.08579020","longitude":"70.24083250"},{"name":"Sughd Province","isoCode":"SU","countryCode":"TJ","latitude":"39.51553260","longitude":"69.09702300"},{"name":"Aileu municipality","isoCode":"AL","countryCode":"TL","latitude":"-8.70439940","longitude":"125.60954740"},{"name":"Ainaro Municipality","isoCode":"AN","countryCode":"TL","latitude":"-9.01131710","longitude":"125.52200120"},{"name":"Baucau Municipality","isoCode":"BA","countryCode":"TL","latitude":"-8.47143080","longitude":"126.45759910"},{"name":"Bobonaro Municipality","isoCode":"BO","countryCode":"TL","latitude":"-8.96554060","longitude":"125.25879640"},{"name":"Cova Lima Municipality","isoCode":"CO","countryCode":"TL","latitude":"-9.26503750","longitude":"125.25879640"},{"name":"Dili municipality","isoCode":"DI","countryCode":"TL","latitude":"-8.24496130","longitude":"125.58766970"},{"name":"Ermera District","isoCode":"ER","countryCode":"TL","latitude":"-8.75248020","longitude":"125.39872940"},{"name":"Lautém Municipality","isoCode":"LA","countryCode":"TL","latitude":"-8.36423070","longitude":"126.90438450"},{"name":"Liquiçá Municipality","isoCode":"LI","countryCode":"TL","latitude":"-8.66740950","longitude":"125.25879640"},{"name":"Manufahi Municipality","isoCode":"MF","countryCode":"TL","latitude":"-9.01454950","longitude":"125.82799590"},{"name":"Manatuto District","isoCode":"MT","countryCode":"TL","latitude":"-8.51556080","longitude":"126.01592550"}
1,{"name":"Viqueque Municipality","isoCode":"VI","countryCode":"TL","latitude":"-8.85979180","longitude":"126.36335160"},{"name":"Ahal Region","isoCode":"A","countryCode":"TM","latitude":"38.63993980","longitude":"59.47209040"},{"name":"Balkan Region","isoCode":"B","countryCode":"TM","latitude":"41.81014720","longitude":"21.09373110"},{"name":"DaÅoguz Region","isoCode":"D","countryCode":"TM","latitude":"41.83687370","longitude":"59.96519040"},{"name":"Lebap Region","isoCode":"L","countryCode":"TM","latitude":"38.12724620","longitude":"64.71624150"},{"name":"Mary Region","isoCode":"M","countryCode":"TM","latitude":"36.94816230","longitude":"62.45041540"},{"name":"Ashgabat","isoCode":"S","countryCode":"TM","latitude":"37.96007660","longitude":"58.32606290"},{"name":"Tunis Governorate","isoCode":"11","countryCode":"TN","latitude":"36.83749460","longitude":"10.19273890"},{"name":"Ariana Governorate","isoCode":"12","countryCode":"TN","latitude":"36.99227510","longitude":"10.12551640"},{"name":"Ben Arous Governorate","isoCode":"13","countryCode":"TN","latitude":"36.64356060","longitude":"10.21515780"},{"name":"Manouba Governorate","isoCode":"14","countryCode":"TN","latitude":"36.84465040","longitude":"9.85714160"},{"name":"Zaghouan Governorate","isoCode":"22","countryCode":"TN","latitude":"36.40911880","longitude":"10.14231720"},{"name":"Bizerte Governorate","isoCode":"23","countryCode":"TN","latitude":"37.16093970","longitude":"9.63413500"},{"name":"Kassrine","isoCode":"31","countryCode":"TN","latitude":"35.17227160","longitude":"8.83076260"},{"name":"Jendouba Governorate","isoCode":"32","countryCode":"TN","latitude":"36.71818620","longitude":"8.74811670"},{"name":"Kef Governorate","isoCode":"33","countryCode":"TN","latitude":"36.12305120","longitude":"8.66005860"},{"name":"Siliana Governorate","isoCode":"34","countryCode":"TN","latitude":"36.08872080","longitude":"9.36453350"},{"name":"Kairouan Governorate","isoCode":"41","countryCode":"TN","latitude":"35.67116630","longitude":"10.10054690"},{"name":"Kasserine Governorate","isoCode":"42","countryCode":"TN","latitude":"35.08091480","longitude":"8.66005860"},{"name":"Sidi Bouzid Governorate","isoCode":"43","countryCode":"TN","latitude":"35.03543860","longitude":"9.48393920"},{"name":"Sousse Governorate","isoCode":"51","countryCode":"TN","latitude":"35.90222670","longitude":"10.34978950"},{"name":"Monastir Governorate","isoCode":"52","countryCode":"TN","latitude":"35.76425150","longitude":"10.81128850"},{"name":"Mahdia Governorate","isoCode":"53","countryCode":"TN","latitude":"35.33525580","longitude":"10.89030990"},{"name":"Sfax Governorate","isoCode":"61","countryCode":"TN","latitude":"34.86065810","longitude":"10.34978950"},{"name":"Gafsa Governorate","isoCode":"71","countryCode":"TN","latitude":"34.37885050","longitude":"8.66005860"},{"name":"Tozeur Governorate","isoCode":"72","countryCode":"TN","latitude":"33.97894910","longitude":"8.04651850"},{"name":"Kebili Governorate","isoCode":"73","countryCode":"TN","latitude":"33.70715510","longitude":"8.97146230"},{"name":"Gabès Governorate","isoCode":"81","countryCode":"TN","latitude":"33.94596480","longitude":"9.72326730"},{"name":"Medenine Governorate","isoCode":"82","countryCode":"TN","latitude":"33.22805650","longitude":"10.89030990"},{"name":"Tataouine Governorate","isoCode":"83","countryCode":"TN","latitude":"32.13441220","longitude":"10.08072980"},{"name":"Ê»Eua","isoCode":"01","countryCode":"TO","latitude":"37.09024000","longitude":"-95.71289100"},{"name":"HaÊ»apai","isoCode":"02","countryCode":"TO","latitude":"-19.75000000","longitude":"-174.36666700"},{"name":"Niuas","isoCode":"03","countryCode":"TO","latitude":"-15.95940000","longitude":"-173.78300000"},{"name":"Tongatapu","isoCode":"04","countryCode":"TO","latitude":"-21.14659680","longitude":"-175.25154820"},{"name":"VavaÊ»u","isoCode":"05","countryCode":"TO","latitude":"-18.62275600","longitude":"-173.99029820"},{"name":"Adana","isoCode":"01","countryCode":"TR","latitude":"37.26123150","longitude":"35.39050460"},{"name":"Adıyaman","isoCode":"02","countryCode":"TR","latitude":"37.90782910","longitude":"38.48499230"},{"name":"Afyonkarahisar","isoCode":"03","countryCode":"TR","latitude":"38.73910990","longitude":"30.71200230"},{"name":"AÄrı","isoCode":"04","countryCode":"TR","latitude":"39.62692180","longitude":"43.02159650"},{"name":"Amasya","isoCode":"05","countryCode":"TR","latitude":"40.65166080","longitude":"35.9
10379660"},{"name":"Ankara","isoCode":"06","countryCode":"TR","latitude":"39.78052450","longitude":"32.71813750"},{"name":"Antalya","isoCode":"07","countryCode":"TR","latitude":"37.09516720","longitude":"31.07937050"},{"name":"Artvin","isoCode":"08","countryCode":"TR","latitude":"41.07866400","longitude":"41.76282230"},{"name":"Aydın","isoCode":"09","countryCode":"TR","latitude":"37.81170330","longitude":"28.48639630"},{"name":"Balıkesir","isoCode":"10","countryCode":"TR","latitude":"39.76167820","longitude":"28.11226790"},{"name":"Bilecik","isoCode":"11","countryCode":"TR","latitude":"40.05665550","longitude":"30.06652360"},{"name":"Bingöl","isoCode":"12","countryCode":"TR","latitude":"39.06263540","longitude":"40.76960950"},{"name":"Bitlis","isoCode":"13","countryCode":"TR","latitude":"38.65231330","longitude":"42.42020280"},{"name":"Bolu","isoCode":"14","countryCode":"TR","latitude":"40.57597660","longitude":"31.57880860"},{"name":"Burdur","isoCode":"15","countryCode":"TR","latitude":"37.46126690","longitude":"30.06652360"},{"name":"Bursa","isoCode":"16","countryCode":"TR","latitude":"40.06554590","longitude":"29.23207840"},{"name":"Ãanakkale","isoCode":"17","countryCode":"TR","latitude":"40.05101040","longitude":"26.98524220"},{"name":"Ãankırı","isoCode":"18","countryCode":"TR","latitude":"40.53690730","longitude":"33.58838930"},{"name":"Ãorum","isoCode":"19","countryCode":"TR","latitude":"40.49982110","longitude":"34.59862630"},{"name":"Denizli","isoCode":"20","countryCode":"TR","latitude":"37.61283950","longitude":"29.23207840"},{"name":"Diyarbakır","isoCode":"21","countryCode":"TR","latitude":"38.10663720","longitude":"40.54268960"},{"name":"Edirne","isoCode":"22","countryCode":"TR","latitude":"41.15172220","longitude":"26.51379640"},{"name":"ElazıÄ","isoCode":"23","countryCode":"TR","latitude":"38.49648040","longitude":"39.21990290"},{"name":"Erzincan","isoCode":"24","countryCode":"TR","latitude":"39.76819140","longitude":"39.05013060"},{"name":"Erzurum","isoCode":"25","countryCode":"TR","latitude":"40.07467990","longitude":"41.66945620"},{"name":"EskiÅehir","isoCode":"26","countryCode":"TR","latitude":"39.63296570","longitude":"31.26263660"},{"name":"Gaziantep","isoCode":"27","countryCode":"TR","latitude":"37.07638820","longitude":"37.38272340"},{"name":"Giresun","isoCode":"28","countryCode":"TR","latitude":"40.64616720","longitude":"38.59355110"},{"name":"GümüÅhane","isoCode":"29","countryCode":"TR","latitude":"40.28036730","longitude":"39.31432530"},{"name":"Hakkâri","isoCode":"30","countryCode":"TR","latitude":"37.44593190","longitude":"43.74498410"},{"name":"Hatay","isoCode":"31","countryCode":"TR","latitude":"36.40184880","longitude":"36.34980970"},{"name":"Isparta","isoCode":"32","countryCode":"TR","latitude":"38.02114640","longitude":"31.07937050"},{"name":"Mersin","isoCode":"33","countryCode":"TR","latitude":"36.81208580","longitude":"34.64147500"},{"name":"Istanbul","isoCode":"34","countryCode":"TR","latitude":"41.16343020","longitude":"28.76644080"},{"name":"İzmir","isoCode":"35","countryCode":"TR","latitude":"38.35916930","longitude":"27.26761160"},{"name":"Kars","isoCode":"36","countryCode":"TR","latitude":"40.28076360","longitude":"42.99195270"},{"name":"Kastamonu","isoCode":"37","countryCode":"TR","latitude":"41.41038630","longitude":"33.69983340"},{"name":"Kayseri","isoCode":"38","countryCode":"TR","latitude":"38.62568540","longitude":"35.74068820"},{"name":"Kırklareli","isoCode":"39","countryCode":"TR","latitude":"41.72597950","longitude":"27.48383900"},{"name":"KırÅehir","isoCode":"40","countryCode":"TR","latitude":"39.22689050","longitude":"33.97500180"},{"name":"Kocaeli","isoCode":"41","countryCode":"TR","latitude":"40.85327040","longitude":"29.88152030"},{"name":"Konya","isoCode":"42","countryCode":"TR","latitude":"37.98381340","longitude":"32.71813750"},{"name":"Kütahya","isoCode":"43","countryCode":"TR","latitude":"39.35813700","longitude":"29.60354950"},{"name":"Malatya","isoCode":"44","countryCode":"TR","latitude":"38.40150570","longitude":"37.95362980"},{"name":"Manisa","isoCode":"45","countryCode":"TR","latitude":"38.84193730","longitude":"28.11226790"},{"name":"KahramanmaraÅ","isoCode":"46","countryCode":"TR","latitude":"37.75030360","longitude":"36.95410700"},{"name":"Mardin","isoCode":"47","countryCode":"TR","latitude":"37.34429290","longitude":"40.61964870"},{"name":"MuÄla","isoCode":"48","countryCode":"TR","latitude":"37.18358190","longitude":"28.48639630"},{"name":"MuÅ","isoCode":"49","countryCode":"TR","latitude":"38.94618880","longitude":"41.75389310"},{"name":"NevÅehir","isoCode":"50","countryCode":"TR","latitude":"38.69393990","longitude":"34.68565090"},{"name":"NiÄde","isoCode":"51","countryCode":"TR","latitude":"38.09930860","longitude":"34.68565090"},{"name":"Ordu","isoCode":"52","countryCode":"TR","latitude":"40.79905800","longitude":"37.38990050"},{"name":"Rize","isoCode":"53","countryCode":"TR","latitude":"40.95814970","longitude":"40.92269850"},{"name":"Sakarya","isoCode":"54","countryCode":"TR","latitude":"40.78885500","longitude":"30.40595400"},{"name":"Samsun","isoCode":"55","countryCode":"TR","latitude":"41.18648590","longitude":"36.13226780"},{"name":"Siirt","isoCode":"56","countryCode":"TR","latitude":"37.86588620","longitude":"42.14945230"},{"name":"Sinop","isoCode":"57","countryCode":"TR","latitude":"41.55947490","longitude":"34.85805320"},{"name":"Sivas","isoCode":"58","countryCode":"TR","latitude":"39.44880390","longitude":"37.12944970"},{"name":"TekirdaÄ","isoCode":"59","countryCode":"TR","latitude":"41.11212270","longitude":"27.26761160"},{"name":"Tokat","isoCode":"60","countryCode":"TR","latitude":"40.39027130","longitude":"36.62518630"},{"name":"Trabzon","isoCode":"61","countryCode":"TR","latitude":"40.79924100","longitude":"39.58479440"},{"name":"Tunceli","isoCode":"62","countryCode":"TR","latitude":"39.30735540","longitude":"39.43877780"},{"name":"Åanlıurfa","isoCode":"63","countryCode":"TR","latitude":"37.35691020","longitude":"39.15436770"},{"name":"UÅak","isoCode":"64","countryCode":"TR","latitude":"38.54313190","longitude":"29.23207840"},{"name":"Van","isoCode":"65","countryCode":"TR","latitude":"38.3
16794170","longitude":"43.71827870"},{"name":"Yozgat","isoCode":"66","countryCode":"TR","latitude":"39.72719790","longitude":"35.10778580"},{"name":"Zonguldak","isoCode":"67","countryCode":"TR","latitude":"41.31249170","longitude":"31.85982510"},{"name":"Aksaray","isoCode":"68","countryCode":"TR","latitude":"38.33520430","longitude":"33.97500180"},{"name":"Bayburt","isoCode":"69","countryCode":"TR","latitude":"40.26032000","longitude":"40.22804800"},{"name":"Karaman","isoCode":"70","countryCode":"TR","latitude":"37.24363360","longitude":"33.61757700"},{"name":"Kırıkkale","isoCode":"71","countryCode":"TR","latitude":"39.88768780","longitude":"33.75552480"},{"name":"Batman","isoCode":"72","countryCode":"TR","latitude":"37.83624960","longitude":"41.36057390"},{"name":"Åırnak","isoCode":"73","countryCode":"TR","latitude":"37.41874810","longitude":"42.49183380"},{"name":"Bartın","isoCode":"74","countryCode":"TR","latitude":"41.58105090","longitude":"32.46097940"},{"name":"Ardahan","isoCode":"75","countryCode":"TR","latitude":"41.11129640","longitude":"42.78316740"},{"name":"IÄdır","isoCode":"76","countryCode":"TR","latitude":"39.88798410","longitude":"44.00483650"},{"name":"Yalova","isoCode":"77","countryCode":"TR","latitude":"40.57759860","longitude":"29.20883030"},{"name":"Karabük","isoCode":"78","countryCode":"TR","latitude":"41.18748900","longitude":"32.74174190"},{"name":"Kilis","isoCode":"79","countryCode":"TR","latitude":"36.82047750","longitude":"37.16873390"},{"name":"Osmaniye","isoCode":"80","countryCode":"TR","latitude":"37.21302580","longitude":"36.17626150"},{"name":"Düzce","isoCode":"81","countryCode":"TR","latitude":"40.87705310","longitude":"31.31927130"},{"name":"Arima","isoCode":"ARI","countryCode":"TT","latitude":"46.79316040","longitude":"-71.25843110"},{"name":"Chaguanas","isoCode":"CHA","countryCode":"TT","latitude":"10.51683870","longitude":"-61.41144820"},{"name":"Couva-Tabaquite-Talparo Regional Corporation","isoCode":"CTT","countryCode":"TT","latitude":"10.42971450","longitude":"-61.37352100"},{"name":"Diego Martin Regional Corporation","isoCode":"DMN","countryCode":"TT","latitude":"10.73622860","longitude":"-61.55448360"},{"name":"Eastern Tobago","isoCode":"ETO","countryCode":"TT","latitude":"11.29793480","longitude":"-60.55885240"},{"name":"Rio Claro-Mayaro Regional Corporation","isoCode":"MRC","countryCode":"TT","latitude":"10.24128320","longitude":"-61.09372060"},{"name":"Penal-Debe Regional Corporation","isoCode":"PED","countryCode":"TT","latitude":"10.13374020","longitude":"-61.44354740"},{"name":"Port of Spain","isoCode":"POS","countryCode":"TT","latitude":"10.66031960","longitude":"-61.50856250"},{"name":"Princes Town Regional Corporation","isoCode":"PRT","countryCode":"TT","latitude":"10.17867460","longitude":"-61.28019960"},{"name":"Point Fortin","isoCode":"PTF","countryCode":"TT","latitude":"10.17027370","longitude":"-61.67133860"},{"name":"San Fernando","isoCode":"SFO","countryCode":"TT","latitude":"34.28194610","longitude":"-118.43897190"},{"name":"Sangre Grande Regional Corporation","isoCode":"SGE","countryCode":"TT","latitude":"10.58529390","longitude":"-61.13158130"},{"name":"Siparia Regional Corporation","isoCode":"SIP","countryCode":"TT","latitude":"10.12456260","longitude":"-61.56032440"},{"name":"San Juan-Laventille Regional Corporation","isoCode":"SJL","countryCode":"TT","latitude":"10.69085780","longitude":"-61.45522130"},{"name":"Tunapuna-Piarco Regional Corporation","isoCode":"TUP","countryCode":"TT","latitude":"10.68590960","longitude":"-61.30352480"},{"name":"Western Tobago","isoCode":"WTO","countryCode":"TT","latitude":"11.18970720","longitude":"-60.77954520"},{"name":"Funafuti","isoCode":"FUN","countryCode":"TV","latitude":"-8.52114710","longitude":"179.19619260"},{"name":"Niutao Island Council","isoCode":"NIT","countryCode":"TV","latitude":"-6.10642580","longitude":"177.34384290"},{"name":"Nukufetau","isoCode":"NKF","countryCode":"TV","latitude":"-8.00000000","longitude":"178.50000000"},{"name":"Nukulaelae","isoCode":"NKL","countryCode":"TV","latitude":"-9.38111100","longitude":"179.85222200"},{"name":"Nanumea","isoCode":"NMA","countryCode":"TV","latitude":"-5.68816170","longitude":"176.13701480"},{"name":"Nanumanga","isoCode":"NMG","countryCode":"TV","latitude":"-6.28580190","longitude":"176.31992800"},{"name":"Nui","isoCode":"NUI","countryCode":"TV","latitude":"-7.23887680","longitude":"177.14852320"}
1,{"name":"Vaitupu","isoCode":"VAI","countryCode":"TV","latitude":"-7.47673270","longitude":"178.67476750"},{"name":"Changhua","isoCode":"CHA","countryCode":"TW","latitude":"24.05179630","longitude":"120.51613520"},{"name":"Chiayi","isoCode":"CYI","countryCode":"TW","latitude":"23.45184280","longitude":"120.25546150"},{"name":"Chiayi","isoCode":"CYQ","countryCode":"TW","latitude":"23.48007510","longitude":"120.44911130"},{"name":"Hsinchu","isoCode":"HSQ","countryCode":"TW","latitude":"24.83872260","longitude":"121.01772460"},{"name":"Hsinchu","isoCode":"HSZ","countryCode":"TW","latitude":"24.81382870","longitude":"120.96747980"},{"name":"Hualien","isoCode":"HUA","countryCode":"TW","latitude":"23.98715890","longitude":"121.60157140"},{"name":"Yilan","isoCode":"ILA","countryCode":"TW","latitude":"24.70210730","longitude":"121.73775020"},{"name":"Keelung","isoCode":"KEE","countryCode":"TW","latitude":"25.12418620","longitude":"121.64758340"},{"name":"Kaohsiung","isoCode":"KHH","countryCode":"TW","latitude":"22.62727840","longitude":"120.30143530"},{"name":"Kinmen","isoCode":"KIN","countryCode":"TW","latitude":"24.34877920","longitude":"118.32856440"},{"name":"Lienchiang","isoCode":"LIE","countryCode":"TW","latitude":"26.15055560","longitude":"119.92888890"},{"name":"Miaoli","isoCode":"MIA","countryCode":"TW","latitude":"24.56015900","longitude":"120.82142650"},{"name":"Nantou","isoCode":"NAN","countryCode":"TW","latitude":"23.96099810","longitude":"120.97186380"},{"name":"New Taipei","isoCode":"NWT","countryCode":"TW","latitude":"24.98752780","longitude":"121.36459470"},{"name":"Penghu","isoCode":"PEN","countryCode":"TW","latitude":"23.57118990","longitude":"119.57931570"},{"name":"Pingtung","isoCode":"PIF","countryCode":"TW","latitude":"22.55197590","longitude":"120.54875970"},{"name":"Taoyuan","isoCode":"TAO","countryCode":"TW","latitude":"24.99362810","longitude":"121.30097980"},{"name":"Tainan","isoCode":"TNN","countryCode":"TW","latitude":"22.99972810","longitude":"120.22702770"},{"name":"Taipei","isoCode":"TPE","countryCode":"TW","latitude":"25.03296940","longitude":"121.56541770"},{"name":"Taitung","isoCode":"TTT","countryCode":"TW","latitude":"22.79724470","longitude":"121.07137020"},{"name":"Taichung","isoCode":"TXG","countryCode":"TW","latitude":"24.14773580","longitude":"120.67364820"},{"name":"Yunlin","isoCode":"YUN","countryCode":"TW","latitude":"23.70920330","longitude":"120.43133730"},{"name":"Arusha","isoCode":"01","countryCode":"TZ","latitude":"-3.38692540","longitude":"36.68299270"},{"name":"Dar es Salaam","isoCode":"02","countryCode":"TZ","latitude":"-6.79235400","longitude":"39.20832840"},{"name":"Dodoma","isoCode":"03","countryCode":"TZ","latitude":"-6.57382280","longitude":"36.26308460"},{"name":"Iringa","isoCode":"04","countryCode":"TZ","latitude":"-7.78874420","longitude":"35.56578620"},{"name":"Kagera","isoCode":"05","countryCode":"TZ","latitude":"-1.30011150","longitude":"31.26263660"},{"name":"Pemba North","isoCode":"06","countryCode":"TZ","latitude":"-5.03193520","longitude":"39.77555710"},{"name":"Zanzibar North","isoCode":"07","countryCode":"TZ","latitude":"-5.93950930","longitude":"39.27910110"},{"name":"Kigoma","isoCode":"08","countryCode":"TZ","latitude":"-4.88240920","longitude":"29.66150550"},{"name":"Kilimanjaro","isoCode":"09","countryCode":"TZ","latitude":"-4.13369270","longitude":"37.80876930"},{"name":"Pemba South","isoCode":"10","countryCode":"TZ","latitude":"-5.31469610","longitude":"39.75495110"},{"name":"Zanzibar South","isoCode":"11","countryCode":"TZ","latitude":"-6.26428510","longitude":"39.44502810"},{"name":"Lindi","isoCode":"12","countryCode":"TZ","latitude":"-9.23433940","longitude":"38.31657250"},{"name":"Mara","isoCode":"13","countryCode":"TZ","latitude":"-1.77535380","longitude":"34.15319470"},{"name":"Mbeya","isoCode":"14","countryCode":"TZ","latitude":"-8.28661120","longitude":"32.81325370"},{"name":"Zanzibar West","isoCode":"15","countryCode":"TZ","latitude":"-6.22981360","longitude":"39.25832930"},{"name":"Morogoro","isoCode":"16","countryCode":"TZ","latitude":"-8.81371730","longitude":"36.95410700"},{"name":"Mtwara","isoCode":"17","countryCode":"TZ","latitude":"-10.33984550","longitude":"40.16574660"},{"name":"Mwanza","isoCode":"18","countryCode":"TZ","latitude":"-2.46711970","longitude":"32.89868120"},{"name":"Pwani","isoCode":"19","countryCode":"TZ","latitude":"-7.32377140","longitude":"38.82054540"},{"name":"Rukwa","isoCode":"20","countryCode":"TZ","latitude":"-8.01094440","longitude":"31.44561790"},{"name":"Ruvuma","isoCode":"21","countryCode":"TZ","latitude":"-10.68787170","longitude":"36.26308460"},{"name":"Shinyanga","isoCode":"22","countryCode":"TZ","latitude":"-3.68099610","longitude":"33.42714030"},{"name":"Singida","isoCode":"23","countryCode":"TZ","latitude":"-6.74533520","longitude":"34.15319470"},{"name":"Tabora","isoCode":"24","countryCode":"TZ","latitude":"-5.03421380","longitude":"32.80844960"},{"name":"Tanga","isoCode":"25","countryCode":"TZ","latitude":"-5.30497890","longitude":"38.31657250"},{"name":"Manyara","isoCode":"26","countryCode":"TZ","latitude":"-4.31500580","longitude":"36.95410700"},{"name":"Geita","isoCode":"27","countryCode":"TZ","latitude":"-2.82422570","longitude":"32.26538870"},{"name":"Katavi","isoCode":"28","countryCode":"TZ","latitude":"-6.36771250","longitude":"31.26263660"},{"name":"Njombe","isoCode":"29","countryCode":"TZ","latitude":"-9.24226320","longitude":"35.12687810"},{"name":"Simiyu","isoCode":"30","countryCode":"TZ","latitude":"-2.83087380","longitude":"34.15319470"},{"name":"Songwe","isoCode":"31","countryCode":"TZ","latitude":"-8.27261200","longitude":"31.71131740"},{"name":"Vinnytska oblast","isoCode":"05","countryCode":"UA","latitude":"49.23308300","longitude":"28.46821690"},{"name":"Volynska oblast","isoCode":"07","countryCode":"UA","latitude":"50.74723300","longitude":"25.32538300"},{"name":"Luhanska oblast","isoCode":"09","countryCode":"UA","latitude":"48.57404100","longitude":"39.30781500"},{"name":"Dnipropetrovska oblast","isoCode":"12","countryCode":"UA","latitude":"48.46471700","longitude":"35.04618300"},{"name":"Donetska oblast","isoCode":"14","countryCode":"UA","latitude":"48.01588300","longitude":"37.80285000"},{"name":"Zhytomyrska oblast","isoCode":"18","countryCode":"UA","latitude":"50.25465000","longitude":"28.65866690"},{"name":"Zakarpatska Oblast","isoCode":"21","countryCode":"UA","latitude":"48.62080000","longitude":"22.28788300"},{"name":"Zaporizka oblast","isoCode":"23","countryCode":"UA","latitude":"47.83880000","longitude":"35.13956700"},{"name":"Ivano-Frankivska oblast","isoCode":"26","countryCode":"UA","latitude":"48.92263300","longitude":"24.71111700"},{"name":"Kyiv","isoCode":"30","countryCode":"UA","latitude":"50.45010000","longitude":"30.52340000"},{"name":"Kyivska oblast","isoCode":"32","countryCode":"UA","latitude":"50.05295060","longitude":"30.76671340"},{"name":"Kirovohradska oblast","isoCode":"35","countryCode":"UA","latitude":"48.50793300","longitude":"32.26231700"},{"name":"Autonomous Republic of Crimea","isoCode":"43","countryCode":"UA","latitude":"44.95211700","longitude":"34.10241700"},{"name":"Lvivska oblast","isoCode":"46","countryCode":"UA","latitude":"49.83968300","longitude":"24.02971700"},{"name":"Mykolaivska oblast","isoCode":"48","countryCode":"UA","latitude":"46.97503300","longitude":"31.99458290"},{"name":"Odeska oblast","isoCode":"51","countryCode":"UA","latitude":"46.48458300","longitude":"30.73260000"},{"name":"Poltavska oblast","isoCode":"53","countryCode":"UA","latitude":"49.64291960","longitude":"32.66753390"},{"name":"Rivnenska oblast","isoCode":"56","countryCode":"UA","latitude":"50.61990000","longitude":"26.25161700"},{"name":"Sumska oblast","isoCode":"59","countryCode":"UA","latitude":"50.90770000","longitude":"34.79810000"},{"name":"Ternopilska oblast","isoCode":"61","countryCode":"UA","latitude":"49.55351700","longitude":"25.59476700"},{"name":"Kharkivska oblast","isoCode":"63","countryCode":"UA","latitude":"49.99350000","longitude":"36.23038300"},{"name":"Khersonska oblast","isoCode":"65","countryCode":"UA","latitude":"46.63541700","longitude":"32.61686700"},{"name":"Khmelnytska oblast","isoCode":"68","countryCode":"UA","latitude":"49.42298300","longitude":"26.98713310"},{"name":"Cherkaska oblast","isoCode":"71","countryCode":"UA","latitude":"49.44443300","longitude":"32.05976700"},{"name":"Chernihivska oblast","isoCode":"74","countryCode":"UA","latitude":"51.49820000","longitude":"31.28934990"},{"name":"Chernivetska oblast","isoCode":"77","countryCode":"UA","latitude":"48.29168300","longitude":"25.93521700"},{"name":"Kalangala District","isoCode":"101","countryCode":"UG","latitude":"-0.63505780","longitude":"32.53727410"},{"name":"Kampala District","isoCode":"102","countryCode":"UG","latitude":"0.34759640","longitude":"32.58251970"},{"name":"Kiboga District","isoCode":"103","countryCode":"UG","latitude":"0.96575900","longitude":"31.71954590"},{"name":"Luwero District","isoCode":"104","countryCode":"UG","latitude":"0.82711180","longitude":"32.62774550"},{"name":"Masaka District","isoCode":"105","countryCode":"UG","latitude":"-0.44636910","longitude":"31.90179540"},{"name":"Mpigi District","isoCode":"106","countryCode":"UG","latitude":"0.22735280","longitude":"32.32492360"},{"name":"Mubende District","isoCode":"107","countryCode":"UG","latitude":"0.57727580","longitude":"31.53700030"},{"name":"Mukono District","isoCode":"108","countryCode":"UG","latitude":"0.28354760","longitude":"32.76330360"},{"name":"Nakasongola District","isoCode":"109","countryCode":"UG","latitude":"1.34897210","longitude":"32.44672380"},{"name":"Rakai District","isoCode":"110","countryCode":"UG","latitude":"-0.70691350","longitude":"31.53700030"},{"name":"Sembabule District","isoCode":"111","countryCode":"UG","latitude":"0.06377150","longitude":"31.35416310"},{"name":"Kayunga District","isoCode":"112","countryCode":"UG","latitude":"0.98601820","longitude":"32.85357550"},{"name":"Wakiso District","isoCode":"113","countryCode":"UG","latitude":"0.06301900","longitude":"32.44672380"},{"name":"Lyantonde District","isoCode":"114","countryCode":"UG","latitude":"-0.22406960","longitude":"31.21684660"},{"name":"Mityana District","isoCode":"115","countryCode":"UG","latitude":"0.44548450","longitude":"32.08374450"},{"name":"Nakaseke District","isoCode":"116","countryCode":"UG","latitude":"1.22308480","longitude":"32.08374450"},{"name":"Buikwe District","isoCode":"117","countryCode":"UG","latitude":"0.31440460","longitude":"32.98883190"},{"name":"Bukomansimbi District","isoCode":"118","countryCode":"UG","latitude":"-0.14327520","longitude":"31.60548930"},{"name":"Butambala District","isoCode":"119","countryCode":"UG","latitude":"0.17425000","longitude":"32.10646680"},{"name":"Buvuma District","isoCode":"120","countryCode":"UG","latitude":"-0.37649
1120","longitude":"33.25879300"},{"name":"Gomba District","isoCode":"121","countryCode":"UG","latitude":"0.22297910","longitude":"31.67393710"},{"name":"Kalungu District","isoCode":"122","countryCode":"UG","latitude":"-0.09528310","longitude":"31.76513620"},{"name":"Kyankwanzi District","isoCode":"123","countryCode":"UG","latitude":"1.09660370","longitude":"31.71954590"},{"name":"Lwengo District","isoCode":"124","countryCode":"UG","latitude":"-0.41652880","longitude":"31.39989950"},{"name":"Kyotera District","isoCode":"125","countryCode":"UG","latitude":"-0.63589880","longitude":"31.54556370"},{"name":"Bugiri District","isoCode":"201","countryCode":"UG","latitude":"0.53161270","longitude":"33.75177230"},{"name":"Busia District","isoCode":"202","countryCode":"UG","latitude":"0.40447310","longitude":"34.01958270"},{"name":"Iganga District","isoCode":"203","countryCode":"UG","latitude":"0.66001370","longitude":"33.48319060"},{"name":"Jinja District","isoCode":"204","countryCode":"UG","latitude":"0.53437430","longitude":"33.30371430"},{"name":"Kamuli District","isoCode":"205","countryCode":"UG","latitude":"0.91871070","longitude":"33.12390490"},{"name":"Kapchorwa District","isoCode":"206","countryCode":"UG","latitude":"1.33502050","longitude":"34.39763560"},{"name":"Katakwi District","isoCode":"207","countryCode":"UG","latitude":"1.97310300","longitude":"34.06414190"},{"name":"Kumi District","isoCode":"208","countryCode":"UG","latitude":"1.48769990","longitude":"33.93039910"},{"name":"Mbale District","isoCode":"209","countryCode":"UG","latitude":"1.03442740","longitude":"34.19768820"},{"name":"Pallisa District","isoCode":"210","countryCode":"UG","latitude":"1.23242060","longitude":"33.75177230"},{"name":"Soroti District","isoCode":"211","countryCode":"UG","latitude":"1.72291170","longitude":"33.52800720"},{"name":"Tororo District","isoCode":"212","countryCode":"UG","latitude":"0.68709940","longitude":"34.06414190"},{"name":"Kaberamaido District","isoCode":"213","countryCode":"UG","latitude":"1.69633220","longitude":"33.21385100"},{"name":"Mayuge District","isoCode":"214","countryCode":"UG","latitude":"-0.21829820","longitude":"33.57280270"},{"name":"Sironko District","isoCode":"215","countryCode":"UG","latitude":"1.23022740","longitude":"34.24910640"},{"name":"Amuria District","isoCode":"216","countryCode":"UG","latitude":"2.03017000","longitude":"33.64275330"},{"name":"Budaka District","isoCode":"217","countryCode":"UG","latitude":"1.10162770","longitude":"33.93039910"},{"name":"Bududa District","isoCode":"218","countryCode":"UG","latitude":"1.00296930","longitude":"34.33381230"},{"name":"Bukedea District","isoCode":"219","countryCode":"UG","latitude":"1.35568980","longitude":"34.10867930"},{"name":"Bukwo District","isoCode":"220","countryCode":"UG","latitude":"1.28186510","longitude":"34.72987650"},{"name":"Butaleja District","isoCode":"221","countryCode":"UG","latitude":"0.84749220","longitude":"33.84112880"},{"name":"Kaliro District","isoCode":"222","countryCode":"UG","latitude":"1.04311070","longitude":"33.48319060"},{"name":"Manafwa District","isoCode":"223","countryCode":"UG","latitude":"0.90635990","longitude":"34.28660910"},{"name":"Namutumba District","isoCode":"224","countryCode":"UG","latitude":"0.84926100","longitude":"33.66233010"},{"name":"Bulambuli District","isoCode":"225","countryCode":"UG","latitude":"1.47988460","longitude":"34.37544140"},{"name":"Buyende District","isoCode":"226","countryCode":"UG","latitude":"1.24136820","longitude":"33.12390490"},{"name":"Kibuku District","isoCode":"227","countryCode":"UG","latitude":"1.04528740","longitude":"33.79925360"},{"name":"Kween District","isoCode":"228","countryCode":"UG","latitude":"1.44387900","longitude":"34.59713200"},{"name":"Luuka District","isoCode":"229","countryCode":"UG","latitude":"0.72505990","longitude":"33.30371430"},{"name":"Namayingo District","isoCode":"230","countryCode":"UG","latitude":"-0.28035750","longitude":"33.75177230"},{"name":"Ngora District","isoCode":"231","countryCode":"UG","latitude":"1.49081150","longitude":"33.75177230"},{"name":"Serere District","isoCode":"232","countryCode":"UG","latitude":"1.49940330","longitude":"33.54900780"},{"name":"Butebo District","isoCode":"233","countryCode":"UG","latitude":"1.21411240","longitude":"33.90808960"},{"name":"Namisindwa District","isoCode":"234","countryCode":"UG","latitude":"0.90710100","longitude":"34.35740370"},{"name":"Adjumani District","isoCode":"301","countryCode":"UG","latitude":"3.25485270","longitude":"31.71954590"},{"name":"Apac District","isoCode":"302","countryCode":"UG","latitude":"1.87302630","longitude":"32.62774550"},{"name":"Arua District","isoCode":"303","countryCode":"UG","latitude":"2.99598460","longitude":"31.17103890"},{"name":"Gulu District","isoCode":"304","countryCode":"UG","latitude":"2.81857760","longitude":"32.44672380"},{"name":"Kitgum District","isoCode":"305","countryCode":"UG","latitude":"3.33968290","longitude":"33.16888830"},{"name":"Kotido District","isoCode":"306","countryCode":"UG","latitude":"3.04156790","longitude":"33.88577470"},{"name":"Lira District","isoCode":"307","countryCode":"UG","latitude":"2.23161690","longitude":"32.94376670"},{"name":"Moroto District","isoCode":"308","countryCode":"UG","latitude":"2.61685450","longitude":"34.59713200"},{"name":"Moyo District","isoCode":"309","countryCode":"UG","latitude":"3.56964640","longitude":"31.67393710"},{"name":"Nebbi District","isoCode":"310","countryCode":"UG","latitude":"2.44093920","longitude":"31.35416310"},{"name":"Nakapiripirit District","isoCode":"311","countryCode":"UG","latitude":"1.96061730","longitude":"34.59713200"},{"name":"Pader District","isoCode":"312","countryCode":"UG","latitude":"2.94306820","longitude":"32.80844960"},{"name":"Yumbe District","isoCode":"313","countryCode":"UG","latitude":"3.4698
10230","longitude":"31.24832910"},{"name":"Abim District","isoCode":"314","countryCode":"UG","latitude":"2.70669800","longitude":"33.65953370"},{"name":"Amolatar District","isoCode":"315","countryCode":"UG","latitude":"1.60544020","longitude":"32.80844960"},{"name":"Amuru District","isoCode":"316","countryCode":"UG","latitude":"2.96678780","longitude":"32.08374450"},{"name":"Dokolo District","isoCode":"317","countryCode":"UG","latitude":"1.96364210","longitude":"33.03387670"},{"name":"Kaabong District","isoCode":"318","countryCode":"UG","latitude":"3.51262150","longitude":"33.97500180"},{"name":"Koboko District","isoCode":"319","countryCode":"UG","latitude":"3.52370580","longitude":"31.03351000"},{"name":"Maracha District","isoCode":"320","countryCode":"UG","latitude":"3.28731270","longitude":"30.94030230"},{"name":"Oyam District","isoCode":"321","countryCode":"UG","latitude":"2.27762810","longitude":"32.44672380"},{"name":"Agago District","isoCode":"322","countryCode":"UG","latitude":"2.92508200","longitude":"33.34861470"},{"name":"Alebtong District","isoCode":"323","countryCode":"UG","latitude":"2.25457730","longitude":"33.34861470"},{"name":"Amudat District","isoCode":"324","countryCode":"UG","latitude":"1.79162240","longitude":"34.90655100"},{"name":"Kole District","isoCode":"325","countryCode":"UG","latitude":"2.37010970","longitude":"32.76330360"},{"name":"Lamwo District","isoCode":"326","countryCode":"UG","latitude":"3.57075680","longitude":"32.53727410"},{"name":"Napak District","isoCode":"327","countryCode":"UG","latitude":"2.36299450","longitude":"34.24215970"},{"name":"Nwoya District","isoCode":"328","countryCode":"UG","latitude":"2.56244400","longitude":"31.90179540"},{"name":"Otuke District","isoCode":"329","countryCode":"UG","latitude":"2.52140590","longitude":"33.34861470"},{"name":"Zombo District","isoCode":"330","countryCode":"UG","latitude":"2.55442930","longitude":"30.94173680"},{"name":"Omoro District","isoCode":"331","countryCode":"UG","latitude":"2.71522300","longitude":"32.49200880"},{"name":"Pakwach District","isoCode":"332","countryCode":"UG","latitude":"2.46071410","longitude":"31.49417380"},{"name":"Bundibugyo District","isoCode":"401","countryCode":"UG","latitude":"0.68517630","longitude":"30.02029640"},{"name":"Bushenyi District","isoCode":"402","countryCode":"UG","latitude":"-0.48709180","longitude":"30.20510960"},{"name":"Kabale District","isoCode":"404","countryCode":"UG","latitude":"-1.24930840","longitude":"30.06652360"},{"name":"Kabarole District","isoCode":"405","countryCode":"UG","latitude":"0.58507910","longitude":"30.25127280"},{"name":"Kasese District","isoCode":"406","countryCode":"UG","latitude":"0.06462850","longitude":"30.06652360"},{"name":"Kibaale District","isoCode":"407","countryCode":"UG","latitude":"0.90668020","longitude":"31.07937050"},{"name":"Kisoro District","isoCode":"408","countryCode":"UG","latitude":"-1.22094300","longitude":"29.64991620"},{"name":"Masindi District","isoCode":"409","countryCode":"UG","latitude":"1.49203630","longitude":"31.71954590"},{"name":"Mbarara District","isoCode":"410","countryCode":"UG","latitude":"-0.60715960","longitude":"30.65450220"},{"name":"Ntungamo District","isoCode":"411","countryCode":"UG","latitude":"-0.98073410","longitude":"30.25127280"},{"name":"Rukungiri District","isoCode":"412","countryCode":"UG","latitude":"-0.75184900","longitude":"29.92779470"},{"name":"Kamwenge District","isoCode":"413","countryCode":"UG","latitude":"0.22579300","longitude":"30.48184460"},{"name":"Kanungu District","isoCode":"414","countryCode":"UG","latitude":"-0.81952530","longitude":"29.74260400"},{"name":"Kyenjojo District","isoCode":"415","countryCode":"UG","latitude":"0.60929230","longitude":"30.64012310"},{"name":"Buliisa District","isoCode":"416","countryCode":"UG","latitude":"2.02996070","longitude":"31.53700030"},{"name":"Ibanda District","isoCode":"417","countryCode":"UG","latitude":"-0.09648900","longitude":"30.57395790"},{"name":"Isingiro District","isoCode":"418","countryCode":"UG","latitude":"-0.84354300","longitude":"30.80394740"},{"name":"Kiruhura District","isoCode":"419","countryCode":"UG","latitude":"-0.19279980","longitude":"30.80394740"},{"name":"Buhweju District","isoCode":"420","countryCode":"UG","latitude":"-0.29113590","longitude":"30.29741990"},{"name":"Kiryandongo District","isoCode":"421","countryCode":"UG","latitude":"2.01799070","longitude":"32.08374450"},{"name":"Kyegegwa District","isoCode":"422","countryCode":"UG","latitude":"0.48181930","longitude":"31.05500930"},{"name":"Mitooma District","isoCode":"423","countryCode":"UG","latitude":"-0.61932760","longitude":"30.02029640"},{"name":"Ntoroko District","isoCode":"424","countryCode":"UG","latitude":"1.07881780","longitude":"30.38966510"},{"name":"Rubirizi District","isoCode":"425","countryCode":"UG","latitude":"-0.26424100","longitude":"30.10840330"},{"name":"Sheema District","isoCode":"426","countryCode":"UG","latitude":"-0.55152980","longitude":"30.38966510"},{"name":"Kagadi District","isoCode":"427","countryCode":"UG","latitude":"0.94007610","longitude":"30.81256380"},{"name":"Kakumiro District","isoCode":"428","countryCode":"UG","latitude":"0.78080350","longitude":"31.32413890"},{"name":"Rubanda District","isoCode":"429","countryCode":"UG","latitude":"-1.18611900","longitude":"29.84535760"},{"name":"Bunyangabu District","isoCode":"430","countryCode":"UG","latitude":"0.48709180","longitude":"30.20510960"},{"name":"Rukiga District","isoCode":"431","countryCode":"UG","latitude":"-1.13263370","longitude":"30.04341200"},{"name":"Central Region","isoCode":"C","countryCode":"UG","latitude":"44.29687500","longitude":"-94.74017330"},{"name":"Eastern Region","isoCode":"E","countryCode":"UG","latitude":"6.23740360","longitude":"-0.45023680"},{"name":"Northern Region","isoCode":"N","countryCode":"UG","latitude":"9.54392690","longitude":"-0.90566230"},{"name":"Western Region","isoCode":"W","countryCode":"UG","latitude":"40.76672150","longitude":"-111.88772030"},{"name":"Alaska","isoCode":"AK","countryCode":"US","latitude":"64.20084130","longitude":"-149.49367330"},{"name":"Alabama","isoCode":"AL","countryCode":"US","latitude":"32.31823140","longitude":"-86.90229800"},{"name":"Arkansas","isoCode":"AR","countryCode":"US","latitude":"35.20105000","longitude":"-91.83183340"},{"name":"American Samoa","isoCode":"AS","countryCode":"US","latitude":"-14.27097200","longitude":"-170.13221700"},{"name":"Arizona","isoCode":"AZ","countryCode":"US","latitude":"34.04892810","longitude":"-111.09373110"},{"name":"California","isoCode":"CA","countryCode":"US","latitude":"36.77826100","longitude":"-119.41793240"},{"name":"Colorado","isoCode":"CO","countryCode":"US","latitude":"39.55005070","longitude":"-105.78206740"},{"name":"Connecticut","isoCode":"CT","countryCode":"US","latitude":"41.60322070","longitude":"-73.08774900"},{"name":"District of Columbia","isoCode":"DC","countryCode":"US","latitude":"38.90719230","longitude":"-77.03687070"},{"name":"Delaware","isoCode":"DE","countryCode":"US","latitude":"38.91083250","longitude":"-75.52766990"},{"name":"Florida","isoCode":"FL","countryCode":"US","latitude":"27.66482740","longitude":"-81.51575350"},{"name":"Georgia","isoCode":"GA","countryCode":"US","latitude":"32.16562210","longitude":"-82.90007510"},{"name":"Guam","isoCode":"GU","countryCode":"US","latitude":"13.44430400","longitude":"144.79373100"},{"name":"Hawaii","isoCode":"HI","countryCode":"US","latitude":"19.89676620","longitude":"-155.58278180"},{"name":"Iowa","isoCode":"IA","countryCode":"US","latitude":"41.87800250","longitude":"-93.09770200"},{"name":"Idaho","isoCode":"ID","countryCode":"US","latitude":"44.06820190","longitude":"-114.74204080"},{"name":"Illinois","isoCode":"IL","countryCode":"US","latitude":"40.63312490","longitude":"-89.39852830"},{"name":"Indiana","isoCode":"IN","countryCode":"US","latitude":"40.26719410","longitude":"-86.13490190"},{"name":"Kansas","isoCode":"KS","countryCode":"US","latitude":"39.01190200","longitude":"-98.48424650"},{"name":"Kentucky","isoCode":"KY","countryCode":"US","latitude":"37.83933320","longitude":"-84.27001790"},{"name":"Louisiana","isoCode":"LA","countryCode":"US","latitude":"30.98429770","longitude":"-91.96233270"},{"name":"Massachusetts","isoCode":"MA","countryCode":"US","latitude":"42.40721070","longitude":"-71.38243740"},{"name":"Maryland","isoCode":"MD","countryCode":"US","latitude":"39.04575490","longitude":"-76.64127120"},{"name":"Maine","isoCode":"ME","countryCode":"US","latitude":"45.25378300","longitude":"-69.44546890"},{"name":"Michigan","isoCode":"MI","countryCode":"US","latitude":"44.31484430","longitude":"-85.60236430"},{"name":"Minnesota","isoCode":"MN","countryCode":"US","latitude":"46.72955300","longitude":"-94.68589980"},{"name":"Missouri","isoCode":"MO","countryCode":"US","latitude":"37.96425290","longitude":"-91.83183340"},{"name":"Northern Mariana Islands","isoCode":"MP","countryCode":"US","latitude":"15.09790000","longitude":"145.67390000"},{"name":"Mississippi","isoCode":"MS","countryCode":"US","latitude":"32.35466790","longitude":"-89.39852830"},{"name":"Montana","isoCode":"MT","countryCode":"US","latitude":"46.87968220","longitude":"-110.36256580"},{"name":"North Carolina","isoCode":"NC","countryCode":"US","latitude":"35.75957310","longitude":"-79.01929970"},{"name":"North Dakota","isoCode":"ND","countryCode":"US","latitude":"47.55149260","longitude":"-101.00201190"},{"name":"Nebraska","isoCode":"NE","countryCode":"US","latitude":"41.49253740","longitude":"-99.90181310"},{"name":"New Hampshire","isoCode":"NH","countryCode":"US","latitude":"43.19385160","longitude":"-71.57239530"},{"name":"New Jersey","isoCode":"NJ","countryCode":"US","latitude":"40.05832380","longitude":"-74.40566120"},{"name":"New Mexico","isoCode":"NM","countryCode":"US","latitude":"34.51994020","longitude":"-105.87009010"},{"name":"Nevada","isoCode":"NV","countryCode":"US","latitude":"38.80260970","longitude":"-116.41938900"},{"name":"New York","isoCode":"NY","countryCode":"US","latitude":"40.71277530","longitude":"-74.00597280"},{"name":"Ohio","isoCode":"OH","countryCode":"US","latitude":"40.41728710","longitude":"-82.90712300"},{"name":"Oklahoma","isoCode":"OK","countryCode":"US","latitude":"35.46756020","longitude":"-97.51642760"},{"name":"Oregon","isoCode":"OR","countryCode":"US","latitude":"43.80413340","longitude":"-120.55420120"},{"name":"Pennsylvania","isoCode":"PA","countryCode":"US","latitude":"41.20332160","longitude":"-77.19452470"},{"name":"Puerto Rico","isoCode":"PR","countryCode":"US","latitude":"18.22083300","longitude":"-66.59014900"},{"name":"Rhode Island","isoCode":"RI","countryCode":"US","latitude":"41.58009450","longitude":"-71.47742910"},{"name":"South Carolina","isoCode":"SC","countryCode":"US","latitude":"33.83608100","longitude":"-81.16372450"},{"name":"South Dakota","isoCode":"SD","countryCode":"US","latitude":"43.96951480","longitude":"-99.90181310"},{"name":"Tennessee","isoCode":"TN","countryCode":"US","latitude":"35.51749130","longitude":"-86.58044730"},{"name":"Texas","isoCode":"TX","countryCode":"US","latitude":"31.96859880","longitude":"-99.90181310"},{"name":"United States Minor Outlying Islands","isoCode":"UM","countryCode":"US","latitude":"19.28231920","longitude":"166.64704700"},{"name":"Johnston Atoll","isoCode":"UM-67","countryCode":"US","latitude":"16.72950350","longitude":"-169.53364770"},{"name":"Midway Atoll","isoCode":"UM-71","countryCode":"US","latitude":"28.20721680","longitude":"-177.37349260"},{"name":"Navassa Island","isoCode":"UM-76","countryCode":"US","latitude":"18.41006890","longitude":"-75.01146120"},{"name":"Wake Island","isoCode":"UM-79","countryCode":"US","latitude":"19.27961900","longitude":"166.64993480"},{"name":"Baker Island","isoCode":"UM-81","countryCode":"US","latitude":"0.19362660","longitude":"-176.47690800"},{"name":"Howland Island","isoCode":"UM-84","countryCode":"US","latitude":"0.81132190","longitude":"-176.61827360"},{"name":"Jarvis Island","isoCode":"UM-86","countryCode":"US","latitude":"-0.37435030","longitude":"-159.99672060"},{"name":"Kingman Reef","isoCode":"UM-89","countryCode":"US","latitude":"6.38333300","longitude":"-162.41666700"},{"name":"Palmyra Atoll","isoCode":"UM-95","countryCode":"US","latitude":"5.88850260","longitude":"-162.07866560"},{"name":"Utah","isoCode":"UT","countryCode":"US","latitude":"39.32098010","longitude":"-111.09373110"}
1,{"name":"Virginia","isoCode":"VA","countryCode":"US","latitude":"37.43157340","longitude":"-78.65689420"},{"name":"United States Virgin Islands","isoCode":"VI","countryCode":"US","latitude":"18.33576500","longitude":"-64.89633500"},{"name":"Vermont","isoCode":"VT","countryCode":"US","latitude":"44.55880280","longitude":"-72.57784150"},{"name":"Washington","isoCode":"WA","countryCode":"US","latitude":"47.75107410","longitude":"-120.74013850"},{"name":"Wisconsin","isoCode":"WI","countryCode":"US","latitude":"43.78443970","longitude":"-88.78786780"},{"name":"West Virginia","isoCode":"WV","countryCode":"US","latitude":"38.59762620","longitude":"-80.45490260"},{"name":"Wyoming","isoCode":"WY","countryCode":"US","latitude":"43.07596780","longitude":"-107.29028390"},{"name":"Artigas Department","isoCode":"AR","countryCode":"UY","latitude":"-30.61751120","longitude":"-56.95945590"},{"name":"Canelones Department","isoCode":"CA","countryCode":"UY","latitude":"-34.54087170","longitude":"-55.93076000"},{"name":"Cerro Largo Department","isoCode":"CL","countryCode":"UY","latitude":"-32.44110320","longitude":"-54.35217530"},{"name":"Colonia Department","isoCode":"CO","countryCode":"UY","latitude":"-34.12946780","longitude":"-57.66051840"},{"name":"Durazno Department","isoCode":"DU","countryCode":"UY","latitude":"-33.02324540","longitude":"-56.02846440"},{"name":"Florida Department","isoCode":"FD","countryCode":"UY","latitude":"28.03594950","longitude":"-82.45792890"},{"name":"Flores Department","isoCode":"FS","countryCode":"UY","latitude":"-33.57337530","longitude":"-56.89450280"},{"name":"Lavalleja Department","isoCode":"LA","countryCode":"UY","latitude":"-33.92261750","longitude":"-54.97657940"},{"name":"Maldonado Department","isoCode":"MA","countryCode":"UY","latitude":"-34.55979320","longitude":"-54.86285520"},{"name":"Montevideo Department","isoCode":"MO","countryCode":"UY","latitude":"-34.81815870","longitude":"-56.21382560"},{"name":"Paysandú Department","isoCode":"PA","countryCode":"UY","latitude":"-32.06673660","longitude":"-57.33647890"},{"name":"RÃo Negro Department","isoCode":"RN","countryCode":"UY","latitude":"-32.76763560","longitude":"-57.42952070"},{"name":"Rocha Department","isoCode":"RO","countryCode":"UY","latitude":"-33.96900810","longitude":"-54.02148500"},{"name":"Rivera Department","isoCode":"RV","countryCode":"UY","latitude":"-31.48174210","longitude":"-55.24357590"},{"name":"Salto Department","isoCode":"SA","countryCode":"UY","latitude":"-31.38802800","longitude":"-57.96124550"},{"name":"San José Department","isoCode":"SJ","countryCode":"UY","latitude":"37.34929680","longitude":"-121.90560490"},{"name":"Soriano Department","isoCode":"SO","countryCode":"UY","latitude":"-33.51027920","longitude":"-57.74981030"},{"name":"Tacuarembó Department","isoCode":"TA","countryCode":"UY","latitude":"-31.72068370","longitude":"-55.98598870"},{"name":"Treinta y Tres Department","isoCode":"TT","countryCode":"UY","latitude":"-33.06850860","longitude":"-54.28586270"},{"name":"Andijan Region","isoCode":"AN","countryCode":"UZ","latitude":"40.76859410","longitude":"72.23
1637900"},{"name":"Bukhara Region","isoCode":"BU","countryCode":"UZ","latitude":"40.25041620","longitude":"63.20321510"},{"name":"Fergana Region","isoCode":"FA","countryCode":"UZ","latitude":"40.45680810","longitude":"71.28742090"},{"name":"Jizzakh Region","isoCode":"JI","countryCode":"UZ","latitude":"40.47064150","longitude":"67.57085360"},{"name":"Namangan Region","isoCode":"NG","countryCode":"UZ","latitude":"41.05100370","longitude":"71.09731700"},{"name":"Navoiy Region","isoCode":"NW","countryCode":"UZ","latitude":"42.69885750","longitude":"64.63376850"},{"name":"Qashqadaryo Region","isoCode":"QA","countryCode":"UZ","latitude":"38.89862310","longitude":"66.04635340"},{"name":"Karakalpakstan","isoCode":"QR","countryCode":"UZ","latitude":"43.80413340","longitude":"59.44579880"},{"name":"Samarqand Region","isoCode":"SA","countryCode":"UZ","latitude":"39.62701200","longitude":"66.97497310"},{"name":"Sirdaryo Region","isoCode":"SI","countryCode":"UZ","latitude":"40.38638080","longitude":"68.71549750"},{"name":"Surxondaryo Region","isoCode":"SU","countryCode":"UZ","latitude":"37.94090050","longitude":"67.57085360"},{"name":"Tashkent","isoCode":"TK","countryCode":"UZ","latitude":"41.29949580","longitude":"69.24007340"},{"name":"Tashkent Region","isoCode":"TO","countryCode":"UZ","latitude":"41.22132340","longitude":"69.85974060"},{"name":"Xorazm Region","isoCode":"XO","countryCode":"UZ","latitude":"41.35653360","longitude":"60.85666860"},{"name":"Charlotte Parish","isoCode":"01","countryCode":"VC","latitude":"13.21754510","longitude":"-61.16362440"},{"name":"Saint Andrew Parish","isoCode":"02","countryCode":"VC","latitude":"43.02429990","longitude":"-81.20250000"},{"name":"Saint David Parish","isoCode":"03","countryCode":"VC","latitude":"43.85230950","longitude":"-79.52366540"},{"name":"Saint George Parish","isoCode":"04","countryCode":"VC","latitude":"42.95760900","longitude":"-81.32670500"},{"name":"Saint Patrick Parish","isoCode":"05","countryCode":"VC","latitude":"39.75091860","longitude":"-94.84505560"},{"name":"Grenadines Parish","isoCode":"06","countryCode":"VC","latitude":"13.01229650","longitude":"-61.22773010"},{"name":"Distrito Capital","isoCode":"A","countryCode":"VE","latitude":"41.26148460","longitude":"-95.93108070"},{"name":"Anzoátegui","isoCode":"B","countryCode":"VE","latitude":"8.59130730","longitude":"-63.95861110"},{"name":"Apure","isoCode":"C","countryCode":"VE","latitude":"6.92694830","longitude":"-68.52471490"},{"name":"Aragua","isoCode":"D","countryCode":"VE","latitude":"10.06357580","longitude":"-67.28478750"},{"name":"Barinas","isoCode":"E","countryCode":"VE","latitude":"8.62314980","longitude":"-70.23710450"},{"name":"BolÃvar","isoCode":"F","countryCode":"VE","latitude":"37.61448380","longitude":"-93.41047490"},{"name":"Carabobo","isoCode":"G","countryCode":"VE","latitude":"10.11764330","longitude":"-68.04775090"},{"name":"Cojedes","isoCode":"H","countryCode":"VE","latitude":"9.38166820","longitude":"-68.33392750"},{"name":"Falcón","isoCode":"I","countryCode":"VE","latitude":"11.18106740","longitude":"-69.85974060"},{"name":"Guárico","isoCode":"J","countryCode":"VE","latitude":"8.74893090","longitude":"-66.23671720"},{"name":"Lara","isoCode":"K","countryCode":"VE","latitude":"33.98221650","longitude":"-118.13227470"},{"name":"Mérida","isoCode":"L","countryCode":"VE","latitude":"20.96737020","longitude":"-89.59258570"},{"name":"Miranda","isoCode":"M","countryCode":"VE","latitude":"42.35193830","longitude":"-71.52907660"},{"name":"Monagas","isoCode":"N","countryCode":"VE","latitude":"9.32416520","longitude":"-63.01475780"},{"name":"Nueva Esparta","isoCode":"O","countryCode":"VE","latitude":"10.99707230","longitude":"-63.91132960"},{"name":"Portuguesa","isoCode":"P","countryCode":"VE","latitude":"9.09439990","longitude":"-69.09702300"},{"name":"Sucre","isoCode":"R","countryCode":"VE","latitude":"-19.03534500","longitude":"-65.25921280"},{"name":"Táchira","isoCode":"S","countryCode":"VE","latitude":"7.91370010","longitude":"-72.14161320"},{"name":"Trujillo","isoCode":"T","countryCode":"VE","latitude":"36.67343430","longitude":"-121.62875880"}
1,{"name":"Yaracuy","isoCode":"U","countryCode":"VE","latitude":"10.33938900","longitude":"-68.81088490"},{"name":"Zulia","isoCode":"V","countryCode":"VE","latitude":"10.29102370","longitude":"-72.14161320"},{"name":"Federal Dependencies of Venezuela","isoCode":"W","countryCode":"VE","latitude":"10.93770530","longitude":"-65.35695730"},{"name":"La Guaira","isoCode":"X","countryCode":"VE","latitude":"29.30522680","longitude":"-94.79138540"},{"name":"Delta Amacuro","isoCode":"Y","countryCode":"VE","latitude":"8.84993070","longitude":"-61.14031960"},{"name":"Amazonas","isoCode":"Z","countryCode":"VE","latitude":"-3.41684270","longitude":"-65.85606460"},{"name":"Lai Châu","isoCode":"01","countryCode":"VN","latitude":"22.38622270","longitude":"103.47026310"},{"name":"Là o Cai","isoCode":"02","countryCode":"VN","latitude":"22.48094310","longitude":"103.97549590"},{"name":"Hà Giang","isoCode":"03","countryCode":"VN","latitude":"22.80255880","longitude":"104.97844940"},{"name":"Cao Bằng","isoCode":"04","countryCode":"VN","latitude":"22.63568900","longitude":"106.25221430"},{"name":"SÆ¡n La","isoCode":"05","countryCode":"VN","latitude":"21.10222840","longitude":"103.72891670"},{"name":"Yên Bái","isoCode":"06","countryCode":"VN","latitude":"21.71676890","longitude":"104.89858780"},{"name":"Tuyên Quang","isoCode":"07","countryCode":"VN","latitude":"21.77672460","longitude":"105.22801960"},{"name":"Lạng SÆ¡n","isoCode":"09","countryCode":"VN","latitude":"21.85370800","longitude":"106.76151900"},{"name":"Quảng Ninh","isoCode":"13","countryCode":"VN","latitude":"21.00638200","longitude":"107.29251440"},{"name":"Hòa Bình","isoCode":"14","countryCode":"VN","latitude":"20.68612650","longitude":"105.31311850"},{"name":"Ninh Bình","isoCode":"18","countryCode":"VN","latitude":"20.25061490","longitude":"105.97445360"},{"name":"Thái Bình","isoCode":"20","countryCode":"VN","latitude":"20.44634710","longitude":"106.33658280"},{"name":"Thanh Hóa","isoCode":"21","countryCode":"VN","latitude":"19.80669200","longitude":"105.78518160"},{"name":"Nghá» An","isoCode":"22","countryCode":"VN","latitude":"19.23424890","longitude":"104.92003650"},{"name":"Hà TÄ©nh","isoCode":"23","countryCode":"VN","latitude":"18.35595370","longitude":"105.88774940"},{"name":"Quảng Bình","isoCode":"24","countryCode":"VN","latitude":"17.61027150","longitude":"106.34874740"},{"name":"Quảng Trá»","isoCode":"25","countryCode":"VN","latitude":"16.74030740","longitude":"107.18546790"},{"name":"Thừa Thiên-Huế","isoCode":"26","countryCode":"VN","latitude":"16.46739700","longitude":"107.59053260"},{"name":"Quảng Nam","isoCode":"27","countryCode":"VN","latitude":"15.53935380","longitude":"108.01910200"},{"name":"Kon Tum","isoCode":"28","countryCode":"VN","latitude":"14.34974030","longitude":"108.00046060"},{"name":"Quảng Ngãi","isoCode":"29","countryCode":"VN","latitude":"15.12138730","longitude":"108.80441450"},{"name":"Gia Lai","isoCode":"30","countryCode":"VN","latitude":"13.80789430","longitude":"108.10937500"},{"name":"Bình Äá»nh","isoCode":"31","countryCode":"VN","latitude":"14.16653240","longitude":"108.90268300"},{"name":"Phú Yên","isoCode":"32","countryCode":"VN","latitude":"13.08818610","longitude":"109.09287640"},{"name":"Äắk Lắk","isoCode":"33","countryCode":"VN","latitude":"12.71001160","longitude":"108.23775190"},{"name":"Khánh Hòa","isoCode":"34","countryCode":"VN","latitude":"12.25850980","longitude":"109.05260760"},{"name":"Lâm Äá»ng","isoCode":"35","countryCode":"VN","latitude":"11.57527910","longitude":"108.14286690"},{"name":"Ninh Thuáºn","isoCode":"36","countryCode":"VN","latitude":"11.67387670","longitude":"108.86295720"},{"name":"Tây Ninh","isoCode":"37","countryCode":"VN","latitude":"11.33515540","longitude":"106.10988540"},{"name":"Äá»ng Nai","isoCode":"39","countryCode":"VN","latitude":"11.06863050","longitude":"107.16759760"},{"name":"Bình Thuáºn","isoCode":"40","countryCode":"VN","latitude":"11.09037030","longitude":"108.07207810"},{"name":"Long An","isoCode":"41","countryCode":"VN","latitude":"10.56071680","longitude":"106.64976230"}
1,{"name":"Bà Rá»a-VÅ©ng Tà u","isoCode":"43","countryCode":"VN","latitude":"10.54173970","longitude":"107.24299760"},{"name":"An Giang","isoCode":"44","countryCode":"VN","latitude":"10.52158360","longitude":"105.12589550"},{"name":"Äá»ng Tháp","isoCode":"45","countryCode":"VN","latitude":"10.49379890","longitude":"105.68817880"},{"name":"Tiá»n Giang","isoCode":"46","countryCode":"VN","latitude":"10.44933240","longitude":"106.34205040"},{"name":"Kiên Giang","isoCode":"47","countryCode":"VN","latitude":"9.82495870","longitude":"105.12589550"},{"name":"VÄ©nh Long","isoCode":"49","countryCode":"VN","latitude":"10.23957400","longitude":"105.95719280"},{"name":"Bến Tre","isoCode":"50","countryCode":"VN","latitude":"10.24335560","longitude":"106.37555100"},{"name":"Trà Vinh","isoCode":"51","countryCode":"VN","latitude":"9.81274100","longitude":"106.29929120"},{"name":"Sóc TrÄng","isoCode":"52","countryCode":"VN","latitude":"9.60252100","longitude":"105.97390490"},{"name":"Bắc Kạn","isoCode":"53","countryCode":"VN","latitude":"22.30329230","longitude":"105.87600400"},{"name":"Bắc Giang","isoCode":"54","countryCode":"VN","latitude":"21.28199210","longitude":"106.19747690"},{"name":"Bạc Liêu","isoCode":"55","countryCode":"VN","latitude":"9.29400270","longitude":"105.72156630"},{"name":"Bắc Ninh","isoCode":"56","countryCode":"VN","latitude":"21.12144400","longitude":"106.11105010"},{"name":"Bình Dương","isoCode":"57","countryCode":"VN","latitude":"11.32540240","longitude":"106.47701700"},{"name":"Bình Phưá»c","isoCode":"58","countryCode":"VN","latitude":"11.75118940","longitude":"106.72346390"},{"name":"Cà Mau","isoCode":"59","countryCode":"VN","latitude":"9.15267280","longitude":"105.19607950"},{"name":"Hải Dương","isoCode":"61","countryCode":"VN","latitude":"20.93734130","longitude":"106.31455420"},{"name":"Hà Nam","isoCode":"63","countryCode":"VN","latitude":"20.58351960","longitude":"105.92299000"},{"name":"Hưng Yên","isoCode":"66","countryCode":"VN","latitude":"20.85257110","longitude":"106.01699710"},{"name":"Nam Äá»nh","isoCode":"67","countryCode":"VN","latitude":"20.43882250","longitude":"106.16210530"},{"name":"Phú Thá»","isoCode":"68","countryCode":"VN","latitude":"21.26844300","longitude":"105.20455730"},{"name":"Thái Nguyên","isoCode":"69","countryCode":"VN","latitude":"21.56715590","longitude":"105.82520380"},{"name":"VÄ©nh Phúc","isoCode":"70","countryCode":"VN","latitude":"21.36088050","longitude":"105.54743730"},{"name":"Äiá»n Biên","isoCode":"71","countryCode":"VN","latitude":"21.80423090","longitude":"103.10765250"},{"name":"Äắk Nông","isoCode":"72","countryCode":"VN","latitude":"12.26464760","longitude":"107.60980600"},{"name":"Háºu Giang","isoCode":"73","countryCode":"VN","latitude":"9.75789800","longitude":"105.64125270"},{"name":"Cần ThÆ¡","isoCode":"CT","countryCode":"VN","latitude":"10.03418510","longitude":"105.72255070"},{"name":"Äà Nẵng","isoCode":"DN","countryCode":"VN","latitude":"16.05440680","longitude":"108.20216670"},{"name":"Hà Ná»i","isoCode":"HN","countryCode":"VN","latitude":"21.02776440","longitude":"105.83415980"},{"name":"Hải Phòng","isoCode":"HP","countryCode":"VN","latitude":"20.84491150","longitude":"106.68808410"},{"name":"Há» Chà Minh","isoCode":"SG","countryCode":"VN","latitude":"10.82309890","longitude":"106.62966380"},{"name":"Malampa","isoCode":"MAP","countryCode":"VU","latitude":"-16.40114050","longitude":"167.60778650"},{"name":"Penama","isoCode":"PAM","countryCode":"VU","latitude":"-15.37957580","longitude":"167.90531820"},{"name":"Sanma","isoCode":"SAM","countryCode":"VU","latitude":"-15.48400170","longitude":"166.91820970"},{"name":"Shefa","isoCode":"SEE","countryCode":"VU","latitude":"32.80576500","longitude":"35.16997100"},{"name":"Tafea","isoCode":"TAE","countryCode":"VU","latitude":"-18.72378270","longitude":"169.06450560"},{"name":"Torba","isoCode":"TOB","countryCode":"VU","latitude":"37.07653000","longitude":"27.45657300"},{"name":"A\'ana","isoCode":"AA","countryCode":"WS","latitude":"-13.89841800","longitude":"-171.97529950"},{"name":"Aiga-i-le-Tai","isoCode":"AL","countryCode":"WS","latitude":"-13.85137910","longitude":"-172.03254010"},{"name":"Atua","isoCode":"AT","countryCode":"WS","latitude":"-13.97870530","longitude":"-171.62542830"},{"name":"Fa\'asaleleaga","isoCode":"FA","countryCode":"WS","latitude":"-13.63076380","longitude":"-172.23659810"},{"name":"Gaga\'emauga","isoCode":"GE","countryCode":"WS","latitude":"-13.54286660","longitude":"-172.36688700"},{"name":"Gaga\'ifomauga","isoCode":"GI","countryCode":"WS","latitude":"-13.54680070","longitude":"-172.49693310"},{"name":"Palauli","isoCode":"PA","countryCode":"WS","latitude":"-13.72945790","longitude":"-172.45361150"},{"name":"Satupa\'itea","isoCode":"SA","countryCode":"WS","latitude":"-13.65382140","longitude":"-172.61592710"},{"name":"Tuamasaga","isoCode":"TU","countryCode":"WS","latitude":"-13.91635920","longitude":"-171.82243620"}
1,{"name":"Va\'a-o-Fonoti","isoCode":"VF","countryCode":"WS","latitude":"-13.94709030","longitude":"-171.54318720"},{"name":"Vaisigano","isoCode":"VS","countryCode":"WS","latitude":"-13.54138270","longitude":"-172.70233830"},{"name":"Äakovica District (Gjakove)","isoCode":"XDG","countryCode":"XK","latitude":"42.43757560","longitude":"20.37854380"},{"name":"Gjilan District","isoCode":"XGJ","countryCode":"XK","latitude":"42.46352060","longitude":"21.46940110"},{"name":"Kosovska Mitrovica District","isoCode":"XKM","countryCode":"XK","latitude":"42.89139090","longitude":"20.86599950"},{"name":"PeÄ District","isoCode":"XPE","countryCode":"XK","latitude":"42.65921550","longitude":"20.28876240"},{"name":"Pristina (PriÅtine)","isoCode":"XPI","countryCode":"XK","latitude":"42.66291380","longitude":"21.16550280"},{"name":"Prizren District","isoCode":"XPR","countryCode":"XK","latitude":"42.21525220","longitude":"20.74147720"},{"name":"UroÅ¡evac District (Ferizaj)","isoCode":"XUF","countryCode":"XK","latitude":"42.37018440","longitude":"21.14832810"},{"name":"Abyan Governorate","isoCode":"AB","countryCode":"YE","latitude":"13.63434130","longitude":"46.05632120"},{"name":"\'Adan Governorate","isoCode":"AD","countryCode":"YE","latitude":"12.82574810","longitude":"44.79438040"},{"name":"\'Amran Governorate","isoCode":"AM","countryCode":"YE","latitude":"16.25692140","longitude":"43.94367880"},{"name":"Al Bayda\' Governorate","isoCode":"BA","countryCode":"YE","latitude":"14.35886620","longitude":"45.44980650"},{"name":"Dhamar Governorate","isoCode":"DH","countryCode":"YE","latitude":"14.71953440","longitude":"44.24790150"},{"name":"Hadhramaut Governorate","isoCode":"HD","countryCode":"YE","latitude":"16.93041350","longitude":"49.36531490"},{"name":"Hajjah Governorate","isoCode":"HJ","countryCode":"YE","latitude":"16.11806310","longitude":"43.32946600"},{"name":"Al Hudaydah Governorate","isoCode":"HU","countryCode":"YE","latitude":"15.30530720","longitude":"43.01948970"},{"name":"Ibb Governorate","isoCode":"IB","countryCode":"YE","latitude":"14.14157170","longitude":"44.24790150"},{"name":"Al Jawf Governorate","isoCode":"JA","countryCode":"YE","latitude":"16.79018190","longitude":"45.29938620"},{"name":"Lahij Governorate","isoCode":"LA","countryCode":"YE","latitude":"13.14895880","longitude":"44.85054950"},{"name":"Ma\'rib Governorate","isoCode":"MA","countryCode":"YE","latitude":"15.51588800","longitude":"45.44980650"},{"name":"Al Mahrah Governorate","isoCode":"MR","countryCode":"YE","latitude":"16.52384230","longitude":"51.68342750"},{"name":"Al Mahwit Governorate","isoCode":"MW","countryCode":"YE","latitude":"15.39632290","longitude":"43.56069460"},{"name":"Raymah Governorate","isoCode":"RA","countryCode":"YE","latitude":"14.62776820","longitude":"43.71424840"},{"name":"Sana\'a","isoCode":"SA","countryCode":"YE","latitude":"15.36944510","longitude":"44.19100660"},{"name":"Saada Governorate","isoCode":"SD","countryCode":"YE","latitude":"16.84765280","longitude":"43.94367880"},{"name":"Shabwah Governorate","isoCode":"SH","countryCode":"YE","latitude":"14.75463030","longitude":"46.51626200"},{"name":"Sana\'a Governorate","isoCode":"SN","countryCode":"YE","latitude":"15.31689130","longitude":"44.47480180"},{"name":"Socotra Governorate","isoCode":"SU","countryCode":"YE","latitude":"12.46342050","longitude":"53.82373850"},{"name":"Ta\'izz Governorate","isoCode":"TA","countryCode":"YE","latitude":"13.57758860","longitude":"44.01779890"},{"name":"Eastern Cape","isoCode":"EC","countryCode":"ZA","latitude":"-32.29684020","longitude":"26.41938900"},{"name":"Free State","isoCode":"FS","countryCode":"ZA","latitude":"37.68585250","longitude":"-97.28112560"},{"name":"Gauteng","isoCode":"GP","countryCode":"ZA","latitude":"-26.27075930","longitude":"28.11226790"},{"name":"KwaZulu-Natal","isoCode":"KZN","countryCode":"ZA","latitude":"-28.53055390","longitude":"30.89582420"},{"name":"Limpopo","isoCode":"LP","countryCode":"ZA","latitude":"-23.40129460","longitude":"29.41793240"},{"name":"Mpumalanga","isoCode":"MP","countryCode":"ZA","latitude":"-25.56533600","longitude":"30.52790960"},{"name":"Northern Cape","isoCode":"NC","countryCode":"ZA","latitude":"-29.04668080","longitude":"21.85685860"},{"name":"North West","isoCode":"NW","countryCode":"ZA","latitude":"32.75885200","longitude":"-97.32880600"},{"name":"Western Cape","isoCode":"WC","countryCode":"ZA","latitude":"-33.22779180","longitude":"21.85685860"},{"name":"Western Province","isoCode":"01","countryCode":"ZM","latitude":"6.90160860","longitude":"80.00877460"},{"name":"Central Province","isoCode":"02","countryCode":"ZM","latitude":"7.25649960","longitude":"80.72144170"},{"name":"Eastern Province","isoCode":"03","countryCode":"ZM","latitude":"23.16696880","longitude":"49.36531490"},{"name":"Luapula Province","isoCode":"04","countryCode":"ZM","latitude":"-11.56483100","longitude":"29.04599270"},{"name":"Northern Province","isoCode":"05","countryCode":"ZM","latitude":"8.88550270","longitude":"80.27673270"},{"name":"Northwestern Province","isoCode":"06","countryCode":"ZM","latitude":"-13.00502580","longitude":"24.90422080"},{"name":"Southern Province","isoCode":"07","countryCode":"ZM","latitude":"6.23737500","longitude":"80.54384500"},{"name":"Copperbelt Province","isoCode":"08","countryCode":"ZM","latitude":"-13.05700730","longitude":"27.54958460"},{"name":"Lusaka Province","isoCode":"09","countryCode":"ZM","latitude":"-15.36571290","longitude":"29.23207840"},{"name":"Muchinga Province","isoCode":"10","countryCode":"ZM","latitude":"-15.38219300","longitude":"28.26158000"},{"name":"Bulawayo Province","isoCode":"BU","countryCode":"ZW","latitude":"-20.14895050","longitude":"28.53310380"},{"name":"Harare Province","isoCode":"HA","countryCode":"ZW","latitude":"-17.82162880","longitude":"31.04922590"},{"name":"Manicaland","isoCode":"MA","countryCode":"ZW","latitude":"-18.92163860","longitude":"32.17460500"},{"name":"Mashonaland Central Province","isoCode":"MC","countryCode":"ZW","latitude":"-16.76442950","longitude":"31.07937050"},{"name":"Mashonaland East Province","isoCode":"ME","countryCode":"ZW","latitude":"-18.58716420","longitude":"31.26263660"},{"name":"Midlands Province","isoCode":"MI","countryCode":"ZW","latitude":"-19.05520090","longitude":"29.60354950"},{"name":"Matabeleland North Province","isoCode":"MN","countryCode":"ZW","latitude":"-18.53315660","longitude":"27.54958460"},{"name":"Matabeleland South Province","isoCode":"MS","countryCode":"ZW","latitude":"-21.05233700","longitude":"29.04599270"}
1,{"name":"Masvingo Province","isoCode":"MV","countryCode":"ZW","latitude":"-20.62415090","longitude":"31.26263660"},{"name":"Mashonaland West Province","isoCode":"MW","countryCode":"ZW","latitude":"-17.48510290","longitude":"29.78892480"}]');var l={getAllStates:function(){return d},getStatesOfCountry:function(e=""){return e?d.filter((t=>t.countryCode===e)).sort(s):[]},getStateByCodeAndCountry:function(e,t){if(e&&t)return((e,t,n)=>{if(t&&n&&null!=e){const o=e.findIndex((e=>e.isoCode===t&&e.countryCode===n));return-1!==o?e[o]:void 0}})(d,e,t)},getStateByCode:function(e){if(console.warn("WARNING! 'getStateByCode' has been deprecated, please use the new 'getStateByCodeAndCountry' function instead!"),e)return i(d,e)},sortByIsoCode:function(e){return e.sort(((e,t)=>s(e,t,(e=>`${e.countryCode}-${e.isoCode}`))))}};var c=new class{constructor(){this.countriesCache=null,this.statesCache=new Map,this.postalCodeCache=new Map}getAllCountries(e){return this.countriesCache||(this.countriesCache=r.getAllCountries().map((e=>({name:e.name,code:e.isoCode,flag:e.flag,phonecode:e.phonecode,currency:e.currency,timezones:e.timezones})))),e&&0!==e.length?this.countriesCache.filter((t=>!e.includes(t.code))):this.countriesCache}getStatesByCountry(e){if(!e)return[];const t=e.toUpperCase();if(!this.statesCache.has(t)){const e=l.getStatesOfCountry(t).map((e=>({name:e.name,code:e.isoCode})));this.statesCache.set(t,e)}return this.statesCache.get(t)||[]}async validatePostalCode(e,t){if(!e||!t)return{valid:!1,error:"Country code and postal code required"};const n=t.replace(/\s/g,"").toUpperCase(),o=`${e.toUpperCase()}-${n}`;if(this.postalCodeCache.has(o))return this.postalCodeCache.get(o);if(["CA","IE","AE","SA","QA","KW","OM","BH"].includes(e.toUpperCase())){const n=this.getPostalCodeFormat(e).pattern.test(t),i={valid:n,validatedByFormat:!0,error:n?null:"Invalid postal code format"};return this.postalCodeCache.set(o,i),i}try{const n=t.replace(/\s/g,""),i=await fetch(`https://api.zippopotam.us/${e.toLowerCase()}/${encodeURIComponent(n)}`);if(i.ok){const e=await i.json(),t={valid:!0,country:e.country,countryCode:e["country abbreviation"],postalCode:e["post code"],places:e.places.map((e=>({name:e["place name"],state:e.state,stateCode:e["state abbreviation"],latitude:parseFloat(e.latitude),longitude:parseFloat(e.longitude)})))};return this.postalCodeCache.set(o,t),t}if(404===i.status){const e={valid:!1,error:"Invalid postal code"};return this.postalCodeCache.set(o,e),e}throw new Error(`API error: ${i.status}`)}catch(n){console.error("Postal code validation error:",n);const o=this.getPostalCodeFormat(e).pattern.test(t);return{valid:o,validatedByFormat:!0,error:o?null:"Invalid postal code format"}}}getPostalCodeFormat(e){return{US:{pattern:/^\d{5}(-\d{4})?$/,example:"12345 or 12345-6789",maxLength:10},CA:{pattern:/^[A-Z]\d[A-Z]\s?\d[A-Z]\d$/i,example:"K1A 0B1",maxLength:7},GB:{pattern:/^[A-Z]{1,2}\d[A-Z\d]?\s?\d[A-Z]{2}$/i,example:"SW1A 1AA",maxLength:8},AU:{pattern:/^\d{4}$/,example:"2000",maxLength:4},DE:{pattern:/^\d{5}$/,example:"10115",maxLength:5},FR:{pattern:/^\d{5}$/,example:"75008",maxLength:5},IT:{pattern:/^\d{5}$/,example:"00187",maxLength:5},ES:{pattern:/^\d{5}$/,example:"28013",maxLength:5},NL:{pattern:/^\d{4}\s?[A-Z]{2}$/i,example:"1012 NX",maxLength:7},BR:{pattern:/^\d{5}-?\d{3}$/,example:"01310-100",maxLength:9},JP:{pattern:/^\d{3}-?\d{4}$/,example:"100-0001",maxLength:8},CN:{pattern:/^\d{6}$/,example:"100000",maxLength:6},IN:{pattern:/^\d{6}$/,example:"110001",maxLength:6},MX:{pattern:/^\d{5}$/,example:"06600",maxLength:5},AR:{pattern:/^[A-Z]\d{4}[A-Z]{3}$/i,example:"C1425CLA",maxLength:8},IE:{pattern:/^[A-Z]\d{2}\s?[A-Z0-9]{4}$/i,example:"D02 X285",maxLength:8}}[e?.toUpperCase()]||{pattern:/.+/,example:"Enter postal code",maxLength:20}}clearPostalCodeCache(){this.postalCodeCache.clear()}formatPostalCode(e,t){if(!t)return"";const n=t.replace(/[^\w\s-]/g,"").toUpperCase();switch(e?.toUpperCase()){case"US":return n.length>5?n.slice(0,5)+"-"+n.slice(5,9):n.slice(0,5);case"CA":const e=n.replace(/\s/g,"");return e.length>=3?e.slice(0,3)+" "+e.slice(3,6):e;case"GB":const t=n.replace(/\s/g,"");return t.length>3?t.slice(0,-3)+" "+t.slice(-3):t;case"BR":return n.length>5?n.slice(0,5)+"-"+n.slice(5,8):n;case"JP":return n.length>3?n.slice(0,3)+"-"+n.slice(3,7):n;case"IE":const o=n.replace(/\s/g,"");return o.length>3?o.slice(0,3)+" "+o.slice(3,7):o;default:return n}}}},8520:function(e,t,n){"use strict";n.r(t),n.d(t,{initService:function(){return i}});var o=n(2910);const i=new class{constructor(){this.initPromise=null,this.initData=null,this.lastFetchTime=null,this.cacheTimeout=3e5}async getInitData(e=!1){const t=(new Error).stack?.split("\n")[2]?.trim()||"unknown";console.log(`[InitService] getInitData called by: ${t}, forceRefresh: ${e}, hasCache: ${!!this.initData}, inProgress: ${!!this.initPromise}`);const n=Date.now(),o=!this.lastFetchTime||n-this.lastFetchTime>this.cacheTimeout;return e||!this.initData||o?this.initPromise&&!e?(console.log("[InitService] Request already in progress, returning existing promise"),this.initPromise):(console.log("[InitService] Starting new fetch"),this.initPromise=this.fetchInitData().then((e=>(this.initData=e,this.lastFetchTime=Date.now(),this.initPromise=null,e))).catch((e=>{throw this.initPromise=null,e}
1)),this.initPromise):(console.log("[InitService] Returning cached data"),this.initData)}async fetchInitData(){console.log("[InitService] fetchInitData called from:",(new Error).stack);try{const e=await fetch(o.A.apiHeimguardInitUrl,{method:"GET",credentials:"include",headers:{"Content-Type":"application/json"}});if(!e.ok){if(401===e.status)return{authenticated:!1,user:null,config:this.getDefaultConfig()};throw new Error(`Init API error: ${e.status}`)}const t=await e.json(),n=document.cookie.includes("heimguard.auth")||document.cookie.includes("heimguard.authStatus");return{...t,authenticated:n,user:n&&t.user||null}}catch(e){return console.warn("Failed to fetch init data:",e),{authenticated:!1,user:null,config:this.getDefaultConfig(),error:e instanceof Error?e.message:"Unknown error"}}}getDefaultConfig(){return{features:{auth:!0,profile:!0,affinity:!0,subscriptions:!0,newsletter:!0},theme:{primaryColor:"#4f46e5",logo:"/images/logo.png"}}}clearCache(){this.initData=null,this.lastFetchTime=null,this.initPromise=null}isAuthenticated(){if(void 0!==this.initData?.authenticated)return this.initData.authenticated;return document.cookie.includes("heimguard.auth")||document.cookie.includes("heimguard.authStatus")}getUser(){return this.initData?.user||null}getConfig(){return this.initData?.config||this.getDefaultConfig()}};"undefined"!=typeof window&&(window.HeimGuard=window.HeimGuard||{},window.HeimGuard.initService=i),t.default=i},3649:function(e,t,n){"use strict";n.d(t,{J:function(){return i}});class o{constructor(){this.activeModal=null,this.modalStack=[],this.modalDebounce=new Map,this.DEBOUNCE_TIME=300}static getInstance(){return o.instance||(o.instance=new o),o.instance}canOpenModal(e){if(e){const t=this.modalDebounce.get(e)||0,n=Date.now();if(n-t<this.DEBOUNCE_TIME)return console.log(`[ModalManager] Debouncing modal open for ${e}`),!1;this.modalDebounce.set(e,n)}return null===this.activeModal}registerModal(e,t){return this.activeModal?(console.warn("[ModalManager] Modal already active, preventing duplicate"),!1):(console.log("[ModalManager] Registering modal"+(t?` (${t})`:"")),this.activeModal=e,!0)}unregisterModal(e){this.activeModal===e&&(console.log("[ModalManager] Unregistering modal"),this.activeModal=null)}getActiveModal(){return this.activeModal}closeActiveModal(){this.activeModal&&(console.log("[ModalManager] Force closing active modal"),"function"==typeof this.activeModal.close?this.activeModal.close():"function"==typeof this.activeModal.hide&&this.activeModal.hide(),this.activeModal=null)}reset(){this.activeModal=null,this.modalStack=[],this.modalDebounce.clear()}}const i=o.getInstance()},1667:function(e,t,n){"use strict";n.d(t,{systemRegistry:function(){return a}});var o=n(1916);class i{constructor(){this.services=new Map,this.instances=new Map,this.initializing=new Set,this.initialized=new Set,this.options={allowOverride:!1,autoInitialize:!0}}configure(e){this.options={...this.options,...e}}register(e,t,n){return this.services.has(e)&&!this.options.allowOverride?(o.vF.warn(`Service "${e}" is already registered`,"registry"),this.services.get(e)):(this.services.set(e,t),n&&this.instances.set(e,n),o.vF.debug(`Registered service: ${e}`,"registry"),t)}registerInstance(e,t){return this.instances.has(e)&&!this.options.allowOverride?(o.vF.warn(`Instance "${e}" is already registered`,"registry"),this.instances.get(e)):(this.instances.set(e,t),o.vF.debug(`Registered instance: ${e}`,"registry"),t)}get(e){if(this.instances.has(e))return this.instances.get(e);const t=this.services.get(e);if(t)return t;o.vF.warn(`Service "${e}" not found`,"registry")}async getInstance(e){if(this.instances.has(e))return this.instances.get(e);const t=this.services.get(e);if(t)return this.options.autoInitialize&&t.initialize&&!this.initialized.has(e)&&await this.initializeService(e),this.instances.get(e)||t;o.vF.warn(`Service "${e}" not found`,"registry")}has(e){return this.services.has(e)||this.instances.has(e)}async initializeService(e){const t=this.services.get(e);if(t&&t.initialize)if(this.initializing.has(e))o.vF.warn(`Circular initialization detected for "${e}"`,"registry");else if(!this.initialized.has(e))try{this.initializing.add(e),o.vF.debug(`Initializing service: ${e}`,"registry"),await t.initialize(),this.initialized.add(e),o.vF.debug(`Service initialized: ${e}`,"registry")}catch(t){throw o.vF.error(`Failed to initialize service "${e}":`,"registry",t),t}finally{this.initializing.delete(e)}}
1async initializeAll(){const e=Array.from(this.services.entries());for(const[t,n]of e)n.initialize&&!this.initialized.has(t)&&await this.initializeService(t)}getServiceNames(){return Array.from(new Set([...this.services.keys(),...this.instances.keys()]))}getStatus(){const e={};for(const t of this.getServiceNames())e[t]={registered:!0,initialized:this.initialized.has(t)};return e}cleanupService(e){const t=this.services.get(e),n=this.instances.get(e);if(n&&"function"==typeof n.cleanup)try{n.cleanup()}catch(t){o.vF.error(`Error cleaning up instance "${e}":`,"registry",t)}if(t&&t.cleanup)try{t.cleanup()}catch(t){o.vF.error(`Error cleaning up service "${e}":`,"registry",t)}this.initialized.delete(e)}cleanup(){o.vF.info("Cleaning up all services...","registry");const e=Array.from(this.services.keys()).reverse();for(const t of e)this.cleanupService(t);this.services.clear(),this.instances.clear(),this.initializing.clear(),this.initialized.clear(),o.vF.info("Cleanup complete","registry")}createScope(){const e=new i;return e.configure(this.options),e}}const a=new i;"undefined"!=typeof window&&(window.systemRegistry=a)},7450:function(e,t,n){"use strict";n.d(t,{Ak:function(){return i},zc:function(){return o}});class o{static log(e,t,n={}){const o={id:`error-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,timestamp:(new Date).toISOString(),component:e,error:{message:t.message,stack:t.stack,name:t.name,code:t.code},context:n,type:this.detectErrorType(t),userAgent:navigator.userAgent,url:window.location.href,viewport:{width:window.innerWidth,height:window.innerHeight}};return this.errorLog.unshift(o),this.errorLog.length>this.maxLogSize&&(this.errorLog=this.errorLog.slice(0,this.maxLogSize)),this.isDevelopment()?(console.group(`ð¨ ${e} Error`),console.error("Error:",t),console.table(n),console.groupEnd()):console.error(`[${e}]`,t.message),this.emitErrorEvent(o),this.trackError(o),o}static detectErrorType(e){const t=e.message+" "+(e.stack||"");for(const[e,n]of Object.entries(this.errorPatterns))if(n.test(t))return e;const n=e.code;if(n)switch(n){case"NETWORK_ERROR":case"ECONNREFUSED":return"network";case"ETIMEDOUT":return"timeout";case"ENOTFOUND":return"notFound"}return"NetworkError"===e.name?"network":"TimeoutError"===e.name?"timeout":"ValidationError"===e.name?"validation":"AuthenticationError"===e.name?"auth":"unknown"}static getUserMessage(e,t={}){const n=t.type||this.detectErrorType(e),o={network:"Unable to connect to our servers. Please check your internet connection and try again.",timeout:"The request took too long to complete. Please try again.",auth:"You need to be logged in to perform this action.",validation:"Please check your input and try again.",notFound:"The requested resource could not be found.",serverError:"Our servers are experiencing issues. Please try again later.",rateLimit:"Too many requests. Please wait a moment and try again.",config:`The ${t.component||"application"} is not properly configured. Please contact support.`,unknown:"An unexpected error occurred. Please try again or contact support."};return t.customMessage?t.customMessage:e.userMessage?e.userMessage:o[n]||o.unknown}static handle(e,t={}){const{component:o="Unknown",context:i={},showNotification:a=!0,logError:s=!0,throwError:r=!1}=t;let d=null;s&&(d=this.log(o,e,i));const l=this.detectErrorType(e),c=this.getUserMessage(e,{...t,type:l});a&&"undefined"!=typeof window&&Promise.resolve().then(n.bind(n,5762)).then((({AlertUtils:e})=>{e.error(c,{duration:"network"===l?1e4:5e3})})).catch((()=>{console.error(c)}));const u={success:!1,error:{type:l,message:c,originalMessage:e.message,component:o,timestamp:(new Date).toISOString(),id:d?.id},recovery:this.getRecoveryOptions(l,t)};if(r){const t=new Error(c);throw t.originalError=e,t.errorInfo=u,t}return u}static getRecoveryOptions(e,t={}){const n={canRetry:!1,canFallback:!1,suggestedAction:null,retryDelay:1e3};switch(e){case"network":n.canRetry=!0,n.canFallback=void 0!==t.fallbackUrl,n.suggestedAction="checkConnection",n.retryDelay=3e3;break;case"timeout":n.canRetry=!0,n.retryDelay=2e3,n.suggestedAction="retry";break;case"auth":n.canRetry=!1,n.suggestedAction="login";break;case"validation":n.canRetry=!1,n.suggestedAction="correctInput";break;case"serverError":n.canRetry=!0,n.retryDelay=5e3,n.suggestedAction="waitAndRetry";break;case"rateLimit":n.canRetry=!0,n.retryDelay=6e4,n.suggestedAction="waitAndRetry";break;default:n.canRetry=!0,n.retryDelay=2e3}return n}static async boundary(e,t={}){try{return await e()}catch(e){return this.handle(e,t)}}static async retry(e,t={}){const{maxAttempts:n=3,delay:o=1e3,backoff:i=2,shouldRetry:a=e=>"validation"!==this.detectErrorType(e),onRetry:s=null}=t;let r=null;for(let t=1;t<=n;t++)try{return await e()}catch(e){if(r=e,t===n||!a(r))throw e;const d=o*Math.pow(i,t-1);s&&s(r,t,d),await new Promise((e=>setTimeout(e,d)))}throw r}static emitErrorEvent(e){if("undefined"!=typeof window){const t=new CustomEvent("app:error",{detail:e,bubbles:!0});window.dispatchEvent(t)}}static trackError(e){"undefined"!=typeof window&&window.Sentry&&window.Sentry.captureException(new Error(e.error.message),{contexts:{error:e}})}static isDevelopment(){return"localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname||window.location.hostname.includes(".local")}static getLog(e={}){let t=[...this.errorLog];
1if(e.component&&(t=t.filter((t=>t.component===e.component))),e.type&&(t=t.filter((t=>t.type===e.type))),e.since){const n=new Date(e.since);t=t.filter((e=>new Date(e.timestamp)>=n))}return t}static clearLog(e={}){if(0===Object.keys(e).length)this.errorLog=[];else{const t=this.getLog(e);this.errorLog=this.errorLog.filter((e=>!t.includes(e)))}}static exportLog(e="json"){const t={exportDate:(new Date).toISOString(),errors:this.errorLog,summary:{total:this.errorLog.length,byType:this.errorLog.reduce(((e,t)=>(e[t.type]=(e[t.type]||0)+1,e)),{}),byComponent:this.errorLog.reduce(((e,t)=>(e[t.component]=(e[t.component]||0)+1,e)),{})}};if("json"===e)return JSON.stringify(t,null,2);const n=this.errorLog.map((e=>[e.timestamp,e.component,e.type,e.error.message,e.url]));return[["Timestamp","Component","Type","Message","URL"].join(","),...n.map((e=>e.map((e=>`"${e}"`)).join(",")))].join("\n")}static downloadLog(e="json"){const t=this.exportLog(e),n="json"===e?"json":"csv",o=new Blob([t],{type:"json"===e?"application/json":"text/csv"}),i=URL.createObjectURL(o),a=document.createElement("a");a.href=i,a.download=`error-log-${Date.now()}.${n}`,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(i)}static generateErrorModule(e={}){const{moduleName:t="Authentication Module",errorType:n="loading",userMessage:o=null,showRetry:i=!0,showSupport:a=!0,retryAction:s="window.location.reload()",supportAction:r="mailto:[email protected]",customIcon:d=null,companyName:l="Our Company"}=e,c=this.getErrorUIConfig(n),u=d||c.icon,m=o||c.message;return`\n <div class="error-module w-full max-w-[500px] mx-auto my-8">\n <div class="bg-white rounded-2xl shadow-xl border border-gray-100 overflow-hidden">\n \x3c!-- Error Header --\x3e\n <div class="px-8 pt-8 pb-6 text-center bg-gradient-to-br from-red-50 to-orange-50">\n <div class="mx-auto h-16 w-16 bg-red-100 rounded-2xl flex items-center justify-center mb-4">\n ${u}\n </div>\n <h2 class="text-xl font-bold text-gray-900 mb-2">Oops! Something went wrong</h2>\n <p class="text-gray-600 text-sm">We're having trouble loading the ${t.toLowerCase()}</p>\n </div>\n\n \x3c!-- Error Body --\x3e\n <div class="px-8 py-6">\n \x3c!-- Error Message --\x3e\n <div class="bg-red-50 border border-red-200 rounded-lg p-4 mb-6">\n <div class="flex items-start">\n <div class="flex-shrink-0">\n <svg class="w-5 h-5 text-red-500 mt-0.5" fill="currentColor" viewBox="0 0 20 20">\n <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>\n </svg>\n </div>\n <div class="ml-3">\n <h3 class="text-sm font-medium text-red-800">\n ${c.title}\n </h3>\n <p class="mt-1 text-sm text-red-700">\n ${m}\n </p>\n </div>\n </div>\n </div>\n\n \x3c!-- Action Buttons --\x3e\n <div class="space-y-3">\n ${i?`\n <button\n onclick="${s}"\n class="w-full flex justify-center items-center py-2.5 px-4 border border-transparent rounded-lg shadow-sm text-sm font-medium text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 transition-colors"\n >\n <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>\n </svg>\n Try Again\n </button>\n `:""}\n\n <div class="flex space-x-3">\n <button\n onclick="window.location.href='/'"\n class="flex-1 py-2 px-4 border border-gray-300 rounded-lg text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 transition-colors"\n >\n <svg class="w-4 h-4 mr-1 inline" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>\n </svg>\n Go Home\n </button>\n\n ${a?`\n <button\n onclick="${r.startsWith("mailto:")?`window.location.href='${r}'`:r}"\n class="flex-1 py-2 px-4 border border-gray-300 rounded-lg text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 transition-colors"\n >\n Get Help\n </button>\n `:""}\n </div>\n </div>\n\n \x3c!-- Additional Info --\x3e\n <div class="mt-6 pt-4 border-t border-gray-100">\n <details class="text-sm">\n <summary class="cursor-pointer text-gray-500 hover:text-gray-700 font-medium">\n Technical Details\n </summary>\n <div class="mt-2 text-xs text-gray-500 bg-gray-50 rounded p-3 font-mono">\n Module: ${t}<br>\n Error Type: ${n}<br>\n Timestamp: ${(new Date).toISOString()}<br>
1\n User Agent: ${navigator.userAgent.substring(0,60)}...\n </div>\n </details>\n </div>\n </div>\n\n \x3c!-- Footer --\x3e\n <div class="px-8 py-4 bg-gray-50 border-t border-gray-100">\n <p class="text-center text-xs text-gray-500">\n Still having trouble? Contact\n <a href="${r}" class="text-red-600 hover:text-red-500 font-medium">${l} Support</a>\n </p>\n </div>\n </div>\n </div>\n `}static getErrorUIConfig(e){const t={loading:{title:"Loading Error",message:"We encountered an issue while loading this component. This might be a temporary problem.",icon:'<svg class="w-8 h-8 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>\n </svg>'},network:{title:"Connection Problem",message:"Unable to connect to our servers. Please check your internet connection and try again.",icon:'<svg class="w-8 h-8 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18.364 5.636a9 9 0 010 12.728m0 0l-2.829-2.829m2.829 2.829L21 21M15.536 8.464a5 5 0 010 7.072m0 0l-2.829-2.829m-4.243 2.829a4.978 4.978 0 01-1.414-2.83m-1.414 5.658a9 9 0 01-2.167-9.238m7.824 2.167a1 1 0 111.414 1.414m-1.414-1.414L3 3m8.293 8.293l1.414 1.414"/>\n </svg>'},config:{title:"Configuration Issue",message:"There seems to be a configuration problem. Our team has been notified and is working on it.",icon:'<svg class="w-8 h-8 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>\n </svg>'},permission:{title:"Access Denied",message:"You don't have permission to access this component. Please contact support if you believe this is an error.",icon:'<svg class="w-8 h-8 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>\n </svg>'},timeout:{title:"Request Timeout",message:"The request took too long to complete. Please try again or contact support if the problem persists.",icon:'<svg class="w-8 h-8 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>\n </svg>'},generic:{title:"Unexpected Error",message:"An unexpected error occurred. Please try refreshing the page or contact support for assistance.",icon:'<svg class="w-8 h-8 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>\n </svg>'}};return t[e]||t.generic}static generateInlineError(e,t=!0){return`\n <div class="inline-error-module bg-red-50 border border-red-200 rounded-lg p-4 text-center">\n <div class="flex items-center justify-center mb-3">\n <svg class="w-6 h-6 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>\n </svg>\n </div>\n <p class="text-sm text-red-700 mb-3">${e}</p>\n ${t?'\n <button\n onclick="window.location.reload()"\n class="inline-flex items-center px-3 py-1.5 border border-red-300 text-xs font-medium rounded text-red-700 bg-white hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"\n >\n <svg class="w-3 h-3 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>\n </svg>\n Retry\n </button>\n ':""}\n </div>\n `}}o.errorLog=[],o.maxLogSize=100,o.errorPatterns={network:/network|fetch|connection|offline|dns/i,timeout:/timeout|timedout|abort|cancelled/i,auth:/unauthorized|401|403|forbidden|permission|auth/i,validation:/validation|invali
1d|required|format|type error/i,notFound:/not found|404|missing|does not exist/i,serverError:/500|502|503|504|server error|internal server/i,rateLimit:/rate limit|429|too many requests/i,config:/config|initialization|setup|missing parameter/i};class i{static generateErrorModule(e){return o.generateErrorModule(e)}static getErrorConfig(e){return o.getErrorUIConfig(e)}static generateInlineError(e,t){return o.generateInlineError(e,t)}static logError(e,t,n){return o.log(e,t,n)}}"undefined"!=typeof window&&(window.ErrorHandler=o,window.ErrorModuleUtils=i),t.Ay=o},1175:function(e,t,n){"use strict";n.d(t,{U:function(){return o}});class o{static getCardBrandDisplay(e){return e&&this.BRAND_DISPLAY_MAP[e.toLowerCase()]||"Card"}static getCardBackgroundClass(e){return e&&this.BRAND_BACKGROUND_MAP[e.toLowerCase()]||this.BRAND_BACKGROUND_MAP.card}static formatCardDisplay(e,t){return`${this.getCardBrandDisplay(t)} â¢â¢â¢â¢ ${e}`}static getCardBrandShort(e){return e&&(this.BRAND_SHORT_MAP[e.toLowerCase()]||e)||"Card"}static getCardDisplayInfo(e,t){return{brand:t?.toLowerCase()||"card",displayName:this.getCardBrandDisplay(t),shortName:this.getCardBrandShort(t),backgroundClass:this.getCardBackgroundClass(t),formattedDisplay:this.formatCardDisplay(e,t)}}static isValidCardBrand(e){return Object.prototype.hasOwnProperty.call(this.BRAND_DISPLAY_MAP,e.toLowerCase())}static getSupportedBrands(){return Object.keys(this.BRAND_DISPLAY_MAP)}static formatPriceInterval(e,t=1){if(!e)return"";if(!("month"===e||"year"===e||"week"===e||"day"===e))return"";if(1===t)return`/ ${e}`;return`/ ${t} ${"day"===e?"days":`${e}s`}`}}o.BRAND_DISPLAY_MAP={visa:"Visa",mastercard:"Mastercard",amex:"American Express",discover:"Discover",card:"Card"},o.BRAND_BACKGROUND_MAP={visa:"bg-gradient-to-br from-blue-600 to-blue-700",mastercard:"bg-gradient-to-br from-red-500 to-yellow-500",amex:"bg-gradient-to-br from-green-600 to-green-700",discover:"bg-gradient-to-br from-orange-500 to-orange-600",card:"bg-gradient-to-br from-gray-600 to-gray-700"},o.BRAND_SHORT_MAP={visa:"Visa",mastercard:"MC",amex:"Amex",discover:"Disc",card:"Card",american_express:"Amex"}},7235:function(e,t,n){"use strict";n.d(t,{MR:function(){return r},bW:function(){return u},c:function(){return s}});const o={element:"undefined"!=typeof window?window:void 0,bubbles:!0,cancelable:!0,useNamespace:!0,namespace:"heimguard"},i={element:"undefined"!=typeof window?window:void 0,useCapture:!1,useNamespace:!0,namespace:"heimguard"};function a(e,t={}){const{useNamespace:n=!0,namespace:o="heimguard"}=t;return n?`${o}:${e}`:e}function s(e,t={},n={}){const i={...o,...n},s=a(e,i),r={timestamp:Date.now(),...t};if(i.element){const e=new CustomEvent(s,{detail:r,bubbles:i.bubbles,cancelable:i.cancelable});i.element.dispatchEvent(e)}}function r(e,t,n={}){const o={...i,...n},s=a(e,o);if(o.element){const e=e=>{t(e.detail)};return o.element.addEventListener(s,e,o.useCapture),()=>{o.element.removeEventListener(s,e,o.useCapture)}}return()=>{}}function d(e,t,n={}){let o=null;return o=r(e,(e=>{o&&o(),t(e)}),n),o}function l(e,t,n={}){const o={...i,...n},s=a(e,o);o.element&&o.element.removeEventListener(s,t,o.useCapture)}function c(e,t=5e3,n={}){return new Promise(((o,i)=>{let a=null,s=null;t>0&&(s=setTimeout((()=>{a&&a(),i(new Error(`Timeout waiting for event: ${e}`))}),t)),a=r(e,(e=>{s&&clearTimeout(s),a&&a(),o(e)}),n)}))}function u(e,t,n){const o=Object.entries(t).reduce(((t,[n,o])=>(t[n]=`${e}:${o}`,t)),{});return{events:o,emit(e,t){s(o[e],t,n)},on(e,t,i){return r(o[e],t,{...n,...i})},once(e,t,i){return d(o[e],t,{...n,...i})},off(e,t,i){l(o[e],t,{...n,...i})},wait(e,t,i){return c(o[e],t,{...n,...i})}}}},2972:function(e,t,n){"use strict";n.d(t,{c:function(){return o}});class o{static createCookie(e,t,n,o){let i,a="",s="";i=n?new Date(parseInt(n.toString())):new Date(19249236e5),a="; expires="+i.toUTCString(),o&&(s=`;domain=${o}`),document.cookie=e+"="+t+a+s+"; path=/"}static setCookie(e,t,n={}){const{expires:o,domain:i,path:a="/",secure:s=!1,httpOnly:r=!1,sameSite:d="lax"}=n;let l=`${e}=${t}; path=${a}`;if(o){l+=`; expires=${("number"==typeof o?new Date(o):o).toUTCString()}`}i&&(l+=`; domain=${i}`),s&&(l+="; secure"),r&&(l+="; httponly"),d&&(l+=`; samesite=${d}`),document.cookie=l}static hasCookie(e){return null!=this.getCookie(e)}static getCookie(e){const t=document.cookie.match(new RegExp("(^| )"+e+"=([^;]+)"));return t?t[2]:null}static getAllCookies(){const e={};return document.cookie&&document.cookie.split(";").forEach((t=>{const[n,o]=t.trim().split("=");n&&o&&(e[n]=o)})),e}
1static eraseCookie(e,t){this.createCookie(e,"",3155508e5,t)}static removeCookie(e,t={}){const{domain:n,path:o="/"}=t;let i=`${e}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${o}`;n&&(i+=`; domain=${n}`),document.cookie=i}static clearAll(e){const t=this.getAllCookies();Object.keys(t).forEach((t=>{this.removeCookie(t,{domain:e})}))}static daysInUTC(e){const t=new Date;return t.setDate(t.getDate()+parseInt(e.toString()))}static daysFromNow(e){return Date.now()+24*e*60*60*1e3}static isEnabled(){try{const e="__cookie_test__";this.setCookie(e,"test");const t=this.hasCookie(e);return this.removeCookie(e),t}catch{return!1}}static getCookieSize(e){const t=this.getCookie(e);return t?new Blob([t]).size:0}static getTotalCookieSize(){const e=this.getAllCookies();let t=0;return Object.entries(e).forEach((([e,n])=>{t+=new Blob([`${e}=${n}`]).size})),t}static wouldExceedLimit(e,t,n=4096){const o=new Blob([`${e}=${t}`]).size;return this.getTotalCookieSize()+o>n}}},8689:function(e,t,n){"use strict";n.d(t,{Nq:function(){return o},Yq:function(){return i},fU:function(){return a}});class o{static get defaultLocale(){return this._defaultLocale||"en-US"}static set defaultLocale(e){this._defaultLocale=e}static get defaultTimezone(){return this._defaultTimezone||Intl.DateTimeFormat().resolvedOptions().timeZone}static set defaultTimezone(e){this._defaultTimezone=e}static parse(e){if(!e)return null;if(e instanceof Date)return isNaN(e.getTime())?null:e;if("number"==typeof e)return new Date(e);if("string"==typeof e){const t=new Date(e);return isNaN(t.getTime())?null:t}return null}static format(e,t="medium",n){n||(n=this.defaultLocale||"en-US");const o=this.parse(e);if(!o)return"";if("string"==typeof t&&("ISO"===t||"iso"===t))return o.toISOString();if("string"==typeof t&&"datetime"===t)return this.formatDateTime(o,"medium","short",n);const i="string"==typeof t?{short:{month:"numeric",day:"numeric",year:"2-digit"},medium:{month:"short",day:"numeric",year:"numeric"},long:{month:"long",day:"numeric",year:"numeric"},full:{weekday:"long",month:"long",day:"numeric",year:"numeric"},monthYear:{month:"long",year:"numeric"},dayMonth:{month:"short",day:"numeric"},iso:"ISO",time:{hour:"numeric",minute:"2-digit"},datetime:"datetime"}[t]:t;return i&&"string"!=typeof i?new Intl.DateTimeFormat(n,i).format(o):o.toString()}static formatDateTime(e,t="medium",n="short",o=this.defaultLocale){const i=this.parse(e);if(!i)return"";return`${this.format(i,t,o)} at ${this.formatTime(i,n,o)}`}static formatTime(e,t="short",n=this.defaultLocale){const o=this.parse(e);if(!o)return"";const i={short:{hour:"numeric",minute:"2-digit"},medium:{hour:"numeric",minute:"2-digit",second:"2-digit"},long:{hour:"numeric",minute:"2-digit",second:"2-digit",timeZoneName:"short"}},a=i[t]||i.short;return new Intl.DateTimeFormat(n,a).format(o)}static formatRelative(e,t=this.defaultLocale,n=new Date){const o=this.parse(e);if(!o)return"";const i=o.getTime()-n.getTime();if(Math.abs(i)<6e4)return"just now";const a=[{unit:"year",ms:31536e6},{unit:"month",ms:2592e6},{unit:"week",ms:6048e5},{unit:"day",ms:864e5},{unit:"hour",ms:36e5},{unit:"minute",ms:6e4}],s=new Intl.RelativeTimeFormat(t,{numeric:"auto"});for(const{unit:e,ms:t}of a){const n=Math.round(i/t);if(Math.abs(n)>=1)return s.format(n,e)}return"just now"}static formatSubscriptionDate(e,t={}){const n=this.parse(e);if(!n)return{display:"N/A",relative:null,isUpcoming:!1,daysUntil:null};const o=this.getDaysUntil(n),i=this.format(n,"long");let a="";return null!==o&&(o<0?a="Overdue":0===o?a="Today":1===o?a="Tomorrow":o<=7?a=`In ${o} days`:o<=30&&(a=`In ${Math.round(o/7)} weeks`)),{display:i,relative:a,isUpcoming:null!==o&&o>=0&&o<=7,isPastDue:null!==o&&o<0,daysUntil:o,date:n}}static formatRelativeDate(e){const t=this.parse(e);if(!t)return"N/A";const n=this.getDaysUntil(t);if(null===n)return"N/A";if(n<0)return`${Math.abs(n)} days ago`;if(0===n)return"Today";if(1===n)return"Tomorrow";if(n<=7)return`in ${n} days`;if(n<=30){const e=Math.round(n/7);return`in ${e} ${1===e?"week":"weeks"}`}{const e=Math.round(n/30);return`in ${e} ${1===e?"month":"months"}`}}static getDaysBetween(e,t=new Date){const n=this.parse(e),o=this.parse(t);if(!n||!o)return null;const i=n.getTime()-o.getTime();return Math.floor(i/864e5)}static getDaysUntil(e){return this.getDaysBetween(e,new Date)}static getNextBillingDate(e={}){const{startDate:t=new Date,interval:n="month",intervalCount:o=1,trialDays:i=0}=e,a=this.parse(t)||new Date;if(i>0)return a.setDate(a.getDate()+i),a;switch(n){case"day":a.setDate(a.getDate()+o);break;case"week":a.setDate(a.getDate()+7*o);break;case"month":default:a.setMonth(a.getMonth()+o);break;case"year":a.setFullYear(a.getFullYear()+o)}return a}static add(e,t,n="days"){const o=this.parse(e);if(!o)return null;const i=new Date(o);switch(n){case"seconds":i.setSeconds(i.getSeconds()+t);break;case"minutes":i.setMinutes(i.getMinutes()+t);break;case"hours":i.setHours(i.getHours()+t);break;case"days":i.setDate(i.getDate()+t);break;case"weeks":i.setDate(i.getDate()+7*t);break;case"months":i.setMonth(i.getMonth()+t);break;case"years":i.setFullYear(i.getFullYear()+t)}return i}static isPast(e){const t=this.parse(e);return!!t&&t<new Date}static isFuture(e){const t=this.parse(e);return!!t&&t>new Date}static isToday(e){const t=this.parse(e);if(!t)return!1;const n=new Date;return t.toDateString()===n.toDateString()}
1static isBetween(e,t,n){const o=this.parse(e),i=this.parse(t),a=this.parse(n);return!!(o&&i&&a)&&(o>=i&&o<=a)}static startOf(e,t="day"){const n=this.parse(e);if(!n)return null;const o=new Date(n);switch(t){case"day":o.setHours(0,0,0,0);break;case"week":o.setDate(o.getDate()-o.getDay()),o.setHours(0,0,0,0);break;case"month":o.setDate(1),o.setHours(0,0,0,0);break;case"year":o.setMonth(0,1),o.setHours(0,0,0,0)}return o}static endOf(e,t="day"){const n=this.parse(e);if(!n)return null;const o=new Date(n);switch(t){case"day":o.setHours(23,59,59,999);break;case"week":o.setDate(o.getDate()+(6-o.getDay())),o.setHours(23,59,59,999);break;case"month":o.setMonth(o.getMonth()+1,0),o.setHours(23,59,59,999);break;case"year":o.setMonth(11,31),o.setHours(23,59,59,999)}return o}static formatDuration(e,t={}){if(!e||e<0)return"0s";const{units:n=["d","h","m","s"],separator:o=" ",verbose:i=!1}=t,a={d:{ms:864e5,verbose:"day"},h:{ms:36e5,verbose:"hour"},m:{ms:6e4,verbose:"minute"},s:{ms:1e3,verbose:"second"},ms:{ms:1,verbose:"millisecond"}},s=[];let r=e;for(const e of n){const{ms:t,verbose:n}=a[e],o=Math.floor(r/t);if(o>0){if(i){const e=1===o?n:`${n}s`;s.push(`${o} ${e}`)}else s.push(`${o}${e}`);r-=o*t}}return s.join(o)||"0s"}static getAge(e){const t=this.parse(e);if(!t)return null;const n=new Date;let o=n.getFullYear()-t.getFullYear();const i=n.getMonth()-t.getMonth();return(i<0||0===i&&n.getDate()<t.getDate())&&o--,o}}const i=(...e)=>o.format(...e),a=(...e)=>o.formatTime(...e)},3482:function(e,t,n){"use strict";n.d(t,{Df:function(){return a},FR:function(){return d},HE:function(){return o},Hs:function(){return r},N4:function(){return u},YR:function(){return s},i$:function(){return i},pN:function(){return l},t0:function(){return c}});const o={LOGIN_START:"login:start",LOGIN_SUCCESS:"login:success",LOGIN_ERROR:"login:error",LOGOUT_START:"logout:start",LOGOUT_SUCCESS:"logout:success",LOGOUT_ERROR:"logout:error",REGISTER_START:"register:start",REGISTER_SUCCESS:"register:success",REGISTER_ERROR:"register:error",SESSION_CHECK:"session:check",SESSION_VALID:"session:valid",SESSION_INVALID:"session:invalid",SESSION_EXPIRED:"session:expired",STATE_CHANGED:"state:changed",SOCIAL_LOGIN:"social:login",SOCIAL_LINK:"social:link",SOCIAL_UNLINK:"social:unlink"},i={LOADED:"loaded",UPDATED:"updated",ERROR:"error",SECTION_CHANGE:"section:change",STATS_UPDATED:"stats:updated",COMPONENT_READY:"component:ready",COMPONENT_ERROR:"component:error"},a={METHOD_ADDED:"method:added",METHOD_UPDATED:"method:updated",METHOD_REMOVED:"method:removed",METHOD_DEFAULT:"method:default",PROCESS_START:"process:start",PROCESS_SUCCESS:"process:success",PROCESS_ERROR:"process:error"},s={CREATED:"created",UPDATED:"updated",CANCELLED:"cancelled",REACTIVATED:"reactivated",EXPIRED:"expired"},r={VALIDATE:"validate",SUBMIT:"submit",SUCCESS:"success",ERROR:"error"},d={ROUTE_CHANGED:"route:changed",TAB_CHANGED:"tab:changed",SECTION_CHANGED:"section:changed"},l={CLICK:"click",FOCUS:"focus",BLUR:"blur",MODAL_OPEN:"modal:open",MODAL_CLOSE:"modal:close",MODAL_SUBMIT:"modal:submit",ALERT_SHOW:"alert:show",ALERT_HIDE:"alert:hide"},c={GLOBAL:"global",NETWORK:"network",VALIDATION:"validation",UNAUTHORIZED:"unauthorized",SERVER:"server"}
1,u={LOAD:"load",CREATE:"create",UPDATE:"update",DELETE:"delete"}},6534:function(e,t,n){"use strict";n.d(t,{b:function(){return i}});var o=n(1916);class i{constructor(e={}){this.listeners=new Map,this.config={namespace:e.namespace||"heimguard",debug:e.debug||!1,maxListeners:e.maxListeners||100}}emit(e,t){const n=`${this.config.namespace}:${e}`,i=new CustomEvent(n,{detail:t,bubbles:!0,cancelable:!0});document.dispatchEvent(i);const a=this.listeners.get(e);a&&a.forEach((n=>{try{n(t)}catch(t){o.vF.error(`Error in event handler for ${e}:`,"general",t)}})),this.config.debug&&o.vF.debug(`[${this.config.namespace}] ${e}`,"general",t)}on(e,t,n){const i=this.listeners.get(e)||new Set;i.size>=this.config.maxListeners&&o.vF.warn(`Max listeners (${this.config.maxListeners}) reached for event "${e}". This might indicate a memory leak.`,"general"),i.add(t),this.listeners.set(e,i);const a=`${this.config.namespace}:${e}`,s=e=>{t(e.detail)},r=n?.element||document,d=n?.capture||!1;return r.addEventListener(a,s,d),()=>{i.delete(t),0===i.size&&this.listeners.delete(e),r.removeEventListener(a,s,d)}}once(e,t,n){const o=this.on(e,(e=>{o(),t(e)}),n);return o}off(e,t){const n=this.listeners.get(e);n&&(n.delete(t),0===n.size&&this.listeners.delete(e))}removeAllListeners(e){e?this.listeners.delete(e):this.listeners.clear()}waitFor(e,t=5e3){return new Promise(((n,o)=>{let i=null;const a=this.once(e,(e=>{i&&clearTimeout(i),n(e)}));t>0&&(i=setTimeout((()=>{a(),o(new Error(`Timeout waiting for event: ${e}`))}),t))}))}batchEmit(e){e.forEach((({event:e,data:t})=>{this.emit(e,t)}))}createHandlers(){const e=[];return{on:(t,n,o)=>{const i=this.on(t,n,o);return e.push(i),i},once:(t,n,o)=>{const i=this.once(t,n,o);return e.push(i),i},emit:(e,t)=>{this.emit(e,t)},cleanup:()=>{e.forEach((e=>e())),e.length=0}}}listenerCount(e){if(e)return this.listeners.get(e)?.size||0;let t=0;return this.listeners.forEach((e=>{t+=e.size})),t}eventNames(){return Array.from(this.listeners.keys())}}},8215:function(e,t,n){"use strict";n.d(t,{AC:function(){return c},nU:function(){return s},sV:function(){return v}});var o=n(7235),i=n(3482);const a=(0,o.bW)("auth",i.HE),s=(0,o.bW)("profile",i.i$),r=(0,o.bW)("payment",i.Df),d=(0,o.bW)("subscription",i.YR),l=(0,o.bW)("form",i.Hs),c=(0,o.bW)("nav",i.FR),u=(0,o.bW)("ui",i.pN),m=(0,o.bW)("error",i.t0),g=(0,o.bW)("data",i.N4);const h={onLogin:e=>a.on("LOGIN_SUCCESS",e),onLogout:e=>a.on("LOGOUT_SUCCESS",e),onStateChange:e=>a.on("STATE_CHANGED",e),onSessionExpired:e=>a.on("SESSION_EXPIRED",e),emitLogin:e=>a.emit("LOGIN_SUCCESS",e),emitLogout:e=>a.emit("LOGOUT_SUCCESS",e),emitStateChange:e=>a.emit("STATE_CHANGED",e)},p={onLoaded:e=>s.on("LOADED",e),onUpdated:e=>s.on("UPDATED",e),onStatsUpdated:e=>s.on("STATS_UPDATED",e),emitLoaded:e=>s.emit("LOADED",e),emitUpdated:e=>s.emit("UPDATED",e),emitStatsUpdated:e=>s.emit("STATS_UPDATED",e)},y={onMethodAdded:e=>r.on("METHOD_ADDED",e),onMethodRemoved:e=>r.on("METHOD_REMOVED",e),onProcessSuccess:e=>r.on("PROCESS_SUCCESS",e),onProcessError:e=>r.on("PROCESS_ERROR",e),emitMethodAdded:e=>r.emit("METHOD_ADDED",e),emitMethodRemoved:e=>r.emit("METHOD_REMOVED",e),emitProcessSuccess:e=>r.emit("PROCESS_SUCCESS",e),emitProcessError:e=>r.emit("PROCESS_ERROR",e)},C={onModalOpen:e=>u.on("MODAL_OPEN",e),onModalClose:e=>u.on("MODAL_CLOSE",e),onAlertShow:e=>u.on("ALERT_SHOW",e),emitModalOpen:e=>u.emit("MODAL_OPEN",e),emitModalClose:e=>u.emit("MODAL_CLOSE",e),emitAlertShow:e=>u.emit("ALERT_SHOW",e)},f={onGlobalError:e=>m.on("GLOBAL",e),onNetworkError:e=>m.on("NETWORK",e),onUnauthorized:e=>m.on("UNAUTHORIZED",e),emitGlobalError:e=>m.emit("GLOBAL",e),emitNetworkError:e=>m.emit("NETWORK",e),emitUnauthorized:e=>m.emit("UNAUTHORIZED",e)},v={Auth:a,Profile:s,Payment:r,Subscription:d,Form:l,Navigation:c,UI:u,Error:m,Data:g,auth:h,profile:p,payment:y,ui:C,errors:f,emit:function(e,t){(function(e){return t=>{const[n,...o]=e.split(":"),i=o.join(":");switch(n){case"auth":a.emit(i,t);break;case"profile":s.emit(i,t);break;case"payment":r.emit(i,t);break;case"subscription":d.emit(i,t);break;case"form":l.emit(i,t);break;case"nav":c.emit(i,t);break;case"ui":u.emit(i,t);break;case"error":m.emit(i,t);break;case"data":g.emit(i,t);break;default:console.warn(`Unknown event category: ${n}`)}}})(e)(t)},on:function(e,t){return function(e){return t=>{const[n,...o]=e.split(":"),i=o.join(":");switch(n){case"auth":return a.on(i,t);case"profile":return s.on(i,t);case"payment":return r.on(i,t);case"subscription":return d.on(i,t);case"form":return l.on(i,t);case"nav":return c.on(i,t);case"ui":return u.on(i,t);case"error":return m.on(i,t);case"data":return g.on(i,t);default:return console.warn(`Unknown event category: ${n}
1`),()=>{}}}}(e)(t)},once:function(e,t){const[n,...o]=e.split(":"),i=o.join(":");switch(n){case"auth":return a.once(i,t);case"profile":return s.once(i,t);case"payment":return r.once(i,t);case"subscription":return d.once(i,t);case"form":return l.once(i,t);case"nav":return c.once(i,t);case"ui":return u.once(i,t);case"error":return m.once(i,t);case"data":return g.once(i,t);default:return console.warn(`Unknown event category: ${n}`),()=>{}}},wait:function(e,t){const[n,...o]=e.split(":"),i=o.join(":");switch(n){case"auth":return a.wait(i,t);case"profile":return s.wait(i,t);case"payment":return r.wait(i,t);case"subscription":return d.wait(i,t);case"form":return l.wait(i,t);case"nav":return c.wait(i,t);case"ui":return u.wait(i,t);case"error":return m.wait(i,t);case"data":return g.wait(i,t);default:return console.warn(`Unknown event category: ${n}`),Promise.reject(new Error(`Unknown event category: ${n}`))}}}},8354:function(e,t,n){"use strict";n.d(t,{AC:function(){return i.AC},MR:function(){return o.MR},ProfileEvents:function(){return i.nU},c:function(){return o.c},sV:function(){return i.sV}});n(6534);var o=n(7235),i=(n(3482),n(8215))},9088:function(e,t,n){"use strict";class o{constructor(e={},t={}){this.state=this.deepClone(e),this.prevState=this.deepClone(e),this.subscribers=new Map,this.middleware=[],this.history=[],this.options={maxHistory:10,enableLogging:!1,enableDevTools:!0,...t},this.isUpdating=!1,this.updateQueue=[],this.options.enableDevTools&&"undefined"!=typeof window&&this.setupDevTools()}getState(e){return e?this.getNestedValue(this.state,e):this.deepClone(this.state)}setState(e,t){if(this.isUpdating)this.updateQueue.push({pathOrUpdates:e,value:t});else{this.isUpdating=!0;try{this.prevState=this.deepClone(this.state),"string"==typeof e?this.setNestedValue(this.state,e,t):this.state=this.deepMerge(this.state,e),this.runMiddleware(),this.addToHistory(),this.notifySubscribers(),this.options.enableLogging&&this.logUpdate(e,t)}finally{if(this.isUpdating=!1,this.updateQueue.length>0){const e=this.updateQueue.shift();this.setState(e.pathOrUpdates,e.value)}}}}subscribe(e,t={}){const n=Symbol("subscriber");if(this.subscribers.set(n,{callback:e,paths:t.paths||[],selector:t.selector,immediate:!1!==t.immediate}),!1!==t.immediate){e(t.selector?t.selector(this.state):this.state,void 0,[])}return()=>{this.subscribers.delete(n)}}use(e){return this.middleware.push(e),()=>{const t=this.middleware.indexOf(e);t>-1&&this.middleware.splice(t,1)}}notifySubscribers(){const e=this.getChanges();this.subscribers.forEach((({callback:t,paths:n,selector:o})=>{if(n.length>0){if(!e.some((e=>n.some((t=>e.startsWith(t)||t.startsWith(e))))))return}const i=o?o(this.state):this.state,a=o?o(this.prevState):this.prevState;if(!this.deepEqual(i,a))try{t(i,a,e)}catch(e){console.error("Error in state subscriber:",e)}}))}getChanges(){const e=[],t=(n,o,i="")=>{if(this.deepEqual(n,o))return;if("object"!=typeof n||null===n||"object"!=typeof o||null===o)return void e.push(i);new Set([...Object.keys(n),...Object.keys(o)]).forEach((e=>{const a=i?`${i}.${e}`:e;t(n[e],o[e],a)}))};return t(this.state,this.prevState),e}runMiddleware(){this.middleware.forEach((e=>{try{e(this.state,this.prevState,this)}catch(e){console.error("Error in state middleware:",e)}}))}addToHistory(){this.history.push({state:this.deepClone(this.state),timestamp:Date.now()}),this.history.length>this.options.maxHistory&&this.history.shift()}reset(){this.setState(this.history[0]?.state||{})}undo(e=1){const t=Math.max(0,this.history.length-1-e);this.history[t]&&this.setState(this.history[t].state)}derive(e,t){const n=new o(e(this.state),{...this.options,enableDevTools:!1});return this.subscribe((t=>{const o=e(t);n.setState(o)})),t&&n.subscribe((e=>{t(this,e)})),n}batch(e){const t=this.isUpdating;this.isUpdating=!0;try{e(this)}finally{if(!t&&(this.isUpdating=!1,this.updateQueue.length>0)){const e=this.updateQueue.splice(0).reduce(((e,{pathOrUpdates:t,value:n})=>("string"==typeof t?this.setNestedValue(e,t,n):Object.assign(e,t),e)),{});this.setState(e)}}}setupDevTools(){"undefined"!=typeof window&&window.__REDUX_DEVTOOLS_EXTENSION__&&(this.devTools=window.__REDUX_DEVTOOLS_EXTENSION__.connect({
1name:"HeimGuard StateStore",features:{pause:!0,lock:!0,persist:!0,export:!0,import:"custom",jump:!0,skip:!0,reorder:!0,dispatch:!0,test:!0}}),this.devTools.init(this.state),this.devTools.subscribe((e=>{"DISPATCH"===e.type&&e.state&&this.setState(JSON.parse(e.state))})))}logUpdate(e,t){console.group("ð State Update"),console.log("Previous:",this.prevState),console.log("Updates:","string"==typeof e?{[e]:t}:e),console.log("Current:",this.state),console.log("Changes:",this.getChanges()),console.groupEnd(),this.devTools&&this.devTools.send("string"==typeof e?`SET ${e}`:"SET_STATE",this.state)}deepClone(e){return null===e||"object"!=typeof e?e:e instanceof Date?new Date(e.getTime()):e instanceof Array?e.map((e=>this.deepClone(e))):e instanceof Object?Object.keys(e).reduce(((t,n)=>(t[n]=this.deepClone(e[n]),t)),{}):e}deepEqual(e,t){if(e===t)return!0;if(null==e||null==t)return!1;if(typeof e!=typeof t)return!1;if("object"!=typeof e)return e===t;const n=Object.keys(e),o=Object.keys(t);return n.length===o.length&&n.every((n=>this.deepEqual(e[n],t[n])))}deepMerge(e,t){const n={...e};return Object.keys(t).forEach((o=>{t[o]&&"object"==typeof t[o]&&!Array.isArray(t[o])&&e[o]&&"object"==typeof e[o]&&!Array.isArray(e[o])?n[o]=this.deepMerge(e[o],t[o]):n[o]=t[o]})),n}getNestedValue(e,t){return t.split(".").reduce(((e,t)=>e?.[t]),e)}setNestedValue(e,t,n){const o=t.split("."),i=o.pop();o.reduce(((e,t)=>(e[t]||(e[t]={}),e[t])),e)[i]=n}}new o({},{enableLogging:!1,enableDevTools:!1});t.A=o},5762:function(e,t,n){"use strict";n.r(t),n.d(t,{AlertUtils:function(){return i}});var o=n(7411);class i{static show(e={}){const t={...this.defaultConfig,...e,id:e.id||`alert-${Date.now()}`};if(this.activeAlerts.size>=(t.maxAlerts||3)){const e=this.activeAlerts.keys().next().value;this.hide(e)}const n=this.createAlertElement(t);if(this.getContainer(t.position||"top-right").appendChild(n),this.activeAlerts.set(t.id,{element:n,config:t,timeout:null}),requestAnimationFrame((()=>{n.classList.add("show")})),t.duration&&t.duration>0){const e=this.activeAlerts.get(t.id);e&&(e.timeout=window.setTimeout((()=>{this.hide(t.id)}),t.duration))}return t.id}static hide(e){const t=this.activeAlerts.get(e);t&&(t.timeout&&clearTimeout(t.timeout),t.element.classList.remove("show"),t.element.classList.add("hide"),setTimeout((()=>{t.element.parentNode&&t.element.remove(),this.activeAlerts.delete(e)}),300))}static hideAll(){for(const e of this.activeAlerts.keys())this.hide(e)}static createAlertElement(e){const{id:t,type:n="info",title:i,message:a,icon:s,dismissible:r,actions:d=[]}=e,l=this.getTypeConfig(n),c=document.createElement("div");c.id=t,c.className=`\n alert flex items-start p-4 rounded-lg shadow-lg mb-4\n ${l.classes}\n transform transition-all duration-300 ease-in-out\n opacity-0 translate-y-2\n `.trim(),c.setAttribute("role","alert");const u=s||l.icon,m=u?`\n <div class="flex-shrink-0">\n ${u}\n </div>\n `:"",g=`\n <div class="ml-3 flex-1">\n ${i?`<p class="text-sm font-medium ${l.titleClass}">${i}</p>`:""}\n ${a?`<p class="text-sm ${i?"mt-1":""} ${l.textClass}">${a}</p>`:""}\n ${d.length>0?this.createActions(d,l):""}\n </div>\n `,h=r?`\n <button\n type="button"\n class="ml-3 inline-flex -m-1.5 p-1.5 rounded-lg focus:outline-none focus:ring-2 ${l.dismissClass}"\n onclick="AlertUtils.hide('${t}')"\n >\n <span class="sr-only">Dismiss</span>\n ${o.H.render("x",{class:"w-5 h-5"})}\n </button>\n `:"";return c.innerHTML=m+g+h,c}static createActions(e,t){return`<div class="mt-3 flex space-x-4">${e.map((e=>`\n <button\n type="button"\n class="text-sm font-medium ${e.class||t.actionClass} hover:underline focus:outline-none"\n onclick="${e.onClick}"\n >\n ${e.label}\n </button>\n `)).join("")}</div>`}static getContainer(e){const t=`alert-container-${e}`;let n=document.getElementById(t);return n||(n=document.createElement("div"),n.id=t,n.className=`\n fixed z-50 pointer-events-none\n ${this.getPositionClasses(e)}\n `.trim(),n.style.cssText="\n min-width: 320px;\n max-width: 500px;\n ",document.body.appendChild(n)),n.querySelectorAll(".alert").forEach((e=>{e.style.pointerEvents="auto"})),n}static getPositionClasses(e){const t={"top-left":"top-4 left-4","top-center":"top-4 left-1/2 transform -translate-x-1/2","top-right":"top-4 right-4","bottom-left":"bottom-4 left-4","bottom-center":"bottom-4 left-1/2 transform -translate-x-1/2","bottom-right":"bottom-4 right-4",center:"top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"};return t[e]||t["top-right"]}static getTypeConfig(e){const t={success:{classes:"bg-green-50 border border-green-200",titleClass:"text-green-800",textClass:"text-green-700",dismissClass:"text-green-500 hover:bg-green-100 focus:ring-green-600",actionClass:"text-green-700",icon:o.H.render("check-circle",{class:"w-5 h-5 text-green-400"})},error:{classes:"bg-red-50 border border-red-200",titleClass:"text-red-800",textClass:"text-red-700",dismissClass:"text-red-500 hover:bg-red-100 focus:ring-red-600",actionClass:"text-red-700",icon:o.H.render("x-circle",{class:"w-5 h-5 text-red-400"})},warning:{classes:"bg-yellow-50 border border-yellow-200",titleClass:"text-yellow-800",textClass:"text-yellow-700",dismissClass:"text-yellow-500 hover:bg-yellow-100 focus:ring-yellow-600",actionClass:"text-yellow-700",icon:o.H.render("alert-triangle",{class:"w-5 h-5 text-yellow-400"})},info:{classes:"bg-blue-50 border border-blue-200",titleClass:"text-blue-800",textClass:"text-blue-700",dismissClass:"text-blue-500 hover:bg-blue-100 focus:ring-blue-600",actionClass:"text-blue-700",icon:o.H.render("info",{class:"w-5 h-5 text-blue-400"})}};return t[e]||t.info}static success(e,t={}){return this.show({...t,type:"success",message:e})}
1static error(e,t={}){return this.show({...t,type:"error",message:e})}static warning(e,t={}){return this.show({...t,type:"warning",message:e})}static info(e,t={}){return this.show({...t,type:"info",message:e})}static async confirm(e={}){return new Promise((t=>{const n={title:"Confirm Action",message:"Are you sure you want to continue?",confirmText:"Confirm",cancelText:"Cancel",type:"warning",...e};this.show({...n,type:n.type,dismissible:!1,duration:0,actions:[{label:n.cancelText,onClick:`(() => { AlertUtils.hide('${Date.now()}'); window.alertResolve(false); })()`,class:"text-gray-700 hover:text-gray-900"},{label:n.confirmText,onClick:`(() => { AlertUtils.hide('${Date.now()}'); window.alertResolve(true); })()`}]});window.alertResolve=e=>{delete window.alertResolve,t(e)}}))}static showAlert(e,t,n="error",o={}){let i=null;if(i="string"==typeof e?document.querySelector(e):e,!i)return this.show({message:t,type:n,...o});const a=this.createAlertHTML(t,n,o);i.innerHTML=a,i.classList.remove("hidden"),o.duration&&setTimeout((()=>{i.innerHTML="",i.classList.add("hidden")}),o.duration)}static createAlertHTML(e,t="error",n={}){const i=this.getTypeConfig(t),a=!1!==n.dismissible;return`\n <div class="rounded-md ${i.classes} p-4">\n <div class="flex">\n <div class="flex-shrink-0">\n ${i.icon}\n </div>\n <div class="ml-3">\n <p class="text-sm font-medium ${i.textClass}">\n ${e}\n </p>\n </div>\n ${a?`\n <div class="ml-auto pl-3">\n <div class="-mx-1.5 -my-1.5">\n <button type="button" class="inline-flex rounded-md p-1.5 ${i.dismissClass}">\n <span class="sr-only">Dismiss</span>\n ${o.H.render("x",{class:"h-5 w-5"})}\n </button>\n </div>\n </div>\n `:""}\n </div>\n </div>\n `}}if(i.activeAlerts=new Map,i.defaultConfig={duration:5e3,dismissible:!0,position:"top-right",animation:"fade",maxAlerts:3},"undefined"!=typeof document){const e=document.createElement("style");e.textContent="\n .alert {\n pointer-events: auto;\n }\n .alert.show {\n opacity: 1;\n transform: translateY(0);\n }\n .alert.hide {\n opacity: 0;\n transform: translateY(-0.5rem);\n }\n @keyframes shake {\n 0%, 100% { transform: translateX(0); }\n 25% { transform: translateX(-5px); }\n 75% { transform: translateX(5px); }\n }\n .shake {\n animation: shake 0.5s ease-in-out;\n }\n ",document.head.appendChild(e)}"undefined"!=typeof window&&(window.AlertUtils=i),t.default=i},744:function(e,t,n){"use strict";n.d(t,{A:function(){return i}});var o=n(7411);class i{static setLoading(e,t=!0,n={}){const o="string"==typeof e?document.getElementById(e):e;if(!o)return null;const i=o.id||`btn-${Date.now()}`;o.id||(o.id=i);const a={loadingText:"Loading...",showSpinner:!0,disableButton:!0,preserveWidth:!0,...n};if(!this.originalStates.has(i)){const e=o.querySelector(".button-text")||o.querySelector("span")||o;this.originalStates.set(i,{text:e.textContent||"",disabled:o.disabled,className:o.className,width:o.offsetWidth,innerHTML:o.innerHTML})}const s=this.originalStates.get(i);if(t){if(a.preserveWidth&&(o.style.minWidth=`${s.width}px`),a.disableButton&&(o.disabled=!0,o.classList.add("opacity-75","cursor-not-allowed")),a.showSpinner){const e=this.createSpinner(),t=`<span class="button-text ml-2">${a.loadingText}</span>`;o.innerHTML=`<span class="inline-flex items-center">${e}${t}</span>`}else{const e=o.querySelector(".button-text")||o;e===o?o.textContent=a.loadingText||"":e.textContent=a.loadingText||""}o.classList.add("is-loading")}else this.reset(i);return{restore:()=>this.reset(i),setProgress:e=>this.setProgress(i,e),setError:e=>this.setError(i,e),setSuccess:e=>this.setSuccess(i,e)}}static setButtonLoadingState(e,t){if(!e)return;const n=e.querySelector(".spinner"),o=e.querySelector(".button-text");if(t)e.disabled=!0,e.classList.add("opacity-75","cursor-not-allowed"),n&&n.classList.remove("hidden"),o&&(o.textContent="Processing...");else if(e.disabled=!1,e.classList.remove("opacity-75","cursor-not-allowed"),n&&n.classList.add("hidden"),o){const t=e.closest(".register-component"),n=e.closest(".login-component"),i=e.closest(".forgot-password-component");o.textContent=t?"Create Account":n?"Sign In":i?"Send Reset Link":"Submit"}}static setButtonLoading(e,t){this.setButtonLoadingState(e,t)}static setSubmitting(e,t="Submitting..."){return this.setLoading(e,!0,{loadingText:t})}static setProgress(e,t){const n=document.getElementById(e);if(!n)return;(n.querySelector(".progress-bar")||this.createProgressBar(n)).style.width=`${Math.min(100,Math.max(0,t))}%`}static setSuccess(e,t="Success!",n=2e3){const i="string"==typeof e?document.getElementById(e):e;if(!i)return;const a=i.id||`btn-${Date.now()}`;
1i.id||(i.id=a),this.originalStates.has(a)||this.originalStates.set(a,{text:i.textContent||"",disabled:i.disabled,className:i.className,width:i.offsetWidth,innerHTML:i.innerHTML}),i.disabled=!0,i.classList.remove("bg-red-600","hover:bg-red-700","bg-primary-600","hover:bg-primary-700"),i.classList.add("bg-green-600","hover:bg-green-700");const s=o.H.render("check",{class:"w-5 h-5 inline-block mr-2"});i.innerHTML=s+t,n>0&&setTimeout((()=>{this.reset(a)}),n)}static setError(e,t="Error!",n=3e3){const i="string"==typeof e?document.getElementById(e):e;if(!i)return;const a=i.id||`btn-${Date.now()}`;i.id||(i.id=a),this.originalStates.has(a)||this.originalStates.set(a,{text:i.textContent||"",disabled:i.disabled,className:i.className,width:i.offsetWidth,innerHTML:i.innerHTML}),i.disabled=!1,i.classList.remove("bg-primary-600","hover:bg-primary-700","bg-green-600","hover:bg-green-700"),i.classList.add("bg-red-600","hover:bg-red-700","shake");const s=o.H.render("alert-circle",{class:"w-5 h-5 inline-block mr-2"});i.innerHTML=s+t,setTimeout((()=>{i.classList.remove("shake")}),500),n>0&&setTimeout((()=>{this.reset(a)}),n)}static reset(e){const t="string"==typeof e?document.getElementById(e):e;if(!t)return;const n=t.id,o=this.originalStates.get(n);if(!o)return;t.innerHTML=o.innerHTML,t.disabled=o.disabled,t.className=o.className,t.style.minWidth="",t.classList.remove("is-loading");const i=t.querySelector(".progress-bar");i&&i.remove(),this.originalStates.delete(n)}static setState(e,t,n={}){switch(t){case"loading":return this.setLoading(e,!0,n);case"success":return this.setSuccess(e,n.text,n.duration);case"error":return this.setError(e,n.text,n.duration);case"disabled":const t="string"==typeof e?document.getElementById(e):e;t&&(t.disabled=!1!==n.disabled);break;default:return this.reset(e)}}static createButton(e={}){const{id:t=`btn-${Date.now()}`,text:n="Submit",type:o="button",variant:i="primary",size:a="md",fullWidth:s=!1,icon:r=null,iconPosition:d="left",disabled:l=!1,loading:c=!1,className:u="",onClick:m=null,attributes:g={}}=e,h={primary:"bg-primary-600 hover:bg-primary-700 text-white focus:ring-primary-500",secondary:"bg-white hover:bg-gray-50 text-gray-700 border border-gray-300 focus:ring-primary-500",danger:"bg-red-600 hover:bg-red-700 text-white focus:ring-red-500",success:"bg-green-600 hover:bg-green-700 text-white focus:ring-green-500",warning:"bg-yellow-500 hover:bg-yellow-600 text-white focus:ring-yellow-500",ghost:"bg-transparent hover:bg-gray-100 text-gray-700 focus:ring-gray-500",link:"bg-transparent hover:underline text-primary-600 hover:text-primary-700 p-0"},p={xs:"py-1 px-2 text-xs",sm:"py-1.5 px-3 text-sm",md:"py-2 px-4 text-base",lg:"py-3 px-6 text-lg",xl:"py-3.5 px-8 text-xl"};return`\n <button\n id="${t}"\n type="${o}"\n class="${`\n inline-flex items-center justify-center\n font-medium rounded-md shadow-sm\n focus:outline-none focus:ring-2 focus:ring-offset-2\n transition-all duration-200\n disabled:opacity-50 disabled:cursor-not-allowed\n ${s?"w-full":""}\n ${h[i]||h.primary}\n ${p[a]||p.md}\n ${u}\n `.replace(/\s+/g," ").trim()}"\n ${l||c?"disabled":""}\n ${m?`onclick="${m}"`:""}\n ${Object.entries(g).map((([e,t])=>`${e}="${t}"`)).join(" ")}\n >\n ${c?this.createSpinner()+'<span class="button-text ml-2">Loading...</span>':`\n ${r&&"left"===d?`<span class="${n?"mr-2":""}">${r}</span>`:""}\n ${n?`<span class="button-text">${n}</span>`:""}\n ${r&&"right"===d?`<span class="${n?"ml-2":""}">${r}</span>`:""}\n `}\n </button>\n `.replace(/\s+/g," ").trim()}static createSpinner(){return o.H.render("loader",{class:"spinner animate-spin h-5 w-5"})}static createProgressBar(e){const t=document.createElement("div");return t.className="progress-bar absolute bottom-0 left-0 h-1 bg-primary-600 transition-all duration-300",t.style.width="0%",e.style.position="relative",e.appendChild(t),t}static createButtonGroup(e=[],t={}){const{spacing:n="normal",alignment:o="left",responsive:i=!0,vertical:a=!1}=t,s={none:a?"space-y-0":"space-x-0",tight:a?"space-y-1":"space-x-1",normal:a?"space-y-2":"space-x-2",loose:a?"space-y-4":"space-x-4"},r=e.map((e=>this.createButton(e))).join("");return`\n <div class="${`\n ${a?"flex flex-col":"flex flex-row"}\n ${{left:"justify-start",center:"justify-center",right:"justify-end",between:"justify-between",around:"justify-around"}[o]}\n ${s[n]}\n ${i&&!a?"flex-wrap gap-2":""}\n `.replace(/\s+/g," ").trim()}">\n ${r}\n </div>\n `}static attachHandler(e,t,n={}){const o="string"==typeof e?document.getElementById(e):e;if(!o||!t)return;const{loadingText:i="Processing...",successText:a="Success!",errorText:s="Error!",showSuccess:r=!0,showError:d=!0,resetDelay:l=2e3}=n;o.addEventListener("click",(async e=>{e.preventDefault();const n=this.setLoading(o,!0,{loadingText:i});if(n)try{const i=await t(e);
1return r&&!1!==i?this.setSuccess(o,a,l):n.restore(),i}catch(e){throw console.error("Button handler error:",e),d?this.setError(o,s,l):n.restore(),e}}))}static addRippleEffect(e){const t="string"==typeof e?document.getElementById(e):e;t&&(t.style.position="relative",t.style.overflow="hidden",t.addEventListener("click",(function(e){const t=document.createElement("span"),n=this.getBoundingClientRect(),o=Math.max(n.width,n.height),i=e.clientX-n.left-o/2,a=e.clientY-n.top-o/2;t.style.width=t.style.height=o+"px",t.style.left=i+"px",t.style.top=a+"px",t.classList.add("ripple"),t.style.position="absolute",t.style.borderRadius="50%",t.style.backgroundColor="rgba(255, 255, 255, 0.5)",t.style.animation="ripple-animation 0.6s ease-out",this.appendChild(t),setTimeout((()=>{t.remove()}),600)})))}}i.originalStates=new Map},8252:function(e,t,n){"use strict";n(7411)},7411:function(e,t,n){"use strict";n.d(t,{H:function(){return i}});const o={x:'<path stroke-linecap="round" stroke-linejoin="round" d="M18 6L6 18M6 6l12 12"/>',check:'<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/>',"check-circle":'<path stroke-linecap="round" stroke-linejoin="round" d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path stroke-linecap="round" stroke-linejoin="round" d="M22 4L12 14.01l-3-3"/>',"x-circle":'<circle cx="12" cy="12" r="10"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 9l-6 6"/><path stroke-linecap="round" stroke-linejoin="round" d="M9 9l6 6"/>',"alert-triangle":'<path stroke-linecap="round" stroke-linejoin="round" d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>',"alert-circle":'<circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>',info:'<circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/>',"chevron-right":'<path stroke-linecap="round" stroke-linejoin="round" d="M9 18l6-6-6-6"/>',"chevron-left":'<path stroke-linecap="round" stroke-linejoin="round" d="M15 18l-6-6 6-6"/>',"chevron-down":'<path stroke-linecap="round" stroke-linejoin="round" d="M6 9l6 6 6-6"/>',"chevron-up":'<path stroke-linecap="round" stroke-linejoin="round" d="M18 15l-6-6-6 6"/>',"credit-card":'<rect x="1" y="4" width="22" height="16" rx="2" ry="2"/><line x1="1" y1="10" x2="23" y2="10"/>',"dollar-sign":'<line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/>',plus:'<line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>',loader:'<line x1="12" y1="2" x2="12" y2="6"/><line x1="12" y1="18" x2="12" y2="22"/><line x1="4.93" y1="4.93" x2="7.76" y2="7.76"/><line x1="16.24" y1="16.24" x2="19.07" y2="19.07"/><line x1="2" y1="12" x2="6" y2="12"/><line x1="18" y1="12" x2="22" y2="12"/><line x1="4.93" y1="19.07" x2="7.76" y2="16.24"/><line x1="16.24" y1="7.76" x2="19.07" y2="4.93"/>',user:'<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',mail:'<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/>',lock:'<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>',eye:'<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>',"eye-off":'<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/>',star:'<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>',trash:'<polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>',"trash-2":'<polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/>',calendar:'<rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/>',clock:'<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',"map-pin":'<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/>',upload:'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/>',camera:'<path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/>',edit:'<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>',"more-vertical":'<circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/>',zap:'<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>',"shield-check":'<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="M9 12l2 2 4-4"/>',award:'<circle cx="12" cy="8" r="7"/><polyline points="8.21 13.89 7 23 12 20 17 23 15.79 13.88"/>',clipboard:'<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><rect x="8" y="2" width="8" height="4" rx="1" ry="1"/>',image:'<rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/>',link:'<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>',key:'<path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/>',"user-plus":'<path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="8.5" cy="7" r="4"/><line x1="20" y1="8" x2="20" y2="14"/><line x1="23" y1="11" x2="17" y2="11"/>',"refresh-cw":'<polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/>',tag:'<path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"/><line x1="7" y1="7" x2="7.01" y2="7"/>',"file-text":'<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/>',"clipboard-list":'<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><rect x="8" y="2" width="8" height="4" rx="1" ry="1"/><line x1="12" y1="11" x2="12" y2="11"/><line x1="12" y1="16" x2="12" y2="16"/><line x1="8" y1="11" x2="8" y2="11"/><line x1="8" y1="16" x2="8" y2="16"/>',"clipboard-check":'<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><rect x="8" y="2" width="8" height="4" rx="1" ry="1"/><path d="M9 14l2 2 4-4"/>',heart:'<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>',phone:'<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/>',"qr-code":'<rect x="2" y="2" width="20" height="20" rx="2"/><rect x="7" y="7" width="3" height="3"/><rect x="14" y="7" width="3" height="3"/><rect x="7" y="14" width="3" height="3"/><rect x="14" y="14" width="3" height="3"/>',filter:'<polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/>',globe:'<circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/>',download:'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/>',"log-in":'<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"/><polyline points="10 17 15 12 10 7"/><line x1="15" y1="12" x2="3" y2="12"/>',"log-out":'<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/>',settings:'<circle cx="12" cy="12" r="3"/><path d="M12 1v6m0 6v6m9-9h-6m-6 0H3m16.24-6.36l-4.24 4.24m-6 6-4.24 4.24m0-10.48l4.24 4.24m6 6l4.24 4.24"/>',bell:'<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/>',search:'<circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/>
1',menu:'<line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="18" x2="21" y2="18"/>',"arrow-up":'<line x1="12" y1="19" x2="12" y2="5"/><polyline points="5 12 12 5 19 12"/>',"arrow-down":'<line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/>',"external-link":'<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/>',copy:'<rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>',save:'<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/>',gift:'<polyline points="20 12 20 22 4 22 4 12"/><rect x="2" y="7" width="20" height="5"/><line x1="12" y1="22" x2="12" y2="7"/><path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z"/><path d="M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z"/>'};class i{static render(e,t){const n=o[e];if(!n)return console.warn(`Icon not found: ${e}`),"";const i=t?.size||20,a=t?.strokeWidth||2;return`<svg \n class="${t?.class||""}" \n width="${i}" \n height="${i}"\n viewBox="0 0 24 24"\n fill="none"\n stroke="currentColor"\n stroke-width="${a}"\n stroke-linecap="round"\n stroke-linejoin="round"\n >${n}</svg>`}static getIcon(e,t,n=""){const o=this[e];if(!o||!(t in o))return console.warn(`Icon not found: ${e}.${t}`),"";const i=o[t];if("function"==typeof i){const e=i();return n?e.replace(/class="[^"]*"/,`class="${n}"`):e}return n?i.replace(/class="[^"]*"/,`class="${n}"`):i}static createSocialButton(e,t="",n=""){const o={google:{icon:this.social.google,text:t||"Google",focusRing:"focus:ring-blue-500"},facebook:{icon:this.social.facebook,text:t||"Facebook",focusRing:"focus:ring-blue-600"},magic:{icon:"function"==typeof this.social.magicLink?this.social.magicLink():this.social.magicLink,text:t||"Magic Link",focusRing:"focus:ring-secondary-500"},apple:{icon:this.social.apple,text:t||"Apple",focusRing:"focus:ring-gray-500"},github:{icon:this.social.github,text:t||"GitHub",focusRing:"focus:ring-gray-500"}}[e];if(!o)return"";return`\n <button data-social-login="${e}" class="${`flex justify-center items-center py-2.5 px-4 border border-gray-300 rounded-xl text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 ${o.focusRing} transition-all duration-200 shadow-sm hover:shadow-md w-full`} ${n}" title="Continue with ${o.text}">\n ${o.icon}\n <span class="ml-2 hidden sm:inline">${o.text}</span>\n </button>\n `}static getCategories(){return["auth","social","status","payment","general","ui"]}}i.auth={email:()=>i.render("mail",{class:"w-5 h-5 text-gray-400"}),password:()=>i.render("lock",{class:"w-5 h-5 text-gray-400"}),user:()=>i.render("user",{class:"w-5 h-5 text-gray-400"}),userPlus:()=>i.render("user-plus",{class:"w-8 h-8 text-white"}),login:()=>i.render("lock",{class:"h-8 w-8 text-white"}),eyeOpen:()=>i.render("eye",{class:"h-5 w-5 text-gray-400 hover:text-gray-600"}),eyeClosed:()=>i.render("eye-off",{class:"h-5 w-5 text-gray-400 hover:text-gray-600"}),key:()=>i.render("key",{class:"h-8 w-8 text-white"})},i.social={google:'<svg class="w-5 h-5" viewBox="0 0 24 24">\n <path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/>\n <path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/>\n <path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/>\n <path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/>\n </svg>',facebook:'<svg class="w-5 h-5" fill="#1877F2" viewBox="0 0 24 24">\n <path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>\n </svg>',magicLink:()=>i.render("link",{class:"w-5 h-5 text-secondary-600"}),apple:'<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">\n <path d="M12.017 0C8.396 0 8.034.016 8.034.016 8.034.016 7.48.095 7.076.233a3.743 3.743 0 0 0-1.296.777c-.412.384-.738.849-.952 1.395-.214.546-.32 1.135-.32 1.765 0 .63.106 1.219.32 1.765.214.546.54 1.011.952 1.395a3.743 3.743 0 0 0 1.296.777c.404.138.958.217.958.217s.362.016 3.983.016c3.621 0 3.983-.016 3.983-.016s.554-.079.958-.217a3.743 3.743 0 0 0 1.296-.777c.412-.384.738-.849.952-1.395.214-.546.32-1.135.32-1.765 0-.63-.106-1.219-.32
1-1.765a3.598 3.598 0 0 0-.952-1.395 3.743 3.743 0 0 0-1.296-.777C15.554.095 15 .016 15 .016S14.638 0 12.017 0z"/>\n </svg>',github:'<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">\n <path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>\n </svg>'},i.status={success:()=>i.render("check",{class:"h-8 w-8 text-green-600"}),error:()=>i.render("x-circle",{class:"h-8 w-8 text-red-600"}),warning:()=>i.render("alert-triangle",{class:"h-8 w-8 text-yellow-600"}),info:()=>i.render("info",{class:"h-8 w-8 text-blue-600"}),loading:()=>i.render("loader",{class:"w-5 h-5 animate-spin text-current"})},i.payment={creditCard:()=>i.render("credit-card",{class:"w-5 h-5"}),creditCardSolid:()=>i.render("credit-card",{class:"w-6 h-6"}),dollar:()=>i.render("dollar-sign",{class:"w-5 h-5"})},i.general={clipboard:()=>i.render("clipboard",{class:"w-5 h-5"}),calendar:()=>i.render("calendar",{class:"w-5 h-5"}),clock:()=>i.render("clock",{class:"w-4 h-4"}),location:()=>i.render("map-pin",{class:"w-4 h-4"}),image:()=>i.render("image",{class:"w-4 h-4"}),edit:()=>i.render("edit",{class:"w-4 h-4"}),plus:()=>i.render("plus",{class:"w-4 h-4"}),menuVertical:()=>i.render("more-vertical",{class:"w-5 h-5"}),lightning:()=>i.render("zap",{class:"w-5 h-5"}),shieldCheck:()=>i.render("shield-check",{class:"w-8 h-8"}),badge:()=>i.render("award",{class:"w-4 h-4"}),info:()=>i.render("info",{class:"w-5 h-5"}),upload:()=>i.render("upload",{class:"w-5 h-5"}),camera:()=>i.render("camera",{class:"w-5 h-5"}),trash:()=>i.render("trash",{class:"w-5 h-5"}),star:()=>i.render("star",{class:"w-5 h-5"}),phone:()=>i.render("phone",{class:"w-5 h-5"})},i.ui={close:()=>i.render("x",{class:"h-6 w-6"}),add:()=>i.render("plus",{class:"w-5 h-5"}),arrowRight:()=>i.render("chevron-right",{class:"w-5 h-5"}),arrowLeft:()=>i.render("chevron-left",{class:"w-5 h-5"}),refresh:()=>i.render("refresh-cw",{class:"w-5 h-5"}),check:()=>i.render("check",{class:"w-5 h-5"}),star:()=>i.render("star",{class:"w-5 h-5"}),tag:()=>i.render("tag",{class:"w-5 h-5"}),creditCard:()=>i.render("credit-card",{class:"w-5 h-5"}),loader:()=>i.render("loader",{class:"w-5 h-5"})},t.A=i},4432:function(e,t,n){"use strict";n.d(t,{W:function(){return i}});var o=n(7411);class i{static show(e,t={}){const n={...this.defaultConfig,...t,id:t.id||`loading-${Date.now()}`},o="string"==typeof e?document.querySelector(e):e;if(!o)return console.warn("LoadingUtils: Target element not found"),{hide:async()=>{},update:()=>{}};const i={position:o.style.position,pointerEvents:o.style.pointerEvents,filter:o.style.filter},a=this.createLoader(n);n.overlay&&(o.style.position="relative",o.appendChild(a)),n.blur&&(o.style.filter="blur(2px)"),o.style.pointerEvents="none",o.setAttribute("aria-busy","true");const s=Date.now();return this.activeLoaders.set(n.id,{element:o,loader:a,config:n,originalState:i,startTime:s}),{hide:()=>this.hide(n.id),update:e=>this.updateMessage(n.id,e)}}static async hide(e){const t=this.activeLoaders.get(e);if(!t)return;const{element:n,loader:o,config:i,originalState:a,startTime:s}=t,r=Date.now()-s;r<i.minDuration&&await new Promise((e=>setTimeout(e,i.minDuration-r))),o&&o.parentNode&&(o.classList.add("fade-out"),setTimeout((()=>o.remove()),300)),n.style.position=a.position,n.style.pointerEvents=a.pointerEvents,n.style.filter=a.filter,n.removeAttribute("aria-busy"),this.activeLoaders.delete(e)}static hideAll(){const e=[];for(const t of this.activeLoaders.keys())e.push(this.hide(t));Promise.all(e)}static updateMessage(e,t){const n=this.activeLoaders.get(e);if(!n)return;const o=n.loader.querySelector(".loading-message");o&&(o.textContent=t)}static createLoader(e){const t=document.createElement("div");t.className="loading-overlay absolute inset-0 flex items-center justify-center z-50 transition-opacity duration-300",t.style.backgroundColor=`rgba(255, 255, 255, ${e.opacity})`;const n=[];return e.spinner&&n.push(this.createSpinner(e.spinnerSize)),e.message&&n.push(`\n <div class="loading-message text-gray-700 text-sm font-medium ${e.spinner?"mt-3":""}">\n ${e.message}\n </div>\n `),t.innerHTML=`\n <div class="text-center">\n ${n.join("")}\n </div>\n `,t}static createSpinner(e="md"){const t={sm:"h-8 w-8",md:"h-12 w-12",lg:"h-16 w-16",xl:"h-20 w-20"},n=t[e]||t.md;return`\n <div class="mx-auto ${n}">\n ${o.H.render("loader",{class:`animate-spin ${n} text-primary-600`})}\n </div>\n `}static skeleton(e,t={}){const n={lines:3,animated:!0,...t},o="string"==typeof e?document.querySelector(e):e;if(!o)return{remove:()=>{}};const i=Array(n.lines).fill(0).map(((e,t)=>`\n <div class="skeleton-line ${n.animated?"animate-pulse":""} bg-gray-200 rounded h-4 ${t<n.lines-1?"mb-2":""}" \n style="width: ${30*Math.random()+70}%"></div>\n `)).join("");return o.innerHTML=`<div class="skeleton-loader">${i}</div>`,{remove:()=>{const e=o.querySelector(".skeleton-loader");e&&e.remove()}}}static progress(e,t={}){const n={value:0,max:100,showLabel:!0,color:"primary",height:"h-2",animated:!0,...t},o="string"==typeof e?document.querySelector(e):e;if(!o)return{update:()=>{},hide:()=>{}};const i=`progress-${Date.now()}`,a=`\n <div id="${i}" class="progress-container">\n ${n.showLabel?`\n <div class="flex justify-between mb-1">
1\n <span class="text-sm font-medium text-gray-700">Loading...</span>\n <span class="text-sm font-medium text-gray-700 progress-label">${n.value}%</span>\n </div>\n `:""}\n <div class="w-full bg-gray-200 rounded-full ${n.height} overflow-hidden">\n <div class="progress-bar bg-${n.color}-600 ${n.height} rounded-full transition-all duration-300 ${n.animated?"progress-animated":""}"\n style="width: ${n.value}%"\n role="progressbar"\n aria-valuenow="${n.value}"\n aria-valuemin="0"\n aria-valuemax="${n.max}">\n </div>\n </div>\n </div>\n `;return o.innerHTML=a,{update:e=>{const t=document.getElementById(i);if(!t)return;const o=t.querySelector(".progress-bar"),a=t.querySelector(".progress-label");if(o){const t=Math.min(100,Math.max(0,e/n.max*100));o.style.width=`${t}%`,o.setAttribute("aria-valuenow",e.toString())}a&&(a.textContent=`${Math.round(e/n.max*100)}%`)},hide:()=>{const e=document.getElementById(i);e&&e.remove()}}}static spinner(e,t={}){const n={size:"sm",color:"primary",position:"before",...t},o="string"==typeof e?document.querySelector(e):e;if(!o)return{remove:()=>{}};const i=o.innerHTML,a=this.createSpinner(n.size);return"before"===n.position?o.innerHTML=a+" "+i:"after"===n.position?o.innerHTML=i+" "+a:o.innerHTML=a,{remove:()=>{o.innerHTML=i}}}static async withLoading(e,t={}){const{target:n=document.body,message:o="Loading...",onError:i=null,...a}=t,s=this.show(n,{message:o,...a});try{return await e()}catch(e){throw i&&i(e),e}finally{await s.hide()}}}if(i.activeLoaders=new Map,i.defaultConfig={overlay:!0,spinner:!0,message:"",minDuration:300,blur:!1,opacity:.75},"undefined"!=typeof document){const e=document.createElement("style");e.textContent="\n .loading-overlay {\n backdrop-filter: blur(1px);\n }\n .fade-out {\n opacity: 0 !important;\n }\n .skeleton-line {\n background: linear-gradient(90deg, #f3f4f6 25%, #e5e7eb 50%, #f3f4f6 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n }\n @keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n .progress-animated {\n background-image: linear-gradient(\n 45deg,\n rgba(255, 255, 255, .15) 25%,\n transparent 25%,\n transparent 50%,\n rgba(255, 255, 255, .15) 50%,\n rgba(255, 255, 255, .15) 75%,\n transparent 75%,\n transparent\n );\n background-size: 1rem 1rem;\n animation: progress-bar-stripes 1s linear infinite;\n }\n @keyframes progress-bar-stripes {\n 0% { background-position: 1rem 0; }\n 100% { background-position: 0 0; }\n }\n ",document.head.appendChild(e)}"undefined"!=typeof window&&(window.LoadingUtils=i)},4811:function(e,t,n){"use strict";n.r(t),n.d(t,{ModalUtils:function(){return i}});var o=n(7411);class i{static show(e={}){const t={...this.defaultConfig,...e,id:e.id||`modal-${Date.now()}`,zIndex:this.zIndexCounter++};this.activeModals.has(t.id)&&this.hide(t.id);const{backdrop:n,modal:o}=this.createModal(t);return document.body.appendChild(n),document.body.appendChild(o),this.activeModals.set(t.id,{backdrop:n,modal:o,config:t}),this.attachEventListeners(t.id),requestAnimationFrame((()=>{n.classList.add("opacity-100"),o.classList.add("opacity-100");const e=o.querySelector(".modal-dialog");e&&requestAnimationFrame((()=>{e.classList.remove("scale-95","opacity-0"),e.classList.add("scale-100","opacity-100")})),t.focus&&setTimeout((()=>this.focusFirstElement(o)),300)})),document.body.classList.add("modal-open"),t.id}static async hide(e){const t=this.activeModals.get(e);if(!t)return;const{backdrop:n,modal:o,config:i}=t;if(i.onBeforeClose){if(!1===await i.onBeforeClose())return}const a=o.querySelector(".modal-dialog");return a&&(a.classList.remove("scale-100","opacity-100"),a.classList.add("scale-95","opacity-0")),setTimeout((()=>{n.classList.remove("opacity-100"),n.classList.add("opacity-0"),o.classList.remove("opacity-100"),o.classList.add("opacity-0")}),100),new Promise((t=>{setTimeout((()=>
1{if(n.remove(),o.remove(),this.activeModals.delete(e),0===this.activeModals.size){document.body.classList.remove("modal-open"),document.body.style.paddingRight="";const e=document.body.dataset.scrollY,t=document.body.dataset.scrollX;void 0!==e&&void 0!==t&&(window.scrollTo(parseInt(t,10),parseInt(e,10)),delete document.body.dataset.scrollY,delete document.body.dataset.scrollX)}i.onClose&&i.onClose(),t()}),300)}))}static async hideAll(){const e=[];for(const t of this.activeModals.keys())e.push(this.hide(t));await Promise.all(e)}static async hideModal(e){if(e)return this.hide(e);const t=Array.from(this.activeModals.entries());if(0===t.length)return;const n=t.sort(((e,t)=>(t[1].config.zIndex||0)-(e[1].config.zIndex||0)))[0];return n?this.hide(n[0]):void 0}static createModal(e){const{id:t,title:n,content:i,footer:a,size:s,showClose:r,showHeader:d,centered:l,zIndex:c,className:u=""}=e,m=document.createElement("div");m.className="modal-backdrop fixed inset-0 bg-black/50 backdrop-blur-sm transition-all duration-300 opacity-0",m.style.zIndex=c.toString();const g=document.createElement("div");g.id=t,g.className=`\n modal fixed inset-0 overflow-y-auto transition-all duration-300 opacity-0\n ${l?"flex min-h-screen py-4 px-4 sm:px-6 lg:px-8":""}\n `.trim(),g.style.zIndex=(c+1).toString(),g.setAttribute("role","dialog"),g.setAttribute("aria-modal","true"),n&&g.setAttribute("aria-labelledby",`${t}-title`);const h=`\n <div class="modal-container ${l?"mx-auto":"mx-auto mt-10 mb-10"} ${this.getSizeClasses(s)}">\n <div class="modal-dialog relative bg-white rounded-2xl shadow-2xl transform transition-all duration-300 scale-95 opacity-0 max-h-[calc(100vh-10px)] overflow-y-auto ${u}">\n ${d&&(n||r)?`\n <div class="modal-header px-6 py-4 border-b border-gray-200">\n <div class="flex items-center justify-between">\n ${n?`<h3 id="${t}-title" class="text-lg font-medium text-gray-900">${n}</h3>`:"<div></div>"}\n ${r?`\n <button\n type="button"\n class="modal-close text-gray-400 hover:text-gray-500 focus:outline-none focus:text-gray-500 transition ease-in-out duration-150"\n aria-label="Close"\n >\n ${o.H.render("x",{class:"h-6 w-6"})}\n </button>\n `:""}\n </div>\n </div>\n `:!d&&r?`\n <button\n type="button"\n class="modal-close absolute top-4 right-4 z-10 text-gray-400 hover:text-gray-500 bg-white rounded-full p-2 shadow-lg hover:shadow-xl transition-all duration-150 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-400"\n aria-label="Close"\n >\n ${o.H.render("x",{class:"h-5 w-5"})}\n </button>\n `:""}\n \n <div class="modal-body ${d?"px-6 py-4":""}">\n ${i||""}\n </div>\n \n ${a?`\n <div class="modal-footer px-6 py-4 border-t border-gray-200">\n ${a}\n </div>\n `:""}\n </div>\n </div>\n `;return g.innerHTML=h,{backdrop:m,modal:g}}static getSizeClasses(e){const t={xs:"max-w-xs w-full",sm:"max-w-sm w-full",md:"max-w-md w-full",lg:"max-w-lg w-full",xl:"max-w-xl w-full","2xl":"max-w-2xl w-full","3xl":"max-w-3xl w-full","4xl":"max-w-4xl w-full",full:"max-w-full w-full mx-4",auth:"max-w-[500px] w-full"};return t[e]||t.md}static attachEventListeners(e){const t=this.activeModals.get(e);if(!t)return;const{backdrop:n,modal:o,config:i}=t,a=o.querySelector(".modal-close");if(a&&a.addEventListener("click",(()=>this.hide(e))),i.closeOnBackdrop){n.addEventListener("click",(()=>this.hide(e)));const t=o.querySelector(".modal-container");t&&t.addEventListener("click",(e=>{e.target===t&&e.stopPropagation()}))}if(i.closeOnEscape){const n=t=>{if("Escape"===t.key){const t=Array.from(this.activeModals.entries()).sort(((e,t)=>(t[1].config.zIndex||0)-(e[1].config.zIndex||0)))[0];t&&t[0]===e&&this.hide(e)}};document.addEventListener("keydown",n),t.escapeHandler=n}}static focusFirstElement(e){const t=e.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not
1([tabindex="-1"])');t.length>0&&t[0].focus()}static async confirm(e={}){return new Promise((t=>{const n={title:"Confirm",message:"Are you sure?",confirmText:"Confirm",cancelText:"Cancel",confirmClass:"bg-primary-600 hover:bg-primary-700 text-white",cancelClass:"bg-white hover:bg-gray-50 text-gray-700 border border-gray-300",...e},o=this.show({title:n.title,content:`<p class="text-sm text-gray-500">${n.message}</p>`,footer:`\n <div class="flex justify-end space-x-3">\n <button\n type="button"\n class="cancel-btn inline-flex justify-center px-4 py-2 text-sm font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 ${n.cancelClass}"\n >\n ${n.cancelText}\n </button>\n <button\n type="button"\n class="confirm-btn inline-flex justify-center px-4 py-2 text-sm font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 ${n.confirmClass}"\n >\n ${n.confirmText}\n </button>\n </div>\n `,size:"sm",closeOnBackdrop:!1,closeOnEscape:!1}),i=this.activeModals.get(o);if(i){const e=i.modal.querySelector(".confirm-btn"),n=i.modal.querySelector(".cancel-btn");e?.addEventListener("click",(async()=>{await this.hide(o),t(!0)})),n?.addEventListener("click",(async()=>{await this.hide(o),t(!1)}))}}))}static async prompt(e={}){return new Promise((t=>{const n={title:"Enter Value",message:"Please enter a value:",placeholder:"",defaultValue:"",confirmText:"OK",cancelText:"Cancel",inputType:"text",...e},o=`prompt-input-${Date.now()}`,i=this.show({title:n.title,content:`\n <div>\n ${n.message?`<p class="text-sm text-gray-500 mb-3">${n.message}</p>`:""}\n <input\n id="${o}"\n type="${n.inputType}"\n class="shadow-sm focus:ring-primary-500 focus:border-primary-500 block w-full sm:text-sm border-gray-300 rounded-md"\n placeholder="${n.placeholder}"\n value="${n.defaultValue}"\n />\n </div>\n `,footer:`\n <div class="flex justify-end space-x-3">\n <button\n type="button"\n class="cancel-btn inline-flex justify-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"\n >\n ${n.cancelText}\n </button>\n <button\n type="button"\n class="confirm-btn inline-flex justify-center px-4 py-2 text-sm font-medium text-white bg-primary-600 border border-transparent rounded-md hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"\n >\n ${n.confirmText}\n </button>\n </div>\n `,size:"sm",closeOnBackdrop:!1,closeOnEscape:!1}),a=this.activeModals.get(i);if(a){const e=a.modal.querySelector(`#${o}`),n=a.modal.querySelector(".confirm-btn"),s=a.modal.querySelector(".cancel-btn");e?.focus(),e?.addEventListener("keypress",(e=>{"Enter"===e.key&&n?.click()})),n?.addEventListener("click",(async()=>{const n=e?.value||"";await this.hide(i),t(n)})),s?.addEventListener("click",(async()=>{await this.hide(i),t(null)}))}}))}static loading(e={}){const t={message:"Loading...",showSpinner:!0,...e};return this.show({content:`\n <div class="text-center py-8">\n ${t.showSpinner?`\n ${o.H.render("loader",{class:"animate-spin h-12 w-12 text-primary-600 mx-auto mb-4"})}\n `:""}\n <p class="text-gray-600">${t.message}</p>\n </div>\n `,size:"xs",showClose:!1,closeOnBackdrop:!1,closeOnEscape:!1,centered:!0})}}if(i.activeModals=new Map,i.zIndexCounter=1e3,i.defaultConfig={size:"md",closeOnBackdrop:!0,closeOnEscape:!0,showClose:!0,showHeader:!0,centered:!0,animation:"fade",backdrop:!0,focus:!0},"undefined"!=typeof document){const e=document.createElement("style");
1e.textContent="\n .modal-backdrop.show {\n opacity: 0.5;\n }\n .modal.show {\n opacity: 1;\n }\n .modal-open {\n overflow: hidden;\n }\n .modal-container {\n transform: scale(0.95);\n transition: transform 0.3s ease-out;\n }\n .modal.show .modal-container {\n transform: scale(1);\n }\n /* Ensure modal dialog scrolls properly */\n .modal-dialog {\n display: flex;\n flex-direction: column;\n }\n .modal-dialog .modal-header,\n .modal-dialog .modal-footer {\n flex-shrink: 0;\n }\n .modal-dialog .modal-body {\n flex-grow: 1;\n overflow-y: auto;\n }\n ",document.head.appendChild(e)}"undefined"!=typeof window&&(window.ModalUtils=i),t.default=i},3716:function(e,t,n){"use strict";n.d(t,{Aw:function(){return o.A},Nm:function(){return a},Hj:function(){return i.A}});n(5762);var o=n(744),i=n(7411);class a{static setupValidation(e,t={}){const n={errorMessage:"This field is required",validateOnChange:!0,validateOnSubmit:!0,showErrorIcon:!0,...t};this.ensureFieldWrapper(e),n.validateOnChange&&(e.addEventListener("change",(()=>{this.validateCheckbox(e,n)})),e.addEventListener("blur",(()=>{e.hasAttribute("data-touched")||(e.setAttribute("data-touched","true"),this.validateCheckbox(e,n))}))),e.removeAttribute("required"),e.setAttribute("data-validation-required","true"),e._validationSettings=n}static ensureFieldWrapper(e){if(e.closest(".checkbox-field"))return;const t=e.parentElement;t&&!t.classList.contains("checkbox-field")&&t.classList.add("checkbox-field")}static validateCheckbox(e,t){const n=t||e._validationSettings||{};return e.hasAttribute("data-validation-required")&&!e.checked?(this.showError(e,n.errorMessage||"This field is required",n.showErrorIcon),!1):(this.clearError(e),!0)}static showError(e,t,n=!0){const o=e.closest(".checkbox-field")||e.parentElement;if(!o)return;e.classList.add("border-red-500","text-red-600"),e.classList.remove("border-gray-300","text-primary-600");let a=o.querySelector('[role="alert"]');if(!a){a=document.createElement("div"),a.className="mt-2 flex items-start gap-1.5",a.setAttribute("role","alert");const e=n?i.H.render("alert-circle",{class:"w-4 h-4 text-red-500 flex-shrink-0 mt-0.5"}):"";a.innerHTML=`\n ${e}\n <span class="text-sm text-red-600 font-medium">${t}</span>\n `,o.appendChild(a)}}static clearError(e){const t=e.closest(".checkbox-field")||e.parentElement;if(!t)return;e.classList.remove("border-red-500","text-red-600"),e.classList.add("border-gray-300","text-primary-600");const n=t.querySelector('[role="alert"]');n&&n.remove()}static validateAll(e){const t=e.querySelectorAll('input[type="checkbox"][data-validation-required]');let n=!0;return t.forEach((e=>{this.validateCheckbox(e)||(n=!1)})),n}static setupAllInContainer(e,t={}){e.querySelectorAll('input[type="checkbox"][required]').forEach((e=>{const n=e.dataset.errorMessage||t.errorMessage;this.setupValidation(e,{...t,errorMessage:n})}
1))}static reset(e){this.clearError(e),e.removeAttribute("data-touched")}}n(4811),n(4432),n(8252);class s{static show(e,t="default",n={}){const{containerId:o="auth-module-container",containerClass:i="",animate:a=!0,onOpen:s,onClose:r}=n;let d=document.getElementById(o);d||(d=document.createElement("div"),d.id=o,d.className=`module-container ${i}`.trim(),document.body.appendChild(d));const l=d.innerHTML,c=d.classList.contains("hidden");return d.innerHTML=e,d.classList.remove("hidden"),d.classList.add(`${t}-module`),this.activeModules.set(o,{container:d,type:t,previousContent:l,wasHidden:c,onClose:r}),a&&(d.style.opacity="0",d.style.transform="translateY(10px)",requestAnimationFrame((()=>{d.style.transition="all 0.3s ease-out",d.style.opacity="1",d.style.transform="translateY(0)"}))),s&&s(d),d}static async hide(e="auth-module-container"){const t=this.activeModules.get(e);if(!t){const t=document.getElementById(e);return void(t&&t.classList.add("hidden"))}const{container:n,onClose:o}=t;if(o){if(!1===await o())return}return new Promise((t=>{n.style.transition="all 0.3s ease-out",n.style.opacity="0",n.style.transform="translateY(10px)",setTimeout((()=>{n.innerHTML="",n.classList.add("hidden"),n.style.opacity="",n.style.transform="",this.activeModules.delete(e),t()}),300)}))}static async hideAll(){const e=[];for(const t of this.activeModules.keys())e.push(this.hide(t));await Promise.all(e)}static async replace(e,t,n={}){const o=document.getElementById(e);if(!o)return this.show(t,"default",{containerId:e,...n});const{animate:i=!0}=n;return i?(o.style.transition="opacity 0.2s ease-out",o.style.opacity="0",await new Promise((e=>setTimeout(e,200))),o.innerHTML=t,o.style.opacity="1"):o.innerHTML=t,o}static toggle(e="auth-module-container"){const t=document.getElementById(e);t&&(t.classList.contains("hidden")?t.classList.remove("hidden"):this.hide(e))}static isVisible(e="auth-module-container"){const t=document.getElementById(e);return null!==t&&!t.classList.contains("hidden")}static notify(e,t="info",n={}){const{duration:o=5e3,position:a="top-right",animate:s=!0,dismissible:r=!0}=n,d=`notification-${Date.now()}`,l=document.createElement("div");l.id=d,l.className=`notification-module ${a}`;const c={"top-right":"fixed top-4 right-4 z-50","top-left":"fixed top-4 left-4 z-50","bottom-right":"fixed bottom-4 right-4 z-50","bottom-left":"fixed bottom-4 left-4 z-50","top-center":"fixed top-4 left-1/2 transform -translate-x-1/2 z-50","bottom-center":"fixed bottom-4 left-1/2 transform -translate-x-1/2 z-50"};return l.className+=` ${c[a]||c["top-right"]}`,l.innerHTML=`\n <div class="max-w-sm w-full ${{info:"bg-blue-100 border-blue-400 text-blue-700",success:"bg-green-100 border-green-400 text-green-700",warning:"bg-yellow-100 border-yellow-400 text-yellow-700",error:"bg-red-100 border-red-400 text-red-700"}[t]} px-4 py-3 rounded-lg shadow-lg border flex items-center justify-between">\n <span class="text-sm">${e}</span>\n ${r?`\n <button class="ml-4 text-current opacity-70 hover:opacity-100" onclick="ModuleUtils.hide('${d}')">\n ${i.H.render("x",{class:"w-4 h-4"})}\n </button>\n `:""}\n </div>\n `,document.body.appendChild(l),s&&(l.style.opacity="0",l.style.transform="translateX(100%)",requestAnimationFrame((()=>{l.style.transition="all 0.3s ease-out",l.style.opacity="1",l.style.transform="translateX(0)"}))),o>0&&setTimeout((()=>{this.hide(d)}),o),d}}s.activeModules=new Map,"undefined"!=typeof window&&(window.ModuleUtils=s);var r=n(1667);class d{static async switchToTab(e){const t=r.systemRegistry.get("profileSystem");if(t&&"function"==typeof t.switchProfileTab){return await t.switchProfileTab(e)||!1}const n=new CustomEvent("heimguard:profile:navigate",{detail:{section:e},bubbles:!0});document.dispatchEvent(n);try{if(!this.validSections.includes(e))return console.error(`[ProfileTabUtils] Invalid section: ${e}`),!1;const t=document.querySelector(".profile-component"),n=document.querySelector("#profile-dashboard");if(!t&&!n)return window.location.hash=e,!0;const o=document.querySelector(`[href="#${e}"]`);return o?(o.click(),!0):(window.location.hash=e,!0)}catch(e){return console.error("[ProfileTabUtils] Error switching tab:",e),!1}}static getActiveSection(){const e=window.location.hash.substring(1);if(e)return e;const t=document.querySelector(".sidebar-item.active");if(t){const e=t.getAttribute("href");if(e&&e.startsWith("#"))return e.substring(1)}return null}static isSectionActive(e){return this.getActiveSection()===e}static getValidSections(){return this.validSections}static isValidSection(e){return this.validSections.includes(e)}}d.validSections=["profile","addresses","payment","subscriptions","invoices","security","newsletters","activity","rewards","affinity"];d.switchToTab},2910:function(e,t,n){"use strict";var o=n(1916),i=n(5606);const a={env:"production",apiBaseUrl:i.env.API_BASE_URL||"/api/heimguard",cmsUrl:i.env.CMS_URL||"http://localhost",isDev:!1,apiLoginUrl:"/api/heimguard/login",apiLogoutUrl:"/api/heimguard/logout",apiTwoFactorUrl:"/api/heimguard/two-factor-login",apiTwoFactorResetUrl:"/api/heimguard/two-factor-reset",logoutRedirectUrl:"/",loginUrl:"/login",apiRegisterUrl:"/api/heimguard/registration/register",apiVerifyEmailUrl:"/api/heimguard/registration/verify",apiResetPasswordUrl:"/api/heimguard/password/reset",apiSetPasswordUrl:"/api/heimguard/password/set",apiChangePasswordUrl:"/api/heimguard/password/change",apiValidateResetTokenUrl:"/api/heimguard/password/validate-token",apiPasswordlessEmailUrl:"/api/heimguard/send-passwordless-email",apiPasswordlessLoginUrl:"/api/heimguard/passwordless-login",apiPasswordlessStatusUrl:"/api/heimguard/passwordless-login/status",apiGoogleLoginUrl:"/api/heimguard/google/login",apiGoogleCallbackUrl:"/api/heimguard/google/oauth2callback",apiGoogleLogoutUrl:"/api/heimguard/google/logout",apiGoogleLinkUrl:"/api/heimguard/google/login/link",apiGoogleUnlinkUrl:"/api/heimguard/google/login/unlink",apiFacebookLoginUrl:"/api/heimguard/facebook/login",apiFacebookCallbackUrl:"/api/heimguard/facebook/oauth2callback",apiFacebookLinkUrl:"/api/heimguard/facebook/login/link",apiFacebookUnlinkUrl:"/api/heimguard/facebook/login/unlink",apiGetProfileUrl:"/api/heimguard/profile/get-profile",apiEditProfileUrl:"/api/heimguard/profile/edit-profile",apiProfileEmailChangeInitiate:"/api/heimguard/profile/email-change/initiate",apiGetAllAddresses:"/api/heimguard/profile/addresses/all",apiAddAddress:"/api/heimguard/profile/addresses/add-address",apiUpdateAddress:"/api/heimguard/profile/addresses/update-ad
1dress",apiDeleteAddress:"/api/heimguard/profile/addresses/delete-address",apiGetBillingInfoUrl:"/api/heimguard/profile/billing/all",apiUpdateBillingInfoUrl:"/api/heimguard/profile/billing/update",apiGetPaymentMethodsUrl:"/api/heimguard/profile/payment-methods/all",apiAddPaymentMethodUrl:"/api/heimguard/profile/payment-methods/add",apiUpdatePaymentMethodUrl:"/api/heimguard/profile/payment-methods/update",apiDeletePaymentMethodUrl:"/api/heimguard/profile/payment-methods/delete",apiGetSubscriptionsUrl:"/api/heimguard/profile/subscriptions/all",apiAddSubscriptionUrl:"/api/heimguard/profile/subscriptions/add",apiUpdateSubscriptionUrl:"/api/heimguard/profile/subscriptions/update",apiDeleteSubscriptionUrl:"/api/heimguard/profile/subscriptions/delete",apiCancelSubscriptionUrl:"/api/heimguard/profile/subscriptions/cancel",apiGetInvoicesUrl:"/api/heimguard/profile/invoices/all",apiGetInvoicePdfUrl:"/api/heimguard/profile/invoice-pdf",apiGetCommentsUrl:"/api/heimguard/profile/comments",apiGetFollowedUrl:"/api/heimguard/profile/followed",apiGetActivitiesUrl:"/api/heimguard/profile/activities/all",apiGetRecentActivitiesUrl:"/api/heimguard/profile/activities/recent",apiGetActivitiesByTypeUrl:"/api/heimguard/profile/activities/by-type",apiGetActivitySummaryUrl:"/api/heimguard/profile/activities/summary",apiProfileAvatarUrl:"/api/heimguard/profile/avatar/upload",apiProfileAvatarDeleteUrl:"/api/heimguard/profile/avatar/delete",apiProfileAvatarGetUrl:"/api/heimguard/profile/avatar/get",apiPurchaseUrl:"/api/heimguard/access/purchase",apiLikeUrl:"/api/heimguard/like",apiLikeStatusUrl:"/api/heimguard/like/status",apiFollowUrl:"/api/heimguard/follow",apiFollowStatusUrl:"/api/heimguard/follow/status",apiAffinityUserItemsUrl:"/api/heimguard/affinity/user-items",apiGetAdUrl:"/api/heimguard/ads/get",apiNotificationsUrl:"/api/heimguard/notification",apiGetNewslettersUrl:"/api/heimguard/profile/newsletters/all",apiUpdateNewslettersUrl:"/api/heimguard/profile/newsletters/subscribe",apiCommentsGetUrl:"/api/heimguard/comments/get",apiCommentsAddUrl:"/api/heimguard/comments/add",apiCommentsGetChildrenUrl:"/api/heimguard/comments/get-children",apiTwoFactorSetupUrl:"/api/heimguard/two-factor-login/setup",apiBackupCodesGenerateUrl:"/api/heimguard/backup-codes/generate",apiResendVerificationUrl:"/api/heimguard/registration/verify",apiValidateSessionUrl:"/api/heimguard/auth/validate",apiAccessWall:"/api/heimguard/access-wall/get",apiHeimguardSettingsUrl:"/api/heimguard/init",apiHeimguardInitUrl:"/api/heimguard/init",loginRedirectUrl:"/profile",registerRedirectUrl:"/profile",registerPageUrl:"/register",heimguardConfig:{profile:{url:"/profile",useModal:!1},login:{url:"/api/heimguard/login",useModal:!0},register:{url:"/api/heimguard/registration",useModal:!0},forgotPassword:{url:"/api/heimguard/forgot-password",useModal:!0},magicLink:{url:"/api/heimguard/magic-link",useModal:!0},notifications:[],terms:"",privacyPolicy:""}};"undefined"!=typeof window&&o.vF.info("Config initialized: "+(a.isDev?"Development Mode":"Production Mode"),"init"),t.A=a},1916:function(e,t,n){"use strict";var o;n.d(t,{vF:function(){return a}}),function(e){e[e.NONE=0]="NONE",e[e.ERROR=1]="ERROR",e[e.WARN=2]="WARN",e[e.INFO=3]="INFO",e[e.DEBUG=4]="DEBUG"}(o||(o={}));class i{constructor(){this.defaultConfig={enabled:!1,level:o.ERROR,categories:{theme:!1,auth:!1,payment:!1,profile:!1,registry:!1,init:!1,api:!1,general:!1}},this.config=this.loadConfig()}static getInstance(){return i.instance||(i.instance=new i),i.instance}loadConfig(){if("localhost"!==window.location.hostname&&!window.location.hostname.includes("staging")&&!window.location.hostname.includes("dev"))return localStorage.removeItem("heimguard_logger_config"),this.defaultConfig;const e=new URLSearchParams(window.location.search),t=e.get("debug"),n=e.get("log"),i=localStorage.getItem("heimguard_logger_config");let a=this.defaultConfig;if(i)try{a={...this.defaultConfig,...JSON.parse(i)}}catch(e){}"true"!==t&&"true"!==n||(a.enabled=!0,a.level=o.DEBUG,Object.keys(a.categories).forEach((e=>{a.categories[e]=!0})));const s=e.get("logCategories");if(s){s.split(",").forEach((e=>{e in a.categories&&(a.categories[e]=!0)})),a.enabled=!0}return a}updateConfig(e){this.config={...this.config,...e},localStorage.setItem("heimguard_logger_config",JSON.stringify(this.config))}shouldLog(e,t){return!!this.config.enabled&&(!(e>this.config.level)&&!(t&&!this.config.categories[t]))}formatMessage(e,t,n){(new Date).toISOString();return`${t?`[${t}]`:""} ${n}`}log(e,t){this.shouldLog(o.INFO,t)&&console.log(this.formatMessage("INFO",t,e))}debug(e,t,...n){this.shouldLog(o.DEBUG,t)&&console.log(this.formatMessage("DEBUG",t,e),...n)}info(e,t,...n){this.shouldLog(o.INFO,t)&&console.info(this.formatMessage("INFO",t,e),...n)}warn(e,t,...n){this.shouldLog(o.WARN,t)&&console.warn(this.formatMessage("WARN",t,e),...n)}error(e,t,...n){this.shouldLog(o.ERROR,t)&&console.error(this.formatMessage("ERROR",t,e),...n)}group(e,t){this.shouldLog(o.DEBUG,t)&&console.group(this.formatMessage("GROUP",t,e))}groupEnd(){this.config.enabled&&console.groupEnd()}table(e,t){this.shouldLog(o.DEBUG,t)&&console.table(e)}enableTemporary(e=3e5){const t={...this.config};this.updateConfig({enabled:!0,level:o.DEBUG,categories:Object.keys(this.config.categories).reduce(((e,t)=>(e[t]=!0,e)),{})}),setTimeout((()=>{this.updateConfig(t)}),e)}getConfig(){return{...this.config}}}const a=i.getInstance()}},t={};function n(o){var i=t[o];if(void 0!==i)return i.exports;var a=t[o]={id:o,exports:{}};return e[o](a,a.exports,n),a.exports}
1n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var o in t)n.o(t,o)&&!n.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.nc=void 0,function(){"use strict";var e=n(5072),t=n.n(e),o=n(7825),i=n.n(o),a=n(7659),s=n.n(a),r=n(5056),d=n.n(r),l=n(540),c=n.n(l),u=n(1113),m=n.n(u),g=n(9051),h={};h.styleTagTransform=m(),h.setAttributes=d(),h.insert=s().bind(null,"head"),h.domAPI=i(),h.insertStyleElement=c();t()(g.A,h),g.A&&g.A.locals&&g.A.locals;var p=n(117),y={};y.styleTagTransform=m(),y.setAttributes=d(),y.insert=s().bind(null,"head"),y.domAPI=i(),y.insertStyleElement=c();t()(p.A,y),p.A&&p.A.locals&&p.A.locals;var C=new Promise((e=>{"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>e())):e()})),f=n(2910),v=n(8520),b=n(1916),w=n(7310);class S{constructor(e={}){this.initData=null,this.initDataTimestamp=null,this.navContainers=new Map,this.managedItems=new Map,S.isProcessing?b.vF.warn("DynamicHeaderNav initialization already in progress","init"):(this.config={navContainerSelectors:[".Page-header-end"],userMenuContainerSelectors:[".Page-header-end"],navItemCloneSelector:".Navigation-items > li:has(a[href])",navItemClass:"Navigation-items-item",initApiUrl:f.A.apiHeimguardInitUrl||"/api/heimguard/init",retryAttempts:3,retryDelay:1e3,cacheTimeout:3e5,...e},this.navItemsConfig=[{key:"login",text:"Login in",defaultHref:"/login",triggerAttr:"data-login-trigger",navRole:"login",defaultUseModal:!0,showWhen:"guest"},{key:"register",text:"Register",defaultHref:"/register",triggerAttr:"data-register-trigger",navRole:"register",defaultUseModal:!1,showWhen:"guest"},{key:"profile",text:"Profile",defaultHref:"/profile",triggerAttr:"data-profile-trigger",navRole:"profile",defaultUseModal:!0,showWhen:"authenticated"},{key:"logout",text:"Logout",defaultHref:"#",triggerAttr:"data-logout-trigger",navRole:"logout",defaultUseModal:!1,showWhen:"authenticated"}],this.debouncedReinitialize=this.debounce((()=>{this.initialize()}),500),this.initialize(),S.instances.add(this),window.addEventListener("heimguard:navigation:refresh",(()=>{b.vF.debug("Navigation refresh requested","init"),this.debouncedReinitialize()})))}async initialize(){try{S.isProcessing=!0,b.vF.debug("Initializing DynamicHeaderNav...","init"),await this.waitForDOM(),await w.default.load(),await this.fetchInitData(),this.findNavContainers(),this.createNavigationItems(),this.updateAuthState(),this.setupObservers(),b.vF.debug("DynamicHeaderNav initialized successfully","init"),this.emitEvent("initialized")}catch(e){b.vF.error("Failed to initialize DynamicHeaderNav:","init",e),this.handleInitError(e)}finally{S.isProcessing=!1}}async waitForDOM(){"loading"===document.readyState&&await new Promise((e=>{document.addEventListener("DOMContentLoaded",(()=>e()),{once:!0})}))}async fetchInitData(){try{b.vF.debug("Fetching init data via InitService...","init");const e=await v.default.getInitData();return this.initData={...e,heimguardSettings:e.config||e.heimguardSettings||{},user:e.user,authenticated:e.authenticated},this.initDataTimestamp=Date.now(),b.vF.debug("Init data fetched successfully","init"),this.initData}catch(e){return b.vF.warn("Failed to fetch init data, using fallback:","init",e.message),this.initData=this.getFallbackData(),this.initDataTimestamp=Date.now(),this.initData}}validateInitData(){if(!this.initData)return;const e=["login","register","profile"];for(const t of e)this.initData[t]&&"object"==typeof this.initData[t]||(b.vF.warn(`Invalid or missing config for "${t}", using defaults`,"init"),this.initData[t]=this.navItemsConfig.find((e=>e.key===t))||{})}getFallbackData(){const e={};return this.navItemsConfig.forEach((t=>{e[t.key]={url:t.defaultHref,useModal:t.defaultUseModal}})),e}findNavContainers(){if(this.navContainers.clear(),this.config.navContainerSelectors.forEac
1h((e=>{document.querySelectorAll(e).forEach(((t,n)=>{const o=`${e}-${n}`;this.navContainers.set(o,{element:t,selector:e,items:new Map}),b.vF.debug(`Found nav container: ${e}`,"init")}))})),0===this.navContainers.size)throw new Error("No navigation containers found")}createNavigationItems(){this.navContainers.forEach(((e,t)=>{try{this.isUserMenuContainer(e.selector)?this.createUserMenuInContainer(e):this.createItemsInContainer(e)}catch(e){b.vF.error(`Failed to create items in container ${t}:`,"init",e)}}))}isUserMenuContainer(e){return this.config.userMenuContainerSelectors.some((t=>e.includes(t)))}createItemsInContainer(e){const{element:t,items:n}=e;if(t.querySelector('[data-nav-managed="true"]'))return void b.vF.debug("Container already has managed nav items, skipping","init");const o=this.findTemplateItem(t);o?(this.clearManagedItems(t),this.navItemsConfig.forEach((e=>{try{if(!this.shouldShowItem(e))return;const i=this.createNavItem(o,e);i&&(t.appendChild(i),n.set(e.key,i))}catch(t){b.vF.error(`Failed to create nav item "${e.key}":`,"init",t)}}))):b.vF.warn("No template item found in container:","init",t)}findTemplateItem(e){let t=e.querySelector(this.config.navItemCloneSelector);return t||(t=e.querySelector("li")),t||(t=this.createDefaultTemplate()),t}createDefaultTemplate(){const e=document.createElement("li");e.className="Navigation-items-item";const t=document.createElement("div");t.className="NavigationItem-text";const n=document.createElement("a");return n.href="#",t.appendChild(n),e.appendChild(t),e}clearManagedItems(e){this.navItemsConfig.forEach((t=>{e.querySelectorAll(`[data-nav-role="${t.navRole}"]`).forEach((e=>{const t=e.closest(".Navigation-items-item");t&&t.remove()}))}))}getIsAuthenticated(){const e=window.HeimGuard?.AuthStateManager;if(e&&"function"==typeof e.isAuthenticated)return e.isAuthenticated();if(this.initData?.authenticated)return!0;return!!document.cookie.split(";").find((e=>e.trim().startsWith("heimguard.authStatus=")))}shouldShowItem(e){const t=this.getIsAuthenticated();switch(b.vF.debug(`Nav item "${e.key}" visibility check:`,"init",{showWhen:e.showWhen,isAuthenticated:t}),e.showWhen){case"guest":return!t;case"authenticated":return t;default:return!0}}clearManagedUserMenu(e){e.querySelectorAll('bsp-user-menu[data-nav-managed="true"]').forEach((e=>e.remove()))}createUserMenuInContainer(e){const{element:t}=e;this.clearManagedUserMenu(t);const n=this.getIsAuthenticated(),o=document.createElement("bsp-user-menu");o.setAttribute("data-nav-managed","true");const i=document.createElement("div");i.className="UserMenu";const a=document.createElement("div");a.className="UserMenu-trigger";const s=document.createElement("a");if(s.className="UserMenu-trigger-icon",s.href="#",s.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor"><path d="M230.92,212c-15.23-26.33-38.7-45.21-66.09-54.16a72,72,0,1,0-73.66,0C63.78,166.78,40.31,185.66,25.08,212a8,8,0,1,0,13.85,8c18.84-32.56,52.14-52,89.07-52s70.23,19.44,89.07,52a8,8,0,1,0,13.85-8ZM72,96a56,56,0,1,1,56,56A56.06,56.06,0,0,1,72,96Z"/></svg>',n||(s.setAttribute("data-login-trigger",""),s.setAttribute("data-nav-role","login")),a.appendChild(s),n){const e=document.createElement("span");e.className="UserMenu-trigger-chevron",e.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor"><path d="M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,53.66,90.34L128,164.69l74.34-74.35a8,8,0,0,1,11.32,11.32Z"/></svg>',a.appendChild(e)}if(i.appendChild(a),n){const e=document.createElement("ul");e.className="UserMenu-items";const t=document.createElement("li");t.className="UserMenu-items-item";const n=document.createElement("a");n.className="UserMenu-link",n.href="#",n.setAttribute("data-profile-trigger",""),n.setAttribute("data-nav-role","profile"),n.textContent="Profile",t.appendChild(n),e.appendChild(t);const o=document.createElement("li");o.className="UserMenu-items-item";const a=document.createElement("a");a.className="UserMenu-link",a.href="#",a.setAttribute("data-logout-trigger",""),a.setAttribute("data-nav-role","logout"),a.textContent="Log out",o.appendChild(a),e.appendChild(o),i.appendChild(e)}o.appendChild(i);const r=t.querySelector(".Page-header-menu-trigger");r?t.insertBefore(o,r):t.appendChild(o),b.vF.debug(`UserMenu created (authenticated: ${n})`,"init")}createNavItem(e,t){const n=e.cloneNode(!0);this.cleanupNavItem(n,t);let o=n.querySelector("a");if(!o){const e=n.querySelector(".NavigationItem-text")||n;o=document.createElement("a"),e.appendChild(o)}return this.configureAnchor(o,t),t.icon&&this.addIcon(o,t.icon),n.setAttribute("data-nav-key",t.key),n.setAttribute("data-nav-managed","true"),n}cleanupNavItem(e,t){e.classList.remove("hidden","uk-active","uk-open","active");["data-login-trigger","data-logout-trigger","data-profile-trigger","data-register-trigger","data-nav-role"].forEach((t=>{e.removeAttribute(t)}));e.querySelectorAll(".uk-navbar-dropdown, .Navigation-items-item-submenu, .submenu").forEach((e=>e.remove())),e.id&&(e.id=`nav-${t.key}-${Date.now()}`)}configureAnchor(e,t){const n=this.initData?.[t.key]||{},o=n.useModal??t.defaultUseModal,i=n.url||t.defaultHref,a="profile"===t.key&&w.default.isCabotWealth()?"My Profile":t.text;e.textContent=a,e.href=o?"#":i,e.setAttribute("data-nav-role",t.navRole),e.removeAttribute("uk-toggle"),e.removeAttribute("uk-tooltip"),o&&t.triggerAttr&&(e.hasAttribute(t.triggerAttr)||e.setAttribute(t.triggerAttr,"")),e.hasAttribute("role")||e.setAttribute("role","menuitem"),"logout"===t.key&&(e.hasAttribute("aria-label")||e.setAttribute("aria-label","Logout from your account"),e.hasAttribute("data-logout-trigger")||e.setAttribute("data-logout-trigger",""))}addIcon(e,t){const n=`icon-${t}`;if(!e.querySelector(".icon")){const t=document.createElement("span");t.className=`icon ${n}`,e.insertBefore(t,e.firstChild)}}updateAuthState(){const e=window.HeimGuard?.AuthStateManager;if(e)try{"function"==typeof e.updateNavAttributes&&e.updateNavAttributes(),"function"==typeof e.updateNavVisibility&&e.updateNavVisibility(),b.vF.debug("AuthStateManager UI updated","auth")}catch(e){b.vF.error("Failed to update AuthStateManager:","auth",e)}else b.vF.warn("AuthStateManager not available yet, navigation items already created based on init data","auth")}setupObservers(){this.observer&&this.observer.disconnect(),this.observer=new MutationObserver((e=>{e.some((e=>Array.from(e.addedNodes).some((e=>{if(1!==e.nodeType)return!1;const t=e;return this.config.navContainerSelectors.some((e=>t.matches?.(e)||t.querySelector?.(e)))}))))&&(b.vF.debug("Navigation structure changed, reinitializing...","init"),this.debouncedReinitialize())})),this.observer.observe(document.body,{childList:!0,subtree:!0})}debounce(e,t){let n;return function(...o){clearTimeout(n),n=setTimeout((()=>{clearTimeout(n),e(...o)}),t)}}delay(e){return new Promise((t=>setTimeout(t,e)))}handleInitError(e){this.emitEvent("error",{error:e});try{b.vF.debug("Attempting to create navigation with defaults...","init"),this.initData=this.getFallbackData(),this.findNavContainers(),this.createNavigationItems()}catch(e){b.vF.error("Fallback initialization also failed:","init",e)}}emitEvent(e,t={}){const n=new CustomEvent(`dynamicnav:${e}`,{detail:{...t,instance:this},bubbles:!0,cancelable:!0});document.dispatchEvent(n)}updateItems(){this.createNavigationItems(),this.updateAuthState()}async refresh(){this.initData=null,this.initDataTimestamp=null,await this.fetchInitData(),this.updateItems()}destroy(){this.observer&&this.observer.disconnect(),this.navContainers.forEac
1h((e=>{e.items.forEach((e=>{e&&e.parentNode&&e.remove()}))})),this.navContainers.clear(),this.managedItems.clear(),S.instances.delete(this),b.vF.debug("DynamicHeaderNav instance destroyed","init")}static destroyAll(){this.instances.forEach((e=>e.destroy())),this.instances.clear()}}S.instances=new Set,S.isProcessing=!1;var x=S,A=n(1667);var T=new class{constructor(){this.isRedirecting=!1,this.loginUrl=null,this.useModal=!1,this.profileUrl="/profile",this.lastProfileCheck=0,this.profileCheckDebounce=2e3}async initialize(){this.isRedirecting=!1,b.vF.debug("Starting initialization...","init");try{const e=(await Promise.resolve().then(n.bind(n,7310))).default,t=await e.load();if(b.vF.debug("HeimguardSettings loaded:","init",t),b.vF.debug("Settings type:","init",typeof t),b.vF.debug("Settings keys:","init",t?Object.keys(t):"null"),t?.login&&"object"==typeof t.login){const e=t.login;this.loginUrl=e.url||this.loginUrl,this.useModal=e.useModal||!1,b.vF.debug("Login URL set to:","init",this.loginUrl),b.vF.debug("Use modal:","init",this.useModal)}else b.vF.warn("No login config in settings","init");if(t?.profile&&"object"==typeof t.profile){const e=t.profile;this.profileUrl=e.url||this.profileUrl,b.vF.debug("Profile URL set to:","init",this.profileUrl)}b.vF.debug(`Initialized with loginUrl: ${this.loginUrl}, profileUrl: ${this.profileUrl}`,"init")}catch(e){b.vF.error("Failed to load settings:","init",e)}}shouldHandlePath(e){if(e.includes(f.A.apiGetProfileUrl)){b.vF.debug("Profile API 401 detected","init");const e=Date.now();if(e-this.lastProfileCheck<this.profileCheckDebounce)return b.vF.debug("Profile check debounced, ignoring","init"),!1;this.lastProfileCheck=e;const t=window.location.pathname;let n=this.profileUrl;try{n=new URL(this.profileUrl).pathname}catch(e){}return t===n||t.startsWith(n+"/")?(b.vF.debug("On protected page, will redirect","init"),!0):(b.vF.debug("Not on protected page, ignoring 401","init"),!1)}if(e.includes("/api/"))return b.vF.debug("Other API call, not redirecting","init"),!1;if(!this.profileUrl){const e=window.location.pathname;return"/profile"===e||e.startsWith("/profile/")}const t=window.location.pathname;let n=this.profileUrl;try{n=new URL(this.profileUrl).pathname}catch(e){}return b.vF.debug(`Checking path: ${t} against profile path: ${n}`,"init"),t===n||t.startsWith(n+"/")}handle401(e=window.location.pathname){b.vF.debug("handle401 called with path:","init",e),b.vF.debug("isRedirecting:","init",this.isRedirecting),b.vF.debug("loginUrl:","init",this.loginUrl),b.vF.debug("current pathname:","init",window.location.pathname);if(document.cookie.split("; ").find((e=>e.startsWith("heimguard.authStatus=")))&&(b.vF.debug("Auth cookie exists but got 401 - possible stale session","init"),this.clearAuthCookies()),this.isRedirecting)return void b.vF.debug("Already redirecting, skipping","init");if(this.loginUrl&&window.location.pathname===this.loginUrl)return void b.vF.debug("Already on login page, skipping","init");if(!this.shouldHandlePath(e))return void b.vF.debug("Path should not trigger redirect:","init",e);this.isRedirecting=!0;const t=window.location.pathname+window.location.search+window.location.hash,n=encodeURIComponent(t);try{const e=A.systemRegistry.get("authStateManager");e&&"function"==typeof e.clearAuthState&&e.clearAuthState()}catch(e){b.vF.warn("Failed to clear auth state:","init",e)}if(sessionStorage.setItem("heimguard_auth_message","You need to be logged in to access this page"),sessionStorage.setItem("heimguard_auth_message_type","info"),!this.loginUrl)return b.vF.error("No login URL configured - cannot redirect","init"),this.isRedirecting=!1,void b.vF.warn("Authentication required but no login URL available","init");const o=`${this.loginUrl}?return=${n}`;b.vF.debug("Redirecting to:","init",o),b.vF.debug("Current location:","init",window.location.href),setTimeout((()=>{this.isRedirecting=!1}),100);try{window.location.href=o,b.vF.debug("Redirect initiated successfully","init")}catch(e){b.vF.error("Redirect failed:","init",e),this.isRedirecting=!1}}setupEventListener(){b.vF.debug("Setting up event listener for heimguard:unauthorized","init");const e=e=>{b.vF.debug("!!!! Received heimguard:unauthorized event !!!!","init",e);const t=e,n=t.detail?.path||window.location.pathname;b.vF.debug("Event detail:","init",t.detail),b.vF.debug("Request path:","init",n),b.vF.debug("Current loginUrl:","init",this.loginUrl),b.vF.debug("Current isRedirecting:","init",this.isRedirecting),this.handle401(n)};window.addEventListener("heimguard:unauthorized",e),window.__global401Handler=this,window.__global401HandlerListener=e,b.vF.debug('Event listener attached. Test with: window.dispatchEvent(new CustomEvent("heimguard:unauthorized", { detail: { path: "/profile", status: 401 } }))',"init")}setupFetchInterceptor(){const e=window.fetch;window.fetch=function(t,n){return e.apply(this,[t,n]).then((e=>{const n="string"==typeof t?t:t.toString();if(401===e.status&&n.includes("/api/")){b.vF.debug("Intercepted 401 from:","init",n),n.includes(f.A.apiGetProfileUrl)?b.vF.debug("Profile API endpoint 401 detected","init"):n.includes("/api/heimguard/")&&b.vF.debug("Other Heimguard API endpoint 401:","init",n);const e=n.includes(f.A.apiGetProfileUrl)?500:0;setTimeout((()=>{window.dispatchEvent(new CustomEvent("heimguard:unauthorized",{detail:{path:n,status:401}}))}),e)}return e}))}}clearAuthCookies(){["heimguard.authStatus","heimguard.user","heimguard.token","heimguard.session"].forEach((e=>{document.cookie=`${e}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`,document.cookie=`${e}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${window.location.hostname};`;const t=window.location.hostname.split(".");if(t.length>2){const n=t.slice(-2).join(".");document.cookie=`${e}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.${n};`}})),b.vF.debug("Cleared auth cookies","init")}};class M{constructor(){this.currentTheme="default",this.loadSavedTheme(),this.loadCMSTheme().catch((()=>{})),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>this.loadCMSTheme())):setTimeout((()=>this.loadCMSTheme()),100)}static getInstance(){return M.instance||(M.instance=new M),M.instance}setTheme(e){this.currentTheme=e,"default"===e?document.documentElement.removeAttribute("data-theme"):document.documentElement.setAttribute("data-theme",e),localStorage.setItem("heimguard-theme",e)}getTheme(){return this.currentTheme}setCustomColors(e){const t=document.documentElement;
1e.primary&&Object.entries(e.primary).forEach((([e,n])=>{if("string"==typeof n&&n.includes(" "))t.style.setProperty(`--color-primary-${e}`,n);else{const o=this.hexToRgb(n);if(o){const n=`${o.r} ${o.g} ${o.b}`;t.style.setProperty(`--color-primary-${e}`,n)}}})),e.secondary&&Object.entries(e.secondary).forEach((([e,n])=>{if("string"==typeof n&&n.includes(" "))t.style.setProperty(`--color-secondary-${e}`,n);else{const o=this.hexToRgb(n);if(o){const n=`${o.r} ${o.g} ${o.b}`;t.style.setProperty(`--color-secondary-${e}`,n)}}})),this.setTheme("custom"),localStorage.setItem("heimguard-custom-colors",JSON.stringify(e))}loadSavedTheme(){const e=localStorage.getItem("heimguard-theme");if(e&&(this.setTheme(e),"custom"===e)){const e=localStorage.getItem("heimguard-custom-colors");if(e)try{const t=JSON.parse(e);this.setCustomColors(t)}catch(e){}}}async loadCMSTheme(){try{let e=window.HeimGuard?.initService?.getInitData?await window.HeimGuard.initService.getInitData():null;if(!e){const t=(await Promise.resolve().then(n.bind(n,8520))).default;e=await t.getInitData()}
1if(e?.theme){const{primaryColor:t,secondaryColor:n,preset:o,autoGenerateShades:i,customShades:a}=e.theme;if(t||n){const e={};if(t)if(!1!==i)e.primary=this.generateColorShades(t);else if(a)try{const t=JSON.parse(a);e.primary=t.primary}catch(n){e.primary=this.generateColorShades(t)}if(n)if(!1!==i)e.secondary=this.generateColorShades(n);else if(a)try{const t=JSON.parse(a);e.secondary=t.secondary}catch(t){e.secondary=this.generateColorShades(n)}this.setCustomColors(e)}}}catch(e){}}generateColorShades(e){const t=this.hexToRgb(e);if(!t)return null;const n={},o=this.rgbToHsl(t.r,t.g,t.b);return Object.entries({50:.95,100:.9,200:.82,300:.7,400:.58,500:.5,600:.42,700:.36,800:.28,900:.2}).forEach((([e,t])=>{const i=this.hslToRgb(o.h,o.s,t);n[e]=`${i.r} ${i.g} ${i.b}`})),n}hexToRgb(e){const t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return t?{r:parseInt(t[1],16),g:parseInt(t[2],16),b:parseInt(t[3],16)}:null}rgbToHsl(e,t,n){e/=255,t/=255,n/=255;const o=Math.max(e,t,n),i=Math.min(e,t,n);let a=0,s=0;const r=(o+i)/2;if(o!==i){const d=o-i;switch(s=r>.5?d/(2-o-i):d/(o+i),o){case e:a=((t-n)/d+(t<n?6:0))/6;break;case t:a=((n-e)/d+2)/6;break;case n:a=((e-t)/d+4)/6}}return{h:a,s:s,l:r}}hslToRgb(e,t,n){let o,i,a;if(0===t)o=i=a=n;else{const s=(e,t,n)=>(n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e),r=n<.5?n*(1+t):n+t-n*t,d=2*n-r;o=s(d,r,e+1/3),i=s(d,r,e),a=s(d,r,e-1/3)}return{r:Math.round(255*o),g:Math.round(255*i),b:Math.round(255*a)}}static getColorReplacementMap(){return{"indigo-50":"primary-50","indigo-100":"primary-100","indigo-200":"primary-200","indigo-300":"primary-300","indigo-400":"primary-400","indigo-500":"primary-500","indigo-600":"primary-600","indigo-700":"primary-700","indigo-800":"primary-800","indigo-900":"primary-900","purple-50":"secondary-50","purple-100":"secondary-100","purple-200":"secondary-200","purple-300":"secondary-300","purple-400":"secondary-400","purple-500":"secondary-500","purple-600":"secondary-600","purple-700":"secondary-700","purple-800":"secondary-800","purple-900":"secondary-900"}}}const E=M.getInstance();var P=n(7411);class N{constructor(){this.autoCloseTimeout=null,this.escapeHandler=null,this.checkForVerificationParams(),this.setupEventListeners()}checkForVerificationParams(){const e=new URLSearchParams(window.location.search),t=e.get("verified"),n=e.get("message");"true"===t&&"email_verified"===n&&(this.handleVerificationSuccess(),this.cleanUpUrl())}handleVerificationSuccess(){this.showVerificationSuccessModal(),this.updateProfileVerificationStatus();const e=new CustomEvent("heimguard:email:verified",{detail:{verified:!0},bubbles:!0});document.dispatchEvent(e)}updateProfileVerificationStatus(){document.querySelectorAll("[data-verification-badge]").forEach((e=>{e.classList.remove("hidden")}));const e=A.systemRegistry.get("profileSystem");e&&e.profileData&&(e.profileData.isVerified=!0,e.refreshProfile())}showVerificationSuccessModal(){document.body.insertAdjacentHTML("beforeend",N.MODAL_HTML),this.addAnimationStyles(),requestAnimationFrame((()=>{const e=document.getElementById("verification-modal"),t=document.getElementById("verification-modal-content");e&&t&&(e.classList.add("opacity-100"),t.classList.remove("scale-95","opacity-0"),t.classList.add("scale-100","opacity-100"))})),this.autoCloseTimeout=window.setTimeout((()=>{this.closeModal()}),15e3),this.setupModalEventListeners()}setupModalEventListeners(){const e=document.getElementById("verification-modal");e&&(e.addEventListener("click",(t=>{t.target===e&&this.closeModal()})),this.escapeHandler=e=>{"Escape"===e.key&&this.closeModal()},document.addEventListener("keydown",this.escapeHandler))}closeModal(){const e=document.getElementById("verification-modal"),t=document.getElementById("verification-modal-content");e&&t&&(e.classList.remove("opacity-100"),t.classList.remove("scale-100","opacity-100"),t.classList.add("scale-95","opacity-0"),setTimeout((()=>{e.remove()}),300)),null!==this.autoCloseTimeout&&(clearTimeout(this.autoCloseTimeout),this.autoCloseTimeout=null),this.escapeHandler&&(document.removeEventListener("keydown",this.escapeHandler),this.escapeHandler=null)}cleanUpUrl(){const e=new URL(window.location.href);e.searchParams.delete("verified"),e.searchParams.delete("message"),window.history.replaceState({},"",e.toString())}setupEventListeners(){document.addEventListener("heimguard:profile:updated",(e=>{e.detail?.profileData?.isVerified&&this.updateProfileVerificationStatus()}))}addAnimationStyles(){document.getElementById("verification-modal-styles")||document.head.insertAdjacentHTML("beforeend",N.ANIMATION_
1STYLES)}destroy(){null!==this.autoCloseTimeout&&(clearTimeout(this.autoCloseTimeout),this.autoCloseTimeout=null),this.escapeHandler&&(document.removeEventListener("keydown",this.escapeHandler),this.escapeHandler=null);const e=document.getElementById("verification-modal");e&&e.remove()}}N.MODAL_HTML=`\n <div id="verification-modal" class="fixed inset-0 bg-gray-500 bg-opacity-75 flex items-center justify-center z-50 transition-opacity duration-300">\n <div class="bg-white rounded-xl shadow-2xl px-8 py-6 max-w-md mx-auto transform transition-all duration-300 scale-95 opacity-0" id="verification-modal-content">\n \x3c!-- Success Icon with Animation --\x3e\n <div class="relative mb-6">\n <div class="flex items-center justify-center w-16 h-16 mx-auto bg-green-100 rounded-full">\n ${P.H.render("check",{class:"w-8 h-8 text-green-600 animate-scale-in"})}\n </div>\n \x3c!-- Ripple Effect --\x3e\n <div class="absolute inset-0 flex items-center justify-center">\n <div class="w-16 h-16 bg-green-200 rounded-full animate-ping"></div>\n </div>\n </div>\n\n <h3 class="text-xl font-bold text-center text-gray-900 mb-3">\n Your email has been successfully verified!\n </h3>\n\n <div class="flex gap-3">\n <button onclick="document.getElementById('verification-modal').remove()"\n class="flex-1 px-6 py-3 bg-primary-600 text-white font-medium rounded-lg hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 transition-all transform hover:scale-105">\n Explore My Profile\n </button>\n <button onclick="window.location.href='/'"\n class="px-6 py-3 bg-gray-200 text-gray-700 font-medium rounded-lg hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 transition-colors">\n Browse Site\n </button>\n </div>\n </div>\n </div>\n `,N.ANIMATION_STYLES='\n <style id="verification-modal-styles">\n @keyframes scale-in {\n 0% {\n transform: scale(0);\n opacity: 0;\n }\n 50% {\n transform: scale(1.1);\n }\n 100% {\n transform: scale(1);\n opacity: 1;\n }\n }\n\n .animate-scale-in {\n animation: scale-in 0.5s ease-out 0.3s both;\n }\n\n @keyframes ping {\n 75%, 100% {\n transform: scale(2);\n opacity: 0;\n }\n }\n\n .animate-ping {\n animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;\n }\n\n /* Smooth transitions for modal */\n #verification-modal {\n transition: opacity 0.3s ease-out;\n }\n\n #verification-modal-content {\n transition: all 0.3s ease-out;\n }\n </style>\n ';var L=N,D=n(8200);class I{constructor(e="/api/heimguard"){this.baseUrl=e,this.defaultHeaders={"Content-Type":"application/json",Accept:"application/json"},this.silent=!1}async request(e,t={}){console.log("[BaseAPIService.request] Start - endpoint:",e);const n=(this.baseUrl.startsWith("/api"),`${this.baseUrl}${e}`);this.silent||t.silent||console.log("ð API Request:",{url:n,method:t.method||"GET",endpoint:e,baseUrl:this.baseUrl});const o={credentials:"include",headers:{...this.defaultHeaders,...t.headers},...t};t.body instanceof FormData&&delete o.headers["Content-Type"];try{const e=await fetch(n,o),i=e.headers.get("content-type");let a;if(i&&i.includes("application/json"))try{a=await e.json()}catch(t){console.error("JSON parsing failed:",t);const n=await e.text();console.error("Raw response:",n),a={message:"Invalid JSON response from server",rawResponse:n.substring(0,200)}}else if(i&&i.includes("text/"))a=await e.text();else if(e.ok)a={};else try{a=await e.text()}catch{a=await e.blob()}if(!e.ok)throw this.silent||t.silent||console.error("API Error Response:",{status:e.status,statusText:e.statusText,data:a}),new k(e.status,e.statusText,a,n);return a}catch(e){if(e instanceof k)throw e;throw this.silent||t.silent||console.error("API Request failed:",e),new k(0,e instanceof Error?e.name:"Network Error",{message:e instanceof Error?e.message:"Failed to connect to server"},n)}}async get(e,t={}){const n=new URLSearchParams(t).toString(),o=n?`${e}?${n}`:e;return this.request(o,{method:"GET"})}async post(e,t){return console.log("[BaseAPIService.post] Called with endpoint:",e,"data:",t),this.request(e,{method:"POST",body:t instanceof FormData?t:JSON.stringify(t)})}async put(e,t){return this.request(e,{method:"PUT",body:t instanceof FormData?t:JSON.stringify(t)})}async delete(e){return this.request(e,{method:"DELETE"})}async patch(e,t){return this.request(e,{method:"PATCH",body:JSON.stringify(t)})}handleError(e){throw console.error("API Error:",e),e instanceof k&&401===e.status&&this.handleUnauthorized(e.url),e}handleUnauthorized(e){window.dispatchEvent(new CustomEvent("heimguard:unauthorized",{detail:{path:e||window.location.pathname,status:401}}))}setDefaultHeader(e,t){null==t?delete this.defaultHeaders[e]:this.defaultHeaders[e]=t}withBaseUrl(e){const t=new this.constructor(e);return t.defaultHeaders={...this.defaultHeaders},t}}
1class k extends Error{constructor(e,t,n,o){super(n?.message||n?.error||t||"API Error"),this.name="APIError",this.status=e,this.statusText=t,this.data=n,this.url=o}is(e){return this.status===e}getUserMessage(){switch(this.status){case 400:return this.data?.message||"Invalid request. Please check your input.";case 401:return"You need to be logged in to perform this action.";case 403:return"You do not have permission to perform this action.";case 404:return"The requested resource was not found.";case 409:return this.data?.message||"A conflict occurred. Please try again.";case 422:return this.data?.message||"Validation failed. Please check your input.";case 429:return"Too many requests. Please try again later.";case 500:return"A server error occurred. Please try again later.";case 0:return"Network error. Please check your connection.";default:return this.message||"An unexpected error occurred."}}getValidationErrors(){return 422===this.status&&this.data?.errors?this.data.errors:{}}}class O{constructor(e={}){this.baseUrl=e.baseUrl||f.A.apiBaseUrl||"/api/heimguard",this.timeout=e.timeout||3e4,this.credentials=e.credentials||"include"}getEndpoint(e){return e.startsWith("/api/")?e:`${this.baseUrl}${e}`}async request(e,t={}){const n=new AbortController,o=setTimeout((()=>n.abort()),this.timeout),i={credentials:this.credentials,headers:{Accept:"application/json",...t.headers},signal:n.signal};t.body&&"string"==typeof t.body&&(i.headers["Content-Type"]="application/json");try{const n=await fetch(e,{...i,...t});clearTimeout(o);const a=n.headers.get("content-type");let s=null;if(s=a&&a.includes("application/json")?await n.json():await n.text(),!n.ok)throw new k(n.status,n.statusText,s,e);return{ok:!0,status:n.status,data:s,headers:n.headers}}catch(t){if(clearTimeout(o),t instanceof Error&&"AbortError"===t.name)throw new k(408,"Request Timeout",{message:"Request timeout"},e);if(t instanceof TypeError&&t.message.includes("fetch"))throw new k(0,"Network Error",{message:"Network error - please check your connection"},e);if(t instanceof k)throw t;throw new k(0,"Unknown Error",{message:t instanceof Error?t.message:"Unknown error"},e)}}async get(e,t={}){return this.request(this.getEndpoint(e),{method:"GET",...t})}async post(e,t,n={}){return this.request(this.getEndpoint(e),{method:"POST",body:JSON.stringify(t),...n})}async put(e,t,n={}){return this.request(this.getEndpoint(e),{method:"PUT",body:JSON.stringify(t),...n})}async delete(e,t={}){return this.request(this.getEndpoint(e),{method:"DELETE",...t})}async login(e){return this.post(f.A.apiLoginUrl,e)}async logout(){return this.post(f.A.apiLogoutUrl,{})}async register(e){return this.post(f.A.apiRegisterUrl,e)}async resetPassword(e){return this.post(f.A.apiResetPasswordUrl,e)}async setNewPassword(e){return this.post(f.A.apiSetPasswordUrl,e)}async changePassword(e){return this.post(f.A.apiChangePasswordUrl,e)}async validateSession(){return this.get(f.A.apiGetProfileUrl)}async completeTwoFactor(e){return this.post(f.A.apiTwoFactorUrl,e)}async setupTwoFactor(){return this.post(f.A.apiTwoFactorSetupUrl,{})}async disableTwoFactor(e){return this.post(f.A.apiTwoFactorResetUrl,{password:e})}async generateBackupCodes(){return this.post(f.A.apiBackupCodesGenerateUrl,{})}async sendMagicLink(e){return this.post(f.A.apiPasswordlessEmailUrl,e)}async verifyMagicLink(e){return this.post(f.A.apiPasswordlessLoginUrl,e)}async checkMagicLinkStatus(e){return this.post(f.A.apiPasswordlessStatusUrl,{token:e})}async getGoogleAuthUrl(){return this.get(f.A.apiGoogleLoginUrl)}async googleCallback(e){return this.post(f.A.apiGoogleCallbackUrl,e)}async googleLogout(){return this.post(f.A.apiGoogleLogoutUrl,{})}async linkGoogleAccount(){return this.post(f.A.apiGoogleLinkUrl,{})}async unlinkGoogleAccount(){return this.post(f.A.apiGoogleUnlinkUrl,{})}async getFacebookAuthUrl(){return this.get(f.A.apiFacebookLoginUrl)}async facebookCallback(e){return this.post(f.A.apiFacebookCallbackUrl,e)}async linkFacebookAccount(){return this.post(f.A.apiFacebookLinkUrl,{})}async unlinkFacebookAccount(){return this.post(f.A.apiFacebookUnlinkUrl,{})}async getProfile(){return this.get(f.A.apiGetProfileUrl)}async updateProfile(e){return this.put(f.A.apiEditProfileUrl,e)}async uploadAvatar(e){const t=new FormData;return t.append("avatar",e),this.request(this.getEndpoint(f.A.apiProfileAvatarUrl),{method:"POST",body:t,headers:{Accept:"application/json"}})}async verifyEmail(e){return this.post(f.A.apiVerifyEmailUrl,e)}async resendVerificationEmail(){return this.post(f.A.apiResendVerificationUrl,{})}}const R=new O;var B=n(7147);class $ extends B.z{static render(e){return super.render({type:"email",placeholder:e.placeholder||"[email protected]",autocomplete:"email",...e})}static validate(e,t={}){const n=super.validate(e,t),o=String(e||"");if(o&&!this.isValidEmail(o)&&n.push("Please enter a valid email address"),o&&!1!==t.checkTypos){const e=this.checkCommonTypos(o);e&&n.push(e)}return n}static isValidEmail(e){return/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(e)}static checkCommonTypos(e){const t={"gmial.com":"Did you mean gmail.com?","gmai.com":"Did you mean gmail.com?","gmil.com":"Did you mean gmail.com?","yahooo.com":"Did you mean yahoo.com?","yaho.com":"Did you mean yahoo.com?","homail.com":"Did you mean hotmail.com?","hotmial.com":"Did you mean hotmail.com?","outlok.com":"Did you mean outlook.com?","iclould.com":"Did you mean icloud.com?"},n=e.split("@")[1];return n&&t[n.toLowerCase()]?t[n.toLowerCase()]:null}static normalize(e){return e.trim().toLowerCase()}static getDomain(e){const t=e.split("@");return 2===t.length?t[1]:null}static getUsername(e){const t=e.split("@");return 2===t.length?t[0]:null}static isFreeProvider(e){const t=this.getDomain(e);return!!t&&["gmail.com","yahoo.com","hotmail.com","outlook.com","aol.com","mail.com","protonmail.com","icloud.com","yandex.com","gmx.com"].includes(t.toLowerCase())}static isDisposableProvider(e){const t=this.getDomain(e);return!!t&&["tempmail.com","throwaway.email","guerrillamail.com","10minutemail.com","mailinator.com","maildrop.cc","trashmail.com","fakeinbox.com","yopmail.com"].includes(t.toLowerCase())}static suggestCorrection(e){const t=this.getDomain(e);if(!t)return null;const n={"gmial.com":"gmail.com","gmai.com":"gmail.com","gmil.com":"gmail.com","yahooo.com":"yaho
1o.com","yaho.com":"yahoo.com","homail.com":"hotmail.com","hotmial.com":"hotmail.com","outlok.com":"outlook.com","iclould.com":"icloud.com"}[t.toLowerCase()];if(n){return`${this.getUsername(e)}@${n}`}return null}}class U extends B.z{static render(e){const{showToggle:t=!0,showStrength:n=!1,...o}=e,i=o.id||`field-${o.name}`,a=super.render({type:"password",autocomplete:o.autocomplete||"current-password",...o,inputClassName:t?`${o.inputClassName||""} !pr-10`.trim():o.inputClassName});if(!t&&!n)return a;let s=a;return t&&(s=e.icon?s.replace(/(<input[^>]+>)(\s*<\/div>)/,`$1${this.renderToggleButton(i)}$2`):s.replace(/(<input[^>]+>)/,`<div class="relative">$1${this.renderToggleButton(i)}</div>`)),n&&(s+=this.renderStrengthIndicator(i)),s}static renderToggleButton(e){return`\n <button\n type="button"\n class="toggle-password absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 hover:text-gray-600 focus:outline-none focus:text-gray-600 z-10"\n data-target="${e}"\n aria-label="Toggle password visibility"\n tabindex="-1"\n >\n <svg class="show-password h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />\n </svg>\n <svg class="hide-password h-5 w-5 hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" />\n </svg>\n </button>\n `}static renderStrengthIndicator(e){return`\n <div id="${e}-strength" class="mt-2 hidden">\n <div class="flex justify-between mb-1">\n <span class="text-xs text-gray-600">Password strength</span>\n <span class="text-xs text-gray-600 strength-text"></span>\n </div>\n <div class="w-full bg-gray-200 rounded-full h-1.5">\n <div class="strength-bar h-1.5 rounded-full transition-all duration-300" style="width: 0%"></div>\n </div>\n </div>\n `}static validate(e,t={}){const n=super.validate(e,t),o=String(e||"");if(!o)return n;const i=t.minLength||4,a=t.requireUppercase||!1,s=t.requireLowercase||!1,r=t.requireNumbers||!1,d=t.requireSpecialChars||!1,l=!1!==t.checkWeak;return o.length<i&&n.push(`Password must be at least ${i} characters`),a&&!/[A-Z]/.test(o)&&n.push("Password must contain at least one uppercase letter"),s&&!/[a-z]/.test(o)&&n.push("Password must contain at least one lowercase letter"),r&&!/[0-9]/.test(o)&&n.push("Password must contain at least one number"),d&&!/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(o)&&n.push("Password must contain at least one special character"),l&&this.isWeakPassword(o)&&n.push("This password is too common. Please choose a stronger password."),n}static isWeakPassword(e){return["password","12345678","123456789","qwerty","abc123","password123","11111111","iloveyou","welcome","monkey","dragon","sunshine","princess","football","baseball"].includes(e.toLowerCase())}static calculateStrength(e){if(!e)return{score:0,level:"None",color:"bg-gray-200"};let t=0;return e.length>=8&&(t+=1),e.length>=12&&(t+=1),e.length>=16&&(t+=1),/[a-z]/.test(e)&&(t+=1),/[A-Z]/.test(e)&&(t+=1),/[0-9]/.test(e)&&(t+=1),/[^a-zA-Z0-9]/.test(e)&&(t+=2),/(.)\1{2,}/.test(e)&&(t-=1),/^[0-9]+$/.test(e)&&(t-=1),/^[a-zA-Z]+$/.test(e)&&(t-=1),t=Math.max(0,Math.min(t,8)),t<=2?{score:25,level:"Weak",color:"bg-red-500"}:t<=4?{score:50,level:"Fair",color:"bg-yellow-500"}:t<=6?{score:75,level:"Good",color:"bg-green-500"}:{score:100,level:"Strong",color:"bg-green-600"}}static attachToggleHandler(e){e.querySelectorAll(".toggle-password").forEach((e=>{e.addEventListener("click",(t=>{t.preventDefault();const n=e.dataset.target;if(!n)return;const o=document.getElementById(n);if(!o)return;const i=e.querySelector(".show-password"),a=e.querySelector(".hide-password");i&&a&&("password"===o.type?(o.type="text",i.classList.add("hidden"),a.classList.remove("hidden")):(o.type="password",i.classList.remove("hidden"),a.classList.add("hidden")))}))}))}
1static attachStrengthHandler(e){const t=document.getElementById(`${e.id}-strength`);if(!t)return;const n=t.querySelector(".strength-bar"),o=t.querySelector(".strength-text");n&&o&&e.addEventListener("input",(()=>{const i=e.value;if(!i)return void t.classList.add("hidden");t.classList.remove("hidden");const a=this.calculateStrength(i);n.style.width=`${a.score}%`,n.className=`strength-bar h-1.5 rounded-full transition-all duration-300 ${a.color}`,o.textContent=a.level,o.className=`text-xs strength-text ${a.color.replace("bg-","text-")}`}))}static generatePassword(e=16,t={}){const n={uppercase:!0,lowercase:!0,numbers:!0,symbols:!0,...t};let o="";if(n.lowercase&&(o+="abcdefghijklmnopqrstuvwxyz"),n.uppercase&&(o+="ABCDEFGHIJKLMNOPQRSTUVWXYZ"),n.numbers&&(o+="0123456789"),n.symbols&&(o+="!@#$%^&*()_+-=[]{}|;:,.<>?"),!o)return"";let i="";const a=new Uint32Array(e);crypto.getRandomValues(a);for(let t=0;t<e;t++)i+=o[a[t]%o.length];return i}static passwordsMatch(e,t){return e===t}static getRequirementsText(e={}){const t=[];return e.minLength&&t.push(`At least ${e.minLength} characters`),e.requireUppercase&&t.push("One uppercase letter"),e.requireLowercase&&t.push("One lowercase letter"),e.requireNumbers&&t.push("One number"),e.requireSpecialChars&&t.push("One special character"),t}}var F=n(744);function z(e){if(!e)return!1;return/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(e)}function H(e){if(!e||!e.includes("@"))return null;const t={"gmial.com":"gmail.com","gmai.com":"gmail.com","gmil.com":"gmail.com","yahooo.com":"yahoo.com","yaho.com":"yahoo.com","homail.com":"hotmail.com","hotmial.com":"hotmail.com","outlok.com":"outlook.com","iclould.com":"icloud.com"},n=e.split("@")[1]?.toLowerCase();return n&&t[n]?`Did you mean ${t[n]}?`:null}function G(e,t="US"){if(!e)return!1;const n=e.replace(/\D/g,""),o={US:/^1?[2-9]\d{2}[2-9]\d{6}$/,UK:/^(?:44)?7\d{9}$/,CA:/^1?[2-9]\d{2}[2-9]\d{6}$/,AU:/^(?:61)?4\d{8}$/,DE:/^(?:49)?1[5-7]\d{8,9}$/,FR:/^(?:33)?[67]\d{8}$/,JP:/^(?:81)?[789]0\d{8}$/,IN:/^(?:91)?[6-9]\d{9}$/};return(o[t]||o.US).test(n)}const _={login:{email:{required:!0,validate:e=>{if(!z(e))return"Please enter a valid email address";const t=H(e);return t||null}},password:{required:!0,validate:e=>!e||e.length<1?"Password is required":null}},register:{email:{required:!0,validate:e=>{if(!z(e))return"Please enter a valid email address";const t=H(e);return t||null}},password:{required:!0,validate:e=>!e||e.length<1?"Password is required":null},confirmPassword:{required:!0,validate:(e,t)=>e!==t?.password?"Passwords do not match":null},agreeTerms:{required:!0,validate:e=>e?null:"You must agree to the terms to continue"}},forgotPassword:{email:{required:!0,validate:e=>z(e)?null:"Please enter a valid email address"}},resetPassword:{password:{required:!0,validate:e=>!e||e.length<1?"Password is required":null},confirmPassword:{required:!0,validate:(e,t)=>e!==t?.password?"Passwords do not match":null}},profile:{firstName:{required:!0,minLength:2,pattern:/^[a-zA-Z\s'-]+$/,validate:e=>e.length<2?"First name must be at least 2 characters":/^[a-zA-Z\s'-]+$/.test(e)?null:"First name can only contain letters, spaces, hyphens, and apostrophes"},lastName:{required:!0,minLength:2,pattern:/^[a-zA-Z\s'-]+$/,validate:e=>e.length<2?"Last name must be at least 2 characters":/^[a-zA-Z\s'-]+$/.test(e)?null:"Last name can only contain letters, spaces, hyphens, and apostrophes"},email:{required:!0,validate:e=>z(e)?null:"Please enter a valid email address"},phone:{required:!1,validate:e=>e&&!G(e)?"Please enter a valid phone number":null}}};function K(e,t){const n={};for(const[o,i]of Object.entries(t)){const t=e[o];if(!i.required||t&&("string"!=typeof t||t.trim())){if(t||i.required){if(i.validate&&"function"==typeof i.validate){const a=i.validate(t,e);if(a){n[o]=a;continue}}i.pattern&&!i.pattern.test(t)&&(n[o]=i.patternMessage||`${o} format is invalid`),"string"==typeof t&&(i.minLength&&t.length<i.minLength&&(n[o]=i.minLengthMessage||`${o} must be at least ${i.minLength} characters`),i.maxLength&&t.length>i.maxLength&&(n[o]=i.maxLengthMessage||`${o} must not exceed ${i.maxLength} characters`))}}else n[o]=i.requiredMessage||`${o} is required`}return{isValid:0===Object.keys(n).length,errors:n}}const j={email:z,phone:G,password:function(e,t={}){if(!e)return{valid:!1,errors:["Password is required"]};const n={minLength:4,maxLength:128,requireUppercase:!1,requireLowercase:!1,requireNumbers:!1,requireSpecialChars:!1,disallowSpaces:!1,disallowCommon:!0,...t},o=[];if(e.length<n.minLength&&o.push(`Password must be at least ${n.minLength} characters`),e.length>n.maxLength&&o.push(`Password must not exceed ${n.maxLength} characters`),n.requireUppercase&&!/[A-Z]/.test(e)&&o.push("Password must contain at least one uppercase letter"),n.requireLowercase&&!/[a-z]/.test(e)&&o.push("Password must contain at least one lowercase letter"),n.requireNumbers&&!/[0-9]/.test(e)&&o.push("Password must contain at least one number"),n.requireSpecialChars&&!
1/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(e)&&o.push("Password must contain at least one special character"),n.disallowSpaces&&/\s/.test(e)&&o.push("Password must not contain spaces"),n.disallowCommon){["password","password123","12345678","123456789","qwerty","abc123","111111","iloveyou","welcome","admin","letmein","monkey","dragon","sunshine","princess","football","baseball","11111111","password1"].includes(e.toLowerCase())&&o.push("This password is too common. Please choose a stronger password")}return{valid:0===o.length,errors:o}},url:function(e){if(!e)return!1;try{const t=new URL(e);return"http:"===t.protocol||"https:"===t.protocol}catch{try{return new URL(`https://${e}`),!0}catch{return!1}}},creditCard:function(e){if(!e)return!1;const t=e.replace(/\D/g,"");if(t.length<13||t.length>19)return!1;let n=0,o=!1;for(let e=t.length-1;e>=0;e--){let i=parseInt(t[e]);o&&(i*=2,i>9&&(i-=9)),n+=i,o=!o}return n%10==0},postalCode:function(e,t="US"){if(!e)return!1;const n={US:/^\d{5}(-\d{4})?$/,UK:/^[A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}$/i,CA:/^[A-Z]\d[A-Z] ?\d[A-Z]\d$/i,AU:/^\d{4}$/,DE:/^\d{5}$/,FR:/^\d{5}$/,JP:/^\d{3}-?\d{4}$/,IN:/^\d{6}$/};return(n[t]||n.US).test(e)},date:function(e,t={}){if(!e)return!1;const n=e instanceof Date?e:new Date(e);if(isNaN(n.getTime()))return!1;const o=new Date;if(t.min){if(n<(t.min instanceof Date?t.min:new Date(t.min)))return!1}if(t.max){if(n>(t.max instanceof Date?t.max:new Date(t.max)))return!1}return!(!1===t.past&&n<o)&&!(!1===t.future&&n>o)},age:function(e,t=0,n=120){if(!e)return!1;const o=e instanceof Date?e:new Date(e);if(isNaN(o.getTime()))return!1;const i=new Date,a=Math.floor((i.getTime()-o.getTime())/315576e5);return a>=t&&a<=n},file:function(e,t={}){const n={maxSize:10485760,allowedTypes:[],allowedExtensions:[],...t};if(!e)return!1;if(e.size>n.maxSize)return!1;if(n.allowedTypes.length>0){if(!n.allowedTypes.some((t=>{if(t.includes("*")){const[n]=t.split("/");return e.type.startsWith(n+"/")}return e.type===t})))return!1}if(n.allowedExtensions.length>0){const t=e.name.split(".").pop()?.toLowerCase();if(!t||!n.allowedExtensions.includes(t))return!1}return!0},schemas:_,validateForm:K,checkEmailTypos:H,passwordStrength:function(e){if(!e)return{score:0,level:"None",color:"",percentage:0};let t=0;e.length>=8&&(t+=1),e.length>=12&&(t+=1),e.length>=16&&(t+=1),/[a-z]/.test(e)&&(t+=1),/[A-Z]/.test(e)&&(t+=1),/[0-9]/.test(e)&&(t+=1),/[^a-zA-Z0-9]/.test(e)&&(t+=2),/(.)\1{2,}/.test(e)&&(t-=1),/^[0-9]+$/.test(e)&&(t-=1),/^[a-zA-Z]+$/.test(e)&&(t-=1),t=Math.max(0,Math.min(t,8));const n=[{min:0,max:2,level:"Weak",color:"red",percentage:25},{min:3,max:4,level:"Fair",color:"yellow",percentage:50},{min:5,max:6,level:"Good",color:"green",percentage:75},{min:7,max:8,level:"Strong",color:"green",percentage:100}],o=n.find((e=>t>=e.min&&t<=e.max))||n[0];return{score:t,level:o.level,color:o.color,percentage:o.percentage}},getCreditCardType:function(e){if(!e)return null;const t=e.replace(/\D/g,""),n={visa:/^4/,mastercard:/^5[1-5]|^2[2-7]/,amex:/^3[47]/,discover:/^6(?:011|5)/,diners:/^3(?:0[0-5]|[68])/,jcb:/^35/};for(const[e,o]of Object.entries(n))if(o.test(t))return e;return null},formatPhone:function(e,t="US"){const n=e.replace(/\D/g,"");return"US"===t&&10===n.length?`(${n.slice(0,3)}) ${n.slice(3,6)}-${n.slice(6)}`:e},normalizeEmail:function(e){return e.trim().toLowerCase()}};const V=new class{constructor(){this.defaultRequirements={minLength:10,maxLength:128,requireUppercase:!0,requireLowercase:!0,requireNumbers:!0,requireSpecial:!0,specialCharacters:'!@#$%^&*(),.?":{}|<>',customPattern:"",customMessage:""}}validate(e,t={}){const n={...this.defaultRequirements,...t},o=[],i={length:e.length,hasUppercase:/[A-Z]/.test(e),hasLowercase:/[a-z]/.test(e),hasNumbers:/\d/.test(e),hasSpecial:new RegExp(`[${n.specialCharacters.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}]`).test(e)};if(e.length<n.minLength&&o.push(`at least ${n.minLength} characters`),n.maxLength&&e.length>n.maxLength&&o.push(`no more than ${n.maxLength} characters`),n.requireUppercase&&!i.hasUppercase&&o.push("uppercase letter"),n.requireLowercase&&!i.hasLowercase&&o.push("lowercase letter"),n.requireNumbers&&!i.hasNumbers&&o.push("number"),n.requireSpecial&&!i.hasSpecial&&o.push("special character"),n.customPattern){new RegExp(n.customPattern).test(e)||o.push(n.customMessage||"meet custom requirements")}return{valid:0===o.length,errors:o,details:i,strength:this.calculateStrength(e,i)}}calculateStrength(e,t){const n=t||{hasUppercase:/[A-Z]/.test(e),hasLowercase:/[a-z]/.test(e),hasNumbers:/\d/.test(e),hasSpecial:/[!@#$%^&*(),.?":{}|<>]/.test(e)};let o=0;e.length>=8&&(o+=20),e.length>=12&&(o+=20),e.length>=16&&(o+=10),n.hasUppercase&&(o+=15),n.hasLowercase&&(o+=15),n.hasNumbers&&(o+=15),n.hasSpecial&&(o+=15);const i=[n.hasUppercase,n.hasLowercase,n.hasNumbers,n.hasSpecial].filter(
1Boolean).length;let a,s;return i>=3&&(o+=10),4===i&&(o+=10),o<30?(a="weak",s="red"):o<50?(a="fair",s="orange"):o<70?(a="good",s="yellow"):o<90?(a="strong",s="green"):(a="excellent",s="emerald"),{score:o,level:a,color:s,percentage:Math.min(o,100)}}generateErrorMessage(e){if(0===e.length)return"";if(1===e.length)return`Password must contain ${e[0]}`;const t=[...e],n=t.pop();return`Password must contain ${t.join(", ")} and ${n}`}validateMatch(e,t){return t?e!==t?{valid:!1,error:"Passwords do not match"}:{valid:!0,error:null}:{valid:!1,error:"Please confirm your password"}}getRequirements(e={}){let t=e.passwordRequirements||e.heimguardConfig?.register?.passwordRequirements||e.register?.passwordRequirements;if(!t){const n={},o=e.heimguardConfig||e;void 0!==o.passwordMinLength&&(n.minLength=o.passwordMinLength),void 0!==o.passwordMaxLength&&(n.maxLength=o.passwordMaxLength),void 0!==o.passwordRequireUppercase&&(n.requireUppercase=o.passwordRequireUppercase),void 0!==o.passwordRequireNumbers&&(n.requireNumbers=o.passwordRequireNumbers),void 0!==o.passwordRequireSpecialChars&&(n.requireSpecial=o.passwordRequireSpecialChars),t=n}return{...this.defaultRequirements,...t||{}}}generateTips(e){const t=[];return e.minLength&&t.push(`At least ${e.minLength} characters`),e.requireUppercase&&t.push("Include uppercase letters"),e.requireLowercase&&t.push("Include lowercase letters"),e.requireNumbers&&t.push("Include numbers"),e.requireSpecial&&t.push("Include special characters"),t}};class q{static currency(e,t={}){if(null==e||isNaN(e))return"";const{currency:n="USD",locale:o=this.defaultLocale,showCents:i="auto",sign:a="standard"}=t;let s=2,r=2;return"never"===i?(s=0,r=0):"auto"===i&&e%1==0&&(s=0),new Intl.NumberFormat(o,{style:"currency",currency:n,minimumFractionDigits:s,maximumFractionDigits:r,currencySign:a}).format(e)}static number(e,t={}){if(null==e||isNaN(e))return"";const{locale:n=this.defaultLocale,decimals:o="auto",notation:i="standard",compactDisplay:a="short",signDisplay:s="auto"}=t,r={notation:i,compactDisplay:a,signDisplay:s};return"auto"===o||"number"==typeof o&&(r.minimumFractionDigits=o,r.maximumFractionDigits=o),new Intl.NumberFormat(n,r).format(e)}static percentage(e,t={}){if(null==e||isNaN(e))return"";const{locale:n=this.defaultLocale,decimals:o=0,isDecimal:i=!1,signDisplay:a="auto"}=t,s=i?e:e/100;return new Intl.NumberFormat(n,{style:"percent",minimumFractionDigits:o,maximumFractionDigits:o,signDisplay:a}).format(s)}static fileSize(e,t={}){if(!e||0===e)return"0 B";if(isNaN(e))return"";const{decimals:n=2,binary:o=!1,locale:i=this.defaultLocale}=t,a=o?1024:1e3,s=o?["B","KiB","MiB","GiB","TiB","PiB"]:["B","KB","MB","GB","TB","PB"],r=Math.floor(Math.log(e)/Math.log(a)),d=e/Math.pow(a,r);return`${this.number(d,{locale:i,decimals:n})} ${s[r]}`}static phone(e,t={}){if(!e)return"";const{country:n="US",international:o=!1}=t,i=e.replace(/\D/g,"");if("US"===n){if(10===i.length)return o?`+1 (${i.slice(0,3)}) ${i.slice(3,6)}-${i.slice(6)}`:`(${i.slice(0,3)}) ${i.slice(3,6)}-${i.slice(6)}`;if(11===i.length&&"1"===i[0])return`+1 (${i.slice(1,4)}) ${i.slice(4,7)}-${i.slice(7)}`}return"UK"===n&&11===i.length?`+44 ${i.slice(1,5)} ${i.slice(5,8)} ${i.slice(8)}`:o&&!e.startsWith("+")?`+${i}`:e}
1static creditCard(e,t={}){if(!e)return"";const{showLast:n=4,separator:o=" ",maskChar:i="â¢"}=t,a=e.replace(/\D/g,"");if(a.length<n)return e;const s=a.slice(-n),r=i.repeat(a.length-n)+s;return r.match(/.{1,4}/g)?.join(o)||r}static formatName(e,t={}){if(!e)return"";const{format:n="proper",lastFirst:o=!1}=t,i=e.trim().split(/\s+/).map((e=>{switch(n){case"upper":return e.toUpperCase();case"lower":return e.toLowerCase();default:return e.includes("'")?e.split("'").map((e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase())).join("'"):e.startsWith("Mc")&&e.length>2?"Mc"+e.charAt(2).toUpperCase()+e.slice(3).toLowerCase():e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()}}));if(o&&i.length>=2){return`${i.pop()}, ${i.join(" ")}`}return i.join(" ")}static address(e,t={}){if(!e)return"";const{format:n="multi",includeCountry:o=!0,countryFormat:i="name"}=t,a=[];e.line1&&a.push(e.line1),e.line2&&a.push(e.line2);const s=[];if(e.city&&s.push(e.city),e.state&&("postal"===n&&e.stateCode?s.push(e.stateCode):s.push(e.state)),e.postalCode||e.zip){const t=s[s.length-1]||"";s[s.length-1]=t+" "+(e.postalCode||e.zip)}if(s.length>0&&a.push(s.join(", ")),o&&e.country&&"US"!==e.country){const t="code"===i&&e.countryCode?e.countryCode:e.country;a.push(t)}switch(n){case"single":return a.join(", ");case"postal":return a.join("\n").toUpperCase();default:return a.join("\n")}}static truncate(e,t={}){if(!e)return"";const{length:n=50,suffix:o="...",breakWords:i=!0,middle:a=!1}=t;if(e.length<=n)return e;if(a){const t=Math.ceil((n-o.length)/2),i=Math.floor((n-o.length)/2);return e.slice(0,t)+o+e.slice(-i)}const s=e.slice(0,n-o.length);if(!i){const e=s.lastIndexOf(" ");if(e>0)return s.slice(0,e)+o}return s+o}static list(e,t={}){if(!e||0===e.length)return"";if(1===e.length)return String(e[0]);const{conjunction:n="and",separator:o=", ",locale:i=this.defaultLocale,oxford:a=!0}=t;if("undefined"!=typeof Intl&&"ListFormat"in Intl)try{return new(0,Intl.ListFormat)(i,{style:"long",type:"conjunction"}).format(e.map(String))}catch(e){}if(2===e.length)return`${e[0]} ${n} ${e[1]}`;const s=e[e.length-1],r=a?o:" ";return`${e.slice(0,-1).join(o)}${r}${n} ${s}`}static boolean(e,t={}){const{format:n="yes/no",capitalize:o=!0}=t,i={"yes/no":e?"yes":"no","true/false":e?"true":"false","on/off":e?"on":"off","enabled/disabled":e?"enabled":"disabled","active/inactive":e?"active":"inactive"}[n]||String(e);return o?i.charAt(0).toUpperCase()+i.slice(1):i}static unit(e,t,n={}){if(null==e||isNaN(e))return"";const{locale:o=this.defaultLocale,precision:i=2,long:a=!1}=n;if("undefined"!=typeof Intl&&Intl.NumberFormat)try{return new Intl.NumberFormat(o,{style:"unit",unit:t,unitDisplay:a?"long":"short",minimumFractionDigits:i,maximumFractionDigits:i}).format(e)}catch(e){}return this.number(e,{locale:o,decimals:i})+(a?` ${t}`:t)}static pluralize(e,t,n=null,o=!0){const i=1===e?t:n||`${t}s`;return o?`${e} ${i}`:i}}q.defaultLocale="en-US";const W=(...e)=>q.currency(...e);var Z=class{constructor(e){this.authConfig=e,this.formId=`login-form-${Date.now()}`,this.alertId=`login-alert-${Date.now()}`}generateHTML(e=!1,t){const n=this.authConfig.getTemplateData(),o=this.authConfig.getConfig().heimguardConfig,{register:i,forgotPassword:a}=o,s=i.useModal?"#":i.url,r=!i.useModal,d=o.registerLinkText||"Sign up";return e?`\n <div class="auth-modal-wrapper">\n <div class="auth-component login-component w-full">\n ${this.renderHeader(n,!0)}\n ${this.renderForm()}\n ${this.renderFooter(s,!0,r,d)}\n </div>\n </div>\n `:`\n <div class="auth-component login-component w-full max-w-[500px] mx-auto">\n \x3c!-- Card Container --\x3e\n <div class="bg-white rounded-2xl shadow-xl border border-gray-100 overflow-hidden">\n ${this.renderHeader(n,!1)}\n ${this.renderForm()}\n ${this.renderFooter(s,!1,r,d)}\n </div>\n </div>\n `}renderHeader(e,t){const n=e.companyName||"your account";return`\n <div class="${t?"px-4 sm:px-8 pt-8 pb-6 text-center bg-gradient-to-br from-primary-50 to-blue-50 rounded-t-2xl":"px-4 sm:px-8 pt-8 pb-6 text-center bg-gradient-to-br from-primary-50 to-blue-50 -m-8 mb-6"}">\n <div class="mx-auto h-16 w-16 bg-primary-600 rounded-2xl flex items-center justify-center mb-4 shadow-lg">\n ${P.A.auth.login()}\n </div>\n ${e.companyImgSrc?`<img src="${e.companyImgSrc}" alt="${n}" class="h-6 sm:h-8 lg:h-10 mx-auto mb-4">`:""}\n <h2 class="text-2xl font-bold text-gray-900 mb-2">Sign in to ${n}</h2>\n <p class="text-gray-600 text-sm">Welcome back! Please sign in to continue</p>\n </div>\n `}renderForm(){return`\n <div class="px-4 sm:px-8 py-6">\n ${`\n <div id="${this.alertId}" class="rounded-md p-4 border shadow-lg hidden mb-4 alert-container" role="alert">\n <div class="flex">\n <div class="flex-shrink-0 alert-icon">\n \x3c!-- Icon will be updated dynamically --\x3e\n </div>\n <div class="flex-1 ml-3">\n <div class="text-sm alert-message"></div>\n </div>\n </div>\n </div>\n `}\n\n <form id="${this.formId}" class="space-y-5">\n ${$.render({id:`${this.formId}-email`,name:"email",label:"Email Address",placeholder:"Enter your email",required:!0,icon:P.A.auth.email()})}\n\n ${U.render({id:`${this.formId}-password`,name:"password",label:"Password",placeholder:"Enter your password",required:!0,showToggle:!0,icon:P.A.auth.password(),autocomplete:"current-password"})}\n\n \x3c!-- Remember Me & Forgot Password --\x3e\n <div class="flex flex-col items-center sm:flex-row sm:justify-between gap-2">\n <div class="flex items-center">\n <input\n id="${this.formId}-remember"\n name="remember"\n type="checkbox"\n class="h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300 rounded"\n >\n <label for="${this.formId}-remember" class="ml-2 block text-sm text-gray-700">\n Remember me\n </label>\n </div>\n\n <a href="#" class="text-sm text-primary-600 hover:text-primary-500 font-medium transition-colors" data-forgot-password-trigger>\n Forgot your password?\n </a>\n </div>\n\n \x3c!-- Submit Button --\x3e\n <button\n type="submit"\n id="${this.formId}-submit"\n class="w-full flex justify-center py-2.5 px-4 border border-transparent roun
1ded-lg shadow-sm text-sm font-medium text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition-colors"\n >\n Sign In\n </button>\n </form>\n\n ${this.renderSocialLogin()}\n </div>\n `}renderSocialLogin(){const e=this.authConfig.getConfig().heimguardConfig,t=e.isGoogleLoginSetup||!1,n=e.isFacebookLoginSetup||!1,o=e.isMagicLinkSetup||!1,i=[];if(t&&i.push({name:"google",title:"Google",icon:P.A.social.google,color:"blue",textPosition:"right"}),n&&i.push({name:"facebook",title:"Facebook",icon:P.A.social.facebook,color:"blue",textPosition:"right"}),o&&i.push({name:"magic",title:"Send Me a Link",icon:P.A.social.magicLink(),color:"purple",textPosition:"right"}),0===i.length)return"";const a=i.map((e=>`\n <button\n type="button"\n data-social-login="${e.name}"\n class="flex justify-center items-center py-2.5 px-4 border border-gray-300 rounded-xl text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-${e.color}-500 transition-all duration-200 shadow-sm hover:shadow-md w-full"\n title="Continue with ${e.title}"\n >\n ${"left"===e.textPosition?`<span class="mr-2">${e.title}</span>`:""}\n ${e.icon}\n ${"right"===e.textPosition?`<span class="ml-2">${e.title}</span>`:""}\n </button>\n `)).join("\n");return`\n \x3c!-- Divider --\x3e\n <div class="mt-8 mb-6">\n <div class="relative">\n <div class="absolute inset-0 flex items-center">\n <div class="w-full border-t border-gray-200"></div>\n </div>\n <div class="relative flex justify-center text-sm">\n <span class="px-3 bg-white text-gray-500 font-medium">Or continue with</span>\n </div>\n </div>\n </div>\n\n \x3c!-- Social Login Buttons --\x3e\n <div class="grid ${1===i.length?"grid-cols-1":2===i.length?"grid-cols-2":"grid-cols-3"} gap-3">\n ${a}\n </div>\n `}renderFooter(e,t,n=!1,o="Sign up"){const i=t?"px-4 sm:px-8 py-6 bg-gray-50 border-t border-gray-100 rounded-b-2xl":"px-4 sm:px-8 py-6 bg-gray-50 border-t border-gray-100",a=w.default.isCabotWealth();return`\n <div class="${i}">\n <p class="text-center text-sm text-gray-600">\n Don't have an account?\n ${a?'<br><span class="block mt-2">':""}\n <a href="${e}" class="${a?"inline-flex items-center justify-center px-6 py-2.5 bg-primary-600 text-white hover:text-white text-sm font-bold rounded-lg hover:bg-primary-700 transition-colors shadow-sm":"text-primary-600 hover:text-primary-500 font-semibold transition-colors"}"${n?' target="_blank" rel="noopener noreferrer"':""} data-register-trigger>\n ${o}\n </a>\n ${a?"</span>":""}\n </p>\n </div>\n `}setupFormHandling(e){this.initializeEvents()}initializeEvents(){const e=document.querySelector(".login-component");if(!e)return;const t=e.querySelector(`#${this.formId}`);if(!t)return;U.attachToggleHandler(e),t.addEventListener("submit",(e=>this.handleSubmit(e)));const n=e.querySelector("[data-forgot-password-trigger]");n&&n.addEventListener("click",(e=>this.handleForgotPassword(e)));const o=e.querySelector("[data-register-trigger]");o&&"#"===o.getAttribute("href")&&o.addEventListener("click",(e=>this.handleRegisterLink(e)));e.querySelectorAll("[data-social-login]").forEach((e=>{e.addEventListener("click",(e=>this.handleSocialLogin(e)))})),this.setupFieldValidation(t)}async handleSubmit(e){e.preventDefault();const t=e.target,o=this.getFormElements(t);this.hideAlert();const i={email:o.email.value.trim(),password:o.password.value,remember:o.rememberMe.checked},a=K(i,_.login);if(a.isValid){F.A.setLoading(o.submitButton,!0),this.setFieldsEnabled(!1);try{const e=this.authConfig.getAuthAPI(),t=await e.login(i);if(t.ok)try{const e=new URLSearchParams(window.location.search),o=e.get("referrerUrl")||e.get("returnUrl"),i=o?decodeURIComponent(o):t.data.redirectUrl;if(i)this.showAlert("Login successful! Redirecting...","success"),setTimeout((()=>{try{window.location.href=i}catch(e){console.error("[LoginForm] Redirect failed:",e),window.location.reload()}}),1e3);else{if(sessionStorage.getItem("pendingSubscriptionPlan")){this.showAlert("Login successful! Continuing with your subscription...","success");const e=new CustomEvent("auth:login:success",{detail:{user:t.data.user},bubbles:!0});document.dispatchEvent(e),setTimeout((()=>
1{Promise.resolve().then(n.bind(n,4811)).then((({ModalUtils:e})=>{e.hideAll()}))}),1e3)}else{this.showAlert("Login successful!","success");const e=new CustomEvent("auth:login:success",{detail:{user:t.data.user},bubbles:!0});document.dispatchEvent(e),setTimeout((()=>{window.location.reload()}),1e3)}}}catch(e){console.error("[LoginForm] Error in success handler:",e),window.location.reload()}else{const e=t.data?.message||"Login failed. Please check your credentials.";this.showAlert(e,"error"),F.A.setLoading(o.submitButton,!1),this.setFieldsEnabled(!0)}}catch(e){console.error("[LoginForm] Login error:",e);let t="Login failed. Please try again.";if(e&&"object"==typeof e)if("status"in e&&"message"in e){const n=e;t=429===n.status?n.message||"Too many login attempts. Please try again later.":401===n.status?"Invalid email or password.":0===n.status?"Network error. Please check your connection.":n.message||t}else"message"in e&&(t=e.message);this.showAlert(t,"error"),F.A.setLoading(o.submitButton,!1),this.setFieldsEnabled(!0)}}else this.showAlert("Please fix the following errors: "+Object.values(a.errors).join(", "),"error")}handleForgotPassword(e){e.preventDefault(),e.stopPropagation();const{forgotPassword:t}=this.authConfig.getConfig().heimguardConfig;t.useModal&&this.authConfig.onModeSwitch?this.authConfig.onModeSwitch("forgotPassword"):window.location.href=t.url}handleRegisterLink(e){e.preventDefault(),e.stopPropagation(),this.authConfig.onModeSwitch&&this.authConfig.onModeSwitch("register")}handleSocialLogin(e){e.preventDefault();const t=e.currentTarget,n=t.getAttribute("data-social-login");if(!n)return;const o=new CustomEvent("auth:social:login",{detail:{provider:n},bubbles:!0});t.dispatchEvent(o)}getPasswordRequirements(){const e=this.authConfig.getConfig();return V.getRequirements(e)}setupFieldValidation(e){const t=e.querySelector(`#${this.formId}-email`);t&&(t.addEventListener("blur",(()=>{const e=t.value.trim();if(e)if(j.email(e)){const t=j.checkEmailTypos(e);t?this.showFieldError("email",t):this.clearFieldError("email")}else this.showFieldError("email","Please enter a valid email address");else this.showFieldError("email","Email is required")})),t.addEventListener("focus",(()=>{this.clearFieldError("email")})));const n=e.querySelector(`#${this.formId}-password`);n&&(n.addEventListener("blur",(()=>{const e=n.value,t=this.getPasswordRequirements().minLength||4;e?e.length<t?this.showFieldError("password",`Password must be at least ${t} characters`):this.clearFieldError("password"):this.showFieldError("password","Password is required")})),n.addEventListener("focus",(()=>{this.clearFieldError("password")})))}showFieldError(e,t){const n=document.getElementById(`${this.formId}-${e}`);if(!n)return;const o=n.closest(".flex");o&&(o.classList.remove("border-gray-300","focus-within:border-primary-500"),o.classList.add("border-red-500","focus-within:border-red-600"));const i=n.closest(".form-field");if(!i)return;const a=i.querySelector(".mt-1");if(!a)return;let s=a.querySelector(".field-error");s||(s=document.createElement("div"),s.className="field-error text-sm text-red-600 mt-1",s.setAttribute("role","alert"),a.appendChild(s)),s.textContent=t}clearFieldError(e){const t=document.getElementById(`${this.formId}-${e}`);if(!t)return;const n=t.closest(".flex");n&&(n.classList.remove("border-red-500","focus-within:border-red-600"),n.classList.add("border-gray-300","focus-within:border-primary-500"));const o=t.closest(".form-field");if(!o)return;const i=o.querySelector(".mt-1");if(!i)return;const a=i.querySelector(".field-error");a&&a.remove()}getFormElements(e){return{form:e,email:e.querySelector('input[name="email"]'),password:e.querySelector('input[name="password"]'),rememberMe:e.querySelector('input[name="remember"]'),submitButton:e.querySelector('button[type="submit"]')}}setFieldsEnabled(e){const t=document.getElementById(this.formId);if(!t)return;t.querySelectorAll("input, button").forEach((t=>{t.disabled=!e}))}showAlert(e,t="info"){const n=document.getElementById(this.alertId);if(!n)return;const o={success:{container:"bg-green-50 border-green-200",icon:P.A.render("check-circle",{class:"h-5 w-5 text-green-400"}),text:"text-green-800"},error:{container:"bg-red-50 border-red-200",icon:P.A.render("x-circle",{class:"h-5 w-5 text-red-400"}),text:"text-red-800"},warning:{container:"bg-yellow-50 border-yellow-200",icon:P.A.render("alert-triangle",{class:"h-5 w-5 text-yellow-400"}),text:"text-yellow-800"},info:{container:"bg-blue-50 border-blue-200",icon:P.A.render("info",{class:"h-5 w-5 text-blue-400"}),text:"text-blue-800"}}[t];n.className=`rounded-md p-4 border shadow-lg mb-4 alert-container ${o.container}`;const i=n.querySelector(".alert-icon");i&&(i.innerHTML=o.icon);const a=n.querySelector(".alert-message");a&&(a.className=`text-sm alert-message ${o.text}`,a.textContent=e),n.classList.remove("hidden")}hideAlert(){const e=document.getElementById(this.alertId);e&&e.classList.add("hidden")}destroy(){this.hideAlert()}},Y=n(3716),J=n(7140);class Q{constructor(e){this.authConfig=e,this.formId=`register-form-${Date.now()}`,this.alertId=`register-alert-${Date.now()}`}generateHTML(e=!1,t){const n=this.authConfig.getTemplateData(),{login:o}=this.authConfig.getConfig().heimguardConfig,{hasTerms:i,hasPrivacy:a,hasAny:s}=this.authConfig.hasTermsOrPrivacy(),r=o.useModal?"#":o.url;return e?`\n <div class="auth-modal-wrapper">\n <div class="auth-component register-component w-full">\n ${this.renderHeader(n,e)}\n ${this.renderForm(i,a,s)}\n ${this.renderFooter(r,e)}\n </div>\n </div>\n `:`\n <div class="auth-component register-component w-full max-w-[500px] mx-auto">\n \x3c!-- Card Container --\x3e\n <div class="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">\n ${this.renderHeader(n,e)}\n ${this.renderForm(i,a,s)}\n ${this.renderFooter(r,e)}\n </div>\n </div>\n `}renderHeader(e,t){return`\n <div class="px-8 pt-8 pb-6 text-center bg-gradient-to-br from-primary-50/50 to-secondary-50/50 ${t?"":"-m-8 mb-6"} ${t?"rounded-t-2xl":""}">\n <div class="mx-auto h-16 w-16 bg-primary-600 rounded-2xl flex items-center justify-center mb-4 shadow-md">\n ${P.A.auth.userPlus()}\n </div>\n ${e.companyImgSrc?`<img src="${e.companyImgSrc}" alt="${e.companyName}" class="h-10 mx-auto mb-4 opacity-90">`:""}\n <h2 class="text-2xl font-bold text-gray-900 mb-2">Create your account</h2>\n <p class="text-gray-700 text-sm">Join ${e.companyName} today</p>\n </div>\n `}renderForm(e,t,n){const o=this.getPasswordRequirements(),i=$.render({id:`${this.formId}-email`,name:"email",label:"Email Address",placeholder:"Enter your email",required:!0,icon:P.A.auth.email()}),a=U.render({id:`${this.formId}-password`,name:"password",label:"Password",placeholder:"Create a password",required:!0,showToggle:!0,showStrength:!0,icon:P.A.auth.password(),autocomplete:"new-password",requirements:o});this.passwordRequirements=o;const s=U.render({id:`${this.formId}-confirmPassword`,name:"confirmPassword",label:"Confirm Password",placeholder:"Confirm your password",required:!0,showToggle:!0,icon:P.A.auth.password(),autocomplete:"new-password"}),r=`\n <div id="${this.alertId}" class="rounded-md p-4 border shadow-lg hidden mb-4 alert-container" role="alert">\n <div class="flex">\n <div class="flex-shrink-0 alert-icon">\n \x3c!-- Icon will be updated dynamically --\x3e\n </div>\n <div class="flex-1 ml-3">\n <div class="text-sm alert-message"></div>\n </div>\n </div>\n </div>
1\n `,d=this.renderTermsCheckbox(e,t,n);return`\n <div class="px-8 py-6">\n ${r}\n\n <form id="${this.formId}" class="space-y-5" novalidate>\n ${i}\n ${a}\n ${s}\n \n \x3c!-- Honeypot field - hidden from users, catches bots --\x3e\n <div style="position: absolute; left: -9999px; height: 0; width: 0; overflow: hidden;">\n <input \n type="text" \n name="website" \n id="${this.formId}-website" \n tabindex="-1" \n autocomplete="off"\n aria-hidden="true"\n />\n <label for="${this.formId}-website">Leave this field empty</label>\n </div>\n \n ${d}\n\n \x3c!-- Submit Button --\x3e\n <button\n type="submit"\n id="${this.formId}-submit"\n class="w-full flex justify-center py-2.5 px-4 border border-transparent rounded-lg shadow-sm text-sm font-medium text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition-colors"\n >\n Create Account\n </button>\n </form>\n\n ${this.renderSocialLogin()}\n </div>\n `}renderTermsCheckbox(e,t,n){const{terms:o,privacyPolicy:i}=this.authConfig.getConfig().heimguardConfig;let a="";return a=e&&t?`I agree to the <a href="${o}" target="_blank" class="text-primary-600 hover:text-primary-500 font-medium">Terms of Service</a> and <a href="${i}" target="_blank" class="text-primary-600 hover:text-primary-500 font-medium">Privacy Policy</a>`:e?`I agree to the <a href="${o}" target="_blank" class="text-primary-600 hover:text-primary-500 font-medium">Terms of Service</a>`:t?`I agree to the <a href="${i}" target="_blank" class="text-primary-600 hover:text-primary-500 font-medium">Privacy Policy</a>`:"I agree to the Terms of Service and Privacy Policy",`\n <div class="flex items-start gap-2">\n <input\n type="checkbox"\n name="agreeTerms"\n id="${this.formId}-agreeTerms"\n required\n data-error-message="You must agree to the terms to continue"\n class="h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-400 rounded mt-1"\n />\n <label for="${this.formId}-agreeTerms" class="text-sm text-gray-700">\n ${a}\n </label>\n </div>\n `}renderSocialLogin(){const e=this.authConfig.getConfig().heimguardConfig,t=e.isGoogleLoginSetup||!1,n=e.isFacebookLoginSetup||!1,o=[];if(t&&o.push({name:"google",title:"Google",icon:P.A.social.google,color:"blue"}),n&&o.push({name:"facebook",title:"Facebook",icon:P.A.social.facebook,color:"blue"}),0===o.length)return"";const i=o.map((e=>`\n <button\n type="button"\n data-social-login="${e.name}"\n class="flex justify-center items-center py-2.5 px-4 border border-gray-300 rounded-xl text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-${e.color}-500 transition-all duration-200 shadow-sm hover:shadow w-full"\n title="Continue with ${e.title}"\n >\n ${e.icon}\n <span class="ml-2 hidden sm:inline">${e.title}</span>\n </button>\n `)).join("\n");return`\n \x3c!-- Divider --\x3e\n <div class="mt-8 mb-6">\n <div class="relative">\n <div class="absolute inset-0 flex items-center">\n <div class="w-full border-t border-gray-300"></div>\n </div>\n <div class="relative flex justify-center text-sm">\n <span class="px-3 bg-white text-gray-600 font-medium">Or continue with</span>\n </div>\n </div>\n </div>\n\n \x3c!-- Social Login Buttons --\x3e\n <div class="grid ${1===o.length?"grid-cols-1":"grid-cols-2"} gap-3">\n ${i}\n </div>\n `}renderFooter(e,t){return`\n <div class="px-8 py-6 bg-gray-50 border-t border-gray-200 ${t?"rounded-b-2xl":""}">\n <p class="text-center text-sm text-gray-700">\n Already have an account?\n <a href="${e}" class="text-primary-600 hover:text-primary-500 font-semibold transition-colors" data-login-trigger>\n Sign in\n </a>\n </p>\n </div>\n `}setupFormHandling(e){const t=e||document,n=t.querySelector(`#${this.formId}`);n&&(U.attachToggleHandler(t),n.addEventListener("submit",(async e=>{e.preventDefault(),await this.handleSubmit(n)})),this.setupFieldValidation(n),t instanceof HTMLElement&&(t._authComponent=this))}getPasswordRequirements(){const e=this.authConfig.getConfig();return V.getRequirements(e)}setupFieldValidation(e){const t=e.querySelector(`#${this.formId}-email`);t&&(t.addEventListener("blur",(()=>{const e=t.value.trim(),n=t.closest(".form-field");if(n)if(e)if(j.email(e)){const t=j.checkEmailTypos(e);
1t?this.showFieldError(n,t):this.clearFieldError(n)}else this.showFieldError(n,"Please enter a valid email address");else this.showFieldError(n,"Email is required")})),t.addEventListener("focus",(()=>{const e=t.closest(".form-field");e&&this.clearFieldError(e)})));const n=e.querySelector(`#${this.formId}-password`);n&&(n.addEventListener("input",(e=>{const t=e.target,o=V.calculateStrength(t.value),i=n.closest(".form-field")?.querySelector("[data-strength-indicator]");i&&(i.style.width=`${o.percentage}%`,i.className=`h-full transition-all duration-300 bg-${o.color}-500`)})),n.addEventListener("blur",(()=>{const e=n.value,t=n.closest(".form-field");if(!t)return;const o=this.passwordRequirements||this.getPasswordRequirements();if(e){const n=V.validate(e,o);if(n.valid)this.clearFieldError(t);else{const e=V.generateErrorMessage(n.errors);this.showFieldError(t,e)}}else this.showFieldError(t,"Password is required")})),n.addEventListener("focus",(()=>{const e=n.closest(".form-field");e&&this.clearFieldError(e)})));const o=e.querySelector(`#${this.formId}-confirmPassword`);o&&(o.addEventListener("blur",(()=>{this.validatePasswordMatch()})),o.addEventListener("focus",(()=>{const e=o.closest(".form-field");e&&this.clearFieldError(e)})));const i=e.querySelector(`#${this.formId}-agreeTerms`);i&&Y.Nm.setupValidation(i,{errorMessage:i.dataset.errorMessage||"You must agree to the terms to continue",validateOnChange:!0,showErrorIcon:!0})}async handleSubmit(e){const t=e.querySelector(`#${this.formId}-submit`);document.getElementById(this.alertId);this.clearErrors();const n=new FormData(e),o={email:n.get("email"),password:n.get("password"),confirmPassword:n.get("confirmPassword"),agreeTerms:"on"===n.get("agreeTerms")},i=Y.Nm.validateAll(e),a=this.validateForm(o);if(!a.isValid||!i)return void(a.isValid||this.showErrors(a.errors));const s=Y.Aw.setSubmitting(t.id,"Creating account...");try{const e=await fetch(f.A.apiRegisterUrl,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},credentials:"include",body:JSON.stringify({email:o.email,password:o.password,password_confirmation:o.confirmPassword,website:n.get("website")||""})}),t=await e.json();if(!e.ok)throw new Error(t.message||"Registration failed");await this.handleRegistrationSuccess(t)}catch(e){console.error("Registration error:",e);const t=this.getErrorMessage(e);this.showAlert(t,"error"),s?.restore()}}validateForm(e){const t=this.passwordRequirements||this.getPasswordRequirements();return K(e,{email:_.register.email,password:{required:!0,validate:e=>{const n=V.validate(e,t);return n.valid?null:V.generateErrorMessage(n.errors)}},confirmPassword:{required:!0,validate:(e,t)=>{const n=V.validateMatch(t.password,e);return n.valid?null:n.error}},agreeTerms:{required:!0,validate:e=>e?null:"You must agree to the terms to continue"}})}validatePasswordMatch(){const e=document.getElementById(`${this.formId}-password`),t=document.getElementById(`${this.formId}-confirmPassword`);if(!e||!t)return;const n=t.closest(".form-field");if(!n)return;const o=V.validateMatch(e.value,t.value);!o.valid&&t.value&&o.error?this.showFieldError(n,o.error):this.clearFieldError(n)}showErrors(e){Object.entries(e).forEach((([e,t])=>{const n=document.getElementById(`${this.formId}-${e}`);if(n){const e=n.closest(".form-field");e&&this.showFieldError(e,Array.isArray(t)?t[0]:t)}}
1)),Object.keys(e).length>0&&this.showAlert("Please correct the errors and try again","error")}showFieldError(e,t){const n=e.querySelector(".flex");if(!n)return;n.classList.add("border-red-500","focus-within:border-red-600"),n.classList.remove("border-gray-300","focus-within:border-primary-500");let o=e.querySelector('[role="alert"]');o||(o=document.createElement("div"),o.className="mt-1.5 flex items-start gap-1.5",o.setAttribute("role","alert"),o.innerHTML=`\n ${P.A.render("alert-circle",{class:"w-4 h-4 text-red-500 flex-shrink-0 mt-0.5"})}\n <span class="text-sm text-red-600 font-medium">${t}</span>\n `,n.insertAdjacentElement("afterend",o))}clearFieldError(e){const t=e.querySelector(".flex");if(!t)return;t.classList.remove("border-red-500","focus-within:border-red-600"),t.classList.add("border-gray-300","focus-within:border-primary-500");const n=e.querySelector('[role="alert"]');n&&n.remove()}clearErrors(){const e=document.getElementById(this.formId);if(!e)return;e.querySelectorAll(".form-field").forEach((e=>{this.clearFieldError(e)})),e.querySelectorAll('input[type="checkbox"]').forEach((e=>{Y.Nm.clearError(e)}));const t=document.getElementById(this.alertId);t&&t.classList.add("hidden")}showAlert(e,t="error"){const n=document.getElementById(this.alertId);if(!n)return;const o={error:{bg:"bg-red-50",border:"border-red-300",text:"text-red-700",iconColor:"text-red-500",icon:P.A.render("x-circle",{class:"h-5 w-5 text-red-500"})},success:{bg:"bg-green-50",border:"border-green-300",text:"text-green-700",iconColor:"text-green-500",icon:P.A.render("check-circle",{class:"h-5 w-5 text-green-500"})},info:{bg:"bg-blue-50",border:"border-blue-300",text:"text-blue-700",iconColor:"text-blue-500",icon:P.A.render("info",{class:"h-5 w-5 text-blue-500"})}},i=o[t]||o.error;n.className=n.className.replace(/bg-\w+-50|border-\w+-200/g,""),n.classList.add(i.bg,i.border);const a=n.querySelector(".alert-icon");a&&(a.innerHTML=i.icon);const s=n.querySelector(".alert-message");s&&(s.className=`text-sm alert-message ${i.text}`,s.textContent=e),n.classList.remove("hidden")}getErrorMessage(e){const t=e.message||e.toString();return t.includes("network")||t.includes("fetch")?"Unable to connect to the server. Please check your internet connection.":t.includes("already exists")||t.includes("409")?"An account with this email already exists. Please sign in instead.":t.includes("Invalid")||t.includes("400")?"Please check your information and try again.":t.includes("timeout")?"The request timed out. Please try again.":t.includes("500")||t.includes("server")?"A server error occurred. Please try again later.":t||"An unexpected error occurred. Please try again."}async handleRegistrationSuccess(e){this.clearErrors(),console.log("[RegisterForm] Registration result:",e);const t=document.getElementById(this.formId),n=t?.querySelector('[name="email"]');
1{const t={id:"",email:n?.value||e.email||"your email",firstName:"",lastName:"",displayName:"",verified:!1,provider:"basic"};sessionStorage.setItem("showingRegistrationModal","true"),(0,J.KM)(J.QU.REGISTER_SUCCESS,{user:t,requiresVerification:!1}),this.showRegistrationSuccessModal(t)}}showRegistrationSuccessModal(e){Promise.all([Promise.resolve().then(n.bind(n,6833)),Promise.resolve().then(n.bind(n,4811))]).then((([{Modal:t},{ModalUtils:n}])=>{n.hideAll().then((()=>{setTimeout((()=>{this.escapeHtml(e.email);const n=this.authConfig.getTemplateData(),o=n.companyImgSrc?`<img src="${n.companyImgSrc}" alt="${n.companyName||"Company"}" class="h-12 mx-auto mb-4">`:"",i=!!sessionStorage.getItem("pendingSubscriptionPlan"),a=i?"Continue Order":"Start Exploring",s=i?"shopping-cart":"arrow-right",r=i?"View Plans":"Go to Profile",d=i?"credit-card":"user",l=i?"Your account is ready! Continue to complete your subscription.":"Your account has been created successfully! Click below to get started.",c=new t({id:"registration-success-modal",title:"",content:`\n <div class="text-center p-6">\n \x3c!-- Success animation --\x3e\n <div class="mx-auto w-24 h-24 bg-primary-100 rounded-full flex items-center justify-center mb-6 animate-pulse">\n ${P.A.render("check",{class:"w-12 h-12 text-primary-500"})}\n </div>\n\n \x3c!-- Company logo --\x3e\n ${o}\n\n \x3c!-- Welcome message --\x3e\n <h2 class="text-2xl font-bold text-gray-900 mb-2">Welcome to ${n.companyName||"our platform"}!</h2>\n <p class="text-gray-600 mb-6">Your account has been created successfully.</p>\n\n \x3c!-- Account details --\x3e\n <div class="bg-gray-50 rounded-lg p-4 mb-6 text-left">\n <h3 class="text-sm font-semibold text-gray-700 mb-2">Account Details</h3>\n <div class="space-y-1">\n <div class="flex justify-between">\n <span class="text-sm text-gray-600">Email:</span>\n <span class="text-sm font-medium text-gray-900">${this.escapeHtml(e.email)}</span>\n </div>\n <div class="flex justify-between">\n <span class="text-sm text-gray-600">Status:</span>\n <span class="text-sm font-medium text-primary-600">Account Created</span>\n </div>\n </div>\n </div>\n\n \x3c!-- Success message --\x3e\n <p class="text-sm text-gray-600 mb-6">\n ${l}\n </p>\n\n \x3c!-- Action buttons --\x3e\n <div class="space-y-3">\n <button\n type="button"\n id="registration-success-explore"\n class="w-full py-3 px-4 bg-primary-600 text-white font-medium rounded-lg hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition-colors"\n >\n ${P.A.render(s,{class:"inline-block w-5 h-5 mr-2"})}\n ${a}\n </button>\n <button\n type="button"\n id="registration-success-profile"\n class="w-full py-3 px-4 bg-white text-gray-700 font-medium rounded-lg border border-gray-300 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 transition-colors"\n >\n ${P.A.render(d,{class:"inline-block w-5 h-5 mr-2"})}\n ${r}\n </button>\n </div>\n </div>\n `,size:"medium",closeButton:!0,closeOnOverlay:!1,closeOnEscape:!1});c.open(),setTimeout((()=>{this.setupRegistrationSuccessHandlers(c,e)}),100)}),100)}))}))}setupRegistrationSuccessHandlers(e,t){const n=t=>{sessionStorage.removeItem("showingRegistrationModal"),e.close(),setTimeout((()=>{window.location.href=t}),100)},o=!!sessionStorage.getItem("pendingSubscriptionPlan"),i=document.getElementById("registration-success-explore");i&&i.addEventListener("click",(()=>{n(o?window.location.href:"/")}));const a=document.getElementById("registration-success-profile");a&&a.addEventListener("click",(()=>{o?(sessionStorage.removeItem("pendingSubscriptionPlan"),n("/subscribe")):n("/profile")}))}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}destroy(){const e=document.getElementById(this.formId);e&&e.reset()}}"undefined"!=typeof window&&(window.testRegistrationModal=()=>{new Q({getTemplateData:()=>({companyName:"Your Company",companyImgSrc:""}),getConfig:()=>({heimguardConfig:{}})}).showRegistrationSuccessModal({id:"123",email:"[email protected]",firstName:"John",lastName:"Doe",displayName:"John Doe",verified:!1,provider:"basic"})});var X=Q;var ee=class{constructor(e){this.authConfig=e,this.formId=`forgot-password-form-${Date.now()}`,this.alertId=`forgot-password-alert-${Date.now()}`}generateHTML(e=!1,t){const n=this.authConfig.getTemplateData();return e?`\n <div class="auth-modal-wrapper">\n <div class="auth-component forgot-password-component w-full">\n ${this.renderHeader(n,e,t)}\n ${this.renderForm()}\n ${this.renderFooter(e,t)}\n </div>\n </div>\n `:`\n <div class="auth-component forgot-password-component w-full max-w-[500px] mx-auto">\n \x3c!-- Card Container --\x3e\n <div class="bg-white rounded-2xl shadow-xl border border-gray-100 overflow-hidden">\n ${this.renderHeader(n,e,t)}\n ${this.renderForm()}\n ${this.renderFooter(e,t)}\n </div>\n </div>\n `}renderHeader(e,t,n){return`\n <div class="px-8 pt-8 pb-6 text-center bg-gradient-to-br from-primary-50 to-secondary-50 ${t?"":"-m-8 mb-6"} ${t?"rounded-t-2xl":""}">\n <div class="mx-auto h-16 w-16 bg-primary-600 rounded-2xl flex items-center justify-center mb-4 mt-4 shadow-lg">\n ${P.A.auth.key()}\n </div>\n ${e.companyImgSrc?`<img src="${e.companyImgSrc}" alt="${e.companyName}" class="h-10 mx-auto mb-4 opacity-90">`:""}\n <h2 class="text-2xl font-bold text-gray-900 mb-2 px-4">${n?.title||"Forgot your password?"}</h2>\n <p class="text-gray-600 text-sm px-4">${n?.description||"We'll email you a link to reset it."}</p>\n </div>\n `}renderForm(){const e=$.render({id:`${this.formId}-email`,name:"email",label:"Email Address",placeholder:"Enter your email address",required:!0,icon:P.A.auth.email(),helperText:"Enter the email address associated with your account"});return`\n <div class="px-8 py-6">\n ${`\n <div id="${this.alertId}" class="rounded-md p-4 border shadow-lg hidden mb-4 alert-container" role="alert">\n <div class="flex">\n <div class="flex-shrink-0 alert-icon">\n \x3c!-- Icon will be updated dynamically --\x3e\n </div>\n <div class="flex-1 ml-3">\n <div class="text-sm alert-message"></div>\n </div>\n </div>\n </div>\n `}\n \n <form id="${this.formId}" class="space-y-5" novalidate>\n ${e}\n \n \x3c!-- Submit Button --\x3e\n <button\n type="submit"\n id="${this.formId}-submit"\n class="w-full flex justify-center py-2.5 px-4 border border-transparent roun
1ded-lg shadow-sm text-sm font-medium text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition-colors"\n >\n Send Reset Link\n </button>\n </form>\n </div>\n `}renderFooter(e,t){const n=e?"":"rounded-b-2xl";let o="";if(t?.showSupportEmail){const e=this.authConfig.getConfig();o=`\n <p class="text-sm text-gray-600">\n Having issues? \n <a href="mailto:${e.heimguardConfig?.generalConfig?.companySupportEmail||"[email protected]"}" class="font-medium text-primary-600 hover:text-primary-500 transition-colors">\n Contact our support team\n </a>\n </p>\n `}else o=`\n <a href="#" class="text-sm text-gray-500 hover:text-gray-700 transition" data-login-trigger>\n ${P.A.render("chevron-left",{class:"w-4 h-4 inline mr-1"})}\n Back to sign in\n </a>\n `;return`\n <div class="px-8 py-6 bg-gray-50 border-t border-gray-100 ${n}">\n <div class="text-center">\n ${o}\n </div>\n </div>\n `}setupFormHandling(e){const t=e||document,n=t.querySelector(`#${this.formId}`);n&&(n.addEventListener("submit",(async e=>{e.preventDefault(),await this.handleSubmit(n)})),t instanceof HTMLElement&&(t._authComponent=this))}async handleSubmit(e){const t=e.querySelector(`#${this.formId}-submit`);document.getElementById(this.alertId);this.clearErrors();const n={email:new FormData(e).get("email")},o=K(n,_.forgotPassword);if(!o.isValid)return void this.showErrors(o.errors);const i=F.A.setSubmitting(t.id,"Sending...");try{const e=await fetch(f.A.apiResetPasswordUrl,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},credentials:"include",body:JSON.stringify(n)}),t=await e.json();if(!e.ok){if(404===e.status)return void await this.handleSuccess(n.email);throw new Error(t.message||"Failed to send reset link")}await this.handleSuccess(n.email)}catch(e){console.error("Forgot password error:",e);const t=this.getErrorMessage(e);this.showAlert(t,"error"),i?.restore()}}async handleSuccess(e){const t=document.querySelector(`#${this.formId}-email`)?.closest(".form-field");t&&this.clearFieldError(t),this.showAlert("Password reset link sent! Please check your email.","success");const n=document.getElementById(this.formId);n&&(n.reset(),n.style.opacity="0.5",n.style.pointerEvents="none");const o=n?.querySelector(`#${this.formId}-submit`);o&&F.A.setSuccess(o,"Email Sent!",3e3),setTimeout((()=>{n&&(n.style.opacity="1",n.style.pointerEvents="auto"),o&&(o.disabled=!1,o.textContent="Send Reset Link")}),5e3)}showErrors(e){Object.entries(e).forEach((([e,t])=>{const n=document.getElementById(`${this.formId}-${e}`);if(n){const e=n.closest(".form-field");e&&this.showFieldError(e,Array.isArray(t)?t[0]:t)}}
1))}showFieldError(e,t){const n=e.querySelector(".flex");if(!n)return;n.classList.add("border-red-500","focus-within:border-red-600"),n.classList.remove("border-gray-300","focus-within:border-primary-500");let o=e.querySelector('[role="alert"]');o||(o=document.createElement("div"),o.className="mt-1.5 flex items-start gap-1.5",o.setAttribute("role","alert"),o.innerHTML=`\n ${P.A.render("alert-circle",{class:"w-4 h-4 text-red-500 flex-shrink-0 mt-0.5"})}\n <span class="text-sm text-red-600 font-medium">${t}</span>\n `,n.insertAdjacentElement("afterend",o))}clearFieldError(e){const t=e.querySelector(".flex");if(!t)return;t.classList.remove("border-red-500","focus-within:border-red-600"),t.classList.add("border-gray-300","focus-within:border-primary-500");const n=e.querySelector('[role="alert"]');n&&n.remove()}clearErrors(){const e=document.getElementById(this.formId);if(!e)return;e.querySelectorAll(".form-field").forEach((e=>{const t=e.querySelector(".flex");t&&(t.classList.remove("border-red-500","focus-within:border-red-600"),t.classList.add("border-gray-300","focus-within:border-primary-500"));const n=e.querySelector('[role="alert"]');n&&n.remove()}));const t=document.getElementById(this.alertId);t&&t.classList.add("hidden");const n=e.nextElementSibling;n&&n.classList.contains("bg-green-50")&&n.remove()}showAlert(e,t="error"){const n=document.getElementById(this.alertId);if(!n)return;const o={error:{bg:"bg-red-50",border:"border-red-200",text:"text-red-700",iconColor:"text-red-400",icon:P.A.render("x-circle",{class:"h-5 w-5 text-red-400"})},success:{bg:"bg-green-50",border:"border-green-200",text:"text-green-700",iconColor:"text-green-400",icon:P.A.render("check-circle",{class:"h-5 w-5 text-green-400"})},info:{bg:"bg-blue-50",border:"border-blue-200",text:"text-blue-700",iconColor:"text-blue-400",icon:P.A.render("info",{class:"h-5 w-5 text-blue-400"})}},i=o[t]||o.error;n.className=n.className.replace(/bg-\w+-50|border-\w+-200/g,""),n.classList.add(i.bg,i.border);const a=n.querySelector(".alert-icon");a&&(a.innerHTML=i.icon);const s=n.querySelector(".alert-message");s&&(s.className=`text-sm alert-message ${i.text}`,s.textContent=e),n.classList.remove("hidden")}getErrorMessage(e){const t=e.message||e.toString();return t.includes("network")||t.includes("fetch")?"Unable to connect to the server. Please check your internet connection.":t.includes("rate limit")||t.includes("429")?"Too many attempts. Please wait a few minutes before trying again.":t.includes("timeout")?"The request timed out. Please try again.":t.includes("500")||t.includes("server")?"A server error occurred. Please try again later.":t||"An unexpected error occurred. Please try again."}destroy(){const e=document.getElementById(this.formId);e&&e.reset()}},te=n(8050);var ne=class{constructor(e){this.token=null,this.email=null,this.tokenValidated=!1,this.tokenValid=!1,this.eventListeners=new Map,this.authConfig=e,this.formId=`set-new-password-form-${Date.now()}`,this.alertId=`set-new-password-alert-${Date.now()}`}addTrackedListener(e,t,n){e.addEventListener(t,n),this.eventListeners.has(e)||this.eventListeners.set(e,[]),this.eventListeners.get(e).push({event:t,handler:n})}generateHTML(e=!1,t){const n=new URLSearchParams(window.location.search),o=n.get("reset-token")||n.get("token")||n.get("t")||"",i=n.get("email")||n.get("e")||"";if(o){if(sessionStorage.setItem("heimguard_reset_token",o),i&&sessionStorage.setItem("heimguard_reset_email",i),this.token=o,this.email=i,window.history&&window.history.replaceState){const e=window.location.pathname;window.history.replaceState({},"",e)}}else this.token=sessionStorage.getItem("heimguard_reset_token")||"",this.email=sessionStorage.getItem("heimguard_reset_email")||"";const a=this.authConfig.getConfig(),s=V.getRequirements(a),r=U.render({id:`${this.formId}-password`,name:"password",label:"New Password",placeholder:"Enter your new password",required:!0,showToggle:!0,showStrength:!0,icon:P.A.auth.password(),autocomplete:"new-password"}),d=U.render({id:`${this.formId}-confirmPassword`,name:"confirmPassword",label:"Confirm New Password",placeholder:"Confirm your new password",required:!0,showToggle:!0,icon:P.A.auth.password(),autocomplete:"new-password"});return e?`\n <div class="auth-modal-wrapper">\n <div class="auth-component set-new-password-component w-full">\n ${this.renderHeader()}\n ${this.renderForm(r,d,s)}\n </div>\n </div>\n `:`\n <div class="auth-component set-new-password-component w-full max-w-[500px] mx-auto">\n \x3c!-- Card Container --\x3e\n <div class="bg-white rounded-2xl shadow-xl border border-gray-100 overflow-hidden">\n ${this.renderHeader()}\n ${this.renderForm(r,d,s)}\n </div>\n </div>\n `}renderHeader(){return`\n \x3c!-- Header --\x3e\n <div class="bg-gradient-to-r from-primary-600 to-secondary-600 px-8 py-10 text-center">\n <div class="inline-flex items-center justify-center w-16 h-16 bg-white/20 backdrop-blur rounded-full mb-4 mt-4">\n ${P.A.auth.key()}\n </div>\n <h2 class="text-2xl font-bold text-white mb-2">Set New Password</h2>\n <p class="text-white/80 text-sm">\n Please choose a strong password for your account\n </p>\n </div>\n `}renderForm(e,t,n){const o=V.generateTips(n);return`\n \x3c!-- Form Body --\x3e\n <div class="p-8">\n \x3c!-- Alert Container --\x3e\n <div id="${this.alertId}"></div>\n\n \x3c!-- Token Status --\x3e\n ${this.renderTokenStatus()}\n\n <form id="${this.formId}" class="space-y-6">\n \x3c!-- Hidden fields --\x3e\n <input type="hidden" name="token" value="${this.escapeHtml(this.token||"")}">\n <input type="hidden" name="email" value="${this.escapeHtml(this.email||"")}">\n\n ${e}\n\n \x3c!-- Password Requirements --\x3e\n ${this.renderPasswordRequirements(o)}\n\n ${t}\n\n \x3c!-- Submit Button - starts disabled, enabled by JS when token is valid and passwords match --\x3e\n <button\n type="submit"\n id="${this.formId}-submit"\n class="w-full flex justify-center py-2.5 px-4 border border-transparent roun
1ded-lg shadow-sm text-sm font-medium text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"\n disabled\n >\n Reset Password\n </button>\n </form>\n\n \x3c!-- Footer Links --\x3e\n <div class="mt-8 text-center">\n <p class="text-sm text-gray-600">\n Remember your password?\n <a href="#" data-login-trigger class="font-medium text-primary-600 hover:text-primary-500 transition-colors">\n Back to login\n </a>\n </p>\n </div>\n </div>\n `}renderTokenStatus(){return`<div id="${this.formId}-token-status" class="mb-6"></div>`}renderPasswordRequirements(e){return e&&0!==e.length?`\n <div class="bg-gray-50 rounded-lg p-4">\n <h4 class="text-sm font-medium text-gray-700 mb-2">Password Requirements:</h4>\n <ul class="space-y-1">\n ${e.map((e=>`\n <li class="flex items-start text-sm text-gray-600">\n ${P.A.render("check-circle",{class:"w-4 h-4 text-gray-400 mr-2 mt-0.5 flex-shrink-0"})}\n ${e}\n </li>\n `)).join("")}\n </ul>\n </div>\n `:""}async setupFormHandling(e){!this.tokenValidated&&this.token&&await this.validateToken(e);const t=e.querySelector(`#${this.formId}`);if(!t)return;const n=this.authConfig.getConfig(),o=V.getRequirements(n),i=t.querySelector(`#${this.formId}-password`);if(i){const n=n=>{const i=n.target;this.validatePasswordField(i.value,o);const a=t.querySelector(`#${this.formId}-confirmPassword`);a&&a.value&&this.validatePasswordMatch(),this.updateSubmitButtonState(e)};this.addTrackedListener(i,"input",n)}const a=t.querySelector(`#${this.formId}-confirmPassword`);if(a){const t=()=>{this.validatePasswordMatch(),this.updateSubmitButtonState(e)};this.addTrackedListener(a,"input",t)}this.addTrackedListener(t,"submit",(async e=>{e.preventDefault(),await this.handleSubmit(t)})),this.setupPasswordToggles(e)}async validateToken(e){if(!this.token)return this.tokenValidated=!0,this.tokenValid=!1,void this.showTokenStatusMessage(e,"error","Invalid Reset Link","This password reset link is invalid or has expired. Please request a new password reset.");const t=sessionStorage.getItem("heimguard_token_validated"),n=sessionStorage.getItem("heimguard_reset_token");if(t&&n===this.token){const n="true"===t;return this.tokenValidated=!0,this.tokenValid=n,void(n?(this.email&&this.showTokenStatusMessage(e,"info",null,`Setting new password for <strong>${this.email}</strong>`),this.updateSubmitButtonState(e)):this.showTokenStatusMessage(e,"error","Invalid Reset Link","This password reset link is invalid or has expired. Please request a new password reset."))}try{const t=await fetch(f.A.apiValidateResetTokenUrl,{method:"POST",credentials:"include",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({"reset-token":this.token})}),n=await t.json();this.tokenValidated=!0,this.tokenValid="success"===n.status,sessionStorage.setItem("heimguard_token_validated",this.tokenValid.toString()),this.tokenValid?(this.email&&this.showTokenStatusMessage(e,"info",null,`Setting new password for <strong>${this.email}</strong>`),this.updateSubmitButtonState(e)):this.showTokenInvalidError(e,n.message||"This password reset link is invalid or has expired.")}catch(e){console.error("[SetNewPasswordForm] Token validation failed:",e),this.tokenValidated=!0,this.tokenValid=!0,sessionStorage.setItem("heimguard_token_validated","true")}}updateSubmitButtonState(e){const t=e.querySelector(`#${this.formId}-submit`);if(!t)return;if(!this.tokenValid)return void t.setAttribute("disabled","");const n=e.querySelector(`#${this.formId}`);if(!n)return;const o=n.querySelector(`#${this.formId}-password`),i=n.querySelector(`#${this.formId}-confirmPassword`),a=o?.value||"",s=i?.value||"",r=this.authConfig.getConfig(),d=V.getRequirements(r),l=a&&s&&a===s,c=V.validate(a,d).valid;this.tokenValid&&c&&l?t.removeAttribute("disabled"):t.setAttribute("disabled","")}showTokenStatusMessage(e,t,n,o){const i=e.querySelector(`#${this.formId}-token-status`);i&&(i.innerHTML="error"===t?`\n <div class="p-4 bg-red-50 border border-red-200 rounded-lg">\n <div class="flex items-start">\n ${P.A.status.error()}\n <div class="ml-3">\n ${n?`<h3 class="text-sm font-medium text-red-800">${n}</h3>`:""}\n <p class="text-sm text-red-700 ${n?"mt-1":""}">\n ${o}\n </p>\n </div>\n </div>\n </div>\n `:`\n <div class="p-4 bg-blue-50 border border-blue-200 rounded-lg">\n <div class="flex items-center">\n ${P.A.status.info()}\n <div class="ml-3">\n <p class="text-sm text-blue-800">\n ${o}\n </p>\n </div>\n </div>\n </div>\n `)}showTokenInvalidError(e,t){const n=e.querySelector(`#${this.formId}`);if(!n)return;this.showAlert(t,"error");const o=n.querySelector(`#${this.formId}-submit`);o&&(o.disabled=!0,o.textContent="Link Expired");n.querySelectorAll("input").forEach((e=>{e.disabled=!0})),n.style.opacity="0.6",n.style.pointerEvents="none"}setupPasswordToggles(e){e.querySelectorAll(".toggle-password").forEach((e=>{this.addTrackedListener(e,"click",(()=>{const t=e.getAttribute("data-target");if(!t)return;const n=document.getElementById(t);if(!n)return;const o=e.querySelector(".show-password"),i=e.querySelector(".hide-password");"password"===n.type?(n.type="text",o?.classList.add("hidden"),i?.classList.remove("hidden")):(n.type="password",o?.classList.remove("hidden"),i?.classList.add("hidden"))}))}))}validatePasswordField(e,t){const n=document.querySelector(`#${this.formId}-password-strength`);if(!n)return;const o=V.validate(e,t),i=o.strength,a={red:{bg:"bg-red-500",text:"text-red-600"},orange:{bg:"bg-orange-500",text:"text-orange-600"},yellow:{bg:"bg-yellow-500",text:"text-yellow-600"},green:{bg:"bg-green-500",text:"text-green-600"},emerald:{bg:"bg-green-600",text:"text-green-700"}},s=n.querySelector(".strength-bar"),r=n.querySelector(".strength-text");if(e){n.classList.remove("hidden"),s.style.width=`${i.percentage}%`;const e=a[i.color]||a.green;s.className=`strength-bar h-1.5 rounded-full transition-all duration-300 ${e.bg}`,r.textContent=i.level,r.className=`text-xs strength-text ${e.text}`}else n.classList.add("hidden");const d=document.querySelector(`#${this.formId}-password`),l=d?.closest(".form-field");
1if(l)if(!o.valid&&e.length>0){const e=V.generateErrorMessage(o.errors);this.showFieldError(l,e)}else this.clearFieldError(l)}validatePasswordMatch(){const e=document.querySelector(`#${this.formId}-password`)?.value||"",t=document.querySelector(`#${this.formId}-confirmPassword`)?.value||"",n=document.querySelector(`#${this.formId}-confirmPassword`),o=n?.closest(".form-field");if(!o)return;const i=V.validateMatch(e,t);!i.valid&&t?this.showFieldError(o,i.error||"Passwords do not match"):this.clearFieldError(o)}async handleSubmit(e){const t=e.querySelector(`#${this.formId}-submit`);this.clearErrors();const n=new FormData(e),o={token:n.get("token"),email:n.get("email"),password:n.get("password"),confirmPassword:n.get("confirmPassword")},i=this.validateForm(o);if(!i.isValid)return void this.showErrors(i.errors);const a=F.A.setSubmitting(t.id,"Resetting password...");try{const e={"reset-token":o.token,password:o.password},t=await fetch(f.A.apiSetPasswordUrl,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},credentials:"include",body:JSON.stringify(e)}),n=await t.json();if(!t.ok)throw new Error(n.message||"Failed to reset password");await this.handleSuccess(n)}catch(e){console.error("Password reset error:",e);const t=this.getErrorMessage(e);this.showAlert(t,"error"),a?.restore()}}validateForm(e){const t={};e.token||(t.general="Invalid or missing reset token");const n=this.authConfig.getConfig(),o=V.getRequirements(n);if(e.password){const n=V.validate(e.password,o);n.valid||(t.password=V.generateErrorMessage(n.errors))}else t.password="Password is required";if(e.confirmPassword){const n=V.validateMatch(e.password,e.confirmPassword);n.valid||(t.confirmPassword=n.error||"Passwords do not match")}else t.confirmPassword="Please confirm your password";return{isValid:0===Object.keys(t).length,errors:t}}async handleSuccess(e){this.clearErrors(),sessionStorage.removeItem("heimguard_reset_token"),sessionStorage.removeItem("heimguard_reset_email"),sessionStorage.removeItem("heimguard_token_validated");const t=e?.success&&e?.user,o=t?"Password reset successfully! Redirecting to your profile...":"Password reset successfully! Redirecting to login...";this.showAlert(o,"success");const i=document.getElementById(this.formId);i&&(i.reset(),i.style.opacity="0.5",i.style.pointerEvents="none");const a=i?.querySelector(`#${this.formId}-submit`);a&&F.A.setSuccess(a,"Password Reset!",3e3);const s=await Promise.resolve().then(n.bind(n,7310)).then((e=>e.default)),r=await s.load();setTimeout((()=>{try{if(t&&r?.profile?.url)window.location.href=r.profile.url;else{const e=r?.login?.url,n=r?.profile?.url;if(!e)return console.error("[SetNewPasswordForm] No login URL found in HeimGuard settings"),void this.showManualRedirectOption(t,r);const o=new URL(e,window.location.origin);n&&o.searchParams.set("referrerUrl",encodeURIComponent(n)),window.location.href=o.toString()}}catch(e){console.error("Failed to redirect:",e),this.showManualRedirectOption(t,r)}}),2e3)}showManualRedirectOption(e,t){const n=document.getElementById(this.formId);if(!n)return;const o=t?.profile?.url,i=t?.login?.url;if(!o&&e)return void this.showAlert("Password reset successfully! Please navigate to your profile manually.","success");if(!i&&!e)return void this.showAlert("Password reset successfully! Please navigate to the login page manually.","success");const a=e?"Go to Profile":"Go to Login";let s=e?o:i;if(!e&&i&&o){const e=new URL(i,window.location.origin);e.searchParams.set("referrerUrl",encodeURIComponent(o)),s=e.toString()}this.showAlert("Password reset successfully!","success");const r=document.getElementById(this.alertId);if(r){const e=document.createElement("div");e.className="mt-3",e.innerHTML=`\n <a href="${s}" \n class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">\n ${a}\n </a>\n `,r.appendChild(e)}n.style.opacity="1",n.style.pointerEvents="auto"}showErrors(e){Object.entries(e).forEach((([e,t])=>
1{"general"===e?this.showAlert(t,"error"):this.showFieldErrorByName(e,t)}))}showFieldErrorByName(e,t){const n=document.getElementById(`${this.formId}-${e}`);if(!n)return;const o=n.closest(".form-field");o&&this.showFieldError(o,t)}showFieldError(e,t){const n=e.querySelector(".flex");n&&(n.classList.remove("border-gray-300","focus-within:border-primary-500"),n.classList.add("border-red-500","focus-within:border-red-500"));const o=e.querySelector(".field-error");o&&o.remove();const i=document.createElement("div");i.className="field-error mt-1 text-sm text-red-600",i.textContent=t,e.appendChild(i)}clearFieldError(e){const t=e.querySelector(".flex");t&&(t.classList.remove("border-red-500","focus-within:border-red-500"),t.classList.add("border-gray-300","focus-within:border-primary-500"));const n=e.querySelector(".field-error");n&&n.remove()}clearErrors(){document.querySelectorAll(".field-error").forEach((e=>e.remove())),document.querySelectorAll(".border-red-500").forEach((e=>{e.classList.remove("border-red-500","focus-within:border-red-500"),e.classList.add("border-gray-300","focus-within:border-primary-500")}))}showAlert(e,t="info"){const n=document.getElementById(this.alertId);n&&(n.innerHTML=te.Alert.render({message:e,variant:t,id:`${this.alertId}-alert`}),"error"===t&&setTimeout((()=>{const e=n.querySelector(".alert");e&&e.remove()}),5e3))}getErrorMessage(e){const t=e.message||"An error occurred",n={"Invalid token":"This password reset link is invalid or has expired","Token expired":"This password reset link has expired. Please request a new one","User not found":"No account found with this email address","Network error":"Unable to connect. Please check your internet connection"};for(const[e,o]of Object.entries(n))if(t.toLowerCase().includes(e.toLowerCase()))return o;return t}escapeHtml(e){const t={"&":"&","<":"<",">":">",'"':""","'":"'"};return e.replace(/[&<>"']/g,(e=>t[e]))}destroy(){this.eventListeners.forEach(((e,t)=>{e.forEach((({event:e,handler:n})=>{t.removeEventListener(e,n)}))})),this.eventListeners.clear();const e=document.getElementById(this.formId);e&&e.reset(),sessionStorage.removeItem("heimguard_reset_token"),sessionStorage.removeItem("heimguard_reset_email"),sessionStorage.removeItem("heimguard_token_validated")}},oe=n(2554),ie=n(7450),ae=n(2972);class se{constructor(e={}){this.state={isAuthenticated:!1,user:null,provider:null,isLoading:!1,error:null,sessionExpiry:null,requiresTwoFactor:!1,tempToken:null,rememberMe:!1},this.config={authCookie:"heimguard.authStatus",userCookie:"heimguard.user",providerCookie:"heimguard.provider",validateOnInit:!0,sessionCheckInterval:3e5,...e},this.listeners=new Set,this.providers=new Map,this.sessionCheckTimer=null,this.initialized=!1,this.handleAuthEvent=this.handleAuthEvent.bind(this),this.checkSession=this.checkSession.bind(this)}async initialize(){if(this.initialized)console.log("AuthManager already initialized");else try{console.log("ð Initializing AuthManager..."),await this.loadStateFromCookies(),this.config.validateOnInit&&this.state.isAuthenticated&&await this.validateSession(),this.setupEventListeners(),this.startSessionMonitoring(),this.initialized=!0,(0,J.KM)(J.QU.STATE_CHANGED,{oldState:{},newState:this.getState(),reason:"initialization"}),console.log("â
AuthManager initialized:",this.getState())}catch(e){console.error("â AuthManager initialization failed:",e),this.handleError(e,"initialization")}}getState(){return{...this.state}}subscribe(e){return this.listeners.add(e),e(this.getState()),()=>this.listeners.delete(e)}setState(e,t="unknown"){const n={...this.state};this.state={...this.state,...e},this.saveStateToCookies(),this.notifyListeners(),(0,J.KM)(J.QU.STATE_CHANGED,{oldState:n,newState:this.getState(),updates:e,reason:t}),this.updateBodyClasses()}notifyListeners(){const e=this.getState();this.listeners.forEach((t=>{try{t(e)}catch(e){console.error("Error in state listener:",e)}}))}registerProvider(e,t){if(!t)throw new Error(`Invalid provider for type: ${e}`);this.providers.set(e,t),console.log(`â
Registered auth provider: ${e}`)}getProvider(e){return this.providers.get(e)||null}async login(e,t){const n=this.providers.get(e);if(!n)throw new Error(`Unknown auth provider: ${e}`);
1console.log(`ð Attempting login with provider: ${e}`),this.setState({isLoading:!0,error:null},"login-start"),(0,J.KM)(J.QU.LOGIN_START,{provider:e});try{const o=await n.login(t);return o.requiresTwoFactor?(this.setState({isLoading:!1,requiresTwoFactor:!0,tempToken:o.tempToken,provider:e},"two-factor-required"),(0,J.KM)(J.QU.TWO_FACTOR_REQUIRED,{provider:e,tempToken:o.tempToken}),o):(this.setState({isAuthenticated:!0,user:o.user,provider:e,isLoading:!1,error:null,sessionExpiry:o.expiresAt?new Date(o.expiresAt):null,requiresTwoFactor:!1,tempToken:null},"login-success"),(0,J.KM)(J.QU.LOGIN_SUCCESS,{user:o.user,provider:e,remember:this.state.rememberMe}),console.log("â
Login successful:",o.user),o)}catch(t){const n=this.handleError(t,"login");throw this.setState({isLoading:!1,error:n.message},"login-error"),(0,J.KM)(J.QU.LOGIN_ERROR,{error:n,provider:e}),n}}async completeTwoFactor(e){if(!this.state.requiresTwoFactor||!this.state.tempToken)throw new Error("Two-factor authentication not required");const t=this.providers.get(this.state.provider);if(!t||!t.supports||!t.supports("twoFactor"))throw new Error("Provider does not support two-factor authentication");this.setState({isLoading:!0},"two-factor-start"),(0,J.KM)(J.QU.TWO_FACTOR_START,{provider:this.state.provider});try{const n=await t.login({code:e,tempToken:this.state.tempToken});return this.setState({isAuthenticated:!0,user:n.user,isLoading:!1,error:null,sessionExpiry:n.expiresAt?new Date(n.expiresAt):null,requiresTwoFactor:!1,tempToken:null},"two-factor-success"),(0,J.KM)(J.QU.TWO_FACTOR_SUCCESS,{user:n.user,provider:this.state.provider}),n}catch(e){const t=this.handleError(e,"two-factor");throw this.setState({isLoading:!1,error:t.message},"two-factor-error"),(0,J.KM)(J.QU.TWO_FACTOR_ERROR,{error:t,provider:this.state.provider}),t}}async logout(){if(!this.state.isAuthenticated)return void console.log("No active session to logout");const e=this.providers.get(this.state.provider);this.setState({isLoading:!0},"logout-start"),(0,J.KM)(J.QU.LOGOUT_START,{provider:this.state.provider});try{e&&await e.logout(),this.clearAuthState(),(0,J.KM)(J.QU.LOGOUT_SUCCESS,{provider:this.state.provider}),console.log("â
Logout successful")}catch(e){console.error("Logout error:",e),this.clearAuthState(),(0,J.KM)(J.QU.LOGOUT_ERROR,{error:e,provider:this.state.provider})}}async register(e,t="basic"){const n=this.providers.get(t);if(!n||n.supports&&!n.supports("register"))throw new Error(`Provider ${t} does not support registration`);this.setState({isLoading:!0,error:null},"register-start"),(0,J.KM)(J.QU.REGISTER_START,{provider:t});try{const o=await n.login(e);return o.user&&o.success?this.setState({isAuthenticated:!0,user:o.user,provider:t,isLoading:!1,error:null,sessionExpiry:o.expiresAt?new Date(o.expiresAt):null},"register-success"):this.setState({isLoading:!1},"register-success-no-login"),(0,J.KM)(J.QU.REGISTER_SUCCESS,{user:o.user,requiresVerification:!o.user?.verified}),o}catch(e){const n=this.handleError(e,"register");throw this.setState({isLoading:!1,error:n.message},"register-error"),(0,J.KM)(J.QU.REGISTER_ERROR,{error:n,provider:t}),n}}async validateSession(){const e=this.providers.get(this.state.provider);if(!e||!this.state.isAuthenticated)return!1;try{const t=await e.validateSession();return!1!==t?(this.setState({user:t,sessionExpiry:null},"session-validated"),(0,J.KM)(J.QU.SESSION_VALID,{user:t}),!0):(this.clearAuthState("session-invalid"),(0,J.KM)(J.QU.SESSION_INVALID,t),!1)}catch(e){return console.error("Session validation error:",e),this.state.isAuthenticated}}async refreshToken(){const e=this.providers.get(this.state.provider);if(!e||e.supports&&!e.supports("sessionRefresh"))return!1;try{const t=await e.validateSession();return!1!==t&&(this.setState({user:t},"token-refreshed"),(0,J.KM)(J.QU.SESSION_REFRESHED,{user:t}),!0)}catch(e){return console.error("Token refresh error:",e),(0,J.KM)(J.QU.SESSION_REFRESH_ERROR,{error:e}),!1}}async loadStateFromCookies(){try{const e=ae.c.getCookie(this.config.authCookie);if(!e)return void console.log("No auth cookie found");const t=this.decodeAuthCookie(e);if(t){const e=ae.c.getCookie(this.config.userCookie),n=ae.c.getCookie(this.config.providerCookie);this.state={...this.state,isAuthenticated:!0,user:e?JSON.parse(atob(e)):t,provider:n||t.provider||"basic",sessionExpiry:t.expiresAt?new Date(t.expiresAt):null},console.log("ð¦ Loaded auth state from cookies:",this.state.provider)}}catch(e){console.error("Error loading state from cookies:",e),this.clearAuthState("cookie-error")}}saveStateToCookies(){try{if(this.state.isAuthenticated&&this.state.user){const e={id:this.state.user.id,email:this.state.user.email,provider:this.state.provider,expiresAt:this.state.sessionExpiry?.toISOString()},t=btoa(JSON.stringify(e)),n=new Date;n.setDate(n.getDate()+7),ae.c.createCookie(this.config.authCookie,t,n.getTime(),void 0),this.state.user&&ae.c.createCookie(this.config.userCookie,btoa(JSON.stringify(this.state.user)),n.getTime(),void 0),this.state.provider&&ae.c.createCookie(this.config.providerCookie,this.state.provider,n.getTime(),void 0)}else this.clearCookies()}catch(e){console.error("Error saving state to cookies:",e)}}clearCookies(){[this.config.authCookie,this.config.userCookie,this.config.providerCookie,"heimguard.token","heimguard.session","auth_token","session_token"].forEach((e=>{try{ae.c.eraseCookie(e,void 0)}catch(t){console.warn(`Failed to clear cookie ${e}:`,t)}}))}decodeAuthCookie(e){try{const t=atob(e);return JSON.parse(t)}catch(e){return console.error("Failed to decode auth cookie:",e),null}}clearAuthState(e="manual"){this.setState({isAuthenticated:!1,user:null,provider:null,error:null,sessionExpiry:null,requiresTwoFactor:!1,tempToken:null,isLoading:!1},e),this.clearCookies()}setupEventListeners(){(0,J.sQ)(J.QU.SESSION_EXPIRED,this.handleAuthEvent),(0,J.sQ)(J.QU.LOGIN_SUCCESS,this.handleAuthEvent),(0,J.sQ)(J.QU.LOGOUT_SUCCESS,this.handleAuthEvent),window.addEventListener("auth:login",this.handleAuthEvent),window.addEventListener("auth:logout",this.handleAuthEvent),window.addEventListener("heimguard:logout",this.handleAuthEvent)}handleAuthEvent(e){const t=e.type||e.eventName,n=e.detail||e;if("AuthManager"!==n.source)switch(t){case J.QU.SESSION_EXPIRED:case"auth:session:expired":this.clearAuthState("session-expired");break;case J.QU.LOGIN_SUCCESS:case"auth:login":n.user&&this.setState({isAuthenticated:!0,user:n.user,provider:n.provider||"basic"},"external-login");break;case J.QU.LOGOUT_SUCCESS:case"auth:logout":case"heimguard:logout":this.clearAuthState("external-logout")}}startSessionMonitoring(){this.sessionCheckTimer&&clearInterval(this.sessionCheckTimer),this.sessionCheckTimer=setInterval(this.checkSession,this.config.sessionCheckInterval)}async checkSession(){if(this.state.isAuthenticated&&this.state.sessionExpiry){const e=this.state.sessionExpiry.getTime(),t=Date.now();if(e<=t)return console.log("â° Session expired"),this.clearAuthState("session-expired"),void(0,J.KM)(J.QU.SESSION_EXPIRED,{lastActivity:this.state.sessionExpiry});e-t<3e5&&(console.log("ð Session expiring soon, attempting refresh..."),await this.refreshToken())}}updateBodyClasses(){"undefined"!=typeof document&&(document.body.classList.toggle("user-authenticated",this.state.isAuthenticated),document.body.classList.toggle("user-guest",!this.state.isAuthenticated),this.state.provider&&document.body.classList.add(`auth-
1provider-${this.state.provider}`),this.state.user?.role&&document.body.classList.add(`user-role-${this.state.user.role}`))}handleError(e,t){return{code:"AUTH_ERROR",message:ie.zc.handle(e,{component:"AuthManager",context:{operation:t},showNotification:!1}).error.message,details:{operation:t}}}destroy(){this.sessionCheckTimer&&clearInterval(this.sessionCheckTimer),this.listeners.clear(),this.clearAuthState("destroy"),this.initialized=!1}hasRole(e){return this.state.user?.role===e}usedProvider(e){return this.state.provider===e}isAuthenticated(){return this.state.isAuthenticated}getUser(){return this.state.user}getCurrentProviderType(){return this.state.provider}isLoading(){return this.state.isLoading}}var re=new se,de=n(4811);class le{constructor(){this.isLoggingOut=!1,this.lastLogoutAttempt=0,this.LOGOUT_DEBOUNCE_MS=1e3,this.logoutAbortController=null,this.setupEventListeners()}setupEventListeners(){document.addEventListener("click",(e=>{const t=e.target.closest("[data-logout-trigger]");t&&(e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.handleLogout(t))}),{capture:!0}),window.addEventListener(J.QU.UI_LOGOUT,(async e=>{const t=e,n=this.showFullPageLoader();try{await this.performLogout(t.detail?.manual||!1)}catch(e){this.removeFullPageLoader(n);const t=e instanceof Error?e.message:"Unknown error occurred";this.showLogoutError(t)}})),window.addEventListener("pageshow",(e=>{e.persisted&&!this.isUserLoggedIn()&&this.checkAuthStatus()}))}async handleLogout(e){const t=Date.now();if(t-this.lastLogoutAttempt<this.LOGOUT_DEBOUNCE_MS)return void console.log("â ï¸ Logout attempt too soon after previous attempt",{timeSinceLastAttempt:t-this.lastLogoutAttempt,debounceMs:this.LOGOUT_DEBOUNCE_MS});if(this.isLoggingOut||!e)return void console.log("â ï¸ Logout already in progress or no button element",{isLoggingOut:this.isLoggingOut});this.lastLogoutAttempt=t,console.log("ðª Logout triggered from UI element");const n=e.innerHTML;e.disabled;this.setButtonLoading(e,!0);const o=this.showFullPageLoader();try{await this.performLogout(!0)}catch(t){console.error("â Logout failed:",t),this.removeFullPageLoader(o),this.setButtonLoading(e,!1,n);const i=t instanceof Error?t.message:"Logout failed";this.showLogoutError(i),confirm("Logout failed. Would you like to clear your session locally and reload the page?")&&this.forceLogout()}}async performLogout(e=!1){if(this.isLoggingOut)console.log("ð Logout already in progress");else{if(this.isLoggingOut=!0,console.log("ðª Starting logout process...",{manual:e,timestamp:(new Date).toISOString(),isProfilePage:window.location.pathname.includes("/profile"),stack:(new Error).stack}),window.location.pathname.includes("/profile")){console.log("ð Detected logout from profile page - using fast logout"),this.clearLocalSession();const t=document.getElementById("logout-overlay");if(t){const e=t.querySelector(".text-center");e&&(e.innerHTML=`\n <div class="mb-4">\n ${P.H.render("check",{class:"w-16 h-16 text-green-500 mx-auto"})}\n </div>\n <h3 class="text-lg font-semibold text-gray-900 mb-2">Logged Out</h3>\n <p class="text-gray-600">Redirecting to homepage...</p>\n `)}return setTimeout((()=>{window.location.href="/"}),1e3),void fetch(this.getLogoutUrl(),{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({manual:e,timestamp:Date.now()})}).catch((e=>console.log("Background logout request failed:",e)))}this.logoutAbortController&&(console.log("â ï¸ Cancelling previous logout request"),this.logoutAbortController.abort()),this.logoutAbortController=new AbortController,(0,J.KM)(J.QU.LOGOUT_START,{manual:e,source:"LogoutHandler",provider:"basic"});try{const t=this.getLogoutUrl();console.log("ð¡ Sending logout request to:",t);const n=new Promise(((e,t)=>{setTimeout((()=>t(new Error("Logout request timed out after 5 seconds"))),5e3)})),o=await Promise.race([fetch(t,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({manual:e,timestamp:Date.now()}),signal:this.logoutAbortController.signal}),n]);if(console.log("ð¡ Logout response:",{status:o.status,statusText:o.statusText,headers:Object.fromEntries(o.headers.entries()),url:o.url,redirected:o.redirected}),!o.ok){if(401===o.status){console.log("â ï¸ Got 401 during logout - session already expired or cleared"),this.clearLocalSession();const t=this.getLogoutProvider();return(0,J.KM)(J.QU.LOGOUT_SUCCESS,{manual:e,response:{alreadyLoggedOut:!0},source:"LogoutHandler",provider:t}),void this.handleLogoutRedirect({alreadyLoggedOut:!0})}let t="";try{const e=await o.json();t=e.message||e.error||JSON.stringify(e),console.error("â Logout error response body:",e)}catch(e){try{t=await o.text(),console.error("â Logout error response text:",t)}catch(e){t="Unable to read error response"}}throw new Error(`Logout request failed: ${o.status} ${o.statusText}. ${t}`)}let i={};try{i=await o.json()}catch(e){console.log("Logout response was not JSON (this is normal)")}console.log("â
Logout request successful:",i),this.isLoggingOut=!1,this.clearLocalSession();const a=this.getLogoutProvider();(0,J.KM)(J.QU.LOGOUT_SUCCESS,{manual:e,response:i,source:"LogoutHandler",provider:a}),this.handleLogoutRedirect(i)}catch(t){if("AbortError"===t?.name)return void console.log("â ï¸ Logout request was aborted");const n=t instanceof Error?t.message:"Unknown error";if(console.error("â Logout process failed:",t),n.includes("timed out")){console.error("â±ï¸ Logout request timed out - forcing local logout"),this.clearLocalSession();const e=document.getElementById("logout-overlay");if(e){const t=e.querySelector(".text-center");t&&(t.innerHTML=`\n <div class="mb-4">\n ${P.H.render("check",{class:"w-16 h-16 text-green-500 mx-auto"})}\n </div>\n <h3 class="text-lg font-semibold text-gray-900 mb-2">Logged Out</h3>\n <p class="text-gray-600">Redirecting...</p>\n `)}return void setTimeout((()=>{window.location.reload()}),1e3)}throw t instanceof TypeError&&t.message.includes("fetch")&&console.error("ð Network error during logout - possible CORS issue or network connectivity problem"),console.error("â Error c
1ontext:",{errorType:t?.constructor?.name,errorMessage:n,manual:e,timestamp:(new Date).toISOString(),userAgent:navigator.userAgent,online:navigator.onLine}),ie.zc.log("Logout",t,{manual:e}),(0,J.KM)(J.QU.LOGOUT_ERROR,{error:{code:"LOGOUT_FAILED",message:n,provider:this.getLogoutProvider()},manual:e,source:"LogoutHandler"}),t}finally{console.log("ð Logout performLogout finally block - resetting flag"),this.isLoggingOut=!1}}}getLogoutProvider(){return this.isGoogleLogin()?"google":this.isFacebookLogin()?"facebook":"basic"}getLogoutUrl(){const e=this.isGoogleLogin(),t=this.isFacebookLogin(),n=window.HeimGuard?.data,o=!0===n?.isSocialAuth;return console.log("ð Determining logout URL:",{isGoogleLogin:e,isFacebookLogin:t,isSocialAuth:o,hgDataAvailable:!!n,googleLogoutUrl:f.A.apiGoogleLogoutUrl,standardLogoutUrl:f.A.apiLogoutUrl,cookies:{authStatus:!!ae.c.getCookie("heimguard.authStatus"),auth:!!ae.c.getCookie("heimguard.auth"),googleAuth:!!ae.c.getCookie("google_auth"),facebookAuth:!!ae.c.getCookie("facebook_auth")}}),e?(console.log("ð Detected Google login, using Google logout URL"),f.A.apiGoogleLogoutUrl):(console.log("ð Using standard logout URL"),f.A.apiLogoutUrl)}isGoogleLogin(){const e=window.HeimGuard?.data;if(!0===e?.isGoogleAuth)return console.log("ð Detected Google auth from HG init data"),!0;const t=ae.c.getCookie("heimguard.authStatus");if(t)try{const e=JSON.parse(atob(t));return"google"===e.loginMethod||e.isGoogleLogin}catch(e){}return ae.c.hasCookie("google_auth")||"true"===sessionStorage.getItem("google_login")||"google"===localStorage.getItem("heimguard_login_method")}isFacebookLogin(){const e=window.HeimGuard?.data;if(!0===e?.isFacebookAuth)return console.log("ð Detected Facebook auth from HG init data"),!0;const t=ae.c.getCookie("heimguard.authStatus");if(t)try{const e=JSON.parse(atob(t));return"facebook"===e.loginMethod||e.isFacebookLogin}catch(e){}return ae.c.hasCookie("facebook_auth")||"true"===sessionStorage.getItem("facebook_login")||"facebook"===localStorage.getItem("heimguard_login_method")}clearLocalSession(){console.log("ð§¹ Clearing local session data...");["heimguard.auth","heimguard.authStatus","heimguard.loggedIn","heimguard.user","heimguard.token","heimguard.session","google_auth","facebook_auth","auth_token","session_token"].forEach((e=>{ae.c.removeCookie(e,{path:"/"}),console.log(`ðï¸ Attempting to clear cookie: ${e}`),ae.c.eraseCookie(e)}));["heimguard_user","auth_data","google_login","facebook_login","user_session"].forEach((e=>{sessionStorage.getItem(e)&&(sessionStorage.removeItem(e),console.log(`ðï¸ Cleared session storage: ${e}`))}));["heimguard_login_method","auth_token","user_data"].forEach((e=>{localStorage.getItem(e)&&(localStorage.removeItem(e),console.log(`ðï¸ Cleared local storage: ${e}`))})),document.body.classList.remove("user-authenticated"),document.body.classList.add("user-guest"),document.body.classList.remove("user-role-admin","user-role-user","user-role-premium")}handleLogoutRedirect(e){console.log("â
Logout completed successfully"),setTimeout((()=>{de.ModalUtils.hideModal();const e=document.getElementById("auth-module-container");e&&e.classList.add("hidden"),this.isLoggingOut=!0,this.logoutAbortController&&this.logoutAbortController.abort(),console.log("ð Reloading page to update audience variations..."),window.location.replace(window.location.href)}),500)}forceLogout(){console.log("â ï¸ Forcing logout...");const e=this.showFullPageLoader();this.clearLocalSession();const t=this.getLogoutProvider();(0,J.KM)(J.QU.LOGOUT_SUCCESS,{manual:!0,forced:!0,source:"LogoutHandler",provider:t}),setTimeout((()=>{const t=e.querySelector(".text-center");t&&(t.innerHTML=`\n <div class="mb-4">\n ${P.H.render("check",{class:"w-16 h-16 text-green-500 mx-auto"})}\n </div>\n <h3 class="text-lg font-semibold text-gray-900 mb-2">Session Cleared</h3>\n <p class="text-gray-600">You have been logged out. Redirecting...</p>\n `)}),500),setTimeout((()=>{window.location.reload()}),2e3)}showFullPageLoader(){const e=document.createElement("div");return e.id="logout-overlay",e.className="fixed inset-0 z-[9999] bg-white/95 backdrop-blur-sm flex items-center justify-center",e.innerHTML=`\n <div class="text-center">\n \x3c!-- Spinner --\x3e\n <div class="relative inline-block">\n <div class="w-16 h-16 border-4 border-gray-200 border-t-primary-600 rounded-full animate-spin"></div>\n <div class="absolute inset-0 flex items-center justify-center">\n ${P.H.render("log-out",{class:"w-8 h-8 text-primary-600"})}\n </div>\n </div>\n \n \x3c!-- Text --\x3e\n <p class="mt-4 text-lg font-medium text-gray-900">Logging out...</p>\n <p class="mt-2 text-sm text-gray-600">Please wait while we securely sign you out</p>\n \n \x3c!-- Progress dots --\x3e\n <div class="mt-6 flex justify-center space-x-2">\n <div class="w-2 h-2 bg-primary-600 rounded-full animate-bounce" style="animation-delay: 0ms"></div>\n <div class="w-2 h-2 bg-primary-600 rounded-full animate-bounce" style="animation-delay: 150ms"></div>\n <div class="w-2 h-2 bg-primary-600 rounded-full animate-bounce" style="animation-delay: 300ms"></div>\n </div>\n </div>\n `,e.style.opacity="0",document.body.appendChild(e),document.body.style.overflow="hidden",requestAnimationFrame((()=>{e.style.transition="opacity 0.3s ease-out",e.style.opacity="1"})),e}removeFullPageLoader(e){e&&document.body.contains(e)&&(e.style.transition="opacity 0.3s ease-out",e.style.opacity="0",setTimeout((()=>{document.body.contains(e)&&e.remove(),document.body.style.overflow=""}),300))}setButtonLoading(e,t,n=null){e&&(t?(e.disabled=!0,e.innerHTML=`\n ${P.H.render("loader",{class:"animate-spin h-4 w-4 mr-2 inline"})}\n Logging out...\n `):(e.disabled=!1,n&&(e.innerHTML=n)))}
1showLogoutError(e){let t=e,n="Unknown Error";e.includes("NetworkError")||e.includes("fetch")?(n="Network Error",t="Unable to connect to the server. Please check your internet connection."):e.includes("401")?(n="Session Expired",t="Your session has already expired."):e.includes("403")?(n="Access Denied",t="You do not have permission to perform this action."):e.includes("500")||e.includes("502")||e.includes("503")?(n="Server Error",t="The server is experiencing issues. Please try again later."):e.includes("CORS")&&(n="Configuration Error",t="There is a configuration issue preventing logout.");const o=document.createElement("div");o.className="fixed top-4 right-4 z-50 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-lg shadow-lg max-w-md",o.innerHTML=`\n <div class="flex items-start">\n ${P.H.render("x-circle",{class:"w-5 h-5 mr-2 mt-0.5 flex-shrink-0"})}\n <div class="flex-1">\n <h4 class="font-semibold">Logout Failed - ${n}</h4>\n <p class="text-sm mt-1">${t}</p>\n <details class="mt-2">\n <summary class="text-xs cursor-pointer hover:text-red-800">Technical details</summary>\n <p class="text-xs mt-1 font-mono">${e}</p>\n </details>\n </div>\n <button onclick="this.parentElement.parentElement.remove()" class="ml-2 text-red-400 hover:text-red-600">\n ${P.H.render("x",{class:"w-5 h-5"})}\n </button>\n </div>\n `,document.body.appendChild(o),setTimeout((()=>{document.body.contains(o)&&o.remove()}),1e4)}isUserLoggedIn(){return ae.c.hasCookie("heimguard.authStatus")||ae.c.hasCookie("auth_token")||null!==sessionStorage.getItem("auth_data")}checkAuthStatus(){this.isUserLoggedIn()||(this.clearLocalSession(),this.isProtectedPage()&&Promise.resolve().then(n.bind(n,7310)).then((async e=>{try{const t=await e.default.load(),n=t?.login?.url;n?(console.log("ð User not logged in on protected page, redirecting to:",n),window.location.href=n):console.error("[LogoutHandler] No login URL found in HeimGuard settings")}catch(e){console.error("[LogoutHandler] Failed to load HeimGuard settings:",e)}})))}isProtectedPage(){const e=window.location.pathname;return["/profile","/dashboard","/account","/settings"].some((t=>e.startsWith(t)||e.includes(t)))}static logout(){(0,J.KM)(J.QU.UI_LOGOUT,{manual:!0})}destroy(){this.isLoggingOut=!1}}let ce=null;ce?b.vF.warn("LogoutHandler instance already exists!","auth"):(b.vF.debug("Creating LogoutHandler singleton instance","auth"),ce=new le);var ue=le;class me{constructor(){this.name="authSystem",this.authSystem=null,this.authStateManager=null,this.authManager=null,this.logoutHandler=null}async initialize(){b.vF.debug("Initializing...","auth"),this.authStateManager=new oe.A,A.systemRegistry.registerInstance("authStateManager",this.authStateManager),this.authManager=new se,A.systemRegistry.registerInstance("authManager",this.authManager),this.logoutHandler=new ue,A.systemRegistry.registerInstance("logoutHandler",this.logoutHandler),this.authSystem=new ve,A.systemRegistry.registerInstance("authSystem",this.authSystem),A.systemRegistry.registerInstance("logout",(()=>{ue.logout()})),A.systemRegistry.registerInstance("createStyleguideDemo",((e,t={})=>{const n=document.getElementById(e);if(!n)return b.vF.error(`Container with ID '${e}' not found`,"auth"),null;const o=ve.createStyleguideInstance({autoScan:!1});return o.renderModule(n,"login",t),o})),b.vF.debug("Initialization complete","auth")}cleanup(){b.vF.debug("Cleaning up...","auth"),this.authSystem=null,this.authStateManager=null,this.authManager=null,this.logoutHandler=null}}var ge=class{constructor(e,t=null){this.authConfig=e,this.authSystem=t,this.formId=`magic-link-form-${Date.now()}`,this.alertId=`magic-link-alert-${Date.now()}`}generateHTML(e=!1){const t=this.authConfig.getTemplateData();return e?`\n <div class="auth-modal-wrapper">\n <div class="auth-component magic-link-component w-full">\n ${this.renderHeader(t)}\n ${this.renderForm()}\n ${this.renderFooter()}\n </div>\n </div>\n `:`\n <div class="auth-component magic-link-component w-full max-w-[500px] mx-auto">\n \x3c!-- Card Container --\x3e\n <div class="bg-white rounded-2xl shadow-xl border border-gray-100 overflow-hidden">\n ${this.renderHeader(t)}\n ${this.renderForm()}\n ${this.renderFooter()}\n </div>\n </div>\n `}renderHeader(e){return`\n <div class="px-8 pt-8 pb-6 text-center bg-gradient-to-br from-secondary-50 to-primary-50">\n <div class="mx-auto h-16 w-16 bg-secondary-600 rounded-2xl flex items-center justify-center mb-4 shadow-lg">\n ${P.A.auth.email()}\n </div>\n ${e.companyImgSrc?`<img src="${e.companyImgSrc}" alt="${e.companyName}" class="h-10 mx-auto mb-4 opacity-90">`:""}\n <h2 class="text-2xl font-bold text-gray-900 mb-2">Sign in with magic link</h2>\n <p class="text-gray-600 text-sm">We'll email you a secure link to sign in instantly</p>\n </div>\n `}renderForm(){const e=$.render({id:`${this.formId}-email`,name:"email",label:"Email Address",placeholder:"Enter your email address",required:!0,icon:P.A.auth.email(),helperText:"We'll send a magic link to this email address",autocomplete:"email"});return`\n <div class="px-8 py-6">\n ${`\n <div id="${this.alertId}" class="rounded-md p-4 border shadow-lg hidden mb-4 alert-container" role="alert">\n <div class="flex">\n <div class="flex-shrink-0 alert-icon">\n \x3c!-- Icon will be updated dynamically --\x3e\n </div>\n <div class="flex-1 ml-3">\n <div class="text-sm alert-message"></div>\n </div>\n </div>\n </div>\n `}\n\n <form id="${this.formId}" class="space-y-5" novalidate>\n ${e}\n\n \x3c!-- Submit Button --\x3e\n <button\n type="submit"\n id="${this.formId}-submit"\n class="w-full flex justify-center py-2.5 px-4 border border-transparent roun
1ded-lg shadow-sm text-sm font-medium text-white bg-secondary-600 hover:bg-secondary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-secondary-500 transition-colors"\n >\n ${P.A.render("mail",{class:"w-5 h-5 mr-2"})}\n Send Magic Link\n </button>\n </form>\n\n \x3c!-- Alternative login options --\x3e\n <div class="mt-6">\n <div class="relative">\n <div class="absolute inset-0 flex items-center">\n <div class="w-full border-t border-gray-200"></div>\n </div>\n <div class="relative flex justify-center text-sm">\n <span class="px-3 bg-white text-gray-500 font-medium">Or sign in with</span>\n </div>\n </div>\n\n <div class="mt-4 space-y-3">\n <button\n type="button"\n class="w-full flex justify-center items-center py-2.5 px-4 border border-gray-300 rounded-lg text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition-colors"\n data-login-trigger\n >\n ${P.A.render("key",{class:"w-5 h-5 mr-2"})}\n Use Password Instead\n </button>\n </div>\n </div>\n </div>\n `}renderFooter(){const e=this.authConfig.getConfig().heimguardConfig,{register:t}=e;return`\n <div class="px-8 py-6 bg-gray-50 border-t border-gray-100">\n <p class="text-center text-sm text-gray-600">\n Don't have an account?\n <a href="${t.useModal?"#":t.url}" class="text-primary-600 hover:text-primary-500 font-semibold transition-colors"${t.useModal?"":' target="_blank" rel="noopener noreferrer"'} data-register-trigger>\n ${e.registerLinkText||"Sign up"}\n </a>\n </p>\n </div>\n `}setupFormHandling(e){const t=e.querySelector(`#${this.formId}`);t&&(t.addEventListener("submit",(async e=>{e.preventDefault(),await this.handleSubmit(t)})),this.setupFieldValidation(t),e._authComponent=this)}setupFieldValidation(e){const t=e.querySelector(`#${this.formId}-email`);t&&(t.addEventListener("blur",(()=>{const e=t.value.trim(),n=t.closest(".form-field");if(n)if(e)if(j.email(e)){const t=j.checkEmailTypos(e);t?this.showFieldError(n,t):this.clearFieldError(n)}else this.showFieldError(n,"Please enter a valid email address");else this.showFieldError(n,"Email is required")})),t.addEventListener("focus",(()=>{const e=t.closest(".form-field");e&&this.clearFieldError(e)})))}async handleSubmit(e){const t=e.querySelector(`#${this.formId}-submit`);this.clearErrors();const n={email:new FormData(e).get("email"),sourceUrl:window.location.href},o=this.validateForm(n);if(!o.isValid)return void this.showErrors(o.errors);const i=F.A.setSubmitting(t.id,"Sending magic link...");try{const e=await fetch(f.A.apiPasswordlessEmailUrl,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},credentials:"include",body:JSON.stringify(n)}),t=await e.json();if(!e.ok)throw new Error(t.message||"Failed to send magic link");await this.handleSuccess(n.email)}catch(e){console.error("Magic link error:",e);const t=this.getErrorMessage(e);this.showAlert(t,"error"),i?.restore()}}validateForm(e){return K(e,{email:{required:!0,validate:e=>{if(!j.email(e))return"Please enter a valid email address";const t=j.checkEmailTypos(e);return t||null}}})}getExpirationText(){const e=parseFloat(this.authConfig.getPasswordlessLoginLinkExpirationHours());if(isNaN(e)||e<=0)return"15 minutes";if(e<1){const t=Math.round(60*e);return`${t} ${1===t?"minute":"minutes"}`}if(1===e)return"1 hour";if(e<24)return`${e} hours`;const t=Math.floor(e/24),n=e%24;return 0===n?`${t} ${1===t?"day":"days"}`:`${t} ${1===t?"day":"days"} and ${n} ${1===n?"hour":"hours"}`}async handleSuccess(e){const t=document.getElementById(this.formId)?.closest(".auth-component");if(!t)return;this.showAlert("Magic link sent! Please check your email.","success");const n=!!t.closest(".modal-body"),o=`\n \x3c!-- Header section --\x3e\n <div class="px-8 pt-8 pb-6 text-center bg-gradient-to-br from-secondary-50 to-primary-50">\n <div class="mx-auto h-16 w-16 bg-secondary-600 rounded-2xl flex items-center justify-center mb-4 shadow-lg">\n ${P.A.auth.email()}\n </div>\n ${this.authConfig.getTemplateData().companyImgSrc?`<img src="${this.authConfig.getTemplateData().companyImgSrc}" alt="${this.authConfig.getTemplateData().companyName}" class="h-10 mx-auto mb-4 opacity-90">`:""}\n <h2 class="text-2xl font-bold text-gray-900 mb-2">Check your email!</h2>\n <p class="text-gray-600 text-sm">We've sent a magic link to <strong class="font-semibold text-gray-900">${this.escapeHtml(e)}</strong></p>\n </div>\n\n \x3c!-- Main content --\x3e\n <div class="px-8 py-6">\n \x3c!-- Large email icon --\x3e\n <div class="mx-auto w-20 h-20 bg-secondary-100 rounded-full flex items-center justify-center mb-6">\n ${P.A.render("mail",{class:"w-10 h-10 text-secondary-500"})}\n </div>
1\n\n \x3c!-- Instructions --\x3e\n <div class="bg-secondary-50 border border-secondary-200 rounded-lg p-4 mb-6">\n <div class="flex">\n <div class="flex-shrink-0">\n ${P.A.render("info",{class:"h-5 w-5 text-secondary-400"})}\n </div>\n <div class="ml-3">\n <h3 class="text-sm font-medium text-secondary-800">How it works</h3>\n <p class="text-sm text-secondary-700 mt-1">Click the link in your email to sign in instantly. The link expires in ${this.getExpirationText()} for security.</p>\n </div>\n </div>\n </div>\n\n \x3c!-- Action buttons --\x3e\n <div class="space-y-3">\n <button\n type="button"\n id="${this.formId}-try-again"\n class="w-full flex justify-center py-2.5 px-4 border border-gray-300 rounded-lg text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-secondary-500 transition-colors"\n >\n ${P.A.render("qr-code",{class:"w-4 h-4 mr-1.5"})}\n Try Different Email\n </button>\n\n <button\n type="button"\n class="w-full flex justify-center py-2.5 px-4 border border-gray-300 rounded-lg text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 transition-colors"\n data-login-trigger\n >\n ${P.A.render("key",{class:"w-4 h-4 mr-1.5"})}\n Sign In With Password\n </button>\n </div>\n </div>\n\n \x3c!-- Footer section --\x3e\n <div class="px-8 py-6 bg-gray-50 border-t border-gray-100 ${n?"":"rounded-b-2xl"}">\n <p class="text-center text-sm text-gray-600">\n Didn't receive the email? Check your spam folder or\n <a href="#" class="text-primary-600 hover:text-primary-500 font-semibold transition-colors" id="${this.formId}-contact-support">\n contact support\n </a>\n </p>\n </div>\n `;let i;if(n?i=t:(i=t.querySelector(".bg-white.rounded-2xl"),i||(i=t.closest(".auth-component"))),i){if(n)i.innerHTML=o;else{const e=`\n <div class="bg-white rounded-2xl shadow-xl border border-gray-100 overflow-hidden">\n ${o}\n </div>\n `,t=i.closest(".auth-component");t?t.innerHTML=e:i.innerHTML=o}this.setupSuccessHandlers()}}setupSuccessHandlers(){const e=document.getElementById(`${this.formId}-try-again`);e&&e.addEventListener("click",(e=>{e.preventDefault(),Promise.resolve().then(n.bind(n,4811)).then((({ModalUtils:e})=>{e.hideAll()})),setTimeout((()=>{const e=A.systemRegistry.get("authSystem");e&&e.showMagicLogin()}),150)}));const t=document.getElementById(`${this.formId}-contact-support`);t&&t.addEventListener("click",(e=>{e.preventDefault(),window.location.href="/contact-us"}))}showErrors(e){Object.entries(e).forEach((([e,t])=>{const n=document.getElementById(`${this.formId}-${e}`);if(n){const e=n.closest(".form-field");e&&this.showFieldError(e,Array.isArray(t)?t[0]:t)}}
1))}showFieldError(e,t){const n=e.querySelector(".flex");if(!n)return;n.classList.add("border-red-500","focus-within:border-red-600"),n.classList.remove("border-gray-300","focus-within:border-primary-500");let o=e.querySelector('[role="alert"]');o||(o=document.createElement("div"),o.className="mt-1.5 flex items-start gap-1.5",o.setAttribute("role","alert"),o.innerHTML=`\n ${P.A.render("alert-circle",{class:"w-4 h-4 text-red-500 flex-shrink-0 mt-0.5"})}\n <span class="text-sm text-red-600 font-medium">${t}</span>\n `,n.insertAdjacentElement("afterend",o))}clearFieldError(e){const t=e.querySelector(".flex");if(!t)return;t.classList.remove("border-red-500","focus-within:border-red-600"),t.classList.add("border-gray-300","focus-within:border-primary-500");const n=e.querySelector('[role="alert"]');n&&n.remove()}clearErrors(){const e=document.getElementById(this.formId);if(!e)return;e.querySelectorAll(".form-field").forEach((e=>{this.clearFieldError(e)}));const t=document.getElementById(this.alertId);t&&t.classList.add("hidden");const n=e.parentElement?.querySelector(".bg-secondary-50");n&&n.remove()}showAlert(e,t="error"){const n=document.getElementById(this.alertId);if(!n)return;const o={error:{bg:"bg-red-50",border:"border-red-200",text:"text-red-700",iconColor:"text-red-400",icon:P.A.render("x-circle",{class:"h-5 w-5 text-red-400"})},success:{bg:"bg-green-50",border:"border-green-200",text:"text-green-700",iconColor:"text-green-400",icon:P.A.render("check-circle",{class:"h-5 w-5 text-green-400"})},info:{bg:"bg-blue-50",border:"border-blue-200",text:"text-blue-700",iconColor:"text-blue-400",icon:P.A.render("info",{class:"h-5 w-5 text-blue-400"})}}[t];n.className=n.className.replace(/bg-\w+-50|border-\w+-200/g,""),n.classList.add(o.bg,o.border);const i=n.querySelector(".alert-icon");i&&(i.innerHTML=o.icon);const a=n.querySelector(".alert-message");a&&(a.className=`text-sm alert-message ${o.text}`,a.textContent=e),n.classList.remove("hidden")}getErrorMessage(e){const t=e.message||e.toString();return t.includes("network")||t.includes("fetch")?"Unable to connect to the server. Please check your internet connection.":t.includes("rate limit")||t.includes("429")?"Too many attempts. Please wait a few minutes before trying again.":t.includes("invalid")||t.includes("400")?"Please enter a valid email address.":t.includes("timeout")?"The request timed out. Please try again.":t.includes("500")||t.includes("server")?"A server error occurred. Please try again later.":t||"An unexpected error occurred. Please try again."}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}destroy(){const e=document.getElementById(this.formId);e&&e.reset()}},he=n(5762);var pe=class{constructor(){this.originalButtonContent=new Map}handleSocialLoginButton(e){const t=e.getAttribute("data-social-login");if("magic"===t)this.handleMagicLoginButton(e);else{this.setSocialButtonLoading(e,!0,t);try{this.handleSocialLogin(t)}catch(n){console.error(`${t} login error:`,n);const o=document.querySelector(".auth-alert");o&&he.AlertUtils.showAlert(o,`${t} login failed. Please try again.`,"error"),this.setSocialButtonLoading(e,!1,t)}}}handleMagicLoginButton(e){this.setSocialButtonLoading(e,!0,"magic"),(0,J.KM)(J.QU.UI_SHOW_MAGIC_LINK),setTimeout((()=>{this.setSocialButtonLoading(e,!1,"magic")}),500)}handleSocialLogin(e){try{const t=new URLSearchParams(window.location.search).get("referrerUrl"),n=t||window.location.href,o=encodeURIComponent(n);let i;switch(e){case"google":i=f.A.apiGoogleLoginUrl;break;case"facebook":i=f.A.apiFacebookLoginUrl;break;default:throw new Error(`Unsupported social login provider: ${e}`)}if(!i)throw new Error(`${e} login URL not configured`);const a=`${i}?returnUrl=${o}`;console.log(`ð Redirecting to ${e} login:`,a),window.location.href=a}catch(t){console.error(`â ${e} login error:`,t),ie.zc.log(`SocialLogin-${e}`,t,{provider:e});const n=document.querySelector(".auth-alert");n&&he.AlertUtils.showAlert(n,`${e} login is currently unavailable. Please try again later or use another method.`,"error");const o=document.querySelector(`[data-social-login="${e}"]`);o&&this.setSocialButtonLoading(o,!1,e)}}setSocialButtonLoading(e,t,n){if(e)if(t)this.originalButtonContent.set(e,e.innerHTML),e.disabled=!0,e.classList.add("opacity-75","cursor-not-allowed","pointer-events-none"),e.innerHTML=P.H.render("loader",{class:"w-5 h-5 animate-spin"});else{const t=this.originalButtonContent.get(e);t&&(e.innerHTML=t,this.originalButtonContent.delete(e)),e.disabled=!1,e.classList.remove("opacity-75","cursor-not-allowed","pointer-events-none")}}setupEventListeners(){document.addEventListener("click",(e=>{const t=e.target.closest("[data-social-login]");t&&(e.preventDefault(),this.handleSocialLoginButton(t))}))}destroy(){this.originalButtonContent.clear()}};class ye{constructor(e){this.authSystem=e}async scanAndRenderModules(){for(const e of ye.MODULE_DEFINITIONS)await this.renderModuleType(e)}async renderModuleType({tag:e,componentName:t,moduleName:n}){const o=document.querySelectorAll(e);if(!o.length)return;console.log(`ð Found ${o.length} ${e} tag(s)`);const i=Array.from(o).map((e=>this.renderModule(e,t,n)));await Promise.all(i)}async renderModule(e,t,n){try{const o=this.authSystem.isLoggedIn();if(console.log(`[ModuleRenderer] Checking login status for ${t} page:`,o),("login"===t||"register"===t)&&o){console.log(`ð User already logged in, redirecting from ${t} page...`);const n=this.authSystem.authConfig.getConfig().heimguardConfig?.profile?.url||"/profile";return e.innerHTML='\n <div class="auth-module-wrapper my-8">\n <div class="bg-white rounded-2xl shadow-xl border border-gray-100 p-8 text-center max-w-md mx-auto">\n <div class="mx-auto h-16 w-16 bg-green-100 rounded-full flex items-center justify-center mb-4">\n <svg class="w-8 h-8 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>\n </svg>\n </div>\n <h2 class="text-xl font-semibold text-gray-900 mb-2">Already Logged In</h2>\n <p class="text-gray-600 mb-4">Redirecting to your profile...</p>\n <div class="inline-flex items-center justify-center">\n <div class="animate-spin rounded-full h-4 w-4 border-b-2 border-primary-600"></div>\n </div>\n </div>\n </div>\n ',void setTimeout((()=>{window.location.href=n}),1e3)}e.innerHTML=ye.LOADING_HTML;const i=this.authSystem.getComponent(t);if(!i)throw new Error(`Component ${t} not found`);let a;
1"forgotPassword"===t&&(a={title:e.dataset.title,description:e.dataset.description,showSupportEmail:"true"===e.dataset.showSupportEmail});const s=i.generateHTML(!1,a);if(!s)throw new Error(`Failed to generate HTML for ${n}`);const r=`<div class="auth-module-wrapper my-8">${s}</div>`;e.innerHTML=r;const d=e.querySelector(".auth-component");d&&i.setupFormHandling&&i.setupFormHandling(d),console.log(`â
Rendered ${n} successfully`)}catch(o){console.error(`â Failed to render ${n}`,o),ie.Ak.logError(n,o,{componentName:t}),e.innerHTML=this.renderErrorModule(n,o)}}async renderModuleDirectly(e,t,n={}){if(!e)return void console.warn("â ï¸ No target element provided for module render");const o=`${t.charAt(0).toUpperCase()+t.slice(1)} Module`;try{e.innerHTML=ye.LOADING_HTML;const i=this.authSystem.getComponent(t);if(!i)throw new Error(`Component ${t} not found`);let a;if(n.templateData||n.config){const e=this.authSystem.authConfig.getConfig();try{n.templateData&&Object.assign(e.templateData,n.templateData),n.config&&Object.assign(e.heimguardConfig,n.config),a=i.generateHTML()}finally{Object.assign(e.heimguardConfig,e.heimguardConfig),Object.assign(e.templateData,e.templateData)}}else a=i.generateHTML();const s=`<div class="auth-module-wrapper my-8">${a}</div>`;e.innerHTML=s;const r=e.querySelector(".auth-component");r&&i.setupFormHandling&&i.setupFormHandling(r),console.log(`â
${o} rendered directly`)}catch(t){console.error(`â Error rendering ${o}:`,t),e.innerHTML=this.renderErrorModule(o,t)}}renderErrorModule(e,t){const n=this.getErrorType(t);return ie.Ak.generateErrorModule({moduleName:e,errorType:n,userMessage:null,showRetry:!0,showSupport:!0,retryAction:`(function() { const authSystem = window.systemRegistry?.get('authSystem'); if (authSystem) authSystem.retryModuleRender('${e}'); })()`,supportAction:f.A.supportEmail||"mailto:[email protected]",companyName:this.authSystem.authConfig.getTemplateData().companyName||"Our Company"})}getErrorType(e){const t=e.message.toLowerCase();return t.includes("network")||t.includes("fetch")?"network":t.includes("config")||t.includes("initialization")?"config":t.includes("permission")||t.includes("unauthorized")?"permission":t.includes("timeout")?"timeout":"generic"}getModuleDefinitions(){return[...ye.MODULE_DEFINITIONS]}}ye.MODULE_DEFINITIONS=[{tag:"HgLoginModule",componentName:"login",moduleName:"Login Module"},{tag:"HgRegisterModule",componentName:"register",moduleName:"Register Module"},{tag:"HgForgotPasswordModule",componentName:"forgotPassword",moduleName:"Forgot Password Module"},{tag:"HgSetNewPasswordModule",componentName:"setNewPassword",moduleName:"Set New Password Module"}],ye.LOADING_HTML='\n <div class="auth-component-loading w-full max-w-[500px] mx-auto">\n <div class="bg-white rounded-2xl shadow-xl border border-gray-100 overflow-hidden animate-pulse">\n \x3c!-- Header skeleton --\x3e\n <div class="px-8 pt-8 pb-6 bg-gradient-to-br from-gray-100 to-gray-50">\n <div class="mx-auto h-16 w-16 bg-gray-300 rounded-2xl mb-4"></div>\n <div class="h-8 bg-gray-300 rounded w-3/4 mx-auto mb-2"></div>\n <div class="h-4 bg-gray-200 rounded w-1/2 mx-auto"></div>\n </div>\n\n \x3c!-- Form skeleton --\x3e\n <div class="px-8 py-6 space-y-5">\n \x3c!-- Email field skeleton --\x3e\n <div>\n <div class="h-4 w-24 bg-gray-200 rounded mb-2"></div>\n <div class="h-10 bg-gray-100 rounded-lg"></div>\n </div>\n\n \x3c!-- Password field skeleton --\x3e\n <div>\n <div class="h-4 w-20 bg-gray-200 rounded mb-2"></div>\n <div class="h-10 bg-gray-100 rounded-lg"></div>\n </div>\n\n \x3c!-- Button skeleton --\x3e\n <div class="h-11 bg-gray-300 rounded-lg"></div>\n\n \x3c!-- Link skeleton --\x3e\n <div class="h-4 w-32 bg-gray-200 rounded mx-auto"></div>\n </div>\n\n \x3c!-- Footer skeleton --\x3e\n <div class="px-8 py-6 bg-gray-50 border-t border-gray-100">\n <div class="h-4 bg-gray-200 rounded w-3/4 mx-auto"></div>\n </div>\n </div>\n </div>\n ';var Ce=ye;class fe{constructor(e={}){this.isInitialized=!1,this.initError=null,this.components=null,this.isShowingModal=!1,this.options={autoScan:!1!==e.autoScan,enableLogout:!1!==e.enableLogout,demoMode:e.demoMode??!1},this.authConfig=D.fl,this.socialAuthHandler=new pe,this.moduleRenderer=new Ce(this),this.options.enableLogout&&(this.logoutHandler=new ue),this.init()}
1async init(){if(!this.isInitialized)try{if(this.options.demoMode)this.authConfig.loadDemoConfig();else{const e=await this.authConfig.load();if(!e.success&&!e.usedFallback)throw e.error}this.initializeComponents(),this.setupGlobalListeners(),await oe.A.init(),this.options.autoScan&&await this.moduleRenderer.scanAndRenderModules(),this.checkURLParameters(),this.isInitialized=!0,b.vF.info("AuthSystem initialized successfully","auth",{demoMode:this.options.demoMode})}catch(e){b.vF.error("Failed to initialize AuthSystem","auth",e),this.initError=e,ie.zc.handle(e,{component:"AuthSystem.init",context:{demoMode:this.options.demoMode,autoScan:this.options.autoScan}});try{this.authConfig.loadDemoConfig(),this.initializeComponents(),this.setupGlobalListeners(),this.options.autoScan&&await this.moduleRenderer.scanAndRenderModules(),this.checkURLParameters(),this.isInitialized=!0,b.vF.info("AuthSystem initialized in fallback demo mode","auth",{})}catch(e){b.vF.error("Fallback initialization also failed","auth",e),ie.zc.handle(e,{component:"AuthSystem.init-fallback"})}}}initializeComponents(){const e={getTemplateData:()=>this.authConfig.getTemplateData(),getConfig:()=>this.authConfig.getConfig(),getAuthAPI:()=>R,hasTermsOrPrivacy:()=>this.authConfig.hasTermsOrPrivacy(),onModeSwitch:e=>this.handleModeSwitch(e),getPasswordlessLoginLinkExpirationHours:()=>this.authConfig.getPasswordlessLoginLinkExpirationHours()};this.components={login:new Z(e),register:new X(e),forgotPassword:new ee(e),setNewPassword:new ne(e),magicLink:new ge(e,this)}}getComponent(e){const t=this.components?.[e];return t?("render"in t||(t.render=async()=>{b.vF.warn(`Component ${e} doesn't have a render method`,"auth",{component:e})}),t):null}handleModeSwitch(e){switch(e){case"login":this.showLogin();break;case"register":this.showRegister();break;case"forgotPassword":this.showForgotPassword();break;default:b.vF.warn("Unknown auth mode","auth",{mode:e})}}setupGlobalListeners(){fe.globalListenersSetup?b.vF.info("Global listeners already set up, skipping...","auth",{}):(document.addEventListener("click",(e=>{const t=e.target;if(t.closest("[data-login-trigger]")){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation();const t=window.scrollY,n=window.scrollX,o=window.innerWidth-document.documentElement.clientWidth;requestAnimationFrame((()=>{o>0&&(document.body.style.paddingRight=`${o}px`),document.body.dataset.scrollY=String(t),document.body.dataset.scrollX=String(n),this.showLogin(),setTimeout((()=>{window.scrollTo(n,t)}),0)}))}t.closest("[data-register-trigger]")&&this.authConfig.shouldUseModal("register")&&(e.preventDefault(),this.showRegister()),t.closest("[data-forgot-password-trigger]")&&(e.preventDefault(),this.showForgotPassword()),t.closest("[data-profile-trigger]")&&(e.preventDefault(),this.navigateToProfile())})),this.socialAuthHandler.setupEventListeners(),window.addEventListener(J.QU.UI_SHOW_MAGIC_LINK,(()=>{this.showMagicLogin()})),window.addEventListener(J.QU.STATE_CHANGED,(e=>{b.vF.info("AuthSystem received auth state change","auth",{action:e.detail.action}),this.handleAuthStateChange(e.detail)})),window.addEventListener(J.QU.UI_SHOW_LOGIN,(()=>this.showLogin())),window.addEventListener(J.QU.UI_SHOW_REGISTER,(()=>this.showRegister())),window.addEventListener(J.QU.UI_SHOW_FORGOT_PASSWORD,(()=>
1this.showForgotPassword())),fe.globalListenersSetup=!0,b.vF.info("Global listeners set up","auth",{}))}checkURLParameters(){if(fe.globalUrlParamsChecked)return void b.vF.info("URL parameters already checked by another AuthSystem instance","auth",{});fe.globalUrlParamsChecked=!0;const e=new URLSearchParams(window.location.search),t=e.get("auth")||e.get("action");t&&(b.vF.info("Found auth action in URL","auth",{authAction:t}),setTimeout((()=>{if(this.isShowingModal)b.vF.info("Modal already showing, skipping URL parameter trigger","auth",{});else switch(t){case"login":this.showLogin();break;case"register":this.showRegister();break;case"forgot-password":case"forgotPassword":case"reset-password":this.showForgotPassword();break;case"magic-link":case"magicLink":this.showMagicLogin();break;default:b.vF.warn("Unknown auth action","auth",{authAction:t})}}),100))}handleAuthStateChange(e){const{action:t}=e;"logout"===t?(b.vF.info("AuthSystem handling logout state change","auth",{}),de.ModalUtils.hideAll(),this.clearFormStates()):"login"===t&&(b.vF.info("AuthSystem handling login state change","auth",{}),de.ModalUtils.hideModal())}clearFormStates(){this.components&&Object.values(this.components).forEach((e=>{if(e?.destroy)try{e.destroy()}catch(e){b.vF.warn("Error cleaning up component","auth",{error:e})}}))}navigateToProfile(){const e=this.authConfig.getComponentConfig("profile"),t=e?.url||"/profile";b.vF.info("Navigating to profile","auth",{profileUrl:t}),window.location.href=t}showLogin(){!!document.querySelector(".modal-body")||this.authConfig.shouldUseModal("login")?this.showLoginModal():window.location.href=this.authConfig.getRedirectUrl("login")}showRegister(){this.authConfig.shouldUseModal("register")?this.showRegisterModal():window.open(this.authConfig.getRedirectUrl("register"),"_blank","noopener,noreferrer")}showForgotPassword(){!!document.querySelector(".modal-body")||this.authConfig.shouldUseModal("forgotPassword")?this.showForgotPasswordModal():window.location.href=this.authConfig.getRedirectUrl("forgotPassword")}showModal(e,t){if(this.components)if(this.isShowingModal)b.vF.info(`Modal is already being shown, ignoring ${e} request`,"auth",{componentName:e});else{if(("login"===e||"register"===e)&&this.isLoggedIn())return b.vF.info(`User already logged in, not showing ${e} modal`,"auth",{componentName:e}),void Promise.resolve().then(n.bind(n,8050)).then((({Alert:e})=>{e.flash({message:"You are already logged in!",variant:"info",duration:3e3})}));this.isShowingModal=!0,de.ModalUtils.hideAll(),setTimeout((()=>{const n=this.components[e],o=n.generateHTML(!0),i=de.ModalUtils.show({content:o,size:"auth",className:`auth-modal ${t}`,showHeader:!1,closeOnBackdrop:!0,closeOnEscape:!0,onClose:()=>{b.vF.info("Modal closed","auth",{componentName:e}),this.isShowingModal=!1,n.destroy&&n.destroy()}}),a=document.getElementById(i);a&&n.setupFormHandling&&n.setupFormHandling(a),setTimeout((()=>{this.isShowingModal=!1}),200)}),100)}}showLoginModal(){this.showModal("login","login-modal")}showRegisterModal(){this.showModal("register","register-modal")}showForgotPasswordModal(){this.showModal("forgotPassword","forgot-password-modal")}showMagicLogin(){this.showModal("magicLink","magic-link-modal")}async rescanModules(){this.isInitialized?await this.moduleRenderer.scanAndRenderModules():b.vF.warn("AuthSystem not initialized yet","auth",{})}async renderModule(e,t,n={}){this.isInitialized||await this.init(),await this.moduleRenderer.renderModuleDirectly(e,t,n)}async retryModuleRender(e){b.vF.info(`Retrying render for ${e}`,"auth"),this.isInitialized&&!this.initError||await this.init(),await this.moduleRenderer.scanAndRenderModules()}setDisplayMode(e,t){this.authConfig.setDisplayMode(e,t)}logout(){this.logoutHandler?ue.logout():b.vF.warn("Logout handler not enabled","auth")}isLoggedIn(){const e=oe.A.isAuthenticated();return b.vF.debug(`isLoggedIn check: ${e}`,"auth"),e}getCurrentUser(){return"undefined"!=typeof window&&window.SessionValidator?window.SessionValidator.getUserData():null}destroy(){this.clearFormStates();document.querySelectorAll(".modal").forEach((e=>{const t=e;t._authComponent?.destroy?t._authComponent.destroy():t._formCleanup&&t._formCleanup()})),de.ModalUtils.hideAll(),this.socialAuthHandler?.destroy&&this.socialAuthHandler.destroy(),this.logoutHandler?.destroy&&this.logoutHandler.destroy(),window.SessionValidator?.destroy&&window.SessionValidator.destroy(),this.isInitialized=!1,b.vF.info("AuthSystem destroyed and cleaned up","auth")}static createDemoInstance(){return new fe({demoMode:!0})}static createStyleguideInstance(e={}){return new fe({demoMode:!0,autoScan:!1!==e.autoScan,...e})}}fe.globalListenersSetup=!1,fe.globalUrlParamsChecked=!1;var ve=fe;class be{constructor(e={}){this.options={modalId:"auth-modal",containerClass:"auth-modal-container",...e},this.currentForm=null,this.currentModal=null,this.forms=new Map,this.handleAuthEvent=this.handleAuthEvent.bind(this),this.handleFormSwitch=this.handleFormSwitch.bind(this)}async initialize(){this.setupEventListeners(),this.unsubscribeAuth=re.subscribe((e=>{e.isAuthenticated&&this.currentModal&&this.hide()})),console.log("â
AuthModal initialized")}registerForm(e,t){this.forms.set(e,t)}async show(e,t={}){const n=this.forms.get(e);if(!n)return void console.error(`Form type "${e}" not registered`);this.currentModal&&await this.hide();const o=this.createModalContent(e,n);this.currentModal=await de.ModalUtils.show({title:"",content:o,size:"auth",className:`auth-modal auth-modal-${e}`,closeOnEscape:!0,closeOnBackdrop:!0,showHeader:!1,onClose:()=>{this.currentForm=null,this.currentModal=null}}),this.currentForm=e;const i=document.querySelector(`.auth-modal-${e} .auth-modal-wrapper`);i&&n.setContainer&&(n.setContainer(i),await(n.render?.()))}async hide(){this.currentModal&&(await de.ModalUtils.hide(this.currentModal),this.currentModal=null,this.currentForm=null)}createModalContent(e,t){return`\n <div class="auth-modal-wrapper" data-form-type="${e}">\n \x3c!-- Form will be rendered here --\x3e\n </div>\n `}getModalTitle(e){return{login:"Sign In",register:"Create Account",forgotPassword:"Reset Password",magicLink:"Magic Link Sign In",twoFactor:"Two-Factor Authentication"}[e]||"Authentication"}
1setupEventListeners(){(0,J.sQ)(J.QU.UI_SHOW_LOGIN,(()=>this.show("login"))),(0,J.sQ)(J.QU.UI_SHOW_REGISTER,(()=>this.show("register"))),(0,J.sQ)(J.QU.UI_SHOW_FORGOT_PASSWORD,(()=>this.show("forgotPassword"))),(0,J.sQ)(J.QU.UI_SHOW_MAGIC_LINK,(()=>this.show("magicLink"))),(0,J.sQ)(J.QU.UI_SHOW_TWO_FACTOR,(()=>this.show("twoFactor"))),(0,J.sQ)(J.QU.UI_HIDE_ALL,(()=>this.hide())),(0,J.sQ)("auth:show:login",(()=>this.show("login"))),(0,J.sQ)("auth:show:register",(()=>this.show("register"))),(0,J.sQ)("auth:show:forgot-password",(()=>this.show("forgotPassword"))),(0,J.sQ)("auth:hide",(()=>this.hide())),document.addEventListener("click",this.handleFormSwitch)}handleFormSwitch(e){const t=e.target.closest("[data-auth-switch]");if(!t||!this.currentModal)return;const n=t.getAttribute("data-auth-switch");n&&this.forms.has(n)&&(e.preventDefault(),this.show(n))}handleAuthEvent(e){const{type:t,detail:n}=e;t!==J.QU.LOGIN_SUCCESS&&t!==J.QU.REGISTER_SUCCESS||this.hide()}destroy(){document.removeEventListener("click",this.handleFormSwitch),this.unsubscribeAuth&&this.unsubscribeAuth(),this.hide(),this.forms.clear()}}new be;new class{constructor(e={}){this.sessionCheckTimer=null,this.lastCheckTime=0,this.isChecking=!1,this.refreshTimeoutId=null,this.boundHandlers={handleStorageChange:this.handleStorageChange.bind(this),handleVisibilityChange:this.handleVisibilityChange.bind(this),handleOnline:this.handleOnline.bind(this),handleOffline:this.handleOffline.bind(this)},this.storageKey=e.storageKey||"heimguard_session",this.checkInterval=e.checkInterval||6e4,this.refreshThreshold=e.refreshThreshold||3e5}init(){this.validateSession(),this.startSessionChecks(),this.registerEventListeners()}registerEventListeners(){window.addEventListener("storage",this.boundHandlers.handleStorageChange),document.addEventListener("visibilitychange",this.boundHandlers.handleVisibilityChange),window.addEventListener("online",this.boundHandlers.handleOnline),window.addEventListener("offline",this.boundHandlers.handleOffline)}startSessionChecks(){this.stopSessionChecks(),this.sessionCheckTimer=window.setInterval((()=>{!this.isChecking&&this.shouldCheckSession()&&this.validateSession()}),this.checkInterval)}stopSessionChecks(){null!==this.sessionCheckTimer&&(clearInterval(this.sessionCheckTimer),this.sessionCheckTimer=null)}shouldCheckSession(){return Date.now()-this.lastCheckTime>=this.checkInterval}async validateSession(e=!1){if(this.isChecking&&!e)return this.getStoredSession();if(!e&&!this.shouldCheckSession())return this.getStoredSession();this.isChecking=!0,this.lastCheckTime=Date.now();try{const e=await R.validateSession();if(e.ok&&e.data.success){const t={valid:!0,user:e.data.user,expiresAt:e.data.expiresAt,provider:e.data.provider,checkedAt:Date.now()};return this.storeSession(t),(0,J.KM)(J.QU.SESSION_VALID,{user:t.user,provider:t.provider}),this.needsRefresh(t)&&this.scheduleRefresh(t),t}return this.clearSession(),(0,J.KM)(J.QU.SESSION_EXPIRED,{lastActivity:new Date}),null}catch(e){return console.error("Session validation error:",e),function(e){return e instanceof Error&&(e.message.toLowerCase().includes("network")||e.message.toLowerCase().includes("fetch")||"NetworkError"===e.name)}
1(e)||this.clearSession(),this.getStoredSession()}finally{this.isChecking=!1}}needsRefresh(e){if(!e.expiresAt)return!1;const t=Date.now(),n=new Date(e.expiresAt).getTime()-t;return n>0&&n<=this.refreshThreshold}scheduleRefresh(e){null!==this.refreshTimeoutId&&clearTimeout(this.refreshTimeoutId);const t=Date.now(),n=new Date(e.expiresAt).getTime(),o=Math.max(0,n-t-this.refreshThreshold);this.refreshTimeoutId=window.setTimeout((()=>{this.refreshSession()}),o)}async refreshSession(){try{const e=await R.post("/auth/refresh",{});if(e.ok&&e.data.success){const t={valid:!0,user:e.data.user,expiresAt:e.data.expiresAt,provider:e.data.provider,checkedAt:Date.now()};return this.storeSession(t),(0,J.KM)(J.QU.SESSION_REFRESHED,{user:t.user,provider:t.provider}),t}}catch(e){console.error("Session refresh error:",e)}return null}getStoredSession(){try{const e=localStorage.getItem(this.storageKey);if(!e)return null;const t=JSON.parse(e);if(t.expiresAt){const e=Date.now();if(e>=new Date(t.expiresAt).getTime())return this.clearSession(),null}return t}catch(e){return console.error("Error reading session:",e),null}}storeSession(e){try{localStorage.setItem(this.storageKey,JSON.stringify(e)),this.broadcastSessionChange(e)}catch(e){console.error("Error storing session:",e)}}clearSession(){try{localStorage.removeItem(this.storageKey),null!==this.refreshTimeoutId&&(clearTimeout(this.refreshTimeoutId),this.refreshTimeoutId=null),this.broadcastSessionChange(null)}catch(e){console.error("Error clearing session:",e)}}broadcastSessionChange(e){try{const t=`${this.storageKey}_broadcast`,n={session:e,timestamp:Date.now()};localStorage.setItem(t,JSON.stringify(n)),setTimeout((()=>{localStorage.removeItem(t)}),100)}catch(e){}}handleStorageChange(e){if(e.key===`${this.storageKey}_broadcast`&&e.newValue)try{const t=JSON.parse(e.newValue);t.session?(0,J.KM)(J.QU.SESSION_VALID,{user:t.session.user,provider:t.session.provider}):(0,J.KM)(J.QU.SESSION_EXPIRED,{lastActivity:new Date})}catch(e){console.error("Error handling storage change:",e)}}handleVisibilityChange(){document.hidden||this.validateSession()}handleOnline(){this.validateSession(!0),this.startSessionChecks()}handleOffline(){this.stopSessionChecks()}isAuthenticated(){const e=this.getStoredSession();return null!==e&&e.valid}getCurrentUser(){const e=this.getStoredSession();return e?.user||null}getProvider(){const e=this.getStoredSession();return e?.provider||null}destroy(){this.stopSessionChecks(),null!==this.refreshTimeoutId&&(clearTimeout(this.refreshTimeoutId),this.refreshTimeoutId=null),window.removeEventListener("storage",this.boundHandlers.handleStorageChange),document.removeEventListener("visibilitychange",this.boundHandlers.handleVisibilityChange),window.removeEventListener("online",this.boundHandlers.handleOnline),window.removeEventListener("offline",this.boundHandlers.handleOffline)}};new class{constructor(e={}){this.authCookieName=e.authCookieName||"heimguard_auth",this.tokenPrefix=e.tokenPrefix||"Bearer"}getAuthToken(){return this.getCookie(this.authCookieName)}setAuthHeader(e={}){const t=this.getAuthToken();return t&&(e.Authorization=`${this.tokenPrefix} ${t}`),e}setSecurityHeaders(e={}){return{...e,...this.setAuthHeader({})}}getCookie(e){const t=`; ${document.cookie}`.split(`; ${e}=`);if(2===t.length){const e=t.pop()?.split(";").shift();if(!e)return null;try{return decodeURIComponent(e)}catch{return e}}return null}setCookie(e,t,n={}){const o={path:"/",secure:"https:"===window.location.protocol,sameSite:"Lax",maxAge:2592e3,...n};let i=`${e}=${encodeURIComponent(t)}`;o.maxAge&&(i+=`; max-age=${o.maxAge}`),o.expires&&(i+=`; expires=${o.expires.toUTCString()}`),o.path&&(i+=`; path=${o.path}`),o.domain&&(i+=`; domain=${o.domain}`),o.secure&&(i+="; secure"),o.sameSite&&(i+=`; samesite=${o.sameSite}`),o.httpOnly&&console.warn("Cannot set httpOnly flag from JavaScript"),document.cookie=i}deleteCookie(e,t={}){this.setCookie(e,"",{...t,maxAge:0,expires:new Date(0)})}areCookiesEnabled(){try{const e="_heimguard_cookie_test";this.setCookie(e,"test",{maxAge:60});const t="test"===this.getCookie(e);return this.deleteCookie(e),t}catch{return!1}}parseJWT(e){try{const t=e.split(".");if(3!==t.length)return null;const n=t[1].replace(/-/g,"+").replace(/_/g,"/"),o=decodeURIComponent(atob(n).split("").map((e=>"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2))).join(""));return JSON.parse(o)}catch(e){return console.error("Error parsing JWT:",e),null}}isTokenExpired(e){const t=this.parseJWT(e);
1if(!t?.exp)return!0;const n=1e3*t.exp;return Date.now()>=n}getTokenExpiration(e){const t=this.parseJWT(e);return t?.exp?new Date(1e3*t.exp):null}storeTempToken(e,t,n=900){try{const o={token:t,expiresAt:Date.now()+1e3*n};sessionStorage.setItem(`heimguard_temp_${e}`,JSON.stringify(o))}catch(e){console.error("Error storing temp token:",e)}}getTempToken(e){try{const t=sessionStorage.getItem(`heimguard_temp_${e}`);if(!t)return null;const n=JSON.parse(t);return Date.now()>=n.expiresAt?(this.clearTempToken(e),null):n.token}catch(e){return console.error("Error getting temp token:",e),null}}clearTempToken(e){try{sessionStorage.removeItem(`heimguard_temp_${e}`)}catch(e){console.error("Error clearing temp token:",e)}}generateState(e=32){const t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",n=new Uint8Array(e);return crypto.getRandomValues(n),Array.from(n,(e=>t[e%62])).join("")}storeOAuthState(e,t){try{const n={state:e,provider:t,createdAt:Date.now(),expiresAt:Date.now()+6e5};sessionStorage.setItem("heimguard_oauth_state",JSON.stringify(n))}catch(e){console.error("Error storing OAuth state:",e)}}verifyOAuthState(e,t){try{const n=sessionStorage.getItem("heimguard_oauth_state");if(!n)return!1;const o=JSON.parse(n);return sessionStorage.removeItem("heimguard_oauth_state"),o.state===e&&o.provider===t&&Date.now()<o.expiresAt}catch(e){return console.error("Error verifying OAuth state:",e),!1}}clearAuthStorage(){this.deleteCookie(this.authCookieName);const e=[];for(let t=0;t<sessionStorage.length;t++){const n=sessionStorage.key(t);n?.startsWith("heimguard_")&&e.push(n)}e.forEach((e=>sessionStorage.removeItem(e))),["heimguard_session","heimguard_user"].forEach((e=>localStorage.removeItem(e)))}};Error;var we=n(6833);class Se{constructor(){this.supportEmail=null,this.loginUrl=null,this.initialize()}async initialize(){"expired"===new URLSearchParams(window.location.search).get("passwordlessLoginToken")&&(await this.loadHeimguardConfig(),this.showExpiredTokenModal(),this.removeTokenParameter())}async loadHeimguardConfig(){try{const e=await v.initService.getInitData();console.log("[PasswordlessLoginHandler] Init data loaded:",e),e.generalConfig?.companySupportEmail?(this.supportEmail=e.generalConfig.companySupportEmail,console.log("[PasswordlessLoginHandler] Found support email:",this.supportEmail)):console.log("[PasswordlessLoginHandler] No support email in config"),e.login?.url?(this.loginUrl=e.login.url,console.log("[PasswordlessLoginHandler] Found login URL:",this.loginUrl)):console.log("[PasswordlessLoginHandler] No login URL in config")}catch(e){console.error("[PasswordlessLoginHandler] Error loading config:",e)}}showExpiredTokenModal(){console.log("[PasswordlessLoginHandler] Showing modal with:"),console.log(" - Support email:",this.supportEmail),console.log(" - Login URL:",this.loginUrl),console.log(" - Full HeimGuard config:",window.HeimGuard);const e=this.supportEmail?`<a href="mailto:${this.supportEmail}" class="text-primary-600 hover:text-primary-700 underline font-medium">contact customer support</a>`:"contact customer support";console.log("[PasswordlessLoginHandler] Support link HTML:",e);const t=new we.Modal({title:"Something Went Wrong",content:`\n <div class="space-y-4">\n <div class="flex justify-center mb-4">\n <div class="w-16 h-16 bg-amber-100 rounded-full flex items-center justify-center">\n ${Y.Hj.render("alert-circle",{class:"w-8 h-8 text-amber-600"})}\n </div>\n </div>\n\n <p class="text-gray-700 text-center text-lg">\n Sorry, this magic link has expired.\n </p>\n\n <p class="text-gray-700 text-center">\n Please ${e} for assistance.\n </p>\n </div>\n `,footer:`\n <div class="flex justify-center items-center space-x-3">\n ${this.loginUrl?`\n <button\n id="modal-login"\n class="bg-primary-600 hover:bg-primary-700 text-white px-6 py-2 rounded-lg transition-colors font-medium flex items-center space-x-2"\n >\n ${Y.Hj.render("log-in",{class:"w-4 h-4"})}
1\n <span>Go to Login</span>\n </button>\n `:""}\n <button\n id="modal-close"\n class="bg-gray-600 hover:bg-gray-700 text-white px-6 py-2 rounded-lg transition-colors font-medium"\n >\n Close\n </button>\n </div>\n `,size:"small",closeButton:!0,closeOnOverlay:!0,closeOnEscape:!0});t.open(),setTimeout((()=>{const e=document.getElementById("modal-close");e&&e.addEventListener("click",(()=>{t.close()}));const n=document.getElementById("modal-login");n&&this.loginUrl&&n.addEventListener("click",(()=>{window.location.href=this.loginUrl}))}),0)}removeTokenParameter(){const e=new URL(window.location.href);e.searchParams.delete("passwordlessLoginToken"),window.history.replaceState({},document.title,e.toString())}}"undefined"!=typeof document&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>{new Se})):new Se);n(8252);var xe,Ae;(Ae=xe||(xe={})).LOGIN_STARTED="auth:login:started",Ae.LOGIN_SUCCESS="auth:login:success",Ae.LOGIN_ERROR="auth:login:error",Ae.LOGOUT_STARTED="auth:logout:started",Ae.LOGOUT_SUCCESS="auth:logout:success",Ae.LOGOUT_ERROR="auth:logout:error",Ae.REGISTER_STARTED="auth:register:started",Ae.REGISTER_SUCCESS="auth:register:success",Ae.REGISTER_ERROR="auth:register:error",Ae.SESSION_VALIDATED="auth:session:validated",Ae.SESSION_EXPIRED="auth:session:expired",Ae.SESSION_ERROR="auth:session:error",Ae.TWO_FACTOR_REQUIRED="auth:2fa:required",Ae.TWO_FACTOR_SUCCESS="auth:2fa:success",Ae.TWO_FACTOR_ERROR="auth:2fa:error",Ae.PASSWORD_RESET_REQUESTED="auth:password:reset:requested",Ae.PASSWORD_RESET_SUCCESS="auth:password:reset:success",Ae.PASSWORD_RESET_ERROR="auth:password:reset:error",Ae.SHOW_LOGIN_MODAL="auth:ui:showLogin",Ae.SHOW_REGISTER_MODAL="auth:ui:showRegister",Ae.CLOSE_AUTH_MODAL="auth:ui:closeModal",Ae.STATE_CHANGED="auth:state:changed",Ae.USER_UPDATED="auth:user:updated","undefined"!=typeof window&&(A.systemRegistry.has("authSystem")||async function(){const e=new me;A.systemRegistry.register("authSystemAdapter",e),await e.initialize()}().catch((e=>{console.error("[Auth] Failed to initialize auth system:",e)})),window.testRedirect=()=>{console.log("Testing redirect..."),window.dispatchEvent(new CustomEvent("heimguard:unauthorized",{detail:{path:"/profile",status:401},bubbles:!0}))});(()=>{if("undefined"!=typeof window){const e=A.systemRegistry.get("authSystem");if(e)return e}})();var Te=n(2551),Me=n.n(Te),Ee=n(8354);var Pe=class{constructor(e={profileData:null,onNavigate:null}){this.options={profileData:e.profileData||null,onNavigate:e.onNavigate||null},this.modal=null}show(){const e=this.calculateDetailedCompletion(),t=`\n <div class="profile-completion-modal">\n \x3c!-- Overall Progress --\x3e\n <div class="mb-6">\n <div class="flex items-center justify-between mb-3">\n <h3 class="text-lg font-medium text-gray-900">Overall Completion</h3>\n <span class="text-2xl font-bold ${100===e.percentage?"text-green-600":"text-primary-600"}">\n ${e.percentage}%\n </span>\n </div>\n <div class="w-full bg-gray-200 rounded-full h-3">\n <div\n class="h-3 rounded-full transition-all duration-500 ${100===e.percentage?"bg-gradient-to-r from-green-500 to-green-600":"bg-gradient-to-r from-primary-500 to-secondary-600"}"\n style="width: ${e.percentage}%"\n ></div>\n </div>\n </div>\n\n ${100===e.percentage?`\n \x3c!-- Completed State --\x3e\n <div class="text-center py-8">\n <div class="inline-flex items-center justify-center w-16 h-16 bg-green-100 rounded-full mb-4">\n ${P.H.getIcon("general","check-circle","w-8 h-8 text-green-600")}\n </div>\n <h4 class="text-lg font-semibold text-gray-900 mb-2">Profile Complete!</h4>\n <p class="text-gray-600">Great job! Your profile is 100% complete.</p>\n </div>\n `:`\n \x3c!-- Completion Items --\x3e\n <div class="space-y-3">\n ${e.fields.map((e=>this.renderCompletionItem(e))).join("")}\n </div>\n\n \x3c!-- Tips --\x3e\n <div class="mt-6 p-4 bg-blue-50 rounded-lg">\n <div class="flex">\n ${P.H.getIcon("general","info","w-5 h-5 text-blue-500 mt-0.5")}\n <div class="ml-2">\n <h5 class="text-sm font-medium text-blue-900">Why complete your profile?</h5>\n <ul class="mt-1 text-sm text-blue-700 space-y-1">\n <li>⢠Faster checkout with saved information</li>\n <li>⢠Personalized recommendations</li>\n <li>⢠Better account security</li>\n <li>⢠Exclusive member benefits</li>\n </ul>\n </div>\n </div>\n </div>\n `}\n </div>\n `;this.modal=new we.Modal({title:"Profile Completion",content:t,size:"medium",closeButton:!0}),this.modal.open(),setTimeout((()=>this.attachEventListeners()),100)}calculateDetailedCompletion(){const e=this.options.profileData||{},t=w.default.isCabotWealth(),n=t?{email:40,firstName:20,lastName:20,mobile:10,sms:10,address:0,avatar:0}:{email:35,firstName:15,lastName:15,mobile:10,sms:10,address:10,avatar:5},o=[{field:"isEmailVerified",label:"Verify Email",section:"profile",weight:n.email,completed:!(!e.isEmailVerified&&!e.isVerified),icon:"email",iconType:"auth",action:"Verify",hint:"Confirm your email address"},{field:"firstName",label:"First Name",section:"profile",weight:n.firstName,completed:!(!e.firstName||!e.firstName.trim()),icon:"user",iconType:"general",action:"Add",hint:"Add your first name"},{field:"lastName",label:"Last Name",section:"profile",weight:n.lastName,completed:!(!e.lastName||!e.lastName.trim()),icon:"user",iconType:"general",action:"Add",hint:"Add your last name"},{field:"mobileNumber",label:"Mobile Number",section:"profile",weight:n.mobile,completed:!!e.mobileNumber,icon:"phone",iconType:"general",action:"Add",hint:"Add your phone number"},{field:"smsOptIn",label:"SMS Opt-In",section:"profile",weight:n.sms,completed:!!e.smsAgreementOptIn,icon:"email",iconType:"general",action:"Add",hint:"Enable SMS notifications"}];
1t||o.push({field:"defaultAddress",label:"Default Address",section:"addresses",weight:n.address,completed:!!e.defaultAddress,icon:"location",iconType:"general",action:"Add",hint:"Save a default address"}),t||o.push({field:"avatarUrl",label:"Profile Picture",section:"profile",weight:n.avatar,completed:!(!e.avatarUrl&&!e.avatarImgSrc),icon:"image",iconType:"general",action:"Upload",hint:"Add a profile photo"});const i=o.filter((e=>e.completed)).reduce(((e,t)=>e+t.weight),0);return{percentage:Math.round(i),fields:o.filter((e=>!e.completed))}}renderCompletionItem(e){return`\n <div class="flex items-center justify-between p-3 rounded-lg border ${e.completed?"border-green-200 bg-green-50":"border-gray-200 bg-white hover:bg-gray-50"} transition-colors">\n <div class="flex items-center">\n <div class="flex-shrink-0">\n ${e.completed?P.H.getIcon("general","check-circle","w-5 h-5 text-green-600"):P.H.getIcon(e.iconType,e.icon,"w-5 h-5 text-gray-400")}\n </div>\n <div class="ml-3">\n <p class="text-sm font-medium ${e.completed?"text-green-900":"text-gray-900"}">\n ${e.label}\n </p>\n <p class="text-xs ${e.completed?"text-green-700":"text-gray-500"}">\n ${e.completed?"Completed":e.hint}\n </p>\n </div>\n </div>\n ${!e.completed&&this.options.onNavigate?`\n <button\n data-action="resend-verification"\n data-section="${e.section}"\n data-field="${e.field}"\n class="ml-4 text-sm font-medium text-primary-600 hover:text-primary-700 flex items-center"\n >\n ${e.action}\n ${P.H.getIcon("ui","arrowRight","w-4 h-4 ml-1")}\n </button>\n `:`\n <span class="text-sm text-gray-400 font-medium">\n +${e.weight}%\n </span>\n `}\n </div>\n `}attachEventListeners(){if(!this.modal)return;const e=document.querySelector(".modal-content");e&&e.querySelectorAll('[data-action="navigate"]').forEach((e=>{e.addEventListener("click",(e=>{const t=e.currentTarget,n=t.getAttribute("data-section"),o=t.getAttribute("data-field");n&&this.options.onNavigate&&(this.modal?.close(),setTimeout((()=>{this.options.onNavigate&&this.options.onNavigate(n,o||void 0)}),100))}))}))}};var Ne=class{constructor(e,t={profileData:null,api:null}){this._ignoreNextHashChange=!1,this._isLoadingSection=null,this.eventUnsubscribers=[],this.completionModal=null,this.mobileMenuOpen=!1,this.isCabotWealth=!1,this.container=e,this.options={onSectionChange:()=>{},...t},this.currentSection="profile",this.sectionComponents=new Map,this.hashChangeHandler=async()=>{if(this._ignoreNextHashChange)return void(this._ignoreNextHashChange=!1);const e=window.location.hash.substring(1);e&&["profile","addresses","payment","subscriptions","invoices","security","newsletters","activity","rewards","affinity"].includes(e)&&await this.loadSection(e)}}async render(){await w.default.load(),this.isCabotWealth=w.default.isCabotWealth();const e=this.options.profileData?.profileCreationDate?new Date(this.options.profileData.profileCreationDate).getFullYear():(new Date).getFullYear(),t={activeSubscriptions:0,paymentMethodsCount:0,addressCount:0,affinityCount:0,...this.options.profileData?.stats};this.container.innerHTML=Me()({profile:{...this.options.profileData,stats:t,initials:this.getInitials(this.options.profileData),hideAvatar:this.isCabotWealth,hideMemberSince:this.isCabotWealth,hideActivity:this.isCabotWealth},memberYear:e,subscription:{hideFreeTrial:this.isCabotWealth,hideOffers:this.isCabotWealth,sortByGroups:this.isCabotWealth}}),this.attachEventListeners();const n=window.location.hash.substring(1)||"profile";await this.loadSection(n),this.calculateProfileCompletion(),this.fetchInitialCounts()}getInitials(e){if(!e)return"U";const t=e.firstName||"",n=e.lastName||"";if(t&&n)return`${t.charAt(0)}${n.charAt(0)}`.toUpperCase();if(t)return t.substring(0,2).toUpperCase();if(e.displayName){const t=e.displayName.split(" ");return t.length>1?`${t[0].charAt(0)}${t[1].charAt(0)}`.toUpperCase():e.displayName.substring(0,2).toUpperCase()}return"U"}calculateProfileCompletion(){if(!this.options.profileData)return 0;const e=this.options.profileData,t=this.isCabotWealth?{email:40,firstName:20,lastName:20,mobile:10,sms:10,address:0,avatar:0}:{email:35,firstName:15,lastName:15,mobile:10,sms:10,address:10,avatar:5},n=[{field:"isEmailVerified",weight:t.email,check:()=>!(!e.isEmailVerified&&!e.isVerified)},{field:"firstName",weight:t.firstName,check:()=>
1!(!e.firstName||!e.firstName.trim())},{field:"lastName",weight:t.lastName,check:()=>!(!e.lastName||!e.lastName.trim())},{field:"mobileNumber",weight:t.mobile,check:()=>!!e.mobileNumber},{field:"smsOptIn",weight:t.sms,check:()=>!!e.smsAgreementOptIn}];this.isCabotWealth||n.push({field:"defaultAddress",weight:t.address,check:()=>!!e.defaultAddress}),this.isCabotWealth||n.push({field:"avatarUrl",weight:t.avatar,check:()=>!(!e.avatarUrl&&!e.avatarImgSrc)});let o=0;n.forEach((e=>{e.check()&&(o+=e.weight)}));const i=Math.round(o),a=this.container.querySelector("#profile-completion"),s=this.container.querySelector("#profile-completion-bar");return a&&(a.textContent=`${i}%`),s&&(s.style.width=`${i}%`,100===i?(s.classList.remove("bg-primary-600"),s.classList.add("bg-green-600")):(s.classList.remove("bg-green-600"),s.classList.add("bg-primary-600"))),i}async fetchInitialCounts(){await Promise.all([this.fetchInitialSubscriptionCount(),this.fetchInitialPaymentMethodCount(),this.fetchInitialAddressCount(),this.fetchInitialAffinityCount()])}async fetchInitialSubscriptionCount(){try{const e=await fetch(f.A.apiGetSubscriptionsUrl,{credentials:"include"});let t=0;if(e.ok){const n=await e.json();if(console.log("[ProfileDashboard] Initial subscription data:",n),n.subscriptions)if(Array.isArray(n.subscriptions))t=n.subscriptions.filter((e=>{const t=e.subscriptionState||e.state||e.status;return"active"===t||"live"===t||"canceled"===t})).length;else if("object"==typeof n.subscriptions){t=Object.values(n.subscriptions).filter((e=>{const t=e.subscriptionState||e.state||e.status;return"active"===t||"live"===t||"canceled"===t})).length}}this.updateSubscriptionCount(t)}catch(e){console.error("Error fetching subscription count:",e),this.updateSubscriptionCount(0)}}async fetchInitialPaymentMethodCount(){try{const e=await fetch(f.A.apiGetPaymentMethodsUrl,{credentials:"include"});let t=0;if(e.ok){const n=await e.json();n.paymentMethods&&(Array.isArray(n.paymentMethods)?t=n.paymentMethods.length:"object"==typeof n.paymentMethods&&(t=Object.keys(n.paymentMethods).length))}this.updatePaymentMethodCount(t)}catch(e){console.error("Error fetching payment method count:",e),this.updatePaymentMethodCount(0)}}async fetchInitialAddressCount(){try{const e=await fetch(f.A.apiGetAllAddresses,{credentials:"include"});let t=0;if(e.ok){const n=await e.json();n.addresses&&(Array.isArray(n.addresses)?t=n.addresses.length:"object"==typeof n.addresses&&(t=Object.keys(n.addresses).length))}this.updateAddressCount(t)}catch(e){console.error("Error fetching address count:",e),this.updateAddressCount(0)}}async fetchInitialAffinityCount(){try{const e=await fetch(f.A.apiAffinityUserItemsUrl,{method:"GET",credentials:"include"});let t=0;if(e.ok){t=(await e.json()).totalCount||0}this.options.profileData&&(this.options.profileData.stats||(this.options.profileData.stats={}),this.options.profileData.stats.affinityCount=t);const n=this.container.querySelector('a[href="#affinity"] .rounded-full');n&&t>0&&(n.textContent=t.toString())}catch(e){console.error("Error fetching affinity count:",e)}}attachEventListeners(){this.container.addEventListener("click",(e=>{e.target.closest("[data-profile-completion-info]")&&(e.preventDefault(),e.stopPropagation(),this.completionModal||(this.completionModal=new Pe({profileData:this.options.profileData,onNavigate:async(e,t)=>{await this.loadSection(e),"profile"===e&&"avatarUrl"===t?setTimeout((()=>{(0,Ee.c)("profile:edit:avatar",{})}),300):"profile"===e&&setTimeout((()=>{const e=document.querySelector("#edit-profile-btn");e&&e.click()}),300)}})),this.completionModal.show())}));const e=this.container.querySelector("#header-avatar-edit");e&&e.addEventListener("click",(async e=>{e.preventDefault(),e.stopPropagation(),await this.loadSection("profile"),setTimeout((()=>{(0,Ee.c)("profile:edit:avatar",{})}),300)})),this.setupMobileMenu(),this.container.querySelectorAll(".sidebar-item").forEach((e=>{e.addEventListener("click",(async t=>{t.preventDefault();const n=e.getAttribute("href")?.substring(1);n&&await this.loadSection(n)}))})),this.container.querySelectorAll(".quick-stat-card").forEach((e=>{e.addEventListener("click",(async()=>{const t=e.getAttribute("data-target-section");t&&await this.loadSection(t)}))})),this.eventUnsubscribers.push(Ee.AC.on("TAB_CHANGED",(({section:e})=>{this.loadSection(e)}))),window.addEventListener("hashchange",this.hashChangeHandler),this.eventUnsubscribers.push(Ee.ProfileEvents.on("UPDATED",(({data:e})=>{this.updateProfileData(e)}))),this.eventUnsubscribers.push(Ee.ProfileEvents.on("STATS_UPDATED",(({stats:e})=>{void 0!==e.paymentMethods&&this.updatePaymentMethodCount(e.paymentMethods)}))),this.eventUnsubscribers.push(Ee.ProfileEvents.on("STATS_UPDATED",(({stats:e})=>{void 0!==e.addressCount&&this.updateAddressCount(e.addressCount)}))),this.eventUnsubscribers.push(Ee.ProfileEvents.on("STATS_UPDATED",(({stats:e})=>{void 0!==e.activeSubscriptions&&this.updateSubscriptionCount(e.activeSubscriptions)}))),this.container.querySelectorAll("[data-logout-trigger]").forEach((e=>{e.addEventListener("click",(async()=>{await this.handleLogout()}))}))}setupMobileMenu(){const e=this.container.querySelector("#mobile-menu-toggle"),t=this.container.querySelector("#mobile-menu-close"),n=this.container.querySelector("#mobile-menu-overlay"),o=this.container.querySelector("#mobile-sidebar");e&&o&&n&&(e.addEventListener("click",(()=>{this.mobileMenuOpen=!0,o.classList.remove("-translate-x-full"),n.classList.remove("hidden"),document.body.classList.add("overflow-hidden")})),t&&t.addEventListener("click",(()=>{this.closeMobileMenu()})),n.addEventListener("click",(()=>{this.closeMobileMenu()})),this.container.querySelectorAll(".mobile-nav-item").forEach((e=>{e.addEventListener("click",(()=>{this.closeMobileMenu()}))})))}closeMobileMenu(){const e=this.container.querySelector("#mobile-sidebar"),t=this.container.querySelector("#mobile-menu-overlay");e&&t&&(this.mobileMenuOpen=!1,e.classList.add("-translate-x-full"),t.classList.add("hidden"),document.body.classList.remove("overflow-hidden"))}updateActiveMenuItem(e){this.container.querySelectorAll(".sidebar-item").forEach((t=>{const n=t.getAttribute("href")?.substring(1);n===e?(t.classList.add("active","bg-primary-50","text-primary-700"),t.classList.remove("text-gray-700")):(t.classList.remove("active","bg-primary-50","text-primary-700"),t.classList.add("text-gray-700"))}))}showSection(e){this.container.querySelectorAll(".hg-section").forEach((e=>{e.classList.add("hidden")}));const t=this.container.querySelector(`#${e}-section`);t&&t.classList.remove("hidden")}async loadSection(e){if(this._isLoadingSection===e)return;this._isLoadingSection=e,this.currentSection=e,this.updateActiveMenuItem(e),this.showSection(e),window.location.hash!==`#${e}`&&(this._ignoreNextHashChange=!0,window.location.hash=e);const t=this.container.querySelector(`#${e}-section`);if(!t)return console.error(`Section container not found: ${e}-section`),void(this._isLoadingSection=null);if(this.sectionComponents.has(e)){const n=this.sectionComponents.get(e);if(n&&n.refresh&&!t.querySelector(".hg-section-loading"))return await n.refresh(),void(this._isLoadingSection=null);n&&n.cleanup&&(n.cleanup(),this.sectionComponents.delete(e))}try{t.innerHTML=`\n <div class="hg-section-loading p-12 text-center">\n <div class="animate-spin h-8 w-8 border-4 border-primary-600 border-t-transparent roun
1ded-full mx-auto mb-4"></div>\n <p class="text-gray-600">Loading ${e}...</p>\n </div>\n `,t.innerHTML="";let n=null;const o=this.options.componentRegistry?this.options.componentRegistry.get(e):null;o?n=new o(t,{profileData:this.options.profileData,api:this.options.api}):t.innerHTML=`\n <div class="p-8 text-center">\n <div class="inline-flex items-center justify-center w-16 h-16 bg-gray-100 rounded-full mb-4">\n <svg class="w-8 h-8 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />\n </svg>\n </div>\n <h3 class="text-lg font-semibold text-gray-900 mb-2">${e.charAt(0).toUpperCase()+e.slice(1)}</h3>\n <p class="text-gray-600">This section is coming soon!</p>\n </div>\n `,n&&n.render&&(await n.render(),this.sectionComponents.set(e,n)),this.options.onSectionChange&&this.options.onSectionChange(e)}catch(n){console.error(`Error loading section ${e}:`,n),t.innerHTML=`\n <div class="p-8 text-center">\n <div class="inline-flex items-center justify-center w-16 h-16 bg-red-100 rounded-full mb-4">\n <svg class="w-8 h-8 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n </div>\n <h3 class="text-lg font-semibold text-gray-900 mb-2">Error Loading Section</h3>\n <p class="text-gray-600">${n.message||"An unexpected error occurred"}</p>\n <button class="mt-4 inline-flex items-center px-4 py-2 bg-primary-600 text-white text-sm font-medium rounded-lg hover:bg-primary-700" onclick="location.reload()">\n Refresh Page\n </button>\n </div>\n `}finally{this._isLoadingSection=null}}async updateProfile(e){if(e){if(JSON.stringify(this.options.profileData)!==JSON.stringify(e)){this.options.profileData=e;const t=this.container.querySelector("#header-profile-name"),n=this.container.querySelector("#sidebar-profile-name");t&&(t.textContent=e.firstName||"User"),n&&(n.textContent=`${e.firstName||""} ${e.lastName||""}`.trim()),this.calculateProfileCompletion(),this.completionModal&&(this.completionModal.options.profileData=e);const o=this.container.querySelector("#header-avatar");if(o){const t=e.avatarUrl||e.avatarImgSrc;if(t){const e=(new Date).getTime(),n=t+(t.includes("?")?"&":"?")+"t="+e;if("IMG"===o.tagName)o.src=n;else{const e=document.createElement("img");e.id="header-avatar",e.className=o.className,e.src=n,e.alt="Profile",o.parentNode?.replaceChild(e,o)}this.container.querySelectorAll(`img[src*="${t}"]`).forEach((e=>{e.src.includes(t)&&(e.src=n)}))}}for(const[t,n]of this.sectionComponents)n&&n.updateProfile&&await n.updateProfile(e)}}else console.error("[ProfileDashboard] updateProfile called with undefined profileData")}updateProfileData(e){e?this.updateProfile(e):console.warn("[ProfileDashboard] updateProfileData called with undefined profileData")}async handleLogout(){try{window.dispatchEvent(new CustomEvent("auth:ui:logout",{detail:{manual:!0}}))}catch(e){console.error("Logout error:",e),window.dispatchEvent(new CustomEvent("auth:ui:logout",{detail:{manual:!0}}))}}updatePaymentMethodCount(e){const t=this.container.querySelector('[data-stat="paymentMethods"]');t&&(t.textContent=(e||0).toString()),this.options.profileData&&(this.options.profileData.stats||(this.options.profileData.stats={}),this.options.profileData.stats.paymentMethodsCount=e)}updateAddressCount(e){const t=this.container.querySelector('[data-stat="savedAddresses"]');t&&(t.textContent=(e||0).toString()),this.options.profileData&&(this.options.profileData.stats||(this.options.profileData.stats={}),this.options.profileData.stats.addressCount=e)}updateSubscriptionCount(e){const t=this.container.querySelector('[data-stat="activeSubscriptions"]');t&&(t.textContent=(e||0).toString()),this.options.profileData&&(this.options.profileData.stats||(this.options.profileData.stats={}),this.options.profileData.stats.activeSubscriptions=e)}cleanup(){window.removeEventListener("hashchange",this.hashChangeHandler),this.sectionComponents.forEac
1h((e=>{e.cleanup&&e.cleanup()})),this.sectionComponents.clear(),this.eventUnsubscribers.forEach((e=>e())),this.eventUnsubscribers=[],this.completionModal=null,this.mobileMenuOpen&&this.closeMobileMenu()}},Le=n(6730),De=n(2404),Ie=n(1678),ke=n(8243),Oe=n(3960),Re=n(5606);class Be{static render({title:e="Something went wrong",message:t="We encountered an unexpected error. Please try again.",error:n=null,showDetails:o=!1,onRetry:i=null,onDismiss:a=null,variant:s="error",className:r=""}){const d={error:Y.Hj.render("alert-circle",{class:"w-12 h-12 text-red-500"}),warning:Y.Hj.render("alert-triangle",{class:"w-12 h-12 text-yellow-500"}),info:Y.Hj.render("info",{class:"w-12 h-12 text-blue-500"})},l={error:"bg-red-50",warning:"bg-yellow-50",info:"bg-blue-50"},c=this.getUserFriendlyMessage(n,t),u=`\n <div class="text-center ${l[s]||l.error} rounded-lg p-8">\n <div class="flex justify-center mb-4">\n ${d[s]||d.error}\n </div>\n \n <h3 class="text-lg font-semibold text-gray-900 mb-2">\n ${this.escapeHtml(e)}\n </h3>\n \n <p class="text-gray-600 mb-6 max-w-md mx-auto">\n ${this.escapeHtml(c)}\n </p>\n \n ${this.renderActions(i,a)}\n \n ${o&&n?this.renderErrorDetails(n):""}\n </div>\n `;return Oe.Z.render({content:u,variant:"bordered",className:`error-card ${r}`})}static getUserFriendlyMessage(e,t){if(!e)return t;if(e.getUserMessage&&"function"==typeof e.getUserMessage)return e.getUserMessage();if(e.status)switch(e.status){case 401:return"You need to be logged in to view this content. Please log in and try again.";case 403:return"You don't have permission to access this content.";case 404:return"The requested information could not be found.";case 429:return"Too many requests. Please wait a moment and try again.";case 500:case 502:case 503:return"Our servers are experiencing issues. Please try again in a few moments.";default:return t}if(e.message){if(e.message.includes("Network")||e.message.includes("fetch"))return"Unable to connect to our servers. Please check your internet connection and try again.";if(e.message.includes("aborted"))return"The request was cancelled. Please try again."}return t}static renderActions(e,t){if(!e&&!t)return"";const n=[];if(e){let t;if("function"==typeof e){const n=`errorcard_retry_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;window[n]=e,t=`window.${n}(); delete window.${n};`}else t=e;n.push(Ie.$.render({text:"Try Again",variant:"primary",icon:Y.Hj.render("refresh-cw",{class:"w-4 h-4"}),onClick:t,className:"retry-btn"}))}if(t){let e;if("function"==typeof t){const n=`errorcard_dismiss_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;window[n]=t,e=`window.${n}(); delete window.${n};`}else e=t;n.push(Ie.$.render({text:"Dismiss",variant:"white",onClick:e,className:"dismiss-btn"}))}return`\n <div class="flex justify-center gap-3">\n ${n.join("")}\n </div>\n `}static renderErrorDetails(e){let t="";return e.status&&(t+=`Status: ${e.status}\n`),e.statusText&&(t+=`Status Text: ${e.statusText}\n`),e.message&&(t+=`Message: ${e.message}\n`),e.stack&&void 0!==Re&&Re.env,`\n <details class="mt-6 text-left">\n <summary class="cursor-pointer text-sm text-gray-500 hover:text-gray-700">\n Show technical details\n </summary>\n <pre class="mt-2 p-4 bg-gray-100 rounded text-xs text-gray-700 overflow-x-auto">\n${this.escapeHtml(t.trim())}\n </pre>\n </details>\n `}static escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}static renderNetworkError(e={}){return this.render({title:"Connection Problem",message:"Unable to connect to our servers. Please check your internet connection and try again.",variant:"error",...e})}static renderAuthError(e={}){return this.render({title:"Authentication Required",message:"You need to be logged in to view this content.",variant:"warning",onRetry:'() => (window.location.href = "/login")',...e})}static renderPermissionError(e={}){return this.render({title:"Access Denied",message:"You don't have permission to access this content.",variant:"error",...e})}static renderNotFoundError(e={}){return this.render({title:"Not Found",message:"The content you're looking for could not be found.",variant:"warning",...e})}
1static renderServerError(e={}){return this.render({title:"Server Error",message:"Our servers are experiencing issues. Please try again later.",variant:"error",...e})}}class $e extends B.z{static render(e){return super.render({type:"text",...e})}static validate(e,t={}){const n=super.validate(e,t),o=String(e||"");return t.alphaOnly&&o&&!/^[a-zA-Z\s]*$/.test(o)&&n.push("Only letters and spaces are allowed"),t.alphaNumeric&&o&&!/^[a-zA-Z0-9\s]*$/.test(o)&&n.push("Only letters, numbers, and spaces are allowed"),t.noSpecialChars&&o&&/[^a-zA-Z0-9\s\-_]/.test(o)&&n.push("Special characters are not allowed"),n}}var Ue=n(6894),Fe=(n(4436),n(8689)),ze=n(4148),He=n(5856);class Ge{static async resizeImage(e,t,n,o=.9){return new Promise(((i,a)=>{const s=new FileReader;s.onload=s=>{if(!s.target?.result)return void a(new Error("Failed to read file"));const r=new Image;r.onload=()=>{let s=r.width,d=r.height;if(s>t||d>n){const e=s/d;s>d?(s=t,d=s/e):(d=n,s=d*e)}const l=document.createElement("canvas");l.width=s,l.height=d;const c=l.getContext("2d");c?(c.imageSmoothingEnabled=!0,c.imageSmoothingQuality="high",c.drawImage(r,0,0,s,d),l.toBlob((t=>{if(!t)return void a(new Error("Failed to create blob"));const n=new File([t],e.name,{type:e.type,lastModified:Date.now()});i(n)}),e.type,o)):a(new Error("Failed to get canvas context"))},r.onerror=()=>a(new Error("Failed to load image")),r.src=s.target.result},s.onerror=()=>a(new Error("Failed to read file")),s.readAsDataURL(e)}))}static async optimizeImage(e,t=500){if(e.size<=1024*t)return e;let n=.9,o=e;for(;n>.1&&o.size>1024*t;)o=await this.resizeImage(e,1e3,1e3,n),n-=.1;return o}static async convertToWebP(e,t=.9){return new Promise(((n,o)=>{const i=new FileReader;i.onload=i=>{if(!i.target?.result)return void o(new Error("Failed to read file"));const a=new Image;a.onload=()=>{const i=document.createElement("canvas");i.width=a.width,i.height=a.height;const s=i.getContext("2d");s?(s.drawImage(a,0,0),i.toBlob((t=>{if(t){const o=new File([t],e.name.replace(/\.[^.]+$/,".webp"),{type:"image/webp",lastModified:Date.now()});n(o)}else n(e)}),"image/webp",t)):o(new Error("Failed to get canvas context"))},a.onerror=()=>o(new Error("Failed to load image")),a.src=i.target.result},i.onerror=()=>o(new Error("Failed to read file")),i.readAsDataURL(e)}))}static supportsWebP(){const e=document.createElement("canvas");return e.width=1,e.height=1,5===e.toDataURL("image/webp").indexOf("image/webp")}static async calculateAverageBrightness(e){return new Promise(((t,n)=>{const o=new FileReader;o.onload=e=>{if(!e.target?.result)return void n(new Error("Failed to read file"));const o=new Image;o.onload=()=>{const e=document.createElement("canvas"),i=e.getContext("2d");if(!i)return void n(new Error("Failed to get canvas context"));const a=100;e.width=a,e.height=a,i.drawImage(o,0,0,a,a);const s=i.getImageData(0,0,a,a).data;let r=0;for(let e=0;e<s.length;e+=4)r+=.299*s[e]+.587*s[e+1]+.114*s[e+2];r/=1e4,t(r)},o.onerror=()=>n(new Error("Failed to load image")),o.src=e.target.result},o.onerror=()=>n(new Error("Failed to read file")),o.readAsDataURL(e)}))}static async createSquareCrop(e){return new Promise(((t,n)=>{const o=new FileReader;o.onload=o=>{if(!o.target?.result)return void n(new Error("Failed to read file"));const i=new Image;i.onload=()=>{const o=Math.min(i.width,i.height),a=(i.width-o)/2,s=(i.height-o)/2,r=document.createElement("canvas");r.width=o,r.height=o;const d=r.getContext("2d");d?(d.drawImage(i,a,s,o,o,0,0,o,o),r.toBlob((o=>{if(!o)return void n(new Error("Failed to create blob"));const i=new File([o],e.name,{type:e.type,lastModified:Date.now()});t(i)}),e.type,.9)):n(new Error("Failed to get canvas context"))},i.onerror=()=>n(new Error("Failed to load image")),i.src=o.target.result},o.onerror=()=>n(new Error("Failed to read file")),o.readAsDataURL(e)}))}static async getImageDimensions(e){return new Promise(((t,n)=>{const o=new FileReader;o.onload=e=>{if(!e.target?.result)return void n(new Error("Failed to read file"));const o=new Image;o.onload=()=>{t({width:o.width,height:o.height})},o.onerror=()=>n(new Error("Failed to load image")),o.src=e.target.result},o.onerror=()=>n(new Error("Failed to read file")),o.readAsDataURL(e)}))}}var _e=class{constructor(e={profileData:null}){this.options={profileData:e.profileData||null,onUpload:e.onUpload||null,onRemove:e.onRemove||null},this.modal=null,this.fileInput=null,this.isDragging=!1,this.isRemoving=!1}show(){const e=!(!this.options.profileData?.avatarImgSrc&&!this.options.profileData?.avatarUrl),t=`\n <div class="avatar-modal-content">\n \x3c!-- Current Avatar Preview --\x3e\n <div class="text-center mb-6">\n <div class="inline-block relative">\n ${e?`\n <img \n class="h-32 w-32 rounded-full object-cover ring-4 ring-gray-200 shadow-lg mx-auto" \n src="${this.options.profileData.avatarImgSrc||this.options.profileData.avatarUrl}" \n alt="Current avatar"\n />\n `:`\n <div class="h-32 w-32 rounded-full bg-primary-600 flex items-center justify-center ring-4 ring-gray-200 shadow-lg mx-auto">
1\n <span class="text-4xl font-bold text-white">\n ${this.options.profileData?.initials||"U"}\n </span>\n </div>\n `}\n ${e?`\n <button \n type="button"\n id="remove-avatar-btn"\n class="absolute bottom-0 right-0 bg-red-600 text-white rounded-full p-2 hover:bg-red-700 transition-colors shadow-lg"\n title="Remove avatar"\n >\n ${P.H.render("trash",{class:"w-4 h-4"})}\n </button>\n `:""}\n </div>\n </div>\n \n \x3c!-- Instructions --\x3e\n <div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">\n <div class="flex">\n <div class="flex-shrink-0">\n ${P.H.getIcon("general","info","h-5 w-5 text-blue-400")}\n </div>\n <div class="ml-3 text-sm text-blue-700">\n <p class="font-medium mb-1">Photo Requirements:</p>\n <ul class="list-disc list-inside space-y-1">\n <li>JPG, PNG or GIF format</li>\n <li>Maximum file size: 5MB</li>\n <li>Recommended: Square image, at least 200x200px</li>\n <li>Clear photo of your face works best</li>\n </ul>\n </div>\n </div>\n </div>\n \n \x3c!-- Upload Area --\x3e\n <div \n id="drop-zone"\n class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center hover:border-gray-400 transition-colors cursor-pointer"\n >\n <div class="pointer-events-none">\n ${P.H.getIcon("general","upload","h-12 w-12 text-gray-400 mx-auto mb-4")}\n <p class="text-sm text-gray-600 mb-2">\n Drag and drop your image here, or\n </p>\n <button \n type="button"\n id="select-file-btn"\n class="pointer-events-auto inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"\n >\n Select a file\n </button>\n </div>\n </div>\n \n \x3c!-- Hidden file input --\x3e\n <input \n type="file" \n id="avatar-file-input" \n accept="image/jpeg,image/png,image/gif" \n class="hidden" \n />\n </div>\n `;this.modal=new we.Modal({title:"Update Profile Picture",content:t,size:"medium",closeButton:!0}),this.modal.open(),setTimeout((()=>this.attachEventListeners()),100)}attachEventListeners(){if(!this.modal)return;const e=document.querySelector(".modal-content");if(!e)return;this.fileInput=e.querySelector("#avatar-file-input"),this.fileInput&&this.fileInput.addEventListener("change",(e=>this.handleFileSelect(e)));const t=e.querySelector("#select-file-btn");t&&t.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation(),this.fileInput?.click()}));const n=e.querySelector("#drop-zone");n&&(n.addEventListener("click",(()=>this.fileInput?.click())),n.addEventListener("dragover",(e=>this.handleDragOver(e))),n.addEventListener("dragleave",(e=>this.handleDragLeave(e))),n.addEventListener("drop",(e=>this.handleDrop(e))));const o=e.querySelector("#remove-avatar-btn");o&&o.addEventListener("click",(e=>{e.preventDefault(),this.handleRemove()}))}handleFileSelect(e){const t=e.target,n=t.files?.[0];n&&this.validateAndUpload(n)}handleDragOver(e){if(e.preventDefault(),e.stopPropagation(),!this.isDragging){this.isDragging=!0;e.currentTarget.classList.add("border-primary-500","bg-primary-50")}}handleDragLeave(e){e.preventDefault(),e.stopPropagation();const t=e.relatedTarget,n=e.currentTarget;n.contains(t)||(this.isDragging=!1,n.classList.remove("border-primary-500","bg-primary-50"))}handleDrop(e){e.preventDefault(),e.stopPropagation(),this.isDragging=!1;e.currentTarget.classList.remove("border-primary-500","bg-primary-50");const t=e.dataTransfer?.files;t&&t.length>0&&this.validateAndUpload(t[0])}async validateAndUpload(e){if(!["image/jpeg","image/png","image/gif"].includes(e.type))return void te.Alert.error("Please select a JPG, PNG or GIF image");if(e.size>5242880)te.Alert.error("Image size must be less than 5MB");else{try{const t=await Ge.getImageDimensions(e);if(t.width<200||t.height<200)return void te.Alert.error("Image must be at least 200x200 pixels")}catch(e){console.error("Failed to check image dimensions:",e)}this.modal?.close(),this.options.onUpload?await this.options.onUpload(e):(0,Ee.c)("profile:avatar:upload",{file:e})}}async handleRemove(){if(this.isRemoving)return;if(await this.showRemoveConfirmation()){this.isRemoving=!0;try{this.modal?.close(),this.options.onRemove?await this.options.onRemove():(0,Ee.c)("profile:avatar:remove",{})}finally{this.isRemoving=!1}}}showRemoveConfirmation(){return new Promise((e=>{const t=new we.Modal({title:"Remove Profile Picture",content:`\n <div class="text-center">\n <div class="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100 mb-4">\n ${P.H.getIcon("general","exclamation","h-6 w-6 text-red-600")}\n </div>\n <p class="text-sm text-gray-600">\n Are you sure you want to remove your profile picture? Your initials will be displayed instead.\n </p>\n </div>\n `,size:"small",closeButton:!1,footer:'\n <div class="flex gap-2 justify-end">\n <button class="px-4 py-2 text-gray-600 hover:text-gray-800" onclick="this.closest(\'.modal\')?.remove(); document.body.style.overflow = \'\';">Cancel</button>\n <button class="px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700" id="confirm-remove-btn">Remove</button>\n </div>\n '});t.open(),setTimeout((()=>{const n=document.getElementById("confirm-remove-btn");n&&n.addEventListener("click",(()=>{t.close(),e(!0)}))}),100)}))}};class Ke{constructor(e={}){this.options={onCancel:null,...e},this.container=null,this.progressBar=null,this.progressText=null}show(e,t){this.hide(),this.container=document.createElement("div"),this.container.id="avatar-upload-progress",this.container.className="fixed bottom-4 right-4 bg-white rounded-lg shadow-2xl p-4 w-80 z-[9998] transform transition-all duration-300 translate-y-full",this.container.innerHTML=`\n <div class="flex items-center gap-3">\n <div class="relative flex-shrink-0">\n <img src="${t}" class="w-12 h-12 rounded-full object-cover" alt="Uploading avatar" />\n <div class="absolute inset-0 rounded-full border-2 border-primary-600 border-t-transparent animate-spin"></div>\n </div>\n <div class="flex-1">\n <div class="flex justify-between items-center mb-1">\n <p class="text-sm font-medium text-gray-900">Uploading avatar...</p>\n <button type="button" class="text-gray-400 hover:text-gray-600" id="cancel-upload">\n ${Y.Hj.render("x",{class:"w-4 h-4"})}\n </button>\n </div>\n <div class="relative">\n <div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">\n <div id="progress-bar" class="bg-gradient-to-r from-primary-500 to-primary-600 h-2 rounded-full transition-all duration-300 ease-out" style="width: 0%"></div>\n </div>\n <p id="progress-text" class="text-xs text-gray-500 mt-1">0% complete</p>\n </div>\n </div>\n </div>\n \n <div id="progress-stages" class="mt-3 space-y-1 text-xs">\n <div id="stage-optimize" class="flex items-center text-gray-500">\n ${Y.Hj.render("refresh-cw",{class:"w-3 h-3 mr-1 animate-spin"})}\n Optimizing image...\n </div>\n </div>\n `,document.body.appendChild(this.container),this.progressBar=this.container.querySelector("#progress-bar"),this.progressText=this.container.querySelector("#progress-text");const n=this.container.querySelector("#cancel-upload");n&&n.addEventListener("click",(()=>{this.hide(),this.options.onCancel&&this.options.onCancel()})),requestAnimationFrame((()=>{this.container&&this.container.classList.remove("translate-y-full")}))}updateProgress(e,t){if(!this.container)return;this.progressBar&&(this.progressBar.style.width=`${e}%`),this.progressText&&(this.progressText.textContent=`${e}% complete`);const n=this.container.querySelector("#progress-stages");if(n){const o={optimize:"Optimizing image...",upload:"Uploading to server...",process:"Processing image..."},i={optimize:Y.Hj.render("refresh-cw",{class:"w-3 h-3 mr-1 animate-spin"}),upload:Y.Hj.render("cloud-upload",{class:"w-3 h-3 mr-1 animate-pulse"}),process:Y.Hj.render("settings",{class:"w-3 h-3 mr-1 animate-spin"})};n.innerHTML=`\n <div class="flex items-center ${100===e?"text-green-600":"text-primary-600"}">\n ${i[t]}\n ${o[t]}\n </div>\n `}}showSuccess(){this.container&&(this.container.innerHTML=`\n <div class="flex items-center gap-3">\n <div class="flex-shrink-0">\n <div class="w-12 h-12 rounded-full bg-green-100 flex items-center justify-center">\n ${Y.Hj.render("check",{class:"w-6 h-6 text-green-600"})}\n </div>\n </div>\n <div class="flex-1">\n <p class="text-sm font-medium text-gray-900">Upload complete!</p>\n <p class="text-xs text-gray-500">Your profile picture has been updated</p>\n </div>\n </div>\n `,setTimeout((()=>this.hide()),3e3))}showError(e){this.container&&(this.container.innerHTML=`\n <div class="flex items-center gap-3">\n <div class="flex-shrink-0">\n <div class="w-12 h-12 rounded-full bg-red-100 flex items-center justify-center">\n <svg class="w-6 h-6 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />\n </svg>\n </div>\n </div>\n <div class="flex-1">\n <p class="text-sm font-medium text-gray-900">Upload failed</p>\n <p class="text-xs text-gray-500">${e}</p>\n </div>\n </div>\n `,setTimeout((()=>this.hide()),5e3))}hide(){this.container&&(this.container.classList.add("translate-y-full"),setTimeout((()=>{this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container),this.container=null,this.progressBar=null,this.progressText=null}),300))}}class je extends Le.${constructor(e,t={}){super(e,t),this._isChangingEmail=!1,this.api=t.api||new ze.q,this.store.setState({isLoading:!t.profileData,isEditMode:!1,originalData:null,isSaving:!1,error:null,profileData:t.profileData||null,data:t.profileData||null,isEmailEditMode:!1,originalEmail:null,enableChangeEmail:!0,companySupportEmail:null,enableSmsOptInField:!1,smsConsentText:null})}getDefaultOptions(){return{autoInit:!0,debug:!1}}async onInit(){this.store.subscribe(((e,t,n)=>{(n.includes("isEditMode")||n.includes("profileData")||n.includes("isEmailEditMode")||n.includes("enableChangeEmail")||n.includes("companySupportEmail")||n.includes("smsConsentText")||n.includes("enableSmsOptInField"))&&this.updateContent(),n.includes("isSaving")&&this.updateSaveButtonState(e.isSaving)})),this.setupGlobalEventHandlers(),this.loadDefaultBillingAddress(),this.loadConfigSettings(),this.setupResendVerificationListener()}async fetchData(){if(!this.store.getState().profileData&&this.api)try{const e=await this.api.getProfile();if(!e.success||!e.data)throw new Error("Failed to fetch profile data");{const t=e.data.profile;this.store.setState({profileData:t,data:t,isLoading:!1,error:null})}}catch(e){this.store.setState({isLoading:!1,error:e instanceof Error?e:new Error("Unknown error")})}}async render(){this.store.getState();this.container.innerHTML=`\n <div class="profile-component-container">\n <div class="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden">\n ${De.b.render({icon:De.b.icons.user,title:"Profile Information",subtitle:"Manage your personal details and contact information",actions:""})}\n\n <div class="profile-content-area">\n ${this.renderProfileContent()}\n </div>\n </div>\n </div>\n `,this.attachEventListeners(),this.attachDynamicListeners(),this.updateHeaderActions()}renderProfileContent(){const e=this.store.getState();if(e.isLoading)return this.renderLoadingState();if(e.error)return Be.render({title:"Failed to load profile",error:e.error.message,onRetry:()=>this.fetchData()});if(!e.profileData)return this.renderLoadingState();const t=e.profileData,n=this.calculateMemberYears(t.profileCreationDate),o=w.default.isCabotWealth(),i=`\n <form id="profile-form">\n <div class="space-y-6">\n <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">\n ${this.renderEmailField(t)}\n ${this.renderNameFields(t)}\n ${this.renderPhoneFields(t)}\n ${this.renderSMSOptInField(t)}\n ${this.renderAddressSection(t,o?"col-span-2":"")}\n ${o?"":this.renderMemberInfo(t,n)}\n </div>\n </div>\n </form>\n `,a=e.isEditMode?`\n <div class="flex justify-end space-x-3">\n ${Ie.$.cancel("Cancel",{id:"cancel-edit-btn"})}\n ${Ie.$.save("Save Changes",{id:"save-profile-btn",loading:e.isSaving})}\n </div>\n `:"";return`\n <div class="px-4 py-4 sm:px-6">\n ${i}\n </div>\n ${a?`\n <div class="px-4 py-3 sm:px-6 border-t border-gray-200">\n ${a}\n </div>\n `:""}\n `}renderLoadingState(){return`\n <div class="p-6">\n ${ke.k.render({text:"Loading profile information..."})}\n </div>\n `}updateContent(){const e=this.container.querySelector(".profile-content-area");e&&(e.innerHTML=this.renderProfileContent(),this.updateHeaderActions(),this.attachDynamicListeners())}updateHeaderActions(){const e=this.store.getState(),t=this.container.querySelector(".heimguard-component-header");if(t){const n=t.querySelector(".heimguard-header-actions");
1if(n){const t=e.isEditMode?"":`\n <button id="edit-profile-btn" class="inline-flex items-center px-4 py-2 text-white rounded-lg transition-all border border-white/25 text-sm font-medium shadow-lg" style="background-color: rgba(255, 255, 255, 0.1) !important; backdrop-filter: blur(8px) !important;">\n ${P.H.getIcon("general","edit","w-4 h-4 mr-2")}\n Edit Profile\n </button>\n <style>\n #edit-profile-btn {\n background-color: rgba(255, 255, 255, 0.1) !important;\n backdrop-filter: blur(8px) !important;\n }\n #edit-profile-btn:hover {\n background-color: rgba(255, 255, 255, 0.2) !important;\n }\n </style>\n `;n.innerHTML=t}}}attachEventListeners(){this.cleanup.addEventListener(this.container,"click",this.handleClick.bind(this)),this.attachDynamicListeners()}setupResendVerificationListener(){this.cleanup.addEventListener(document,"click",(e=>{const t=e.target.closest(je.RESEND_BUTTON_SELECTOR);t&&t instanceof HTMLButtonElement&&(e.preventDefault(),e.stopPropagation(),this.handleResendVerification(t))}))}handleClick(e){const t=e.target,n=t.closest("#edit-profile-btn"),o=t.closest("#cancel-edit-btn"),i=t.closest("#save-profile-btn"),a=t.closest('a[href="#addresses"]'),s=t.closest("#edit-email-btn"),r=t.closest("#cancel-email-edit-btn"),d=t.closest("#save-email-btn");n?this.toggleEditMode(!0):o?(this.restoreOriginalData(),this.toggleEditMode(!1)):i?(e.preventDefault(),e.stopPropagation(),this.saveProfile()):a?(e.preventDefault(),Ee.AC.emit("TAB_CHANGED",{section:"addresses"})):s?(e.preventDefault(),e.stopPropagation(),this.toggleEmailEditMode(!0)):r?(e.preventDefault(),e.stopPropagation(),this.toggleEmailEditMode(!1)):d&&(e.preventDefault(),e.stopPropagation(),this.handleEmailChange())}setupGlobalEventHandlers(){const e=(0,Ee.MR)("profile:edit:avatar",(()=>{const e=this.store.getState();new _e({profileData:e.profileData,onUpload:async e=>{await this.handleAvatarUpload(e)},onRemove:async()=>{await this.handleAvatarRemove()}}).show()})),t=(0,Ee.MR)("profile:avatar:upload",(async e=>{e&&e.file&&await this.handleAvatarUpload(e.file)})),n=(0,Ee.MR)("profile:avatar:remove",(async()=>{await this.handleAvatarRemove()}));this.cleanup.addCleanupTask((()=>{e(),t(),n()}))}attachDynamicListeners(){const e=this.container.querySelector("#profile-form");e&&this.cleanup.addEventListener(e,"submit",(e=>e.preventDefault()));this.container.querySelectorAll("input.intl-phone-field").forEach((async e=>{await Ue.I.initialize(e)}))}async toggleEditMode(e){const t=this.store.getState();e&&t.profileData&&this.store.setState({originalData:{firstName:t.profileData.firstName||"",lastName:t.profileData.lastName||"",mobileNumber:t.profileData.mobileNumber||"",otherPhone:t.profileData.alternatePhone||t.profileData.otherPhone||"",smsAgreementOptIn:t.profileData.smsAgreementOptIn||!1}}),this.store.setState({isEditMode:e,isSaving:!1})}updateSaveButtonState(e){const t=this.container.querySelector("#save-profile-btn");t&&(t.disabled=e,t.innerHTML=e?'\n <svg class="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">\n <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>\n <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>\n </svg>\n Saving...\n ':"Save Changes")}renderEmailField(e){const t=this.store.getState(),n=e.isEmailVerified||e.isVerified;return t.isEmailEditMode?`\n <div class="lg:col-span-2 bg-gray-50 rounded-lg p-4">\n <label class="text-sm font-medium text-gray-700 block mb-1">\n Email Address\n </label>\n <div class="space-y-3">\n <div class="flex items-center gap-3">\n ${P.H.getIcon("auth","email","w-4 h-4 text-gray-400")}\n <input\n type="email"\n id="new-email-input"\n name="newEmail"\n value="${e.email||""}"\n class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500"\n placeholder="Enter new email address"\
1n required\n />\n </div>\n <div class="flex items-center gap-2">\n <button\n type="button"\n id="cancel-email-edit-btn"\n class="inline-flex items-center px-3 py-1.5 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"\n >\n Cancel\n </button>\n <button\n type="button"\n id="save-email-btn"\n class="inline-flex items-center px-3 py-1.5 text-sm font-medium text-white bg-primary-600 border border-transparent rounded-md hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"\n >\n ${P.H.getIcon("ui","check","w-4 h-4 mr-1")}\n Save\n </button>\n </div>\n </div>\n </div>\n `:`\n <div class="lg:col-span-2 bg-gray-50 rounded-lg p-4">\n <label class="text-sm font-medium text-gray-700 block mb-1">\n Email Address\n </label>\n <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">\n <div class="flex items-center">\n ${P.H.getIcon("auth","email","w-4 h-4 mr-2 text-gray-400")}\n <p class="text-gray-900 font-medium">${e.email||""}</p>\n </div>\n <div class="flex items-center flex-wrap gap-2">\n ${t.enableChangeEmail?`\n <button\n type="button"\n id="edit-email-btn"\n class="inline-flex items-center px-3 py-1.5 text-xs font-medium rounded-md text-primary-700 bg-primary-100 hover:bg-primary-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition-colors"\n >\n ${P.H.getIcon("general","edit","w-3 h-3 mr-1")}\n Change Email\n </button>\n `:""}\n ${n?`\n <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">\n ${P.H.getIcon("status","success","w-3 h-3 mr-1")}\n Verified\n </span>\n `:`\n\n <button\n type='button'\n data-profile-completion-info>\n <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">\n ${P.H.getIcon("status","warning","w-3 h-3 mr-1")}\n Not Verified\n </span>\n </button>\n ${t.isEditMode?`\n <button\n type="button"\n data-action="resend-verification"\n class="inline-flex items-center px-3 py-1.5 text-xs font-medium rounded-md text-primary-700 bg-primary-100 hover:bg-primary-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition-colors"\n >\n ${P.H.getIcon("auth","email","w-3 h-3 mr-1")}\n Resend Verification\n </button>\n `:""}\n `}\n </div>\n </div>\n <div class="mt-1">\n <p class="text-xs text-gray-500">Primary account email</p>\n ${t.enableChangeEmail?"":`\n <p class="text-xs text-gray-600 mt-1">\n ${t.companySupportEmail?`\n To change your email address, please <a href="mailto:${t.companySupportEmail}" class="text-primary-600 hover:text-primary-700 underline">contact customer support</a>.\n `:"\n To change your email address, please contact customer support.\n "}\n </p>\n `}\n </div>\n </div>\n `}renderNameFields(e){if(this.store.getState().isEditMode){return $e.render({name:"firstName",label:"First Name",value:e.firstName||"",required:!0,containerClassName:"bg-white rounded-lg p-4 border border-gray-200 hover:border-gray-300 transition-colors"})+$e.render({name:"lastName",label:"Last Name",value:e.lastName||"",required:!0,containerClassName:"bg-white rounded-lg p-4 border border-gray-200 hover:border-gray-300 transition-colors"})}return`\n <div class="bg-white rounded-lg p-4 border border-gray-200">\n <label class="text-sm font-medium text-gray-700 block mb-1">First Name</label>\n <p class="text-gray-900 font-medium" data-field="firstName">${e.firstName||"Not provided"}</p>\n </div>\n <div class="bg-white rounded-lg p-4 border border-gray-200">\n <label class="text-sm font-medium text-gray-700 block mb-1">Last Name</label>\n <p class="text-gray-900 font-medium" data-field="lastName">${e.lastName||"Not provided"}</p>\n </div>\n `}renderPhoneFields(e){if(this.store.getState().isEditMode){return Ue.I.render({name:"mobileNumber",label:"Mobile Number",value:e.mobileNumber||"",defaultCountry:w.default.getDefaultCountry().toLowerCase()||"us",preferredCountries:["ca","us"],separateDialCode:!0,autoPlaceholder:"aggressive",hint:"optional",containerClassName:"bg-white rounded-lg p-4 border border-gray-200 hover:border-gray-300 transition-colors"})+Ue.I.render({name:"otherPhone",label:"Other Phone",value:e.alternatePhone||e.otherPhone||"",defaultCountry:w.default.getDefaultCountry().toLowerCase()||"us",preferredCountries:["ca","us"],separateDialCode:!0,autoPlaceholder:"aggressive",hint:"optional",containerClassName:"bg-white rounded-lg p-4 border border-gray-200 hover:border-gray-300 transition-colors"})}{const t=e.mobileNumber||"",n=e.alternatePhone||e.otherPhone||"";return`\n <div class="bg-white rounded-lg p-4 border border-gray-200">\n <label class="text-sm font-medium text-gray-700 block mb-1">Mobile Number</label>\n <p class="${t?"text-gray-900 font-medium":"text-gray-500 italic"}" data-field="mobileNumber">\n ${t||"Not provided"}\n </p>\n </div>\n <div class="bg-white rounded-lg p-4 border border-gray-200">\n <label class="text-sm font-medium text-gray-700 block mb-1">Other Phone</label>\n <p class="${n?"text-gray-900 font-medium":"text-gray-500 italic"}" data-field="otherPhone">\n ${n||"Not provided"}\n </p>\n </div>\n `}}renderSMSOptInField(e){if(!this.store.getState().enableSmsOptInField)return"";const t=this.store.getState(),n=e.smsAgreementOptIn||!1,o=t.smsConsentText||"By checking this box, you consent to receive text messages at the mobile number provided that may be sent via an automated system (only US and Canadian customers will receive messages at this time). Consent is not a condition of purchase. Text STOP to cancel at any time. Message & data rates may apply. By continuing, you agree to Cabot Wealth Network's Terms of Service and Privacy Policy.";return t.isEditMode?`\n <div class="lg:col-span-2 bg-white rounded-lg p-4 border border-gray-200 hover:border-gray-300 transition-colors">\n <div class="space-y-3">\n <label class="flex items-start cursor-pointer">\n <div class="flex items-center h-5">\n <input\n type="checkbox"\n name="smsAgreementOptIn"\n class="h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300 rounded"\n ${n?"checked":""}\n />\n </div>\n <div class="ml-3">
1\n <span class="text-sm font-medium text-gray-700 block mb-1">SMS Notifications</span>\n <p class="text-xs text-gray-600 leading-relaxed">\n ${o}\n </p>\n </div>\n </label>\n </div>\n </div>\n `:`\n <div class="lg:col-span-2 bg-white rounded-lg p-4 border border-gray-200">\n <label class="text-sm font-medium text-gray-700 block mb-1">SMS Notifications</label> \n <div class="flex items-center justify-between">\n <p class="${n?"text-gray-900 font-medium":"text-gray-500 italic"}">\n ${n?"Enabled":"Disabled"}\n </p>\n ${n?`\n <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">\n ${P.H.getIcon("status","success","w-3 h-3 mr-1")}\n Active\n </span>\n `:""}\n </div>\n ${n?'\n <p class="text-xs text-gray-500 mt-1">You will receive SMS notifications at your mobile number</p>\n ':""}\n </div>\n `}renderAddressSection(e,t){return`\n <div class="bg-white rounded-lg p-4 border border-gray-200 ${t}">\n <div class="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3">\n <div class="flex items-start">\n ${P.H.getIcon("general","location","w-4 h-4 mr-2 text-gray-400 mt-0.5")}\n <div class="flex-1">\n <label class="text-sm font-medium text-gray-700 block mb-1">Default Address</label>\n <div class="text-gray-900" data-field="defaultAddress" id="default-address-container">\n ${e.defaultAddress?`\n <p class="text-sm">${this.formatAddress(e.defaultAddress)}</p>\n `:'\n <p class="text-sm text-gray-500 italic">No default address set</p>\n '}\n </div>\n </div>\n </div>\n <a href="#addresses" class="text-primary-600 hover:text-primary-700 text-sm font-medium flex items-center sm:ml-4 whitespace-nowrap self-start sm:self-auto">\n Manage\n ${P.H.getIcon("ui","arrowRight","w-4 h-4 ml-1")}\n </a>\n </div>\n </div>\n `}renderMemberInfo(e,t){return`\n <div class="bg-gradient-to-br from-primary-50 to-secondary-50 rounded-lg p-4 border border-primary-200">\n <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">\n <div>\n <label class="text-sm font-medium text-gray-700 flex items-center mb-2">\n ${P.H.getIcon("general","calendar","w-4 h-4 mr-1 text-primary-600")}\n Member Since\n </label>\n <p class="text-gray-900 font-medium text-lg" data-field="profileCreationDate">\n ${e.profileCreationDate?(0,Fe.Yq)(e.profileCreationDate):"Not available"}\n </p>\n </div>\n <div class="text-center sm:text-right">\n <span class="inline-flex items-center px-4 py-2 text-sm font-medium bg-green-100 text-green-800 rounded-full">\n ${P.H.getIcon("general","badge","w-4 h-4 mr-1")}\n ${t}+ Years\n </span>\n <p class="text-xs text-gray-600 mt-1">Loyal Member</p>\n </div>\n </div>\n </div>\n `}extractFormData(){const e=this.container.querySelector("#profile-form");if(!e)return{};const t=new FormData(e),n=this.store.getState().profileData,o=e.querySelector('input[name="mobileNumber"]'),i=e.querySelector('input[name="otherPhone"]'),a=e.querySelector('input[name="smsAgreementOptIn"]'),s=o?Ue.I.getNumber(o):"",r=i?Ue.I.getNumber(i):"",d=!!a&&a.checked;return{firstName:t.get("firstName")||n?.firstName||"",lastName:t.get("lastName")||n?.lastName||"",mobileNumber:s||n?.mobileNumber||"",otherPhone:r||n?.otherPhone||n?.alternatePhone||"",smsAgreementOptIn:d}}restoreOriginalData(){const e=this.store.getState();if(!e.originalData)return;const t=this.container.querySelector("#profile-form");
1t&&Object.entries(e.originalData).forEach((([e,n])=>{const o=t.querySelector(`[name="${e}"]`);o&&(o.classList.contains("intl-phone-field")?Ue.I.setNumber(o,n):"checkbox"===o.type?o.checked=n:o.value=n)}))}async saveProfile(){if(this.store.getState().isSaving)return;this.store.setState({isSaving:!0});const e=this.extractFormData(),t=K(e,this.getValidationRules());if(!t.isValid){const e=Object.values(t.errors)[0];return te.Alert.error(e),void this.store.setState({isSaving:!1})}const n=this.container.querySelector("#profile-form");if(n){const e=n.querySelector('input[name="mobileNumber"]'),t=n.querySelector('input[name="otherPhone"]');if(e&&e.value&&!Ue.I.isValid(e))return te.Alert.error("Please enter a valid mobile phone number"),void this.store.setState({isSaving:!1});if(t&&t.value&&!Ue.I.isValid(t))return te.Alert.error("Please enter a valid other phone number"),void this.store.setState({isSaving:!1})}try{await this.api.updateProfile(e);const t=await this.api.getProfile();if(!t.success||!t.data)throw new Error("Failed to fetch updated profile data");{let e=null;if("profile"in t.data&&t.data.profile)e=t.data.profile;else if("email"in t.data)e=t.data;else{const n=t.data;n&&"object"==typeof n&&(n.id||n.userId||n.email)&&(e=n)}if(!e||!e.email)throw console.error("[ProfileInfo] Unable to find valid profile data in response:",t.data),new Error("Invalid profile data structure received from server");this.store.setState({profileData:e,data:e,isSaving:!1}),await this.toggleEditMode(!1),te.Alert.success("Profile updated successfully!"),Ee.ProfileEvents.emit("UPDATED",{data:e}),document.dispatchEvent(new CustomEvent("heimguard:profile:updated",{detail:{profileData:e},bubbles:!0}))}}catch(e){console.error("Failed to save profile:",e),te.Alert.error(e.message||"Failed to update profile"),this.store.setState({isSaving:!1})}}getValidationRules(){return{firstName:{required:!0,minLength:2,requiredMessage:"First name is required",minLengthMessage:"First name must be at least 2 characters"},lastName:{required:!0,minLength:2,requiredMessage:"Last name is required",minLengthMessage:"Last name must be at least 2 characters"}}}calculateMemberYears(e){if(!e)return 0;const t=new Date(e);if(isNaN(t.getTime()))return 0;const n=Math.floor(((new Date).getTime()-t.getTime())/315576e5);return Math.max(0,n)}formatAddress(e){if(!e)return"";const t=[];e.street1&&t.push(e.street1),e.street2&&t.push(e.street2);const n=[];return e.city&&n.push(e.city),(e.region||e.state)&&n.push(e.region||e.state),(e.postalCode||e.zip)&&n.push(e.postalCode||e.zip),n.length>0&&t.push(n.join(", ")),e.country&&"undefined"!==e.country&&t.push(this.getCountryName(e.country)),t.join(", ")}getCountryName(e){if(window.HeimGuard?.geoService){const t=window.HeimGuard.geoService.getAllCountries().find((t=>t.code===e));return t?t.name:e}return{US:"United States",CA:"Canada",GB:"United Kingdom",IE:"Ireland",AU:"Australia",NZ:"New Zealand",DE:"Germany",FR:"France",ES:"Spain",IT:"Italy",NL:"Netherlands",BE:"Belgium",CH:"Switzerland",AT:"Austria",SE:"Sweden",NO:"Norway",DK:"Denmark",FI:"Finland",PL:"Poland",PT:"Portugal",GR:"Greece",CZ:"Czech Republic",HU:"Hungary",RO:"Romania",BG:"Bulgaria",HR:"Croatia",SK:"Slovakia",SI:"Slovenia",LT:"Lithuania",LV:"Latvia",EE:"Estonia",CY:"Cyprus",LU:"Luxembourg",MT:"Malta"}[e]||e}async updateProfile(e){this.store.setState({profileData:e,data:e}),this.updateContent(),this.loadDefaultBillingAddress()}async refresh(){this.store.getState().profileData||(this.store.setState({isLoading:!0}),await this.fetchData()),this.loadDefaultBillingAddress()}async loadDefaultBillingAddress(){try{const e=await He.A.getAddresses();if(e&&e.addresses){let t=[];"object"!=typeof e.addresses||Array.isArray(e.addresses)?Array.isArray(e.addresses)&&(t=e.addresses):t=Object.values(e.addresses);const n=t.find((e=>e.isDefaultBilling));if(n){const e=this.container.querySelector("#default-address-container");e&&(e.innerHTML=`<p class="text-sm">${this.formatAddress(n)}</p>`)}}}catch(e){console.error("[ProfileInfo] Failed to load default billing address:",e)}}async loadConfigSettings(){try{const e=await v.initService.getInitData(),t=e.generalConfig?.enableChangeEmail??!0,n=e.generalConfig?.companySupportEmail||null,o=e.profileUIConfig?.enableSmsOptInField??!1,i=e.profileUIConfig?.smsOptInAgreementMessage||null;this.store.setState({enableChangeEmail:t,companySupportEmail:n,enableSmsOptInField:o,smsConsentText:i})}catch(e){console.error("[ProfileInfo] Failed to load config settings:",e)}}toggleEmailEditMode(e){const t=this.store.getState();e&&t.profileData?this.store.setState({isEmailEditMode:!0,originalEmail:t.profileData.email||null}):this.store.setState({isEmailEditMode:!1,originalEmail:null})}validateNewEmail(e){if(!e||!e.trim())return{isValid:!1,error:"Email address is required"};if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e))return{isValid:!1,error:"Please enter a valid email address"};const t=this.store.getState();return e===t.profileData?.email?{isValid:!1,error:"New email must be different from current email"}:{isValid:!0}}async showEmailChangeConfirmation(e,t){const n=`\n <div class="space-y-3">\n <p class="text-sm text-gray-600">\n You are about to change your email address. This will require verification of your new email.\n </p>\n <div class="bg-gray-50 rounded-lg p-3 space-y-2">\n <div>
1\n <span class="text-xs font-medium text-gray-600">Current Email:</span>\n <p class="text-sm text-gray-900 break-all">${e}</p>\n </div>\n <div>\n <span class="text-xs font-medium text-gray-600">New Email:</span>\n <p class="text-sm text-gray-900 font-medium break-all">${t}</p>\n </div>\n </div>\n </div>\n `;return we.Modal.confirm({title:"Confirm Email Change",message:n,confirmText:"Change Email",cancelText:"Cancel",confirmClass:"bg-primary-600 hover:bg-primary-700 text-white",cancelClass:"bg-gray-200 hover:bg-gray-300 text-gray-800"})}async handleEmailChange(){if(this._isChangingEmail)return;const e=this.store.getState();if(!e.profileData)return;const t=this.container.querySelector("#new-email-input");if(!t)return;const n=t.value.trim(),o=e.profileData.email||"",i=this.validateNewEmail(n);if(!i.isValid)return te.Alert.error(i.error||"Invalid email address"),void t.focus();this._isChangingEmail=!0;try{if(!await this.showEmailChangeConfirmation(o,n))return void(this._isChangingEmail=!1)}catch(e){throw this._isChangingEmail=!1,e}const a=this.container.querySelector("#save-email-btn");a&&(a.disabled=!0,a.innerHTML='\n <svg class="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">\n <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>\n <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>\n </svg>\n Processing...\n ');try{const e=await fetch(f.A.apiProfileEmailChangeInitiate,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({newEmail:n})});if(!e.ok){const t=await e.json().catch((()=>({message:"Failed to change email address"})));throw new Error(t.message||"Failed to change email address")}te.Alert.success("Email change request submitted! Please check your new email address to confirm the change."),this.toggleEmailEditMode(!1)}catch(e){console.error("[ProfileInfo] Email change error:",e),te.Alert.error(e.message||"Failed to change email address")}finally{this._isChangingEmail=!1,a&&(a.disabled=!1,a.innerHTML=`\n ${P.H.getIcon("ui","check","w-4 h-4 mr-1")}\n Save\n `)}}async handleResendVerification(e){if(e.hasAttribute("data-is-resending"))return;const t=e.innerHTML;e.setAttribute("data-is-resending","true"),e.disabled=!0,e.innerHTML=`\n ${P.H.getIcon("status","loading","w-3 h-3 mr-1 animate-spin")}\n Sending...\n `;try{const n=await fetch(f.A.apiResendVerificationUrl,{method:"GET",credentials:"include"});if(!n.ok){const e=await n.json();throw new Error(e.message||"Failed to send verification email")}te.Alert.success("Verification email sent! Please check your inbox."),e.innerHTML=`\n ${P.H.getIcon("status","success","w-3 h-3 mr-1")}\n Email Sent\n `,setTimeout((()=>{e.innerHTML=t,e.disabled=!1,e.removeAttribute("data-is-resending")}),3e3)}catch(n){console.error("[ProfileInfo] Failed to resend verification:",n),te.Alert.error(n.message||"Failed to send verification email"),e.innerHTML=t,e.disabled=!1,e.removeAttribute("data-is-resending")}}async handleAvatarRemove(){const e=this.container.querySelector("#remove-picture-btn"),t=e?.textContent;e&&(e.textContent="Removing...",e.disabled=!0);try{if((await this.api.deleteAvatar()).success){const e=this.store.getState();if(e.profileData){const t={...e.profileData,avatarUrl:null,avatarImgSrc:null,hasCustomAvatar:!1};this.store.setState({profileData:t,data:t})}te.Alert.success("Profile picture removed successfully"),Ee.ProfileEvents.emit("UPDATED",{data:this.store.getState().profileData})}}catch(e){console.error("Avatar removal error:",e),te.Alert.error(e.message||"Failed to remove profile picture")}finally{e&&t&&(e.textContent=t,e.disabled=!1)}}async handleAvatarUpload(e){const t=new Ke({onCancel:()=>{te.Alert.info("Upload cancelled")}}),n=URL.createObjectURL(e);t.show(e,n);try{t.updateProgress(10,"optimize");let n=e;try{await Ge.calculateAverageBrightness(e);e.size>512e3&&(n=await Ge.optimizeImage(e,500))}catch(e){console.warn("Image optimization failed:",e)}t.updateProgress(30,"upload");const o=setInterval((()=>{const e=document.querySelector("#progress-bar"),n=parseInt(e?.style.width||"30");n<90&&t.updateProgress(n+10,"upload")}),200),i=await this.api.uploadAvatar({file:n});clearInterval(o),t.updateProgress(95,"process");let a=null;if(i.success&&i.data?.avatarUrl&&(a=i.data.avatarUrl),a){const e=this.store.getState();if(e.profileData){const t={...e.profileData,avatarUrl:a,avatarImgSrc:a,hasCustomAvatar:!0};this.store.setState({profileData:t,data:t})}t.updateProgress(100,"process"),t.showSuccess(),te.Alert.success("Profile picture updated successfully"),Ee.ProfileEvents.emit("UPDATED",{data:this.store.getState().profileData})}else{if(!i.success){const e=i.message||("string"==typeof i.error?i.error:i.error?.message)||"Upload failed";throw new Error(e)}try{const e=await this.api.getProfile();if(e.success&&e.data?.profile?.avatarUrl){const n=e.data.profile.avatarUrl,o=this.store.getState();if(o.profileData){const e={...o.profileData,avatarUrl:n,avatarImgSrc:n,hasCustomAvatar:!0};this.store.setState({profileData:e,data:e})}t.showSuccess(),window.location.reload()}else t.showSuccess(),te.Alert.success("Profile picture uploaded. Please refresh the page to see changes.")}catch(e){console.error("Failed to fetch updated profile:",e),t.showSuccess(),te.Alert.success("Profile picture uploaded. Please refresh the page to see changes.")}}}catch(e){console.error("Avatar upload error:",e),te.Alert.error(e instanceof Error?e.message:"Failed to upload profile picture"),t.showError(e.message||"Failed to upload profile picture")}finally{URL.revokeObjectURL(n);const e=this.container.querySelector("#avatar-file-input");e&&(e.value="")}}async onDestroy(){this.container.querySelectorAll("input.intl-phone-field").forEach((e=>{Ue.I.destroy(e)})),await super.onDestroy()}}je.RESEND_BUTTON_SELECTOR='[data-action="resend-verification"]';var Ve=class{constructor(e,t={}){this.impl=new je(e,t)}async render(){return this.impl.render()}cleanup(){this.impl.destroy()}async updateProfile(e){return this.impl.updateProfile(e)}async refresh(){return this.impl.refresh()}};class qe extends Le.${constructor(e,t={}){super(e,t),this.isVerifyingEmail=!1,this.api=t.api||new ze.q,this.authApi=t.authApi||new O,this.formId=`security-form-${Date.now()}`}getDefaultOptions(){return{autoInit:!0,debug:!1}}getInitialState(){const e=this.options;return{isLoading:!e.profileData,profileData:e.profileData||null,securityInfo:null,isChangingPassword:!1,isSendingReset:!1,error:null,passwordRequirements:null,data:null}}async onInit(){this.subscribe(((e,t,n)=>{(n.includes("isChangingPassword")||n.includes("profileData"))&&this.updateContent()}));
1this.getState().profileData||await this.loadProfileData(),await this.loadPasswordRequirements(),this.setupProfileUpdateListener(),this.render()}async loadProfileData(){try{this.setState({isLoading:!0});const e=await this.api.getProfile();console.log("[SecuritySettings] Profile API response:",e),e.success&&e.data?.profile&&(console.log("[SecuritySettings] Profile data from API:",e.data.profile),console.log("[SecuritySettings] Profile data keys:",Object.keys(e.data.profile)),console.log("[SecuritySettings] Email verified from API:",e.data.profile.isEmailVerified),console.log("[SecuritySettings] Checking other possible field names:"),console.log(" - emailVerified:",e.data.profile.emailVerified),console.log(" - isVerified:",e.data.profile.isVerified),console.log(" - verified:",e.data.profile.verified),this.setState({profileData:e.data.profile,isLoading:!1}))}catch(e){console.error("Failed to load profile data:",e),this.setState({error:new Error("Failed to load profile data"),isLoading:!1})}}async loadPasswordRequirements(){try{const e=await w.default.load(),t=V.getRequirements(e);this.setState({passwordRequirements:t})}catch(e){console.error("Failed to load password requirements:",e)}}async render(){await this.loadProfileData();const{isLoading:e,error:t,profileData:n}=this.getState();console.log("[SecuritySettings] Rendering with profile data:",n),console.log("[SecuritySettings] Email verified status:",n?.isEmailVerified),this.container.innerHTML=`\n <div class="security-component-container">\n <div class="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden">\n ${De.b.render({icon:De.b.icons.shield,title:"Security Settings",subtitle:"Manage your account security and password settings",actions:""})}\n\n \x3c!-- Content Area --\x3e\n <div class="security-content-area">\n ${this.renderContent()}\n </div>\n </div>\n </div>\n `,this.attachEventHandlers()}renderContent(){const{isLoading:e,error:t,profileData:n}=this.getState();return e?ke.k.render({text:"Loading security settings..."}):t?Be.render({title:"Unable to Load Security Settings",message:t instanceof Error?t.message:String(t),onRetry:()=>this.loadProfileData()}):n?`\n <div class="px-4 py-6 sm:px-6">\n <div class="space-y-6">\n \x3c!-- Password Management Section --\x3e\n ${this.renderPasswordSection()}\n\n \x3c!-- Account Security Status --\x3e\n ${this.renderSecurityStatus()}\n </div>\n </div>\n `:ke.k.render({text:"Loading security settings..."})}updateContent(){const e=this.container.querySelector(".security-content-area");e&&(e.innerHTML=this.renderContent(),this.attachEventHandlers())}renderPasswordSection(){const{profileData:e,isChangingPassword:t}=this.getState();return t?this.renderChangePasswordForm():Oe.Z.render({title:"Password",content:`\n <div class="space-y-4">\n <div class="text-sm text-gray-600">\n <p>Keep your account secure by using a strong, unique password.</p>\n </div>\n\n <div class="flex flex-col sm:flex-row gap-3">\n <button\n id="change-password-btn"\n class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"\n >\n ${P.H.render("edit",{class:"w-4 h-4 mr-2"})}\n Change Password\n </button>\n\n <button\n id="reset-password-btn"\n class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"\n >\n ${P.H.render("mail",{class:"w-4 h-4 mr-2"})}\n Reset via Email\n </button>\n </div>\n\n ${e?.email?`\n <div class="mt-4 p-3 bg-gray-50 rounded-lg">\n <p class="text-sm text-gray-600">\n Password reset email will be sent to: <strong>${e.email}</strong>\n </p>\n </div>\n `:""}\n </div>\n `})}renderChangePasswordForm(){const{passwordRequirements:e}=this.getState(),t=V.generateTips(e||{});return Oe.Z.render({title:"Change Password",content:`\n <form id="${this.formId}" class="space-y-4">\n <div id="password-alert"></div>\n\n ${U.render({id:`${this.formId}-current`,name:"currentPassword",label:"Current Password",placeholder:"Enter your current password",required:!0,showToggle:!0,icon:P.H.auth.password(),autocomplete:"current-password"})}\n\n ${U.render({id:`${this.formId}-new`,name:"newPassword",label:"New Password",placeholder:"Enter your new password",required:!0,showToggle:!0,showStrength:!0,icon:P.H.auth.password(),autocomplete:"new-password"})}\n\n \x3c!-- Password Requirements --\x3e\n ${t&&t.length>0?`\n <div class="bg-gray-50 rounded-lg p-4">\n <h4 class="text-sm font-medium text-gray-700 mb-2">Password Requirements:</h4>\n <ul class="space-y-1">\n ${t.map((e=>`\n <li class="flex items-start text-sm text-gray-600">\n ${P.H.render("check-circle",{class:"w-4 h-4 text-gray-400 mr-2 mt-0.5 flex-shrink-0"})}\n ${e}\n </li>\n `)).join("")}\n </ul>\n </div>\n `:""}\n\n ${U.render({id:`${this.formId}-confirm`,name:"confirmPassword",label:"Confirm New Password",placeholder:"Confirm your new password",required:!0,showToggle:!0,icon:P.H.auth.password(),autocomplete:"new-password"})}\n\n <div class="flex justify-end space-x-3 pt-4">\n <button\n type="button"\n id="cancel-change-btn"\n class="px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"\n >\n Cancel\n </button>\n <button\n type="submit"\n id="${this.formId}-submit"\n class="px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"\n >\n Update Password\n </button>\n </div>\n </form>\n `})}renderSecurityStatus(){const{profileData:e}=this.getState();
1console.log("[SecuritySettings] renderSecurityStatus - profileData:",e),console.log("[SecuritySettings] renderSecurityStatus - isEmailVerified:",e?.isEmailVerified);const t=e?.isEmailVerified||e?.isVerified;return console.log("[SecuritySettings] renderSecurityStatus - computed isVerified:",t),Oe.Z.render({title:"Account Security Status",content:`\n <div class="space-y-3">\n \x3c!-- Email Verification Status --\x3e\n <div class="flex items-center justify-between py-2">\n <div class="flex items-center">\n ${t?P.H.render("check-circle",{class:"w-5 h-5 text-green-500 mr-3"}):P.H.render("x-circle",{class:"w-5 h-5 text-red-500 mr-3"})}\n <span class="text-sm font-medium text-gray-900">Email Verified</span>\n </div>\n ${t?"":'\n <button \n id="verify-email-btn"\n class="text-sm text-primary-600 hover:text-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition-colors"\n >\n Verify Email\n </button>\n '}\n </div>\n </div>\n `})}attachEventHandlers(){const e=this.container.querySelector("#change-password-btn");e&&e.addEventListener("click",(()=>{this.setState({isChangingPassword:!0})}));const t=this.container.querySelector("#reset-password-btn");t&&t.addEventListener("click",(()=>{this.handleResetPassword()}));const n=this.container.querySelector("#cancel-change-btn");n&&n.addEventListener("click",(()=>{this.setState({isChangingPassword:!1})}));const o=this.container.querySelector(`#${this.formId}`);o&&(this.setupPasswordValidation(o),o.addEventListener("submit",(e=>{e.preventDefault(),this.handleChangePassword(o)}))),this.setupPasswordToggles();const i=this.container.querySelector("#verify-email-btn");i&&i.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation(),this.handleVerifyEmail()}))}setupPasswordValidation(e){const{passwordRequirements:t}=this.getState(),n=e.querySelector(`#${this.formId}-new`);n&&n.addEventListener("input",(()=>{const o=n.value,i=V.validate(o,t||{}),a=e.querySelector(`#${this.formId}-new-strength`);if(a&&o){a.classList.remove("hidden");const e=a.querySelector(".strength-bar"),t=a.querySelector(".strength-text");if(e&&t){e.style.width=`${i.strength.percentage}%`;const n={red:{bg:"bg-red-500",text:"text-red-600"},orange:{bg:"bg-orange-500",text:"text-orange-600"},yellow:{bg:"bg-yellow-500",text:"text-yellow-600"},green:{bg:"bg-green-500",text:"text-green-600"},emerald:{bg:"bg-green-600",text:"text-green-700"}},o=n[i.strength.color]||n.green;e.className=`strength-bar h-1.5 rounded-full transition-all duration-300 ${o.bg}`,t.textContent=i.strength.level,t.className=`text-xs strength-text ${o.text}`}}else a&&!o&&a.classList.add("hidden");const s=e.querySelector(`#${this.formId}-confirm`);s&&s.value&&this.validatePasswordMatch(e)}));const o=e.querySelector(`#${this.formId}-confirm`);o&&o.addEventListener("input",(()=>{this.validatePasswordMatch(e)}))}validatePasswordMatch(e){const t=e.querySelector(`#${this.formId}-new`)?.value||"",n=e.querySelector(`#${this.formId}-confirm`)?.value||"",o=e.querySelector(`#${this.formId}-confirm`)?.closest(".form-field");if(!o)return;const i=V.validateMatch(t,n);!i.valid&&n?this.showFieldError(o,i.error||"Passwords do not match"):this.clearFieldError(o)}setupPasswordToggles(){this.container.querySelectorAll(".toggle-password").forEach((e=>{e.addEventListener("click",(()=>{const t=e.getAttribute("data-target");if(!t)return;const n=document.getElementById(t);if(!n)return;const o=e.querySelector(".show-password"),i=e.querySelector(".hide-password");"password"===n.type?(n.type="text",o?.classList.add("hidden"),i?.classList.remove("hidden")):(n.type="password",o?.classList.remove("hidden"),i?.classList.add("hidden"))}))}))}async handleChangePassword(e){const t=e.querySelector(`#${this.formId}-submit`),n=e.querySelector("#password-alert");n&&(n.innerHTML="");const o=new FormData(e),i={currentPassword:o.get("currentPassword"),newPassword:o.get("newPassword"),confirmPassword:o.get("confirmPassword")},a=this.validateChangePassword(i);if(!a.isValid)return void this.showErrors(a.errors);const s=F.A.setSubmitting(t.id,"Updating password...");try{(await this.authApi.changePassword({currentPassword:i.currentPassword,newPassword:i.newPassword})).ok&&(n&&(n.innerHTML=te.Alert.render({message:"Password updated successfully!",variant:"success"})),e.reset(),setTimeout((()=>{this.setState({isChangingPassword:!1})}),2e3))}catch(e){if(console.error("Failed to change password:",e),n){const t=e.message||"Failed to update password. Please try again.";n.innerHTML=te.Alert.render({message:t,variant:"error"})}}
1finally{s?.restore()}}async handleResetPassword(){const{profileData:e}=this.getState();if(!e?.email)return void console.error("No email address available");if(!await we.Modal.confirm({title:"Reset Password via Email",message:`\n <p class="text-gray-600 mb-4">\n We'll send a password reset link to:\n </p>\n <p class="font-medium text-gray-900 mb-4">\n ${e.email}\n </p>\n <p class="text-sm text-gray-600">\n You'll receive an email with instructions to create a new password.\n </p>\n `,confirmText:"Send Reset Email",cancelText:"Cancel"}))return;const t=new we.Modal({title:"Sending Reset Email",content:`\n <div class="text-center py-8">\n <div class="animate-spin h-12 w-12 text-primary-600 mx-auto mb-4">\n ${P.H.render("loader")}\n </div>\n <p class="text-gray-600">Please wait...</p>\n </div>\n `,size:"small",closeButton:!1,closeOnOverlay:!1,closeOnEscape:!1});t.open();try{const n=await this.authApi.resetPassword({email:e.email});t.close(),n.ok&&await we.Modal.alert({title:"Reset Email Sent",message:`\n <div class="text-center">\n <div class="mx-auto w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mb-4">\n <svg class="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>\n </svg>\n </div>\n <p class="text-gray-600 mb-2">\n Password reset email sent to:\n </p>\n <p class="font-medium text-gray-900 mb-4">\n ${e.email}\n </p>\n <p class="text-sm text-gray-600">\n Please check your email and follow the instructions to reset your password.\n </p>\n </div>\n `,buttonText:"OK",buttonClass:"bg-primary-600 hover:bg-primary-700 text-white"})}catch(e){t.close(),await we.Modal.alert({title:"Error",message:e.message||"Failed to send reset email. Please try again."})}}async handleVerifyEmail(){if(this.isVerifyingEmail)return void console.log("[SecuritySettings] Verify email already in progress");const e=this.container.querySelector("#verify-email-btn");if(!e)return;this.isVerifyingEmail=!0;const t=e.innerHTML;e.disabled=!0,e.innerHTML=`\n ${P.H.render("loader",{class:"w-3 h-3 mr-1 animate-spin"})}\n Sending...\n `;try{console.log("[SecuritySettings] Calling resend verification API");const n=await fetch(f.A.apiResendVerificationUrl,{method:"GET",credentials:"include"});if(!n.ok){const e=await n.json();throw new Error(e.message||"Failed to send verification email")}console.log("[SecuritySettings] Verification email sent successfully"),te.Alert.success("Verification email sent! Please check your inbox."),e.innerHTML=`\n ${P.H.render("check",{class:"w-3 h-3 mr-1"})}\n Email Sent\n `,setTimeout((()=>{e.innerHTML=t,e.disabled=!1,this.isVerifyingEmail=!1}),3e3)}catch(n){console.error("[SecuritySettings] Failed to resend verification:",n),te.Alert.error(n.message||"Failed to send verification email"),e.innerHTML=t,e.disabled=!1,this.isVerifyingEmail=!1}}validateChangePassword(e){const t={},{passwordRequirements:n}=this.getState();if(e.currentPassword||(t.currentPassword="Current password is required"),e.newPassword){const o=V.validate(e.newPassword,n||{});o.valid||(t.newPassword=V.generateErrorMessage(o.errors))}else t.newPassword="New password is required";if(e.confirmPassword){const n=V.validateMatch(e.newPassword,e.confirmPassword);n.valid||(t.confirmPassword=n.error||"Passwords do not match")}else t.confirmPassword="Please confirm your password";return e.currentPassword&&e.newPassword&&e.currentPassword===e.newPassword&&(t.newPassword="New password must be different from current password"),{isValid:0===Object.keys(t).length,errors:t}}showErrors(e){Object.entries(e).forEach((([e,t])=>{const n=this.container.querySelector(`[name="${e}"]`);if(n){const e=n.closest(".form-field");
1e&&this.showFieldError(e,t)}}))}showFieldError(e,t){const n=e.querySelector(".flex");n&&(n.classList.remove("border-gray-300","focus-within:border-primary-500"),n.classList.add("border-red-500","focus-within:border-red-500"));const o=e.querySelector(".field-error");o&&o.remove();const i=document.createElement("div");i.className="field-error mt-1 text-sm text-red-600",i.textContent=t,e.appendChild(i)}clearFieldError(e){const t=e.querySelector(".flex");t&&(t.classList.remove("border-red-500","focus-within:border-red-500"),t.classList.add("border-gray-300","focus-within:border-primary-500"));const n=e.querySelector(".field-error");n&&n.remove()}setupProfileUpdateListener(){Ee.ProfileEvents.on("UPDATED",(({data:e})=>{console.log("[SecuritySettings] Received profile update event:",e),console.log("[SecuritySettings] Current profile ID:",this.getState().profileData?.id),e&&e.id===this.getState().profileData?.id&&(console.log("[SecuritySettings] Updating profile data from event"),this.setState({profileData:e}),this.updateContent())}))}async onDestroy(){}}var We=qe,Ze=n(4047),Ye=n(4849),Je=n(3593),Qe=n(9632),Xe=n(8215);var et=new class{constructor(){this.activeModal=null,this.manager=Ye.default,this.config=Ze.A}async openAddModal(){if(this.activeModal)console.warn("Modal already open");else{(0,Je.id)(Je.i$.ADD_ADDRESS_CLICKED);try{await this.manager.loadAddresses();const e=0===this.manager.getAddresses().length,t=new Qe.W({isFirstAddress:e,hideAddressType:!0,forceBillingOnly:!0,showDefaults:!0,showAccountAddress:!0,onSave:async e=>{try{const t={firstName:e.firstName,lastName:e.lastName,street1:e.street1,street2:e.street2,city:e.city,region:e.region,postalCode:e.postalCode,country:e.country,phone:e.phone,mobileNumber:e.mobileNumber,otherPhone:e.otherPhone,smsAgreementOptIn:e.smsAgreementOptIn,isShipping:e.isShipping,isBilling:e.isBilling,isDefaultShipping:e.isDefaultShipping,isDefaultBilling:e.isDefaultBilling,isAccount:e.isAccount},n=await this.manager.addAddress(t);if(e.isDefaultBilling)try{const t=await ze._.getProfile();if(t.success&&t.data?.profile){const n=t.data.profile,o={};if(!n.firstName&&!n.lastName&&e.firstName&&e.lastName&&(o.firstName=e.firstName,o.lastName=e.lastName),e.mobileNumber&&(o.mobileNumber=e.mobileNumber),e.otherPhone&&(o.otherPhone=e.otherPhone),void 0!==e.smsAgreementOptIn&&(o.smsAgreementOptIn=e.smsAgreementOptIn),Object.keys(o).length>0){const e=await ze._.updateProfile(o);if(console.log("[AddressModalHandler] Updated profile with contact info from default billing address"),e.success&&e.data){const t={...n,...e.data,...o};Xe.nU.emit("UPDATED",{data:t})}}}}catch(e){console.error("[AddressModalHandler] Failed to update profile with names:",e)}(0,Je.id)(Je.i$.ADDRESS_MODAL_SAVED,{address:n,isNew:!0}),te.Alert.success(this.config.getMessage("success","add"))}catch(e){throw console.error("Failed to add address:",e),e}},onCancel:()=>{this.closeModal()}});t.render(),this.activeModal=t,(0,Je.id)(Je.i$.ADDRESS_MODAL_OPENED,{mode:"add"})}catch(e){throw console.error("Failed to open add modal:",e),e}}}async openEditModal(e){if(this.activeModal)return void console.warn("Modal already open");await this.manager.loadAddresses();const t=this.manager.getAddressById(e);if(!t)return console.error("Address not found:",e),void console.error("Available addresses:",this.manager.getAddresses());(0,Je.id)(Je.i$.EDIT_ADDRESS_CLICKED,{addressId:e});try{let n,o,i;try{const e=await ze._.getProfile();if(e.success&&e.data?.profile){const t=e.data.profile;n=t.mobileNumber,o=t.otherPhone,i=t.smsAgreementOptIn}}catch(e){console.error("[AddressModalHandler] Failed to load profile data:",e)}const a={firstName:t.firstName,lastName:t.lastName,street1:t.street1,street2:t.street2,city:t.city,region:t.region,postalCode:t.postalCode,country:t.country,phone:t.phone,mobileNumber:t.mobileNumber||n,otherPhone:t.otherPhone||o,smsAgreementOptIn:void 0!==t.smsAgreementOptIn?t.smsAgreementOptIn:i,isShipping:void 0===t.isShipping||t.isShipping,isBilling:void 0===t.isBilling||t.isBilling,isDefaultShipping:t.isDefaultShipping,isDefaultBilling:t.isDefaultBilling,isAccount:t.isAccount},s=new Qe.W({address:a,hideAddressType:!0,forceBillingOnly:!0,showDefaults:!0,showAccountAddress:!0,onSave:async t=>{try{const n={firstName:t.firstName,lastName:t.lastName,street1:t.street1,street2:t.street2,city:t.city,region:t.region,postalCode:t.postalCode,country:t.country,phone:t.phone,mobileNumber:t.mobileNumber,otherPhone:t.otherPhone,smsAgreementOptIn:t.smsAgreementOptIn,isShipping:t.isShipping,isBilling:t.isBilling,isDefaultShipping:t.isDefaultShipping,isDefaultBilling:t.isDefaultBilling,isAccount:t.isAccount},o=await this.manager.updateAddress(e,n);if(t.isDefaultBilling)try{const e=await ze._.getProfile();if(e.success&&e.data?.profile){const n=e.data.profile,o={};if(!n.firstName&&!n.lastName&&t.firstName&&t.lastName&&(o.firstName=t.firstName,o.lastName=t.lastName),t.mobileNumber&&(o.mobileNumber=t.mobileNumber),t.otherPhone&&(
1o.otherPhone=t.otherPhone),void 0!==t.smsAgreementOptIn&&(o.smsAgreementOptIn=t.smsAgreementOptIn),Object.keys(o).length>0){const e=await ze._.updateProfile(o);if(console.log("[AddressModalHandler] Updated profile with contact info from default billing address"),e.success&&e.data){const t={...n,...e.data,...o};Xe.nU.emit("UPDATED",{data:t})}}}}catch(e){console.error("[AddressModalHandler] Failed to update profile with contact info:",e)}(0,Je.id)(Je.i$.ADDRESS_MODAL_SAVED,{address:o,isNew:!1}),te.Alert.success(this.config.getMessage("success","update"))}catch(e){throw console.error("Failed to update address:",e),e}},onCancel:()=>{this.closeModal()}});s.render(),this.activeModal=s,(0,Je.id)(Je.i$.ADDRESS_MODAL_OPENED,{mode:"edit",addressId:e})}catch(e){throw console.error("Failed to open edit modal:",e),e}}closeModal(){this.activeModal&&(this.activeModal instanceof Qe.W?"close"in this.activeModal&&"function"==typeof this.activeModal.close&&this.activeModal.close():this.activeModal instanceof we.Modal&&this.activeModal.close(),this.activeModal=null,(0,Je.id)(Je.i$.ADDRESS_MODAL_CLOSED))}async confirmDelete(e){await this.manager.loadAddresses();const t=this.manager.getAddressById(e);if(!t)return console.error("Address not found for delete:",e),void console.error("Available addresses:",this.manager.getAddresses());const n=`\n <div class="-mt-4 -mx-2">\n <div class="flex items-center justify-center w-12 h-12 mx-auto bg-red-100 rounded-full mb-3">\n <svg class="w-6 h-6 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />\n </svg>\n </div>\n \n <h3 class="text-lg font-medium text-gray-900 text-center mb-2">Delete Address</h3>\n <p class="text-sm text-gray-600 text-center mb-4">${t.isDefaultShipping||t.isDefaultBilling?this.config.getMessage("confirm","deleteDefault"):this.config.getMessage("confirm","delete")}</p>\n \n <div class="bg-gray-50 rounded-lg p-3 mb-4">\n <div class="text-sm text-gray-700">\n <p class="font-medium">${t.firstName} ${t.lastName}</p>\n <p class="text-gray-600">${t.street1}</p>\n ${t.street2?`<p class="text-gray-600">${t.street2}</p>`:""}\n <p class="text-gray-600">${t.city}, ${t.region} ${t.postalCode}</p>\n </div>\n </div>\n \n <div class="flex gap-3">\n <button id="cancel-delete-btn" class="flex-1 px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 transition-colors font-medium">\n Cancel\n </button>\n <button id="confirm-delete-btn" class="flex-1 px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors font-medium">\n Delete Address\n </button>\n </div>\n </div>\n `,o=new we.Modal({content:n,size:"small",title:"",closeButton:!1,onClose:()=>{this.activeModal=null}});o.open(),this.activeModal=o;const i=document.getElementById("cancel-delete-btn"),a=document.getElementById("confirm-delete-btn");i&&i.addEventListener("click",(()=>{o.close(),this.activeModal=null})),a&&a.addEventListener("click",(async()=>{try{a.disabled=!0,a.innerHTML='\n <svg class="animate-spin h-4 w-4 mx-auto" fill="none" viewBox="0 0 24 24">\n <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>\n <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>\n </svg>\n ',await this.manager.deleteAddress(e),o.close(),this.activeModal=null,te.Alert.success(this.config.getMessage("success","delete"))}catch(e){console.error("Failed to delete address:",e),te.Alert.error("Failed to delete address. Please try again."),a.disabled=!1,a.innerHTML="Delete Address"}}))}},tt=n(7876);
1class nt extends tt.A{constructor(e,t={}){super(e,t),this.manager=Ye.default,this.modalHandler=et,this.config=Ze.A,this.eventListenersAttached=!1,this.recentlySavedAddressId=null,this.highlightTimeout=null}getDefaultOptions(){return{autoInit:!0,debug:!1}}getInitialState(){return{isLoading:!0,error:null,data:null,profileData:this.options.profileData,addresses:[]}}async onInit(){this.store.subscribe(((e,t,n)=>{n.includes("addresses")&&!e.isLoading&&this.updateContent()})),this.setupAddressEventListeners()}getComponentClassName(){return"addresses"}getComponentName(){return"addresses"}getHeaderConfig(){return{icon:De.b.icons.address,title:"Addresses",subtitle:"Manage your billing addresses",actions:()=>this.renderHeaderActions()}}getLoadingMessage(){return this.config.getMessage("loading")||"Loading addresses..."}async loadData(){const e=await this.manager.loadAddresses(),{ProfileEvents:t}=await Promise.resolve().then(n.bind(n,8354));return t.emit("STATS_UPDATED",{stats:{addressCount:e.length}}),{addresses:e}}async fetchData(){return{addresses:(await this.loadData()).addresses}}renderMainContent(){const e=this.getState();if(!e.data||!e.data.addresses||0===e.data.addresses.length)return"";return"\n <style>\n .address-highlight {\n animation: highlightPulse 2s ease-in-out;\n box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.2);\n border-color: rgb(34, 197, 94) !important;\n }\n \n @keyframes highlightPulse {\n 0% {\n box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.7);\n transform: scale(1);\n }\n 50% {\n box-shadow: 0 0 0 10px rgba(34, 197, 94, 0);\n transform: scale(1.02);\n }\n 100% {\n box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.2);\n transform: scale(1);\n }\n }\n \n .address-highlight .animate-bounce {\n animation: bounce 1s infinite;\n }\n </style>\n "+this.renderAddressList()}isEmptyState(e){return!e||!e.addresses||0===e.addresses.length}getEmptyStateConfig(){return{icon:'<svg class="w-16 h-16 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />\n </svg>',title:this.config.getMessage("empty","title"),message:this.config.getMessage("empty","message"),action:'\n <button id="add-first-address-btn" class="inline-flex items-center px-6 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-all font-medium shadow-md hover:shadow-lg transform hover:-translate-y-0.5">\n <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />\n </svg>\n Add Your First Address\n </button>\n '}}renderHeaderActions(){return`\n <button id="add-address-btn" class="inline-flex items-center px-4 py-2 bg-white/20 backdrop-blur text-white rounded-lg hover:bg-white/30 transition-all border border-white/30 text-sm font-medium">\n ${P.H.getIcon("ui","add","w-4 h-4 mr-2")}\n Add Address\n </button>\n `}renderAddressList(){const{defaultAddresses:e,regularAddresses:t}=this.categorizeAddresses();return`\n <div class="p-6">\n ${e.length>0?`\n <div class="mb-8">\n <h3 class="text-sm font-semibold text-gray-700 flex items-center mb-4">\n ${P.H.render("check-circle",{class:"w-5 h-5 mr-2 text-primary-600"})}\n Default Addresses\n </h3>\n <div class="grid gap-4 ${n=e.length,1===n?"lg:grid-cols-1":2===n?"lg:grid-cols-2":"lg:grid-cols-3"}">\n ${e.map((e=>this.renderAddressCard(e,!0))).join("")}\n </div>\n </div>\n `:""}\n\n ${t.length>0?`\n <div>\n <h3 class="text-sm font-semibold text-gray-700 mb-4">\n Other Addresses\n </h3>\n <div class="grid gap-4 lg:grid-cols-3">\n ${t.map((e=>this.renderAddressCard(e,!1))).join("")}\n </div>\n </div>\n `:""}\n </div>\n `;var n}categorizeAddresses(){const e=this.getState(),t=(e.data?.addresses||[]).filter((e=>e&&"object"==typeof e)),n=t.find((e=>e.isAccount)),o=t.filter((e=>!e.isAccount&&(e.isDefaultShipping||e.isDefaultBilling)));return{defaultAddresses:n?[n,...o]:o,regularAddresses:t.filter((e=>!e.isAccount&&!e.isDefaultShipping&&!e.isDefaultBilling))}}renderAddressCard(e,t=!1){const n=[];e.isAccount&&n.push({text:"Account",color:"secondary"}),e.isDefaultShipping&&n.push({text:"Default Shipping",color:"primary"}),e.isDefaultBilling&&n.push({text:"Default Billing",color:"success"});const o=!e.isAccount,i=this.recentlySavedAddressId===e.id;return`\n <div class="${t?"bg-primary-50 border-primary-200":"bg-white border-primary-200"} border rounded-lg p-5 hover:shadow-md transition-shadow relative ${i?"address-highlight":""}
1" data-address-id="${e.id}">\n \x3c!-- Recently Saved Indicator --\x3e\n ${i?'\n <div class="absolute top-2 right-2 bg-green-500 text-white text-xs px-2 py-1 rounded-full shadow-lg animate-bounce">\n <span class="flex items-center">\n <svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">\n <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />\n </svg>\n Saved!\n </span>\n </div>\n ':""}\n \n \x3c!-- Badges Row --\x3e\n ${n.length>0?`\n <div class="flex flex-wrap gap-2 mb-3">\n ${n.map((e=>`\n <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${"secondary"===e.color?"bg-secondary-100 text-secondary-800":"primary"===e.color?"bg-primary-100 text-primary-800":"success"===e.color?"bg-green-100 text-green-800":"bg-gray-100 text-gray-800"}">\n ${"Account"===e.text?'\n <svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">\n <path fill-rule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" clip-rule="evenodd" />\n </svg>\n ':'\n <svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">\n <path d="M3 12v3c0 1.657 3.134 3 7 3s7-1.343 7-3v-3c0 1.657-3.134 3-7 3s-7-1.343-7-3z" />\n <path d="M3 7v3c0 1.657 3.134 3 7 3s7-1.343 7-3V7c0 1.657-3.134 3-7 3S3 8.657 3 7z" />\n <path d="M17 5c0 1.657-3.134 3-7 3S3 6.657 3 5s3.134-3 7-3 7 1.343 7 3z" />\n </svg>\n '}\n ${e.text}\n </span>\n `)).join("")}\n </div>\n `:""}\n\n \x3c!-- Name and Actions Row --\x3e\n <div class="flex justify-between items-start mb-3">\n <h4 class="text-lg font-semibold text-gray-900">\n ${e.firstName} ${e.lastName}\n </h4>\n <div class="flex items-center space-x-1">\n <button \n class="edit-address-btn p-1.5 text-gray-400 hover:text-gray-600 transition-colors" \n data-address-id="${e.id}" \n title="Edit address"\n >\n <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />\n </svg>\n </button>\n ${o?`\n <button \n class="delete-address-btn p-1.5 text-gray-400 hover:text-red-600 transition-colors" \n data-address-id="${e.id}" \n title="Delete address"\n >\n <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />\n </svg>\n </button>\n `:""}\n </div>\n </div>\n\n \x3c!-- Address Details --\x3e\n <div class="text-sm text-gray-600 space-y-1">\n <div>${e.street1}</div>\n ${e.street2?`<div>${e.street2}</div>`:""}\n <div>${e.city}, ${e.region} ${e.postalCode}</div>\n <div>${this.getCountryName(e.country)}</div>\n </div>\n\n \x3c!-- Footer with Type Tags --\x3e\n <div class="mt-4 pt-3 border-t border-primary-100 flex items-center justify-between">\n <div class="flex items-center space-x-3">\n ${e.isShipping?'\n <span class="inline-flex items-center text-xs text-gray-500">\n <svg class="w-4 h-4 mr-1 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1\n <path d="M9 17a2 2 0 11-4 0 2 2 0 014 0zM19 17a2 2 0 11-4 0 2 2 0 014 0z" />\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16V6a1 1 0 00-1-1H4a1 1 0 00-1 1v10a1 1 0 001 1h1m8-1a1 1 0 01-1 1H9m4-1V8a1 1 0 011-1h2.586a1 1 0 01.707.293l3.414 3.414a1 1 0 01.293.707V16a1 1 0 01-1 1h-1m-6-1a1 1 0 001 1h1M5 17a2 2 0 104 0m-4 0a2 2 0 114 0m6 0a2 2 0 104 0m-4 0a2 2 0 114 0" />\n </svg>\n Shipping\n </span>\n ':""}\n ${e.isBilling?'\n <span class="inline-flex items-center text-xs text-gray-500">\n <svg class="w-4 h-4 mr-1 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" />\n </svg>\n Billing\n </span>\n ':""}\n </div>\n </div>\n </div>\n `}getCountryName(e){if(window.HeimGuard?.geoService){const t=window.HeimGuard.geoService.getAllCountries().find((t=>t.code===e));return t?t.name:e}return{US:"United States",CA:"Canada",GB:"United Kingdom",AU:"Australia",NZ:"New Zealand"}[e]||e}attachEventListeners(){this.eventListenersAttached||(this.addDelegatedListener("#add-address-btn","click",(()=>{this.modalHandler.openAddModal()})),this.addDelegatedListener("#add-first-address-btn","click",(()=>{this.modalHandler.openAddModal()})),this.addDelegatedListener(".edit-address-btn","click",((e,t)=>{const n=t.dataset.addressId;n&&this.modalHandler.openEditModal(n)})),this.addDelegatedListener(".delete-address-btn","click",((e,t)=>{const n=t.dataset.addressId;n&&this.modalHandler.confirmDelete(n)})),this.eventListenersAttached=!0)}setupAddressEventListeners(){document.addEventListener("profile:addresses:refresh",(async()=>{await this.refresh()}));const e=(0,Je.Ge)(Je.i$.ADDRESS_MODAL_SAVED,(async e=>{console.log("[AddressList] ADDRESS_MODAL_SAVED event received:",e),e.address&&e.address.id&&(this.recentlySavedAddressId=e.address.id,this.highlightTimeout&&clearTimeout(this.highlightTimeout),setTimeout((()=>{const t=document.querySelector(`[data-address-id="${e.address.id}"]`);t&&t.scrollIntoView({behavior:"smooth",block:"center"})}),100),this.highlightTimeout=setTimeout((()=>{this.recentlySavedAddressId=null,this.refresh()}),5e3))})),t=(0,Je.Ge)(Je.i$.ADDRESS_ADDED,(async e=>{if(console.log("[AddressList] ADDRESS_ADDED event received:",e),await this.refresh(),void 0!==e.count){const{ProfileEvents:t}=await Promise.resolve().then(n.bind(n,8354));t.emit("STATS_UPDATED",{stats:{addressCount:e.count}})}})),o=(0,Je.Ge)(Je.i$.ADDRESS_UPDATED,(async e=>{console.log("[AddressList] ADDRESS_UPDATED event received:",e),await this.refresh()})),i=(0,Je.Ge)(Je.i$.ADDRESS_DELETED,(async e=>{if(console.log("[AddressList] ADDRESS_DELETED event received:",e),await this.refresh(),void 0!==e.count){const{ProfileEvents:t}=await Promise.resolve().then(n.bind(n,8354));t.emit("STATS_UPDATED",{stats:{addressCount:e.count}})}})),a=(0,Je.Ge)(Je.i$.ADDRESS_LIST_UPDATED,(async e=>{console.log("[AddressList] ADDRESS_LIST_UPDATED event received:",e),await this.refresh()}));this.cleanup.addCleanupTask(e),this.cleanup.addCleanupTask(t),this.cleanup.addCleanupTask(o),this.cleanup.addCleanupTask(i),this.cleanup.addCleanupTask(a),this.cleanup.addCleanupTask((()=>{this.highlightTimeout&&clearTimeout(this.highlightTimeout)}))}async onDestroy(){this.highlightTimeout&&(clearTimeout(this.highlightTimeout),this.highlightTimeout=null)}async refresh(){console.log("[AddressList] Refreshing address list"),await super.refresh()}}class ot{constructor(e,t={}){this.impl=new nt(e,t)}async render(){return this.impl.render()}cleanup(){this.impl.destroy()}destroy(){this.impl.destroy()}async refresh(){return this.impl.refresh()}}new class{constructor(e={}){this.config=Ze.A,this.manager=Ye.default,this.modalHandler=et,this.options=e,this.instances=new Map,this.initialize()}initialize(){b.vF.debug("AddressSystem initializing...","profile"),this.setupGlobalListeners(),b.vF.debug("AddressSystem initialized","profile")}setupGlobalListeners(){document.addEventListener("heimguard:profile:updated",(e=>{const t=e,{profileData:n}=t.detail;n?.defaultAddress&&(0,Je.id)(Je.i$.ADDRESS_COUNT_CHANGED,{count:this.manager.getCount()})}))}async renderAddressList(e,t={}){if(!e)return console.error("Container element required"),null;const n=this.instances.get(e);n&&n.cleanup();const o=new ot(e,{...this.options,...t});return await o.render(),this.instances.set(e,o),o}openAddModal(){return this.modalHandler.openAddModal()}openEditModal(e){return this.modalHandler.openEditModal(e)}getManager(){return this.manager}getAddressCount(){return this.manager.getCount()}
1cleanup(){this.instances.forEach((e=>{e.cleanup()})),this.instances.clear()}};function it(e){return e?"localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname?e.replace("https://localhost","http://localhost"):e:null}function at(e){return e?{id:e.id,email:e.email,firstName:e.firstName||"",lastName:e.lastName||"",initials:rt(e.firstName,e.lastName),mobileNumber:e.mobileNumber||e.mobileNumber||"",otherPhone:e.alternatePhone||e.otherPhone||"",avatarUrl:it(e.profilePicture||e.avatarImgSrc||e.avatarcompanyImgSrc||e.avatarUrl||e.avatar||null),avatarImgSrc:it(e.profilePicture||e.avatarImgSrc||e.avatarcompanyImgSrc||e.avatarUrl||e.avatar||null),hasCustomAvatar:!!(e.profilePicture||e.avatarImgSrc||e.avatarcompanyImgSrc||e.avatarUrl||e.avatar),memberSince:e.profileCreationDate,lastUpdated:e.lastUpdated,defaultAddress:(()=>{console.log("[ProfileTransformers] Default address in API data:",e.defaultAddress);const t=(n=e.defaultAddress)?{id:n.id,street1:n.street1||n.addressLine1||"",street2:n.street2||n.addressLine2||"",city:n.city||"",state:n.region||n.state||"",postalCode:n.postalCode||n.zip||"",country:n.country||w.default.getDefaultCountry()||"US",isDefault:n.isDefault||!1,type:n.type||"home"}:null;var n;return console.log("[ProfileTransformers] Transformed address:",t),t})(),profileCompletion:st(e),membershipYears:dt(e.profileCreationDate),_raw:e}:null}function st(e){return[{value:e.firstName,weight:15},{value:e.lastName,weight:15},{value:e.email,weight:20},{value:e.mobileNumber||e.mobileNumber,weight:10},{value:e.defaultAddress,weight:15},{value:e.avatarcompanyImgSrc,weight:10},{value:e.paymentMethods&&e.paymentMethods.length>0,weight:15}].reduce(((e,t)=>e+(t.value?t.weight:0)),0)}function rt(e,t){return(e?.charAt(0)?.toUpperCase()||"")+(t?.charAt(0)?.toUpperCase()||"")||"U"}function dt(e){if(!e)return 0;const t=Math.floor(((new Date).getTime()-new Date(e).getTime())/315576e5);return Math.max(0,t)}var lt=n(2512),ct=n(6532);class ut{static async init(){if(this.state.initialized)b.vF.debug("Already initialized","payment");else{b.vF.debug("Initializing...","payment");try{this.state.initialized=!0,(0,ct.wJ)(ct.aC.STATE_INITIALIZED,{state:this.getState()}),b.vF.debug("Initialized successfully","payment")}catch(e){throw b.vF.error("Initialization failed:","payment",e),this.state.error=e instanceof Error?e.message:String(e),e}}}static getState(){return{...this.state,paymentMethods:[...this.state.paymentMethods]}}static updateState(e){const t=this.getState();Object.assign(this.state,e),this.state.lastUpdate=Date.now(),this.notifyListeners(t,this.state),(0,ct.wJ)(ct.aC.STATE_CHANGED,{oldState:t,newState:this.getState(),updates:e})}static setPaymentMethods(e){const t=e.find((e=>e.isDefault));this.updateState({paymentMethods:e,defaultMethodId:t?.id||null,isLoading:!1,error:null}),(0,ct.wJ)(ct.aC.METHODS_UPDATED,{methods:e,count:e.length,defaultMethodId:t?.id||null})}static setDefaultMethod(e){const t=this.state.paymentMethods.map((t=>({...t,isDefault:t.id===e})));this.updateState({paymentMethods:t,defaultMethodId:e}),(0,ct.wJ)(ct.aC.DEFAULT_CHANGED,{methodId:e,previousDefault:this.state.defaultMethodId})}static addPaymentMethod(e){if(!e)return void b.vF.warn("Attempted to add undefined payment method","payment");const t=[...this.state.paymentMethods,e];1===t.length&&(e.isDefault=!0),this.setPaymentMethods(t)}static removePaymentMethod(e){const t=this.state.paymentMethods.filter((t=>t.id!==e)),n=this.state.defaultMethodId===e;n&&t.length>0&&(t[0].isDefault=!0),this.setPaymentMethods(t),(0,ct.wJ)(ct.aC.METHOD_REMOVED,{methodId:e,count:t.length,wasDefault:n})}static setLoading(e){this.updateState({isLoading:e})}static setError(e){this.updateState({error:e instanceof Error?e.message:e,isLoading:!1})}static setRecurlyReady(e,t=null){this.updateState({recurlyReady:e,recurlyPublicKey:t||this.state.recurlyPublicKey}),e&&(0,ct.wJ)(ct.aC.RECURLY_READY,{publicKey:t})}static clearState(){this.updateState({paymentMethods:[],defaultMethodId:null,isLoading:!1,error:null,recurlyReady:!1}),(0,ct.wJ)(ct.aC.STATE_CLEARED)}static subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}
1static notifyListeners(e,t){this.listeners.forEach((n=>{try{n(t,e)}catch(e){b.vF.error("Listener error:","payment",e)}}))}static getMethodById(e){return this.state.paymentMethods.find((t=>t.id===e))}static getDefaultMethod(){return this.state.paymentMethods.find((e=>e.isDefault))}static getMethodCount(){return this.state.paymentMethods.length}static hasPaymentMethods(){return this.state.paymentMethods.length>0}}ut.state={paymentMethods:[],defaultMethodId:null,isLoading:!1,error:null,recurlyPublicKey:null,recurlyReady:!1,initialized:!1,lastUpdate:null},ut.listeners=new Set;var mt=ut,gt=n(9948),ht=n(2046);var pt=new class{constructor(){this.manager=lt.Ay,this.stateManager=mt,this.modalHandler=gt.Ay,this.config=ht.Ay,this.isInitialized=!1,this.cleanupFunctions=[],this.components=new Map,this.eventHandlers=(0,ct.Ac)()}async initialize(e={}){if(this.isInitialized)b.vF.debug("Already initialized","payment");else{b.vF.debug("Initializing...","payment");try{e.config&&this.config.update(e.config),await this.stateManager.init(),await this.manager.initialize(),e.recurlyPublicKey&&(await this.modalHandler.initialize(e.recurlyPublicKey),this.stateManager.setRecurlyReady(!0,e.recurlyPublicKey)),this.setupEventHandlers(),this.setupManagerSync(),!1!==e.autoRender&&await this.autoRender(),this.isInitialized=!0,(0,ct.wJ)(ct.aC.SYSTEM_READY),b.vF.debug("Initialization complete","payment")}catch(e){throw b.vF.error("Initialization failed:","payment",e),(0,ct.wJ)(ct.aC.SYSTEM_ERROR,{error:e}),e}}}setupEventHandlers(){this.eventHandlers.on(ct.aC.METHOD_ADDED,(e=>{const t=e.method;b.vF.debug("Payment method added:","payment",t),t?(this.stateManager.addPaymentMethod(t),this.refreshComponents()):b.vF.warn("Received METHOD_ADDED event with undefined method","payment")})),this.eventHandlers.on(ct.aC.METHOD_REMOVED,(e=>{const t=e.methodId;b.vF.debug("Payment method removed:","payment",t),this.stateManager.removePaymentMethod(t),this.refreshComponents()})),this.eventHandlers.on(ct.aC.METHOD_UPDATED,(e=>{const t=e.method;b.vF.debug("Payment method updated:","payment",t);const n=this.stateManager.getState().paymentMethods.map((e=>e.id===t.id?t:e));this.stateManager.setPaymentMethods(n),this.refreshComponents()})),this.eventHandlers.on(ct.aC.DEFAULT_CHANGED,(e=>{const t=e.methodId;b.vF.debug("Default payment method changed:","payment",t),this.stateManager.setDefaultMethod(t),this.refreshComponents()})),this.eventHandlers.on(ct.aC.METHODS_LOADING,(()=>{this.stateManager.setLoading(!0)})),this.eventHandlers.on(ct.aC.METHODS_LOADED,(e=>{const t=e.methods;this.stateManager.setPaymentMethods(t)})),this.eventHandlers.on(ct.aC.METHODS_ERROR,(e=>{const t=e.error;b.vF.error("Methods error:","payment",t),this.stateManager.setError(t)})),this.eventHandlers.on(ct.aC.RECURLY_ERROR,(e=>{const t=e.error;b.vF.error("Recurly error:","payment",t),this.stateManager.setError(t)}))}setupManagerSync(){this.stateManager.subscribe(((e,t)=>{e.paymentMethods!==t.paymentMethods&&this.refreshComponents()}))}async autoRender(){b.vF.debug("Auto-rendering payment components...","payment"),await C;const e=document.querySelectorAll("[data-payment-methods], .payment-methods-container");for(const t of e)await this.renderPaymentMethods(t);const t=document.querySelectorAll("[data-payment-count]");for(const e of t)this.renderPaymentCount(e)}async renderPaymentMethods(e){if(e)try{const{default:t}=await Promise.resolve().then(n.bind(n,3583)),o=new t(e,{onAddClick:()=>this.modalHandler.openAddModal(),onRemoveClick:e=>this.modalHandler.confirmRemove(e),onDefaultClick:e=>this.modalHandler.setDefault(e),api:this.manager});return await o.render(),this.components.set(e,o),o}catch(e){throw b.vF.error("Failed to render payment methods:","payment",e),e}}renderPaymentCount(e){if(!e)return;const t=()=>{const t=this.manager.getCount();e.textContent=t.toString();const n=e;"true"===e.dataset.hideEmpty&&0===t?n.style.display="none":n.style.display=""};t();const n=(0,ct.yH)(ct.aC.METHODS_UPDATED,t);this.cleanupFunctions.push(n)}async refreshComponents(){for(const[e,t]of this.components)t&&t.refresh&&await t.refresh()}async openAddPaymentModal(){return this.modalHandler.openAddModal()}async loadPaymentMethods(e=!1){return this.manager.loadPaymentMethods(e)}getPaymentMethods(){return this.manager.getPaymentMethods()}getPaymentMethod(e){return this.manager.getPaymentMethodById(e)}getDefaultPaymentMethod(){return this.manager.getDefaultPaymentMethod()}async setDefaultPaymentMethod(e){return this.modalHandler.setDefault(e)}async removePaymentMethod(e){return this.modalHandler.confirmRemove(e)}isReady(){return this.isInitialized&&this.manager.isRecurlyReady()}cleanup(){b.vF.debug("Cleaning up...","payment"),this.eventHandlers.cleanup();for(const[e,t]of this.components)t&&t.cleanup&&t.cleanup();this.components.clear(),this.modalHandler.cleanup&&this.modalHandler.cleanup(),this.stateManager.clearState(),this.manager.clear(),this.isInitialized=!1}};const yt=new class{constructor(){this.name="paymentSystem",this.initialized=!1}async initialize(){b.vF.debug("Initializing payment system...","payment");const{systemRegistry:e}=await Promise.resolve().then(n.bind(n,1667));e.registerInstance("paymentSystem",pt),e.registerInstance("paymentManager",lt.Ay),e.registerInstance("paymentStateManager",mt),e.registerInstance("paymentModalHandler",gt.Ay),e.registerInstance("paymentConfig",ht.Ay),await pt.initialize({}),this.initialized=!0,b.vF.debug("Payment system initialized successfully","payment")}cleanup(){pt&&pt.cleanup(),this.initialized=!1}async openAddPaymentModal(){return pt.openAddPaymentModal()}async loadPaymentMethods(e){return pt.loadPaymentMethods(e)}getPaymentMethods(){return pt.getPaymentMethods()}getPaymentMethod(e){return pt.getPaymentMethod(e)}getDefaultPaymentMethod(){return pt.getDefaultPaymentMethod()}async setDefaultPaymentMethod(e){return pt.setDefaultPaymentMethod(e)}async removePaymentMethod(e){return pt.removePaymentMethod(e)}isReady(){return pt.isReady()}async renderPaymentMethods(e){return pt.renderPaymentMethods(e)}async refreshComponents(){return pt.refreshComponents()}};n(8886);var Ct=n(3583),ft=n(4081);n(6957),n(1458);if("undefined"!=typeof window){A.systemRegistry.register("paymentSystemAdapter",yt);const e=()=>!!document.querySelector("[data-payment-methods], .payment-methods-container, [data-payment-count]"),t=()=>{e()&&yt.initialize()};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",t):t()}var vt=n(4432),bt=n(1175);class wt{constructor(e,t){this.container=e,this.options={subscription:t.subscription||null,onCancel:t.onCancel,onUpdate:t.onUpdate,onChangePayment:t.onChangePayment,onReactivate:t.onReactivate}}render(){const e=this.options.subscription;if(!e)return;const t="active"===e.status,n=e.cancelAtPeriodEnd,o="trialing"===e.status,i="expired"===e.status||"expired"===e.subscriptionState,a="canceled"===e.status||"canceled"===e.subscriptionState,s="paused"===e.status||"paused"===e.subscriptionState,r="future"===e.status||"future"===e.subscriptionState;
1this.getStatusDisplay(e.status,n);this.container.className="h-full",this.container.innerHTML=`\n <div class="subscription-card w-full group relative overflow-hidden border-2 rounded-xl p-6 transition-all duration-300 hover:shadow-xl h-full flex flex-col ${t&&!n?"border-secondary-200 bg-gradient-to-br from-secondary-50 via-white to-secondary-50/30 shadow-lg":o?"border-primary-200 bg-gradient-to-br from-primary-50 via-white to-primary-50/30 shadow-lg":r?"border-cyan-200 bg-gradient-to-br from-cyan-50 via-white to-cyan-50/30 shadow-lg":n?"border-yellow-300 bg-yellow-50/50":s?"border-gray-300 bg-gray-50":a?"border-amber-200 bg-amber-50/50 opacity-75":i?"border-red-200 bg-red-50/50 opacity-75":"border-gray-300 bg-gray-50"}">\n \x3c!-- Status Banner --\x3e\n <div class="absolute inset-x-0 top-0 h-1 ${t&&!n?"bg-secondary-500":o?"bg-primary-500":r?"bg-cyan-500":n?"bg-yellow-400":s?"bg-gray-400":a?"bg-amber-600":i?"bg-red-500":"bg-gray-400"}"></div>\n \n\n \x3c!-- Background Pattern --\x3e\n <div class="absolute inset-0 opacity-5">\n <div class="absolute inset-0" style="background-image: url('data:image/svg+xml,%3Csvg width="60" height="60" viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="none" fill-rule="evenodd"%3E%3Cg fill="%239C92AC" fill-opacity="0.4"%3E%3Cpath d="M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z"/%3E%3C/g%3E%3C/g%3E%3C/svg%3E');"></div>\n </div>\n\n <div class="relative flex-1 flex flex-col">\n \x3c!-- Top Section with Plan Info --\x3e\n <div class="flex items-start justify-between mb-4 gap-4">\n <div class="flex-1 min-w-0">\n <h3 class="text-lg font-bold text-gray-900 mb-2" title="${e.planName||"Subscription"}">${e.planName||"Subscription"}</h3>\n ${e.accountUserName?`<p class="text-sm text-gray-500 mb-2">Account: ${e.accountUserName}</p>`:""}\n <div class="flex items-baseline space-x-1">\n <span class="text-xs text-gray-500">${e.currency||"USD"}</span>\n ${void 0!==e.tax&&e.tax>0?`\n <div class="flex flex-col">\n <div class="flex items-baseline space-x-1">\n <span class="text-2xl font-bold text-gray-900">
1${this.formatAmount(e.subTotal||e.amount||e.totalWithTax||e.total||0)}</span>\n <span class="text-sm text-gray-600">/ ${this.formatInterval(e.interval,e.intervalCount)}</span>\n </div>\n <div class="text-xs text-gray-500 space-y-0.5">\n <div>Tax (${e.taxRate||0}%): ${e.currency+" "||0}${this.formatAmount(e.tax)}</div>\n <div>Total: ${e.currency+" "||0}${this.formatAmount(e.totalWithTax||e.total||e.subTotal||e.amount||0)}</div>\n </div>\n </div>\n `:`\n <span class="text-2xl font-bold text-gray-900">${this.formatAmount(e.subTotal||e.amount||e.total||e.amount||0)}</span>\n <span class="text-sm text-gray-600">/ ${this.formatInterval(e.interval,e.intervalCount)}</span>\n `}\n </div>\n </div>\n\n \x3c!-- Actions Menu (hide for expired/canceled) --\x3e\n ${i||a?"":`\n <div class="relative">\n <button class="p-2 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg transition-colors" data-action="menu">\n ${P.H.getIcon("general","menuVertical","w-5 h-5")}\n </button>\n\n \x3c!-- Dropdown Menu --\x3e\n <div class="action-menu hidden absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-xl border border-gray-200 py-1 z-10">\n <button class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-primary-50 hover:text-primary-600 transition-colors flex items-center" data-action="payment">\n ${P.H.getIcon("payment","creditCard","w-4 h-4 mr-2")}\n Update Payment\n </button>\n ${void 0!==this.options.onCancel?`\n <div class="border-t border-gray-100 my-1"></div>\n <button class="w-full px-4 py-2 text-left text-sm text-red-600 hover:bg-red-50 transition-colors flex items-center" data-action="cancel">\n ${P.H.getIcon("ui","close","w-4 h-4 mr-2")}\n Cancel Subscription\n </button>\n `:""}\n </div>\n </div>\n `}\n </div>\n\n \x3c!-- Billing Details --\x3e\n <div class="space-y-3 flex-1">\n \x3c!-- Status and Dates Grid --\x3e\n <div class="grid grid-cols-2 gap-3">\n \x3c!-- Activation Date --\x3e\n ${e.activatedAt||e.createdAt?`\n <div class="bg-gray-50 rounded-lg p-3">\n <p class="text-xs text-gray-500 mb-1">${r?"Starts On":"Activated"}</p>\n <p class="text-sm font-medium text-gray-900">${Fe.Nq.format(e.activatedAt||e.createdAt,"medium")}</p>\n </div>\n `:""}\n \n \x3c!-- Current Period End --\x3e\n ${e.currentPeriodEndsAt||e.currentPeriodEnd?`\n <div class="bg-gray-50 rounded-lg p-3">\n <p class="text-xs text-gray-500 mb-1">${i?"Expired On":e.nextBillingDate&&t&&!o&&!n?"Renews On":"Ends On"}</p>\n <p class="text-sm font-medium text-gray-900">${Fe.Nq.format(e.currentPeriodEndsAt||e.currentPeriodEnd,"medium")}</p>\n </div>\n `:""}\n </div>\n\n \x3c!-- Next Billing Date (for active subscriptions) --\x3e\n ${e.nextBillingDate&&t&&!o&&!n?`\n <div class="bg-white rounded-lg p-3 border border-gray-200">\n <div class="flex items-center justify-between">\n <div class="flex items-center">\n ${P.H.getIcon("general","calendar","w-5 h-5 mr-2 text-gray-400")}\n <div>\n <p class="text-sm text-gray-600">Next billing</p>\n <p class="font-medium text-gray-900">${Fe.Nq.format(e.nextBillingDate,"long")}</p>\n </div>\n </div>\n ${e.nextBillingDate&&null!==Fe.Nq.getDaysUntil(e.nextBillingDate)&&Fe.Nq.getDaysUntil(e.nextBillingDate)<=7?`\n <sp
1an class="text-xs font-medium text-orange-600 bg-orange-100 px-2 py-1 rounded-full">\n ${e.nextBillingDate?Fe.Nq.getDaysUntil(e.nextBillingDate)??0:0} days\n </span>\n `:""}\n </div>\n </div>\n `:""}\n\n \x3c!-- Payment Method --\x3e\n ${e.paymentMethod&&"object"==typeof e.paymentMethod?`\n <div class="bg-white rounded-lg p-3 border border-gray-200">\n <div class="flex items-center justify-between">\n <div class="flex items-center">\n <div class="w-10 h-6 ${bt.U.getCardBackgroundClass(e.paymentMethod.brand)} rounded flex items-center justify-center text-white text-xs font-bold mr-3">\n ${bt.U.getCardBrandShort(e.paymentMethod.brand)}\n </div>\n <div>\n <p class="text-sm text-gray-600">Payment</p>\n <p class="font-medium text-gray-900">â¢â¢â¢â¢ ${e.paymentMethod.last4}</p>\n </div>\n </div>\n </div>\n </div>\n `:""}\n </div>\n\n \x3c!-- Cancellation Warning --\x3e\n ${n?`\n <div class="bg-yellow-100 border border-yellow-200 text-yellow-700 rounded-lg p-4 mb-4 flex items-start">\n ${P.H.getIcon("status","warning","w-5 h-5 mr-2 flex-shrink-0 mt-0.5")}\n <div class="flex-1">\n <p class="font-medium text-sm">Subscription ending soon</p>\n <p class="text-xs mt-1">\n This subscription will end on ${Fe.Nq.format(e.currentPeriodEnd,"long")}.\n You can reactivate it anytime before then.\n </p>\n </div>\n </div>\n `:""}\n\n \x3c!-- Bottom Section --\x3e\n <div class="flex items-center justify-between pt-4 border-t border-gray-100 mt-auto">\n \x3c!-- Status Badge --\x3e\n <div class="flex items-center">\n ${t&&!n?'<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">\n <span class="w-2 h-2 mr-1 bg-green-400 rounded-full"></span>\n Active\n </span>':o?'<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">\n <span class="w-2 h-2 mr-1 bg-blue-400 rounded-full"></span>\n Trial\n </span>':n?'<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">\n <span class="w-2 h-2 mr-1 bg-yellow-400 rounded-full"></span>\n Cancelling\n </span>':s?'<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-200 text-gray-800">\n <span class="w-2 h-2 mr-1 bg-gray-400 rounded-full"></span>\n Paused\n </span>':r?'<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-cyan-100 text-cyan-800">\n <span class="w-2 h-2 mr-1 bg-cyan-400 rounded-full"></span>\n Future\n </span>':i?'<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">\n <span class="w-2 h-2 mr-1 bg-red-400 rounded-full"></span>\n Expired\n </span>':a?'<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-amber-200 text-amber-700">\n <span class="w-2 h-2 mr-1 bg-amber-600 rounded-full"></span>\n Canceled\n </span>':""}\n </div>\n\n \x3c!-- Quick Action Buttons --\x3e\n ${n?'\n <button class="inline-flex items-center px-3 py-1.5 bg-green-600 text-white text-xs font-medium rounded-lg hover:bg-green-700 transition-colors shadow-sm hover:shadow" data-action="reactivate">\n Reactivate\n </button>\n ':""}\n \x3c!-- Payment Information --\x3e\n ${e.cardType?`\n <div class="flex items-center">\n ${P.H.getIcon("payment","credit-card","w-5 h-5 mr-2")}\n <div class="flex items-center space-x-2 tracking-wider">\n <div class="w-10 h-6 ${bt.U.getCardBackgroun
1dClass(e.cardType)} rounded flex items-center justify-center text-white text-xs font-bold">\n ${bt.U.getCardBrandShort(e.cardType)}\n </div>\n ${e.lastFour?`<p class="text-xs">â¢â¢â¢â¢ ${e.lastFour}</p>`:""}\n </div>\n </div>\n `:""}\n </div>\n </div>\n </div>\n `,this.attachEventListeners()}getStatusDisplay(e,t){if(t)return{label:"Cancelling",textColor:"text-yellow-700",bgColor:"bg-yellow-100",borderColor:"border-yellow-200",icon:'<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />'};const n={active:{label:"Active",textColor:"text-green-700",bgColor:"bg-green-100",borderColor:"border-green-200",icon:'<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />'},trialing:{label:"Trial",textColor:"text-blue-700",bgColor:"bg-blue-100",borderColor:"border-blue-200",icon:'<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd" />'},past_due:{label:"Past Due",textColor:"text-red-700",bgColor:"bg-red-100",borderColor:"border-red-200",icon:'<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />'},canceled:{label:"Canceled",textColor:"text-gray-700",bgColor:"bg-gray-100",borderColor:"border-gray-200",icon:'<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />'}};return n[e]||n.active}formatAmount(e){return e.toFixed(2)}formatInterval(e,t){if(!e)return"month";const n=t>1?`${e}s`:e;return t>1?`${t} ${n}`:n}attachEventListeners(){const e=this.container.querySelector('[data-action="menu"]'),t=this.container.querySelector(".action-menu");e&&t&&(e.addEventListener("click",(e=>{e.stopPropagation(),t.classList.toggle("hidden")})),document.addEventListener("click",(e=>{this.container.contains(e.target)||t.classList.add("hidden")})));const n=this.container.querySelector('[data-action="cancel"]');n&&this.options.onCancel&&n.addEventListener("click",(e=>{e.stopPropagation(),t?.classList.add("hidden"),this.options.subscription?.id&&this.options.onCancel&&this.options.onCancel(this.options.subscription.id)}));const o=this.container.querySelector('[data-action="update"]');o&&this.options.onUpdate&&o.addEventListener("click",(e=>{e.stopPropagation(),t?.classList.add("hidden"),this.options.subscription?.id&&this.options.onUpdate&&this.options.onUpdate(this.options.subscription.id)}));const i=this.container.querySelector('[data-action="payment"]');i&&this.options.onChangePayment&&i.addEventListener("click",(e=>{e.stopPropagation(),t?.classList.add("hidden"),this.options.subscription?.id&&this.options.onChangePayment&&this.options.onChangePayment(this.options.subscription.id)}));const a=this.container.querySelector('[data-action="reactivate"]');a&&this.options.onReactivate&&a.addEventListener("click",(()=>{this.options.subscription?.id&&this.options.onReactivate&&this.options.onReactivate(this.options.subscription.id)}))}}var St=n(3039),xt=n(7663);const At="subscriptions:updated",Tt="subscription:added",Mt="subscription:cancelled",Et="subscription:updated",Pt="subscription:reactivated",Nt="Failed to create subscription. Please check your information and try again.",Lt="Failed to reactivate subscription. Please try again.",Dt="Subscription created successfully!",It="Subscription reactivated successfully";class kt extends tt.A{constructor(e,t={}){super(e,t),this.subscriptionCardInstances=[],this.mainButtonListenerAttached=!1,this.activeSubscriptionFlow=null,this.isShowingModal=!1,this.lastModalCallTime=0,this.MODAL_DEBOUNCE_TIME=1e3,this.displaySettings={showFilters:!0,showSort:!0,showLegend:!0,showProgress:!0},this.activeFilters={status:[],interval:[]}
1,this.allowCancellation=!1,this.isCabotWealth=!1,console.log("[SubscriptionsList] Constructor called",{container:e,containerId:e.id,containerClass:e.className}),this.initializeDisplaySettings(),this.loadProfileUIConfig().then((()=>{const e=this.getState();!e.isLoading&&e.subscriptions.length>0&&this.renderContent()}))}getDefaultOptions(){return{autoInit:!0,debug:!1}}initializeDisplaySettings(){const e=this.options,t=this.container.dataset.displayMode||e.displayMode||"full",n={full:{showFilters:!0,showSort:!0,showLegend:!0,showProgress:!0},inline:{showFilters:!1,showSort:!1,showLegend:!1,showProgress:!1},compact:{showFilters:!1,showSort:!1,showLegend:!0,showProgress:!0}},o=n[t]||n.full;this.displaySettings={...o},void 0!==this.container.dataset.showFilters&&(this.displaySettings.showFilters="true"===this.container.dataset.showFilters),void 0!==this.container.dataset.showSort&&(this.displaySettings.showSort="true"===this.container.dataset.showSort),void 0!==this.container.dataset.showLegend&&(this.displaySettings.showLegend="true"===this.container.dataset.showLegend),void 0!==this.container.dataset.showProgress&&(this.displaySettings.showProgress="true"===this.container.dataset.showProgress),void 0!==e.showFilters&&(this.displaySettings.showFilters=e.showFilters),void 0!==e.showSort&&(this.displaySettings.showSort=e.showSort),void 0!==e.showLegend&&(this.displaySettings.showLegend=e.showLegend),void 0!==e.showProgress&&(this.displaySettings.showProgress=e.showProgress),this.container.classList.add(`hg-subscriptions--${t}`),console.log("[SubscriptionsList] Display settings:",{mode:t,settings:this.displaySettings})}async loadProfileUIConfig(){try{console.log("[SubscriptionsList] Loading profile UI config..."),await w.default.load(),this.isCabotWealth=w.default.isCabotWealth(),console.log("[SubscriptionsList] Updated isCabotWealth to:",this.isCabotWealth);const e=D.fl.getProfileUIConfig();console.log("[SubscriptionsList] Loaded profile UI config:",e),void 0!==e.showSubscriptionFilters&&(this.displaySettings.showFilters=e.showSubscriptionFilters,console.log("[SubscriptionsList] Updated showFilters to:",this.displaySettings.showFilters)),void 0!==e.allowSubscriptionCancellation&&(this.allowCancellation=e.allowSubscriptionCancellation,console.log("[SubscriptionsList] Updated allowCancellation to:",this.allowCancellation))}catch(e){console.warn("[SubscriptionsList] Failed to load profile UI config:",e)}}getInitialState(){return{isLoading:!0,error:null,data:null,profileData:this.options.profileData,subscriptions:[],availablePlans:[],currentPage:1,totalPages:1,totalCount:0}}async onInit(){this.store.subscribe(((e,t,n)=>{n.includes("data")&&!e.isLoading&&this.updateContent()}))}getComponentClassName(){return"hg-subscriptions"}getComponentName(){return"subscriptions"}getHeaderConfig(){return{icon:De.b.icons.subscription,title:"Subscriptions",subtitle:"Manage your active subscriptions and billing",actions:()=>`\n <button id="add-subscription-btn" class="inline-flex items-center px-4 py-2 bg-white/20 backdrop-blur text-white rounded-lg hover:bg-white/30 transition-all border border-white/30 text-sm font-medium">\n ${P.H.getIcon("general","plus","w-4 h-4 mr-2")}\n ${this.isCabotWealth?"Add a Subscription":"Subscribe to Plan"}\n </button>\n `}}renderShell(e){const t=this.container.dataset.displayMode||this.options.displayMode||"full";if("inline"!==t)if("compact"!==t)super.renderShell(e);else{const t={...e,actions:""};super.renderShell(t)}else this.container.innerHTML=`\n <div class="${this.getComponentClassName()}-container ${this.getComponentClassName()}-container--inline">\n <div class="${this.getComponentClassName()}-content-area">\n \x3c!-- Content will be inserted here --\x3e\n </div>\n </div>\n `}getLoadingMessage(){return"Loading your subscriptions..."}async loadData(){console.log("[SubscriptionsList] loadData called - fetching subscriptions...");const e=this.getState(),t=await xt.G.getSubscriptions(e.currentPage,10);console.log("[SubscriptionsList] Raw API response:",t),console.log("[
1SubscriptionsList] Response data:",t.data),console.log("[SubscriptionsList] Subscriptions in response:",t.data?.subscriptions);let o=[];t.success&&t.data?.subscriptions?Array.isArray(t.data.subscriptions)?(o=t.data.subscriptions,console.log("[SubscriptionsList] Subscriptions is array, length:",o.length)):(o=Object.values(t.data.subscriptions),console.log("[SubscriptionsList] Subscriptions is object, converted to array, length:",o.length)):console.log("[SubscriptionsList] No subscriptions found in response");const i=this.transformSubscriptions(o);i.sort(((e,t)=>{const n={active:0,trialing:1,future:2,past_due:3,paused:4,canceled:5,expired:6};return(n[e.status]??7)-(n[t.status]??7)}));const a=t.data?.pagesCount||1,s=t.data?.totalCount||i.length;console.log("[SubscriptionsList] Pagination data from API:",{pagesCount:t.data?.pagesCount,totalCount:t.data?.totalCount,currentPageItems:i.length,currentPage:e.currentPage}),this.setState({totalPages:a,totalCount:s});const r=t.data?.activeCount||i.filter((e=>"active"===e.status)).length,{ProfileEvents:d}=await Promise.resolve().then(n.bind(n,8354));return d.emit("STATS_UPDATED",{stats:{activeSubscriptions:r}}),{subscriptions:i}}async fetchData(){return await this.loadData()}isEmptyState(e){return!e||!e.subscriptions||0===e.subscriptions.length}getEmptyStateConfig(){return{icon:P.H.getIcon("payment","dollar","w-16 h-16 text-gray-400"),title:"No active subscriptions",message:this.isCabotWealth?"Subscribe to a plan to unlock premium services features and benefits":"Subscribe to a plan to unlock premium features and benefits",action:`\n <button id="add-first-subscription-btn" class="inline-flex items-center px-6 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-all font-medium shadow-md hover:shadow-lg transform hover:-translate-y-0.5">\n ${P.H.getIcon("general","plus","w-5 h-5 mr-2")}\n Browse Available Plans\n </button>\n `}}renderMainContent(){const e=this.getState();if(!e.data||!e.data.subscriptions||0===e.data.subscriptions.length)return"";const t=e.data.subscriptions,n=t.length>=3&&this.displaySettings.showFilters;let o=[...t];n&&this.activeFilters&&(o=this.applyFilters(o));const i=this.isCabotWealth?'Want to make changes to your subscription? <a class="text-secondary-600" href="/contact-us">Contact us</a>':"";return`\n <div class="p-6">\n ${n?this.renderFilters(t):""}\n <div class="${1===o.length?"w-1/2 mx-auto":"grid grid-cols-1 md:grid-cols-2 gap-6 auto-rows-fr"}${n?"mt-6":""}">\n ${o.map((e=>`\n <div data-subscription="${e.id}" class="flex"></div>\n `)).join("")}\n </div>\n ${0===o.length&&n?`\n <div class="text-center py-12">\n <div class="text-gray-400 mb-4">\n ${P.H.getIcon("general","search","w-12 h-12 mx-auto")}\n </div>\n <p class="text-gray-600 font-medium">No subscriptions match your filters</p>\n <button class="mt-3 text-primary-600 hover:text-primary-700 text-sm font-medium" data-action="clear-filters">\n Clear filters\n </button>\n </div>\n `:""}\n\n \x3c!-- Pagination --\x3e\n ${this.renderPagination()}\n ${this.isCabotWealth?`\n <div class="text-center py-16">\n ${i?`<p class="text-gray-600 mb-8 max-w-md mx-auto">${i}</p>`:""}\n </div>\n `:""}\n </div>\n `}renderPagination(){const e=this.getState();if(e.totalPages<=1)return"";return`\n <div class="mt-6 pt-6 border-t border-gray-200 px-6 pb-6">\n <div class="flex items-center justify-between">\n <div class="text-sm text-gray-700">\n Showing <span class="font-medium">${10*(e.currentPage-1)+1}</span> to <span class="font-medium">${Math.min(10*e.currentPage,e.totalCount)}</span> of <span class="font-medium">${e.totalCount}</span> subscriptions\n </div>\n <nav class="flex items-center space-x-2" role="navigation" aria-label="Pagination">\n ${this.renderPaginationButton("prev",e.currentPage-1,e.currentPage>1,"Previous")}\n ${this.renderPageNumbers(e.currentPage,e.totalPages)}\n ${this.renderPaginationButton("next",e.currentPage+1,e.currentPage<e.totalPages,"Next")}\n </nav>\n </div>\n </div>\n `}renderPaginationButton(e,t,n,o){return`\n <button \n type="button"\n class="relative inline-flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors ${n?"text-gray-700 bg-white border border-gray-300 hover:bg-gray-50 hover:text-gray-900":"text-gray-400 bg-gray-100 border border-gray-200 cursor-not-allowed"}"\n data-page="${t}"\n ${n?"":"disabled"}\n aria-label="${o} page">\n ${o}\n </button>\n `}renderPageNumbers(e,t){const n=[];for(let e=1;e<=t;e++)n.push(e);return n.map((t=>{const n=t===e;return`\n <button \n type="button"\n class="relative inline-flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors ${n?"z-10 bg-primary-600 text-white border border-primary-600":"text-gray-700 bg-white border border-gray-300 hover:bg-gray-100"}"\n data-page="${t}"\n ${n?'aria-current="page"':""}\n aria-label="Go to page ${t}">\n ${t}\n </button>\n `})).join("")}async handlePageChange(e){if(e===this.getState().currentPage)return;const t=`subscriptions-page-${Date.now()}`;try{vt.W.show(this.container,{message:"Loading subscriptions...",spinner:!0,overlay:!0,id:t}),this.setState({currentPage:e}),await this.refresh()}catch(e){console.error("Error changing page:",e),te.Alert.error("Failed to load page. Please try again.")}finally{await vt.W.hide(t)}}transformSubscriptions(e){if(e&&"object"==typeof e&&!Array.isArray(e)){return Object.values(e).filter((e=>e&&"object"==typeof e&&"subscriptionId"in e)).map(((e,t)=>
1(console.log("[SubscriptionsList] Transforming subscription:",JSON.stringify(e,null,2)),console.log("[SubscriptionsList] currencies field:",e.currencies),console.log("[SubscriptionsList] unitAmount field:",e.unitAmount),console.log("[SubscriptionsList] plan field:",e.plan),{id:e.subscriptionId,subscriptionId:e.subscriptionId,planCode:e.planCode,planName:e.planName||e.planCode||"Unknown Plan",planId:e.planCode,status:this.mapSubscriptionState(e.subscriptionState||e.status),subscriptionState:e.subscriptionState||e.status,accountUserName:e.accountUserName,accountEmail:e.accountEmail,amount:e.unitAmount||(e.currencies&&e.currencies[0]?e.currencies[0].unit_amount/100:this.getPlanAmount(e.planCode)),subTotal:e.subTotal||e.amount||0,total:e.total||e.amount||0,currency:e.currency||(e.currencies&&e.currencies[0]?e.currencies[0].currency:"CAD"),interval:e.interval||e.plan&&e.plan.interval||this.getPlanInterval(e.planCode,e.intervalLength),intervalCount:e.intervalLength||e.plan&&e.plan.intervalCount||1,currentPeriodStart:e.currentPeriodStartedAt||(new Date).toISOString(),currentPeriodEnd:e.currentPeriodEndsAt||new Date(Date.now()+2592e6).toISOString(),currentPeriodStartedAt:e.currentPeriodStartedAt||(new Date).toISOString(),currentPeriodEndsAt:e.currentPeriodEndsAt||new Date(Date.now()+2592e6).toISOString(),nextBillingDate:e.nextBillingDate||e.currentPeriodEndsAt||new Date(Date.now()+2592e6).toISOString(),cancelAtPeriodEnd:e.cancelAtPeriodEnd||!1,quantity:e.quantity||1,unitAmou
1nt:e.unitAmount||(e.currencies&&e.currencies[0]?e.currencies[0].unit_amount/100:this.getPlanAmount(e.planCode)),intervalLength:e.intervalLength||1,createdAt:e.createdAt||e.activatedAt||(new Date).toISOString(),updatedAt:e.updatedAt||(new Date).toISOString(),tax:e.tax,taxType:e.taxType,taxRate:e.taxRate,cardType:e.cardType,lastFour:e.lastFour})))}return Array.isArray(e)?e.map(((e,t)=>({id:e.subscriptionId,subscriptionId:e.subscriptionId,planCode:e.planCode,planName:e.planName||e.planCode||"Unknown Plan",planId:e.planCode,status:this.mapSubscriptionState(e.subscriptionState||e.status),subscriptionState:e.subscriptionState||e.status,accountUserName:e.accountUserName,accountEmail:e.accountEmail,amount:e.total||e.subTotal||0,subTotal:e.subTotal||0,total:e.total||0,currency:e.currency||"USD",interval:this.getPlanInterval(e.planCode,e.intervalLength),intervalCount:e.intervalCount||1,currentPeriodStart:e.currentPeriodStart||e.activatedAt||(new Date).toISOString(),currentPeriodEnd:e.currentPeriodEnd||e.currentPeriodEndsAt||new Date(Date.now()+2592e6).toISOString(),currentPeriodEndsAt:e.currentPeriodEndsAt,nextBillingDate:e.nextBillingDate||e.currentPeriodEndsAt||new Date(Date.now()+2592e6).toISOString(),cancelAtPeriodEnd:e.cancelAtPeriodEnd||!1,quantity:e.quantity||1,unitAmou
1nt:e.unitAmount||e.total||0,intervalLength:e.intervalLength||1,createdAt:e.createdAt||e.activatedAt||(new Date).toISOString(),updatedAt:e.updatedAt||(new Date).toISOString(),tax:e.tax,taxType:e.taxType,taxRate:e.taxRate,cardType:e.cardType,lastFour:e.lastFour}))):[]}mapSubscriptionState(e){return{active:"active",canceled:"canceled",expired:"expired",future:"future",in_trial:"trialing",live:"active",paused:"paused",past_due:"past_due"}[e?.toLowerCase()]||"active"}getPlanAmount(e){return{"basic-monthly":9.99,"premium-monthly":29.99,"basic-annual":99.99,"premium-annual":299.99}[e]||0}getPlanInterval(e,t){if(e?.includes("annual")||e?.includes("yearly"))return"year";if(t)switch(t){case 1:default:return"month";case 3:return"3 months";case 12:return"year";case 24:return"24 months";case 26:return"26 months"}return"month"}attachEventListeners(){this.mainButtonListenerAttached?console.log("[SubscriptionsList] Main button listener already attached, skipping"):(console.log("[SubscriptionsList] Attaching main button listener"),this.addDelegatedListener("#add-subscription-btn, #add-first-subscription-btn","click",(e=>{e.preventDefault(),e.stopPropagation(),console.log("[SubscriptionsList] Subscribe button clicked"),this.showAddSubscriptionModal()})),this.mainButtonListenerAttached=!0),this.addDelegatedListener(".filter-btn","click",(e=>{e.preventDefault();const t=e.target.closest(".filter-btn");if(t){const e=t.dataset.filterType,n=t.dataset.filterValue;e&&n&&this.handleFilterClick(e,n)}})),this.addDelegatedListener('[data-action="clear-filters"]',"click",(e=>{e.preventDefault(),this.clearFilters()}));const e=this.getState();if(this.cleanupCardInstances(),e.data&&e.data.subscriptions){const t=e.data.subscriptions;let n=t;t.length>=3&&this.displaySettings.showFilters&&this.activeFilters&&(n=this.applyFilters(t)),n.forEach((e=>{const t=this.container.querySelector(`[data-subscription="${e.id}"]`);if(t){const n=new wt(t,{subscription:e,onCancel:this.allowCancellation?e=>this.confirmCancelSubscription(e):void 0,onUpdate:e=>this.updateSubscription(e),onChangePayment:async e=>await this.changePaymentMethod(e),onReactivate:e=>this.reactivateSubscription(e)});n.render(),this.subscriptionCardInstances.push(n)}}))}const t=this.container.querySelector('nav[aria-label="Pagination"]');t&&t.addEventListener("click",(t=>{const n=t.target.closest("[data-page]");if(n&&!n.disabled){const t=parseInt(n.dataset.page||"1",10);isNaN(t)||t===e.currentPage||this.handlePageChange(t)}}))}cleanupCardInstances(){this.subscriptionCardInstances.forEach((e=>{})),this.subscriptionCardInstances=[]}showAddSubscriptionModal(){console.log("[SubscriptionsList] showAddSubscriptionModal called");const e=Date.now();if(e-this.lastModalCallTime<this.MODAL_DEBOUNCE_TIME)return void console.log("[SubscriptionsList] Debouncing rapid click");if(this.lastModalCallTime=e,this.isShowingModal||this.activeSubscriptionFlow)return void console.log("[SubscriptionsList] Modal already showing, preventing duplicate",{isShowingModal:this.isShowingModal,hasActiveFlow:!!this.activeSubscriptionFlow});console.log("[SubscriptionsList] Setting isShowingModal to true"),this.isShowingModal=!0,this.activeSubscriptionFlow&&(this.activeSubscriptionFlow.hide?.(),this.activeSubscriptionFlow=null);const t=new St.default({onSuccess:async e=>{try{await this.handleSubscriptionAdded(e),te.Alert.flash({message:Dt,variant:"success"})}catch(e){te.Alert.flash({message:Nt,variant:"error"})}finally{this.activeSubscriptionFlow=null,this.isShowingModal=!1}},onCancel:()=>{this.activeSubscriptionFlow&&this.activeSubscriptionFlow.hide?.(),this.activeSubscriptionFlow=null,this.isShowingModal=!1}});this.activeSubscriptionFlow=t,t.show()}async handleSubscriptionAdded(e){try{await this.render();const t=this.getState(),o=t.data&&t.data.subscriptions?t.data.subscriptions.filter((e=>"active"===e.status)).length:0,{ProfileEvents:i}=await Promise.resolve().then(n.bind(n,8354));i.emit("STATS_UPDATED",{stats:{activeSubscriptions:o}});const a=this.options;return a.onSubscriptionAdded&&a.onSubscriptionAdded(e),{success:!0}}catch(e){throw e}}confirmCancelSubscription(e){const t=this.getState(),n=t.data&&t.data.subscriptions?t.data.subscriptions.find((t=>t.id===e)):null;n&&this.showCancellationModal(n)}showCancellationModal(e){const t=document.createElement("div");t.className="fixed inset-0 z-50 flex items-center justify-center p-4",t.innerHTML=`\n \x3c!-- Backdrop --\x3e\n <div class="absolute inset-0 bg-black/50 backdrop-blur-sm transition-opacity duration-300" data-action="close-modal"></div>\n\n \x3c!-- Modal --\x3e\n <div class="relative bg-white rounded-2xl shadow-2xl w-full max-w-2xl transform transition-all duration-300 scale-95 opacity-0">\n \x3c!-- Header --\x3e\n <div class="px-6 pt-6 pb-4 border-b border-gray-200">\n <div class="flex items-center justify-between">\n <h2 class="text-xl font-bold text-gray-900">Cancel Subscription</h2>\n <button class="p-2 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg transition-colors" data-action="close-modal">\n ${P.H.getIcon("ui","close","w-5 h-5")}\n </button>\n </div>\n </div>\n\n \x3c!-- Content --\x3e\n <div class="p-6">\n \x3c!-- Icon --\x3e\n <div class="mx-auto flex items-center justify-center h-16 w-16 rounded-full bg-yellow-100 mb-4">\n ${P.H.getIcon("status","warning","h-8 w-8 text-yellow-600")}\n </div>\n\n \x3c!-- Message --\x3e\n <div class="text-center mb-6">\n <h3 class="text-lg font-semibold text-gray-900 mb-2">\n Subscription Cancellation\n </h3>\n <p class="text-gray-600 mb-4">\n Cancel your <strong>${e.planName}</strong> subscription.\n </p>\n\n \x3c!-- Current Subscription Info --\x3e\n <div class="bg-gray-50 rounded-lg p-4 mb-4">\n <p class="text-sm text-gray-600 mb-2">Current subscription:</p>\n <div class="space-y-1">\n <p class="font-medium text-gray-900">${e.planName}</p>\n <p class="text-sm text-gray-600">Active until ${this.formatDate(e.currentPeriodEnd)}</p>\n </div>\n </div>\n\n <div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4 mb-4">
1\n <h4 class="font-semibold text-yellow-800 mb-2">Are you sure you want to cancel?</h4>\n <p class="text-sm text-yellow-700">\n ⢠You'll lose access to premium features when your current billing period ends<br>\n ⢠Your subscription will remain active until ${(()=>{const t=e.currentPeriodEnd||e.currentPeriodEndsAt;return t?Fe.Nq.format(t,"long"):"the end of your billing period"})()}<br>\n ⢠You can reactivate your subscription anytime before it expires\n </p>\n </div>\n\n <div class="bg-gray-50 rounded-lg p-4">\n <p class="text-sm text-gray-600 mb-2">\n <strong>What happens next:</strong>\n </p>\n <ul class="text-sm text-gray-600 space-y-1">\n <li>⢠Your card will not be charged again</li>\n <li>⢠You'll receive a confirmation email</li>\n <li>⢠Access continues until the end of your billing period</li>\n </ul>\n </div>\n </div>\n </div>\n\n \x3c!-- Footer --\x3e\n <div class="px-6 py-4 bg-gray-50 border-t border-gray-200 rounded-b-2xl">\n <div class="flex space-x-3">\n <button\n class="flex-1 px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors flex items-center justify-center"\n data-action="confirm-cancel"\n data-subscription-id="${e.id}"\n >\n ${P.H.getIcon("ui","close","w-4 h-4 mr-2")}\n Yes, Cancel Subscription\n </button>\n <button\n class="flex-1 px-4 py-2 bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300 transition-colors"\n data-action="close-modal"\n >\n Keep Subscription\n </button>\n </div>\n </div>\n </div>\n `,document.body.appendChild(t),document.body.classList.add("overflow-hidden"),requestAnimationFrame((()=>{const e=t.querySelector(".absolute"),n=t.querySelector(".relative");e&&e.classList.add("opacity-100"),n&&(n.classList.remove("scale-95","opacity-0"),n.classList.add("scale-100","opacity-100"))}));const n=async e=>{const n=e.target.closest("[data-action]"),o=n?.getAttribute("data-action");if("close-modal"===o)this.closeModal(t);else if("confirm-cancel"===o){const e=n.getAttribute("data-subscription-id");e&&await this.performCancellation(e,t)}};t.addEventListener("click",n),this.cleanup.addCleanupTask((()=>{t.removeEventListener("click",n),t.parentNode&&(t.remove(),document.body.classList.remove("overflow-hidden"))}))}updateSubscription(e){te.Alert.flash({message:"Update functionality coming soon",variant:"info"})}async changePaymentMethod(e){const t=this.getState(),n=t.data&&t.data.subscriptions?t.data.subscriptions.find((t=>t.id===e)):null;n&&await this.showPaymentChangeModal(n)}async showPaymentChangeModal(e){let t="[email protected]";try{const e=await v.initService.getInitData();e?.generalConfig?.companySupportEmail&&(t=e.generalConfig.companySupportEmail)}catch(e){console.error("Failed to get support email:",e)}const n=`\n <div class="text-center py-4">\n <div class="inline-flex items-center justify-center w-16 h-16 bg-blue-100 rounded-full mb-4">\n <svg class="w-8 h-8 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n </div>\n <h3 class="text-lg font-semibold text-gray-900 mb-2">Update Payment Method</h3>\n <p class="text-gray-600 mb-4">\n The ability to update payment methods for subscriptions is coming soon! We're working hard to bring you this feature.\n </p>\n \n ${e.paymentMethod&&"object"==typeof e.paymentMethod?`\n <div class="bg-gray-50 rounded-lg p-4 mb-4">\n <p class="text-xs text-gray-500 mb-2">Current payment method:</p>\n <div class="flex items-center justify-center">
1\n <div class="w-10 h-6 ${bt.U.getCardBackgroundClass(e.paymentMethod.brand)} rounded flex items-center justify-center text-white text-xs font-bold mr-2">\n ${bt.U.getCardBrandShort(e.paymentMethod.brand)}\n </div>\n <span class="font-medium text-gray-900">â¢â¢â¢â¢ ${e.paymentMethod.last4}</span>\n </div>\n </div>\n `:""}\n \n <p class="text-sm text-gray-500">\n For immediate assistance with your <strong>${e.planName}</strong> subscription, please contact our customer support team at \n <a href="mailto:${t}" class="text-blue-600 hover:text-blue-700 font-medium">\n ${t}\n </a>\n </p>\n </div>\n `,o=new we.Modal({title:"Feature Coming Soon",content:n,footer:'\n <div class="flex justify-end">\n <button id="update-payment-close-btn" class="px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">\n Got it\n </button>\n </div>\n ',size:"small",closeButton:!0,closeOnOverlay:!0,closeOnEscape:!0});o.open(),setTimeout((()=>{const e=document.getElementById("update-payment-close-btn");e&&e.addEventListener("click",(()=>{o.close()}))}),100)}async performCancellation(e,t){try{const n=t.querySelector('[data-action="confirm-cancel"]');n.innerHTML;n.disabled=!0,n.innerHTML=`\n ${P.H.getIcon("ui","loader","w-4 h-4 mr-2 animate-spin")}\n Cancelling...\n `;const o=await xt.G.cancelSubscription(e);if(!o.success)throw new Error(o.error?.message||"Failed to cancel subscription");this.closeModal(t),te.Alert.flash({message:"Your subscription has been cancelled. You will continue to have access until the end of your billing period.",variant:"success",duration:5e3}),await this.loadData(),this.render()}catch(e){console.error("Failed to cancel subscription:",e);const n=t.querySelector('[data-action="confirm-cancel"]');n&&(n.disabled=!1,n.innerHTML=`\n ${P.H.getIcon("ui","close","w-4 h-4 mr-2")}\n Yes, Cancel Subscription\n `),te.Alert.flash({message:e instanceof Error?e.message:"Failed to cancel subscription. Please try again.",variant:"error",duration:4e3})}}closeModal(e){const t=e.querySelector(".absolute"),n=e.querySelector(".relative");t&&t.classList.remove("opacity-100"),n&&(n.classList.remove("scale-100","opacity-100"),n.classList.add("scale-95","opacity-0")),this.setTimeout((()=>{e.remove(),document.body.classList.remove("overflow-hidden")}),300)}async reactivateSubscription(e){const t=this.getState(),n=t.data&&t.data.subscriptions?t.data.subscriptions.find((t=>t.id===e)):null;if(n)try{te.Alert.flash({message:"Reactivating your subscription...",variant:"info",duration:2e3}),await new Promise((e=>this.setTimeout((()=>e()),1500))),n.cancelAtPeriodEnd=!1,n.status="active",await this.render(),te.Alert.flash({message:It,variant:"success",duration:5e3})}catch(e){te.Alert.flash({message:Lt,variant:"error"})}}formatDate(e){return Fe.Nq.formatSubscriptionDate(e).display||"N/A"}async getRecurlyKey(){if(window.HeimGuard?.authSystem?.authConfig){const e=window.HeimGuard.authSystem.authConfig.getRecurlyPublicKey();if(e)return e}try{const e=await fetch(f.A.apiHeimguardInitUrl,{credentials:"include"});if(e.ok){const t=await e.json();return t.recurlyPublicKey||t.recurly_public_key}}catch(e){}return null}async fetchAddresses(){try{const e=await fetch(f.A.apiGetAllAddresses,{credentials:"include"});if(e.ok){const t=await e.json();if(t.addresses)return"object"!=typeof t.addresses||Array.isArray(t.addresses)?t.addresses:Object.values(t.addresses)}return[]}catch(e){return[]}}async savePaymentMethod(e){const t={recurlyToken:e.tokenId,cardholderName:e.cardholderName,firstName:e.billingAddress.firstName,lastName:e.billingAddress.lastName,billingAddressId:e.billingAddress.id,isDefault:!1,saveCard:!0},n=await fetch(f.A.apiAddPaymentMethodUrl,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(t)});if(!n.ok&&200!==n.status){const e=await n.json().catch((()=>({})));throw new Error(e.message||"Failed to save payment method")}return n}renderFilters(e){const t=[...new Set(e.map((e=>e.status)))],n=[...new Set(e.map((e=>e.interval)))],o=["all",...t],i=["all",...n],a=0===this.activeFilters.status.length?"all":1===this.activeFilters.status.length?this.activeFilters.status[0]:"all",s=0===this.activeFilters.interval.length?"all":1===this.activeFilters.interval.length?this.activeFilters.interval[0]:"all";return`\n <div class="flex flex-col sm:flex-row gap-4 mb-6">\n \x3c!-- Status Filter --\x3e\n <div class="flex items-center gap-2">
1\n <span class="text-sm font-medium text-gray-700">Status:</span>\n <div class="inline-flex rounded-lg shadow-sm" role="group">\n ${o.map(((e,t)=>`\n <button\n type="button"\n class="filter-btn ${0===t?"rounded-l-lg":""} ${t===o.length-1?"rounded-r-lg -ml-px":"-ml-px"} ${a===e?"bg-primary-600 text-white border-primary-600 hover:bg-primary-700 z-10":"bg-white text-gray-700 border-gray-300 hover:bg-gray-50"} relative inline-flex items-center px-3 py-1.5 text-sm font-medium border focus:z-10 focus:outline-none focus:ring-2 focus:ring-primary-500 transition-colors"\n data-filter-type="status"\n data-filter-value="${e}"\n >\n ${"all"===e?"All":this.getStatusLabel(e)}\n </button>\n `)).join("")}\n </div>\n </div>\n\n \x3c!-- Interval Filter - Only show if there are multiple intervals --\x3e\n ${n.length>1?`\n <div class="flex items-center gap-2">\n <span class="text-sm font-medium text-gray-700">Billing:</span>\n <div class="inline-flex rounded-lg shadow-sm" role="group">\n ${i.map(((e,t)=>`\n <button\n type="button"\n class="filter-btn ${0===t?"rounded-l-lg":""} ${t===i.length-1?"rounded-r-lg -ml-px":"-ml-px"} ${s===e?"bg-primary-600 text-white border-primary-600 hover:bg-primary-700 z-10":"bg-white text-gray-700 border-gray-300 hover:bg-gray-50"} relative inline-flex items-center px-3 py-1.5 text-sm font-medium border focus:z-10 focus:outline-none focus:ring-2 focus:ring-primary-500 transition-colors"\n data-filter-type="interval"\n data-filter-value="${e}"\n >\n ${"all"===e?"All":this.getIntervalLabel(e)}\n </button>\n `)).join("")}\n </div>\n </div>\n `:""}\n\n \x3c!-- Active filter indicator --\x3e\n ${this.activeFilters.status.length>0||this.activeFilters.interval.length>0?`\n <div class="flex items-center gap-2 ml-auto">\n <span class="text-xs text-gray-500">\n ${this.getActiveFilterCount()} filter${this.getActiveFilterCount()>1?"s":""} active\n </span>\n <button\n class="text-xs text-primary-600 hover:text-primary-700 font-medium"\n data-action="clear-filters"\n >\n Clear\n </button>\n </div>\n `:""}\n </div>\n `}getActiveFilterCount(){return(this.activeFilters.status.length>0?1:0)+(this.activeFilters.interval.length>0?1:0)}applyFilters(e){return e.filter((e=>{if(this.activeFilters.status.length>0){const t=this.activeFilters.status,n=t.includes("active");if(!(t.includes(e.status)||n&&"canceled"===e.status))return!1}return!(this.activeFilters.interval.length>0&&!this.activeFilters.interval.includes(e.interval))}))}getStatusLabel(e){return{active:"Active",trialing:"Trial",past_due:"Past Due",canceled:"Canceled",paused:"Paused",expired:"Expired"}[e]||e}getIntervalLabel(e){return{month:"Monthly",year:"Annual",week:"Weekly",day:"Daily"}[e]||e}handleFilterClick(e,t){this.activeFilters[e]="all"===t?[]:[t],this.updateFilterUI(),this.updateSubscriptionCards()}clearFilters(){this.activeFilters={status:[],interval:[]},this.updateFilterUI(),this.updateSubscriptionCards()}updateFilterUI(){this.container.querySelectorAll(".filter-btn").forEach((e=>{const t=e.getAttribute("data-filter-type"),n=e.getAttribute("data-filter-value");if(t&&n){("all"===n?0===this.activeFilters[t].length:this.activeFilters[t].includes(n))?(e.classList.remove("bg-white","text-gray-700","border-gray-300","hover:bg-gray-50"),e.classList.add("bg-primary-600","text-white","border-primary-600","hover:bg-primary-700","z-10")):(e.classList.remove("bg-primary-600","text-white","border-primary-600","hover:bg-primary-700","z-10"),e.classList.add("bg-white","text-gray-700","border-gray-300","hover:bg-gray-50"))}}));const e=this.activeFilters.status.length>0||this.activeFilters.interval.length>0,t=this.container.querySelector(".flex.items-center.gap-2.ml-auto");if(t)if(e){t.classList.remove("hidden");const e=t.querySelector(".text-xs.text-gray-500");if(e){const t=this.getActiveFilterCount();e.textContent=`${t} filter${t>1?"s":""} active`}}else t.classList.add("hidden")}updateSubscriptionCards(){const e=this.getState();if(!e.data||!e.data.subscriptions)return;const t=e.data.subscriptions,n=this.applyFilters(t);this.container.querySelectorAll("[data-subscription]").forEach((e=>{e.style.display="none"}
1)),n.forEach((e=>{const t=this.container.querySelector(`[data-subscription="${e.id}"]`);t&&(t.style.display="flex")}));const o=this.container.querySelector(".grid"),i=this.container.querySelector(".text-center.py-12");if(0===n.length&&(this.activeFilters.status.length>0||this.activeFilters.interval.length>0)){if(!i&&o){const e=`\n <div class="text-center py-12 col-span-full">\n <div class="text-gray-400 mb-4">\n ${P.H.getIcon("general","search","w-12 h-12 mx-auto")}\n </div>\n <p class="text-gray-600 font-medium">No subscriptions match your filters</p>\n <button class="mt-3 text-primary-600 hover:text-primary-700 text-sm font-medium" data-action="clear-filters">\n Clear filters\n </button>\n </div>\n `;o.insertAdjacentHTML("afterend",e)}}else i&&i.remove()}async onDestroy(){this.cleanupCardInstances(),this.activeSubscriptionFlow&&(this.activeSubscriptionFlow.hide?.(),this.activeSubscriptionFlow=null),this.isShowingModal=!1}async refresh(){this.activeSubscriptionFlow&&(this.activeSubscriptionFlow.hide?.(),this.activeSubscriptionFlow=null),this.isShowingModal=!1,await this.render()}}var Ot=kt;class Rt{constructor(e={}){this.config={autoScan:!0,containerSelector:"[data-subscriptions-container]",tagName:"HgSubscriptions",apiBaseUrl:e.apiBaseUrl||"/api/heimguard",...e},this.instances=new Map,this.api=xt.G,this.isInitialized=!1,this.config.autoScan&&this.initialize()}async initialize(){if(!this.isInitialized)try{this.config.autoScan&&await this.scanAndRenderTags(),this.setupEventListeners(),this.isInitialized=!0,b.vF.debug("SubscriptionsSystem initialized","general")}catch(e){b.vF.error("Failed to initialize SubscriptionsSystem:","general",e)}}async scanAndRenderTags(){const e=document.getElementsByTagName(this.config.tagName);for(const t of Array.from(e))await this.renderSubscriptions(t);const t=document.querySelectorAll(this.config.containerSelector);for(const e of Array.from(t))this.instances.has(e)||await this.renderSubscriptions(e)}async renderSubscriptions(e,t={}){if(this.instances.has(e)){const t=this.instances.get(e);return await t.render(),t}try{const n={};e.dataset.displayMode&&(n.displayMode=e.dataset.displayMode),void 0!==e.dataset.showFilters&&(n.showFilters="true"===e.dataset.showFilters),void 0!==e.dataset.showSort&&(n.showSort="true"===e.dataset.showSort),void 0!==e.dataset.showLegend&&(n.showLegend="true"===e.dataset.showLegend),void 0!==e.dataset.showProgress&&(n.showProgress="true"===e.dataset.showProgress);const o=new Ot(e,{api:this.api,...n,...t,onSubscriptionAdded:e=>{this.handleSubscriptionAdded(e)},onSubscriptionCancelled:e=>{this.handleSubscriptionCancelled(e)},onSubscriptionUpdated:e=>{this.handleSubscriptionUpdated(e)},onSubscriptionReactivated:e=>{this.handleSubscriptionReactivated(e)}});return await o.render(),this.instances.set(e,o),o}catch(e){throw console.error("Failed to render subscriptions:",e),e}}setupEventListeners(){document.addEventListener(At,(async e=>{await this.refreshAll()})),document.addEventListener("payment:methods:updated",(async e=>{await this.refreshAll()})),document.addEventListener("heimguard:logout",(()=>{this.cleanup()})),document.addEventListener("heimguard:profile:sectionChange",(e=>{"subscriptions"===e.detail.section&&this.refreshAll()}))}handleSubscriptionAdded(e){const t=new CustomEvent(Tt,{detail:{subscription:e},bubbles:!0});document.dispatchEvent(t),this.refreshAll()}handleSubscriptionCancelled(e){const t=new CustomEvent(Mt,{detail:{id:e},bubbles:!0});document.dispatchEvent(t),this.refreshAll()}handleSubscriptionUpdated(e){const t=new CustomEvent(Et,{detail:{subscription:e},bubbles:!0});document.dispatchEvent(t),this.refreshAll()}handleSubscriptionReactivated(e){const t=new CustomEvent(Pt,{detail:{id:e},bubbles:!0});document.dispatchEvent(t),this.refreshAll()}async refreshAll(){const e=[];for(const[t,n]of this.instances)n.render&&e.push(n.render());await Promise.all(e)}async getSubscriptions(){const e=await this.api.getSubscriptions();if(!e.success||!e.data)return[];let t=[];return Array.isArray(e.data.subscriptions)?t=e.data.subscriptions:e.data.subscriptions&&"object"==typeof e.data.subscriptions&&(t=Object.values(e.data.subscriptions)),t.map((e=>({...e,planId:e.planCode,subscriptionState:e.status,amount:e.unitAmou
1nt,intervalCount:e.intervalLength,currentPeriodStart:e.currentPeriodStartedAt,currentPeriodEnd:e.currentPeriodEndsAt,cancelAtPeriodEnd:!1,paymentMethod:void 0})))}async getAvailablePlans(){const e=await this.api.getAvailablePlans();return e?.data?.plans||[]}async createSubscription(e,t){const n=await this.api.createSubscription({planCode:e,billingInfoId:t});if(!n.success||!n.data)throw new Error("Failed to create subscription");const o=n.data;return{...o,planId:o.planId||o.planCode,subscriptionState:o.status,amount:o.amount||0,intervalCount:o.intervalCount||1,currentPeriodStart:o.currentPeriodStart||"",currentPeriodEnd:o.currentPeriodEnd||"",cancelAtPeriodEnd:!1,paymentMethod:void 0}}async cancelSubscription(e){if(!(await this.api.cancelSubscription(e)).success)throw new Error("Failed to cancel subscription")}async reactivateSubscription(e){const t=await this.api.updateSubscription({id:e,planCode:void 0});if(!t.success||!t.data)throw new Error("Failed to reactivate subscription");return t.data}async updateSubscription(e,t){const n=await this.api.updateSubscription({id:e,planCode:t.planCode,paymentMethodId:t.paymentMethodId});if(n.success&&n.data)return n.data;throw new Error("Failed to update subscription")}cleanup(){for(const[e,t]of this.instances)t.cleanup&&t.cleanup();this.instances.clear(),this.isInitialized=!1}static async render(e,t={}){const n=new Rt({autoScan:!1,...t});return await n.initialize(),await n.renderSubscriptions(e,t)}static async showSubscriptionFlow(e={}){const{default:t}=await Promise.resolve().then(n.bind(n,3039)),o=new t({onSuccess:async t=>{const n=new CustomEvent(Tt,{detail:{subscription:t},bubbles:!0});document.dispatchEvent(n),e.onSuccess&&await e.onSuccess(t)},onCancel:e.onCancel,...e});return o.show(),o}}var Bt=Rt;const $t=new class{constructor(){this.name="subscriptionsSystem",this.subscriptionsSystem=null}async initialize(){b.vF.debug("Initializing subscriptions system...","general");const{systemRegistry:e}=await Promise.resolve().then(n.bind(n,1667));this.subscriptionsSystem=new Bt({autoScan:!0}),await this.subscriptionsSystem.initialize(),e.registerInstance("subscriptionsSystem",this.subscriptionsSystem),b.vF.debug("Subscriptions system initialized successfully","general")}cleanup(){this.subscriptionsSystem&&(this.subscriptionsSystem.cleanup(),this.subscriptionsSystem=null)}async getSubscriptions(){if(!this.subscriptionsSystem)throw new Error("SubscriptionsSystem not initialized");return(await this.subscriptionsSystem.getSubscriptions()).map((e=>({...e,planId:e.planId||e.planCode,subscriptionState:e.status,amount:e.amount||0,intervalCount:e.intervalCount||1,currentPeriodStart:e.currentPeriodStart||"",currentPeriodEnd:e.currentPeriodEnd||"",cancelAtPeriodEnd:e.cancelAtPeriodEnd||!1,paymentMethod:e.paymentMethod})))}async getAvailablePlans(){if(!this.subscriptionsSystem)throw new Error("SubscriptionsSystem not initialized");return this.subscriptionsSystem.getAvailablePlans()}async createSubscription(e,t){if(!this.subscriptionsSystem)throw new Error("SubscriptionsSystem not initialized");return this.subscriptionsSystem.createSubscription(e,t)}async cancelSubscription(e){if(!this.subscriptionsSystem)throw new Error("SubscriptionsSystem not initialized");return this.subscriptionsSystem.cancelSubscription(e)}async reactivateSubscription(e){if(!this.subscriptionsSystem)throw new Error("SubscriptionsSystem not initialized");const t=await this.subscriptionsSystem.reactivateSubscription(e);return{...t,planId:t.planId||t.planCode,subscriptionState:t.status,amount:t.amount||0,intervalCount:t.intervalCount||1,currentPeriodStart:t.currentPeriodStart||"",currentPeriodEnd:t.currentPeriodEnd||"",cancelAtPeriodEnd:t.cancelAtPeriodEnd||!1,paymentMethod:t.paymentMethod}}async updateSubscription(e,t){if(!this.subscriptionsSystem)throw new Error("SubscriptionsSystem not initialized");const n={planCode:t.planCode||t.planId,amount:t.amount,intervalCount:t.intervalCount},o=await this.subscriptionsSystem.updateSubscription(e,n);return{...o,planId:o.planId||o.planCode,subscriptionState:o.status,amount:o.amount||0,intervalCount:o.intervalCount||1,currentPeriodStart:o.currentPeriodStart||"",currentPeriodEnd:o.currentPeriodEnd||"",cancelAtPeriodEnd:o.cancelAtPeriodEnd||!1,paymentMethod:o.paymentMethod}}async refreshAll(){if(!this.subscriptionsSystem)throw new Error("SubscriptionsSystem not initialized");return this.subscriptionsSystem.refreshAll()}
1async renderSubscriptions(e,t={}){if(!this.subscriptionsSystem)throw new Error("SubscriptionsSystem not initialized");return this.subscriptionsSystem.renderSubscriptions(e,t)}static async showSubscriptionFlow(e={}){return Bt.showSubscriptionFlow(e)}};"undefined"!=typeof window&&(["auth:login:success","auth:register:success","auth:state:changed"].forEach((e=>{try{(document._listeners?.[e]||[]).forEach((t=>{document.removeEventListener(e,t)}))}catch(t){console.log(`[SubscriptionFlow] Attempted cleanup of ${e} listeners`)}})),console.log("[SubscriptionFlow] Cleaned up stale authentication event listeners"),A.systemRegistry.register("subscriptionsSystemAdapter",$t),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>{$t.initialize()})):$t.initialize());var Ut=n(8231);const Ft="paid",zt="pending",Ht="failed",Gt="voided",_t="refunded",Kt="past_due",jt="processing",Vt="overdue",qt="cancelled",Wt="all",Zt="date_desc",Yt="date_asc",Jt="amount_desc",Qt="amount_asc",Xt={[Ft]:{label:"Paid",bgColor:"bg-green-100",textColor:"text-green-800",icon:"check"},[zt]:{label:"Pending",bgColor:"bg-yellow-100",textColor:"text-yellow-800",icon:"clock"},[Ht]:{label:"Failed",bgColor:"bg-red-100",textColor:"text-red-800",icon:"error"},[Gt]:{label:"Voided",bgColor:"bg-gray-100",textColor:"text-gray-800",icon:"void"},[_t]:{label:"Refunded",bgColor:"bg-secondary-100",textColor:"text-secondary-800",icon:"refund"},[Kt]:{label:"Past Due",bgColor:"bg-orange-100",textColor:"text-orange-800",icon:"warning"},[jt]:{label:"Processing",bgColor:"bg-blue-100",textColor:"text-blue-800",icon:"processing"},[Vt]:{label:"Overdue",bgColor:"bg-orange-100",textColor:"text-orange-800",icon:"warning"},[qt]:{label:"Cancelled",bgColor:"bg-gray-100",textColor:"text-gray-800",icon:"cancel"}};class en extends Ut.pZ{constructor(){super({baseURL:f.A.apiBaseUrl}),b.vF.debug(`Initialized with baseURL: ${this.baseURL}`,"api")}async getInvoices(e={}){const{page:t=1,pageSize:n=50}=e;try{const e=f.A.apiGetInvoicesUrl.replace(f.A.apiBaseUrl,""),o=await this.get(e,{params:{pageNumber:t,pageSize:n}});if(o.data&&"error"===o.data.status)return{success:!0,data:{invoices:[],pagesCount:0,totalCount:0}};if(o.success&&o.data&&o.data.invoices){return{success:!0,data:this.transformInvoiceResponse(o.data)}}return{success:!0,data:{invoices:[],pagesCount:0,totalCount:0}}}catch(e){throw e}}async collectInvoice(e,t){if(!e)throw new Error("Invoice ID is required");const n={invoiceId:e,recurlyToken:t.recurlyToken,billingAddressId:t.billingAddressId,default:t.default||!1};t.accountId&&(n.accountId=t.accountId,console.log("[InvoicesAPI] Including accountId in collect-invoice request:",t.accountId)),console.log("[InvoicesAPI] Collect invoice request body:",JSON.stringify(n,null,2));try{return await this.post("/profile/invoices/collect-invoice",n,{credentials:"include"})}catch(e){throw e}}async downloadInvoicePdf(e){if(!e)throw new Error("Invoice ID is required");const t=await fetch(`${f.A.apiGetInvoicePdfUrl}?invoiceId=${e}`,{method:"GET",credentials:"include",headers:{Accept:"application/pdf"}});if(!t.ok)throw new Error(`Failed to download invoice: ${t.statusText}`);const n=await t.blob();if(0===n.size)throw new Error("Received empty PDF file");const o=window.URL.createObjectURL(n),i=document.createElement("a");i.href=o,i.download=`invoice-${e}.pdf`,i.style.display="none";try{document.body.appendChild(i),i.click()}finally{document.body.removeChild(i),window.URL.revokeObjectURL(o)}return n}transformInvoiceResponse(e){if(!e||!e.invoices)return{invoices:[],pagesCount:0,totalCount:0};return{invoices:Object.entries(e.invoices).map((([e,t])=>({id:t.invoiceId||t.id||`inv_${e}`,invoiceId:t.invoiceId,invoiceNumber:t.invoiceNumber,subscriptionId:t.subscriptionId,amount:void 0!==t.total?t.total:t.invoiceBalance,currency:t.currency||"USD",status:this.mapInvoiceState(t.invoiceState),dueDate:t.dueDate,paidAt:"paid"===t.invoiceState?t.invoiceCreationDate:void 0,createdAt:t.invoiceCreationDate,lineItems:t.items?.map(((e,t)=>({id:e.id||`item_${t}`,description:e.description,amount:e.amount,quantity:e.quantity}))),downloadUrl:void 0,accountId:t.accountId,isOutstandingInvoice:t.isOutstandingInvoice||!1}))),pagesCount:e.pagesCount||1,totalCount:e.totalCount,userActiveAccountsIds:e.userActiveAccountsIds||[]}}mapInvoiceState(e){return{paid:Ft,open:zt,pending:zt,past_due:Kt,failed:Ht,voided:Gt,closed:Ft}[e]||zt}}const tn=new en;var nn=n(6534);const on={INVOICES_LOADING:"invoices:loading",INVOICES_LOADED:"invoices:loaded",INVOICES_ERROR:"invoices:error",INVOICES_UPDATED:"invoices:updated",INVOICE_DOWNLOAD_CLICKED:"invoice:download:clicked",INVOICE_DOWNLOAD_SUCCESS:"invoice:download:success",INVOICE_DOWNLOAD_ERROR:"invoice:download:error",INVOICE_FILTER_CHANGED:"invoice:filter:changed",INVOICE_SEARCH_CHANGED:"invoice:search:changed",INVOICE_SORT_CHANGED:"invoice:sort:changed",INVOICE_PAGE_CHANGED:"invoice:page:changed",INVOICE_MODAL_OPEN:"invoice:modal:open",INVOICE_MODAL_CLOSE:"invoice:modal:close",INVOICE_EXPORT_CLICKED:"invoice:export:clicked"},an=new nn.b({namespace:"invoice",debug:!1});function sn(e,t={}){const n={timestamp:Date.now(),...t};
1an.emit(e,n)}function rn(e,t,n){return an.on(e,t,n)}var dn=new class{constructor(){this.invoices=[],this.filteredInvoices=[],this.isLoading=!1,this.error=null,this.currentFilter=Wt,this.currentSort=Zt,this.searchQuery="",this.currentPage=1,this.itemsPerPage=10,this.lastFetch=null,this.cacheTimeout=3e5}convertAPIInvoice(e){return{id:e.id||e.invoiceId,invoiceId:e.invoiceId,invoiceNumber:e.invoiceNumber,number:e.invoiceNumber,date:e.invoiceCreationDate,dueDate:e.dueDate,paidDate:void 0,amount:e.invoiceBalance,currency:e.currency||"CAD",status:this.mapInvoiceState(e.invoiceState),description:`Invoice #${e.invoiceNumber}`,accountUserName:e.accountUserName}}mapInvoiceState(e){return{paid:Ft,open:zt,pending:zt,past_due:Kt,overdue:Vt,failed:Ht,voided:qt,closed:Ft}[e]||zt}async loadInvoices(e=!1){if(!e&&this.isCacheValid())return this.invoices;this.isLoading=!0,this.error=null,sn(on.INVOICES_LOADING);try{const e=await tn.getInvoices();if(e.success&&e.data){const t=e.data.invoices||{},n=Object.values(t);return this.invoices=n.map((e=>this.convertAPIInvoice(e))),this.lastFetch=Date.now(),this.applyFiltersAndSort(),sn(on.INVOICES_LOADED,{invoices:this.invoices,count:this.invoices.length}),this.invoices}throw new Error("Failed to load invoices")}catch(e){throw this.error=e instanceof Error?e.message:"Unknown error",sn(on.INVOICES_ERROR,{error:this.error}),e}finally{this.isLoading=!1}}isCacheValid(){return null!==this.lastFetch&&Date.now()-this.lastFetch<this.cacheTimeout&&this.invoices.length>0}getInvoiceById(e){return this.invoices.find((t=>t.id===e))||null}applyFiltersAndSort(){let e=[...this.invoices];if(this.currentFilter!==Wt&&(e=e.filter((e=>e.status===this.currentFilter))),this.searchQuery){const t=this.searchQuery.toLowerCase();e=e.filter((e=>e.number?.toLowerCase().includes(t)||e.description?.toLowerCase().includes(t)||e.id?.toLowerCase().includes(t)))}e.sort(((e,t)=>{switch(this.currentSort){case Yt:return new Date(e.date).getTime()-new Date(t.date).getTime();case Zt:return new Date(t.date).getTime()-new Date(e.date).getTime();case Qt:return e.amount-t.amount;case Jt:return t.amount-e.amount;default:return new Date(t.date).getTime()-new Date(e.date).getTime()}})),this.filteredInvoices=e,this.resetPagination(),sn(on.INVOICES_UPDATED,{invoices:this.filteredInvoices,filter:this.currentFilter,sort:this.currentSort,search:this.searchQuery})}setFilter(e){this.currentFilter!==e&&(this.currentFilter=e,this.applyFiltersAndSort(),sn(on.INVOICE_FILTER_CHANGED,{filter:e}))}setSort(e){this.currentSort!==e&&(this.currentSort=e,this.applyFiltersAndSort(),sn(on.INVOICE_SORT_CHANGED,{sort:e}))}setSearchQuery(e){this.searchQuery!==e&&(this.searchQuery=e,this.applyFiltersAndSort(),sn(on.INVOICE_SEARCH_CHANGED,{query:e}))}setCurrentPage(e){const t=this.getTotalPages();e>=1&&e<=t&&e!==this.currentPage&&(this.currentPage=e,sn(on.INVOICE_PAGE_CHANGED,{page:e}))}getPaginatedInvoices(){const e=(this.currentPage-1)*this.itemsPerPage,t=e+this.itemsPerPage;return this.filteredInvoices.slice(e,t)}getTotalPages(){return Math.ceil(this.filteredInvoices.length/this.itemsPerPage)}resetPagination(){this.currentPage=1}async downloadInvoicePdf(e){sn(on.INVOICE_DOWNLOAD_CLICKED,{invoiceId:e});try{await tn.downloadInvoicePdf(e),sn(on.INVOICE_DOWNLOAD_SUCCESS,{invoiceId:e})}catch(t){const n=t instanceof Error?t.message:"Unknown error";throw sn(on.INVOICE_DOWNLOAD_ERROR,{invoiceId:e,error:n}),t}}getStatistics(){const e={total:this.invoices.length,totalAmount:0,byStatus:{},recentInvoices:[]};return this.invoices.forEach((t=>{e.totalAmount+=t.amount||0,e.byStatus[t.status]=(e.byStatus[t.status]||0)+1})),e.recentInvoices=this.invoices.sort(((e,t)=>new Date(t.date).getTime()-new Date(e.date).getTime())).slice(0,5),e}reset(){this.invoices=[],this.filteredInvoices=[],this.isLoading=!1,this.error=null,this.currentFilter=Wt,this.currentSort=Zt,this.searchQuery="",this.currentPage=1,this.lastFetch=null}getInvoices(){return[...this.invoices]}getFilteredInvoices(){return[...this.filteredInvoices]}getIsLoading(){return this.isLoading}getError(){return this.error}getCurrentFilter(){return this.currentFilter}getCurrentSort(){return this.currentSort}getSearchQuery(){return this.searchQuery}getCurrentPage(){return this.currentPage}getItemsPerPage(){return this.itemsPerPage}};var ln=new class{constructor(){this.baseUrl=f.A.apiBaseUrl||"/api/heimguard"}get apiEndpoints(){return{invoices:f.A.apiGetInvoicesUrl||`${this.baseUrl}/profile/invoices/all`,invoicePdf:f.A.apiGetInvoicePdfUrl||`${this.baseUrl}/profile/invoice-pdf`,downloadInvoice:`${this.baseUrl}/profile/invoice/download`}}get displaySettings(){return{invoicesPerPage:10,showPdfDownload:!0,show
1Filters:!0,showSearch:!0,showPagination:!0,dateFormat:"medium",currencyDisplay:"symbol"}}get features(){return{enablePdfDownload:!0,enableCsvExport:!1,enableBulkDownload:!1,enableAdvancedFilters:!1,enableInvoiceDetails:!0}}getMessage(e,t){return{error:{loadFailed:"Failed to load invoices. Please try again.",downloadFailed:"Failed to download invoice. Please try again.",pdfFailed:"Failed to generate PDF. Please try again.",noInvoices:"No invoices found."},success:{downloaded:"Invoice downloaded successfully.",exported:"Invoices exported successfully."},empty:{noInvoices:"No invoices yet",noInvoicesDesc:"You don't have any invoices yet. They'll appear here once you make a purchase.",noResults:"No invoices match your criteria",noResultsDesc:"Try adjusting your filters or search terms."}}[e]?.[t]||""}get validation(){return{maxSearchLength:100,validStatuses:["paid","pending","failed","voided","refunded","past_due"],dateRangeMaxDays:365}}};var cn=class{constructor(){this.manager=dn,this.config=ln,this.activeDownloads=new Set,this.recentDownloads=new Map,this.DOWNLOAD_COOLDOWN=2e3}async downloadInvoicePdf(e,t=null){if(this.activeDownloads.has(e))return void console.warn("[InvoiceDownloadHandler] Download already in progress for:",e);const n=Date.now(),o=this.recentDownloads.get(e);if(o&&n-o<this.DOWNLOAD_COOLDOWN)return console.warn(`[InvoiceDownloadHandler] Download cooldown active for ${e}. Please wait.`),void te.Alert.warning("Please wait a moment before downloading again");this.activeDownloads.add(e),this.recentDownloads.set(e,n),this.cleanupOldDownloads();let i=null;t&&(i=t.innerHTML,t.innerHTML=`\n ${P.H.render("loader",{class:"animate-spin w-4 h-4 mr-2"})} Downloading...\n `,t instanceof HTMLButtonElement&&(t.disabled=!0));try{await this.manager.downloadInvoicePdf(e),te.Alert.success("Invoice downloaded successfully")}catch(e){console.error("[InvoiceDownloadHandler] Download failed:",e);const t=this.config?.getMessage?this.config.getMessage("error","downloadFailed"):"Failed to download invoice";te.Alert.error(t)}finally{this.activeDownloads.delete(e),t&&i&&(t.innerHTML=i,t instanceof HTMLButtonElement&&(t.disabled=!1))}}cleanupOldDownloads(){const e=Date.now(),t=5*this.DOWNLOAD_COOLDOWN;for(const[n,o]of this.recentDownloads.entries())e-o>t&&this.recentDownloads.delete(n)}async downloadMultipleInvoices(e){if(!e||0===e.length)return void te.Alert.warning("Please select invoices to download");const t=this.showDownloadProgress(e.length);let n=0;const o=[];for(const i of e)try{await this.downloadInvoicePdf(i),n++,this.updateProgress(t,n,e.length)}catch(e){o.push({invoiceId:i,error:e instanceof Error?e.message:"Unknown error"})}t&&t.close(),0===o.length?te.Alert.success(`Downloaded ${n} invoice${n>1?"s":""}`):te.Alert.warning(`Downloaded ${n} of ${e.length} invoices. ${o.length} failed.`)}showDownloadProgress(e){return console.log(`[InvoiceDownloadHandler] Downloading ${e} invoices...`),null}updateProgress(e,t,n){console.log(`[InvoiceDownloadHandler] Progress: ${t}/${n}`)}exportToCsv(e){if(e&&0!==e.length)try{const t=this.generateCsv(e),n=new Blob([t],{type:"text/csv;charset=utf-8;"}),o=document.createElement("a"),i=URL.createObjectURL(n);o.setAttribute("href",i),o.setAttribute("download",`invoices_${(new Date).toISOString().split("T")[0]}.csv`),o.style.visibility="hidden",document.body.appendChild(o),o.click(),document.body.removeChild(o),te.Alert.success("Invoices exported successfully")}catch(e){console.error("[InvoiceDownloadHandler] Export failed:",e),te.Alert.error("Failed to export invoices")}else te.Alert.warning("No invoices to export")}generateCsv(e){const t=e.map((e=>[e.number||e.id,new Date(e.date).toLocaleDateString(),e.amount.toString(),e.currency||"CAD",e.status,e.description||""]));return[["Invoice Number","Date","Amount","Currency","Status","Description"].join(","),...t.map((e=>e.map((e=>`"${e}"`)).join(",")))].join("\n")}cleanup(){this.activeDownloads.clear(),this.recentDownloads.clear()}};class un extends tt.A{constructor(e,t={}){super(e,t),this.invoiceApi=tn,this.config=ln,this.eventListenersAttached=!1,this.downloadHandler=t.downloadHandler||new cn}getDefaultOptions(){return{autoInit:!0,debug:!1}}getInitialState(){return{isLoading:!0,error:null,data:null,profileData:this.options.profileData,invoices:[],filteredInvoices:[],currentPage:1,itemsPerPage:10,totalPages:1,activeFilter:Wt,availableStatuses:new Set}}async onInit(){this.store.subscribe(((e,t,n)=>{(n.includes("data")||n.includes("activeFilter")||n.includes("currentPage"))&&!e.isLoading&&this.updateContent()})),this.setupEventListeners()}getComponentClassName(){return"hg-invoices"}getComponentName(){return"invoices"}getHeaderConfig(){return{icon:De.b.icons.invoice,title:"Invoices",subtitle:"View and download your billing history",actions:()=>this.renderHeaderActions()}}getLoadingMessage(){return"Loading your invoices..."}shouldUpdateHeaderActions(){const e=this.getState();return!(!e.data||!e.data.availableStatuses)&&e.data.availableStatuses.size>1}convertAPIInvoice(e){let t=!1;"paid"===e.invoiceState||"paid"===e.status||void 0!==e.invoiceBalance&&e.invoiceBalance<=0&&("paid"===e.invoiceState||"paid"===e.status)||(t=void 0!==e.isOutstandingInvoice?e.isOutstandingInvoice:"open"===e.status&&(e.amount>0||e.invoiceBalance>0));return{id:e.id||e.invoiceId,invoiceId:e.invoiceId,invoiceNumber:e.invoiceNumber,number:e.invoiceNumber,date:e.invoiceCreationDate||e.createdAt||(new Date).toISOString(),dueDate:e.dueDate,paidDate:"paid"===e.invoiceState?e.invoiceCreationDate:void 0,amount:void 0!==e.total?e.total:void 0!==e.amount?e.amount:e.invoiceBalance,paidAmount:"paid"===e.invoiceState?e.invoiceBalance:void 0,currency:e.currency||"CAD",status:e.status||this.mapInvoiceState(e.invoiceState),description:`Invoice #${e.invoiceNumber}`,accountUserName:e.accountUserName||"",accountId:e.accountId||"",isOutstandingInvoice:t}}mapInvoiceState(e){return{paid:Ft,open:zt,pending:zt,past_due:Kt,overdue:Vt,failed:Ht,voided:qt,closed:Ft}[e?.toLowerCase()]||zt}async loadData(){const e=this.getState(),t={page:e.currentPage,pageSize:e.itemsPerPage};try{const n=await this.invoiceApi.getInvoices(t);if(n.success&&n.data){let t;if(Array.isArray(n.data.invoices))t=n.data.invoices;else{const e=n.data.invoices||{};t=Object.values(e)}const o=t.map((e=>this.convertAPIInvoice(e))),i=new Set(o.map(((e,t,n)=>e.status))),a=this.applyFilters(o),s=n.data.pagesCount||Math.ceil(a.length/e.itemsPerPage),r=n.data.userActiveAccountsIds||[];this.setState({userActiveAccountsIds:r});return{invoices:o,filteredInvoices:a,availableStatuses:i,totalPages:Math.max(1,s),totalCount:n.data.totalCount,currentPage:e.currentPage,serverPagination:!!n.data.pagesCount,userActiveAccountsIds:r}}throw new Error("Failed to load invoices")}catch(e){if(e.message&&e.message.includes("Failed to retrieve invoices"))return{invoices:[],filteredInvoices:[],availableStatuses:new Set,totalPages:0,currentPage:1};throw e}}async fetchData(){return await this.loadData()}applyFilters(e){const t=this.getState();let n=[...e];return t.activeFilter!==Wt&&(n=n.filter((e=>e.status===t.activeFilter))),n.sort(((e,t)=>new Date(t.date).getTime()-new Date(e.date).getTime())),n}getPaginatedInvoices(){const e=this.getState();if(!e.data||!e.data.filteredInvoices)return[];if(e.data.serverPagination)return e.data.filteredInvoices;const t=(e.currentPage-1)*e.itemsPerPage,n=t+e.itemsPerPage;return e.data.filteredInvoices.slice(t,n)}isEmptyState(e){console.log("[InvoicesList] Checking empty state, data:",e);const t=!e||!e.invoices||0===e.invoices.length;return console.log("[InvoicesList] Is empty:",t),t}getEmptyStateConfig(){return this.options.profileData?.stats?.activeSubscriptions>0?{icon:P.H.render("clock",{class:"w-16 h-16 text-yellow-600"}),title:"Invoices are being generated",message:"Your first invoice will appear here after your billing cycle begins. This usually happens within 24 hours of subscribing.",action:`\n <a href="#subscriptions" class="hg-view-subscriptions inline-flex items-center px-6 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-all font-medium shadow-md hover:shadow-lg transform hover:-translate-y-0.5">\n ${P.H.render("info",{class:"w-5 h-5 mr-2"})}\n View Subscriptions\n </a>\n `}:{icon:P.H.render("file-text",{class:"w-16 h-16 text-primary-400"}
1),title:this.config?.getMessage("empty","noInvoices")||"No invoices yet",message:this.config?.getMessage("empty","noInvoicesDesc")||"Invoices will appear here once you subscribe to a plan.",action:`\n <a href="#subscriptions" class="hg-browse-plans inline-flex items-center px-6 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-all font-medium shadow-md hover:shadow-lg transform hover:-translate-y-0.5">\n ${P.H.render("dollar-sign",{class:"w-5 h-5 mr-2"})}\n Browse Plans\n </a>\n `}}renderMainContent(){const e=this.getState();return e.data&&e.data.invoices&&0!==e.data.invoices.length?`\n ${this.renderFilterBar()}\n ${this.renderInvoicesTable()}\n ${e.data.totalPages&&e.data.totalPages>1?this.renderPagination():""}\n `:""}renderHeaderActions(){const e=window.location.search.includes("test-invoice-settlement"),t=[];return t.push(`\n <button class="hg-reload-invoices flex items-center px-3 py-2 bg-white/20 backdrop-blur text-white rounded-lg hover:bg-white/30 transition-all text-sm font-medium" title="Refresh invoices">\n ${P.H.render("refresh-cw",{class:"w-4 h-4"})}\n </button>\n `),e&&t.push(`\n <button class="hg-test-settlement-enabled flex items-center px-3 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-all text-sm font-medium" title="Test settlement enabled">\n ${P.H.render("check",{class:"w-4 h-4 mr-1"})}\n Test: Enabled\n </button>\n <button class="hg-test-settlement-disabled flex items-center px-3 py-2 bg-orange-500 text-white rounded-lg hover:bg-orange-600 transition-all text-sm font-medium" title="Test settlement disabled">\n ${P.H.render("x",{class:"w-4 h-4 mr-1"})}\n Test: Disabled\n </button>\n `),t.length>0?`\n <div class="flex items-center space-x-2">\n ${t.join("")}\n </div>\n `:""}renderFilterOptions(){const e=this.getState(),t=[];return t.push(`\n <button class="hg-filter-option w-full px-4 py-2 text-left text-sm hover:bg-gray-50 transition-colors flex items-center justify-between ${e.activeFilter===Wt?"bg-primary-50 text-primary-700":"text-gray-700"}" data-filter="${Wt}">\n <span class="flex items-center">\n ${P.H.render("archive",{class:"w-4 h-4 mr-2"})}\n All Invoices\n </span>\n <span class="text-xs font-medium ${e.activeFilter===Wt?"text-primary-600":"text-gray-500"}">${e.data&&e.data.invoices?e.data.invoices.length:0}</span>\n </button>\n `),e.data&&e.data.availableStatuses&&e.data.availableStatuses.size>0&&(t.push('<div class="border-t border-gray-100 my-1"></div>'),Array.from(e.data.availableStatuses).sort().forEach((n=>{const o=Xt[n]||{label:n,bgColor:"bg-gray-100",textColor:"text-gray-800"},i=e.data&&e.data.invoices?e.data.invoices.filter((e=>e.status===n)).length:0;t.push(`\n <button class="hg-filter-option w-full px-4 py-2 text-left text-sm hover:bg-gray-50 transition-colors flex items-center justify-between ${e.activeFilter===n?"bg-primary-50 text-primary-700":"text-gray-700"}" data-filter="${n}">\n <span class="flex items-center">\n <span class="inline-flex items-center justify-center w-2 h-2 mr-2 rounded-full ${o.bgColor}"></span>\n <span class="${o.textColor}">${o.label}</span>\n </span>\n <span class="text-xs font-medium ${e.activeFilter===n?"text-primary-600":"text-gray-500"}">${i}</span>\n </button>\n `)}))),t.join("")}renderFilterBar(){const e=this.getState();if(e.activeFilter===Wt)return"";const t=Xt[e.activeFilter]||{label:e.activeFilter};return`\n <div class="px-6 pt-4">\n <div class="flex items-center justify-between bg-primary-50 border border-primary-200 rounded-lg px-4 py-2">\n <div class="flex items-center text-sm text-primary-700">\n ${P.H.render("filter",{class:"w-4 h-4 mr-2"})}\n Showing ${e.data&&e.data.filteredInvoices?e.data.filteredInvoices.length:0} ${t.label.toLowerCase()}\n </div>\n <button class="hg-clear-filter text-primary-600 hover:text-primary-700 text-sm font-medium">\n Clear filter\n </button>\n </div>\n </div>\n `}renderInvoicesTable(){const e=this.getPaginatedInvoices();
1this.getState();return 0===e.length?this.renderNoResultsState():`\n <div class="overflow-x-auto">\n <table class="min-w-full divide-y divide-gray-200">\n <thead>\n <tr>\n <th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">\n Invoice\n </th>\n <th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">\n Date\n </th>\n <th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">\n Description\n </th>\n <th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">\n Amount\n </th>\n <th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">\n Status\n </th>\n <th class="px-6 py-3 bg-gray-50 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">\n Actions\n </th>\n </tr>\n </thead>\n <tbody class="bg-white divide-y divide-gray-200">\n ${e.map((e=>this.renderInvoiceRow(e))).join("")}\n </tbody>\n </table>\n </div>\n `}renderInvoiceRow(e){const t=Xt[e.status]||Xt.pending;return`\n <tr class="${e.isOutstandingInvoice?"hover:bg-orange-25 bg-orange-50 border-l-4 border-l-orange-400 transition-colors":"hover:bg-gray-50 transition-colors"}">\n <td class="px-6 py-4 whitespace-nowrap">\n <div class="text-sm font-medium text-gray-900">${e.invoiceNumber||e.id}</div>\n </td>\n <td class="px-6 py-4 whitespace-nowrap">\n <div class="text-sm text-gray-900">${(0,Fe.Yq)(e.date)}</div>\n </td>\n <td class="px-6 py-4">\n <div class="text-sm text-gray-900">${e.description||"Subscription"}</div>\n ${e.accountUserName?`\n <div class="text-xs text-gray-500 mt-1">\n Account: ${e.accountUserName}\n </div>\n `:""}\n </td>\n <td class="px-6 py-4 whitespace-nowrap">\n <div class="text-sm font-medium text-gray-900">\n ${W(e.amount,{currency:e.currency})}\n </div>\n </td>\n <td class="px-6 py-4 whitespace-nowrap">\n <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${t.bgColor} ${t.textColor}">\n ${t.label}\n </span>
1\n ${e.paidDate&&"paid"===e.status?`\n <div class="text-xs text-gray-500 mt-1">\n Paid ${(0,Fe.Yq)(e.paidDate)}\n </div>\n `:""}\n </td>\n <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">\n <div class="flex items-center justify-end space-x-2">\n ${e.isOutstandingInvoice?`\n <button class="hg-collect-invoice px-3 py-1 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors font-medium text-sm"\n data-invoice='${JSON.stringify(e).replace(/'/g,"'")}'\n title="Pay Invoice">\n ${P.H.render("credit-card",{class:"w-4 h-4 inline mr-1"})}\n Pay Invoice\n </button>\n `:""}\n <button class="hg-view-invoice text-gray-600 hover:text-gray-900 transition-colors"\n data-invoice='${JSON.stringify(e).replace(/'/g,"'")}'\n title="Quick View">\n ${P.H.render("eye",{class:"w-5 h-5"})}\n </button>\n <button class="hg-download-invoice text-gray-600 hover:text-gray-900 transition-colors"\n data-invoice-id="${e.invoiceId||e.id}"\n title="Download PDF">\n ${P.H.render("download",{class:"w-5 h-5"})}\n </button>\n </div>\n </td>\n </tr>\n `}renderPagination(){const e=this.getState();let t,n,o;if(e.data?.serverPagination){const i=e.data.filteredInvoices?e.data.filteredInvoices.length:0;t=(e.currentPage-1)*e.itemsPerPage+1,n=(e.currentPage-1)*e.itemsPerPage+i,o=e.data.totalCount||e.data.totalPages*e.itemsPerPage}else t=(e.currentPage-1)*e.itemsPerPage+1,n=Math.min(e.currentPage*e.itemsPerPage,e.data&&e.data.filteredInvoices?e.data.filteredInvoices.length:0),o=e.data&&e.data.filteredInvoices?e.data.filteredInvoices.length:0;return`\n <div class="mt-6 pt-6 px-6 pb-6 border-t border-gray-200 flex items-center justify-between">\n <div class="text-sm text-gray-700">\n Showing ${t} to ${n} of ${o} invoices\n </div>\n <div class="flex items-center space-x-2">\n <button class="hg-prev-page px-3 py-1 border border-gray-300 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"\n ${1===e.currentPage?"disabled":""}>\n Previous\n </button>\n\n <div class="flex items-center space-x-1">\n ${this.renderPageNumbers()}\n </div>\n\n <button class="hg-next-page px-3 py-1 border border-gray-300 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"\n ${e.currentPage===(e.data&&e.data.totalPages?e.data.totalPages:1)?"disabled":""}>\n Next\n </button>\n </div>\n </div>\n `}renderPageNumbers(){const e=this.getState(),t=[],n=e.data&&e.data.totalPages?e.data.totalPages:1;if(n<=5)for(let e=1;e<=n;e++)t.push(this.renderPageButton(e));else{t.push(this.renderPageButton(1)),e.currentPage>3&&t.push('<span class="px-2 text-gray-500">...</span>');const o=Math.max(2,e.currentPage-1),i=Math.min(n-1,e.currentPage+1);for(let e=o;e<=i;e++)t.push(this.renderPageButton(e));e.currentPage<n-2&&t.push('<span class="px-2 text-gray-500">...</span>'),t.push(this.renderPageButton(n))}return t.join("")}renderPageButton(e){const t=e===this.getState().currentPage;return`\n <button class="hg-page-number px-3 py-1 text-sm font-medium rounded-md transition-colors\n ${t?"bg-primary-600 text-white":"text-gray-700 hover:bg-gray-100"}"\n data-page="${e}"\n ${t?"disabled":""}>\n ${e}\n </button>\n `}renderNoResultsState(){return this.renderEmptyState({icon:P.H.render("meh",{class:"w-16 h-16 text-gray-400"}),title:this.config?.getMessage("empty","noResults")||"No invoices match your criteria",message:this.config?.getMessage("empty","noResultsDesc")||"Try adjusting your filters.",action:`\n <button class="hg-clear-filter inline-flex items-center px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors font-medium">\n ${P.H.render("x",{class:"w-4 h-4 mr-2"})}\n Clear Filter\n </button>\n `})}attachEventListeners(){if(this.eventListenersAttached)return void this.attachDropdownListeners();this.eventListenersAttached=!0;const e=this.getState();this.addDelegatedListener(".hg-filter-toggle","click",(e=>{e.stopPropagation();const t=this.container.querySelector("#hg-filter-dropdown"),n=t?.querySelector(".hg-filter-menu");n?.classList.toggle("hidden")})),this.attachDropdownListeners(),this.addDelegatedListener(".hg-filter-option","click",(async t=>{t.stopPropagation();
1const n=t.currentTarget.dataset.filter;if(this.setState({activeFilter:n,currentPage:1}),e.data&&e.data.invoices){const t=this.applyFilters(e.data.invoices);this.setState({data:{...e.data,filteredInvoices:t,totalPages:Math.ceil(t.length/e.itemsPerPage)}})}})),this.addDelegatedListener(".hg-clear-filter","click",(async()=>{if(this.setState({activeFilter:Wt,currentPage:1}),e.data&&e.data.invoices){const t=this.applyFilters(e.data.invoices);this.setState({data:{...e.data,filteredInvoices:t,totalPages:Math.ceil(t.length/e.itemsPerPage)}})}})),this.addDelegatedListener(".hg-reload-invoices","click",(async e=>{e.preventDefault(),await this.refresh()})),this.addDelegatedListener(".hg-test-settlement-enabled","click",(async e=>{e.preventDefault(),await this.testInvoiceSettlement(!0)})),this.addDelegatedListener(".hg-test-settlement-disabled","click",(async e=>{e.preventDefault(),await this.testInvoiceSettlement(!1)})),this.addDelegatedListener(".hg-view-invoice","click",(e=>{e.preventDefault(),e.stopPropagation();const t=e.target.closest(".hg-view-invoice");if(!t)return;const n=t.getAttribute("data-invoice");if(n)try{const e=JSON.parse(n);console.log("[InvoicesList] Opening invoice modal for invoice:",e.id);const t=new we.Modal({id:`invoice-details-${e.id}`,title:"Invoice Details",content:this.renderInvoiceModal(e),size:"medium",closeOnOverlay:!0});t.open(),this.setTimeout((()=>{const n=document.getElementById(`invoice-details-${e.id}`);if(!n)return;const o=n.querySelector(".hg-collect-invoice-modal");if(o){const e=async()=>{const e=o.getAttribute("data-invoice");if(e)try{const n=JSON.parse(e);t.close(),await this.handleInvoiceCollection(n)}catch(e){console.error("Failed to collect invoice:",e),te.Alert.error("Failed to process invoice collection")}};o.addEventListener("click",e,{once:!0})}const i=n.querySelector(".hg-download-invoice-modal");if(i){let e=!1;const t=async()=>{if(e)return void console.log("[InvoicesList] Download already in progress, ignoring click");const t=i.getAttribute("data-invoice-id");if(!t)return void te.Alert.error("Invoice ID not found");e=!0;const n=i.innerHTML;i.disabled=!0,i.innerHTML=`\n ${P.H.render("loader",{class:"animate-spin h-5 w-5 mr-2"})}\n Downloading...\n `;try{await this.downloadHandler.downloadInvoicePdf(t,null)}catch(e){console.error("Failed to download invoice:",e),te.Alert.error("Failed to download invoice")}finally{i.innerHTML=n,i.disabled=!1,e=!1}};i.addEventListener("click",t)}}),100)}catch(e){console.error("Failed to parse invoice data:",e),te.Alert.error("Failed to view invoice details")}})),this.addDelegatedListener(".hg-collect-invoice","click",(async e=>{console.log("[InvoicesList] Pay Invoice button clicked"),e.preventDefault(),e.stopPropagation();const t=e.target.closest(".hg-collect-invoice");if(!t)return void console.log("[InvoicesList] Button not found");const n=t.getAttribute("data-invoice");if(n)try{const e=JSON.parse(n);console.log("[InvoicesList] Processing invoice:",e),await this.handleInvoiceCollection(e)}catch(e){console.error("Failed to parse invoice data:",e),te.Alert.error("Unable to process request")}else console.log("[InvoicesList] Invoice data not found")})),this.addDelegatedListener(".hg-download-invoice","click",(async e=>{e.preventDefault(),e.stopPropagation();const t=e.target.closest(".hg-download-invoice");if(!t)return;const n=t.getAttribute("data-invoice-id");n?await this.downloadHandler.downloadInvoicePdf(n,t):te.Alert.error("Invoice ID not found")})),this.addDelegatedListener(".hg-prev-page","click",(async()=>{const e=this.getState();if(e.currentPage>1){const t=e.data?.serverPagination;this.setState({currentPage:e.currentPage-1}),t&&await this.render()}})),this.addDelegatedListener(".hg-next-page","click",(async()=>{const e=this.getState();if(e.data&&e.data.totalPages&&e.currentPage<e.data.totalPages){const t=e.data?.serverPagination;this.setState({currentPage:e.currentPage+1}),t&&await this.render()}})),this.addDelegatedListener(".hg-page-number","click",(async e=>{const t=e.target.closest(".hg-page-number");if(!t)return;const n=parseInt(t.dataset.page||"1"),o=this.getState();if(n!==o.currentPage){const e=o.data?.serverPagination;this.setState({currentPage:n}),e&&await this.render()}})),this.attachNavigationListeners()}attachDropdownListeners(){const e=this.container.querySelector("#hg-filter-dropdown");
1if(e){const t=e.querySelector(".hg-filter-menu"),n=this.closeDropdownHandler;n&&document.removeEventListener("click",n);const o=n=>{e.contains(n.target)||t?.classList.add("hidden")};this.closeDropdownHandler=o,this.cleanup.addEventListener(document,"click",o)}}attachNavigationListeners(){this.addDelegatedListener(".hg-view-subscriptions, .hg-browse-plans","click",(e=>{e.preventDefault(),console.log("[InvoicesList] Browse Plans clicked, navigating to subscriptions");const t=window.HeimGuard;t?.switchProfileTab?(console.log("[InvoicesList] Using switchProfileTab method"),t.switchProfileTab("subscriptions")):window.location.hash?(console.log("[InvoicesList] Using hash navigation"),window.location.hash="subscriptions"):(console.log("[InvoicesList] Using custom event dispatch"),document.dispatchEvent(new CustomEvent("heimguard:profile:sectionChange",{detail:{section:"subscriptions"}})))}))}setupEventListeners(){const e=rn(on.INVOICES_UPDATED,(async()=>{await this.render()}));this.cleanup.addCleanupTask(e)}async onDestroy(){}async refresh(){await this.render()}async handleInvoiceCollection(e){try{console.log("[InvoicesList] handleInvoiceCollection called with invoice:",{invoiceId:e.invoiceId,isOutstandingInvoice:e.isOutstandingInvoice});const t=await v.initService.getInitData(),n=!1!==t?.generalConfig?.enableInvoiceSettlement;if(console.log("[InvoicesList] Invoice settlement enabled:",n),!n)return console.log("[InvoicesList] Invoice settlement is disabled, showing customer support modal"),void await this.showCustomerSupportModal(e);console.log("[InvoicesList] Showing payment method collection screen"),await this.collectWithExistingPaymentMethod(e)}catch(e){console.error("[InvoicesList] Error handling invoice collection:",e),te.Alert.error("Failed to collect invoice payment")}}async showCustomerSupportModal(e){const t=await v.initService.getInitData();let n=t?.generalConfig?.companySupportEmail||"[email protected]",o=t?.generalConfig?.companySupportPhone||"",i=t?.generalConfig?.companyName||"Customer Support";new we.Modal({title:"Invoice Payment Support",size:"large",content:`\n <div class="text-center space-y-6">\n <div class="flex justify-center">\n <div class="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center">\n <svg class="w-8 h-8 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" />\n </svg>\n </div>\n </div>\n\n <div class="space-y-4">\n <h3 class="text-lg font-semibold text-gray-900">Contact Customer Support</h3>\n <p class="text-gray-700">\n To settle your outstanding invoice, please contact our customer support team. They'll be happy to assist you with payment processing.\n </p>\n\n <div class="bg-gray-50 rounded-lg p-4 space-y-3">\n <p class="text-sm text-gray-600">\n <strong>Invoice Number:</strong> ${e.invoiceNumber||e.number||e.id}\n </p>\n <p class="text-sm text-gray-600">\n <strong>Amount:</strong> ${W(e.amount,{currency:e.currency})}\n </p>\n <p class="text-sm text-gray-600">\n <strong>Status:</strong> <span class="text-orange-600 font-medium">Past Due</span>\n </p>\n </div>\n\n <div class="bg-blue-50 rounded-lg p-4 space-y-3">\n <p class="text-sm text-gray-600">\n <strong>Contact ${i}:</strong>\n </p>\n <div class="space-y-2">\n ${o?`\n <div class="flex items-center justify-center">\n <svg class="w-4 h-4 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042
111.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" />\n </svg>\n <a href="tel:${o}" class="text-blue-600 hover:text-blue-700 font-medium">\n ${o}\n </a>\n </div>\n `:""}\n <div class="flex items-center justify-center">\n <svg class="w-4 h-4 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />\n </svg>\n <a href="mailto:${n}" class="text-blue-600 hover:text-blue-700 font-medium">\n ${n}\n </a>\n </div>\n </div>\n </div>\n\n <p class="text-sm text-gray-500">\n Please reference your invoice number when contacting support.\n </p>\n </div>\n\n <div class="flex justify-center pt-4">\n <button class="px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white rounded-lg font-medium transition-colors" onclick="this.closest('.modal-overlay, [role=dialog]').remove()">\n Got it\n </button>\n </div>\n </div>\n `,closeOnOverlay:!0}).open()}async collectWithExistingPaymentMethod(e){try{console.log("[InvoicesList] Processing invoice with existing payment method capabilities"),await this.showPaymentMethodUpdateScreen(e)}catch(e){console.error("[InvoicesList] Error collecting with existing payment method:",e),te.Alert.error("Failed to process payment method")}}async showPaymentMethodUpdateScreen(e){try{console.log("[InvoicesList] Showing payment method update screen for invoice payment");const[t,n]=await Promise.all([this.fetchAddressesForModal(),w.default.load()]);if(!n.recurlyPublicKey)return void te.Alert.error("Payment configuration is not available. Please contact support.");const o=this.renderPaymentUpdateModalContent(e,t),i=new we.Modal({id:`payment-update-${e.invoiceId}`,title:"Update Payment Method",content:o,size:"large",closeOnOverlay:!0});i.open(),this.setTimeout((()=>{this.setupPaymentUpdateModalListeners(i,e,t,n.recurlyPublicKey)}),100)}catch(e){console.error("[InvoicesList] Error showing payment update screen:",e),te.Alert.error("Failed to open payment update screen")}}renderPaymentUpdateModalContent(e,t){const n=this.sortAddresses(t);return`\n <div>\n \x3c!-- Invoice Information --\x3e\n <div class="mb-6">\n <h3 class="text-lg font-semibold text-gray-900 mb-3">Pay Invoice #${e.invoiceNumber||e.id}</h3>\n <div class="bg-gradient-to-r from-blue-50 to-indigo-50 border border-blue-200 rounded-lg p-4">\n <div class="flex justify-between items-center">\n <span class="text-gray-700 font-medium">Amount to pay:</span>\n <span class="text-xl font-bold text-gray-900">${W(e.amount,{currency:e.currency})}</span>\n </div>\n </div>\n </div>\n\n \x3c!-- Progress Indicator --\x3e\n <div class="mb-6">\n <div class="flex items-center justify-between text-sm">\n <div class="flex items-center">\n <div class="w-8 h-8 bg-primary-600 text-white rounded-full flex items-center justify-center text-sm font-medium">1</div>\n <span class="ml-2 text-primary-600 font-semibold">Select Billing Address</span>\n </div>\n <div class="flex-1 mx-4 h-px bg-gray-300"></div>\n <div class="flex items-center">\n <div class="w-8 h-8 bg-gray-300 text-gray-500 rounded-full flex items-center justify-center text-sm font-medium">2</div>\n <span class="ml-2 text-gray-500">Payment Details</span>\n </div>\n </div>\n </div>\n\n \x3c!-- Step Content Container --\x3e\n <div id="step-content"
1class="min-h-[300px]">\n ${this.renderBillingAddressStep(n)}\n </div>\n\n \x3c!-- Navigation --\x3e\n <div class="flex items-center justify-between pt-6 border-t mt-6">\n <button type="button" id="back-button" class="flex items-center px-4 py-2 text-gray-700 hover:text-gray-900 hover:bg-gray-100 rounded-lg transition-all invisible" data-action="back">\n ${P.H.render("chevron-left",{class:"w-4 h-4 mr-2"})}\n Back\n </button>\n <div class="flex items-center space-x-3">\n <button type="button" class="px-4 py-2 text-gray-700 border border-gray-300 rounded-lg hover:bg-gray-50 font-medium transition-all" data-action="cancel">\n Cancel\n </button>\n <button type="button" id="continue-button" class="px-6 py-2.5 bg-primary-600 text-white rounded-lg hover:bg-primary-700 disabled:opacity-50 disabled:cursor-not-allowed font-medium flex items-center transition-all" data-action="continue" disabled>\n <span>Continue</span>\n ${P.H.render("chevron-right",{class:"w-4 h-4 ml-2"})}\n </button>\n </div>\n </div>\n </div>\n `}renderBillingAddressStep(e){return`\n <div>\n <div class="mb-6">\n <h3 class="text-lg font-semibold text-gray-900 mb-2">Select Billing Address</h3>\n <p class="text-gray-600">Choose the billing address for your payment method</p>\n </div>\n\n <div class="space-y-3 mb-6" id="address-list">\n ${e.map(((e,t)=>this.renderAddressCard(e,0===t))).join("")}\n\n \x3c!-- Add New Address Option --\x3e\n <div class="border-2 border-dashed border-gray-300 rounded-lg p-4 hover:border-primary-400 hover:bg-primary-50/30 transition-all cursor-pointer group"\n id="add-new-address-card" data-action="add-address">\n <div class="flex items-center space-x-3">\n <div class="w-10 h-10 bg-gray-100 rounded-full flex items-center justify-center group-hover:bg-primary-100 transition-colors">\n ${P.H.render("plus",{class:"w-5 h-5 text-gray-600 group-hover:text-primary-600"})}\n </div>\n <div>\n <h4 class="font-medium text-gray-900 group-hover:text-primary-700 transition-colors">Add New Address</h4>\n <p class="text-sm text-gray-500">Create a new billing address for this payment method</p>\n </div>\n </div>\n </div>\n </div>\n\n \x3c!-- Security Note --\x3e\n <div class="bg-gradient-to-r from-blue-50 to-indigo-50 border border-blue-200 rounded-lg p-4 flex items-start">\n ${P.H.render("lock",{class:"w-5 h-5 text-blue-600 mt-0.5 mr-3 flex-shrink-0"})}\n <div class="flex-1">\n <h4 class="text-sm font-medium text-blue-900">Secure Payment</h4>\n <p class="text-sm text-blue-700 mt-1">Your payment information is encrypted and secure. We never store your full card details.</p>\n </div>\n </div>\n </div>\n `}setupPaymentUpdateModalListeners(e,t,n,o){let i=1,a=null,s=null;const r=e=>{const t=["Select Billing Address","Payment Details"],n=document.querySelector(".flex.items-center.justify-between.text-sm");n&&(n.innerHTML=t.map(((n,o)=>{const i=o+1,a=i===e,s=i<e;return`\n <div class="flex items-center">\n <div class="w-10 h-10 ${a?"bg-primary-600 text-white shadow-lg":s?"bg-green-600 text-white shadow-lg":"bg-gray-300 text-gray-500"} rounded-full flex items-center justify-center text-sm font-medium">\n ${s?"â":i}\n </div>\n <span class="ml-3 ${a?"text-primary-600 font-semibold":s?"text-green-600 font-semibold":"text-gray-500"}">${n}</span>\n </div>\n ${o<t.length-1?'<div class="flex-1 mx-6 h-px bg-gray-300"></div>':""}\n `})).join(""))},d=(e=n)=>{const t=document.querySelectorAll('input[name="billing-address"]'),o=document.getElementById("continue-button"),i=t[0];i&&i.checked&&(a=e.find((e=>e.id===i.value)),o&&(o.disabled=!1)),t.forEach((t=>{t.addEventListener("change",(t=>{const n=t.target;n.checked&&(a=e.find((e=>e.id===n.value)),o&&(o.disabled=!1))}))}))},l=document.getElementById("continue-button");if(l){const n=l.cloneNode(!0);l.parentNode?.replaceChild(n,l),n.addEventListener("click",(async()=>
1{if(1===i){if(console.log("[InvoicesList] ð² CONTINUE BUTTON CLICKED - STEP 1"),!a)return void te.Alert.error("Please select a billing address");i=2,r(i);const n=document.getElementById("step-content");n&&(n.innerHTML='\n <div id="payment-modal-container"></div>\n ');const d=document.getElementById("back-button");d&&d.classList.remove("invisible");const l=document.getElementById("continue-button");l&&(l.style.display="none"),s&&(console.log("[InvoicesList] Cleaning up existing payment modal"),s.hide(),s=null);try{console.log("[InvoicesList] Creating new PaymentModal instance"),console.log("[InvoicesList] STACK TRACE:",(new Error).stack),console.log("[InvoicesList] Invoice accountId:",t.accountId),s=new ft.default({addresses:[a],recurlyPublicKey:o,inline:!0,isOutstandingInvoiceFlow:t.isOutstandingInvoice,onSuccess:async n=>{if(t.isOutstandingInvoice){console.log("[InvoicesList] ð OUTSTANDING INVOICE SETTLEMENT - UPDATING ACCOUNT"),console.log("[InvoicesList] ð Payment data received:",n);try{console.log("[InvoicesList] ð§ Updating payment method for invoice account:",t.accountId);const o=await this.updatePaymentMethodsForOutstandingInvoice(t,n);console.log("[InvoicesList] ð UPDATE RESULT:",o?"SUCCESS":"FAILED"),o?(console.log("[InvoicesList] â
ACCOUNT UPDATED - Showing success confirmation"),await this.handleInvoicePaymentCompletion(t,n,e)):(console.error("[InvoicesList] â UPDATE FAILED - Payment method update failed"),te.Alert.error("Failed to update payment method"))}catch(e){console.error("[InvoicesList] â EXCEPTION in outstanding invoice settlement:",e),te.Alert.error("Failed to settle invoice")}}else i=3,await this.handlePaymentMethodAddition(t,n,e)},onCancel:()=>{e.close()}});const n=document.getElementById("payment-modal-container");n&&s&&await s.renderInline(n)}catch(e){console.error("[InvoicesList] Error initializing payment modal:",e),te.Alert.error("Failed to initialize payment form")}}}))}const c=document.getElementById("back-button");if(c){const e=c.cloneNode(!0);c.parentNode?.replaceChild(e,c),e.addEventListener("click",(()=>{if(2===i){i=1,r(i);const t=document.getElementById("step-content");t&&(t.innerHTML=this.renderBillingAddressStep(n),d()),e.classList.add("invisible");const o=document.getElementById("continue-button");o&&(o.style.display=""),s&&(s.hide(),s=null)}}))}const u=document.querySelector('[data-action="cancel"]');console.log("[InvoicesList] Cancel button element:",u),u?(console.log("[InvoicesList] Adding click listener to cancel button"),u.addEventListener("click",(()=>{console.log("[InvoicesList] Cancel button clicked, closing modal"),e.close()}))):console.error('[InvoicesList] Could not find cancel button with selector [data-action="cancel"]');const m=document.querySelector("#add-new-address-card");m&&m.addEventListener("click",(async()=>{await this.handleAddNewAddressForInvoice(e,t,n,o,(e=>{a=e}),a)})),d()}async handlePaymentMethodAddition(e,t,n){try{console.log("[InvoicesList] Adding payment method for invoice:",e.invoiceId);const o=document.getElementById("step-content");o&&(o.innerHTML=`\n <div class="text-center py-8">\n <div class="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-4">\n ${P.H.render("credit-card",{class:"w-8 h-8 text-blue-600"})}\n </div>\n <h3 class="text-lg font-semibold text-gray-900 mb-2">Adding Payment Method...</h3>\n <p class="text-gray-600">Please wait while we securely save your payment information.</p>\n <div class="mt-4">\n ${P.H.render("loader",{class:"animate-spin h-8 w-8 text-primary-600 mx-auto"})}\n </div>\n </div>\n `);document.querySelectorAll('#back-button, #continue-button, [data-action="cancel"]').forEach((e=>{e.style.display="none"}));if(!await this.addPaymentMethodForInvoice(e,t))throw new Error("Failed to add payment method");await this.showInvoicePaymentReviewScreen(e,t,n)}catch(e){const t=e instanceof Error?e.message:"Unknown error";console.error("[InvoicesList] Error adding payment method:",e),te.Alert.error(`Failed to add payment method: ${t}`);const n=document.getElementById("step-content");n&&(n.innerHTML=`\n <div class="text-center py-8">\n <div class="w-16 h-16 bg-red-100 rounded-full flex items-center justify-center mx-auto mb-4">\n ${P.H.render("x",{class:"w-8 h-8 text-red-600"})}\n </div>\n <h3 class="text-lg font-semibold text-gray-900 mb-2">Error Adding Payment Method</h3>\n <p class="text-gray-600">There was an error saving your payment method:</p>\n <p class="text-red-600 text-sm mt-2 font-mono">${t}</p>\n <div class="mt-6">\n <button class="px-6 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 font-medium" onclick="location.reload()">\n Try Again\n </button>\n </div>\n </div>\n `)}}
1async showInvoicePaymentReviewScreen(e,t,n){console.log("[InvoicesList] Showing payment review screen for invoice:",e.invoiceId);const o=t.number||"****",i=o.length>4?`****-****-****-${o.slice(-4)}`:"****-****-****-****",a=document.getElementById("step-content");a&&(a.innerHTML=`\n <div class="py-6">\n <div class="text-center mb-6">\n <div class="w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-4">\n ${P.H.render("check",{class:"w-8 h-8 text-green-600"})}\n </div>\n <h3 class="text-lg font-semibold text-gray-900 mb-2">Review Payment Details</h3>\n <p class="text-gray-600">Please review your payment information before proceeding.</p>\n </div>\n\n <div class="space-y-4">\n \x3c!-- Invoice Details --\x3e\n <div class="bg-gray-50 rounded-lg p-4">\n <h4 class="font-medium text-gray-900 mb-2">Invoice Details</h4>\n <div class="space-y-1 text-sm">\n <div class="flex justify-between">\n <span class="text-gray-600">Invoice Number:</span>\n <span class="font-medium">#${e.invoiceNumber||e.id}</span>\n </div>\n <div class="flex justify-between">\n <span class="text-gray-600">Amount:</span>\n <span class="font-medium text-lg">${W(e.amount,{currency:e.currency})}</span>\n </div>\n <div class="flex justify-between">\n <span class="text-gray-600">Status:</span>\n <span class="px-2 py-1 bg-orange-100 text-orange-800 rounded text-xs font-medium">Past Due</span>\n </div>\n </div>\n </div>\n\n \x3c!-- Payment Method --\x3e\n <div class="bg-gray-50 rounded-lg p-4">\n <h4 class="font-medium text-gray-900 mb-2">Payment Method</h4>\n <div class="flex items-center space-x-3">\n <div class="w-8 h-8 bg-blue-100 rounded flex items-center justify-center">\n ${P.H.render("credit-card",{class:"w-4 h-4 text-blue-600"})}\n </div>\n <div>\n <p class="font-medium text-sm">${i}</p>\n <p class="text-xs text-gray-600">Expires ${t.exp_month||"XX"}/${t.exp_year||"XX"}</p>\n </div>\n </div>\n </div>\n\n ${t.billingAddress?`\n \x3c!-- Billing Address --\x3e\n <div class="bg-gray-50 rounded-lg p-4">\n <h4 class="font-medium text-gray-900 mb-2">Billing Address</h4>\n <div class="text-sm text-gray-600">\n <p>${t.billingAddress.first_name||""} ${t.billingAddress.last_name||""}</p>\n <p>${t.billingAddress.street1||""}</p>\n ${t.billingAddress.street2?`<p>${t.billingAddress.street2}</p>`:""}\n <p>${t.billingAddress.city||""}, ${t.billingAddress.region||""} ${t.billingAddress.postal_code||""}</p>\n <p>${t.billingAddress.country||""}</p>\n </div>\n </div>\n `:""}\n\n \x3c!-- Confirmation --\x3e\n <div class="bg-blue-50 border border-blue-200 rounded-lg p-4">\n <div class="flex items-start space-x-3">\n <div class="w-5 h-5 text-blue-600 mt-0.5">\n ${P.H.render("info",{class:"w-5 h-5"})}\n </div>\n <div class="text-sm">\n <p class="text-blue-800 font-medium">Ready to Process Payment</p>\n <p class="text-blue-700 mt-1">Your payment method has been saved securely. Click "Process Payment" to complete the transaction for ${W(e.amount,{currency:e.currency})}. The invoice will be automatically settled by Recurly.</p>\n </div>\n </div>\n </div>\n </div>\n </div>\n `);const s=document.getElementById("back-button"),r=document.getElementById("continue-button");
1s&&(s.style.display="inline-flex",s.textContent="Edit Payment",s.onclick=()=>{window.location.reload()}),r&&(r.style.display="inline-flex",r.textContent="Process Payment",r.className="px-6 py-3 bg-green-600 text-white rounded-lg hover:bg-green-700 font-medium",r.onclick=async()=>{await this.handleInvoicePaymentCompletion(e,t,n)})}async handleInvoicePaymentCompletion(e,t,n){try{console.log("[InvoicesList] Showing invoice payment confirmation for:",e.invoiceId);document.querySelectorAll('#back-button, #continue-button, [data-action="cancel"]').forEach((e=>{e.style.display="none"}));const o=document.getElementById("step-content");if(o){o.innerHTML=`\n <div class="text-center py-8">\n <div class="w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-4">\n ${P.H.render("check",{class:"w-8 h-8 text-green-600"})}\n </div>\n <h3 class="text-lg font-semibold text-gray-900 mb-2">Payment Successful!</h3>\n <p class="text-gray-600">Your invoice #${e.invoiceNumber||e.id} has been paid successfully.</p>\n <p class="text-sm text-gray-500 mt-2">The payment method was added and the invoice was automatically settled by Recurly.</p>\n\n \x3c!-- Payment Summary --\x3e\n <div class="mt-6 bg-gray-50 rounded-lg p-4 text-left max-w-md mx-auto">\n <h4 class="font-medium text-gray-900 mb-2 text-center">Payment Summary</h4>\n <div class="space-y-2 text-sm">\n <div class="flex justify-between">\n <span class="text-gray-600">Invoice:</span>\n <span class="font-medium">#${e.invoiceNumber||e.id}</span>\n </div>\n <div class="flex justify-between">\n <span class="text-gray-600">Amount Paid:</span>\n <span class="font-medium">${W(e.amount,{currency:e.currency})}</span>\n </div>\n <div class="flex justify-between">\n <span class="text-gray-600">Payment Method:</span>\n <span class="font-medium">****-${t.number?t.number.slice(-4):"XXXX"}</span>\n </div>\n <div class="flex justify-between">\n <span class="text-gray-600">Status:</span>\n <span class="px-2 py-1 bg-green-100 text-green-800 rounded text-xs font-medium">Paid</span>\n </div>\n </div>\n </div>\n\n <div class="mt-6">\n <button id="success-close-button" class="px-6 py-3 bg-green-600 text-white rounded-lg hover:bg-green-700 font-medium">\n Close\n </button>\n </div>\n </div>\n `;const i=`setup_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;console.log(`[InvoicesList][${i}] Setting up close button for modal`),requestAnimationFrame((()=>{setTimeout((()=>{const e=document.getElementById("success-close-button");if(console.log(`[InvoicesList][${i}] Button lookup:`,{found:!!e,hasListeners:e?e._listeners:void 0}),e){const t=e._listenerCount||0;t>0&&console.warn(`[InvoicesList][${i}] â ï¸ Button already has ${t} listeners!`),e._listenerCount=t+1;const o=n;e.addEventListener("click",(async e=>{const t=`click_${Date.now()}`;console.log(`[InvoicesList][${i}][${t}] Close button clicked`),console.log(`[InvoicesList][${i}][${t}] Modal state:`,{modalExists:!!o,hasCloseMethod:"function"==typeof o?.close});try{o&&"function"==typeof o.close?(console.log(`[InvoicesList][${i}][${t}] Calling close()`),o.close(),console.log(`[InvoicesList][${i}][${t}] Close() completed`)):console.error(`[InvoicesList][${i}][${t}] â Cannot close - invalid modal reference`),console.log(`[InvoicesList][${i}][${t}] Starting refresh`),await this.refresh(),console.log(`[InvoicesList][${i}][${t}] Refresh completed`)}catch(e){console.error(`[InvoicesList][${i}][${t}] Error:`,e)}}),{once:!0}),console.log(`[InvoicesList][${i}] â
Listener added (total: ${e._listenerCount})`)}else console.error(`[InvoicesList][${i}] â Button not found!`),console.error(`[InvoicesList][${i}] All buttons with ID:`,Array.from(document.querySelectorAll("[id]")).filter((e=>e.id)).map((e=>e.id)))}),100)}))}}catch(e){console.error("[InvoicesList] Error showing payment confirmation:",e),te.Alert.error("Payment processed, but failed to show confirmation"),n.close(),await this.refresh()}}async addPaymentMethodForInvoice(e,t){try{if(console.log("[InvoicesList] Adding payment method for invoice with accountId:",{invoiceId:e.invoiceId,accountId:e.accountId,paymentData:t}),!e.accountId)throw new Error("Invoice accountId is required");if(!t.tokenId)throw new Error("Payment token is required");if(!t.billingAddress?.id)throw new Error("Billing address ID is required");const n={accountId:e.accountId,recurlyToken:t.tokenId,billingAddressId:t.billingAddress.id,default:!1};console.log("[InvoicesList] Calling payment method add API with data:",n);const o=await this.addPaymentMethodForInvoiceAPI(n);return o.success?(console.log("[InvoicesList] Payment method added successfully for invoice payment:",o.data),!0):(console.error("[InvoicesList] Failed to add payment method for invoice:",o.error),te.Alert.error(`Failed to add payment method: ${o.error?.message||"Unknown error"}`),!1)}catch(e){return console.error("[InvoicesList] Error adding payment method for invoice:",e),te.Alert.error("Failed to add payment method for invoice payment"),!1}}async handleAddNewAddressForInvoice(e,t,n,o,i,a){try{console.log("[InvoicesList] Opening address modal for new address creation");const s=document.getElementById("add-new-address-card"),r=document.getElementById("step-content");
1if(s&&r){r.innerHTML='\n <div>\n <div id="inline-address-form-container"></div>\n </div>\n ';const s=new Qe.W({inline:!0,forceBillingOnly:!0,hideAddressType:!0,hideBackButton:!0,isFirstAddress:0===n.length,title:"Add Billing Address",submitText:"Save Address",onSave:async a=>{try{const s=await He.A.addAddress(a);if(s&&(s.addresses||"success"===s.status)){const a=await this.fetchAddressesForModal(!0);te.Alert.success("Address added successfully"),n=a;const s=document.getElementById("step-content");if(s){s.innerHTML=this.renderBillingAddressStep(a);const n=s.querySelectorAll('input[name="billing-address"]'),r=document.getElementById("continue-button");n.forEach((e=>{e.addEventListener("change",(e=>{const t=e.target;if(t.checked){const e=a.find((e=>e.id===t.value));i&&i(e),r&&(r.disabled=!1)}}))}));const d=s.querySelector("#add-new-address-card");if(d&&d.addEventListener("click",(async()=>{const s=a.find((e=>{const t=Array.from(n).find((t=>t.value===e.id));return t?.checked}));await this.handleAddNewAddressForInvoice(e,t,a,o,i,s)})),n.length>0){const e=n[n.length-1];e.checked=!0;const t=a.find((t=>t.id===e.value));i&&i(t),r&&(r.disabled=!1)}}}else console.error("[InvoicesList] Failed to save address:",s),te.Alert.error("Failed to save address")}catch(e){console.error("[InvoicesList] Error saving address:",e),te.Alert.error("Failed to save billing address")}},onCancel:()=>{console.log("[InvoicesList] Address creation cancelled"),r.innerHTML=this.renderBillingAddressStep(n);const s=r.querySelectorAll('input[name="billing-address"]'),d=document.getElementById("continue-button");if(a){const e=Array.from(s).find((e=>e.value===a.id));e&&(e.checked=!0,d&&(d.disabled=!1))}s.forEach((e=>{e.addEventListener("change",(e=>{const t=e.target;if(t.checked){const e=n.find((e=>e.id===t.value));i&&i(e),d&&(d.disabled=!1)}}))}));const l=r.querySelector("#add-new-address-card");l&&l.addEventListener("click",(async()=>{await this.handleAddNewAddressForInvoice(e,t,n,o,i,a)}))}}),d=document.getElementById("inline-address-form-container");d&&await s.renderInline(d);const l=document.getElementById("back-button");if(l){l.classList.remove("invisible");const i=l.cloneNode(!0);l.parentNode?.replaceChild(i,l),i.addEventListener("click",(()=>{r.innerHTML=this.renderBillingAddressStep(n),this.setupPaymentUpdateModalListeners(e,t,n,o)}))}}}catch(e){console.error("[InvoicesList] Error opening address modal:",e),te.Alert.error("Failed to open address form")}}async validatePaymentForm(){try{console.log("[InvoicesList] Debugging payment form structure...");const e=document.querySelector("#payment-modal-container");if(!e)return console.error("[InvoicesList] Payment modal container not found"),!1;console.log("[InvoicesList] Payment container HTML:",e.innerHTML.substring(0,500));const t=e.querySelectorAll("[data-recurly]");console.log("[InvoicesList] Found Recurly fields:",Array.from(t).map((e=>e.getAttribute("data-recurly"))));const n=e.querySelectorAll("input, select, textarea");console.log("[InvoicesList] All form inputs:",Array.from(n).map((e=>{const t=e;return{name:t.name,type:t.type,id:t.id,required:t.required,value:t.value}})));const o=e.querySelectorAll('input[type="checkbox"]');console.log("[InvoicesList] Found checkboxes:",Array.from(o).map((e=>{const t=e;return{name:t.name,id:t.id,checked:t.checked,required:t.required}})));const i=e.innerHTML.trim().length>0;return console.log("[InvoicesList] Payment container has content:",i),i}catch(e){return console.error("[InvoicesList] Error validating payment form:",e),!1}}async submitPaymentForm(e){try{console.log("[InvoicesList] Submitting payment form");const e=document.querySelector('#payment-modal-container button[data-action="continue"]');if(e)return console.log("[InvoicesList] Found PaymentModal continue button, clicking it"),void e.click();const t=Array.from(document.querySelectorAll("#payment-modal-container button")).find((e=>e.textContent?.includes("Continue")||e.textContent?.includes("Review")||e.textContent?.includes("Submit")));if(t)return console.log("[InvoicesList] Found continue/submit button by text, clicking it"),void t.click();const n=document.querySelector("#payment-modal-container form");if(!n)throw new Error("Could not find payment form or continue button");{console.log("[InvoicesList] Found payment form, dispatching submit event");const e=new Event("submit",{bubbles:!0,cancelable:!0});n.dispatchEvent(e)}}catch(e){throw console.error("[InvoicesList] Error submitting payment form:",e),e}}setupAddressSelectionHandlers(e){const t=document.querySelectorAll('input[name="billing-address"]'),n=document.getElementById("continue-button"),o=t[0];o&&o.checked&&n&&(n.disabled=!1),t.forEach((e=>{e.addEventListener("change",(e=>{e.target.checked&&n&&(n.disabled=!1)}))}));const i=document.querySelector("#add-new-address-card");if(i){const e=i.cloneNode(!0);i.parentNode?.replaceChild(e,i),e.addEventListener("click",(async()=>{}))}}async addPaymentMethodForInvoiceAPI(e){try{console.log("[InvoicesList] Making isolated invoice payment method API call:",e);const t=e.accountId?.startsWith("test_account_");if(t)return console.log("[InvoicesList] Test mode detected - mocking API response"),{success:!0,data:{paymentMethodId:"test_pm_"+Date.now(),message:"Test payment method added successfully"}};const n=await fetch(`${f.A.apiBaseUrl}/profile/payment-methods/add`,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(e)});if(!n.ok)throw new Error(`API call failed: ${n.status} ${n.statusText}`);const o=await n.json();return console.log("[InvoicesList] Invoice payment method API response:",o),{success:!0,data:o}}catch(e){return console.error("[InvoicesList] Invoice payment method API error:",e),{success:!1,error:e}}}renderAddressCard(e,t=!1){return`\n <label class="block cursor-pointer address-card" data-address-id="${e.
1id}">\n <input type="radio" name="billing-address" value="${e.id}" class="sr-only address-radio" ${t?"checked":""}>\n <div class="relative border-2 rounded-lg p-4 transition-all duration-200 border-gray-200 hover:border-gray-300 hover:shadow-md hover:bg-gray-50/50 address-card-inner">\n \x3c!-- Selection Indicator --\x3e\n <div class="absolute top-4 right-4">\n <div class="w-6 h-6 rounded-full border-2 transition-all duration-200 flex items-center justify-center border-gray-300 bg-white address-indicator">\n </div>\n </div>\n\n <div class="pr-10">\n <div class="flex items-center mb-2">\n <h4 class="font-semibold text-gray-900">${e.firstName} ${e.lastName}</h4>\n ${this.renderAddressBadges(e)}\n </div>\n\n <div class="text-sm text-gray-600 space-y-1">\n <p class="font-medium">${e.street1}${e.street2?`, ${e.street2}`:""}</p>\n <p>${e.city}, ${e.region} ${e.postalCode}</p>\n <p>${this.getCountryName(e.country)}</p>\n </div>\n </div>\n </div>\n\n <style>\n .address-card .address-radio:checked ~ .address-card-inner {\n border-color: rgb(37 99 235) !important;\n background-color: rgb(239 246 255 / 0.5) !important;\n }\n .address-card .address-radio:checked ~ .address-card-inner .address-indicator {\n border-color: rgb(37 99 235) !important;\n background-color: rgb(37 99 235) !important;\n }\n .address-card .address-radio:checked ~ .address-card-inner .address-indicator::after {\n content: "â";\n color: white;\n font-size: 14px;\n font-weight: bold;\n }\n </style>\n </label>\n `}renderAddressBadges(e){const t=[];return e.isDefaultBilling?t.push('<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-primary-100 text-primary-800 ml-2">Default Billing</span>'):e.isBilling&&t.push('<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-gray-100 text-gray-800 ml-2">Billing</span>'),e.isDefaultShipping?t.push('<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800 ml-2">Default Shipping</span>'):e.isShipping&&t.push('<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-gray-100 text-gray-800 ml-2">Shipping</span>'),t.join("")}sortAddresses(e){return e.sort(((e,t)=>e.isDefaultBilling&&!t.isDefaultBilling?-1:!e.isDefaultBilling&&t.isDefaultBilling?1:e.isBilling&&!t.isBilling?-1:!e.isBilling&&t.isBilling?1:(e.firstName||"").localeCompare(t.firstName||"")))}getCountryName(e){return{US:"United States",CA:"Canada",GB:"United Kingdom",AU:"Australia"}[e]||e}async collectWithSelectedPaymentMethod(e,t){try{if(console.log("[InvoicesList] Collecting with selected payment method:",t),!e.invoiceId)return console.error("[InvoicesList] No invoice ID available for collection:",e),void te.Alert.error("Invoice ID is missing. Cannot collect payment.");if(!await we.Modal.confirm({title:"Confirm Payment",message:`\n <div class="space-y-4">\n <p class="text-gray-700">You are about to pay invoice #${e.invoiceNumber||e.id} for ${W(e.amount,{currency:e.currency})} using your selected payment method.</p>\n <div class="bg-blue-50 border border-blue-200 rounded-lg p-3">\n <p class="text-sm text-blue-800">Your existing payment method will be charged immediately.</p>\n </div>\n </div>\n `,confirmText:"Pay Now",cancelText:"Cancel",confirmClass:"bg-green-600 hover:bg-green-700 text-white"}))return void console.log("[InvoicesList] Payment cancelled by user");if(console.log("[InvoicesList] Processing payment with existing method:",t),!e.invoiceId)return console.error("[InvoicesList] No invoice ID available:",e),void te.Alert.error("Invoice ID is missing. Cannot process payment.");try{te.Alert.success(`Payment processed successfully! Invoice #${e.invoiceNumber||e.id} has been paid with your existing payment method.`),await this.render()}catch(e){console.error("[InvoicesList] Error processing payment with existing method:",e),te.Alert.error("Failed to process payment with existing payment method")}}
1catch(e){console.error("[InvoicesList] Error collecting with selected payment method:",e),te.Alert.error("Failed to process payment with selected method")}}formatCardBrand(e){return{visa:"Visa",mastercard:"Mastercard",master:"Mastercard",amex:"American Express",american_express:"American Express",discover:"Discover",card:"Card"}[e?.toLowerCase()]||"Card"}getCardGradient(e){const t={visa:"from-blue-600 to-blue-700",mastercard:"from-red-500 to-orange-600",amex:"from-green-600 to-teal-600",discover:"from-orange-500 to-yellow-600",card:"from-gray-600 to-gray-700"};return t[e?.toLowerCase()]||t.card}async openPaymentVerificationModal(e){try{const e=(await w.default.load()).recurlyPublicKey;if(!e)return void te.Alert.error("Payment configuration is not available. Please contact support.");const t=await this.fetchAddressesForModal(),n=new ft.default({addresses:t,recurlyPublicKey:e,onSuccess:async e=>{console.log("[InvoicesList] Payment verification successful:",e),(0,ct.wJ)(ct.aC.MODAL_SUCCESS,{method:e}),n.hide()},onCancel:()=>{console.log("[InvoicesList] Payment verification cancelled"),(0,ct.wJ)(ct.aC.MODAL_CLOSED)},onAddressNeeded:async()=>await this.fetchAddressesForModal()});await n.show(),console.log("[InvoicesList] Payment verification modal opened successfully")}catch(e){console.error("[InvoicesList] Error opening payment verification modal:",e),te.Alert.error("Failed to open payment verification modal. Please try again.")}}async fetchAddressesForModal(e=!1){try{const{default:t}=await Promise.resolve().then(n.bind(n,4849));return await t.loadAddresses(e)}catch(e){return console.warn("Addresses fetch error:",e),[]}}async showAddFirstPaymentMethodModal(e){const t=`\n <div class="p-6">\n <div class="text-center mb-6">\n <div class="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-4">\n <svg class="w-8 h-8 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" />\n </svg>\n </div>\n <h3 class="text-lg font-semibold text-gray-900 mb-2">Add Payment Method</h3>\n <p class="text-gray-600">You need to add a payment method to pay for this invoice.</p>\n </div>\n\n <div class="bg-gray-50 rounded-lg p-4 mb-6">\n <div class="flex justify-between items-center">\n <span class="text-gray-600">Invoice #${e.invoiceNumber||e.id}</span>\n <span class="text-xl font-bold text-gray-900">${W(e.amount,{currency:e.currency})}</span>\n </div>\n </div>\n\n <div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">\n <div class="flex items-start">\n <svg class="w-5 h-5 text-blue-600 mt-0.5 mr-3 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n <div>\n <h4 class="text-sm font-medium text-blue-900 mb-1">Payment Setup</h4>\n <p class="text-sm text-blue-700">After adding your payment method, we'll automatically charge it for this invoice.</p>\n </div>\n </div>\n </div>\n\n <div class="flex items-center justify-between pt-4 border-t">\n <button type="button" class="px-4 py-2 text-gray-700 border border-gray-300 rounded-lg hover:bg-gray-50 font-medium" data-action="cancel">\n Cancel\n </button>\n <button type="button" class="px-6 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 font-medium" data-action="go-to-payment-tab">\n Go to Payment Tab\n </button>\n </div>\n </div>\n `,n=new we.Modal({id:`add-first-payment-${e.invoiceId}`,title:"Pay Invoice",content:t,size:"medium",closeOnOverlay:!0});n.open(),this.setTimeout((()=>{const e=document.querySelector('[data-action="go-to-payment-tab"]'),t=document.querySelector('[data-action="cancel"]');e&&e.addEventListener("click",(()=>{n.close(),window.location.hash="payment"})),t&&t.addEventListener("click",(()=>{n.close()}))}),100)}async collectInvoice(e,t){try{const n={recurlyToken:t.tokenId,billingAddressId:t.billingAddressId,default:t.setAsDefault};t.accountId&&(n.accountId=t.accountId,console.log("[InvoicesList] Including accountId in collect-invoice request:",t.accountId));const o=await this.invoiceApi.collectInvoice(e,n);if(o.success)return te.Alert.success("Invoice collected successfully"),!0;{const e="string"==typeof o.error?o.error:"Failed to collect invoice";return te.Alert.error(e),!1}}
1catch(e){return console.error("[InvoicesList] Error collecting invoice:",e),te.Alert.error(e.message||"Failed to collect invoice"),!1}}renderInvoiceModal(e){return`\n <div class="p-6">\n <div class="flex items-center justify-between mb-6">\n <h3 class="text-2xl font-semibold text-gray-900">Invoice #${e.invoiceNumber||e.id}</h3>\n <div class="flex items-center space-x-2">\n <span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium ${Xt[e.status]?.bgColor||"bg-gray-100"} ${Xt[e.status]?.textColor||"text-gray-800"}">\n ${Xt[e.status]?.label||e.status}\n </span>\n ${e.isOutstandingInvoice?'<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-orange-100 text-orange-800">\n Outstanding\n </span>':""}\n </div>\n </div>\n\n <div class="space-y-4">\n \x3c!-- Invoice Details --\x3e\n <div class="grid grid-cols-2 gap-4">\n <div>\n <p class="text-sm text-gray-500">Invoice Date</p>\n <p class="text-base font-medium text-gray-900">${(0,Fe.Yq)(e.date)}</p>\n </div>\n <div>\n <p class="text-sm text-gray-500">Due Date</p>\n <p class="text-base font-medium text-gray-900">${(0,Fe.Yq)(e.dueDate||e.date)}</p>\n </div>\n </div>\n\n \x3c!-- Payment Details --\x3e\n <div class="border-t pt-4">\n <h4 class="text-sm font-semibold text-gray-700 mb-3">Payment Details</h4>\n <div class="space-y-2">\n <div class="flex justify-between text-base font-semibold">\n <span class="text-gray-900">Amount</span>\n <span class="text-gray-900">${W(e.amount,{currency:e.currency})}</span>\n </div>\n ${void 0!==e.paidAmount&&"paid"===e.status?`\n <div class="flex justify-between text-sm text-green-600 border-t pt-2">\n <span>Paid Amount</span>\n <span>${W(e.paidAmount,{currency:e.currency})}</span>\n </div>\n `:""}\n </div>\n </div>\n\n <div class="grid grid-cols-2 gap-4">\n <div>\n <p class="text-sm text-gray-500">Status</p>\n <p class="text-base font-medium ${Xt[e.status]?.textColor||"text-gray-900"}">\n ${Xt[e.status]?.label||e.status}
1\n ${e.paidDate&&"paid"===e.status?`<br><span class="text-xs text-gray-500">Paid on ${(0,Fe.Yq)(e.paidDate)}</span>`:""}\n </p>\n </div>\n <div>\n <p class="text-sm text-gray-500">Currency</p>\n <p class="text-base font-medium text-gray-900">${e.currency||"CAD"}</p>\n </div>\n </div>\n\n ${e.description?`\n <div class="border-t pt-4">\n <p class="text-sm text-gray-500">Description</p>\n <p class="text-base text-gray-900">${e.description}</p>\n </div>\n `:""}\n\n ${e.accountUserName?`\n <div class="border-t pt-4">\n <p class="text-sm text-gray-500">Account</p>\n <p class="text-base text-gray-900">${e.accountUserName}</p>\n </div>\n `:""}\n\n\n \x3c!-- Action Buttons --\x3e\n <div class="mt-6 pt-6 border-t">\n ${e.isOutstandingInvoice?`\n <button class="hg-collect-invoice-modal w-full inline-flex items-center justify-center px-6 py-3 bg-green-600 text-white font-medium rounded-lg hover:bg-green-700 transition-colors mb-3"\n data-invoice='${JSON.stringify(e).replace(/'/g,"'")}'>\n ${P.H.render("credit-card",{class:"w-5 h-5 mr-2"})}\n Settle Outstanding Invoice\n </button>\n `:""}\n <button class="hg-download-invoice-modal w-full inline-flex items-center justify-center px-6 py-3 bg-primary-600 text-white font-medium rounded-lg hover:bg-primary-700 transition-colors"\n data-invoice-id="${e.invoiceId||e.id}">\n ${P.H.render("download",{class:"w-5 h-5 mr-2"})}\n Download Invoice PDF\n </button>\n </div>\n </div>\n </div>\n `}async showInvoicePaymentComingSoonModal(e){let t="[email protected]",n="";try{const e=await v.initService.getInitData();e?.generalConfig?.companySupportEmail&&(t=e.generalConfig.companySupportEmail),e?.generalConfig?.companySupportPhone&&(n=e.generalConfig.companySupportPhone)}catch(e){console.error("Failed to get support contact info:",e)}await we.Modal.confirm({title:"Invoice Payment",message:`\n <div class="text-center space-y-6">\n <div class="flex justify-center">\n <div class="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center">\n <svg class="w-8 h-8 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n </div>\n </div>\n\n <div class="space-y-4">\n <p class="text-gray-700">\n We are working hard to bring you this feature. In the meantime, you can settle outstanding invoices by calling customer support and quoting your invoice number.\n </p>\n\n <div class="bg-gray-50 rounded-lg p-4 space-y-3">\n <p class="text-sm text-gray-600">\n <strong>Invoice Number:</strong> ${e.invoiceNumber||e.number||e.id}\n </p>\n\n <div class="text-sm text-gray-600">\n <p class="mb-2">Contact our customer support team:</p>\n <div class="space-y-1">\n ${n?`\n <div class="flex items-center justify-center">\n <svg class="w-4 h-4 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" />\n </svg>\n <a href="tel:${n}" class="text-blue-600 hover:text-blue-700 font-medium">\n ${n}\n </a>\n </div>\n `:""}\n <div class="flex items-center justify-center">\n <svg class="w-4 h-4 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />\n </svg>\n <a href="mailto:${t}" class="text-blue-600 hover:text-blue-700 font-medium">\n ${t}\n </a>\n </div>\n </div>\n </div>\n </div>\n\n ${n?'<p class="text-sm text-gray-500">For immediate assistance, please call the phone number above.</p>':'<p class="text-sm text-gray-500">If this is urgent, you can also call our customer service team directly for immediate assistance.</p>'}\n </div>\n </div>\n `,confirmText:"Got it",confirmClass:"bg-blue-600 hover:bg-blue-700 text-white"})}async updatePaymentMethodsForOutstandingInvoice(e,t){try{if(console.log("[InvoicesList] Updating payment method for invoice account:",e.accountId),!e.accountId)return console.error("[InvoicesList] No accountId found on invoice"),!1;if(!t?.tokenId)return console.error("[InvoicesList] No tokenId in payment data"),!1;try{return await this.updatePaymentMethodForInvoice(e.accountId,e,{tokenId:t.tokenId,billingAddress:t.billingAddress})?(te.Alert.success("Successfully updated payment method"),!0):(te.Alert.error("Failed to update payment method"),!1)}catch(t){return console.error(`Error updating payment method for account ${e.accountId}:`,t),te.Alert.error("Failed to update payment method"),!1}}catch(e){return console.error("[InvoicesList] Error updating payment method for outstanding invoice:",e),te.Alert.error("Failed to update payment method"),!1}}async updatePaymentMethodForInvoice(e,t,n){try{const o=t.invoiceId?.startsWith("test_invoice_");
1if(o)return console.log("[InvoicesList] Test mode detected - mocking payment method update"),!0;const i={accountId:e,invoiceId:t.invoiceId,recurlyToken:n?.tokenId,billingAddressId:n?.billingAddress?.id,default:!1};console.log("[InvoicesList] Updating payment method for account:",e),console.log("[InvoicesList] Request body:",i);const a=await fetch(`${f.A.apiBaseUrl}/profile/payment-methods/update`,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(i)});if(a.ok){const t=await a.json();return console.log("[InvoicesList] Update response for account",e,":",t),!1!==t.success}return console.error("Payment method update API failed:",a.status,a.statusText),!1}catch(e){return console.error("[InvoicesList] Error calling payment method update API:",e),!1}}async testInvoiceSettlement(e){console.log(`[InvoicesList] Testing invoice settlement - enabled: ${e}`);const t={id:"test_invoice_"+Date.now(),invoiceId:"test_invoice_"+Date.now(),invoiceNumber:"TEST-"+Math.floor(1e4*Math.random()),number:"TEST-"+Math.floor(1e4*Math.random()),date:new Date(Date.now()-2592e6).toISOString(),dueDate:new Date(Date.now()-1296e6).toISOString(),amount:125.99,currency:"USD",status:Kt,description:"Test Outstanding Invoice",accountUserName:"[email protected]",accountId:"test_account_456",isOutstandingInvoice:!0},n=v.initService.getInitData;v.initService.getInitData=async()=>{const t=await n.call(v.initService);return{...t,generalConfig:{...t?.generalConfig,enableInvoiceSettlement:e}}};try{console.log("[InvoicesList] Simulating invoice settlement flow - Settlement "+(e?"ENABLED":"DISABLED")),te.Alert.success("Testing: Invoice settlement "+(e?"ENABLED":"DISABLED")),await this.handleInvoiceCollection(t)}catch(e){console.error("[InvoicesList] Error in test invoice settlement:",e),te.Alert.error(`Test failed: ${e instanceof Error?e.message:"Unknown error"}`)}finally{v.initService.getInitData=n}}}var mn=un;if("undefined"!=typeof window){const e=()=>{document.querySelectorAll('[data-hg-component="invoices-list"]').forEach((e=>{e.dataset.initialized||(new un(e),e.dataset.initialized="true")}))};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",e):e()}var gn=class{constructor(e,t={}){this.impl=new mn(e,t)}async render(){return this.impl.render()}cleanup(){this.impl.destroy()}destroy(){this.impl.destroy()}async refresh(){return this.impl.refresh()}};new class{constructor(){this.manager=dn,this.config=ln,this.instances=new Map,this.handlers=new Map,this.cleanupFunctions=[],this.isInitialized=!1}async initialize(e={}){if(!this.isInitialized)try{this.initializeHandlers(),this.setupEventListeners(),!1!==e.autoScan&&await this.scanAndRender(),this.isInitialized=!0,console.log("[InvoiceSystem] Initialized successfully")}catch(e){throw console.error("[InvoiceSystem] Failed to initialize:",e),e}}initializeHandlers(){const e=new cn;this.handlers.set("download",e)}setupEventListeners(){const e=Ee.sV.Profile.on("SECTION_CHANGE",(e=>{"invoices"===e.section&&this.refreshAll()}));this.cleanupFunctions.push(e);const t=Ee.sV.Auth.on("LOGOUT_SUCCESS",(()=>{this.cleanup()}));this.cleanupFunctions.push(t);const n=Ee.sV.Payment.on("PROCESS_SUCCESS",(async()=>{await this.manager.loadInvoices(!0),this.refreshAll()}));this.cleanupFunctions.push(n)}async scanAndRender(){const e=document.querySelectorAll("[data-invoices-list], .invoices-content");for(const t of e)this.instances.has(t)||await this.renderInvoicesList(t)}async renderInvoicesList(e,t={}){try{const n=new gn(e,{...t,manager:this.manager,config:this.config,downloadHandler:this.handlers.get("download")});return await n.render(),this.instances.set(e,n),n}catch(e){throw console.error("[InvoiceSystem] Failed to render invoices list:",e),e}}async refreshAll(){const e=[];for(const[,t]of this.instances)t&&"function"==typeof t.render&&e.push(t.render());await Promise.all(e)}getManager(){return this.manager}getConfig(){return this.config}cleanup(){this.cleanupFunctions.forEach((e=>e())),this.cleanupFunctions=[];for(const[,e]of this.instances)e&&"function"==typeof e.cleanup&&e.cleanup();this.instances.clear();for(const[,e]of this.handlers)e&&"function"==typeof e.cleanup&&e.cleanup();this.handlers.clear(),this.manager.reset(),this.isInitialized=!1,console.log("[InvoiceSystem] Cleaned up")}async exportInvoices(e={}){console.warn("[InvoiceSystem] Export functionality not yet implemented")}};const hn={name:"invoiceSystemAdapter",initialize:async()=>{}};"undefined"!=typeof window&&A.systemRegistry.register("invoiceSystemAdapter",hn);class pn{static render({id:e="",currentPage:t,totalPages:n,showPageNumbers:o=!0,maxPageNumbers:i=5,showFirstLast:a=!0,showPrevNext:s=!0,className:r="",onPageChange:d,prevText:l="Previous",nextText:c="Next",firstText:u="First",lastText:m="Last"}){if(n<=1)return"";
1const g=["pagination",r].filter(Boolean).join(" "),h=e?`id="${e}"`:"",p=this.getPageNumbers(t,n,i);return`\n <nav ${h} class="${g}" role="navigation" aria-label="Pagination">\n <ul class="pagination-list">\n ${this.renderFirstButton(t,a,u)}\n ${this.renderPrevButton(t,s,l)}\n ${o?this.renderPageNumbers(p,t):""}\n ${this.renderNextButton(t,n,s,c)}\n ${this.renderLastButton(t,n,a,m)}\n </ul>\n </nav>\n `}static renderSimple({id:e="",currentPage:t,totalPages:n,className:o="",onPageChange:i,prevText:a="Previous",nextText:s="Next"}){if(n<=1)return"";return`\n <nav ${e?`id="${e}"`:""} class="${["pagination pagination-simple",o].filter(Boolean).join(" ")}" role="navigation" aria-label="Pagination">\n <div class="pagination-simple-content">\n ${this.renderPrevButton(t,!0,a)}\n <span class="pagination-info">\n Page ${t} of ${n}\n </span>\n ${this.renderNextButton(t,n,!0,s)}\n </div>\n </nav>\n `}static getPageNumbers(e,t,n){const o=[],i=Math.floor(n/2);let a=Math.max(1,e-i),s=Math.min(t,e+i);s-a+1<n&&(1===a?s=Math.min(t,a+n-1):s===t&&(a=Math.max(1,s-n+1)));for(let e=a;e<=s;e++)o.push(e);return o}static renderFirstButton(e,t,n){return t&&1!==e?`\n <li class="pagination-item">\n <button \n type="button"\n class="pagination-button"\n data-page="1"\n aria-label="Go to first page">\n ${n}\n </button>\n </li>\n `:""}static renderPrevButton(e,t,n){if(!t)return"";const o=1===e;return`\n <li class="pagination-item">\n <button \n type="button"\n class="pagination-button ${o?"disabled":""}"\n data-page="${e-1}"\n ${o?"disabled":""}\n aria-label="Go to previous page">\n ${n}\n </button>\n </li>\n `}static renderNextButton(e,t,n,o){if(!n)return"";const i=e===t;return`\n <li class="pagination-item">\n <button \n type="button"\n class="pagination-button ${i?"disabled":""}"\n data-page="${e+1}"\n ${i?"disabled":""}\n aria-label="Go to next page">\n ${o}\n </button>\n </li>\n `}static renderLastButton(e,t,n,o){return n&&e!==t?`\n <li class="pagination-item">\n <button \n type="button"\n class="pagination-button"\n data-page="${t}"\n aria-label="Go to last page">\n ${o}\n </button>\n </li>\n `:""}static renderPageNumbers(e,t){return e.map((e=>{const n=e===t;return`\n <li class="pagination-item">\n <button \n type="button"\n class="pagination-button ${n?"active":""}"\n data-page="${e}"\n ${n?'aria-current="page"':""}\n aria-label="Go to page ${e}">\n ${e}\n </button>\n </li>\n `})).join("")}static attachEventListeners(e,t){t&&e.addEventListener("click",(e=>{const n=e.target.closest("[data-page]");if(n&&!n.disabled&&!n.classList.contains("disabled")){const e=parseInt(n.dataset.page||"1",10);isNaN(e)||t(e)}}))}}class yn extends Ut.pZ{constructor(e){super({baseURL:e||f.A.apiBaseUrl||"/api/heimguard"})}async get(e,t={}){try{return await super.get(e,t)}catch(t){if(t instanceof Ut.LG&&404===t.status&&(e.includes("/status")||e.includes("/affinity/user-items")))return{success:!1,data:void 0};throw t}}async getLikeStatus(e){try{return await this.get("/like/status",{params:{contentId:e}})}catch(e){return console.warn("Failed to get like status:",e),{success:!0,data:{isLiked:!1,likeCount:0}}}}async toggleLike(e,t){const n=t?"likeActionRemove":"likeActionAdd";return await this.post("/like",{contentId:e,likeAction:n})}async getFollowStatus(e){try{return await this.get("/follow/status",{params:{contentId:e}})}catch(e){return console.warn("Failed to get follow status:",e),{success:!0,data:{isFollowing:!1,followCount:0}}}}async toggleFollow(e,t){const n=t?"followActionRemove":"followActionAdd";return await this.post("/follow",{contentId:e,followAction:n})}async getStatus(e){try{const[t,n]=await Promise.all([this.getLikeStatus(e),this.getFollowStatus(e)]),o=t.data||{isLiked:!1,likeCount:0},i=n.data||{isFollowing:!1,followCount:0};return{success:!0,data:{...o,...i}}}catch(e){return{success:!0,data:{isLiked:!1,likeCount:0,isFollowing:!1,followCount:0}}}}async getUserItems(e="all",t=1,n=12){return await this.get("/affinity/user-items",{params:{type:e,page:t,pageSize:n}})}async getComments(e,t=1,n=20){return await this.get("/comments/get",{params:{contentId:e,pageNumber:t,pageSize:n}})}async addComment(e,t,n){return this.post("/comments/add",{contentId:e,commentBody:t,parentId:n||null})}async getChildComments(e){return this.get("/comments/get-children",{params:{parentId:e}})}}const Cn=new yn,fn="all",vn="liked",bn="followed",wn="/affinity/like",Sn="/affinity/like/status",xn="/affinity/follow",An="/affinity/follow/status",Tn="/affinity/user/items",Mn="/affinity/comments",En="/affinity/comments/add",Pn="/affinity/comments/children";var Nn=new class{constructor(){this.baseUrl=f.A.apiBaseUrl||"/api/heimguard"}get apiEndpoints(){return{like:wn,likeStatus:Sn,follow:xn,followStatus:A
1n,userItems:Tn,commentsGet:Mn,commentsAdd:En,commentsChildren:Pn}}get displaySettings(){return{itemsPerPage:20,showFilters:!0,showSearch:!1,showPagination:!0,showEmptyState:!0,enableInfiniteScroll:!1,cardLayout:"grid",showThumbnails:!0,showDescriptions:!0,showInteractionDate:!0,showContentType:!0}}get features(){return{enableLike:!0,enableFollow:!0,enableComments:!0,enableShare:!1,enableBookmark:!1,enableAnalytics:!1,enableBulkActions:!1,enableExport:!1,enableNotifications:!0}}getMessage(e,t){return{error:{loadFailed:"Failed to load content. Please try again.",likeFailed:"Failed to update like status. Please try again.",followFailed:"Failed to update follow status. Please try again.",commentsFailed:"Failed to load comments. Please try again.",networkError:"Network error. Please check your connection.",unauthorized:"You need to be logged in to perform this action.",forbidden:"You do not have permission to perform this action."},success:{liked:"Added to your liked content.",unliked:"Removed from your liked content.",followed:"Now following this content.",unfollowed:"No longer following this content.",commentAdded:"Comment added successfully."},empty:{noItems:"No content found",noItemsDesc:"You haven't liked or followed any content yet.",noLiked:"No liked content yet",noLikedDesc:"Content you like will appear here.",noFollowed:"Not following anything yet",noFollowedDesc:"Authors and topics you follow will appear here.",noResults:"No content matches your criteria",noResultsDesc:"Try adjusting your filters or search terms.",noComments:"No comments yet",noCommentsDesc:"Be the first to comment on this content."},loading:{items:"Loading your content...",more:"Loading more...",status:"Updating...",comments:"Loading comments..."}}[e]?.[t]||""}get ui(){return{debounceDelay:300,animationDuration:200,toastDuration:3e3,maxRetries:3,loadingIndicatorDelay:500,errorRetryDelay:1e3}}get validation(){return{maxCommentLength:500,minSearchLength:2,maxSearchLength:100,validContentTypes:["article","video","podcast","author","topic","series"],validAffinityTypes:["like","follow","both"]}}get performance(){return{enableCaching:!0,cacheExpiry:3e5,enablePrefetch:!1,enableLazyLoading:!0,enableVirtualScrolling:!1,batchSize:20}}};const Ln={ITEMS_LOADING:"affinity:items:loading",ITEMS_LOADED:"affinity:items:loaded",ITEMS_ERROR:"affinity:items:error",ITEMS_UPDATED:"affinity:items:updated",LIKE_LOADING:"affinity:like:loading",LIKE_SUCCESS:"affinity:like:success",LIKE_ERROR:"affinity:like:error",LIKE_STATUS_CHANGED:"affinity:like:status:changed",FOLLOW_LOADING:"affinity:follow:loading",FOLLOW_SUCCESS:"affinity:follow:success",FOLLOW_ERROR:"affinity:follow:error",FOLLOW_STATUS_CHANGED:"affinity:follow:status:changed",STATUS_LOADING:"affinity:status:loading",STATUS_LOADED:"affinity:status:loaded",STATUS_ERROR:"affinity:status:error",FILTER_CHANGED:"affinity:filter:changed",PAGE_CHANGED:"affinity:page:changed",SORT_CHANGED:"affinity:sort:changed",WIDGET_INITIALIZED:"affinity:widget:initialized",WIDGET_DESTROYED:"affinity:widget:destroyed",DASHBOARD_OPENED:"affinity:dashboard:opened",DASHBOARD_CLOSED:"affinity:dashboard:closed",COMMENTS_LOADING:"affinity:comments:loading",COMMENTS_LOADED:"affinity:comments:loaded",COMMENTS_ERROR:"affinity:comments:error",COMMENT_ADDED:"affinity:comment:added",COMMENT_ERROR:"affinity:comment:error"},Dn=new nn.b({namespace:"affinity",debug:!1});function In(e,t={}){const n={timestamp:Date.now(),source:"affinity",...t};Dn.emit(e,n)}function kn(e,t,n){return Dn.on(e,t,n)}function On(e,t,n=0){In(Ln.LIKE_STATUS_CHANGED,{contentId:e,isLiked:t,likeCount:n,action:t?"liked":"unliked"})}function Rn(e,t,n=0){In(Ln.FOLLOW_STATUS_CHANGED,{contentId:e,isFollowing:t,followCount:n,action:t?"followed":"unfollowed"})}var Bn=new class{constructor(){this.api=Cn,this.config=Nn,this.cache=new Map,this.pendingRequests=new Map}async getLikeStatus(e){if(!e)throw new Error("Content ID is required");const t=`like:${e}`;if(this.cache.has(t)){const e=this.cache.get(t);if(Date.now()-e.timestamp<this.config.performance.cacheExpiry)return e.data}if(this.pendingRequests.has(t))return this.pendingRequests.get(t);const n=this._getLikeStatusFromAPI(e);this.pendingRequests.set(t,n);try{const e=await n;return this.cache.set(t,{data:e,timestamp:Date.now()}),e}
1catch(t){throw In(Ln.LIKE_ERROR,{contentId:e,error:t}),t}finally{this.pendingRequests.delete(t)}}async toggleLike(e,t=!1){if(!e)throw new Error("Content ID is required");In(Ln.LIKE_LOADING,{contentId:e});try{const n=await this.api.toggleLike(e,t),o=!t,i=n.data?.count||0,a=`like:${e}`;return this.cache.set(a,{data:{isLiked:o,likeCount:i},timestamp:Date.now()}),On(e,o,i),In(Ln.LIKE_SUCCESS,{contentId:e,isLiked:o,likeCount:i,action:o?"liked":"unliked"}),{isLiked:o,likeCount:i}}catch(t){throw In(Ln.LIKE_ERROR,{contentId:e,error:t}),t}}async getFollowStatus(e){if(!e)throw new Error("Content ID is required");const t=`follow:${e}`;if(this.cache.has(t)){const e=this.cache.get(t);if(Date.now()-e.timestamp<this.config.performance.cacheExpiry)return e.data}if(this.pendingRequests.has(t))return this.pendingRequests.get(t);const n=this._getFollowStatusFromAPI(e);this.pendingRequests.set(t,n);try{const e=await n;return this.cache.set(t,{data:e,timestamp:Date.now()}),e}catch(t){throw In(Ln.FOLLOW_ERROR,{contentId:e,error:t}),t}finally{this.pendingRequests.delete(t)}}async toggleFollow(e,t=!1){if(!e)throw new Error("Content ID is required");In(Ln.FOLLOW_LOADING,{contentId:e});try{const n=await this.api.toggleFollow(e,t),o=!t,i=n.data?.count||0,a=`follow:${e}`;return this.cache.set(a,{data:{isFollowing:o,followCount:i},timestamp:Date.now()}),Rn(e,o,i),In(Ln.FOLLOW_SUCCESS,{contentId:e,isFollowing:o,followCount:i,action:o?"followed":"unfollowed"}),{isFollowing:o,followCount:i}}catch(t){throw In(Ln.FOLLOW_ERROR,{contentId:e,error:t}),t}}async getStatus(e){if(!e)throw new Error("Content ID is required");In(Ln.STATUS_LOADING,{contentId:e});try{const[t,n]=await Promise.all([this.getLikeStatus(e),this.getFollowStatus(e)]),o={...t,...n};return In(Ln.STATUS_LOADED,{contentId:e,status:o}),o}catch(t){throw In(Ln.STATUS_ERROR,{contentId:e,error:t}),t}}async getUserItems(e=fn,t=1,n=null){const o=n||this.config.displaySettings.itemsPerPage;In(Ln.ITEMS_LOADING,{filter:e,page:t,pageSize:o});try{const n=await this.api.getUserItems(e,t,o);let i=[],a=0,s=1;if(n.success&&n.data){const e=n.data;"items"in e&&"totalCount"in e?(i=e.items||[],a=e.totalCount||0,s=e.totalPages||1):"pagination"in e&&(i=e.data||[],a=e.pagination.totalCount,s=e.pagination.totalPages)}In(Ln.ITEMS_LOADED,{filter:e,page:t,pageSize:o,items:i,totalCount:a,totalPages:s||1});const r={items:i,totalCount:a,totalPages:s,currentPage:t,page:t,pageSize:o};if(n.success&&n.data){const e=n.data;void 0!==e.totalLiked&&(r.totalLiked=e.totalLiked),void 0!==e.totalFollowed&&(r.totalFollowed=e.totalFollowed)}return r}catch(n){throw In(Ln.ITEMS_ERROR,{filter:e,page:t,pageSize:o,error:n}),n}}clearCache(e=null){e?(this.cache.delete(`like:${e}`),this.cache.delete(`follow:${e}`)):this.cache.clear()}clearExpiredCache(){const e=Date.now(),t=this.config.performance.cacheExpiry;for(const[n,o]of this.cache.entries())e-o.timestamp>t&&this.cache.delete(n)}
1getCacheStats(){return{size:this.cache.size,pendingRequests:this.pendingRequests.size,entries:Array.from(this.cache.keys())}}async _getLikeStatusFromAPI(e){const t=await this.api.getLikeStatus(e);return t.success&&t.data?t.data:{isLiked:!1,likeCount:0}}async _getFollowStatusFromAPI(e){const t=await this.api.getFollowStatus(e);return t.success&&t.data?t.data:{isFollowing:!1,followCount:0}}};class $n extends Le.${constructor(e,t={}){super(e,t),this.manager=Bn,this.config=t.config||Nn,this.pageSize=t.pageSize||this.config.displaySettings.itemsPerPage,this.store.setState({items:[],currentPage:1,totalPages:1,totalCount:0,isLoading:!1,error:null,filter:t.filter||fn})}getDefaultOptions(){return{autoInit:!1,debug:!1}}async onInit(){this.injectStyles(),this.store.subscribe(((e,t,n)=>{n.includes("filter")&&this.updateFilterTabs(),(n.includes("items")||n.includes("currentPage")||n.includes("totalPages")||n.includes("isLoading")||n.includes("error"))&&this.updateContentArea(),(n.includes("items")||n.includes("totalCount")||n.includes("apiResponse"))&&(this.updateStats(),this.updateFilterButtons())}))}injectStyles(){if(document.getElementById("affinity-dashboard-styles"))return;const e=document.createElement("style");e.id="affinity-dashboard-styles",e.textContent='\n .affinity-dashboard {\n background: #fff;\n }\n\n .affinity-items-grid {\n display: grid;\n grid-template-columns: repeat(1, 1fr);\n gap: 1rem;\n margin-bottom: 2rem;\n }\n @media (min-width: 640px) {\n .affinity-items-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1.25rem;\n }\n }\n @media (min-width: 1024px) {\n .affinity-items-grid {\n grid-template-columns: repeat(3, 1fr);\n gap: 1.5rem;\n }\n }\n\n .affinity-item-card {\n background: #ffffff;\n border: 1px solid #e5e7eb;\n border-radius: 0.75rem;\n overflow: hidden;\n transition: all 0.2s;\n cursor: pointer;\n position: relative;\n display: flex;\n flex-direction: column;\n }\n\n .affinity-item-card:hover {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n transform: translateY(-2px);\n }\n \n .affinity-item-card[data-affinity-type="liked"] {\n border-left: 3px solid #e91e63;\n }\n \n .affinity-item-card[data-affinity-type="followed"] {\n border-left: 3px solid #2196f3;\n }\n \n .affinity-item-card[data-affinity-type="both"] {\n background: linear-gradient(to right, rgba(233, 30, 99, 0.03) 0%, rgba(33, 150, 243, 0.03) 100%);\n position: relative;\n border-left: 3px solid #8b5cf6; /* Purple as a mix of pink and blue */\n }\n \n .affinity-item-card[data-affinity-type="both"]::before {\n content: \'\';\n position: absolute;\n left: -3px;\n top: 0;\n bottom: 0;\n width: 3px;\n background: linear-gradient(to bottom, #e91e63 0%, #8b5cf6 50%, #2196f3 100%);\n border-radius: 0.75rem 0 0 0.75rem;\n }\n\n .affinity-item-thumbnail {\n position: relative;\n padding-bottom: 56.25%; /* 16:9 aspect ratio */\n background: #f3f4f6;\n overflow: hidden;\n }\n \n .affinity-item-card[data-affinity-type="liked"] .affinity-item-thumbnail {\n background: linear-gradient(135deg, rgba(233, 30, 99, 0.05) 0%, rgba(233, 30, 99, 0.02) 100%);\n }\n \n .affinity-item-card[data-affinity-type="followed"] .affinity-item-thumbnail {\n background: linear-gradient(135deg, rgba(33, 150, 243, 0.05) 0%, rgba(33, 150, 243, 0.02) 100%);\n }\n \n .affinity-item-card[data-affinity-type="both"] .affinity-item-thumbnail {\n background: linear-gradient(135deg, rgba(233, 30, 99, 0.04) 0%, rgba(33, 150, 243, 0.04) 100%);\n }\n\n .affinity-item-thumbnail img {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n background-color: #f3f4f6;\n }\n\n .affinity-item-placeholder {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 40px;\n height: 40px;\n color: #9ca3af;\n opacity: 0.6;\n }
1\n\n .affinity-indicators {\n position: absolute;\n top: 0.75rem;\n right: 0.75rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n z-index: 10;\n }\n\n .affinity-indicator {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);\n backdrop-filter: blur(8px);\n background-color: rgba(0, 0, 0, 0.05);\n }\n \n .affinity-indicator svg {\n width: 18px;\n height: 18px;\n }\n\n .affinity-indicator.liked {\n background: rgba(233, 30, 99, 0.9);\n }\n\n .affinity-indicator.followed {\n background: rgba(33, 150, 243, 0.9);\n }\n\n .affinity-item-content {\n padding: 1rem;\n background: #fff;\n flex: 1;\n display: flex;\n flex-direction: column;\n }\n \n .affinity-item-card[data-affinity-type="liked"] .affinity-item-content {\n background: linear-gradient(to right, rgba(233, 30, 99, 0.02) 0%, transparent 100%);\n }\n \n .affinity-item-card[data-affinity-type="followed"] .affinity-item-content {\n background: linear-gradient(to right, rgba(33, 150, 243, 0.02) 0%, transparent 100%);\n }\n\n .affinity-item-title {\n font-size: 1rem;\n font-weight: 600;\n margin-bottom: auto;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n flex: 1;\n }\n\n .affinity-item-title a {\n color: #212529;\n text-decoration: none;\n }\n\n .affinity-item-title a:hover {\n color: #0056b3;\n }\n\n .affinity-item-meta {\n font-size: 0.875rem;\n color: #6c757d;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n }\n\n .affinity-item-type {\n display: inline-flex;\n align-items: center;\n padding: 0.125rem 0.5rem;\n font-size: 0.75rem;\n font-weight: 500;\n border-radius: 0.25rem;\n background: #e5e7eb;\n color: #374151;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.2s;\n }\n \n .affinity-item-type:hover {\n transform: scale(1.05);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n text-decoration: none;\n }\n \n .affinity-item-type.comment {\n background: #dbeafe;\n color: #1e40af;\n }\n \n .affinity-item-type.article {\n background: #d1fae5;\n color: #065f46;\n }\n \n .affinity-item-type.video {\n background: #fce7f3;\n color: #9d174d;\n }\n \n .affinity-item-type.image,\n .affinity-item-type.gallery {\n background: #f3e8ff;\n color: #6b21a8;\n }\n\n .affinity-item-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-top: 0.75rem;\n }\n\n .affinity-remove-btn {\n background: none;\n border: none;\n padding: 0.25rem;\n cursor: pointer;\n color: #dc2626;\n transition: opacity 0.2s;\n }\n\n .affinity-remove-btn:hover {\n opacity: 0.7;\n }\n\n .affinity-filter-group {\n display: flex;\n gap: 0.5rem;\n }\n\n .affinity-filter-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.75rem;\n font-size: 0.75rem;\n font-weight: 500;\n background: none;\n color: #6b7280;\n border: none;\n cursor: pointer;\n transition: all 0.2s;\n border-radius: 0.375rem;\n }\n\n .affinity-filter-btn:hover {\n background: #f3f4f6;\n color: #374151;\n }\n\n .affinity-filter-btn.active {\n background: #f3f4f6;\n color: #111827;\n font-weight: 600;\n }\n \n .filter-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 1.25rem;\n height: 1.25rem;\n padding: 0 0.25rem;\n background: #e5e7eb;\n color: #374151;\n font-size: 0.6875rem;\n font-weight: 600;\n border-radius: 9999px;\n margin-left: 0.125rem;\n }\n \n .affinity-filter-btn.active .filter-count {\n background: #4b5563;\n color: white;\n }\n\n .filter-icon {\n width: 0.875rem;\n height: 0.875rem;\n }\n\n @media (min-width: 640px) {\n .affinity-filter-group {\n gap: 1rem;\n }\n .affinity-filter-btn {\n gap: 0.375rem;\n padding: 0.5rem 1rem;\n font-size: 0.875rem;\n }\n .filter-icon {\n width: 1rem;\n height: 1rem;\n }\n }\n\n .filter-icon.heart {\n color: #e91e63;\n }\n\n .filter-icon.circle {\n color: #2196f3;\n }\n\n /* Loading state for cards being removed */\n .affinity-item-card.remov
1ing {\n position: relative;\n opacity: 0.6;\n pointer-events: none;\n }\n\n .affinity-item-card.removing::after {\n content: \'\';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(255, 255, 255, 0.8);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 20;\n }\n\n /* Loading spinner overlay */\n .affinity-loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(255, 255, 255, 0.9);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n min-height: 300px;\n }\n\n ',document.head.appendChild(e)}async fetchData(){await this.loadItems()}async render(){this.isInitialized||await this.init(),this.container.innerHTML=this.getTemplate(),this.attachEventListeners(),await this.fetchData()}updateContent(){const e=this.container.querySelector(".affinity-dashboard-content");e&&(e.innerHTML=this.getContentTemplate()),this.updateFilterTabs()}updateContentArea(){const e=this.container.querySelector(".affinity-dashboard-content");e&&(e.innerHTML=this.getContentTemplate())}updateFilterTabs(){const e=this.store.getState();this.container.querySelectorAll(".affinity-filter-btn").forEach((t=>{const n=t,o=n.getAttribute("data-filter")===e.filter;n.classList.toggle("active",o),n.setAttribute("aria-pressed",o?"true":"false")}))}updateFilterButtons(){const e=this.container.querySelector(".affinity-filter-group");e&&(e.innerHTML=this.getFilterButtons(),this.updateFilterTabs())}updateStats(){const e=this.container.querySelector(".affinity-stats");if(e){const t=this.store.getState(),n=t.items.filter((e=>"liked"===e.affinityType||"both"===e.affinityType||e.isLiked)).length,o=t.items.filter((e=>"followed"===e.affinityType||"both"===e.affinityType||e.isFollowing)).length;e.textContent=`${t.totalCount} total ⢠${n} liked ⢠${o} followed`}}getTemplate(){this.store.getState();return`\n <div class="affinity-dashboard">\n <div class="mb-6">\n ${this.getStatsAndFilters()}\n </div>\n <div class="affinity-dashboard-content-wrapper" style="position: relative;">\n <div class="affinity-dashboard-content">\n ${this.getContentTemplate()}\n </div>\n </div>\n </div>\n `}getStatsAndFilters(){return`\n <div class="flex items-center justify-center">\n <div class="affinity-filter-group">\n ${this.getFilterButtons()}\n </div>\n </div>\n `}getFilterButtons(){const e=this.store.getState();let t=0,n=0;if(e.apiResponse&&"object"==typeof e.apiResponse){const o=e.apiResponse;console.log("[AffinityDashboard] Getting counts from apiResponse:",o),void 0!==o.totalLiked&&(t=o.totalLiked),void 0!==o.totalFollowed&&(n=o.totalFollowed)}0===t&&0===n&&e.items.length>0&&(console.log("[AffinityDashboard] No counts in response, counting current items"),e.items.forEach((e=>{("liked"===e.affinityType||"both"===e.affinityType||e.isLiked)&&t++,("followed"===e.affinityType||"both"===e.affinityType||e.isFollowing)&&n++})));return[{value:fn,label:"All",icon:null,count:e.totalCount},{value:vn,label:"Liked",icon:"heart",count:t},{value:bn,label:"Followed",icon:"circle",count:n}].map((t=>{const n=e.filter===t.value;return`\n <button\n class="affinity-filter-btn ${n?"active":""}"\n data-filter="${t.value}"\n ${n?'aria-pressed="true"':'aria-pressed="false"'}>\n ${"heart"===t.icon?'<svg class="filter-icon heart" width="16" height="16" fill="currentColor" viewBox="0 0 24 24"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg>':"circle"===t.icon?'<svg class="filter-icon circle" width="16" height="16" fill="currentColor" viewBox="0 0 24 24"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path></svg>':""}
1\n <span>${t.label}</span>\n <span class="filter-count">${t.count}</span>\n </button>\n `})).join("")}getContentTemplate(){const e=this.store.getState();return e.isLoading?`\n <div style="min-height: 300px; display: flex; align-items: center; justify-content: center;">\n ${ke.k.render({text:"Loading your content..."})}\n </div>\n `:e.error?te.Alert.render({variant:"error",title:"Error",message:e.error.message||"An error occurred"}):0===e.items.length?this.getEmptyStateTemplate():`\n <div class="affinity-items-grid">\n ${e.items.map((e=>this.getItemTemplate(e))).join("")}\n </div>\n ${this.getPaginationTemplate()}\n `}getEmptyStateTemplate(){let e="",t="";switch(this.store.getState().filter){case vn:t="No liked content",e="You haven't liked any content yet";break;case bn:t="No followed content",e="You haven't followed any content yet";break;default:t="No items found",e="You haven't liked or followed any content yet"}return`\n <div class="text-center py-16">\n <div class="mx-auto w-24 h-24 bg-gray-100 rounded-full flex items-center justify-center mb-6">\n <svg class="w-12 h-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"></path>\n </svg>\n </div>\n <h3 class="text-lg font-semibold text-gray-900 mb-2">${t}</h3>\n <p class="text-gray-600">${e}</p>\n </div>\n `}getPlaceholderIcon(e){const t=e.toLowerCase();return"comment"===t?'<svg class="affinity-item-placeholder" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-4 4z"></path>\n </svg>':"article"===t?'<svg class="affinity-item-placeholder" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>\n </svg>':"video"===t?'<svg class="affinity-item-placeholder" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"></path>\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>\n </svg>':"image"===t||"gallery"===t?'<svg class="affinity-item-placeholder" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path>\n </svg>':'<svg class="affinity-item-placeholder" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>\n </svg>'}getItemTemplate(e){const t=e.affinityType||(e.isLiked?"liked":e.isFollowing?"followed":""),n=e.publishDate?new Date(e.publishDate).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}):"";return`\n <div class="affinity-item-card" data-content-id="${e.id}" data-affinity-type="${t}">\n <div class="affinity-item-thumbnail">\n <div class="affinity-indicators">\n ${"liked"===t||"both"===t?'<div class="affinity-indicator liked"><svg fill="currentColor" viewBox="0 0 24 24"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg></div>':""}\n ${"followed"===t||"both"===t?'<div class="affinity-indicator followed"><svg fill="currentColor" viewBox="0 0 24 24">
1<path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path></svg></div>':""}\n </div>\n ${e.thumbnail?`<img src="${e.thumbnail}" alt="${e.title||""}" />`:this.getPlaceholderIcon(e.type||e.contentType||"content")}\n </div>\n <div class="affinity-item-content">\n <h3 class="affinity-item-title">\n <a href="${e.url||"#"}" target="_blank">${e.title||"Untitled"}</a>\n </h3>\n <div class="affinity-item-footer">\n <div class="affinity-item-meta">\n <a href="${e.url||"#"}" \n target="_blank"\n class="affinity-item-type ${(e.type||e.contentType||"").toLowerCase()}" \n title="View ${e.type||e.contentType||"content"}">\n ${e.type||e.contentType||"Content"}\n </a>\n <span class="affinity-item-date">⢠${n}</span>\n </div>\n <button class="affinity-remove-btn" data-action="remove" data-content-id="${e.id}" title="Remove from favorites">\n <svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>\n </svg>\n </button>\n </div>\n </div>\n </div>\n `}getPaginationTemplate(){const e=this.store.getState();return e.totalPages<=1?"":pn.render({currentPage:e.currentPage,totalPages:e.totalPages,onPageChange:e=>this.changePage(e)})}async loadItems(){const e=this.store.getState();try{this.store.setState({isLoading:!0,error:null});const t=await this.manager.getUserItems(e.filter,e.currentPage,this.pageSize);console.log("[AffinityDashboard] API Response:",t),this.store.setState({items:t.items,totalPages:t.totalPages,totalCount:t.totalCount,apiResponse:t,isLoading:!1})}catch(e){this.store.setState({error:e,isLoading:!1})}}async changeFilter(e){e!==this.store.getState().filter&&(console.log("[AffinityDashboard] Changing filter to:",e),this.store.setState({filter:e,currentPage:1,isLoading:!0}),await this.loadItems())}async changePage(e){e!==this.store.getState().currentPage&&(this.store.setState({currentPage:e}),await this.loadItems())}formatDate(e){return new Date(e).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}attachEventListeners(){this.cleanup.addEventListener(this.container,"click",this.handleClick.bind(this))}async handleClick(e){const t=e.target,n=t.closest("[data-filter]");if(n){e.preventDefault();const t=n.dataset.filter;return void(t&&await this.changeFilter(t))}const o=t.closest('[data-action="remove"]');if(o){e.preventDefault();const t=o.dataset.contentId;t&&await this.removeItem(t)}}async removeItem(e){try{const t=this.store.getState(),n=t.items.find((t=>t.id===e));if(!n)return;const o=this.container.querySelector(`[data-content-id="${e}"]`);o&&(o.classList.add("removing"),o.style.transition="opacity 0.3s ease-out, transform 0.3s ease-out",o.style.opacity="0.5",o.style.transform="scale(0.95)");const i=[];"liked"!==n.affinityType&&"both"!==n.affinityType||i.push(this.manager.toggleLike(e,!0)),"followed"!==n.affinityType&&"both"!==n.affinityType||i.push(this.manager.toggleFollow(e,!0)),await Promise.all(i);t.items.filter((t=>t.id!==e)),Math.max(0,t.totalCount-1);o&&await new Promise((e=>{o.addEventListener("transitionend",(()=>e(void 0)),{once:!0}),o.style.opacity="0",o.style.transform="scale(0.8)"})),console.log("[AffinityDashboard] Reloading items after deletion..."),await this.loadItems(),console.log("[AffinityDashboard] Items reloaded, new state:",this.store.getState())}catch(t){console.error("Failed to remove item:",t);const n=this.container.querySelector(`[data-content-id="${e}"]`);n&&(n.classList.remove("removing"),n.style.opacity="1",n.style.transform="scale(1)")}}}var Un=$n;class Fn extends tt.A{constructor(e,t={}){super(e,t),this.dashboard=null}getDefaultOptions(){return{autoInit:!0,debug:!1}}getInitialState(){return{isLoading:!0,error:null,data:null,profileData:this.options.profileData,items:[],hasMore:!1,totalCount:0}}getComponentClassName(){return"hg-profile-followed"}getComponentName(){return"followed"}getHeaderConfig(){return{icon:De.b.icons.heart||De.b.icons.default,title:"Liked & Followed Content",subtitle:"Manage your favorite content and topics you follow",actions:()=>this.getHeaderActions()}}getHeaderActions(){return""}getLoadingMessage(){return"Loading your followed content..."}async loadData(){return{}}isEmptyState(e){return!1}renderMainContent(){return'\n <div class="p-4 sm:p-6">\n <div id="affinity-dashboard-container">\n \x3c!-- AffinityDashboard will be rendered here --\x3e\n </div>\n </div>\n '}attachEventListeners(){const e=this.container.querySelector("#affinity-dashboard-container");e&&(this.dashboard=new Un(e,{filter:fn,api:this.options.api,config:this.options.config}),this.dashboard.render())}async onDestroy(){this.dashboard?.destroy&&this.dashboard.destroy(),this.dashboard=null}async refresh(){this.dashboard&&"function"==typeof this.dashboard.refresh&&this.dashboard.refresh()}}var zn=Fn;var Hn=class{constructor(e,t={}){this.impl=new zn(e,t)}async render(){return this.impl.render()}cleanup(){this.impl.destroy()}destroy(){this.impl.destroy()}refresh(){this.impl.refresh()}},Gn=(n(7051),n(1363)),_n=n(1964);class Kn extends tt.A{constructor(e,t={}){super(e,t),this.activityDashboard=null,this.api=_n.A,console.log("[ProfileActivity] Using ActivityAPI:",this.api)}getDefaultOptions(){return{autoInit:!0,debug:!1}}getInitialState(){return{isLoading:!0,error:null,data:null,profileData:this.options.profileData,activities:[],hasMore:!1}}getComponentClassName(){return"hg-profile-activity"}getComponentName(){return"activity"}getHeaderConfig(){return{icon:De.b.icons.activity,title:"Activity History",subtitle:"Track your account activity and security events",actions:()=>this.renderHeaderActions()}}renderHeaderActions(){return De.b.renderButton({text:"",icon:P.H.render("refresh-cw",{class:"w-4 h-4"}),className:"activity-refresh-btn"})}getLoadingMessage(){return"Loading your activity history..."}async loadData(){return{}}isEmptyState(e){return!1}renderMainContent(){return'\n <div class="p-6">\n <div id="activity-dashboard-container">\n \x3c!-- ActivityDashboard will be rendered here --\x3e\n </div>\n </div>\n '}attachEventListeners(){const e=this.container.querySelector("#activity-dashboard-container");e&&(this.activityDashboard=new Gn.A(e,{api:this.api,profileData:this.getState().profileData,showHeader:!1}),this.activityDashboard.render());this.addDelegatedListener(".activity-refresh-btn","click",(()=>{this.activityDashboard&&this.activityDashboard.refresh()}));this.cleanup.addEventListener(document,"heimguard:activity:new",(()=>{this.activityDashboard&&this.activityDashboard.refresh()}))}async onDestroy(){this.activityDashboard?.destroy&&this.activityDashboard.destroy(),this.activityDashboard=null}async refresh(){this.activityDashboard&&this.activityDashboard.refresh()}}var jn=Kn;const Vn={name:"activitySystemAdapter",initialize:async()=>{const e=document.querySelectorAll('[data-hg-component="activity"]');for(const t of e)if(!t.dataset.initialized){const{default:e}=await Promise.resolve().then(n.bind(n,7051));new e(t).initialize(),t.dataset.initialized="true"}}};if("undefined"!=typeof window){A.systemRegistry.register("activitySystemAdapter",Vn);const e=()=>{Vn.initialize()};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",e):e()}var qn=class extends I{constructor(){super("/api/heimguard")}async getAllNewsletters(){try{const e=await fetch(f.A.apiGetNewslettersUrl,{method:"GET",credentials:"same-origin"}),t=await e.json();if(!e.ok)throw new Error(t.message||"Failed to fetch newsletters");return t}catch(e){throw console.error("Fetch newsletters error:",e),e}}async updateSubscriptions(e){try{const t=await fetch(f.A.apiUpdateNewslettersUrl,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"same-origin",body:JSON.stringify({newsletterCodes:e})}),n=await t.json();if(!t.ok)throw new Error(n.message||"Failed to update subscriptions");return n}catch(e){throw console.error("Newsletter subscription error:",e),e}}};class Wn extends tt.A{constructor(e,t={}){super(e,t),this.processingToggles=new Set,this.listenersAttached=!1,this.toggleDebounceTimers=new Map,this.isCabotWealth=!1,this.hideNewsLetterThumbnail=!1,this.api=new qn}getDefaultOptions(){return{autoInit:!0,debug:!1}}getInitialState(){return{isLoading:!0,error:null,data:null,profileData:this.options.profileData,newsletters:[],originalSelections:new Set}}async onInit(){this.injectStyles()}injectStyles(){if(document.getElementById("newsletter-component-styles"))return;const e=document.createElement("style");e.id="newsletter-component-styles",e.textContent='\n .hg-newsletters .line-clamp-2 {\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n /* Toggle switch styles */\n .hg-newsletters .toggle-switch {\
1n position: relative;\n display: inline-block;\n width: 44px;\n height: 24px;\n }\n\n .hg-newsletters .toggle-switch input[type="checkbox"] {\n opacity: 0;\n width: 0;\n height: 0;\n position: absolute;\n }\n\n .hg-newsletters .toggle-slider {\n position: absolute;\n cursor: pointer;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: #e5e7eb;\n transition: background-color 0.4s;\n border-radius: 24px;\n }\n\n .hg-newsletters .toggle-slider:before {\n position: absolute;\n content: "";\n height: 18px;\n width: 18px;\n left: 3px;\n bottom: 3px;\n background-color: white;\n transition: transform 0.4s;\n border-radius: 50%;\n box-shadow: 0 2px 4px rgba(0,0,0,0.2);\n }\n\n .hg-newsletters input[type="checkbox"]:checked + .toggle-slider {\n background-color: #4f46e5;\n }\n\n .hg-newsletters input[type="checkbox"]:checked + .toggle-slider:before {\n transform: translateX(20px);\n }\n\n .hg-newsletters input[type="checkbox"]:disabled + .toggle-slider {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n /* Hide default checkbox appearance */\n .hg-newsletters input[type="checkbox"].newsletter-checkbox {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n margin: 0;\n }\n\n .hg-newsletters .newsletter-thumbnail {\n position: relative;\n overflow: hidden;\n }\n ',document.head.appendChild(e)}getComponentClassName(){return"hg-newsletters"}getComponentName(){return"newsletters"}getHeaderConfig(){return{icon:De.b.icons.mail,title:"Email Preferences",subtitle:"Choose which newsletters you'd like to receive"}}getLoadingMessage(){return"Loading newsletter preferences..."}async loadData(){const e=(await this.api.getAllNewsletters()).newsletters||[];await w.default.load(),this.isCabotWealth=w.default.isCabotWealth(),this.hideNewsLetterThumbnail=w.default.hideNewsLetterThumbnail();const t=e.map((e=>({id:e.id,newsletterCode:e.newsletterCode,title:e.title,description:e.description,tagline:e.tagline,thumbnailUrl:e.thumbnailUrl,hasAccess:void 0===e.hasAccess||e.hasAccess,isSubscribed:e.isSubscribed||!1,allowAll:void 0===e.allowAll||e.allowAll,ctaButtonText:e.ctaButtonText,ctaMessage:e.ctaMessage,requiredPlans:e.requiredPlans||[]}))),n=new Set(t.filter((e=>e.isSubscribed)).map((e=>e.newsletterCode)));return{newsletters:t,originalSelections:n}}async fetchData(){return await this.loadData()}isEmptyState(e){return!e||!e.newsletters||0===e.newsletters.length}getEmptyStateConfig(){return{icon:De.b.icons.mail,title:"No newsletters available",message:"There are no newsletters available at this time. Check back later for updates."}}renderMainContent(){const e=this.getState();return e.data&&e.data.newsletters&&0!==e.data.newsletters.length?this.renderNewsletterList():""}renderNewsletterList(){const e=this.getState();this._newsletterFilter||(this._newsletterFilter="all");const t=this._newsletterFilter;let n=e.data&&e.data.newsletters?e.data.newsletters:[];"free"===t?n=n.filter((e=>!0===e.allowAll)):"advisory"===t&&(n=n.filter((e=>!1===e.allowAll)));const o=[...n].sort(((e,t)=>{const n=e.isSubscribed&&e.hasAccess,o=t.isSubscribed&&t.hasAccess;if(n&&!o)return-1;if(!n&&o)return 1;const i=e.isSubscribed&&!e.hasAccess,a=t.isSubscribed&&!t.hasAccess;if(i&&!a)return-1;if(!i&&a)return 1;const s=!e.isSubscribed&&e.hasAccess,r=!t.isSubscribed&&t.hasAccess;return s&&!r?-1:!s&&r?1:(e.title||"").localeCompare(t.title||"")})).map((e=>this.renderNewsletterItem(e))).join("");console.log({newsletterItems:o});let i="";if(this.isCabotWealth){const n=e.data&&e.data.newsletters?e.data.newsletters:[],o=n.some((e=>!0===e.allowAll)),a=n.some((e=>!1===e.allowAll)),s=[{key:"all",label:"All",show:!0},{key:"free",label:"Free",show:o},{key:"advisory",label:"Premium",show:a}].filter((e=>e.show)).map((e=>`\n <button type="button" data-newsletter-filter="${e.key}" class="px-4 py-1.5 text-sm font-medium rounded-md transition-all duration-200 ${t===e.key?"bg-primary-600 text-white shadow-sm":"text-gray-600 hover:text-gray-900"}">\n ${e.label}\n </button>\n `)).join("");
1[!0,o,a].filter(Boolean).length>1&&(i=`\n <div class="mb-6">\n <div class="inline-flex rounded-lg border border-gray-300 bg-white p-1">\n ${s}\n </div>\n </div>\n `)}return`\n <div class="p-6">\n ${i}\n <div class="grid gap-4 md:grid-cols-2 lg:grid-cols-3">\n ${o}\n </div>\n </div>\n `}renderNewsletterItem(e){const t=e.isSubscribed;return console.log("[ProfileNewsletters] Rendering newsletter:",{title:e.title,hasAccess:e.hasAccess,requiredPlans:e.requiredPlans,ctaButtonText:e.ctaButtonText}),`\n <div class="newsletter-card group relative bg-white rounded-lg shadow-sm border border-gray-200 hover:shadow-md hover:border-gray-300 transition-all duration-200 overflow-hidden" data-newsletter-code="${e.newsletterCode}" data-allow-all="${e.allowAll}">\n \x3c!-- Loading overlay --\x3e\n <div class="newsletter-loading-overlay hidden absolute inset-0 bg-white bg-opacity-75 z-10 flex items-center justify-center">\n <div class="flex items-center space-x-2">\n <svg class="animate-spin h-5 w-5 text-primary-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">\n <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>\n <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>\n </svg>\n <span class="text-sm text-gray-600">Updating...</span>\n </div>\n </div>\n \x3c!-- Only show thumbnail if isCabotWealth is true and hideNewsLetterThumbnail is not true --\x3e\n ${this.isCabotWealth&&!this.hideNewsLetterThumbnail?e.thumbnailUrl?`\n <div class="newsletter-thumbnail relative h-40 bg-gradient-to-br from-gray-50 to-gray-100">\n <img src="${e.thumbnailUrl}"\n alt="${e.title}"\n class="w-full h-full object-cover">\n ${e.hasAccess?"":'\n <div class="absolute inset-0 bg-gray-200 flex flex-col items-center justify-center">\n <svg class="w-12 h-12 text-gray-400 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"\n d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />\n </svg>\n <p class="text-gray-400 text-sm font-medium">Subscribe to Access</p>\n </div>\n '}\n </div>\n `:`\n <div class="newsletter-thumbnail relative h-40 bg-gradient-to-br from-gray-50 to-gray-100 flex items-center justify-center">\n ${e.hasAccess?'\n <svg class="w-12 h-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"\n d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />\n </svg>\n ':'\n <div class="absolute inset-0 bg-gray-200 flex flex-col items-center justify-center">\n <svg class="w-12 h-12 text-gray-400 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"\n d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />\n </svg>\n <p class="text-gray-400 text-sm font-medium">Subscribe to Access</p>\n </div>\n '}\n </div>\n `:""}\n\n <div class="p-5">\n <div class="flex items-start justify-between mb-3">\n <div class="flex-1 pr-3">\n <h3 class="text-base font-semibold text-gray-900 leading-tight">\n ${e.title||"Newsletter"}\n </h3>\n </div>\n ${e.hasAccess?`\n <div class="flex-shrink-0">\n <label class="newsletter-toggle-switch" style="position: relative; display: inline-block; width: 44px; height: 24px;">\n <input type="checkbox"\n class="newsletter-checkbox"\n style="opacity: 0; width: 0; height: 0; position: absolute;"\n value="${e.newsletterCode}"\n ${t?"checked":""}\n data-newsletter-code="${e.newsletterCode}">
1\n <span class="newsletter-toggle-slider" style="position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: ${t?"#4f46e5":"#e5e7eb"}; transition: background-color 0.4s; border-radius: 24px;">\n <span style="position: absolute; content: ''; height: 18px; width: 18px; left: 3px; bottom: 3px; background-color: white; transition: transform 0.4s; border-radius: 50%; box-shadow: 0 2px 4px rgba(0,0,0,0.2); transform: translateX(${t?"20px":"0"});"></span>\n </span>\n </label>\n </div>\n `:""}\n </div>\n\n ${e.description?`\n <p class="text-sm text-gray-600 mb-3 line-clamp-2">\n ${e.description}\n </p>\n `:""}\n\n ${!e.hasAccess&&e.requiredPlans&&e.requiredPlans.length>0?`\n <div class="mt-3 p-3 bg-amber-50 border border-amber-100 rounded-md cursor-pointer hover:bg-amber-100 transition-colors newsletter-subscribe-cta" data-newsletter-code="${e.newsletterCode}">\n <div class="flex items-center justify-center">\n <svg class="w-4 h-4 text-amber-600 mr-2 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />\n </svg>\n <p class="text-xs text-amber-800 font-medium">Subscribe to Access</p>\n </div>\n </div>\n `:e.hasAccess?`\n <div class="flex items-center text-xs ${e.isSubscribed?"text-green-600":"text-gray-500"}">\n ${e.isSubscribed?'\n <svg class="w-3.5 h-3.5 mr-1" fill="currentColor" viewBox="0 0 20 20">\n <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>\n </svg>\n <span class="font-medium">Subscribed</span>\n ':"\n <span>Click toggle to subscribe</span>\n "}\n </div>\n `:""}\n </div>\n </div>\n `}attachEventListeners(){this.listenersAttached?console.log("[ProfileNewsletters] Listeners already attached, skipping"):(this.listenersAttached=!0,console.log("[ProfileNewsletters] Attaching event listeners"),this.addDelegatedListener("[data-newsletter-filter]","click",(e=>{const t=e.target.getAttribute("data-newsletter-filter");t&&(this._newsletterFilter=t,this.render())})),this.addDelegatedListener(".newsletter-checkbox","change",(async e=>{e.stopPropagation();const t=e.target,n=t.value,o=t.checked;console.log(`[ProfileNewsletters] Toggle clicked for ${n}, checked: ${o}`);const i=this.toggleDebounceTimers.get(n);if(i&&(clearTimeout(i),console.log(`[ProfileNewsletters] Cleared existing timer for ${n}`)),this.processingToggles.has(n))return console.log(`[ProfileNewsletters] Already processing ${n}, skipping`),void e.preventDefault();const a=t.nextElementSibling,s=a.firstElementChild;o?(a.style.backgroundColor="#4f46e5",s.style.transform="translateX(20px)"):(a.style.backgroundColor="#e5e7eb",s.style.transform="translateX(0)");const r=setTimeout((async()=>{this.toggleDebounceTimers.delete(n),this.processingToggles.add(n);try{await this.handleSingleToggle(n,o)}finally{this.processingToggles.delete(n)}}),300);this.toggleDebounceTimers.set(n,r)})),this.addDelegatedListener(".newsletter-subscribe-cta","click",(async e=>{e.preventDefault();const t=e.target,n=t.closest("[data-newsletter-code]")?.getAttribute("data-newsletter-code");console.log("[ProfileNewsletters] Subscribe CTA clicked for newsletter:",n),this.openSubscriptionModal()})))}async handleSingleToggle(e,t){const n=this.getState(),o=n.data?.newsletters?.find((t=>t.newsletterCode===e)),i=o?.title||"Newsletter",a=this.container.querySelector(`.newsletter-card[data-newsletter-code="${e}"]`),s=a?.querySelector(".newsletter-loading-overlay"),r=this.container.querySelector(`input[value="${e}"]`);r&&(r.disabled=!0),s&&s.classList.remove("hidden");try{const o=n.data?.newsletters?.filter((t=>t.isSubscribed&&t.newsletterCode!==e))?.map((e=>e.newsletterCode))||[],a=t?[...o,e]:o,s=await this.api.updateSubscriptions(a);if(!s.success){if(r){r.checked=!t;const e=r.nextElementSibling,n=e.firstElementChild;t?(e.style.backgroundColor="#e5e7eb",n.style.transform="translateX(0)"):(e.style.backgroundColor="#4f46e5",n.style.transform="translateX(20px)")}throw new Error(s.message||"Failed to update subscription")}if(n.data&&n.data.newsletters){const o=n.data.newsletters.map((n=>({...n,isSubscribed:n.newsletterCode===e?t:n.isSubscribed})));this.setState({data:{...n.data,newsletters:o,originalSelections:new Set(a
1)}})}te.Alert.flash({message:t?`Successfully subscribed to ${i}!`:`Successfully unsubscribed from ${i}!`,variant:"success",duration:2e3})}catch(e){if(console.error("Failed to toggle newsletter subscription:",e),te.Alert.flash({message:"Failed to update subscription. Please try again.",variant:"error"}),r){r.checked=!t;const e=r.nextElementSibling,n=e.firstElementChild;t?(e.style.backgroundColor="#e5e7eb",n.style.transform="translateX(0)"):(e.style.backgroundColor="#4f46e5",n.style.transform="translateX(20px)")}}finally{s&&s.classList.add("hidden"),r&&(r.disabled=!1)}}openSubscriptionModal(){window.location.hash="subscriptions"}areSetsEqual(e,t){if(e.size!==t.size)return!1;for(const n of e)if(!t.has(n))return!1;return!0}async onDestroy(){this.listenersAttached=!1,this.processingToggles.clear(),this.toggleDebounceTimers.forEach((e=>clearTimeout(e))),this.toggleDebounceTimers.clear()}async refresh(){await this.render()}}var Zn=Wn;var Yn=class{constructor(e,t={}){this.impl=new Zn(e,t)}async render(){return this.impl.render()}cleanup(){this.impl.destroy()}destroy(){this.impl.destroy()}async refresh(){return this.impl.refresh()}};const Jn="profile:loaded",Qn="profile:updated",Xn="profile:error",eo="profile:section:change",to="profile:stats:updated",no="profile:completion:calculated";function oo(e,t={}){const n=new CustomEvent(`heimguard:${e}`,{detail:{timestamp:Date.now(),...t},bubbles:!0,cancelable:!0});document.dispatchEvent(n)}class io{constructor(e){this.config=e,this.api=new ze.q,this.profileData=null,this.activeSection=e.defaultSection,this.components=new Map,this.stats={},this.isLoading=!1}async loadProfile(){if(this.isLoading)return console.warn("[ProfileManager] Profile already loading"),this.profileData;this.isLoading=!0;try{console.log("[ProfileManager] Loading profile data...");const e=await this.api.getProfile();if(!e.success||!e.data)throw new Error(e.message||"Failed to load profile");const{profile:t,stats:n}=e.data,o={...t,stats:n?{activeSubscriptions:n.activeSubscriptions||0,paymentMethods:n.paymentMethodsCount||0,addressCount:n.addressCount||0,commentCount:0,activityCount:0,invoiceCount:0,followCount:n.affinityCount||0,likeCount:0}:void 0};return this.profileData=this.normalizeProfileData(o),oo(Jn,{profileData:this.profileData}),this.calculateProfileCompletion(),this.profileData}catch(e){throw console.error("[ProfileManager] Failed to load profile:",e),oo(Xn,{error:e}),e}finally{this.isLoading=!1}}normalizeProfileData(e){const t={profileCreationDate:(new Date).toISOString(),firstName:"",lastName:"",email:"",displayName:"User",mobileNumber:"",alternatePhone:"",avatarUrl:null,emailVerified:!1,twoFactorEnabled:!1,stats:{activeSubscriptions:0,paymentMethods:0,addressCount:0,commentCount:0,activityCount:0,invoiceCount:0,followCount:0,likeCount:0},...e};return t.mobileNumber=e.mobileNumber||e.mobilePhone||"",t.alternatePhone=e.alternatePhone||"",t.otherPhone=e.otherPhone||e.alternatePhone||"",t.initials=this.generateInitials(t.firstName,t.lastName),t.displayName&&"User"!==t.displayName||(t.displayName=this.generateDisplayName(t)),t}generateInitials(e,t){return(e?.charAt(0)?.toUpperCase()||"")+(t?.charAt(0)?.toUpperCase()||"")||"U"}generateDisplayName(e){return e.firstName&&e.lastName?`${e.firstName} ${e.lastName}`:e.firstName?e.firstName:e.email?e.email.split("@")[0]:"User"}async updateProfile(e){try{console.log("[ProfileManager] Updating profile with:",e);const t={firstName:e.firstName,lastName:e.lastName,displayName:e.displayName,mobileNumber:e.mobileNumber||e.mobilePhone,otherPhone:e.otherPhone||e.alternatePhone,email:e.email};console.log("[ProfileManager] API updates:",t);const n=await this.api.updateProfile(t);if(!n.success||!n.data)throw new Error(n.message||"Failed to update profile");const o=n.data;return console.log("[ProfileManager] API response:",o),this.profileData={...this.profileData,...o,mobileNumber:o.mobileNumber||o.mobilePhone||this.profileData.mobileNumber,alternatePhone:o.alternatePhone||this.profileData.alternatePhone,otherPhone:o.otherPhone||o.alternatePhone||this.profileData.otherPhone,stats:this.profileData.stats},o.stats&&(this.profileData.stats={...this.profileData.stats,activeSubscriptions:o.stats.activeSubscriptions||this.profileData.stats.activeSubscriptions,paymentMethods:o.stats.paymentMethodsCount||this.profileData.stats.paymentMethods,addressCount:o.stats.addressCount||this.profileData.stats.addressCount,followCount:o.stats.affinityCount||this.profileData.stats.followCount}),this.profileData.initials=this.generateInitials(this.profileData.firstName,this.profileData.lastName),this.profileData.displayName=this.generateDisplayName(this.profileData),oo(Qn,{profileData:this.profileData,updates:e}),this.calculateProfileCompletion(),this.profileData}catch(e){throw console.error("[ProfileManager] Failed to update profile:",e),oo(Xn,{error:e}),e}}calculateProfileCompletion(){const e=this.config.completionWeights||{};let t=0,n=0;const o={firstName:!!this.profileData?.firstName,lastName:!!this.profileData?.lastName,email:!!this.profileData?.email,mobileNumber:!!this.profileData?.mobileNumber,defaultAddress:!!this.profileData?.defaultAddress,paymentMethod:(this.profileData?.stats?.paymentMethods||0)>0,subscription:(this.profileData?.stats?.activeSubscriptions||0)>0};for(const[i,a]of Object.entries(e))t+=a,o[i]&&(n+=a);const i={percentage:t>0?Math.round(n/t*100):0,completed:n,total:t,fields:o};return this.profileData&&(this.profileData.completion=i),oo(no,{completion:i}),i}updateStats(e){this.stats={...this.stats,...e},this.profileData&&(this.profileData.stats={...this.profileData.stats,...e}),oo(to,{stats:this.stats})}getProfileData(){return this.profileData}setActiveSection(e){const t=this.activeSection;this.activeSection=e,oo(eo,{section:e,previousSection:t})}getActiveSection(){return this.activeSection}registerComponent(e,t){this.components.set(e,t)}getComponent(e){return this.components.get(e)}clear(){this.profileData=null,this.stats={},this.components.clear(),this.activeSection=this.config.defaultSection}static async switchToSection(e){try{if(!["profile","addresses","payment","subscriptions","invoices","security","newsletters","activity","rewards","affinity"].includes(e))return console.error(`[ProfileManager] Invalid section: ${e}`),!1;const t=document.querySelector(".profile-component"),n=document.querySelector("#profile-dashboard");if(!t&&!n)return window.location.hash=e,!0;const o=document.querySelector(`[href="#${e}"]`);if(o)return o.click(),!0;const i=new CustomEvent("heimguard:profile:navigate",{detail:{section:e},bubbles:!0});return document.dispatchEvent(i),await new Promise((e=>setTimeout(e,100))),!0}catch(e){return console.error("[ProfileManager] Error switching profile section:",e),!1}}}const ao=new class{constructor(){this.name="profileSystem",this.profileSystem=null,this.isInitialized=!1}async initialize(){if(this.isInitialized)return void b.vF.debug("Profile system already initialized, skipping","profile");if(window.__profileSystemInitialized)return void b.vF.debug("Profile system already initialized globally, skipping","profile");this.isInitialized=!0,window.__profileSystemInitialized=!0,b.vF.debug("Initializing profile system...","profile");const{systemRegistry:e}=await Promise.resolve().then(n.bind(n,1667));this.profileSystem=new so({autoScan:!0}),e.registerInstance("profileSystem",this.profileSystem),e.registerInstance("switchProfileTab",io.switchToSection),b.vF.debug("Profile system initialized successfully","profile")}cleanup(){this.profileSystem&&(this.profileSystem.cleanup(),this.profileSystem=null)}get profileData(){return this.profileSystem?.profileData||null}refreshProfile(){this.profileSystem&&this.profileSystem.refreshProfile()}async showDashboard(){this.profileSystem&&await this.profileSystem.showDashboard()}async showSection(e){this.profileSystem&&await this.profileSystem.showSection(e)}getProfileData(){return this.profileSystem?.getProfileData()||null}async switchProfileTab(e){return io.switchToSection(e)}};class so{get profileData(){return this._profileData?{isVerified:this._profileData.isEmailVerified||!1,...this._profileData}:null}set profileData(e){this._profileData=e}constructor(e={}){this.config={apiBaseUrl:f.A.apiBaseUrl||"/api/heimguard",autoScan:!0,containerSelector:"#profile-dashboard-container",...e},this.components=new Map,this.api=new ze.q,this._profileData=null,this.activeSection="profile",this.dashboardInstance=null,this.initialize()}async initialize(){try{this.registerComponents(),this.config.autoScan&&await this.scanAndRenderTags(),this.setupEventListeners()}catch(e){console.error("[ProfileSystem] Initialization error:",e)}}registerComponents(){this.components.set("dashboard",Ne),this.components.set("profile",Ve),this.components.set("addresses",ot),this.components.set("payment",Ct.default),this.components.set("subscriptions",Ot),this.components.set("invoices",mn),this.components.set("affinity",Hn),this.components.set("newsletters",Yn),this.components.set("security",We),jn&&this.components.set("activity",jn)}async scanAndRenderTags(){const e={HgProfileDashboard:"dashboard",HgProfileInfo:"profile",HgAddressManager:"addresses",HgPaymentMethods:"payment",HgSubscriptions:"subscriptions",HgSecuritySettings:"security",HgPreferences:"preferences"};for(const[t,n]of Object.entries(e)){const e=document.getElementsByTagName(t);for(const t of Array.from(e))"dashboard"===n?await this.renderDashboard(t):await this.renderComponent(t,n)}}async renderDashboard(e){try{console.log("[ProfileSystem] Fetching profile data...");const t=await this.api.getProfile();if(console.log("[ProfileSystem] Profile API response:",t),!t.success||!t.data)throw console.error("[ProfileSystem] Profile API failed:",t.error),new Error(t.error?.message||"Failed to load profile");console.log("[ProfileSystem] Raw response data:",t.data);const o=t.data.profile||t.data;console.log("[ProfileSystem] Raw profile data:",o),console.log("[ProfileSystem] Fetching addresses for default address...");let i=null;try{const{default:e}=await Promise.resolve().then(n.bind(n,4849)),t=await e.loadAddresses();console.log("[ProfileSystem] Addresses from AddressManager:",t);const o=t.find((e=>e.isDefaultShipping||e.isDefaultBilling||e.isDefault));o?(i={street1:o.street1||"",street2:o.street2||"",city:o.city||"",region:o.region||o.state||"",postalCode:o.postalCode||o.zip||""},console.log("[ProfileSystem] Found default address:",i)):console.log("[ProfileSystem] No default address found")}catch(e){console.warn("[ProfileSystem] Failed to fetch addresses:",e)}const a={...o,defaultAddress:i},s=at(a);console.log("[ProfileSystem] Transformed data with default address:",s),this.profileData={profileCreationDate:(new Date).toISOString(),firstName:"",lastName:"",displayName:"User",stats:{activeSubscriptions:0,paymentMethods:0,addressCount:0,commentCount:0,activityCount:0},...a,...s};const r=new Ne(e,{profileData:this.profileData,onSectionChange:e=>{this.activeSection=e;const t=new CustomEvent("heimguard:profile:sectionChange",{detail:{section:e},bubbles:!0});document.dispatchEvent(t)},api:this.api,componentRegistry:this.components});await r.render(),this.dashboardInstance=r,this.checkForEmailChangeSuccess()}catch(t){if(console.error("[ProfileSystem] Error loading profile:",t),401===t.status)return e.innerHTML='\n <div class="flex items-center justify-center min-h-screen">\n <div class="text-center">\n <div class="animate-spin h-8 w-8 border-4 border-primary-600 border-t-transparent roun
1ded-full mx-auto mb-4"></div>\n <p class="text-gray-600" id="redirect-message">Redirecting to login...</p>\n <div id="manual-redirect" class="mt-4 hidden">\n <p class="text-sm text-gray-500 mb-3">Having trouble? Click below to continue:</p>\n <a href="#" id="login-link" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">\n Go to Login\n </a>\n </div>\n </div>\n </div>\n ',this.setupManualRedirect(),console.log("[ProfileSystem] Will dispatch heimguard:unauthorized event"),console.log("[ProfileSystem] Event detail:",{path:window.location.pathname,status:401}),console.log("[ProfileSystem] Global handler exists?",!!window.__global401Handler),console.log("[ProfileSystem] Handler listener exists?",!!window.__global401HandlerListener),setTimeout((()=>{console.log("[ProfileSystem] Now dispatching event...");const e=new CustomEvent("heimguard:unauthorized",{detail:{path:window.location.pathname,status:401},bubbles:!0,cancelable:!0}),t=window.dispatchEvent(e);console.log("[ProfileSystem] Event dispatched:",t)}),500),void setTimeout((()=>{const e=document.getElementById("manual-redirect"),t=document.getElementById("redirect-message");e&&t&&(console.warn("[ProfileSystem] Redirect timeout - showing manual option"),e.classList.remove("hidden"),t.textContent="Automatic redirect failed")}),5e3);e.innerHTML=Be.render({title:"Unable to Load Profile",error:t,showDetails:!1,onRetry:()=>this.renderDashboard(e)});const n=e.querySelector(".retry-btn");n&&n.addEventListener("click",(async()=>{await this.renderDashboard(e)}))}}async renderComponent(e,t){const n=this.components.get(t);if(n)try{const o={profileData:this.profileData,api:this.api};console.log(`[ProfileSystem] Rendering component '${t}' with profileData:`,this.profileData),"activity"===t&&(o.apiBaseUrl=this.config.apiBaseUrl);const i=new n(e,o);if(await i.render(),"payment"===t){const t=async()=>{await i.render()};document.addEventListener("payment:methods:updated",t),e._paymentUpdateHandler=t}}catch(n){he.AlertUtils.showAlert(e,`Failed to load ${t}`,"error")}}setupEventListeners(){document.addEventListener("heimguard:profile:updated",(async e=>{const t=e.detail.profileData,n=at(t);this.profileData={...t,...n},this.dashboardInstance&&await this.dashboardInstance.updateProfile(this.profileData)})),document.addEventListener("heimguard:profile:navigate",(async e=>{const t=e,{section:n}=t.detail;this.dashboardInstance&&await this.dashboardInstance.loadSection(n)})),document.addEventListener("heimguard:address:default:shipping:set",(async e=>{console.log("[ProfileSystem] Default shipping address changed"),await this.refreshDefaultAddress()})),document.addEventListener("heimguard:address:default:billing:set",(async e=>{console.log("[ProfileSystem] Default billing address changed"),await this.refreshDefaultAddress()})),document.addEventListener("heimguard:address:updated",(async e=>{console.log("[ProfileSystem] Address updated, checking for default address changes"),await this.refreshDefaultAddress()})),document.addEventListener("heimguard:logout",(()=>{this.cleanup()}))}async showDashboard(){const e=document.querySelector(this.config.containerSelector);e&&await this.renderDashboard(e)}async showSection(e){this.dashboardInstance&&await this.dashboardInstance.loadSection(e)}getProfileData(){return this.profileData}async refreshProfile(){const e=await this.api.getProfile();if(!e.success||!e.data)throw new Error(e.error?.message||"Failed to load profile");const t=e.data.profile||e.data;if(!t)throw console.error("[ProfileSystem] No profile data in response:",e),new Error("No profile data returned from server");const n=at(t);this.profileData={profileCreationDate:t.profileCreationDate||(new Date).toISOString(),firstName:"",lastName:"",displayName:"User",stats:{activeSubscriptions:0,addressCount:0},...t,...n||{}},this.dashboardInstance&&await this.dashboardInstance.updateProfile(this.profileData);const o=new CustomEvent("heimguard:profile:refreshed",{detail:{profileData:this.profileData},bubbles:!0});document.dispatchEvent(o)}async refreshDefaultAddress(){if(this.profileData)try{console.log("[ProfileSystem] Refreshing default address...");const{default:e}=await Promise.resolve().then(n.bind(n,4849)),t=await e.loadAddresses(!0);console.log("[ProfileSystem] Updated addresses:",t);const o=t.find((e=>e.isDefaultShipping||e.isDefaultBilling||e.isDefault)),i=o?{street1:o.street1||"",street2:o.street2||"",city:o.city||"",region:o.region||o.state||"",postalCode:o.postalCode||o.zip||""}:null;console.log("[ProfileSystem] Updated default address:",i),this.profileData={...this.profileData,defaultAddress:i},this.dashboardInstance&&await this.dashboardInstance.updateProfile(this.profileData),console.log("[ProfileSystem] Default address refreshed successfully")}catch(e){console.error("[ProfileSystem] Failed to refresh default address:",e)}}async setupManualRedirect(){try{const e=(await Promise.resolve().then(n.bind(n,7310))).default,t=await e.load(),o=t?.login?.url;if(!o){console.error("[ProfileSystem] No login URL found in HeimGuard settings");const e=document.getElementById("redirect-message");return void(e&&(e.textContent="Unable to find login page. Please navigate manually."))}const i=document.getElementById("login-link");i&&(i.href=o,i.addEventListener("click",(e=>{e.preventDefault(),i.textContent="Redirecting...",i.style.pointerEvents="none",i.style.opacity="0.5";const t=window.location.href,n=o.includes("?")?"&":"?",a=`${o}${n}referrerUrl=${encodeURIComponent(t)}`;window.location.href=a})))}catch(e){console.error("[ProfileSystem] Failed to setup manual redirect:",e);const t=document.getElementById("redirect-message");t&&(t.textContent="Unable to load settings. Please navigate manually.")}}checkForEmailChangeSuccess(){try{const e=new URLSearchParams(window.location.search),t=e.get("emailChanged"),n=e.get("newEmail");if("true"===t&&n){console.log("[ProfileSystem] Email change success detected, showing modal");const e=new URL(window.location.href);e.searchParams.delete("emailChanged"),e.searchParams.delete("newEmail"),window.history.replaceState({},document.title,e.toString()),setTimeout((()=>{this.showEmailChangeSuccessModal(n)}),500)}}catch(e){console.error("[ProfileSystem] Error checking email change success:",e)}}async showEmailChangeSuccessModal(e){try{const{Modal:t}=await Promise.resolve().then(n.bind(n,6833)),o=`\n <div class="text-center space-y-4">\n <div class="mx-auto flex items-center justify-center h-16 w-16 rounded-full bg-green-100">\n <svg class="h-8 w-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>\n </svg>\n </div>\n <div>\n <h3 class="text-lg font-medium text-gray-900 mb-2">Email Address Updated!</h3>\n <p class="text-sm text-gray-600 mb-4">\n Your email address has been successfully changed to:\n </p>\n <div class="bg-green-50 border border-green-200 rounded-lg p-3">\n <p class="text-sm font-medium text-green-800 break-all">${e}</p>\n </div>\n <p class="text-xs text-gray-500 mt-3">\n You can now use this email address to log in to your account.\n </p>\n </div>\n </div>\n `;await t.alert({title:"Success",message:o,buttonText:"Continue",buttonClass:"bg-green-600 hover:bg-green-700 text-white"}),await this.refreshProfile()}catch(e){console.error("[ProfileSystem] Error showing email change success modal:",e)}}cleanup(){this.dashboardInstance&&this.dashboardInstance.cleanup(),this.components.clear(),this.profileData=null,document.querySelectorAll("[data-payment-method-container]").forEach((e=>{const t=e._paymentUpdateHandler;t&&document.removeEventListener("payment:methods:updated",t)}))}}let ro=!1;"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(async()=>{ro?console.log("[ProfileSystem] Already initialized, skipping"):(ro=!0,A.systemRegistry.register("profileSystemAdapter",ao),await ao.initialize())})):ro||(ro=!0,A.systemRegistry.register("profileSystemAdapter",ao),ao.initialize());class lo extends Le.${constructor(e,t={}){super(e,t),this.api=t.api||Cn,this.manager=t.manager||Bn,this.config=t.config||Nn,this.store.setState({contentId:t.contentId,isActionBar:t.isActionBar||!1,isLoggedIn:t.isLoggedIn||!1,isLiked:!1,likeCount:0,isFollowing:!1,followCount:0,isLoading:!1,data:null,error:null})}getDefaultOptions(){return{autoInit:!0,debug:!1}}async onInit(){this.store.subscribe(((e,t,n)=>{(n.includes("isLiked")||n.includes("isFollowing")||n.includes("likeCount")||n.includes("followCount"))&&this.updateButtonStates()}))}async fetchData(){this.store.getState().isLoggedIn&&await this.loadStatus()}async render(){const e=this.store.getState();this.injectStyles(),e.isActionBar?await this.renderActionBarWidget():await this.renderStandaloneWidget(),this.setupGlobalListeners(),await this.fetchData()}updateButtonStates(){const e=this.store.getState(),t=this.container.querySelector(".hg-affinity-like"),n=this.container.querySelector(".hg-affinity-follow");if(t){t.classList.toggle("is-liked",e.isLiked);const n=t.querySelector(".hg-affinity-count");n&&(n.textContent=e.likeCount.toString())}if(n){n.classList.toggle("is-following",e.isFollowing);const t=n.querySelector(".hg-affinity-count");t&&(t.textContent=e.followCount.toString())}}injectStyles(){if(document.getElementById("hg-affinity-styles"))return;const e=document.createElement("style");e.id="hg-affinity-styles",e.textContent="\n /* ActionBar widget container */\n .hg-affinity-actionbar {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n }\n \n /* Like button styles */\n .hg-affinity-like.is-liked .hg-affinity-icon {\n fill: #ef4444;\n stroke: #ef4444;\n color: #ef4444;\n }\n \n .hg-affinity-like.is-liked .ActionLink-message {\n color: #ef4444;\n }\n \n /* Follow button styles */\n .hg-affinity-follow.is-following .hg-affinity-icon {\n fill: #6366f1;\n stroke: #6366f1;\n color: #6366f1;\n }\n \n .hg-affinity-follow.is-following .ActionLink-message {\n color: #6366f1;\n }\n \n /* Hover effects */\n .hg-affinity-like:hover .hg-affinity-icon {\n stroke: #ef4444;\n transform: scale(1.1);\n transition: all 0.2s ease;\n }\n \n .hg-affinity-follow:hover .hg-affinity-icon {\n stroke: #6366f1;\n transform: scale(1.1);\n transition: all 0.2s ease;\n }\n \n /* Loading states */\n .hg-affinity-loading {\n opacity: 0.5;
1\n cursor: not-allowed;\n pointer-events: none;\n }\n \n /* ActionBar specific styles */\n .ActionBar .hg-affinity-widget {\n margin-left: auto;\n }\n \n .ActionBar .ActionLink-count {\n margin-left: 0.25rem;\n font-size: 0.875em;\n opacity: 0.8;\n }\n ",document.head.appendChild(e)}async renderActionBarWidget(){this.container.innerHTML=this.getActionBarTemplate(),this.attachEventListeners()}async renderStandaloneWidget(){this.container.innerHTML=this.getStandaloneTemplate(),this.attachEventListeners()}getActionBarTemplate(){return`\n <div class="hg-affinity-widget hg-affinity-actionbar">\n ${this.getLikeButtonActionBar()}\n ${this.getFollowButtonActionBar()}\n </div>\n `}getStandaloneTemplate(){return`\n <div class="hg-affinity-widget-standalone">\n ${this.getLikeButton()}\n ${this.getFollowButton()}\n </div>\n `}getLikeButton(){const e=this.store.getState(),t=e.isLiked,n=e.likeCount;return`\n <button \n class="hg-affinity-like ${t?"is-liked":""}"\n data-action="like"\n aria-pressed="${t}"\n title="${t?"Unlike":"Like"}">\n <span class="hg-affinity-icon">â¤ï¸</span>\n ${n>0?`<span class="hg-affinity-count">${n}</span>`:""}\n </button>\n `}getFollowButton(){const e=this.store.getState(),t=e.isFollowing,n=e.followCount;return`\n <button \n class="hg-affinity-follow ${t?"is-following":""}"\n data-action="follow"\n aria-pressed="${t}"\n title="${t?"Unfollow":"Follow"}">\n <span class="hg-affinity-icon">ð¥</span>\n ${n>0?`<span class="hg-affinity-count">${n}</span>`:""}\n </button>\n `}getLikeButtonActionBar(){const e=this.store.getState(),t=e.isLiked,n=e.likeCount;return`\n <button \n class="ActionLink hg-affinity-like ${t?"is-liked":""}"\n data-action="like"\n aria-pressed="${t}"\n title="${t?"Unlike":"Like"}">\n <svg class="ActionLink-icon hg-affinity-icon" width="16" height="16" viewBox="0 0 24 24" fill="${t?"currentColor":"none"}" stroke="currentColor" stroke-width="2">\n <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>\n </svg>\n <span class="ActionLink-message">${t?"Liked":"Like"}</span>\n ${n>0?`<span class="ActionLink-count hg-affinity-count">${n}</span>`:""}\n </button>\n `}getFollowButtonActionBar(){const e=this.store.getState(),t=e.isFollowing,n=e.followCount;return`\n <button \n class="ActionLink hg-affinity-follow ${t?"is-following":""}"\n data-action="follow"\n aria-pressed="${t}"\n title="${t?"Unfollow":"Follow"}">\n <svg class="ActionLink-icon hg-affinity-icon" width="16" height="16" viewBox="0 0 24 24" fill="${t?"currentColor":"none"}" stroke="currentColor" stroke-width="2">\n <path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>\n <circle cx="8.5" cy="7" r="4"></circle>\n <path d="M20 8v6M23 11h-6"></path>\n </svg>\n <span class="ActionLink-message">${t?"Following":"Follow"}</span>\n ${n>0?`<span class="ActionLink-count hg-affinity-count">${n}</span>`:""}\n </button>\n `}async loadStatus(){const e=this.store.getState();if(e.contentId)try{const t=await this.manager.getStatus(e.contentId);this.store.setState(t)}catch(e){console.error("Failed to load status:",e),this.store.setState({error:e})}}updateState(e){this.store.setState(e)}attachEventListeners(){this.cleanup.addEventListener(this.container,"click",this.handleClick.bind(this))}async handleClick(e){const t=this.store.getState(),n=e.target.closest("[data-action]");if(!n||!t.contentId)return;const o=n.dataset.action;"like"===o?await this.handleLike():"follow"===o&&await this.handleFollow()}async handleLike(){const e=this.store.getState();if(e.contentId&&!e.isLoading)try{this.store.setState({isLoading:!0});const t=await this.manager.toggleLike(e.contentId,e.isLiked);this.store.setState({isLiked:t.isLiked,likeCount:t.likeCount,isLoading:!1})}catch(e){console.error("Failed to toggle like:",e),this.store.setState({isLoading:!1,error:e})}}async handleFollow(){const e=this.store.getState();if(e.contentId&&!e.isLoading)try{this.store.setState({isLoading:!0});const t=await this.manager.toggleFollow(e.contentId,e.isFollowing);
1this.store.setState({isFollowing:t.isFollowing,followCount:t.followCount,isLoading:!1})}catch(e){console.error("Failed to toggle follow:",e),this.store.setState({isLoading:!1,error:e})}}setupGlobalListeners(){const e=this.store.getState(),t=kn(Ln.LIKE_STATUS_CHANGED,(t=>{t.contentId===e.contentId&&void 0!==t.isLiked&&this.store.setState({isLiked:t.isLiked,likeCount:t.likeCount||0})})),n=kn(Ln.FOLLOW_STATUS_CHANGED,(t=>{t.contentId===e.contentId&&void 0!==t.isFollowing&&this.store.setState({isFollowing:t.isFollowing,followCount:t.followCount||0})}));this.cleanup.addCleanupTask(t),this.cleanup.addCleanupTask(n)}}var co=lo;function uo(){return[()=>ae.c.hasCookie("heimguard.authStatus"),()=>document.body.classList.contains("user-authenticated"),()=>null!==sessionStorage.getItem("heimguard_user"),()=>document.cookie.includes("auth_token")].some((e=>{try{return e()}catch(e){return!1}}))}function mo(){const e=document.querySelector('meta[name="brightspot.contentId"]');if(e?.content)return e.content;const t=document.querySelector('meta[name="content-id"]')?.content;if(t)return t;const n=document.body.getAttribute("data-content-id");if(n)return n;const o=document.querySelector('main, article, [role="main"]'),i=o?.getAttribute("data-content-id");if(i)return i;const a=[/\/(?:article|post|content|blog|news|story)\/([^\/\?]+)/,/\/([a-zA-Z0-9-]+)$/,/[?&](?:id|contentId|articleId|postId)=([^&]+)/];for(const e of a){const t=window.location.href.match(e);if(t&&t[1])return t[1]}const s=document.title.split("|")[0].trim();if(s&&"Home"!==s)return go(s);return`content-${Date.now()}`}function go(e){return e.toString().toLowerCase().trim().replace(/\s+/g,"-").replace(/[^\w\-]+/g,"").replace(/\-\-+/g,"-").replace(/^-+/,"").replace(/-+$/,"")}class ho{constructor(){this.config={apiBase:"/api/heimguard",commentsPerPage:10,enableComments:!1,allowAnonymousComments:!1,moderateComments:!1,showCommentLikes:!0,allowNestedComments:!0,maxCommentDepth:3,enableProfanityFilter:!1,blockedWords:[],profanityWarningMessage:"Your comment contains inappropriate language. Please revise before posting.",commentMaxLength:5e3,hideCommentsBehindButton:!1,sortByThreadEngagement:!1}}static getInstance(){return ho.instance||(ho.instance=new ho),ho.instance}setConfig(e){this.config={...this.config,...e}}getConfig(){return{...this.config}}get apiBase(){return this.config.apiBase}get commentsPerPage(){return this.config.commentsPerPage}get enableComments(){return this.config.enableComments}get allowAnonymousComments(){return this.config.allowAnonymousComments}get moderateComments(){return this.config.moderateComments}get showCommentLikes(){return this.config.showCommentLikes}get allowNestedComments(){return this.config.allowNestedComments}get maxCommentDepth(){return this.config.maxCommentDepth}get enableProfanityFilter(){return this.config.enableProfanityFilter}get blockedWords(){return this.config.blockedWords}get profanityWarningMessage(){return this.config.profanityWarningMessage}get commentMaxLength(){return this.config.commentMaxLength}get hideCommentsBehindButton(){return this.config.hideCommentsBehindButton}get sortByThreadEngagement(){return this.config.sortByThreadEngagement}async loadFromServer(){try{const e=await fetch(`${this.config.apiBase}/init`,{credentials:"include"});if(e.ok){const t=await e.json();t.commentsConfig&&this.setConfig({enableComments:t.commentsConfig.enableComments,commentsPerPage:t.commentsConfig.commentsPerPage,allowAnonymousComments:t.commentsConfig.allowAnonymousComments,moderateComments:t.commentsConfig.moderateComments,showCommentLikes:t.commentsConfig.showCommentLikes,allowNestedComments:t.commentsConfig.allowNestedComments,maxCommentDepth:t.commentsConfig.maxCommentDepth,enableProfanityFilter:t.commentsConfig.enableProfanityFilter||!1,blockedWords:t.commentsConfig.blockedWords||[],profanityWarningMessage:t.commentsConfig.profanityWarningMessage||"Your comment contains inappropriate language. Please revise before posting.",commentMaxLength:t.commentsConfig.commentMaxLength||5e3,hideCommentsBehindButton:t.commentsConfig.hideCommentsBehindButton||!1,sortByThreadEngagement:t.commentsConfig.sortByThreadEngagement||!1})}}catch(e){console.warn("Failed to load comments config from server:",e)}}}class po{constructor(e={}){this.processedBars=new WeakSet,this.observer=null,this.options={enabled:!0,actionBarSelector:".ActionBar",excludeSelectors:[".ActionBar--noAffinity",".ActionBar--minimal"],delay:100,...e},this.options.enabled&&this.initialize()}initialize(){this.injectStyles(),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>this.scanAndInject())):setTimeout((()=>this.scanAndInject()),this.options.delay),this.setupObserver()}injectStyles(){if(document.getElementById("affinity-auto-injector-styles"))return;const e=document.createElement("style");e.id="affinity-auto-injector-styles",e.textContent="\n .hg-affinity-icon {\n width: 1em;\n height: 1em;\n vertical-align: middle;\n }\n .affinity-like-btn.is-liked svg {\n fill: #e53e3e;\n stroke: #e53e3e;\n }\n .affinity-follow-btn.is-following svg {\n fill: #3182ce;\n }\n .affinity-comments-btn svg {\n stroke: #6b7280;\n }\n .affinity-comments-btn:hover svg {\n stroke: #374151;\n }\n \n /* Loading state styles */\n .ActionLink.is-loading {\n position: relative;\n pointer-events: none;\n opacity: 0.7;\n }\n \n .ActionLink.is-loading .hg-affinity-icon {\n animation: pulse 1.5s ease-in-out infinite;\n }\n \n .ActionLink.is-loading .ActionLink-message {\n opacity: 0.5;\n }\n \n @keyframes pulse {\n 0% {\n opacity: 0.3;\n }\n 50% {\n opacity: 1;\n }\n 100% {\n opacity: 0.3;\n }\n }\n \n /* Spinner overlay */\n .affinity-spinner {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 16px;\n height: 16px;\n }\n \n .affinity-spinner::after {\n content: '';\n display: block;\n width: 16px;\n height: 16px;\n border: 2px solid #e5e7eb;\n border-top-color: #3b82f6;\n border-radius: 50%;\n animation: spin 0.6s linear infinite;\n }\n \n @keyframes spin {\n to {\n transform: rotate(360deg);\n }\n }\n ",document.head.appendChild(e)}setupObserver(){this.observer=new MutationObserver((e=>{let t=!1;e.forEach((e=>{"childList"===e.type&&e.addedNodes.length>
10&&e.addedNodes.forEach((e=>{e instanceof Element&&(e.matches(this.options.actionBarSelector)||e.querySelector(this.options.actionBarSelector))&&(t=!0)}))})),t&&setTimeout((()=>this.scanAndInject()),this.options.delay)})),document.body&&this.observer.observe(document.body,{childList:!0,subtree:!0})}async scanAndInject(){if(!uo())return void console.log("[AffinityAutoInjector] User not logged in, skipping injection");const e=document.querySelectorAll(this.options.actionBarSelector);for(const t of e){if(this.processedBars.has(t))continue;this.options.excludeSelectors.some((e=>t.matches(e)))||(t.querySelector('[data-hg-component="affinity-widget"]')?this.processedBars.add(t):await this.injectWidget(t))}}async injectWidget(e){try{const t=mo();if(!t)return void console.warn("[AffinityAutoInjector] Could not detect content ID for ActionBar");const n=this.findInsertionPoint(e);if(!n)return void console.warn("[AffinityAutoInjector] Could not find suitable insertion point in ActionBar");const o=this.createLikeButton(t),i=this.createFollowButton(t),a=ho.getInstance();let s=null;try{await a.loadFromServer(),console.log("[AffinityAutoInjector] Comments debug:",{enableComments:a.enableComments,config:a.getConfig()}),a.enableComments?(console.log("[AffinityAutoInjector] Creating comments button"),s=this.createCommentsButton(t)):console.log("[AffinityAutoInjector] Comments disabled, skipping comments button")}catch(e){console.warn("[AffinityAutoInjector] Failed to load comments config:",e)}n.element.appendChild(o),n.element.appendChild(i),s&&n.element.appendChild(s),e.setAttribute("data-affinity-processed","true"),this.processedBars.add(e),this.initializeInteractionHandlers(o,i,s,t),In(Ln.WIDGET_INITIALIZED,{element:e,contentId:t,context:"actionbar-auto-inject"}),console.log("[AffinityAutoInjector] Affinity buttons injected into ActionBar",{contentId:t,actionBar:e})}catch(e){console.error("[AffinityAutoInjector] Failed to inject widget:",e)}}createLikeButton(e){const t=document.createElement("li");return t.className="ActionBar-items-item",t.innerHTML=`\n <div class="ActionLink affinity-like-btn hg-affinity-like" data-link="#" data-social-service="like" data-content-id="${e}">\n <svg fill="none" stroke="currentColor" viewBox="0 0 24 24" class="hg-affinity-icon">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path>\n </svg>\n <div class="ActionLink-message">Like</div>\n </div>\n `,t}createFollowButton(e){const t=document.createElement("li");return t.className="ActionBar-items-item",t.innerHTML=`\n <div class="ActionLink affinity-follow-btn hg-affinity-follow" data-link="#" data-social-service="follow" data-content-id="${e}">\n <svg fill="currentColor" viewBox="0 0 24 24" class="hg-affinity-icon">\n <path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path>\n </svg>\n <div class="ActionLink-message">Follow</div>\n </div>\n `,t}createCommentsButton(e){const t=document.createElement("li");return t.className="ActionBar-items-item",t.innerHTML=`\n <div class="ActionLink affinity-comments-btn hg-affinity-comments" data-link="#comments" data-social-service="comments" data-content-id="${e}">\n <svg fill="none" stroke="currentColor" viewBox="0 0 24 24" class="hg-affinity-icon">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />\n </svg>\n <div class="ActionLink-message">Comment</div>\n </div>\n `,t}async initializeInteractionHandlers(e,t,n,o){try{const n=await Bn.getStatus(o),i=e.querySelector(".affinity-like-btn");if(i&&n.isLiked){i.classList.add("is-liked");const e=i.querySelector(".ActionLink-message");e&&(e.textContent="Like"+(n.likeCount>0?` (${n.likeCount})`:""))}const a=t.querySelector(".affinity-follow-btn");if(a&&n.isFollowing){a.classList.add("is-following");const e=a.querySelector(".ActionLink-message");e&&(e.textContent="Following"+(n.followCount>0?` (${n.followCount})`:""))}}catch(e){console.error("[AffinityAutoInjector] Failed to load initial status:",e)}e.addEventListener("click",(async t=>{t.preventDefault();const n=e.querySelector(".affinity-like-btn");if(!n||n.classList.contains("is-loading"))return;const i=n.classList.contains("is-liked");n.classList.add("is-loading");const a=document.createElement("div");a.className="affinity-spinner",n.appendChild(a);try{const e=await Bn.toggleLike(o,i);n.classList.toggle("is-liked");const t=n.querySelector(".ActionLink-message");t&&(t.textContent=`${e.isLiked?"Liked":"Like"}${e.likeCount>0?` (${e.likeCount})`:""}`)}catch(e){console.error("[AffinityAutoInjector] Like action failed:",e)}finally{n.classList.remove("is-loading"),a.remove()}})),t.addEventListener("click",(async e=>{e.preventDefault();const n=t.querySelector(".affinity-follow-btn");if(!n||n.classList.contains("is-loading"))return;const i=n.classList.contains("is-following");n.classList.add("is-loading");const a=document.createElement("div");a.className="affinity-spinner",n.appendChild(a);try{const e=await Bn.toggleFollow(o,i);n.classList.toggle("is-following");const t=n.querySelector(".ActionLink-message");t&&(t.textContent=`${e.isFollowing?"Following":"Follow"}${e.followCount>0?` (${e.followCount})`:""}`)}catch(e){console.error("[AffinityAutoInjector] Follow action failed:",e)}finally{n.classList.remove("is-loading"),a.remove()}})),n&&n.addEventListener("click",(e=>{e.preventDefault(),this.scrollToComments()}))}scrollToComments(){const e=document.querySelector('.comments-widget, [data-hg-component="comments-widget"], .hg-commenting-module');
1if(e){const t=getComputedStyle(document.documentElement).getPropertyValue("--headerHeight"),n=parseInt(t)||120,o=e.getBoundingClientRect().top+window.pageYOffset,i=o-n-100;console.log("[AffinityAutoInjector] Scrolling to comments:",{headerHeight:n,elementTop:o,targetPosition:i}),window.scrollTo({top:i,behavior:"smooth"}),setTimeout((()=>{const t=e.querySelector(".comment-form-textarea");t&&t.focus()}),500)}else console.warn("[AffinityAutoInjector] Comments section not found on page")}findInsertionPoint(e){const t=[".ActionBar-items",".ActionBar-actions",".ActionBar-right",".ActionBar-end"];for(const n of t){const t=e.querySelector(n);if(t)return{element:t,before:!1}}return null}enable(){this.options.enabled=!0,this.initialize()}disable(){this.options.enabled=!1,this.observer&&(this.observer.disconnect(),this.observer=null)}scan(){this.scanAndInject()}cleanup(){this.disable(),this.processedBars=new WeakSet}}let yo=null;var Co={getInstance(e){return yo||(yo=new po(e)),yo},enable(){return this.getInstance().enable()},disable(){return this.getInstance().disable()},scan(){return this.getInstance().scan()},cleanup(){return this.getInstance().cleanup()}};class fo{constructor(e={}){this.manager=Bn,this.widgets=new Map,this.dashboards=new Map,this.profiles=new Map,this.eventCleanup=[],this.config={autoScan:!0,enableGlobalEvents:!0,enableAnalytics:!1,autoInjectActionBars:!0,...e},this.initialize()}initialize(){b.vF.debug("Initializing Affinity System...","affinity"),this.config.enableGlobalEvents&&this.setupGlobalEventListeners(),this.config.autoScan&&this.scanAndInitialize(),this.config.autoInjectActionBars&&(Co.getInstance({enabled:!0,delay:200}),b.vF.debug("ActionBar auto-injection enabled","affinity")),this.setupCacheCleanup(),b.vF.debug("Affinity System initialized","affinity")}scanAndInitialize(){this.scanAffinityWidgets(),this.scanAffinityDashboards(),this.scanProfileFollowed()}scanAffinityWidgets(){document.querySelectorAll('[data-hg-component="affinity-widget"]').forEach((e=>{e.dataset.initialized||this.initializeWidget(e)}))}scanAffinityDashboards(){document.querySelectorAll('[data-hg-component="affinity-dashboard"]').forEach((e=>{e.dataset.initialized||this.initializeDashboard(e)}))}scanProfileFollowed(){document.querySelectorAll('[data-hg-component="profile-followed"]').forEach((e=>{e.dataset.initialized||this.initializeProfileFollowed(e)}))}initializeWidget(e,t={}){const n=this.generateId("widget");try{const o=new co(e,{manager:this.manager,config:Nn,...t});return this.widgets.set(n,o),e.dataset.widgetId=n,e.dataset.initialized="true",In(Ln.WIDGET_INITIALIZED,{widgetId:n,element:e}),o}catch(e){throw b.vF.error("Failed to initialize affinity widget:","affinity",e),e}}initializeDashboard(e,t={}){const n=this.generateId("dashboard");try{const o=new Un(e,{api:this.manager.api,config:Nn,...t});return this.dashboards.set(n,o),e.dataset.dashboardId=n,e.dataset.initialized="true",o.render(),In(Ln.DASHBOARD_OPENED,{dashboardId:n,element:e}),o}catch(e){throw b.vF.error("Failed to initialize affinity dashboard:","affinity",e),e}}initializeProfileFollowed(e,t={}){const n=this.generateId("profile");try{const o=new Hn(e,{api:this.manager.api,config:Nn,...t});return this.profiles.set(n,o),e.dataset.profileId=n,e.dataset.initialized="true",o.render(),o}catch(e){throw b.vF.error("Failed to initialize profile followed component:","affinity",e),e}}setupGlobalEventListeners(){const e=kn(Ln.LIKE_STATUS_CHANGED,(e=>{e.contentId&&void 0!==e.isLiked&&this.updateWidgetStates(e.contentId,{isLiked:e.isLiked,likeCount:e.likeCount})})),t=kn(Ln.FOLLOW_STATUS_CHANGED,(e=>{e.contentId&&void 0!==e.isFollowing&&this.updateWidgetStates(e.contentId,{isFollowing:e.isFollowing,followCount:e.followCount})})),n=new MutationObserver((e=>{if(this.config.autoScan){let t=!1;e.forEach((e=>{"childList"===e.type&&e.addedNodes.length>0&&(t=!0)})),t&&this.scanAndInitialize()}}));document.body?n.observe(document.body,{childList:!0,subtree:!0}):document.addEventListener("DOMContentLoaded",(()=>{document.body&&n.observe(document.body,{childList:!0,subtree:!0})})),this.eventCleanup.push(e,t,(()=>n.disconnect()))}
1updateWidgetStates(e,t){this.widgets.forEach((n=>{n.contentId===e&&n.updateState&&n.updateState(t)}))}setupCacheCleanup(){const e=setInterval((()=>{this.manager.clearExpiredCache()}),Nn.performance.cacheExpiry);this.eventCleanup.push((()=>clearInterval(e)))}generateId(e="affinity"){return`${e}_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}getWidget(e){return this.widgets.get(e)||null}getDashboard(e){return this.dashboards.get(e)||null}getProfile(e){return this.profiles.get(e)||null}removeWidget(e){const t=this.widgets.get(e);t&&t.cleanup&&t.cleanup(),this.widgets.delete(e),In(Ln.WIDGET_DESTROYED,{widgetId:e})}removeDashboard(e){const t=this.dashboards.get(e);t&&t.cleanup&&t.cleanup(),this.dashboards.delete(e),In(Ln.DASHBOARD_CLOSED,{dashboardId:e})}removeProfile(e){const t=this.profiles.get(e);t&&t.cleanup&&t.cleanup(),this.profiles.delete(e)}getStats(){return{widgets:this.widgets.size,dashboards:this.dashboards.size,profiles:this.profiles.size,cache:this.manager.getCacheStats()}}cleanup(){b.vF.debug("Cleaning up Affinity System...","affinity"),this.widgets.forEach(((e,t)=>{this.removeWidget(t)})),this.dashboards.forEach(((e,t)=>{this.removeDashboard(t)})),this.profiles.forEach(((e,t)=>{this.removeProfile(t)})),this.eventCleanup.forEach((e=>e())),this.eventCleanup=[],this.config.autoInjectActionBars&&Co.cleanup(),this.manager.clearCache(),b.vF.debug("Affinity System cleaned up","affinity")}}let vo=null;var bo={getInstance(){return vo||(vo=new fo),vo},get manager(){return this.getInstance().manager},get widgets(){return this.getInstance().widgets},get dashboards(){return this.getInstance().dashboards},get profiles(){return this.getInstance().profiles},initializeWidget(...e){return this.getInstance().initializeWidget(...e)},initializeDashboard(...e){return this.getInstance().initializeDashboard(...e)},initializeProfileFollowed(...e){return this.getInstance().initializeProfileFollowed(...e)},getStats(){return this.getInstance().getStats()},cleanup(){return this.getInstance().cleanup()}};if("undefined"!=typeof window){const e={name:"affinitySystemAdapter",initialize:async()=>{}};A.systemRegistry.register("affinitySystemAdapter",e);const t=bo.getInstance();window.HeimGuard=window.HeimGuard||{},window.HeimGuard.affinitySystem=t,window.HeimGuard.affinityManager=Bn,window.HeimGuard.affinityConfig=Nn,b.vF.debug("AffinitySystem initialized and attached to window.HeimGuard","affinity")}const wo={DEFAULT_OPTIONS:{apiEndpoint:f.A.apiAccessWall,containerSelector:"HgAccessWall"}},So="accesswall:access:checked",xo="accesswall:displayed",Ao="accesswall:access:granted",To="accesswall:access:denied",Mo="accesswall:subscription:completed";class Eo extends Ut.pZ{constructor(){super({baseURL:f.A.apiBaseUrl}),this.cache=new Map,this.pendingRequests=new Map,this.CACHE_DURATION=3e5}async fetchAccessWallData(e){if(this.pendingRequests.has(e))return console.log(`[AccessWallAPI] Reusing pending request for shortCode: ${e}`),this.pendingRequests.get(e);const t=this.cache.get(e);if(t&&Date.now()-t.timestamp<this.CACHE_DURATION)return console.log(`[AccessWallAPI] Returning cached data for shortCode: ${e}`),t.data;const n=this.makeRequest(e);this.pendingRequests.set(e,n);try{const t=await n;return t.success&&this.cache.set(e,{data:t,timestamp:Date.now()}),t}finally{this.pendingRequests.delete(e)}}async makeRequest(e){try{const t=f.A.apiAccessWall.replace(f.A.apiBaseUrl,"");return this.get(t,{params:{shortCode:e}})}catch(e){return console.error("[AccessWallAPI] Error fetching access wall data:",e),e instanceof Ut.LG?(console.log("[AccessWallAPI] APIError caught - status:",e.status,"message:",e.message),{success:!1,error:{message:e.message||"Unable to load subscription plans.",code:e.status?String(e.status):"API_ERROR"}}):{success:!1,error:{message:"Unable to load subscription plans. Please try again later.",code:"NETWORK_ERROR"}}}}}const Po=new class{constructor(){this.name="accessWallSystem",this.accessWallSystem=null,this.isInitializing=!1,this.isInitialized=!1}async initialize(){if(this.isInitialized||this.isInitializing)b.vF.debug("Access wall system already initialized or initializing, skipping","general");else{this.isInitializing=!0,b.vF.debug("Initializing access wall system...","general");try{const{systemRegistry:e}=await Promise.resolve().then(n.bind(n,1667));Io.hasAccessWalls()?(this.accessWallSystem=new Io({autoScan:!0}),await this.accessWallSystem.initialize(),e.registerInstance("accessWallSystem",this.accessWallSystem),b.vF.debug("Acce
1ss wall system initialized successfully","general")):b.vF.debug("No access walls found, skipping initialization","general"),this.isInitialized=!0}finally{this.isInitializing=!1}}}cleanup(){this.accessWallSystem&&(this.accessWallSystem.cleanup(),this.accessWallSystem=null)}async checkUserAccess(){if(!this.accessWallSystem)throw new Error("AccessWallSystem not initialized");return this.accessWallSystem.checkUserAccess()}getUserAccessState(){return this.accessWallSystem?this.accessWallSystem.getUserAccessState():null}async hasAccess(e){return!!this.accessWallSystem&&this.accessWallSystem.hasAccess(e)}async renderAccessWall(e,t={}){return this.accessWallSystem||(this.accessWallSystem=new Io({autoScan:!1}),await this.accessWallSystem.initialize()),this.accessWallSystem.renderAccessWall(e,t)}async refreshAll(){if(this.accessWallSystem)return this.accessWallSystem.refreshAll()}static hasAccessWalls(){return Io.hasAccessWalls()}static async render(e,t={}){return Io.render(e,t)}};const No=new Eo;class Lo{constructor(e={}){this.options={...wo.DEFAULT_OPTIONS,onSubscriptionSuccess:e.onSubscriptionSuccess||(async()=>{}),onAccessGranted:e.onAccessGranted||(()=>{}),onAccessDenied:e.onAccessDenied||(()=>{}),...e},this.state={accessWallData:null,availablePlans:[],shortCode:null,displaySettings:{showFilters:!0,showSort:!0,showLegend:!0,showProgress:!0}},this.api=No,this.containers=[],this.subscriptionFlow=null,this.isCabotWealth=!1}static hasAccessWalls(){const e=wo.DEFAULT_OPTIONS.containerSelector||"HgAccessWall";return document.querySelectorAll(e).length>0}async initialize(){try{const e=document.querySelectorAll(this.options.containerSelector);if(this.containers=Array.from(e),0===this.containers.length)return;for(const e of this.containers)await this.render(e)}catch(e){throw e}}async render(e){try{await w.default.load(),this.isCabotWealth=w.default.isCabotWealth();const t=new URLSearchParams(window.location.search),n=t.get("shortCode"),o=t.get("plan_id"),i=e.getAttribute("shortCode")||e.getAttribute("data-access-wall")||e.dataset.accessWall;let a=n||i,s=!!n;if(!a)throw new Error("No shortCode found in URL parameter or container attributes");const r=e.getAttribute("data-access-wall-layout")||e.dataset.accessWallLayout||"modal";this.state.displaySettings={showFilters:void 0!==e.dataset.showFilters?"true"===e.dataset.showFilters:void 0===this.options.showFilters||this.options.showFilters,showSort:void 0!==e.dataset.showSort?"true"===e.dataset.showSort:void 0===this.options.showSort||this.options.showSort,showLegend:void 0!==e.dataset.showLegend?"true"===e.dataset.showLegend:void 0===this.options.showLegend||this.options.showLegend,showProgress:void 0!==e.dataset.showProgress?"true"===e.dataset.showProgress:void 0===this.options.showProgress||this.options.showProgress};const d="true"===e.dataset.showLogin,l=e.dataset.redirectUrl||w.default.getLibraryPageUrl();let c,u;if(e.innerHTML="inline"===r?this.getInlineLoadingHTML():this.getLoadingHTML(),c=null,s&&n){try{console.log("[AccessWall] Trying shortCode from URL parameter:",n),c=await this.api.fetchAccessWallData(n),console.log("[AccessWall] URL parameter response:",c)}catch(e){console.log("[AccessWall] URL parameter request threw error:",e),c={success:!1,error:{message:e instanceof Error?e.message:"Request failed",code:"API_ERROR"}}}if(!c.success&&c.error){const e=String(c.error.code),t=c.error.message?.toLowerCase()||"",o=e.startsWith("40")||"404"===e||"403"===e||"401"===e||"400"===e||"500"===e&&t.includes("not found")||t.includes("accesswall not found");console.log("[AccessWall] URL parameter failed with code:",e,"message:",t,"isNotFoundError:",o),o&&i&&i!==n&&(console.log("[AccessWall] URL parameter shortCode failed - falling back to data attribute:",i),a=i,s=!1,c=null)}}if((!c||!c.success)&&a&&(!s||null===c))try{console.log("[AccessWall] Using shortCode from data attribute:",a),c=await this.api.fetchAccessWallData(a),console.log("[AccessWall] Data attribute response:",c)}catch(e){console.log("[AccessWall] Data attribute request threw error:",e),c={success:!1,error:{message:e instanceof Error?e.message:"Request failed",code:"API_ERROR"}}}if(console.log("[AccessWall] Final API response:",c),!c||!c.success||!c.data){if(s&&n&&!i)throw new Error(`Access wall '${n}' not found`);throw new Error(c?.error?.message||"Failed to load access wall data")}if(u=c.data,console.log("[AccessWall] Rendering with layoutType:",r,"shortCode:",a,"displaySettings:",this.state.displaySettings),this.state.accessWallData=u,this.state.availablePlans=u.plans||[],o){console.log("[AccessWall] Filtering plans for plan_id:",o);const e=this.state.availablePlans.filter((e=>e.id===o));e.length>0?(this.state.availablePlans=e,console.log("[AccessWall] Filtered to single plan:",e[0])):console.warn("[AccessWall] No plan found with id:",o)}this.state.shortCode=a,"inline"===r?(console.log("[AccessWall] Rendering inline subscription flow"),await this.renderInlineSubscriptionFlowWithTransition(e)):(console.log("[AccessWall] Rendering modal access wall"),await this.renderAccessWall(e,u,d,l))}catch(t){const n=t instanceof Error?t.message:"An error occurred";e.innerHTML=this.getErrorHTML(n)}}async renderAccessWall(e,t,n=!1,o){o||(o=w.default.getLibraryPageUrl());const i=oe.A.isAuthenticated();let a='<div class="access-wall-container bg-white rounded-lg shadow-xl p-8 max-w-2xl mx-auto text-center transition-all duration-300 opacity-0">';a+=n&&!i?`\n \x3c!-- Login Section --\x3e\n <div class="mb-8">\n <h2 class="text-3xl font-bold text-gray-900 mb-6">\n Login to Access ${t.title||"Premium Content"}\n </h2>\n <button\n data-login-trigger="true"\n data-redirect-url="${o}"\n class="inline-flex items-center px-8 py-3 bg-primary-600 text-white text-lg font-semibold rounded-full hover:bg-primary-700 hover:text-white transition-all duration-200"\n >\n ${P.A.render("log-in",{class:"w-5 h-5 mr-2"})}\n Login\n </button>\n </div>\n\n \x3c!-- Separator --\x3e\n <hr class="my-8 border-gray-200">\n\n \x3c!-- Not a Subscriber Section --\x3e\n <div class="mb-8">\n <h2 class="text-3xl font-bold text-gray-900 mb-3">\n Not a ${t.title||"Premium"} Subscriber?\n </h2>\n <p class="text-lg text-gray-600 max-w-xl mx-auto">\n Subscribe for Full Access\n </p>\n </div>\n `:`\n \x3c!-- Header --\x3e\n <div class="mb-8">\n <h2 class="text-3xl font-bold text-gray-900 mb-3">\n ${t.title||"Subscribe for Full Access"}\n </h2>\n ${t.description?`\n <p class="text-lg text-gray-600 max-w-xl mx-auto">\n ${t.description}\n </p>\n `:""}\n </div>\n `,a+=`\n \x3c!-- Benefits --\x3e\n <div class="mb-8">\n <div class="bg-blue-50 rounded-xl p-6">\n <h3 class="text-lg font-semibold text-gray-900 mb-4">${this.isCabotWealth?"Included in Your Subscription":"What you'll get:"}</h3>\n <ul class="space-y-3 text-left max-w-md mx-auto">\n <li class="flex items-start">\n <svg class="w-5 h-5 text-green-500 mr-3 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />\n </svg>
1\n <span class="text-gray-700">Unlimited access to all premium content</span>\n </li>\n <li class="flex items-start">\n <svg class="w-5 h-5 text-green-500 mr-3 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />\n </svg>\n <span class="text-gray-700">Cancel anytime - no commitment</span>\n </li>\n <li class="flex items-start">\n <svg class="w-5 h-5 text-green-500 mr-3 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />\n </svg>\n <span class="text-gray-700">New content added regularly</span>\n </li>\n </ul>\n </div>\n </div>\n\n \x3c!-- Subscribe Button --\x3e\n <button\n id="open-subscription-modal"\n class="inline-flex items-center px-8 py-3 bg-primary-600 text-white text-lg font-semibold rounded-full hover:bg-primary-700 hover:text-white transition-all duration-200"\n >\n ${P.A.render("dollar-sign",{class:"w-5 h-5 mr-2"})}\n ${this.isCabotWealth?"Included in Your Subscription":"View Subscription Plans Now"}\n </button>\n\n \x3c!-- Security Note --\x3e\n <div class="mt-6 flex items-center justify-center text-sm text-gray-500">\n <svg class="w-4 h-4 mr-2 text-green-600" fill="currentColor" viewBox="0 0 20 20">\n <path fill-rule="evenodd" d="M2.166 4.999A11.954 11.954 0 0010 1.944 11.954 11.954 0 0017.834 5c.11.65.166 1.32.166 2.001 0 5.225-3.34 9.67-8 11.317C5.34 16.67 2 12.225 2 7c0-.682.057-1.35.166-2.001zm11.541 3.708a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />\n </svg>\n <span>Secure payment ⢠Cancel anytime</span>\n </div>\n </div>\n `,e.innerHTML=a;const s=e.querySelector(".access-wall-container");s&&requestAnimationFrame((()=>{s.classList.remove("opacity-0"),s.classList.add("opacity-100")}));const r=e.querySelector("#open-subscription-modal");r&&(this._buttonClickHandler&&r.removeEventListener("click",this._buttonClickHandler),this._buttonClickHandler=()=>this.openSubscriptionModal(),r.addEventListener("click",this._buttonClickHandler))}async renderInlineSubscriptionFlowWithTransition(e){const t=document.createElement("div");t.style.opacity="0",t.style.transition="opacity 300ms ease-in-out",e.classList.add("access-wall-inline"),this.state.displaySettings.showFilters||e.setAttribute("data-show-filters","false"),this.state.displaySettings.showSort||e.setAttribute("data-show-sort","false"),this.state.displaySettings.showLegend||e.setAttribute("data-show-legend","false"),this.state.displaySettings.showProgress||e.setAttribute("data-show-progress","false"),this.subscriptionFlow=new St.default({shortCode:this.state.shortCode||void 0,inline:!0,container:t,displaySettings:this.state.displaySettings,accessWallData:{title:this.state.accessWallData?.title,description:this.state.accessWallData?.description},onSuccess:async e=>{try{await this.handleSubscriptionSuccess(e)}catch(e){throw te.Alert.flash({message:"Failed to process subscription",variant:"error"}),e}},onCancel:()=>{this.subscriptionFlow=null,this.render(e)}});const n=this.subscriptionFlow.show(),o=new Promise((e=>setTimeout(e,300)));await Promise.all([n,o]),e.innerHTML="",e.appendChild(t),requestAnimationFrame((()=>{t.style.opacity="1",setTimeout((()=>{e.classList.add("loaded")}),100)}))}async renderInlineSubscriptionFlow(e){e.classList.add("access-wall-inline"),this.state.displaySettings.showFilters||e.setAttribute("data-show-filters","false"),this.state.displaySettings.showSort||e.setAttribute("data-show-sort","false"),this.state.displaySettings.showLegend||e.setAttribute("data-show-legend","false"),this.state.displaySettings.showProgress||e.setAttribute("data-show-progress","false"),this.subscriptionFlow=new St.default({shortCode:this.state.shortCode||void 0,inline:!0,container:e,displaySettings:this.state.displaySettings,accessWallData:{title:this.state.accessWallData?.title,de
1scription:this.state.accessWallData?.description},onSuccess:async e=>{try{await this.handleSubscriptionSuccess(e)}catch(e){throw te.Alert.flash({message:"Failed to process subscription",variant:"error"}),e}},onCancel:()=>{this.subscriptionFlow=null,this.render(e)}}),await this.subscriptionFlow.show()}async openSubscriptionModal(){this.subscriptionFlow&&(this.subscriptionFlow.hide(),this.subscriptionFlow=null),this.subscriptionFlow=new St.default({shortCode:this.state.shortCode||void 0,onSuccess:async e=>{try{await this.handleSubscriptionSuccess(e)}catch(e){throw te.Alert.flash({message:"Failed to process subscription",variant:"error"}),e}},onCancel:()=>{this.subscriptionFlow=null}}),this.subscriptionFlow.show()}async handleSubscriptionSuccess(e){const t=this.containers[0];t&&(t.innerHTML='\n <div class="text-center py-16">\n <div class="mx-auto flex items-center justify-center h-24 w-24 rounded-full bg-green-100 mb-6">\n <svg class="h-12 w-12 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />\n </svg>\n </div>\n <h3 class="text-2xl font-bold text-gray-900 mb-2">Welcome!</h3>\n <p class="text-lg text-gray-600 mb-8">Your subscription has been activated successfully.</p>\n <button onclick="window.location.reload()"\n class="px-8 py-3 bg-primary-600 text-white font-medium rounded-lg hover:bg-primary-700 transition-colors">\n Continue to Content\n </button>\n </div>\n '),this.options.onSubscriptionSuccess&&await this.options.onSubscriptionSuccess(e)}getLoadingHTML(){return'\n <div class="access-wall-loading">\n \x3c!-- Skeleton that matches the final layout to prevent jumpiness --\x3e\n <div class="access-wall-container bg-white rounded-lg shadow-xl p-8 max-w-2xl mx-auto text-center animate-pulse">\n \x3c!-- Header skeleton --\x3e\n <div class="mb-8">\n <div class="h-8 bg-gray-200 rounded w-3/4 mx-auto mb-3"></div>\n <div class="h-4 bg-gray-200 rounded w-1/2 mx-auto"></div>\n </div>\n \n \x3c!-- Benefits skeleton --\x3e\n <div class="mb-8">\n <div class="bg-gray-50 rounded-xl p-6">\n <div class="h-5 bg-gray-200 rounded w-1/3 mx-auto mb-4"></div>\n <div class="space-y-3 text-left max-w-md mx-auto">\n <div class="flex items-start">\n <div class="w-5 h-5 bg-gray-200 rounded-full mr-3 mt-0.5 flex-shrink-0"></div>\n <div class="h-4 bg-gray-200 rounded flex-1"></div>\n </div>\n <div class="flex items-start">\n <div class="w-5 h-5 bg-gray-200 rounded-full mr-3 mt-0.5 flex-shrink-0"></div>\n <div class="h-4 bg-gray-200 rounded flex-1"></div>\n </div>\n <div class="flex items-start">\n <div class="w-5 h-5 bg-gray-200 rounded-full mr-3 mt-0.5 flex-shrink-0"></div>\n <div class="h-4 bg-gray-200 rounded flex-1"></div>\n </div>\n </div>\n </div>\n </div>\n \n \x3c!-- Button skeleton --\x3e\n <div class="h-12 bg-gray-200 rounded-full w-64 mx-auto mb-6"></div>\n \n \x3c!-- Security note skeleton --\x3e\n <div class="flex items-center justify-center">\n <div class="w-4 h-4 bg-gray-200 rounded mr-2"></div>\n <div class="h-3 bg-gray-200 rounded w-48"></div>\n </div>\n </div>\n </div>\n '}getInlineLoadingHTML(){return'\n <div class="access-wall-inline-loading">\n \x3c!-- Skeleton that matches the subscription flow layout --\x3e\n <div class="subscription-flow-container animate-pulse">\n \x3c!-- Header skeleton --\x3e\n <div class="mb-8 text-center">\n <div class="h-10 bg-gray-200 rounded w-3/4 mx-auto mb-4"></div>\n <div class="h-6 bg-gray-200 rounded w-1/2 mx-auto"></div>\n </div>\n \n \x3c!-- Plan cards skeleton --\x3e\n <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">\n \x3c!-- Plan card 1 --\x3e\n <div class="bg-white border border-gray-200 rounded-xl p-6">\n <div class="h-6 bg-gray-200 rounded w-2/3 mb-2"></div>\n <div class="h-8 bg-gray-200 rounded w-1/2 mb-4"></div>\n <div class="space-y-2 mb-6">\n <div class="h-4 bg-gray-200 rounded"></div>\n <div class="h-4 bg-gray-200 rounded w-4/5"></div>\n <div class="h-4 bg-gray-200 rounded w-3/4"></div>\n </div>\n <div class="h-12 bg-gray-200 rounded-lg"></div>\n </div>\n \n \x3c!-- Plan card 2 (highlighted) --\x3e\n <div class="bg-white border-2 border-primary-200 rounded-xl p-6 relative">\n <div class="absolute -top-3 left-1/2 transform -translate-x-1/2">\n <div class="h-6 bg-gray-200 rounded-full w-24"></div>\n </div>\n <div class="h-6 bg-gray-200 rounded w-2/3 mb-2"></div>\n <div class="h-8 bg-gray-200 rounded w-1/2 mb-4"></div>\n <div class="space-y-2 mb-6">\n <div class="h-4 bg-gray-200 rounded"></div>\n <div class="h-4 bg-gray-200 rounded w-4/5"></div>\n <div class="h-4 bg-gray-200 rounded w-3/4"></div>\n </div>\n <div class="h-12 bg-gray-200 rounded-lg"></div>\n </div>\n \n \x3c!-- Plan card 3 --\x3e\n <div class="bg-white border border-gray-200 rounded-xl p-6">\n <div class="h-6 bg-gray-200 rounded w-2/3 mb-2"></div>\n <div class="h-8 bg-gray-200 rounded w-1/2 mb-4"></div>\n <div class="space-y-2 mb-6">\n <div class="h-4 bg-gray-200 rounded"></div>\n <div class="h-4 bg-gray-200 rounded w-4/5"></div>\n <div class="h-4 bg-gray-200 rounded w-3/4"></div>\n </div>\n <div class="h-12 bg-gray-200 rounded-lg"></div>\n </div>\n </div>\n \n \x3c!-- Security badges skeleton --\x3e\n <div class="flex items-center justify-center space-x-6 text-sm">\n <div class="flex items-center">\n <div class="w-5 h-5 bg-gray-200 rounded mr-2"></div>\n <div class="h-4 bg-gray-200 rounded w-20"></div>\n </div>\n <div class="flex items-center">\n <div class="w-5 h-5 bg-gray-200 rounded mr-2"></div>\n <div class="h-4 bg-gray-200 rounded w-24"></div>\n </div>\n <div class="flex items-center">\n <div class="w-5 h-5 bg-gray-200 rounded mr-2"></div>\n <div class="h-4 bg-gray-200 rounded w-20"></div>\n </div>\n </div>\n </div>\n </div>\n '}getErrorHTML(e){return`\n <div class="text-center py-12">\n <svg class="w-16 h-16 text-red-500 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"\n d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n <h3 class="text-lg font-semibold text-gray-900 mb-2">Unable to Load</h3>\n <p class="text-gray-600">${e}</p>\n </div>\n `}async refresh(){this.containers.length>0&&await this.render(this.containers[0])}destroy(){this.subscriptionFlow&&(this.subscriptionFlow.hide(),this.subscriptionFlow=null),this._buttonClickHandler&&(this.containers.forEac
1h((e=>{const t=e.querySelector("#open-subscription-modal");t&&t.removeEventListener("click",this._buttonClickHandler)})),this._buttonClickHandler=void 0)}}"undefined"!=typeof window&&(A.systemRegistry.register("accessWallSystemAdapter",Po),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>{Po.initialize()})):Po.initialize());const Do=new Eo;class Io{constructor(e={}){this.config={autoScan:!0,containerSelector:wo.DEFAULT_OPTIONS.containerSelector||"HgAccessWall",tagName:"HgAccessWall",apiBaseUrl:e.apiBaseUrl||"/api/heimguard",apiEndpoint:wo.DEFAULT_OPTIONS.apiEndpoint||f.A.apiAccessWall||"/api/heimguard/access-wall",...e},this.instances=new Map,this.api=Do,this.userAccessState=null,this.isInitialized=!1,this.config.autoScan&&this.initialize()}async initialize(){if(!this.isInitialized)try{await this.checkUserAccess(),this.config.autoScan&&await this.scanAndRenderWalls(),this.setupEventListeners(),this.isInitialized=!0,console.log("â
AccessWallSystem initialized")}catch(e){console.error("â Failed to initialize AccessWallSystem:",e)}}async checkUserAccess(){this.userAccessState={hasAccess:!1,isAuthenticated:!!window.HeimGuard?.user};const e=new CustomEvent(So,{detail:{accessState:this.userAccessState},bubbles:!0});document.dispatchEvent(e)}async scanAndRenderWalls(){const e=document.getElementsByTagName(this.config.tagName);for(const t of Array.from(e))await this.renderAccessWall(t);const t=document.querySelectorAll(this.config.containerSelector);for(const e of Array.from(t))this.instances.has(e)||await this.renderAccessWall(e)}async renderAccessWall(e,t={}){if(this.instances.has(e))return this.instances.get(e);try{const n=this.extractWallConfig(e),o=new Lo({...this.config,...n,...t,onSubscriptionSuccess:async e=>{await this.handleSubscriptionSuccess(e)},onAccessGranted:()=>{this.handleAccessGranted(e)},onAccessDenied:()=>{this.handleAccessDenied(e)}});return await o.initialize(),this.instances.set(e,o),o}catch(e){throw console.error("Failed to render access wall:",e),e}}extractWallConfig(e){const t={};return e.dataset.wallType&&(t.wallType=e.dataset.wallType),e.dataset.shortCode&&(t.shortCode=e.dataset.shortCode),e.dataset.contentId&&(t.contentId=e.dataset.contentId),e.dataset.maxViews&&(t.maxViews=parseInt(e.dataset.maxViews,10)),void 0!==e.dataset.showFilters&&(t.showFilters="true"===e.dataset.showFilters),void 0!==e.dataset.showSort&&(t.showSort="true"===e.dataset.showSort),void 0!==e.dataset.showLegend&&(t.showLegend="true"===e.dataset.showLegend),void 0!==e.dataset.showProgress&&(t.showProgress="true"===e.dataset.showProgress),t}setupEventListeners(){document.addEventListener("subscription:added",(async e=>{const t=e;await this.handleSubscriptionUpdate(t.detail)})),document.addEventListener(J.QU.LOGIN_SUCCESS,(async()=>{console.log("ð AccessWallSystem: Login success detected, refreshing access walls"),await this.checkUserAccess(),await this.refreshAll()})),document.addEventListener(J.QU.LOGOUT_SUCCESS,(()=>{console.log("ð AccessWallSystem: Logout success detected, clearing access walls"),this.userAccessState=null,this.cleanup()})),document.addEventListener(J.QU.STATE_CHANGED,(async e=>{const t=e,{newState:n,action:o}=t.detail;"login"===o&&n.isAuthenticated?(console.log("ð AccessWallSystem: Auth state changed to authenticated, refreshing access walls"),await this.checkUserAccess(),await this.refreshAll()):"logout"!==o||n.isAuthenticated||(console.log("ð AccessWallSystem: Auth state changed to unauthenticated, clearing access walls"),this.userAccessState=null,this.cleanup())})),document.addEventListener(xo,(e=>{const t=e;this.trackWallDisplay(t.detail)}))}async handleSubscriptionSuccess(e){await this.checkUserAccess();const t=new CustomEvent(Mo,{detail:{subscription:e},bubbles:!0});document.dispatchEvent(t),await this.refreshAll()}async handleSubscriptionUpdate(e){await this.checkUserAccess(),await this.refreshAll()}handleAccessGranted(e){const t=e,n=new CustomEvent(Ao,{detail:{container:e,wallType:t.dataset.wallType,contentId:t.dataset.contentId},bubbles:!0});document.dispatchEvent(n)}handleAccessDenied(e){const t=e,n=new CustomEvent(To,{detail:{container:e,wallType:t.dataset.wallType,contentId:t.dataset.contentId},bubbles:!0});document.dispatchEvent(n)}trackWallDisplay(e){console.log("Access wall displayed:",e)}async refreshAll(){const e=[];for(const[,t]of this.instances)"refresh"in t&&"function"==typeof t.refresh?e.push(t.refresh()):"initialize"in t&&"function"==typeof t.initialize&&e.push(t.initialize());await Promise.all(e)}getUserAccessState(){return this.userAccessState}async hasAccess(e){return!1}cleanup(){for(const[,e]of this.instances)"destroy"in e&&"function"==typeof e.destroy&&e.destroy();this.instances.clear(),this.isInitialized=!1}static hasAccessWalls(){return Lo.hasAccessWalls()}static async render(e,t={}){const n=new Io({autoScan:!1,...t});return await n.initialize(),await n.renderAccessWall(e,t)}}const ko={containerSelector:"HgAccessWallPromo"},Oo="accesswallpromo:login:clicked",Ro="accesswallpromo:subscribe:clicked";class Bo{constructor(e={}){this.options={containerSelector:ko.containerSelector,...e},this.containers=[]}static hasAccessWallPromos(){const e=ko.containerSelector||"HgAccessWallPromo";return document.querySelectorAll(e).length>0}async initialize(){const e=document.querySelectorAll(this.options.containerSelector);if(this.containers=Array.from(e),await w.default.load(),this.isCabotWealth=w.default.isCabotWealth(),0!==this.containers.length)for(const e of this.containers
1)this.render(e)}render(e){const t=e.dataset.accessWallUrl||"",n="true"===e.dataset.showLogin,o=e.dataset.loginTitle||"Login to Access Premium Content",i=e.dataset.moduleTitle||"Not a Premium Subscriber?",a=e.dataset.moduleDescription||"Subscribe for Full Access",s=[e.dataset.benefitOne,e.dataset.benefitTwo,e.dataset.benefitThree,e.dataset.benefitFour].filter((e=>e&&e.trim()));let r=oe.A.isAuthenticated();if(!r){r=document.cookie.split(";").map((e=>e.trim())).some((e=>e.startsWith("heimguard_auth=")||e.startsWith("heimguard.auth=")||e.startsWith("heimguard.authStatus=")))}let d='\n <div class="access-wall-promo-container max-w-2xl mx-auto my-[60px]">\n <div class="promo-card bg-white rounded-lg shadow-lg p-8 text-center">\n ';n&&!r&&(d+=`\n \x3c!-- Login Section --\x3e\n <div class="login-section mb-8 pb-8 border-b border-gray-200">\n <h2 class="text-2xl font-bold text-gray-900 mb-6">\n ${o}\n </h2>\n <button\n class="promo-login-button inline-flex items-center px-8 py-3 bg-primary-600 text-white text-base font-semibold rounded-md hover:bg-primary-700 hover:text-white transition-colors"\n data-login-trigger\n >\n ${this.isCabotWealth?"":P.A.render("log-in",{class:"w-5 h-5 mr-2"})}\n Login\n </button>\n </div>\n `),d+=`\n \x3c!-- Subscription Section --\x3e\n <div class="subscription-section">\n <h2 class="text-2xl font-bold text-gray-900 mb-2">\n ${i}\n </h2>\n <p class="text-lg text-gray-600 mb-8">\n ${a}\n </p>\n \n`,s.length>0&&(d+=`\n \x3c!-- Benefits Section --\x3e\n <div class="bg-gray-50 rounded-lg p-6 mb-8">\n <h3 class="text-lg font-semibold text-gray-900 mb-4">${this.isCabotWealth?"Included in Your Subscription":"What you'll get:"}</h3>\n <ul class="space-y-3 text-left max-w-md mx-auto">\n ${s.map((e=>`\n <li class="flex items-start">\n <svg class="w-5 h-5 text-green-500 mr-3 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />\n </svg>\n <span class="text-gray-700">${e}</span>\n </li>\n `)).join("")}\n </ul>\n </div>`),t&&(d+=`\n <a\n href="${t}"\n class="promo-subscribe-button inline-flex items-center px-8 py-3 bg-primary-600 text-white text-base font-semibold rounded-md hover:bg-primary-700 hover:text-white transition-colors mb-4"\n >\n ${this.isCabotWealth?"":P.A.render("dollar-sign",{class:"w-5 h-5 mr-2"})}\n ${this.isCabotWealth?"Choose Your Plan":"View Subscription Plans Now"}\n </a>\n \n \x3c!-- Security Note --\x3e\n <div class="flex items-center justify-center text-sm text-gray-500">\n <svg class="w-4 h-4 mr-2 text-green-600" fill="currentColor" viewBox="0 0 20 20">\n <path fill-rule="evenodd" d="M2.166 4.999A11.954 11.954 0 0010 1.944 11.954 11.954 0 0017.834 5c.11.65.166 1.32.166 2.001 0 5.225-3.34 9.67-8 11.317C5.34 16.67 2 12.225 2 7c0-.682.057-1.35.166-2.001zm11.541 3.708a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />\n </svg>\n <span>Secure payment ⢠Cancel anytime</span>\n </div>`),d+="\n </div>\n </div>\n </div>\n ",e.innerHTML=d,this.attachEventListeners(e)}attachEventListeners(e){const t=e.querySelector(".promo-login-button");t&&t.addEventListener("click",(()=>{const e=new URLSearchParams(window.location.search).get("returnUrl");window.dispatchEvent(new CustomEvent(Oo));const t=document.querySelector("[data-auth-modal]");t&&t.dispatchEvent(new CustomEvent("show",{detail:{mode:"login",returnUrl:e}}))}
1));const n=e.querySelector(".promo-subscribe-button");n&&n.addEventListener("click",(()=>{window.dispatchEvent(new CustomEvent(Ro))}))}}if("undefined"!=typeof window){const e=()=>{if(Bo.hasAccessWallPromos()){(new Bo).initialize()}};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",e):e()}var $o=n(9088);class Uo{constructor(){this.config=ho.getInstance()}getAuthorDisplayName(e){const t=e.authorName||e.name,n=e.authorEmail||e.email,o=e.inactiveAuthorName;return t&&t.trim()?t.trim():n&&n.trim()?n.trim():o&&o.trim()?o.trim():"Anonymous"}async getComments(e,t=1){try{const n=new URLSearchParams({contentId:e,pageNumber:t.toString(),pageSize:this.config.commentsPerPage.toString()}),o=await fetch(`${this.config.apiBase}/comments/get?${n}`,{method:"GET",credentials:"include",headers:{Accept:"application/json"}});if(!o.ok)throw new Error(`HTTP error! status: ${o.status}`);const i=await o.json();let a=[];i.comments&&(Array.isArray(i.comments)?a=i.comments:"object"==typeof i.comments&&(a=Object.values(i.comments)));const s=a.map((t=>({id:t.id,contentId:t.contentId||e,author:{id:t.authorId||t.userId||t.authorPublicId||t.author?.id||"",name:this.getAuthorDisplayName(t),email:t.authorEmail||t.email,inactiveAuthorName:t.inactiveAuthorName,avatarUrl:t.authorImageUrl||t.authorAvatarUrl||t.avatarUrl||t.authorAvatar||t.authorImgSrc},body:t.body||t.text||"",createDate:t.createdDate||t.createDate||(new Date).toISOString(),parent:t.parentId||t.parent||null,childrenCount:t.childrenCount||0,likeCount:t.likeCount||0,isLiked:!0===t.isLiked,children:[]}))),r=await Promise.all(s.map((async e=>{if(e.childrenCount>0){const t=await this.getChildComments(e.id);t.success&&t.data&&(e.children=t.data.comments)}return e}))),d=i.totalPages||1,l=i.currentPage||t;return{success:!0,data:{comments:r,totalPages:d,currentPage:l,totalComments:i.totalComments||0,hasMore:l<d}}}catch(e){return console.error("Failed to fetch comments:",e),{success:!1,error:e instanceof Error?e.message:"Failed to fetch comments"}}}async getChildComments(e){try{const t=new URLSearchParams({parentId:e}),n=await fetch(`${this.config.apiBase}/comments/get-children?${t}`,{method:"GET",credentials:"include",headers:{Accept:"application/json"}});if(!n.ok)throw new Error(`HTTP error! status: ${n.status}`);const o=await n.json();let i=[];o.comments&&(Array.isArray(o.comments)?i=o.comments:"object"==typeof o.comments&&(i=Object.values(o.comments)));const a=i.map((t=>({id:t.id,contentId:t.contentId||"",author:{id:t.authorId||t.userId||t.authorPublicId||t.author?.id||"",name:this.getAuthorDisplayName(t),email:t.authorEmail||t.email,inactiveAuthorName:t.inactiveAuthorName,avatarUrl:t.authorImageUrl||t.authorAvatarUrl||t.avatarUrl||t.authorAvatar||t.authorImgSrc},body:t.body||t.text||"",createDate:t.createdDate||t.createDate||(new Date).toISOString(),parent:e,childrenCount:t.childrenCount||0,likeCount:t.likeCount||0,isLiked:!0===t.isLiked,children:[]}))),s=await Promise.all(a.map((async e=>{if(e.childrenCount>0){const t=await this.getChildComments(e.id);t.success&&t.data&&(e.children=t.data.comments)}return e})));return{success:!0,data:{comments:s,totalPages:1,currentPage:1,totalComments:s.length,hasMore:!1}}}catch(e){return console.error("Failed to fetch child comments:",e),{success:!1,error:e instanceof Error?e.message:"Failed to fetch child comments"}}}async addComment(e){try{const t={contentId:e.contentId,commentBody:e.body,parentId:e.parent||null},n=await fetch(`${this.config.apiBase}/comments/add`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(t)});if(!n.ok){const e=await n.text();if(console.error("[CommentsAPI] Error response:",e),401===n.status)throw new Error("You must be logged in to comment");throw new Error(`HTTP error! status: ${n.status}, message: ${e}`)}const o=await n.json();return{success:!0,data:o.comment||o}}catch(e){return console.error("Failed to add comment:",e),{success:!1,error:e instanceof Error?e.message:"Failed to add comment"}}}async likeComment(e){try{const t=window.location.href,n=await fetch(`${this.config.apiBase}/like`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",Accept:"application/json"}
1,body:JSON.stringify({contentId:e,likeAction:"likeActionAdd",contentUrl:t})});if(!n.ok)throw new Error(`HTTP error! status: ${n.status}`);return{success:!0}}catch(e){return console.error("Failed to like comment:",e),{success:!1,error:e instanceof Error?e.message:"Failed to like comment"}}}async unlikeComment(e){try{const t=window.location.href,n=await fetch(`${this.config.apiBase}/like`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({contentId:e,likeAction:"likeActionRemove",contentUrl:t})});if(!n.ok)throw new Error(`HTTP error! status: ${n.status}`);return{success:!0}}catch(e){return console.error("Failed to unlike comment:",e),{success:!1,error:e instanceof Error?e.message:"Failed to unlike comment"}}}}class Fo{constructor(e,t){this.container=e,this.options=t}render(){const{comment:e,currentUser:t,showLikes:n,canReply:o,depth:i}=this.options,a=t?.id||t?.userId||t?.publicId,s=e.author.id;let r=t&&a&&s&&a===s;if(!r&&t){const n=t.name||`${t.firstName} ${t.lastName}`.trim();r=n&&n===e.author.name}const d=Fe.Nq.parse(e.createDate);let l=d;d&&d>new Date&&(l=new Date(d),l.setFullYear((new Date).getFullYear()));const c=l?Fe.Nq.formatRelative(l):"Unknown time",u=0===i;this.container.innerHTML=`\n <div class="comment">\n <div class="comment-header">\n <div class="comment-avatar">\n ${e.author.avatarUrl?`<img src="${e.author.avatarUrl}" alt="${e.author.name}">`:`<div class="avatar-placeholder">\n ${e.author.name?e.author.name.charAt(0).toUpperCase():"?"}\n </div>`}\n </div>\n \n <div class="comment-meta">\n <div class="comment-author-info">\n <span class="comment-author-name">${e.author.name}</span>\n ${r?'<span class="comment-author-badge">You</span>':""}\n </div>\n <div class="comment-time">${c}</div>\n </div>\n </div>\n \n <div class="comment-body">\n ${this.formatCommentBody(e.body)}\n </div>\n \n <div class="comment-actions">\n <div class="comment-action-buttons">\n ${n?this.renderLikeButton():""}\n ${o?this.renderReplyButton():""}\n </div>\n ${u&&this.getTotalReplyCount(e)>0?`<div class="comment-replies-count">${this.getTotalReplyCount(e)} ${1===this.getTotalReplyCount(e)?"reply":"replies"}</div>`:""}\n </div>\n </div>\n `,this.attachEventListeners()}formatCommentBody(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\n/g,"<br>").replace(/(https?:\/\/[^\s]+)/g,'<a href="$1" target="_blank" rel="noopener noreferrer" class="comment-link">$1</a>')}renderLikeButton(){const{comment:e}=this.options,t=e.isLiked||!1,n=e.likeCount||0;return`\n <button class="comment-like-btn ${t?"liked":""}" data-action="like">\n ${P.H.render("heart",{class:"w-4 h-4"})}\n <span>${n>0?n:"Like"}</span>\n </button>\n `}renderReplyButton(){return'\n <button class="comment-reply-btn" data-action="reply">\n <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" />\n </svg>\n <span>Reply</span>\n </button>\n '}attachEventListeners(){const e=this.container.querySelector('[data-action="like"]');e&&e.addEventListener("click",(e=>{e.preventDefault(),this.options.onLike()}));const t=this.container.querySelector('[data-action="reply"]');t&&t.addEventListener("click",(e=>{e.preventDefault(),this.options.onReply()}))}getTotalReplyCount(e){let t=0;return e.children&&e.children.length>0?(t+=e.children.length,e.children.forEach((e=>{t+=this.getTotalReplyCount(e)}))):e.childrenCount>0&&(t=e.childrenCount),t}destroy(){}}class zo{constructor(e){this.blockedWordsRegex=null,this.config=e,this.buildRegex()}buildRegex(){if(!this.config.enabled||!this.config.blockedWords?.length)return void(this.blockedWordsRegex=null);const e=this.config.blockedWords.map((e=>{const t=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/\\\*/g,"\\S*");return`(\\b${t}\\b|${t})`}));this.blockedWordsRegex=new RegExp(e.join("|"),"gi")}check(e){if(!this.config.enabled||!this.blockedWordsRegex)return{isClean:!0,foundWords:[]};const t=e.match(this.blockedWordsRegex);if(!t||0===t.length)return{isClean:!0,foundWords:[]};return{isClean:!1,foundWords:Array.from(new Set(t.map((e=>e.toLowerCase())))),message:this.config.warningMessage||"Your comment contains inappropriate language."}}clean(e){return this.config.enabled&&this.blockedWordsRegex?e.replace(this.blockedWordsRegex,(e=>"*".repeat(e.length))):e}updateConfig(e){this.config={...this.config,...e},this.buildRegex()}getConfig(){return{...this.config}}}class Ho{constructor(e,t){this.isSubmitting=!1,this.profanityFilter=null,this.config=ho.getInstance(),this.container=e,this.options=t,this.config.enableProfanityFilter&&this.config.blockedWords.length>0?this.profanityFilter=new zo({enabled:!0,blockedWords:this.config.blockedWords,warningMessage:this.config.profanityWarningMessage}):t.profanityFilter&&(this.profanityFilter=new zo(t.profanityFilter))}render(){const e=this.options.placeholder||(this.options.isReply?"Write a reply...":"Add a comment..."),t=!this.options.isReply&&this.options.currentUser;this.container.innerHTML=`\n <form class="comment-form ${this.options.isReply?"comment-form-reply":""}">\n <div class="comment-form-wrapper ${t?"comment-form-with-avatar":""}">\n ${t?`\n <div class="comment-form-top">\n <div class="comment-form-avatar">\n ${this.options.currentUser.avatarUrl?`\n <img \n src="${this.options.currentUser.avatarUrl}" \n alt="${this.options.currentUser.name}"\n class="comment-avatar-img"\n >\n `:`\n <div class="comment-avatar-placeholder">\n ${this.options.currentUser.name.charAt(0).toUpperCase()}\n </div>\n `}\n </div>\n \n <textarea \n class="comment-form-textarea" \n placeholder="${e}"\n rows="${this.options.isReply?3:4}"\n maxlength="${this.config.commentMaxLength}"\n ></textarea>\n </div>\n `:`\n <textarea \n class="comment-form-textarea" \n placeholder="${e}"\n rows="${this.options.isReply?3:4}"\n maxlength="${this.config.commentMaxLength}"\n ></textarea>\n `}\n \n \n <div class="comment-form-footer">\n <div class="comment-form-helpers">
1\n <span class="comment-char-count">\n <span class="current">0</span> / ${this.config.commentMaxLength}\n </span>\n </div>\n \n <div class="comment-form-actions">\n ${this.options.isReply&&this.options.onCancel?'\n <button type="button" class="comment-form-cancel">\n Cancel\n </button>\n ':""}\n <button type="submit" class="comment-form-submit" disabled>\n ${this.options.isReply?"Reply":"Post"}\n </button>\n </div>\n </div>\n </div>\n </form>\n `,this.attachEventListeners()}attachEventListeners(){const e=this.container.querySelector(".comment-form"),t=this.container.querySelector(".comment-form-textarea"),n=this.container.querySelector(".comment-form-submit"),o=this.container.querySelector(".comment-form-cancel"),i=this.container.querySelector(".comment-char-count .current");t.addEventListener("input",(()=>{const e=t.value,o=e.trim().length;i.textContent=o.toString();let a=!1;if(this.profanityFilter&&e){const t=this.profanityFilter.check(e);t.isClean||(a=!0,te.Alert.warning(t.message||"Your comment contains inappropriate language."))}n.disabled=0===o||this.isSubmitting||a;const s=t.offsetHeight;t.style.height="auto",t.style.height=Math.max(s,t.scrollHeight)+"px"})),e.addEventListener("submit",(async e=>{e.preventDefault();const o=t.value.trim();if(o&&!this.isSubmitting){this.isSubmitting=!0,n.disabled=!0,n.innerHTML='\n <span class="animate-spin inline-block w-4 h-4 border-2 border-white border-t-transparent rounded-full"></span>\n <span class="ml-2">Posting...</span>\n ';try{await this.options.onSubmit(o,this.options.parentId),t.value="",i.textContent="0",t.style.height="auto"}catch(e){console.error("Failed to submit comment:",e)}finally{this.isSubmitting=!1,n.disabled=0===t.value.trim().length,n.textContent=this.options.isReply?"Reply":"Post"}}})),o&&o.addEventListener("click",(()=>{this.options.onCancel&&this.options.onCancel()})),t.addEventListener("keydown",(t=>{"Enter"===t.key&&(t.metaKey||t.ctrlKey)&&(t.preventDefault(),e.dispatchEvent(new Event("submit"))),"Escape"===t.key&&this.options.isReply&&this.options.onCancel&&(t.preventDefault(),this.options.onCancel())}
1))}destroy(){}}class Go{constructor(e,t){this.commentItems=new Map,this.replyForms=new Map,this.container=e,this.options=t}render(){this.destroy();const e=this.buildCommentTree(this.options.comments);this.container.innerHTML=e.length>0?e.map((e=>this.renderComment(e,0))).join(""):'<p class="text-gray-500 text-center py-8">No comments yet. Be the first to comment!</p>',this.initializeCommentItems()}buildCommentTree(e){if(!Array.isArray(e))return console.warn("[CommentsList] Comments is not an array:",e),[];const t=e.filter((e=>!e.parent));return console.log("[CommentsList] Root comments:",t.length),console.log("[CommentsList] Total comments including nested:",this.countAllComments(e)),t}countAllComments(e){let t=e.length;return e.forEach((e=>{e.children&&e.children.length>0&&(t+=this.countAllComments(e.children))})),t}renderComment(e,t){const n=e.children&&e.children.length>0,o=this.options.allowNested&&t<this.options.maxDepth;return`\n <div class="comment-thread" data-comment-id="${e.id}" data-depth="${t}">\n <div class="comment-item-container"></div>\n ${o?'<div class="comment-reply-form-container hidden"></div>':""}\n ${n?`\n <div class="comment-replies ${t>=this.options.maxDepth?"max-depth":""}">\n ${e.children.map((e=>this.renderComment(e,t+1))).join("")}\n </div>\n `:""}\n </div>\n `}initializeCommentItems(){this.container.querySelectorAll(".comment-thread").forEach((e=>{const t=e.getAttribute("data-comment-id"),n=parseInt(e.getAttribute("data-depth")),o=this.findComment(t);if(!o)return;const i=e.querySelector(".comment-item-container");if(i){const e=new Fo(i,{comment:o,currentUser:this.options.currentUser,showLikes:this.options.showLikes,canReply:this.options.allowNested&&n<this.options.maxDepth,depth:n,onReply:()=>this.showReplyForm(t),onLike:()=>this.options.onLike(t,o.isLiked||!1)});e.render(),this.commentItems.set(t,e)}}))}findComment(e){const t=n=>{for(const o of n){if(o.id===e)return o;if(o.children&&o.children.length>0){const e=t(o.children);if(e)return e}}return null};return t(this.options.comments)}showReplyForm(e){const t=this.container.querySelector(`[data-comment-id="${e}"]`),n=t?.querySelector(".comment-reply-form-container");if(n&&(this.container.querySelectorAll(".comment-thread").forEach((e=>{e.classList.remove("replying")})),this.container.querySelectorAll(".comment-reply-form-container").forEach((e=>{e!==n&&e.classList.add("hidden")})),n.classList.toggle("hidden"),n.classList.contains("hidden")?t.classList.remove("replying"):t.classList.add("replying"),!this.replyForms.has(e)&&!n.classList.contains("hidden"))){const o=parseInt(t.getAttribute("data-depth")),i=this.findComment(e),a=new Ho(n,{contentId:"",parentId:e,placeholder:`Replying to ${i?.author.name||"comment"}...`,onSubmit:async o=>{window.HeimGuard?.commentsWidget&&await window.HeimGuard.commentsWidget.handleCommentSubmit(o,e),n.classList.add("hidden"),t.classList.remove("replying")},onCancel:()=>{n.classList.add("hidden"),t.classList.remove("replying")},maxDepth:o+1,isReply:!0});a.render(),this.replyForms.set(e,a),setTimeout((()=>{const e=n.querySelector("textarea");e&&e.focus()}),100)}}update(e){this.options.comments=e,this.render()}destroy(){this.commentItems.forEach((e=>e.destroy())),this.commentItems.clear(),this.replyForms.forEach((e=>e.destroy())),this.replyForms.clear()}}class _o extends Le.${constructor(e,t){super(e,{autoInit:!1}),this.config=ho.getInstance(),this.api=new Uo,this.commentsList=null,this.commentForm=null,this.initialized=!1,this.commentsStore=new $o.A({comments:[],isLoading:!0,error:null,currentPage:1,totalPages:1,totalComments:0,hasMore:!1,isAuthenticated:!1,currentUser:null,commentsRevealed:!1}),this.widgetOptions={apiBase:"/api/heimguard",commentsPerPage:10,...t},this.widgetOptions.apiBase&&this.config.setConfig({apiBase:this.widgetOptions.apiBase}),this.widgetOptions.commentsPerPage&&this.config.setConfig({commentsPerPage:this.widgetOptions.commentsPerPage}),this.commentsStore.subscribe((()=>{this.initialized&&this.updateCommentsList()}))}
1async init(){if(!this.initialized){this.initialized=!0;try{if(await this.config.loadFromServer(),!this.config.enableComments)return console.log("Comments are disabled"),void(this.container.style.display="none");await this.checkAuthentication(),await this.render(),this.config.hideCommentsBehindButton||await this.loadComments(),this.widgetOptions.onReady&&this.widgetOptions.onReady()}catch(e){console.error("Failed to initialize comments widget:",e),this.commentsStore.setState({isLoading:!1,error:"Failed to initialize comments"}),this.widgetOptions.onError&&this.widgetOptions.onError(e)}}}getUserDisplayName(e){const t=e.name||e.fullName;if(t&&t.trim())return t.trim();const n=`${e.firstName||""} ${e.lastName||""}`.trim();if(n)return n;const o=e.email;return o&&o.trim()?o.trim():"Anonymous"}async checkAuthentication(){try{const e=await fetch(`${this.config.apiBase}/profile/get-profile`,{credentials:"include"});if(e.ok){const t=await e.json();let n=null,o=!1;t.email||t.firstName||t.lastName||t.profileCreationDate?(n=t,o=!0):t.success&&t.data&&(t.data.profile?(n=t.data.profile,o=!0):(t.data.email||t.data.id||t.data.userId)&&(n=t.data,o=!0));const i=n?{id:n.id||n.userId||n.publicId||"",name:this.getUserDisplayName(n),email:n.email||"",avatarUrl:n.avatarImgSrc||n.avatarUrl||n.profilePicture||n.profileImageUrl||n.avatar||n.photoUrl||""}:null;this.commentsStore.setState({isAuthenticated:o,currentUser:i})}}catch(e){console.warn("Failed to check authentication:",e)}}async loadComments(e=1){this.commentsStore.setState({isLoading:!0,error:null});const t=await this.api.getComments(this.widgetOptions.contentId,e);if(t.success&&t.data)console.log("[CommentsWidget] Pagination debug:",{currentPage:t.data.currentPage,totalPages:t.data.totalPages,totalComments:t.data.totalComments,hasMore:t.data.hasMore,commentsLoaded:t.data.comments.length}),this.commentsStore.setState({comments:1===e?t.data.comments:[...this.commentsStore.getState().comments,...t.data.comments],currentPage:t.data.currentPage,totalPages:t.data.totalPages,totalComments:t.data.totalComments,hasMore:t.data.hasMore,isLoading:!1});else{const e=t.error?.includes("401")||t.error?.includes("Unauthorized");this.commentsStore.setState({isLoading:!1,error:e?null:t.error||"Failed to load comments"})}}async render(){const e=this.commentsStore.getState();if(this.config.hideCommentsBehindButton&&!e.commentsRevealed){this.container.innerHTML=`\n <div class="comments-widget" data-content-id="${this.widgetOptions.contentId}">\n <div class="comments-reveal-container">\n <button class="comments-reveal-btn" type="button">\n <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />\n </svg>\n <span>View Comments</span>\n </button>\n </div>\n </div>\n `;const e=this.container.querySelector(".comments-reveal-btn");return void(e&&e.addEventListener("click",(async()=>{this.commentsStore.setState({commentsRevealed:!0}),await this.render(),await this.loadComments()})))}const t=this.container.querySelector(".moderation-notices-container"),n=t?t.innerHTML:"";this.container.innerHTML=`\n <div class="comments-widget" data-content-id="${this.widgetOptions.contentId}">\n <div class="comments-header">\n <h3 class="comments-title">\n <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />\n </svg>\n <span class="comments-count">Comments${e.totalComments>0?` (${e.totalComments})`:e.comments.length>0?` (${e.comments.length})`:""}</span>\n </h3>\n </div>
1\n\n ${this.renderCommentForm()}\n\n <div class="moderation-notices-container">${n}</div>\n\n <div class="comments-list-container">\n ${e.error?this.renderError():""}\n ${e.isLoading&&0===e.comments.length?this.renderLoading():""}\n <div class="comments-list"></div>\n </div>\n\n ${(()=>(console.log("[CommentsWidget] Render decision:",{hasMore:e.hasMore,currentPage:e.currentPage,totalPages:e.totalPages,willShowLoadMore:e.hasMore}),e.hasMore?this.renderLoadMore():""))()}\n </div>\n `,this.initializeComponents(),this.attachEventListeners()}renderCommentForm(){return this.commentsStore.getState().isAuthenticated?'<div class="comment-form-container"></div>':'\n <div class="comments-login-prompt">\n <div class="login-prompt-content">\n <svg class="login-prompt-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />\n </svg>\n <h3>Join the conversation</h3>\n <p>Please <a href="#" data-login-trigger class="login-link">log in</a> to leave a comment.</p>\n </div>\n </div>\n '}renderLoading(){return'\n <div class="comments-loading">\n <div class="animate-pulse">\n <div class="loading-comment">\n <div class="loading-comment-content">\n <div class="loading-avatar"></div>\n <div class="loading-text">\n <div class="loading-line w-1/4 mb-2"></div>\n <div class="loading-line w-3/4"></div>\n </div>\n </div>\n </div>\n <div class="loading-comment mt-4">\n <div class="loading-comment-content">\n <div class="loading-avatar"></div>\n <div class="loading-text">\n <div class="loading-line w-1/3 mb-2"></div>\n <div class="loading-line w-2/3"></div>\n </div>\n </div>\n </div>\n </div>\n </div>\n '}renderError(){return`\n <div class="comments-error">\n <p class="text-red-600">${this.commentsStore.getState().error}</p>\n <button class="retry-btn text-primary-600 hover:text-primary-700 font-medium mt-2">\n Try Again\n </button>\n </div>\n `}renderLoadMore(){const e=this.commentsStore.getState(),t=e.totalComments-e.comments.length;return`\n <div class="comments-load-more">\n <button class="load-more-btn" data-loading="false">\n <span class="load-more-content">\n <svg class="load-more-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"/>\n </svg>\n <span class="load-more-text">\n Load More Comments${t>0?` (${t} remaining)`:""}\n </span>\n </span>\n <span class="load-more-spinner hidden">\n <svg class="animate-spin" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>\n </svg>\n <span>Loading...</span>\n </span>\n </button>\n </div>\n `}initializeComponents(){const e=this.commentsStore.getState(),t=this.container.querySelector(".comment-form-container");t&&(e.isAuthenticated||this.config.allowAnonymousComments)&&(this.commentForm=new Ho(t,{contentId:this.widgetOptions.contentId,onSubmit:this.handleCommentSubmit.bind(this),maxDepth:0,currentUser:e.currentUser}),this.commentForm.render());const n=this.container.querySelector(".comments-list");n&&(this.commentsList=new Go(n,{comments:e.comments,currentUser:e.currentUser,showLikes:this.config.showCommentLikes,allowNested:this.config.allowNestedComments,maxDepth:this.config.maxCommentDepth,onReply:this.handleReply.bind(this),onLike:this.handleLike.bind(this)}),this.commentsList.render())}attachEventListeners(){const e=this.container.querySelector(".retry-btn");e&&e.addEventListener("click",(()=>this.loadComments()));const t=this.container.querySelector(".load-more-btn");t&&t.addEventListener("click",(()=>{this.handleLoadMore()}));const n=this.container.querySelector("[data-login-trigger]");n&&n.addEventListener("click",(e=>{e.preventDefault(),window.HeimGuard?.authSystem&&window.HeimGuard.authSystem.showLogin()}))}async handleCommentSubmit(e,t){const n=await this.api.addComment({contentId:this.widgetOptions.contentId,body:e,parent:t});if(n.success){const o=n.data;if(o?.requiresModeration||!1||!(!1!==o?.isPublished)){const n=`moderation-${Date.now()}-${t||"root"}`;await this.loadComments(),setTimeout((()=>{this.showPersistentModerationFeedback(t,n,e)}),100)}else{await this.loadComments();const e=o?.commentId;e&&setTimeout((()=>{const t=this.container.querySelector(`[data-comment-id="${e}"]`);t&&(t.classList.add("highlight-new"),setTimeout((()=>t.classList.remove("highlight-new")),3e3))}),100),te.Alert.success("Your comment has been posted successfully!")}this.updateCommentCount()}else te.Alert.error(n.error||"Failed to add comment")}showPersistentModerationFeedback(e,t,n){console.log("Showing persistent moderation feedback for parentId:",e);const o=t||`moderation-${Date.now()}-${e||"root"}`;if(document.getElementById(o))return;const i=this.commentsStore.getState().currentUser,a=i?.name||"Anonymous",s=(new Date).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"2-digit",minute:"2-digit"}),r=e=>{const t=document.createElement("div");return t.textContent=e,t.innerHTML},d=`\n <div id="${o}" class="moderation-comment-wrapper mb-4">\n \x3c!-- Comment preview and moderation notice in single blue box --\x3e\n <div class="bg-blue-50 border border-blue-200 rounded-lg p-4">\n <div class="flex items-start">\n ${i?.avatarUrl?`\n <img src="${i.avatarUrl}" alt="${a}" class="w-10 h-10 rounded-full mr-3">\n `:`\n <div class="w-10 h-10 rounded-full bg-gradient-to-br from-primary-400 to-primary-600 flex items-center justify-center text-white font-semibold mr-3">\n ${a.charAt(0).toUpperCase()}\n </div>\n `}\n <div class="flex-1">\n <div class="flex items-baseline space-x-2 mb-2">
1\n <span class="text-sm font-semibold text-gray-900">${r(a)}</span>\n <span class="text-xs text-gray-500">${s}</span>\n </div>\n <div class="text-sm text-gray-700 mb-3">\n ${n?r(n):"Your comment"}\n </div>\n \x3c!-- Moderation notice inside the box --\x3e\n <div class="text-sm text-gray-600 italic">\n Thanks! Your comment has been submitted for approval. Comments will be published after moderation by an editor. \n No abusive material, personal attacks, profanity, spam or material of a similar nature will be considered for publication. \n Please bear with us if it doesn't appear straight away.\n </div>\n </div>\n <button class="flex-shrink-0 ml-3 text-blue-400 hover:text-blue-600" onclick="document.getElementById('${o}').remove()">\n <svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n `;if(e){const t=this.container.querySelector(`.comment-thread[data-comment-id="${e}"]`);if(t){let e=t.querySelector(".comment-replies");const n=t.querySelector(".comment-reply-form-container");if(!e){const o=n||t.querySelector(".comment-item-wrapper");if(o){const n='<div class="comment-replies pl-12 mt-6 space-y-4"></div>';o.insertAdjacentHTML("afterend",n),e=t.querySelector(".comment-replies")}}if(e)e.insertAdjacentHTML("afterbegin",d);else{const e=t.querySelector(".comment-item-wrapper");e&&e.insertAdjacentHTML("afterend",d)}}else{const t=this.container.querySelector(`[data-comment-id="${e}"]`);t?t.insertAdjacentHTML("afterend",`<div class="pl-12 mt-4">${d}</div>`):this.showInGeneralContainer(d)}}else this.showInGeneralContainer(d)}showInGeneralContainer(e){let t=this.container.querySelector(".moderation-notices-container");t&&t.insertAdjacentHTML("beforeend",e)}showModerationFeedback(e){console.log("Showing moderation feedback for parentId:",e);const t='\n <div class="moderation-notice bg-blue-50 border border-blue-200 rounded-lg p-4 mb-4 animate-fade-in">\n <div class="flex items-start">\n <div class="flex-shrink-0">\n <svg class="h-5 w-5 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n </div>\n <div class="ml-3 flex-1">\n <h3 class="text-sm font-medium text-blue-800">\n Your comment is being reviewed\n </h3>\n <p class="mt-1 text-sm text-blue-700">\n Thank you for your comment! It has been submitted and will appear once it has been approved by our moderation team.\n </p>\n </div>\n <button class="flex-shrink-0 ml-3 text-blue-400 hover:text-blue-600" onclick="this.closest(\'.moderation-notice\').remove()">\n <svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />\n </svg>\n </button>\n </div>\n </div>\n ';if(e){console.log("Looking for parent comment thread for parentId:",e);const n=this.container.querySelector(`.comment-thread[data-comment-id="${e}"]`);if(n){console.log("Found parent thread");const e=n.querySelector(".comment-reply-form-container");if(e)console.log("Found reply form container, inserting notice as sibling"),e.insertAdjacentHTML("afterend",t);else{let e=n.querySelector(".comment-replies");if(!e){console.log("Creating replies container for notice");const t=n.querySelector(".comment-item-wrapper");t&&(t.insertAdjacentHTML("afterend",'<div class="comment-replies pl-12 mt-6 space-y-4"></div>'),e=n.querySelector(".comment-replies"))}if(e)console.log("Inserting notice in replies container"),e.insertAdjacentHTML("afterbegin",t);else{const e=n.querySelector(".comment-item-wrapper");e&&e.insertAdjacentHTML("afterend",t)}}}else{console.log("Thread not found, looking by data-comment-id");const n=this.container.querySelector(`[data-comment-id="${e}"]`);if(n){console.log("Found parent element by data-comment-id");const e=n.querySelector(".comment-reply-form-container");if(e)e.insertAdjacentHTML("afterend",t);else{const e=n.querySelector(".comment-actions");e?e.insertAdjacentHTML("afterend",t):n.insertAdjacentHTML("beforeend",t)}}else{console.log("No parent element found, showing at top of list");const e=this.container.querySelector(".comments-list");e&&e.insertAdjacentHTML("afterbegin",t)}}}else{const e=this.container.querySelector(".comment-form-container");if(e){const n=e.nextElementSibling?.classList.contains("moderation-notice");n||e.insertAdjacentHTML("afterend",t)}}te.Alert.flash({message:"Your comment has been submitted for moderation",variant:"info",duration:3e3})}handleReply(e){}async handleLike(e,t){if((t?await this.api.unlikeComment(e):await this.api.likeComment(e)).success){const n=this.commentsStore.getState().comments,o=n=>n.map((n=>n.id===e?{...n,isLiked:!t,likeCount:(n.likeCount||0)+(t?-1:1)}:n.children?{...n,children:o(n.children)}:n));this.commentsStore.setState({comments:o(n)})}}updateCommentCount(){const e=this.commentsStore.getState(),t=this.container.querySelector(".comments-count");if(t){const n=e.totalComments||e.comments.length,o=this.config.hideCommentsBehindButton?"Vie
1w Comments":"Comments";t.textContent=`${o}${n>0?` (${n})`:""}`}}updateCommentsList(){const e=this.commentsStore.getState();this.updateCommentCount();const t=this.container.querySelector(".comments-loading");t&&!e.isLoading&&t.remove();const n=this.container.querySelector(".comments-error");if(e.error&&!n){const e=this.container.querySelector(".comments-list-container");if(e){const t=this.renderError();e.insertAdjacentHTML("afterbegin",t)}}else!e.error&&n&&n.remove();if(this.commentsList&&!e.isLoading){const t=Array.isArray(e.comments)?e.comments:[];this.commentsList.update(t)}this.updateLoadMoreButton()}updateLoadMoreButton(){const e=this.commentsStore.getState(),t=this.container.querySelector(".comments-load-more"),n=this.container.querySelector(".comments-widget");if(console.log("[CommentsWidget] updateLoadMoreButton:",{hasMore:e.hasMore,currentPage:e.currentPage,totalPages:e.totalPages,existingLoadMore:!!t}),e.hasMore&&!t&&n){const e=this.renderLoadMore();n.insertAdjacentHTML("beforeend",e);const t=this.container.querySelector(".load-more-btn");t&&t.addEventListener("click",(()=>{this.handleLoadMore()}))}else!e.hasMore&&t&&t.remove()}async handleLoadMore(){const e=this.commentsStore.getState();if(this.container.querySelector(".load-more-btn")&&!e.isLoading){this.setLoadMoreLoading(!0);try{await this.loadComments(e.currentPage+1)}catch(e){console.error("Failed to load more comments:",e),te.Alert.error("Failed to load more comments")}finally{this.setLoadMoreLoading(!1)}}}setLoadMoreLoading(e){const t=this.container.querySelector(".load-more-btn");if(!t)return;const n=t.querySelector(".load-more-content"),o=t.querySelector(".load-more-spinner");e?(t.setAttribute("data-loading","true"),t.disabled=!0,n?.classList.add("hidden"),o?.classList.remove("hidden")):(t.setAttribute("data-loading","false"),t.disabled=!1,n?.classList.remove("hidden"),o?.classList.add("hidden"))}destroy(){this.commentsList?.destroy(),this.commentForm?.destroy(),super.destroy()}}var Ko=n(3541),jo={};jo.styleTagTransform=m(),jo.setAttributes=d(),jo.insert=s().bind(null,"head"),jo.domAPI=i(),jo.insertStyleElement=c();t()(Ko.A,jo),Ko.A&&Ko.A.locals&&Ko.A.locals;function Vo(e){const t="string"==typeof e.container?document.querySelector(e.container):e.container;if(!t)throw new Error("Comments container not found");const n=new _o(t,e);return n.init(),n}"undefined"!=typeof window&&(window.HeimGuard=window.HeimGuard||{},window.HeimGuard.initCommentsWidget=Vo,window.HeimGuard.CommentsWidget=_o);class qo{constructor(){this.initialized=!1,this.config=ho.getInstance(),this.MODULE_TAG="HgCommentingModule"}static getInstance(){return qo.instance||(qo.instance=new qo),qo.instance}async init(){if(!this.initialized){this.initialized=!0;try{if(await this.config.loadFromServer(),!this.config.enableComments)return b.vF.debug("Comments are disabled in CMS settings","general"),void this.hideAllModules();b.vF.debug("Comments are enabled, scanning for modules...","general"),await this.scanAndRenderModules()}catch(e){b.vF.error("Failed to initialize:","general",e)}}}async scanAndRenderModules(){const e=document.querySelectorAll(this.MODULE_TAG);b.vF.debug(`Found ${e.length} comment module(s)`,"general");for(const t of e)await this.renderModule(t)}async renderModule(e){try{const t=this.getContentId(e);if(!t)return b.vF.warn("No content ID found for module","general",e),void(e.style.display="none");e.innerHTML=this.getLoadingHTML();const n=document.createElement("div");n.className="hg-commenting-module",n.setAttribute("data-content-id",t),e.replaceWith(n);const o=Vo({contentId:t,container:n,onReady:()=>{b.vF.debug(`Widget initialized for content ${t}`,"general")},onError:e=>{b.vF.error(`Widget error for content ${t}:`,"general",e),n.innerHTML=this.getErrorHTML()}});window.HeimGuard=window.HeimGuard||{},window.HeimGuard.commentsWidget=o}catch(t){b.vF.error("Failed to render module:","general",t),e.innerHTML=this.getErrorHTML()}}getContentId(e){const t=e.getAttribute("data-content-id");if(t)return t;const n=document.querySelector('meta[name="brightspot.contentId"]')?.getAttribute("content");
1if(n)return n;const o=document.querySelector('meta[name="content-id"]')?.getAttribute("content");if(o)return o;const i=document.body.getAttribute("data-content-id");if(i)return i;const a=window.location.pathname.match(/\/content\/([a-f0-9-]+)/);if(a)return a[1];const s=document.querySelector('script[type="application/ld+json"]');if(s)try{const e=JSON.parse(s.textContent||"{}");if(e["@id"]||e.identifier)return e["@id"]||e.identifier}catch(e){}return null}getLoadingHTML(){return'\n <div class="hg-commenting-module-loading p-8 text-center">\n <div class="inline-flex items-center space-x-2 text-gray-500">\n <div class="animate-spin rounded-full h-5 w-5 border-2 border-gray-300 border-t-primary-600"></div>\n <span>Loading comments...</span>\n </div>\n </div>\n '}getErrorHTML(){return'\n <div class="hg-commenting-module-error p-8 text-center text-red-600">\n <p>Unable to load comments. Please try refreshing the page.</p>\n </div>\n '}hideAllModules(){document.querySelectorAll(this.MODULE_TAG).forEach((e=>{e.style.display="none"}))}}const Wo=qo.getInstance();class Zo{constructor(){this.initialized=!1}static getInstance(){return Zo.instance||(Zo.instance=new Zo),Zo.instance}async init(){if(!this.initialized){this.initialized=!0;try{await Wo.init()}catch(e){console.error("[CommentsWidgetLoader] Failed to initialize:",e)}}}}C.then((()=>{Zo.getInstance().init()}));Zo.getInstance();class Yo{constructor(e={}){this.config={initUrl:e.initUrl||f.A.apiHeimguardSettingsUrl,notificationsUrl:e.notificationsUrl||f.A.apiNotificationsUrl}}async fetchNotifications(){try{const e=await v.default.getInitData();return e.notifications||[]}catch(e){return b.vF.error("Error checking for notifications:","api",e),ie.Ak.logError("BannerAPI.fetchNotifications",e),[]}}async fetchBanner(e){try{const t=await fetch(`${this.config.notificationsUrl}?shortCode=${e}`,{method:"GET",headers:{Accept:"application/json","Content-Type":"application/json"},credentials:"include"});if(!t.ok){if(404===t.status)return null;throw new Error(`HTTP error! status: ${t.status}`)}const n=await t.json();return this.processBannerData(n)}catch(t){return b.vF.error("Error fetching banner:","api",t),ie.Ak.logError("BannerAPI.fetchBanner",t,{shortCode:e,url:this.config.notificationsUrl}),null}}processBannerData(e){const t=e.position||e.placement||"Top Right";return{id:e.id||e.shortCode||"",shortCode:e.shortCode,title:e.name||e.title||"",content:e.description||e.content||"",placement:t,backgroundColor:e.backgroundColor||"#ffffff",textColor:e.textColor||"#000000",buttonText:e.buttonTitle||e.buttonText||"",buttonUrl:e.buttonLink||e.buttonUrl||"",buttonColor:e.buttonColor||"#4f46e5",buttonTextColor:e.buttonTextColor||"#ffffff",imageUrl:e.image||e.imageUrl||"",icon:e.icon||"",delay:1e3*(e.delayInSeconds||e.delay||0),duration:e.duration?1e3*e.duration:null,showCloseButton:!1!==e.showCloseButton,isActive:!1!==e.isActive,overlay:!0,width:e.width||(this.isModalPlacement(t)?"500px":"400px"),height:e.height||"auto",cssOverride:e.cssOverride||"",minPageViews:e.minPageViews||0,targets:e.targets||"",showOnPageLoad:e.showOnPageLoad||!1,showOnExitIntent:e.showOnExitIntent||!1,scrollDepthPercent:e.scrollDepthPercent||void 0}}isModalPlacement(e){return"Centered"===e||"Center"===e||"Modal"===e}}new Yo;class Jo{static canShowNotification(e){const t=this.getFrequencyData();if(t.dismissedNotifications.has(e))return!1;if(t.notificationCount>=this.MAX_NOTIFICATIONS_PER_SESSION)return!1;return!(Date.now()-t.lastShownTimestamp<this.MIN_TIME_BETWEEN_NOTIFICATIONS)}static recordNotificationShown(e){const t=this.getFrequencyData();t.notificationCount+=1,t.lastShownTimestamp=Date.now(),this.saveFrequencyData(t)}static recordNotificationDismissed(e){const t=this.getFrequencyData();t.dismissedNotifications.add(e),this.saveFrequencyData(t)}static getFrequencyData(){try{const e=sessionStorage.getItem(this.SESSION_STORAGE_KEY);if(e){const t=JSON.parse(e);return{notificationCount:t.notificationCount||0,lastShownTimestamp:t.lastShownTimestamp||0,dismissedNotifications:new Set(t.dismissedNotifications||[])}}}catch(e){}return{notificationCount:0,lastShownTimestamp:0,dismissedNotifications:new Set}}static saveFrequencyData(e){try{const t={notificationCount:e.notificationCount,lastShownTimestamp:e.lastShownTimestamp,dismissedNotifications:Array.from(e.dismissedNotifications)};sessionStorage.setItem(this.SESSION_STORAGE_KEY,JSON.stringify(t))}catch(e){}}static getTimeUntilNextAllowed(){const e=this.getFrequencyData(),t=Date.now()-e.lastShownTimestamp,n=this.MIN_TIME_BETWEEN_NOTIFICATIONS-t;return Math.max(0,Math.ceil(n/1e3))}static isSessionLimitReached(){return this.getFrequencyData().notificationCount>=this.MAX_NOTIFICATIONS_PER_SESSION}static resetFrequencyData(){sessionStorage.removeItem(this.SESSION_STORAGE_KEY)}}Jo.SESSION_STORAGE_KEY="heimguard_notification_frequency",Jo.MAX_NOTIFICATIONS_PER_SESSION=3,Jo.MIN_TIME_BETWEEN_NOTIFICATIONS=6e4;class Qo{constructor(){this.activeBanners=new Map,this.closedBanners=new Set,this.storagePrefix="banner_closed_"}isClosed(e){if(this.closedBanners.has(e))return!0;return"true"===sessionStorage.getItem(`${this.storagePrefix}${e}
1`)&&(this.closedBanners.add(e),!0)}markClosed(e){sessionStorage.setItem(`${this.storagePrefix}${e}`,"true"),this.closedBanners.add(e)}addBanner(e,t){this.activeBanners.set(e,t)}removeBanner(e){this.activeBanners.delete(e)}getBanner(e){return this.activeBanners.get(e)}getAllBanners(){return Array.from(this.activeBanners.values())}isActive(e){return this.activeBanners.has(e)}clearClosedBanners(){Object.keys(sessionStorage).forEach((e=>{e.startsWith(this.storagePrefix)&&sessionStorage.removeItem(e)})),this.closedBanners.clear()}getActiveBannerCount(){return this.activeBanners.size}destroy(){this.activeBanners.clear(),this.closedBanners.clear()}}const Xo=700,ei=500,ti="cubic-bezier(0.34, 1.56, 0.64, 1)",ni="banner-slide-down",oi="banner-toast-slide-down",ii="banner-toast-slide-up",ai="banner-modal",si="banner-slide-right",ri="banner-slide-left",di="banner-slide-top",li="banner-slide-bottom";class ci{constructor(){this.animationDuration=Xo/1e3+"s",this.animationEasing=ti,this.modalAnimationDuration=ei/1e3+"s"}generateStyles(e){return`\n ${this.getKeyframes()}\n ${this.getAnimationRules()}\n ${e.cssOverride||""}\n `}getKeyframes(){return"\n @keyframes slideInRight {\n from {\n transform: translateX(120%);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n }\n\n @keyframes slideInLeft {\n from {\n transform: translateX(-120%);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n }\n\n @keyframes slideInTop {\n from {\n transform: translateY(-120%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n }\n\n @keyframes slideInBottom {\n from {\n transform: translateY(120%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n }\n\n @keyframes fadeInScale {\n from {\n opacity: 0;\n transform: scale(0.9);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n }\n\n @keyframes slideOutRight {\n from {\n transform: translateX(0);\n opacity: 1;\n }\n to {\n transform: translateX(120%);\n opacity: 0;\n }\n }\n\n @keyframes slideOutLeft {\n from {\n transform: translateX(0);\n opacity: 1;\n }\n to {\n transform: translateX(-120%);\n opacity: 0;\n }\n }\n\n @keyframes slideOutTop {\n from {\n transform: translateY(0);\n opacity: 1;\n }\n to {\n transform: translateY(-120%);\n opacity: 0;\n }\n }\n\n @keyframes slideOutBottom {\n from {\n transform: translateY(0);\n opacity: 1;\n }\n to {\n transform: translateY(120%);\n opacity: 0;\n }\n }\n\n @keyframes fadeOutScale {\n from {\n opacity: 1;\n transform: scale(1);\n }\n to {\n opacity: 0;\n transform: scale(0.95);\n }\n }\n "}getAnimationRules(){return`\n .banner-slide-right.banner-show {\n animation: slideInRight ${this.animationDuration} ${this.animationEasing} forwards;\n }\n\n .banner-slide-left.banner-show {\n animation: slideInLeft ${this.animationDuration} ${this.animationEasing} forwards;\n }\n\n .banner-slide-top.banner-show {\n animation: slideInTop ${this.animationDuration} ${this.animationEasing} forwards;\n }\n\n .banner-slide-bottom.banner-show {\n animation: slideInBottom ${this.animationDuration} ${this.animationEasing} forwards;\n }\n\n .banner-modal.banner-show {\n animation: fadeInScale ${this.modalAnimationDuration} ${this.animationEasing} forwards;\n }\n\n .banner-slide-right.banner-hide {\n animation: slideOutRight 0.5s ease-in forwards;\n }\n\n .banner-slide-left.banner-hide {\n animation: slideOutLeft 0.5s ease-in forwards;\n }\n\n .banner-slide-top.banner-hide {\n animation: slideOutTop 0.5s ease-in forwards;\n }\n\n .banner-slide-bottom.banner-hide {\n animation: slideOutBottom 0.5s ease-in forwards;\n }\n\n .banner-modal.banner-hide {\n animation: fadeOutScale 0.3s ease-in forwards;\n }\n\n .heimguard-banner-overlay {\n transition: opacity 0.3s ease-in-out;\n }\n\n .heimguard-banner {\n will-change: transform, opacity;\n }\n `}createStyleElement(e){const t=document.createElement("style");return t.textContent=e,t}}const ui="Top Left",mi="Top",gi="Top Right",hi="Centered",pi="Bottom Left",yi="Bottom",Ci="Bottom Right",fi="Slide Right",vi="Slide Left",bi="Slide Top",wi="Slide Bottom",Si="Center",xi="Modal",Ai={[ui]:{wrapper:"fixed top-4 left-4",container:"w-96 max-w-md bg-white shadow-2xl transition-all duration-500 ease-out rounded-xl overflow-hidden banner-toast-slide-down"},[mi]:{wrapper:"fixed top-4 left-1/2 transform -translate-x-1/2",container:"w-96 max-w-md bg-white shadow-2xl transition-all duration-500 ease-out rounded-xl overflow-hidden banner-toast-slide-down"},[gi]:{wrapper:"fixed top-4 right-4",container:"w-96 max-w-md bg-white shadow-2xl transition-all duration-500 ease-out rounded-xl overflow-hidden banner-toast-slide-down"},[hi]:{wrapper:"fixed inset-0 z-50 flex items-center justify-center",container:"relative z-50 rounded-xl shadow-2xl transition-all duration-700 ease-out max-w-lg mx-4 overflow-hidden banner-modal"},[pi]:{wrapper:"fixed bottom-4 left-4",container:"w-96 max-w-md bg-white shadow-2xl transition-all duration-500 ease-out rounded-xl overflow-hidden banner-toast-slide-up"}
1,[yi]:{wrapper:"fixed bottom-4 left-1/2 transform -translate-x-1/2",container:"w-96 max-w-md bg-white shadow-2xl transition-all duration-500 ease-out rounded-xl overflow-hidden banner-toast-slide-up"},[Ci]:{wrapper:"fixed bottom-4 right-4",container:"w-96 max-w-md bg-white shadow-2xl transition-all duration-500 ease-out rounded-xl overflow-hidden banner-toast-slide-up"},[fi]:{wrapper:"fixed right-5 top-5 bottom-5 z-50",container:"h-full shadow-2xl transition-all duration-700 ease-out rounded-xl overflow-hidden banner-slide-right"},[vi]:{wrapper:"fixed left-5 top-5 bottom-5 z-50",container:"h-full shadow-2xl transition-all duration-700 ease-out rounded-xl overflow-hidden banner-slide-left"},[bi]:{wrapper:"fixed top-5 left-5 right-5 z-50",container:"w-full shadow-2xl transition-all duration-700 ease-out rounded-xl overflow-hidden banner-slide-top"},[wi]:{wrapper:"fixed bottom-5 left-5 right-5 z-50",container:"w-full shadow-2xl transition-all duration-700 ease-out rounded-xl overflow-hidden banner-slide-bottom"},[Si]:{wrapper:"fixed inset-0 z-50 flex items-center justify-center",container:"relative z-50 rounded-xl shadow-2xl transition-all duration-700 ease-out max-w-lg mx-4 overflow-hidden banner-modal"},[xi]:{wrapper:"fixed inset-0 z-50 flex items-center justify-center",container:"relative z-50 rounded-xl shadow-2xl transition-all duration-700 ease-out max-w-lg mx-4 overflow-hidden banner-modal"}},Ti=e=>e===hi||e===Si||e===xi;class Mi{constructor(){this.styles=new ci}createElement(e){const t=this.createWrapper(e),n=this.styles.createStyleElement(this.styles.generateStyles(e)),o=this.createOverlay(e),i=this.createContainer(e);if(t.appendChild(n),o){["Top Left","Top","Top Right","Bottom Left","Bottom","Bottom Right"].includes(e.placement)?(o.id="heimguard-overlay-"+e.id,o.setAttribute("data-banner-id",e.id),document.body.appendChild(o),t.setAttribute("data-overlay-id","heimguard-overlay-"+e.id)):t.appendChild(o)}return t.appendChild(i),t}createWrapper(e){const t=document.createElement("div");t.className="heimguard-banner-wrapper",t.setAttribute("data-banner-id",e.id),t.setAttribute("data-placement",e.placement);const n=this.getPlacementClasses(e.placement);t.className+=` ${n.wrapper}`;return["Top Left","Top","Top Right","Bottom Left","Bottom","Bottom Right"].includes(e.placement)&&(t.style.zIndex="9999"),t}createOverlay(e){const t=e.placement,n=Ti(t),o=["Top Left","Top","Top Right","Bottom Left","Bottom","Bottom Right"].includes(t);if(!n&&!o&&!e.overlay)return null;const i=document.createElement("div");return n?i.className="heimguard-banner-overlay fixed inset-0 bg-black bg-opacity-50 z-40":o?(i.className="heimguard-banner-overlay fixed inset-0 bg-black bg-opacity-20",i.style.zIndex="9998",console.log("Created toast overlay for position:",t)):i.className="heimguard-banner-overlay fixed inset-0 bg-black bg-opacity-30 z-40",i.style.opacity="0",i.style.transition="opacity 0.3s ease-in-out",i}createContainer(e){const t=document.createElement("div"),n=this.getPlacementClasses(e.placement),o=this.getAnimationClass(e.placement);return t.className=`heimguard-banner ${n.container} ${o}`,e.backgroundColor&&(t.style.backgroundColor=e.backgroundColor),e.textColor&&(t.style.color=e.textColor),this.setContainerDimensions(t,e),t.innerHTML=this.generateContent(e),t}setContainerDimensions(e,t){const n=t.placement;"Slide Left"===n||"Slide Right"===n?(e.style.width=t.width||"400px",e.style.height="calc(100vh - 40px)"):"Slide Top"===n||"Slide Bottom"===n?(e.style.height="300px",e.style.width="calc(100vw - 40px)"):Ti(n)&&(e.style.width=t.width||"auto",e.style.maxWidth="500px",e.style.height=t.height||"auto",e.style.maxHeight="90vh")}generateContent(e){return(t=e.placement)===ui||t===mi||t===gi||t===pi||t===yi||t===Ci?this.generateToastContent(e):(e=>e===bi||e===wi)(e.placement)?this.generateHorizontalContent(e):this.generateVerticalContent(e);var t}generateHorizontalContent(e){const t=!!e.imageUrl,n=!!e.buttonText;return`\n <div class="h-full flex bg-white">\n ${this.renderCloseButton(e)}\n\n ${t?`\n <div class="flex-shrink-0 h-full">\n <img src="${e.imageUrl}"\n alt="${e.title||"Banner image"}"\n class="h-full w-auto object-cover"\n style="max-width: 400px;">\n </div>\n `:""}\n\n <div class="flex-1 p-6 flex flex-col justify-center">\n ${e.icon&&"none"!==e.icon?this.renderNotificationIcon(e,"large"):this.renderTitle(e)}\n ${this.renderImage(e)}\n ${this.renderContent(e)}\n ${n?`\n <div class="flex gap-4">\n <a href="${e.buttonUrl}"\n class="inline-flex items-center px-6 py-2 bg-primary-600 text-white rounded-lg font-medium hover:bg-primary-700 transition-all transform hover:scale-105 shadow-sm"\n style="background-color: ${e.buttonColor}; color: ${e.buttonTextColor}"\n ${e.buttonUrl?.startsWith("http")?'target="_blank" rel="noopener noreferrer"':""}>\n ${e.buttonText}\n <svg class="w-4 h-4 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />\n </svg>\n </a>\n </div>\n `:""}\n </div>\n </div>\n `}generateVerticalContent(e){const t=Ti(e.placement),n=e.placement.includes("Slide");return`\n <div class="h-full flex flex-col bg-white ${t?"rounded-xl":""}" style="${t?"":"height: calc(100vh - 40px);"}">\n ${this.renderCloseButton(e)}\n\n <div class="flex-1 ${t?"p-8":"p-6"} overflow-y-auto flex flex-col">\n ${e.icon&&"none"!==e.icon?this.renderNotificationIcon(e,"large"):this.renderTitle(e)}\n ${this.renderImage(e,t)}\n ${this.renderContent(e,t)}\n ${this.renderButton(e,t)}\n </div>\n\n ${n&&!t?this.renderFooter(e):""}\n </div>\n `}generateToastContent(e){const t=!!e.imageUrl,n=!!e.buttonText,o=!!e.icon&&"none"!==e.icon;return`\n <div class="relative bg-white rounded-xl shadow-2xl">\n ${this.renderToastCloseButton(e)}\n \n <div class="p-6">\n ${o?this.renderNotificationIcon(e,"small"):this.renderToastTitle(e)}\n ${t?this.renderToastImage(e):""}\n ${this.renderToastContent(e)}\n ${n?this.renderToastButton(e):""}\n </div>\n </div>\n `}renderNotificationIcon(e,t="small"){if(!e.icon||"none"===e.icon)return"";const n="large"===t?"w-8 h-8":"w-6 h-6",o=this.getIconSvg(e.icon,"large"===t?"w-5 h-5":"w-4 h-4");return`\n <div class="flex items-center ${"large"===t?"mb-4":"mb-3"}">\n <div class="flex-shrink-0 mr-3">\n <div class="flex items-center justify-center ${n} ${this.getIconColorClasses(e.icon)} rounded-full">\n ${o}\n </div>\n </div>\n ${e.title?`\n <h3 class="${"large"===t?"text-lg font-semibold":"text-base font-semibold"} text-gray-900 flex-1" style="color: ${e.textColor||""}">\n ${e.title}\n </h3>\n `:""}\n </div>\n `}getIconSvg(e,t){return{Information:`\n <svg class="${t} text-current" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n `,info:`\n <svg class="${t} text-current" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n `,Warning:`\n <svg class="${t} text-current" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" />\n </svg>\n `,warning:`\n <svg class="${t} text-current" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" />\n </svg>\n `,Success:`\n <svg class="${t} text-current" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n `,success:`\n <svg class="${t} text-current" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n `,Error:`\n <svg class="${t} text-current" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n `,"Error/Alert":`\n <svg class="${t} text-current" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n `,error:`\n <svg class="${t} text-current" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />\n </svg>\n `}[e]||""}getIconColorClasses(e){return{Information:"bg-blue-100 text-blue-600",info:"bg-blue-100 text-blue-600",Warning:"bg-orange-100 text-orange-600",warning:"bg-orange-100 text-orange-600",Success:"bg-green-100 text-green-600",success:"bg-green-100 text-green-600",Error:"bg-red-100 text-red-600","Error/Alert":"bg-red-100 text-red-600",error:"bg-red-100 text-red-600"}[e]||"bg-gray-100 text-gray-600"}renderToastCloseButton(e){return e.showCloseButton?'\n <button class="absolute top-2 right-2 z-10 w-6 h-6 flex items-center justify-center rounded-full bg-gray-100 hover:bg-gray-200 transition-colors"\n aria-label="Close notification"\n data-close>\n <svg class="w-3 h-3 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />\n </svg>\n </button>\n ':""}renderToastImage(e){return e.imageUrl?`\n <div class="mb-3 flex-shrink-0">\n <img src="${e.imageUrl}"\n alt="${e.title||"Notification image"}"\n class="w-full object-cover rounded"\n loading="lazy">\n </div>\n `:""}renderToastTitle(e){return e.title?`\n <h3 class="text-sm font-semibold text-gray-900 mb-2" style="color: ${e.textColor||""}">\n ${e.title}\n </h3>\n `:""}renderToastContent(e){return e.content?`\n <p class="text-sm text-gray-600 mb-4 leading-relaxed" style="color: ${e.textColor||""}">\n ${e.content}\n </p>\n `:""}renderToastButton(e){if(!e.buttonText||!e.buttonUrl)return"";const t=e.buttonUrl.startsWith("http"),n=e.buttonColor||"var(--primary-600, #4f46e5)",o=e.buttonTextColor||"var(--primary-50, #ffffff)",i=e.buttonColor?this.darkenColor
1(e.buttonColor,10):"var(--primary-700, #4338ca)";return`\n <a href="${e.buttonUrl}"\n class="inline-flex items-center text-sm font-medium px-4 py-2 rounded-lg transition-colors"\n style="background-color: ${n}; color: ${o};"\n onmouseover="this.style.backgroundColor='${i}'"\n onmouseout="this.style.backgroundColor='${n}'"\n ${t?'target="_blank" rel="noopener noreferrer"':""}>\n ${e.buttonText}\n <svg class="w-4 h-4 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />\n </svg>\n </a>\n `}darkenColor(e,t){if(e.startsWith("var("))return e.replace("600","700").replace("500","600").replace("400","500");if(e.startsWith("#")){const n=e.slice(1),o=parseInt(n,16),i=Math.round(2.55*t),a=(o>>16)-i,s=(o>>8&255)-i,r=(255&o)-i;return"#"+(16777216+65536*(a<255?a<1?0:a:255)+256*(s<255?s<1?0:s:255)+(r<255?r<1?0:r:255)).toString(16).slice(1)}return e}renderCloseButton(e){return e.showCloseButton?'\n <button class="absolute top-3 right-3 z-10 w-8 h-8 flex items-center justify-center rounded-full bg-white/80 backdrop-blur-sm hover:bg-white shadow-sm hover:shadow-md transition-all duration-200"\n aria-label="Close notification"\n data-close>\n <svg class="w-4 h-4 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />\n </svg>\n </button>\n ':""}renderTitle(e){return e.title?`\n <h2 class="text-2xl font-bold mb-4 text-gray-900" style="color: ${e.textColor||""}">\n ${e.title}\n </h2>\n `:""}renderImage(e,t=!1){return e.imageUrl?`\n <div class="mb-6 flex-shrink-0">\n <img src="${e.imageUrl}"\n alt="${e.title||"Notification image"}"\n class="w-full h-auto rounded-lg object-cover"\n style="max-height: ${t?"300px":"250px"};"\n loading="lazy">\n </div>\n `:""}renderContent(e,t=!1){return e.content?`\n <div class="text-gray-600 mb-6 ${t?"":"flex-grow"}" style="color: ${e.textColor||""}">\n ${e.content}\n </div>\n `:""}renderButton(e,t=!1){if(!e.buttonText||!e.buttonUrl)return"";const n=e.buttonUrl.startsWith("http"),o=e.buttonColor||"var(--primary-600, #4f46e5)",i=e.buttonTextColor||"var(--primary-50, #ffffff)",a=e.buttonColor?this.darkenColor(e.buttonColor,10):"var(--primary-700, #4338ca)",s=e.buttonColor?this.darkenColor(e.buttonColor,20):"var(--primary-800, #3730a3)";return`\n <div class="${t?"mt-6":"mt-auto pt-6"}">\n <a href="${e.buttonUrl}"\n class="inline-flex items-center justify-center w-full px-6 py-3 rounded-xl font-semibold transition-all duration-200 shadow-lg hover:shadow-xl transform hover:-translate-y-0.5 active:translate-y-0"\n style="background-color: ${o}; color: ${i};"\n onmouseover="this.style.backgroundColor='${a}'"\n onmouseout="this.style.backgroundColor='${o}'"\n onmousedown="this.style.backgroundColor='${s}'"\n onmouseup="this.style.backgroundColor='${a}'"\n ${n?'target="_blank" rel="noopener noreferrer"':""}>\n ${e.buttonText}\n <svg class="w-4 h-4 ml-2 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />\n </svg>\n </a>\n </div>\n `}renderFooter(e){return'\n <div class="border-t border-gray-100 px-6 py-3 bg-gray-50/50 flex-shrink-0">\n <div class="flex items-center justify-center text-xs text-gray-400">\n <span>Powered by HeimGuard</span>\n </div>\n </div>\n '}getPlacementClasses(e){return Ai[e]||Ai[mi]}getAnimationClass(e){return{"Top Left":oi,Top:oi,"Top Right":oi,Centered:ai,"Bottom Left":ii,Bottom:ii,"Bottom Right":ii,"Slide Right":si,"Slide Left":ri,"
1Slide Top":di,"Slide Bottom":li,Center:ai,Modal:ai}[e]||ni}}class Ei{constructor(){this.animationDuration=Xo,this.hideAnimationDuration=ei}applyInitialState(e,t){const n=e.querySelector(".heimguard-banner");if(!n)return;switch(t){case ui:case mi:case gi:n.style.transform="translateY(-100%)",n.style.opacity="0";break;case pi:case yi:case Ci:n.style.transform="translateY(100%)",n.style.opacity="0";break;case hi:case Si:case xi:n.style.opacity="0",n.style.transform="scale(0.9)";break;case fi:n.style.transform="translateX(calc(100% + 20px))";break;case vi:n.style.transform="translateX(calc(-100% - 20px))";break;case bi:n.style.transform="translateY(calc(-100% - 20px))";break;case wi:n.style.transform="translateY(calc(100% + 20px))"}const o=e.querySelector(".heimguard-banner-overlay");o&&(o.style.opacity="0",o.style.transition="opacity 0.3s ease-in-out")}applyShowState(e,t){return new Promise((t=>{const n=e.querySelector(".heimguard-banner");n?setTimeout((()=>{n.style.transform="none",n.style.opacity="1";let o=e.querySelector(".heimguard-banner-overlay");if(!o){const t=e.getAttribute("data-overlay-id");t&&(o=document.getElementById(t))}o&&(o.style.opacity="1"),t()}),50):t()}))}applyHideState(e,t){return new Promise((n=>{const o=e.querySelector(".heimguard-banner");if(!o)return void n();switch(t){case ui:case mi:case gi:o.style.transform="translateY(-100%)",o.style.opacity="0";break;case pi:case yi:case Ci:o.style.transform="translateY(100%)",o.style.opacity="0";break;case hi:case Si:case xi:o.style.opacity="0",o.style.transform="scale(0.9)";break;case fi:o.style.transform="translateX(calc(100% + 20px))";break;case vi:o.style.transform="translateX(calc(-100% - 20px))";break;case bi:o.style.transform="translateY(calc(-100% - 20px))";break;case wi:o.style.transform="translateY(calc(100% + 20px))"}let i=e.querySelector(".heimguard-banner-overlay");if(!i){const t=e.getAttribute("data-overlay-id");t&&(i=document.getElementById(t))}i&&(i.style.opacity="0"),setTimeout((()=>{n()}),this.hideAnimationDuration)}))}getAnimationClass(e){return{[ui]:oi,[mi]:oi,[gi]:oi,[hi]:ai,[pi]:ii,[yi]:ii,[Ci]:ii,[fi]:si,[vi]:ri,[bi]:di,[wi]:li,[Si]:ai,[xi]:ai}[e]||ni}isModalPlacement(e){return Ti(e)}lockBodyScroll(){document.body.style.overflow="hidden"}unlockBodyScroll(){document.body.style.overflow=""}waitForFrame(){return new Promise((e=>requestAnimationFrame((()=>e()))))}}class Pi{constructor(){this.listeners=new Map,this.eventPrefix="heimguard:banner:"}emit(e,t={}){const n=new CustomEvent(`${this.eventPrefix}${e}`,{detail:t,bubbles:!0});document.dispatchEvent(n)}on(e,t){const n=`${this.eventPrefix}${e}`;this.listeners.has(n)||this.listeners.set(n,new Set),this.listeners.get(n).add(t),document.addEventListener(n,t)}off(e,t){const n=`${this.eventPrefix}${e}`;this.listeners.has(n)&&(this.listeners.get(n).delete(t),document.removeEventListener(n,t))}setupBannerHandlers(e,t={}){const n=new Map;if(t.onClose){const o=e.querySelector("[data-close]");if(o){const e=e=>{e.preventDefault(),e.stopPropagation(),t.onClose()};o.addEventListener("click",e),n.set("close",{element:o,handler:e,event:"click"})}}if(t.onOverlayClick){const o=e.querySelector(".heimguard-banner-overlay");if(o){const e=e=>{e.target===o&&t.onOverlayClick()};o.addEventListener("click",e),n.set("overlay",{element:o,handler:e,event:"click"})}}if(t.onLinkClick){e.querySelectorAll("a").forEach(((e,o)=>{const i=n=>{n.preventDefault(),t.onClose&&t.onClose();const i=e.href;i&&"#"!==i&&(window.location.href=i),t.onLinkClick({url:e.href,text:e.textContent,index:o})};e.addEventListener("click",i),n.set(`link-${o}`,{element:e,handler:i,event:"click"})}))}if(t.onEscape){const e=e=>{"Escape"===e.key&&t.onEscape()};document.addEventListener("keydown",e),n.set("escape",{element:document,handler:e,event:"keydown"})}return n}cleanupHandlers(e){e&&(e.forEach((({element:e,handler:t,event:n})=>{e.removeEventListener(n,t)})),e.clear())}destroy(){this.listeners.forEach(((e,t)=>{e.forEach((e=>{document.removeEventListener(t,e)}))}
1)),this.listeners.clear()}}class Ni{constructor(e={}){this.id=`banner_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,this.options={shortCode:e.shortCode||null,autoLoad:!1!==e.autoLoad,checkInit:!1!==e.checkInit,...e},this.api=new Yo(e.apiConfig),this.state=new Qo,this.renderer=new Mi,this.animations=new Ei,this.events=new Pi,this.banner=null,this.isLoaded=!1,this.isVisible=!1,this.element=null,this.boundHandlers=null,this.shortCode=e.shortCode||void 0,this.options.autoLoad&&this.init()}async init(){try{if(!this.options.shortCode&&this.options.checkInit)return void await this.checkInitForNotifications();if(this.options.shortCode){if(this.state.isClosed(this.options.shortCode))return;if(!Jo.canShowNotification(this.options.shortCode))return;await this.load()}}catch(e){b.vF.error("Failed to initialize banner module:","general",e),this.events.emit("error",{error:e,module:this})}}async checkInitForNotifications(){const e=await this.api.fetchNotifications();0!==e.length&&e.forEach(((e,t)=>{if(this.state.isClosed(e))return;const n=new Ni({shortCode:e,autoLoad:!1,checkInit:!1});this.state.addBanner(e,n);setTimeout((()=>{n.load()}),500*t)}))}async load(){if(this.isLoaded)return void(this.banner&&!this.isVisible&&this.show());const e=await this.api.fetchBanner(this.options.shortCode);e&&(this.banner=e,this.isLoaded=!0,this.banner.isActive&&this.show(),this.events.emit("loaded",{banner:this.banner,module:this}))}show(){if(!this.banner||this.isVisible)return;const e=this.banner,t=e.showOnPageLoad||!1,n=e.showOnExitIntent||!1,o=e.delay||0;if(t)return this.executeShow(),void(n&&this.setupExitIntentDetection());o>0&&setTimeout((()=>{this.isVisible||this.executeShow()}),o),n&&this.setupExitIntentDetection(),e.scrollDepthPercent&&e.scrollDepthPercent>0&&this.setupScrollDepthDetection(e.scrollDepthPercent),t||n||0!==o||e.scrollDepthPercent||this.executeShow()}async executeShow(){if(!this.banner||this.isVisible)return;await(async()=>{this.animations.isModalPlacement(this.banner.placement)&&this.animations.lockBodyScroll(),this.element=this.renderer.createElement(this.banner),document.body.appendChild(this.element),this.animations.applyInitialState(this.element,this.banner.placement),await this.animations.waitForFrame(),await this.animations.applyShowState(this.element,this.banner.placement),this.isVisible=!0,this.setupEventHandlers(),this.banner.duration&&setTimeout((()=>{this.hide()}),this.banner.duration),Jo.recordNotificationShown(this.shortCode||this.banner.id),this.events.emit("show",{banner:this.banner,module:this})})()}setupExitIntentDetection(){let e=!1;const t=n=>{const o=n;e||this.isVisible||o.clientY<=50&&o.movementY<0&&(e=!0,this.executeShow(),document.removeEventListener("mousemove",t))},n=o=>{const i=o;e||this.isVisible||i.clientY<=0&&(e=!0,this.executeShow(),document.removeEventListener("mousemove",t),document.removeEventListener("mouseleave",n))};document.addEventListener("mousemove",t),document.addEventListener("mouseleave",n),this.boundHandlers||(this.boundHandlers=new Map),this.boundHandlers.set("exitIntent",{element:document,handler:t,event:"mousemove"}),this.boundHandlers.set("exitLeave",{element:document,handler:n,event:"mouseleave"})}setupScrollDepthDetection(e){let t=!1;const n=()=>
1{if(t||this.isVisible)return;const o=window.pageYOffset||document.documentElement.scrollTop,i=document.documentElement.scrollHeight-window.innerHeight;Math.round(o/i*100)>=e&&(t=!0,this.executeShow(),window.removeEventListener("scroll",n))};window.addEventListener("scroll",n,{passive:!0}),this.boundHandlers||(this.boundHandlers=new Map),this.boundHandlers.set("scrollDepth",{element:window,handler:n,event:"scroll"})}async hide(){if(this.isVisible&&this.element&&this.banner){if(await this.animations.applyHideState(this.element,this.banner.placement),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element){const e=this.element.getAttribute("data-overlay-id");if(e){const t=document.getElementById(e);t&&t.parentNode===document.body&&document.body.removeChild(t)}}this.isVisible=!1,this.animations.isModalPlacement(this.banner.placement)&&this.animations.unlockBodyScroll(),this.state.markClosed(this.shortCode||this.banner.id),Jo.recordNotificationDismissed(this.shortCode||this.banner.id),this.boundHandlers&&(this.events.cleanupHandlers(this.boundHandlers),this.boundHandlers=null),this.events.emit("hide",{banner:this.banner,module:this})}}setupEventHandlers(){if(!this.element)return;const e={onClose:()=>this.hide(),onOverlayClick:()=>this.hide(),onLinkClick:e=>{this.events.emit("click",{...e,banner:this.banner,module:this})}},t=["Top Left","Top","Top Right","Bottom Left","Bottom","Bottom Right"].includes(this.banner?.placement||"");this.banner&&(this.animations.isModalPlacement(this.banner.placement)||t)&&(e.onEscape=()=>this.hide()),this.boundHandlers=this.events.setupBannerHandlers(this.element,e)}destroy(){if(this.hide(),this.element){const e=this.element.getAttribute("data-overlay-id");if(e){const t=document.getElementById(e);t&&t.parentNode===document.body&&document.body.removeChild(t)}}this.boundHandlers&&(this.boundHandlers.forEach((e=>{e.element.removeEventListener(e.event,e.handler)})),this.boundHandlers.clear(),this.boundHandlers=null);this.state.getAllBanners().forEach((e=>{e!==this&&e.destroy()})),this.state.destroy(),this.events.destroy(),this.banner=null,this.isLoaded=!1,this.isVisible=!1,this.element=null}static async show(e,t={}){const n=new Ni({...t,shortCode:e,autoLoad:!1,checkInit:!1});return await n.init(),n}static async loadFromInit(){if(window.HeimGuard?.bannerModuleInitialized)return window.HeimGuard.bannerModuleInstance;window.HeimGuard=window.HeimGuard||{},window.HeimGuard.bannerModuleInitialized=!0;const e=new Ni({autoLoad:!1,checkInit:!0});return await e.init(),window.HeimGuard.bannerModuleInstance=e,e}}window.HeimGuard=window.HeimGuard||{},window.HeimGuard.BannerModule=Ni;var Li=Ni;const Di={modern:{cardClass:"bg-gradient-to-br from-white to-gray-50 rounded-2xl shadow-2xl p-8 text-center w-full border border-gray-100 relative overflow-hidden",iconClass:"w-20 h-20 mx-auto mb-6 bg-gradient-to-br from-primary-50 to-primary-100 rounded-2xl p-4 shadow-lg text-primary-600",titleClass:"text-3xl font-bold text-gray-900 mb-3 tracking-tight",descriptionClass:"text-gray-600 mb-8 text-lg leading-relaxed",buttonClass:"bg-gradient-to-r from-primary-600 to-primary-700 hover:from-primary-700 hover:to-primary-800 text-white font-semibold py-4 px-8 rounded-xl transition-all duration-300 transform hover:scale-[1.02] hover:shadow-xl w-full text-lg"},minimal:{cardClass:"bg-white rounded-lg shadow-md p-8 text-center w-full border border-gray-200",iconClass:"w-16 h-16 mx-auto mb-4 text-primary-600",titleClass:"text-2xl font-semibold text-gray-900 mb-2",descriptionClass:"text-gray-600 mb-6",buttonClass:"bg-primary-600 hover:bg-primary-700 text-white font-medium py-3 px-6 rounded-lg transition-colors duration-200 w-full"},dark:{cardClass:"bg-gray-900 rounded-2xl shadow-2xl p-8 text-center w-full border border-gray-800 relative overflow-hidden",iconClass:"w-20 h-20 mx-auto mb-6 bg-gray-800 rounded-2xl p-4 shadow-lg text-primary-400",titleClass:"text-3xl font-bold text-white mb-3 tracking-tight",descriptionClass:"text-gray-300 mb-8 text-lg leading-relaxed",buttonClass:"bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-600 hover:to-primary-700 text-white font-semibold py-4 px-8 rounded-xl transition-all duration-300 transform hover:scale-[1.02] hover:shadow-xl w-full text-lg"},glass:{cardClass:"backdrop-blur-lg bg-white/70 rounded-2xl shadow-2xl p-8 text-center w-full border border-white/20 relative overflow-hidden",iconClass:"w-20 h-20 mx-auto mb-6 bg-white/50 backdrop-blur rounded-2xl p-4 shadow-lg text-primary-600",titleClass:"text-3xl font-bold text-gray-900 mb-3 tracking-tight",descriptionClass:"text-gray-700 mb-8 text-lg leading-relaxed",buttonClass:"bg-gradient-to-r from-primary-600/90 to-primary-700/90 backdrop-blur hover:from-primary-700 hover:to-primary-800 text-white font-semibold py-4 px-8 rounded-xl transition-all duration-300 transform hover:scale-[1.02] hover:shadow-xl w-full text-lg"},vibrant:{cardClass:"bg-gradient-to-br from-primary-50 via-primary-100 to-secondary-50 rounded-2xl shadow-2xl p-8 text-center w-full border border-primary-200 relative overflow-hidden",iconClass:"w-20 h-20 mx-auto mb-6 bg-gradient-to-br from-primary-500 to-primary-600 rounded-2xl p-4 shadow-lg text-white",titleClass:"text-3xl font-bold bg-gradient-to-r from-primary-600 to-primary-700 bg-clip-text text-transparent mb-3",descriptionClass:"text-gray-700 mb-8 text-lg leading-relaxed",buttonClass:"bg-gradient-to-r from-primary-600 to-primary-700 hover:from-primary-700 hover:to-primary-800 text-white font-semibold py-4 px-8 rounded-xl transition-all duration-300 transform hover:scale-[1.02] hover:shadow-xl w-full text-lg shadow-primary-500/25"}};class Ii{constructor(e){this.element=e,this.config=this.parseConfig(),this.render()}parseConfig(){const e=this.element.dataset.authType||"login",t=this.element.dataset.style||"vibrant",n=Di[t]||Di.modern,o=this.getDefaults(e);return{authType:e,style:t,title:this.element.dataset.title||o.title,de
1scription:this.element.dataset.description||o.description,buttonText:this.element.dataset.buttonText||o.buttonText,buttonClass:this.element.dataset.buttonClass||n.buttonClass||o.buttonClass,cardClass:this.element.dataset.cardClass||n.cardClass||o.cardClass,iconClass:this.element.dataset.iconClass||n.iconClass||o.iconClass,titleClass:this.element.dataset.titleClass||n.titleClass||o.titleClass,descriptionClass:this.element.dataset.descriptionClass||n.descriptionClass||o.descriptionClass}}getDefaults(e){return"register"===e?{title:"Start Your Journey",description:"Join thousands of members enjoying exclusive content, special offers, and premium features",buttonText:"Create Free Account",buttonClass:"bg-gradient-to-r from-primary-600 to-primary-700 hover:from-primary-700 hover:to-primary-800 text-white font-semibold py-4 px-8 rounded-xl transition-all duration-300 transform hover:scale-105 hover:shadow-xl w-full text-lg",cardClass:"bg-gradient-to-br from-white to-gray-50 rounded-2xl shadow-2xl p-8 text-center w-full border border-gray-100 relative overflow-hidden",iconClass:"w-20 h-20 mx-auto mb-6 text-primary-600 bg-primary-50 rounded-2xl p-4 shadow-lg",titleClass:"text-3xl font-bold text-gray-900 mb-3 tracking-tight",descriptionClass:"text-gray-600 mb-8 text-lg leading-relaxed"}:{title:"Welcome Back",description:"Access your account to continue where you left off",buttonText:"Sign In to Account",buttonClass:"bg-gradient-to-r from-gray-800 to-gray-900 hover:from-gray-900 hover:to-black text-white font-semibold py-4 px-8 rounded-xl transition-all duration-300 transform hover:scale-105 hover:shadow-xl w-full text-lg",cardClass:"bg-gradient-to-br from-white to-gray-50 rounded-2xl shadow-2xl p-8 text-center w-full border border-gray-100 relative overflow-hidden",iconClass:"w-20 h-20 mx-auto mb-6 text-gray-700 bg-gray-100 rounded-2xl p-4 shadow-lg",titleClass:"text-3xl font-bold text-gray-900 mb-3 tracking-tight",descriptionClass:"text-gray-600 mb-8 text-lg leading-relaxed"}}render(){const{authType:e,title:t,description:n,buttonText:o,buttonClass:i,cardClass:a,iconClass:s,titleClass:r,descriptionClass:d}=this.config,l="register"===e?"user-plus":"log-in",c="vibrant"===this.config.style,u=c||"register"===e?"primary":"gray",m=`\n <div class="${a}" data-auth-card="${e}">\n \x3c!-- Decorative background elements --\x3e\n ${c?'\n <div class="absolute top-0 right-0 -mt-8 -mr-8 w-32 h-32 bg-primary-400 rounded-full opacity-20 blur-3xl"></div>\n <div class="absolute bottom-0 left-0 -mb-8 -ml-8 w-40 h-40 bg-secondary-400 rounded-full opacity-20 blur-3xl"></div>\n <div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-64 h-64 bg-primary-300 rounded-full opacity-10 blur-3xl"></div>\n ':`\n <div class="absolute top-0 right-0 -mt-4 -mr-4 w-24 h-24 bg-${u}-200 rounded-full opacity-10 blur-2xl"></div>\n <div class="absolute bottom-0 left-0 -mb-4 -ml-4 w-32 h-32 bg-${u}-300 rounded-full opacity-10 blur-3xl"></div>\n `}\n \n \x3c!-- Icon with animation --\x3e\n <div class="${s} relative group">\n <div class="absolute inset-0 bg-${u}-200 rounded-2xl opacity-20 group-hover:opacity-30 transition-opacity duration-300 blur-xl"></div>\n ${P.H.render(l,{class:"w-full h-full relative z-10"})}\n </div>\n \n \x3c!-- Title with subtle animation --\x3e\n <h3 class="${r} relative z-10">${t}</h3>\n \n \x3c!-- Description --\x3e\n <p class="${d} relative z-10">${n}</p>\n \n \x3c!-- Button with icon --\x3e\n <button \n type="button"\n class="${i} group relative z-10 flex items-center justify-center gap-2"\n data-${e}-trigger\n aria-label="${"login"===e?"Open login modal":"Open registration modal"}"\n >\n <span>${o}</span>\n ${P.H.render("arrow-right",{class:"w-5 h-5 transition-transform duration-300 group-hover:translate-x-1"})}\n </button>\n </div>\n `;if(this.element.innerHTML=m,this.element.dataset.style){const e=this.element.querySelector("[data-auth-card]");e&&e.setAttribute("style",this.element.dataset.style)}
1}static initialize(){document.querySelectorAll("HgAuthCard, [data-hg-auth-card]").forEach((e=>{new Ii(e)}))}static initializeElement(e){return new Ii(e)}}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>Ii.initialize())):Ii.initialize();const ki=new class{constructor(){this.name="AuthCardSystem",this.initialized=!1,this.setup()}async initialize(){this.initialized||(b.vF.debug("Initializing...","general"),Ii.initialize(),this.observeAuthCards(),this.initialized=!0,b.vF.debug("Initialization complete","general"))}setup(){"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>this.initialize())):this.initialize()}observeAuthCards(){new MutationObserver((e=>{e.forEach((e=>{e.addedNodes.forEach((e=>{if(e.nodeType===Node.ELEMENT_NODE){const t=e;("HGAUTHCARD"===t.tagName||t.hasAttribute("data-hg-auth-card"))&&Ii.initializeElement(t);t.querySelectorAll("HgAuthCard, [data-hg-auth-card]").forEach((e=>{Ii.initializeElement(e)}))}}))}))})).observe(document.body,{childList:!0,subtree:!0})}};A.systemRegistry.registerInstance("AuthCardSystem",ki);class Oi{constructor(e={}){this.config={adsUrl:e.adsUrl||f.A.apiGetAdUrl}}async fetchAd(e){console.log(`ð Fetching ad data for adcode: ${e}`);try{const t=await fetch(`${this.config.adsUrl}?adcode=${encodeURIComponent(e)}`,{method:"GET",headers:{Accept:"application/json","Content-Type":"application/json"},credentials:"include"});if(!t.ok){if(404===t.status)return console.log("â¹ï¸ No ad found for adcode:",e),null;throw new Error(`HTTP error! status: ${t.status}`)}const n=await t.json();return console.log("ð Ad data received:",n),this.processAdData(n)}catch(t){return console.error("â Error fetching ad:",t),ie.Ak.logError("AdsAPI.fetchAd",t,{adcode:e,url:this.config.adsUrl}),null}}processAdData(e){return e.promo?{id:e.id,internalName:e.internalName,shortCode:e.shortCode,customCss:e.customCss,promo:e.promo,type:"promo",adcode:e.shortCode}:{id:e.id||e.adcode||"",shortCode:e.shortCode||e.adcode||"",adcode:e.adcode||"",content:e.content||"",type:e.type||"html",width:e.width,height:e.height,className:e.className,styles:e.styles||{}}}}new Oi;class Ri{render(e,t){if(t.width&&(e.style.width=t.width),t.height&&(e.style.height=t.height),t.styles&&Object.entries(t.styles).forEach((([t,n])=>{e.style[t]=n})),t.className&&(e.className=t.className),e.classList.add("hg-ad",`hg-ad--${t.type||"html"}`),e.setAttribute("data-ad-id",t.id),e.setAttribute("data-ad-loaded","true"),t.customCss){const n=document.createElement("style");n.textContent=t.customCss,e.appendChild(n)}switch(t.type){case"promo":this.renderPromo(e,t);break;case"iframe":this.renderIframe(e,t);break;case"script":this.renderScript(e,t);break;default:this.renderHtml(e,t)}}renderPromo(e,t){if(!t.promo)return void console.error("No promo data found for ad:",t.id);const n=t.promo,o=n.hubspotFormId&&n.hubspotPortalId;let i='\n <div class="hg-ad-card rounded-lg border border-gray-200 shadow-lg overflow-hidden hover:shadow-xl">\n ';if(n.imageOnTop||!1?(i+='<div class="flex flex-col">',n.image?.url&&(i+=`\n <div class="hg-ad-card__image flex-shrink-0 w-full flex items-center justify-center p-4 border-b border-gray-200">\n <img \n src="${this.escapeHtml(n.image.url)}" \n alt="${this.escapeHtml(n.image.altText||n.title||"")}" \n class="max-w-full max-h-full object-contain"\n loading="lazy"\n />\n </div>\n `),i+='\n <div class="hg-ad-card__content w-full p-6 flex flex-col">\n '):(i+='<div class="flex flex-col md:flex-row">',n.image?.url&&(i+=`\n <div class="hg-ad-card__image flex-shrink-0 w-full md:w-1/3 flex items-center justify-center p-4">\n <img \n src="${this.escapeHtml(n.image.url)}" \n alt="${this.escapeHtml(n.image.altText||n.title||"")}" \n class="max-w-full max-h-full object-contain"\n loading="lazy"\n />\n </div>\n `),i+=`\n <div class="hg-ad-card__content ${n.image?.url?"w-full md:w-2/3":"w-full"} p-6 flex flex-col">\n `),i+="\n <div>\n ",n.title&&(i+=`\n <h3 class="hg-ad-card__title text-2xl font-bold text-gray-900 mb-3">\n ${this.escapeHtml(n.title)}\n </h3>\n `),n.description&&(i+=`\n <div class="hg-ad-card__description text-gray-600 text-base leading-relaxed mb-4">\n ${n.description}\n </div>\n `),n.buttonTitle&&n.buttonLink&&!o&&(i+=`\n <div class="mt-4">\n <a \n href="${this.escapeHtml(n.buttonLink)}" \n class="hg-ad-card__button inline-flex items-center px-5 py-2.5 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors duration-200"\n target="_blank"\n rel="noopener noreferrer"\n >\n ${this.escapeHtml(n.buttonTitle)}\n </a>\n </div>\n `),o&&(i+='\n <div class="hg-ad-card__hubspot-container mt-6">\n \x3c!-- HubSpot form will be rendered here --\x3e\n </div>\n '),i+="\n </div>\n </div>\n </div>\n </div>\n ",e.innerHTML=i,o){const t=e.querySelector(".hg-ad-card__hubspot-container");t&&this.renderHubSpotForm(t,n,!0)}}renderHtml(e,t){e.innerHTML=t.content||""}renderIframe(e,t){const n=document.createElement("iframe");n.srcdoc=t.content||"",n.style.width="100%",n.style.height="100%",
1n.style.border="none",n.setAttribute("scrolling","no"),n.setAttribute("frameborder","0"),e.innerHTML="",e.appendChild(n)}renderScript(e,t){e.innerHTML=t.content||""}createPlaceholder(e){e.innerHTML='\n <div class="hg-ad-placeholder">\n <div class="hg-ad-placeholder__spinner"></div>\n </div>\n '}clear(e){e.innerHTML="",e.removeAttribute("data-ad-loaded")}renderNotFound(e,t){e.classList.add("hg-ad","hg-ad--placeholder","hg-ad--notfound"),e.innerHTML=`\n <div class="hg-ad-placeholder-content">\n <div class="text-center p-8 bg-gray-50 rounded-lg border border-gray-200">\n <div class="mb-4">\n <svg class="w-16 h-16 mx-auto text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>\n </svg>\n </div>\n <h3 class="text-lg font-medium text-gray-900 mb-2">Ad Space Available</h3>\n <p class="text-sm text-gray-500">Contact us to advertise here</p>\n <div class="mt-3 text-xs text-gray-400">Ad code: ${this.escapeHtml(t)}</div>\n </div>\n </div>\n `}renderError(e,t){e.classList.add("hg-ad","hg-ad--placeholder","hg-ad--error"),e.innerHTML=`\n <div class="hg-ad-placeholder-content">\n <div class="text-center p-6 bg-red-50 rounded-lg border border-red-200">\n <div class="mb-3">\n <svg class="w-12 h-12 mx-auto text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>\n </svg>\n </div>\n <h3 class="text-base font-medium text-red-900">Unable to Load Ad</h3>\n <p class="text-sm text-red-700 mt-1">Please try again later</p>\n <div class="mt-2 text-xs text-red-500">Ad code: ${this.escapeHtml(t)}</div>\n </div>\n </div>\n `}renderHubSpotForm(e,t,n=!1){const o=`hg-hubspot-form-${t.hubspotFormId}-${Date.now()}`;if(e.innerHTML=`\n <div class="hg-ad-hubspot">\n ${n||!t.title&&!t.description?"":`\n <div class="hg-ad-hubspot__header mb-6">\n ${t.title?`<h3 class="text-2xl font-bold text-gray-900 mb-2">${this.escapeHtml(t.title)}</h3>`:""}\n ${t.description?`<p class="text-gray-600">${this.escapeHtml(t.description)}</p>`:""}\n </div>\n `}\n <div id="${o}" class="hubspot-form-container">\n \x3c!-- Loading placeholder --\x3e\n <div class="hg-hubspot-loading">\n <div class="flex items-center justify-center py-8">\n <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>\n </div>\n <p class="text-center text-gray-500 text-sm">Loading form...</p>\n </div>\n </div>\n </div>\n `,window.hbspt)this.createHubSpotForm(o,t);else{const e=document.createElement("script");e.src="//js.hsforms.net/forms/embed/v2.js",e.charset="utf-8",e.type="text/javascript",e.onload=()=>{this.createHubSpotForm(o,t)},document.head.appendChild(e)}}createHubSpotForm(e,t){setTimeout((()=>{const n=document.getElementById(e);if(n)if(window.hbspt&&window.hbspt.forms)try{window.hbspt.forms.create({portalId:t.hubspotPortalId,formId:t.hubspotFormId,target:`#${e}`,region:"na1",css:"",cssClass:"hg-hubspot-form",onFormReady:e=>{console.log("HubSpot form ready:",t.hubspotFormId);const o=n.querySelector(".hg-hubspot-loading");o&&o.remove()},onFormSubmit:e=>{console.log("HubSpot form submitted:",t.hubspotFormId)},onFormSubmitted:()=>{console.log("HubSpot form submission complete:",t.hubspotFormId)}})}catch(e){console.error("Failed to create HubSpot form:",e),n.innerHTML='\n <div class="text-center py-8">\n <p class="text-red-600">Failed to load form. Please try again later.</p>\n </div>\n '}else console.error("HubSpot forms library not available");else console.error("HubSpot form container not found:",e)}),100)}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}}class Bi{constructor(){this.loadedAds=new Map,this.adElements=new WeakMap}isLoaded(e){return this.loadedAds.has(e)}markLoaded(e,t){this.loadedAds.set(e,t),this.adElements.set(t.element,t)}getAd(e){return this.loadedAds.get(e)}getAdByElement(e){return this.adElements.get(e)}getAllAds(){return Array.from(this.loadedAds.values())}removeAd(e){const t=this.loadedAds.get(e);t&&(this.adElements.delete(t.element),this.loadedAds.delete(e))}clear(){this.loadedAds.clear()}getStats(){return{totalLoaded:this.loadedAds.size,adcodes:Array.from(this.loadedAds.keys())}}}class $i{constructor(){this.events=new Map,this.eventTarget=new EventTarget}on(e,t){return this.events.has(e)||this.events.set(e,new Set),this.events.get(e).add(t),()=>{this.off(e,t)}}off(e,t){const n=this.events.get(e);n&&n.delete(t)}emit(e,t){const n=this.events.get(e);
1n&&n.forEach((n=>{try{n(t)}catch(t){console.error(`Error in ad event handler for ${e}:`,t)}}));const o=new CustomEvent(`heimguard:ads:${e}`,{detail:t,bubbles:!0,cancelable:!0});this.eventTarget.dispatchEvent(o),t.module?.element&&t.module.element.dispatchEvent(o)}clear(){this.events.clear()}trackImpression(e,t){this.emit("impression",{adcode:e,module:t})}trackClick(e,t,n){this.emit("click",{adcode:e,module:t,data:{target:n}})}setupClickTracking(e,t,n){const o=e=>{const o=e.target;("A"===o.tagName||"BUTTON"===o.tagName||null!==o.closest("a")||null!==o.closest("button"))&&this.trackClick(t,n,o)};e.addEventListener("click",o),e.__adClickHandler=o}removeClickTracking(e){const t=e.__adClickHandler;t&&(e.removeEventListener("click",t),delete e.__adClickHandler)}}class Ui{constructor(e,t={}){this.id=`ad_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,this.element=e,this.adcode=t.adcode||e.dataset.adcode||"",this.options={element:e,adcode:this.adcode,autoLoad:!1!==t.autoLoad,...t},this.api=new Oi(t.apiConfig),this.renderer=new Ri,this.state=new Bi,this.events=new $i,this.data=null,this.isLoaded=!1,this.adcode&&this.options.autoLoad&&this.load()}async load(){if(this.isLoaded)console.log("â
Ad already loaded for adcode:",this.adcode);else if(this.adcode)try{if(this.state.isLoaded(this.adcode))return void console.log("â¹ï¸ Ad already loaded for adcode:",this.adcode);this.events.emit("loading",{adcode:this.adcode,module:this}),this.renderer.createPlaceholder(this.element);const e=await this.api.fetchAd(this.adcode);if(!e)return console.log("â¹ï¸ No ad data received for adcode:",this.adcode),this.element.style.display="none",void this.events.emit("notfound",{adcode:this.adcode,module:this});this.data=e,this.isLoaded=!0,this.renderer.render(this.element,e),this.state.markLoaded(this.adcode,this),this.events.emit("loaded",{adcode:this.adcode,data:e,module:this}),("script"===e.type||e.content&&e.content.includes("<script"))&&this.executeScripts()}catch(e){console.error("â Failed to load ad:",e),this.events.emit("error",{error:e,adcode:this.adcode,module:this}),this.element.style.display="none"}else console.warn("â ï¸ No adcode provided for ad element")}executeScripts(){this.element.querySelectorAll("script").forEach((e=>{const t=document.createElement("script");Array.from(e.attributes).forEach((e=>{t.setAttribute(e.name,e.value)})),e.textContent&&(t.textContent=e.textContent),e.parentNode?.replaceChild(t,e)}))}async refresh(){this.isLoaded=!1,this.data=null,await this.load()}destroy(){this.element.innerHTML="",this.state.removeAd(this.adcode),this.events.emit("destroy",{adcode:this.adcode,module:this}),this.data=null,this.isLoaded=!1}static async initializeAll(){const e=document.querySelectorAll("HgAdModule[data-adcode]"),t=[];for(const n of Array.from(e)){const e=new Ui(n);t.push(e)}return t}static initializeElement(e){return new Ui(e)}}window.HeimGuard=window.HeimGuard||{},window.HeimGuard.AdsModule=Ui;var Fi=Ui;const zi=new class{constructor(){this.name="AdsSystem",this.initialized=!1,this.observer=null,this.modules=[],this.state=new Bi,this.events=new $i,this.setup()}async setup(){await C,await this.initialize()}async initialize(){if(!this.initialized){b.vF.debug("Initializing...","ads");try{await this.initializeAds(),this.startObserving(),this.setupEventListeners(),this.initialized=!0,b.vF.debug("Initialization complete","ads")}catch(e){throw b.vF.error("Failed to initialize:","ads",e),e}}}async initializeAds(){const e=document.querySelectorAll("HgAdModule[data-adcode]");b.vF.debug(`Found ${e.length} ad elements to initialize`,"ads");for(const t of Array.from(e))try{const e=new Fi(t);this.modules.push(e),e.adcode&&this.state.markLoaded(e.adcode,e),this.events.setupClickTracking(t,e.adcode,e),this.events.trackImpression(e.adcode,e)}catch(e){b.vF.error("Failed to initialize ad element:","ads",e,t)}}startObserving(){this.observer=new MutationObserver((e=>{e.forEach((e=>{e.addedNodes.forEach((e=>{if(e.nodeType===Node.ELEMENT_NODE){const t=e;"HGADMODULE"===t.tagName&&t.hasAttribute("data-adcode")&&this.initializeAdElement(t);t.querySelectorAll("HgAdModule[data-adcode]").forEach((e=>{this.initializeAdElement(e)}))}}
1)),e.removedNodes.forEach((e=>{if(e.nodeType===Node.ELEMENT_NODE){const t=e;"HGADMODULE"===t.tagName&&this.cleanupAdElement(t);t.querySelectorAll("HgAdModule[data-adcode]").forEach((e=>{this.cleanupAdElement(e)}))}}))}))})),this.observer.observe(document.body,{childList:!0,subtree:!0})}async initializeAdElement(e){if(!e.hasAttribute("data-ad-initialized")){e.setAttribute("data-ad-initialized","true");try{const t=new Fi(e);this.modules.push(t),t.adcode&&this.state.markLoaded(t.adcode,t),this.events.setupClickTracking(e,t.adcode,t),this.events.trackImpression(t.adcode,t),b.vF.debug(`Initialized ad element with adcode: ${t.adcode}`,"ads")}catch(t){b.vF.error("Failed to initialize ad element:","ads",t,e)}}}cleanupAdElement(e){const t=this.state.getAdByElement(e);if(t){this.events.removeClickTracking(e),t.destroy();const n=this.modules.findIndex((e=>e===t));n>-1&&this.modules.splice(n,1),b.vF.debug(`Cleaned up ad element with adcode: ${t.adcode}`,"ads")}}setupEventListeners(){document.addEventListener("visibilitychange",(()=>{document.hidden?b.vF.debug("Page hidden, pausing ads","ads"):b.vF.debug("Page visible, resuming ads","ads")})),window.addEventListener("heimguard:ads:refresh",(e=>{const t=e.detail?.adcode;t?this.refreshAd(t):this.refreshAll()}))}async refreshAd(e){const t=this.state.getAd(e);t&&t instanceof Fi&&await t.refresh()}async refreshAll(){b.vF.debug("Refreshing all ads...","ads");const e=this.modules.map((e=>e.refresh()));await Promise.all(e)}getStatus(){const e=this.state.getStats();return{initialized:this.initialized,totalAds:e.totalLoaded,loadedAds:e.adcodes}}destroy(){this.observer&&(this.observer.disconnect(),this.observer=null),this.modules.forEach((e=>e.destroy())),this.modules=[],this.state.clear(),this.events.clear(),this.initialized=!1,b.vF.debug("Destroyed","ads")}};A.systemRegistry.registerInstance("adsSystem",zi),window.HeimGuard=window.HeimGuard||{},window.HeimGuard.adsSystem=zi;var Hi=zi;class Gi{static async initialize(){await Hi.initialize()}static async loadAd(e,t){if(!t&&!(t=document.querySelector(`HgAdModule[data-adcode="${e}"]`)))return console.warn(`No element found for adcode: ${e}`),null;const n=new Fi(t,{adcode:e});return await n.load(),n}static async refreshAll(){await Hi.refreshAll()}static async refreshAd(e){await Hi.refreshAd(e)}static getStatus(){return Hi.getStatus()}static createAdElement(e,t){const n=document.createElement("HgAdModule");n.setAttribute("data-adcode",e),t.appendChild(n);Fi.initializeElement(n);return n}static removeAd(e){document.querySelectorAll(`HgAdModule[data-adcode="${e}"]`).forEach((e=>{e.remove()}))}static getLoadedAds(){return Hi.getStatus().loadedAds}static isAdLoaded(e){return Hi.getStatus().loadedAds.includes(e)}}window.HeimGuard=window.HeimGuard||{},window.HeimGuard.AdsSystemAdapter=Gi,b.vF.debug("Module loaded","ads");const _i="hubspot";function Ki(){return window._hsq=window._hsq||[],window._hsq}function ji(e){if(!e?.email)return void b.vF.warn("Cannot identify user without email",_i);const t=Ki(),n={email:e.email};e.firstName&&(n.firstname=e.firstName),e.lastName&&(n.lastname=e.lastName),e.id&&(n.id=e.id),t.push(["identify",n]),t.push(["trackPageView"]),b.vF.info(`Identified user to HubSpot: ${e.email}`,_i)}function Vi(){const e=(0,J.sQ)(J.QU.LOGIN_SUCCESS,(e=>{b.vF.debug("Login success received, identifying user",_i),e.user&&ji(e.user)})),t=(0,J.sQ)(J.QU.REGISTER_SUCCESS,(e=>{e.user&&!e.requiresVerification&&(b.vF.debug("Register success (auto-login) received, identifying user",_i),ji(e.user))})),n=(0,J.sQ)(J.QU.SESSION_VALID,(e=>{b.vF.debug("Session valid received, identifying user",_i);const t=e.user;t?.email&&ji(t)})),o=(0,J.sQ)(J.QU.LOGOUT_SUCCESS,(()=>{b.vF.debug("Logout success received, clearing identity",_i),Ki().push(["revokeCookieConsent"]),b.vF.info("Cleared HubSpot identity",_i)}));return()=>{e(),t(),n(),o()}}let qi=null;qi?b.vF.warn("HubSpot identity tracking already initialized",_i):(async function(){if(document.getElementById("hs-script-loader"))b.vF.debug("HubSpot tracking script already loaded",_i);else try{const e=await v.initService.getInitData(),t=e?.hubspotConfig?.portalId;if(!t)return void b.vF.debug("No HubSpot portal ID configured, skipping script load",_i);const n=document.createElement("script");n.id="hs-script-loader",n.type="text/javascript",n.async=!0,n.defer=!0,n.src=`//js.hs-scripts.com/${t}.js`,document.head.appendChild(n),b.vF.info(`HubSpot tracking script loaded for portal: ${t}`,_i)}catch(e){b.vF.error("Failed to load HubSpot tracking script",_i,e)}}(),qi=Vi(),b.vF.debug("HubSpot identity tracking initialized",_i)),b.vF.debug("Module loaded","hubspot"),C.then((()=>{b.vF.info("Initializing 401 handler...","init"),T.initialize().then((()=>{b.vF.info("401 handler initialized with settings","init"),T.setupEventListener(),T.setupFetchInterceptor()})).catch((e=>{b.vF.error("Failed to initialize 401 handler:","init",e),T.setupEventListener(),T.setupFetchInterceptor()}))}));const Wi={namespace:"HeimGuard",debug:!1,features:{emailVerification:!0,affinity:!0}};C.then((async()=>{window.systemRegistry=A.systemRegistry;try{if(await(async()=>{b.vF.info("ð Initializing SystemRegistry services...","init");try{await A.systemRegistry.initializeAll(),b.vF.info("â SystemRegistry services initialized","init")}catch(e){b.vF.error("â Failed to initialize SystemRegistry services:","init",e)}})(),await(async()=>{try{await T.initialize(),T.setupEventListener(),T.setupFetchInterceptor(),window[Wi.namespace].global401Handler=T,b.vF.info("â Global 401 Handler initialized","init")}catch(e){b.vF.error("Failed to initialize global 401 handler:","init",e)}const e=new x;window[Wi.namespace].DynamicHeaderNav=e,b.vF.info("â DynamicHeaderNav initialized","init"),window[Wi.namespace].themeManager=E,b.vF.info("â ThemeManager initialized","init"),Wi.features.emailVerification&&(window[Wi.namespace].verificationHandler=new L,b.vF.info("â EnhancedVerificationHandler initialized","init")),Wi.debug&&b.vF.info("â ModuleTypeTracker initialized","init"),Li.loadFromInit(),b.vF.info("â BannerModule initialized","init");const t=A.systemRegistry.getStatus();b.vF.debug("â SystemRegistry modules:","init",t),b.vF.debug("â AuthSystem initialized:","init",A.systemRegistry.has("authSystem")),b.vF.debug("â ProfileSystem initialized:","init",A.systemRegistry.has("profileSystem")),b.vF.debug("â PaymentSystem initialized:","init",A.systemRegistry.has("paymentSystem")),b.vF.debug("â SubscriptionsSystem initialized:","init",A.systemRegistry.has("subscriptionsSystem")),b.vF.debug("â AccessWallSystem initialized:","init",A.systemRegistry.has("accessWallSystem")),b.vF.debug("â AffinitySystem initialized:","init",!!window[Wi.namespace].affinitySystem)})(),b.vF.info("ð HeimGuard application initialized successfully","init"),window.dispatchEvent(new CustomEvent("heimguard:ready",{detail:{modules:Object.keys(window[Wi.namespace]),config:Wi}})),Wi.debug){const e={config:Wi,modules:{auth:!!window[Wi.namespace].authSystem,profile:!!window[Wi.namespace].profileSystem,affinity:!!window[Wi.namespace].affinitySystem,headerNav:!!window[Wi.namespace].DynamicHeaderNav,verification:!!window[Wi.namespace].verificationHandler,banner:!!window.BannerModule},auth:window[Wi.namespace].authSystem,profile:window[Wi.namespace].profileSystem,affinity:window[Wi.namespace].affinitySystem,checkModule:e=>{const t=!!window[Wi.namespace][e],n=!!window[e];return{inNamespace:t,inWindow:n,available:t||n}}};window[Wi.namespace].debug=e,b.vF.debug("ð Debug info available at:","init",`window.${Wi.namespace}.debug`),b.vF.debug("ð Module status:","init",window[Wi.namespace].debug.modules)}}catch(e){b.vF.error("â Failed to initialize HeimGuard application:","init",e),window.dispatchEvent(new CustomEvent("heimguard:error",{detail:{error:e.message}}))}}))}()}(); 2//# sourceMappingURL=all.min.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.