Files
Addon-Odoo19/.odoo-data/filestore/odoo19/23/233e634f857ca165474f2553ab7f86de756bd2b5
T
2026-05-31 10:17:09 +07:00

10455 lines
1.7 MiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* /web/static/lib/luxon/luxon.js */
var luxon=(function(exports){'use strict';function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,_toPropertyKey(descriptor.key),descriptor);}}
function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}
function _extends(){_extends=Object.assign?Object.assign.bind():function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}
return target;};return _extends.apply(this,arguments);}
function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;_setPrototypeOf(subClass,superClass);}
function _getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf.bind():function _getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o);};return _getPrototypeOf(o);}
function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}
function _isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));return true;}catch(e){return false;}}
function _construct(Parent,args,Class){if(_isNativeReflectConstruct()){_construct=Reflect.construct.bind();}else{_construct=function _construct(Parent,args,Class){var a=[null];a.push.apply(a,args);var Constructor=Function.bind.apply(Parent,a);var instance=new Constructor();if(Class)_setPrototypeOf(instance,Class.prototype);return instance;};}
return _construct.apply(null,arguments);}
function _isNativeFunction(fn){return Function.toString.call(fn).indexOf("[native code]")!==-1;}
function _wrapNativeSuper(Class){var _cache=typeof Map==="function"?new Map():undefined;_wrapNativeSuper=function _wrapNativeSuper(Class){if(Class===null||!_isNativeFunction(Class))return Class;if(typeof Class!=="function"){throw new TypeError("Super expression must either be null or a function");}
if(typeof _cache!=="undefined"){if(_cache.has(Class))return _cache.get(Class);_cache.set(Class,Wrapper);}
function Wrapper(){return _construct(Class,arguments,_getPrototypeOf(this).constructor);}
Wrapper.prototype=Object.create(Class.prototype,{constructor:{value:Wrapper,enumerable:false,writable:true,configurable:true}});return _setPrototypeOf(Wrapper,Class);};return _wrapNativeSuper(Class);}
function _objectWithoutPropertiesLoose(source,excluded){if(source==null)return{};var target={};var sourceKeys=Object.keys(source);var key,i;for(i=0;i<sourceKeys.length;i++){key=sourceKeys[i];if(excluded.indexOf(key)>=0)continue;target[key]=source[key];}
return target;}
function _unsupportedIterableToArray(o,minLen){if(!o)return;if(typeof o==="string")return _arrayLikeToArray(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(o);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _arrayLikeToArray(o,minLen);}
function _arrayLikeToArray(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2;}
function _createForOfIteratorHelperLoose(o,allowArrayLike){var it=typeof Symbol!=="undefined"&&o[Symbol.iterator]||o["@@iterator"];if(it)return(it=it.call(o)).next.bind(it);if(Array.isArray(o)||(it=_unsupportedIterableToArray(o))||allowArrayLike&&o&&typeof o.length==="number"){if(it)o=it;var i=0;return function(){if(i>=o.length)return{done:true};return{done:false,value:o[i++]};};}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}
function _toPrimitive(input,hint){if(typeof input!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(typeof res!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}
return(hint==="string"?String:Number)(input);}
function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return typeof key==="symbol"?key:String(key);}
var LuxonError=function(_Error){_inheritsLoose(LuxonError,_Error);function LuxonError(){return _Error.apply(this,arguments)||this;}
return LuxonError;}(_wrapNativeSuper(Error));var InvalidDateTimeError=function(_LuxonError){_inheritsLoose(InvalidDateTimeError,_LuxonError);function InvalidDateTimeError(reason){return _LuxonError.call(this,"Invalid DateTime: "+reason.toMessage())||this;}
return InvalidDateTimeError;}(LuxonError);var InvalidIntervalError=function(_LuxonError2){_inheritsLoose(InvalidIntervalError,_LuxonError2);function InvalidIntervalError(reason){return _LuxonError2.call(this,"Invalid Interval: "+reason.toMessage())||this;}
return InvalidIntervalError;}(LuxonError);var InvalidDurationError=function(_LuxonError3){_inheritsLoose(InvalidDurationError,_LuxonError3);function InvalidDurationError(reason){return _LuxonError3.call(this,"Invalid Duration: "+reason.toMessage())||this;}
return InvalidDurationError;}(LuxonError);var ConflictingSpecificationError=function(_LuxonError4){_inheritsLoose(ConflictingSpecificationError,_LuxonError4);function ConflictingSpecificationError(){return _LuxonError4.apply(this,arguments)||this;}
return ConflictingSpecificationError;}(LuxonError);var InvalidUnitError=function(_LuxonError5){_inheritsLoose(InvalidUnitError,_LuxonError5);function InvalidUnitError(unit){return _LuxonError5.call(this,"Invalid unit "+unit)||this;}
return InvalidUnitError;}(LuxonError);var InvalidArgumentError=function(_LuxonError6){_inheritsLoose(InvalidArgumentError,_LuxonError6);function InvalidArgumentError(){return _LuxonError6.apply(this,arguments)||this;}
return InvalidArgumentError;}(LuxonError);var ZoneIsAbstractError=function(_LuxonError7){_inheritsLoose(ZoneIsAbstractError,_LuxonError7);function ZoneIsAbstractError(){return _LuxonError7.call(this,"Zone is an abstract class")||this;}
return ZoneIsAbstractError;}(LuxonError);var n="numeric",s="short",l="long";var DATE_SHORT={year:n,month:n,day:n};var DATE_MED={year:n,month:s,day:n};var DATE_MED_WITH_WEEKDAY={year:n,month:s,day:n,weekday:s};var DATE_FULL={year:n,month:l,day:n};var DATE_HUGE={year:n,month:l,day:n,weekday:l};var TIME_SIMPLE={hour:n,minute:n};var TIME_WITH_SECONDS={hour:n,minute:n,second:n};var TIME_WITH_SHORT_OFFSET={hour:n,minute:n,second:n,timeZoneName:s};var TIME_WITH_LONG_OFFSET={hour:n,minute:n,second:n,timeZoneName:l};var TIME_24_SIMPLE={hour:n,minute:n,hourCycle:"h23"};var TIME_24_WITH_SECONDS={hour:n,minute:n,second:n,hourCycle:"h23"};var TIME_24_WITH_SHORT_OFFSET={hour:n,minute:n,second:n,hourCycle:"h23",timeZoneName:s};var TIME_24_WITH_LONG_OFFSET={hour:n,minute:n,second:n,hourCycle:"h23",timeZoneName:l};var DATETIME_SHORT={year:n,month:n,day:n,hour:n,minute:n};var DATETIME_SHORT_WITH_SECONDS={year:n,month:n,day:n,hour:n,minute:n,second:n};var DATETIME_MED={year:n,month:s,day:n,hour:n,minute:n};var DATETIME_MED_WITH_SECONDS={year:n,month:s,day:n,hour:n,minute:n,second:n};var DATETIME_MED_WITH_WEEKDAY={year:n,month:s,day:n,weekday:s,hour:n,minute:n};var DATETIME_FULL={year:n,month:l,day:n,hour:n,minute:n,timeZoneName:s};var DATETIME_FULL_WITH_SECONDS={year:n,month:l,day:n,hour:n,minute:n,second:n,timeZoneName:s};var DATETIME_HUGE={year:n,month:l,day:n,weekday:l,hour:n,minute:n,timeZoneName:l};var DATETIME_HUGE_WITH_SECONDS={year:n,month:l,day:n,weekday:l,hour:n,minute:n,second:n,timeZoneName:l};var Zone=function(){function Zone(){}
var _proto=Zone.prototype;_proto.offsetName=function offsetName(ts,opts){throw new ZoneIsAbstractError();};_proto.formatOffset=function formatOffset(ts,format){throw new ZoneIsAbstractError();};_proto.offset=function offset(ts){throw new ZoneIsAbstractError();};_proto.equals=function equals(otherZone){throw new ZoneIsAbstractError();};_createClass(Zone,[{key:"type",get:function get(){throw new ZoneIsAbstractError();}},{key:"name",get:function get(){throw new ZoneIsAbstractError();}},{key:"ianaName",get:function get(){return this.name;}},{key:"isUniversal",get:function get(){throw new ZoneIsAbstractError();}},{key:"isValid",get:function get(){throw new ZoneIsAbstractError();}}]);return Zone;}();var singleton$1=null;var SystemZone=function(_Zone){_inheritsLoose(SystemZone,_Zone);function SystemZone(){return _Zone.apply(this,arguments)||this;}
var _proto=SystemZone.prototype;_proto.offsetName=function offsetName(ts,_ref){var format=_ref.format,locale=_ref.locale;return parseZoneInfo(ts,format,locale);};_proto.formatOffset=function formatOffset$1(ts,format){return formatOffset(this.offset(ts),format);};_proto.offset=function offset(ts){return-new Date(ts).getTimezoneOffset();};_proto.equals=function equals(otherZone){return otherZone.type==="system";};_createClass(SystemZone,[{key:"type",get:function get(){return"system";}},{key:"name",get:function get(){return new Intl.DateTimeFormat().resolvedOptions().timeZone;}},{key:"isUniversal",get:function get(){return false;}},{key:"isValid",get:function get(){return true;}}],[{key:"instance",get:function get(){if(singleton$1===null){singleton$1=new SystemZone();}
return singleton$1;}}]);return SystemZone;}(Zone);var dtfCache={};function makeDTF(zone){if(!dtfCache[zone]){dtfCache[zone]=new Intl.DateTimeFormat("en-US",{hour12:false,timeZone:zone,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",era:"short"});}
return dtfCache[zone];}
var typeToPos={year:0,month:1,day:2,era:3,hour:4,minute:5,second:6};function hackyOffset(dtf,date){var formatted=dtf.format(date).replace(/\u200E/g,""),parsed=/(\d+)\/(\d+)\/(\d+) (AD|BC),? (\d+):(\d+):(\d+)/.exec(formatted),fMonth=parsed[1],fDay=parsed[2],fYear=parsed[3],fadOrBc=parsed[4],fHour=parsed[5],fMinute=parsed[6],fSecond=parsed[7];return[fYear,fMonth,fDay,fadOrBc,fHour,fMinute,fSecond];}
function partsOffset(dtf,date){var formatted=dtf.formatToParts(date);var filled=[];for(var i=0;i<formatted.length;i++){var _formatted$i=formatted[i],type=_formatted$i.type,value=_formatted$i.value;var pos=typeToPos[type];if(type==="era"){filled[pos]=value;}else if(!isUndefined(pos)){filled[pos]=parseInt(value,10);}}
return filled;}
var ianaZoneCache={};var IANAZone=function(_Zone){_inheritsLoose(IANAZone,_Zone);IANAZone.create=function create(name){if(!ianaZoneCache[name]){ianaZoneCache[name]=new IANAZone(name);}
return ianaZoneCache[name];};IANAZone.resetCache=function resetCache(){ianaZoneCache={};dtfCache={};};IANAZone.isValidSpecifier=function isValidSpecifier(s){return this.isValidZone(s);};IANAZone.isValidZone=function isValidZone(zone){if(!zone){return false;}
try{new Intl.DateTimeFormat("en-US",{timeZone:zone}).format();return true;}catch(e){return false;}};function IANAZone(name){var _this;_this=_Zone.call(this)||this;_this.zoneName=name;_this.valid=IANAZone.isValidZone(name);return _this;}
var _proto=IANAZone.prototype;_proto.offsetName=function offsetName(ts,_ref){var format=_ref.format,locale=_ref.locale;return parseZoneInfo(ts,format,locale,this.name);};_proto.formatOffset=function formatOffset$1(ts,format){return formatOffset(this.offset(ts),format);};_proto.offset=function offset(ts){var date=new Date(ts);if(isNaN(date))return NaN;var dtf=makeDTF(this.name);var _ref2=dtf.formatToParts?partsOffset(dtf,date):hackyOffset(dtf,date),year=_ref2[0],month=_ref2[1],day=_ref2[2],adOrBc=_ref2[3],hour=_ref2[4],minute=_ref2[5],second=_ref2[6];if(adOrBc==="BC"){year=-Math.abs(year)+1;}
var adjustedHour=hour===24?0:hour;var asUTC=objToLocalTS({year:year,month:month,day:day,hour:adjustedHour,minute:minute,second:second,millisecond:0});var asTS=+date;var over=asTS%1000;asTS-=over>=0?over:1000+over;return(asUTC-asTS)/(60*1000);};_proto.equals=function equals(otherZone){return otherZone.type==="iana"&&otherZone.name===this.name;};_createClass(IANAZone,[{key:"type",get:function get(){return"iana";}},{key:"name",get:function get(){return this.zoneName;}},{key:"isUniversal",get:function get(){return false;}},{key:"isValid",get:function get(){return this.valid;}}]);return IANAZone;}(Zone);var _excluded=["base"],_excluded2=["padTo","floor"];var intlLFCache={};function getCachedLF(locString,opts){if(opts===void 0){opts={};}
var key=JSON.stringify([locString,opts]);var dtf=intlLFCache[key];if(!dtf){dtf=new Intl.ListFormat(locString,opts);intlLFCache[key]=dtf;}
return dtf;}
var intlDTCache={};function getCachedDTF(locString,opts){if(opts===void 0){opts={};}
var key=JSON.stringify([locString,opts]);var dtf=intlDTCache[key];if(!dtf){dtf=new Intl.DateTimeFormat(locString,opts);intlDTCache[key]=dtf;}
return dtf;}
var intlNumCache={};function getCachedINF(locString,opts){if(opts===void 0){opts={};}
var key=JSON.stringify([locString,opts]);var inf=intlNumCache[key];if(!inf){inf=new Intl.NumberFormat(locString,opts);intlNumCache[key]=inf;}
return inf;}
var intlRelCache={};function getCachedRTF(locString,opts){if(opts===void 0){opts={};}
var _opts=opts;_opts.base;var cacheKeyOpts=_objectWithoutPropertiesLoose(_opts,_excluded);var key=JSON.stringify([locString,cacheKeyOpts]);var inf=intlRelCache[key];if(!inf){inf=new Intl.RelativeTimeFormat(locString,opts);intlRelCache[key]=inf;}
return inf;}
var sysLocaleCache=null;function systemLocale(){if(sysLocaleCache){return sysLocaleCache;}else{sysLocaleCache=new Intl.DateTimeFormat().resolvedOptions().locale;return sysLocaleCache;}}
var weekInfoCache={};function getCachedWeekInfo(locString){var data=weekInfoCache[locString];if(!data){var locale=new Intl.Locale(locString);data="getWeekInfo"in locale?locale.getWeekInfo():locale.weekInfo;weekInfoCache[locString]=data;}
return data;}
function parseLocaleString(localeStr){var xIndex=localeStr.indexOf("-x-");if(xIndex!==-1){localeStr=localeStr.substring(0,xIndex);}
var uIndex=localeStr.indexOf("-u-");if(uIndex===-1){return[localeStr];}else{var options;var selectedStr;try{options=getCachedDTF(localeStr).resolvedOptions();selectedStr=localeStr;}catch(e){var smaller=localeStr.substring(0,uIndex);options=getCachedDTF(smaller).resolvedOptions();selectedStr=smaller;}
var _options=options,numberingSystem=_options.numberingSystem,calendar=_options.calendar;return[selectedStr,numberingSystem,calendar];}}
function intlConfigString(localeStr,numberingSystem,outputCalendar){if(outputCalendar||numberingSystem){if(!localeStr.includes("-u-")){localeStr+="-u";}
if(outputCalendar){localeStr+="-ca-"+outputCalendar;}
if(numberingSystem){localeStr+="-nu-"+numberingSystem;}
return localeStr;}else{return localeStr;}}
function mapMonths(f){var ms=[];for(var i=1;i<=12;i++){var dt=DateTime.utc(2009,i,1);ms.push(f(dt));}
return ms;}
function mapWeekdays(f){var ms=[];for(var i=1;i<=7;i++){var dt=DateTime.utc(2016,11,13+i);ms.push(f(dt));}
return ms;}
function listStuff(loc,length,englishFn,intlFn){var mode=loc.listingMode();if(mode==="error"){return null;}else if(mode==="en"){return englishFn(length);}else{return intlFn(length);}}
function supportsFastNumbers(loc){if(loc.numberingSystem&&loc.numberingSystem!=="latn"){return false;}else{return loc.numberingSystem==="latn"||!loc.locale||loc.locale.startsWith("en")||new Intl.DateTimeFormat(loc.intl).resolvedOptions().numberingSystem==="latn";}}
var PolyNumberFormatter=function(){function PolyNumberFormatter(intl,forceSimple,opts){this.padTo=opts.padTo||0;this.floor=opts.floor||false;opts.padTo;opts.floor;var otherOpts=_objectWithoutPropertiesLoose(opts,_excluded2);if(!forceSimple||Object.keys(otherOpts).length>0){var intlOpts=_extends({useGrouping:false},opts);if(opts.padTo>0)intlOpts.minimumIntegerDigits=opts.padTo;this.inf=getCachedINF(intl,intlOpts);}}
var _proto=PolyNumberFormatter.prototype;_proto.format=function format(i){if(this.inf){var fixed=this.floor?Math.floor(i):i;return this.inf.format(fixed);}else{var _fixed=this.floor?Math.floor(i):roundTo(i,3);return padStart(_fixed,this.padTo);}};return PolyNumberFormatter;}();var PolyDateFormatter=function(){function PolyDateFormatter(dt,intl,opts){this.opts=opts;this.originalZone=undefined;var z=undefined;if(this.opts.timeZone){this.dt=dt;}else if(dt.zone.type==="fixed"){var gmtOffset=-1*(dt.offset/60);var offsetZ=gmtOffset>=0?"Etc/GMT+"+gmtOffset:"Etc/GMT"+gmtOffset;if(dt.offset!==0&&IANAZone.create(offsetZ).valid){z=offsetZ;this.dt=dt;}else{z="UTC";this.dt=dt.offset===0?dt:dt.setZone("UTC").plus({minutes:dt.offset});this.originalZone=dt.zone;}}else if(dt.zone.type==="system"){this.dt=dt;}else if(dt.zone.type==="iana"){this.dt=dt;z=dt.zone.name;}else{z="UTC";this.dt=dt.setZone("UTC").plus({minutes:dt.offset});this.originalZone=dt.zone;}
var intlOpts=_extends({},this.opts);intlOpts.timeZone=intlOpts.timeZone||z;this.dtf=getCachedDTF(intl,intlOpts);}
var _proto2=PolyDateFormatter.prototype;_proto2.format=function format(){if(this.originalZone){return this.formatToParts().map(function(_ref){var value=_ref.value;return value;}).join("");}
return this.dtf.format(this.dt.toJSDate());};_proto2.formatToParts=function formatToParts(){var _this=this;var parts=this.dtf.formatToParts(this.dt.toJSDate());if(this.originalZone){return parts.map(function(part){if(part.type==="timeZoneName"){var offsetName=_this.originalZone.offsetName(_this.dt.ts,{locale:_this.dt.locale,format:_this.opts.timeZoneName});return _extends({},part,{value:offsetName});}else{return part;}});}
return parts;};_proto2.resolvedOptions=function resolvedOptions(){return this.dtf.resolvedOptions();};return PolyDateFormatter;}();var PolyRelFormatter=function(){function PolyRelFormatter(intl,isEnglish,opts){this.opts=_extends({style:"long"},opts);if(!isEnglish&&hasRelative()){this.rtf=getCachedRTF(intl,opts);}}
var _proto3=PolyRelFormatter.prototype;_proto3.format=function format(count,unit){if(this.rtf){return this.rtf.format(count,unit);}else{return formatRelativeTime(unit,count,this.opts.numeric,this.opts.style!=="long");}};_proto3.formatToParts=function formatToParts(count,unit){if(this.rtf){return this.rtf.formatToParts(count,unit);}else{return[];}};return PolyRelFormatter;}();var fallbackWeekSettings={firstDay:1,minimalDays:4,weekend:[6,7]};var Locale=function(){Locale.fromOpts=function fromOpts(opts){return Locale.create(opts.locale,opts.numberingSystem,opts.outputCalendar,opts.weekSettings,opts.defaultToEN);};Locale.create=function create(locale,numberingSystem,outputCalendar,weekSettings,defaultToEN){if(defaultToEN===void 0){defaultToEN=false;}
var specifiedLocale=locale||Settings.defaultLocale;var localeR=specifiedLocale||(defaultToEN?"en-US":systemLocale());var numberingSystemR=numberingSystem||Settings.defaultNumberingSystem;var outputCalendarR=outputCalendar||Settings.defaultOutputCalendar;var weekSettingsR=validateWeekSettings(weekSettings)||Settings.defaultWeekSettings;return new Locale(localeR,numberingSystemR,outputCalendarR,weekSettingsR,specifiedLocale);};Locale.resetCache=function resetCache(){sysLocaleCache=null;intlDTCache={};intlNumCache={};intlRelCache={};};Locale.fromObject=function fromObject(_temp){var _ref2=_temp===void 0?{}:_temp,locale=_ref2.locale,numberingSystem=_ref2.numberingSystem,outputCalendar=_ref2.outputCalendar,weekSettings=_ref2.weekSettings;return Locale.create(locale,numberingSystem,outputCalendar,weekSettings);};function Locale(locale,numbering,outputCalendar,weekSettings,specifiedLocale){var _parseLocaleString=parseLocaleString(locale),parsedLocale=_parseLocaleString[0],parsedNumberingSystem=_parseLocaleString[1],parsedOutputCalendar=_parseLocaleString[2];this.locale=parsedLocale;this.numberingSystem=numbering||parsedNumberingSystem||null;this.outputCalendar=outputCalendar||parsedOutputCalendar||null;this.weekSettings=weekSettings;this.intl=intlConfigString(this.locale,this.numberingSystem,this.outputCalendar);this.weekdaysCache={format:{},standalone:{}};this.monthsCache={format:{},standalone:{}};this.meridiemCache=null;this.eraCache={};this.specifiedLocale=specifiedLocale;this.fastNumbersCached=null;}
var _proto4=Locale.prototype;_proto4.listingMode=function listingMode(){var isActuallyEn=this.isEnglish();var hasNoWeirdness=(this.numberingSystem===null||this.numberingSystem==="latn")&&(this.outputCalendar===null||this.outputCalendar==="gregory");return isActuallyEn&&hasNoWeirdness?"en":"intl";};_proto4.clone=function clone(alts){if(!alts||Object.getOwnPropertyNames(alts).length===0){return this;}else{return Locale.create(alts.locale||this.specifiedLocale,alts.numberingSystem||this.numberingSystem,alts.outputCalendar||this.outputCalendar,validateWeekSettings(alts.weekSettings)||this.weekSettings,alts.defaultToEN||false);}};_proto4.redefaultToEN=function redefaultToEN(alts){if(alts===void 0){alts={};}
return this.clone(_extends({},alts,{defaultToEN:true}));};_proto4.redefaultToSystem=function redefaultToSystem(alts){if(alts===void 0){alts={};}
return this.clone(_extends({},alts,{defaultToEN:false}));};_proto4.months=function months$1(length,format){var _this2=this;if(format===void 0){format=false;}
return listStuff(this,length,months,function(){var intl=format?{month:length,day:"numeric"}:{month:length},formatStr=format?"format":"standalone";if(!_this2.monthsCache[formatStr][length]){_this2.monthsCache[formatStr][length]=mapMonths(function(dt){return _this2.extract(dt,intl,"month");});}
return _this2.monthsCache[formatStr][length];});};_proto4.weekdays=function weekdays$1(length,format){var _this3=this;if(format===void 0){format=false;}
return listStuff(this,length,weekdays,function(){var intl=format?{weekday:length,year:"numeric",month:"long",day:"numeric"}:{weekday:length},formatStr=format?"format":"standalone";if(!_this3.weekdaysCache[formatStr][length]){_this3.weekdaysCache[formatStr][length]=mapWeekdays(function(dt){return _this3.extract(dt,intl,"weekday");});}
return _this3.weekdaysCache[formatStr][length];});};_proto4.meridiems=function meridiems$1(){var _this4=this;return listStuff(this,undefined,function(){return meridiems;},function(){if(!_this4.meridiemCache){var intl={hour:"numeric",hourCycle:"h12"};_this4.meridiemCache=[DateTime.utc(2016,11,13,9),DateTime.utc(2016,11,13,19)].map(function(dt){return _this4.extract(dt,intl,"dayperiod");});}
return _this4.meridiemCache;});};_proto4.eras=function eras$1(length){var _this5=this;return listStuff(this,length,eras,function(){var intl={era:length};if(!_this5.eraCache[length]){_this5.eraCache[length]=[DateTime.utc(-40,1,1),DateTime.utc(2017,1,1)].map(function(dt){return _this5.extract(dt,intl,"era");});}
return _this5.eraCache[length];});};_proto4.extract=function extract(dt,intlOpts,field){var df=this.dtFormatter(dt,intlOpts),results=df.formatToParts(),matching=results.find(function(m){return m.type.toLowerCase()===field;});return matching?matching.value:null;};_proto4.numberFormatter=function numberFormatter(opts){if(opts===void 0){opts={};}
return new PolyNumberFormatter(this.intl,opts.forceSimple||this.fastNumbers,opts);};_proto4.dtFormatter=function dtFormatter(dt,intlOpts){if(intlOpts===void 0){intlOpts={};}
return new PolyDateFormatter(dt,this.intl,intlOpts);};_proto4.relFormatter=function relFormatter(opts){if(opts===void 0){opts={};}
return new PolyRelFormatter(this.intl,this.isEnglish(),opts);};_proto4.listFormatter=function listFormatter(opts){if(opts===void 0){opts={};}
return getCachedLF(this.intl,opts);};_proto4.isEnglish=function isEnglish(){return this.locale==="en"||this.locale.toLowerCase()==="en-us"||new Intl.DateTimeFormat(this.intl).resolvedOptions().locale.startsWith("en-us");};_proto4.getWeekSettings=function getWeekSettings(){if(this.weekSettings){return this.weekSettings;}else if(!hasLocaleWeekInfo()){return fallbackWeekSettings;}else{return getCachedWeekInfo(this.locale);}};_proto4.getStartOfWeek=function getStartOfWeek(){return this.getWeekSettings().firstDay;};_proto4.getMinDaysInFirstWeek=function getMinDaysInFirstWeek(){return this.getWeekSettings().minimalDays;};_proto4.getWeekendDays=function getWeekendDays(){return this.getWeekSettings().weekend;};_proto4.equals=function equals(other){return this.locale===other.locale&&this.numberingSystem===other.numberingSystem&&this.outputCalendar===other.outputCalendar;};_proto4.toString=function toString(){return"Locale("+this.locale+", "+this.numberingSystem+", "+this.outputCalendar+")";};_createClass(Locale,[{key:"fastNumbers",get:function get(){if(this.fastNumbersCached==null){this.fastNumbersCached=supportsFastNumbers(this);}
return this.fastNumbersCached;}}]);return Locale;}();var singleton=null;var FixedOffsetZone=function(_Zone){_inheritsLoose(FixedOffsetZone,_Zone);FixedOffsetZone.instance=function instance(offset){return offset===0?FixedOffsetZone.utcInstance:new FixedOffsetZone(offset);};FixedOffsetZone.parseSpecifier=function parseSpecifier(s){if(s){var r=s.match(/^utc(?:([+-]\d{1,2})(?::(\d{2}))?)?$/i);if(r){return new FixedOffsetZone(signedOffset(r[1],r[2]));}}
return null;};function FixedOffsetZone(offset){var _this;_this=_Zone.call(this)||this;_this.fixed=offset;return _this;}
var _proto=FixedOffsetZone.prototype;_proto.offsetName=function offsetName(){return this.name;};_proto.formatOffset=function formatOffset$1(ts,format){return formatOffset(this.fixed,format);};_proto.offset=function offset(){return this.fixed;};_proto.equals=function equals(otherZone){return otherZone.type==="fixed"&&otherZone.fixed===this.fixed;};_createClass(FixedOffsetZone,[{key:"type",get:function get(){return"fixed";}},{key:"name",get:function get(){return this.fixed===0?"UTC":"UTC"+formatOffset(this.fixed,"narrow");}},{key:"ianaName",get:function get(){if(this.fixed===0){return"Etc/UTC";}else{return"Etc/GMT"+formatOffset(-this.fixed,"narrow");}}},{key:"isUniversal",get:function get(){return true;}},{key:"isValid",get:function get(){return true;}}],[{key:"utcInstance",get:function get(){if(singleton===null){singleton=new FixedOffsetZone(0);}
return singleton;}}]);return FixedOffsetZone;}(Zone);var InvalidZone=function(_Zone){_inheritsLoose(InvalidZone,_Zone);function InvalidZone(zoneName){var _this;_this=_Zone.call(this)||this;_this.zoneName=zoneName;return _this;}
var _proto=InvalidZone.prototype;_proto.offsetName=function offsetName(){return null;};_proto.formatOffset=function formatOffset(){return"";};_proto.offset=function offset(){return NaN;};_proto.equals=function equals(){return false;};_createClass(InvalidZone,[{key:"type",get:function get(){return"invalid";}},{key:"name",get:function get(){return this.zoneName;}},{key:"isUniversal",get:function get(){return false;}},{key:"isValid",get:function get(){return false;}}]);return InvalidZone;}(Zone);function normalizeZone(input,defaultZone){if(isUndefined(input)||input===null){return defaultZone;}else if(input instanceof Zone){return input;}else if(isString(input)){var lowered=input.toLowerCase();if(lowered==="default")return defaultZone;else if(lowered==="local"||lowered==="system")return SystemZone.instance;else if(lowered==="utc"||lowered==="gmt")return FixedOffsetZone.utcInstance;else return FixedOffsetZone.parseSpecifier(lowered)||IANAZone.create(input);}else if(isNumber(input)){return FixedOffsetZone.instance(input);}else if(typeof input==="object"&&"offset"in input&&typeof input.offset==="function"){return input;}else{return new InvalidZone(input);}}
var numberingSystems={arab:"[\u0660-\u0669]",arabext:"[\u06F0-\u06F9]",bali:"[\u1B50-\u1B59]",beng:"[\u09E6-\u09EF]",deva:"[\u0966-\u096F]",fullwide:"[\uFF10-\uFF19]",gujr:"[\u0AE6-\u0AEF]",hanidec:"[|一|二|三|四|五|六|七|八|九]",khmr:"[\u17E0-\u17E9]",knda:"[\u0CE6-\u0CEF]",laoo:"[\u0ED0-\u0ED9]",limb:"[\u1946-\u194F]",mlym:"[\u0D66-\u0D6F]",mong:"[\u1810-\u1819]",mymr:"[\u1040-\u1049]",orya:"[\u0B66-\u0B6F]",tamldec:"[\u0BE6-\u0BEF]",telu:"[\u0C66-\u0C6F]",thai:"[\u0E50-\u0E59]",tibt:"[\u0F20-\u0F29]",latn:"\\d"};var numberingSystemsUTF16={arab:[1632,1641],arabext:[1776,1785],bali:[6992,7001],beng:[2534,2543],deva:[2406,2415],fullwide:[65296,65303],gujr:[2790,2799],khmr:[6112,6121],knda:[3302,3311],laoo:[3792,3801],limb:[6470,6479],mlym:[3430,3439],mong:[6160,6169],mymr:[4160,4169],orya:[2918,2927],tamldec:[3046,3055],telu:[3174,3183],thai:[3664,3673],tibt:[3872,3881]};var hanidecChars=numberingSystems.hanidec.replace(/[\[|\]]/g,"").split("");function parseDigits(str){var value=parseInt(str,10);if(isNaN(value)){value="";for(var i=0;i<str.length;i++){var code=str.charCodeAt(i);if(str[i].search(numberingSystems.hanidec)!==-1){value+=hanidecChars.indexOf(str[i]);}else{for(var key in numberingSystemsUTF16){var _numberingSystemsUTF=numberingSystemsUTF16[key],min=_numberingSystemsUTF[0],max=_numberingSystemsUTF[1];if(code>=min&&code<=max){value+=code-min;}}}}
return parseInt(value,10);}else{return value;}}
var digitRegexCache={};function resetDigitRegexCache(){digitRegexCache={};}
function digitRegex(_ref,append){var numberingSystem=_ref.numberingSystem;if(append===void 0){append="";}
var ns=numberingSystem||"latn";if(!digitRegexCache[ns]){digitRegexCache[ns]={};}
if(!digitRegexCache[ns][append]){digitRegexCache[ns][append]=new RegExp(""+numberingSystems[ns]+append);}
return digitRegexCache[ns][append];}
var now=function now(){return Date.now();},defaultZone="system",defaultLocale=null,defaultNumberingSystem=null,defaultOutputCalendar=null,twoDigitCutoffYear=60,throwOnInvalid,defaultWeekSettings=null;var Settings=function(){function Settings(){}
Settings.resetCaches=function resetCaches(){Locale.resetCache();IANAZone.resetCache();DateTime.resetCache();resetDigitRegexCache();};_createClass(Settings,null,[{key:"now",get:function get(){return now;},set:function set(n){now=n;}},{key:"defaultZone",get:function get(){return normalizeZone(defaultZone,SystemZone.instance);},set:function set(zone){defaultZone=zone;}},{key:"defaultLocale",get:function get(){return defaultLocale;},set:function set(locale){defaultLocale=locale;}},{key:"defaultNumberingSystem",get:function get(){return defaultNumberingSystem;},set:function set(numberingSystem){defaultNumberingSystem=numberingSystem;}},{key:"defaultOutputCalendar",get:function get(){return defaultOutputCalendar;},set:function set(outputCalendar){defaultOutputCalendar=outputCalendar;}},{key:"defaultWeekSettings",get:function get(){return defaultWeekSettings;},set:function set(weekSettings){defaultWeekSettings=validateWeekSettings(weekSettings);}},{key:"twoDigitCutoffYear",get:function get(){return twoDigitCutoffYear;},set:function set(cutoffYear){twoDigitCutoffYear=cutoffYear%100;}},{key:"throwOnInvalid",get:function get(){return throwOnInvalid;},set:function set(t){throwOnInvalid=t;}}]);return Settings;}();var Invalid=function(){function Invalid(reason,explanation){this.reason=reason;this.explanation=explanation;}
var _proto=Invalid.prototype;_proto.toMessage=function toMessage(){if(this.explanation){return this.reason+": "+this.explanation;}else{return this.reason;}};return Invalid;}();var nonLeapLadder=[0,31,59,90,120,151,181,212,243,273,304,334],leapLadder=[0,31,60,91,121,152,182,213,244,274,305,335];function unitOutOfRange(unit,value){return new Invalid("unit out of range","you specified "+value+" (of type "+typeof value+") as a "+unit+", which is invalid");}
function dayOfWeek(year,month,day){var d=new Date(Date.UTC(year,month-1,day));if(year<100&&year>=0){d.setUTCFullYear(d.getUTCFullYear()-1900);}
var js=d.getUTCDay();return js===0?7:js;}
function computeOrdinal(year,month,day){return day+(isLeapYear(year)?leapLadder:nonLeapLadder)[month-1];}
function uncomputeOrdinal(year,ordinal){var table=isLeapYear(year)?leapLadder:nonLeapLadder,month0=table.findIndex(function(i){return i<ordinal;}),day=ordinal-table[month0];return{month:month0+1,day:day};}
function isoWeekdayToLocal(isoWeekday,startOfWeek){return(isoWeekday-startOfWeek+7)%7+1;}
function gregorianToWeek(gregObj,minDaysInFirstWeek,startOfWeek){if(minDaysInFirstWeek===void 0){minDaysInFirstWeek=4;}
if(startOfWeek===void 0){startOfWeek=1;}
var year=gregObj.year,month=gregObj.month,day=gregObj.day,ordinal=computeOrdinal(year,month,day),weekday=isoWeekdayToLocal(dayOfWeek(year,month,day),startOfWeek);var weekNumber=Math.floor((ordinal-weekday+14-minDaysInFirstWeek)/7),weekYear;if(weekNumber<1){weekYear=year-1;weekNumber=weeksInWeekYear(weekYear,minDaysInFirstWeek,startOfWeek);}else if(weekNumber>weeksInWeekYear(year,minDaysInFirstWeek,startOfWeek)){weekYear=year+1;weekNumber=1;}else{weekYear=year;}
return _extends({weekYear:weekYear,weekNumber:weekNumber,weekday:weekday},timeObject(gregObj));}
function weekToGregorian(weekData,minDaysInFirstWeek,startOfWeek){if(minDaysInFirstWeek===void 0){minDaysInFirstWeek=4;}
if(startOfWeek===void 0){startOfWeek=1;}
var weekYear=weekData.weekYear,weekNumber=weekData.weekNumber,weekday=weekData.weekday,weekdayOfJan4=isoWeekdayToLocal(dayOfWeek(weekYear,1,minDaysInFirstWeek),startOfWeek),yearInDays=daysInYear(weekYear);var ordinal=weekNumber*7+weekday-weekdayOfJan4-7+minDaysInFirstWeek,year;if(ordinal<1){year=weekYear-1;ordinal+=daysInYear(year);}else if(ordinal>yearInDays){year=weekYear+1;ordinal-=daysInYear(weekYear);}else{year=weekYear;}
var _uncomputeOrdinal=uncomputeOrdinal(year,ordinal),month=_uncomputeOrdinal.month,day=_uncomputeOrdinal.day;return _extends({year:year,month:month,day:day},timeObject(weekData));}
function gregorianToOrdinal(gregData){var year=gregData.year,month=gregData.month,day=gregData.day;var ordinal=computeOrdinal(year,month,day);return _extends({year:year,ordinal:ordinal},timeObject(gregData));}
function ordinalToGregorian(ordinalData){var year=ordinalData.year,ordinal=ordinalData.ordinal;var _uncomputeOrdinal2=uncomputeOrdinal(year,ordinal),month=_uncomputeOrdinal2.month,day=_uncomputeOrdinal2.day;return _extends({year:year,month:month,day:day},timeObject(ordinalData));}
function usesLocalWeekValues(obj,loc){var hasLocaleWeekData=!isUndefined(obj.localWeekday)||!isUndefined(obj.localWeekNumber)||!isUndefined(obj.localWeekYear);if(hasLocaleWeekData){var hasIsoWeekData=!isUndefined(obj.weekday)||!isUndefined(obj.weekNumber)||!isUndefined(obj.weekYear);if(hasIsoWeekData){throw new ConflictingSpecificationError("Cannot mix locale-based week fields with ISO-based week fields");}
if(!isUndefined(obj.localWeekday))obj.weekday=obj.localWeekday;if(!isUndefined(obj.localWeekNumber))obj.weekNumber=obj.localWeekNumber;if(!isUndefined(obj.localWeekYear))obj.weekYear=obj.localWeekYear;delete obj.localWeekday;delete obj.localWeekNumber;delete obj.localWeekYear;return{minDaysInFirstWeek:loc.getMinDaysInFirstWeek(),startOfWeek:loc.getStartOfWeek()};}else{return{minDaysInFirstWeek:4,startOfWeek:1};}}
function hasInvalidWeekData(obj,minDaysInFirstWeek,startOfWeek){if(minDaysInFirstWeek===void 0){minDaysInFirstWeek=4;}
if(startOfWeek===void 0){startOfWeek=1;}
var validYear=isInteger(obj.weekYear),validWeek=integerBetween(obj.weekNumber,1,weeksInWeekYear(obj.weekYear,minDaysInFirstWeek,startOfWeek)),validWeekday=integerBetween(obj.weekday,1,7);if(!validYear){return unitOutOfRange("weekYear",obj.weekYear);}else if(!validWeek){return unitOutOfRange("week",obj.weekNumber);}else if(!validWeekday){return unitOutOfRange("weekday",obj.weekday);}else return false;}
function hasInvalidOrdinalData(obj){var validYear=isInteger(obj.year),validOrdinal=integerBetween(obj.ordinal,1,daysInYear(obj.year));if(!validYear){return unitOutOfRange("year",obj.year);}else if(!validOrdinal){return unitOutOfRange("ordinal",obj.ordinal);}else return false;}
function hasInvalidGregorianData(obj){var validYear=isInteger(obj.year),validMonth=integerBetween(obj.month,1,12),validDay=integerBetween(obj.day,1,daysInMonth(obj.year,obj.month));if(!validYear){return unitOutOfRange("year",obj.year);}else if(!validMonth){return unitOutOfRange("month",obj.month);}else if(!validDay){return unitOutOfRange("day",obj.day);}else return false;}
function hasInvalidTimeData(obj){var hour=obj.hour,minute=obj.minute,second=obj.second,millisecond=obj.millisecond;var validHour=integerBetween(hour,0,23)||hour===24&&minute===0&&second===0&&millisecond===0,validMinute=integerBetween(minute,0,59),validSecond=integerBetween(second,0,59),validMillisecond=integerBetween(millisecond,0,999);if(!validHour){return unitOutOfRange("hour",hour);}else if(!validMinute){return unitOutOfRange("minute",minute);}else if(!validSecond){return unitOutOfRange("second",second);}else if(!validMillisecond){return unitOutOfRange("millisecond",millisecond);}else return false;}
function isUndefined(o){return typeof o==="undefined";}
function isNumber(o){return typeof o==="number";}
function isInteger(o){return typeof o==="number"&&o%1===0;}
function isString(o){return typeof o==="string";}
function isDate(o){return Object.prototype.toString.call(o)==="[object Date]";}
function hasRelative(){try{return typeof Intl!=="undefined"&&!!Intl.RelativeTimeFormat;}catch(e){return false;}}
function hasLocaleWeekInfo(){try{return typeof Intl!=="undefined"&&!!Intl.Locale&&("weekInfo"in Intl.Locale.prototype||"getWeekInfo"in Intl.Locale.prototype);}catch(e){return false;}}
function maybeArray(thing){return Array.isArray(thing)?thing:[thing];}
function bestBy(arr,by,compare){if(arr.length===0){return undefined;}
return arr.reduce(function(best,next){var pair=[by(next),next];if(!best){return pair;}else if(compare(best[0],pair[0])===best[0]){return best;}else{return pair;}},null)[1];}
function pick(obj,keys){return keys.reduce(function(a,k){a[k]=obj[k];return a;},{});}
function hasOwnProperty(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop);}
function validateWeekSettings(settings){if(settings==null){return null;}else if(typeof settings!=="object"){throw new InvalidArgumentError("Week settings must be an object");}else{if(!integerBetween(settings.firstDay,1,7)||!integerBetween(settings.minimalDays,1,7)||!Array.isArray(settings.weekend)||settings.weekend.some(function(v){return!integerBetween(v,1,7);})){throw new InvalidArgumentError("Invalid week settings");}
return{firstDay:settings.firstDay,minimalDays:settings.minimalDays,weekend:Array.from(settings.weekend)};}}
function integerBetween(thing,bottom,top){return isInteger(thing)&&thing>=bottom&&thing<=top;}
function floorMod(x,n){return x-n*Math.floor(x/n);}
function padStart(input,n){if(n===void 0){n=2;}
var isNeg=input<0;var padded;if(isNeg){padded="-"+(""+-input).padStart(n,"0");}else{padded=(""+input).padStart(n,"0");}
return padded;}
function parseInteger(string){if(isUndefined(string)||string===null||string===""){return undefined;}else{return parseInt(string,10);}}
function parseFloating(string){if(isUndefined(string)||string===null||string===""){return undefined;}else{return parseFloat(string);}}
function parseMillis(fraction){if(isUndefined(fraction)||fraction===null||fraction===""){return undefined;}else{var f=parseFloat("0."+fraction)*1000;return Math.floor(f);}}
function roundTo(number,digits,towardZero){if(towardZero===void 0){towardZero=false;}
var factor=Math.pow(10,digits),rounder=towardZero?Math.trunc:Math.round;return rounder(number*factor)/factor;}
function isLeapYear(year){return year%4===0&&(year%100!==0||year%400===0);}
function daysInYear(year){return isLeapYear(year)?366:365;}
function daysInMonth(year,month){var modMonth=floorMod(month-1,12)+1,modYear=year+(month-modMonth)/12;if(modMonth===2){return isLeapYear(modYear)?29:28;}else{return[31,null,31,30,31,30,31,31,30,31,30,31][modMonth-1];}}
function objToLocalTS(obj){var d=Date.UTC(obj.year,obj.month-1,obj.day,obj.hour,obj.minute,obj.second,obj.millisecond);if(obj.year<100&&obj.year>=0){d=new Date(d);d.setUTCFullYear(obj.year,obj.month-1,obj.day);}
return+d;}
function firstWeekOffset(year,minDaysInFirstWeek,startOfWeek){var fwdlw=isoWeekdayToLocal(dayOfWeek(year,1,minDaysInFirstWeek),startOfWeek);return-fwdlw+minDaysInFirstWeek-1;}
function weeksInWeekYear(weekYear,minDaysInFirstWeek,startOfWeek){if(minDaysInFirstWeek===void 0){minDaysInFirstWeek=4;}
if(startOfWeek===void 0){startOfWeek=1;}
var weekOffset=firstWeekOffset(weekYear,minDaysInFirstWeek,startOfWeek);var weekOffsetNext=firstWeekOffset(weekYear+1,minDaysInFirstWeek,startOfWeek);return(daysInYear(weekYear)-weekOffset+weekOffsetNext)/7;}
function untruncateYear(year){if(year>99){return year;}else return year>Settings.twoDigitCutoffYear?1900+year:2000+year;}
function parseZoneInfo(ts,offsetFormat,locale,timeZone){if(timeZone===void 0){timeZone=null;}
var date=new Date(ts),intlOpts={hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"};if(timeZone){intlOpts.timeZone=timeZone;}
var modified=_extends({timeZoneName:offsetFormat},intlOpts);var parsed=new Intl.DateTimeFormat(locale,modified).formatToParts(date).find(function(m){return m.type.toLowerCase()==="timezonename";});return parsed?parsed.value:null;}
function signedOffset(offHourStr,offMinuteStr){var offHour=parseInt(offHourStr,10);if(Number.isNaN(offHour)){offHour=0;}
var offMin=parseInt(offMinuteStr,10)||0,offMinSigned=offHour<0||Object.is(offHour,-0)?-offMin:offMin;return offHour*60+offMinSigned;}
function asNumber(value){var numericValue=Number(value);if(typeof value==="boolean"||value===""||Number.isNaN(numericValue))throw new InvalidArgumentError("Invalid unit value "+value);return numericValue;}
function normalizeObject(obj,normalizer){var normalized={};for(var u in obj){if(hasOwnProperty(obj,u)){var v=obj[u];if(v===undefined||v===null)continue;normalized[normalizer(u)]=asNumber(v);}}
return normalized;}
function formatOffset(offset,format){var hours=Math.trunc(Math.abs(offset/60)),minutes=Math.trunc(Math.abs(offset%60)),sign=offset>=0?"+":"-";switch(format){case"short":return""+sign+padStart(hours,2)+":"+padStart(minutes,2);case"narrow":return""+sign+hours+(minutes>0?":"+minutes:"");case"techie":return""+sign+padStart(hours,2)+padStart(minutes,2);default:throw new RangeError("Value format "+format+" is out of range for property format");}}
function timeObject(obj){return pick(obj,["hour","minute","second","millisecond"]);}
var monthsLong=["January","February","March","April","May","June","July","August","September","October","November","December"];var monthsShort=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];var monthsNarrow=["J","F","M","A","M","J","J","A","S","O","N","D"];function months(length){switch(length){case"narrow":return[].concat(monthsNarrow);case"short":return[].concat(monthsShort);case"long":return[].concat(monthsLong);case"numeric":return["1","2","3","4","5","6","7","8","9","10","11","12"];case"2-digit":return["01","02","03","04","05","06","07","08","09","10","11","12"];default:return null;}}
var weekdaysLong=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"];var weekdaysShort=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];var weekdaysNarrow=["M","T","W","T","F","S","S"];function weekdays(length){switch(length){case"narrow":return[].concat(weekdaysNarrow);case"short":return[].concat(weekdaysShort);case"long":return[].concat(weekdaysLong);case"numeric":return["1","2","3","4","5","6","7"];default:return null;}}
var meridiems=["AM","PM"];var erasLong=["Before Christ","Anno Domini"];var erasShort=["BC","AD"];var erasNarrow=["B","A"];function eras(length){switch(length){case"narrow":return[].concat(erasNarrow);case"short":return[].concat(erasShort);case"long":return[].concat(erasLong);default:return null;}}
function meridiemForDateTime(dt){return meridiems[dt.hour<12?0:1];}
function weekdayForDateTime(dt,length){return weekdays(length)[dt.weekday-1];}
function monthForDateTime(dt,length){return months(length)[dt.month-1];}
function eraForDateTime(dt,length){return eras(length)[dt.year<0?0:1];}
function formatRelativeTime(unit,count,numeric,narrow){if(numeric===void 0){numeric="always";}
if(narrow===void 0){narrow=false;}
var units={years:["year","yr."],quarters:["quarter","qtr."],months:["month","mo."],weeks:["week","wk."],days:["day","day","days"],hours:["hour","hr."],minutes:["minute","min."],seconds:["second","sec."]};var lastable=["hours","minutes","seconds"].indexOf(unit)===-1;if(numeric==="auto"&&lastable){var isDay=unit==="days";switch(count){case 1:return isDay?"tomorrow":"next "+units[unit][0];case-1:return isDay?"yesterday":"last "+units[unit][0];case 0:return isDay?"today":"this "+units[unit][0];}}
var isInPast=Object.is(count,-0)||count<0,fmtValue=Math.abs(count),singular=fmtValue===1,lilUnits=units[unit],fmtUnit=narrow?singular?lilUnits[1]:lilUnits[2]||lilUnits[1]:singular?units[unit][0]:unit;return isInPast?fmtValue+" "+fmtUnit+" ago":"in "+fmtValue+" "+fmtUnit;}
function stringifyTokens(splits,tokenToString){var s="";for(var _iterator=_createForOfIteratorHelperLoose(splits),_step;!(_step=_iterator()).done;){var token=_step.value;if(token.literal){s+=token.val;}else{s+=tokenToString(token.val);}}
return s;}
var _macroTokenToFormatOpts={D:DATE_SHORT,DD:DATE_MED,DDD:DATE_FULL,DDDD:DATE_HUGE,t:TIME_SIMPLE,tt:TIME_WITH_SECONDS,ttt:TIME_WITH_SHORT_OFFSET,tttt:TIME_WITH_LONG_OFFSET,T:TIME_24_SIMPLE,TT:TIME_24_WITH_SECONDS,TTT:TIME_24_WITH_SHORT_OFFSET,TTTT:TIME_24_WITH_LONG_OFFSET,f:DATETIME_SHORT,ff:DATETIME_MED,fff:DATETIME_FULL,ffff:DATETIME_HUGE,F:DATETIME_SHORT_WITH_SECONDS,FF:DATETIME_MED_WITH_SECONDS,FFF:DATETIME_FULL_WITH_SECONDS,FFFF:DATETIME_HUGE_WITH_SECONDS};var Formatter=function(){Formatter.create=function create(locale,opts){if(opts===void 0){opts={};}
return new Formatter(locale,opts);};Formatter.parseFormat=function parseFormat(fmt){var current=null,currentFull="",bracketed=false;var splits=[];for(var i=0;i<fmt.length;i++){var c=fmt.charAt(i);if(c==="'"){if(currentFull.length>0){splits.push({literal:bracketed||/^\s+$/.test(currentFull),val:currentFull});}
current=null;currentFull="";bracketed=!bracketed;}else if(bracketed){currentFull+=c;}else if(c===current){currentFull+=c;}else{if(currentFull.length>0){splits.push({literal:/^\s+$/.test(currentFull),val:currentFull});}
currentFull=c;current=c;}}
if(currentFull.length>0){splits.push({literal:bracketed||/^\s+$/.test(currentFull),val:currentFull});}
return splits;};Formatter.macroTokenToFormatOpts=function macroTokenToFormatOpts(token){return _macroTokenToFormatOpts[token];};function Formatter(locale,formatOpts){this.opts=formatOpts;this.loc=locale;this.systemLoc=null;}
var _proto=Formatter.prototype;_proto.formatWithSystemDefault=function formatWithSystemDefault(dt,opts){if(this.systemLoc===null){this.systemLoc=this.loc.redefaultToSystem();}
var df=this.systemLoc.dtFormatter(dt,_extends({},this.opts,opts));return df.format();};_proto.dtFormatter=function dtFormatter(dt,opts){if(opts===void 0){opts={};}
return this.loc.dtFormatter(dt,_extends({},this.opts,opts));};_proto.formatDateTime=function formatDateTime(dt,opts){return this.dtFormatter(dt,opts).format();};_proto.formatDateTimeParts=function formatDateTimeParts(dt,opts){return this.dtFormatter(dt,opts).formatToParts();};_proto.formatInterval=function formatInterval(interval,opts){var df=this.dtFormatter(interval.start,opts);return df.dtf.formatRange(interval.start.toJSDate(),interval.end.toJSDate());};_proto.resolvedOptions=function resolvedOptions(dt,opts){return this.dtFormatter(dt,opts).resolvedOptions();};_proto.num=function num(n,p){if(p===void 0){p=0;}
if(this.opts.forceSimple){return padStart(n,p);}
var opts=_extends({},this.opts);if(p>0){opts.padTo=p;}
return this.loc.numberFormatter(opts).format(n);};_proto.formatDateTimeFromString=function formatDateTimeFromString(dt,fmt){var _this=this;var knownEnglish=this.loc.listingMode()==="en",useDateTimeFormatter=this.loc.outputCalendar&&this.loc.outputCalendar!=="gregory",string=function string(opts,extract){return _this.loc.extract(dt,opts,extract);},formatOffset=function formatOffset(opts){if(dt.isOffsetFixed&&dt.offset===0&&opts.allowZ){return"Z";}
return dt.isValid?dt.zone.formatOffset(dt.ts,opts.format):"";},meridiem=function meridiem(){return knownEnglish?meridiemForDateTime(dt):string({hour:"numeric",hourCycle:"h12"},"dayperiod");},month=function month(length,standalone){return knownEnglish?monthForDateTime(dt,length):string(standalone?{month:length}:{month:length,day:"numeric"},"month");},weekday=function weekday(length,standalone){return knownEnglish?weekdayForDateTime(dt,length):string(standalone?{weekday:length}:{weekday:length,month:"long",day:"numeric"},"weekday");},maybeMacro=function maybeMacro(token){var formatOpts=Formatter.macroTokenToFormatOpts(token);if(formatOpts){return _this.formatWithSystemDefault(dt,formatOpts);}else{return token;}},era=function era(length){return knownEnglish?eraForDateTime(dt,length):string({era:length},"era");},tokenToString=function tokenToString(token){switch(token){case"S":return _this.num(dt.millisecond);case"u":case"SSS":return _this.num(dt.millisecond,3);case"s":return _this.num(dt.second);case"ss":return _this.num(dt.second,2);case"uu":return _this.num(Math.floor(dt.millisecond/10),2);case"uuu":return _this.num(Math.floor(dt.millisecond/100));case"m":return _this.num(dt.minute);case"mm":return _this.num(dt.minute,2);case"h":return _this.num(dt.hour%12===0?12:dt.hour%12);case"hh":return _this.num(dt.hour%12===0?12:dt.hour%12,2);case"H":return _this.num(dt.hour);case"HH":return _this.num(dt.hour,2);case"Z":return formatOffset({format:"narrow",allowZ:_this.opts.allowZ});case"ZZ":return formatOffset({format:"short",allowZ:_this.opts.allowZ});case"ZZZ":return formatOffset({format:"techie",allowZ:_this.opts.allowZ});case"ZZZZ":return dt.zone.offsetName(dt.ts,{format:"short",locale:_this.loc.locale});case"ZZZZZ":return dt.zone.offsetName(dt.ts,{format:"long",locale:_this.loc.locale});case"z":return dt.zoneName;case"a":return meridiem();case"d":return useDateTimeFormatter?string({day:"numeric"},"day"):_this.num(dt.day);case"dd":return useDateTimeFormatter?string({day:"2-digit"},"day"):_this.num(dt.day,2);case"c":return _this.num(dt.weekday);case"ccc":return weekday("short",true);case"cccc":return weekday("long",true);case"ccccc":return weekday("narrow",true);case"E":return _this.num(dt.weekday);case"EEE":return weekday("short",false);case"EEEE":return weekday("long",false);case"EEEEE":return weekday("narrow",false);case"L":return useDateTimeFormatter?string({month:"numeric",day:"numeric"},"month"):_this.num(dt.month);case"LL":return useDateTimeFormatter?string({month:"2-digit",day:"numeric"},"month"):_this.num(dt.month,2);case"LLL":return month("short",true);case"LLLL":return month("long",true);case"LLLLL":return month("narrow",true);case"M":return useDateTimeFormatter?string({month:"numeric"},"month"):_this.num(dt.month);case"MM":return useDateTimeFormatter?string({month:"2-digit"},"month"):_this.num(dt.month,2);case"MMM":return month("short",false);case"MMMM":return month("long",false);case"MMMMM":return month("narrow",false);case"y":return useDateTimeFormatter?string({year:"numeric"},"year"):_this.num(dt.year);case"yy":return useDateTimeFormatter?string({year:"2-digit"},"year"):_this.num(dt.year.toString().slice(-2),2);case"yyyy":return useDateTimeFormatter?string({year:"numeric"},"year"):_this.num(dt.year,4);case"yyyyyy":return useDateTimeFormatter?string({year:"numeric"},"year"):_this.num(dt.year,6);case"G":return era("short");case"GG":return era("long");case"GGGGG":return era("narrow");case"kk":return _this.num(dt.weekYear.toString().slice(-2),2);case"kkkk":return _this.num(dt.weekYear,4);case"W":return _this.num(dt.weekNumber);case"WW":return _this.num(dt.weekNumber,2);case"n":return _this.num(dt.localWeekNumber);case"nn":return _this.num(dt.localWeekNumber,2);case"ii":return _this.num(dt.localWeekYear.toString().slice(-2),2);case"iiii":return _this.num(dt.localWeekYear,4);case"o":return _this.num(dt.ordinal);case"ooo":return _this.num(dt.ordinal,3);case"q":return _this.num(dt.quarter);case"qq":return _this.num(dt.quarter,2);case"X":return _this.num(Math.floor(dt.ts/1000));case"x":return _this.num(dt.ts);default:return maybeMacro(token);}};return stringifyTokens(Formatter.parseFormat(fmt),tokenToString);};_proto.formatDurationFromString=function formatDurationFromString(dur,fmt){var _this2=this;var tokenToField=function tokenToField(token){switch(token[0]){case"S":return"millisecond";case"s":return"second";case"m":return"minute";case"h":return"hour";case"d":return"day";case"w":return"week";case"M":return"month";case"y":return"year";default:return null;}},tokenToString=function tokenToString(lildur){return function(token){var mapped=tokenToField(token);if(mapped){return _this2.num(lildur.get(mapped),token.length);}else{return token;}};},tokens=Formatter.parseFormat(fmt),realTokens=tokens.reduce(function(found,_ref){var literal=_ref.literal,val=_ref.val;return literal?found:found.concat(val);},[]),collapsed=dur.shiftTo.apply(dur,realTokens.map(tokenToField).filter(function(t){return t;}));return stringifyTokens(tokens,tokenToString(collapsed));};return Formatter;}();var ianaRegex=/[A-Za-z_+-]{1,256}(?::?\/[A-Za-z0-9_+-]{1,256}(?:\/[A-Za-z0-9_+-]{1,256})?)?/;function combineRegexes(){for(var _len=arguments.length,regexes=new Array(_len),_key=0;_key<_len;_key++){regexes[_key]=arguments[_key];}
var full=regexes.reduce(function(f,r){return f+r.source;},"");return RegExp("^"+full+"$");}
function combineExtractors(){for(var _len2=arguments.length,extractors=new Array(_len2),_key2=0;_key2<_len2;_key2++){extractors[_key2]=arguments[_key2];}
return function(m){return extractors.reduce(function(_ref,ex){var mergedVals=_ref[0],mergedZone=_ref[1],cursor=_ref[2];var _ex=ex(m,cursor),val=_ex[0],zone=_ex[1],next=_ex[2];return[_extends({},mergedVals,val),zone||mergedZone,next];},[{},null,1]).slice(0,2);};}
function parse(s){if(s==null){return[null,null];}
for(var _len3=arguments.length,patterns=new Array(_len3>1?_len3-1:0),_key3=1;_key3<_len3;_key3++){patterns[_key3-1]=arguments[_key3];}
for(var _i=0,_patterns=patterns;_i<_patterns.length;_i++){var _patterns$_i=_patterns[_i],regex=_patterns$_i[0],extractor=_patterns$_i[1];var m=regex.exec(s);if(m){return extractor(m);}}
return[null,null];}
function simpleParse(){for(var _len4=arguments.length,keys=new Array(_len4),_key4=0;_key4<_len4;_key4++){keys[_key4]=arguments[_key4];}
return function(match,cursor){var ret={};var i;for(i=0;i<keys.length;i++){ret[keys[i]]=parseInteger(match[cursor+i]);}
return[ret,null,cursor+i];};}
var offsetRegex=/(?:(Z)|([+-]\d\d)(?::?(\d\d))?)/;var isoExtendedZone="(?:"+offsetRegex.source+"?(?:\\[("+ianaRegex.source+")\\])?)?";var isoTimeBaseRegex=/(\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d{1,30}))?)?)?/;var isoTimeRegex=RegExp(""+isoTimeBaseRegex.source+isoExtendedZone);var isoTimeExtensionRegex=RegExp("(?:T"+isoTimeRegex.source+")?");var isoYmdRegex=/([+-]\d{6}|\d{4})(?:-?(\d\d)(?:-?(\d\d))?)?/;var isoWeekRegex=/(\d{4})-?W(\d\d)(?:-?(\d))?/;var isoOrdinalRegex=/(\d{4})-?(\d{3})/;var extractISOWeekData=simpleParse("weekYear","weekNumber","weekDay");var extractISOOrdinalData=simpleParse("year","ordinal");var sqlYmdRegex=/(\d{4})-(\d\d)-(\d\d)/;var sqlTimeRegex=RegExp(isoTimeBaseRegex.source+" ?(?:"+offsetRegex.source+"|("+ianaRegex.source+"))?");var sqlTimeExtensionRegex=RegExp("(?: "+sqlTimeRegex.source+")?");function int(match,pos,fallback){var m=match[pos];return isUndefined(m)?fallback:parseInteger(m);}
function extractISOYmd(match,cursor){var item={year:int(match,cursor),month:int(match,cursor+1,1),day:int(match,cursor+2,1)};return[item,null,cursor+3];}
function extractISOTime(match,cursor){var item={hours:int(match,cursor,0),minutes:int(match,cursor+1,0),seconds:int(match,cursor+2,0),milliseconds:parseMillis(match[cursor+3])};return[item,null,cursor+4];}
function extractISOOffset(match,cursor){var local=!match[cursor]&&!match[cursor+1],fullOffset=signedOffset(match[cursor+1],match[cursor+2]),zone=local?null:FixedOffsetZone.instance(fullOffset);return[{},zone,cursor+3];}
function extractIANAZone(match,cursor){var zone=match[cursor]?IANAZone.create(match[cursor]):null;return[{},zone,cursor+1];}
var isoTimeOnly=RegExp("^T?"+isoTimeBaseRegex.source+"$");var isoDuration=/^-?P(?:(?:(-?\d{1,20}(?:\.\d{1,20})?)Y)?(?:(-?\d{1,20}(?:\.\d{1,20})?)M)?(?:(-?\d{1,20}(?:\.\d{1,20})?)W)?(?:(-?\d{1,20}(?:\.\d{1,20})?)D)?(?:T(?:(-?\d{1,20}(?:\.\d{1,20})?)H)?(?:(-?\d{1,20}(?:\.\d{1,20})?)M)?(?:(-?\d{1,20})(?:[.,](-?\d{1,20}))?S)?)?)$/;function extractISODuration(match){var s=match[0],yearStr=match[1],monthStr=match[2],weekStr=match[3],dayStr=match[4],hourStr=match[5],minuteStr=match[6],secondStr=match[7],millisecondsStr=match[8];var hasNegativePrefix=s[0]==="-";var negativeSeconds=secondStr&&secondStr[0]==="-";var maybeNegate=function maybeNegate(num,force){if(force===void 0){force=false;}
return num!==undefined&&(force||num&&hasNegativePrefix)?-num:num;};return[{years:maybeNegate(parseFloating(yearStr)),months:maybeNegate(parseFloating(monthStr)),weeks:maybeNegate(parseFloating(weekStr)),days:maybeNegate(parseFloating(dayStr)),hours:maybeNegate(parseFloating(hourStr)),minutes:maybeNegate(parseFloating(minuteStr)),seconds:maybeNegate(parseFloating(secondStr),secondStr==="-0"),milliseconds:maybeNegate(parseMillis(millisecondsStr),negativeSeconds)}];}
var obsOffsets={GMT:0,EDT:-4*60,EST:-5*60,CDT:-5*60,CST:-6*60,MDT:-6*60,MST:-7*60,PDT:-7*60,PST:-8*60};function fromStrings(weekdayStr,yearStr,monthStr,dayStr,hourStr,minuteStr,secondStr){var result={year:yearStr.length===2?untruncateYear(parseInteger(yearStr)):parseInteger(yearStr),month:monthsShort.indexOf(monthStr)+1,day:parseInteger(dayStr),hour:parseInteger(hourStr),minute:parseInteger(minuteStr)};if(secondStr)result.second=parseInteger(secondStr);if(weekdayStr){result.weekday=weekdayStr.length>3?weekdaysLong.indexOf(weekdayStr)+1:weekdaysShort.indexOf(weekdayStr)+1;}
return result;}
var rfc2822=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|(?:([+-]\d\d)(\d\d)))$/;function extractRFC2822(match){var weekdayStr=match[1],dayStr=match[2],monthStr=match[3],yearStr=match[4],hourStr=match[5],minuteStr=match[6],secondStr=match[7],obsOffset=match[8],milOffset=match[9],offHourStr=match[10],offMinuteStr=match[11],result=fromStrings(weekdayStr,yearStr,monthStr,dayStr,hourStr,minuteStr,secondStr);var offset;if(obsOffset){offset=obsOffsets[obsOffset];}else if(milOffset){offset=0;}else{offset=signedOffset(offHourStr,offMinuteStr);}
return[result,new FixedOffsetZone(offset)];}
function preprocessRFC2822(s){return s.replace(/\([^()]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").trim();}
var rfc1123=/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (\d\d) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d\d):(\d\d):(\d\d) GMT$/,rfc850=/^(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d) (\d\d):(\d\d):(\d\d) GMT$/,ascii=/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ( \d|\d\d) (\d\d):(\d\d):(\d\d) (\d{4})$/;function extractRFC1123Or850(match){var weekdayStr=match[1],dayStr=match[2],monthStr=match[3],yearStr=match[4],hourStr=match[5],minuteStr=match[6],secondStr=match[7],result=fromStrings(weekdayStr,yearStr,monthStr,dayStr,hourStr,minuteStr,secondStr);return[result,FixedOffsetZone.utcInstance];}
function extractASCII(match){var weekdayStr=match[1],monthStr=match[2],dayStr=match[3],hourStr=match[4],minuteStr=match[5],secondStr=match[6],yearStr=match[7],result=fromStrings(weekdayStr,yearStr,monthStr,dayStr,hourStr,minuteStr,secondStr);return[result,FixedOffsetZone.utcInstance];}
var isoYmdWithTimeExtensionRegex=combineRegexes(isoYmdRegex,isoTimeExtensionRegex);var isoWeekWithTimeExtensionRegex=combineRegexes(isoWeekRegex,isoTimeExtensionRegex);var isoOrdinalWithTimeExtensionRegex=combineRegexes(isoOrdinalRegex,isoTimeExtensionRegex);var isoTimeCombinedRegex=combineRegexes(isoTimeRegex);var extractISOYmdTimeAndOffset=combineExtractors(extractISOYmd,extractISOTime,extractISOOffset,extractIANAZone);var extractISOWeekTimeAndOffset=combineExtractors(extractISOWeekData,extractISOTime,extractISOOffset,extractIANAZone);var extractISOOrdinalDateAndTime=combineExtractors(extractISOOrdinalData,extractISOTime,extractISOOffset,extractIANAZone);var extractISOTimeAndOffset=combineExtractors(extractISOTime,extractISOOffset,extractIANAZone);function parseISODate(s){return parse(s,[isoYmdWithTimeExtensionRegex,extractISOYmdTimeAndOffset],[isoWeekWithTimeExtensionRegex,extractISOWeekTimeAndOffset],[isoOrdinalWithTimeExtensionRegex,extractISOOrdinalDateAndTime],[isoTimeCombinedRegex,extractISOTimeAndOffset]);}
function parseRFC2822Date(s){return parse(preprocessRFC2822(s),[rfc2822,extractRFC2822]);}
function parseHTTPDate(s){return parse(s,[rfc1123,extractRFC1123Or850],[rfc850,extractRFC1123Or850],[ascii,extractASCII]);}
function parseISODuration(s){return parse(s,[isoDuration,extractISODuration]);}
var extractISOTimeOnly=combineExtractors(extractISOTime);function parseISOTimeOnly(s){return parse(s,[isoTimeOnly,extractISOTimeOnly]);}
var sqlYmdWithTimeExtensionRegex=combineRegexes(sqlYmdRegex,sqlTimeExtensionRegex);var sqlTimeCombinedRegex=combineRegexes(sqlTimeRegex);var extractISOTimeOffsetAndIANAZone=combineExtractors(extractISOTime,extractISOOffset,extractIANAZone);function parseSQL(s){return parse(s,[sqlYmdWithTimeExtensionRegex,extractISOYmdTimeAndOffset],[sqlTimeCombinedRegex,extractISOTimeOffsetAndIANAZone]);}
var INVALID$2="Invalid Duration";var lowOrderMatrix={weeks:{days:7,hours:7*24,minutes:7*24*60,seconds:7*24*60*60,milliseconds:7*24*60*60*1000},days:{hours:24,minutes:24*60,seconds:24*60*60,milliseconds:24*60*60*1000},hours:{minutes:60,seconds:60*60,milliseconds:60*60*1000},minutes:{seconds:60,milliseconds:60*1000},seconds:{milliseconds:1000}},casualMatrix=_extends({years:{quarters:4,months:12,weeks:52,days:365,hours:365*24,minutes:365*24*60,seconds:365*24*60*60,milliseconds:365*24*60*60*1000},quarters:{months:3,weeks:13,days:91,hours:91*24,minutes:91*24*60,seconds:91*24*60*60,milliseconds:91*24*60*60*1000},months:{weeks:4,days:30,hours:30*24,minutes:30*24*60,seconds:30*24*60*60,milliseconds:30*24*60*60*1000}},lowOrderMatrix),daysInYearAccurate=146097.0/400,daysInMonthAccurate=146097.0/4800,accurateMatrix=_extends({years:{quarters:4,months:12,weeks:daysInYearAccurate/7,days:daysInYearAccurate,hours:daysInYearAccurate*24,minutes:daysInYearAccurate*24*60,seconds:daysInYearAccurate*24*60*60,milliseconds:daysInYearAccurate*24*60*60*1000},quarters:{months:3,weeks:daysInYearAccurate/28,days:daysInYearAccurate/4,hours:daysInYearAccurate*24/4,minutes:daysInYearAccurate*24*60/4,seconds:daysInYearAccurate*24*60*60/4,milliseconds:daysInYearAccurate*24*60*60*1000/4},months:{weeks:daysInMonthAccurate/7,days:daysInMonthAccurate,hours:daysInMonthAccurate*24,minutes:daysInMonthAccurate*24*60,seconds:daysInMonthAccurate*24*60*60,milliseconds:daysInMonthAccurate*24*60*60*1000}},lowOrderMatrix);var orderedUnits$1=["years","quarters","months","weeks","days","hours","minutes","seconds","milliseconds"];var reverseUnits=orderedUnits$1.slice(0).reverse();function clone$1(dur,alts,clear){if(clear===void 0){clear=false;}
var conf={values:clear?alts.values:_extends({},dur.values,alts.values||{}),loc:dur.loc.clone(alts.loc),conversionAccuracy:alts.conversionAccuracy||dur.conversionAccuracy,matrix:alts.matrix||dur.matrix};return new Duration(conf);}
function durationToMillis(matrix,vals){var _vals$milliseconds;var sum=(_vals$milliseconds=vals.milliseconds)!=null?_vals$milliseconds:0;for(var _iterator=_createForOfIteratorHelperLoose(reverseUnits.slice(1)),_step;!(_step=_iterator()).done;){var unit=_step.value;if(vals[unit]){sum+=vals[unit]*matrix[unit]["milliseconds"];}}
return sum;}
function normalizeValues(matrix,vals){var factor=durationToMillis(matrix,vals)<0?-1:1;orderedUnits$1.reduceRight(function(previous,current){if(!isUndefined(vals[current])){if(previous){var previousVal=vals[previous]*factor;var conv=matrix[current][previous];var rollUp=Math.floor(previousVal/conv);vals[current]+=rollUp*factor;vals[previous]-=rollUp*conv*factor;}
return current;}else{return previous;}},null);orderedUnits$1.reduce(function(previous,current){if(!isUndefined(vals[current])){if(previous){var fraction=vals[previous]%1;vals[previous]-=fraction;vals[current]+=fraction*matrix[previous][current];}
return current;}else{return previous;}},null);}
function removeZeroes(vals){var newVals={};for(var _i=0,_Object$entries=Object.entries(vals);_i<_Object$entries.length;_i++){var _Object$entries$_i=_Object$entries[_i],key=_Object$entries$_i[0],value=_Object$entries$_i[1];if(value!==0){newVals[key]=value;}}
return newVals;}
var Duration=function(_Symbol$for){function Duration(config){var accurate=config.conversionAccuracy==="longterm"||false;var matrix=accurate?accurateMatrix:casualMatrix;if(config.matrix){matrix=config.matrix;}
this.values=config.values;this.loc=config.loc||Locale.create();this.conversionAccuracy=accurate?"longterm":"casual";this.invalid=config.invalid||null;this.matrix=matrix;this.isLuxonDuration=true;}
Duration.fromMillis=function fromMillis(count,opts){return Duration.fromObject({milliseconds:count},opts);};Duration.fromObject=function fromObject(obj,opts){if(opts===void 0){opts={};}
if(obj==null||typeof obj!=="object"){throw new InvalidArgumentError("Duration.fromObject: argument expected to be an object, got "+(obj===null?"null":typeof obj));}
return new Duration({values:normalizeObject(obj,Duration.normalizeUnit),loc:Locale.fromObject(opts),conversionAccuracy:opts.conversionAccuracy,matrix:opts.matrix});};Duration.fromDurationLike=function fromDurationLike(durationLike){if(isNumber(durationLike)){return Duration.fromMillis(durationLike);}else if(Duration.isDuration(durationLike)){return durationLike;}else if(typeof durationLike==="object"){return Duration.fromObject(durationLike);}else{throw new InvalidArgumentError("Unknown duration argument "+durationLike+" of type "+typeof durationLike);}};Duration.fromISO=function fromISO(text,opts){var _parseISODuration=parseISODuration(text),parsed=_parseISODuration[0];if(parsed){return Duration.fromObject(parsed,opts);}else{return Duration.invalid("unparsable","the input \""+text+"\" can't be parsed as ISO 8601");}};Duration.fromISOTime=function fromISOTime(text,opts){var _parseISOTimeOnly=parseISOTimeOnly(text),parsed=_parseISOTimeOnly[0];if(parsed){return Duration.fromObject(parsed,opts);}else{return Duration.invalid("unparsable","the input \""+text+"\" can't be parsed as ISO 8601");}};Duration.invalid=function invalid(reason,explanation){if(explanation===void 0){explanation=null;}
if(!reason){throw new InvalidArgumentError("need to specify a reason the Duration is invalid");}
var invalid=reason instanceof Invalid?reason:new Invalid(reason,explanation);if(Settings.throwOnInvalid){throw new InvalidDurationError(invalid);}else{return new Duration({invalid:invalid});}};Duration.normalizeUnit=function normalizeUnit(unit){var normalized={year:"years",years:"years",quarter:"quarters",quarters:"quarters",month:"months",months:"months",week:"weeks",weeks:"weeks",day:"days",days:"days",hour:"hours",hours:"hours",minute:"minutes",minutes:"minutes",second:"seconds",seconds:"seconds",millisecond:"milliseconds",milliseconds:"milliseconds"}[unit?unit.toLowerCase():unit];if(!normalized)throw new InvalidUnitError(unit);return normalized;};Duration.isDuration=function isDuration(o){return o&&o.isLuxonDuration||false;};var _proto=Duration.prototype;_proto.toFormat=function toFormat(fmt,opts){if(opts===void 0){opts={};}
var fmtOpts=_extends({},opts,{floor:opts.round!==false&&opts.floor!==false});return this.isValid?Formatter.create(this.loc,fmtOpts).formatDurationFromString(this,fmt):INVALID$2;};_proto.toHuman=function toHuman(opts){var _this=this;if(opts===void 0){opts={};}
if(!this.isValid)return INVALID$2;var l=orderedUnits$1.map(function(unit){var val=_this.values[unit];if(isUndefined(val)){return null;}
return _this.loc.numberFormatter(_extends({style:"unit",unitDisplay:"long"},opts,{unit:unit.slice(0,-1)})).format(val);}).filter(function(n){return n;});return this.loc.listFormatter(_extends({type:"conjunction",style:opts.listStyle||"narrow"},opts)).format(l);};_proto.toObject=function toObject(){if(!this.isValid)return{};return _extends({},this.values);};_proto.toISO=function toISO(){if(!this.isValid)return null;var s="P";if(this.years!==0)s+=this.years+"Y";if(this.months!==0||this.quarters!==0)s+=this.months+this.quarters*3+"M";if(this.weeks!==0)s+=this.weeks+"W";if(this.days!==0)s+=this.days+"D";if(this.hours!==0||this.minutes!==0||this.seconds!==0||this.milliseconds!==0)s+="T";if(this.hours!==0)s+=this.hours+"H";if(this.minutes!==0)s+=this.minutes+"M";if(this.seconds!==0||this.milliseconds!==0)
s+=roundTo(this.seconds+this.milliseconds/1000,3)+"S";if(s==="P")s+="T0S";return s;};_proto.toISOTime=function toISOTime(opts){if(opts===void 0){opts={};}
if(!this.isValid)return null;var millis=this.toMillis();if(millis<0||millis>=86400000)return null;opts=_extends({suppressMilliseconds:false,suppressSeconds:false,includePrefix:false,format:"extended"},opts,{includeOffset:false});var dateTime=DateTime.fromMillis(millis,{zone:"UTC"});return dateTime.toISOTime(opts);};_proto.toJSON=function toJSON(){return this.toISO();};_proto.toString=function toString(){return this.toISO();};_proto[_Symbol$for]=function(){if(this.isValid){return"Duration { values: "+JSON.stringify(this.values)+" }";}else{return"Duration { Invalid, reason: "+this.invalidReason+" }";}};_proto.toMillis=function toMillis(){if(!this.isValid)return NaN;return durationToMillis(this.matrix,this.values);};_proto.valueOf=function valueOf(){return this.toMillis();};_proto.plus=function plus(duration){if(!this.isValid)return this;var dur=Duration.fromDurationLike(duration),result={};for(var _i2=0,_orderedUnits=orderedUnits$1;_i2<_orderedUnits.length;_i2++){var k=_orderedUnits[_i2];if(hasOwnProperty(dur.values,k)||hasOwnProperty(this.values,k)){result[k]=dur.get(k)+this.get(k);}}
return clone$1(this,{values:result},true);};_proto.minus=function minus(duration){if(!this.isValid)return this;var dur=Duration.fromDurationLike(duration);return this.plus(dur.negate());};_proto.mapUnits=function mapUnits(fn){if(!this.isValid)return this;var result={};for(var _i3=0,_Object$keys=Object.keys(this.values);_i3<_Object$keys.length;_i3++){var k=_Object$keys[_i3];result[k]=asNumber(fn(this.values[k],k));}
return clone$1(this,{values:result},true);};_proto.get=function get(unit){return this[Duration.normalizeUnit(unit)];};_proto.set=function set(values){if(!this.isValid)return this;var mixed=_extends({},this.values,normalizeObject(values,Duration.normalizeUnit));return clone$1(this,{values:mixed});};_proto.reconfigure=function reconfigure(_temp){var _ref=_temp===void 0?{}:_temp,locale=_ref.locale,numberingSystem=_ref.numberingSystem,conversionAccuracy=_ref.conversionAccuracy,matrix=_ref.matrix;var loc=this.loc.clone({locale:locale,numberingSystem:numberingSystem});var opts={loc:loc,matrix:matrix,conversionAccuracy:conversionAccuracy};return clone$1(this,opts);};_proto.as=function as(unit){return this.isValid?this.shiftTo(unit).get(unit):NaN;};_proto.normalize=function normalize(){if(!this.isValid)return this;var vals=this.toObject();normalizeValues(this.matrix,vals);return clone$1(this,{values:vals},true);};_proto.rescale=function rescale(){if(!this.isValid)return this;var vals=removeZeroes(this.normalize().shiftToAll().toObject());return clone$1(this,{values:vals},true);};_proto.shiftTo=function shiftTo(){for(var _len=arguments.length,units=new Array(_len),_key=0;_key<_len;_key++){units[_key]=arguments[_key];}
if(!this.isValid)return this;if(units.length===0){return this;}
units=units.map(function(u){return Duration.normalizeUnit(u);});var built={},accumulated={},vals=this.toObject();var lastUnit;for(var _i4=0,_orderedUnits2=orderedUnits$1;_i4<_orderedUnits2.length;_i4++){var k=_orderedUnits2[_i4];if(units.indexOf(k)>=0){lastUnit=k;var own=0;for(var ak in accumulated){own+=this.matrix[ak][k]*accumulated[ak];accumulated[ak]=0;}
if(isNumber(vals[k])){own+=vals[k];}
var i=Math.trunc(own);built[k]=i;accumulated[k]=(own*1000-i*1000)/1000;}else if(isNumber(vals[k])){accumulated[k]=vals[k];}}
for(var key in accumulated){if(accumulated[key]!==0){built[lastUnit]+=key===lastUnit?accumulated[key]:accumulated[key]/this.matrix[lastUnit][key];}}
normalizeValues(this.matrix,built);return clone$1(this,{values:built},true);};_proto.shiftToAll=function shiftToAll(){if(!this.isValid)return this;return this.shiftTo("years","months","weeks","days","hours","minutes","seconds","milliseconds");};_proto.negate=function negate(){if(!this.isValid)return this;var negated={};for(var _i5=0,_Object$keys2=Object.keys(this.values);_i5<_Object$keys2.length;_i5++){var k=_Object$keys2[_i5];negated[k]=this.values[k]===0?0:-this.values[k];}
return clone$1(this,{values:negated},true);};_proto.equals=function equals(other){if(!this.isValid||!other.isValid){return false;}
if(!this.loc.equals(other.loc)){return false;}
function eq(v1,v2){if(v1===undefined||v1===0)return v2===undefined||v2===0;return v1===v2;}
for(var _i6=0,_orderedUnits3=orderedUnits$1;_i6<_orderedUnits3.length;_i6++){var u=_orderedUnits3[_i6];if(!eq(this.values[u],other.values[u])){return false;}}
return true;};_createClass(Duration,[{key:"locale",get:function get(){return this.isValid?this.loc.locale:null;}},{key:"numberingSystem",get:function get(){return this.isValid?this.loc.numberingSystem:null;}},{key:"years",get:function get(){return this.isValid?this.values.years||0:NaN;}},{key:"quarters",get:function get(){return this.isValid?this.values.quarters||0:NaN;}},{key:"months",get:function get(){return this.isValid?this.values.months||0:NaN;}},{key:"weeks",get:function get(){return this.isValid?this.values.weeks||0:NaN;}},{key:"days",get:function get(){return this.isValid?this.values.days||0:NaN;}},{key:"hours",get:function get(){return this.isValid?this.values.hours||0:NaN;}},{key:"minutes",get:function get(){return this.isValid?this.values.minutes||0:NaN;}},{key:"seconds",get:function get(){return this.isValid?this.values.seconds||0:NaN;}},{key:"milliseconds",get:function get(){return this.isValid?this.values.milliseconds||0:NaN;}},{key:"isValid",get:function get(){return this.invalid===null;}},{key:"invalidReason",get:function get(){return this.invalid?this.invalid.reason:null;}},{key:"invalidExplanation",get:function get(){return this.invalid?this.invalid.explanation:null;}}]);return Duration;}(Symbol.for("nodejs.util.inspect.custom"));var INVALID$1="Invalid Interval";function validateStartEnd(start,end){if(!start||!start.isValid){return Interval.invalid("missing or invalid start");}else if(!end||!end.isValid){return Interval.invalid("missing or invalid end");}else if(end<start){return Interval.invalid("end before start","The end of an interval must be after its start, but you had start="+start.toISO()+" and end="+end.toISO());}else{return null;}}
var Interval=function(_Symbol$for){function Interval(config){this.s=config.start;this.e=config.end;this.invalid=config.invalid||null;this.isLuxonInterval=true;}
Interval.invalid=function invalid(reason,explanation){if(explanation===void 0){explanation=null;}
if(!reason){throw new InvalidArgumentError("need to specify a reason the Interval is invalid");}
var invalid=reason instanceof Invalid?reason:new Invalid(reason,explanation);if(Settings.throwOnInvalid){throw new InvalidIntervalError(invalid);}else{return new Interval({invalid:invalid});}};Interval.fromDateTimes=function fromDateTimes(start,end){var builtStart=friendlyDateTime(start),builtEnd=friendlyDateTime(end);var validateError=validateStartEnd(builtStart,builtEnd);if(validateError==null){return new Interval({start:builtStart,end:builtEnd});}else{return validateError;}};Interval.after=function after(start,duration){var dur=Duration.fromDurationLike(duration),dt=friendlyDateTime(start);return Interval.fromDateTimes(dt,dt.plus(dur));};Interval.before=function before(end,duration){var dur=Duration.fromDurationLike(duration),dt=friendlyDateTime(end);return Interval.fromDateTimes(dt.minus(dur),dt);};Interval.fromISO=function fromISO(text,opts){var _split=(text||"").split("/",2),s=_split[0],e=_split[1];if(s&&e){var start,startIsValid;try{start=DateTime.fromISO(s,opts);startIsValid=start.isValid;}catch(e){startIsValid=false;}
var end,endIsValid;try{end=DateTime.fromISO(e,opts);endIsValid=end.isValid;}catch(e){endIsValid=false;}
if(startIsValid&&endIsValid){return Interval.fromDateTimes(start,end);}
if(startIsValid){var dur=Duration.fromISO(e,opts);if(dur.isValid){return Interval.after(start,dur);}}else if(endIsValid){var _dur=Duration.fromISO(s,opts);if(_dur.isValid){return Interval.before(end,_dur);}}}
return Interval.invalid("unparsable","the input \""+text+"\" can't be parsed as ISO 8601");};Interval.isInterval=function isInterval(o){return o&&o.isLuxonInterval||false;};var _proto=Interval.prototype;_proto.length=function length(unit){if(unit===void 0){unit="milliseconds";}
return this.isValid?this.toDuration.apply(this,[unit]).get(unit):NaN;};_proto.count=function count(unit,opts){if(unit===void 0){unit="milliseconds";}
if(!this.isValid)return NaN;var start=this.start.startOf(unit,opts);var end;if(opts!=null&&opts.useLocaleWeeks){end=this.end.reconfigure({locale:start.locale});}else{end=this.end;}
end=end.startOf(unit,opts);return Math.floor(end.diff(start,unit).get(unit))+(end.valueOf()!==this.end.valueOf());};_proto.hasSame=function hasSame(unit){return this.isValid?this.isEmpty()||this.e.minus(1).hasSame(this.s,unit):false;};_proto.isEmpty=function isEmpty(){return this.s.valueOf()===this.e.valueOf();};_proto.isAfter=function isAfter(dateTime){if(!this.isValid)return false;return this.s>dateTime;};_proto.isBefore=function isBefore(dateTime){if(!this.isValid)return false;return this.e<=dateTime;};_proto.contains=function contains(dateTime){if(!this.isValid)return false;return this.s<=dateTime&&this.e>dateTime;};_proto.set=function set(_temp){var _ref=_temp===void 0?{}:_temp,start=_ref.start,end=_ref.end;if(!this.isValid)return this;return Interval.fromDateTimes(start||this.s,end||this.e);};_proto.splitAt=function splitAt(){var _this=this;if(!this.isValid)return[];for(var _len=arguments.length,dateTimes=new Array(_len),_key=0;_key<_len;_key++){dateTimes[_key]=arguments[_key];}
var sorted=dateTimes.map(friendlyDateTime).filter(function(d){return _this.contains(d);}).sort(function(a,b){return a.toMillis()-b.toMillis();}),results=[];var s=this.s,i=0;while(s<this.e){var added=sorted[i]||this.e,next=+added>+this.e?this.e:added;results.push(Interval.fromDateTimes(s,next));s=next;i+=1;}
return results;};_proto.splitBy=function splitBy(duration){var dur=Duration.fromDurationLike(duration);if(!this.isValid||!dur.isValid||dur.as("milliseconds")===0){return[];}
var s=this.s,idx=1,next;var results=[];while(s<this.e){var added=this.start.plus(dur.mapUnits(function(x){return x*idx;}));next=+added>+this.e?this.e:added;results.push(Interval.fromDateTimes(s,next));s=next;idx+=1;}
return results;};_proto.divideEqually=function divideEqually(numberOfParts){if(!this.isValid)return[];return this.splitBy(this.length()/numberOfParts).slice(0,numberOfParts);};_proto.overlaps=function overlaps(other){return this.e>other.s&&this.s<other.e;};_proto.abutsStart=function abutsStart(other){if(!this.isValid)return false;return+this.e===+other.s;};_proto.abutsEnd=function abutsEnd(other){if(!this.isValid)return false;return+other.e===+this.s;};_proto.engulfs=function engulfs(other){if(!this.isValid)return false;return this.s<=other.s&&this.e>=other.e;};_proto.equals=function equals(other){if(!this.isValid||!other.isValid){return false;}
return this.s.equals(other.s)&&this.e.equals(other.e);};_proto.intersection=function intersection(other){if(!this.isValid)return this;var s=this.s>other.s?this.s:other.s,e=this.e<other.e?this.e:other.e;if(s>=e){return null;}else{return Interval.fromDateTimes(s,e);}};_proto.union=function union(other){if(!this.isValid)return this;var s=this.s<other.s?this.s:other.s,e=this.e>other.e?this.e:other.e;return Interval.fromDateTimes(s,e);};Interval.merge=function merge(intervals){var _intervals$sort$reduc=intervals.sort(function(a,b){return a.s-b.s;}).reduce(function(_ref2,item){var sofar=_ref2[0],current=_ref2[1];if(!current){return[sofar,item];}else if(current.overlaps(item)||current.abutsStart(item)){return[sofar,current.union(item)];}else{return[sofar.concat([current]),item];}},[[],null]),found=_intervals$sort$reduc[0],final=_intervals$sort$reduc[1];if(final){found.push(final);}
return found;};Interval.xor=function xor(intervals){var _Array$prototype;var start=null,currentCount=0;var results=[],ends=intervals.map(function(i){return[{time:i.s,type:"s"},{time:i.e,type:"e"}];}),flattened=(_Array$prototype=Array.prototype).concat.apply(_Array$prototype,ends),arr=flattened.sort(function(a,b){return a.time-b.time;});for(var _iterator=_createForOfIteratorHelperLoose(arr),_step;!(_step=_iterator()).done;){var i=_step.value;currentCount+=i.type==="s"?1:-1;if(currentCount===1){start=i.time;}else{if(start&&+start!==+i.time){results.push(Interval.fromDateTimes(start,i.time));}
start=null;}}
return Interval.merge(results);};_proto.difference=function difference(){var _this2=this;for(var _len2=arguments.length,intervals=new Array(_len2),_key2=0;_key2<_len2;_key2++){intervals[_key2]=arguments[_key2];}
return Interval.xor([this].concat(intervals)).map(function(i){return _this2.intersection(i);}).filter(function(i){return i&&!i.isEmpty();});};_proto.toString=function toString(){if(!this.isValid)return INVALID$1;return"["+this.s.toISO()+" \u2013 "+this.e.toISO()+")";};_proto[_Symbol$for]=function(){if(this.isValid){return"Interval { start: "+this.s.toISO()+", end: "+this.e.toISO()+" }";}else{return"Interval { Invalid, reason: "+this.invalidReason+" }";}};_proto.toLocaleString=function toLocaleString(formatOpts,opts){if(formatOpts===void 0){formatOpts=DATE_SHORT;}
if(opts===void 0){opts={};}
return this.isValid?Formatter.create(this.s.loc.clone(opts),formatOpts).formatInterval(this):INVALID$1;};_proto.toISO=function toISO(opts){if(!this.isValid)return INVALID$1;return this.s.toISO(opts)+"/"+this.e.toISO(opts);};_proto.toISODate=function toISODate(){if(!this.isValid)return INVALID$1;return this.s.toISODate()+"/"+this.e.toISODate();};_proto.toISOTime=function toISOTime(opts){if(!this.isValid)return INVALID$1;return this.s.toISOTime(opts)+"/"+this.e.toISOTime(opts);};_proto.toFormat=function toFormat(dateFormat,_temp2){var _ref3=_temp2===void 0?{}:_temp2,_ref3$separator=_ref3.separator,separator=_ref3$separator===void 0?" ":_ref3$separator;if(!this.isValid)return INVALID$1;return""+this.s.toFormat(dateFormat)+separator+this.e.toFormat(dateFormat);};_proto.toDuration=function toDuration(unit,opts){if(!this.isValid){return Duration.invalid(this.invalidReason);}
return this.e.diff(this.s,unit,opts);};_proto.mapEndpoints=function mapEndpoints(mapFn){return Interval.fromDateTimes(mapFn(this.s),mapFn(this.e));};_createClass(Interval,[{key:"start",get:function get(){return this.isValid?this.s:null;}},{key:"end",get:function get(){return this.isValid?this.e:null;}},{key:"isValid",get:function get(){return this.invalidReason===null;}},{key:"invalidReason",get:function get(){return this.invalid?this.invalid.reason:null;}},{key:"invalidExplanation",get:function get(){return this.invalid?this.invalid.explanation:null;}}]);return Interval;}(Symbol.for("nodejs.util.inspect.custom"));var Info=function(){function Info(){}
Info.hasDST=function hasDST(zone){if(zone===void 0){zone=Settings.defaultZone;}
var proto=DateTime.now().setZone(zone).set({month:12});return!zone.isUniversal&&proto.offset!==proto.set({month:6}).offset;};Info.isValidIANAZone=function isValidIANAZone(zone){return IANAZone.isValidZone(zone);};Info.normalizeZone=function normalizeZone$1(input){return normalizeZone(input,Settings.defaultZone);};Info.getStartOfWeek=function getStartOfWeek(_temp){var _ref=_temp===void 0?{}:_temp,_ref$locale=_ref.locale,locale=_ref$locale===void 0?null:_ref$locale,_ref$locObj=_ref.locObj,locObj=_ref$locObj===void 0?null:_ref$locObj;return(locObj||Locale.create(locale)).getStartOfWeek();};Info.getMinimumDaysInFirstWeek=function getMinimumDaysInFirstWeek(_temp2){var _ref2=_temp2===void 0?{}:_temp2,_ref2$locale=_ref2.locale,locale=_ref2$locale===void 0?null:_ref2$locale,_ref2$locObj=_ref2.locObj,locObj=_ref2$locObj===void 0?null:_ref2$locObj;return(locObj||Locale.create(locale)).getMinDaysInFirstWeek();};Info.getWeekendWeekdays=function getWeekendWeekdays(_temp3){var _ref3=_temp3===void 0?{}:_temp3,_ref3$locale=_ref3.locale,locale=_ref3$locale===void 0?null:_ref3$locale,_ref3$locObj=_ref3.locObj,locObj=_ref3$locObj===void 0?null:_ref3$locObj;return(locObj||Locale.create(locale)).getWeekendDays().slice();};Info.months=function months(length,_temp4){if(length===void 0){length="long";}
var _ref4=_temp4===void 0?{}:_temp4,_ref4$locale=_ref4.locale,locale=_ref4$locale===void 0?null:_ref4$locale,_ref4$numberingSystem=_ref4.numberingSystem,numberingSystem=_ref4$numberingSystem===void 0?null:_ref4$numberingSystem,_ref4$locObj=_ref4.locObj,locObj=_ref4$locObj===void 0?null:_ref4$locObj,_ref4$outputCalendar=_ref4.outputCalendar,outputCalendar=_ref4$outputCalendar===void 0?"gregory":_ref4$outputCalendar;return(locObj||Locale.create(locale,numberingSystem,outputCalendar)).months(length);};Info.monthsFormat=function monthsFormat(length,_temp5){if(length===void 0){length="long";}
var _ref5=_temp5===void 0?{}:_temp5,_ref5$locale=_ref5.locale,locale=_ref5$locale===void 0?null:_ref5$locale,_ref5$numberingSystem=_ref5.numberingSystem,numberingSystem=_ref5$numberingSystem===void 0?null:_ref5$numberingSystem,_ref5$locObj=_ref5.locObj,locObj=_ref5$locObj===void 0?null:_ref5$locObj,_ref5$outputCalendar=_ref5.outputCalendar,outputCalendar=_ref5$outputCalendar===void 0?"gregory":_ref5$outputCalendar;return(locObj||Locale.create(locale,numberingSystem,outputCalendar)).months(length,true);};Info.weekdays=function weekdays(length,_temp6){if(length===void 0){length="long";}
var _ref6=_temp6===void 0?{}:_temp6,_ref6$locale=_ref6.locale,locale=_ref6$locale===void 0?null:_ref6$locale,_ref6$numberingSystem=_ref6.numberingSystem,numberingSystem=_ref6$numberingSystem===void 0?null:_ref6$numberingSystem,_ref6$locObj=_ref6.locObj,locObj=_ref6$locObj===void 0?null:_ref6$locObj;return(locObj||Locale.create(locale,numberingSystem,null)).weekdays(length);};Info.weekdaysFormat=function weekdaysFormat(length,_temp7){if(length===void 0){length="long";}
var _ref7=_temp7===void 0?{}:_temp7,_ref7$locale=_ref7.locale,locale=_ref7$locale===void 0?null:_ref7$locale,_ref7$numberingSystem=_ref7.numberingSystem,numberingSystem=_ref7$numberingSystem===void 0?null:_ref7$numberingSystem,_ref7$locObj=_ref7.locObj,locObj=_ref7$locObj===void 0?null:_ref7$locObj;return(locObj||Locale.create(locale,numberingSystem,null)).weekdays(length,true);};Info.meridiems=function meridiems(_temp8){var _ref8=_temp8===void 0?{}:_temp8,_ref8$locale=_ref8.locale,locale=_ref8$locale===void 0?null:_ref8$locale;return Locale.create(locale).meridiems();};Info.eras=function eras(length,_temp9){if(length===void 0){length="short";}
var _ref9=_temp9===void 0?{}:_temp9,_ref9$locale=_ref9.locale,locale=_ref9$locale===void 0?null:_ref9$locale;return Locale.create(locale,null,"gregory").eras(length);};Info.features=function features(){return{relative:hasRelative(),localeWeek:hasLocaleWeekInfo()};};return Info;}();function dayDiff(earlier,later){var utcDayStart=function utcDayStart(dt){return dt.toUTC(0,{keepLocalTime:true}).startOf("day").valueOf();},ms=utcDayStart(later)-utcDayStart(earlier);return Math.floor(Duration.fromMillis(ms).as("days"));}
function highOrderDiffs(cursor,later,units){var differs=[["years",function(a,b){return b.year-a.year;}],["quarters",function(a,b){return b.quarter-a.quarter+(b.year-a.year)*4;}],["months",function(a,b){return b.month-a.month+(b.year-a.year)*12;}],["weeks",function(a,b){var days=dayDiff(a,b);return(days-days%7)/7;}],["days",dayDiff]];var results={};var earlier=cursor;var lowestOrder,highWater;for(var _i=0,_differs=differs;_i<_differs.length;_i++){var _differs$_i=_differs[_i],unit=_differs$_i[0],differ=_differs$_i[1];if(units.indexOf(unit)>=0){lowestOrder=unit;results[unit]=differ(cursor,later);highWater=earlier.plus(results);if(highWater>later){results[unit]--;cursor=earlier.plus(results);if(cursor>later){highWater=cursor;results[unit]--;cursor=earlier.plus(results);}}else{cursor=highWater;}}}
return[cursor,results,highWater,lowestOrder];}
function _diff(earlier,later,units,opts){var _highOrderDiffs=highOrderDiffs(earlier,later,units),cursor=_highOrderDiffs[0],results=_highOrderDiffs[1],highWater=_highOrderDiffs[2],lowestOrder=_highOrderDiffs[3];var remainingMillis=later-cursor;var lowerOrderUnits=units.filter(function(u){return["hours","minutes","seconds","milliseconds"].indexOf(u)>=0;});if(lowerOrderUnits.length===0){if(highWater<later){var _cursor$plus;highWater=cursor.plus((_cursor$plus={},_cursor$plus[lowestOrder]=1,_cursor$plus));}
if(highWater!==cursor){results[lowestOrder]=(results[lowestOrder]||0)+remainingMillis/(highWater-cursor);}}
var duration=Duration.fromObject(results,opts);if(lowerOrderUnits.length>0){var _Duration$fromMillis;return(_Duration$fromMillis=Duration.fromMillis(remainingMillis,opts)).shiftTo.apply(_Duration$fromMillis,lowerOrderUnits).plus(duration);}else{return duration;}}
var MISSING_FTP="missing Intl.DateTimeFormat.formatToParts support";function intUnit(regex,post){if(post===void 0){post=function post(i){return i;};}
return{regex:regex,deser:function deser(_ref){var s=_ref[0];return post(parseDigits(s));}};}
var NBSP=String.fromCharCode(160);var spaceOrNBSP="[ "+NBSP+"]";var spaceOrNBSPRegExp=new RegExp(spaceOrNBSP,"g");function fixListRegex(s){return s.replace(/\./g,"\\.?").replace(spaceOrNBSPRegExp,spaceOrNBSP);}
function stripInsensitivities(s){return s.replace(/\./g,"").replace(spaceOrNBSPRegExp," ").toLowerCase();}
function oneOf(strings,startIndex){if(strings===null){return null;}else{return{regex:RegExp(strings.map(fixListRegex).join("|")),deser:function deser(_ref2){var s=_ref2[0];return strings.findIndex(function(i){return stripInsensitivities(s)===stripInsensitivities(i);})+startIndex;}};}}
function offset(regex,groups){return{regex:regex,deser:function deser(_ref3){var h=_ref3[1],m=_ref3[2];return signedOffset(h,m);},groups:groups};}
function simple(regex){return{regex:regex,deser:function deser(_ref4){var s=_ref4[0];return s;}};}
function escapeToken(value){return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&");}
function unitForToken(token,loc){var one=digitRegex(loc),two=digitRegex(loc,"{2}"),three=digitRegex(loc,"{3}"),four=digitRegex(loc,"{4}"),six=digitRegex(loc,"{6}"),oneOrTwo=digitRegex(loc,"{1,2}"),oneToThree=digitRegex(loc,"{1,3}"),oneToSix=digitRegex(loc,"{1,6}"),oneToNine=digitRegex(loc,"{1,9}"),twoToFour=digitRegex(loc,"{2,4}"),fourToSix=digitRegex(loc,"{4,6}"),literal=function literal(t){return{regex:RegExp(escapeToken(t.val)),deser:function deser(_ref5){var s=_ref5[0];return s;},literal:true};},unitate=function unitate(t){if(token.literal){return literal(t);}
switch(t.val){case"G":return oneOf(loc.eras("short"),0);case"GG":return oneOf(loc.eras("long"),0);case"y":return intUnit(oneToSix);case"yy":return intUnit(twoToFour,untruncateYear);case"yyyy":return intUnit(four);case"yyyyy":return intUnit(fourToSix);case"yyyyyy":return intUnit(six);case"M":return intUnit(oneOrTwo);case"MM":return intUnit(two);case"MMM":return oneOf(loc.months("short",true),1);case"MMMM":return oneOf(loc.months("long",true),1);case"L":return intUnit(oneOrTwo);case"LL":return intUnit(two);case"LLL":return oneOf(loc.months("short",false),1);case"LLLL":return oneOf(loc.months("long",false),1);case"d":return intUnit(oneOrTwo);case"dd":return intUnit(two);case"o":return intUnit(oneToThree);case"ooo":return intUnit(three);case"HH":return intUnit(two);case"H":return intUnit(oneOrTwo);case"hh":return intUnit(two);case"h":return intUnit(oneOrTwo);case"mm":return intUnit(two);case"m":return intUnit(oneOrTwo);case"q":return intUnit(oneOrTwo);case"qq":return intUnit(two);case"s":return intUnit(oneOrTwo);case"ss":return intUnit(two);case"S":return intUnit(oneToThree);case"SSS":return intUnit(three);case"u":return simple(oneToNine);case"uu":return simple(oneOrTwo);case"uuu":return intUnit(one);case"a":return oneOf(loc.meridiems(),0);case"kkkk":return intUnit(four);case"kk":return intUnit(twoToFour,untruncateYear);case"W":return intUnit(oneOrTwo);case"WW":return intUnit(two);case"E":case"c":return intUnit(one);case"EEE":return oneOf(loc.weekdays("short",false),1);case"EEEE":return oneOf(loc.weekdays("long",false),1);case"ccc":return oneOf(loc.weekdays("short",true),1);case"cccc":return oneOf(loc.weekdays("long",true),1);case"Z":case"ZZ":return offset(new RegExp("([+-]"+oneOrTwo.source+")(?::("+two.source+"))?"),2);case"ZZZ":return offset(new RegExp("([+-]"+oneOrTwo.source+")("+two.source+")?"),2);case"z":return simple(/[a-z_+-/]{1,256}?/i);case" ":return simple(/[^\S\n\r]/);default:return literal(t);}};var unit=unitate(token)||{invalidReason:MISSING_FTP};unit.token=token;return unit;}
var partTypeStyleToTokenVal={year:{"2-digit":"yy",numeric:"yyyyy"},month:{numeric:"M","2-digit":"MM",short:"MMM",long:"MMMM"},day:{numeric:"d","2-digit":"dd"},weekday:{short:"EEE",long:"EEEE"},dayperiod:"a",dayPeriod:"a",hour12:{numeric:"h","2-digit":"hh"},hour24:{numeric:"H","2-digit":"HH"},minute:{numeric:"m","2-digit":"mm"},second:{numeric:"s","2-digit":"ss"},timeZoneName:{long:"ZZZZZ",short:"ZZZ"}};function tokenForPart(part,formatOpts,resolvedOpts){var type=part.type,value=part.value;if(type==="literal"){var isSpace=/^\s+$/.test(value);return{literal:!isSpace,val:isSpace?" ":value};}
var style=formatOpts[type];var actualType=type;if(type==="hour"){if(formatOpts.hour12!=null){actualType=formatOpts.hour12?"hour12":"hour24";}else if(formatOpts.hourCycle!=null){if(formatOpts.hourCycle==="h11"||formatOpts.hourCycle==="h12"){actualType="hour12";}else{actualType="hour24";}}else{actualType=resolvedOpts.hour12?"hour12":"hour24";}}
var val=partTypeStyleToTokenVal[actualType];if(typeof val==="object"){val=val[style];}
if(val){return{literal:false,val:val};}
return undefined;}
function buildRegex(units){var re=units.map(function(u){return u.regex;}).reduce(function(f,r){return f+"("+r.source+")";},"");return["^"+re+"$",units];}
function match(input,regex,handlers){var matches=input.match(regex);if(matches){var all={};var matchIndex=1;for(var i in handlers){if(hasOwnProperty(handlers,i)){var h=handlers[i],groups=h.groups?h.groups+1:1;if(!h.literal&&h.token){all[h.token.val[0]]=h.deser(matches.slice(matchIndex,matchIndex+groups));}
matchIndex+=groups;}}
return[matches,all];}else{return[matches,{}];}}
function dateTimeFromMatches(matches){var toField=function toField(token){switch(token){case"S":return"millisecond";case"s":return"second";case"m":return"minute";case"h":case"H":return"hour";case"d":return"day";case"o":return"ordinal";case"L":case"M":return"month";case"y":return"year";case"E":case"c":return"weekday";case"W":return"weekNumber";case"k":return"weekYear";case"q":return"quarter";default:return null;}};var zone=null;var specificOffset;if(!isUndefined(matches.z)){zone=IANAZone.create(matches.z);}
if(!isUndefined(matches.Z)){if(!zone){zone=new FixedOffsetZone(matches.Z);}
specificOffset=matches.Z;}
if(!isUndefined(matches.q)){matches.M=(matches.q-1)*3+1;}
if(!isUndefined(matches.h)){if(matches.h<12&&matches.a===1){matches.h+=12;}else if(matches.h===12&&matches.a===0){matches.h=0;}}
if(matches.G===0&&matches.y){matches.y=-matches.y;}
if(!isUndefined(matches.u)){matches.S=parseMillis(matches.u);}
var vals=Object.keys(matches).reduce(function(r,k){var f=toField(k);if(f){r[f]=matches[k];}
return r;},{});return[vals,zone,specificOffset];}
var dummyDateTimeCache=null;function getDummyDateTime(){if(!dummyDateTimeCache){dummyDateTimeCache=DateTime.fromMillis(1555555555555);}
return dummyDateTimeCache;}
function maybeExpandMacroToken(token,locale){if(token.literal){return token;}
var formatOpts=Formatter.macroTokenToFormatOpts(token.val);var tokens=formatOptsToTokens(formatOpts,locale);if(tokens==null||tokens.includes(undefined)){return token;}
return tokens;}
function expandMacroTokens(tokens,locale){var _Array$prototype;return(_Array$prototype=Array.prototype).concat.apply(_Array$prototype,tokens.map(function(t){return maybeExpandMacroToken(t,locale);}));}
var TokenParser=function(){function TokenParser(locale,format){this.locale=locale;this.format=format;this.tokens=expandMacroTokens(Formatter.parseFormat(format),locale);this.units=this.tokens.map(function(t){return unitForToken(t,locale);});this.disqualifyingUnit=this.units.find(function(t){return t.invalidReason;});if(!this.disqualifyingUnit){var _buildRegex=buildRegex(this.units),regexString=_buildRegex[0],handlers=_buildRegex[1];this.regex=RegExp(regexString,"i");this.handlers=handlers;}}
var _proto=TokenParser.prototype;_proto.explainFromTokens=function explainFromTokens(input){if(!this.isValid){return{input:input,tokens:this.tokens,invalidReason:this.invalidReason};}else{var _match=match(input,this.regex,this.handlers),rawMatches=_match[0],matches=_match[1],_ref6=matches?dateTimeFromMatches(matches):[null,null,undefined],result=_ref6[0],zone=_ref6[1],specificOffset=_ref6[2];if(hasOwnProperty(matches,"a")&&hasOwnProperty(matches,"H")){throw new ConflictingSpecificationError("Can't include meridiem when specifying 24-hour format");}
return{input:input,tokens:this.tokens,regex:this.regex,rawMatches:rawMatches,matches:matches,result:result,zone:zone,specificOffset:specificOffset};}};_createClass(TokenParser,[{key:"isValid",get:function get(){return!this.disqualifyingUnit;}},{key:"invalidReason",get:function get(){return this.disqualifyingUnit?this.disqualifyingUnit.invalidReason:null;}}]);return TokenParser;}();function explainFromTokens(locale,input,format){var parser=new TokenParser(locale,format);return parser.explainFromTokens(input);}
function parseFromTokens(locale,input,format){var _explainFromTokens=explainFromTokens(locale,input,format),result=_explainFromTokens.result,zone=_explainFromTokens.zone,specificOffset=_explainFromTokens.specificOffset,invalidReason=_explainFromTokens.invalidReason;return[result,zone,specificOffset,invalidReason];}
function formatOptsToTokens(formatOpts,locale){if(!formatOpts){return null;}
var formatter=Formatter.create(locale,formatOpts);var df=formatter.dtFormatter(getDummyDateTime());var parts=df.formatToParts();var resolvedOpts=df.resolvedOptions();return parts.map(function(p){return tokenForPart(p,formatOpts,resolvedOpts);});}
var INVALID="Invalid DateTime";var MAX_DATE=8.64e15;function unsupportedZone(zone){return new Invalid("unsupported zone","the zone \""+zone.name+"\" is not supported");}
function possiblyCachedWeekData(dt){if(dt.weekData===null){dt.weekData=gregorianToWeek(dt.c);}
return dt.weekData;}
function possiblyCachedLocalWeekData(dt){if(dt.localWeekData===null){dt.localWeekData=gregorianToWeek(dt.c,dt.loc.getMinDaysInFirstWeek(),dt.loc.getStartOfWeek());}
return dt.localWeekData;}
function clone(inst,alts){var current={ts:inst.ts,zone:inst.zone,c:inst.c,o:inst.o,loc:inst.loc,invalid:inst.invalid};return new DateTime(_extends({},current,alts,{old:current}));}
function fixOffset(localTS,o,tz){var utcGuess=localTS-o*60*1000;var o2=tz.offset(utcGuess);if(o===o2){return[utcGuess,o];}
utcGuess-=(o2-o)*60*1000;var o3=tz.offset(utcGuess);if(o2===o3){return[utcGuess,o2];}
return[localTS-Math.min(o2,o3)*60*1000,Math.max(o2,o3)];}
function tsToObj(ts,offset){ts+=offset*60*1000;var d=new Date(ts);return{year:d.getUTCFullYear(),month:d.getUTCMonth()+1,day:d.getUTCDate(),hour:d.getUTCHours(),minute:d.getUTCMinutes(),second:d.getUTCSeconds(),millisecond:d.getUTCMilliseconds()};}
function objToTS(obj,offset,zone){return fixOffset(objToLocalTS(obj),offset,zone);}
function adjustTime(inst,dur){var oPre=inst.o,year=inst.c.year+Math.trunc(dur.years),month=inst.c.month+Math.trunc(dur.months)+Math.trunc(dur.quarters)*3,c=_extends({},inst.c,{year:year,month:month,day:Math.min(inst.c.day,daysInMonth(year,month))+Math.trunc(dur.days)+Math.trunc(dur.weeks)*7}),millisToAdd=Duration.fromObject({years:dur.years-Math.trunc(dur.years),quarters:dur.quarters-Math.trunc(dur.quarters),months:dur.months-Math.trunc(dur.months),weeks:dur.weeks-Math.trunc(dur.weeks),days:dur.days-Math.trunc(dur.days),hours:dur.hours,minutes:dur.minutes,seconds:dur.seconds,milliseconds:dur.milliseconds}).as("milliseconds"),localTS=objToLocalTS(c);var _fixOffset=fixOffset(localTS,oPre,inst.zone),ts=_fixOffset[0],o=_fixOffset[1];if(millisToAdd!==0){ts+=millisToAdd;o=inst.zone.offset(ts);}
return{ts:ts,o:o};}
function parseDataToDateTime(parsed,parsedZone,opts,format,text,specificOffset){var setZone=opts.setZone,zone=opts.zone;if(parsed&&Object.keys(parsed).length!==0||parsedZone){var interpretationZone=parsedZone||zone,inst=DateTime.fromObject(parsed,_extends({},opts,{zone:interpretationZone,specificOffset:specificOffset}));return setZone?inst:inst.setZone(zone);}else{return DateTime.invalid(new Invalid("unparsable","the input \""+text+"\" can't be parsed as "+format));}}
function toTechFormat(dt,format,allowZ){if(allowZ===void 0){allowZ=true;}
return dt.isValid?Formatter.create(Locale.create("en-US"),{allowZ:allowZ,forceSimple:true}).formatDateTimeFromString(dt,format):null;}
function _toISODate(o,extended){var longFormat=o.c.year>9999||o.c.year<0;var c="";if(longFormat&&o.c.year>=0)c+="+";c+=padStart(o.c.year,longFormat?6:4);if(extended){c+="-";c+=padStart(o.c.month);c+="-";c+=padStart(o.c.day);}else{c+=padStart(o.c.month);c+=padStart(o.c.day);}
return c;}
function _toISOTime(o,extended,suppressSeconds,suppressMilliseconds,includeOffset,extendedZone){var c=padStart(o.c.hour);if(extended){c+=":";c+=padStart(o.c.minute);if(o.c.millisecond!==0||o.c.second!==0||!suppressSeconds){c+=":";}}else{c+=padStart(o.c.minute);}
if(o.c.millisecond!==0||o.c.second!==0||!suppressSeconds){c+=padStart(o.c.second);if(o.c.millisecond!==0||!suppressMilliseconds){c+=".";c+=padStart(o.c.millisecond,3);}}
if(includeOffset){if(o.isOffsetFixed&&o.offset===0&&!extendedZone){c+="Z";}else if(o.o<0){c+="-";c+=padStart(Math.trunc(-o.o/60));c+=":";c+=padStart(Math.trunc(-o.o%60));}else{c+="+";c+=padStart(Math.trunc(o.o/60));c+=":";c+=padStart(Math.trunc(o.o%60));}}
if(extendedZone){c+="["+o.zone.ianaName+"]";}
return c;}
var defaultUnitValues={month:1,day:1,hour:0,minute:0,second:0,millisecond:0},defaultWeekUnitValues={weekNumber:1,weekday:1,hour:0,minute:0,second:0,millisecond:0},defaultOrdinalUnitValues={ordinal:1,hour:0,minute:0,second:0,millisecond:0};var orderedUnits=["year","month","day","hour","minute","second","millisecond"],orderedWeekUnits=["weekYear","weekNumber","weekday","hour","minute","second","millisecond"],orderedOrdinalUnits=["year","ordinal","hour","minute","second","millisecond"];function normalizeUnit(unit){var normalized={year:"year",years:"year",month:"month",months:"month",day:"day",days:"day",hour:"hour",hours:"hour",minute:"minute",minutes:"minute",quarter:"quarter",quarters:"quarter",second:"second",seconds:"second",millisecond:"millisecond",milliseconds:"millisecond",weekday:"weekday",weekdays:"weekday",weeknumber:"weekNumber",weeksnumber:"weekNumber",weeknumbers:"weekNumber",weekyear:"weekYear",weekyears:"weekYear",ordinal:"ordinal"}[unit.toLowerCase()];if(!normalized)throw new InvalidUnitError(unit);return normalized;}
function normalizeUnitWithLocalWeeks(unit){switch(unit.toLowerCase()){case"localweekday":case"localweekdays":return"localWeekday";case"localweeknumber":case"localweeknumbers":return"localWeekNumber";case"localweekyear":case"localweekyears":return"localWeekYear";default:return normalizeUnit(unit);}}
function guessOffsetForZone(zone){if(!zoneOffsetGuessCache[zone]){if(zoneOffsetTs===undefined){zoneOffsetTs=Settings.now();}
zoneOffsetGuessCache[zone]=zone.offset(zoneOffsetTs);}
return zoneOffsetGuessCache[zone];}
function quickDT(obj,opts){var zone=normalizeZone(opts.zone,Settings.defaultZone);if(!zone.isValid){return DateTime.invalid(unsupportedZone(zone));}
var loc=Locale.fromObject(opts);var ts,o;if(!isUndefined(obj.year)){for(var _i=0,_orderedUnits=orderedUnits;_i<_orderedUnits.length;_i++){var u=_orderedUnits[_i];if(isUndefined(obj[u])){obj[u]=defaultUnitValues[u];}}
var invalid=hasInvalidGregorianData(obj)||hasInvalidTimeData(obj);if(invalid){return DateTime.invalid(invalid);}
var offsetProvis=guessOffsetForZone(zone);var _objToTS=objToTS(obj,offsetProvis,zone);ts=_objToTS[0];o=_objToTS[1];}else{ts=Settings.now();}
return new DateTime({ts:ts,zone:zone,loc:loc,o:o});}
function diffRelative(start,end,opts){var round=isUndefined(opts.round)?true:opts.round,format=function format(c,unit){c=roundTo(c,round||opts.calendary?0:2,true);var formatter=end.loc.clone(opts).relFormatter(opts);return formatter.format(c,unit);},differ=function differ(unit){if(opts.calendary){if(!end.hasSame(start,unit)){return end.startOf(unit).diff(start.startOf(unit),unit).get(unit);}else return 0;}else{return end.diff(start,unit).get(unit);}};if(opts.unit){return format(differ(opts.unit),opts.unit);}
for(var _iterator=_createForOfIteratorHelperLoose(opts.units),_step;!(_step=_iterator()).done;){var unit=_step.value;var count=differ(unit);if(Math.abs(count)>=1){return format(count,unit);}}
return format(start>end?-0:0,opts.units[opts.units.length-1]);}
function lastOpts(argList){var opts={},args;if(argList.length>0&&typeof argList[argList.length-1]==="object"){opts=argList[argList.length-1];args=Array.from(argList).slice(0,argList.length-1);}else{args=Array.from(argList);}
return[opts,args];}
var zoneOffsetTs;var zoneOffsetGuessCache={};var DateTime=function(_Symbol$for){function DateTime(config){var zone=config.zone||Settings.defaultZone;var invalid=config.invalid||(Number.isNaN(config.ts)?new Invalid("invalid input"):null)||(!zone.isValid?unsupportedZone(zone):null);this.ts=isUndefined(config.ts)?Settings.now():config.ts;var c=null,o=null;if(!invalid){var unchanged=config.old&&config.old.ts===this.ts&&config.old.zone.equals(zone);if(unchanged){var _ref=[config.old.c,config.old.o];c=_ref[0];o=_ref[1];}else{var ot=isNumber(config.o)&&!config.old?config.o:zone.offset(this.ts);c=tsToObj(this.ts,ot);invalid=Number.isNaN(c.year)?new Invalid("invalid input"):null;c=invalid?null:c;o=invalid?null:ot;}}
this._zone=zone;this.loc=config.loc||Locale.create();this.invalid=invalid;this.weekData=null;this.localWeekData=null;this.c=c;this.o=o;this.isLuxonDateTime=true;}
DateTime.now=function now(){return new DateTime({});};DateTime.local=function local(){var _lastOpts=lastOpts(arguments),opts=_lastOpts[0],args=_lastOpts[1],year=args[0],month=args[1],day=args[2],hour=args[3],minute=args[4],second=args[5],millisecond=args[6];return quickDT({year:year,month:month,day:day,hour:hour,minute:minute,second:second,millisecond:millisecond},opts);};DateTime.utc=function utc(){var _lastOpts2=lastOpts(arguments),opts=_lastOpts2[0],args=_lastOpts2[1],year=args[0],month=args[1],day=args[2],hour=args[3],minute=args[4],second=args[5],millisecond=args[6];opts.zone=FixedOffsetZone.utcInstance;return quickDT({year:year,month:month,day:day,hour:hour,minute:minute,second:second,millisecond:millisecond},opts);};DateTime.fromJSDate=function fromJSDate(date,options){if(options===void 0){options={};}
var ts=isDate(date)?date.valueOf():NaN;if(Number.isNaN(ts)){return DateTime.invalid("invalid input");}
var zoneToUse=normalizeZone(options.zone,Settings.defaultZone);if(!zoneToUse.isValid){return DateTime.invalid(unsupportedZone(zoneToUse));}
return new DateTime({ts:ts,zone:zoneToUse,loc:Locale.fromObject(options)});};DateTime.fromMillis=function fromMillis(milliseconds,options){if(options===void 0){options={};}
if(!isNumber(milliseconds)){throw new InvalidArgumentError("fromMillis requires a numerical input, but received a "+typeof milliseconds+" with value "+milliseconds);}else if(milliseconds<-MAX_DATE||milliseconds>MAX_DATE){return DateTime.invalid("Timestamp out of range");}else{return new DateTime({ts:milliseconds,zone:normalizeZone(options.zone,Settings.defaultZone),loc:Locale.fromObject(options)});}};DateTime.fromSeconds=function fromSeconds(seconds,options){if(options===void 0){options={};}
if(!isNumber(seconds)){throw new InvalidArgumentError("fromSeconds requires a numerical input");}else{return new DateTime({ts:seconds*1000,zone:normalizeZone(options.zone,Settings.defaultZone),loc:Locale.fromObject(options)});}};DateTime.fromObject=function fromObject(obj,opts){if(opts===void 0){opts={};}
obj=obj||{};var zoneToUse=normalizeZone(opts.zone,Settings.defaultZone);if(!zoneToUse.isValid){return DateTime.invalid(unsupportedZone(zoneToUse));}
var loc=Locale.fromObject(opts);var normalized=normalizeObject(obj,normalizeUnitWithLocalWeeks);var _usesLocalWeekValues=usesLocalWeekValues(normalized,loc),minDaysInFirstWeek=_usesLocalWeekValues.minDaysInFirstWeek,startOfWeek=_usesLocalWeekValues.startOfWeek;var tsNow=Settings.now(),offsetProvis=!isUndefined(opts.specificOffset)?opts.specificOffset:zoneToUse.offset(tsNow),containsOrdinal=!isUndefined(normalized.ordinal),containsGregorYear=!isUndefined(normalized.year),containsGregorMD=!isUndefined(normalized.month)||!isUndefined(normalized.day),containsGregor=containsGregorYear||containsGregorMD,definiteWeekDef=normalized.weekYear||normalized.weekNumber;if((containsGregor||containsOrdinal)&&definiteWeekDef){throw new ConflictingSpecificationError("Can't mix weekYear/weekNumber units with year/month/day or ordinals");}
if(containsGregorMD&&containsOrdinal){throw new ConflictingSpecificationError("Can't mix ordinal dates with month/day");}
var useWeekData=definiteWeekDef||normalized.weekday&&!containsGregor;var units,defaultValues,objNow=tsToObj(tsNow,offsetProvis);if(useWeekData){units=orderedWeekUnits;defaultValues=defaultWeekUnitValues;objNow=gregorianToWeek(objNow,minDaysInFirstWeek,startOfWeek);}else if(containsOrdinal){units=orderedOrdinalUnits;defaultValues=defaultOrdinalUnitValues;objNow=gregorianToOrdinal(objNow);}else{units=orderedUnits;defaultValues=defaultUnitValues;}
var foundFirst=false;for(var _iterator2=_createForOfIteratorHelperLoose(units),_step2;!(_step2=_iterator2()).done;){var u=_step2.value;var v=normalized[u];if(!isUndefined(v)){foundFirst=true;}else if(foundFirst){normalized[u]=defaultValues[u];}else{normalized[u]=objNow[u];}}
var higherOrderInvalid=useWeekData?hasInvalidWeekData(normalized,minDaysInFirstWeek,startOfWeek):containsOrdinal?hasInvalidOrdinalData(normalized):hasInvalidGregorianData(normalized),invalid=higherOrderInvalid||hasInvalidTimeData(normalized);if(invalid){return DateTime.invalid(invalid);}
var gregorian=useWeekData?weekToGregorian(normalized,minDaysInFirstWeek,startOfWeek):containsOrdinal?ordinalToGregorian(normalized):normalized,_objToTS2=objToTS(gregorian,offsetProvis,zoneToUse),tsFinal=_objToTS2[0],offsetFinal=_objToTS2[1],inst=new DateTime({ts:tsFinal,zone:zoneToUse,o:offsetFinal,loc:loc});if(normalized.weekday&&containsGregor&&obj.weekday!==inst.weekday){return DateTime.invalid("mismatched weekday","you can't specify both a weekday of "+normalized.weekday+" and a date of "+inst.toISO());}
if(!inst.isValid){return DateTime.invalid(inst.invalid);}
return inst;};DateTime.fromISO=function fromISO(text,opts){if(opts===void 0){opts={};}
var _parseISODate=parseISODate(text),vals=_parseISODate[0],parsedZone=_parseISODate[1];return parseDataToDateTime(vals,parsedZone,opts,"ISO 8601",text);};DateTime.fromRFC2822=function fromRFC2822(text,opts){if(opts===void 0){opts={};}
var _parseRFC2822Date=parseRFC2822Date(text),vals=_parseRFC2822Date[0],parsedZone=_parseRFC2822Date[1];return parseDataToDateTime(vals,parsedZone,opts,"RFC 2822",text);};DateTime.fromHTTP=function fromHTTP(text,opts){if(opts===void 0){opts={};}
var _parseHTTPDate=parseHTTPDate(text),vals=_parseHTTPDate[0],parsedZone=_parseHTTPDate[1];return parseDataToDateTime(vals,parsedZone,opts,"HTTP",opts);};DateTime.fromFormat=function fromFormat(text,fmt,opts){if(opts===void 0){opts={};}
if(isUndefined(text)||isUndefined(fmt)){throw new InvalidArgumentError("fromFormat requires an input string and a format");}
var _opts=opts,_opts$locale=_opts.locale,locale=_opts$locale===void 0?null:_opts$locale,_opts$numberingSystem=_opts.numberingSystem,numberingSystem=_opts$numberingSystem===void 0?null:_opts$numberingSystem,localeToUse=Locale.fromOpts({locale:locale,numberingSystem:numberingSystem,defaultToEN:true}),_parseFromTokens=parseFromTokens(localeToUse,text,fmt),vals=_parseFromTokens[0],parsedZone=_parseFromTokens[1],specificOffset=_parseFromTokens[2],invalid=_parseFromTokens[3];if(invalid){return DateTime.invalid(invalid);}else{return parseDataToDateTime(vals,parsedZone,opts,"format "+fmt,text,specificOffset);}};DateTime.fromString=function fromString(text,fmt,opts){if(opts===void 0){opts={};}
return DateTime.fromFormat(text,fmt,opts);};DateTime.fromSQL=function fromSQL(text,opts){if(opts===void 0){opts={};}
var _parseSQL=parseSQL(text),vals=_parseSQL[0],parsedZone=_parseSQL[1];return parseDataToDateTime(vals,parsedZone,opts,"SQL",text);};DateTime.invalid=function invalid(reason,explanation){if(explanation===void 0){explanation=null;}
if(!reason){throw new InvalidArgumentError("need to specify a reason the DateTime is invalid");}
var invalid=reason instanceof Invalid?reason:new Invalid(reason,explanation);if(Settings.throwOnInvalid){throw new InvalidDateTimeError(invalid);}else{return new DateTime({invalid:invalid});}};DateTime.isDateTime=function isDateTime(o){return o&&o.isLuxonDateTime||false;};DateTime.parseFormatForOpts=function parseFormatForOpts(formatOpts,localeOpts){if(localeOpts===void 0){localeOpts={};}
var tokenList=formatOptsToTokens(formatOpts,Locale.fromObject(localeOpts));return!tokenList?null:tokenList.map(function(t){return t?t.val:null;}).join("");};DateTime.expandFormat=function expandFormat(fmt,localeOpts){if(localeOpts===void 0){localeOpts={};}
var expanded=expandMacroTokens(Formatter.parseFormat(fmt),Locale.fromObject(localeOpts));return expanded.map(function(t){return t.val;}).join("");};DateTime.resetCache=function resetCache(){zoneOffsetTs=undefined;zoneOffsetGuessCache={};};var _proto=DateTime.prototype;_proto.get=function get(unit){return this[unit];};_proto.getPossibleOffsets=function getPossibleOffsets(){if(!this.isValid||this.isOffsetFixed){return[this];}
var dayMs=86400000;var minuteMs=60000;var localTS=objToLocalTS(this.c);var oEarlier=this.zone.offset(localTS-dayMs);var oLater=this.zone.offset(localTS+dayMs);var o1=this.zone.offset(localTS-oEarlier*minuteMs);var o2=this.zone.offset(localTS-oLater*minuteMs);if(o1===o2){return[this];}
var ts1=localTS-o1*minuteMs;var ts2=localTS-o2*minuteMs;var c1=tsToObj(ts1,o1);var c2=tsToObj(ts2,o2);if(c1.hour===c2.hour&&c1.minute===c2.minute&&c1.second===c2.second&&c1.millisecond===c2.millisecond){return[clone(this,{ts:ts1}),clone(this,{ts:ts2})];}
return[this];};_proto.resolvedLocaleOptions=function resolvedLocaleOptions(opts){if(opts===void 0){opts={};}
var _Formatter$create$res=Formatter.create(this.loc.clone(opts),opts).resolvedOptions(this),locale=_Formatter$create$res.locale,numberingSystem=_Formatter$create$res.numberingSystem,calendar=_Formatter$create$res.calendar;return{locale:locale,numberingSystem:numberingSystem,outputCalendar:calendar};};_proto.toUTC=function toUTC(offset,opts){if(offset===void 0){offset=0;}
if(opts===void 0){opts={};}
return this.setZone(FixedOffsetZone.instance(offset),opts);};_proto.toLocal=function toLocal(){return this.setZone(Settings.defaultZone);};_proto.setZone=function setZone(zone,_temp){var _ref2=_temp===void 0?{}:_temp,_ref2$keepLocalTime=_ref2.keepLocalTime,keepLocalTime=_ref2$keepLocalTime===void 0?false:_ref2$keepLocalTime,_ref2$keepCalendarTim=_ref2.keepCalendarTime,keepCalendarTime=_ref2$keepCalendarTim===void 0?false:_ref2$keepCalendarTim;zone=normalizeZone(zone,Settings.defaultZone);if(zone.equals(this.zone)){return this;}else if(!zone.isValid){return DateTime.invalid(unsupportedZone(zone));}else{var newTS=this.ts;if(keepLocalTime||keepCalendarTime){var offsetGuess=zone.offset(this.ts);var asObj=this.toObject();var _objToTS3=objToTS(asObj,offsetGuess,zone);newTS=_objToTS3[0];}
return clone(this,{ts:newTS,zone:zone});}};_proto.reconfigure=function reconfigure(_temp2){var _ref3=_temp2===void 0?{}:_temp2,locale=_ref3.locale,numberingSystem=_ref3.numberingSystem,outputCalendar=_ref3.outputCalendar;var loc=this.loc.clone({locale:locale,numberingSystem:numberingSystem,outputCalendar:outputCalendar});return clone(this,{loc:loc});};_proto.setLocale=function setLocale(locale){return this.reconfigure({locale:locale});};_proto.set=function set(values){if(!this.isValid)return this;var normalized=normalizeObject(values,normalizeUnitWithLocalWeeks);var _usesLocalWeekValues2=usesLocalWeekValues(normalized,this.loc),minDaysInFirstWeek=_usesLocalWeekValues2.minDaysInFirstWeek,startOfWeek=_usesLocalWeekValues2.startOfWeek;var settingWeekStuff=!isUndefined(normalized.weekYear)||!isUndefined(normalized.weekNumber)||!isUndefined(normalized.weekday),containsOrdinal=!isUndefined(normalized.ordinal),containsGregorYear=!isUndefined(normalized.year),containsGregorMD=!isUndefined(normalized.month)||!isUndefined(normalized.day),containsGregor=containsGregorYear||containsGregorMD,definiteWeekDef=normalized.weekYear||normalized.weekNumber;if((containsGregor||containsOrdinal)&&definiteWeekDef){throw new ConflictingSpecificationError("Can't mix weekYear/weekNumber units with year/month/day or ordinals");}
if(containsGregorMD&&containsOrdinal){throw new ConflictingSpecificationError("Can't mix ordinal dates with month/day");}
var mixed;if(settingWeekStuff){mixed=weekToGregorian(_extends({},gregorianToWeek(this.c,minDaysInFirstWeek,startOfWeek),normalized),minDaysInFirstWeek,startOfWeek);}else if(!isUndefined(normalized.ordinal)){mixed=ordinalToGregorian(_extends({},gregorianToOrdinal(this.c),normalized));}else{mixed=_extends({},this.toObject(),normalized);if(isUndefined(normalized.day)){mixed.day=Math.min(daysInMonth(mixed.year,mixed.month),mixed.day);}}
var _objToTS4=objToTS(mixed,this.o,this.zone),ts=_objToTS4[0],o=_objToTS4[1];return clone(this,{ts:ts,o:o});};_proto.plus=function plus(duration){if(!this.isValid)return this;var dur=Duration.fromDurationLike(duration);return clone(this,adjustTime(this,dur));};_proto.minus=function minus(duration){if(!this.isValid)return this;var dur=Duration.fromDurationLike(duration).negate();return clone(this,adjustTime(this,dur));};_proto.startOf=function startOf(unit,_temp3){var _ref4=_temp3===void 0?{}:_temp3,_ref4$useLocaleWeeks=_ref4.useLocaleWeeks,useLocaleWeeks=_ref4$useLocaleWeeks===void 0?false:_ref4$useLocaleWeeks;if(!this.isValid)return this;var o={},normalizedUnit=Duration.normalizeUnit(unit);switch(normalizedUnit){case"years":o.month=1;case"quarters":case"months":o.day=1;case"weeks":case"days":o.hour=0;case"hours":o.minute=0;case"minutes":o.second=0;case"seconds":o.millisecond=0;break;}
if(normalizedUnit==="weeks"){if(useLocaleWeeks){var startOfWeek=this.loc.getStartOfWeek();var weekday=this.weekday;if(weekday<startOfWeek){o.weekNumber=this.weekNumber-1;}
o.weekday=startOfWeek;}else{o.weekday=1;}}
if(normalizedUnit==="quarters"){var q=Math.ceil(this.month/3);o.month=(q-1)*3+1;}
return this.set(o);};_proto.endOf=function endOf(unit,opts){var _this$plus;return this.isValid?this.plus((_this$plus={},_this$plus[unit]=1,_this$plus)).startOf(unit,opts).minus(1):this;};_proto.toFormat=function toFormat(fmt,opts){if(opts===void 0){opts={};}
return this.isValid?Formatter.create(this.loc.redefaultToEN(opts)).formatDateTimeFromString(this,fmt):INVALID;};_proto.toLocaleString=function toLocaleString(formatOpts,opts){if(formatOpts===void 0){formatOpts=DATE_SHORT;}
if(opts===void 0){opts={};}
return this.isValid?Formatter.create(this.loc.clone(opts),formatOpts).formatDateTime(this):INVALID;};_proto.toLocaleParts=function toLocaleParts(opts){if(opts===void 0){opts={};}
return this.isValid?Formatter.create(this.loc.clone(opts),opts).formatDateTimeParts(this):[];};_proto.toISO=function toISO(_temp4){var _ref5=_temp4===void 0?{}:_temp4,_ref5$format=_ref5.format,format=_ref5$format===void 0?"extended":_ref5$format,_ref5$suppressSeconds=_ref5.suppressSeconds,suppressSeconds=_ref5$suppressSeconds===void 0?false:_ref5$suppressSeconds,_ref5$suppressMillise=_ref5.suppressMilliseconds,suppressMilliseconds=_ref5$suppressMillise===void 0?false:_ref5$suppressMillise,_ref5$includeOffset=_ref5.includeOffset,includeOffset=_ref5$includeOffset===void 0?true:_ref5$includeOffset,_ref5$extendedZone=_ref5.extendedZone,extendedZone=_ref5$extendedZone===void 0?false:_ref5$extendedZone;if(!this.isValid){return null;}
var ext=format==="extended";var c=_toISODate(this,ext);c+="T";c+=_toISOTime(this,ext,suppressSeconds,suppressMilliseconds,includeOffset,extendedZone);return c;};_proto.toISODate=function toISODate(_temp5){var _ref6=_temp5===void 0?{}:_temp5,_ref6$format=_ref6.format,format=_ref6$format===void 0?"extended":_ref6$format;if(!this.isValid){return null;}
return _toISODate(this,format==="extended");};_proto.toISOWeekDate=function toISOWeekDate(){return toTechFormat(this,"kkkk-'W'WW-c");};_proto.toISOTime=function toISOTime(_temp6){var _ref7=_temp6===void 0?{}:_temp6,_ref7$suppressMillise=_ref7.suppressMilliseconds,suppressMilliseconds=_ref7$suppressMillise===void 0?false:_ref7$suppressMillise,_ref7$suppressSeconds=_ref7.suppressSeconds,suppressSeconds=_ref7$suppressSeconds===void 0?false:_ref7$suppressSeconds,_ref7$includeOffset=_ref7.includeOffset,includeOffset=_ref7$includeOffset===void 0?true:_ref7$includeOffset,_ref7$includePrefix=_ref7.includePrefix,includePrefix=_ref7$includePrefix===void 0?false:_ref7$includePrefix,_ref7$extendedZone=_ref7.extendedZone,extendedZone=_ref7$extendedZone===void 0?false:_ref7$extendedZone,_ref7$format=_ref7.format,format=_ref7$format===void 0?"extended":_ref7$format;if(!this.isValid){return null;}
var c=includePrefix?"T":"";return c+_toISOTime(this,format==="extended",suppressSeconds,suppressMilliseconds,includeOffset,extendedZone);};_proto.toRFC2822=function toRFC2822(){return toTechFormat(this,"EEE, dd LLL yyyy HH:mm:ss ZZZ",false);};_proto.toHTTP=function toHTTP(){return toTechFormat(this.toUTC(),"EEE, dd LLL yyyy HH:mm:ss 'GMT'");};_proto.toSQLDate=function toSQLDate(){if(!this.isValid){return null;}
return _toISODate(this,true);};_proto.toSQLTime=function toSQLTime(_temp7){var _ref8=_temp7===void 0?{}:_temp7,_ref8$includeOffset=_ref8.includeOffset,includeOffset=_ref8$includeOffset===void 0?true:_ref8$includeOffset,_ref8$includeZone=_ref8.includeZone,includeZone=_ref8$includeZone===void 0?false:_ref8$includeZone,_ref8$includeOffsetSp=_ref8.includeOffsetSpace,includeOffsetSpace=_ref8$includeOffsetSp===void 0?true:_ref8$includeOffsetSp;var fmt="HH:mm:ss.SSS";if(includeZone||includeOffset){if(includeOffsetSpace){fmt+=" ";}
if(includeZone){fmt+="z";}else if(includeOffset){fmt+="ZZ";}}
return toTechFormat(this,fmt,true);};_proto.toSQL=function toSQL(opts){if(opts===void 0){opts={};}
if(!this.isValid){return null;}
return this.toSQLDate()+" "+this.toSQLTime(opts);};_proto.toString=function toString(){return this.isValid?this.toISO():INVALID;};_proto[_Symbol$for]=function(){if(this.isValid){return"DateTime { ts: "+this.toISO()+", zone: "+this.zone.name+", locale: "+this.locale+" }";}else{return"DateTime { Invalid, reason: "+this.invalidReason+" }";}};_proto.valueOf=function valueOf(){return this.toMillis();};_proto.toMillis=function toMillis(){return this.isValid?this.ts:NaN;};_proto.toSeconds=function toSeconds(){return this.isValid?this.ts/1000:NaN;};_proto.toUnixInteger=function toUnixInteger(){return this.isValid?Math.floor(this.ts/1000):NaN;};_proto.toJSON=function toJSON(){return this.toISO();};_proto.toBSON=function toBSON(){return this.toJSDate();};_proto.toObject=function toObject(opts){if(opts===void 0){opts={};}
if(!this.isValid)return{};var base=_extends({},this.c);if(opts.includeConfig){base.outputCalendar=this.outputCalendar;base.numberingSystem=this.loc.numberingSystem;base.locale=this.loc.locale;}
return base;};_proto.toJSDate=function toJSDate(){return new Date(this.isValid?this.ts:NaN);};_proto.diff=function diff(otherDateTime,unit,opts){if(unit===void 0){unit="milliseconds";}
if(opts===void 0){opts={};}
if(!this.isValid||!otherDateTime.isValid){return Duration.invalid("created by diffing an invalid DateTime");}
var durOpts=_extends({locale:this.locale,numberingSystem:this.numberingSystem},opts);var units=maybeArray(unit).map(Duration.normalizeUnit),otherIsLater=otherDateTime.valueOf()>this.valueOf(),earlier=otherIsLater?this:otherDateTime,later=otherIsLater?otherDateTime:this,diffed=_diff(earlier,later,units,durOpts);return otherIsLater?diffed.negate():diffed;};_proto.diffNow=function diffNow(unit,opts){if(unit===void 0){unit="milliseconds";}
if(opts===void 0){opts={};}
return this.diff(DateTime.now(),unit,opts);};_proto.until=function until(otherDateTime){return this.isValid?Interval.fromDateTimes(this,otherDateTime):this;};_proto.hasSame=function hasSame(otherDateTime,unit,opts){if(!this.isValid)return false;var inputMs=otherDateTime.valueOf();var adjustedToZone=this.setZone(otherDateTime.zone,{keepLocalTime:true});return adjustedToZone.startOf(unit,opts)<=inputMs&&inputMs<=adjustedToZone.endOf(unit,opts);};_proto.equals=function equals(other){return this.isValid&&other.isValid&&this.valueOf()===other.valueOf()&&this.zone.equals(other.zone)&&this.loc.equals(other.loc);};_proto.toRelative=function toRelative(options){if(options===void 0){options={};}
if(!this.isValid)return null;var base=options.base||DateTime.fromObject({},{zone:this.zone}),padding=options.padding?this<base?-options.padding:options.padding:0;var units=["years","months","days","hours","minutes","seconds"];var unit=options.unit;if(Array.isArray(options.unit)){units=options.unit;unit=undefined;}
return diffRelative(base,this.plus(padding),_extends({},options,{numeric:"always",units:units,unit:unit}));};_proto.toRelativeCalendar=function toRelativeCalendar(options){if(options===void 0){options={};}
if(!this.isValid)return null;return diffRelative(options.base||DateTime.fromObject({},{zone:this.zone}),this,_extends({},options,{numeric:"auto",units:["years","months","days"],calendary:true}));};DateTime.min=function min(){for(var _len=arguments.length,dateTimes=new Array(_len),_key=0;_key<_len;_key++){dateTimes[_key]=arguments[_key];}
if(!dateTimes.every(DateTime.isDateTime)){throw new InvalidArgumentError("min requires all arguments be DateTimes");}
return bestBy(dateTimes,function(i){return i.valueOf();},Math.min);};DateTime.max=function max(){for(var _len2=arguments.length,dateTimes=new Array(_len2),_key2=0;_key2<_len2;_key2++){dateTimes[_key2]=arguments[_key2];}
if(!dateTimes.every(DateTime.isDateTime)){throw new InvalidArgumentError("max requires all arguments be DateTimes");}
return bestBy(dateTimes,function(i){return i.valueOf();},Math.max);};DateTime.fromFormatExplain=function fromFormatExplain(text,fmt,options){if(options===void 0){options={};}
var _options=options,_options$locale=_options.locale,locale=_options$locale===void 0?null:_options$locale,_options$numberingSys=_options.numberingSystem,numberingSystem=_options$numberingSys===void 0?null:_options$numberingSys,localeToUse=Locale.fromOpts({locale:locale,numberingSystem:numberingSystem,defaultToEN:true});return explainFromTokens(localeToUse,text,fmt);};DateTime.fromStringExplain=function fromStringExplain(text,fmt,options){if(options===void 0){options={};}
return DateTime.fromFormatExplain(text,fmt,options);};DateTime.buildFormatParser=function buildFormatParser(fmt,options){if(options===void 0){options={};}
var _options2=options,_options2$locale=_options2.locale,locale=_options2$locale===void 0?null:_options2$locale,_options2$numberingSy=_options2.numberingSystem,numberingSystem=_options2$numberingSy===void 0?null:_options2$numberingSy,localeToUse=Locale.fromOpts({locale:locale,numberingSystem:numberingSystem,defaultToEN:true});return new TokenParser(localeToUse,fmt);};DateTime.fromFormatParser=function fromFormatParser(text,formatParser,opts){if(opts===void 0){opts={};}
if(isUndefined(text)||isUndefined(formatParser)){throw new InvalidArgumentError("fromFormatParser requires an input string and a format parser");}
var _opts2=opts,_opts2$locale=_opts2.locale,locale=_opts2$locale===void 0?null:_opts2$locale,_opts2$numberingSyste=_opts2.numberingSystem,numberingSystem=_opts2$numberingSyste===void 0?null:_opts2$numberingSyste,localeToUse=Locale.fromOpts({locale:locale,numberingSystem:numberingSystem,defaultToEN:true});if(!localeToUse.equals(formatParser.locale)){throw new InvalidArgumentError("fromFormatParser called with a locale of "+localeToUse+", "+("but the format parser was created for "+formatParser.locale));}
var _formatParser$explain=formatParser.explainFromTokens(text),result=_formatParser$explain.result,zone=_formatParser$explain.zone,specificOffset=_formatParser$explain.specificOffset,invalidReason=_formatParser$explain.invalidReason;if(invalidReason){return DateTime.invalid(invalidReason);}else{return parseDataToDateTime(result,zone,opts,"format "+formatParser.format,text,specificOffset);}};_createClass(DateTime,[{key:"isValid",get:function get(){return this.invalid===null;}},{key:"invalidReason",get:function get(){return this.invalid?this.invalid.reason:null;}},{key:"invalidExplanation",get:function get(){return this.invalid?this.invalid.explanation:null;}},{key:"locale",get:function get(){return this.isValid?this.loc.locale:null;}},{key:"numberingSystem",get:function get(){return this.isValid?this.loc.numberingSystem:null;}},{key:"outputCalendar",get:function get(){return this.isValid?this.loc.outputCalendar:null;}},{key:"zone",get:function get(){return this._zone;}},{key:"zoneName",get:function get(){return this.isValid?this.zone.name:null;}},{key:"year",get:function get(){return this.isValid?this.c.year:NaN;}},{key:"quarter",get:function get(){return this.isValid?Math.ceil(this.c.month/3):NaN;}},{key:"month",get:function get(){return this.isValid?this.c.month:NaN;}},{key:"day",get:function get(){return this.isValid?this.c.day:NaN;}},{key:"hour",get:function get(){return this.isValid?this.c.hour:NaN;}},{key:"minute",get:function get(){return this.isValid?this.c.minute:NaN;}},{key:"second",get:function get(){return this.isValid?this.c.second:NaN;}},{key:"millisecond",get:function get(){return this.isValid?this.c.millisecond:NaN;}},{key:"weekYear",get:function get(){return this.isValid?possiblyCachedWeekData(this).weekYear:NaN;}},{key:"weekNumber",get:function get(){return this.isValid?possiblyCachedWeekData(this).weekNumber:NaN;}},{key:"weekday",get:function get(){return this.isValid?possiblyCachedWeekData(this).weekday:NaN;}},{key:"isWeekend",get:function get(){return this.isValid&&this.loc.getWeekendDays().includes(this.weekday);}},{key:"localWeekday",get:function get(){return this.isValid?possiblyCachedLocalWeekData(this).weekday:NaN;}},{key:"localWeekNumber",get:function get(){return this.isValid?possiblyCachedLocalWeekData(this).weekNumber:NaN;}},{key:"localWeekYear",get:function get(){return this.isValid?possiblyCachedLocalWeekData(this).weekYear:NaN;}},{key:"ordinal",get:function get(){return this.isValid?gregorianToOrdinal(this.c).ordinal:NaN;}},{key:"monthShort",get:function get(){return this.isValid?Info.months("short",{locObj:this.loc})[this.month-1]:null;}},{key:"monthLong",get:function get(){return this.isValid?Info.months("long",{locObj:this.loc})[this.month-1]:null;}},{key:"weekdayShort",get:function get(){return this.isValid?Info.weekdays("short",{locObj:this.loc})[this.weekday-1]:null;}},{key:"weekdayLong",get:function get(){return this.isValid?Info.weekdays("long",{locObj:this.loc})[this.weekday-1]:null;}},{key:"offset",get:function get(){return this.isValid?+this.o:NaN;}},{key:"offsetNameShort",get:function get(){if(this.isValid){return this.zone.offsetName(this.ts,{format:"short",locale:this.locale});}else{return null;}}},{key:"offsetNameLong",get:function get(){if(this.isValid){return this.zone.offsetName(this.ts,{format:"long",locale:this.locale});}else{return null;}}},{key:"isOffsetFixed",get:function get(){return this.isValid?this.zone.isUniversal:null;}},{key:"isInDST",get:function get(){if(this.isOffsetFixed){return false;}else{return this.offset>this.set({month:1,day:1}).offset||this.offset>this.set({month:5}).offset;}}},{key:"isInLeapYear",get:function get(){return isLeapYear(this.year);}},{key:"daysInMonth",get:function get(){return daysInMonth(this.year,this.month);}},{key:"daysInYear",get:function get(){return this.isValid?daysInYear(this.year):NaN;}},{key:"weeksInWeekYear",get:function get(){return this.isValid?weeksInWeekYear(this.weekYear):NaN;}},{key:"weeksInLocalWeekYear",get:function get(){return this.isValid?weeksInWeekYear(this.localWeekYear,this.loc.getMinDaysInFirstWeek(),this.loc.getStartOfWeek()):NaN;}}],[{key:"DATE_SHORT",get:function get(){return DATE_SHORT;}},{key:"DATE_MED",get:function get(){return DATE_MED;}},{key:"DATE_MED_WITH_WEEKDAY",get:function get(){return DATE_MED_WITH_WEEKDAY;}},{key:"DATE_FULL",get:function get(){return DATE_FULL;}},{key:"DATE_HUGE",get:function get(){return DATE_HUGE;}},{key:"TIME_SIMPLE",get:function get(){return TIME_SIMPLE;}},{key:"TIME_WITH_SECONDS",get:function get(){return TIME_WITH_SECONDS;}},{key:"TIME_WITH_SHORT_OFFSET",get:function get(){return TIME_WITH_SHORT_OFFSET;}},{key:"TIME_WITH_LONG_OFFSET",get:function get(){return TIME_WITH_LONG_OFFSET;}},{key:"TIME_24_SIMPLE",get:function get(){return TIME_24_SIMPLE;}},{key:"TIME_24_WITH_SECONDS",get:function get(){return TIME_24_WITH_SECONDS;}},{key:"TIME_24_WITH_SHORT_OFFSET",get:function get(){return TIME_24_WITH_SHORT_OFFSET;}},{key:"TIME_24_WITH_LONG_OFFSET",get:function get(){return TIME_24_WITH_LONG_OFFSET;}},{key:"DATETIME_SHORT",get:function get(){return DATETIME_SHORT;}},{key:"DATETIME_SHORT_WITH_SECONDS",get:function get(){return DATETIME_SHORT_WITH_SECONDS;}},{key:"DATETIME_MED",get:function get(){return DATETIME_MED;}},{key:"DATETIME_MED_WITH_SECONDS",get:function get(){return DATETIME_MED_WITH_SECONDS;}},{key:"DATETIME_MED_WITH_WEEKDAY",get:function get(){return DATETIME_MED_WITH_WEEKDAY;}},{key:"DATETIME_FULL",get:function get(){return DATETIME_FULL;}},{key:"DATETIME_FULL_WITH_SECONDS",get:function get(){return DATETIME_FULL_WITH_SECONDS;}},{key:"DATETIME_HUGE",get:function get(){return DATETIME_HUGE;}},{key:"DATETIME_HUGE_WITH_SECONDS",get:function get(){return DATETIME_HUGE_WITH_SECONDS;}}]);return DateTime;}(Symbol.for("nodejs.util.inspect.custom"));function friendlyDateTime(dateTimeish){if(DateTime.isDateTime(dateTimeish)){return dateTimeish;}else if(dateTimeish&&dateTimeish.valueOf&&isNumber(dateTimeish.valueOf())){return DateTime.fromJSDate(dateTimeish);}else if(dateTimeish&&typeof dateTimeish==="object"){return DateTime.fromObject(dateTimeish);}else{throw new InvalidArgumentError("Unknown datetime argument: "+dateTimeish+", of type "+typeof dateTimeish);}}
var VERSION="3.5.0";exports.DateTime=DateTime;exports.Duration=Duration;exports.FixedOffsetZone=FixedOffsetZone;exports.IANAZone=IANAZone;exports.Info=Info;exports.Interval=Interval;exports.InvalidZone=InvalidZone;exports.Settings=Settings;exports.SystemZone=SystemZone;exports.VERSION=VERSION;exports.Zone=Zone;Object.defineProperty(exports,'__esModule',{value:true});return exports;})({});luxon.DateTime.prototype[Symbol.toStringTag]="LuxonDateTime";luxon.Duration.prototype[Symbol.toStringTag]="LuxonDuration";luxon.Interval.prototype[Symbol.toStringTag]="LuxonInterval";luxon.Settings.prototype[Symbol.toStringTag]="LuxonSettings";luxon.Info.prototype[Symbol.toStringTag]="LuxonInfo";luxon.Zone.prototype[Symbol.toStringTag]="LuxonZone";;
/* /web/static/src/polyfills/object.js */
if(!Object.hasOwn){Object.hasOwn=(obj,key)=>Object.prototype.hasOwnProperty.call(obj,key);};
/* /web/static/src/polyfills/array.js */
if(!Array.prototype.at){Object.defineProperty(Array.prototype,"at",{enumerable:false,value:function(index){if(index>=0){return this[index];}
return this[this.length+index];}});};
/* /web/static/src/polyfills/promise.js */
if(!Promise.withResolvers){Promise.withResolvers=function withResolvers(){let resolve,reject;const promise=new Promise((res,rej)=>{resolve=res;reject=rej;});return{promise,resolve,reject};};};
/* /web/static/src/polyfills/set.js */
odoo.define('@web/polyfills/set',[],function(require){'use strict';let __exports={};const difference=__exports.difference=function(s){if(!(s instanceof Set)){throw new Error("argument must be a Set");}
return new Set([...this].filter((e)=>!s.has(e)));};if(!Set.prototype.difference){Object.defineProperty(Set.prototype,"difference",{enumerable:false,value:difference,});}
return __exports;});;
/* /web/static/lib/owl/owl.js */
(function(exports){'use strict';function filterOutModifiersFromData(dataList){dataList=dataList.slice();const modifiers=[];let elm;while((elm=dataList[0])&&typeof elm==="string"){modifiers.push(dataList.shift());}
return{modifiers,data:dataList};}
const config={shouldNormalizeDom:true,mainEventHandler:(data,ev,currentTarget)=>{if(typeof data==="function"){data(ev);}
else if(Array.isArray(data)){data=filterOutModifiersFromData(data).data;data[0](data[1],ev);}
return false;},};class VToggler{constructor(key,child){this.key=key;this.child=child;}
mount(parent,afterNode){this.parentEl=parent;this.child.mount(parent,afterNode);}
moveBeforeDOMNode(node,parent){this.child.moveBeforeDOMNode(node,parent);}
moveBeforeVNode(other,afterNode){this.moveBeforeDOMNode((other&&other.firstNode())||afterNode);}
patch(other,withBeforeRemove){if(this===other){return;}
let child1=this.child;let child2=other.child;if(this.key===other.key){child1.patch(child2,withBeforeRemove);}
else{child2.mount(this.parentEl,child1.firstNode());if(withBeforeRemove){child1.beforeRemove();}
child1.remove();this.child=child2;this.key=other.key;}}
beforeRemove(){this.child.beforeRemove();}
remove(){this.child.remove();}
firstNode(){return this.child.firstNode();}
toString(){return this.child.toString();}}
function toggler(key,child){return new VToggler(key,child);}
class OwlError extends Error{}
const{setAttribute:elemSetAttribute,removeAttribute}=Element.prototype;const tokenList=DOMTokenList.prototype;const tokenListAdd=tokenList.add;const tokenListRemove=tokenList.remove;const isArray=Array.isArray;const{split,trim}=String.prototype;const wordRegexp=/\s+/;function setAttribute(key,value){switch(value){case false:case undefined:removeAttribute.call(this,key);break;case true:elemSetAttribute.call(this,key,"");break;default:elemSetAttribute.call(this,key,value);}}
function createAttrUpdater(attr){return function(value){setAttribute.call(this,attr,value);};}
function attrsSetter(attrs){if(isArray(attrs)){if(attrs[0]==="class"){setClass.call(this,attrs[1]);}
else{setAttribute.call(this,attrs[0],attrs[1]);}}
else{for(let k in attrs){if(k==="class"){setClass.call(this,attrs[k]);}
else{setAttribute.call(this,k,attrs[k]);}}}}
function attrsUpdater(attrs,oldAttrs){if(isArray(attrs)){const name=attrs[0];const val=attrs[1];if(name===oldAttrs[0]){if(val===oldAttrs[1]){return;}
if(name==="class"){updateClass.call(this,val,oldAttrs[1]);}
else{setAttribute.call(this,name,val);}}
else{removeAttribute.call(this,oldAttrs[0]);setAttribute.call(this,name,val);}}
else{for(let k in oldAttrs){if(!(k in attrs)){if(k==="class"){updateClass.call(this,"",oldAttrs[k]);}
else{removeAttribute.call(this,k);}}}
for(let k in attrs){const val=attrs[k];if(val!==oldAttrs[k]){if(k==="class"){updateClass.call(this,val,oldAttrs[k]);}
else{setAttribute.call(this,k,val);}}}}}
function toClassObj(expr){const result={};switch(typeof expr){case"string":const str=trim.call(expr);if(!str){return{};}
let words=split.call(str,wordRegexp);for(let i=0,l=words.length;i<l;i++){result[words[i]]=true;}
return result;case"object":for(let key in expr){const value=expr[key];if(value){key=trim.call(key);if(!key){continue;}
const words=split.call(key,wordRegexp);for(let word of words){result[word]=value;}}}
return result;case"undefined":return{};case"number":return{[expr]:true};default:return{[expr]:true};}}
function setClass(val){val=val===""?{}:toClassObj(val);const cl=this.classList;for(let c in val){tokenListAdd.call(cl,c);}}
function updateClass(val,oldVal){oldVal=oldVal===""?{}:toClassObj(oldVal);val=val===""?{}:toClassObj(val);const cl=this.classList;for(let c in oldVal){if(!(c in val)){tokenListRemove.call(cl,c);}}
for(let c in val){if(!(c in oldVal)){tokenListAdd.call(cl,c);}}}
function batched(callback){let scheduled=false;return async(...args)=>{if(!scheduled){scheduled=true;await Promise.resolve();scheduled=false;callback(...args);}};}
function inOwnerDocument(el){if(!el){return false;}
if(el.ownerDocument.contains(el)){return true;}
const rootNode=el.getRootNode();return rootNode instanceof ShadowRoot&&el.ownerDocument.contains(rootNode.host);}
function isAttachedToDocument(element,documentElement){let current=element;const shadowRoot=documentElement.defaultView.ShadowRoot;while(current){if(current===documentElement){return true;}
if(current.parentNode){current=current.parentNode;}
else if(current instanceof shadowRoot&&current.host){current=current.host;}
else{return false;}}
return false;}
function validateTarget(target){const document=target&&target.ownerDocument;if(document){if(!document.defaultView){throw new OwlError("Cannot mount a component: the target document is not attached to a window (defaultView is missing)");}
const HTMLElement=document.defaultView.HTMLElement;if(target instanceof HTMLElement||target instanceof ShadowRoot){if(!isAttachedToDocument(target,document)){throw new OwlError("Cannot mount a component on a detached dom node");}
return;}}
throw new OwlError("Cannot mount component: the target is not a valid DOM element");}
class EventBus extends EventTarget{trigger(name,payload){this.dispatchEvent(new CustomEvent(name,{detail:payload}));}}
function whenReady(fn){return new Promise(function(resolve){if(document.readyState!=="loading"){resolve(true);}
else{document.addEventListener("DOMContentLoaded",resolve,false);}}).then(fn||function(){});}
async function loadFile(url){const result=await fetch(url);if(!result.ok){throw new OwlError("Error while fetching xml templates");}
return await result.text();}
class Markup extends String{}
function htmlEscape(str){if(str instanceof Markup){return str;}
if(str===undefined){return markup("");}
if(typeof str==="number"){return markup(String(str));}
[["&","&amp;"],["<","&lt;"],[">","&gt;"],["'","&#x27;"],['"',"&quot;"],["`","&#x60;"],].forEach((pairs)=>{str=String(str).replace(new RegExp(pairs[0],"g"),pairs[1]);});return markup(str);}
function markup(valueOrStrings,...placeholders){if(!Array.isArray(valueOrStrings)){return new Markup(valueOrStrings);}
const strings=valueOrStrings;let acc="";let i=0;for(;i<placeholders.length;++i){acc+=strings[i]+htmlEscape(placeholders[i]);}
acc+=strings[i];return new Markup(acc);}
function createEventHandler(rawEvent){const eventName=rawEvent.split(".")[0];const capture=rawEvent.includes(".capture");if(rawEvent.includes(".synthetic")){return createSyntheticHandler(eventName,capture);}
else{return createElementHandler(eventName,capture);}}
let nextNativeEventId=1;function createElementHandler(evName,capture=false){let eventKey=`__event__${evName}_${nextNativeEventId++}`;if(capture){eventKey=`${eventKey}_capture`;}
function listener(ev){const currentTarget=ev.currentTarget;if(!currentTarget||!inOwnerDocument(currentTarget))
return;const data=currentTarget[eventKey];if(!data)
return;config.mainEventHandler(data,ev,currentTarget);}
function setup(data){this[eventKey]=data;this.addEventListener(evName,listener,{capture});}
function remove(){delete this[eventKey];this.removeEventListener(evName,listener,{capture});}
function update(data){this[eventKey]=data;}
return{setup,update,remove};}
let nextSyntheticEventId=1;function createSyntheticHandler(evName,capture=false){let eventKey=`__event__synthetic_${evName}`;if(capture){eventKey=`${eventKey}_capture`;}
setupSyntheticEvent(evName,eventKey,capture);const currentId=nextSyntheticEventId++;function setup(data){const _data=this[eventKey]||{};_data[currentId]=data;this[eventKey]=_data;}
function remove(){delete this[eventKey];}
return{setup,update:setup,remove};}
function nativeToSyntheticEvent(eventKey,event){let dom=event.target;while(dom!==null){const _data=dom[eventKey];if(_data){for(const data of Object.values(_data)){const stopped=config.mainEventHandler(data,event,dom);if(stopped)
return;}}
dom=dom.parentNode;}}
const CONFIGURED_SYNTHETIC_EVENTS={};function setupSyntheticEvent(evName,eventKey,capture=false){if(CONFIGURED_SYNTHETIC_EVENTS[eventKey]){return;}
document.addEventListener(evName,(event)=>nativeToSyntheticEvent(eventKey,event),{capture,});CONFIGURED_SYNTHETIC_EVENTS[eventKey]=true;}
const getDescriptor$3=(o,p)=>Object.getOwnPropertyDescriptor(o,p);const nodeProto$4=Node.prototype;const nodeInsertBefore$3=nodeProto$4.insertBefore;const nodeSetTextContent$1=getDescriptor$3(nodeProto$4,"textContent").set;const nodeRemoveChild$3=nodeProto$4.removeChild;class VMulti{constructor(children){this.children=children;}
mount(parent,afterNode){const children=this.children;const l=children.length;const anchors=new Array(l);for(let i=0;i<l;i++){let child=children[i];if(child){child.mount(parent,afterNode);}
else{const childAnchor=document.createTextNode("");anchors[i]=childAnchor;nodeInsertBefore$3.call(parent,childAnchor,afterNode);}}
this.anchors=anchors;this.parentEl=parent;}
moveBeforeDOMNode(node,parent=this.parentEl){this.parentEl=parent;const children=this.children;const anchors=this.anchors;for(let i=0,l=children.length;i<l;i++){let child=children[i];if(child){child.moveBeforeDOMNode(node,parent);}
else{const anchor=anchors[i];nodeInsertBefore$3.call(parent,anchor,node);}}}
moveBeforeVNode(other,afterNode){if(other){const next=other.children[0];afterNode=(next?next.firstNode():other.anchors[0])||null;}
const children=this.children;const parent=this.parentEl;const anchors=this.anchors;for(let i=0,l=children.length;i<l;i++){let child=children[i];if(child){child.moveBeforeVNode(null,afterNode);}
else{const anchor=anchors[i];nodeInsertBefore$3.call(parent,anchor,afterNode);}}}
patch(other,withBeforeRemove){if(this===other){return;}
const children1=this.children;const children2=other.children;const anchors=this.anchors;const parentEl=this.parentEl;for(let i=0,l=children1.length;i<l;i++){const vn1=children1[i];const vn2=children2[i];if(vn1){if(vn2){vn1.patch(vn2,withBeforeRemove);}
else{const afterNode=vn1.firstNode();const anchor=document.createTextNode("");anchors[i]=anchor;nodeInsertBefore$3.call(parentEl,anchor,afterNode);if(withBeforeRemove){vn1.beforeRemove();}
vn1.remove();children1[i]=undefined;}}
else if(vn2){children1[i]=vn2;const anchor=anchors[i];vn2.mount(parentEl,anchor);nodeRemoveChild$3.call(parentEl,anchor);}}}
beforeRemove(){const children=this.children;for(let i=0,l=children.length;i<l;i++){const child=children[i];if(child){child.beforeRemove();}}}
remove(){const parentEl=this.parentEl;if(this.isOnlyChild){nodeSetTextContent$1.call(parentEl,"");}
else{const children=this.children;const anchors=this.anchors;for(let i=0,l=children.length;i<l;i++){const child=children[i];if(child){child.remove();}
else{nodeRemoveChild$3.call(parentEl,anchors[i]);}}}}
firstNode(){const child=this.children[0];return child?child.firstNode():this.anchors[0];}
toString(){return this.children.map((c)=>(c?c.toString():"")).join("");}}
function multi(children){return new VMulti(children);}
const getDescriptor$2=(o,p)=>Object.getOwnPropertyDescriptor(o,p);const nodeProto$3=Node.prototype;const characterDataProto$1=CharacterData.prototype;const nodeInsertBefore$2=nodeProto$3.insertBefore;const characterDataSetData$1=getDescriptor$2(characterDataProto$1,"data").set;const nodeRemoveChild$2=nodeProto$3.removeChild;class VSimpleNode{constructor(text){this.text=text;}
mountNode(node,parent,afterNode){this.parentEl=parent;nodeInsertBefore$2.call(parent,node,afterNode);this.el=node;}
moveBeforeDOMNode(node,parent=this.parentEl){this.parentEl=parent;nodeInsertBefore$2.call(parent,this.el,node);}
moveBeforeVNode(other,afterNode){nodeInsertBefore$2.call(this.parentEl,this.el,other?other.el:afterNode);}
beforeRemove(){}
remove(){nodeRemoveChild$2.call(this.parentEl,this.el);}
firstNode(){return this.el;}
toString(){return this.text;}}
class VText$1 extends VSimpleNode{mount(parent,afterNode){this.mountNode(document.createTextNode(toText(this.text)),parent,afterNode);}
patch(other){const text2=other.text;if(this.text!==text2){characterDataSetData$1.call(this.el,toText(text2));this.text=text2;}}}
class VComment extends VSimpleNode{mount(parent,afterNode){this.mountNode(document.createComment(toText(this.text)),parent,afterNode);}
patch(){}}
function text(str){return new VText$1(str);}
function comment(str){return new VComment(str);}
function toText(value){switch(typeof value){case"string":return value;case"number":return String(value);case"boolean":return value?"true":"false";default:return value||"";}}
const getDescriptor$1=(o,p)=>Object.getOwnPropertyDescriptor(o,p);const nodeProto$2=Node.prototype;const elementProto=Element.prototype;const characterDataProto=CharacterData.prototype;const characterDataSetData=getDescriptor$1(characterDataProto,"data").set;const nodeGetFirstChild=getDescriptor$1(nodeProto$2,"firstChild").get;const nodeGetNextSibling=getDescriptor$1(nodeProto$2,"nextSibling").get;const NO_OP$1=()=>{};function makePropSetter(name){return function setProp(value){this[name]=value===0?0:value?value.valueOf():"";};}
const cache$1={};function createBlock(str){if(str in cache$1){return cache$1[str];}
const doc=new DOMParser().parseFromString(`<t>${str}</t>`,"text/xml");const node=doc.firstChild.firstChild;if(config.shouldNormalizeDom){normalizeNode(node);}
const tree=buildTree(node);const context=buildContext(tree);const template=tree.el;const Block=buildBlock(template,context);cache$1[str]=Block;return Block;}
function normalizeNode(node){if(node.nodeType===Node.TEXT_NODE){if(!/\S/.test(node.textContent)){node.remove();return;}}
if(node.nodeType===Node.ELEMENT_NODE){if(node.tagName==="pre"){return;}}
for(let i=node.childNodes.length-1;i>=0;--i){normalizeNode(node.childNodes.item(i));}}
function buildTree(node,parent=null,domParentTree=null){switch(node.nodeType){case Node.ELEMENT_NODE:{let currentNS=domParentTree&&domParentTree.currentNS;const tagName=node.tagName;let el=undefined;const info=[];if(tagName.startsWith("block-text-")){const index=parseInt(tagName.slice(11),10);info.push({type:"text",idx:index});el=document.createTextNode("");}
if(tagName.startsWith("block-child-")){if(!domParentTree.isRef){addRef(domParentTree);}
const index=parseInt(tagName.slice(12),10);info.push({type:"child",idx:index});el=document.createTextNode("");}
currentNS||(currentNS=node.namespaceURI);if(!el){el=currentNS?document.createElementNS(currentNS,tagName):document.createElement(tagName);}
if(el instanceof Element){if(!domParentTree){const fragment=document.createElement("template").content;fragment.appendChild(el);}
const attrs=node.attributes;for(let i=0;i<attrs.length;i++){const attrName=attrs[i].name;const attrValue=attrs[i].value;if(attrName.startsWith("block-handler-")){const idx=parseInt(attrName.slice(14),10);info.push({type:"handler",idx,event:attrValue,});}
else if(attrName.startsWith("block-attribute-")){const idx=parseInt(attrName.slice(16),10);info.push({type:"attribute",idx,name:attrValue,tag:tagName,});}
else if(attrName.startsWith("block-property-")){const idx=parseInt(attrName.slice(15),10);info.push({type:"property",idx,name:attrValue,tag:tagName,});}
else if(attrName==="block-attributes"){info.push({type:"attributes",idx:parseInt(attrValue,10),});}
else if(attrName==="block-ref"){info.push({type:"ref",idx:parseInt(attrValue,10),});}
else{el.setAttribute(attrs[i].name,attrValue);}}}
const tree={parent,firstChild:null,nextSibling:null,el,info,refN:0,currentNS,};if(node.firstChild){const childNode=node.childNodes[0];if(node.childNodes.length===1&&childNode.nodeType===Node.ELEMENT_NODE&&childNode.tagName.startsWith("block-child-")){const tagName=childNode.tagName;const index=parseInt(tagName.slice(12),10);info.push({idx:index,type:"child",isOnlyChild:true});}
else{tree.firstChild=buildTree(node.firstChild,tree,tree);el.appendChild(tree.firstChild.el);let curNode=node.firstChild;let curTree=tree.firstChild;while((curNode=curNode.nextSibling)){curTree.nextSibling=buildTree(curNode,curTree,tree);el.appendChild(curTree.nextSibling.el);curTree=curTree.nextSibling;}}}
if(tree.info.length){addRef(tree);}
return tree;}
case Node.TEXT_NODE:case Node.COMMENT_NODE:{const el=node.nodeType===Node.TEXT_NODE?document.createTextNode(node.textContent):document.createComment(node.textContent);return{parent:parent,firstChild:null,nextSibling:null,el,info:[],refN:0,currentNS:null,};}}
throw new OwlError("boom");}
function addRef(tree){tree.isRef=true;do{tree.refN++;}while((tree=tree.parent));}
function parentTree(tree){let parent=tree.parent;while(parent&&parent.nextSibling===tree){tree=parent;parent=parent.parent;}
return parent;}
function buildContext(tree,ctx,fromIdx){if(!ctx){const children=new Array(tree.info.filter((v)=>v.type==="child").length);ctx={collectors:[],locations:[],children,cbRefs:[],refN:tree.refN,refList:[]};fromIdx=0;}
if(tree.refN){const initialIdx=fromIdx;const isRef=tree.isRef;const firstChild=tree.firstChild?tree.firstChild.refN:0;const nextSibling=tree.nextSibling?tree.nextSibling.refN:0;if(isRef){for(let info of tree.info){info.refIdx=initialIdx;}
tree.refIdx=initialIdx;updateCtx(ctx,tree);fromIdx++;}
if(nextSibling){const idx=fromIdx+firstChild;ctx.collectors.push({idx,prevIdx:initialIdx,getVal:nodeGetNextSibling});buildContext(tree.nextSibling,ctx,idx);}
if(firstChild){ctx.collectors.push({idx:fromIdx,prevIdx:initialIdx,getVal:nodeGetFirstChild});buildContext(tree.firstChild,ctx,fromIdx);}}
return ctx;}
function updateCtx(ctx,tree){for(let info of tree.info){switch(info.type){case"text":ctx.locations.push({idx:info.idx,refIdx:info.refIdx,setData:setText,updateData:setText,});break;case"child":if(info.isOnlyChild){ctx.children[info.idx]={parentRefIdx:info.refIdx,isOnlyChild:true,};}
else{ctx.children[info.idx]={parentRefIdx:parentTree(tree).refIdx,afterRefIdx:info.refIdx,};}
break;case"property":{const refIdx=info.refIdx;const setProp=makePropSetter(info.name);ctx.locations.push({idx:info.idx,refIdx,setData:setProp,updateData:setProp,});break;}
case"attribute":{const refIdx=info.refIdx;let updater;let setter;if(info.name==="class"){setter=setClass;updater=updateClass;}
else{setter=createAttrUpdater(info.name);updater=setter;}
ctx.locations.push({idx:info.idx,refIdx,setData:setter,updateData:updater,});break;}
case"attributes":ctx.locations.push({idx:info.idx,refIdx:info.refIdx,setData:attrsSetter,updateData:attrsUpdater,});break;case"handler":{const{setup,update}=createEventHandler(info.event);ctx.locations.push({idx:info.idx,refIdx:info.refIdx,setData:setup,updateData:update,});break;}
case"ref":const index=ctx.cbRefs.push(info.idx)-1;ctx.locations.push({idx:info.idx,refIdx:info.refIdx,setData:makeRefSetter(index,ctx.refList),updateData:NO_OP$1,});}}}
function buildBlock(template,ctx){let B=createBlockClass(template,ctx);if(ctx.cbRefs.length){const cbRefs=ctx.cbRefs;const refList=ctx.refList;let cbRefsNumber=cbRefs.length;B=class extends B{mount(parent,afterNode){refList.push(new Array(cbRefsNumber));super.mount(parent,afterNode);for(let cbRef of refList.pop()){cbRef();}}
remove(){super.remove();for(let cbRef of cbRefs){let fn=this.data[cbRef];fn(null);}}};}
if(ctx.children.length){B=class extends B{constructor(data,children){super(data);this.children=children;}};B.prototype.beforeRemove=VMulti.prototype.beforeRemove;return(data,children=[])=>new B(data,children);}
return(data)=>new B(data);}
function createBlockClass(template,ctx){const{refN,collectors,children}=ctx;const colN=collectors.length;ctx.locations.sort((a,b)=>a.idx-b.idx);const locations=ctx.locations.map((loc)=>({refIdx:loc.refIdx,setData:loc.setData,updateData:loc.updateData,}));const locN=locations.length;const childN=children.length;const childrenLocs=children;const isDynamic=refN>0;const nodeCloneNode=nodeProto$2.cloneNode;const nodeInsertBefore=nodeProto$2.insertBefore;const elementRemove=elementProto.remove;class Block{constructor(data){this.data=data;}
beforeRemove(){}
remove(){elementRemove.call(this.el);}
firstNode(){return this.el;}
moveBeforeDOMNode(node,parent=this.parentEl){this.parentEl=parent;nodeInsertBefore.call(parent,this.el,node);}
moveBeforeVNode(other,afterNode){nodeInsertBefore.call(this.parentEl,this.el,other?other.el:afterNode);}
toString(){const div=document.createElement("div");this.mount(div,null);return div.innerHTML;}
mount(parent,afterNode){const el=nodeCloneNode.call(template,true);nodeInsertBefore.call(parent,el,afterNode);this.el=el;this.parentEl=parent;}
patch(other,withBeforeRemove){}}
if(isDynamic){Block.prototype.mount=function mount(parent,afterNode){const el=nodeCloneNode.call(template,true);const refs=new Array(refN);this.refs=refs;refs[0]=el;for(let i=0;i<colN;i++){const w=collectors[i];refs[w.idx]=w.getVal.call(refs[w.prevIdx]);}
if(locN){const data=this.data;for(let i=0;i<locN;i++){const loc=locations[i];loc.setData.call(refs[loc.refIdx],data[i]);}}
nodeInsertBefore.call(parent,el,afterNode);if(childN){const children=this.children;for(let i=0;i<childN;i++){const child=children[i];if(child){const loc=childrenLocs[i];const afterNode=loc.afterRefIdx?refs[loc.afterRefIdx]:null;child.isOnlyChild=loc.isOnlyChild;child.mount(refs[loc.parentRefIdx],afterNode);}}}
this.el=el;this.parentEl=parent;};Block.prototype.patch=function patch(other,withBeforeRemove){if(this===other){return;}
const refs=this.refs;if(locN){const data1=this.data;const data2=other.data;for(let i=0;i<locN;i++){const val1=data1[i];const val2=data2[i];if(val1!==val2){const loc=locations[i];loc.updateData.call(refs[loc.refIdx],val2,val1);}}
this.data=data2;}
if(childN){let children1=this.children;const children2=other.children;for(let i=0;i<childN;i++){const child1=children1[i];const child2=children2[i];if(child1){if(child2){child1.patch(child2,withBeforeRemove);}
else{if(withBeforeRemove){child1.beforeRemove();}
child1.remove();children1[i]=undefined;}}
else if(child2){const loc=childrenLocs[i];const afterNode=loc.afterRefIdx?refs[loc.afterRefIdx]:null;child2.mount(refs[loc.parentRefIdx],afterNode);children1[i]=child2;}}}};}
return Block;}
function setText(value){characterDataSetData.call(this,toText(value));}
function makeRefSetter(index,refs){return function setRef(fn){refs[refs.length-1][index]=()=>fn(this);};}
const getDescriptor=(o,p)=>Object.getOwnPropertyDescriptor(o,p);const nodeProto$1=Node.prototype;const nodeInsertBefore$1=nodeProto$1.insertBefore;const nodeAppendChild=nodeProto$1.appendChild;const nodeRemoveChild$1=nodeProto$1.removeChild;const nodeSetTextContent=getDescriptor(nodeProto$1,"textContent").set;class VList{constructor(children){this.children=children;}
mount(parent,afterNode){const children=this.children;const _anchor=document.createTextNode("");this.anchor=_anchor;nodeInsertBefore$1.call(parent,_anchor,afterNode);const l=children.length;if(l){const mount=children[0].mount;for(let i=0;i<l;i++){mount.call(children[i],parent,_anchor);}}
this.parentEl=parent;}
moveBeforeDOMNode(node,parent=this.parentEl){this.parentEl=parent;const children=this.children;for(let i=0,l=children.length;i<l;i++){children[i].moveBeforeDOMNode(node,parent);}
parent.insertBefore(this.anchor,node);}
moveBeforeVNode(other,afterNode){if(other){const next=other.children[0];afterNode=(next?next.firstNode():other.anchor)||null;}
const children=this.children;for(let i=0,l=children.length;i<l;i++){children[i].moveBeforeVNode(null,afterNode);}
this.parentEl.insertBefore(this.anchor,afterNode);}
patch(other,withBeforeRemove){if(this===other){return;}
const ch1=this.children;const ch2=other.children;if(ch2.length===0&&ch1.length===0){return;}
this.children=ch2;const proto=ch2[0]||ch1[0];const{mount:cMount,patch:cPatch,remove:cRemove,beforeRemove,moveBeforeVNode:cMoveBefore,firstNode:cFirstNode,}=proto;const _anchor=this.anchor;const isOnlyChild=this.isOnlyChild;const parent=this.parentEl;if(ch2.length===0&&isOnlyChild){if(withBeforeRemove){for(let i=0,l=ch1.length;i<l;i++){beforeRemove.call(ch1[i]);}}
nodeSetTextContent.call(parent,"");nodeAppendChild.call(parent,_anchor);return;}
let startIdx1=0;let startIdx2=0;let startVn1=ch1[0];let startVn2=ch2[0];let endIdx1=ch1.length-1;let endIdx2=ch2.length-1;let endVn1=ch1[endIdx1];let endVn2=ch2[endIdx2];let mapping=undefined;while(startIdx1<=endIdx1&&startIdx2<=endIdx2){if(startVn1===null){startVn1=ch1[++startIdx1];continue;}
if(endVn1===null){endVn1=ch1[--endIdx1];continue;}
let startKey1=startVn1.key;let startKey2=startVn2.key;if(startKey1===startKey2){cPatch.call(startVn1,startVn2,withBeforeRemove);ch2[startIdx2]=startVn1;startVn1=ch1[++startIdx1];startVn2=ch2[++startIdx2];continue;}
let endKey1=endVn1.key;let endKey2=endVn2.key;if(endKey1===endKey2){cPatch.call(endVn1,endVn2,withBeforeRemove);ch2[endIdx2]=endVn1;endVn1=ch1[--endIdx1];endVn2=ch2[--endIdx2];continue;}
if(startKey1===endKey2){cPatch.call(startVn1,endVn2,withBeforeRemove);ch2[endIdx2]=startVn1;const nextChild=ch2[endIdx2+1];cMoveBefore.call(startVn1,nextChild,_anchor);startVn1=ch1[++startIdx1];endVn2=ch2[--endIdx2];continue;}
if(endKey1===startKey2){cPatch.call(endVn1,startVn2,withBeforeRemove);ch2[startIdx2]=endVn1;const nextChild=ch1[startIdx1];cMoveBefore.call(endVn1,nextChild,_anchor);endVn1=ch1[--endIdx1];startVn2=ch2[++startIdx2];continue;}
mapping=mapping||createMapping(ch1,startIdx1,endIdx1);let idxInOld=mapping[startKey2];if(idxInOld===undefined){cMount.call(startVn2,parent,cFirstNode.call(startVn1)||null);}
else{const elmToMove=ch1[idxInOld];cMoveBefore.call(elmToMove,startVn1,null);cPatch.call(elmToMove,startVn2,withBeforeRemove);ch2[startIdx2]=elmToMove;ch1[idxInOld]=null;}
startVn2=ch2[++startIdx2];}
if(startIdx1<=endIdx1||startIdx2<=endIdx2){if(startIdx1>endIdx1){const nextChild=ch2[endIdx2+1];const anchor=nextChild?cFirstNode.call(nextChild)||null:_anchor;for(let i=startIdx2;i<=endIdx2;i++){cMount.call(ch2[i],parent,anchor);}}
else{for(let i=startIdx1;i<=endIdx1;i++){let ch=ch1[i];if(ch){if(withBeforeRemove){beforeRemove.call(ch);}
cRemove.call(ch);}}}}}
beforeRemove(){const children=this.children;const l=children.length;if(l){const beforeRemove=children[0].beforeRemove;for(let i=0;i<l;i++){beforeRemove.call(children[i]);}}}
remove(){const{parentEl,anchor}=this;if(this.isOnlyChild){nodeSetTextContent.call(parentEl,"");}
else{const children=this.children;const l=children.length;if(l){const remove=children[0].remove;for(let i=0;i<l;i++){remove.call(children[i]);}}
nodeRemoveChild$1.call(parentEl,anchor);}}
firstNode(){const child=this.children[0];return child?child.firstNode():undefined;}
toString(){return this.children.map((c)=>c.toString()).join("");}}
function list(children){return new VList(children);}
function createMapping(ch1,startIdx1,endIdx2){let mapping={};for(let i=startIdx1;i<=endIdx2;i++){mapping[ch1[i].key]=i;}
return mapping;}
const nodeProto=Node.prototype;const nodeInsertBefore=nodeProto.insertBefore;const nodeRemoveChild=nodeProto.removeChild;class VHtml{constructor(html){this.content=[];this.html=html;}
mount(parent,afterNode){this.parentEl=parent;const template=document.createElement("template");template.innerHTML=this.html;this.content=[...template.content.childNodes];for(let elem of this.content){nodeInsertBefore.call(parent,elem,afterNode);}
if(!this.content.length){const textNode=document.createTextNode("");this.content.push(textNode);nodeInsertBefore.call(parent,textNode,afterNode);}}
moveBeforeDOMNode(node,parent=this.parentEl){this.parentEl=parent;for(let elem of this.content){nodeInsertBefore.call(parent,elem,node);}}
moveBeforeVNode(other,afterNode){const target=other?other.content[0]:afterNode;this.moveBeforeDOMNode(target);}
patch(other){if(this===other){return;}
const html2=other.html;if(this.html!==html2){const parent=this.parentEl;const afterNode=this.content[0];const template=document.createElement("template");template.innerHTML=html2;const content=[...template.content.childNodes];for(let elem of content){nodeInsertBefore.call(parent,elem,afterNode);}
if(!content.length){const textNode=document.createTextNode("");content.push(textNode);nodeInsertBefore.call(parent,textNode,afterNode);}
this.remove();this.content=content;this.html=other.html;}}
beforeRemove(){}
remove(){const parent=this.parentEl;for(let elem of this.content){nodeRemoveChild.call(parent,elem);}}
firstNode(){return this.content[0];}
toString(){return this.html;}}
function html(str){return new VHtml(str);}
function createCatcher(eventsSpec){const n=Object.keys(eventsSpec).length;class VCatcher{constructor(child,handlers){this.handlerFns=[];this.afterNode=null;this.child=child;this.handlerData=handlers;}
mount(parent,afterNode){this.parentEl=parent;this.child.mount(parent,afterNode);this.afterNode=document.createTextNode("");parent.insertBefore(this.afterNode,afterNode);this.wrapHandlerData();for(let name in eventsSpec){const index=eventsSpec[name];const handler=createEventHandler(name);this.handlerFns[index]=handler;handler.setup.call(parent,this.handlerData[index]);}}
wrapHandlerData(){for(let i=0;i<n;i++){let handler=this.handlerData[i];let idx=handler.length-2;let origFn=handler[idx];const self=this;handler[idx]=function(ev){const target=ev.target;let currentNode=self.child.firstNode();const afterNode=self.afterNode;while(currentNode&&currentNode!==afterNode){if(currentNode.contains(target)){return origFn.call(this,ev);}
currentNode=currentNode.nextSibling;}};}}
moveBeforeDOMNode(node,parent=this.parentEl){this.parentEl=parent;this.child.moveBeforeDOMNode(node,parent);parent.insertBefore(this.afterNode,node);}
moveBeforeVNode(other,afterNode){if(other){afterNode=other.firstNode()||afterNode;}
this.child.moveBeforeVNode(other?other.child:null,afterNode);this.parentEl.insertBefore(this.afterNode,afterNode);}
patch(other,withBeforeRemove){if(this===other){return;}
this.handlerData=other.handlerData;this.wrapHandlerData();for(let i=0;i<n;i++){this.handlerFns[i].update.call(this.parentEl,this.handlerData[i]);}
this.child.patch(other.child,withBeforeRemove);}
beforeRemove(){this.child.beforeRemove();}
remove(){for(let i=0;i<n;i++){this.handlerFns[i].remove.call(this.parentEl);}
this.child.remove();this.afterNode.remove();}
firstNode(){return this.child.firstNode();}
toString(){return this.child.toString();}}
return function(child,handlers){return new VCatcher(child,handlers);};}
function mount$1(vnode,fixture,afterNode=null){vnode.mount(fixture,afterNode);}
function patch(vnode1,vnode2,withBeforeRemove=false){vnode1.patch(vnode2,withBeforeRemove);}
function remove(vnode,withBeforeRemove=false){if(withBeforeRemove){vnode.beforeRemove();}
vnode.remove();}
const fibersInError=new WeakMap();const nodeErrorHandlers=new WeakMap();function _handleError(node,error){if(!node){return false;}
const fiber=node.fiber;if(fiber){fibersInError.set(fiber,error);}
const errorHandlers=nodeErrorHandlers.get(node);if(errorHandlers){let handled=false;for(let i=errorHandlers.length-1;i>=0;i--){try{errorHandlers[i](error);handled=true;break;}
catch(e){error=e;}}
if(handled){return true;}}
return _handleError(node.parent,error);}
function handleError(params){let{error}=params;if(!(error instanceof OwlError)){error=Object.assign(new OwlError(`An error occured in the owl lifecycle (see this Error's "cause" property)`),{cause:error});}
const node="node"in params?params.node:params.fiber.node;const fiber="fiber"in params?params.fiber:node.fiber;if(fiber){let current=fiber;do{current.node.fiber=current;fibersInError.set(current,error);current=current.parent;}while(current);fibersInError.set(fiber.root,error);}
const handled=_handleError(node,error);if(!handled){console.warn(`[Owl] Unhandled error. Destroying the root component`);try{node.app.destroy();}
catch(e){console.error(e);}
throw error;}}
function makeChildFiber(node,parent){let current=node.fiber;if(current){cancelFibers(current.children);current.root=null;}
return new Fiber(node,parent);}
function makeRootFiber(node){let current=node.fiber;if(current){let root=current.root;root.locked=true;root.setCounter(root.counter+1-cancelFibers(current.children));root.locked=false;current.children=[];current.childrenMap={};current.bdom=null;if(fibersInError.has(current)){fibersInError.delete(current);fibersInError.delete(root);current.appliedToDom=false;if(current instanceof RootFiber){current.mounted=current instanceof MountFiber?[current]:[];}}
return current;}
const fiber=new RootFiber(node,null);if(node.willPatch.length){fiber.willPatch.push(fiber);}
if(node.patched.length){fiber.patched.push(fiber);}
return fiber;}
function throwOnRender(){throw new OwlError("Attempted to render cancelled fiber");}
function cancelFibers(fibers){let result=0;for(let fiber of fibers){let node=fiber.node;fiber.render=throwOnRender;if(node.status===0){node.cancel();}
node.fiber=null;if(fiber.bdom){node.forceNextRender=true;}
else{result++;}
result+=cancelFibers(fiber.children);}
return result;}
class Fiber{constructor(node,parent){this.bdom=null;this.children=[];this.appliedToDom=false;this.deep=false;this.childrenMap={};this.node=node;this.parent=parent;if(parent){this.deep=parent.deep;const root=parent.root;root.setCounter(root.counter+1);this.root=root;parent.children.push(this);}
else{this.root=this;}}
render(){let prev=this.root.node;let scheduler=prev.app.scheduler;let current=prev.parent;while(current){if(current.fiber){let root=current.fiber.root;if(root.counter===0&&prev.parentKey in current.fiber.childrenMap){current=root.node;}
else{scheduler.delayedRenders.push(this);return;}}
prev=current;current=current.parent;}
this._render();}
_render(){const node=this.node;const root=this.root;if(root){try{this.bdom=true;this.bdom=node.renderFn();}
catch(e){node.app.handleError({node,error:e});}
root.setCounter(root.counter-1);}}}
class RootFiber extends Fiber{constructor(){super(...arguments);this.counter=1;this.willPatch=[];this.patched=[];this.mounted=[];this.locked=false;}
complete(){const node=this.node;this.locked=true;let current=undefined;let mountedFibers=this.mounted;try{for(current of this.willPatch){let node=current.node;if(node.fiber===current){const component=node.component;for(let cb of node.willPatch){cb.call(component);}}}
current=undefined;node._patch();this.locked=false;while((current=mountedFibers.pop())){current=current;if(current.appliedToDom){for(let cb of current.node.mounted){cb();}}}
let patchedFibers=this.patched;while((current=patchedFibers.pop())){current=current;if(current.appliedToDom){for(let cb of current.node.patched){cb();}}}}
catch(e){for(let fiber of mountedFibers){fiber.node.willUnmount=[];}
this.locked=false;node.app.handleError({fiber:current||this,error:e});}}
setCounter(newValue){this.counter=newValue;if(newValue===0){this.node.app.scheduler.flush();}}}
class MountFiber extends RootFiber{constructor(node,target,options={}){super(node,null);this.target=target;this.position=options.position||"last-child";}
complete(){let current=this;try{const node=this.node;node.children=this.childrenMap;node.app.constructor.validateTarget(this.target);if(node.bdom){node.updateDom();}
else{node.bdom=this.bdom;if(this.position==="last-child"||this.target.childNodes.length===0){mount$1(node.bdom,this.target);}
else{const firstChild=this.target.childNodes[0];mount$1(node.bdom,this.target,firstChild);}}
node.fiber=null;node.status=1;this.appliedToDom=true;let mountedFibers=this.mounted;while((current=mountedFibers.pop())){if(current.appliedToDom){for(let cb of current.node.mounted){cb();}}}}
catch(e){this.node.app.handleError({fiber:current,error:e});}}}
const KEYCHANGES=Symbol("Key changes");const NO_CALLBACK=()=>{throw new Error("Called NO_CALLBACK. Owl is broken, please report this to the maintainers.");};const objectToString=Object.prototype.toString;const objectHasOwnProperty=Object.prototype.hasOwnProperty;const SUPPORTED_RAW_TYPES=["Object","Array","Set","Map","WeakMap"];const COLLECTION_RAW_TYPES=["Set","Map","WeakMap"];function rawType(obj){return objectToString.call(toRaw(obj)).slice(8,-1);}
function canBeMadeReactive(value){if(typeof value!=="object"){return false;}
return SUPPORTED_RAW_TYPES.includes(rawType(value));}
function possiblyReactive(val,cb){return canBeMadeReactive(val)?reactive(val,cb):val;}
const skipped=new WeakSet();function markRaw(value){skipped.add(value);return value;}
function toRaw(value){return targets.has(value)?targets.get(value):value;}
const targetToKeysToCallbacks=new WeakMap();function observeTargetKey(target,key,callback){if(callback===NO_CALLBACK){return;}
if(!targetToKeysToCallbacks.get(target)){targetToKeysToCallbacks.set(target,new Map());}
const keyToCallbacks=targetToKeysToCallbacks.get(target);if(!keyToCallbacks.get(key)){keyToCallbacks.set(key,new Set());}
keyToCallbacks.get(key).add(callback);if(!callbacksToTargets.has(callback)){callbacksToTargets.set(callback,new Set());}
callbacksToTargets.get(callback).add(target);}
function notifyReactives(target,key){const keyToCallbacks=targetToKeysToCallbacks.get(target);if(!keyToCallbacks){return;}
const callbacks=keyToCallbacks.get(key);if(!callbacks){return;}
for(const callback of[...callbacks]){clearReactivesForCallback(callback);callback();}}
const callbacksToTargets=new WeakMap();function clearReactivesForCallback(callback){const targetsToClear=callbacksToTargets.get(callback);if(!targetsToClear){return;}
for(const target of targetsToClear){const observedKeys=targetToKeysToCallbacks.get(target);if(!observedKeys){continue;}
for(const[key,callbacks]of observedKeys.entries()){callbacks.delete(callback);if(!callbacks.size){observedKeys.delete(key);}}}
targetsToClear.clear();}
function getSubscriptions(callback){const targets=callbacksToTargets.get(callback)||[];return[...targets].map((target)=>{const keysToCallbacks=targetToKeysToCallbacks.get(target);let keys=[];if(keysToCallbacks){for(const[key,cbs]of keysToCallbacks){if(cbs.has(callback)){keys.push(key);}}}
return{target,keys};});}
const targets=new WeakMap();const reactiveCache=new WeakMap();function reactive(target,callback=NO_CALLBACK){if(!canBeMadeReactive(target)){throw new OwlError(`Cannot make the given value reactive`);}
if(skipped.has(target)){return target;}
if(targets.has(target)){return reactive(targets.get(target),callback);}
if(!reactiveCache.has(target)){reactiveCache.set(target,new WeakMap());}
const reactivesForTarget=reactiveCache.get(target);if(!reactivesForTarget.has(callback)){const targetRawType=rawType(target);const handler=COLLECTION_RAW_TYPES.includes(targetRawType)?collectionsProxyHandler(target,callback,targetRawType):basicProxyHandler(callback);const proxy=new Proxy(target,handler);reactivesForTarget.set(callback,proxy);targets.set(proxy,target);}
return reactivesForTarget.get(callback);}
function basicProxyHandler(callback){return{get(target,key,receiver){const desc=Object.getOwnPropertyDescriptor(target,key);if(desc&&!desc.writable&&!desc.configurable){return Reflect.get(target,key,receiver);}
observeTargetKey(target,key,callback);return possiblyReactive(Reflect.get(target,key,receiver),callback);},set(target,key,value,receiver){const hadKey=objectHasOwnProperty.call(target,key);const originalValue=Reflect.get(target,key,receiver);const ret=Reflect.set(target,key,toRaw(value),receiver);if(!hadKey&&objectHasOwnProperty.call(target,key)){notifyReactives(target,KEYCHANGES);}
if(originalValue!==Reflect.get(target,key,receiver)||(key==="length"&&Array.isArray(target))){notifyReactives(target,key);}
return ret;},deleteProperty(target,key){const ret=Reflect.deleteProperty(target,key);notifyReactives(target,KEYCHANGES);notifyReactives(target,key);return ret;},ownKeys(target){observeTargetKey(target,KEYCHANGES,callback);return Reflect.ownKeys(target);},has(target,key){observeTargetKey(target,KEYCHANGES,callback);return Reflect.has(target,key);},};}
function makeKeyObserver(methodName,target,callback){return(key)=>{key=toRaw(key);observeTargetKey(target,key,callback);return possiblyReactive(target[methodName](key),callback);};}
function makeIteratorObserver(methodName,target,callback){return function*(){observeTargetKey(target,KEYCHANGES,callback);const keys=target.keys();for(const item of target[methodName]()){const key=keys.next().value;observeTargetKey(target,key,callback);yield possiblyReactive(item,callback);}};}
function makeForEachObserver(target,callback){return function forEach(forEachCb,thisArg){observeTargetKey(target,KEYCHANGES,callback);target.forEach(function(val,key,targetObj){observeTargetKey(target,key,callback);forEachCb.call(thisArg,possiblyReactive(val,callback),possiblyReactive(key,callback),possiblyReactive(targetObj,callback));},thisArg);};}
function delegateAndNotify(setterName,getterName,target){return(key,value)=>{key=toRaw(key);const hadKey=target.has(key);const originalValue=target[getterName](key);const ret=target[setterName](key,value);const hasKey=target.has(key);if(hadKey!==hasKey){notifyReactives(target,KEYCHANGES);}
if(originalValue!==target[getterName](key)){notifyReactives(target,key);}
return ret;};}
function makeClearNotifier(target){return()=>{const allKeys=[...target.keys()];target.clear();notifyReactives(target,KEYCHANGES);for(const key of allKeys){notifyReactives(target,key);}};}
const rawTypeToFuncHandlers={Set:(target,callback)=>({has:makeKeyObserver("has",target,callback),add:delegateAndNotify("add","has",target),delete:delegateAndNotify("delete","has",target),keys:makeIteratorObserver("keys",target,callback),values:makeIteratorObserver("values",target,callback),entries:makeIteratorObserver("entries",target,callback),[Symbol.iterator]:makeIteratorObserver(Symbol.iterator,target,callback),forEach:makeForEachObserver(target,callback),clear:makeClearNotifier(target),get size(){observeTargetKey(target,KEYCHANGES,callback);return target.size;},}),Map:(target,callback)=>({has:makeKeyObserver("has",target,callback),get:makeKeyObserver("get",target,callback),set:delegateAndNotify("set","get",target),delete:delegateAndNotify("delete","has",target),keys:makeIteratorObserver("keys",target,callback),values:makeIteratorObserver("values",target,callback),entries:makeIteratorObserver("entries",target,callback),[Symbol.iterator]:makeIteratorObserver(Symbol.iterator,target,callback),forEach:makeForEachObserver(target,callback),clear:makeClearNotifier(target),get size(){observeTargetKey(target,KEYCHANGES,callback);return target.size;},}),WeakMap:(target,callback)=>({has:makeKeyObserver("has",target,callback),get:makeKeyObserver("get",target,callback),set:delegateAndNotify("set","get",target),delete:delegateAndNotify("delete","has",target),}),};function collectionsProxyHandler(target,callback,targetRawType){const specialHandlers=rawTypeToFuncHandlers[targetRawType](target,callback);return Object.assign(basicProxyHandler(callback),{get(target,key){if(objectHasOwnProperty.call(specialHandlers,key)){return specialHandlers[key];}
observeTargetKey(target,key,callback);return possiblyReactive(target[key],callback);},});}
let currentNode=null;function saveCurrent(){let n=currentNode;return()=>{currentNode=n;};}
function getCurrent(){if(!currentNode){throw new OwlError("No active component (a hook function should only be called in 'setup')");}
return currentNode;}
function useComponent(){return currentNode.component;}
function applyDefaultProps(props,defaultProps){for(let propName in defaultProps){if(props[propName]===undefined){props[propName]=defaultProps[propName];}}}
const batchedRenderFunctions=new WeakMap();function useState(state){const node=getCurrent();let render=batchedRenderFunctions.get(node);if(!render){const wrapper={fn:batched(node.render.bind(node,false))};render=(...args)=>wrapper.fn(...args);batchedRenderFunctions.set(node,render);node.willDestroy.push(cleanupRenderAndReactives.bind(null,wrapper,render));}
return reactive(state,render);}
const NO_OP=()=>{};function cleanupRenderAndReactives(wrapper,render){wrapper.fn=NO_OP;clearReactivesForCallback(render);}
class ComponentNode{constructor(C,props,app,parent,parentKey){this.fiber=null;this.bdom=null;this.status=0;this.forceNextRender=false;this.nextProps=null;this.children=Object.create(null);this.refs={};this.willStart=[];this.willUpdateProps=[];this.willUnmount=[];this.mounted=[];this.willPatch=[];this.patched=[];this.willDestroy=[];currentNode=this;this.app=app;this.parent=parent;this.props=props;this.parentKey=parentKey;const defaultProps=C.defaultProps;props=Object.assign({},props);if(defaultProps){applyDefaultProps(props,defaultProps);}
const env=(parent&&parent.childEnv)||app.env;this.childEnv=env;for(const key in props){const prop=props[key];if(prop&&typeof prop==="object"&&targets.has(prop)){props[key]=useState(prop);}}
this.component=new C(props,env,this);const ctx=Object.assign(Object.create(this.component),{this:this.component});this.renderFn=app.getTemplate(C.template).bind(this.component,ctx,this);this.component.setup();currentNode=null;}
mountComponent(target,options){const fiber=new MountFiber(this,target,options);this.app.scheduler.addFiber(fiber);this.initiateRender(fiber);}
async initiateRender(fiber){this.fiber=fiber;if(this.mounted.length){fiber.root.mounted.push(fiber);}
const component=this.component;try{await Promise.all(this.willStart.map((f)=>f.call(component)));}
catch(e){this.app.handleError({node:this,error:e});return;}
if(this.status===0&&this.fiber===fiber){fiber.render();}}
async render(deep){if(this.status>=2){return;}
let current=this.fiber;if(current&&(current.root.locked||current.bdom===true)){await Promise.resolve();current=this.fiber;}
if(current){if(!current.bdom&&!fibersInError.has(current)){if(deep){current.deep=deep;}
return;}
deep=deep||current.deep;}
else if(!this.bdom){return;}
const fiber=makeRootFiber(this);fiber.deep=deep;this.fiber=fiber;this.app.scheduler.addFiber(fiber);await Promise.resolve();if(this.status>=2){return;}
if(this.fiber===fiber&&(current||!fiber.parent)){fiber.render();}}
cancel(){this._cancel();delete this.parent.children[this.parentKey];this.app.scheduler.scheduleDestroy(this);}
_cancel(){this.status=2;const children=this.children;for(let childKey in children){children[childKey]._cancel();}}
destroy(){let shouldRemove=this.status===1;this._destroy();if(shouldRemove){this.bdom.remove();}}
_destroy(){const component=this.component;if(this.status===1){for(let cb of this.willUnmount){cb.call(component);}}
for(let child of Object.values(this.children)){child._destroy();}
if(this.willDestroy.length){try{for(let cb of this.willDestroy){cb.call(component);}}
catch(e){this.app.handleError({error:e,node:this});}}
this.status=3;}
async updateAndRender(props,parentFiber){this.nextProps=props;props=Object.assign({},props);const fiber=makeChildFiber(this,parentFiber);this.fiber=fiber;const component=this.component;const defaultProps=component.constructor.defaultProps;if(defaultProps){applyDefaultProps(props,defaultProps);}
currentNode=this;for(const key in props){const prop=props[key];if(prop&&typeof prop==="object"&&targets.has(prop)){props[key]=useState(prop);}}
currentNode=null;const prom=Promise.all(this.willUpdateProps.map((f)=>f.call(component,props)));await prom;if(fiber!==this.fiber){return;}
component.props=props;fiber.render();const parentRoot=parentFiber.root;if(this.willPatch.length){parentRoot.willPatch.push(fiber);}
if(this.patched.length){parentRoot.patched.push(fiber);}}
updateDom(){if(!this.fiber){return;}
if(this.bdom===this.fiber.bdom){for(let k in this.children){const child=this.children[k];child.updateDom();}}
else{this.bdom.patch(this.fiber.bdom,false);this.fiber.appliedToDom=true;this.fiber=null;}}
setRef(name,el){if(el){this.refs[name]=el;}}
firstNode(){const bdom=this.bdom;return bdom?bdom.firstNode():undefined;}
mount(parent,anchor){const bdom=this.fiber.bdom;this.bdom=bdom;bdom.mount(parent,anchor);this.status=1;this.fiber.appliedToDom=true;this.children=this.fiber.childrenMap;this.fiber=null;}
moveBeforeDOMNode(node,parent){this.bdom.moveBeforeDOMNode(node,parent);}
moveBeforeVNode(other,afterNode){this.bdom.moveBeforeVNode(other?other.bdom:null,afterNode);}
patch(){if(this.fiber&&this.fiber.parent){this._patch();this.props=this.nextProps;}}
_patch(){let hasChildren=false;for(let _k in this.children){hasChildren=true;break;}
const fiber=this.fiber;this.children=fiber.childrenMap;this.bdom.patch(fiber.bdom,hasChildren);fiber.appliedToDom=true;this.fiber=null;}
beforeRemove(){this._destroy();}
remove(){this.bdom.remove();}
get name(){return this.component.constructor.name;}
get subscriptions(){const render=batchedRenderFunctions.get(this);return render?getSubscriptions(render):[];}}
const TIMEOUT=Symbol("timeout");const HOOK_TIMEOUT={onWillStart:3000,onWillUpdateProps:3000,};function wrapError(fn,hookName){const error=new OwlError();const timeoutError=new OwlError();const node=getCurrent();return(...args)=>{const onError=(cause)=>{error.cause=cause;error.message=cause instanceof Error?`The following error occurred in ${hookName}: "${cause.message}"`:`Something that is not an Error was thrown in ${hookName} (see this Error's "cause" property)`;throw error;};let result;try{result=fn(...args);}
catch(cause){onError(cause);}
if(!(result instanceof Promise)){return result;}
const timeout=HOOK_TIMEOUT[hookName];if(timeout){const fiber=node.fiber;Promise.race([result.catch(()=>{}),new Promise((resolve)=>setTimeout(()=>resolve(TIMEOUT),timeout)),]).then((res)=>{if(res===TIMEOUT&&node.fiber===fiber&&node.status<=2){timeoutError.message=`${hookName}'s promise hasn't resolved after ${timeout / 1000} seconds`;console.log(timeoutError);}});}
return result.catch(onError);};}
function onWillStart(fn){const node=getCurrent();const decorate=node.app.dev?wrapError:(fn)=>fn;node.willStart.push(decorate(fn.bind(node.component),"onWillStart"));}
function onWillUpdateProps(fn){const node=getCurrent();const decorate=node.app.dev?wrapError:(fn)=>fn;node.willUpdateProps.push(decorate(fn.bind(node.component),"onWillUpdateProps"));}
function onMounted(fn){const node=getCurrent();const decorate=node.app.dev?wrapError:(fn)=>fn;node.mounted.push(decorate(fn.bind(node.component),"onMounted"));}
function onWillPatch(fn){const node=getCurrent();const decorate=node.app.dev?wrapError:(fn)=>fn;node.willPatch.unshift(decorate(fn.bind(node.component),"onWillPatch"));}
function onPatched(fn){const node=getCurrent();const decorate=node.app.dev?wrapError:(fn)=>fn;node.patched.push(decorate(fn.bind(node.component),"onPatched"));}
function onWillUnmount(fn){const node=getCurrent();const decorate=node.app.dev?wrapError:(fn)=>fn;node.willUnmount.unshift(decorate(fn.bind(node.component),"onWillUnmount"));}
function onWillDestroy(fn){const node=getCurrent();const decorate=node.app.dev?wrapError:(fn)=>fn;node.willDestroy.push(decorate(fn.bind(node.component),"onWillDestroy"));}
function onWillRender(fn){const node=getCurrent();const renderFn=node.renderFn;const decorate=node.app.dev?wrapError:(fn)=>fn;fn=decorate(fn.bind(node.component),"onWillRender");node.renderFn=()=>{fn();return renderFn();};}
function onRendered(fn){const node=getCurrent();const renderFn=node.renderFn;const decorate=node.app.dev?wrapError:(fn)=>fn;fn=decorate(fn.bind(node.component),"onRendered");node.renderFn=()=>{const result=renderFn();fn();return result;};}
function onError(callback){const node=getCurrent();let handlers=nodeErrorHandlers.get(node);if(!handlers){handlers=[];nodeErrorHandlers.set(node,handlers);}
handlers.push(callback.bind(node.component));}
class Component{constructor(props,env,node){this.props=props;this.env=env;this.__owl__=node;}
setup(){}
render(deep=false){this.__owl__.render(deep===true);}}
Component.template="";const VText=text("").constructor;class VPortal extends VText{constructor(selector,content){super("");this.target=null;this.selector=selector;this.content=content;}
mount(parent,anchor){super.mount(parent,anchor);this.target=document.querySelector(this.selector);if(this.target){this.content.mount(this.target,null);}
else{this.content.mount(parent,anchor);}}
beforeRemove(){this.content.beforeRemove();}
remove(){if(this.content){super.remove();this.content.remove();this.content=null;}}
patch(other){super.patch(other);if(this.content){this.content.patch(other.content,true);}
else{this.content=other.content;this.content.mount(this.target,null);}}}
function portalTemplate(app,bdom,helpers){let{callSlot}=helpers;return function template(ctx,node,key=""){return new VPortal(ctx.props.target,callSlot(ctx,node,key,"default",false,null));};}
class Portal extends Component{setup(){const node=this.__owl__;onMounted(()=>{const portal=node.bdom;if(!portal.target){const target=document.querySelector(this.props.target);if(target){portal.content.moveBeforeDOMNode(target.firstChild,target);}
else{throw new OwlError("invalid portal target");}}});onWillUnmount(()=>{const portal=node.bdom;portal.remove();});}}
Portal.template="__portal__";Portal.props={target:{type:String,},slots:true,};const isUnionType=(t)=>Array.isArray(t);const isBaseType=(t)=>typeof t!=="object";const isValueType=(t)=>typeof t==="object"&&t&&"value"in t;function isOptional(t){return typeof t==="object"&&"optional"in t?t.optional||false:false;}
function describeType(type){return type==="*"||type===true?"value":type.name.toLowerCase();}
function describe(info){if(isBaseType(info)){return describeType(info);}
else if(isUnionType(info)){return info.map(describe).join(" or ");}
else if(isValueType(info)){return String(info.value);}
if("element"in info){return`list of ${describe({ type: info.element, optional: false })}s`;}
if("shape"in info){return`object`;}
return describe(info.type||"*");}
function toSchema(spec){return Object.fromEntries(spec.map((e)=>e.endsWith("?")?[e.slice(0,-1),{optional:true}]:[e,{type:"*",optional:false}]));}
function validate(obj,spec){let errors=validateSchema(obj,spec);if(errors.length){throw new OwlError("Invalid object: "+errors.join(", "));}}
function validateSchema(obj,schema){if(Array.isArray(schema)){schema=toSchema(schema);}
obj=toRaw(obj);let errors=[];for(let key in obj){if(key in schema){let result=validateType(key,obj[key],schema[key]);if(result){errors.push(result);}}
else if(!("*"in schema)){errors.push(`unknown key '${key}'`);}}
for(let key in schema){const spec=schema[key];if(key!=="*"&&!isOptional(spec)&&!(key in obj)){const isObj=typeof spec==="object"&&!Array.isArray(spec);const isAny=spec==="*"||(isObj&&"type"in spec?spec.type==="*":isObj);let detail=isAny?"":` (should be a ${describe(spec)})`;errors.push(`'${key}' is missing${detail}`);}}
return errors;}
function validateBaseType(key,value,type){if(typeof type==="function"){if(typeof value==="object"){if(!(value instanceof type)){return`'${key}' is not a ${describeType(type)}`;}}
else if(typeof value!==type.name.toLowerCase()){return`'${key}' is not a ${describeType(type)}`;}}
return null;}
function validateArrayType(key,value,descr){if(!Array.isArray(value)){return`'${key}' is not a list of ${describe(descr)}s`;}
for(let i=0;i<value.length;i++){const error=validateType(`${key}[${i}]`,value[i],descr);if(error){return error;}}
return null;}
function validateType(key,value,descr){if(value===undefined){return isOptional(descr)?null:`'${key}' is undefined (should be a ${describe(descr)})`;}
else if(isBaseType(descr)){return validateBaseType(key,value,descr);}
else if(isValueType(descr)){return value===descr.value?null:`'${key}' is not equal to '${descr.value}'`;}
else if(isUnionType(descr)){let validDescr=descr.find((p)=>!validateType(key,value,p));return validDescr?null:`'${key}' is not a ${describe(descr)}`;}
let result=null;if("element"in descr){result=validateArrayType(key,value,descr.element);}
else if("shape"in descr){if(typeof value!=="object"||Array.isArray(value)){result=`'${key}' is not an object`;}
else{const errors=validateSchema(value,descr.shape);if(errors.length){result=`'${key}' doesn't have the correct shape (${errors.join(", ")})`;}}}
else if("values"in descr){if(typeof value!=="object"||Array.isArray(value)){result=`'${key}' is not an object`;}
else{const errors=Object.entries(value).map(([key,value])=>validateType(key,value,descr.values)).filter(Boolean);if(errors.length){result=`some of the values in '${key}' are invalid (${errors.join(", ")})`;}}}
if("type"in descr&&!result){result=validateType(key,value,descr.type);}
if("validate"in descr&&!result){result=!descr.validate(value)?`'${key}' is not valid`:null;}
return result;}
const ObjectCreate=Object.create;function withDefault(value,defaultValue){return value===undefined||value===null||value===false?defaultValue:value;}
function callSlot(ctx,parent,key,name,dynamic,extra,defaultContent){key=key+"__slot_"+name;const slots=ctx.props.slots||{};const{__render,__ctx,__scope}=slots[name]||{};const slotScope=ObjectCreate(__ctx||{});if(__scope){slotScope[__scope]=extra;}
const slotBDom=__render?__render(slotScope,parent,key):null;if(defaultContent){let child1=undefined;let child2=undefined;if(slotBDom){child1=dynamic?toggler(name,slotBDom):slotBDom;}
else{child2=defaultContent(ctx,parent,key);}
return multi([child1,child2]);}
return slotBDom||text("");}
function capture(ctx){const result=ObjectCreate(ctx);for(let k in ctx){result[k]=ctx[k];}
return result;}
function withKey(elem,k){elem.key=k;return elem;}
function prepareList(collection){let keys;let values;if(Array.isArray(collection)){keys=collection;values=collection;}
else if(collection instanceof Map){keys=[...collection.keys()];values=[...collection.values()];}
else if(Symbol.iterator in Object(collection)){keys=[...collection];values=keys;}
else if(collection&&typeof collection==="object"){values=Object.values(collection);keys=Object.keys(collection);}
else{throw new OwlError(`Invalid loop expression: "${collection}" is not iterable`);}
const n=values.length;return[keys,values,n,new Array(n)];}
const isBoundary=Symbol("isBoundary");function setContextValue(ctx,key,value){const ctx0=ctx;while(!ctx.hasOwnProperty(key)&&!ctx.hasOwnProperty(isBoundary)){const newCtx=ctx.__proto__;if(!newCtx){ctx=ctx0;break;}
ctx=newCtx;}
ctx[key]=value;}
function toNumber(val){const n=parseFloat(val);return isNaN(n)?val:n;}
function shallowEqual(l1,l2){for(let i=0,l=l1.length;i<l;i++){if(l1[i]!==l2[i]){return false;}}
return true;}
class LazyValue{constructor(fn,ctx,component,node,key){this.fn=fn;this.ctx=capture(ctx);this.component=component;this.node=node;this.key=key;}
evaluate(){return this.fn.call(this.component,this.ctx,this.node,this.key);}
toString(){return this.evaluate().toString();}}
function safeOutput(value,defaultValue){if(value===undefined||value===null){return defaultValue?toggler("default",defaultValue):toggler("undefined",text(""));}
let safeKey;let block;switch(typeof value){case"object":if(value instanceof Markup){safeKey=`string_safe`;block=html(value);}
else if(value instanceof LazyValue){safeKey=`lazy_value`;block=value.evaluate();}
else if(value instanceof String){safeKey="string_unsafe";block=text(value);}
else{safeKey="block_safe";block=value;}
break;case"string":safeKey="string_unsafe";block=text(value);break;default:safeKey="string_unsafe";block=text(String(value));}
return toggler(safeKey,block);}
function validateProps(name,props,comp){const ComponentClass=typeof name!=="string"?name:comp.constructor.components[name];if(!ComponentClass){return;}
const schema=ComponentClass.props;if(!schema){if(comp.__owl__.app.warnIfNoStaticProps){console.warn(`Component '${ComponentClass.name}' does not have a static props description`);}
return;}
const defaultProps=ComponentClass.defaultProps;if(defaultProps){let isMandatory=(name)=>Array.isArray(schema)?schema.includes(name):name in schema&&!("*"in schema)&&!isOptional(schema[name]);for(let p in defaultProps){if(isMandatory(p)){throw new OwlError(`A default value cannot be defined for a mandatory prop (name: '${p}', component: ${ComponentClass.name})`);}}}
const errors=validateSchema(props,schema);if(errors.length){throw new OwlError(`Invalid props for component '${ComponentClass.name}': `+errors.join(", "));}}
function makeRefWrapper(node){let refNames=new Set();return(name,fn)=>{if(refNames.has(name)){throw new OwlError(`Cannot set the same ref more than once in the same component, ref "${name}" was set multiple times in ${node.name}`);}
refNames.add(name);return fn;};}
const helpers={withDefault,zero:Symbol("zero"),isBoundary,callSlot,capture,withKey,prepareList,setContextValue,shallowEqual,toNumber,validateProps,LazyValue,safeOutput,createCatcher,markRaw,OwlError,makeRefWrapper,};function parseXML(xml){const parser=new DOMParser();const doc=parser.parseFromString(xml,"text/xml");if(doc.getElementsByTagName("parsererror").length){let msg="Invalid XML in template.";const parsererrorText=doc.getElementsByTagName("parsererror")[0].textContent;if(parsererrorText){msg+="\nThe parser has produced the following error message:\n"+parsererrorText;const re=/\d+/g;const firstMatch=re.exec(parsererrorText);if(firstMatch){const lineNumber=Number(firstMatch[0]);const line=xml.split("\n")[lineNumber-1];const secondMatch=re.exec(parsererrorText);if(line&&secondMatch){const columnIndex=Number(secondMatch[0])-1;if(line[columnIndex]){msg+=`\nThe error might be located at xml line ${lineNumber} column ${columnIndex}\n`+`${line}\n${"-".repeat(columnIndex - 1)}^`;}}}}
throw new OwlError(msg);}
return doc;}
const bdom={text,createBlock,list,multi,html,toggler,comment};class TemplateSet{constructor(config={}){this.rawTemplates=Object.create(globalTemplates);this.templates={};this.Portal=Portal;this.dev=config.dev||false;this.translateFn=config.translateFn;this.translatableAttributes=config.translatableAttributes;if(config.templates){if(config.templates instanceof Document||typeof config.templates==="string"){this.addTemplates(config.templates);}
else{for(const name in config.templates){this.addTemplate(name,config.templates[name]);}}}
this.getRawTemplate=config.getTemplate;this.customDirectives=config.customDirectives||{};this.runtimeUtils={...helpers,__globals__:config.globalValues||{}};this.hasGlobalValues=Boolean(config.globalValues&&Object.keys(config.globalValues).length);}
static registerTemplate(name,fn){globalTemplates[name]=fn;}
addTemplate(name,template){if(name in this.rawTemplates){if(!this.dev){return;}
const rawTemplate=this.rawTemplates[name];const currentAsString=typeof rawTemplate==="string"?rawTemplate:rawTemplate instanceof Element?rawTemplate.outerHTML:rawTemplate.toString();const newAsString=typeof template==="string"?template:template.outerHTML;if(currentAsString===newAsString){return;}
throw new OwlError(`Template ${name} already defined with different content`);}
this.rawTemplates[name]=template;}
addTemplates(xml){if(!xml){return;}
xml=xml instanceof Document?xml:parseXML(xml);for(const template of xml.querySelectorAll("[t-name]")){const name=template.getAttribute("t-name");this.addTemplate(name,template);}}
getTemplate(name){var _a;if(!(name in this.templates)){const rawTemplate=((_a=this.getRawTemplate)===null||_a===void 0?void 0:_a.call(this,name))||this.rawTemplates[name];if(rawTemplate===undefined){let extraInfo="";try{const componentName=getCurrent().component.constructor.name;extraInfo=` (for component "${componentName}")`;}
catch{}
throw new OwlError(`Missing template: "${name}"${extraInfo}`);}
const isFn=typeof rawTemplate==="function"&&!(rawTemplate instanceof Element);const templateFn=isFn?rawTemplate:this._compileTemplate(name,rawTemplate);const templates=this.templates;this.templates[name]=function(context,parent){return templates[name].call(this,context,parent);};const template=templateFn(this,bdom,this.runtimeUtils);this.templates[name]=template;}
return this.templates[name];}
_compileTemplate(name,template){throw new OwlError(`Unable to compile a template. Please use owl full build instead`);}
callTemplate(owner,subTemplate,ctx,parent,key){const template=this.getTemplate(subTemplate);return toggler(subTemplate,template.call(owner,ctx,parent,key+subTemplate));}}
const globalTemplates={};function xml(...args){const name=`__template__${xml.nextId++}`;const value=String.raw(...args);globalTemplates[name]=value;return name;}
xml.nextId=1;TemplateSet.registerTemplate("__portal__",portalTemplate);const RESERVED_WORDS="true,false,NaN,null,undefined,debugger,console,window,in,instanceof,new,function,return,eval,void,Math,RegExp,Array,Object,Date,__globals__".split(",");const WORD_REPLACEMENT=Object.assign(Object.create(null),{and:"&&",or:"||",gt:">",gte:">=",lt:"<",lte:"<=",});const STATIC_TOKEN_MAP=Object.assign(Object.create(null),{"{":"LEFT_BRACE","}":"RIGHT_BRACE","[":"LEFT_BRACKET","]":"RIGHT_BRACKET",":":"COLON",",":"COMMA","(":"LEFT_PAREN",")":"RIGHT_PAREN",});const OPERATORS="...,.,===,==,+,!==,!=,!,||,&&,>=,>,<=,<,?,-,*,/,%,typeof ,=>,=,;,in ,new ,|,&,^,~".split(",");let tokenizeString=function(expr){let s=expr[0];let start=s;if(s!=="'"&&s!=='"'&&s!=="`"){return false;}
let i=1;let cur;while(expr[i]&&expr[i]!==start){cur=expr[i];s+=cur;if(cur==="\\"){i++;cur=expr[i];if(!cur){throw new OwlError("Invalid expression");}
s+=cur;}
i++;}
if(expr[i]!==start){throw new OwlError("Invalid expression");}
s+=start;if(start==="`"){return{type:"TEMPLATE_STRING",value:s,replace(replacer){return s.replace(/\$\{(.*?)\}/g,(match,group)=>{return"${"+replacer(group)+"}";});},};}
return{type:"VALUE",value:s};};let tokenizeNumber=function(expr){let s=expr[0];if(s&&s.match(/[0-9]/)){let i=1;while(expr[i]&&expr[i].match(/[0-9]|\./)){s+=expr[i];i++;}
return{type:"VALUE",value:s};}
else{return false;}};let tokenizeSymbol=function(expr){let s=expr[0];if(s&&s.match(/[a-zA-Z_\$]/)){let i=1;while(expr[i]&&expr[i].match(/\w/)){s+=expr[i];i++;}
if(s in WORD_REPLACEMENT){return{type:"OPERATOR",value:WORD_REPLACEMENT[s],size:s.length};}
return{type:"SYMBOL",value:s};}
else{return false;}};const tokenizeStatic=function(expr){const char=expr[0];if(char&&char in STATIC_TOKEN_MAP){return{type:STATIC_TOKEN_MAP[char],value:char};}
return false;};const tokenizeOperator=function(expr){for(let op of OPERATORS){if(expr.startsWith(op)){return{type:"OPERATOR",value:op};}}
return false;};const TOKENIZERS=[tokenizeString,tokenizeNumber,tokenizeOperator,tokenizeSymbol,tokenizeStatic,];function tokenize(expr){const result=[];let token=true;let error;let current=expr;try{while(token){current=current.trim();if(current){for(let tokenizer of TOKENIZERS){token=tokenizer(current);if(token){result.push(token);current=current.slice(token.size||token.value.length);break;}}}
else{token=false;}}}
catch(e){error=e;}
if(current.length||error){throw new OwlError(`Tokenizer error: could not tokenize \`${expr}\``);}
return result;}
const isLeftSeparator=(token)=>token&&(token.type==="LEFT_BRACE"||token.type==="COMMA");const isRightSeparator=(token)=>token&&(token.type==="RIGHT_BRACE"||token.type==="COMMA");function compileExprToArray(expr){const localVars=new Set();const tokens=tokenize(expr);let i=0;let stack=[];while(i<tokens.length){let token=tokens[i];let prevToken=tokens[i-1];let nextToken=tokens[i+1];let groupType=stack[stack.length-1];switch(token.type){case"LEFT_BRACE":case"LEFT_BRACKET":case"LEFT_PAREN":stack.push(token.type);break;case"RIGHT_BRACE":case"RIGHT_BRACKET":case"RIGHT_PAREN":stack.pop();}
let isVar=token.type==="SYMBOL"&&!RESERVED_WORDS.includes(token.value);if(token.type==="SYMBOL"&&!RESERVED_WORDS.includes(token.value)){if(prevToken){if(groupType==="LEFT_BRACE"&&isLeftSeparator(prevToken)&&isRightSeparator(nextToken)){tokens.splice(i+1,0,{type:"COLON",value:":"},{...token});nextToken=tokens[i+1];}
if(prevToken.type==="OPERATOR"&&prevToken.value==="."){isVar=false;}
else if(prevToken.type==="LEFT_BRACE"||prevToken.type==="COMMA"){if(nextToken&&nextToken.type==="COLON"){isVar=false;}}}}
if(token.type==="TEMPLATE_STRING"){token.value=token.replace((expr)=>compileExpr(expr));}
if(nextToken&&nextToken.type==="OPERATOR"&&nextToken.value==="=>"){if(token.type==="RIGHT_PAREN"){let j=i-1;while(j>0&&tokens[j].type!=="LEFT_PAREN"){if(tokens[j].type==="SYMBOL"&&tokens[j].originalValue){tokens[j].value=tokens[j].originalValue;localVars.add(tokens[j].value);}
j--;}}
else{localVars.add(token.value);}}
if(isVar){token.varName=token.value;if(!localVars.has(token.value)){token.originalValue=token.value;token.value=`ctx['${token.value}']`;}}
i++;}
for(const token of tokens){if(token.type==="SYMBOL"&&token.varName&&localVars.has(token.value)){token.originalValue=token.value;token.value=`_${token.value}`;token.isLocal=true;}}
return tokens;}
const paddedValues=new Map([["in "," in "]]);function compileExpr(expr){return compileExprToArray(expr).map((t)=>paddedValues.get(t.value)||t.value).join("");}
const INTERP_REGEXP=/\{\{.*?\}\}|\#\{.*?\}/g;function replaceDynamicParts(s,replacer){let matches=s.match(INTERP_REGEXP);if(matches&&matches[0].length===s.length){return`(${replacer(s.slice(2, matches[0][0] === "{" ? -2 : -1))})`;}
let r=s.replace(INTERP_REGEXP,(s)=>"${"+replacer(s.slice(2,s[0]==="{"?-2:-1))+"}");return"`"+r+"`";}
function interpolate(s){return replaceDynamicParts(s,compileExpr);}
const whitespaceRE=/\s+/g;const xmlDoc=document.implementation.createDocument(null,null,null);const MODS=new Set(["stop","capture","prevent","self","synthetic"]);let nextDataIds={};function generateId(prefix=""){nextDataIds[prefix]=(nextDataIds[prefix]||0)+1;return prefix+nextDataIds[prefix];}
function isProp(tag,key){switch(tag){case"input":return(key==="checked"||key==="indeterminate"||key==="value"||key==="readonly"||key==="readOnly"||key==="disabled");case"option":return key==="selected"||key==="disabled";case"textarea":return key==="value"||key==="readonly"||key==="readOnly"||key==="disabled";case"select":return key==="value"||key==="disabled";case"button":case"optgroup":return key==="disabled";}
return false;}
function toStringExpression(str){return`\`${str.replace(/\\/g, "\\\\").replace(/`/g,"\\`").replace(/\$\{/,"\\${")}\``;}
class BlockDescription{constructor(target,type){this.dynamicTagName=null;this.isRoot=false;this.hasDynamicChildren=false;this.children=[];this.data=[];this.childNumber=0;this.parentVar="";this.id=BlockDescription.nextBlockId++;this.varName="b"+this.id;this.blockName="block"+this.id;this.target=target;this.type=type;}
insertData(str,prefix="d"){const id=generateId(prefix);this.target.addLine(`let ${id} = ${str};`);return this.data.push(id)-1;}
insert(dom){if(this.currentDom){this.currentDom.appendChild(dom);}
else{this.dom=dom;}}
generateExpr(expr){if(this.type==="block"){const hasChildren=this.children.length;let params=this.data.length?`[${this.data.join(", ")}]`:hasChildren?"[]":"";if(hasChildren){params+=", ["+this.children.map((c)=>c.varName).join(", ")+"]";}
if(this.dynamicTagName){return`toggler(${this.dynamicTagName}, ${this.blockName}(${this.dynamicTagName})(${params}))`;}
return`${this.blockName}(${params})`;}
else if(this.type==="list"){return`list(c_block${this.id})`;}
return expr;}
asXmlString(){const t=xmlDoc.createElement("t");t.appendChild(this.dom);return t.innerHTML;}}
BlockDescription.nextBlockId=1;function createContext(parentCtx,params){return Object.assign({block:null,index:0,forceNewBlock:true,translate:parentCtx.translate,translationCtx:parentCtx.translationCtx,tKeyExpr:null,nameSpace:parentCtx.nameSpace,tModelSelectedExpr:parentCtx.tModelSelectedExpr,},params);}
class CodeTarget{constructor(name,on){this.indentLevel=0;this.loopLevel=0;this.code=[];this.hasRoot=false;this.hasCache=false;this.shouldProtectScope=false;this.hasRefWrapper=false;this.name=name;this.on=on||null;}
addLine(line,idx){const prefix=new Array(this.indentLevel+2).join(" ");if(idx===undefined){this.code.push(prefix+line);}
else{this.code.splice(idx,0,prefix+line);}}
generateCode(){let result=[];result.push(`function ${this.name}(ctx, node, key = "") {`);if(this.shouldProtectScope){result.push(` ctx = Object.create(ctx);`);result.push(` ctx[isBoundary] = 1`);}
if(this.hasRefWrapper){result.push(` let refWrapper = makeRefWrapper(this.__owl__);`);}
if(this.hasCache){result.push(` let cache = ctx.cache || {};`);result.push(` let nextCache = ctx.cache = {};`);}
for(let line of this.code){result.push(line);}
if(!this.hasRoot){result.push(`return text('');`);}
result.push(`}`);return result.join("\n ");}
currentKey(ctx){let key=this.loopLevel?`key${this.loopLevel}`:"key";if(ctx.tKeyExpr){key=`${ctx.tKeyExpr} + ${key}`;}
return key;}}
const TRANSLATABLE_ATTRS=["alt","aria-label","aria-placeholder","aria-roledescription","aria-valuetext","label","placeholder","title",];const translationRE=/^(\s*)([\s\S]+?)(\s*)$/;class CodeGenerator{constructor(ast,options){this.blocks=[];this.nextBlockId=1;this.isDebug=false;this.targets=[];this.target=new CodeTarget("template");this.translatableAttributes=TRANSLATABLE_ATTRS;this.staticDefs=[];this.slotNames=new Set();this.helpers=new Set();this.translateFn=options.translateFn||((s)=>s);if(options.translatableAttributes){const attrs=new Set(TRANSLATABLE_ATTRS);for(let attr of options.translatableAttributes){if(attr.startsWith("-")){attrs.delete(attr.slice(1));}
else{attrs.add(attr);}}
this.translatableAttributes=[...attrs];}
this.hasSafeContext=options.hasSafeContext||false;this.dev=options.dev||false;this.ast=ast;this.templateName=options.name;if(options.hasGlobalValues){this.helpers.add("__globals__");}}
generateCode(){const ast=this.ast;this.isDebug=ast.type===12;BlockDescription.nextBlockId=1;nextDataIds={};this.compileAST(ast,{block:null,index:0,forceNewBlock:false,isLast:true,translate:true,translationCtx:"",tKeyExpr:null,});let mainCode=[` let { text, createBlock, list, multi, html, toggler, comment } = bdom;`];if(this.helpers.size){mainCode.push(`let { ${[...this.helpers].join(", ")} } = helpers;`);}
if(this.templateName){mainCode.push(`// Template name: "${this.templateName}"`);}
for(let{id,expr}of this.staticDefs){mainCode.push(`const ${id} = ${expr};`);}
if(this.blocks.length){mainCode.push(``);for(let block of this.blocks){if(block.dom){let xmlString=toStringExpression(block.asXmlString());if(block.dynamicTagName){xmlString=xmlString.replace(/^`<\w+/,`\`<\${tag || '${block.dom.nodeName}'}`);xmlString=xmlString.replace(/\w+>`$/,`\${tag || '${block.dom.nodeName}'}>\``);mainCode.push(`let ${block.blockName} = tag => createBlock(${xmlString});`);}
else{mainCode.push(`let ${block.blockName} = createBlock(${xmlString});`);}}}}
if(this.targets.length){for(let fn of this.targets){mainCode.push("");mainCode=mainCode.concat(fn.generateCode());}}
mainCode.push("");mainCode=mainCode.concat("return "+this.target.generateCode());const code=mainCode.join("\n ");if(this.isDebug){const msg=`[Owl Debug]\n${code}`;console.log(msg);}
return code;}
compileInNewTarget(prefix,ast,ctx,on){const name=generateId(prefix);const initialTarget=this.target;const target=new CodeTarget(name,on);this.targets.push(target);this.target=target;this.compileAST(ast,createContext(ctx));this.target=initialTarget;return name;}
addLine(line,idx){this.target.addLine(line,idx);}
define(varName,expr){this.addLine(`const ${varName} = ${expr};`);}
insertAnchor(block,index=block.children.length){const tag=`block-child-${index}`;const anchor=xmlDoc.createElement(tag);block.insert(anchor);}
createBlock(parentBlock,type,ctx){const hasRoot=this.target.hasRoot;const block=new BlockDescription(this.target,type);if(!hasRoot){this.target.hasRoot=true;block.isRoot=true;}
if(parentBlock){parentBlock.children.push(block);if(parentBlock.type==="list"){block.parentVar=`c_block${parentBlock.id}`;}}
return block;}
insertBlock(expression,block,ctx){let blockExpr=block.generateExpr(expression);if(block.parentVar){let key=this.target.currentKey(ctx);this.helpers.add("withKey");this.addLine(`${block.parentVar}[${ctx.index}] = withKey(${blockExpr}, ${key});`);return;}
if(ctx.tKeyExpr){blockExpr=`toggler(${ctx.tKeyExpr}, ${blockExpr})`;}
if(block.isRoot){if(this.target.on){blockExpr=this.wrapWithEventCatcher(blockExpr,this.target.on);}
this.addLine(`return ${blockExpr};`);}
else{this.define(block.varName,blockExpr);}}
captureExpression(expr,forceCapture=false){if(!forceCapture&&!expr.includes("=>")){return compileExpr(expr);}
const tokens=compileExprToArray(expr);const mapping=new Map();return tokens.map((tok)=>{if(tok.varName&&!tok.isLocal){if(!mapping.has(tok.varName)){const varId=generateId("v");mapping.set(tok.varName,varId);this.define(varId,tok.value);}
tok.value=mapping.get(tok.varName);}
return tok.value;}).join("");}
translate(str,translationCtx){const match=translationRE.exec(str);return match[1]+this.translateFn(match[2],translationCtx)+match[3];}
compileAST(ast,ctx){switch(ast.type){case 1:return this.compileComment(ast,ctx);case 0:return this.compileText(ast,ctx);case 2:return this.compileTDomNode(ast,ctx);case 4:return this.compileTEsc(ast,ctx);case 8:return this.compileTOut(ast,ctx);case 5:return this.compileTIf(ast,ctx);case 9:return this.compileTForeach(ast,ctx);case 10:return this.compileTKey(ast,ctx);case 3:return this.compileMulti(ast,ctx);case 7:return this.compileTCall(ast,ctx);case 15:return this.compileTCallBlock(ast,ctx);case 6:return this.compileTSet(ast,ctx);case 11:return this.compileComponent(ast,ctx);case 12:return this.compileDebug(ast,ctx);case 13:return this.compileLog(ast,ctx);case 14:return this.compileTSlot(ast,ctx);case 16:return this.compileTTranslation(ast,ctx);case 17:return this.compileTTranslationContext(ast,ctx);case 18:return this.compileTPortal(ast,ctx);}}
compileDebug(ast,ctx){this.addLine(`debugger;`);if(ast.content){return this.compileAST(ast.content,ctx);}
return null;}
compileLog(ast,ctx){this.addLine(`console.log(${compileExpr(ast.expr)});`);if(ast.content){return this.compileAST(ast.content,ctx);}
return null;}
compileComment(ast,ctx){let{block,forceNewBlock}=ctx;const isNewBlock=!block||forceNewBlock;if(isNewBlock){block=this.createBlock(block,"comment",ctx);this.insertBlock(`comment(${toStringExpression(ast.value)})`,block,{...ctx,forceNewBlock:forceNewBlock&&!block,});}
else{const text=xmlDoc.createComment(ast.value);block.insert(text);}
return block.varName;}
compileText(ast,ctx){let{block,forceNewBlock}=ctx;let value=ast.value;if(value&&ctx.translate!==false){value=this.translate(value,ctx.translationCtx);}
if(!ctx.inPreTag){value=value.replace(whitespaceRE," ");}
if(!block||forceNewBlock){block=this.createBlock(block,"text",ctx);this.insertBlock(`text(${toStringExpression(value)})`,block,{...ctx,forceNewBlock:forceNewBlock&&!block,});}
else{const createFn=ast.type===0?xmlDoc.createTextNode:xmlDoc.createComment;block.insert(createFn.call(xmlDoc,value));}
return block.varName;}
generateHandlerCode(rawEvent,handler){const modifiers=rawEvent.split(".").slice(1).map((m)=>{if(!MODS.has(m)){throw new OwlError(`Unknown event modifier: '${m}'`);}
return`"${m}"`;});let modifiersCode="";if(modifiers.length){modifiersCode=`${modifiers.join(",")}, `;}
return`[${modifiersCode}${this.captureExpression(handler)}, ctx]`;}
compileTDomNode(ast,ctx){var _a;let{block,forceNewBlock}=ctx;const isNewBlock=!block||forceNewBlock||ast.dynamicTag!==null||ast.ns;let codeIdx=this.target.code.length;if(isNewBlock){if((ast.dynamicTag||ctx.tKeyExpr||ast.ns)&&ctx.block){this.insertAnchor(ctx.block);}
block=this.createBlock(block,"block",ctx);this.blocks.push(block);if(ast.dynamicTag){const tagExpr=generateId("tag");this.define(tagExpr,compileExpr(ast.dynamicTag));block.dynamicTagName=tagExpr;}}
const attrs={};for(let key in ast.attrs){let expr,attrName;if(key.startsWith("t-attf")){expr=interpolate(ast.attrs[key]);const idx=block.insertData(expr,"attr");attrName=key.slice(7);attrs["block-attribute-"+idx]=attrName;}
else if(key.startsWith("t-att")){attrName=key==="t-att"?null:key.slice(6);expr=compileExpr(ast.attrs[key]);if(attrName&&isProp(ast.tag,attrName)){if(attrName==="readonly"){attrName="readOnly";}
if(attrName==="value"){expr=`new String((${expr}) === 0 ? 0 : ((${expr}) || ""))`;}
else{expr=`new Boolean(${expr})`;}
const idx=block.insertData(expr,"prop");attrs[`block-property-${idx}`]=attrName;}
else{const idx=block.insertData(expr,"attr");if(key==="t-att"){attrs[`block-attributes`]=String(idx);}
else{attrs[`block-attribute-${idx}`]=attrName;}}}
else if(this.translatableAttributes.includes(key)){const attrTranslationCtx=((_a=ast.attrsTranslationCtx)===null||_a===void 0?void 0:_a[key])||ctx.translationCtx;attrs[key]=this.translateFn(ast.attrs[key],attrTranslationCtx);}
else{expr=`"${ast.attrs[key]}"`;attrName=key;attrs[key]=ast.attrs[key];}
if(attrName==="value"&&ctx.tModelSelectedExpr){let selectedId=block.insertData(`${ctx.tModelSelectedExpr} === ${expr}`,"attr");attrs[`block-attribute-${selectedId}`]="selected";}}
let tModelSelectedExpr;if(ast.model){const{hasDynamicChildren,baseExpr,expr,eventType,shouldNumberize,shouldTrim,targetAttr,specialInitTargetAttr,}=ast.model;const baseExpression=compileExpr(baseExpr);const bExprId=generateId("bExpr");this.define(bExprId,baseExpression);const expression=compileExpr(expr);const exprId=generateId("expr");this.define(exprId,expression);const fullExpression=`${bExprId}[${exprId}]`;let idx;if(specialInitTargetAttr){let targetExpr=targetAttr in attrs&&`'${attrs[targetAttr]}'`;if(!targetExpr&&ast.attrs){const dynamicTgExpr=ast.attrs[`t-att-${targetAttr}`];if(dynamicTgExpr){targetExpr=compileExpr(dynamicTgExpr);}}
idx=block.insertData(`${fullExpression} === ${targetExpr}`,"prop");attrs[`block-property-${idx}`]=specialInitTargetAttr;}
else if(hasDynamicChildren){const bValueId=generateId("bValue");tModelSelectedExpr=`${bValueId}`;this.define(tModelSelectedExpr,fullExpression);}
else{idx=block.insertData(`${fullExpression}`,"prop");attrs[`block-property-${idx}`]=targetAttr;}
this.helpers.add("toNumber");let valueCode=`ev.target.${targetAttr}`;valueCode=shouldTrim?`${valueCode}.trim()`:valueCode;valueCode=shouldNumberize?`toNumber(${valueCode})`:valueCode;const handler=`[(ev) => { ${fullExpression} = ${valueCode}; }]`;idx=block.insertData(handler,"hdlr");attrs[`block-handler-${idx}`]=eventType;}
for(let ev in ast.on){const name=this.generateHandlerCode(ev,ast.on[ev]);const idx=block.insertData(name,"hdlr");attrs[`block-handler-${idx}`]=ev;}
if(ast.ref){if(this.dev){this.helpers.add("makeRefWrapper");this.target.hasRefWrapper=true;}
const isDynamic=INTERP_REGEXP.test(ast.ref);let name=`\`${ast.ref}\``;if(isDynamic){name=replaceDynamicParts(ast.ref,(expr)=>this.captureExpression(expr,true));}
let setRefStr=`(el) => this.__owl__.setRef((${name}), el)`;if(this.dev){setRefStr=`refWrapper(${name}, ${setRefStr})`;}
const idx=block.insertData(setRefStr,"ref");attrs["block-ref"]=String(idx);}
const nameSpace=ast.ns||ctx.nameSpace;const dom=nameSpace?xmlDoc.createElementNS(nameSpace,ast.tag):xmlDoc.createElement(ast.tag);for(const[attr,val]of Object.entries(attrs)){if(!(attr==="class"&&val==="")){dom.setAttribute(attr,val);}}
block.insert(dom);if(ast.content.length){const initialDom=block.currentDom;block.currentDom=dom;const children=ast.content;for(let i=0;i<children.length;i++){const child=ast.content[i];const subCtx=createContext(ctx,{block,index:block.childNumber,forceNewBlock:false,isLast:ctx.isLast&&i===children.length-1,tKeyExpr:ctx.tKeyExpr,nameSpace,tModelSelectedExpr,inPreTag:ctx.inPreTag||ast.tag==="pre",});this.compileAST(child,subCtx);}
block.currentDom=initialDom;}
if(isNewBlock){this.insertBlock(`${block.blockName}(ddd)`,block,ctx);if(block.children.length&&block.hasDynamicChildren){const code=this.target.code;const children=block.children.slice();let current=children.shift();for(let i=codeIdx;i<code.length;i++){if(code[i].trimStart().startsWith(`const ${current.varName} `)){code[i]=code[i].replace(`const ${current.varName}`,current.varName);current=children.shift();if(!current)
break;}}
this.addLine(`let ${block.children.map((c) => c.varName).join(", ")};`,codeIdx);}}
return block.varName;}
compileTEsc(ast,ctx){let{block,forceNewBlock}=ctx;let expr;if(ast.expr==="0"){this.helpers.add("zero");expr=`ctx[zero]`;}
else{expr=compileExpr(ast.expr);if(ast.defaultValue){this.helpers.add("withDefault");expr=`withDefault(${expr}, ${toStringExpression(ast.defaultValue)})`;}}
if(!block||forceNewBlock){block=this.createBlock(block,"text",ctx);this.insertBlock(`text(${expr})`,block,{...ctx,forceNewBlock:forceNewBlock&&!block});}
else{const idx=block.insertData(expr,"txt");const text=xmlDoc.createElement(`block-text-${idx}`);block.insert(text);}
return block.varName;}
compileTOut(ast,ctx){let{block}=ctx;if(block){this.insertAnchor(block);}
block=this.createBlock(block,"html",ctx);let blockStr;if(ast.expr==="0"){this.helpers.add("zero");blockStr=`ctx[zero]`;}
else if(ast.body){let bodyValue=null;bodyValue=BlockDescription.nextBlockId;const subCtx=createContext(ctx);this.compileAST({type:3,content:ast.body},subCtx);this.helpers.add("safeOutput");blockStr=`safeOutput(${compileExpr(ast.expr)}, b${bodyValue})`;}
else{this.helpers.add("safeOutput");blockStr=`safeOutput(${compileExpr(ast.expr)})`;}
this.insertBlock(blockStr,block,ctx);return block.varName;}
compileTIfBranch(content,block,ctx){this.target.indentLevel++;let childN=block.children.length;this.compileAST(content,createContext(ctx,{block,index:ctx.index}));if(block.children.length>childN){this.insertAnchor(block,childN);}
this.target.indentLevel--;}
compileTIf(ast,ctx,nextNode){let{block,forceNewBlock}=ctx;const codeIdx=this.target.code.length;const isNewBlock=!block||(block.type!=="multi"&&forceNewBlock);if(block){block.hasDynamicChildren=true;}
if(!block||(block.type!=="multi"&&forceNewBlock)){block=this.createBlock(block,"multi",ctx);}
this.addLine(`if (${compileExpr(ast.condition)}) {`);this.compileTIfBranch(ast.content,block,ctx);if(ast.tElif){for(let clause of ast.tElif){this.addLine(`} else if (${compileExpr(clause.condition)}) {`);this.compileTIfBranch(clause.content,block,ctx);}}
if(ast.tElse){this.addLine(`} else {`);this.compileTIfBranch(ast.tElse,block,ctx);}
this.addLine("}");if(isNewBlock){if(block.children.length){const code=this.target.code;const children=block.children.slice();let current=children.shift();for(let i=codeIdx;i<code.length;i++){if(code[i].trimStart().startsWith(`const ${current.varName} `)){code[i]=code[i].replace(`const ${current.varName}`,current.varName);current=children.shift();if(!current)
break;}}
this.addLine(`let ${block.children.map((c) => c.varName).join(", ")};`,codeIdx);}
const args=block.children.map((c)=>c.varName).join(", ");this.insertBlock(`multi([${args}])`,block,ctx);}
return block.varName;}
compileTForeach(ast,ctx){let{block}=ctx;if(block){this.insertAnchor(block);}
block=this.createBlock(block,"list",ctx);this.target.loopLevel++;const loopVar=`i${this.target.loopLevel}`;this.addLine(`ctx = Object.create(ctx);`);const vals=`v_block${block.id}`;const keys=`k_block${block.id}`;const l=`l_block${block.id}`;const c=`c_block${block.id}`;this.helpers.add("prepareList");this.define(`[${keys}, ${vals}, ${l}, ${c}]`,`prepareList(${compileExpr(ast.collection)});`);if(this.dev){this.define(`keys${block.id}`,`new Set()`);}
this.addLine(`for (let ${loopVar} = 0; ${loopVar} < ${l}; ${loopVar}++) {`);this.target.indentLevel++;this.addLine(`ctx[\`${ast.elem}\`] = ${keys}[${loopVar}];`);if(!ast.hasNoFirst){this.addLine(`ctx[\`${ast.elem}_first\`] = ${loopVar} === 0;`);}
if(!ast.hasNoLast){this.addLine(`ctx[\`${ast.elem}_last\`] = ${loopVar} === ${keys}.length - 1;`);}
if(!ast.hasNoIndex){this.addLine(`ctx[\`${ast.elem}_index\`] = ${loopVar};`);}
if(!ast.hasNoValue){this.addLine(`ctx[\`${ast.elem}_value\`] = ${vals}[${loopVar}];`);}
this.define(`key${this.target.loopLevel}`,ast.key?compileExpr(ast.key):loopVar);if(this.dev){this.helpers.add("OwlError");this.addLine(`if (keys${block.id}.has(String(key${this.target.loopLevel}))) { throw new OwlError(\`Got duplicate key in t-foreach: \${key${this.target.loopLevel}}\`)}`);this.addLine(`keys${block.id}.add(String(key${this.target.loopLevel}));`);}
let id;if(ast.memo){this.target.hasCache=true;id=generateId();this.define(`memo${id}`,compileExpr(ast.memo));this.define(`vnode${id}`,`cache[key${this.target.loopLevel}];`);this.addLine(`if (vnode${id}) {`);this.target.indentLevel++;this.addLine(`if (shallowEqual(vnode${id}.memo, memo${id})) {`);this.target.indentLevel++;this.addLine(`${c}[${loopVar}] = vnode${id};`);this.addLine(`nextCache[key${this.target.loopLevel}] = vnode${id};`);this.addLine(`continue;`);this.target.indentLevel--;this.addLine("}");this.target.indentLevel--;this.addLine("}");}
const subCtx=createContext(ctx,{block,index:loopVar});this.compileAST(ast.body,subCtx);if(ast.memo){this.addLine(`nextCache[key${this.target.loopLevel}] = Object.assign(${c}[${loopVar}], {memo: memo${id}});`);}
this.target.indentLevel--;this.target.loopLevel--;this.addLine(`}`);if(!ctx.isLast){this.addLine(`ctx = ctx.__proto__;`);}
this.insertBlock("l",block,ctx);return block.varName;}
compileTKey(ast,ctx){const tKeyExpr=generateId("tKey_");this.define(tKeyExpr,compileExpr(ast.expr));ctx=createContext(ctx,{tKeyExpr,block:ctx.block,index:ctx.index,});return this.compileAST(ast.content,ctx);}
compileMulti(ast,ctx){let{block,forceNewBlock}=ctx;const isNewBlock=!block||forceNewBlock;let codeIdx=this.target.code.length;if(isNewBlock){const n=ast.content.filter((c)=>!c.hasNoRepresentation).length;let result=null;if(n<=1){for(let child of ast.content){const blockName=this.compileAST(child,ctx);result=result||blockName;}
return result;}
block=this.createBlock(block,"multi",ctx);}
let index=0;for(let i=0,l=ast.content.length;i<l;i++){const child=ast.content[i];const forceNewBlock=!child.hasNoRepresentation;const subCtx=createContext(ctx,{block,index,forceNewBlock,isLast:ctx.isLast&&i===l-1,});this.compileAST(child,subCtx);if(forceNewBlock){index++;}}
if(isNewBlock){if(block.hasDynamicChildren&&block.children.length){const code=this.target.code;const children=block.children.slice();let current=children.shift();for(let i=codeIdx;i<code.length;i++){if(code[i].trimStart().startsWith(`const ${current.varName} `)){code[i]=code[i].replace(`const ${current.varName}`,current.varName);current=children.shift();if(!current)
break;}}
this.addLine(`let ${block.children.map((c) => c.varName).join(", ")};`,codeIdx);}
const args=block.children.map((c)=>c.varName).join(", ");this.insertBlock(`multi([${args}])`,block,ctx);}
return block.varName;}
compileTCall(ast,ctx){let{block,forceNewBlock}=ctx;let ctxVar=ctx.ctxVar||"ctx";if(ast.context){ctxVar=generateId("ctx");this.addLine(`let ${ctxVar} = ${compileExpr(ast.context)};`);}
const isDynamic=INTERP_REGEXP.test(ast.name);const subTemplate=isDynamic?interpolate(ast.name):"`"+ast.name+"`";if(block&&!forceNewBlock){this.insertAnchor(block);}
block=this.createBlock(block,"multi",ctx);if(ast.body){this.addLine(`${ctxVar} = Object.create(${ctxVar});`);this.addLine(`${ctxVar}[isBoundary] = 1;`);this.helpers.add("isBoundary");const subCtx=createContext(ctx,{ctxVar});const bl=this.compileMulti({type:3,content:ast.body},subCtx);if(bl){this.helpers.add("zero");this.addLine(`${ctxVar}[zero] = ${bl};`);}}
const key=this.generateComponentKey();if(isDynamic){const templateVar=generateId("template");if(!this.staticDefs.find((d)=>d.id==="call")){this.staticDefs.push({id:"call",expr:`app.callTemplate.bind(app)`});}
this.define(templateVar,subTemplate);this.insertBlock(`call(this, ${templateVar}, ${ctxVar}, node, ${key})`,block,{...ctx,forceNewBlock:!block,});}
else{const id=generateId(`callTemplate_`);this.staticDefs.push({id,expr:`app.getTemplate(${subTemplate})`});this.insertBlock(`${id}.call(this, ${ctxVar}, node, ${key})`,block,{...ctx,forceNewBlock:!block,});}
if(ast.body&&!ctx.isLast){this.addLine(`${ctxVar} = ${ctxVar}.__proto__;`);}
return block.varName;}
compileTCallBlock(ast,ctx){let{block,forceNewBlock}=ctx;if(block){if(!forceNewBlock){this.insertAnchor(block);}}
block=this.createBlock(block,"multi",ctx);this.insertBlock(compileExpr(ast.name),block,{...ctx,forceNewBlock:!block});return block.varName;}
compileTSet(ast,ctx){this.target.shouldProtectScope=true;this.helpers.add("isBoundary").add("withDefault");const expr=ast.value?compileExpr(ast.value||""):"null";if(ast.body){this.helpers.add("LazyValue");const bodyAst={type:3,content:ast.body};const name=this.compileInNewTarget("value",bodyAst,ctx);let key=this.target.currentKey(ctx);let value=`new LazyValue(${name}, ctx, this, node, ${key})`;value=ast.value?(value?`withDefault(${expr}, ${value})`:expr):value;this.addLine(`ctx[\`${ast.name}\`] = ${value};`);}
else{let value;if(ast.defaultValue){const defaultValue=toStringExpression(ctx.translate?this.translate(ast.defaultValue,ctx.translationCtx):ast.defaultValue);if(ast.value){value=`withDefault(${expr}, ${defaultValue})`;}
else{value=defaultValue;}}
else{value=expr;}
this.helpers.add("setContextValue");this.addLine(`setContextValue(${ctx.ctxVar || "ctx"}, "${ast.name}", ${value});`);}
return null;}
generateComponentKey(currentKey="key"){const parts=[generateId("__")];for(let i=0;i<this.target.loopLevel;i++){parts.push(`\${key${i + 1}}`);}
return`${currentKey} + \`${parts.join("__")}\``;}
formatProp(name,value,attrsTranslationCtx,translationCtx){if(name.endsWith(".translate")){const attrTranslationCtx=(attrsTranslationCtx===null||attrsTranslationCtx===void 0?void 0:attrsTranslationCtx[name])||translationCtx;value=toStringExpression(this.translateFn(value,attrTranslationCtx));}
else{value=this.captureExpression(value);}
if(name.includes(".")){let[_name,suffix]=name.split(".");name=_name;switch(suffix){case"bind":value=`(${value}).bind(this)`;break;case"alike":case"translate":break;default:throw new OwlError(`Invalid prop suffix: ${suffix}`);}}
name=/^[a-z_]+$/i.test(name)?name:`'${name}'`;return`${name}: ${value || undefined}`;}
formatPropObject(obj,attrsTranslationCtx,translationCtx){return Object.entries(obj).map(([k,v])=>this.formatProp(k,v,attrsTranslationCtx,translationCtx));}
getPropString(props,dynProps){let propString=`{${props.join(",")}}`;if(dynProps){propString=`Object.assign({}, ${compileExpr(dynProps)}${props.length ? ", " + propString : ""})`;}
return propString;}
compileComponent(ast,ctx){let{block}=ctx;const hasSlotsProp="slots"in(ast.props||{});const props=ast.props?this.formatPropObject(ast.props,ast.propsTranslationCtx,ctx.translationCtx):[];let slotDef="";if(ast.slots){let ctxStr="ctx";if(this.target.loopLevel||!this.hasSafeContext){ctxStr=generateId("ctx");this.helpers.add("capture");this.define(ctxStr,`capture(ctx)`);}
let slotStr=[];for(let slotName in ast.slots){const slotAst=ast.slots[slotName];const params=[];if(slotAst.content){const name=this.compileInNewTarget("slot",slotAst.content,ctx,slotAst.on);params.push(`__render: ${name}.bind(this), __ctx: ${ctxStr}`);}
const scope=ast.slots[slotName].scope;if(scope){params.push(`__scope: "${scope}"`);}
if(ast.slots[slotName].attrs){params.push(...this.formatPropObject(ast.slots[slotName].attrs,ast.slots[slotName].attrsTranslationCtx,ctx.translationCtx));}
const slotInfo=`{${params.join(", ")}}`;slotStr.push(`'${slotName}': ${slotInfo}`);}
slotDef=`{${slotStr.join(", ")}}`;}
if(slotDef&&!(ast.dynamicProps||hasSlotsProp)){this.helpers.add("markRaw");props.push(`slots: markRaw(${slotDef})`);}
let propString=this.getPropString(props,ast.dynamicProps);let propVar;if((slotDef&&(ast.dynamicProps||hasSlotsProp))||this.dev){propVar=generateId("props");this.define(propVar,propString);propString=propVar;}
if(slotDef&&(ast.dynamicProps||hasSlotsProp)){this.helpers.add("markRaw");this.addLine(`${propVar}.slots = markRaw(Object.assign(${slotDef}, ${propVar}.slots))`);}
let expr;if(ast.isDynamic){expr=generateId("Comp");this.define(expr,compileExpr(ast.name));}
else{expr=`\`${ast.name}\``;}
if(this.dev){this.addLine(`helpers.validateProps(${expr}, ${propVar}, this);`);}
if(block&&(ctx.forceNewBlock===false||ctx.tKeyExpr)){this.insertAnchor(block);}
let keyArg=this.generateComponentKey();if(ctx.tKeyExpr){keyArg=`${ctx.tKeyExpr} + ${keyArg}`;}
let id=generateId("comp");const propList=[];for(let p in ast.props||{}){let[name,suffix]=p.split(".");if(!suffix){propList.push(`"${name}"`);}}
this.staticDefs.push({id,expr:`app.createComponent(${ast.isDynamic ? null : expr}, ${!ast.isDynamic}, ${!!ast.slots}, ${!!ast.dynamicProps}, [${propList}])`,});if(ast.isDynamic){keyArg=`(${expr}).name + ${keyArg}`;}
let blockExpr=`${id}(${propString}, ${keyArg}, node, this, ${ast.isDynamic ? expr : null})`;if(ast.isDynamic){blockExpr=`toggler(${expr}, ${blockExpr})`;}
if(ast.on){blockExpr=this.wrapWithEventCatcher(blockExpr,ast.on);}
block=this.createBlock(block,"multi",ctx);this.insertBlock(blockExpr,block,ctx);return block.varName;}
wrapWithEventCatcher(expr,on){this.helpers.add("createCatcher");let name=generateId("catcher");let spec={};let handlers=[];for(let ev in on){let handlerId=generateId("hdlr");let idx=handlers.push(handlerId)-1;spec[ev]=idx;const handler=this.generateHandlerCode(ev,on[ev]);this.define(handlerId,handler);}
this.staticDefs.push({id:name,expr:`createCatcher(${JSON.stringify(spec)})`});return`${name}(${expr}, [${handlers.join(",")}])`;}
compileTSlot(ast,ctx){this.helpers.add("callSlot");let{block}=ctx;let blockString;let slotName;let dynamic=false;let isMultiple=false;if(ast.name.match(INTERP_REGEXP)){dynamic=true;isMultiple=true;slotName=interpolate(ast.name);}
else{slotName="'"+ast.name+"'";isMultiple=isMultiple||this.slotNames.has(ast.name);this.slotNames.add(ast.name);}
const attrs={...ast.attrs};const dynProps=attrs["t-props"];delete attrs["t-props"];let key=this.target.loopLevel?`key${this.target.loopLevel}`:"key";if(isMultiple){key=this.generateComponentKey(key);}
const props=ast.attrs?this.formatPropObject(attrs,ast.attrsTranslationCtx,ctx.translationCtx):[];const scope=this.getPropString(props,dynProps);if(ast.defaultContent){const name=this.compileInNewTarget("defaultContent",ast.defaultContent,ctx);blockString=`callSlot(ctx, node, ${key}, ${slotName}, ${dynamic}, ${scope}, ${name}.bind(this))`;}
else{if(dynamic){let name=generateId("slot");this.define(name,slotName);blockString=`toggler(${name}, callSlot(ctx, node, ${key}, ${name}, ${dynamic}, ${scope}))`;}
else{blockString=`callSlot(ctx, node, ${key}, ${slotName}, ${dynamic}, ${scope})`;}}
if(ast.on){blockString=this.wrapWithEventCatcher(blockString,ast.on);}
if(block){this.insertAnchor(block);}
block=this.createBlock(block,"multi",ctx);this.insertBlock(blockString,block,{...ctx,forceNewBlock:false});return block.varName;}
compileTTranslation(ast,ctx){if(ast.content){return this.compileAST(ast.content,Object.assign({},ctx,{translate:false}));}
return null;}
compileTTranslationContext(ast,ctx){if(ast.content){return this.compileAST(ast.content,Object.assign({},ctx,{translationCtx:ast.translationCtx}));}
return null;}
compileTPortal(ast,ctx){if(!this.staticDefs.find((d)=>d.id==="Portal")){this.staticDefs.push({id:"Portal",expr:`app.Portal`});}
let{block}=ctx;const name=this.compileInNewTarget("slot",ast.content,ctx);let ctxStr="ctx";if(this.target.loopLevel||!this.hasSafeContext){ctxStr=generateId("ctx");this.helpers.add("capture");this.define(ctxStr,`capture(ctx)`);}
let id=generateId("comp");this.staticDefs.push({id,expr:`app.createComponent(null, false, true, false, false)`,});const target=compileExpr(ast.target);const key=this.generateComponentKey();const blockString=`${id}({target: ${target},slots: {'default': {__render: ${name}.bind(this), __ctx: ${ctxStr}}}}, ${key}, node, ctx, Portal)`;if(block){this.insertAnchor(block);}
block=this.createBlock(block,"multi",ctx);this.insertBlock(blockString,block,{...ctx,forceNewBlock:false});return block.varName;}}
const cache=new WeakMap();function parse(xml,customDir){const ctx={inPreTag:false,customDirectives:customDir,};if(typeof xml==="string"){const elem=parseXML(`<t>${xml}</t>`).firstChild;return _parse(elem,ctx);}
let ast=cache.get(xml);if(!ast){ast=_parse(xml.cloneNode(true),ctx);cache.set(xml,ast);}
return ast;}
function _parse(xml,ctx){normalizeXML(xml);return parseNode(xml,ctx)||{type:0,value:""};}
function parseNode(node,ctx){if(!(node instanceof Element)){return parseTextCommentNode(node,ctx);}
return(parseTCustom(node,ctx)||parseTDebugLog(node,ctx)||parseTForEach(node,ctx)||parseTIf(node,ctx)||parseTPortal(node,ctx)||parseTCall(node,ctx)||parseTCallBlock(node)||parseTTranslation(node,ctx)||parseTTranslationContext(node,ctx)||parseTKey(node,ctx)||parseTEscNode(node,ctx)||parseTOutNode(node,ctx)||parseTSlot(node,ctx)||parseComponent(node,ctx)||parseDOMNode(node,ctx)||parseTSetNode(node,ctx)||parseTNode(node,ctx));}
function parseTNode(node,ctx){if(node.tagName!=="t"){return null;}
return parseChildNodes(node,ctx);}
const lineBreakRE=/[\r\n]/;function parseTextCommentNode(node,ctx){if(node.nodeType===Node.TEXT_NODE){let value=node.textContent||"";if(!ctx.inPreTag&&lineBreakRE.test(value)&&!value.trim()){return null;}
return{type:0,value};}
else if(node.nodeType===Node.COMMENT_NODE){return{type:1,value:node.textContent||""};}
return null;}
function parseTCustom(node,ctx){if(!ctx.customDirectives){return null;}
const nodeAttrsNames=node.getAttributeNames();for(let attr of nodeAttrsNames){if(attr==="t-custom"||attr==="t-custom-"){throw new OwlError("Missing custom directive name with t-custom directive");}
if(attr.startsWith("t-custom-")){const directiveName=attr.split(".")[0].slice(9);const customDirective=ctx.customDirectives[directiveName];if(!customDirective){throw new OwlError(`Custom directive "${directiveName}" is not defined`);}
const value=node.getAttribute(attr);const modifiers=attr.split(".").slice(1);node.removeAttribute(attr);try{customDirective(node,value,modifiers);}
catch(error){throw new OwlError(`Custom directive "${directiveName}" throw the following error: ${error}`);}
return parseNode(node,ctx);}}
return null;}
function parseTDebugLog(node,ctx){if(node.hasAttribute("t-debug")){node.removeAttribute("t-debug");const content=parseNode(node,ctx);const ast={type:12,content,};if(content===null||content===void 0?void 0:content.hasNoRepresentation){ast.hasNoRepresentation=true;}
return ast;}
if(node.hasAttribute("t-log")){const expr=node.getAttribute("t-log");node.removeAttribute("t-log");const content=parseNode(node,ctx);const ast={type:13,expr,content,};if(content===null||content===void 0?void 0:content.hasNoRepresentation){ast.hasNoRepresentation=true;}
return ast;}
return null;}
const hasDotAtTheEnd=/\.[\w_]+\s*$/;const hasBracketsAtTheEnd=/\[[^\[]+\]\s*$/;const ROOT_SVG_TAGS=new Set(["svg","g","path"]);function parseDOMNode(node,ctx){const{tagName}=node;const dynamicTag=node.getAttribute("t-tag");node.removeAttribute("t-tag");if(tagName==="t"&&!dynamicTag){return null;}
if(tagName.startsWith("block-")){throw new OwlError(`Invalid tag name: '${tagName}'`);}
ctx=Object.assign({},ctx);if(tagName==="pre"){ctx.inPreTag=true;}
let ns=!ctx.nameSpace&&ROOT_SVG_TAGS.has(tagName)?"http://www.w3.org/2000/svg":null;const ref=node.getAttribute("t-ref");node.removeAttribute("t-ref");const nodeAttrsNames=node.getAttributeNames();let attrs=null;let attrsTranslationCtx=null;let on=null;let model=null;for(let attr of nodeAttrsNames){const value=node.getAttribute(attr);if(attr==="t-on"||attr==="t-on-"){throw new OwlError("Missing event name with t-on directive");}
if(attr.startsWith("t-on-")){on=on||{};on[attr.slice(5)]=value;}
else if(attr.startsWith("t-model")){if(!["input","select","textarea"].includes(tagName)){throw new OwlError("The t-model directive only works with <input>, <textarea> and <select>");}
let baseExpr,expr;if(hasDotAtTheEnd.test(value)){const index=value.lastIndexOf(".");baseExpr=value.slice(0,index);expr=`'${value.slice(index + 1)}'`;}
else if(hasBracketsAtTheEnd.test(value)){const index=value.lastIndexOf("[");baseExpr=value.slice(0,index);expr=value.slice(index+1,-1);}
else{throw new OwlError(`Invalid t-model expression: "${value}" (it should be assignable)`);}
const typeAttr=node.getAttribute("type");const isInput=tagName==="input";const isSelect=tagName==="select";const isCheckboxInput=isInput&&typeAttr==="checkbox";const isRadioInput=isInput&&typeAttr==="radio";const hasTrimMod=attr.includes(".trim");const hasLazyMod=hasTrimMod||attr.includes(".lazy");const hasNumberMod=attr.includes(".number");const eventType=isRadioInput?"click":isSelect||hasLazyMod?"change":"input";model={baseExpr,expr,targetAttr:isCheckboxInput?"checked":"value",specialInitTargetAttr:isRadioInput?"checked":null,eventType,hasDynamicChildren:false,shouldTrim:hasTrimMod,shouldNumberize:hasNumberMod,};if(isSelect){ctx=Object.assign({},ctx);ctx.tModelInfo=model;}}
else if(attr.startsWith("block-")){throw new OwlError(`Invalid attribute: '${attr}'`);}
else if(attr==="xmlns"){ns=value;}
else if(attr.startsWith("t-translation-context-")){const attrName=attr.slice(22);attrsTranslationCtx=attrsTranslationCtx||{};attrsTranslationCtx[attrName]=value;}
else if(attr!=="t-name"){if(attr.startsWith("t-")&&!attr.startsWith("t-att")){throw new OwlError(`Unknown QWeb directive: '${attr}'`);}
const tModel=ctx.tModelInfo;if(tModel&&["t-att-value","t-attf-value"].includes(attr)){tModel.hasDynamicChildren=true;}
attrs=attrs||{};attrs[attr]=value;}}
if(ns){ctx.nameSpace=ns;}
const children=parseChildren(node,ctx);return{type:2,tag:tagName,dynamicTag,attrs,attrsTranslationCtx,on,ref,content:children,model,ns,};}
function parseTEscNode(node,ctx){if(!node.hasAttribute("t-esc")){return null;}
const escValue=node.getAttribute("t-esc");node.removeAttribute("t-esc");const tesc={type:4,expr:escValue,defaultValue:node.textContent||"",};let ref=node.getAttribute("t-ref");node.removeAttribute("t-ref");const ast=parseNode(node,ctx);if(!ast){return tesc;}
if(ast.type===2){return{...ast,ref,content:[tesc],};}
return tesc;}
function parseTOutNode(node,ctx){if(!node.hasAttribute("t-out")&&!node.hasAttribute("t-raw")){return null;}
if(node.hasAttribute("t-raw")){console.warn(`t-raw has been deprecated in favor of t-out. If the value to render is not wrapped by the "markup" function, it will be escaped`);}
const expr=(node.getAttribute("t-out")||node.getAttribute("t-raw"));node.removeAttribute("t-out");node.removeAttribute("t-raw");const tOut={type:8,expr,body:null};const ref=node.getAttribute("t-ref");node.removeAttribute("t-ref");const ast=parseNode(node,ctx);if(!ast){return tOut;}
if(ast.type===2){tOut.body=ast.content.length?ast.content:null;return{...ast,ref,content:[tOut],};}
return tOut;}
function parseTForEach(node,ctx){if(!node.hasAttribute("t-foreach")){return null;}
const html=node.outerHTML;const collection=node.getAttribute("t-foreach");node.removeAttribute("t-foreach");const elem=node.getAttribute("t-as")||"";node.removeAttribute("t-as");const key=node.getAttribute("t-key");if(!key){throw new OwlError(`"Directive t-foreach should always be used with a t-key!" (expression: t-foreach="${collection}" t-as="${elem}")`);}
node.removeAttribute("t-key");const memo=node.getAttribute("t-memo")||"";node.removeAttribute("t-memo");const body=parseNode(node,ctx);if(!body){return null;}
const hasNoTCall=!html.includes("t-call");const hasNoFirst=hasNoTCall&&!html.includes(`${elem}_first`);const hasNoLast=hasNoTCall&&!html.includes(`${elem}_last`);const hasNoIndex=hasNoTCall&&!html.includes(`${elem}_index`);const hasNoValue=hasNoTCall&&!html.includes(`${elem}_value`);return{type:9,collection,elem,body,memo,key,hasNoFirst,hasNoLast,hasNoIndex,hasNoValue,};}
function parseTKey(node,ctx){if(!node.hasAttribute("t-key")){return null;}
const key=node.getAttribute("t-key");node.removeAttribute("t-key");const content=parseNode(node,ctx);if(!content){return null;}
const ast={type:10,expr:key,content,};if(content.hasNoRepresentation){ast.hasNoRepresentation=true;}
return ast;}
function parseTCall(node,ctx){if(!node.hasAttribute("t-call")){return null;}
const subTemplate=node.getAttribute("t-call");const context=node.getAttribute("t-call-context");node.removeAttribute("t-call");node.removeAttribute("t-call-context");if(node.tagName!=="t"){const ast=parseNode(node,ctx);const tcall={type:7,name:subTemplate,body:null,context};if(ast&&ast.type===2){ast.content=[tcall];return ast;}
if(ast&&ast.type===11){return{...ast,slots:{default:{content:tcall,scope:null,on:null,attrs:null,attrsTranslationCtx:null,},},};}}
const body=parseChildren(node,ctx);return{type:7,name:subTemplate,body:body.length?body:null,context,};}
function parseTCallBlock(node,ctx){if(!node.hasAttribute("t-call-block")){return null;}
const name=node.getAttribute("t-call-block");return{type:15,name,};}
function parseTIf(node,ctx){if(!node.hasAttribute("t-if")){return null;}
const condition=node.getAttribute("t-if");node.removeAttribute("t-if");const content=parseNode(node,ctx)||{type:0,value:""};let nextElement=node.nextElementSibling;const tElifs=[];while(nextElement&&nextElement.hasAttribute("t-elif")){const condition=nextElement.getAttribute("t-elif");nextElement.removeAttribute("t-elif");const tElif=parseNode(nextElement,ctx);const next=nextElement.nextElementSibling;nextElement.remove();nextElement=next;if(tElif){tElifs.push({condition,content:tElif});}}
let tElse=null;if(nextElement&&nextElement.hasAttribute("t-else")){nextElement.removeAttribute("t-else");tElse=parseNode(nextElement,ctx);nextElement.remove();}
return{type:5,condition,content,tElif:tElifs.length?tElifs:null,tElse,};}
function parseTSetNode(node,ctx){if(!node.hasAttribute("t-set")){return null;}
const name=node.getAttribute("t-set");const value=node.getAttribute("t-value")||null;const defaultValue=node.innerHTML===node.textContent?node.textContent||null:null;let body=null;if(node.textContent!==node.innerHTML){body=parseChildren(node,ctx);}
return{type:6,name,value,defaultValue,body,hasNoRepresentation:true};}
const directiveErrorMap=new Map([["t-ref","t-ref is no longer supported on components. Consider exposing only the public part of the component's API through a callback prop.",],["t-att","t-att makes no sense on component: props are already treated as expressions"],["t-attf","t-attf is not supported on components: use template strings for string interpolation in props",],]);function parseComponent(node,ctx){let name=node.tagName;const firstLetter=name[0];let isDynamic=node.hasAttribute("t-component");if(isDynamic&&name!=="t"){throw new OwlError(`Directive 't-component' can only be used on <t> nodes (used on a <${name}>)`);}
if(!(firstLetter===firstLetter.toUpperCase()||isDynamic)){return null;}
if(isDynamic){name=node.getAttribute("t-component");node.removeAttribute("t-component");}
const dynamicProps=node.getAttribute("t-props");node.removeAttribute("t-props");const defaultSlotScope=node.getAttribute("t-slot-scope");node.removeAttribute("t-slot-scope");let on=null;let props=null;let propsTranslationCtx=null;for(let name of node.getAttributeNames()){const value=node.getAttribute(name);if(name.startsWith("t-translation-context-")){const attrName=name.slice(22);propsTranslationCtx=propsTranslationCtx||{};propsTranslationCtx[attrName]=value;}
else if(name.startsWith("t-")){if(name.startsWith("t-on-")){on=on||{};on[name.slice(5)]=value;}
else{const message=directiveErrorMap.get(name.split("-").slice(0,2).join("-"));throw new OwlError(message||`unsupported directive on Component: ${name}`);}}
else{props=props||{};props[name]=value;}}
let slots=null;if(node.hasChildNodes()){const clone=node.cloneNode(true);const slotNodes=Array.from(clone.querySelectorAll("[t-set-slot]"));for(let slotNode of slotNodes){if(slotNode.tagName!=="t"){throw new OwlError(`Directive 't-set-slot' can only be used on <t> nodes (used on a <${slotNode.tagName}>)`);}
const name=slotNode.getAttribute("t-set-slot");let el=slotNode.parentElement;let isInSubComponent=false;while(el&&el!==clone){if(el.hasAttribute("t-component")||el.tagName[0]===el.tagName[0].toUpperCase()){isInSubComponent=true;break;}
el=el.parentElement;}
if(isInSubComponent||!el){continue;}
slotNode.removeAttribute("t-set-slot");slotNode.remove();const slotAst=parseNode(slotNode,ctx);let on=null;let attrs=null;let attrsTranslationCtx=null;let scope=null;for(let attributeName of slotNode.getAttributeNames()){const value=slotNode.getAttribute(attributeName);if(attributeName==="t-slot-scope"){scope=value;continue;}
else if(attributeName.startsWith("t-translation-context-")){const attrName=attributeName.slice(22);attrsTranslationCtx=attrsTranslationCtx||{};attrsTranslationCtx[attrName]=value;}
else if(attributeName.startsWith("t-on-")){on=on||{};on[attributeName.slice(5)]=value;}
else{attrs=attrs||{};attrs[attributeName]=value;}}
slots=slots||{};slots[name]={content:slotAst,on,attrs,attrsTranslationCtx,scope};}
const defaultContent=parseChildNodes(clone,ctx);slots=slots||{};if(defaultContent&&!slots.default){slots.default={content:defaultContent,on,attrs:null,attrsTranslationCtx:null,scope:defaultSlotScope,};}}
return{type:11,name,isDynamic,dynamicProps,props,propsTranslationCtx,slots,on,};}
function parseTSlot(node,ctx){if(!node.hasAttribute("t-slot")){return null;}
const name=node.getAttribute("t-slot");node.removeAttribute("t-slot");let attrs=null;let attrsTranslationCtx=null;let on=null;for(let attributeName of node.getAttributeNames()){const value=node.getAttribute(attributeName);if(attributeName.startsWith("t-on-")){on=on||{};on[attributeName.slice(5)]=value;}
else if(attributeName.startsWith("t-translation-context-")){const attrName=attributeName.slice(22);attrsTranslationCtx=attrsTranslationCtx||{};attrsTranslationCtx[attrName]=value;}
else{attrs=attrs||{};attrs[attributeName]=value;}}
return{type:14,name,attrs,attrsTranslationCtx,on,defaultContent:parseChildNodes(node,ctx),};}
function wrapInTTranslationAST(r){const ast={type:16,content:r};if(r===null||r===void 0?void 0:r.hasNoRepresentation){ast.hasNoRepresentation=true;}
return ast;}
function parseTTranslation(node,ctx){if(node.getAttribute("t-translation")!=="off"){return null;}
node.removeAttribute("t-translation");const result=parseNode(node,ctx);if((result===null||result===void 0?void 0:result.type)===3){const children=result.content.map(wrapInTTranslationAST);return makeASTMulti(children);}
return wrapInTTranslationAST(result);}
function wrapInTTranslationContextAST(r,translationCtx){const ast={type:17,content:r,translationCtx,};if(r===null||r===void 0?void 0:r.hasNoRepresentation){ast.hasNoRepresentation=true;}
return ast;}
function parseTTranslationContext(node,ctx){const translationCtx=node.getAttribute("t-translation-context");if(!translationCtx){return null;}
node.removeAttribute("t-translation-context");const result=parseNode(node,ctx);if((result===null||result===void 0?void 0:result.type)===3){const children=result.content.map((c)=>wrapInTTranslationContextAST(c,translationCtx));return makeASTMulti(children);}
return wrapInTTranslationContextAST(result,translationCtx);}
function parseTPortal(node,ctx){if(!node.hasAttribute("t-portal")){return null;}
const target=node.getAttribute("t-portal");node.removeAttribute("t-portal");const content=parseNode(node,ctx);if(!content){return{type:0,value:"",};}
return{type:18,target,content,};}
function parseChildren(node,ctx){const children=[];for(let child of node.childNodes){const childAst=parseNode(child,ctx);if(childAst){if(childAst.type===3){children.push(...childAst.content);}
else{children.push(childAst);}}}
return children;}
function makeASTMulti(children){const ast={type:3,content:children};if(children.every((c)=>c.hasNoRepresentation)){ast.hasNoRepresentation=true;}
return ast;}
function parseChildNodes(node,ctx){const children=parseChildren(node,ctx);switch(children.length){case 0:return null;case 1:return children[0];default:return makeASTMulti(children);}}
function normalizeTIf(el){let tbranch=el.querySelectorAll("[t-elif], [t-else]");for(let i=0,ilen=tbranch.length;i<ilen;i++){let node=tbranch[i];let prevElem=node.previousElementSibling;let pattr=(name)=>prevElem.getAttribute(name);let nattr=(name)=>+!!node.getAttribute(name);if(prevElem&&(pattr("t-if")||pattr("t-elif"))){if(pattr("t-foreach")){throw new OwlError("t-if cannot stay at the same level as t-foreach when using t-elif or t-else");}
if(["t-if","t-elif","t-else"].map(nattr).reduce(function(a,b){return a+b;})>1){throw new OwlError("Only one conditional branching directive is allowed per node");}
let textNode;while((textNode=node.previousSibling)!==prevElem){if(textNode.nodeValue.trim().length&&textNode.nodeType!==8){throw new OwlError("text is not allowed between branching directives");}
textNode.remove();}}
else{throw new OwlError("t-elif and t-else directives must be preceded by a t-if or t-elif directive");}}}
function normalizeTEscTOut(el){for(const d of["t-esc","t-out"]){const elements=[...el.querySelectorAll(`[${d}]`)].filter((el)=>el.tagName[0]===el.tagName[0].toUpperCase()||el.hasAttribute("t-component"));for(const el of elements){if(el.childNodes.length){throw new OwlError(`Cannot have ${d} on a component that already has content`);}
const value=el.getAttribute(d);el.removeAttribute(d);const t=el.ownerDocument.createElement("t");if(value!=null){t.setAttribute(d,value);}
el.appendChild(t);}}}
function normalizeXML(el){normalizeTIf(el);normalizeTEscTOut(el);}
function compile(template,options={hasGlobalValues:false,}){const ast=parse(template,options.customDirectives);const hasSafeContext=template instanceof Node?!(template instanceof Element)||template.querySelector("[t-set], [t-call]")===null:!template.includes("t-set")&&!template.includes("t-call");const codeGenerator=new CodeGenerator(ast,{...options,hasSafeContext});const code=codeGenerator.generateCode();try{return new Function("app, bdom, helpers",code);}
catch(originalError){const{name}=options;const nameStr=name?`template "${name}"`:"anonymous template";const err=new OwlError(`Failed to compile ${nameStr}: ${originalError.message}\n\ngenerated code:\nfunction(app, bdom, helpers) {\n${code}\n}`);err.cause=originalError;throw err;}}
const version="2.8.2";class Scheduler{constructor(){this.tasks=new Set();this.frame=0;this.delayedRenders=[];this.cancelledNodes=new Set();this.processing=false;this.requestAnimationFrame=Scheduler.requestAnimationFrame;}
addFiber(fiber){this.tasks.add(fiber.root);}
scheduleDestroy(node){this.cancelledNodes.add(node);if(this.frame===0){this.frame=this.requestAnimationFrame(()=>this.processTasks());}}
flush(){if(this.delayedRenders.length){let renders=this.delayedRenders;this.delayedRenders=[];for(let f of renders){if(f.root&&f.node.status!==3&&f.node.fiber===f){f.render();}}}
if(this.frame===0){this.frame=this.requestAnimationFrame(()=>this.processTasks());}}
processTasks(){if(this.processing){return;}
this.processing=true;this.frame=0;for(let node of this.cancelledNodes){node._destroy();}
this.cancelledNodes.clear();for(let task of this.tasks){this.processFiber(task);}
for(let task of this.tasks){if(task.node.status===3){this.tasks.delete(task);}}
this.processing=false;}
processFiber(fiber){if(fiber.root!==fiber){this.tasks.delete(fiber);return;}
const hasError=fibersInError.has(fiber);if(hasError&&fiber.counter!==0){this.tasks.delete(fiber);return;}
if(fiber.node.status===3){this.tasks.delete(fiber);return;}
if(fiber.counter===0){if(!hasError){fiber.complete();}
if(fiber.appliedToDom){this.tasks.delete(fiber);}}}}
Scheduler.requestAnimationFrame=window.requestAnimationFrame.bind(window);let hasBeenLogged=false;const apps=new Set();window.__OWL_DEVTOOLS__||(window.__OWL_DEVTOOLS__={apps,Fiber,RootFiber,toRaw,reactive});class App extends TemplateSet{constructor(Root,config={}){super(config);this.scheduler=new Scheduler();this.subRoots=new Set();this.root=null;this.name=config.name||"";this.Root=Root;apps.add(this);if(config.test){this.dev=true;}
this.warnIfNoStaticProps=config.warnIfNoStaticProps||false;if(this.dev&&!config.test&&!hasBeenLogged){console.info(`Owl is running in 'dev' mode.`);hasBeenLogged=true;}
const env=config.env||{};const descrs=Object.getOwnPropertyDescriptors(env);this.env=Object.freeze(Object.create(Object.getPrototypeOf(env),descrs));this.props=config.props||{};}
mount(target,options){const root=this.createRoot(this.Root,{props:this.props});this.root=root.node;this.subRoots.delete(root.node);return root.mount(target,options);}
createRoot(Root,config={}){const props=config.props||{};const env=this.env;if(config.env){this.env=config.env;}
const restore=saveCurrent();const node=this.makeNode(Root,props);restore();if(config.env){this.env=env;}
this.subRoots.add(node);return{node,mount:(target,options)=>{App.validateTarget(target);if(this.dev){validateProps(Root,props,{__owl__:{app:this}});}
const prom=this.mountNode(node,target,options);return prom;},destroy:()=>{this.subRoots.delete(node);node.destroy();this.scheduler.processTasks();},};}
makeNode(Component,props){return new ComponentNode(Component,props,this,null,null);}
mountNode(node,target,options){const promise=new Promise((resolve,reject)=>{let isResolved=false;node.mounted.push(()=>{resolve(node.component);isResolved=true;});let handlers=nodeErrorHandlers.get(node);if(!handlers){handlers=[];nodeErrorHandlers.set(node,handlers);}
handlers.unshift((e)=>{if(!isResolved){reject(e);}
throw e;});});node.mountComponent(target,options);return promise;}
destroy(){if(this.root){for(let subroot of this.subRoots){subroot.destroy();}
this.root.destroy();this.scheduler.processTasks();}
apps.delete(this);}
createComponent(name,isStatic,hasSlotsProp,hasDynamicPropList,propList){const isDynamic=!isStatic;let arePropsDifferent;const hasNoProp=propList.length===0;if(hasSlotsProp){arePropsDifferent=(_1,_2)=>true;}
else if(hasDynamicPropList){arePropsDifferent=function(props1,props2){for(let k in props1){if(props1[k]!==props2[k]){return true;}}
return Object.keys(props1).length!==Object.keys(props2).length;};}
else if(hasNoProp){arePropsDifferent=(_1,_2)=>false;}
else{arePropsDifferent=function(props1,props2){for(let p of propList){if(props1[p]!==props2[p]){return true;}}
return false;};}
const updateAndRender=ComponentNode.prototype.updateAndRender;const initiateRender=ComponentNode.prototype.initiateRender;return(props,key,ctx,parent,C)=>{let children=ctx.children;let node=children[key];if(isDynamic&&node&&node.component.constructor!==C){node=undefined;}
const parentFiber=ctx.fiber;if(node){if(arePropsDifferent(node.props,props)||parentFiber.deep||node.forceNextRender){node.forceNextRender=false;updateAndRender.call(node,props,parentFiber);}}
else{if(isStatic){const components=parent.constructor.components;if(!components){throw new OwlError(`Cannot find the definition of component "${name}", missing static components key in parent`);}
C=components[name];if(!C){throw new OwlError(`Cannot find the definition of component "${name}"`);}
else if(!(C.prototype instanceof Component)){throw new OwlError(`"${name}" is not a Component. It must inherit from the Component class`);}}
node=new ComponentNode(C,props,this,ctx,key);children[key]=node;initiateRender.call(node,new Fiber(node,parentFiber));}
parentFiber.childrenMap[key]=node;return node;};}
handleError(...args){return handleError(...args);}}
App.validateTarget=validateTarget;App.apps=apps;App.version=version;async function mount(C,target,config={}){return new App(C,config).mount(target,config);}
const mainEventHandler=(data,ev,currentTarget)=>{const{data:_data,modifiers}=filterOutModifiersFromData(data);data=_data;let stopped=false;if(modifiers.length){let selfMode=false;const isSelf=ev.target===currentTarget;for(const mod of modifiers){switch(mod){case"self":selfMode=true;if(isSelf){continue;}
else{return stopped;}
case"prevent":if((selfMode&&isSelf)||!selfMode)
ev.preventDefault();continue;case"stop":if((selfMode&&isSelf)||!selfMode)
ev.stopPropagation();stopped=true;continue;}}}
if(Object.hasOwnProperty.call(data,0)){const handler=data[0];if(typeof handler!=="function"){throw new OwlError(`Invalid handler (expected a function, received: '${handler}')`);}
let node=data[1]?data[1].__owl__:null;if(node?node.status===1:true){handler.call(node?node.component:null,ev);}}
return stopped;};function status(component){switch(component.__owl__.status){case 0:return"new";case 2:return"cancelled";case 1:return"mounted";case 3:return"destroyed";}}
function useRef(name){const node=getCurrent();const refs=node.refs;return{get el(){const el=refs[name];return inOwnerDocument(el)?el:null;},};}
function useEnv(){return getCurrent().component.env;}
function extendEnv(currentEnv,extension){const env=Object.create(currentEnv);const descrs=Object.getOwnPropertyDescriptors(extension);return Object.freeze(Object.defineProperties(env,descrs));}
function useSubEnv(envExtension){const node=getCurrent();node.component.env=extendEnv(node.component.env,envExtension);useChildSubEnv(envExtension);}
function useChildSubEnv(envExtension){const node=getCurrent();node.childEnv=extendEnv(node.childEnv,envExtension);}
function useEffect(effect,computeDependencies=()=>[NaN]){let cleanup;let dependencies;onMounted(()=>{dependencies=computeDependencies();cleanup=effect(...dependencies);});onPatched(()=>{const newDeps=computeDependencies();const shouldReapply=newDeps.some((val,i)=>val!==dependencies[i]);if(shouldReapply){dependencies=newDeps;if(cleanup){cleanup();}
cleanup=effect(...dependencies);}});onWillUnmount(()=>cleanup&&cleanup());}
function useExternalListener(target,eventName,handler,eventParams){const node=getCurrent();const boundHandler=handler.bind(node.component);onMounted(()=>target.addEventListener(eventName,boundHandler,eventParams));onWillUnmount(()=>target.removeEventListener(eventName,boundHandler,eventParams));}
config.shouldNormalizeDom=false;config.mainEventHandler=mainEventHandler;const blockDom={config,mount:mount$1,patch,remove,list,multi,text,toggler,createBlock,html,comment,};const __info__={version:App.version,};TemplateSet.prototype._compileTemplate=function _compileTemplate(name,template){return compile(template,{name,dev:this.dev,translateFn:this.translateFn,translatableAttributes:this.translatableAttributes,customDirectives:this.customDirectives,hasGlobalValues:this.hasGlobalValues,});};exports.App=App;exports.Component=Component;exports.EventBus=EventBus;exports.OwlError=OwlError;exports.__info__=__info__;exports.batched=batched;exports.blockDom=blockDom;exports.htmlEscape=htmlEscape;exports.loadFile=loadFile;exports.markRaw=markRaw;exports.markup=markup;exports.mount=mount;exports.onError=onError;exports.onMounted=onMounted;exports.onPatched=onPatched;exports.onRendered=onRendered;exports.onWillDestroy=onWillDestroy;exports.onWillPatch=onWillPatch;exports.onWillRender=onWillRender;exports.onWillStart=onWillStart;exports.onWillUnmount=onWillUnmount;exports.onWillUpdateProps=onWillUpdateProps;exports.reactive=reactive;exports.status=status;exports.toRaw=toRaw;exports.useChildSubEnv=useChildSubEnv;exports.useComponent=useComponent;exports.useEffect=useEffect;exports.useEnv=useEnv;exports.useExternalListener=useExternalListener;exports.useRef=useRef;exports.useState=useState;exports.useSubEnv=useSubEnv;exports.validate=validate;exports.validateType=validateType;exports.whenReady=whenReady;exports.xml=xml;Object.defineProperty(exports,'__esModule',{value:true});__info__.date='2026-01-30T07:49:47.618Z';__info__.hash='52abf8d';__info__.url='https://github.com/odoo/owl';})(this.owl=this.owl||{});;
/* /web/static/lib/owl/odoo_module.js */
odoo.define("@odoo/owl",[],function(){"use strict";return owl;});;
/* /web/static/lib/jquery/jquery.js */
(function(global,factory){"use strict";if(typeof module==="object"&&typeof module.exports==="object"){module.exports=global.document?factory(global,true):function(w){if(!w.document){throw new Error("jQuery requires a window with a document");}
return factory(w);};}else{factory(global);}})(typeof window!=="undefined"?window:this,function(window,noGlobal){"use strict";var arr=[];var getProto=Object.getPrototypeOf;var slice=arr.slice;var flat=arr.flat?function(array){return arr.flat.call(array);}:function(array){return arr.concat.apply([],array);};var push=arr.push;var indexOf=arr.indexOf;var class2type={};var toString=class2type.toString;var hasOwn=class2type.hasOwnProperty;var fnToString=hasOwn.toString;var ObjectFunctionString=fnToString.call(Object);var support={};var isFunction=function isFunction(obj){return typeof obj==="function"&&typeof obj.nodeType!=="number"&&typeof obj.item!=="function";};var isWindow=function isWindow(obj){return obj!=null&&obj===obj.window;};var document=window.document;var preservedScriptAttributes={type:true,src:true,nonce:true,noModule:true};function DOMEval(code,node,doc){doc=doc||document;var i,val,script=doc.createElement("script");script.text=code;if(node){for(i in preservedScriptAttributes){val=node[i]||node.getAttribute&&node.getAttribute(i);if(val){script.setAttribute(i,val);}}}
doc.head.appendChild(script).parentNode.removeChild(script);}
function toType(obj){if(obj==null){return obj+"";}
return typeof obj==="object"||typeof obj==="function"?class2type[toString.call(obj)]||"object":typeof obj;}
var
version="3.6.3",jQuery=function(selector,context){return new jQuery.fn.init(selector,context);};jQuery.fn=jQuery.prototype={jquery:version,constructor:jQuery,length:0,toArray:function(){return slice.call(this);},get:function(num){if(num==null){return slice.call(this);}
return num<0?this[num+this.length]:this[num];},pushStack:function(elems){var ret=jQuery.merge(this.constructor(),elems);ret.prevObject=this;return ret;},each:function(callback){return jQuery.each(this,callback);},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},slice:function(){return this.pushStack(slice.apply(this,arguments));},first:function(){return this.eq(0);},last:function(){return this.eq(-1);},even:function(){return this.pushStack(jQuery.grep(this,function(_elem,i){return(i+1)%2;}));},odd:function(){return this.pushStack(jQuery.grep(this,function(_elem,i){return i%2;}));},eq:function(i){var len=this.length,j=+i+(i<0?len:0);return this.pushStack(j>=0&&j<len?[this[j]]:[]);},end:function(){return this.prevObject||this.constructor();},push:push,sort:arr.sort,splice:arr.splice};jQuery.extend=jQuery.fn.extend=function(){var options,name,src,copy,copyIsArray,clone,target=arguments[0]||{},i=1,length=arguments.length,deep=false;if(typeof target==="boolean"){deep=target;target=arguments[i]||{};i++;}
if(typeof target!=="object"&&!isFunction(target)){target={};}
if(i===length){target=this;i--;}
for(;i<length;i++){if((options=arguments[i])!=null){for(name in options){copy=options[name];if(name==="__proto__"||target===copy){continue;}
if(deep&&copy&&(jQuery.isPlainObject(copy)||(copyIsArray=Array.isArray(copy)))){src=target[name];if(copyIsArray&&!Array.isArray(src)){clone=[];}else if(!copyIsArray&&!jQuery.isPlainObject(src)){clone={};}else{clone=src;}
copyIsArray=false;target[name]=jQuery.extend(deep,clone,copy);}else if(copy!==undefined){target[name]=copy;}}}}
return target;};jQuery.extend({expando:"jQuery"+(version+Math.random()).replace(/\D/g,""),isReady:true,error:function(msg){throw new Error(msg);},noop:function(){},isPlainObject:function(obj){var proto,Ctor;if(!obj||toString.call(obj)!=="[object Object]"){return false;}
proto=getProto(obj);if(!proto){return true;}
Ctor=hasOwn.call(proto,"constructor")&&proto.constructor;return typeof Ctor==="function"&&fnToString.call(Ctor)===ObjectFunctionString;},isEmptyObject:function(obj){var name;for(name in obj){return false;}
return true;},globalEval:function(code,options,doc){DOMEval(code,{nonce:options&&options.nonce},doc);},each:function(obj,callback){var length,i=0;if(isArrayLike(obj)){length=obj.length;for(;i<length;i++){if(callback.call(obj[i],i,obj[i])===false){break;}}}else{for(i in obj){if(callback.call(obj[i],i,obj[i])===false){break;}}}
return obj;},makeArray:function(arr,results){var ret=results||[];if(arr!=null){if(isArrayLike(Object(arr))){jQuery.merge(ret,typeof arr==="string"?[arr]:arr);}else{push.call(ret,arr);}}
return ret;},inArray:function(elem,arr,i){return arr==null?-1:indexOf.call(arr,elem,i);},merge:function(first,second){var len=+second.length,j=0,i=first.length;for(;j<len;j++){first[i++]=second[j];}
first.length=i;return first;},grep:function(elems,callback,invert){var callbackInverse,matches=[],i=0,length=elems.length,callbackExpect=!invert;for(;i<length;i++){callbackInverse=!callback(elems[i],i);if(callbackInverse!==callbackExpect){matches.push(elems[i]);}}
return matches;},map:function(elems,callback,arg){var length,value,i=0,ret=[];if(isArrayLike(elems)){length=elems.length;for(;i<length;i++){value=callback(elems[i],i,arg);if(value!=null){ret.push(value);}}}else{for(i in elems){value=callback(elems[i],i,arg);if(value!=null){ret.push(value);}}}
return flat(ret);},guid:1,support:support});if(typeof Symbol==="function"){jQuery.fn[Symbol.iterator]=arr[Symbol.iterator];}
jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(_i,name){class2type["[object "+name+"]"]=name.toLowerCase();});function isArrayLike(obj){var length=!!obj&&"length"in obj&&obj.length,type=toType(obj);if(isFunction(obj)||isWindow(obj)){return false;}
return type==="array"||length===0||typeof length==="number"&&length>0&&(length-1)in obj;}
var Sizzle=(function(window){var i,support,Expr,getText,isXML,tokenize,compile,select,outermostContext,sortInput,hasDuplicate,setDocument,document,docElem,documentIsHTML,rbuggyQSA,rbuggyMatches,matches,contains,expando="sizzle"+1*new Date(),preferredDoc=window.document,dirruns=0,done=0,classCache=createCache(),tokenCache=createCache(),compilerCache=createCache(),nonnativeSelectorCache=createCache(),sortOrder=function(a,b){if(a===b){hasDuplicate=true;}
return 0;},hasOwn=({}).hasOwnProperty,arr=[],pop=arr.pop,pushNative=arr.push,push=arr.push,slice=arr.slice,indexOf=function(list,elem){var i=0,len=list.length;for(;i<len;i++){if(list[i]===elem){return i;}}
return-1;},booleans="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|"+"ismap|loop|multiple|open|readonly|required|scoped",whitespace="[\\x20\\t\\r\\n\\f]",identifier="(?:\\\\[\\da-fA-F]{1,6}"+whitespace+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",attributes="\\["+whitespace+"*("+identifier+")(?:"+whitespace+"*([*^$|!~]?=)"+whitespace+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+identifier+"))|)"+
whitespace+"*\\]",pseudos=":("+identifier+")(?:\\(("+"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|"+"((?:\\\\.|[^\\\\()[\\]]|"+attributes+")*)|"+".*"+")\\)|)",rwhitespace=new RegExp(whitespace+"+","g"),rtrim=new RegExp("^"+whitespace+"+|((?:^|[^\\\\])(?:\\\\.)*)"+
whitespace+"+$","g"),rcomma=new RegExp("^"+whitespace+"*,"+whitespace+"*"),rcombinators=new RegExp("^"+whitespace+"*([>+~]|"+whitespace+")"+whitespace+"*"),rdescend=new RegExp(whitespace+"|>"),rpseudo=new RegExp(pseudos),ridentifier=new RegExp("^"+identifier+"$"),matchExpr={"ID":new RegExp("^#("+identifier+")"),"CLASS":new RegExp("^\\.("+identifier+")"),"TAG":new RegExp("^("+identifier+"|[*])"),"ATTR":new RegExp("^"+attributes),"PSEUDO":new RegExp("^"+pseudos),"CHILD":new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+
whitespace+"*(even|odd|(([+-]|)(\\d*)n|)"+whitespace+"*(?:([+-]|)"+
whitespace+"*(\\d+)|))"+whitespace+"*\\)|)","i"),"bool":new RegExp("^(?:"+booleans+")$","i"),"needsContext":new RegExp("^"+whitespace+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+whitespace+"*((?:-\\d)?\\d*)"+whitespace+"*\\)|)(?=[^-]|$)","i")},rhtml=/HTML$/i,rinputs=/^(?:input|select|textarea|button)$/i,rheader=/^h\d$/i,rnative=/^[^{]+\{\s*\[native \w/,rquickExpr=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,rsibling=/[+~]/,runescape=new RegExp("\\\\[\\da-fA-F]{1,6}"+whitespace+"?|\\\\([^\\r\\n\\f])","g"),funescape=function(escape,nonHex){var high="0x"+escape.slice(1)-0x10000;return nonHex?nonHex:high<0?String.fromCharCode(high+0x10000):String.fromCharCode(high>>10|0xD800,high&0x3FF|0xDC00);},rcssescape=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,fcssescape=function(ch,asCodePoint){if(asCodePoint){if(ch==="\0"){return"\uFFFD";}
return ch.slice(0,-1)+"\\"+
ch.charCodeAt(ch.length-1).toString(16)+" ";}
return"\\"+ch;},unloadHandler=function(){setDocument();},inDisabledFieldset=addCombinator(function(elem){return elem.disabled===true&&elem.nodeName.toLowerCase()==="fieldset";},{dir:"parentNode",next:"legend"});try{push.apply((arr=slice.call(preferredDoc.childNodes)),preferredDoc.childNodes);arr[preferredDoc.childNodes.length].nodeType;}catch(e){push={apply:arr.length?function(target,els){pushNative.apply(target,slice.call(els));}:function(target,els){var j=target.length,i=0;while((target[j++]=els[i++])){}
target.length=j-1;}};}
function Sizzle(selector,context,results,seed){var m,i,elem,nid,match,groups,newSelector,newContext=context&&context.ownerDocument,nodeType=context?context.nodeType:9;results=results||[];if(typeof selector!=="string"||!selector||nodeType!==1&&nodeType!==9&&nodeType!==11){return results;}
if(!seed){setDocument(context);context=context||document;if(documentIsHTML){if(nodeType!==11&&(match=rquickExpr.exec(selector))){if((m=match[1])){if(nodeType===9){if((elem=context.getElementById(m))){if(elem.id===m){results.push(elem);return results;}}else{return results;}}else{if(newContext&&(elem=newContext.getElementById(m))&&contains(context,elem)&&elem.id===m){results.push(elem);return results;}}}else if(match[2]){push.apply(results,context.getElementsByTagName(selector));return results;}else if((m=match[3])&&support.getElementsByClassName&&context.getElementsByClassName){push.apply(results,context.getElementsByClassName(m));return results;}}
if(support.qsa&&!nonnativeSelectorCache[selector+" "]&&(!rbuggyQSA||!rbuggyQSA.test(selector))&&(nodeType!==1||context.nodeName.toLowerCase()!=="object")){newSelector=selector;newContext=context;if(nodeType===1&&(rdescend.test(selector)||rcombinators.test(selector))){newContext=rsibling.test(selector)&&testContext(context.parentNode)||context;if(newContext!==context||!support.scope){if((nid=context.getAttribute("id"))){nid=nid.replace(rcssescape,fcssescape);}else{context.setAttribute("id",(nid=expando));}}
groups=tokenize(selector);i=groups.length;while(i--){groups[i]=(nid?"#"+nid:":scope")+" "+
toSelector(groups[i]);}
newSelector=groups.join(",");}
try{if(support.cssSupportsSelector&&!CSS.supports("selector(:is("+newSelector+"))")){throw new Error();}
push.apply(results,newContext.querySelectorAll(newSelector));return results;}catch(qsaError){nonnativeSelectorCache(selector,true);}finally{if(nid===expando){context.removeAttribute("id");}}}}}
return select(selector.replace(rtrim,"$1"),context,results,seed);}
function createCache(){var keys=[];function cache(key,value){if(keys.push(key+" ")>Expr.cacheLength){delete cache[keys.shift()];}
return(cache[key+" "]=value);}
return cache;}
function markFunction(fn){fn[expando]=true;return fn;}
function assert(fn){var el=document.createElement("fieldset");try{return!!fn(el);}catch(e){return false;}finally{if(el.parentNode){el.parentNode.removeChild(el);}
el=null;}}
function addHandle(attrs,handler){var arr=attrs.split("|"),i=arr.length;while(i--){Expr.attrHandle[arr[i]]=handler;}}
function siblingCheck(a,b){var cur=b&&a,diff=cur&&a.nodeType===1&&b.nodeType===1&&a.sourceIndex-b.sourceIndex;if(diff){return diff;}
if(cur){while((cur=cur.nextSibling)){if(cur===b){return-1;}}}
return a?1:-1;}
function createInputPseudo(type){return function(elem){var name=elem.nodeName.toLowerCase();return name==="input"&&elem.type===type;};}
function createButtonPseudo(type){return function(elem){var name=elem.nodeName.toLowerCase();return(name==="input"||name==="button")&&elem.type===type;};}
function createDisabledPseudo(disabled){return function(elem){if("form"in elem){if(elem.parentNode&&elem.disabled===false){if("label"in elem){if("label"in elem.parentNode){return elem.parentNode.disabled===disabled;}else{return elem.disabled===disabled;}}
return elem.isDisabled===disabled||elem.isDisabled!==!disabled&&inDisabledFieldset(elem)===disabled;}
return elem.disabled===disabled;}else if("label"in elem){return elem.disabled===disabled;}
return false;};}
function createPositionalPseudo(fn){return markFunction(function(argument){argument=+argument;return markFunction(function(seed,matches){var j,matchIndexes=fn([],seed.length,argument),i=matchIndexes.length;while(i--){if(seed[(j=matchIndexes[i])]){seed[j]=!(matches[j]=seed[j]);}}});});}
function testContext(context){return context&&typeof context.getElementsByTagName!=="undefined"&&context;}
support=Sizzle.support={};isXML=Sizzle.isXML=function(elem){var namespace=elem&&elem.namespaceURI,docElem=elem&&(elem.ownerDocument||elem).documentElement;return!rhtml.test(namespace||docElem&&docElem.nodeName||"HTML");};setDocument=Sizzle.setDocument=function(node){var hasCompare,subWindow,doc=node?node.ownerDocument||node:preferredDoc;if(doc==document||doc.nodeType!==9||!doc.documentElement){return document;}
document=doc;docElem=document.documentElement;documentIsHTML=!isXML(document);if(preferredDoc!=document&&(subWindow=document.defaultView)&&subWindow.top!==subWindow){if(subWindow.addEventListener){subWindow.addEventListener("unload",unloadHandler,false);}else if(subWindow.attachEvent){subWindow.attachEvent("onunload",unloadHandler);}}
support.scope=assert(function(el){docElem.appendChild(el).appendChild(document.createElement("div"));return typeof el.querySelectorAll!=="undefined"&&!el.querySelectorAll(":scope fieldset div").length;});support.cssSupportsSelector=assert(function(){return CSS.supports("selector(*)")&&document.querySelectorAll(":is(:jqfake)")&&!CSS.supports("selector(:is(*,:jqfake))");});support.attributes=assert(function(el){el.className="i";return!el.getAttribute("className");});support.getElementsByTagName=assert(function(el){el.appendChild(document.createComment(""));return!el.getElementsByTagName("*").length;});support.getElementsByClassName=rnative.test(document.getElementsByClassName);support.getById=assert(function(el){docElem.appendChild(el).id=expando;return!document.getElementsByName||!document.getElementsByName(expando).length;});if(support.getById){Expr.filter["ID"]=function(id){var attrId=id.replace(runescape,funescape);return function(elem){return elem.getAttribute("id")===attrId;};};Expr.find["ID"]=function(id,context){if(typeof context.getElementById!=="undefined"&&documentIsHTML){var elem=context.getElementById(id);return elem?[elem]:[];}};}else{Expr.filter["ID"]=function(id){var attrId=id.replace(runescape,funescape);return function(elem){var node=typeof elem.getAttributeNode!=="undefined"&&elem.getAttributeNode("id");return node&&node.value===attrId;};};Expr.find["ID"]=function(id,context){if(typeof context.getElementById!=="undefined"&&documentIsHTML){var node,i,elems,elem=context.getElementById(id);if(elem){node=elem.getAttributeNode("id");if(node&&node.value===id){return[elem];}
elems=context.getElementsByName(id);i=0;while((elem=elems[i++])){node=elem.getAttributeNode("id");if(node&&node.value===id){return[elem];}}}
return[];}};}
Expr.find["TAG"]=support.getElementsByTagName?function(tag,context){if(typeof context.getElementsByTagName!=="undefined"){return context.getElementsByTagName(tag);}else if(support.qsa){return context.querySelectorAll(tag);}}:function(tag,context){var elem,tmp=[],i=0,results=context.getElementsByTagName(tag);if(tag==="*"){while((elem=results[i++])){if(elem.nodeType===1){tmp.push(elem);}}
return tmp;}
return results;};Expr.find["CLASS"]=support.getElementsByClassName&&function(className,context){if(typeof context.getElementsByClassName!=="undefined"&&documentIsHTML){return context.getElementsByClassName(className);}};rbuggyMatches=[];rbuggyQSA=[];if((support.qsa=rnative.test(document.querySelectorAll))){assert(function(el){var input;docElem.appendChild(el).innerHTML="<a id='"+expando+"'></a>"+"<select id='"+expando+"-\r\\' msallowcapture=''>"+"<option selected=''></option></select>";if(el.querySelectorAll("[msallowcapture^='']").length){rbuggyQSA.push("[*^$]="+whitespace+"*(?:''|\"\")");}
if(!el.querySelectorAll("[selected]").length){rbuggyQSA.push("\\["+whitespace+"*(?:value|"+booleans+")");}
if(!el.querySelectorAll("[id~="+expando+"-]").length){rbuggyQSA.push("~=");}
input=document.createElement("input");input.setAttribute("name","");el.appendChild(input);if(!el.querySelectorAll("[name='']").length){rbuggyQSA.push("\\["+whitespace+"*name"+whitespace+"*="+
whitespace+"*(?:''|\"\")");}
if(!el.querySelectorAll(":checked").length){rbuggyQSA.push(":checked");}
if(!el.querySelectorAll("a#"+expando+"+*").length){rbuggyQSA.push(".#.+[+~]");}});assert(function(el){el.innerHTML="<a href='' disabled='disabled'></a>"+"<select disabled='disabled'><option/></select>";var input=document.createElement("input");input.setAttribute("type","hidden");el.appendChild(input).setAttribute("name","D");if(el.querySelectorAll("[name=d]").length){rbuggyQSA.push("name"+whitespace+"*[*^$|!~]?=");}
if(el.querySelectorAll(":enabled").length!==2){rbuggyQSA.push(":enabled",":disabled");}
docElem.appendChild(el).disabled=true;if(el.querySelectorAll(":disabled").length!==2){rbuggyQSA.push(":enabled",":disabled");}});}
if((support.matchesSelector=rnative.test((matches=docElem.matches||docElem.webkitMatchesSelector||docElem.mozMatchesSelector||docElem.oMatchesSelector||docElem.msMatchesSelector)))){assert(function(el){support.disconnectedMatch=matches.call(el,"*");});}
if(!support.cssSupportsSelector){rbuggyQSA.push(":has");}
rbuggyQSA=rbuggyQSA.length&&new RegExp(rbuggyQSA.join("|"));rbuggyMatches=rbuggyMatches.length&&new RegExp(rbuggyMatches.join("|"));hasCompare=rnative.test(docElem.compareDocumentPosition);contains=hasCompare||rnative.test(docElem.contains)?function(a,b){var adown=a.nodeType===9&&a.documentElement||a,bup=b&&b.parentNode;return a===bup||!!(bup&&bup.nodeType===1&&(adown.contains?adown.contains(bup):a.compareDocumentPosition&&a.compareDocumentPosition(bup)&16));}:function(a,b){if(b){while((b=b.parentNode)){if(b===a){return true;}}}
return false;};sortOrder=hasCompare?function(a,b){if(a===b){hasDuplicate=true;return 0;}
var compare=!a.compareDocumentPosition-!b.compareDocumentPosition;if(compare){return compare;}
compare=(a.ownerDocument||a)==(b.ownerDocument||b)?a.compareDocumentPosition(b):1;if(compare&1||(!support.sortDetached&&b.compareDocumentPosition(a)===compare)){if(a==document||a.ownerDocument==preferredDoc&&contains(preferredDoc,a)){return-1;}
if(b==document||b.ownerDocument==preferredDoc&&contains(preferredDoc,b)){return 1;}
return sortInput?(indexOf(sortInput,a)-indexOf(sortInput,b)):0;}
return compare&4?-1:1;}:function(a,b){if(a===b){hasDuplicate=true;return 0;}
var cur,i=0,aup=a.parentNode,bup=b.parentNode,ap=[a],bp=[b];if(!aup||!bup){return a==document?-1:b==document?1:aup?-1:bup?1:sortInput?(indexOf(sortInput,a)-indexOf(sortInput,b)):0;}else if(aup===bup){return siblingCheck(a,b);}
cur=a;while((cur=cur.parentNode)){ap.unshift(cur);}
cur=b;while((cur=cur.parentNode)){bp.unshift(cur);}
while(ap[i]===bp[i]){i++;}
return i?siblingCheck(ap[i],bp[i]):ap[i]==preferredDoc?-1:bp[i]==preferredDoc?1:0;};return document;};Sizzle.matches=function(expr,elements){return Sizzle(expr,null,null,elements);};Sizzle.matchesSelector=function(elem,expr){setDocument(elem);if(support.matchesSelector&&documentIsHTML&&!nonnativeSelectorCache[expr+" "]&&(!rbuggyMatches||!rbuggyMatches.test(expr))&&(!rbuggyQSA||!rbuggyQSA.test(expr))){try{var ret=matches.call(elem,expr);if(ret||support.disconnectedMatch||elem.document&&elem.document.nodeType!==11){return ret;}}catch(e){nonnativeSelectorCache(expr,true);}}
return Sizzle(expr,document,null,[elem]).length>0;};Sizzle.contains=function(context,elem){if((context.ownerDocument||context)!=document){setDocument(context);}
return contains(context,elem);};Sizzle.attr=function(elem,name){if((elem.ownerDocument||elem)!=document){setDocument(elem);}
var fn=Expr.attrHandle[name.toLowerCase()],val=fn&&hasOwn.call(Expr.attrHandle,name.toLowerCase())?fn(elem,name,!documentIsHTML):undefined;return val!==undefined?val:support.attributes||!documentIsHTML?elem.getAttribute(name):(val=elem.getAttributeNode(name))&&val.specified?val.value:null;};Sizzle.escape=function(sel){return(sel+"").replace(rcssescape,fcssescape);};Sizzle.error=function(msg){throw new Error("Syntax error, unrecognized expression: "+msg);};Sizzle.uniqueSort=function(results){var elem,duplicates=[],j=0,i=0;hasDuplicate=!support.detectDuplicates;sortInput=!support.sortStable&&results.slice(0);results.sort(sortOrder);if(hasDuplicate){while((elem=results[i++])){if(elem===results[i]){j=duplicates.push(i);}}
while(j--){results.splice(duplicates[j],1);}}
sortInput=null;return results;};getText=Sizzle.getText=function(elem){var node,ret="",i=0,nodeType=elem.nodeType;if(!nodeType){while((node=elem[i++])){ret+=getText(node);}}else if(nodeType===1||nodeType===9||nodeType===11){if(typeof elem.textContent==="string"){return elem.textContent;}else{for(elem=elem.firstChild;elem;elem=elem.nextSibling){ret+=getText(elem);}}}else if(nodeType===3||nodeType===4){return elem.nodeValue;}
return ret;};Expr=Sizzle.selectors={cacheLength:50,createPseudo:markFunction,match:matchExpr,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:true}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:true},"~":{dir:"previousSibling"}},preFilter:{"ATTR":function(match){match[1]=match[1].replace(runescape,funescape);match[3]=(match[3]||match[4]||match[5]||"").replace(runescape,funescape);if(match[2]==="~="){match[3]=" "+match[3]+" ";}
return match.slice(0,4);},"CHILD":function(match){match[1]=match[1].toLowerCase();if(match[1].slice(0,3)==="nth"){if(!match[3]){Sizzle.error(match[0]);}
match[4]=+(match[4]?match[5]+(match[6]||1):2*(match[3]==="even"||match[3]==="odd"));match[5]=+((match[7]+match[8])||match[3]==="odd");}else if(match[3]){Sizzle.error(match[0]);}
return match;},"PSEUDO":function(match){var excess,unquoted=!match[6]&&match[2];if(matchExpr["CHILD"].test(match[0])){return null;}
if(match[3]){match[2]=match[4]||match[5]||"";}else if(unquoted&&rpseudo.test(unquoted)&&(excess=tokenize(unquoted,true))&&(excess=unquoted.indexOf(")",unquoted.length-excess)-unquoted.length)){match[0]=match[0].slice(0,excess);match[2]=unquoted.slice(0,excess);}
return match.slice(0,3);}},filter:{"TAG":function(nodeNameSelector){var nodeName=nodeNameSelector.replace(runescape,funescape).toLowerCase();return nodeNameSelector==="*"?function(){return true;}:function(elem){return elem.nodeName&&elem.nodeName.toLowerCase()===nodeName;};},"CLASS":function(className){var pattern=classCache[className+" "];return pattern||(pattern=new RegExp("(^|"+whitespace+")"+className+"("+whitespace+"|$)"))&&classCache(className,function(elem){return pattern.test(typeof elem.className==="string"&&elem.className||typeof elem.getAttribute!=="undefined"&&elem.getAttribute("class")||"");});},"ATTR":function(name,operator,check){return function(elem){var result=Sizzle.attr(elem,name);if(result==null){return operator==="!=";}
if(!operator){return true;}
result+="";return operator==="="?result===check:operator==="!="?result!==check:operator==="^="?check&&result.indexOf(check)===0:operator==="*="?check&&result.indexOf(check)>-1:operator==="$="?check&&result.slice(-check.length)===check:operator==="~="?(" "+result.replace(rwhitespace," ")+" ").indexOf(check)>-1:operator==="|="?result===check||result.slice(0,check.length+1)===check+"-":false;};},"CHILD":function(type,what,_argument,first,last){var simple=type.slice(0,3)!=="nth",forward=type.slice(-4)!=="last",ofType=what==="of-type";return first===1&&last===0?function(elem){return!!elem.parentNode;}:function(elem,_context,xml){var cache,uniqueCache,outerCache,node,nodeIndex,start,dir=simple!==forward?"nextSibling":"previousSibling",parent=elem.parentNode,name=ofType&&elem.nodeName.toLowerCase(),useCache=!xml&&!ofType,diff=false;if(parent){if(simple){while(dir){node=elem;while((node=node[dir])){if(ofType?node.nodeName.toLowerCase()===name:node.nodeType===1){return false;}}
start=dir=type==="only"&&!start&&"nextSibling";}
return true;}
start=[forward?parent.firstChild:parent.lastChild];if(forward&&useCache){node=parent;outerCache=node[expando]||(node[expando]={});uniqueCache=outerCache[node.uniqueID]||(outerCache[node.uniqueID]={});cache=uniqueCache[type]||[];nodeIndex=cache[0]===dirruns&&cache[1];diff=nodeIndex&&cache[2];node=nodeIndex&&parent.childNodes[nodeIndex];while((node=++nodeIndex&&node&&node[dir]||(diff=nodeIndex=0)||start.pop())){if(node.nodeType===1&&++diff&&node===elem){uniqueCache[type]=[dirruns,nodeIndex,diff];break;}}}else{if(useCache){node=elem;outerCache=node[expando]||(node[expando]={});uniqueCache=outerCache[node.uniqueID]||(outerCache[node.uniqueID]={});cache=uniqueCache[type]||[];nodeIndex=cache[0]===dirruns&&cache[1];diff=nodeIndex;}
if(diff===false){while((node=++nodeIndex&&node&&node[dir]||(diff=nodeIndex=0)||start.pop())){if((ofType?node.nodeName.toLowerCase()===name:node.nodeType===1)&&++diff){if(useCache){outerCache=node[expando]||(node[expando]={});uniqueCache=outerCache[node.uniqueID]||(outerCache[node.uniqueID]={});uniqueCache[type]=[dirruns,diff];}
if(node===elem){break;}}}}}
diff-=last;return diff===first||(diff%first===0&&diff/first>=0);}};},"PSEUDO":function(pseudo,argument){var args,fn=Expr.pseudos[pseudo]||Expr.setFilters[pseudo.toLowerCase()]||Sizzle.error("unsupported pseudo: "+pseudo);if(fn[expando]){return fn(argument);}
if(fn.length>1){args=[pseudo,pseudo,"",argument];return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase())?markFunction(function(seed,matches){var idx,matched=fn(seed,argument),i=matched.length;while(i--){idx=indexOf(seed,matched[i]);seed[idx]=!(matches[idx]=matched[i]);}}):function(elem){return fn(elem,0,args);};}
return fn;}},pseudos:{"not":markFunction(function(selector){var input=[],results=[],matcher=compile(selector.replace(rtrim,"$1"));return matcher[expando]?markFunction(function(seed,matches,_context,xml){var elem,unmatched=matcher(seed,null,xml,[]),i=seed.length;while(i--){if((elem=unmatched[i])){seed[i]=!(matches[i]=elem);}}}):function(elem,_context,xml){input[0]=elem;matcher(input,null,xml,results);input[0]=null;return!results.pop();};}),"has":markFunction(function(selector){return function(elem){return Sizzle(selector,elem).length>0;};}),"contains":markFunction(function(text){text=text.replace(runescape,funescape);return function(elem){return(elem.textContent||getText(elem)).indexOf(text)>-1;};}),"lang":markFunction(function(lang){if(!ridentifier.test(lang||"")){Sizzle.error("unsupported lang: "+lang);}
lang=lang.replace(runescape,funescape).toLowerCase();return function(elem){var elemLang;do{if((elemLang=documentIsHTML?elem.lang:elem.getAttribute("xml:lang")||elem.getAttribute("lang"))){elemLang=elemLang.toLowerCase();return elemLang===lang||elemLang.indexOf(lang+"-")===0;}}while((elem=elem.parentNode)&&elem.nodeType===1);return false;};}),"target":function(elem){var hash=window.location&&window.location.hash;return hash&&hash.slice(1)===elem.id;},"root":function(elem){return elem===docElem;},"focus":function(elem){return elem===document.activeElement&&(!document.hasFocus||document.hasFocus())&&!!(elem.type||elem.href||~elem.tabIndex);},"enabled":createDisabledPseudo(false),"disabled":createDisabledPseudo(true),"checked":function(elem){var nodeName=elem.nodeName.toLowerCase();return(nodeName==="input"&&!!elem.checked)||(nodeName==="option"&&!!elem.selected);},"selected":function(elem){if(elem.parentNode){elem.parentNode.selectedIndex;}
return elem.selected===true;},"empty":function(elem){for(elem=elem.firstChild;elem;elem=elem.nextSibling){if(elem.nodeType<6){return false;}}
return true;},"parent":function(elem){return!Expr.pseudos["empty"](elem);},"header":function(elem){return rheader.test(elem.nodeName);},"input":function(elem){return rinputs.test(elem.nodeName);},"button":function(elem){var name=elem.nodeName.toLowerCase();return name==="input"&&elem.type==="button"||name==="button";},"text":function(elem){var attr;return elem.nodeName.toLowerCase()==="input"&&elem.type==="text"&&((attr=elem.getAttribute("type"))==null||attr.toLowerCase()==="text");},"first":createPositionalPseudo(function(){return[0];}),"last":createPositionalPseudo(function(_matchIndexes,length){return[length-1];}),"eq":createPositionalPseudo(function(_matchIndexes,length,argument){return[argument<0?argument+length:argument];}),"even":createPositionalPseudo(function(matchIndexes,length){var i=0;for(;i<length;i+=2){matchIndexes.push(i);}
return matchIndexes;}),"odd":createPositionalPseudo(function(matchIndexes,length){var i=1;for(;i<length;i+=2){matchIndexes.push(i);}
return matchIndexes;}),"lt":createPositionalPseudo(function(matchIndexes,length,argument){var i=argument<0?argument+length:argument>length?length:argument;for(;--i>=0;){matchIndexes.push(i);}
return matchIndexes;}),"gt":createPositionalPseudo(function(matchIndexes,length,argument){var i=argument<0?argument+length:argument;for(;++i<length;){matchIndexes.push(i);}
return matchIndexes;})}};Expr.pseudos["nth"]=Expr.pseudos["eq"];for(i in{radio:true,checkbox:true,file:true,password:true,image:true}){Expr.pseudos[i]=createInputPseudo(i);}
for(i in{submit:true,reset:true}){Expr.pseudos[i]=createButtonPseudo(i);}
function setFilters(){}
setFilters.prototype=Expr.filters=Expr.pseudos;Expr.setFilters=new setFilters();tokenize=Sizzle.tokenize=function(selector,parseOnly){var matched,match,tokens,type,soFar,groups,preFilters,cached=tokenCache[selector+" "];if(cached){return parseOnly?0:cached.slice(0);}
soFar=selector;groups=[];preFilters=Expr.preFilter;while(soFar){if(!matched||(match=rcomma.exec(soFar))){if(match){soFar=soFar.slice(match[0].length)||soFar;}
groups.push((tokens=[]));}
matched=false;if((match=rcombinators.exec(soFar))){matched=match.shift();tokens.push({value:matched,type:match[0].replace(rtrim," ")});soFar=soFar.slice(matched.length);}
for(type in Expr.filter){if((match=matchExpr[type].exec(soFar))&&(!preFilters[type]||(match=preFilters[type](match)))){matched=match.shift();tokens.push({value:matched,type:type,matches:match});soFar=soFar.slice(matched.length);}}
if(!matched){break;}}
return parseOnly?soFar.length:soFar?Sizzle.error(selector):tokenCache(selector,groups).slice(0);};function toSelector(tokens){var i=0,len=tokens.length,selector="";for(;i<len;i++){selector+=tokens[i].value;}
return selector;}
function addCombinator(matcher,combinator,base){var dir=combinator.dir,skip=combinator.next,key=skip||dir,checkNonElements=base&&key==="parentNode",doneName=done++;return combinator.first?function(elem,context,xml){while((elem=elem[dir])){if(elem.nodeType===1||checkNonElements){return matcher(elem,context,xml);}}
return false;}:function(elem,context,xml){var oldCache,uniqueCache,outerCache,newCache=[dirruns,doneName];if(xml){while((elem=elem[dir])){if(elem.nodeType===1||checkNonElements){if(matcher(elem,context,xml)){return true;}}}}else{while((elem=elem[dir])){if(elem.nodeType===1||checkNonElements){outerCache=elem[expando]||(elem[expando]={});uniqueCache=outerCache[elem.uniqueID]||(outerCache[elem.uniqueID]={});if(skip&&skip===elem.nodeName.toLowerCase()){elem=elem[dir]||elem;}else if((oldCache=uniqueCache[key])&&oldCache[0]===dirruns&&oldCache[1]===doneName){return(newCache[2]=oldCache[2]);}else{uniqueCache[key]=newCache;if((newCache[2]=matcher(elem,context,xml))){return true;}}}}}
return false;};}
function elementMatcher(matchers){return matchers.length>1?function(elem,context,xml){var i=matchers.length;while(i--){if(!matchers[i](elem,context,xml)){return false;}}
return true;}:matchers[0];}
function multipleContexts(selector,contexts,results){var i=0,len=contexts.length;for(;i<len;i++){Sizzle(selector,contexts[i],results);}
return results;}
function condense(unmatched,map,filter,context,xml){var elem,newUnmatched=[],i=0,len=unmatched.length,mapped=map!=null;for(;i<len;i++){if((elem=unmatched[i])){if(!filter||filter(elem,context,xml)){newUnmatched.push(elem);if(mapped){map.push(i);}}}}
return newUnmatched;}
function setMatcher(preFilter,selector,matcher,postFilter,postFinder,postSelector){if(postFilter&&!postFilter[expando]){postFilter=setMatcher(postFilter);}
if(postFinder&&!postFinder[expando]){postFinder=setMatcher(postFinder,postSelector);}
return markFunction(function(seed,results,context,xml){var temp,i,elem,preMap=[],postMap=[],preexisting=results.length,elems=seed||multipleContexts(selector||"*",context.nodeType?[context]:context,[]),matcherIn=preFilter&&(seed||!selector)?condense(elems,preMap,preFilter,context,xml):elems,matcherOut=matcher?postFinder||(seed?preFilter:preexisting||postFilter)?[]:results:matcherIn;if(matcher){matcher(matcherIn,matcherOut,context,xml);}
if(postFilter){temp=condense(matcherOut,postMap);postFilter(temp,[],context,xml);i=temp.length;while(i--){if((elem=temp[i])){matcherOut[postMap[i]]=!(matcherIn[postMap[i]]=elem);}}}
if(seed){if(postFinder||preFilter){if(postFinder){temp=[];i=matcherOut.length;while(i--){if((elem=matcherOut[i])){temp.push((matcherIn[i]=elem));}}
postFinder(null,(matcherOut=[]),temp,xml);}
i=matcherOut.length;while(i--){if((elem=matcherOut[i])&&(temp=postFinder?indexOf(seed,elem):preMap[i])>-1){seed[temp]=!(results[temp]=elem);}}}}else{matcherOut=condense(matcherOut===results?matcherOut.splice(preexisting,matcherOut.length):matcherOut);if(postFinder){postFinder(null,results,matcherOut,xml);}else{push.apply(results,matcherOut);}}});}
function matcherFromTokens(tokens){var checkContext,matcher,j,len=tokens.length,leadingRelative=Expr.relative[tokens[0].type],implicitRelative=leadingRelative||Expr.relative[" "],i=leadingRelative?1:0,matchContext=addCombinator(function(elem){return elem===checkContext;},implicitRelative,true),matchAnyContext=addCombinator(function(elem){return indexOf(checkContext,elem)>-1;},implicitRelative,true),matchers=[function(elem,context,xml){var ret=(!leadingRelative&&(xml||context!==outermostContext))||((checkContext=context).nodeType?matchContext(elem,context,xml):matchAnyContext(elem,context,xml));checkContext=null;return ret;}];for(;i<len;i++){if((matcher=Expr.relative[tokens[i].type])){matchers=[addCombinator(elementMatcher(matchers),matcher)];}else{matcher=Expr.filter[tokens[i].type].apply(null,tokens[i].matches);if(matcher[expando]){j=++i;for(;j<len;j++){if(Expr.relative[tokens[j].type]){break;}}
return setMatcher(i>1&&elementMatcher(matchers),i>1&&toSelector(tokens.slice(0,i-1).concat({value:tokens[i-2].type===" "?"*":""})).replace(rtrim,"$1"),matcher,i<j&&matcherFromTokens(tokens.slice(i,j)),j<len&&matcherFromTokens((tokens=tokens.slice(j))),j<len&&toSelector(tokens));}
matchers.push(matcher);}}
return elementMatcher(matchers);}
function matcherFromGroupMatchers(elementMatchers,setMatchers){var bySet=setMatchers.length>0,byElement=elementMatchers.length>0,superMatcher=function(seed,context,xml,results,outermost){var elem,j,matcher,matchedCount=0,i="0",unmatched=seed&&[],setMatched=[],contextBackup=outermostContext,elems=seed||byElement&&Expr.find["TAG"]("*",outermost),dirrunsUnique=(dirruns+=contextBackup==null?1:Math.random()||0.1),len=elems.length;if(outermost){outermostContext=context==document||context||outermost;}
for(;i!==len&&(elem=elems[i])!=null;i++){if(byElement&&elem){j=0;if(!context&&elem.ownerDocument!=document){setDocument(elem);xml=!documentIsHTML;}
while((matcher=elementMatchers[j++])){if(matcher(elem,context||document,xml)){results.push(elem);break;}}
if(outermost){dirruns=dirrunsUnique;}}
if(bySet){if((elem=!matcher&&elem)){matchedCount--;}
if(seed){unmatched.push(elem);}}}
matchedCount+=i;if(bySet&&i!==matchedCount){j=0;while((matcher=setMatchers[j++])){matcher(unmatched,setMatched,context,xml);}
if(seed){if(matchedCount>0){while(i--){if(!(unmatched[i]||setMatched[i])){setMatched[i]=pop.call(results);}}}
setMatched=condense(setMatched);}
push.apply(results,setMatched);if(outermost&&!seed&&setMatched.length>0&&(matchedCount+setMatchers.length)>1){Sizzle.uniqueSort(results);}}
if(outermost){dirruns=dirrunsUnique;outermostContext=contextBackup;}
return unmatched;};return bySet?markFunction(superMatcher):superMatcher;}
compile=Sizzle.compile=function(selector,match){var i,setMatchers=[],elementMatchers=[],cached=compilerCache[selector+" "];if(!cached){if(!match){match=tokenize(selector);}
i=match.length;while(i--){cached=matcherFromTokens(match[i]);if(cached[expando]){setMatchers.push(cached);}else{elementMatchers.push(cached);}}
cached=compilerCache(selector,matcherFromGroupMatchers(elementMatchers,setMatchers));cached.selector=selector;}
return cached;};select=Sizzle.select=function(selector,context,results,seed){var i,tokens,token,type,find,compiled=typeof selector==="function"&&selector,match=!seed&&tokenize((selector=compiled.selector||selector));results=results||[];if(match.length===1){tokens=match[0]=match[0].slice(0);if(tokens.length>2&&(token=tokens[0]).type==="ID"&&context.nodeType===9&&documentIsHTML&&Expr.relative[tokens[1].type]){context=(Expr.find["ID"](token.matches[0].replace(runescape,funescape),context)||[])[0];if(!context){return results;}else if(compiled){context=context.parentNode;}
selector=selector.slice(tokens.shift().value.length);}
i=matchExpr["needsContext"].test(selector)?0:tokens.length;while(i--){token=tokens[i];if(Expr.relative[(type=token.type)]){break;}
if((find=Expr.find[type])){if((seed=find(token.matches[0].replace(runescape,funescape),rsibling.test(tokens[0].type)&&testContext(context.parentNode)||context))){tokens.splice(i,1);selector=seed.length&&toSelector(tokens);if(!selector){push.apply(results,seed);return results;}
break;}}}}
(compiled||compile(selector,match))(seed,context,!documentIsHTML,results,!context||rsibling.test(selector)&&testContext(context.parentNode)||context);return results;};support.sortStable=expando.split("").sort(sortOrder).join("")===expando;support.detectDuplicates=!!hasDuplicate;setDocument();support.sortDetached=assert(function(el){return el.compareDocumentPosition(document.createElement("fieldset"))&1;});if(!assert(function(el){el.innerHTML="<a href='#'></a>";return el.firstChild.getAttribute("href")==="#";})){addHandle("type|href|height|width",function(elem,name,isXML){if(!isXML){return elem.getAttribute(name,name.toLowerCase()==="type"?1:2);}});}
if(!support.attributes||!assert(function(el){el.innerHTML="<input/>";el.firstChild.setAttribute("value","");return el.firstChild.getAttribute("value")==="";})){addHandle("value",function(elem,_name,isXML){if(!isXML&&elem.nodeName.toLowerCase()==="input"){return elem.defaultValue;}});}
if(!assert(function(el){return el.getAttribute("disabled")==null;})){addHandle(booleans,function(elem,name,isXML){var val;if(!isXML){return elem[name]===true?name.toLowerCase():(val=elem.getAttributeNode(name))&&val.specified?val.value:null;}});}
return Sizzle;})(window);jQuery.find=Sizzle;jQuery.expr=Sizzle.selectors;jQuery.expr[":"]=jQuery.expr.pseudos;jQuery.uniqueSort=jQuery.unique=Sizzle.uniqueSort;jQuery.text=Sizzle.getText;jQuery.isXMLDoc=Sizzle.isXML;jQuery.contains=Sizzle.contains;jQuery.escapeSelector=Sizzle.escape;var dir=function(elem,dir,until){var matched=[],truncate=until!==undefined;while((elem=elem[dir])&&elem.nodeType!==9){if(elem.nodeType===1){if(truncate&&jQuery(elem).is(until)){break;}
matched.push(elem);}}
return matched;};var siblings=function(n,elem){var matched=[];for(;n;n=n.nextSibling){if(n.nodeType===1&&n!==elem){matched.push(n);}}
return matched;};var rneedsContext=jQuery.expr.match.needsContext;function nodeName(elem,name){return elem.nodeName&&elem.nodeName.toLowerCase()===name.toLowerCase();}
var rsingleTag=(/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i);function winnow(elements,qualifier,not){if(isFunction(qualifier)){return jQuery.grep(elements,function(elem,i){return!!qualifier.call(elem,i,elem)!==not;});}
if(qualifier.nodeType){return jQuery.grep(elements,function(elem){return(elem===qualifier)!==not;});}
if(typeof qualifier!=="string"){return jQuery.grep(elements,function(elem){return(indexOf.call(qualifier,elem)>-1)!==not;});}
return jQuery.filter(qualifier,elements,not);}
jQuery.filter=function(expr,elems,not){var elem=elems[0];if(not){expr=":not("+expr+")";}
if(elems.length===1&&elem.nodeType===1){return jQuery.find.matchesSelector(elem,expr)?[elem]:[];}
return jQuery.find.matches(expr,jQuery.grep(elems,function(elem){return elem.nodeType===1;}));};jQuery.fn.extend({find:function(selector){var i,ret,len=this.length,self=this;if(typeof selector!=="string"){return this.pushStack(jQuery(selector).filter(function(){for(i=0;i<len;i++){if(jQuery.contains(self[i],this)){return true;}}}));}
ret=this.pushStack([]);for(i=0;i<len;i++){jQuery.find(selector,self[i],ret);}
return len>1?jQuery.uniqueSort(ret):ret;},filter:function(selector){return this.pushStack(winnow(this,selector||[],false));},not:function(selector){return this.pushStack(winnow(this,selector||[],true));},is:function(selector){return!!winnow(this,typeof selector==="string"&&rneedsContext.test(selector)?jQuery(selector):selector||[],false).length;}});var rootjQuery,rquickExpr=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,init=jQuery.fn.init=function(selector,context,root){var match,elem;if(!selector){return this;}
root=root||rootjQuery;if(typeof selector==="string"){if(selector[0]==="<"&&selector[selector.length-1]===">"&&selector.length>=3){match=[null,selector,null];}else{match=rquickExpr.exec(selector);}
if(match&&(match[1]||!context)){if(match[1]){context=context instanceof jQuery?context[0]:context;jQuery.merge(this,jQuery.parseHTML(match[1],context&&context.nodeType?context.ownerDocument||context:document,true));if(rsingleTag.test(match[1])&&jQuery.isPlainObject(context)){for(match in context){if(isFunction(this[match])){this[match](context[match]);}else{this.attr(match,context[match]);}}}
return this;}else{elem=document.getElementById(match[2]);if(elem){this[0]=elem;this.length=1;}
return this;}}else if(!context||context.jquery){return(context||root).find(selector);}else{return this.constructor(context).find(selector);}}else if(selector.nodeType){this[0]=selector;this.length=1;return this;}else if(isFunction(selector)){return root.ready!==undefined?root.ready(selector):selector(jQuery);}
return jQuery.makeArray(selector,this);};init.prototype=jQuery.fn;rootjQuery=jQuery(document);var rparentsprev=/^(?:parents|prev(?:Until|All))/,guaranteedUnique={children:true,contents:true,next:true,prev:true};jQuery.fn.extend({has:function(target){var targets=jQuery(target,this),l=targets.length;return this.filter(function(){var i=0;for(;i<l;i++){if(jQuery.contains(this,targets[i])){return true;}}});},closest:function(selectors,context){var cur,i=0,l=this.length,matched=[],targets=typeof selectors!=="string"&&jQuery(selectors);if(!rneedsContext.test(selectors)){for(;i<l;i++){for(cur=this[i];cur&&cur!==context;cur=cur.parentNode){if(cur.nodeType<11&&(targets?targets.index(cur)>-1:cur.nodeType===1&&jQuery.find.matchesSelector(cur,selectors))){matched.push(cur);break;}}}}
return this.pushStack(matched.length>1?jQuery.uniqueSort(matched):matched);},index:function(elem){if(!elem){return(this[0]&&this[0].parentNode)?this.first().prevAll().length:-1;}
if(typeof elem==="string"){return indexOf.call(jQuery(elem),this[0]);}
return indexOf.call(this,elem.jquery?elem[0]:elem);},add:function(selector,context){return this.pushStack(jQuery.uniqueSort(jQuery.merge(this.get(),jQuery(selector,context))));},addBack:function(selector){return this.add(selector==null?this.prevObject:this.prevObject.filter(selector));}});function sibling(cur,dir){while((cur=cur[dir])&&cur.nodeType!==1){}
return cur;}
jQuery.each({parent:function(elem){var parent=elem.parentNode;return parent&&parent.nodeType!==11?parent:null;},parents:function(elem){return dir(elem,"parentNode");},parentsUntil:function(elem,_i,until){return dir(elem,"parentNode",until);},next:function(elem){return sibling(elem,"nextSibling");},prev:function(elem){return sibling(elem,"previousSibling");},nextAll:function(elem){return dir(elem,"nextSibling");},prevAll:function(elem){return dir(elem,"previousSibling");},nextUntil:function(elem,_i,until){return dir(elem,"nextSibling",until);},prevUntil:function(elem,_i,until){return dir(elem,"previousSibling",until);},siblings:function(elem){return siblings((elem.parentNode||{}).firstChild,elem);},children:function(elem){return siblings(elem.firstChild);},contents:function(elem){if(elem.contentDocument!=null&&getProto(elem.contentDocument)){return elem.contentDocument;}
if(nodeName(elem,"template")){elem=elem.content||elem;}
return jQuery.merge([],elem.childNodes);}},function(name,fn){jQuery.fn[name]=function(until,selector){var matched=jQuery.map(this,fn,until);if(name.slice(-5)!=="Until"){selector=until;}
if(selector&&typeof selector==="string"){matched=jQuery.filter(selector,matched);}
if(this.length>1){if(!guaranteedUnique[name]){jQuery.uniqueSort(matched);}
if(rparentsprev.test(name)){matched.reverse();}}
return this.pushStack(matched);};});var rnothtmlwhite=(/[^\x20\t\r\n\f]+/g);function createOptions(options){var object={};jQuery.each(options.match(rnothtmlwhite)||[],function(_,flag){object[flag]=true;});return object;}
jQuery.Callbacks=function(options){options=typeof options==="string"?createOptions(options):jQuery.extend({},options);var
firing,memory,fired,locked,list=[],queue=[],firingIndex=-1,fire=function(){locked=locked||options.once;fired=firing=true;for(;queue.length;firingIndex=-1){memory=queue.shift();while(++firingIndex<list.length){if(list[firingIndex].apply(memory[0],memory[1])===false&&options.stopOnFalse){firingIndex=list.length;memory=false;}}}
if(!options.memory){memory=false;}
firing=false;if(locked){if(memory){list=[];}else{list="";}}},self={add:function(){if(list){if(memory&&!firing){firingIndex=list.length-1;queue.push(memory);}
(function add(args){jQuery.each(args,function(_,arg){if(isFunction(arg)){if(!options.unique||!self.has(arg)){list.push(arg);}}else if(arg&&arg.length&&toType(arg)!=="string"){add(arg);}});})(arguments);if(memory&&!firing){fire();}}
return this;},remove:function(){jQuery.each(arguments,function(_,arg){var index;while((index=jQuery.inArray(arg,list,index))>-1){list.splice(index,1);if(index<=firingIndex){firingIndex--;}}});return this;},has:function(fn){return fn?jQuery.inArray(fn,list)>-1:list.length>0;},empty:function(){if(list){list=[];}
return this;},disable:function(){locked=queue=[];list=memory="";return this;},disabled:function(){return!list;},lock:function(){locked=queue=[];if(!memory&&!firing){list=memory="";}
return this;},locked:function(){return!!locked;},fireWith:function(context,args){if(!locked){args=args||[];args=[context,args.slice?args.slice():args];queue.push(args);if(!firing){fire();}}
return this;},fire:function(){self.fireWith(this,arguments);return this;},fired:function(){return!!fired;}};return self;};function Identity(v){return v;}
function Thrower(ex){throw ex;}
function adoptValue(value,resolve,reject,noValue){var method;try{if(value&&isFunction((method=value.promise))){method.call(value).done(resolve).fail(reject);}else if(value&&isFunction((method=value.then))){method.call(value,resolve,reject);}else{resolve.apply(undefined,[value].slice(noValue));}}catch(value){reject.apply(undefined,[value]);}}
jQuery.extend({Deferred:function(func){var tuples=[["notify","progress",jQuery.Callbacks("memory"),jQuery.Callbacks("memory"),2],["resolve","done",jQuery.Callbacks("once memory"),jQuery.Callbacks("once memory"),0,"resolved"],["reject","fail",jQuery.Callbacks("once memory"),jQuery.Callbacks("once memory"),1,"rejected"]],state="pending",promise={state:function(){return state;},always:function(){deferred.done(arguments).fail(arguments);return this;},"catch":function(fn){return promise.then(null,fn);},pipe:function(){var fns=arguments;return jQuery.Deferred(function(newDefer){jQuery.each(tuples,function(_i,tuple){var fn=isFunction(fns[tuple[4]])&&fns[tuple[4]];deferred[tuple[1]](function(){var returned=fn&&fn.apply(this,arguments);if(returned&&isFunction(returned.promise)){returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject);}else{newDefer[tuple[0]+"With"](this,fn?[returned]:arguments);}});});fns=null;}).promise();},then:function(onFulfilled,onRejected,onProgress){var maxDepth=0;function resolve(depth,deferred,handler,special){return function(){var that=this,args=arguments,mightThrow=function(){var returned,then;if(depth<maxDepth){return;}
returned=handler.apply(that,args);if(returned===deferred.promise()){throw new TypeError("Thenable self-resolution");}
then=returned&&(typeof returned==="object"||typeof returned==="function")&&returned.then;if(isFunction(then)){if(special){then.call(returned,resolve(maxDepth,deferred,Identity,special),resolve(maxDepth,deferred,Thrower,special));}else{maxDepth++;then.call(returned,resolve(maxDepth,deferred,Identity,special),resolve(maxDepth,deferred,Thrower,special),resolve(maxDepth,deferred,Identity,deferred.notifyWith));}}else{if(handler!==Identity){that=undefined;args=[returned];}
(special||deferred.resolveWith)(that,args);}},process=special?mightThrow:function(){try{mightThrow();}catch(e){if(jQuery.Deferred.exceptionHook){jQuery.Deferred.exceptionHook(e,process.stackTrace);}
if(depth+1>=maxDepth){if(handler!==Thrower){that=undefined;args=[e];}
deferred.rejectWith(that,args);}}};if(depth){process();}else{if(jQuery.Deferred.getStackHook){process.stackTrace=jQuery.Deferred.getStackHook();}
window.setTimeout(process);}};}
return jQuery.Deferred(function(newDefer){tuples[0][3].add(resolve(0,newDefer,isFunction(onProgress)?onProgress:Identity,newDefer.notifyWith));tuples[1][3].add(resolve(0,newDefer,isFunction(onFulfilled)?onFulfilled:Identity));tuples[2][3].add(resolve(0,newDefer,isFunction(onRejected)?onRejected:Thrower));}).promise();},promise:function(obj){return obj!=null?jQuery.extend(obj,promise):promise;}},deferred={};jQuery.each(tuples,function(i,tuple){var list=tuple[2],stateString=tuple[5];promise[tuple[1]]=list.add;if(stateString){list.add(function(){state=stateString;},tuples[3-i][2].disable,tuples[3-i][3].disable,tuples[0][2].lock,tuples[0][3].lock);}
list.add(tuple[3].fire);deferred[tuple[0]]=function(){deferred[tuple[0]+"With"](this===deferred?undefined:this,arguments);return this;};deferred[tuple[0]+"With"]=list.fireWith;});promise.promise(deferred);if(func){func.call(deferred,deferred);}
return deferred;},when:function(singleValue){var
remaining=arguments.length,i=remaining,resolveContexts=Array(i),resolveValues=slice.call(arguments),primary=jQuery.Deferred(),updateFunc=function(i){return function(value){resolveContexts[i]=this;resolveValues[i]=arguments.length>1?slice.call(arguments):value;if(!(--remaining)){primary.resolveWith(resolveContexts,resolveValues);}};};if(remaining<=1){adoptValue(singleValue,primary.done(updateFunc(i)).resolve,primary.reject,!remaining);if(primary.state()==="pending"||isFunction(resolveValues[i]&&resolveValues[i].then)){return primary.then();}}
while(i--){adoptValue(resolveValues[i],updateFunc(i),primary.reject);}
return primary.promise();}});var rerrorNames=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;jQuery.Deferred.exceptionHook=function(error,stack){if(window.console&&window.console.warn&&error&&rerrorNames.test(error.name)){window.console.warn("jQuery.Deferred exception: "+error.message,error.stack,stack);}};jQuery.readyException=function(error){window.setTimeout(function(){throw error;});};var readyList=jQuery.Deferred();jQuery.fn.ready=function(fn){readyList.then(fn).catch(function(error){jQuery.readyException(error);});return this;};jQuery.extend({isReady:false,readyWait:1,ready:function(wait){if(wait===true?--jQuery.readyWait:jQuery.isReady){return;}
jQuery.isReady=true;if(wait!==true&&--jQuery.readyWait>0){return;}
readyList.resolveWith(document,[jQuery]);}});jQuery.ready.then=readyList.then;function completed(){document.removeEventListener("DOMContentLoaded",completed);window.removeEventListener("load",completed);jQuery.ready();}
if(document.readyState==="complete"||(document.readyState!=="loading"&&!document.documentElement.doScroll)){window.setTimeout(jQuery.ready);}else{document.addEventListener("DOMContentLoaded",completed);window.addEventListener("load",completed);}
var access=function(elems,fn,key,value,chainable,emptyGet,raw){var i=0,len=elems.length,bulk=key==null;if(toType(key)==="object"){chainable=true;for(i in key){access(elems,fn,i,key[i],true,emptyGet,raw);}}else if(value!==undefined){chainable=true;if(!isFunction(value)){raw=true;}
if(bulk){if(raw){fn.call(elems,value);fn=null;}else{bulk=fn;fn=function(elem,_key,value){return bulk.call(jQuery(elem),value);};}}
if(fn){for(;i<len;i++){fn(elems[i],key,raw?value:value.call(elems[i],i,fn(elems[i],key)));}}}
if(chainable){return elems;}
if(bulk){return fn.call(elems);}
return len?fn(elems[0],key):emptyGet;};var rmsPrefix=/^-ms-/,rdashAlpha=/-([a-z])/g;function fcamelCase(_all,letter){return letter.toUpperCase();}
function camelCase(string){return string.replace(rmsPrefix,"ms-").replace(rdashAlpha,fcamelCase);}
var acceptData=function(owner){return owner.nodeType===1||owner.nodeType===9||!(+owner.nodeType);};function Data(){this.expando=jQuery.expando+Data.uid++;}
Data.uid=1;Data.prototype={cache:function(owner){var value=owner[this.expando];if(!value){value={};if(acceptData(owner)){if(owner.nodeType){owner[this.expando]=value;}else{Object.defineProperty(owner,this.expando,{value:value,configurable:true});}}}
return value;},set:function(owner,data,value){var prop,cache=this.cache(owner);if(typeof data==="string"){cache[camelCase(data)]=value;}else{for(prop in data){cache[camelCase(prop)]=data[prop];}}
return cache;},get:function(owner,key){return key===undefined?this.cache(owner):owner[this.expando]&&owner[this.expando][camelCase(key)];},access:function(owner,key,value){if(key===undefined||((key&&typeof key==="string")&&value===undefined)){return this.get(owner,key);}
this.set(owner,key,value);return value!==undefined?value:key;},remove:function(owner,key){var i,cache=owner[this.expando];if(cache===undefined){return;}
if(key!==undefined){if(Array.isArray(key)){key=key.map(camelCase);}else{key=camelCase(key);key=key in cache?[key]:(key.match(rnothtmlwhite)||[]);}
i=key.length;while(i--){delete cache[key[i]];}}
if(key===undefined||jQuery.isEmptyObject(cache)){if(owner.nodeType){owner[this.expando]=undefined;}else{delete owner[this.expando];}}},hasData:function(owner){var cache=owner[this.expando];return cache!==undefined&&!jQuery.isEmptyObject(cache);}};var dataPriv=new Data();var dataUser=new Data();var rbrace=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,rmultiDash=/[A-Z]/g;function getData(data){if(data==="true"){return true;}
if(data==="false"){return false;}
if(data==="null"){return null;}
if(data===+data+""){return+data;}
if(rbrace.test(data)){return JSON.parse(data);}
return data;}
function dataAttr(elem,key,data){var name;if(data===undefined&&elem.nodeType===1){name="data-"+key.replace(rmultiDash,"-$&").toLowerCase();data=elem.getAttribute(name);if(typeof data==="string"){try{data=getData(data);}catch(e){}
dataUser.set(elem,key,data);}else{data=undefined;}}
return data;}
jQuery.extend({hasData:function(elem){return dataUser.hasData(elem)||dataPriv.hasData(elem);},data:function(elem,name,data){return dataUser.access(elem,name,data);},removeData:function(elem,name){dataUser.remove(elem,name);},_data:function(elem,name,data){return dataPriv.access(elem,name,data);},_removeData:function(elem,name){dataPriv.remove(elem,name);}});jQuery.fn.extend({data:function(key,value){var i,name,data,elem=this[0],attrs=elem&&elem.attributes;if(key===undefined){if(this.length){data=dataUser.get(elem);if(elem.nodeType===1&&!dataPriv.get(elem,"hasDataAttrs")){i=attrs.length;while(i--){if(attrs[i]){name=attrs[i].name;if(name.indexOf("data-")===0){name=camelCase(name.slice(5));dataAttr(elem,name,data[name]);}}}
dataPriv.set(elem,"hasDataAttrs",true);}}
return data;}
if(typeof key==="object"){return this.each(function(){dataUser.set(this,key);});}
return access(this,function(value){var data;if(elem&&value===undefined){data=dataUser.get(elem,key);if(data!==undefined){return data;}
data=dataAttr(elem,key);if(data!==undefined){return data;}
return;}
this.each(function(){dataUser.set(this,key,value);});},null,value,arguments.length>1,null,true);},removeData:function(key){return this.each(function(){dataUser.remove(this,key);});}});jQuery.extend({queue:function(elem,type,data){var queue;if(elem){type=(type||"fx")+"queue";queue=dataPriv.get(elem,type);if(data){if(!queue||Array.isArray(data)){queue=dataPriv.access(elem,type,jQuery.makeArray(data));}else{queue.push(data);}}
return queue||[];}},dequeue:function(elem,type){type=type||"fx";var queue=jQuery.queue(elem,type),startLength=queue.length,fn=queue.shift(),hooks=jQuery._queueHooks(elem,type),next=function(){jQuery.dequeue(elem,type);};if(fn==="inprogress"){fn=queue.shift();startLength--;}
if(fn){if(type==="fx"){queue.unshift("inprogress");}
delete hooks.stop;fn.call(elem,next,hooks);}
if(!startLength&&hooks){hooks.empty.fire();}},_queueHooks:function(elem,type){var key=type+"queueHooks";return dataPriv.get(elem,key)||dataPriv.access(elem,key,{empty:jQuery.Callbacks("once memory").add(function(){dataPriv.remove(elem,[type+"queue",key]);})});}});jQuery.fn.extend({queue:function(type,data){var setter=2;if(typeof type!=="string"){data=type;type="fx";setter--;}
if(arguments.length<setter){return jQuery.queue(this[0],type);}
return data===undefined?this:this.each(function(){var queue=jQuery.queue(this,type,data);jQuery._queueHooks(this,type);if(type==="fx"&&queue[0]!=="inprogress"){jQuery.dequeue(this,type);}});},dequeue:function(type){return this.each(function(){jQuery.dequeue(this,type);});},clearQueue:function(type){return this.queue(type||"fx",[]);},promise:function(type,obj){var tmp,count=1,defer=jQuery.Deferred(),elements=this,i=this.length,resolve=function(){if(!(--count)){defer.resolveWith(elements,[elements]);}};if(typeof type!=="string"){obj=type;type=undefined;}
type=type||"fx";while(i--){tmp=dataPriv.get(elements[i],type+"queueHooks");if(tmp&&tmp.empty){count++;tmp.empty.add(resolve);}}
resolve();return defer.promise(obj);}});var pnum=(/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;var rcssNum=new RegExp("^(?:([+-])=|)("+pnum+")([a-z%]*)$","i");var cssExpand=["Top","Right","Bottom","Left"];var documentElement=document.documentElement;var isAttached=function(elem){return jQuery.contains(elem.ownerDocument,elem);},composed={composed:true};if(documentElement.getRootNode){isAttached=function(elem){return jQuery.contains(elem.ownerDocument,elem)||elem.getRootNode(composed)===elem.ownerDocument;};}
var isHiddenWithinTree=function(elem,el){elem=el||elem;return elem.style.display==="none"||elem.style.display===""&&isAttached(elem)&&jQuery.css(elem,"display")==="none";};function adjustCSS(elem,prop,valueParts,tween){var adjusted,scale,maxIterations=20,currentValue=tween?function(){return tween.cur();}:function(){return jQuery.css(elem,prop,"");},initial=currentValue(),unit=valueParts&&valueParts[3]||(jQuery.cssNumber[prop]?"":"px"),initialInUnit=elem.nodeType&&(jQuery.cssNumber[prop]||unit!=="px"&&+initial)&&rcssNum.exec(jQuery.css(elem,prop));if(initialInUnit&&initialInUnit[3]!==unit){initial=initial/2;unit=unit||initialInUnit[3];initialInUnit=+initial||1;while(maxIterations--){jQuery.style(elem,prop,initialInUnit+unit);if((1-scale)*(1-(scale=currentValue()/initial||0.5))<=0){maxIterations=0;}
initialInUnit=initialInUnit/scale;}
initialInUnit=initialInUnit*2;jQuery.style(elem,prop,initialInUnit+unit);valueParts=valueParts||[];}
if(valueParts){initialInUnit=+initialInUnit||+initial||0;adjusted=valueParts[1]?initialInUnit+(valueParts[1]+1)*valueParts[2]:+valueParts[2];if(tween){tween.unit=unit;tween.start=initialInUnit;tween.end=adjusted;}}
return adjusted;}
var defaultDisplayMap={};function getDefaultDisplay(elem){var temp,doc=elem.ownerDocument,nodeName=elem.nodeName,display=defaultDisplayMap[nodeName];if(display){return display;}
temp=doc.body.appendChild(doc.createElement(nodeName));display=jQuery.css(temp,"display");temp.parentNode.removeChild(temp);if(display==="none"){display="block";}
defaultDisplayMap[nodeName]=display;return display;}
function showHide(elements,show){var display,elem,values=[],index=0,length=elements.length;for(;index<length;index++){elem=elements[index];if(!elem.style){continue;}
display=elem.style.display;if(show){if(display==="none"){values[index]=dataPriv.get(elem,"display")||null;if(!values[index]){elem.style.display="";}}
if(elem.style.display===""&&isHiddenWithinTree(elem)){values[index]=getDefaultDisplay(elem);}}else{if(display!=="none"){values[index]="none";dataPriv.set(elem,"display",display);}}}
for(index=0;index<length;index++){if(values[index]!=null){elements[index].style.display=values[index];}}
return elements;}
jQuery.fn.extend({show:function(){return showHide(this,true);},hide:function(){return showHide(this);},toggle:function(state){if(typeof state==="boolean"){return state?this.show():this.hide();}
return this.each(function(){if(isHiddenWithinTree(this)){jQuery(this).show();}else{jQuery(this).hide();}});}});var rcheckableType=(/^(?:checkbox|radio)$/i);var rtagName=(/<([a-z][^\/\0>\x20\t\r\n\f]*)/i);var rscriptType=(/^$|^module$|\/(?:java|ecma)script/i);(function(){var fragment=document.createDocumentFragment(),div=fragment.appendChild(document.createElement("div")),input=document.createElement("input");input.setAttribute("type","radio");input.setAttribute("checked","checked");input.setAttribute("name","t");div.appendChild(input);support.checkClone=div.cloneNode(true).cloneNode(true).lastChild.checked;div.innerHTML="<textarea>x</textarea>";support.noCloneChecked=!!div.cloneNode(true).lastChild.defaultValue;div.innerHTML="<option></option>";support.option=!!div.lastChild;})();var wrapMap={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};wrapMap.tbody=wrapMap.tfoot=wrapMap.colgroup=wrapMap.caption=wrapMap.thead;wrapMap.th=wrapMap.td;if(!support.option){wrapMap.optgroup=wrapMap.option=[1,"<select multiple='multiple'>","</select>"];}
function getAll(context,tag){var ret;if(typeof context.getElementsByTagName!=="undefined"){ret=context.getElementsByTagName(tag||"*");}else if(typeof context.querySelectorAll!=="undefined"){ret=context.querySelectorAll(tag||"*");}else{ret=[];}
if(tag===undefined||tag&&nodeName(context,tag)){return jQuery.merge([context],ret);}
return ret;}
function setGlobalEval(elems,refElements){var i=0,l=elems.length;for(;i<l;i++){dataPriv.set(elems[i],"globalEval",!refElements||dataPriv.get(refElements[i],"globalEval"));}}
var rhtml=/<|&#?\w+;/;function buildFragment(elems,context,scripts,selection,ignored){var elem,tmp,tag,wrap,attached,j,fragment=context.createDocumentFragment(),nodes=[],i=0,l=elems.length;for(;i<l;i++){elem=elems[i];if(elem||elem===0){if(toType(elem)==="object"){jQuery.merge(nodes,elem.nodeType?[elem]:elem);}else if(!rhtml.test(elem)){nodes.push(context.createTextNode(elem));}else{tmp=tmp||fragment.appendChild(context.createElement("div"));tag=(rtagName.exec(elem)||["",""])[1].toLowerCase();wrap=wrapMap[tag]||wrapMap._default;tmp.innerHTML=wrap[1]+jQuery.htmlPrefilter(elem)+wrap[2];j=wrap[0];while(j--){tmp=tmp.lastChild;}
jQuery.merge(nodes,tmp.childNodes);tmp=fragment.firstChild;tmp.textContent="";}}}
fragment.textContent="";i=0;while((elem=nodes[i++])){if(selection&&jQuery.inArray(elem,selection)>-1){if(ignored){ignored.push(elem);}
continue;}
attached=isAttached(elem);tmp=getAll(fragment.appendChild(elem),"script");if(attached){setGlobalEval(tmp);}
if(scripts){j=0;while((elem=tmp[j++])){if(rscriptType.test(elem.type||"")){scripts.push(elem);}}}}
return fragment;}
var rtypenamespace=/^([^.]*)(?:\.(.+)|)/;function returnTrue(){return true;}
function returnFalse(){return false;}
function expectSync(elem,type){return(elem===safeActiveElement())===(type==="focus");}
function safeActiveElement(){try{return document.activeElement;}catch(err){}}
function on(elem,types,selector,data,fn,one){var origFn,type;if(typeof types==="object"){if(typeof selector!=="string"){data=data||selector;selector=undefined;}
for(type in types){on(elem,type,selector,data,types[type],one);}
return elem;}
if(data==null&&fn==null){fn=selector;data=selector=undefined;}else if(fn==null){if(typeof selector==="string"){fn=data;data=undefined;}else{fn=data;data=selector;selector=undefined;}}
if(fn===false){fn=returnFalse;}else if(!fn){return elem;}
if(one===1){origFn=fn;fn=function(event){jQuery().off(event);return origFn.apply(this,arguments);};fn.guid=origFn.guid||(origFn.guid=jQuery.guid++);}
return elem.each(function(){jQuery.event.add(this,types,fn,data,selector);});}
jQuery.event={global:{},add:function(elem,types,handler,data,selector){var handleObjIn,eventHandle,tmp,events,t,handleObj,special,handlers,type,namespaces,origType,elemData=dataPriv.get(elem);if(!acceptData(elem)){return;}
if(handler.handler){handleObjIn=handler;handler=handleObjIn.handler;selector=handleObjIn.selector;}
if(selector){jQuery.find.matchesSelector(documentElement,selector);}
if(!handler.guid){handler.guid=jQuery.guid++;}
if(!(events=elemData.events)){events=elemData.events=Object.create(null);}
if(!(eventHandle=elemData.handle)){eventHandle=elemData.handle=function(e){return typeof jQuery!=="undefined"&&jQuery.event.triggered!==e.type?jQuery.event.dispatch.apply(elem,arguments):undefined;};}
types=(types||"").match(rnothtmlwhite)||[""];t=types.length;while(t--){tmp=rtypenamespace.exec(types[t])||[];type=origType=tmp[1];namespaces=(tmp[2]||"").split(".").sort();if(!type){continue;}
special=jQuery.event.special[type]||{};type=(selector?special.delegateType:special.bindType)||type;special=jQuery.event.special[type]||{};handleObj=jQuery.extend({type:type,origType:origType,data:data,handler:handler,guid:handler.guid,selector:selector,needsContext:selector&&jQuery.expr.match.needsContext.test(selector),namespace:namespaces.join(".")},handleObjIn);if(!(handlers=events[type])){handlers=events[type]=[];handlers.delegateCount=0;if(!special.setup||special.setup.call(elem,data,namespaces,eventHandle)===false){if(elem.addEventListener){elem.addEventListener(type,eventHandle);}}}
if(special.add){special.add.call(elem,handleObj);if(!handleObj.handler.guid){handleObj.handler.guid=handler.guid;}}
if(selector){handlers.splice(handlers.delegateCount++,0,handleObj);}else{handlers.push(handleObj);}
jQuery.event.global[type]=true;}},remove:function(elem,types,handler,selector,mappedTypes){var j,origCount,tmp,events,t,handleObj,special,handlers,type,namespaces,origType,elemData=dataPriv.hasData(elem)&&dataPriv.get(elem);if(!elemData||!(events=elemData.events)){return;}
types=(types||"").match(rnothtmlwhite)||[""];t=types.length;while(t--){tmp=rtypenamespace.exec(types[t])||[];type=origType=tmp[1];namespaces=(tmp[2]||"").split(".").sort();if(!type){for(type in events){jQuery.event.remove(elem,type+types[t],handler,selector,true);}
continue;}
special=jQuery.event.special[type]||{};type=(selector?special.delegateType:special.bindType)||type;handlers=events[type]||[];tmp=tmp[2]&&new RegExp("(^|\\.)"+namespaces.join("\\.(?:.*\\.|)")+"(\\.|$)");origCount=j=handlers.length;while(j--){handleObj=handlers[j];if((mappedTypes||origType===handleObj.origType)&&(!handler||handler.guid===handleObj.guid)&&(!tmp||tmp.test(handleObj.namespace))&&(!selector||selector===handleObj.selector||selector==="**"&&handleObj.selector)){handlers.splice(j,1);if(handleObj.selector){handlers.delegateCount--;}
if(special.remove){special.remove.call(elem,handleObj);}}}
if(origCount&&!handlers.length){if(!special.teardown||special.teardown.call(elem,namespaces,elemData.handle)===false){jQuery.removeEvent(elem,type,elemData.handle);}
delete events[type];}}
if(jQuery.isEmptyObject(events)){dataPriv.remove(elem,"handle events");}},dispatch:function(nativeEvent){var i,j,ret,matched,handleObj,handlerQueue,args=new Array(arguments.length),event=jQuery.event.fix(nativeEvent),handlers=(dataPriv.get(this,"events")||Object.create(null))[event.type]||[],special=jQuery.event.special[event.type]||{};args[0]=event;for(i=1;i<arguments.length;i++){args[i]=arguments[i];}
event.delegateTarget=this;if(special.preDispatch&&special.preDispatch.call(this,event)===false){return;}
handlerQueue=jQuery.event.handlers.call(this,event,handlers);i=0;while((matched=handlerQueue[i++])&&!event.isPropagationStopped()){event.currentTarget=matched.elem;j=0;while((handleObj=matched.handlers[j++])&&!event.isImmediatePropagationStopped()){if(!event.rnamespace||handleObj.namespace===false||event.rnamespace.test(handleObj.namespace)){event.handleObj=handleObj;event.data=handleObj.data;ret=((jQuery.event.special[handleObj.origType]||{}).handle||handleObj.handler).apply(matched.elem,args);if(ret!==undefined){if((event.result=ret)===false){event.preventDefault();event.stopPropagation();}}}}}
if(special.postDispatch){special.postDispatch.call(this,event);}
return event.result;},handlers:function(event,handlers){var i,handleObj,sel,matchedHandlers,matchedSelectors,handlerQueue=[],delegateCount=handlers.delegateCount,cur=event.target;if(delegateCount&&cur.nodeType&&!(event.type==="click"&&event.button>=1)){for(;cur!==this;cur=cur.parentNode||this){if(cur.nodeType===1&&!(event.type==="click"&&cur.disabled===true)){matchedHandlers=[];matchedSelectors={};for(i=0;i<delegateCount;i++){handleObj=handlers[i];sel=handleObj.selector+" ";if(matchedSelectors[sel]===undefined){matchedSelectors[sel]=handleObj.needsContext?jQuery(sel,this).index(cur)>-1:jQuery.find(sel,this,null,[cur]).length;}
if(matchedSelectors[sel]){matchedHandlers.push(handleObj);}}
if(matchedHandlers.length){handlerQueue.push({elem:cur,handlers:matchedHandlers});}}}}
cur=this;if(delegateCount<handlers.length){handlerQueue.push({elem:cur,handlers:handlers.slice(delegateCount)});}
return handlerQueue;},addProp:function(name,hook){Object.defineProperty(jQuery.Event.prototype,name,{enumerable:true,configurable:true,get:isFunction(hook)?function(){if(this.originalEvent){return hook(this.originalEvent);}}:function(){if(this.originalEvent){return this.originalEvent[name];}},set:function(value){Object.defineProperty(this,name,{enumerable:true,configurable:true,writable:true,value:value});}});},fix:function(originalEvent){return originalEvent[jQuery.expando]?originalEvent:new jQuery.Event(originalEvent);},special:{load:{noBubble:true},click:{setup:function(data){var el=this||data;if(rcheckableType.test(el.type)&&el.click&&nodeName(el,"input")){leverageNative(el,"click",returnTrue);}
return false;},trigger:function(data){var el=this||data;if(rcheckableType.test(el.type)&&el.click&&nodeName(el,"input")){leverageNative(el,"click");}
return true;},_default:function(event){var target=event.target;return rcheckableType.test(target.type)&&target.click&&nodeName(target,"input")&&dataPriv.get(target,"click")||nodeName(target,"a");}},beforeunload:{postDispatch:function(event){if(event.result!==undefined&&event.originalEvent){event.originalEvent.returnValue=event.result;}}}}};function leverageNative(el,type,expectSync){if(!expectSync){if(dataPriv.get(el,type)===undefined){jQuery.event.add(el,type,returnTrue);}
return;}
dataPriv.set(el,type,false);jQuery.event.add(el,type,{namespace:false,handler:function(event){var notAsync,result,saved=dataPriv.get(this,type);if((event.isTrigger&1)&&this[type]){if(!saved.length){saved=slice.call(arguments);dataPriv.set(this,type,saved);notAsync=expectSync(this,type);this[type]();result=dataPriv.get(this,type);if(saved!==result||notAsync){dataPriv.set(this,type,false);}else{result={};}
if(saved!==result){event.stopImmediatePropagation();event.preventDefault();return result&&result.value;}}else if((jQuery.event.special[type]||{}).delegateType){event.stopPropagation();}}else if(saved.length){dataPriv.set(this,type,{value:jQuery.event.trigger(jQuery.extend(saved[0],jQuery.Event.prototype),saved.slice(1),this)});event.stopImmediatePropagation();}}});}
jQuery.removeEvent=function(elem,type,handle){if(elem.removeEventListener){elem.removeEventListener(type,handle);}};jQuery.Event=function(src,props){if(!(this instanceof jQuery.Event)){return new jQuery.Event(src,props);}
if(src&&src.type){this.originalEvent=src;this.type=src.type;this.isDefaultPrevented=src.defaultPrevented||src.defaultPrevented===undefined&&src.returnValue===false?returnTrue:returnFalse;this.target=(src.target&&src.target.nodeType===3)?src.target.parentNode:src.target;this.currentTarget=src.currentTarget;this.relatedTarget=src.relatedTarget;}else{this.type=src;}
if(props){jQuery.extend(this,props);}
this.timeStamp=src&&src.timeStamp||Date.now();this[jQuery.expando]=true;};jQuery.Event.prototype={constructor:jQuery.Event,isDefaultPrevented:returnFalse,isPropagationStopped:returnFalse,isImmediatePropagationStopped:returnFalse,isSimulated:false,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=returnTrue;if(e&&!this.isSimulated){e.preventDefault();}},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=returnTrue;if(e&&!this.isSimulated){e.stopPropagation();}},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=returnTrue;if(e&&!this.isSimulated){e.stopImmediatePropagation();}
this.stopPropagation();}};jQuery.each({altKey:true,bubbles:true,cancelable:true,changedTouches:true,ctrlKey:true,detail:true,eventPhase:true,metaKey:true,pageX:true,pageY:true,shiftKey:true,view:true,"char":true,code:true,charCode:true,key:true,keyCode:true,button:true,buttons:true,clientX:true,clientY:true,offsetX:true,offsetY:true,pointerId:true,pointerType:true,screenX:true,screenY:true,targetTouches:true,toElement:true,touches:true,which:true},jQuery.event.addProp);jQuery.each({focus:"focusin",blur:"focusout"},function(type,delegateType){jQuery.event.special[type]={setup:function(){leverageNative(this,type,expectSync);return false;},trigger:function(){leverageNative(this,type);return true;},_default:function(event){return dataPriv.get(event.target,type);},delegateType:delegateType};});jQuery.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(orig,fix){jQuery.event.special[orig]={delegateType:fix,bindType:fix,handle:function(event){var ret,target=this,related=event.relatedTarget,handleObj=event.handleObj;if(!related||(related!==target&&!jQuery.contains(target,related))){event.type=handleObj.origType;ret=handleObj.handler.apply(this,arguments);event.type=fix;}
return ret;}};});jQuery.fn.extend({on:function(types,selector,data,fn){return on(this,types,selector,data,fn);},one:function(types,selector,data,fn){return on(this,types,selector,data,fn,1);},off:function(types,selector,fn){var handleObj,type;if(types&&types.preventDefault&&types.handleObj){handleObj=types.handleObj;jQuery(types.delegateTarget).off(handleObj.namespace?handleObj.origType+"."+handleObj.namespace:handleObj.origType,handleObj.selector,handleObj.handler);return this;}
if(typeof types==="object"){for(type in types){this.off(type,selector,types[type]);}
return this;}
if(selector===false||typeof selector==="function"){fn=selector;selector=undefined;}
if(fn===false){fn=returnFalse;}
return this.each(function(){jQuery.event.remove(this,types,fn,selector);});}});var
rnoInnerhtml=/<script|<style|<link/i,rchecked=/checked\s*(?:[^=]|=\s*.checked.)/i,rcleanScript=/^\s*<!\[CDATA\[|\]\]>\s*$/g;function manipulationTarget(elem,content){if(nodeName(elem,"table")&&nodeName(content.nodeType!==11?content:content.firstChild,"tr")){return jQuery(elem).children("tbody")[0]||elem;}
return elem;}
function disableScript(elem){elem.type=(elem.getAttribute("type")!==null)+"/"+elem.type;return elem;}
function restoreScript(elem){if((elem.type||"").slice(0,5)==="true/"){elem.type=elem.type.slice(5);}else{elem.removeAttribute("type");}
return elem;}
function cloneCopyEvent(src,dest){var i,l,type,pdataOld,udataOld,udataCur,events;if(dest.nodeType!==1){return;}
if(dataPriv.hasData(src)){pdataOld=dataPriv.get(src);events=pdataOld.events;if(events){dataPriv.remove(dest,"handle events");for(type in events){for(i=0,l=events[type].length;i<l;i++){jQuery.event.add(dest,type,events[type][i]);}}}}
if(dataUser.hasData(src)){udataOld=dataUser.access(src);udataCur=jQuery.extend({},udataOld);dataUser.set(dest,udataCur);}}
function fixInput(src,dest){var nodeName=dest.nodeName.toLowerCase();if(nodeName==="input"&&rcheckableType.test(src.type)){dest.checked=src.checked;}else if(nodeName==="input"||nodeName==="textarea"){dest.defaultValue=src.defaultValue;}}
function domManip(collection,args,callback,ignored){args=flat(args);var fragment,first,scripts,hasScripts,node,doc,i=0,l=collection.length,iNoClone=l-1,value=args[0],valueIsFunction=isFunction(value);if(valueIsFunction||(l>1&&typeof value==="string"&&!support.checkClone&&rchecked.test(value))){return collection.each(function(index){var self=collection.eq(index);if(valueIsFunction){args[0]=value.call(this,index,self.html());}
domManip(self,args,callback,ignored);});}
if(l){fragment=buildFragment(args,collection[0].ownerDocument,false,collection,ignored);first=fragment.firstChild;if(fragment.childNodes.length===1){fragment=first;}
if(first||ignored){scripts=jQuery.map(getAll(fragment,"script"),disableScript);hasScripts=scripts.length;for(;i<l;i++){node=fragment;if(i!==iNoClone){node=jQuery.clone(node,true,true);if(hasScripts){jQuery.merge(scripts,getAll(node,"script"));}}
callback.call(collection[i],node,i);}
if(hasScripts){doc=scripts[scripts.length-1].ownerDocument;jQuery.map(scripts,restoreScript);for(i=0;i<hasScripts;i++){node=scripts[i];if(rscriptType.test(node.type||"")&&!dataPriv.access(node,"globalEval")&&jQuery.contains(doc,node)){if(node.src&&(node.type||"").toLowerCase()!=="module"){if(jQuery._evalUrl&&!node.noModule){jQuery._evalUrl(node.src,{nonce:node.nonce||node.getAttribute("nonce")},doc);}}else{DOMEval(node.textContent.replace(rcleanScript,""),node,doc);}}}}}}
return collection;}
function remove(elem,selector,keepData){var node,nodes=selector?jQuery.filter(selector,elem):elem,i=0;for(;(node=nodes[i])!=null;i++){if(!keepData&&node.nodeType===1){jQuery.cleanData(getAll(node));}
if(node.parentNode){if(keepData&&isAttached(node)){setGlobalEval(getAll(node,"script"));}
node.parentNode.removeChild(node);}}
return elem;}
jQuery.extend({htmlPrefilter:function(html){return html;},clone:function(elem,dataAndEvents,deepDataAndEvents){var i,l,srcElements,destElements,clone=elem.cloneNode(true),inPage=isAttached(elem);if(!support.noCloneChecked&&(elem.nodeType===1||elem.nodeType===11)&&!jQuery.isXMLDoc(elem)){destElements=getAll(clone);srcElements=getAll(elem);for(i=0,l=srcElements.length;i<l;i++){fixInput(srcElements[i],destElements[i]);}}
if(dataAndEvents){if(deepDataAndEvents){srcElements=srcElements||getAll(elem);destElements=destElements||getAll(clone);for(i=0,l=srcElements.length;i<l;i++){cloneCopyEvent(srcElements[i],destElements[i]);}}else{cloneCopyEvent(elem,clone);}}
destElements=getAll(clone,"script");if(destElements.length>0){setGlobalEval(destElements,!inPage&&getAll(elem,"script"));}
return clone;},cleanData:function(elems){var data,elem,type,special=jQuery.event.special,i=0;for(;(elem=elems[i])!==undefined;i++){if(acceptData(elem)){if((data=elem[dataPriv.expando])){if(data.events){for(type in data.events){if(special[type]){jQuery.event.remove(elem,type);}else{jQuery.removeEvent(elem,type,data.handle);}}}
elem[dataPriv.expando]=undefined;}
if(elem[dataUser.expando]){elem[dataUser.expando]=undefined;}}}}});jQuery.fn.extend({detach:function(selector){return remove(this,selector,true);},remove:function(selector){return remove(this,selector);},text:function(value){return access(this,function(value){return value===undefined?jQuery.text(this):this.empty().each(function(){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){this.textContent=value;}});},null,value,arguments.length);},append:function(){return domManip(this,arguments,function(elem){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){var target=manipulationTarget(this,elem);target.appendChild(elem);}});},prepend:function(){return domManip(this,arguments,function(elem){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){var target=manipulationTarget(this,elem);target.insertBefore(elem,target.firstChild);}});},before:function(){return domManip(this,arguments,function(elem){if(this.parentNode){this.parentNode.insertBefore(elem,this);}});},after:function(){return domManip(this,arguments,function(elem){if(this.parentNode){this.parentNode.insertBefore(elem,this.nextSibling);}});},empty:function(){var elem,i=0;for(;(elem=this[i])!=null;i++){if(elem.nodeType===1){jQuery.cleanData(getAll(elem,false));elem.textContent="";}}
return this;},clone:function(dataAndEvents,deepDataAndEvents){dataAndEvents=dataAndEvents==null?false:dataAndEvents;deepDataAndEvents=deepDataAndEvents==null?dataAndEvents:deepDataAndEvents;return this.map(function(){return jQuery.clone(this,dataAndEvents,deepDataAndEvents);});},html:function(value){return access(this,function(value){var elem=this[0]||{},i=0,l=this.length;if(value===undefined&&elem.nodeType===1){return elem.innerHTML;}
if(typeof value==="string"&&!rnoInnerhtml.test(value)&&!wrapMap[(rtagName.exec(value)||["",""])[1].toLowerCase()]){value=jQuery.htmlPrefilter(value);try{for(;i<l;i++){elem=this[i]||{};if(elem.nodeType===1){jQuery.cleanData(getAll(elem,false));elem.innerHTML=value;}}
elem=0;}catch(e){}}
if(elem){this.empty().append(value);}},null,value,arguments.length);},replaceWith:function(){var ignored=[];return domManip(this,arguments,function(elem){var parent=this.parentNode;if(jQuery.inArray(this,ignored)<0){jQuery.cleanData(getAll(this));if(parent){parent.replaceChild(elem,this);}}},ignored);}});jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(name,original){jQuery.fn[name]=function(selector){var elems,ret=[],insert=jQuery(selector),last=insert.length-1,i=0;for(;i<=last;i++){elems=i===last?this:this.clone(true);jQuery(insert[i])[original](elems);push.apply(ret,elems.get());}
return this.pushStack(ret);};});var rnumnonpx=new RegExp("^("+pnum+")(?!px)[a-z%]+$","i");var rcustomProp=/^--/;var getStyles=function(elem){var view=elem.ownerDocument.defaultView;if(!view||!view.opener){view=window;}
return view.getComputedStyle(elem);};var swap=function(elem,options,callback){var ret,name,old={};for(name in options){old[name]=elem.style[name];elem.style[name]=options[name];}
ret=callback.call(elem);for(name in options){elem.style[name]=old[name];}
return ret;};var rboxStyle=new RegExp(cssExpand.join("|"),"i");var whitespace="[\\x20\\t\\r\\n\\f]";var rtrimCSS=new RegExp("^"+whitespace+"+|((?:^|[^\\\\])(?:\\\\.)*)"+whitespace+"+$","g");(function(){function computeStyleTests(){if(!div){return;}
container.style.cssText="position:absolute;left:-11111px;width:60px;"+"margin-top:1px;padding:0;border:0";div.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;"+"margin:auto;border:1px;padding:1px;"+"width:60%;top:1%";documentElement.appendChild(container).appendChild(div);var divStyle=window.getComputedStyle(div);pixelPositionVal=divStyle.top!=="1%";reliableMarginLeftVal=roundPixelMeasures(divStyle.marginLeft)===12;div.style.right="60%";pixelBoxStylesVal=roundPixelMeasures(divStyle.right)===36;boxSizingReliableVal=roundPixelMeasures(divStyle.width)===36;div.style.position="absolute";scrollboxSizeVal=roundPixelMeasures(div.offsetWidth/3)===12;documentElement.removeChild(container);div=null;}
function roundPixelMeasures(measure){return Math.round(parseFloat(measure));}
var pixelPositionVal,boxSizingReliableVal,scrollboxSizeVal,pixelBoxStylesVal,reliableTrDimensionsVal,reliableMarginLeftVal,container=document.createElement("div"),div=document.createElement("div");if(!div.style){return;}
div.style.backgroundClip="content-box";div.cloneNode(true).style.backgroundClip="";support.clearCloneStyle=div.style.backgroundClip==="content-box";jQuery.extend(support,{boxSizingReliable:function(){computeStyleTests();return boxSizingReliableVal;},pixelBoxStyles:function(){computeStyleTests();return pixelBoxStylesVal;},pixelPosition:function(){computeStyleTests();return pixelPositionVal;},reliableMarginLeft:function(){computeStyleTests();return reliableMarginLeftVal;},scrollboxSize:function(){computeStyleTests();return scrollboxSizeVal;},reliableTrDimensions:function(){var table,tr,trChild,trStyle;if(reliableTrDimensionsVal==null){table=document.createElement("table");tr=document.createElement("tr");trChild=document.createElement("div");table.style.cssText="position:absolute;left:-11111px;border-collapse:separate";tr.style.cssText="border:1px solid";tr.style.height="1px";trChild.style.height="9px";trChild.style.display="block";documentElement.appendChild(table).appendChild(tr).appendChild(trChild);trStyle=window.getComputedStyle(tr);reliableTrDimensionsVal=(parseInt(trStyle.height,10)+
parseInt(trStyle.borderTopWidth,10)+
parseInt(trStyle.borderBottomWidth,10))===tr.offsetHeight;documentElement.removeChild(table);}
return reliableTrDimensionsVal;}});})();function curCSS(elem,name,computed){var width,minWidth,maxWidth,ret,isCustomProp=rcustomProp.test(name),style=elem.style;computed=computed||getStyles(elem);if(computed){ret=computed.getPropertyValue(name)||computed[name];if(isCustomProp&&ret){ret=ret.replace(rtrimCSS,"$1")||undefined;}
if(ret===""&&!isAttached(elem)){ret=jQuery.style(elem,name);}
if(!support.pixelBoxStyles()&&rnumnonpx.test(ret)&&rboxStyle.test(name)){width=style.width;minWidth=style.minWidth;maxWidth=style.maxWidth;style.minWidth=style.maxWidth=style.width=ret;ret=computed.width;style.width=width;style.minWidth=minWidth;style.maxWidth=maxWidth;}}
return ret!==undefined?ret+"":ret;}
function addGetHookIf(conditionFn,hookFn){return{get:function(){if(conditionFn()){delete this.get;return;}
return(this.get=hookFn).apply(this,arguments);}};}
var cssPrefixes=["Webkit","Moz","ms"],emptyStyle=document.createElement("div").style,vendorProps={};function vendorPropName(name){var capName=name[0].toUpperCase()+name.slice(1),i=cssPrefixes.length;while(i--){name=cssPrefixes[i]+capName;if(name in emptyStyle){return name;}}}
function finalPropName(name){var final=jQuery.cssProps[name]||vendorProps[name];if(final){return final;}
if(name in emptyStyle){return name;}
return vendorProps[name]=vendorPropName(name)||name;}
var
rdisplayswap=/^(none|table(?!-c[ea]).+)/,cssShow={position:"absolute",visibility:"hidden",display:"block"},cssNormalTransform={letterSpacing:"0",fontWeight:"400"};function setPositiveNumber(_elem,value,subtract){var matches=rcssNum.exec(value);return matches?Math.max(0,matches[2]-(subtract||0))+(matches[3]||"px"):value;}
function boxModelAdjustment(elem,dimension,box,isBorderBox,styles,computedVal){var i=dimension==="width"?1:0,extra=0,delta=0;if(box===(isBorderBox?"border":"content")){return 0;}
for(;i<4;i+=2){if(box==="margin"){delta+=jQuery.css(elem,box+cssExpand[i],true,styles);}
if(!isBorderBox){delta+=jQuery.css(elem,"padding"+cssExpand[i],true,styles);if(box!=="padding"){delta+=jQuery.css(elem,"border"+cssExpand[i]+"Width",true,styles);}else{extra+=jQuery.css(elem,"border"+cssExpand[i]+"Width",true,styles);}}else{if(box==="content"){delta-=jQuery.css(elem,"padding"+cssExpand[i],true,styles);}
if(box!=="margin"){delta-=jQuery.css(elem,"border"+cssExpand[i]+"Width",true,styles);}}}
if(!isBorderBox&&computedVal>=0){delta+=Math.max(0,Math.ceil(elem["offset"+dimension[0].toUpperCase()+dimension.slice(1)]-
computedVal-
delta-
extra-
0.5))||0;}
return delta;}
function getWidthOrHeight(elem,dimension,extra){var styles=getStyles(elem),boxSizingNeeded=!support.boxSizingReliable()||extra,isBorderBox=boxSizingNeeded&&jQuery.css(elem,"boxSizing",false,styles)==="border-box",valueIsBorderBox=isBorderBox,val=curCSS(elem,dimension,styles),offsetProp="offset"+dimension[0].toUpperCase()+dimension.slice(1);if(rnumnonpx.test(val)){if(!extra){return val;}
val="auto";}
if((!support.boxSizingReliable()&&isBorderBox||!support.reliableTrDimensions()&&nodeName(elem,"tr")||val==="auto"||!parseFloat(val)&&jQuery.css(elem,"display",false,styles)==="inline")&&elem.getClientRects().length){isBorderBox=jQuery.css(elem,"boxSizing",false,styles)==="border-box";valueIsBorderBox=offsetProp in elem;if(valueIsBorderBox){val=elem[offsetProp];}}
val=parseFloat(val)||0;return(val+
boxModelAdjustment(elem,dimension,extra||(isBorderBox?"border":"content"),valueIsBorderBox,styles,val))+"px";}
jQuery.extend({cssHooks:{opacity:{get:function(elem,computed){if(computed){var ret=curCSS(elem,"opacity");return ret===""?"1":ret;}}}},cssNumber:{"animationIterationCount":true,"columnCount":true,"fillOpacity":true,"flexGrow":true,"flexShrink":true,"fontWeight":true,"gridArea":true,"gridColumn":true,"gridColumnEnd":true,"gridColumnStart":true,"gridRow":true,"gridRowEnd":true,"gridRowStart":true,"lineHeight":true,"opacity":true,"order":true,"orphans":true,"widows":true,"zIndex":true,"zoom":true},cssProps:{},style:function(elem,name,value,extra){if(!elem||elem.nodeType===3||elem.nodeType===8||!elem.style){return;}
var ret,type,hooks,origName=camelCase(name),isCustomProp=rcustomProp.test(name),style=elem.style;if(!isCustomProp){name=finalPropName(origName);}
hooks=jQuery.cssHooks[name]||jQuery.cssHooks[origName];if(value!==undefined){type=typeof value;if(type==="string"&&(ret=rcssNum.exec(value))&&ret[1]){value=adjustCSS(elem,name,ret);type="number";}
if(value==null||value!==value){return;}
if(type==="number"&&!isCustomProp){value+=ret&&ret[3]||(jQuery.cssNumber[origName]?"":"px");}
if(!support.clearCloneStyle&&value===""&&name.indexOf("background")===0){style[name]="inherit";}
if(!hooks||!("set"in hooks)||(value=hooks.set(elem,value,extra))!==undefined){if(isCustomProp){style.setProperty(name,value);}else{style[name]=value;}}}else{if(hooks&&"get"in hooks&&(ret=hooks.get(elem,false,extra))!==undefined){return ret;}
return style[name];}},css:function(elem,name,extra,styles){var val,num,hooks,origName=camelCase(name),isCustomProp=rcustomProp.test(name);if(!isCustomProp){name=finalPropName(origName);}
hooks=jQuery.cssHooks[name]||jQuery.cssHooks[origName];if(hooks&&"get"in hooks){val=hooks.get(elem,true,extra);}
if(val===undefined){val=curCSS(elem,name,styles);}
if(val==="normal"&&name in cssNormalTransform){val=cssNormalTransform[name];}
if(extra===""||extra){num=parseFloat(val);return extra===true||isFinite(num)?num||0:val;}
return val;}});jQuery.each(["height","width"],function(_i,dimension){jQuery.cssHooks[dimension]={get:function(elem,computed,extra){if(computed){return rdisplayswap.test(jQuery.css(elem,"display"))&&(!elem.getClientRects().length||!elem.getBoundingClientRect().width)?swap(elem,cssShow,function(){return getWidthOrHeight(elem,dimension,extra);}):getWidthOrHeight(elem,dimension,extra);}},set:function(elem,value,extra){var matches,styles=getStyles(elem),scrollboxSizeBuggy=!support.scrollboxSize()&&styles.position==="absolute",boxSizingNeeded=scrollboxSizeBuggy||extra,isBorderBox=boxSizingNeeded&&jQuery.css(elem,"boxSizing",false,styles)==="border-box",subtract=extra?boxModelAdjustment(elem,dimension,extra,isBorderBox,styles):0;if(isBorderBox&&scrollboxSizeBuggy){subtract-=Math.ceil(elem["offset"+dimension[0].toUpperCase()+dimension.slice(1)]-
parseFloat(styles[dimension])-
boxModelAdjustment(elem,dimension,"border",false,styles)-
0.5);}
if(subtract&&(matches=rcssNum.exec(value))&&(matches[3]||"px")!=="px"){elem.style[dimension]=value;value=jQuery.css(elem,dimension);}
return setPositiveNumber(elem,value,subtract);}};});jQuery.cssHooks.marginLeft=addGetHookIf(support.reliableMarginLeft,function(elem,computed){if(computed){return(parseFloat(curCSS(elem,"marginLeft"))||elem.getBoundingClientRect().left-
swap(elem,{marginLeft:0},function(){return elem.getBoundingClientRect().left;}))+"px";}});jQuery.each({margin:"",padding:"",border:"Width"},function(prefix,suffix){jQuery.cssHooks[prefix+suffix]={expand:function(value){var i=0,expanded={},parts=typeof value==="string"?value.split(" "):[value];for(;i<4;i++){expanded[prefix+cssExpand[i]+suffix]=parts[i]||parts[i-2]||parts[0];}
return expanded;}};if(prefix!=="margin"){jQuery.cssHooks[prefix+suffix].set=setPositiveNumber;}});jQuery.fn.extend({css:function(name,value){return access(this,function(elem,name,value){var styles,len,map={},i=0;if(Array.isArray(name)){styles=getStyles(elem);len=name.length;for(;i<len;i++){map[name[i]]=jQuery.css(elem,name[i],false,styles);}
return map;}
return value!==undefined?jQuery.style(elem,name,value):jQuery.css(elem,name);},name,value,arguments.length>1);}});function Tween(elem,options,prop,end,easing){return new Tween.prototype.init(elem,options,prop,end,easing);}
jQuery.Tween=Tween;Tween.prototype={constructor:Tween,init:function(elem,options,prop,end,easing,unit){this.elem=elem;this.prop=prop;this.easing=easing||jQuery.easing._default;this.options=options;this.start=this.now=this.cur();this.end=end;this.unit=unit||(jQuery.cssNumber[prop]?"":"px");},cur:function(){var hooks=Tween.propHooks[this.prop];return hooks&&hooks.get?hooks.get(this):Tween.propHooks._default.get(this);},run:function(percent){var eased,hooks=Tween.propHooks[this.prop];if(this.options.duration){this.pos=eased=jQuery.easing[this.easing](percent,this.options.duration*percent,0,1,this.options.duration);}else{this.pos=eased=percent;}
this.now=(this.end-this.start)*eased+this.start;if(this.options.step){this.options.step.call(this.elem,this.now,this);}
if(hooks&&hooks.set){hooks.set(this);}else{Tween.propHooks._default.set(this);}
return this;}};Tween.prototype.init.prototype=Tween.prototype;Tween.propHooks={_default:{get:function(tween){var result;if(tween.elem.nodeType!==1||tween.elem[tween.prop]!=null&&tween.elem.style[tween.prop]==null){return tween.elem[tween.prop];}
result=jQuery.css(tween.elem,tween.prop,"");return!result||result==="auto"?0:result;},set:function(tween){if(jQuery.fx.step[tween.prop]){jQuery.fx.step[tween.prop](tween);}else if(tween.elem.nodeType===1&&(jQuery.cssHooks[tween.prop]||tween.elem.style[finalPropName(tween.prop)]!=null)){jQuery.style(tween.elem,tween.prop,tween.now+tween.unit);}else{tween.elem[tween.prop]=tween.now;}}}};Tween.propHooks.scrollTop=Tween.propHooks.scrollLeft={set:function(tween){if(tween.elem.nodeType&&tween.elem.parentNode){tween.elem[tween.prop]=tween.now;}}};jQuery.easing={linear:function(p){return p;},swing:function(p){return 0.5-Math.cos(p*Math.PI)/2;},_default:"swing"};jQuery.fx=Tween.prototype.init;jQuery.fx.step={};var
fxNow,inProgress,rfxtypes=/^(?:toggle|show|hide)$/,rrun=/queueHooks$/;function schedule(){if(inProgress){if(document.hidden===false&&window.requestAnimationFrame){window.requestAnimationFrame(schedule);}else{window.setTimeout(schedule,jQuery.fx.interval);}
jQuery.fx.tick();}}
function createFxNow(){window.setTimeout(function(){fxNow=undefined;});return(fxNow=Date.now());}
function genFx(type,includeWidth){var which,i=0,attrs={height:type};includeWidth=includeWidth?1:0;for(;i<4;i+=2-includeWidth){which=cssExpand[i];attrs["margin"+which]=attrs["padding"+which]=type;}
if(includeWidth){attrs.opacity=attrs.width=type;}
return attrs;}
function createTween(value,prop,animation){var tween,collection=(Animation.tweeners[prop]||[]).concat(Animation.tweeners["*"]),index=0,length=collection.length;for(;index<length;index++){if((tween=collection[index].call(animation,prop,value))){return tween;}}}
function defaultPrefilter(elem,props,opts){var prop,value,toggle,hooks,oldfire,propTween,restoreDisplay,display,isBox="width"in props||"height"in props,anim=this,orig={},style=elem.style,hidden=elem.nodeType&&isHiddenWithinTree(elem),dataShow=dataPriv.get(elem,"fxshow");if(!opts.queue){hooks=jQuery._queueHooks(elem,"fx");if(hooks.unqueued==null){hooks.unqueued=0;oldfire=hooks.empty.fire;hooks.empty.fire=function(){if(!hooks.unqueued){oldfire();}};}
hooks.unqueued++;anim.always(function(){anim.always(function(){hooks.unqueued--;if(!jQuery.queue(elem,"fx").length){hooks.empty.fire();}});});}
for(prop in props){value=props[prop];if(rfxtypes.test(value)){delete props[prop];toggle=toggle||value==="toggle";if(value===(hidden?"hide":"show")){if(value==="show"&&dataShow&&dataShow[prop]!==undefined){hidden=true;}else{continue;}}
orig[prop]=dataShow&&dataShow[prop]||jQuery.style(elem,prop);}}
propTween=!jQuery.isEmptyObject(props);if(!propTween&&jQuery.isEmptyObject(orig)){return;}
if(isBox&&elem.nodeType===1){opts.overflow=[style.overflow,style.overflowX,style.overflowY];restoreDisplay=dataShow&&dataShow.display;if(restoreDisplay==null){restoreDisplay=dataPriv.get(elem,"display");}
display=jQuery.css(elem,"display");if(display==="none"){if(restoreDisplay){display=restoreDisplay;}else{showHide([elem],true);restoreDisplay=elem.style.display||restoreDisplay;display=jQuery.css(elem,"display");showHide([elem]);}}
if(display==="inline"||display==="inline-block"&&restoreDisplay!=null){if(jQuery.css(elem,"float")==="none"){if(!propTween){anim.done(function(){style.display=restoreDisplay;});if(restoreDisplay==null){display=style.display;restoreDisplay=display==="none"?"":display;}}
style.display="inline-block";}}}
if(opts.overflow){style.overflow="hidden";anim.always(function(){style.overflow=opts.overflow[0];style.overflowX=opts.overflow[1];style.overflowY=opts.overflow[2];});}
propTween=false;for(prop in orig){if(!propTween){if(dataShow){if("hidden"in dataShow){hidden=dataShow.hidden;}}else{dataShow=dataPriv.access(elem,"fxshow",{display:restoreDisplay});}
if(toggle){dataShow.hidden=!hidden;}
if(hidden){showHide([elem],true);}
anim.done(function(){if(!hidden){showHide([elem]);}
dataPriv.remove(elem,"fxshow");for(prop in orig){jQuery.style(elem,prop,orig[prop]);}});}
propTween=createTween(hidden?dataShow[prop]:0,prop,anim);if(!(prop in dataShow)){dataShow[prop]=propTween.start;if(hidden){propTween.end=propTween.start;propTween.start=0;}}}}
function propFilter(props,specialEasing){var index,name,easing,value,hooks;for(index in props){name=camelCase(index);easing=specialEasing[name];value=props[index];if(Array.isArray(value)){easing=value[1];value=props[index]=value[0];}
if(index!==name){props[name]=value;delete props[index];}
hooks=jQuery.cssHooks[name];if(hooks&&"expand"in hooks){value=hooks.expand(value);delete props[name];for(index in value){if(!(index in props)){props[index]=value[index];specialEasing[index]=easing;}}}else{specialEasing[name]=easing;}}}
function Animation(elem,properties,options){var result,stopped,index=0,length=Animation.prefilters.length,deferred=jQuery.Deferred().always(function(){delete tick.elem;}),tick=function(){if(stopped){return false;}
var currentTime=fxNow||createFxNow(),remaining=Math.max(0,animation.startTime+animation.duration-currentTime),temp=remaining/animation.duration||0,percent=1-temp,index=0,length=animation.tweens.length;for(;index<length;index++){animation.tweens[index].run(percent);}
deferred.notifyWith(elem,[animation,percent,remaining]);if(percent<1&&length){return remaining;}
if(!length){deferred.notifyWith(elem,[animation,1,0]);}
deferred.resolveWith(elem,[animation]);return false;},animation=deferred.promise({elem:elem,props:jQuery.extend({},properties),opts:jQuery.extend(true,{specialEasing:{},easing:jQuery.easing._default},options),originalProperties:properties,originalOptions:options,startTime:fxNow||createFxNow(),duration:options.duration,tweens:[],createTween:function(prop,end){var tween=jQuery.Tween(elem,animation.opts,prop,end,animation.opts.specialEasing[prop]||animation.opts.easing);animation.tweens.push(tween);return tween;},stop:function(gotoEnd){var index=0,length=gotoEnd?animation.tweens.length:0;if(stopped){return this;}
stopped=true;for(;index<length;index++){animation.tweens[index].run(1);}
if(gotoEnd){deferred.notifyWith(elem,[animation,1,0]);deferred.resolveWith(elem,[animation,gotoEnd]);}else{deferred.rejectWith(elem,[animation,gotoEnd]);}
return this;}}),props=animation.props;propFilter(props,animation.opts.specialEasing);for(;index<length;index++){result=Animation.prefilters[index].call(animation,elem,props,animation.opts);if(result){if(isFunction(result.stop)){jQuery._queueHooks(animation.elem,animation.opts.queue).stop=result.stop.bind(result);}
return result;}}
jQuery.map(props,createTween,animation);if(isFunction(animation.opts.start)){animation.opts.start.call(elem,animation);}
animation.progress(animation.opts.progress).done(animation.opts.done,animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always);jQuery.fx.timer(jQuery.extend(tick,{elem:elem,anim:animation,queue:animation.opts.queue}));return animation;}
jQuery.Animation=jQuery.extend(Animation,{tweeners:{"*":[function(prop,value){var tween=this.createTween(prop,value);adjustCSS(tween.elem,prop,rcssNum.exec(value),tween);return tween;}]},tweener:function(props,callback){if(isFunction(props)){callback=props;props=["*"];}else{props=props.match(rnothtmlwhite);}
var prop,index=0,length=props.length;for(;index<length;index++){prop=props[index];Animation.tweeners[prop]=Animation.tweeners[prop]||[];Animation.tweeners[prop].unshift(callback);}},prefilters:[defaultPrefilter],prefilter:function(callback,prepend){if(prepend){Animation.prefilters.unshift(callback);}else{Animation.prefilters.push(callback);}}});jQuery.speed=function(speed,easing,fn){var opt=speed&&typeof speed==="object"?jQuery.extend({},speed):{complete:fn||!fn&&easing||isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&!isFunction(easing)&&easing};if(jQuery.fx.off){opt.duration=0;}else{if(typeof opt.duration!=="number"){if(opt.duration in jQuery.fx.speeds){opt.duration=jQuery.fx.speeds[opt.duration];}else{opt.duration=jQuery.fx.speeds._default;}}}
if(opt.queue==null||opt.queue===true){opt.queue="fx";}
opt.old=opt.complete;opt.complete=function(){if(isFunction(opt.old)){opt.old.call(this);}
if(opt.queue){jQuery.dequeue(this,opt.queue);}};return opt;};jQuery.fn.extend({fadeTo:function(speed,to,easing,callback){return this.filter(isHiddenWithinTree).css("opacity",0).show().end().animate({opacity:to},speed,easing,callback);},animate:function(prop,speed,easing,callback){var empty=jQuery.isEmptyObject(prop),optall=jQuery.speed(speed,easing,callback),doAnimation=function(){var anim=Animation(this,jQuery.extend({},prop),optall);if(empty||dataPriv.get(this,"finish")){anim.stop(true);}};doAnimation.finish=doAnimation;return empty||optall.queue===false?this.each(doAnimation):this.queue(optall.queue,doAnimation);},stop:function(type,clearQueue,gotoEnd){var stopQueue=function(hooks){var stop=hooks.stop;delete hooks.stop;stop(gotoEnd);};if(typeof type!=="string"){gotoEnd=clearQueue;clearQueue=type;type=undefined;}
if(clearQueue){this.queue(type||"fx",[]);}
return this.each(function(){var dequeue=true,index=type!=null&&type+"queueHooks",timers=jQuery.timers,data=dataPriv.get(this);if(index){if(data[index]&&data[index].stop){stopQueue(data[index]);}}else{for(index in data){if(data[index]&&data[index].stop&&rrun.test(index)){stopQueue(data[index]);}}}
for(index=timers.length;index--;){if(timers[index].elem===this&&(type==null||timers[index].queue===type)){timers[index].anim.stop(gotoEnd);dequeue=false;timers.splice(index,1);}}
if(dequeue||!gotoEnd){jQuery.dequeue(this,type);}});},finish:function(type){if(type!==false){type=type||"fx";}
return this.each(function(){var index,data=dataPriv.get(this),queue=data[type+"queue"],hooks=data[type+"queueHooks"],timers=jQuery.timers,length=queue?queue.length:0;data.finish=true;jQuery.queue(this,type,[]);if(hooks&&hooks.stop){hooks.stop.call(this,true);}
for(index=timers.length;index--;){if(timers[index].elem===this&&timers[index].queue===type){timers[index].anim.stop(true);timers.splice(index,1);}}
for(index=0;index<length;index++){if(queue[index]&&queue[index].finish){queue[index].finish.call(this);}}
delete data.finish;});}});jQuery.each(["toggle","show","hide"],function(_i,name){var cssFn=jQuery.fn[name];jQuery.fn[name]=function(speed,easing,callback){return speed==null||typeof speed==="boolean"?cssFn.apply(this,arguments):this.animate(genFx(name,true),speed,easing,callback);};});jQuery.each({slideDown:genFx("show"),slideUp:genFx("hide"),slideToggle:genFx("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(name,props){jQuery.fn[name]=function(speed,easing,callback){return this.animate(props,speed,easing,callback);};});jQuery.timers=[];jQuery.fx.tick=function(){var timer,i=0,timers=jQuery.timers;fxNow=Date.now();for(;i<timers.length;i++){timer=timers[i];if(!timer()&&timers[i]===timer){timers.splice(i--,1);}}
if(!timers.length){jQuery.fx.stop();}
fxNow=undefined;};jQuery.fx.timer=function(timer){jQuery.timers.push(timer);jQuery.fx.start();};jQuery.fx.interval=13;jQuery.fx.start=function(){if(inProgress){return;}
inProgress=true;schedule();};jQuery.fx.stop=function(){inProgress=null;};jQuery.fx.speeds={slow:600,fast:200,_default:400};jQuery.fn.delay=function(time,type){time=jQuery.fx?jQuery.fx.speeds[time]||time:time;type=type||"fx";return this.queue(type,function(next,hooks){var timeout=window.setTimeout(next,time);hooks.stop=function(){window.clearTimeout(timeout);};});};(function(){var input=document.createElement("input"),select=document.createElement("select"),opt=select.appendChild(document.createElement("option"));input.type="checkbox";support.checkOn=input.value!=="";support.optSelected=opt.selected;input=document.createElement("input");input.value="t";input.type="radio";support.radioValue=input.value==="t";})();var boolHook,attrHandle=jQuery.expr.attrHandle;jQuery.fn.extend({attr:function(name,value){return access(this,jQuery.attr,name,value,arguments.length>1);},removeAttr:function(name){return this.each(function(){jQuery.removeAttr(this,name);});}});jQuery.extend({attr:function(elem,name,value){var ret,hooks,nType=elem.nodeType;if(nType===3||nType===8||nType===2){return;}
if(typeof elem.getAttribute==="undefined"){return jQuery.prop(elem,name,value);}
if(nType!==1||!jQuery.isXMLDoc(elem)){hooks=jQuery.attrHooks[name.toLowerCase()]||(jQuery.expr.match.bool.test(name)?boolHook:undefined);}
if(value!==undefined){if(value===null){jQuery.removeAttr(elem,name);return;}
if(hooks&&"set"in hooks&&(ret=hooks.set(elem,value,name))!==undefined){return ret;}
elem.setAttribute(name,value+"");return value;}
if(hooks&&"get"in hooks&&(ret=hooks.get(elem,name))!==null){return ret;}
ret=jQuery.find.attr(elem,name);return ret==null?undefined:ret;},attrHooks:{type:{set:function(elem,value){if(!support.radioValue&&value==="radio"&&nodeName(elem,"input")){var val=elem.value;elem.setAttribute("type",value);if(val){elem.value=val;}
return value;}}}},removeAttr:function(elem,value){var name,i=0,attrNames=value&&value.match(rnothtmlwhite);if(attrNames&&elem.nodeType===1){while((name=attrNames[i++])){elem.removeAttribute(name);}}}});boolHook={set:function(elem,value,name){if(value===false){jQuery.removeAttr(elem,name);}else{elem.setAttribute(name,name);}
return name;}};jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g),function(_i,name){var getter=attrHandle[name]||jQuery.find.attr;attrHandle[name]=function(elem,name,isXML){var ret,handle,lowercaseName=name.toLowerCase();if(!isXML){handle=attrHandle[lowercaseName];attrHandle[lowercaseName]=ret;ret=getter(elem,name,isXML)!=null?lowercaseName:null;attrHandle[lowercaseName]=handle;}
return ret;};});var rfocusable=/^(?:input|select|textarea|button)$/i,rclickable=/^(?:a|area)$/i;jQuery.fn.extend({prop:function(name,value){return access(this,jQuery.prop,name,value,arguments.length>1);},removeProp:function(name){return this.each(function(){delete this[jQuery.propFix[name]||name];});}});jQuery.extend({prop:function(elem,name,value){var ret,hooks,nType=elem.nodeType;if(nType===3||nType===8||nType===2){return;}
if(nType!==1||!jQuery.isXMLDoc(elem)){name=jQuery.propFix[name]||name;hooks=jQuery.propHooks[name];}
if(value!==undefined){if(hooks&&"set"in hooks&&(ret=hooks.set(elem,value,name))!==undefined){return ret;}
return(elem[name]=value);}
if(hooks&&"get"in hooks&&(ret=hooks.get(elem,name))!==null){return ret;}
return elem[name];},propHooks:{tabIndex:{get:function(elem){var tabindex=jQuery.find.attr(elem,"tabindex");if(tabindex){return parseInt(tabindex,10);}
if(rfocusable.test(elem.nodeName)||rclickable.test(elem.nodeName)&&elem.href){return 0;}
return-1;}}},propFix:{"for":"htmlFor","class":"className"}});if(!support.optSelected){jQuery.propHooks.selected={get:function(elem){var parent=elem.parentNode;if(parent&&parent.parentNode){parent.parentNode.selectedIndex;}
return null;},set:function(elem){var parent=elem.parentNode;if(parent){parent.selectedIndex;if(parent.parentNode){parent.parentNode.selectedIndex;}}}};}
jQuery.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){jQuery.propFix[this.toLowerCase()]=this;});function stripAndCollapse(value){var tokens=value.match(rnothtmlwhite)||[];return tokens.join(" ");}
function getClass(elem){return elem.getAttribute&&elem.getAttribute("class")||"";}
function classesToArray(value){if(Array.isArray(value)){return value;}
if(typeof value==="string"){return value.match(rnothtmlwhite)||[];}
return[];}
jQuery.fn.extend({addClass:function(value){var classNames,cur,curValue,className,i,finalValue;if(isFunction(value)){return this.each(function(j){jQuery(this).addClass(value.call(this,j,getClass(this)));});}
classNames=classesToArray(value);if(classNames.length){return this.each(function(){curValue=getClass(this);cur=this.nodeType===1&&(" "+stripAndCollapse(curValue)+" ");if(cur){for(i=0;i<classNames.length;i++){className=classNames[i];if(cur.indexOf(" "+className+" ")<0){cur+=className+" ";}}
finalValue=stripAndCollapse(cur);if(curValue!==finalValue){this.setAttribute("class",finalValue);}}});}
return this;},removeClass:function(value){var classNames,cur,curValue,className,i,finalValue;if(isFunction(value)){return this.each(function(j){jQuery(this).removeClass(value.call(this,j,getClass(this)));});}
if(!arguments.length){return this.attr("class","");}
classNames=classesToArray(value);if(classNames.length){return this.each(function(){curValue=getClass(this);cur=this.nodeType===1&&(" "+stripAndCollapse(curValue)+" ");if(cur){for(i=0;i<classNames.length;i++){className=classNames[i];while(cur.indexOf(" "+className+" ")>-1){cur=cur.replace(" "+className+" "," ");}}
finalValue=stripAndCollapse(cur);if(curValue!==finalValue){this.setAttribute("class",finalValue);}}});}
return this;},toggleClass:function(value,stateVal){var classNames,className,i,self,type=typeof value,isValidValue=type==="string"||Array.isArray(value);if(isFunction(value)){return this.each(function(i){jQuery(this).toggleClass(value.call(this,i,getClass(this),stateVal),stateVal);});}
if(typeof stateVal==="boolean"&&isValidValue){return stateVal?this.addClass(value):this.removeClass(value);}
classNames=classesToArray(value);return this.each(function(){if(isValidValue){self=jQuery(this);for(i=0;i<classNames.length;i++){className=classNames[i];if(self.hasClass(className)){self.removeClass(className);}else{self.addClass(className);}}}else if(value===undefined||type==="boolean"){className=getClass(this);if(className){dataPriv.set(this,"__className__",className);}
if(this.setAttribute){this.setAttribute("class",className||value===false?"":dataPriv.get(this,"__className__")||"");}}});},hasClass:function(selector){var className,elem,i=0;className=" "+selector+" ";while((elem=this[i++])){if(elem.nodeType===1&&(" "+stripAndCollapse(getClass(elem))+" ").indexOf(className)>-1){return true;}}
return false;}});var rreturn=/\r/g;jQuery.fn.extend({val:function(value){var hooks,ret,valueIsFunction,elem=this[0];if(!arguments.length){if(elem){hooks=jQuery.valHooks[elem.type]||jQuery.valHooks[elem.nodeName.toLowerCase()];if(hooks&&"get"in hooks&&(ret=hooks.get(elem,"value"))!==undefined){return ret;}
ret=elem.value;if(typeof ret==="string"){return ret.replace(rreturn,"");}
return ret==null?"":ret;}
return;}
valueIsFunction=isFunction(value);return this.each(function(i){var val;if(this.nodeType!==1){return;}
if(valueIsFunction){val=value.call(this,i,jQuery(this).val());}else{val=value;}
if(val==null){val="";}else if(typeof val==="number"){val+="";}else if(Array.isArray(val)){val=jQuery.map(val,function(value){return value==null?"":value+"";});}
hooks=jQuery.valHooks[this.type]||jQuery.valHooks[this.nodeName.toLowerCase()];if(!hooks||!("set"in hooks)||hooks.set(this,val,"value")===undefined){this.value=val;}});}});jQuery.extend({valHooks:{option:{get:function(elem){var val=jQuery.find.attr(elem,"value");return val!=null?val:stripAndCollapse(jQuery.text(elem));}},select:{get:function(elem){var value,option,i,options=elem.options,index=elem.selectedIndex,one=elem.type==="select-one",values=one?null:[],max=one?index+1:options.length;if(index<0){i=max;}else{i=one?index:0;}
for(;i<max;i++){option=options[i];if((option.selected||i===index)&&!option.disabled&&(!option.parentNode.disabled||!nodeName(option.parentNode,"optgroup"))){value=jQuery(option).val();if(one){return value;}
values.push(value);}}
return values;},set:function(elem,value){var optionSet,option,options=elem.options,values=jQuery.makeArray(value),i=options.length;while(i--){option=options[i];if(option.selected=jQuery.inArray(jQuery.valHooks.option.get(option),values)>-1){optionSet=true;}}
if(!optionSet){elem.selectedIndex=-1;}
return values;}}}});jQuery.each(["radio","checkbox"],function(){jQuery.valHooks[this]={set:function(elem,value){if(Array.isArray(value)){return(elem.checked=jQuery.inArray(jQuery(elem).val(),value)>-1);}}};if(!support.checkOn){jQuery.valHooks[this].get=function(elem){return elem.getAttribute("value")===null?"on":elem.value;};}});support.focusin="onfocusin"in window;var rfocusMorph=/^(?:focusinfocus|focusoutblur)$/,stopPropagationCallback=function(e){e.stopPropagation();};jQuery.extend(jQuery.event,{trigger:function(event,data,elem,onlyHandlers){var i,cur,tmp,bubbleType,ontype,handle,special,lastElement,eventPath=[elem||document],type=hasOwn.call(event,"type")?event.type:event,namespaces=hasOwn.call(event,"namespace")?event.namespace.split("."):[];cur=lastElement=tmp=elem=elem||document;if(elem.nodeType===3||elem.nodeType===8){return;}
if(rfocusMorph.test(type+jQuery.event.triggered)){return;}
if(type.indexOf(".")>-1){namespaces=type.split(".");type=namespaces.shift();namespaces.sort();}
ontype=type.indexOf(":")<0&&"on"+type;event=event[jQuery.expando]?event:new jQuery.Event(type,typeof event==="object"&&event);event.isTrigger=onlyHandlers?2:3;event.namespace=namespaces.join(".");event.rnamespace=event.namespace?new RegExp("(^|\\.)"+namespaces.join("\\.(?:.*\\.|)")+"(\\.|$)"):null;event.result=undefined;if(!event.target){event.target=elem;}
data=data==null?[event]:jQuery.makeArray(data,[event]);special=jQuery.event.special[type]||{};if(!onlyHandlers&&special.trigger&&special.trigger.apply(elem,data)===false){return;}
if(!onlyHandlers&&!special.noBubble&&!isWindow(elem)){bubbleType=special.delegateType||type;if(!rfocusMorph.test(bubbleType+type)){cur=cur.parentNode;}
for(;cur;cur=cur.parentNode){eventPath.push(cur);tmp=cur;}
if(tmp===(elem.ownerDocument||document)){eventPath.push(tmp.defaultView||tmp.parentWindow||window);}}
i=0;while((cur=eventPath[i++])&&!event.isPropagationStopped()){lastElement=cur;event.type=i>1?bubbleType:special.bindType||type;handle=(dataPriv.get(cur,"events")||Object.create(null))[event.type]&&dataPriv.get(cur,"handle");if(handle){handle.apply(cur,data);}
handle=ontype&&cur[ontype];if(handle&&handle.apply&&acceptData(cur)){event.result=handle.apply(cur,data);if(event.result===false){event.preventDefault();}}}
event.type=type;if(!onlyHandlers&&!event.isDefaultPrevented()){if((!special._default||special._default.apply(eventPath.pop(),data)===false)&&acceptData(elem)){if(ontype&&isFunction(elem[type])&&!isWindow(elem)){tmp=elem[ontype];if(tmp){elem[ontype]=null;}
jQuery.event.triggered=type;if(event.isPropagationStopped()){lastElement.addEventListener(type,stopPropagationCallback);}
elem[type]();if(event.isPropagationStopped()){lastElement.removeEventListener(type,stopPropagationCallback);}
jQuery.event.triggered=undefined;if(tmp){elem[ontype]=tmp;}}}}
return event.result;},simulate:function(type,elem,event){var e=jQuery.extend(new jQuery.Event(),event,{type:type,isSimulated:true});jQuery.event.trigger(e,null,elem);}});jQuery.fn.extend({trigger:function(type,data){return this.each(function(){jQuery.event.trigger(type,data,this);});},triggerHandler:function(type,data){var elem=this[0];if(elem){return jQuery.event.trigger(type,data,elem,true);}}});if(!support.focusin){jQuery.each({focus:"focusin",blur:"focusout"},function(orig,fix){var handler=function(event){jQuery.event.simulate(fix,event.target,jQuery.event.fix(event));};jQuery.event.special[fix]={setup:function(){var doc=this.ownerDocument||this.document||this,attaches=dataPriv.access(doc,fix);if(!attaches){doc.addEventListener(orig,handler,true);}
dataPriv.access(doc,fix,(attaches||0)+1);},teardown:function(){var doc=this.ownerDocument||this.document||this,attaches=dataPriv.access(doc,fix)-1;if(!attaches){doc.removeEventListener(orig,handler,true);dataPriv.remove(doc,fix);}else{dataPriv.access(doc,fix,attaches);}}};});}
var location=window.location;var nonce={guid:Date.now()};var rquery=(/\?/);jQuery.parseXML=function(data){var xml,parserErrorElem;if(!data||typeof data!=="string"){return null;}
try{xml=(new window.DOMParser()).parseFromString(data,"text/xml");}catch(e){}
parserErrorElem=xml&&xml.getElementsByTagName("parsererror")[0];if(!xml||parserErrorElem){jQuery.error("Invalid XML: "+(parserErrorElem?jQuery.map(parserErrorElem.childNodes,function(el){return el.textContent;}).join("\n"):data));}
return xml;};var
rbracket=/\[\]$/,rCRLF=/\r?\n/g,rsubmitterTypes=/^(?:submit|button|image|reset|file)$/i,rsubmittable=/^(?:input|select|textarea|keygen)/i;function buildParams(prefix,obj,traditional,add){var name;if(Array.isArray(obj)){jQuery.each(obj,function(i,v){if(traditional||rbracket.test(prefix)){add(prefix,v);}else{buildParams(prefix+"["+(typeof v==="object"&&v!=null?i:"")+"]",v,traditional,add);}});}else if(!traditional&&toType(obj)==="object"){for(name in obj){buildParams(prefix+"["+name+"]",obj[name],traditional,add);}}else{add(prefix,obj);}}
jQuery.param=function(a,traditional){var prefix,s=[],add=function(key,valueOrFunction){var value=isFunction(valueOrFunction)?valueOrFunction():valueOrFunction;s[s.length]=encodeURIComponent(key)+"="+
encodeURIComponent(value==null?"":value);};if(a==null){return"";}
if(Array.isArray(a)||(a.jquery&&!jQuery.isPlainObject(a))){jQuery.each(a,function(){add(this.name,this.value);});}else{for(prefix in a){buildParams(prefix,a[prefix],traditional,add);}}
return s.join("&");};jQuery.fn.extend({serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){var elements=jQuery.prop(this,"elements");return elements?jQuery.makeArray(elements):this;}).filter(function(){var type=this.type;return this.name&&!jQuery(this).is(":disabled")&&rsubmittable.test(this.nodeName)&&!rsubmitterTypes.test(type)&&(this.checked||!rcheckableType.test(type));}).map(function(_i,elem){var val=jQuery(this).val();if(val==null){return null;}
if(Array.isArray(val)){return jQuery.map(val,function(val){return{name:elem.name,value:val.replace(rCRLF,"\r\n")};});}
return{name:elem.name,value:val.replace(rCRLF,"\r\n")};}).get();}});var
r20=/%20/g,rhash=/#.*$/,rantiCache=/([?&])_=[^&]*/,rheaders=/^(.*?):[ \t]*([^\r\n]*)$/mg,rlocalProtocol=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,rnoContent=/^(?:GET|HEAD)$/,rprotocol=/^\/\//,prefilters={},transports={},allTypes="*/".concat("*"),originAnchor=document.createElement("a");originAnchor.href=location.href;function addToPrefiltersOrTransports(structure){return function(dataTypeExpression,func){if(typeof dataTypeExpression!=="string"){func=dataTypeExpression;dataTypeExpression="*";}
var dataType,i=0,dataTypes=dataTypeExpression.toLowerCase().match(rnothtmlwhite)||[];if(isFunction(func)){while((dataType=dataTypes[i++])){if(dataType[0]==="+"){dataType=dataType.slice(1)||"*";(structure[dataType]=structure[dataType]||[]).unshift(func);}else{(structure[dataType]=structure[dataType]||[]).push(func);}}}};}
function inspectPrefiltersOrTransports(structure,options,originalOptions,jqXHR){var inspected={},seekingTransport=(structure===transports);function inspect(dataType){var selected;inspected[dataType]=true;jQuery.each(structure[dataType]||[],function(_,prefilterOrFactory){var dataTypeOrTransport=prefilterOrFactory(options,originalOptions,jqXHR);if(typeof dataTypeOrTransport==="string"&&!seekingTransport&&!inspected[dataTypeOrTransport]){options.dataTypes.unshift(dataTypeOrTransport);inspect(dataTypeOrTransport);return false;}else if(seekingTransport){return!(selected=dataTypeOrTransport);}});return selected;}
return inspect(options.dataTypes[0])||!inspected["*"]&&inspect("*");}
function ajaxExtend(target,src){var key,deep,flatOptions=jQuery.ajaxSettings.flatOptions||{};for(key in src){if(src[key]!==undefined){(flatOptions[key]?target:(deep||(deep={})))[key]=src[key];}}
if(deep){jQuery.extend(true,target,deep);}
return target;}
function ajaxHandleResponses(s,jqXHR,responses){var ct,type,finalDataType,firstDataType,contents=s.contents,dataTypes=s.dataTypes;while(dataTypes[0]==="*"){dataTypes.shift();if(ct===undefined){ct=s.mimeType||jqXHR.getResponseHeader("Content-Type");}}
if(ct){for(type in contents){if(contents[type]&&contents[type].test(ct)){dataTypes.unshift(type);break;}}}
if(dataTypes[0]in responses){finalDataType=dataTypes[0];}else{for(type in responses){if(!dataTypes[0]||s.converters[type+" "+dataTypes[0]]){finalDataType=type;break;}
if(!firstDataType){firstDataType=type;}}
finalDataType=finalDataType||firstDataType;}
if(finalDataType){if(finalDataType!==dataTypes[0]){dataTypes.unshift(finalDataType);}
return responses[finalDataType];}}
function ajaxConvert(s,response,jqXHR,isSuccess){var conv2,current,conv,tmp,prev,converters={},dataTypes=s.dataTypes.slice();if(dataTypes[1]){for(conv in s.converters){converters[conv.toLowerCase()]=s.converters[conv];}}
current=dataTypes.shift();while(current){if(s.responseFields[current]){jqXHR[s.responseFields[current]]=response;}
if(!prev&&isSuccess&&s.dataFilter){response=s.dataFilter(response,s.dataType);}
prev=current;current=dataTypes.shift();if(current){if(current==="*"){current=prev;}else if(prev!=="*"&&prev!==current){conv=converters[prev+" "+current]||converters["* "+current];if(!conv){for(conv2 in converters){tmp=conv2.split(" ");if(tmp[1]===current){conv=converters[prev+" "+tmp[0]]||converters["* "+tmp[0]];if(conv){if(conv===true){conv=converters[conv2];}else if(converters[conv2]!==true){current=tmp[0];dataTypes.unshift(tmp[1]);}
break;}}}}
if(conv!==true){if(conv&&s.throws){response=conv(response);}else{try{response=conv(response);}catch(e){return{state:"parsererror",error:conv?e:"No conversion from "+prev+" to "+current};}}}}}}
return{state:"success",data:response};}
jQuery.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:location.href,type:"GET",isLocal:rlocalProtocol.test(location.protocol),global:true,processData:true,async:true,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":allTypes,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":true,"text json":JSON.parse,"text xml":jQuery.parseXML},flatOptions:{url:true,context:true}},ajaxSetup:function(target,settings){return settings?ajaxExtend(ajaxExtend(target,jQuery.ajaxSettings),settings):ajaxExtend(jQuery.ajaxSettings,target);},ajaxPrefilter:addToPrefiltersOrTransports(prefilters),ajaxTransport:addToPrefiltersOrTransports(transports),ajax:function(url,options){if(typeof url==="object"){options=url;url=undefined;}
options=options||{};var transport,cacheURL,responseHeadersString,responseHeaders,timeoutTimer,urlAnchor,completed,fireGlobals,i,uncached,s=jQuery.ajaxSetup({},options),callbackContext=s.context||s,globalEventContext=s.context&&(callbackContext.nodeType||callbackContext.jquery)?jQuery(callbackContext):jQuery.event,deferred=jQuery.Deferred(),completeDeferred=jQuery.Callbacks("once memory"),statusCode=s.statusCode||{},requestHeaders={},requestHeadersNames={},strAbort="canceled",jqXHR={readyState:0,getResponseHeader:function(key){var match;if(completed){if(!responseHeaders){responseHeaders={};while((match=rheaders.exec(responseHeadersString))){responseHeaders[match[1].toLowerCase()+" "]=(responseHeaders[match[1].toLowerCase()+" "]||[]).concat(match[2]);}}
match=responseHeaders[key.toLowerCase()+" "];}
return match==null?null:match.join(", ");},getAllResponseHeaders:function(){return completed?responseHeadersString:null;},setRequestHeader:function(name,value){if(completed==null){name=requestHeadersNames[name.toLowerCase()]=requestHeadersNames[name.toLowerCase()]||name;requestHeaders[name]=value;}
return this;},overrideMimeType:function(type){if(completed==null){s.mimeType=type;}
return this;},statusCode:function(map){var code;if(map){if(completed){jqXHR.always(map[jqXHR.status]);}else{for(code in map){statusCode[code]=[statusCode[code],map[code]];}}}
return this;},abort:function(statusText){var finalText=statusText||strAbort;if(transport){transport.abort(finalText);}
done(0,finalText);return this;}};deferred.promise(jqXHR);s.url=((url||s.url||location.href)+"").replace(rprotocol,location.protocol+"//");s.type=options.method||options.type||s.method||s.type;s.dataTypes=(s.dataType||"*").toLowerCase().match(rnothtmlwhite)||[""];if(s.crossDomain==null){urlAnchor=document.createElement("a");try{urlAnchor.href=s.url;urlAnchor.href=urlAnchor.href;s.crossDomain=originAnchor.protocol+"//"+originAnchor.host!==urlAnchor.protocol+"//"+urlAnchor.host;}catch(e){s.crossDomain=true;}}
if(s.data&&s.processData&&typeof s.data!=="string"){s.data=jQuery.param(s.data,s.traditional);}
inspectPrefiltersOrTransports(prefilters,s,options,jqXHR);if(completed){return jqXHR;}
fireGlobals=jQuery.event&&s.global;if(fireGlobals&&jQuery.active++===0){jQuery.event.trigger("ajaxStart");}
s.type=s.type.toUpperCase();s.hasContent=!rnoContent.test(s.type);cacheURL=s.url.replace(rhash,"");if(!s.hasContent){uncached=s.url.slice(cacheURL.length);if(s.data&&(s.processData||typeof s.data==="string")){cacheURL+=(rquery.test(cacheURL)?"&":"?")+s.data;delete s.data;}
if(s.cache===false){cacheURL=cacheURL.replace(rantiCache,"$1");uncached=(rquery.test(cacheURL)?"&":"?")+"_="+(nonce.guid++)+
uncached;}
s.url=cacheURL+uncached;}else if(s.data&&s.processData&&(s.contentType||"").indexOf("application/x-www-form-urlencoded")===0){s.data=s.data.replace(r20,"+");}
if(s.ifModified){if(jQuery.lastModified[cacheURL]){jqXHR.setRequestHeader("If-Modified-Since",jQuery.lastModified[cacheURL]);}
if(jQuery.etag[cacheURL]){jqXHR.setRequestHeader("If-None-Match",jQuery.etag[cacheURL]);}}
if(s.data&&s.hasContent&&s.contentType!==false||options.contentType){jqXHR.setRequestHeader("Content-Type",s.contentType);}
jqXHR.setRequestHeader("Accept",s.dataTypes[0]&&s.accepts[s.dataTypes[0]]?s.accepts[s.dataTypes[0]]+
(s.dataTypes[0]!=="*"?", "+allTypes+"; q=0.01":""):s.accepts["*"]);for(i in s.headers){jqXHR.setRequestHeader(i,s.headers[i]);}
if(s.beforeSend&&(s.beforeSend.call(callbackContext,jqXHR,s)===false||completed)){return jqXHR.abort();}
strAbort="abort";completeDeferred.add(s.complete);jqXHR.done(s.success);jqXHR.fail(s.error);transport=inspectPrefiltersOrTransports(transports,s,options,jqXHR);if(!transport){done(-1,"No Transport");}else{jqXHR.readyState=1;if(fireGlobals){globalEventContext.trigger("ajaxSend",[jqXHR,s]);}
if(completed){return jqXHR;}
if(s.async&&s.timeout>0){timeoutTimer=window.setTimeout(function(){jqXHR.abort("timeout");},s.timeout);}
try{completed=false;transport.send(requestHeaders,done);}catch(e){if(completed){throw e;}
done(-1,e);}}
function done(status,nativeStatusText,responses,headers){var isSuccess,success,error,response,modified,statusText=nativeStatusText;if(completed){return;}
completed=true;if(timeoutTimer){window.clearTimeout(timeoutTimer);}
transport=undefined;responseHeadersString=headers||"";jqXHR.readyState=status>0?4:0;isSuccess=status>=200&&status<300||status===304;if(responses){response=ajaxHandleResponses(s,jqXHR,responses);}
if(!isSuccess&&jQuery.inArray("script",s.dataTypes)>-1&&jQuery.inArray("json",s.dataTypes)<0){s.converters["text script"]=function(){};}
response=ajaxConvert(s,response,jqXHR,isSuccess);if(isSuccess){if(s.ifModified){modified=jqXHR.getResponseHeader("Last-Modified");if(modified){jQuery.lastModified[cacheURL]=modified;}
modified=jqXHR.getResponseHeader("etag");if(modified){jQuery.etag[cacheURL]=modified;}}
if(status===204||s.type==="HEAD"){statusText="nocontent";}else if(status===304){statusText="notmodified";}else{statusText=response.state;success=response.data;error=response.error;isSuccess=!error;}}else{error=statusText;if(status||!statusText){statusText="error";if(status<0){status=0;}}}
jqXHR.status=status;jqXHR.statusText=(nativeStatusText||statusText)+"";if(isSuccess){deferred.resolveWith(callbackContext,[success,statusText,jqXHR]);}else{deferred.rejectWith(callbackContext,[jqXHR,statusText,error]);}
jqXHR.statusCode(statusCode);statusCode=undefined;if(fireGlobals){globalEventContext.trigger(isSuccess?"ajaxSuccess":"ajaxError",[jqXHR,s,isSuccess?success:error]);}
completeDeferred.fireWith(callbackContext,[jqXHR,statusText]);if(fireGlobals){globalEventContext.trigger("ajaxComplete",[jqXHR,s]);if(!(--jQuery.active)){jQuery.event.trigger("ajaxStop");}}}
return jqXHR;},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},getScript:function(url,callback){return jQuery.get(url,undefined,callback,"script");}});jQuery.each(["get","post"],function(_i,method){jQuery[method]=function(url,data,callback,type){if(isFunction(data)){type=type||callback;callback=data;data=undefined;}
return jQuery.ajax(jQuery.extend({url:url,type:method,dataType:type,data:data,success:callback},jQuery.isPlainObject(url)&&url));};});jQuery.ajaxPrefilter(function(s){var i;for(i in s.headers){if(i.toLowerCase()==="content-type"){s.contentType=s.headers[i]||"";}}});jQuery._evalUrl=function(url,options,doc){return jQuery.ajax({url:url,type:"GET",dataType:"script",cache:true,async:false,global:false,converters:{"text script":function(){}},dataFilter:function(response){jQuery.globalEval(response,options,doc);}});};jQuery.fn.extend({wrapAll:function(html){var wrap;if(this[0]){if(isFunction(html)){html=html.call(this[0]);}
wrap=jQuery(html,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){wrap.insertBefore(this[0]);}
wrap.map(function(){var elem=this;while(elem.firstElementChild){elem=elem.firstElementChild;}
return elem;}).append(this);}
return this;},wrapInner:function(html){if(isFunction(html)){return this.each(function(i){jQuery(this).wrapInner(html.call(this,i));});}
return this.each(function(){var self=jQuery(this),contents=self.contents();if(contents.length){contents.wrapAll(html);}else{self.append(html);}});},wrap:function(html){var htmlIsFunction=isFunction(html);return this.each(function(i){jQuery(this).wrapAll(htmlIsFunction?html.call(this,i):html);});},unwrap:function(selector){this.parent(selector).not("body").each(function(){jQuery(this).replaceWith(this.childNodes);});return this;}});jQuery.expr.pseudos.hidden=function(elem){return!jQuery.expr.pseudos.visible(elem);};jQuery.expr.pseudos.visible=function(elem){return!!(elem.offsetWidth||elem.offsetHeight||elem.getClientRects().length);};jQuery.ajaxSettings.xhr=function(){try{return new window.XMLHttpRequest();}catch(e){}};var xhrSuccessStatus={0:200,1223:204},xhrSupported=jQuery.ajaxSettings.xhr();support.cors=!!xhrSupported&&("withCredentials"in xhrSupported);support.ajax=xhrSupported=!!xhrSupported;jQuery.ajaxTransport(function(options){var callback,errorCallback;if(support.cors||xhrSupported&&!options.crossDomain){return{send:function(headers,complete){var i,xhr=options.xhr();xhr.open(options.type,options.url,options.async,options.username,options.password);if(options.xhrFields){for(i in options.xhrFields){xhr[i]=options.xhrFields[i];}}
if(options.mimeType&&xhr.overrideMimeType){xhr.overrideMimeType(options.mimeType);}
if(!options.crossDomain&&!headers["X-Requested-With"]){headers["X-Requested-With"]="XMLHttpRequest";}
for(i in headers){xhr.setRequestHeader(i,headers[i]);}
callback=function(type){return function(){if(callback){callback=errorCallback=xhr.onload=xhr.onerror=xhr.onabort=xhr.ontimeout=xhr.onreadystatechange=null;if(type==="abort"){xhr.abort();}else if(type==="error"){if(typeof xhr.status!=="number"){complete(0,"error");}else{complete(xhr.status,xhr.statusText);}}else{complete(xhrSuccessStatus[xhr.status]||xhr.status,xhr.statusText,(xhr.responseType||"text")!=="text"||typeof xhr.responseText!=="string"?{binary:xhr.response}:{text:xhr.responseText},xhr.getAllResponseHeaders());}}};};xhr.onload=callback();errorCallback=xhr.onerror=xhr.ontimeout=callback("error");if(xhr.onabort!==undefined){xhr.onabort=errorCallback;}else{xhr.onreadystatechange=function(){if(xhr.readyState===4){window.setTimeout(function(){if(callback){errorCallback();}});}};}
callback=callback("abort");try{xhr.send(options.hasContent&&options.data||null);}catch(e){if(callback){throw e;}}},abort:function(){if(callback){callback();}}};}});jQuery.ajaxPrefilter(function(s){if(s.crossDomain){s.contents.script=false;}});jQuery.ajaxSetup({accepts:{script:"text/javascript, application/javascript, "+"application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(text){jQuery.globalEval(text);return text;}}});jQuery.ajaxPrefilter("script",function(s){if(s.cache===undefined){s.cache=false;}
if(s.crossDomain){s.type="GET";}});jQuery.ajaxTransport("script",function(s){if(s.crossDomain||s.scriptAttrs){var script,callback;return{send:function(_,complete){script=jQuery("<script>").attr(s.scriptAttrs||{}).prop({charset:s.scriptCharset,src:s.url}).on("load error",callback=function(evt){script.remove();callback=null;if(evt){complete(evt.type==="error"?404:200,evt.type);}});document.head.appendChild(script[0]);},abort:function(){if(callback){callback();}}};}});var oldCallbacks=[],rjsonp=/(=)\?(?=&|$)|\?\?/;jQuery.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var callback=oldCallbacks.pop()||(jQuery.expando+"_"+(nonce.guid++));this[callback]=true;return callback;}});jQuery.ajaxPrefilter("json jsonp",function(s,originalSettings,jqXHR){var callbackName,overwritten,responseContainer,jsonProp=s.jsonp!==false&&(rjsonp.test(s.url)?"url":typeof s.data==="string"&&(s.contentType||"").indexOf("application/x-www-form-urlencoded")===0&&rjsonp.test(s.data)&&"data");if(jsonProp||s.dataTypes[0]==="jsonp"){callbackName=s.jsonpCallback=isFunction(s.jsonpCallback)?s.jsonpCallback():s.jsonpCallback;if(jsonProp){s[jsonProp]=s[jsonProp].replace(rjsonp,"$1"+callbackName);}else if(s.jsonp!==false){s.url+=(rquery.test(s.url)?"&":"?")+s.jsonp+"="+callbackName;}
s.converters["script json"]=function(){if(!responseContainer){jQuery.error(callbackName+" was not called");}
return responseContainer[0];};s.dataTypes[0]="json";overwritten=window[callbackName];window[callbackName]=function(){responseContainer=arguments;};jqXHR.always(function(){if(overwritten===undefined){jQuery(window).removeProp(callbackName);}else{window[callbackName]=overwritten;}
if(s[callbackName]){s.jsonpCallback=originalSettings.jsonpCallback;oldCallbacks.push(callbackName);}
if(responseContainer&&isFunction(overwritten)){overwritten(responseContainer[0]);}
responseContainer=overwritten=undefined;});return"script";}});support.createHTMLDocument=(function(){var body=document.implementation.createHTMLDocument("").body;body.innerHTML="<form></form><form></form>";return body.childNodes.length===2;})();jQuery.parseHTML=function(data,context,keepScripts){if(typeof data!=="string"){return[];}
if(typeof context==="boolean"){keepScripts=context;context=false;}
var base,parsed,scripts;if(!context){if(support.createHTMLDocument){context=document.implementation.createHTMLDocument("");base=context.createElement("base");base.href=document.location.href;context.head.appendChild(base);}else{context=document;}}
parsed=rsingleTag.exec(data);scripts=!keepScripts&&[];if(parsed){return[context.createElement(parsed[1])];}
parsed=buildFragment([data],context,scripts);if(scripts&&scripts.length){jQuery(scripts).remove();}
return jQuery.merge([],parsed.childNodes);};jQuery.fn.load=function(url,params,callback){var selector,type,response,self=this,off=url.indexOf(" ");if(off>-1){selector=stripAndCollapse(url.slice(off));url=url.slice(0,off);}
if(isFunction(params)){callback=params;params=undefined;}else if(params&&typeof params==="object"){type="POST";}
if(self.length>0){jQuery.ajax({url:url,type:type||"GET",dataType:"html",data:params}).done(function(responseText){response=arguments;self.html(selector?jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector):responseText);}).always(callback&&function(jqXHR,status){self.each(function(){callback.apply(this,response||[jqXHR.responseText,status,jqXHR]);});});}
return this;};jQuery.expr.pseudos.animated=function(elem){return jQuery.grep(jQuery.timers,function(fn){return elem===fn.elem;}).length;};jQuery.offset={setOffset:function(elem,options,i){var curPosition,curLeft,curCSSTop,curTop,curOffset,curCSSLeft,calculatePosition,position=jQuery.css(elem,"position"),curElem=jQuery(elem),props={};if(position==="static"){elem.style.position="relative";}
curOffset=curElem.offset();curCSSTop=jQuery.css(elem,"top");curCSSLeft=jQuery.css(elem,"left");calculatePosition=(position==="absolute"||position==="fixed")&&(curCSSTop+curCSSLeft).indexOf("auto")>-1;if(calculatePosition){curPosition=curElem.position();curTop=curPosition.top;curLeft=curPosition.left;}else{curTop=parseFloat(curCSSTop)||0;curLeft=parseFloat(curCSSLeft)||0;}
if(isFunction(options)){options=options.call(elem,i,jQuery.extend({},curOffset));}
if(options.top!=null){props.top=(options.top-curOffset.top)+curTop;}
if(options.left!=null){props.left=(options.left-curOffset.left)+curLeft;}
if("using"in options){options.using.call(elem,props);}else{curElem.css(props);}}};jQuery.fn.extend({offset:function(options){if(arguments.length){return options===undefined?this:this.each(function(i){jQuery.offset.setOffset(this,options,i);});}
var rect,win,elem=this[0];if(!elem){return;}
if(!elem.getClientRects().length){return{top:0,left:0};}
rect=elem.getBoundingClientRect();win=elem.ownerDocument.defaultView;return{top:rect.top+win.pageYOffset,left:rect.left+win.pageXOffset};},position:function(){if(!this[0]){return;}
var offsetParent,offset,doc,elem=this[0],parentOffset={top:0,left:0};if(jQuery.css(elem,"position")==="fixed"){offset=elem.getBoundingClientRect();}else{offset=this.offset();doc=elem.ownerDocument;offsetParent=elem.offsetParent||doc.documentElement;while(offsetParent&&(offsetParent===doc.body||offsetParent===doc.documentElement)&&jQuery.css(offsetParent,"position")==="static"){offsetParent=offsetParent.parentNode;}
if(offsetParent&&offsetParent!==elem&&offsetParent.nodeType===1){parentOffset=jQuery(offsetParent).offset();parentOffset.top+=jQuery.css(offsetParent,"borderTopWidth",true);parentOffset.left+=jQuery.css(offsetParent,"borderLeftWidth",true);}}
return{top:offset.top-parentOffset.top-jQuery.css(elem,"marginTop",true),left:offset.left-parentOffset.left-jQuery.css(elem,"marginLeft",true)};},offsetParent:function(){return this.map(function(){var offsetParent=this.offsetParent;while(offsetParent&&jQuery.css(offsetParent,"position")==="static"){offsetParent=offsetParent.offsetParent;}
return offsetParent||documentElement;});}});jQuery.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(method,prop){var top="pageYOffset"===prop;jQuery.fn[method]=function(val){return access(this,function(elem,method,val){var win;if(isWindow(elem)){win=elem;}else if(elem.nodeType===9){win=elem.defaultView;}
if(val===undefined){return win?win[prop]:elem[method];}
if(win){win.scrollTo(!top?val:win.pageXOffset,top?val:win.pageYOffset);}else{elem[method]=val;}},method,val,arguments.length);};});jQuery.each(["top","left"],function(_i,prop){jQuery.cssHooks[prop]=addGetHookIf(support.pixelPosition,function(elem,computed){if(computed){computed=curCSS(elem,prop);return rnumnonpx.test(computed)?jQuery(elem).position()[prop]+"px":computed;}});});jQuery.each({Height:"height",Width:"width"},function(name,type){jQuery.each({padding:"inner"+name,content:type,"":"outer"+name},function(defaultExtra,funcName){jQuery.fn[funcName]=function(margin,value){var chainable=arguments.length&&(defaultExtra||typeof margin!=="boolean"),extra=defaultExtra||(margin===true||value===true?"margin":"border");return access(this,function(elem,type,value){var doc;if(isWindow(elem)){return funcName.indexOf("outer")===0?elem["inner"+name]:elem.document.documentElement["client"+name];}
if(elem.nodeType===9){doc=elem.documentElement;return Math.max(elem.body["scroll"+name],doc["scroll"+name],elem.body["offset"+name],doc["offset"+name],doc["client"+name]);}
return value===undefined?jQuery.css(elem,type,extra):jQuery.style(elem,type,value,extra);},type,chainable?margin:undefined,chainable);};});});jQuery.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(_i,type){jQuery.fn[type]=function(fn){return this.on(type,fn);};});jQuery.fn.extend({bind:function(types,data,fn){return this.on(types,null,data,fn);},unbind:function(types,fn){return this.off(types,null,fn);},delegate:function(selector,types,data,fn){return this.on(types,selector,data,fn);},undelegate:function(selector,types,fn){return arguments.length===1?this.off(selector,"**"):this.off(types,selector||"**",fn);},hover:function(fnOver,fnOut){return this.mouseenter(fnOver).mouseleave(fnOut||fnOver);}});jQuery.each(("blur focus focusin focusout resize scroll click dblclick "+"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave "+"change select submit keydown keypress keyup contextmenu").split(" "),function(_i,name){jQuery.fn[name]=function(data,fn){return arguments.length>0?this.on(name,null,data,fn):this.trigger(name);};});var rtrim=/^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;jQuery.proxy=function(fn,context){var tmp,args,proxy;if(typeof context==="string"){tmp=fn[context];context=fn;fn=tmp;}
if(!isFunction(fn)){return undefined;}
args=slice.call(arguments,2);proxy=function(){return fn.apply(context||this,args.concat(slice.call(arguments)));};proxy.guid=fn.guid=fn.guid||jQuery.guid++;return proxy;};jQuery.holdReady=function(hold){if(hold){jQuery.readyWait++;}else{jQuery.ready(true);}};jQuery.isArray=Array.isArray;jQuery.parseJSON=JSON.parse;jQuery.nodeName=nodeName;jQuery.isFunction=isFunction;jQuery.isWindow=isWindow;jQuery.camelCase=camelCase;jQuery.type=toType;jQuery.now=Date.now;jQuery.isNumeric=function(obj){var type=jQuery.type(obj);return(type==="number"||type==="string")&&!isNaN(obj-parseFloat(obj));};jQuery.trim=function(text){return text==null?"":(text+"").replace(rtrim,"$1");};if(typeof define==="function"&&define.amd){define("jquery",[],function(){return jQuery;});}
var
_jQuery=window.jQuery,_$=window.$;jQuery.noConflict=function(deep){if(window.$===jQuery){window.$=_$;}
if(deep&&window.jQuery===jQuery){window.jQuery=_jQuery;}
return jQuery;};if(typeof noGlobal==="undefined"){window.jQuery=window.$=jQuery;}
return jQuery;});;
/* /web/static/lib/popper/popper.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?factory(exports):typeof define==='function'&&define.amd?define(['exports'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,factory(global.Popper={}));}(this,(function(exports){'use strict';function getWindow(node){if(node==null){return window;}
if(node.toString()!=='[object Window]'){var ownerDocument=node.ownerDocument;return ownerDocument?ownerDocument.defaultView||window:window;}
return node;}
function isElement(node){var OwnElement=getWindow(node).Element;return node instanceof OwnElement||node instanceof Element;}
function isHTMLElement(node){var OwnElement=getWindow(node).HTMLElement;return node instanceof OwnElement||node instanceof HTMLElement;}
function isShadowRoot(node){if(typeof ShadowRoot==='undefined'){return false;}
var OwnElement=getWindow(node).ShadowRoot;return node instanceof OwnElement||node instanceof ShadowRoot;}
var max=Math.max;var min=Math.min;var round=Math.round;function getUAString(){var uaData=navigator.userAgentData;if(uaData!=null&&uaData.brands&&Array.isArray(uaData.brands)){return uaData.brands.map(function(item){return item.brand+"/"+item.version;}).join(' ');}
return navigator.userAgent;}
function isLayoutViewport(){return!/^((?!chrome|android).)*safari/i.test(getUAString());}
function getBoundingClientRect(element,includeScale,isFixedStrategy){if(includeScale===void 0){includeScale=false;}
if(isFixedStrategy===void 0){isFixedStrategy=false;}
var clientRect=element.getBoundingClientRect();var scaleX=1;var scaleY=1;if(includeScale&&isHTMLElement(element)){scaleX=element.offsetWidth>0?round(clientRect.width)/element.offsetWidth||1:1;scaleY=element.offsetHeight>0?round(clientRect.height)/element.offsetHeight||1:1;}
var _ref=isElement(element)?getWindow(element):window,visualViewport=_ref.visualViewport;var addVisualOffsets=!isLayoutViewport()&&isFixedStrategy;var x=(clientRect.left+(addVisualOffsets&&visualViewport?visualViewport.offsetLeft:0))/scaleX;var y=(clientRect.top+(addVisualOffsets&&visualViewport?visualViewport.offsetTop:0))/scaleY;var width=clientRect.width/scaleX;var height=clientRect.height/scaleY;return{width:width,height:height,top:y,right:x+width,bottom:y+height,left:x,x:x,y:y};}
function getWindowScroll(node){var win=getWindow(node);var scrollLeft=win.pageXOffset;var scrollTop=win.pageYOffset;return{scrollLeft:scrollLeft,scrollTop:scrollTop};}
function getHTMLElementScroll(element){return{scrollLeft:element.scrollLeft,scrollTop:element.scrollTop};}
function getNodeScroll(node){if(node===getWindow(node)||!isHTMLElement(node)){return getWindowScroll(node);}else{return getHTMLElementScroll(node);}}
function getNodeName(element){return element?(element.nodeName||'').toLowerCase():null;}
function getDocumentElement(element){return((isElement(element)?element.ownerDocument:element.document)||window.document).documentElement;}
function getWindowScrollBarX(element){return getBoundingClientRect(getDocumentElement(element)).left+getWindowScroll(element).scrollLeft;}
function getComputedStyle(element){return getWindow(element).getComputedStyle(element);}
function isScrollParent(element){var _getComputedStyle=getComputedStyle(element),overflow=_getComputedStyle.overflow,overflowX=_getComputedStyle.overflowX,overflowY=_getComputedStyle.overflowY;return/auto|scroll|overlay|hidden/.test(overflow+overflowY+overflowX);}
function isElementScaled(element){var rect=element.getBoundingClientRect();var scaleX=round(rect.width)/element.offsetWidth||1;var scaleY=round(rect.height)/element.offsetHeight||1;return scaleX!==1||scaleY!==1;}
function getCompositeRect(elementOrVirtualElement,offsetParent,isFixed){if(isFixed===void 0){isFixed=false;}
var isOffsetParentAnElement=isHTMLElement(offsetParent);var offsetParentIsScaled=isHTMLElement(offsetParent)&&isElementScaled(offsetParent);var documentElement=getDocumentElement(offsetParent);var rect=getBoundingClientRect(elementOrVirtualElement,offsetParentIsScaled,isFixed);var scroll={scrollLeft:0,scrollTop:0};var offsets={x:0,y:0};if(isOffsetParentAnElement||!isOffsetParentAnElement&&!isFixed){if(getNodeName(offsetParent)!=='body'||isScrollParent(documentElement)){scroll=getNodeScroll(offsetParent);}
if(isHTMLElement(offsetParent)){offsets=getBoundingClientRect(offsetParent,true);offsets.x+=offsetParent.clientLeft;offsets.y+=offsetParent.clientTop;}else if(documentElement){offsets.x=getWindowScrollBarX(documentElement);}}
return{x:rect.left+scroll.scrollLeft-offsets.x,y:rect.top+scroll.scrollTop-offsets.y,width:rect.width,height:rect.height};}
function getLayoutRect(element){var clientRect=getBoundingClientRect(element);var width=element.offsetWidth;var height=element.offsetHeight;if(Math.abs(clientRect.width-width)<=1){width=clientRect.width;}
if(Math.abs(clientRect.height-height)<=1){height=clientRect.height;}
return{x:element.offsetLeft,y:element.offsetTop,width:width,height:height};}
function getParentNode(element){if(getNodeName(element)==='html'){return element;}
return(element.assignedSlot||element.parentNode||(isShadowRoot(element)?element.host:null)||getDocumentElement(element));}
function getScrollParent(node){if(['html','body','#document'].indexOf(getNodeName(node))>=0){return node.ownerDocument.body;}
if(isHTMLElement(node)&&isScrollParent(node)){return node;}
return getScrollParent(getParentNode(node));}
function listScrollParents(element,list){var _element$ownerDocumen;if(list===void 0){list=[];}
var scrollParent=getScrollParent(element);var isBody=scrollParent===((_element$ownerDocumen=element.ownerDocument)==null?void 0:_element$ownerDocumen.body);var win=getWindow(scrollParent);var target=isBody?[win].concat(win.visualViewport||[],isScrollParent(scrollParent)?scrollParent:[]):scrollParent;var updatedList=list.concat(target);return isBody?updatedList:updatedList.concat(listScrollParents(getParentNode(target)));}
function isTableElement(element){return['table','td','th'].indexOf(getNodeName(element))>=0;}
function getTrueOffsetParent(element){if(!isHTMLElement(element)||getComputedStyle(element).position==='fixed'){return null;}
return element.offsetParent;}
function getContainingBlock(element){var isFirefox=/firefox/i.test(getUAString());var isIE=/Trident/i.test(getUAString());if(isIE&&isHTMLElement(element)){var elementCss=getComputedStyle(element);if(elementCss.position==='fixed'){return null;}}
var currentNode=getParentNode(element);if(isShadowRoot(currentNode)){currentNode=currentNode.host;}
while(isHTMLElement(currentNode)&&['html','body'].indexOf(getNodeName(currentNode))<0){var css=getComputedStyle(currentNode);if(css.transform!=='none'||css.perspective!=='none'||css.contain==='paint'||['transform','perspective'].indexOf(css.willChange)!==-1||isFirefox&&css.willChange==='filter'||isFirefox&&css.filter&&css.filter!=='none'){return currentNode;}else{currentNode=currentNode.parentNode;}}
return null;}
function getOffsetParent(element){var window=getWindow(element);var offsetParent=getTrueOffsetParent(element);while(offsetParent&&isTableElement(offsetParent)&&getComputedStyle(offsetParent).position==='static'){offsetParent=getTrueOffsetParent(offsetParent);}
if(offsetParent&&(getNodeName(offsetParent)==='html'||getNodeName(offsetParent)==='body'&&getComputedStyle(offsetParent).position==='static')){return window;}
return offsetParent||getContainingBlock(element)||window;}
var top='top';var bottom='bottom';var right='right';var left='left';var auto='auto';var basePlacements=[top,bottom,right,left];var start='start';var end='end';var clippingParents='clippingParents';var viewport='viewport';var popper='popper';var reference='reference';var variationPlacements=basePlacements.reduce(function(acc,placement){return acc.concat([placement+"-"+start,placement+"-"+end]);},[]);var placements=[].concat(basePlacements,[auto]).reduce(function(acc,placement){return acc.concat([placement,placement+"-"+start,placement+"-"+end]);},[]);var beforeRead='beforeRead';var read='read';var afterRead='afterRead';var beforeMain='beforeMain';var main='main';var afterMain='afterMain';var beforeWrite='beforeWrite';var write='write';var afterWrite='afterWrite';var modifierPhases=[beforeRead,read,afterRead,beforeMain,main,afterMain,beforeWrite,write,afterWrite];function order(modifiers){var map=new Map();var visited=new Set();var result=[];modifiers.forEach(function(modifier){map.set(modifier.name,modifier);});function sort(modifier){visited.add(modifier.name);var requires=[].concat(modifier.requires||[],modifier.requiresIfExists||[]);requires.forEach(function(dep){if(!visited.has(dep)){var depModifier=map.get(dep);if(depModifier){sort(depModifier);}}});result.push(modifier);}
modifiers.forEach(function(modifier){if(!visited.has(modifier.name)){sort(modifier);}});return result;}
function orderModifiers(modifiers){var orderedModifiers=order(modifiers);return modifierPhases.reduce(function(acc,phase){return acc.concat(orderedModifiers.filter(function(modifier){return modifier.phase===phase;}));},[]);}
function debounce(fn){var pending;return function(){if(!pending){pending=new Promise(function(resolve){Promise.resolve().then(function(){pending=undefined;resolve(fn());});});}
return pending;};}
function mergeByName(modifiers){var merged=modifiers.reduce(function(merged,current){var existing=merged[current.name];merged[current.name]=existing?Object.assign({},existing,current,{options:Object.assign({},existing.options,current.options),data:Object.assign({},existing.data,current.data)}):current;return merged;},{});return Object.keys(merged).map(function(key){return merged[key];});}
function getViewportRect(element,strategy){var win=getWindow(element);var html=getDocumentElement(element);var visualViewport=win.visualViewport;var width=html.clientWidth;var height=html.clientHeight;var x=0;var y=0;if(visualViewport){width=visualViewport.width;height=visualViewport.height;var layoutViewport=isLayoutViewport();if(layoutViewport||!layoutViewport&&strategy==='fixed'){x=visualViewport.offsetLeft;y=visualViewport.offsetTop;}}
return{width:width,height:height,x:x+getWindowScrollBarX(element),y:y};}
function getDocumentRect(element){var _element$ownerDocumen;var html=getDocumentElement(element);var winScroll=getWindowScroll(element);var body=(_element$ownerDocumen=element.ownerDocument)==null?void 0:_element$ownerDocumen.body;var width=max(html.scrollWidth,html.clientWidth,body?body.scrollWidth:0,body?body.clientWidth:0);var height=max(html.scrollHeight,html.clientHeight,body?body.scrollHeight:0,body?body.clientHeight:0);var x=-winScroll.scrollLeft+getWindowScrollBarX(element);var y=-winScroll.scrollTop;if(getComputedStyle(body||html).direction==='rtl'){x+=max(html.clientWidth,body?body.clientWidth:0)-width;}
return{width:width,height:height,x:x,y:y};}
function contains(parent,child){var rootNode=child.getRootNode&&child.getRootNode();if(parent.contains(child)){return true;}
else if(rootNode&&isShadowRoot(rootNode)){var next=child;do{if(next&&parent.isSameNode(next)){return true;}
next=next.parentNode||next.host;}while(next);}
return false;}
function rectToClientRect(rect){return Object.assign({},rect,{left:rect.x,top:rect.y,right:rect.x+rect.width,bottom:rect.y+rect.height});}
function getInnerBoundingClientRect(element,strategy){var rect=getBoundingClientRect(element,false,strategy==='fixed');rect.top=rect.top+element.clientTop;rect.left=rect.left+element.clientLeft;rect.bottom=rect.top+element.clientHeight;rect.right=rect.left+element.clientWidth;rect.width=element.clientWidth;rect.height=element.clientHeight;rect.x=rect.left;rect.y=rect.top;return rect;}
function getClientRectFromMixedType(element,clippingParent,strategy){return clippingParent===viewport?rectToClientRect(getViewportRect(element,strategy)):isElement(clippingParent)?getInnerBoundingClientRect(clippingParent,strategy):rectToClientRect(getDocumentRect(getDocumentElement(element)));}
function getClippingParents(element){var clippingParents=listScrollParents(getParentNode(element));var canEscapeClipping=['absolute','fixed'].indexOf(getComputedStyle(element).position)>=0;var clipperElement=canEscapeClipping&&isHTMLElement(element)?getOffsetParent(element):element;if(!isElement(clipperElement)){return[];}
return clippingParents.filter(function(clippingParent){return isElement(clippingParent)&&contains(clippingParent,clipperElement)&&getNodeName(clippingParent)!=='body';});}
function getClippingRect(element,boundary,rootBoundary,strategy){var mainClippingParents=boundary==='clippingParents'?getClippingParents(element):[].concat(boundary);var clippingParents=[].concat(mainClippingParents,[rootBoundary]);var firstClippingParent=clippingParents[0];var clippingRect=clippingParents.reduce(function(accRect,clippingParent){var rect=getClientRectFromMixedType(element,clippingParent,strategy);accRect.top=max(rect.top,accRect.top);accRect.right=min(rect.right,accRect.right);accRect.bottom=min(rect.bottom,accRect.bottom);accRect.left=max(rect.left,accRect.left);return accRect;},getClientRectFromMixedType(element,firstClippingParent,strategy));clippingRect.width=clippingRect.right-clippingRect.left;clippingRect.height=clippingRect.bottom-clippingRect.top;clippingRect.x=clippingRect.left;clippingRect.y=clippingRect.top;return clippingRect;}
function getBasePlacement(placement){return placement.split('-')[0];}
function getVariation(placement){return placement.split('-')[1];}
function getMainAxisFromPlacement(placement){return['top','bottom'].indexOf(placement)>=0?'x':'y';}
function computeOffsets(_ref){var reference=_ref.reference,element=_ref.element,placement=_ref.placement;var basePlacement=placement?getBasePlacement(placement):null;var variation=placement?getVariation(placement):null;var commonX=reference.x+reference.width/2-element.width/2;var commonY=reference.y+reference.height/2-element.height/2;var offsets;switch(basePlacement){case top:offsets={x:commonX,y:reference.y-element.height};break;case bottom:offsets={x:commonX,y:reference.y+reference.height};break;case right:offsets={x:reference.x+reference.width,y:commonY};break;case left:offsets={x:reference.x-element.width,y:commonY};break;default:offsets={x:reference.x,y:reference.y};}
var mainAxis=basePlacement?getMainAxisFromPlacement(basePlacement):null;if(mainAxis!=null){var len=mainAxis==='y'?'height':'width';switch(variation){case start:offsets[mainAxis]=offsets[mainAxis]-(reference[len]/2-element[len]/2);break;case end:offsets[mainAxis]=offsets[mainAxis]+(reference[len]/2-element[len]/2);break;}}
return offsets;}
function getFreshSideObject(){return{top:0,right:0,bottom:0,left:0};}
function mergePaddingObject(paddingObject){return Object.assign({},getFreshSideObject(),paddingObject);}
function expandToHashMap(value,keys){return keys.reduce(function(hashMap,key){hashMap[key]=value;return hashMap;},{});}
function detectOverflow(state,options){if(options===void 0){options={};}
var _options=options,_options$placement=_options.placement,placement=_options$placement===void 0?state.placement:_options$placement,_options$strategy=_options.strategy,strategy=_options$strategy===void 0?state.strategy:_options$strategy,_options$boundary=_options.boundary,boundary=_options$boundary===void 0?clippingParents:_options$boundary,_options$rootBoundary=_options.rootBoundary,rootBoundary=_options$rootBoundary===void 0?viewport:_options$rootBoundary,_options$elementConte=_options.elementContext,elementContext=_options$elementConte===void 0?popper:_options$elementConte,_options$altBoundary=_options.altBoundary,altBoundary=_options$altBoundary===void 0?false:_options$altBoundary,_options$padding=_options.padding,padding=_options$padding===void 0?0:_options$padding;var paddingObject=mergePaddingObject(typeof padding!=='number'?padding:expandToHashMap(padding,basePlacements));var altContext=elementContext===popper?reference:popper;var popperRect=state.rects.popper;var element=state.elements[altBoundary?altContext:elementContext];var clippingClientRect=getClippingRect(isElement(element)?element:element.contextElement||getDocumentElement(state.elements.popper),boundary,rootBoundary,strategy);var referenceClientRect=getBoundingClientRect(state.elements.reference);var popperOffsets=computeOffsets({reference:referenceClientRect,element:popperRect,strategy:'absolute',placement:placement});var popperClientRect=rectToClientRect(Object.assign({},popperRect,popperOffsets));var elementClientRect=elementContext===popper?popperClientRect:referenceClientRect;var overflowOffsets={top:clippingClientRect.top-elementClientRect.top+paddingObject.top,bottom:elementClientRect.bottom-clippingClientRect.bottom+paddingObject.bottom,left:clippingClientRect.left-elementClientRect.left+paddingObject.left,right:elementClientRect.right-clippingClientRect.right+paddingObject.right};var offsetData=state.modifiersData.offset;if(elementContext===popper&&offsetData){var offset=offsetData[placement];Object.keys(overflowOffsets).forEach(function(key){var multiply=[right,bottom].indexOf(key)>=0?1:-1;var axis=[top,bottom].indexOf(key)>=0?'y':'x';overflowOffsets[key]+=offset[axis]*multiply;});}
return overflowOffsets;}
var DEFAULT_OPTIONS={placement:'bottom',modifiers:[],strategy:'absolute'};function areValidElements(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}
return!args.some(function(element){return!(element&&typeof element.getBoundingClientRect==='function');});}
function popperGenerator(generatorOptions){if(generatorOptions===void 0){generatorOptions={};}
var _generatorOptions=generatorOptions,_generatorOptions$def=_generatorOptions.defaultModifiers,defaultModifiers=_generatorOptions$def===void 0?[]:_generatorOptions$def,_generatorOptions$def2=_generatorOptions.defaultOptions,defaultOptions=_generatorOptions$def2===void 0?DEFAULT_OPTIONS:_generatorOptions$def2;return function createPopper(reference,popper,options){if(options===void 0){options=defaultOptions;}
var state={placement:'bottom',orderedModifiers:[],options:Object.assign({},DEFAULT_OPTIONS,defaultOptions),modifiersData:{},elements:{reference:reference,popper:popper},attributes:{},styles:{}};var effectCleanupFns=[];var isDestroyed=false;var instance={state:state,setOptions:function setOptions(setOptionsAction){var options=typeof setOptionsAction==='function'?setOptionsAction(state.options):setOptionsAction;cleanupModifierEffects();state.options=Object.assign({},defaultOptions,state.options,options);state.scrollParents={reference:isElement(reference)?listScrollParents(reference):reference.contextElement?listScrollParents(reference.contextElement):[],popper:listScrollParents(popper)};var orderedModifiers=orderModifiers(mergeByName([].concat(defaultModifiers,state.options.modifiers)));state.orderedModifiers=orderedModifiers.filter(function(m){return m.enabled;});runModifierEffects();return instance.update();},forceUpdate:function forceUpdate(){if(isDestroyed){return;}
var _state$elements=state.elements,reference=_state$elements.reference,popper=_state$elements.popper;if(!areValidElements(reference,popper)){return;}
state.rects={reference:getCompositeRect(reference,getOffsetParent(popper),state.options.strategy==='fixed'),popper:getLayoutRect(popper)};state.reset=false;state.placement=state.options.placement;state.orderedModifiers.forEach(function(modifier){return state.modifiersData[modifier.name]=Object.assign({},modifier.data);});for(var index=0;index<state.orderedModifiers.length;index++){if(state.reset===true){state.reset=false;index=-1;continue;}
var _state$orderedModifie=state.orderedModifiers[index],fn=_state$orderedModifie.fn,_state$orderedModifie2=_state$orderedModifie.options,_options=_state$orderedModifie2===void 0?{}:_state$orderedModifie2,name=_state$orderedModifie.name;if(typeof fn==='function'){state=fn({state:state,options:_options,name:name,instance:instance})||state;}}},update:debounce(function(){return new Promise(function(resolve){instance.forceUpdate();resolve(state);});}),destroy:function destroy(){cleanupModifierEffects();isDestroyed=true;}};if(!areValidElements(reference,popper)){return instance;}
instance.setOptions(options).then(function(state){if(!isDestroyed&&options.onFirstUpdate){options.onFirstUpdate(state);}});function runModifierEffects(){state.orderedModifiers.forEach(function(_ref){var name=_ref.name,_ref$options=_ref.options,options=_ref$options===void 0?{}:_ref$options,effect=_ref.effect;if(typeof effect==='function'){var cleanupFn=effect({state:state,name:name,instance:instance,options:options});var noopFn=function noopFn(){};effectCleanupFns.push(cleanupFn||noopFn);}});}
function cleanupModifierEffects(){effectCleanupFns.forEach(function(fn){return fn();});effectCleanupFns=[];}
return instance;};}
var passive={passive:true};function effect$2(_ref){var state=_ref.state,instance=_ref.instance,options=_ref.options;var _options$scroll=options.scroll,scroll=_options$scroll===void 0?true:_options$scroll,_options$resize=options.resize,resize=_options$resize===void 0?true:_options$resize;var window=getWindow(state.elements.popper);var scrollParents=[].concat(state.scrollParents.reference,state.scrollParents.popper);if(scroll){scrollParents.forEach(function(scrollParent){scrollParent.addEventListener('scroll',instance.update,passive);});}
if(resize){window.addEventListener('resize',instance.update,passive);}
return function(){if(scroll){scrollParents.forEach(function(scrollParent){scrollParent.removeEventListener('scroll',instance.update,passive);});}
if(resize){window.removeEventListener('resize',instance.update,passive);}};}
var eventListeners={name:'eventListeners',enabled:true,phase:'write',fn:function fn(){},effect:effect$2,data:{}};function popperOffsets(_ref){var state=_ref.state,name=_ref.name;state.modifiersData[name]=computeOffsets({reference:state.rects.reference,element:state.rects.popper,strategy:'absolute',placement:state.placement});}
var popperOffsets$1={name:'popperOffsets',enabled:true,phase:'read',fn:popperOffsets,data:{}};var unsetSides={top:'auto',right:'auto',bottom:'auto',left:'auto'};function roundOffsetsByDPR(_ref,win){var x=_ref.x,y=_ref.y;var dpr=win.devicePixelRatio||1;return{x:round(x*dpr)/dpr||0,y:round(y*dpr)/dpr||0};}
function mapToStyles(_ref2){var _Object$assign2;var popper=_ref2.popper,popperRect=_ref2.popperRect,placement=_ref2.placement,variation=_ref2.variation,offsets=_ref2.offsets,position=_ref2.position,gpuAcceleration=_ref2.gpuAcceleration,adaptive=_ref2.adaptive,roundOffsets=_ref2.roundOffsets,isFixed=_ref2.isFixed;var _offsets$x=offsets.x,x=_offsets$x===void 0?0:_offsets$x,_offsets$y=offsets.y,y=_offsets$y===void 0?0:_offsets$y;var _ref3=typeof roundOffsets==='function'?roundOffsets({x:x,y:y}):{x:x,y:y};x=_ref3.x;y=_ref3.y;var hasX=offsets.hasOwnProperty('x');var hasY=offsets.hasOwnProperty('y');var sideX=left;var sideY=top;var win=window;if(adaptive){var offsetParent=getOffsetParent(popper);var heightProp='clientHeight';var widthProp='clientWidth';if(offsetParent===getWindow(popper)){offsetParent=getDocumentElement(popper);if(getComputedStyle(offsetParent).position!=='static'&&position==='absolute'){heightProp='scrollHeight';widthProp='scrollWidth';}}
offsetParent=offsetParent;if(placement===top||(placement===left||placement===right)&&variation===end){sideY=bottom;var offsetY=isFixed&&offsetParent===win&&win.visualViewport?win.visualViewport.height:offsetParent[heightProp];y-=offsetY-popperRect.height;y*=gpuAcceleration?1:-1;}
if(placement===left||(placement===top||placement===bottom)&&variation===end){sideX=right;var offsetX=isFixed&&offsetParent===win&&win.visualViewport?win.visualViewport.width:offsetParent[widthProp];x-=offsetX-popperRect.width;x*=gpuAcceleration?1:-1;}}
var commonStyles=Object.assign({position:position},adaptive&&unsetSides);var _ref4=roundOffsets===true?roundOffsetsByDPR({x:x,y:y},getWindow(popper)):{x:x,y:y};x=_ref4.x;y=_ref4.y;if(gpuAcceleration){var _Object$assign;return Object.assign({},commonStyles,(_Object$assign={},_Object$assign[sideY]=hasY?'0':'',_Object$assign[sideX]=hasX?'0':'',_Object$assign.transform=(win.devicePixelRatio||1)<=1?"translate("+x+"px, "+y+"px)":"translate3d("+x+"px, "+y+"px, 0)",_Object$assign));}
return Object.assign({},commonStyles,(_Object$assign2={},_Object$assign2[sideY]=hasY?y+"px":'',_Object$assign2[sideX]=hasX?x+"px":'',_Object$assign2.transform='',_Object$assign2));}
function computeStyles(_ref5){var state=_ref5.state,options=_ref5.options;var _options$gpuAccelerat=options.gpuAcceleration,gpuAcceleration=_options$gpuAccelerat===void 0?true:_options$gpuAccelerat,_options$adaptive=options.adaptive,adaptive=_options$adaptive===void 0?true:_options$adaptive,_options$roundOffsets=options.roundOffsets,roundOffsets=_options$roundOffsets===void 0?true:_options$roundOffsets;var commonStyles={placement:getBasePlacement(state.placement),variation:getVariation(state.placement),popper:state.elements.popper,popperRect:state.rects.popper,gpuAcceleration:gpuAcceleration,isFixed:state.options.strategy==='fixed'};if(state.modifiersData.popperOffsets!=null){state.styles.popper=Object.assign({},state.styles.popper,mapToStyles(Object.assign({},commonStyles,{offsets:state.modifiersData.popperOffsets,position:state.options.strategy,adaptive:adaptive,roundOffsets:roundOffsets})));}
if(state.modifiersData.arrow!=null){state.styles.arrow=Object.assign({},state.styles.arrow,mapToStyles(Object.assign({},commonStyles,{offsets:state.modifiersData.arrow,position:'absolute',adaptive:false,roundOffsets:roundOffsets})));}
state.attributes.popper=Object.assign({},state.attributes.popper,{'data-popper-placement':state.placement});}
var computeStyles$1={name:'computeStyles',enabled:true,phase:'beforeWrite',fn:computeStyles,data:{}};function applyStyles(_ref){var state=_ref.state;Object.keys(state.elements).forEach(function(name){var style=state.styles[name]||{};var attributes=state.attributes[name]||{};var element=state.elements[name];if(!isHTMLElement(element)||!getNodeName(element)){return;}
Object.assign(element.style,style);Object.keys(attributes).forEach(function(name){var value=attributes[name];if(value===false){element.removeAttribute(name);}else{element.setAttribute(name,value===true?'':value);}});});}
function effect$1(_ref2){var state=_ref2.state;var initialStyles={popper:{position:state.options.strategy,left:'0',top:'0',margin:'0'},arrow:{position:'absolute'},reference:{}};Object.assign(state.elements.popper.style,initialStyles.popper);state.styles=initialStyles;if(state.elements.arrow){Object.assign(state.elements.arrow.style,initialStyles.arrow);}
return function(){Object.keys(state.elements).forEach(function(name){var element=state.elements[name];var attributes=state.attributes[name]||{};var styleProperties=Object.keys(state.styles.hasOwnProperty(name)?state.styles[name]:initialStyles[name]);var style=styleProperties.reduce(function(style,property){style[property]='';return style;},{});if(!isHTMLElement(element)||!getNodeName(element)){return;}
Object.assign(element.style,style);Object.keys(attributes).forEach(function(attribute){element.removeAttribute(attribute);});});};}
var applyStyles$1={name:'applyStyles',enabled:true,phase:'write',fn:applyStyles,effect:effect$1,requires:['computeStyles']};function distanceAndSkiddingToXY(placement,rects,offset){var basePlacement=getBasePlacement(placement);var invertDistance=[left,top].indexOf(basePlacement)>=0?-1:1;var _ref=typeof offset==='function'?offset(Object.assign({},rects,{placement:placement})):offset,skidding=_ref[0],distance=_ref[1];skidding=skidding||0;distance=(distance||0)*invertDistance;return[left,right].indexOf(basePlacement)>=0?{x:distance,y:skidding}:{x:skidding,y:distance};}
function offset(_ref2){var state=_ref2.state,options=_ref2.options,name=_ref2.name;var _options$offset=options.offset,offset=_options$offset===void 0?[0,0]:_options$offset;var data=placements.reduce(function(acc,placement){acc[placement]=distanceAndSkiddingToXY(placement,state.rects,offset);return acc;},{});var _data$state$placement=data[state.placement],x=_data$state$placement.x,y=_data$state$placement.y;if(state.modifiersData.popperOffsets!=null){state.modifiersData.popperOffsets.x+=x;state.modifiersData.popperOffsets.y+=y;}
state.modifiersData[name]=data;}
var offset$1={name:'offset',enabled:true,phase:'main',requires:['popperOffsets'],fn:offset};var hash$1={left:'right',right:'left',bottom:'top',top:'bottom'};function getOppositePlacement(placement){return placement.replace(/left|right|bottom|top/g,function(matched){return hash$1[matched];});}
var hash={start:'end',end:'start'};function getOppositeVariationPlacement(placement){return placement.replace(/start|end/g,function(matched){return hash[matched];});}
function computeAutoPlacement(state,options){if(options===void 0){options={};}
var _options=options,placement=_options.placement,boundary=_options.boundary,rootBoundary=_options.rootBoundary,padding=_options.padding,flipVariations=_options.flipVariations,_options$allowedAutoP=_options.allowedAutoPlacements,allowedAutoPlacements=_options$allowedAutoP===void 0?placements:_options$allowedAutoP;var variation=getVariation(placement);var placements$1=variation?flipVariations?variationPlacements:variationPlacements.filter(function(placement){return getVariation(placement)===variation;}):basePlacements;var allowedPlacements=placements$1.filter(function(placement){return allowedAutoPlacements.indexOf(placement)>=0;});if(allowedPlacements.length===0){allowedPlacements=placements$1;}
var overflows=allowedPlacements.reduce(function(acc,placement){acc[placement]=detectOverflow(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,padding:padding})[getBasePlacement(placement)];return acc;},{});return Object.keys(overflows).sort(function(a,b){return overflows[a]-overflows[b];});}
function getExpandedFallbackPlacements(placement){if(getBasePlacement(placement)===auto){return[];}
var oppositePlacement=getOppositePlacement(placement);return[getOppositeVariationPlacement(placement),oppositePlacement,getOppositeVariationPlacement(oppositePlacement)];}
function flip(_ref){var state=_ref.state,options=_ref.options,name=_ref.name;if(state.modifiersData[name]._skip){return;}
var _options$mainAxis=options.mainAxis,checkMainAxis=_options$mainAxis===void 0?true:_options$mainAxis,_options$altAxis=options.altAxis,checkAltAxis=_options$altAxis===void 0?true:_options$altAxis,specifiedFallbackPlacements=options.fallbackPlacements,padding=options.padding,boundary=options.boundary,rootBoundary=options.rootBoundary,altBoundary=options.altBoundary,_options$flipVariatio=options.flipVariations,flipVariations=_options$flipVariatio===void 0?true:_options$flipVariatio,allowedAutoPlacements=options.allowedAutoPlacements;var preferredPlacement=state.options.placement;var basePlacement=getBasePlacement(preferredPlacement);var isBasePlacement=basePlacement===preferredPlacement;var fallbackPlacements=specifiedFallbackPlacements||(isBasePlacement||!flipVariations?[getOppositePlacement(preferredPlacement)]:getExpandedFallbackPlacements(preferredPlacement));var placements=[preferredPlacement].concat(fallbackPlacements).reduce(function(acc,placement){return acc.concat(getBasePlacement(placement)===auto?computeAutoPlacement(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,padding:padding,flipVariations:flipVariations,allowedAutoPlacements:allowedAutoPlacements}):placement);},[]);var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var checksMap=new Map();var makeFallbackChecks=true;var firstFittingPlacement=placements[0];for(var i=0;i<placements.length;i++){var placement=placements[i];var _basePlacement=getBasePlacement(placement);var isStartVariation=getVariation(placement)===start;var isVertical=[top,bottom].indexOf(_basePlacement)>=0;var len=isVertical?'width':'height';var overflow=detectOverflow(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,altBoundary:altBoundary,padding:padding});var mainVariationSide=isVertical?isStartVariation?right:left:isStartVariation?bottom:top;if(referenceRect[len]>popperRect[len]){mainVariationSide=getOppositePlacement(mainVariationSide);}
var altVariationSide=getOppositePlacement(mainVariationSide);var checks=[];if(checkMainAxis){checks.push(overflow[_basePlacement]<=0);}
if(checkAltAxis){checks.push(overflow[mainVariationSide]<=0,overflow[altVariationSide]<=0);}
if(checks.every(function(check){return check;})){firstFittingPlacement=placement;makeFallbackChecks=false;break;}
checksMap.set(placement,checks);}
if(makeFallbackChecks){var numberOfChecks=flipVariations?3:1;var _loop=function _loop(_i){var fittingPlacement=placements.find(function(placement){var checks=checksMap.get(placement);if(checks){return checks.slice(0,_i).every(function(check){return check;});}});if(fittingPlacement){firstFittingPlacement=fittingPlacement;return"break";}};for(var _i=numberOfChecks;_i>0;_i--){var _ret=_loop(_i);if(_ret==="break")break;}}
if(state.placement!==firstFittingPlacement){state.modifiersData[name]._skip=true;state.placement=firstFittingPlacement;state.reset=true;}}
var flip$1={name:'flip',enabled:true,phase:'main',fn:flip,requiresIfExists:['offset'],data:{_skip:false}};function getAltAxis(axis){return axis==='x'?'y':'x';}
function within(min$1,value,max$1){return max(min$1,min(value,max$1));}
function withinMaxClamp(min,value,max){var v=within(min,value,max);return v>max?max:v;}
function preventOverflow(_ref){var state=_ref.state,options=_ref.options,name=_ref.name;var _options$mainAxis=options.mainAxis,checkMainAxis=_options$mainAxis===void 0?true:_options$mainAxis,_options$altAxis=options.altAxis,checkAltAxis=_options$altAxis===void 0?false:_options$altAxis,boundary=options.boundary,rootBoundary=options.rootBoundary,altBoundary=options.altBoundary,padding=options.padding,_options$tether=options.tether,tether=_options$tether===void 0?true:_options$tether,_options$tetherOffset=options.tetherOffset,tetherOffset=_options$tetherOffset===void 0?0:_options$tetherOffset;var overflow=detectOverflow(state,{boundary:boundary,rootBoundary:rootBoundary,padding:padding,altBoundary:altBoundary});var basePlacement=getBasePlacement(state.placement);var variation=getVariation(state.placement);var isBasePlacement=!variation;var mainAxis=getMainAxisFromPlacement(basePlacement);var altAxis=getAltAxis(mainAxis);var popperOffsets=state.modifiersData.popperOffsets;var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var tetherOffsetValue=typeof tetherOffset==='function'?tetherOffset(Object.assign({},state.rects,{placement:state.placement})):tetherOffset;var normalizedTetherOffsetValue=typeof tetherOffsetValue==='number'?{mainAxis:tetherOffsetValue,altAxis:tetherOffsetValue}:Object.assign({mainAxis:0,altAxis:0},tetherOffsetValue);var offsetModifierState=state.modifiersData.offset?state.modifiersData.offset[state.placement]:null;var data={x:0,y:0};if(!popperOffsets){return;}
if(checkMainAxis){var _offsetModifierState$;var mainSide=mainAxis==='y'?top:left;var altSide=mainAxis==='y'?bottom:right;var len=mainAxis==='y'?'height':'width';var offset=popperOffsets[mainAxis];var min$1=offset+overflow[mainSide];var max$1=offset-overflow[altSide];var additive=tether?-popperRect[len]/2:0;var minLen=variation===start?referenceRect[len]:popperRect[len];var maxLen=variation===start?-popperRect[len]:-referenceRect[len];var arrowElement=state.elements.arrow;var arrowRect=tether&&arrowElement?getLayoutRect(arrowElement):{width:0,height:0};var arrowPaddingObject=state.modifiersData['arrow#persistent']?state.modifiersData['arrow#persistent'].padding:getFreshSideObject();var arrowPaddingMin=arrowPaddingObject[mainSide];var arrowPaddingMax=arrowPaddingObject[altSide];var arrowLen=within(0,referenceRect[len],arrowRect[len]);var minOffset=isBasePlacement?referenceRect[len]/2-additive-arrowLen-arrowPaddingMin-normalizedTetherOffsetValue.mainAxis:minLen-arrowLen-arrowPaddingMin-normalizedTetherOffsetValue.mainAxis;var maxOffset=isBasePlacement?-referenceRect[len]/2+additive+arrowLen+arrowPaddingMax+normalizedTetherOffsetValue.mainAxis:maxLen+arrowLen+arrowPaddingMax+normalizedTetherOffsetValue.mainAxis;var arrowOffsetParent=state.elements.arrow&&getOffsetParent(state.elements.arrow);var clientOffset=arrowOffsetParent?mainAxis==='y'?arrowOffsetParent.clientTop||0:arrowOffsetParent.clientLeft||0:0;var offsetModifierValue=(_offsetModifierState$=offsetModifierState==null?void 0:offsetModifierState[mainAxis])!=null?_offsetModifierState$:0;var tetherMin=offset+minOffset-offsetModifierValue-clientOffset;var tetherMax=offset+maxOffset-offsetModifierValue;var preventedOffset=within(tether?min(min$1,tetherMin):min$1,offset,tether?max(max$1,tetherMax):max$1);popperOffsets[mainAxis]=preventedOffset;data[mainAxis]=preventedOffset-offset;}
if(checkAltAxis){var _offsetModifierState$2;var _mainSide=mainAxis==='x'?top:left;var _altSide=mainAxis==='x'?bottom:right;var _offset=popperOffsets[altAxis];var _len=altAxis==='y'?'height':'width';var _min=_offset+overflow[_mainSide];var _max=_offset-overflow[_altSide];var isOriginSide=[top,left].indexOf(basePlacement)!==-1;var _offsetModifierValue=(_offsetModifierState$2=offsetModifierState==null?void 0:offsetModifierState[altAxis])!=null?_offsetModifierState$2:0;var _tetherMin=isOriginSide?_min:_offset-referenceRect[_len]-popperRect[_len]-_offsetModifierValue+normalizedTetherOffsetValue.altAxis;var _tetherMax=isOriginSide?_offset+referenceRect[_len]+popperRect[_len]-_offsetModifierValue-normalizedTetherOffsetValue.altAxis:_max;var _preventedOffset=tether&&isOriginSide?withinMaxClamp(_tetherMin,_offset,_tetherMax):within(tether?_tetherMin:_min,_offset,tether?_tetherMax:_max);popperOffsets[altAxis]=_preventedOffset;data[altAxis]=_preventedOffset-_offset;}
state.modifiersData[name]=data;}
var preventOverflow$1={name:'preventOverflow',enabled:true,phase:'main',fn:preventOverflow,requiresIfExists:['offset']};var toPaddingObject=function toPaddingObject(padding,state){padding=typeof padding==='function'?padding(Object.assign({},state.rects,{placement:state.placement})):padding;return mergePaddingObject(typeof padding!=='number'?padding:expandToHashMap(padding,basePlacements));};function arrow(_ref){var _state$modifiersData$;var state=_ref.state,name=_ref.name,options=_ref.options;var arrowElement=state.elements.arrow;var popperOffsets=state.modifiersData.popperOffsets;var basePlacement=getBasePlacement(state.placement);var axis=getMainAxisFromPlacement(basePlacement);var isVertical=[left,right].indexOf(basePlacement)>=0;var len=isVertical?'height':'width';if(!arrowElement||!popperOffsets){return;}
var paddingObject=toPaddingObject(options.padding,state);var arrowRect=getLayoutRect(arrowElement);var minProp=axis==='y'?top:left;var maxProp=axis==='y'?bottom:right;var endDiff=state.rects.reference[len]+state.rects.reference[axis]-popperOffsets[axis]-state.rects.popper[len];var startDiff=popperOffsets[axis]-state.rects.reference[axis];var arrowOffsetParent=getOffsetParent(arrowElement);var clientSize=arrowOffsetParent?axis==='y'?arrowOffsetParent.clientHeight||0:arrowOffsetParent.clientWidth||0:0;var centerToReference=endDiff/2-startDiff/2;var min=paddingObject[minProp];var max=clientSize-arrowRect[len]-paddingObject[maxProp];var center=clientSize/2-arrowRect[len]/2+centerToReference;var offset=within(min,center,max);var axisProp=axis;state.modifiersData[name]=(_state$modifiersData$={},_state$modifiersData$[axisProp]=offset,_state$modifiersData$.centerOffset=offset-center,_state$modifiersData$);}
function effect(_ref2){var state=_ref2.state,options=_ref2.options;var _options$element=options.element,arrowElement=_options$element===void 0?'[data-popper-arrow]':_options$element;if(arrowElement==null){return;}
if(typeof arrowElement==='string'){arrowElement=state.elements.popper.querySelector(arrowElement);if(!arrowElement){return;}}
if(!contains(state.elements.popper,arrowElement)){return;}
state.elements.arrow=arrowElement;}
var arrow$1={name:'arrow',enabled:true,phase:'main',fn:arrow,effect:effect,requires:['popperOffsets'],requiresIfExists:['preventOverflow']};function getSideOffsets(overflow,rect,preventedOffsets){if(preventedOffsets===void 0){preventedOffsets={x:0,y:0};}
return{top:overflow.top-rect.height-preventedOffsets.y,right:overflow.right-rect.width+preventedOffsets.x,bottom:overflow.bottom-rect.height+preventedOffsets.y,left:overflow.left-rect.width-preventedOffsets.x};}
function isAnySideFullyClipped(overflow){return[top,right,bottom,left].some(function(side){return overflow[side]>=0;});}
function hide(_ref){var state=_ref.state,name=_ref.name;var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var preventedOffsets=state.modifiersData.preventOverflow;var referenceOverflow=detectOverflow(state,{elementContext:'reference'});var popperAltOverflow=detectOverflow(state,{altBoundary:true});var referenceClippingOffsets=getSideOffsets(referenceOverflow,referenceRect);var popperEscapeOffsets=getSideOffsets(popperAltOverflow,popperRect,preventedOffsets);var isReferenceHidden=isAnySideFullyClipped(referenceClippingOffsets);var hasPopperEscaped=isAnySideFullyClipped(popperEscapeOffsets);state.modifiersData[name]={referenceClippingOffsets:referenceClippingOffsets,popperEscapeOffsets:popperEscapeOffsets,isReferenceHidden:isReferenceHidden,hasPopperEscaped:hasPopperEscaped};state.attributes.popper=Object.assign({},state.attributes.popper,{'data-popper-reference-hidden':isReferenceHidden,'data-popper-escaped':hasPopperEscaped});}
var hide$1={name:'hide',enabled:true,phase:'main',requiresIfExists:['preventOverflow'],fn:hide};var defaultModifiers$1=[eventListeners,popperOffsets$1,computeStyles$1,applyStyles$1];var createPopper$1=popperGenerator({defaultModifiers:defaultModifiers$1});var defaultModifiers=[eventListeners,popperOffsets$1,computeStyles$1,applyStyles$1,offset$1,flip$1,preventOverflow$1,arrow$1,hide$1];var createPopper=popperGenerator({defaultModifiers:defaultModifiers});exports.applyStyles=applyStyles$1;exports.arrow=arrow$1;exports.computeStyles=computeStyles$1;exports.createPopper=createPopper;exports.createPopperLite=createPopper$1;exports.defaultModifiers=defaultModifiers;exports.detectOverflow=detectOverflow;exports.eventListeners=eventListeners;exports.flip=flip$1;exports.hide=hide$1;exports.offset=offset$1;exports.popperGenerator=popperGenerator;exports.popperOffsets=popperOffsets$1;exports.preventOverflow=preventOverflow$1;Object.defineProperty(exports,'__esModule',{value:true});})));;
/* /web/static/lib/bootstrap/js/dist/util/index.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?factory(exports):typeof define==='function'&&define.amd?define(['exports'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,factory(global.Index={}));})(this,(function(exports){'use strict';const MAX_UID=1000000;const MILLISECONDS_MULTIPLIER=1000;const TRANSITION_END='transitionend';const parseSelector=selector=>{if(selector&&window.CSS&&window.CSS.escape){selector=selector.replace(/#([^\s"#']+)/g,(match,id)=>`#${CSS.escape(id)}`);}
return selector;};const toType=object=>{if(object===null||object===undefined){return`${object}`;}
return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase();};const getUID=prefix=>{do{prefix+=Math.floor(Math.random()*MAX_UID);}while(document.getElementById(prefix));return prefix;};const getTransitionDurationFromElement=element=>{if(!element){return 0;}
let{transitionDuration,transitionDelay}=window.getComputedStyle(element);const floatTransitionDuration=Number.parseFloat(transitionDuration);const floatTransitionDelay=Number.parseFloat(transitionDelay);if(!floatTransitionDuration&&!floatTransitionDelay){return 0;}
transitionDuration=transitionDuration.split(',')[0];transitionDelay=transitionDelay.split(',')[0];return(Number.parseFloat(transitionDuration)+Number.parseFloat(transitionDelay))*MILLISECONDS_MULTIPLIER;};const triggerTransitionEnd=element=>{element.dispatchEvent(new Event(TRANSITION_END));};const isElement=object=>{if(!object||typeof object!=='object'){return false;}
if(typeof object.jquery!=='undefined'){object=object[0];}
return typeof object.nodeType!=='undefined';};const getElement=object=>{if(isElement(object)){return object.jquery?object[0]:object;}
if(typeof object==='string'&&object.length>0){return document.querySelector(parseSelector(object));}
return null;};const isVisible=element=>{if(!isElement(element)||element.getClientRects().length===0){return false;}
const elementIsVisible=getComputedStyle(element).getPropertyValue('visibility')==='visible';const closedDetails=element.closest('details:not([open])');if(!closedDetails){return elementIsVisible;}
if(closedDetails!==element){const summary=element.closest('summary');if(summary&&summary.parentNode!==closedDetails){return false;}
if(summary===null){return false;}}
return elementIsVisible;};const isDisabled=element=>{if(!element||element.nodeType!==Node.ELEMENT_NODE){return true;}
if(element.classList.contains('disabled')){return true;}
if(typeof element.disabled!=='undefined'){return element.disabled;}
return element.hasAttribute('disabled')&&element.getAttribute('disabled')!=='false';};const findShadowRoot=element=>{if(!document.documentElement.attachShadow){return null;}
if(typeof element.getRootNode==='function'){const root=element.getRootNode();return root instanceof ShadowRoot?root:null;}
if(element instanceof ShadowRoot){return element;}
if(!element.parentNode){return null;}
return findShadowRoot(element.parentNode);};const noop=()=>{};const reflow=element=>{element.offsetHeight;};const getjQuery=()=>{if(window.jQuery&&!document.body.hasAttribute('data-bs-no-jquery')){return window.jQuery;}
return null;};const DOMContentLoadedCallbacks=[];const onDOMContentLoaded=callback=>{if(document.readyState==='loading'){if(!DOMContentLoadedCallbacks.length){document.addEventListener('DOMContentLoaded',()=>{for(const callback of DOMContentLoadedCallbacks){callback();}});}
DOMContentLoadedCallbacks.push(callback);}else{callback();}};const isRTL=()=>document.documentElement.dir==='rtl';const defineJQueryPlugin=plugin=>{onDOMContentLoaded(()=>{const $=getjQuery();if($){const name=plugin.NAME;const JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface;$.fn[name].Constructor=plugin;$.fn[name].noConflict=()=>{$.fn[name]=JQUERY_NO_CONFLICT;return plugin.jQueryInterface;};}});};const execute=(possibleCallback,args=[],defaultValue=possibleCallback)=>{return typeof possibleCallback==='function'?possibleCallback(...args):defaultValue;};const executeAfterTransition=(callback,transitionElement,waitForTransition=true)=>{if(!waitForTransition){execute(callback);return;}
const durationPadding=5;const emulatedDuration=getTransitionDurationFromElement(transitionElement)+durationPadding;let called=false;const handler=({target})=>{if(target!==transitionElement){return;}
called=true;transitionElement.removeEventListener(TRANSITION_END,handler);execute(callback);};transitionElement.addEventListener(TRANSITION_END,handler);setTimeout(()=>{if(!called){triggerTransitionEnd(transitionElement);}},emulatedDuration);};const getNextActiveElement=(list,activeElement,shouldGetNext,isCycleAllowed)=>{const listLength=list.length;let index=list.indexOf(activeElement);if(index===-1){return!shouldGetNext&&isCycleAllowed?list[listLength-1]:list[0];}
index+=shouldGetNext?1:-1;if(isCycleAllowed){index=(index+listLength)%listLength;}
return list[Math.max(0,Math.min(index,listLength-1))];};exports.defineJQueryPlugin=defineJQueryPlugin;exports.execute=execute;exports.executeAfterTransition=executeAfterTransition;exports.findShadowRoot=findShadowRoot;exports.getElement=getElement;exports.getNextActiveElement=getNextActiveElement;exports.getTransitionDurationFromElement=getTransitionDurationFromElement;exports.getUID=getUID;exports.getjQuery=getjQuery;exports.isDisabled=isDisabled;exports.isElement=isElement;exports.isRTL=isRTL;exports.isVisible=isVisible;exports.noop=noop;exports.onDOMContentLoaded=onDOMContentLoaded;exports.parseSelector=parseSelector;exports.reflow=reflow;exports.toType=toType;exports.triggerTransitionEnd=triggerTransitionEnd;Object.defineProperty(exports,Symbol.toStringTag,{value:'Module'});}));;
/* /web/static/lib/bootstrap/js/dist/dom/data.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory():typeof define==='function'&&define.amd?define(factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Data=factory());})(this,(function(){'use strict';const elementMap=new Map();const data={set(element,key,instance){if(!elementMap.has(element)){elementMap.set(element,new Map());}
const instanceMap=elementMap.get(element);if(!instanceMap.has(key)&&instanceMap.size!==0){console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);return;}
instanceMap.set(key,instance);},get(element,key){if(elementMap.has(element)){return elementMap.get(element).get(key)||null;}
return null;},remove(element,key){if(!elementMap.has(element)){return;}
const instanceMap=elementMap.get(element);instanceMap.delete(key);if(instanceMap.size===0){elementMap.delete(element);}}};return data;}));;
/* /web/static/lib/bootstrap/js/dist/dom/event-handler.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('../util/index.js')):typeof define==='function'&&define.amd?define(['../util/index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.EventHandler=factory(global.Index));})(this,(function(index_js){'use strict';const namespaceRegex=/[^.]*(?=\..*)\.|.*/;const stripNameRegex=/\..*/;const stripUidRegex=/::\d+$/;const eventRegistry={};let uidEvent=1;const customEvents={mouseenter:'mouseover',mouseleave:'mouseout'};const nativeEvents=new Set(['click','dblclick','mouseup','mousedown','contextmenu','mousewheel','DOMMouseScroll','mouseover','mouseout','mousemove','selectstart','selectend','keydown','keypress','keyup','orientationchange','touchstart','touchmove','touchend','touchcancel','pointerdown','pointermove','pointerup','pointerleave','pointercancel','gesturestart','gesturechange','gestureend','focus','blur','change','reset','select','submit','focusin','focusout','load','unload','beforeunload','resize','move','DOMContentLoaded','readystatechange','error','abort','scroll']);function makeEventUid(element,uid){return uid&&`${uid}::${uidEvent++}`||element.uidEvent||uidEvent++;}
function getElementEvents(element){const uid=makeEventUid(element);element.uidEvent=uid;eventRegistry[uid]=eventRegistry[uid]||{};return eventRegistry[uid];}
function bootstrapHandler(element,fn){return function handler(event){hydrateObj(event,{delegateTarget:element});if(handler.oneOff){EventHandler.off(element,event.type,fn);}
return fn.apply(element,[event]);};}
function bootstrapDelegationHandler(element,selector,fn){return function handler(event){const domElements=element.querySelectorAll(selector);for(let{target}=event;target&&target!==this;target=target.parentNode){for(const domElement of domElements){if(domElement!==target){continue;}
hydrateObj(event,{delegateTarget:target});if(handler.oneOff){EventHandler.off(element,event.type,selector,fn);}
return fn.apply(target,[event]);}}};}
function findHandler(events,callable,delegationSelector=null){return Object.values(events).find(event=>event.callable===callable&&event.delegationSelector===delegationSelector);}
function normalizeParameters(originalTypeEvent,handler,delegationFunction){const isDelegated=typeof handler==='string';const callable=isDelegated?delegationFunction:handler||delegationFunction;let typeEvent=getTypeEvent(originalTypeEvent);if(!nativeEvents.has(typeEvent)){typeEvent=originalTypeEvent;}
return[isDelegated,callable,typeEvent];}
function addHandler(element,originalTypeEvent,handler,delegationFunction,oneOff){if(typeof originalTypeEvent!=='string'||!element){return;}
let[isDelegated,callable,typeEvent]=normalizeParameters(originalTypeEvent,handler,delegationFunction);if(originalTypeEvent in customEvents){const wrapFunction=fn=>{return function(event){if(!event.relatedTarget||event.relatedTarget!==event.delegateTarget&&!event.delegateTarget.contains(event.relatedTarget)){return fn.call(this,event);}};};callable=wrapFunction(callable);}
const events=getElementEvents(element);const handlers=events[typeEvent]||(events[typeEvent]={});const previousFunction=findHandler(handlers,callable,isDelegated?handler:null);if(previousFunction){previousFunction.oneOff=previousFunction.oneOff&&oneOff;return;}
const uid=makeEventUid(callable,originalTypeEvent.replace(namespaceRegex,''));const fn=isDelegated?bootstrapDelegationHandler(element,handler,callable):bootstrapHandler(element,callable);fn.delegationSelector=isDelegated?handler:null;fn.callable=callable;fn.oneOff=oneOff;fn.uidEvent=uid;handlers[uid]=fn;element.addEventListener(typeEvent,fn,isDelegated);}
function removeHandler(element,events,typeEvent,handler,delegationSelector){const fn=findHandler(events[typeEvent],handler,delegationSelector);if(!fn){return;}
element.removeEventListener(typeEvent,fn,Boolean(delegationSelector));delete events[typeEvent][fn.uidEvent];}
function removeNamespacedHandlers(element,events,typeEvent,namespace){const storeElementEvent=events[typeEvent]||{};for(const[handlerKey,event]of Object.entries(storeElementEvent)){if(handlerKey.includes(namespace)){removeHandler(element,events,typeEvent,event.callable,event.delegationSelector);}}}
function getTypeEvent(event){event=event.replace(stripNameRegex,'');return customEvents[event]||event;}
const EventHandler={on(element,event,handler,delegationFunction){addHandler(element,event,handler,delegationFunction,false);},one(element,event,handler,delegationFunction){addHandler(element,event,handler,delegationFunction,true);},off(element,originalTypeEvent,handler,delegationFunction){if(typeof originalTypeEvent!=='string'||!element){return;}
const[isDelegated,callable,typeEvent]=normalizeParameters(originalTypeEvent,handler,delegationFunction);const inNamespace=typeEvent!==originalTypeEvent;const events=getElementEvents(element);const storeElementEvent=events[typeEvent]||{};const isNamespace=originalTypeEvent.startsWith('.');if(typeof callable!=='undefined'){if(!Object.keys(storeElementEvent).length){return;}
removeHandler(element,events,typeEvent,callable,isDelegated?handler:null);return;}
if(isNamespace){for(const elementEvent of Object.keys(events)){removeNamespacedHandlers(element,events,elementEvent,originalTypeEvent.slice(1));}}
for(const[keyHandlers,event]of Object.entries(storeElementEvent)){const handlerKey=keyHandlers.replace(stripUidRegex,'');if(!inNamespace||originalTypeEvent.includes(handlerKey)){removeHandler(element,events,typeEvent,event.callable,event.delegationSelector);}}},trigger(element,event,args){if(typeof event!=='string'||!element){return null;}
const $=index_js.getjQuery();const typeEvent=getTypeEvent(event);const inNamespace=event!==typeEvent;let jQueryEvent=null;let bubbles=true;let nativeDispatch=true;let defaultPrevented=false;if(inNamespace&&$){jQueryEvent=$.Event(event,args);$(element).trigger(jQueryEvent);bubbles=!jQueryEvent.isPropagationStopped();nativeDispatch=!jQueryEvent.isImmediatePropagationStopped();defaultPrevented=jQueryEvent.isDefaultPrevented();}
const evt=hydrateObj(new Event(event,{bubbles,cancelable:true}),args);if(defaultPrevented){evt.preventDefault();}
if(nativeDispatch){element.dispatchEvent(evt);}
if(evt.defaultPrevented&&jQueryEvent){jQueryEvent.preventDefault();}
return evt;}};function hydrateObj(obj,meta={}){for(const[key,value]of Object.entries(meta)){try{obj[key]=value;}catch(_unused){Object.defineProperty(obj,key,{configurable:true,get(){return value;}});}}
return obj;}
return EventHandler;}));;
/* /web/static/lib/bootstrap/js/dist/dom/manipulator.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory():typeof define==='function'&&define.amd?define(factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Manipulator=factory());})(this,(function(){'use strict';function normalizeData(value){if(value==='true'){return true;}
if(value==='false'){return false;}
if(value===Number(value).toString()){return Number(value);}
if(value===''||value==='null'){return null;}
if(typeof value!=='string'){return value;}
try{return JSON.parse(decodeURIComponent(value));}catch(_unused){return value;}}
function normalizeDataKey(key){return key.replace(/[A-Z]/g,chr=>`-${chr.toLowerCase()}`);}
const Manipulator={setDataAttribute(element,key,value){element.setAttribute(`data-bs-${normalizeDataKey(key)}`,value);},removeDataAttribute(element,key){element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);},getDataAttributes(element){if(!element){return{};}
const attributes={};const bsKeys=Object.keys(element.dataset).filter(key=>key.startsWith('bs')&&!key.startsWith('bsConfig'));for(const key of bsKeys){let pureKey=key.replace(/^bs/,'');pureKey=pureKey.charAt(0).toLowerCase()+pureKey.slice(1,pureKey.length);attributes[pureKey]=normalizeData(element.dataset[key]);}
return attributes;},getDataAttribute(element,key){return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));}};return Manipulator;}));;
/* /web/static/lib/bootstrap/js/dist/dom/selector-engine.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('../util/index.js')):typeof define==='function'&&define.amd?define(['../util/index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.SelectorEngine=factory(global.Index));})(this,(function(index_js){'use strict';const getSelector=element=>{let selector=element.getAttribute('data-bs-target');if(!selector||selector==='#'){let hrefAttribute=element.getAttribute('href');if(!hrefAttribute||!hrefAttribute.includes('#')&&!hrefAttribute.startsWith('.')){return null;}
if(hrefAttribute.includes('#')&&!hrefAttribute.startsWith('#')){hrefAttribute=`#${hrefAttribute.split('#')[1]}`;}
selector=hrefAttribute&&hrefAttribute!=='#'?hrefAttribute.trim():null;}
return selector?selector.split(',').map(sel=>index_js.parseSelector(sel)).join(','):null;};const SelectorEngine={find(selector,element=document.documentElement){return[].concat(...Element.prototype.querySelectorAll.call(element,selector));},findOne(selector,element=document.documentElement){return Element.prototype.querySelector.call(element,selector);},children(element,selector){return[].concat(...element.children).filter(child=>child.matches(selector));},parents(element,selector){const parents=[];let ancestor=element.parentNode.closest(selector);while(ancestor){parents.push(ancestor);ancestor=ancestor.parentNode.closest(selector);}
return parents;},prev(element,selector){let previous=element.previousElementSibling;while(previous){if(previous.matches(selector)){return[previous];}
previous=previous.previousElementSibling;}
return[];},next(element,selector){let next=element.nextElementSibling;while(next){if(next.matches(selector)){return[next];}
next=next.nextElementSibling;}
return[];},focusableChildren(element){const focusables=['a','button','input','textarea','select','details','[tabindex]','[contenteditable="true"]'].map(selector=>`${selector}:not([tabindex^="-"])`).join(',');return this.find(focusables,element).filter(el=>!index_js.isDisabled(el)&&index_js.isVisible(el));},getSelectorFromElement(element){const selector=getSelector(element);if(selector){return SelectorEngine.findOne(selector)?selector:null;}
return null;},getElementFromSelector(element){const selector=getSelector(element);return selector?SelectorEngine.findOne(selector):null;},getMultipleElementsFromSelector(element){const selector=getSelector(element);return selector?SelectorEngine.find(selector):[];}};return SelectorEngine;}));;
/* /web/static/lib/bootstrap/js/dist/util/config.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('../dom/manipulator.js'),require('./index.js')):typeof define==='function'&&define.amd?define(['../dom/manipulator','./index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Config=factory(global.Manipulator,global.Index));})(this,(function(Manipulator,index_js){'use strict';class Config{static get Default(){return{};}
static get DefaultType(){return{};}
static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!');}
_getConfig(config){config=this._mergeConfigObj(config);config=this._configAfterMerge(config);this._typeCheckConfig(config);return config;}
_configAfterMerge(config){return config;}
_mergeConfigObj(config,element){const jsonConfig=index_js.isElement(element)?Manipulator.getDataAttribute(element,'config'):{};return{...this.constructor.Default,...(typeof jsonConfig==='object'?jsonConfig:{}),...(index_js.isElement(element)?Manipulator.getDataAttributes(element):{}),...(typeof config==='object'?config:{})};}
_typeCheckConfig(config,configTypes=this.constructor.DefaultType){for(const[property,expectedTypes]of Object.entries(configTypes)){const value=config[property];const valueType=index_js.isElement(value)?'element':index_js.toType(value);if(!new RegExp(expectedTypes).test(valueType)){throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);}}}}
return Config;}));;
/* /web/static/lib/bootstrap/js/dist/util/component-functions.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?factory(exports,require('../dom/event-handler.js'),require('../dom/selector-engine.js'),require('./index.js')):typeof define==='function'&&define.amd?define(['exports','../dom/event-handler','../dom/selector-engine','./index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,factory(global.ComponentFunctions={},global.EventHandler,global.SelectorEngine,global.Index));})(this,(function(exports,EventHandler,SelectorEngine,index_js){'use strict';const enableDismissTrigger=(component,method='hide')=>{const clickEvent=`click.dismiss${component.EVENT_KEY}`;const name=component.NAME;EventHandler.on(document,clickEvent,`[data-bs-dismiss="${name}"]`,function(event){if(['A','AREA'].includes(this.tagName)){event.preventDefault();}
if(index_js.isDisabled(this)){return;}
const target=SelectorEngine.getElementFromSelector(this)||this.closest(`.${name}`);const instance=component.getOrCreateInstance(target);instance[method]();});};exports.enableDismissTrigger=enableDismissTrigger;Object.defineProperty(exports,Symbol.toStringTag,{value:'Module'});}));;
/* /web/static/lib/bootstrap/js/dist/util/backdrop.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('../dom/event-handler.js'),require('./config.js'),require('./index.js')):typeof define==='function'&&define.amd?define(['../dom/event-handler','./config','./index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Backdrop=factory(global.EventHandler,global.Config,global.Index));})(this,(function(EventHandler,Config,index_js){'use strict';const NAME='backdrop';const CLASS_NAME_FADE='fade';const CLASS_NAME_SHOW='show';const EVENT_MOUSEDOWN=`mousedown.bs.${NAME}`;const Default={className:'modal-backdrop',clickCallback:null,isAnimated:false,isVisible:true,rootElement:'body'};const DefaultType={className:'string',clickCallback:'(function|null)',isAnimated:'boolean',isVisible:'boolean',rootElement:'(element|string)'};class Backdrop extends Config{constructor(config){super();this._config=this._getConfig(config);this._isAppended=false;this._element=null;}
static get Default(){return Default;}
static get DefaultType(){return DefaultType;}
static get NAME(){return NAME;}
show(callback){if(!this._config.isVisible){index_js.execute(callback);return;}
this._append();const element=this._getElement();if(this._config.isAnimated){index_js.reflow(element);}
element.classList.add(CLASS_NAME_SHOW);this._emulateAnimation(()=>{index_js.execute(callback);});}
hide(callback){if(!this._config.isVisible){index_js.execute(callback);return;}
this._getElement().classList.remove(CLASS_NAME_SHOW);this._emulateAnimation(()=>{this.dispose();index_js.execute(callback);});}
dispose(){if(!this._isAppended){return;}
EventHandler.off(this._element,EVENT_MOUSEDOWN);this._element.remove();this._isAppended=false;}
_getElement(){if(!this._element){const backdrop=document.createElement('div');backdrop.className=this._config.className;if(this._config.isAnimated){backdrop.classList.add(CLASS_NAME_FADE);}
this._element=backdrop;}
return this._element;}
_configAfterMerge(config){config.rootElement=index_js.getElement(config.rootElement);return config;}
_append(){if(this._isAppended){return;}
const element=this._getElement();this._config.rootElement.append(element);EventHandler.on(element,EVENT_MOUSEDOWN,()=>{index_js.execute(this._config.clickCallback);});this._isAppended=true;}
_emulateAnimation(callback){index_js.executeAfterTransition(callback,this._getElement(),this._config.isAnimated);}}
return Backdrop;}));;
/* /web/static/lib/bootstrap/js/dist/util/focustrap.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('../dom/event-handler.js'),require('../dom/selector-engine.js'),require('./config.js')):typeof define==='function'&&define.amd?define(['../dom/event-handler','../dom/selector-engine','./config'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Focustrap=factory(global.EventHandler,global.SelectorEngine,global.Config));})(this,(function(EventHandler,SelectorEngine,Config){'use strict';const NAME='focustrap';const DATA_KEY='bs.focustrap';const EVENT_KEY=`.${DATA_KEY}`;const EVENT_FOCUSIN=`focusin${EVENT_KEY}`;const EVENT_KEYDOWN_TAB=`keydown.tab${EVENT_KEY}`;const TAB_KEY='Tab';const TAB_NAV_FORWARD='forward';const TAB_NAV_BACKWARD='backward';const Default={autofocus:true,trapElement:null};const DefaultType={autofocus:'boolean',trapElement:'element'};class FocusTrap extends Config{constructor(config){super();this._config=this._getConfig(config);this._isActive=false;this._lastTabNavDirection=null;}
static get Default(){return Default;}
static get DefaultType(){return DefaultType;}
static get NAME(){return NAME;}
activate(){if(this._isActive){return;}
if(this._config.autofocus){this._config.trapElement.focus();}
EventHandler.off(document,EVENT_KEY);EventHandler.on(document,EVENT_FOCUSIN,event=>this._handleFocusin(event));EventHandler.on(document,EVENT_KEYDOWN_TAB,event=>this._handleKeydown(event));this._isActive=true;}
deactivate(){if(!this._isActive){return;}
this._isActive=false;EventHandler.off(document,EVENT_KEY);}
_handleFocusin(event){const{trapElement}=this._config;if(event.target===document||event.target===trapElement||trapElement.contains(event.target)){return;}
const elements=SelectorEngine.focusableChildren(trapElement);if(elements.length===0){trapElement.focus();}else if(this._lastTabNavDirection===TAB_NAV_BACKWARD){elements[elements.length-1].focus();}else{elements[0].focus();}}
_handleKeydown(event){if(event.key!==TAB_KEY){return;}
this._lastTabNavDirection=event.shiftKey?TAB_NAV_BACKWARD:TAB_NAV_FORWARD;}}
return FocusTrap;}));;
/* /web/static/lib/bootstrap/js/dist/util/sanitizer.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?factory(exports):typeof define==='function'&&define.amd?define(['exports'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,factory(global.Sanitizer={}));})(this,(function(exports){'use strict';const ARIA_ATTRIBUTE_PATTERN=/^aria-[\w-]*$/i;const DefaultAllowlist={'*':['class','dir','id','lang','role',ARIA_ATTRIBUTE_PATTERN],a:['target','href','title','rel'],area:[],b:[],br:[],col:[],code:[],dd:[],div:[],dl:[],dt:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:['src','srcset','alt','title','width','height'],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]};const uriAttributes=new Set(['background','cite','href','itemtype','longdesc','poster','src','xlink:href']);const SAFE_URL_PATTERN=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;const allowedAttribute=(attribute,allowedAttributeList)=>{const attributeName=attribute.nodeName.toLowerCase();if(allowedAttributeList.includes(attributeName)){if(uriAttributes.has(attributeName)){return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue));}
return true;}
return allowedAttributeList.filter(attributeRegex=>attributeRegex instanceof RegExp).some(regex=>regex.test(attributeName));};function sanitizeHtml(unsafeHtml,allowList,sanitizeFunction){if(!unsafeHtml.length){return unsafeHtml;}
if(sanitizeFunction&&typeof sanitizeFunction==='function'){return sanitizeFunction(unsafeHtml);}
const domParser=new window.DOMParser();const createdDocument=domParser.parseFromString(unsafeHtml,'text/html');const elements=[].concat(...createdDocument.body.querySelectorAll('*'));for(const element of elements){const elementName=element.nodeName.toLowerCase();if(!Object.keys(allowList).includes(elementName)){element.remove();continue;}
const attributeList=[].concat(...element.attributes);const allowedAttributes=[].concat(allowList['*']||[],allowList[elementName]||[]);for(const attribute of attributeList){if(!allowedAttribute(attribute,allowedAttributes)){element.removeAttribute(attribute.nodeName);}}}
return createdDocument.body.innerHTML;}
exports.DefaultAllowlist=DefaultAllowlist;exports.sanitizeHtml=sanitizeHtml;Object.defineProperty(exports,Symbol.toStringTag,{value:'Module'});}));;
/* /web/static/lib/bootstrap/js/dist/util/scrollbar.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('../dom/manipulator.js'),require('../dom/selector-engine.js'),require('./index.js')):typeof define==='function'&&define.amd?define(['../dom/manipulator','../dom/selector-engine','./index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Scrollbar=factory(global.Manipulator,global.SelectorEngine,global.Index));})(this,(function(Manipulator,SelectorEngine,index_js){'use strict';const SELECTOR_FIXED_CONTENT='.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';const SELECTOR_STICKY_CONTENT='.sticky-top';const PROPERTY_PADDING='padding-right';const PROPERTY_MARGIN='margin-right';class ScrollBarHelper{constructor(){this._element=document.body;}
getWidth(){const documentWidth=document.documentElement.clientWidth;return Math.abs(window.innerWidth-documentWidth);}
hide(){const width=this.getWidth();this._disableOverFlow();this._setElementAttributes(this._element,PROPERTY_PADDING,calculatedValue=>calculatedValue+width);this._setElementAttributes(SELECTOR_FIXED_CONTENT,PROPERTY_PADDING,calculatedValue=>calculatedValue+width);this._setElementAttributes(SELECTOR_STICKY_CONTENT,PROPERTY_MARGIN,calculatedValue=>calculatedValue-width);}
reset(){this._resetElementAttributes(this._element,'overflow');this._resetElementAttributes(this._element,PROPERTY_PADDING);this._resetElementAttributes(SELECTOR_FIXED_CONTENT,PROPERTY_PADDING);this._resetElementAttributes(SELECTOR_STICKY_CONTENT,PROPERTY_MARGIN);}
isOverflowing(){return this.getWidth()>0;}
_disableOverFlow(){this._saveInitialAttribute(this._element,'overflow');this._element.style.overflow='hidden';}
_setElementAttributes(selector,styleProperty,callback){const scrollbarWidth=this.getWidth();const manipulationCallBack=element=>{if(element!==this._element&&window.innerWidth>element.clientWidth+scrollbarWidth){return;}
this._saveInitialAttribute(element,styleProperty);const calculatedValue=window.getComputedStyle(element).getPropertyValue(styleProperty);element.style.setProperty(styleProperty,`${callback(Number.parseFloat(calculatedValue))}px`);};this._applyManipulationCallback(selector,manipulationCallBack);}
_saveInitialAttribute(element,styleProperty){const actualValue=element.style.getPropertyValue(styleProperty);if(actualValue){Manipulator.setDataAttribute(element,styleProperty,actualValue);}}
_resetElementAttributes(selector,styleProperty){const manipulationCallBack=element=>{const value=Manipulator.getDataAttribute(element,styleProperty);if(value===null){element.style.removeProperty(styleProperty);return;}
Manipulator.removeDataAttribute(element,styleProperty);element.style.setProperty(styleProperty,value);};this._applyManipulationCallback(selector,manipulationCallBack);}
_applyManipulationCallback(selector,callBack){if(index_js.isElement(selector)){callBack(selector);return;}
for(const sel of SelectorEngine.find(selector,this._element)){callBack(sel);}}}
return ScrollBarHelper;}));;
/* /web/static/lib/bootstrap/js/dist/util/swipe.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('../dom/event-handler.js'),require('./config.js'),require('./index.js')):typeof define==='function'&&define.amd?define(['../dom/event-handler','./config','./index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Swipe=factory(global.EventHandler,global.Config,global.Index));})(this,(function(EventHandler,Config,index_js){'use strict';const NAME='swipe';const EVENT_KEY='.bs.swipe';const EVENT_TOUCHSTART=`touchstart${EVENT_KEY}`;const EVENT_TOUCHMOVE=`touchmove${EVENT_KEY}`;const EVENT_TOUCHEND=`touchend${EVENT_KEY}`;const EVENT_POINTERDOWN=`pointerdown${EVENT_KEY}`;const EVENT_POINTERUP=`pointerup${EVENT_KEY}`;const POINTER_TYPE_TOUCH='touch';const POINTER_TYPE_PEN='pen';const CLASS_NAME_POINTER_EVENT='pointer-event';const SWIPE_THRESHOLD=40;const Default={endCallback:null,leftCallback:null,rightCallback:null};const DefaultType={endCallback:'(function|null)',leftCallback:'(function|null)',rightCallback:'(function|null)'};class Swipe extends Config{constructor(element,config){super();this._element=element;if(!element||!Swipe.isSupported()){return;}
this._config=this._getConfig(config);this._deltaX=0;this._supportPointerEvents=Boolean(window.PointerEvent);this._initEvents();}
static get Default(){return Default;}
static get DefaultType(){return DefaultType;}
static get NAME(){return NAME;}
dispose(){EventHandler.off(this._element,EVENT_KEY);}
_start(event){if(!this._supportPointerEvents){this._deltaX=event.touches[0].clientX;return;}
if(this._eventIsPointerPenTouch(event)){this._deltaX=event.clientX;}}
_end(event){if(this._eventIsPointerPenTouch(event)){this._deltaX=event.clientX-this._deltaX;}
this._handleSwipe();index_js.execute(this._config.endCallback);}
_move(event){this._deltaX=event.touches&&event.touches.length>1?0:event.touches[0].clientX-this._deltaX;}
_handleSwipe(){const absDeltaX=Math.abs(this._deltaX);if(absDeltaX<=SWIPE_THRESHOLD){return;}
const direction=absDeltaX/this._deltaX;this._deltaX=0;if(!direction){return;}
index_js.execute(direction>0?this._config.rightCallback:this._config.leftCallback);}
_initEvents(){if(this._supportPointerEvents){EventHandler.on(this._element,EVENT_POINTERDOWN,event=>this._start(event));EventHandler.on(this._element,EVENT_POINTERUP,event=>this._end(event));this._element.classList.add(CLASS_NAME_POINTER_EVENT);}else{EventHandler.on(this._element,EVENT_TOUCHSTART,event=>this._start(event));EventHandler.on(this._element,EVENT_TOUCHMOVE,event=>this._move(event));EventHandler.on(this._element,EVENT_TOUCHEND,event=>this._end(event));}}
_eventIsPointerPenTouch(event){return this._supportPointerEvents&&(event.pointerType===POINTER_TYPE_PEN||event.pointerType===POINTER_TYPE_TOUCH);}
static isSupported(){return'ontouchstart'in document.documentElement||navigator.maxTouchPoints>0;}}
return Swipe;}));;
/* /web/static/lib/bootstrap/js/dist/util/template-factory.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('../dom/selector-engine.js'),require('./config.js'),require('./sanitizer.js'),require('./index.js')):typeof define==='function'&&define.amd?define(['../dom/selector-engine','./config','./sanitizer','./index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.TemplateFactory=factory(global.SelectorEngine,global.Config,global.Sanitizer,global.Index));})(this,(function(SelectorEngine,Config,sanitizer_js,index_js){'use strict';const NAME='TemplateFactory';const Default={allowList:sanitizer_js.DefaultAllowlist,content:{},extraClass:'',html:false,sanitize:true,sanitizeFn:null,template:'<div></div>'};const DefaultType={allowList:'object',content:'object',extraClass:'(string|function)',html:'boolean',sanitize:'boolean',sanitizeFn:'(null|function)',template:'string'};const DefaultContentType={entry:'(string|element|function|null)',selector:'(string|element)'};class TemplateFactory extends Config{constructor(config){super();this._config=this._getConfig(config);}
static get Default(){return Default;}
static get DefaultType(){return DefaultType;}
static get NAME(){return NAME;}
getContent(){return Object.values(this._config.content).map(config=>this._resolvePossibleFunction(config)).filter(Boolean);}
hasContent(){return this.getContent().length>0;}
changeContent(content){this._checkContent(content);this._config.content={...this._config.content,...content};return this;}
toHtml(){const templateWrapper=document.createElement('div');templateWrapper.innerHTML=this._maybeSanitize(this._config.template);for(const[selector,text]of Object.entries(this._config.content)){this._setContent(templateWrapper,text,selector);}
const template=templateWrapper.children[0];const extraClass=this._resolvePossibleFunction(this._config.extraClass);if(extraClass){template.classList.add(...extraClass.split(' '));}
return template;}
_typeCheckConfig(config){super._typeCheckConfig(config);this._checkContent(config.content);}
_checkContent(arg){for(const[selector,content]of Object.entries(arg)){super._typeCheckConfig({selector,entry:content},DefaultContentType);}}
_setContent(template,content,selector){const templateElement=SelectorEngine.findOne(selector,template);if(!templateElement){return;}
content=this._resolvePossibleFunction(content);if(!content){templateElement.remove();return;}
if(index_js.isElement(content)){this._putElementInTemplate(index_js.getElement(content),templateElement);return;}
if(this._config.html){templateElement.innerHTML=this._maybeSanitize(content);return;}
templateElement.textContent=content;}
_maybeSanitize(arg){return this._config.sanitize?sanitizer_js.sanitizeHtml(arg,this._config.allowList,this._config.sanitizeFn):arg;}
_resolvePossibleFunction(arg){return index_js.execute(arg,[this]);}
_putElementInTemplate(element,templateElement){if(this._config.html){templateElement.innerHTML='';templateElement.append(element);return;}
templateElement.textContent=element.textContent;}}
return TemplateFactory;}));;
/* /web/static/lib/bootstrap/js/dist/base-component.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./dom/data.js'),require('./dom/event-handler.js'),require('./util/config.js'),require('./util/index.js')):typeof define==='function'&&define.amd?define(['./dom/data','./dom/event-handler','./util/config','./util/index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.BaseComponent=factory(global.Data,global.EventHandler,global.Config,global.Index));})(this,(function(Data,EventHandler,Config,index_js){'use strict';const VERSION='5.3.3';class BaseComponent extends Config{constructor(element,config){super();element=index_js.getElement(element);if(!element){return;}
this._element=element;this._config=this._getConfig(config);Data.set(this._element,this.constructor.DATA_KEY,this);}
dispose(){Data.remove(this._element,this.constructor.DATA_KEY);EventHandler.off(this._element,this.constructor.EVENT_KEY);for(const propertyName of Object.getOwnPropertyNames(this)){this[propertyName]=null;}}
_queueCallback(callback,element,isAnimated=true){index_js.executeAfterTransition(callback,element,isAnimated);}
_getConfig(config){config=this._mergeConfigObj(config,this._element);config=this._configAfterMerge(config);this._typeCheckConfig(config);return config;}
static getInstance(element){return Data.get(index_js.getElement(element),this.DATA_KEY);}
static getOrCreateInstance(element,config={}){return this.getInstance(element)||new this(element,typeof config==='object'?config:null);}
static get VERSION(){return VERSION;}
static get DATA_KEY(){return`bs.${this.NAME}`;}
static get EVENT_KEY(){return`.${this.DATA_KEY}`;}
static eventName(name){return`${name}${this.EVENT_KEY}`;}}
return BaseComponent;}));;
/* /web/static/lib/bootstrap/js/dist/alert.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./base-component.js'),require('./dom/event-handler.js'),require('./util/component-functions.js'),require('./util/index.js')):typeof define==='function'&&define.amd?define(['./base-component','./dom/event-handler','./util/component-functions','./util/index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Alert=factory(global.BaseComponent,global.EventHandler,global.ComponentFunctions,global.Index));})(this,(function(BaseComponent,EventHandler,componentFunctions_js,index_js){'use strict';const NAME='alert';const DATA_KEY='bs.alert';const EVENT_KEY=`.${DATA_KEY}`;const EVENT_CLOSE=`close${EVENT_KEY}`;const EVENT_CLOSED=`closed${EVENT_KEY}`;const CLASS_NAME_FADE='fade';const CLASS_NAME_SHOW='show';class Alert extends BaseComponent{static get NAME(){return NAME;}
close(){const closeEvent=EventHandler.trigger(this._element,EVENT_CLOSE);if(closeEvent.defaultPrevented){return;}
this._element.classList.remove(CLASS_NAME_SHOW);const isAnimated=this._element.classList.contains(CLASS_NAME_FADE);this._queueCallback(()=>this._destroyElement(),this._element,isAnimated);}
_destroyElement(){this._element.remove();EventHandler.trigger(this._element,EVENT_CLOSED);this.dispose();}
static jQueryInterface(config){return this.each(function(){const data=Alert.getOrCreateInstance(this);if(typeof config!=='string'){return;}
if(data[config]===undefined||config.startsWith('_')||config==='constructor'){throw new TypeError(`No method named "${config}"`);}
data[config](this);});}}
componentFunctions_js.enableDismissTrigger(Alert,'close');index_js.defineJQueryPlugin(Alert);return Alert;}));;
/* /web/static/lib/bootstrap/js/dist/button.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./base-component.js'),require('./dom/event-handler.js'),require('./util/index.js')):typeof define==='function'&&define.amd?define(['./base-component','./dom/event-handler','./util/index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Button=factory(global.BaseComponent,global.EventHandler,global.Index));})(this,(function(BaseComponent,EventHandler,index_js){'use strict';const NAME='button';const DATA_KEY='bs.button';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const CLASS_NAME_ACTIVE='active';const SELECTOR_DATA_TOGGLE='[data-bs-toggle="button"]';const EVENT_CLICK_DATA_API=`click${EVENT_KEY}${DATA_API_KEY}`;class Button extends BaseComponent{static get NAME(){return NAME;}
toggle(){this._element.setAttribute('aria-pressed',this._element.classList.toggle(CLASS_NAME_ACTIVE));}
static jQueryInterface(config){return this.each(function(){const data=Button.getOrCreateInstance(this);if(config==='toggle'){data[config]();}});}}
EventHandler.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_TOGGLE,event=>{event.preventDefault();const button=event.target.closest(SELECTOR_DATA_TOGGLE);const data=Button.getOrCreateInstance(button);data.toggle();});index_js.defineJQueryPlugin(Button);return Button;}));;
/* /web/static/lib/bootstrap/js/dist/carousel.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./base-component.js'),require('./dom/event-handler.js'),require('./dom/manipulator.js'),require('./dom/selector-engine.js'),require('./util/index.js'),require('./util/swipe.js')):typeof define==='function'&&define.amd?define(['./base-component','./dom/event-handler','./dom/manipulator','./dom/selector-engine','./util/index','./util/swipe'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Carousel=factory(global.BaseComponent,global.EventHandler,global.Manipulator,global.SelectorEngine,global.Index,global.Swipe));})(this,(function(BaseComponent,EventHandler,Manipulator,SelectorEngine,index_js,Swipe){'use strict';const NAME='carousel';const DATA_KEY='bs.carousel';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const ARROW_LEFT_KEY='ArrowLeft';const ARROW_RIGHT_KEY='ArrowRight';const TOUCHEVENT_COMPAT_WAIT=500;const ORDER_NEXT='next';const ORDER_PREV='prev';const DIRECTION_LEFT='left';const DIRECTION_RIGHT='right';const EVENT_SLIDE=`slide${EVENT_KEY}`;const EVENT_SLID=`slid${EVENT_KEY}`;const EVENT_KEYDOWN=`keydown${EVENT_KEY}`;const EVENT_MOUSEENTER=`mouseenter${EVENT_KEY}`;const EVENT_MOUSELEAVE=`mouseleave${EVENT_KEY}`;const EVENT_DRAG_START=`dragstart${EVENT_KEY}`;const EVENT_LOAD_DATA_API=`load${EVENT_KEY}${DATA_API_KEY}`;const EVENT_CLICK_DATA_API=`click${EVENT_KEY}${DATA_API_KEY}`;const CLASS_NAME_CAROUSEL='carousel';const CLASS_NAME_ACTIVE='active';const CLASS_NAME_SLIDE='slide';const CLASS_NAME_END='carousel-item-end';const CLASS_NAME_START='carousel-item-start';const CLASS_NAME_NEXT='carousel-item-next';const CLASS_NAME_PREV='carousel-item-prev';const SELECTOR_ACTIVE='.active';const SELECTOR_ITEM='.carousel-item';const SELECTOR_ACTIVE_ITEM=SELECTOR_ACTIVE+SELECTOR_ITEM;const SELECTOR_ITEM_IMG='.carousel-item img';const SELECTOR_INDICATORS='.carousel-indicators';const SELECTOR_DATA_SLIDE='[data-bs-slide], [data-bs-slide-to]';const SELECTOR_DATA_RIDE='[data-bs-ride="carousel"]';const KEY_TO_DIRECTION={[ARROW_LEFT_KEY]:DIRECTION_RIGHT,[ARROW_RIGHT_KEY]:DIRECTION_LEFT};const Default={interval:5000,keyboard:true,pause:'hover',ride:false,touch:true,wrap:true};const DefaultType={interval:'(number|boolean)',keyboard:'boolean',pause:'(string|boolean)',ride:'(boolean|string)',touch:'boolean',wrap:'boolean'};class Carousel extends BaseComponent{constructor(element,config){super(element,config);this._interval=null;this._activeElement=null;this._isSliding=false;this.touchTimeout=null;this._swipeHelper=null;this._indicatorsElement=SelectorEngine.findOne(SELECTOR_INDICATORS,this._element);this._addEventListeners();if(this._config.ride===CLASS_NAME_CAROUSEL){this.cycle();}}
static get Default(){return Default;}
static get DefaultType(){return DefaultType;}
static get NAME(){return NAME;}
next(){this._slide(ORDER_NEXT);}
nextWhenVisible(){if(!document.hidden&&index_js.isVisible(this._element)){this.next();}}
prev(){this._slide(ORDER_PREV);}
pause(){if(this._isSliding){index_js.triggerTransitionEnd(this._element);}
this._clearInterval();}
cycle(){this._clearInterval();this._updateInterval();this._interval=setInterval(()=>this.nextWhenVisible(),this._config.interval);}
_maybeEnableCycle(){if(!this._config.ride){return;}
if(this._isSliding){EventHandler.one(this._element,EVENT_SLID,()=>this.cycle());return;}
this.cycle();}
to(index){const items=this._getItems();if(index>items.length-1||index<0){return;}
if(this._isSliding){EventHandler.one(this._element,EVENT_SLID,()=>this.to(index));return;}
const activeIndex=this._getItemIndex(this._getActive());if(activeIndex===index){return;}
const order=index>activeIndex?ORDER_NEXT:ORDER_PREV;this._slide(order,items[index]);}
dispose(){if(this._swipeHelper){this._swipeHelper.dispose();}
super.dispose();}
_configAfterMerge(config){config.defaultInterval=config.interval;return config;}
_addEventListeners(){if(this._config.keyboard){EventHandler.on(this._element,EVENT_KEYDOWN,event=>this._keydown(event));}
if(this._config.pause==='hover'){EventHandler.on(this._element,EVENT_MOUSEENTER,()=>this.pause());EventHandler.on(this._element,EVENT_MOUSELEAVE,()=>this._maybeEnableCycle());}
if(this._config.touch&&Swipe.isSupported()){this._addTouchEventListeners();}}
_addTouchEventListeners(){for(const img of SelectorEngine.find(SELECTOR_ITEM_IMG,this._element)){EventHandler.on(img,EVENT_DRAG_START,event=>event.preventDefault());}
const endCallBack=()=>{if(this._config.pause!=='hover'){return;}
this.pause();if(this.touchTimeout){clearTimeout(this.touchTimeout);}
this.touchTimeout=setTimeout(()=>this._maybeEnableCycle(),TOUCHEVENT_COMPAT_WAIT+this._config.interval);};const swipeConfig={leftCallback:()=>this._slide(this._directionToOrder(DIRECTION_LEFT)),rightCallback:()=>this._slide(this._directionToOrder(DIRECTION_RIGHT)),endCallback:endCallBack};this._swipeHelper=new Swipe(this._element,swipeConfig);}
_keydown(event){if(/input|textarea/i.test(event.target.tagName)){return;}
const direction=KEY_TO_DIRECTION[event.key];if(direction){event.preventDefault();this._slide(this._directionToOrder(direction));}}
_getItemIndex(element){return this._getItems().indexOf(element);}
_setActiveIndicatorElement(index){if(!this._indicatorsElement){return;}
const activeIndicator=SelectorEngine.findOne(SELECTOR_ACTIVE,this._indicatorsElement);activeIndicator.classList.remove(CLASS_NAME_ACTIVE);activeIndicator.removeAttribute('aria-current');const newActiveIndicator=SelectorEngine.findOne(`[data-bs-slide-to="${index}"]`,this._indicatorsElement);if(newActiveIndicator){newActiveIndicator.classList.add(CLASS_NAME_ACTIVE);newActiveIndicator.setAttribute('aria-current','true');}}
_updateInterval(){const element=this._activeElement||this._getActive();if(!element){return;}
const elementInterval=Number.parseInt(element.getAttribute('data-bs-interval'),10);this._config.interval=elementInterval||this._config.defaultInterval;}
_slide(order,element=null){if(this._isSliding){return;}
const activeElement=this._getActive();const isNext=order===ORDER_NEXT;const nextElement=element||index_js.getNextActiveElement(this._getItems(),activeElement,isNext,this._config.wrap);if(nextElement===activeElement){return;}
const nextElementIndex=this._getItemIndex(nextElement);const triggerEvent=eventName=>{return EventHandler.trigger(this._element,eventName,{relatedTarget:nextElement,direction:this._orderToDirection(order),from:this._getItemIndex(activeElement),to:nextElementIndex});};const slideEvent=triggerEvent(EVENT_SLIDE);if(slideEvent.defaultPrevented){return;}
if(!activeElement||!nextElement){return;}
const isCycling=Boolean(this._interval);this.pause();this._isSliding=true;this._setActiveIndicatorElement(nextElementIndex);this._activeElement=nextElement;const directionalClassName=isNext?CLASS_NAME_START:CLASS_NAME_END;const orderClassName=isNext?CLASS_NAME_NEXT:CLASS_NAME_PREV;nextElement.classList.add(orderClassName);index_js.reflow(nextElement);activeElement.classList.add(directionalClassName);nextElement.classList.add(directionalClassName);const completeCallBack=()=>{nextElement.classList.remove(directionalClassName,orderClassName);nextElement.classList.add(CLASS_NAME_ACTIVE);activeElement.classList.remove(CLASS_NAME_ACTIVE,orderClassName,directionalClassName);this._isSliding=false;triggerEvent(EVENT_SLID);};this._queueCallback(completeCallBack,activeElement,this._isAnimated());if(isCycling){this.cycle();}}
_isAnimated(){return this._element.classList.contains(CLASS_NAME_SLIDE);}
_getActive(){return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM,this._element);}
_getItems(){return SelectorEngine.find(SELECTOR_ITEM,this._element);}
_clearInterval(){if(this._interval){clearInterval(this._interval);this._interval=null;}}
_directionToOrder(direction){if(index_js.isRTL()){return direction===DIRECTION_LEFT?ORDER_PREV:ORDER_NEXT;}
return direction===DIRECTION_LEFT?ORDER_NEXT:ORDER_PREV;}
_orderToDirection(order){if(index_js.isRTL()){return order===ORDER_PREV?DIRECTION_LEFT:DIRECTION_RIGHT;}
return order===ORDER_PREV?DIRECTION_RIGHT:DIRECTION_LEFT;}
static jQueryInterface(config){return this.each(function(){const data=Carousel.getOrCreateInstance(this,config);if(typeof config==='number'){data.to(config);return;}
if(typeof config==='string'){if(data[config]===undefined||config.startsWith('_')||config==='constructor'){throw new TypeError(`No method named "${config}"`);}
data[config]();}});}}
EventHandler.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_SLIDE,function(event){const target=SelectorEngine.getElementFromSelector(this);if(!target||!target.classList.contains(CLASS_NAME_CAROUSEL)){return;}
event.preventDefault();const carousel=Carousel.getOrCreateInstance(target);const slideIndex=this.getAttribute('data-bs-slide-to');if(slideIndex){carousel.to(slideIndex);carousel._maybeEnableCycle();return;}
if(Manipulator.getDataAttribute(this,'slide')==='next'){carousel.next();carousel._maybeEnableCycle();return;}
carousel.prev();carousel._maybeEnableCycle();});EventHandler.on(window,EVENT_LOAD_DATA_API,()=>{const carousels=SelectorEngine.find(SELECTOR_DATA_RIDE);for(const carousel of carousels){Carousel.getOrCreateInstance(carousel);}});index_js.defineJQueryPlugin(Carousel);return Carousel;}));;
/* /web/static/lib/bootstrap/js/dist/collapse.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./base-component.js'),require('./dom/event-handler.js'),require('./dom/selector-engine.js'),require('./util/index.js')):typeof define==='function'&&define.amd?define(['./base-component','./dom/event-handler','./dom/selector-engine','./util/index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Collapse=factory(global.BaseComponent,global.EventHandler,global.SelectorEngine,global.Index));})(this,(function(BaseComponent,EventHandler,SelectorEngine,index_js){'use strict';const NAME='collapse';const DATA_KEY='bs.collapse';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const EVENT_SHOW=`show${EVENT_KEY}`;const EVENT_SHOWN=`shown${EVENT_KEY}`;const EVENT_HIDE=`hide${EVENT_KEY}`;const EVENT_HIDDEN=`hidden${EVENT_KEY}`;const EVENT_CLICK_DATA_API=`click${EVENT_KEY}${DATA_API_KEY}`;const CLASS_NAME_SHOW='show';const CLASS_NAME_COLLAPSE='collapse';const CLASS_NAME_COLLAPSING='collapsing';const CLASS_NAME_COLLAPSED='collapsed';const CLASS_NAME_DEEPER_CHILDREN=`:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;const CLASS_NAME_HORIZONTAL='collapse-horizontal';const WIDTH='width';const HEIGHT='height';const SELECTOR_ACTIVES='.collapse.show, .collapse.collapsing';const SELECTOR_DATA_TOGGLE='[data-bs-toggle="collapse"]';const Default={parent:null,toggle:true};const DefaultType={parent:'(null|element)',toggle:'boolean'};class Collapse extends BaseComponent{constructor(element,config){super(element,config);this._isTransitioning=false;this._triggerArray=[];const toggleList=SelectorEngine.find(SELECTOR_DATA_TOGGLE);for(const elem of toggleList){const selector=SelectorEngine.getSelectorFromElement(elem);const filterElement=SelectorEngine.find(selector).filter(foundElement=>foundElement===this._element);if(selector!==null&&filterElement.length){this._triggerArray.push(elem);}}
this._initializeChildren();if(!this._config.parent){this._addAriaAndCollapsedClass(this._triggerArray,this._isShown());}
if(this._config.toggle){this.toggle();}}
static get Default(){return Default;}
static get DefaultType(){return DefaultType;}
static get NAME(){return NAME;}
toggle(){if(this._isShown()){this.hide();}else{this.show();}}
show(){if(this._isTransitioning||this._isShown()){return;}
let activeChildren=[];if(this._config.parent){activeChildren=this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element=>element!==this._element).map(element=>Collapse.getOrCreateInstance(element,{toggle:false}));}
if(activeChildren.length&&activeChildren[0]._isTransitioning){return;}
const startEvent=EventHandler.trigger(this._element,EVENT_SHOW);if(startEvent.defaultPrevented){return;}
for(const activeInstance of activeChildren){activeInstance.hide();}
const dimension=this._getDimension();this._element.classList.remove(CLASS_NAME_COLLAPSE);this._element.classList.add(CLASS_NAME_COLLAPSING);this._element.style[dimension]=0;this._addAriaAndCollapsedClass(this._triggerArray,true);this._isTransitioning=true;const complete=()=>{this._isTransitioning=false;this._element.classList.remove(CLASS_NAME_COLLAPSING);this._element.classList.add(CLASS_NAME_COLLAPSE,CLASS_NAME_SHOW);this._element.style[dimension]='';EventHandler.trigger(this._element,EVENT_SHOWN);};const capitalizedDimension=dimension[0].toUpperCase()+dimension.slice(1);const scrollSize=`scroll${capitalizedDimension}`;this._queueCallback(complete,this._element,true);this._element.style[dimension]=`${this._element[scrollSize]}px`;}
hide(){if(this._isTransitioning||!this._isShown()){return;}
const startEvent=EventHandler.trigger(this._element,EVENT_HIDE);if(startEvent.defaultPrevented){return;}
const dimension=this._getDimension();this._element.style[dimension]=`${this._element.getBoundingClientRect()[dimension]}px`;index_js.reflow(this._element);this._element.classList.add(CLASS_NAME_COLLAPSING);this._element.classList.remove(CLASS_NAME_COLLAPSE,CLASS_NAME_SHOW);for(const trigger of this._triggerArray){const element=SelectorEngine.getElementFromSelector(trigger);if(element&&!this._isShown(element)){this._addAriaAndCollapsedClass([trigger],false);}}
this._isTransitioning=true;const complete=()=>{this._isTransitioning=false;this._element.classList.remove(CLASS_NAME_COLLAPSING);this._element.classList.add(CLASS_NAME_COLLAPSE);EventHandler.trigger(this._element,EVENT_HIDDEN);};this._element.style[dimension]='';this._queueCallback(complete,this._element,true);}
_isShown(element=this._element){return element.classList.contains(CLASS_NAME_SHOW);}
_configAfterMerge(config){config.toggle=Boolean(config.toggle);config.parent=index_js.getElement(config.parent);return config;}
_getDimension(){return this._element.classList.contains(CLASS_NAME_HORIZONTAL)?WIDTH:HEIGHT;}
_initializeChildren(){if(!this._config.parent){return;}
const children=this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE);for(const element of children){const selected=SelectorEngine.getElementFromSelector(element);if(selected){this._addAriaAndCollapsedClass([element],this._isShown(selected));}}}
_getFirstLevelChildren(selector){const children=SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN,this._config.parent);return SelectorEngine.find(selector,this._config.parent).filter(element=>!children.includes(element));}
_addAriaAndCollapsedClass(triggerArray,isOpen){if(!triggerArray.length){return;}
for(const element of triggerArray){element.classList.toggle(CLASS_NAME_COLLAPSED,!isOpen);element.setAttribute('aria-expanded',isOpen);}}
static jQueryInterface(config){const _config={};if(typeof config==='string'&&/show|hide/.test(config)){_config.toggle=false;}
return this.each(function(){const data=Collapse.getOrCreateInstance(this,_config);if(typeof config==='string'){if(typeof data[config]==='undefined'){throw new TypeError(`No method named "${config}"`);}
data[config]();}});}}
EventHandler.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_TOGGLE,function(event){if(event.target.tagName==='A'||event.delegateTarget&&event.delegateTarget.tagName==='A'){event.preventDefault();}
for(const element of SelectorEngine.getMultipleElementsFromSelector(this)){Collapse.getOrCreateInstance(element,{toggle:false}).toggle();}});index_js.defineJQueryPlugin(Collapse);return Collapse;}));;
/* /web/static/lib/bootstrap/js/dist/dropdown.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('@popperjs/core'),require('./base-component.js'),require('./dom/event-handler.js'),require('./dom/manipulator.js'),require('./dom/selector-engine.js'),require('./util/index.js')):typeof define==='function'&&define.amd?define(['@popperjs/core','./base-component','./dom/event-handler','./dom/manipulator','./dom/selector-engine','./util/index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Dropdown=factory(global.Popper,global.BaseComponent,global.EventHandler,global.Manipulator,global.SelectorEngine,global.Index));})(this,(function(Popper,BaseComponent,EventHandler,Manipulator,SelectorEngine,index_js){'use strict';function _interopNamespaceDefault(e){const n=Object.create(null,{[Symbol.toStringTag]:{value:'Module'}});if(e){for(const k in e){if(k!=='default'){const d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:()=>e[k]});}}}
n.default=e;return Object.freeze(n);}
const Popper__namespace=_interopNamespaceDefault(Popper);const NAME='dropdown';const DATA_KEY='bs.dropdown';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const ESCAPE_KEY='Escape';const TAB_KEY='Tab';const ARROW_UP_KEY='ArrowUp';const ARROW_DOWN_KEY='ArrowDown';const RIGHT_MOUSE_BUTTON=2;const EVENT_HIDE=`hide${EVENT_KEY}`;const EVENT_HIDDEN=`hidden${EVENT_KEY}`;const EVENT_SHOW=`show${EVENT_KEY}`;const EVENT_SHOWN=`shown${EVENT_KEY}`;const EVENT_CLICK_DATA_API=`click${EVENT_KEY}${DATA_API_KEY}`;const EVENT_KEYDOWN_DATA_API=`keydown${EVENT_KEY}${DATA_API_KEY}`;const EVENT_KEYUP_DATA_API=`keyup${EVENT_KEY}${DATA_API_KEY}`;const CLASS_NAME_SHOW='show';const CLASS_NAME_DROPUP='dropup';const CLASS_NAME_DROPEND='dropend';const CLASS_NAME_DROPSTART='dropstart';const CLASS_NAME_DROPUP_CENTER='dropup-center';const CLASS_NAME_DROPDOWN_CENTER='dropdown-center';const SELECTOR_DATA_TOGGLE='[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)';const SELECTOR_DATA_TOGGLE_SHOWN=`${SELECTOR_DATA_TOGGLE}.${CLASS_NAME_SHOW}`;const SELECTOR_MENU='.dropdown-menu:not(.o-dropdown--menu)';const SELECTOR_NAVBAR='.navbar';const SELECTOR_MENU_NOT_SUB='.dropdown-menu:not(.o-dropdown--menu):not(.o_wysiwyg_submenu)';const SELECTOR_NAVBAR_NAV='.navbar-nav';const SELECTOR_VISIBLE_ITEMS='.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';const PLACEMENT_TOP=index_js.isRTL()?'top-end':'top-start';const PLACEMENT_TOPEND=index_js.isRTL()?'top-start':'top-end';const PLACEMENT_BOTTOM=index_js.isRTL()?'bottom-end':'bottom-start';const PLACEMENT_BOTTOMEND=index_js.isRTL()?'bottom-start':'bottom-end';const PLACEMENT_RIGHT=index_js.isRTL()?'left-start':'right-start';const PLACEMENT_LEFT=index_js.isRTL()?'right-start':'left-start';const PLACEMENT_TOPCENTER='top';const PLACEMENT_BOTTOMCENTER='bottom';const Default={autoClose:true,boundary:'clippingParents',display:'dynamic',offset:[0,2],popperConfig:null,reference:'toggle'};const DefaultType={autoClose:'(boolean|string)',boundary:'(string|element)',display:'string',offset:'(array|string|function)',popperConfig:'(null|object|function)',reference:'(string|element|object)'};class Dropdown extends BaseComponent{constructor(element,config){super(element,config);this._popper=null;this._parent=this._element.parentNode;this._menu=SelectorEngine.next(this._element,SELECTOR_MENU)[0]||SelectorEngine.prev(this._element,SELECTOR_MENU)[0]||SelectorEngine.findOne(SELECTOR_MENU,this._parent);this._inNavbar=this._detectNavbar();}
static get Default(){return Default;}
static get DefaultType(){return DefaultType;}
static get NAME(){return NAME;}
toggle(){return this._isShown()?this.hide():this.show();}
show(){if(index_js.isDisabled(this._element)||this._isShown()){return;}
const relatedTarget={relatedTarget:this._element};const showEvent=EventHandler.trigger(this._element,EVENT_SHOW,relatedTarget);if(showEvent.defaultPrevented){return;}
this._createPopper();if('ontouchstart'in document.documentElement&&!this._parent.closest(SELECTOR_NAVBAR_NAV)){for(const element of[].concat(...document.body.children)){EventHandler.on(element,'mouseover',index_js.noop);}}
this._element.focus();this._element.setAttribute('aria-expanded',true);this._menu.classList.add(CLASS_NAME_SHOW);this._element.classList.add(CLASS_NAME_SHOW);EventHandler.trigger(this._element,EVENT_SHOWN,relatedTarget);}
hide(){if(index_js.isDisabled(this._element)||!this._isShown()){return;}
const relatedTarget={relatedTarget:this._element};this._completeHide(relatedTarget);}
dispose(){if(this._popper){this._popper.destroy();}
super.dispose();}
update(){this._inNavbar=this._detectNavbar();if(this._popper){this._popper.update();}}
_completeHide(relatedTarget){const hideEvent=EventHandler.trigger(this._element,EVENT_HIDE,relatedTarget);if(hideEvent.defaultPrevented){return;}
if('ontouchstart'in document.documentElement){for(const element of[].concat(...document.body.children)){EventHandler.off(element,'mouseover',index_js.noop);}}
if(this._popper){this._popper.destroy();}
this._menu.classList.remove(CLASS_NAME_SHOW);this._element.classList.remove(CLASS_NAME_SHOW);this._element.setAttribute('aria-expanded','false');Manipulator.removeDataAttribute(this._menu,'popper');EventHandler.trigger(this._element,EVENT_HIDDEN,relatedTarget);}
_getConfig(config){config=super._getConfig(config);if(typeof config.reference==='object'&&!index_js.isElement(config.reference)&&typeof config.reference.getBoundingClientRect!=='function'){throw new TypeError(`${NAME.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);}
return config;}
_createPopper(){if(typeof Popper__namespace==='undefined'){throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)');}
let referenceElement=this._element;if(this._config.reference==='parent'){referenceElement=this._parent;}else if(index_js.isElement(this._config.reference)){referenceElement=index_js.getElement(this._config.reference);}else if(typeof this._config.reference==='object'){referenceElement=this._config.reference;}
const popperConfig=this._getPopperConfig();this._popper=Popper__namespace.createPopper(referenceElement,this._menu,popperConfig);}
_isShown(){return this._menu.classList.contains(CLASS_NAME_SHOW);}
_getPlacement(){const parentDropdown=this._parent;if(parentDropdown.classList.contains(CLASS_NAME_DROPEND)){return PLACEMENT_RIGHT;}
if(parentDropdown.classList.contains(CLASS_NAME_DROPSTART)){return PLACEMENT_LEFT;}
if(parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)){return PLACEMENT_TOPCENTER;}
if(parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)){return PLACEMENT_BOTTOMCENTER;}
const isEnd=getComputedStyle(this._menu).getPropertyValue('--bs-position').trim()==='end';if(parentDropdown.classList.contains(CLASS_NAME_DROPUP)){return isEnd?PLACEMENT_TOPEND:PLACEMENT_TOP;}
return isEnd?PLACEMENT_BOTTOMEND:PLACEMENT_BOTTOM;}
_detectNavbar(){return this._element.closest(SELECTOR_NAVBAR)!==null;}
_getOffset(){const{offset}=this._config;if(typeof offset==='string'){return offset.split(',').map(value=>Number.parseInt(value,10));}
if(typeof offset==='function'){return popperData=>offset(popperData,this._element);}
return offset;}
_getPopperConfig(){const defaultBsPopperConfig={placement:this._getPlacement(),modifiers:[{name:'preventOverflow',options:{boundary:this._config.boundary}},{name:'offset',options:{offset:this._getOffset()}}]};if(this._inNavbar||this._config.display==='static'){Manipulator.setDataAttribute(this._menu,'popper','static');defaultBsPopperConfig.modifiers=[{name:'applyStyles',enabled:false}];}
return{...defaultBsPopperConfig,...index_js.execute(this._config.popperConfig,[defaultBsPopperConfig])};}
_selectMenuItem({key,target}){const items=SelectorEngine.find(SELECTOR_VISIBLE_ITEMS,this._menu).filter(element=>index_js.isVisible(element));if(!items.length){return;}
index_js.getNextActiveElement(items,target,key===ARROW_DOWN_KEY,!items.includes(target)).focus();}
static jQueryInterface(config){return this.each(function(){const data=Dropdown.getOrCreateInstance(this,config);if(typeof config!=='string'){return;}
if(typeof data[config]==='undefined'){throw new TypeError(`No method named "${config}"`);}
data[config]();});}
static clearMenus(event){if(event.button===RIGHT_MOUSE_BUTTON||event.type==='keyup'&&event.key!==TAB_KEY){return;}
const openToggles=SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN);for(const toggle of openToggles){const context=Dropdown.getInstance(toggle);if(!context||context._config.autoClose===false){continue;}
const composedPath=event.composedPath();const isMenuTarget=composedPath.includes(context._menu);if(composedPath.includes(context._element)||context._config.autoClose==='inside'&&!isMenuTarget||context._config.autoClose==='outside'&&isMenuTarget){continue;}
if(context._menu.contains(event.target)&&(event.type==='keyup'&&event.key===TAB_KEY||/input|select|option|textarea|form/i.test(event.target.tagName))){continue;}
const relatedTarget={relatedTarget:context._element};if(event.type==='click'){relatedTarget.clickEvent=event;}
context._completeHide(relatedTarget);}}
static dataApiKeydownHandler(event){const isInput=/input|textarea/i.test(event.target.tagName);const isEscapeEvent=event.key===ESCAPE_KEY;const isUpOrDownEvent=[ARROW_UP_KEY,ARROW_DOWN_KEY].includes(event.key);if(!isUpOrDownEvent&&!isEscapeEvent){return;}
if(isInput&&!isEscapeEvent){return;}
event.preventDefault();const getToggleButton=this.matches(SELECTOR_DATA_TOGGLE)?this:SelectorEngine.prev(this,SELECTOR_DATA_TOGGLE)[0]||SelectorEngine.next(this,SELECTOR_DATA_TOGGLE)[0]||SelectorEngine.findOne(SELECTOR_DATA_TOGGLE,event.delegateTarget.parentNode);const instance=Dropdown.getOrCreateInstance(getToggleButton);if(isUpOrDownEvent){event.stopPropagation();instance.show();instance._selectMenuItem(event);return;}
if(instance._isShown()){event.stopPropagation();instance.hide();getToggleButton.focus();}}}
EventHandler.on(document,EVENT_KEYDOWN_DATA_API,SELECTOR_DATA_TOGGLE,Dropdown.dataApiKeydownHandler);EventHandler.on(document,EVENT_KEYDOWN_DATA_API,SELECTOR_MENU_NOT_SUB,Dropdown.dataApiKeydownHandler);EventHandler.on(document,EVENT_CLICK_DATA_API,Dropdown.clearMenus);EventHandler.on(document,EVENT_KEYUP_DATA_API,Dropdown.clearMenus);EventHandler.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_TOGGLE,function(event){event.preventDefault();Dropdown.getOrCreateInstance(this).toggle();});index_js.defineJQueryPlugin(Dropdown);return Dropdown;}));;
/* /web/static/lib/bootstrap/js/dist/modal.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./base-component.js'),require('./dom/event-handler.js'),require('./dom/selector-engine.js'),require('./util/backdrop.js'),require('./util/component-functions.js'),require('./util/focustrap.js'),require('./util/index.js'),require('./util/scrollbar.js')):typeof define==='function'&&define.amd?define(['./base-component','./dom/event-handler','./dom/selector-engine','./util/backdrop','./util/component-functions','./util/focustrap','./util/index','./util/scrollbar'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Modal=factory(global.BaseComponent,global.EventHandler,global.SelectorEngine,global.Backdrop,global.ComponentFunctions,global.Focustrap,global.Index,global.Scrollbar));})(this,(function(BaseComponent,EventHandler,SelectorEngine,Backdrop,componentFunctions_js,FocusTrap,index_js,ScrollBarHelper){'use strict';const NAME='modal';const DATA_KEY='bs.modal';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const ESCAPE_KEY='Escape';const EVENT_HIDE=`hide${EVENT_KEY}`;const EVENT_HIDE_PREVENTED=`hidePrevented${EVENT_KEY}`;const EVENT_HIDDEN=`hidden${EVENT_KEY}`;const EVENT_SHOW=`show${EVENT_KEY}`;const EVENT_SHOWN=`shown${EVENT_KEY}`;const EVENT_RESIZE=`resize${EVENT_KEY}`;const EVENT_CLICK_DISMISS=`click.dismiss${EVENT_KEY}`;const EVENT_MOUSEDOWN_DISMISS=`mousedown.dismiss${EVENT_KEY}`;const EVENT_KEYDOWN_DISMISS=`keydown.dismiss${EVENT_KEY}`;const EVENT_CLICK_DATA_API=`click${EVENT_KEY}${DATA_API_KEY}`;const CLASS_NAME_OPEN='modal-open';const CLASS_NAME_FADE='fade';const CLASS_NAME_SHOW='show';const CLASS_NAME_STATIC='modal-static';const OPEN_SELECTOR='.modal.show';const SELECTOR_DIALOG='.modal-dialog';const SELECTOR_MODAL_BODY='.modal-body';const SELECTOR_DATA_TOGGLE='[data-bs-toggle="modal"]';const Default={backdrop:true,focus:true,keyboard:true};const DefaultType={backdrop:'(boolean|string)',focus:'boolean',keyboard:'boolean'};class Modal extends BaseComponent{constructor(element,config){super(element,config);this._dialog=SelectorEngine.findOne(SELECTOR_DIALOG,this._element);this._backdrop=this._initializeBackDrop();this._focustrap=this._initializeFocusTrap();this._isShown=false;this._isTransitioning=false;this._scrollBar=new ScrollBarHelper();this._addEventListeners();}
static get Default(){return Default;}
static get DefaultType(){return DefaultType;}
static get NAME(){return NAME;}
toggle(relatedTarget){return this._isShown?this.hide():this.show(relatedTarget);}
show(relatedTarget){if(this._isShown||this._isTransitioning){return;}
const showEvent=EventHandler.trigger(this._element,EVENT_SHOW,{relatedTarget});if(showEvent.defaultPrevented){return;}
this._isShown=true;this._isTransitioning=true;this._scrollBar.hide();document.body.classList.add(CLASS_NAME_OPEN);this._adjustDialog();this._backdrop.show(()=>this._showElement(relatedTarget));}
hide(){if(!this._isShown||this._isTransitioning){return;}
const hideEvent=EventHandler.trigger(this._element,EVENT_HIDE);if(hideEvent.defaultPrevented){return;}
this._isShown=false;this._isTransitioning=true;this._focustrap.deactivate();this._element.classList.remove(CLASS_NAME_SHOW);this._queueCallback(()=>this._hideModal(),this._element,this._isAnimated());}
dispose(){EventHandler.off(window,EVENT_KEY);EventHandler.off(this._dialog,EVENT_KEY);this._backdrop.dispose();this._focustrap.deactivate();super.dispose();}
handleUpdate(){this._adjustDialog();}
_initializeBackDrop(){return new Backdrop({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()});}
_initializeFocusTrap(){return new FocusTrap({trapElement:this._element});}
_showElement(relatedTarget){if(!document.body.contains(this._element)){document.body.append(this._element);}
this._element.style.display='block';this._element.removeAttribute('aria-hidden');this._element.setAttribute('aria-modal',true);this._element.setAttribute('role','dialog');this._element.scrollTop=0;const modalBody=SelectorEngine.findOne(SELECTOR_MODAL_BODY,this._dialog);if(modalBody){modalBody.scrollTop=0;}
index_js.reflow(this._element);this._element.classList.add(CLASS_NAME_SHOW);const transitionComplete=()=>{if(this._config?.focus){this._focustrap.activate();}
this._isTransitioning=false;EventHandler.trigger(this._element,EVENT_SHOWN,{relatedTarget});};this._queueCallback(transitionComplete,this._dialog,this._isAnimated());}
_addEventListeners(){EventHandler.on(this._element,EVENT_KEYDOWN_DISMISS,event=>{if(event.key!==ESCAPE_KEY){return;}
if(this._config.keyboard){this.hide();return;}
this._triggerBackdropTransition();});EventHandler.on(window,EVENT_RESIZE,()=>{if(this._isShown&&!this._isTransitioning){this._adjustDialog();}});EventHandler.on(this._element,EVENT_MOUSEDOWN_DISMISS,event=>{EventHandler.one(this._element,EVENT_CLICK_DISMISS,event2=>{if(this._element!==event.target||this._element!==event2.target){return;}
if(this._config.backdrop==='static'){this._triggerBackdropTransition();return;}
if(this._config.backdrop){this.hide();}});});}
_hideModal(){this._element.style.display='none';this._element.setAttribute('aria-hidden',true);this._element.removeAttribute('aria-modal');this._element.removeAttribute('role');this._isTransitioning=false;this._backdrop.hide(()=>{document.body.classList.remove(CLASS_NAME_OPEN);this._resetAdjustments();this._scrollBar.reset();EventHandler.trigger(this._element,EVENT_HIDDEN);});}
_isAnimated(){return this._element.classList.contains(CLASS_NAME_FADE);}
_triggerBackdropTransition(){const hideEvent=EventHandler.trigger(this._element,EVENT_HIDE_PREVENTED);if(hideEvent.defaultPrevented){return;}
const isModalOverflowing=this._element.scrollHeight>document.documentElement.clientHeight;const initialOverflowY=this._element.style.overflowY;if(initialOverflowY==='hidden'||this._element.classList.contains(CLASS_NAME_STATIC)){return;}
if(!isModalOverflowing){this._element.style.overflowY='hidden';}
this._element.classList.add(CLASS_NAME_STATIC);this._queueCallback(()=>{this._element.classList.remove(CLASS_NAME_STATIC);this._queueCallback(()=>{this._element.style.overflowY=initialOverflowY;},this._dialog);},this._dialog);this._element.focus();}
_adjustDialog(){const isModalOverflowing=this._element.scrollHeight>document.documentElement.clientHeight;const scrollbarWidth=this._scrollBar.getWidth();const isBodyOverflowing=scrollbarWidth>0;if(isBodyOverflowing&&!isModalOverflowing){const property=index_js.isRTL()?'paddingLeft':'paddingRight';this._element.style[property]=`${scrollbarWidth}px`;}
if(!isBodyOverflowing&&isModalOverflowing){const property=index_js.isRTL()?'paddingRight':'paddingLeft';this._element.style[property]=`${scrollbarWidth}px`;}}
_resetAdjustments(){this._element.style.paddingLeft='';this._element.style.paddingRight='';}
static jQueryInterface(config,relatedTarget){return this.each(function(){const data=Modal.getOrCreateInstance(this,config);if(typeof config!=='string'){return;}
if(typeof data[config]==='undefined'){throw new TypeError(`No method named "${config}"`);}
data[config](relatedTarget);});}}
EventHandler.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_TOGGLE,function(event){const target=SelectorEngine.getElementFromSelector(this);if(['A','AREA'].includes(this.tagName)){event.preventDefault();}
EventHandler.one(target,EVENT_SHOW,showEvent=>{if(showEvent.defaultPrevented){return;}
EventHandler.one(target,EVENT_HIDDEN,()=>{if(index_js.isVisible(this)){this.focus();}});});const alreadyOpen=SelectorEngine.findOne(OPEN_SELECTOR);if(alreadyOpen){Modal.getInstance(alreadyOpen).hide();}
const data=Modal.getOrCreateInstance(target);data.toggle(this);});componentFunctions_js.enableDismissTrigger(Modal);index_js.defineJQueryPlugin(Modal);return Modal;}));;
/* /web/static/lib/bootstrap/js/dist/offcanvas.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./base-component.js'),require('./dom/event-handler.js'),require('./dom/selector-engine.js'),require('./util/backdrop.js'),require('./util/component-functions.js'),require('./util/focustrap.js'),require('./util/index.js'),require('./util/scrollbar.js')):typeof define==='function'&&define.amd?define(['./base-component','./dom/event-handler','./dom/selector-engine','./util/backdrop','./util/component-functions','./util/focustrap','./util/index','./util/scrollbar'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Offcanvas=factory(global.BaseComponent,global.EventHandler,global.SelectorEngine,global.Backdrop,global.ComponentFunctions,global.Focustrap,global.Index,global.Scrollbar));})(this,(function(BaseComponent,EventHandler,SelectorEngine,Backdrop,componentFunctions_js,FocusTrap,index_js,ScrollBarHelper){'use strict';const NAME='offcanvas';const DATA_KEY='bs.offcanvas';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const EVENT_LOAD_DATA_API=`load${EVENT_KEY}${DATA_API_KEY}`;const ESCAPE_KEY='Escape';const CLASS_NAME_SHOW='show';const CLASS_NAME_SHOWING='showing';const CLASS_NAME_HIDING='hiding';const CLASS_NAME_BACKDROP='offcanvas-backdrop';const OPEN_SELECTOR='.offcanvas.show';const EVENT_SHOW=`show${EVENT_KEY}`;const EVENT_SHOWN=`shown${EVENT_KEY}`;const EVENT_HIDE=`hide${EVENT_KEY}`;const EVENT_HIDE_PREVENTED=`hidePrevented${EVENT_KEY}`;const EVENT_HIDDEN=`hidden${EVENT_KEY}`;const EVENT_RESIZE=`resize${EVENT_KEY}`;const EVENT_CLICK_DATA_API=`click${EVENT_KEY}${DATA_API_KEY}`;const EVENT_KEYDOWN_DISMISS=`keydown.dismiss${EVENT_KEY}`;const SELECTOR_DATA_TOGGLE='[data-bs-toggle="offcanvas"]';const Default={backdrop:true,keyboard:true,scroll:false};const DefaultType={backdrop:'(boolean|string)',keyboard:'boolean',scroll:'boolean'};class Offcanvas extends BaseComponent{constructor(element,config){super(element,config);this._isShown=false;this._backdrop=this._initializeBackDrop();this._focustrap=this._initializeFocusTrap();this._addEventListeners();}
static get Default(){return Default;}
static get DefaultType(){return DefaultType;}
static get NAME(){return NAME;}
toggle(relatedTarget){return this._isShown?this.hide():this.show(relatedTarget);}
show(relatedTarget){if(this._isShown){return;}
const showEvent=EventHandler.trigger(this._element,EVENT_SHOW,{relatedTarget});if(showEvent.defaultPrevented){return;}
this._isShown=true;this._backdrop.show();if(!this._config.scroll){new ScrollBarHelper().hide();}
this._element.setAttribute('aria-modal',true);this._element.setAttribute('role','dialog');this._element.classList.add(CLASS_NAME_SHOWING);const completeCallBack=()=>{if(!this._config.scroll||this._config.backdrop){this._focustrap.activate();}
this._element.classList.add(CLASS_NAME_SHOW);this._element.classList.remove(CLASS_NAME_SHOWING);EventHandler.trigger(this._element,EVENT_SHOWN,{relatedTarget});};this._queueCallback(completeCallBack,this._element,true);}
hide(){if(!this._isShown){return;}
const hideEvent=EventHandler.trigger(this._element,EVENT_HIDE);if(hideEvent.defaultPrevented){return;}
this._focustrap.deactivate();this._element.blur();this._isShown=false;this._element.classList.add(CLASS_NAME_HIDING);this._backdrop.hide();const completeCallback=()=>{this._element.classList.remove(CLASS_NAME_SHOW,CLASS_NAME_HIDING);this._element.removeAttribute('aria-modal');this._element.removeAttribute('role');if(!this._config.scroll){new ScrollBarHelper().reset();}
EventHandler.trigger(this._element,EVENT_HIDDEN);};this._queueCallback(completeCallback,this._element,true);}
dispose(){this._backdrop.dispose();this._focustrap.deactivate();super.dispose();}
_initializeBackDrop(){const clickCallback=()=>{if(this._config.backdrop==='static'){EventHandler.trigger(this._element,EVENT_HIDE_PREVENTED);return;}
this.hide();};const isVisible=Boolean(this._config.backdrop);return new Backdrop({className:CLASS_NAME_BACKDROP,isVisible,isAnimated:true,rootElement:this._element.parentNode,clickCallback:isVisible?clickCallback:null});}
_initializeFocusTrap(){return new FocusTrap({trapElement:this._element});}
_addEventListeners(){EventHandler.on(this._element,EVENT_KEYDOWN_DISMISS,event=>{if(event.key!==ESCAPE_KEY){return;}
if(this._config.keyboard){this.hide();return;}
EventHandler.trigger(this._element,EVENT_HIDE_PREVENTED);});}
static jQueryInterface(config){return this.each(function(){const data=Offcanvas.getOrCreateInstance(this,config);if(typeof config!=='string'){return;}
if(data[config]===undefined||config.startsWith('_')||config==='constructor'){throw new TypeError(`No method named "${config}"`);}
data[config](this);});}}
EventHandler.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_TOGGLE,function(event){const target=SelectorEngine.getElementFromSelector(this);if(['A','AREA'].includes(this.tagName)){event.preventDefault();}
if(index_js.isDisabled(this)){return;}
EventHandler.one(target,EVENT_HIDDEN,()=>{if(index_js.isVisible(this)){this.focus();}});const alreadyOpen=SelectorEngine.findOne(OPEN_SELECTOR);if(alreadyOpen&&alreadyOpen!==target){Offcanvas.getInstance(alreadyOpen).hide();}
const data=Offcanvas.getOrCreateInstance(target);data.toggle(this);});EventHandler.on(window,EVENT_LOAD_DATA_API,()=>{for(const selector of SelectorEngine.find(OPEN_SELECTOR)){Offcanvas.getOrCreateInstance(selector).show();}});EventHandler.on(window,EVENT_RESIZE,()=>{for(const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')){if(getComputedStyle(element).position!=='fixed'){Offcanvas.getOrCreateInstance(element).hide();}}});componentFunctions_js.enableDismissTrigger(Offcanvas);index_js.defineJQueryPlugin(Offcanvas);return Offcanvas;}));;
/* /web/static/lib/bootstrap/js/dist/tooltip.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('@popperjs/core'),require('./base-component.js'),require('./dom/event-handler.js'),require('./dom/manipulator.js'),require('./util/index.js'),require('./util/sanitizer.js'),require('./util/template-factory.js')):typeof define==='function'&&define.amd?define(['@popperjs/core','./base-component','./dom/event-handler','./dom/manipulator','./util/index','./util/sanitizer','./util/template-factory'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Tooltip=factory(global.Popper,global.BaseComponent,global.EventHandler,global.Manipulator,global.Index,global.Sanitizer,global.TemplateFactory));})(this,(function(Popper,BaseComponent,EventHandler,Manipulator,index_js,sanitizer_js,TemplateFactory){'use strict';function _interopNamespaceDefault(e){const n=Object.create(null,{[Symbol.toStringTag]:{value:'Module'}});if(e){for(const k in e){if(k!=='default'){const d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:()=>e[k]});}}}
n.default=e;return Object.freeze(n);}
const Popper__namespace=_interopNamespaceDefault(Popper);const NAME='tooltip';const DISALLOWED_ATTRIBUTES=new Set(['sanitize','allowList','sanitizeFn']);const CLASS_NAME_FADE='fade';const CLASS_NAME_MODAL='modal';const CLASS_NAME_SHOW='show';const SELECTOR_TOOLTIP_INNER='.tooltip-inner';const SELECTOR_MODAL=`.${CLASS_NAME_MODAL}`;const EVENT_MODAL_HIDE='hide.bs.modal';const TRIGGER_HOVER='hover';const TRIGGER_FOCUS='focus';const TRIGGER_CLICK='click';const TRIGGER_MANUAL='manual';const EVENT_HIDE='hide';const EVENT_HIDDEN='hidden';const EVENT_SHOW='show';const EVENT_SHOWN='shown';const EVENT_INSERTED='inserted';const EVENT_CLICK='click';const EVENT_FOCUSIN='focusin';const EVENT_FOCUSOUT='focusout';const EVENT_MOUSEENTER='mouseenter';const EVENT_MOUSELEAVE='mouseleave';const AttachmentMap={AUTO:'auto',TOP:'top',RIGHT:index_js.isRTL()?'left':'right',BOTTOM:'bottom',LEFT:index_js.isRTL()?'right':'left'};const Default={allowList:sanitizer_js.DefaultAllowlist,animation:true,boundary:'clippingParents',container:false,customClass:'',delay:0,fallbackPlacements:['top','right','bottom','left'],html:false,offset:[0,6],placement:'top',popperConfig:null,sanitize:true,sanitizeFn:null,selector:false,template:'<div class="tooltip" role="tooltip">'+'<div class="tooltip-arrow"></div>'+'<div class="tooltip-inner"></div>'+'</div>',title:'',trigger:'hover focus'};const DefaultType={allowList:'object',animation:'boolean',boundary:'(string|element)',container:'(string|element|boolean)',customClass:'(string|function)',delay:'(number|object)',fallbackPlacements:'array',html:'boolean',offset:'(array|string|function)',placement:'(string|function)',popperConfig:'(null|object|function)',sanitize:'boolean',sanitizeFn:'(null|function)',selector:'(string|boolean)',template:'string',title:'(string|element|function)',trigger:'string'};class Tooltip extends BaseComponent{constructor(element,config){if(typeof Popper__namespace==='undefined'){throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)');}
super(element,config);this._isEnabled=true;this._timeout=0;this._isHovered=null;this._activeTrigger={};this._popper=null;this._templateFactory=null;this._newContent=null;this.tip=null;this._setListeners();if(!this._config.selector){this._fixTitle();}}
static get Default(){return Default;}
static get DefaultType(){return DefaultType;}
static get NAME(){return NAME;}
enable(){this._isEnabled=true;}
disable(){this._isEnabled=false;}
toggleEnabled(){this._isEnabled=!this._isEnabled;}
toggle(){if(!this._isEnabled){return;}
this._activeTrigger.click=!this._activeTrigger.click;if(this._isShown()){this._leave();return;}
this._enter();}
dispose(){clearTimeout(this._timeout);EventHandler.off(this._element.closest(SELECTOR_MODAL),EVENT_MODAL_HIDE,this._hideModalHandler);if(this._element.getAttribute('data-bs-original-title')){this._element.setAttribute('title',this._element.getAttribute('data-bs-original-title'));}
this._disposePopper();super.dispose();}
show(){if(this._element.style.display==='none'){throw new Error('Please use show on visible elements');}
if(!(this._isWithContent()&&this._isEnabled)){return;}
const showEvent=EventHandler.trigger(this._element,this.constructor.eventName(EVENT_SHOW));const shadowRoot=index_js.findShadowRoot(this._element);const isInTheDom=(shadowRoot||this._element.ownerDocument.documentElement).contains(this._element);if(showEvent.defaultPrevented||!isInTheDom){return;}
this._disposePopper();const tip=this._getTipElement();this._element.setAttribute('aria-describedby',tip.getAttribute('id'));const{container}=this._config;if(!this._element.ownerDocument.documentElement.contains(this.tip)){container.append(tip);EventHandler.trigger(this._element,this.constructor.eventName(EVENT_INSERTED));}
this._popper=this._createPopper(tip);tip.classList.add(CLASS_NAME_SHOW);if('ontouchstart'in document.documentElement){for(const element of[].concat(...document.body.children)){EventHandler.on(element,'mouseover',index_js.noop);}}
const complete=()=>{EventHandler.trigger(this._element,this.constructor.eventName(EVENT_SHOWN));if(this._isHovered===false){this._leave();}
this._isHovered=false;};this._queueCallback(complete,this.tip,this._isAnimated());}
hide(){if(!this._isShown()){return;}
const hideEvent=EventHandler.trigger(this._element,this.constructor.eventName(EVENT_HIDE));if(hideEvent.defaultPrevented){return;}
const tip=this._getTipElement();tip.classList.remove(CLASS_NAME_SHOW);if('ontouchstart'in document.documentElement){for(const element of[].concat(...document.body.children)){EventHandler.off(element,'mouseover',index_js.noop);}}
this._activeTrigger[TRIGGER_CLICK]=false;this._activeTrigger[TRIGGER_FOCUS]=false;this._activeTrigger[TRIGGER_HOVER]=false;this._isHovered=null;const complete=()=>{if(this._isWithActiveTrigger()){return;}
if(!this._isHovered){this._disposePopper();}
this._element.removeAttribute('aria-describedby');EventHandler.trigger(this._element,this.constructor.eventName(EVENT_HIDDEN));};this._queueCallback(complete,this.tip,this._isAnimated());}
update(){if(this._popper){this._popper.update();}}
_isWithContent(){return Boolean(this._getTitle());}
_getTipElement(){if(!this.tip){this.tip=this._createTipElement(this._newContent||this._getContentForTemplate());}
return this.tip;}
_createTipElement(content){const tip=this._getTemplateFactory(content).toHtml();if(!tip){return null;}
tip.classList.remove(CLASS_NAME_FADE,CLASS_NAME_SHOW);tip.classList.add(`bs-${this.constructor.NAME}-auto`);const tipId=index_js.getUID(this.constructor.NAME).toString();tip.setAttribute('id',tipId);if(this._isAnimated()){tip.classList.add(CLASS_NAME_FADE);}
return tip;}
setContent(content){this._newContent=content;if(this._isShown()){this._disposePopper();this.show();}}
_getTemplateFactory(content){if(this._templateFactory){this._templateFactory.changeContent(content);}else{this._templateFactory=new TemplateFactory({...this._config,content,extraClass:this._resolvePossibleFunction(this._config.customClass)});}
return this._templateFactory;}
_getContentForTemplate(){return{[SELECTOR_TOOLTIP_INNER]:this._getTitle()};}
_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute('data-bs-original-title');}
_initializeOnDelegatedTarget(event){return this.constructor.getOrCreateInstance(event.delegateTarget,this._getDelegateConfig());}
_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(CLASS_NAME_FADE);}
_isShown(){return this.tip&&this.tip.classList.contains(CLASS_NAME_SHOW);}
_createPopper(tip){const placement=index_js.execute(this._config.placement,[this,tip,this._element]);const attachment=AttachmentMap[placement.toUpperCase()];return Popper__namespace.createPopper(this._element,tip,this._getPopperConfig(attachment));}
_getOffset(){const{offset}=this._config;if(typeof offset==='string'){return offset.split(',').map(value=>Number.parseInt(value,10));}
if(typeof offset==='function'){return popperData=>offset(popperData,this._element);}
return offset;}
_resolvePossibleFunction(arg){return index_js.execute(arg,[this._element]);}
_getPopperConfig(attachment){const defaultBsPopperConfig={placement:attachment,modifiers:[{name:'flip',options:{fallbackPlacements:this._config.fallbackPlacements}},{name:'offset',options:{offset:this._getOffset()}},{name:'preventOverflow',options:{boundary:this._config.boundary}},{name:'arrow',options:{element:`.${this.constructor.NAME}-arrow`}},{name:'preSetPlacement',enabled:true,phase:'beforeMain',fn:data=>{this._getTipElement().setAttribute('data-popper-placement',data.state.placement);}}]};return{...defaultBsPopperConfig,...index_js.execute(this._config.popperConfig,[defaultBsPopperConfig])};}
_setListeners(){const triggers=this._config.trigger.split(' ');for(const trigger of triggers){if(trigger==='click'){EventHandler.on(this._element,this.constructor.eventName(EVENT_CLICK),this._config.selector,event=>{const context=this._initializeOnDelegatedTarget(event);context.toggle();});}else if(trigger!==TRIGGER_MANUAL){const eventIn=trigger===TRIGGER_HOVER?this.constructor.eventName(EVENT_MOUSEENTER):this.constructor.eventName(EVENT_FOCUSIN);const eventOut=trigger===TRIGGER_HOVER?this.constructor.eventName(EVENT_MOUSELEAVE):this.constructor.eventName(EVENT_FOCUSOUT);EventHandler.on(this._element,eventIn,this._config.selector,event=>{const context=this._initializeOnDelegatedTarget(event);context._activeTrigger[event.type==='focusin'?TRIGGER_FOCUS:TRIGGER_HOVER]=true;context._enter();});EventHandler.on(this._element,eventOut,this._config.selector,event=>{const context=this._initializeOnDelegatedTarget(event);context._activeTrigger[event.type==='focusout'?TRIGGER_FOCUS:TRIGGER_HOVER]=context._element.contains(event.relatedTarget);context._leave();});}}
this._hideModalHandler=()=>{if(this._element){this.hide();}};EventHandler.on(this._element.closest(SELECTOR_MODAL),EVENT_MODAL_HIDE,this._hideModalHandler);}
_fixTitle(){const title=this._element.getAttribute('title');if(!title){return;}
if(!this._element.getAttribute('aria-label')&&!this._element.textContent.trim()){this._element.setAttribute('aria-label',title);}
this._element.setAttribute('data-bs-original-title',title);this._element.removeAttribute('title');}
_enter(){if(this._isShown()||this._isHovered){this._isHovered=true;return;}
this._isHovered=true;this._setTimeout(()=>{if(this._isHovered){this.show();}},this._config.delay.show);}
_leave(){if(this._isWithActiveTrigger()){return;}
this._isHovered=false;this._setTimeout(()=>{if(!this._isHovered){this.hide();}},this._config.delay.hide);}
_setTimeout(handler,timeout){clearTimeout(this._timeout);this._timeout=setTimeout(handler,timeout);}
_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(true);}
_getConfig(config){const dataAttributes=Manipulator.getDataAttributes(this._element);for(const dataAttribute of Object.keys(dataAttributes)){if(DISALLOWED_ATTRIBUTES.has(dataAttribute)){delete dataAttributes[dataAttribute];}}
config={...dataAttributes,...(typeof config==='object'&&config?config:{})};config=this._mergeConfigObj(config);config=this._configAfterMerge(config);this._typeCheckConfig(config);return config;}
_configAfterMerge(config){config.container=config.container===false?document.body:index_js.getElement(config.container);if(typeof config.delay==='number'){config.delay={show:config.delay,hide:config.delay};}
if(typeof config.title==='number'){config.title=config.title.toString();}
if(typeof config.content==='number'){config.content=config.content.toString();}
return config;}
_getDelegateConfig(){const config={};for(const[key,value]of Object.entries(this._config)){if(this.constructor.Default[key]!==value){config[key]=value;}}
config.selector=false;config.trigger='manual';return config;}
_disposePopper(){if(this._popper){this._popper.destroy();this._popper=null;}
if(this.tip){this.tip.remove();this.tip=null;}}
static jQueryInterface(config){return this.each(function(){const data=Tooltip.getOrCreateInstance(this,config);if(typeof config!=='string'){return;}
if(typeof data[config]==='undefined'){throw new TypeError(`No method named "${config}"`);}
data[config]();});}}
index_js.defineJQueryPlugin(Tooltip);return Tooltip;}));;
/* /web/static/lib/bootstrap/js/dist/popover.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./tooltip.js'),require('./util/index.js')):typeof define==='function'&&define.amd?define(['./tooltip','./util/index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Popover=factory(global.Tooltip,global.Index));})(this,(function(Tooltip,index_js){'use strict';const NAME='popover';const SELECTOR_TITLE='.popover-header';const SELECTOR_CONTENT='.popover-body';const Default={...Tooltip.Default,content:'',offset:[0,8],placement:'right',template:'<div class="popover" role="tooltip">'+'<div class="popover-arrow"></div>'+'<h3 class="popover-header"></h3>'+'<div class="popover-body"></div>'+'</div>',trigger:'click'};const DefaultType={...Tooltip.DefaultType,content:'(null|string|element|function)'};class Popover extends Tooltip{static get Default(){return Default;}
static get DefaultType(){return DefaultType;}
static get NAME(){return NAME;}
_isWithContent(){return this._getTitle()||this._getContent();}
_getContentForTemplate(){return{[SELECTOR_TITLE]:this._getTitle(),[SELECTOR_CONTENT]:this._getContent()};}
_getContent(){return this._resolvePossibleFunction(this._config.content);}
static jQueryInterface(config){return this.each(function(){const data=Popover.getOrCreateInstance(this,config);if(typeof config!=='string'){return;}
if(typeof data[config]==='undefined'){throw new TypeError(`No method named "${config}"`);}
data[config]();});}}
index_js.defineJQueryPlugin(Popover);return Popover;}));;
/* /web/static/lib/bootstrap/js/dist/scrollspy.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./base-component.js'),require('./dom/event-handler.js'),require('./dom/selector-engine.js'),require('./util/index.js')):typeof define==='function'&&define.amd?define(['./base-component','./dom/event-handler','./dom/selector-engine','./util/index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.ScrollSpy=factory(global.BaseComponent,global.EventHandler,global.SelectorEngine,global.Index));})(this,(function(BaseComponent,EventHandler,SelectorEngine,index_js){'use strict';const NAME='scrollspy';const DATA_KEY='bs.scrollspy';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const EVENT_ACTIVATE=`activate${EVENT_KEY}`;const EVENT_CLICK=`click${EVENT_KEY}`;const EVENT_LOAD_DATA_API=`load${EVENT_KEY}${DATA_API_KEY}`;const CLASS_NAME_DROPDOWN_ITEM='dropdown-item';const CLASS_NAME_ACTIVE='active';const SELECTOR_DATA_SPY='[data-bs-spy="scroll"]';const SELECTOR_TARGET_LINKS='[href]';const SELECTOR_NAV_LIST_GROUP='.nav, .list-group';const SELECTOR_NAV_LINKS='.nav-link';const SELECTOR_NAV_ITEMS='.nav-item';const SELECTOR_LIST_ITEMS='.list-group-item';const SELECTOR_LINK_ITEMS=`${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`;const SELECTOR_DROPDOWN='.dropdown';const SELECTOR_DROPDOWN_TOGGLE='.dropdown-toggle';const Default={offset:null,rootMargin:'0px 0px -25%',smoothScroll:false,target:null,threshold:[0.1,0.5,1]};const DefaultType={offset:'(number|null)',rootMargin:'string',smoothScroll:'boolean',target:'element',threshold:'array'};class ScrollSpy extends BaseComponent{constructor(element,config){super(element,config);this._targetLinks=new Map();this._observableSections=new Map();this._rootElement=getComputedStyle(this._element).overflowY==='visible'?null:this._element;this._activeTarget=null;this._observer=null;this._previousScrollData={visibleEntryTop:0,parentScrollTop:0};this.refresh();}
static get Default(){return Default;}
static get DefaultType(){return DefaultType;}
static get NAME(){return NAME;}
refresh(){this._initializeTargetsAndObservables();this._maybeEnableSmoothScroll();if(this._observer){this._observer.disconnect();}else{this._observer=this._getNewObserver();}
for(const section of this._observableSections.values()){this._observer.observe(section);}}
dispose(){this._observer.disconnect();super.dispose();}
_configAfterMerge(config){config.target=index_js.getElement(config.target)||document.body;config.rootMargin=config.offset?`${config.offset}px 0px -30%`:config.rootMargin;if(typeof config.threshold==='string'){config.threshold=config.threshold.split(',').map(value=>Number.parseFloat(value));}
return config;}
_maybeEnableSmoothScroll(){if(!this._config.smoothScroll){return;}
EventHandler.off(this._config.target,EVENT_CLICK);EventHandler.on(this._config.target,EVENT_CLICK,SELECTOR_TARGET_LINKS,event=>{const observableSection=this._observableSections.get(event.target.hash);if(observableSection){event.preventDefault();const root=this._rootElement||window;const height=observableSection.offsetTop-this._element.offsetTop;if(root.scrollTo){root.scrollTo({top:height,behavior:'smooth'});return;}
root.scrollTop=height;}});}
_getNewObserver(){const options={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver(entries=>this._observerCallback(entries),options);}
_observerCallback(entries){const targetElement=entry=>this._targetLinks.get(`#${entry.target.id}`);const activate=entry=>{this._previousScrollData.visibleEntryTop=entry.target.offsetTop;this._process(targetElement(entry));};const parentScrollTop=(this._rootElement||document.documentElement).scrollTop;const userScrollsDown=parentScrollTop>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=parentScrollTop;for(const entry of entries){if(!entry.isIntersecting){this._activeTarget=null;this._clearActiveClass(targetElement(entry));continue;}
const entryIsLowerThanPrevious=entry.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(userScrollsDown&&entryIsLowerThanPrevious){activate(entry);if(!parentScrollTop){return;}
continue;}
if(!userScrollsDown&&!entryIsLowerThanPrevious){activate(entry);}}}
_initializeTargetsAndObservables(){this._targetLinks=new Map();this._observableSections=new Map();const targetLinks=SelectorEngine.find(SELECTOR_TARGET_LINKS,this._config.target);for(const anchor of targetLinks){if(!anchor.hash||index_js.isDisabled(anchor)){continue;}
const observableSection=SelectorEngine.findOne(decodeURI(anchor.hash),this._element);if(index_js.isVisible(observableSection)){this._targetLinks.set(decodeURI(anchor.hash),anchor);this._observableSections.set(anchor.hash,observableSection);}}}
_process(target){if(this._activeTarget===target){return;}
this._clearActiveClass(this._config.target);this._activeTarget=target;target.classList.add(CLASS_NAME_ACTIVE);this._activateParents(target);EventHandler.trigger(this._element,EVENT_ACTIVATE,{relatedTarget:target});}
_activateParents(target){if(target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)){SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE,target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE);return;}
for(const listGroup of SelectorEngine.parents(target,SELECTOR_NAV_LIST_GROUP)){for(const item of SelectorEngine.prev(listGroup,SELECTOR_LINK_ITEMS)){item.classList.add(CLASS_NAME_ACTIVE);}}}
_clearActiveClass(parent){parent.classList.remove(CLASS_NAME_ACTIVE);const activeNodes=SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE}`,parent);for(const node of activeNodes){node.classList.remove(CLASS_NAME_ACTIVE);}}
static jQueryInterface(config){return this.each(function(){const data=ScrollSpy.getOrCreateInstance(this,config);if(typeof config!=='string'){return;}
if(data[config]===undefined||config.startsWith('_')||config==='constructor'){throw new TypeError(`No method named "${config}"`);}
data[config]();});}}
EventHandler.on(window,EVENT_LOAD_DATA_API,()=>{for(const spy of SelectorEngine.find(SELECTOR_DATA_SPY)){ScrollSpy.getOrCreateInstance(spy);}});index_js.defineJQueryPlugin(ScrollSpy);return ScrollSpy;}));;
/* /web/static/lib/bootstrap/js/dist/tab.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./base-component.js'),require('./dom/event-handler.js'),require('./dom/selector-engine.js'),require('./util/index.js')):typeof define==='function'&&define.amd?define(['./base-component','./dom/event-handler','./dom/selector-engine','./util/index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Tab=factory(global.BaseComponent,global.EventHandler,global.SelectorEngine,global.Index));})(this,(function(BaseComponent,EventHandler,SelectorEngine,index_js){'use strict';const NAME='tab';const DATA_KEY='bs.tab';const EVENT_KEY=`.${DATA_KEY}`;const EVENT_HIDE=`hide${EVENT_KEY}`;const EVENT_HIDDEN=`hidden${EVENT_KEY}`;const EVENT_SHOW=`show${EVENT_KEY}`;const EVENT_SHOWN=`shown${EVENT_KEY}`;const EVENT_CLICK_DATA_API=`click${EVENT_KEY}`;const EVENT_KEYDOWN=`keydown${EVENT_KEY}`;const EVENT_LOAD_DATA_API=`load${EVENT_KEY}`;const ARROW_LEFT_KEY='ArrowLeft';const ARROW_RIGHT_KEY='ArrowRight';const ARROW_UP_KEY='ArrowUp';const ARROW_DOWN_KEY='ArrowDown';const HOME_KEY='Home';const END_KEY='End';const CLASS_NAME_ACTIVE='active';const CLASS_NAME_FADE='fade';const CLASS_NAME_SHOW='show';const CLASS_DROPDOWN='dropdown';const SELECTOR_DROPDOWN_TOGGLE='.dropdown-toggle';const SELECTOR_DROPDOWN_MENU='.dropdown-menu';const NOT_SELECTOR_DROPDOWN_TOGGLE=`:not(${SELECTOR_DROPDOWN_TOGGLE})`;const SELECTOR_TAB_PANEL='.list-group, .nav, [role="tablist"]';const SELECTOR_OUTER='.nav-item, .list-group-item';const SELECTOR_INNER=`.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`;const SELECTOR_DATA_TOGGLE='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]';const SELECTOR_INNER_ELEM=`${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`;const SELECTOR_DATA_TOGGLE_ACTIVE=`.${CLASS_NAME_ACTIVE}[data-bs-toggle="tab"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="pill"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="list"]`;class Tab extends BaseComponent{constructor(element){super(element);this._parent=this._element.closest(SELECTOR_TAB_PANEL);if(!this._parent){return;}
this._setInitialAttributes(this._parent,this._getChildren());EventHandler.on(this._element,EVENT_KEYDOWN,event=>this._keydown(event));}
static get NAME(){return NAME;}
show(){const innerElem=this._element;if(this._elemIsActive(innerElem)){return;}
const active=this._getActiveElem();const hideEvent=active?EventHandler.trigger(active,EVENT_HIDE,{relatedTarget:innerElem}):null;const showEvent=EventHandler.trigger(innerElem,EVENT_SHOW,{relatedTarget:active});if(showEvent.defaultPrevented||hideEvent&&hideEvent.defaultPrevented){return;}
this._deactivate(active,innerElem);this._activate(innerElem,active);}
_activate(element,relatedElem){if(!element){return;}
element.classList.add(CLASS_NAME_ACTIVE);this._activate(SelectorEngine.getElementFromSelector(element));const complete=()=>{if(element.getAttribute('role')!=='tab'){element.classList.add(CLASS_NAME_SHOW);return;}
element.removeAttribute('tabindex');element.setAttribute('aria-selected',true);this._toggleDropDown(element,true);EventHandler.trigger(element,EVENT_SHOWN,{relatedTarget:relatedElem});};this._queueCallback(complete,element,element.classList.contains(CLASS_NAME_FADE));}
_deactivate(element,relatedElem){if(!element){return;}
element.classList.remove(CLASS_NAME_ACTIVE);element.blur();this._deactivate(SelectorEngine.getElementFromSelector(element));const complete=()=>{if(element.getAttribute('role')!=='tab'){element.classList.remove(CLASS_NAME_SHOW);return;}
element.setAttribute('aria-selected',false);element.setAttribute('tabindex','-1');this._toggleDropDown(element,false);EventHandler.trigger(element,EVENT_HIDDEN,{relatedTarget:relatedElem});};this._queueCallback(complete,element,element.classList.contains(CLASS_NAME_FADE));}
_keydown(event){if(![ARROW_LEFT_KEY,ARROW_RIGHT_KEY,ARROW_UP_KEY,ARROW_DOWN_KEY,HOME_KEY,END_KEY].includes(event.key)){return;}
event.stopPropagation();event.preventDefault();const children=this._getChildren().filter(element=>!index_js.isDisabled(element));let nextActiveElement;if([HOME_KEY,END_KEY].includes(event.key)){nextActiveElement=children[event.key===HOME_KEY?0:children.length-1];}else{const isNext=[ARROW_RIGHT_KEY,ARROW_DOWN_KEY].includes(event.key);nextActiveElement=index_js.getNextActiveElement(children,event.target,isNext,true);}
if(nextActiveElement){nextActiveElement.focus({preventScroll:true});Tab.getOrCreateInstance(nextActiveElement).show();}}
_getChildren(){return SelectorEngine.find(SELECTOR_INNER_ELEM,this._parent);}
_getActiveElem(){return this._getChildren().find(child=>this._elemIsActive(child))||null;}
_setInitialAttributes(parent,children){this._setAttributeIfNotExists(parent,'role','tablist');for(const child of children){this._setInitialAttributesOnChild(child);}}
_setInitialAttributesOnChild(child){child=this._getInnerElement(child);const isActive=this._elemIsActive(child);const outerElem=this._getOuterElement(child);child.setAttribute('aria-selected',isActive);if(outerElem!==child){this._setAttributeIfNotExists(outerElem,'role','presentation');}
if(!isActive){child.setAttribute('tabindex','-1');}
this._setAttributeIfNotExists(child,'role','tab');this._setInitialAttributesOnTargetPanel(child);}
_setInitialAttributesOnTargetPanel(child){const target=SelectorEngine.getElementFromSelector(child);if(!target){return;}
this._setAttributeIfNotExists(target,'role','tabpanel');if(child.id){this._setAttributeIfNotExists(target,'aria-labelledby',`${child.id}`);}}
_toggleDropDown(element,open){const outerElem=this._getOuterElement(element);if(!outerElem.classList.contains(CLASS_DROPDOWN)){return;}
const toggle=(selector,className)=>{const element=SelectorEngine.findOne(selector,outerElem);if(element){element.classList.toggle(className,open);}};toggle(SELECTOR_DROPDOWN_TOGGLE,CLASS_NAME_ACTIVE);toggle(SELECTOR_DROPDOWN_MENU,CLASS_NAME_SHOW);outerElem.setAttribute('aria-expanded',open);}
_setAttributeIfNotExists(element,attribute,value){if(!element.hasAttribute(attribute)){element.setAttribute(attribute,value);}}
_elemIsActive(elem){return elem.classList.contains(CLASS_NAME_ACTIVE);}
_getInnerElement(elem){return elem.matches(SELECTOR_INNER_ELEM)?elem:SelectorEngine.findOne(SELECTOR_INNER_ELEM,elem);}
_getOuterElement(elem){return elem.closest(SELECTOR_OUTER)||elem;}
static jQueryInterface(config){return this.each(function(){const data=Tab.getOrCreateInstance(this);if(typeof config!=='string'){return;}
if(data[config]===undefined||config.startsWith('_')||config==='constructor'){throw new TypeError(`No method named "${config}"`);}
data[config]();});}}
EventHandler.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_TOGGLE,function(event){if(['A','AREA'].includes(this.tagName)){event.preventDefault();}
if(index_js.isDisabled(this)){return;}
Tab.getOrCreateInstance(this).show();});EventHandler.on(window,EVENT_LOAD_DATA_API,()=>{for(const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)){Tab.getOrCreateInstance(element);}});index_js.defineJQueryPlugin(Tab);return Tab;}));;
/* /web/static/lib/bootstrap/js/dist/toast.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./base-component.js'),require('./dom/event-handler.js'),require('./util/component-functions.js'),require('./util/index.js')):typeof define==='function'&&define.amd?define(['./base-component','./dom/event-handler','./util/component-functions','./util/index'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Toast=factory(global.BaseComponent,global.EventHandler,global.ComponentFunctions,global.Index));})(this,(function(BaseComponent,EventHandler,componentFunctions_js,index_js){'use strict';const NAME='toast';const DATA_KEY='bs.toast';const EVENT_KEY=`.${DATA_KEY}`;const EVENT_MOUSEOVER=`mouseover${EVENT_KEY}`;const EVENT_MOUSEOUT=`mouseout${EVENT_KEY}`;const EVENT_FOCUSIN=`focusin${EVENT_KEY}`;const EVENT_FOCUSOUT=`focusout${EVENT_KEY}`;const EVENT_HIDE=`hide${EVENT_KEY}`;const EVENT_HIDDEN=`hidden${EVENT_KEY}`;const EVENT_SHOW=`show${EVENT_KEY}`;const EVENT_SHOWN=`shown${EVENT_KEY}`;const CLASS_NAME_FADE='fade';const CLASS_NAME_HIDE='hide';const CLASS_NAME_SHOW='show';const CLASS_NAME_SHOWING='showing';const DefaultType={animation:'boolean',autohide:'boolean',delay:'number'};const Default={animation:true,autohide:true,delay:5000};class Toast extends BaseComponent{constructor(element,config){super(element,config);this._timeout=null;this._hasMouseInteraction=false;this._hasKeyboardInteraction=false;this._setListeners();}
static get Default(){return Default;}
static get DefaultType(){return DefaultType;}
static get NAME(){return NAME;}
show(){const showEvent=EventHandler.trigger(this._element,EVENT_SHOW);if(showEvent.defaultPrevented){return;}
this._clearTimeout();if(this._config.animation){this._element.classList.add(CLASS_NAME_FADE);}
const complete=()=>{this._element.classList.remove(CLASS_NAME_SHOWING);EventHandler.trigger(this._element,EVENT_SHOWN);this._maybeScheduleHide();};this._element.classList.remove(CLASS_NAME_HIDE);index_js.reflow(this._element);this._element.classList.add(CLASS_NAME_SHOW,CLASS_NAME_SHOWING);this._queueCallback(complete,this._element,this._config.animation);}
hide(){if(!this.isShown()){return;}
const hideEvent=EventHandler.trigger(this._element,EVENT_HIDE);if(hideEvent.defaultPrevented){return;}
const complete=()=>{this._element.classList.add(CLASS_NAME_HIDE);this._element.classList.remove(CLASS_NAME_SHOWING,CLASS_NAME_SHOW);EventHandler.trigger(this._element,EVENT_HIDDEN);};this._element.classList.add(CLASS_NAME_SHOWING);this._queueCallback(complete,this._element,this._config.animation);}
dispose(){this._clearTimeout();if(this.isShown()){this._element.classList.remove(CLASS_NAME_SHOW);}
super.dispose();}
isShown(){return this._element.classList.contains(CLASS_NAME_SHOW);}
_maybeScheduleHide(){if(!this._config.autohide){return;}
if(this._hasMouseInteraction||this._hasKeyboardInteraction){return;}
this._timeout=setTimeout(()=>{this.hide();},this._config.delay);}
_onInteraction(event,isInteracting){switch(event.type){case'mouseover':case'mouseout':{this._hasMouseInteraction=isInteracting;break;}
case'focusin':case'focusout':{this._hasKeyboardInteraction=isInteracting;break;}}
if(isInteracting){this._clearTimeout();return;}
const nextElement=event.relatedTarget;if(this._element===nextElement||this._element.contains(nextElement)){return;}
this._maybeScheduleHide();}
_setListeners(){EventHandler.on(this._element,EVENT_MOUSEOVER,event=>this._onInteraction(event,true));EventHandler.on(this._element,EVENT_MOUSEOUT,event=>this._onInteraction(event,false));EventHandler.on(this._element,EVENT_FOCUSIN,event=>this._onInteraction(event,true));EventHandler.on(this._element,EVENT_FOCUSOUT,event=>this._onInteraction(event,false));}
_clearTimeout(){clearTimeout(this._timeout);this._timeout=null;}
static jQueryInterface(config){return this.each(function(){const data=Toast.getOrCreateInstance(this,config);if(typeof config==='string'){if(typeof data[config]==='undefined'){throw new TypeError(`No method named "${config}"`);}
data[config](this);}});}}
componentFunctions_js.enableDismissTrigger(Toast);index_js.defineJQueryPlugin(Toast);return Toast;}));;
/* /web/static/src/libs/bootstrap.js */
odoo.define('@web/libs/bootstrap',['@web/core/utils/scrolling'],function(require){'use strict';let __exports={};const{compensateScrollbar,getScrollingElement}=require("@web/core/utils/scrolling");const bsSanitizeAllowList=Tooltip.Default.allowList;bsSanitizeAllowList["*"].push("title","style",/^data-[\w-]+/);bsSanitizeAllowList.header=[];bsSanitizeAllowList.main=[];bsSanitizeAllowList.footer=[];bsSanitizeAllowList.caption=[];bsSanitizeAllowList.col=["span"];bsSanitizeAllowList.colgroup=["span"];bsSanitizeAllowList.table=[];bsSanitizeAllowList.thead=[];bsSanitizeAllowList.tbody=[];bsSanitizeAllowList.tfooter=[];bsSanitizeAllowList.tr=[];bsSanitizeAllowList.th=["colspan","rowspan"];bsSanitizeAllowList.td=["colspan","rowspan"];bsSanitizeAllowList.address=[];bsSanitizeAllowList.article=[];bsSanitizeAllowList.aside=[];bsSanitizeAllowList.blockquote=[];bsSanitizeAllowList.section=[];bsSanitizeAllowList.button=["type"];bsSanitizeAllowList.del=[];Tooltip.Default.placement="auto";Tooltip.Default.fallbackPlacement=["bottom","right","left","top"];Tooltip.Default.html=true;Tooltip.Default.trigger="hover";Tooltip.Default.container="body";Tooltip.Default.boundary="window";Tooltip.Default.delay={show:1000,hide:0};const bootstrapShowFunction=Tooltip.prototype.show;Tooltip.prototype.show=function(){document.querySelectorAll(".tooltip").forEach((el)=>el.remove());const errorsToIgnore=["Please use show on visible elements"];try{return bootstrapShowFunction.call(this);}catch(error){if(errorsToIgnore.includes(error.message)){return 0;}
throw error;}};Dropdown.prototype._detectNavbar=function(){return false;};const bsAdjustDialogFunction=Modal.prototype._adjustDialog;Modal.prototype._adjustDialog=function(){const document=this._element.ownerDocument;this._scrollBar.reset();document.body.classList.remove("modal-open");const scrollable=getScrollingElement(document);if(document.body.contains(scrollable)){compensateScrollbar(scrollable,true);}
this._scrollBar.hide();document.body.classList.add("modal-open");return bsAdjustDialogFunction.apply(this,arguments);};const bsResetAdjustmentsFunction=Modal.prototype._resetAdjustments;Modal.prototype._resetAdjustments=function(){const document=this._element.ownerDocument;this._scrollBar.reset();document.body.classList.remove("modal-open");const scrollable=getScrollingElement(document);if(document.body.contains(scrollable)){compensateScrollbar(scrollable,false);}
return bsResetAdjustmentsFunction.apply(this,arguments);};return __exports;});;
/* /web/static/src/legacy/js/libs/jquery.js */
odoo.define('@web/legacy/js/libs/jquery',[],function(require){'use strict';let __exports={};$.extend($.expr[':'],{data:function(element,index,matches){return $(element).data(matches[3]);},});$.fn.extend({odooBounce:function(extraClass){for(const el of this){el.classList.add('o_catch_attention',extraClass);setTimeout(()=>el.classList.remove('o_catch_attention',extraClass),400);}
return this;},prependEvent:function(events,selector,data,handler){this.on.apply(this,arguments);events=events.split(' ');return this.each(function(){var el=this;events.forEach((evNameNamespaced)=>{var evName=evNameNamespaced.split('.')[0];var handler=$._data(el,'events')[evName].pop();$._data(el,'events')[evName].unshift(handler);});});},getScrollingElement(document=window.document){const $baseScrollingElement=$(document.scrollingElement);if($baseScrollingElement.isScrollable()&&$baseScrollingElement.hasScrollableContent()){return $baseScrollingElement;}
const bodyHeight=$(document.body).height();for(const el of document.body.children){if(bodyHeight-el.scrollHeight>1.5){continue;}
const $el=$(el);if($el.isScrollable()){return $el;}}
return $baseScrollingElement;},getScrollingTarget(contextItem=window.document){const isElement=obj=>obj&&obj.nodeType===Node.ELEMENT_NODE;const isJQuery=obj=>obj&&('jquery'in obj);const $scrollingElement=isElement(contextItem)?$(contextItem):isJQuery(contextItem)?contextItem:$().getScrollingElement(contextItem);const document=$scrollingElement[0].ownerDocument;return $scrollingElement.is(document.scrollingElement)?$(document.defaultView):$scrollingElement;},hasScrollableContent(){return this[0].scrollHeight>this[0].clientHeight;},isScrollable(){if(!this.length){return false;}
const overflow=this.css('overflow-y');const el=this[0];return overflow==='auto'||overflow==='scroll'||(overflow==='visible'&&el===el.ownerDocument.scrollingElement);},});const originalScrollTop=$.fn.scrollTop;$.fn.scrollTop=function(value){if(value!==undefined&&this.filter('html, body').length){const $withRealScrollable=this.not('html, body').add($().getScrollingElement(this[0].ownerDocument));originalScrollTop.apply($withRealScrollable,arguments);return this;}else if(value===undefined&&this.eq(0).is('html, body')){return originalScrollTop.apply($().getScrollingElement(this[0].ownerDocument),arguments);}
return originalScrollTop.apply(this,arguments);};const originalAnimate=$.fn.animate;$.fn.animate=function(properties,...rest){const props=Object.assign({},properties);if('scrollTop'in props&&this.filter('html, body').length){const $withRealScrollable=this.not('html, body').add($().getScrollingElement(this[0].ownerDocument));originalAnimate.call($withRealScrollable,{'scrollTop':props['scrollTop']},...rest);delete props['scrollTop'];}
if(!Object.keys(props).length){return this;}
return originalAnimate.call(this,props,...rest);};return __exports;});;
/* /web/static/src/legacy/js/core/class.js */
odoo.define('@web/legacy/js/core/class',[],function(require){'use strict';let __exports={};function OdooClass(){}
var initializing=false;var fnTest=/xyz/.test(function(){xyz();})?/\b_super\b/:/.*/;OdooClass.extend=function(){var _super=this.prototype;var args=[...arguments];args.unshift({});const prop={};args.forEach((arg)=>{Object.assign(prop,arg);});initializing=true;var This=this;var prototype=new This();initializing=false;Object.keys(prop).forEach((name)=>{prototype[name]=typeof prop[name]=="function"&&fnTest.test(prop[name])?(function(name,fn){return function(){var tmp=this._super;this._super=_super[name];var ret=fn.apply(this,arguments);this._super=tmp;return ret;};})(name,prop[name]):prop[name];});function Class(){if(this.constructor!==OdooClass){throw new Error("You can only instanciate objects with the 'new' operator");}
this._super=null;if(!initializing&&this.init){var ret=this.init.apply(this,arguments);if(ret){return ret;}}
return this;}
Class.include=function(properties){Object.keys(properties).forEach((name)=>{if(typeof properties[name]!=='function'||!fnTest.test(properties[name])){prototype[name]=properties[name];}else if(typeof prototype[name]==='function'&&prototype.hasOwnProperty(name)){prototype[name]=(function(name,fn,previous){return function(){var tmp=this._super;this._super=previous;var ret=fn.apply(this,arguments);this._super=tmp;return ret;};})(name,properties[name],prototype[name]);}else if(typeof _super[name]==='function'){prototype[name]=(function(name,fn){return function(){var tmp=this._super;this._super=_super[name];var ret=fn.apply(this,arguments);this._super=tmp;return ret;};})(name,properties[name]);}});};Class.prototype=prototype;Class.constructor=Class;Class.extend=this.extend;return Class;};__exports[Symbol.for("default")]=OdooClass;return __exports;});;
/* /web/static/src/env.js */
odoo.define('@web/env',['@odoo/owl','@web/core/utils/hooks','@web/core/registry','@web/core/templates','@web/core/l10n/translation','@web/session','@web/core/browser/feature_detection'],function(require){'use strict';let __exports={};const{App,EventBus}=require("@odoo/owl");const{SERVICES_METADATA}=require("@web/core/utils/hooks");const{registry}=require("@web/core/registry");const{getTemplate}=require("@web/core/templates");const{appTranslateFn}=require("@web/core/l10n/translation");const{session}=require("@web/session");const{isMacOS}=require("@web/core/browser/feature_detection");__exports.makeEnv=makeEnv;function makeEnv(){const bus=new EventBus();const prom=new Promise((resolve)=>{bus.addEventListener("SERVICES-LOADED",resolve,{once:true});});return{bus,isReady:prom,services:{},debug:odoo.debug,get isSmall(){throw new Error("UI service not initialized!");},};}
const serviceRegistry=registry.category("services");serviceRegistry.addValidation({start:Function,dependencies:{type:Array,element:String,optional:true},async:{type:[{type:Array,element:String},{value:true}],optional:true},"*":true,});let startServicesPromise=null;__exports.startServices=startServices;async function startServices(env){await Promise.resolve();const toStart=new Map();serviceRegistry.addEventListener("UPDATE",async(ev)=>{await Promise.resolve();const{operation,key:name,value:service}=ev.detail;if(operation==="delete"){return;}
if(toStart.size){const namedService=Object.assign(Object.create(service),{name});toStart.set(name,namedService);}else{await _startServices(env,toStart);}});await _startServices(env,toStart);}
async function _startServices(env,toStart){if(startServicesPromise){return startServicesPromise.then(()=>_startServices(env,toStart));}
const services=env.services;for(const[name,service]of serviceRegistry.getEntries()){if(!(name in services)){const namedService=Object.assign(Object.create(service),{name});toStart.set(name,namedService);}}
async function start(){let service=null;const proms=[];while((service=findNext())){const name=service.name;toStart.delete(name);const entries=(service.dependencies||[]).map((dep)=>[dep,services[dep]]);const dependencies=Object.fromEntries(entries);if(name in services){continue;}
const value=service.start(env,dependencies);if("async"in service){SERVICES_METADATA[name]=service.async;}
proms.push(Promise.resolve(value).then((val)=>{services[name]=val||null;}));}
await Promise.all(proms);if(proms.length){return start();}}
startServicesPromise=start().finally(()=>{startServicesPromise=null;});await startServicesPromise;env.bus.trigger("SERVICES-LOADED");if(toStart.size){const missingDeps=new Set();for(const service of toStart.values()){for(const dependency of service.dependencies){if(!(dependency in services)&&!toStart.has(dependency)){missingDeps.add(dependency);}}}
const depNames=[...missingDeps].join(", ");throw new Error(`Some services could not be started: ${[
...toStart.keys(),
]}. Missing dependencies: ${depNames}`);}
function findNext(){for(const s of toStart.values()){if(s.dependencies){if(s.dependencies.every((d)=>d in services)){return s;}}else{return s;}}
return null;}}
const customDirectives=__exports.customDirectives={click:(node,value,modifiers)=>{let mods="";if(modifiers.includes("synthetic")){mods+=".synthetic";}
if(modifiers.includes("capture")){mods+=".capture";}
const handlerFunction=`(ev) => __globals__.click(ev, (${value}).bind(this), '${JSON.stringify(
modifiers
)}')`;node.setAttribute(`t-on-click${mods}`,handlerFunction);node.setAttribute(`t-on-auxclick${mods}`,handlerFunction);},};const globalValues=__exports.globalValues={click:(ev,value,modifiers)=>{if(ev.button===0||ev.button===1){modifiers=JSON.parse(modifiers);for(const modifier of modifiers){if(modifier==="stop"){ev.stopPropagation();}
if(modifier==="prevent"){ev.preventDefault();}}
const ctrlKey=isMacOS()?ev.metaKey:ev.ctrlKey;const isMiddleClick=(ctrlKey&&ev.button===0)||ev.button===1;value(ev,isMiddleClick);}},};__exports.mountComponent=mountComponent;async function mountComponent(component,target,appConfig={}){let{env}=appConfig;const isRoot=!env;if(isRoot){env=await makeEnv();await startServices(env);}
const app=new App(component,{env,getTemplate,dev:env.debug||session.test_mode,warnIfNoStaticProps:!session.test_mode,name:component.constructor.name,translatableAttributes:["data-tooltip"],translateFn:appTranslateFn,customDirectives,globalValues,...appConfig,});const root=await app.mount(target);if(isRoot){odoo.__WOWL_DEBUG__={root};}
return app;}
return __exports;});;
/* /web/static/src/core/action_swiper/action_swiper.js */
odoo.define('@web/core/action_swiper/action_swiper',['@web/core/browser/browser','@web/core/l10n/localization','@web/core/utils/numbers','@odoo/owl','@web/core/utils/concurrency'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{localization}=require("@web/core/l10n/localization");const{clamp}=require("@web/core/utils/numbers");const{Component,onMounted,onWillUnmount,useRef,useState}=require("@odoo/owl");const{Deferred}=require("@web/core/utils/concurrency");const isScrollSwipable=(scrollables)=>{return{left:!scrollables.filter((e)=>e.scrollLeft!==0).length,right:!scrollables.filter((e)=>e.scrollLeft+Math.round(e.getBoundingClientRect().width)!==e.scrollWidth).length,};};const ActionSwiper=__exports.ActionSwiper=class ActionSwiper extends Component{static template="web.ActionSwiper";static props={onLeftSwipe:{type:Object,args:{action:Function,icon:String,bgColor:String,},optional:true,},onRightSwipe:{type:Object,args:{action:Function,icon:String,bgColor:String,},optional:true,},slots:Object,animationOnMove:{type:Boolean,optional:true},animationType:{type:String,optional:true},swipeDistanceRatio:{type:Number,optional:true},swipeInvalid:{type:Function,optional:true},};static defaultProps={onLeftSwipe:undefined,onRightSwipe:undefined,animationOnMove:true,animationType:"bounce",swipeDistanceRatio:2,};setup(){this.actionTimeoutId=null;this.resetTimeoutId=null;this.defaultState={containerStyle:"",isSwiping:false,width:undefined,};this.root=useRef("root");this.targetContainer=useRef("targetContainer");this.state=useState({...this.defaultState});this.scrollables=undefined;this.startX=undefined;this.swipedDistance=0;this.isScrollValidated=false;onMounted(()=>{if(this.targetContainer.el){this.state.width=this.targetContainer.el.getBoundingClientRect().width;}
if(this.props.onLeftSwipe||this.props.onRightSwipe){const classes=new Set(this.root.el.classList);classes.delete("o_actionswiper");for(const className of classes){this.targetContainer.el.firstChild.classList.add(className);this.root.el.classList.remove(className);}}});onWillUnmount(()=>{browser.clearTimeout(this.actionTimeoutId);browser.clearTimeout(this.resetTimeoutId);});}
get localizedProps(){return{onLeftSwipe:localization.direction==="rtl"?this.props.onRightSwipe:this.props.onLeftSwipe,onRightSwipe:localization.direction==="rtl"?this.props.onLeftSwipe:this.props.onRightSwipe,};}
_onTouchEndSwipe(){if(this.state.isSwiping){this.state.isSwiping=false;if(this.localizedProps.onRightSwipe&&this.swipedDistance>this.state.width/this.props.swipeDistanceRatio){this.swipedDistance=this.state.width;this.handleSwipe(this.localizedProps.onRightSwipe.action);}else if(this.localizedProps.onLeftSwipe&&this.swipedDistance<-this.state.width/this.props.swipeDistanceRatio){this.swipedDistance=-this.state.width;this.handleSwipe(this.localizedProps.onLeftSwipe.action);}else{this.state.containerStyle="";}}}
_onTouchMoveSwipe(ev){if(this.state.isSwiping){if(this.props.swipeInvalid&&this.props.swipeInvalid()){this.state.isSwiping=false;return;}
const{onLeftSwipe,onRightSwipe}=this.localizedProps;this.swipedDistance=clamp(ev.touches[0].clientX-this.startX,onLeftSwipe?-this.state.width:0,onRightSwipe?this.state.width:0);if(Math.abs(this.swipedDistance)>40){ev.preventDefault();}
if(!this.isScrollValidated&&this.scrollables&&!isScrollSwipable(this.scrollables)[this.swipedDistance>0?"left":"right"]){return this._reset();}
this.isScrollValidated=true;if(this.props.animationOnMove){this.state.containerStyle=`transform: translateX(${this.swipedDistance}px)`;}}}
_onTouchStartSwipe(ev){this.scrollables=ev.composedPath().filter((e)=>e.nodeType===1&&this.targetContainer.el.contains(e)&&e.scrollWidth>e.getBoundingClientRect().width&&["auto","scroll"].includes(window.getComputedStyle(e)["overflow-x"]));if(!this.state.width){this.state.width=this.targetContainer&&this.targetContainer.el.getBoundingClientRect().width;}
this.state.isSwiping=true;this.isScrollValidated=false;this.startX=ev.touches[0].clientX;}
_reset(){Object.assign(this.state,{...this.defaultState});this.scrollables=undefined;this.startX=undefined;this.swipedDistance=0;this.isScrollValidated=false;}
handleSwipe(action){if(this.props.animationType==="bounce"){this.state.containerStyle=`transform: translateX(${this.swipedDistance}px)`;this.actionTimeoutId=browser.setTimeout(async()=>{await action(Promise.resolve());this._reset();},500);}else if(this.props.animationType==="forwards"){this.state.containerStyle=`transform: translateX(${this.swipedDistance}px)`;this.actionTimeoutId=browser.setTimeout(async()=>{const prom=new Deferred();await action(prom);this.state.isSwiping=true;this.state.containerStyle=`transform: translateX(${-this.swipedDistance}px)`;this.resetTimeoutId=browser.setTimeout(()=>{prom.resolve();this._reset();},100);},100);}else{return action(Promise.resolve());}}}
return __exports;});;
/* /web/static/src/core/anchor_scroll_prevention.js */
odoo.define('@web/core/anchor_scroll_prevention',['@web/core/browser/browser'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");browser.addEventListener("click",(ev)=>{const href=ev.target.closest("a")?.getAttribute("href");if(href&&href==="#"){ev.preventDefault();return;}});return __exports;});;
/* /web/static/src/core/assets.js */
odoo.define('@web/core/assets',['@odoo/owl','@web/session','@web/core/registry'],function(require){'use strict';let __exports={};const{Component,onWillStart,whenReady,xml}=require("@odoo/owl");const{session}=require("@web/session");const{registry}=require("@web/core/registry");const globalBundleCache=__exports.globalBundleCache=new Map();const assetCacheByDocument=__exports.assetCacheByDocument=new WeakMap();function getGlobalBundleCache(){return globalBundleCache;}
function getAssetCache(targetDoc){if(!assetCacheByDocument.has(targetDoc)){assetCacheByDocument.set(targetDoc,new Map());}
return assetCacheByDocument.get(targetDoc);}
__exports.computeBundleCacheMap=computeBundleCacheMap;function computeBundleCacheMap(targetDoc){const cacheMap=getGlobalBundleCache();for(const script of targetDoc.head.querySelectorAll("script[src]")){cacheMap.set(script.getAttribute("src"),Promise.resolve());}
for(const link of targetDoc.head.querySelectorAll("link[rel=stylesheet][href]")){cacheMap.set(link.getAttribute("href"),Promise.resolve());}}
whenReady(()=>computeBundleCacheMap(document));const onLoadAndError=(el,onLoad,onError)=>{const onLoadListener=(event)=>{removeListeners();onLoad(event);};const onErrorListener=(error)=>{removeListeners();onError(error);};const removeListeners=()=>{el.removeEventListener("load",onLoadListener);el.removeEventListener("error",onErrorListener);};el.addEventListener("load",onLoadListener);el.addEventListener("error",onErrorListener);window.addEventListener("pagehide",()=>{removeListeners();});};__exports.getBundle=getBundle;function getBundle(){return assets.getBundle(...arguments);}
__exports.loadBundle=loadBundle;function loadBundle(){return assets.loadBundle(...arguments);}
__exports.loadJS=loadJS;function loadJS(){return assets.loadJS(...arguments);}
__exports.loadCSS=loadCSS;function loadCSS(){return assets.loadCSS(...arguments);}
const AssetsLoadingError=__exports.AssetsLoadingError=class AssetsLoadingError extends Error{}
const LazyComponent=__exports.LazyComponent=class LazyComponent extends Component{static template=xml`<t t-component="Component" t-props="componentProps"/>`;static props={Component:String,bundle:String,props:{type:[Object,Function],optional:true},};setup(){onWillStart(async()=>{await loadBundle(this.props.bundle);this.Component=registry.category("lazy_components").get(this.props.Component);});}
get componentProps(){return typeof this.props.props==="function"?this.props.props():this.props.props;}}
const assets=__exports.assets={retries:{count:3,delay:5000,extraDelay:2500,},getBundle(bundleName){const cacheMap=getGlobalBundleCache();if(cacheMap.has(bundleName)){return cacheMap.get(bundleName);}
const url=new URL(`/web/bundle/${bundleName}`,location.origin);for(const[key,value]of Object.entries(session.bundle_params||{})){url.searchParams.set(key,value);}
const promise=fetch(url).then(async(response)=>{const cssLibs=[];const jsLibs=[];if(!response.bodyUsed){const result=await response.json();for(const{src,type}of Object.values(result)){if(type==="link"&&src){cssLibs.push(src);}else if(type==="script"&&src){jsLibs.push(src);}}}
return{cssLibs,jsLibs};}).catch((reason)=>{cacheMap.delete(bundleName);throw new AssetsLoadingError(`The loading of ${url} failed`,{cause:reason});});cacheMap.set(bundleName,promise);return promise;},loadBundle(bundleName,{targetDoc=document,css=true,js=true}={}){if(typeof bundleName!=="string"){throw new Error(`loadBundle(bundleName:string) accepts only bundleName argument as a string ! Not ${JSON.stringify(
bundleName
)} as ${typeof bundleName}`);}
return getBundle(bundleName).then(({cssLibs,jsLibs})=>{const promises=[];if(css&&cssLibs){promises.push(...cssLibs.map((url)=>assets.loadCSS(url,{targetDoc})));}
if(js&&jsLibs){promises.push(...jsLibs.map((url)=>assets.loadJS(url,{targetDoc})));}
return Promise.all(promises);});},loadCSS(url,{retryCount=0,targetDoc=document}={}){const cacheMap=getAssetCache(targetDoc);if(cacheMap.has(url)){return cacheMap.get(url);}
const linkEl=targetDoc.createElement("link");linkEl.setAttribute("href",url);linkEl.type="text/css";linkEl.rel="stylesheet";const promise=new Promise((resolve,reject)=>onLoadAndError(linkEl,resolve,async(error)=>{cacheMap.delete(url);if(retryCount<assets.retries.count){const delay=assets.retries.delay+assets.retries.extraDelay*retryCount;await new Promise((res)=>setTimeout(res,delay));linkEl.remove();loadCSS(url,{retryCount:retryCount+1,targetDoc}).then(resolve).catch((reason)=>{cacheMap.delete(url);reject(reason);});}else{reject(new AssetsLoadingError(`The loading of ${url} failed`,{cause:error}));}}));cacheMap.set(url,promise);targetDoc.head.appendChild(linkEl);return promise;},loadJS(url,{targetDoc=document}={}){const cacheMap=getAssetCache(targetDoc);if(cacheMap.has(url)){return cacheMap.get(url);}
const scriptEl=targetDoc.createElement("script");scriptEl.setAttribute("src",url);scriptEl.type=url.includes("web/static/lib/pdfjs/")?"module":"text/javascript";const promise=new Promise((resolve,reject)=>onLoadAndError(scriptEl,resolve,(error)=>{cacheMap.delete(url);reject(new AssetsLoadingError(`The loading of ${url} failed`,{cause:error}));}));cacheMap.set(url,promise);targetDoc.head.appendChild(scriptEl);return promise;},};return __exports;});;
/* /web/static/src/core/autocomplete/autocomplete.js */
odoo.define('@web/core/autocomplete/autocomplete',['@web/core/utils/concurrency','@web/core/utils/hooks','@web/core/utils/scrolling','@web/core/utils/timing','@web/core/hotkeys/hotkey_service','@web/core/position/position_hook','@odoo/owl','@web/core/utils/classname'],function(require){'use strict';let __exports={};const{Deferred}=require("@web/core/utils/concurrency");const{useAutofocus,useForwardRefToParent,useService}=require("@web/core/utils/hooks");const{isScrollableY,scrollTo}=require("@web/core/utils/scrolling");const{useDebounced}=require("@web/core/utils/timing");const{getActiveHotkey}=require("@web/core/hotkeys/hotkey_service");const{usePosition}=require("@web/core/position/position_hook");const{Component,onWillUpdateProps,useExternalListener,useRef,useState}=require("@odoo/owl");const{mergeClasses}=require("@web/core/utils/classname");const AutoComplete=__exports.AutoComplete=class AutoComplete extends Component{static template="web.AutoComplete";static props={value:{type:String,optional:true},id:{type:String,optional:true},sources:{type:Array,element:{type:Object,shape:{placeholder:{type:String,optional:true},options:[Array,Function],optionSlot:{type:String,optional:true},},},},placeholder:{type:String,optional:true},title:{type:String,optional:true},autocomplete:{type:String,optional:true},autoSelect:{type:Boolean,optional:true},resetOnSelect:{type:Boolean,optional:true},onInput:{type:Function,optional:true},onCancel:{type:Function,optional:true},onChange:{type:Function,optional:true},onBlur:{type:Function,optional:true},onFocus:{type:Function,optional:true},searchOnInputClick:{type:Boolean,optional:true},input:{type:Function,optional:true},inputDebounceDelay:{type:Number,optional:true},dropdown:{type:Boolean,optional:true},autofocus:{type:Boolean,optional:true},class:{type:String,optional:true},slots:{type:Object,optional:true},menuPositionOptions:{type:Object,optional:true},menuCssClass:{type:[String,Array,Object],optional:true},selectOnBlur:{type:Boolean,optional:true},};static defaultProps={value:"",placeholder:"",title:"",autocomplete:"new-password",autoSelect:false,dropdown:true,onInput:()=>{},onCancel:()=>{},onChange:()=>{},onBlur:()=>{},onFocus:()=>{},searchOnInputClick:true,inputDebounceDelay:250,menuPositionOptions:{},menuCssClass:{},};get timeout(){return this.props.inputDebounceDelay;}
setup(){this.nextSourceId=0;this.nextOptionId=0;this.sources=[];this.inEdition=false;this.mouseSelectionActive=false;this.isOptionSelected=false;this.state=useState({navigationRev:0,optionsRev:0,open:false,activeSourceOption:null,value:this.props.value,});this.inputRef=useForwardRefToParent("input");this.listRef=useRef("sourcesList");if(this.props.autofocus){useAutofocus({refName:"input"});}
this.root=useRef("root");this.debouncedProcessInput=useDebounced(async()=>{const currentPromise=this.pendingPromise;this.pendingPromise=null;this.props.onInput({inputValue:this.inputRef.el.value,});try{await this.open(true);currentPromise.resolve();}catch{currentPromise.reject();}finally{if(currentPromise===this.loadingPromise){this.loadingPromise=null;}}},this.timeout);useExternalListener(window,"scroll",this.externalClose,true);useExternalListener(window,"pointerdown",this.externalClose,true);useExternalListener(window,"mousemove",()=>(this.mouseSelectionActive=true),true);this.hotkey=useService("hotkey");this.hotkeysToRemove=[];onWillUpdateProps((nextProps)=>{if(this.props.value!==nextProps.value||this.forceValFromProp){this.forceValFromProp=false;if(!this.inEdition){this.state.value=nextProps.value;this.inputRef.el.value=nextProps.value;}}});if(this.props.dropdown){usePosition("sourcesList",()=>this.targetDropdown,this.dropdownOptions);}else{this.open(false);}}
get targetDropdown(){return this.inputRef.el;}
get activeSourceOptionId(){if(!this.isOpened||!this.state.activeSourceOption){return undefined;}
const[sourceIndex,optionIndex]=this.state.activeSourceOption;const source=this.sources[sourceIndex];return`${this.props.id || "autocomplete"}_${sourceIndex}_${
source.isLoading ? "loading" : optionIndex
}`;}
get dropdownOptions(){return{position:"bottom-start",...this.props.menuPositionOptions,};}
get isOpened(){return this.state.open;}
get hasOptions(){for(const source of this.sources){if(source.isLoading||source.options.length){return true;}}
return false;}
get activeOption(){if(!this.state.activeSourceOption){return null;}
const[sourceIndex,optionIndex]=this.state.activeSourceOption;return this.sources[sourceIndex].options[optionIndex];}
open(useInput=false){this.state.open=true;return this.loadSources(useInput);}
close(){this.state.open=false;this.state.activeSourceOption=null;this.mouseSelectionActive=false;}
cancel(){if(this.inputRef.el.value.length){if(this.props.autoSelect){this.inputRef.el.value=this.props.value;this.props.onCancel();}}
this.close();}
async loadSources(useInput){this.sources=[];this.state.activeSourceOption=null;const proms=[];for(const pSource of this.props.sources){const source=this.makeSource(pSource);this.sources.push(source);const options=this.loadOptions(pSource.options,useInput?this.inputRef.el.value.trim():"");if(options instanceof Promise){source.isLoading=true;const prom=options.then((options)=>{source.options=options.map((option)=>this.makeOption(option));source.isLoading=false;this.state.optionsRev++;});proms.push(prom);}else{source.options=options.map((option)=>this.makeOption(option));}}
await Promise.all(proms);this.navigate(0);this.scroll();}
get displayOptions(){return!this.props.dropdown||(this.isOpened&&this.hasOptions);}
loadOptions(options,request){if(typeof options==="function"){return options(request);}else{return options;}}
makeOption(option){return{cssClass:"",data:{},...option,id:++this.nextOptionId,unselectable:!option.onSelect,};}
makeSource(source){return{id:++this.nextSourceId,options:[],isLoading:false,placeholder:source.placeholder,optionSlot:source.optionSlot,};}
isActiveSourceOption([sourceIndex,optionIndex]){return(this.state.activeSourceOption&&this.state.activeSourceOption[0]===sourceIndex&&this.state.activeSourceOption[1]===optionIndex);}
selectOption(option){this.inEdition=false;if(option.unselectable){return;}
if(this.props.resetOnSelect){this.inputRef.el.value="";}
this.isOptionSelected=true;this.forceValFromProp=true;option.onSelect();this.close();}
navigate(direction){let step=Math.sign(direction);if(!step){this.state.activeSourceOption=null;step=1;}else{this.state.navigationRev++;}
do{if(this.state.activeSourceOption){let[sourceIndex,optionIndex]=this.state.activeSourceOption;let source=this.sources[sourceIndex];optionIndex+=step;if(0>optionIndex||optionIndex>=source.options.length){sourceIndex+=step;source=this.sources[sourceIndex];while(source&&source.isLoading){sourceIndex+=step;source=this.sources[sourceIndex];}
if(source){optionIndex=step<0?source.options.length-1:0;}}
this.state.activeSourceOption=source?[sourceIndex,optionIndex]:null;}else{let sourceIndex=step<0?this.sources.length-1:0;let source=this.sources[sourceIndex];while(source&&source.isLoading){sourceIndex+=step;source=this.sources[sourceIndex];}
if(source){const optionIndex=step<0?source.options.length-1:0;if(optionIndex<source.options.length){this.state.activeSourceOption=[sourceIndex,optionIndex];}}}}while(this.activeOption?.unselectable);}
onInputBlur(){if(this.ignoreBlur){this.ignoreBlur=false;return;}
if(this.props.selectOnBlur&&!this.isOptionSelected&&this.sources[0]){const firstOption=this.sources[0].options[0];if(firstOption){this.state.activeSourceOption=firstOption.unselectable?null:[0,0];this.selectOption(this.activeOption);}}
this.props.onBlur({inputValue:this.inputRef.el.value,});this.inEdition=false;this.isOptionSelected=false;}
onInputClick(){if(!this.isOpened&&this.props.searchOnInputClick){this.open(this.inputRef.el.value.trim()!==this.props.value.trim());}else{this.close();}}
onInputChange(ev){if(this.ignoreBlur){ev.stopImmediatePropagation();}
this.props.onChange({inputValue:this.inputRef.el.value,isOptionSelected:this.ignoreBlur,});}
async onInput(){this.inEdition=true;this.pendingPromise=this.pendingPromise||new Deferred();this.loadingPromise=this.pendingPromise;this.debouncedProcessInput();}
onInputFocus(ev){this.inputRef.el.setSelectionRange(0,this.inputRef.el.value.length);this.props.onFocus(ev);}
get autoCompleteRootClass(){let classList="";if(this.props.class){classList+=this.props.class;}
if(this.props.dropdown){classList+=" dropdown";}
return classList;}
get ulDropdownClass(){return mergeClasses(this.props.menuCssClass,{"dropdown-menu ui-autocomplete":this.props.dropdown,"list-group":!this.props.dropdown,});}
async onInputKeydown(ev){const hotkey=getActiveHotkey(ev);const isSelectKey=hotkey==="enter"||hotkey==="tab";if(this.loadingPromise&&isSelectKey){if(hotkey==="enter"){ev.stopPropagation();ev.preventDefault();}
await this.loadingPromise;}
switch(hotkey){case"enter":if(!this.isOpened||!this.state.activeSourceOption){return;}
this.selectOption(this.activeOption);break;case"escape":if(!this.isOpened){return;}
this.cancel();break;case"tab":case"shift+tab":if(!this.isOpened){return;}
if(this.props.autoSelect&&this.state.activeSourceOption&&(this.state.navigationRev>0||this.inputRef.el.value.length>0)){this.selectOption(this.activeOption);}
this.close();return;case"arrowup":this.navigate(-1);if(!this.isOpened){this.open(true);}
this.scroll();break;case"arrowdown":this.navigate(+1);if(!this.isOpened){this.open(true);}
this.scroll();break;default:return;}
ev.stopPropagation();ev.preventDefault();}
onOptionMouseEnter(indices){if(!this.mouseSelectionActive){return;}
const[sourceIndex,optionIndex]=indices;if(this.sources[sourceIndex].options[optionIndex]?.unselectable){this.state.activeSourceOption=null;}else{this.state.activeSourceOption=indices;}}
onOptionMouseLeave(){this.state.activeSourceOption=null;}
onOptionClick(option){this.selectOption(option);this.inputRef.el.focus();}
onOptionPointerDown(option,ev){this.ignoreBlur=true;if(option.unselectable){ev.preventDefault();}}
externalClose(ev){if(this.isOpened&&!this.root.el.contains(ev.target)){this.cancel();}}
scroll(){if(!this.activeSourceOptionId){return;}
if(isScrollableY(this.listRef.el)){const element=this.listRef.el.querySelector(`#${this.activeSourceOptionId}`);if(element){scrollTo(element);}}}}
return __exports;});;
/* /web/static/src/core/barcode/ZXingBarcodeDetector.js */
odoo.define('@web/core/barcode/ZXingBarcodeDetector',[],function(require){'use strict';let __exports={};__exports.buildZXingBarcodeDetector=buildZXingBarcodeDetector;function buildZXingBarcodeDetector(ZXing){const ZXingFormats=new Map([["aztec",ZXing.BarcodeFormat.AZTEC],["code_39",ZXing.BarcodeFormat.CODE_39],["code_128",ZXing.BarcodeFormat.CODE_128],["data_matrix",ZXing.BarcodeFormat.DATA_MATRIX],["ean_8",ZXing.BarcodeFormat.EAN_8],["ean_13",ZXing.BarcodeFormat.EAN_13],["itf",ZXing.BarcodeFormat.ITF],["pdf417",ZXing.BarcodeFormat.PDF_417],["qr_code",ZXing.BarcodeFormat.QR_CODE],["upc_a",ZXing.BarcodeFormat.UPC_A],["upc_e",ZXing.BarcodeFormat.UPC_E],]);const allSupportedFormats=Array.from(ZXingFormats.keys());class ZXingBarcodeDetector{constructor(opts={}){const formats=opts.formats||allSupportedFormats;const hints=new Map([[ZXing.DecodeHintType.POSSIBLE_FORMATS,formats.map((format)=>ZXingFormats.get(format)),],[ZXing.DecodeHintType.TRY_HARDER,true],]);this.reader=new ZXing.MultiFormatReader();this.reader.setHints(hints);}
async detect(video){if(!(video instanceof HTMLVideoElement)){throw new DOMException("imageDataFrom() requires an HTMLVideoElement","InvalidArgumentError");}
if(!isVideoElementReady(video)){throw new DOMException("HTMLVideoElement is not ready","InvalidStateError");}
const canvas=document.createElement("canvas");let barcodeArea;if(this.cropArea&&(this.cropArea.x||this.cropArea.y)){barcodeArea=this.cropArea;}else{barcodeArea={x:0,y:0,width:video.videoWidth,height:video.videoHeight,};}
canvas.width=barcodeArea.width;canvas.height=barcodeArea.height;const ctx=canvas.getContext("2d");ctx.drawImage(video,barcodeArea.x,barcodeArea.y,barcodeArea.width,barcodeArea.height,0,0,barcodeArea.width,barcodeArea.height);const luminanceSource=new ZXing.HTMLCanvasElementLuminanceSource(canvas);const binaryBitmap=new ZXing.BinaryBitmap(new ZXing.HybridBinarizer(luminanceSource));try{const result=this.reader.decodeWithState(binaryBitmap);const{resultPoints}=result;const boundingBox=DOMRectReadOnly.fromRect({x:resultPoints[0].x,y:resultPoints[0].y,height:Math.max(1,Math.abs(resultPoints[1].y-resultPoints[0].y)),width:Math.max(1,Math.abs(resultPoints[1].x-resultPoints[0].x)),});const cornerPoints=resultPoints;const format=Array.from(ZXingFormats).find(([k,val])=>val===result.getBarcodeFormat());const rawValue=result.getText();return[{boundingBox,cornerPoints,format,rawValue,},];}catch(err){if(err.name==="NotFoundException"){return[];}
throw err;}}
setCropArea(cropArea){this.cropArea=cropArea;}}
ZXingBarcodeDetector.getSupportedFormats=async()=>allSupportedFormats;return ZXingBarcodeDetector;}
const HAVE_NOTHING=0;const HAVE_METADATA=1;__exports.isVideoElementReady=isVideoElementReady;function isVideoElementReady(video){return![HAVE_NOTHING,HAVE_METADATA].includes(video.readyState);}
return __exports;});;
/* /web/static/src/core/barcode/barcode_dialog.js */
odoo.define('@web/core/barcode/barcode_dialog',['@web/core/l10n/translation','@web/core/dialog/dialog','@odoo/owl','@web/core/barcode/barcode_video_scanner'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{Dialog}=require("@web/core/dialog/dialog");const{Component,useState}=require("@odoo/owl");const{BarcodeVideoScanner,isBarcodeScannerSupported}=require("@web/core/barcode/barcode_video_scanner");const BarcodeDialog=__exports.BarcodeDialog=class BarcodeDialog extends Component{static template="web.BarcodeDialog";static components={BarcodeVideoScanner,Dialog,};static props=["facingMode","close","onResult","onError"];setup(){this.state=useState({barcodeScannerSupported:isBarcodeScannerSupported(),errorMessage:_t("Check your browser permissions"),});}
onResult(result){this.props.close();this.props.onResult(result);}
onError(error){this.state.barcodeScannerSupported=false;this.state.errorMessage=error.message;}}
__exports.scanBarcode=scanBarcode;async function scanBarcode(env,facingMode="environment"){let res;let rej;const promise=new Promise((resolve,reject)=>{res=resolve;rej=reject;});env.services.dialog.add(BarcodeDialog,{facingMode,onResult:(result)=>res(result),onError:(error)=>rej(error),});return promise;}
return __exports;});;
/* /web/static/src/core/barcode/barcode_video_scanner.js */
odoo.define('@web/core/barcode/barcode_video_scanner',['@web/core/browser/browser','@web/core/utils/concurrency','@web/core/assets','@web/core/barcode/ZXingBarcodeDetector','@web/core/barcode/crop_overlay','@odoo/owl','@web/core/l10n/translation','@web/core/utils/objects'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{delay}=require("@web/core/utils/concurrency");const{loadJS}=require("@web/core/assets");const{isVideoElementReady,buildZXingBarcodeDetector}=require("@web/core/barcode/ZXingBarcodeDetector");const{CropOverlay}=require("@web/core/barcode/crop_overlay");const{Component,onMounted,onWillStart,onWillUnmount,status,useRef,useState}=require("@odoo/owl");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{pick}=require("@web/core/utils/objects");const BarcodeVideoScanner=__exports.BarcodeVideoScanner=class BarcodeVideoScanner extends Component{static template="web.BarcodeVideoScanner";static components={CropOverlay,};static props={cssClass:{type:String,optional:true},facingMode:{type:String,validate:(fm)=>["environment","left","right","user"].includes(fm),},close:{type:Function,optional:true},onReady:{type:Function,optional:true},onResult:Function,onError:Function,placeholder:{type:String,optional:true},delayBetweenScan:{type:Number,optional:true},};static defaultProps={cssClass:"w-100 h-100",};setup(){this.videoPreviewRef=useRef("videoPreview");this.detectorTimeout=null;this.stream=null;this.detector=null;this.overlayInfo={};this.zoomRatio=1;this.scanPaused=false;this.state=useState({isReady:false,});onWillStart(async()=>{let DetectorClass;if("BarcodeDetector"in window){DetectorClass=BarcodeDetector;}else{await loadJS("/web/static/lib/zxing-library/zxing-library.js");DetectorClass=buildZXingBarcodeDetector(window.ZXing);}
const formats=await DetectorClass.getSupportedFormats();this.detector=new DetectorClass({formats});});onMounted(async()=>{const constraints={video:{facingMode:this.props.facingMode},audio:false,};try{this.stream=await browser.navigator.mediaDevices.getUserMedia(constraints);}catch(err){const errors={NotFoundError:_t("No device can be found."),NotAllowedError:_t("Odoo needs your authorization first."),};const errorMessage=_t("Could not start scanning. %(message)s",{message:errors[err.name]||err.message,});this.props.onError(new Error(errorMessage));return;}
if(!this.videoPreviewRef.el){this.cleanStreamAndTimeout();const errorMessage=_t("Barcode Video Scanner could not be mounted properly.");this.props.onError(new Error(errorMessage));return;}
this.videoPreviewRef.el.srcObject=this.stream;const ready=await this.isVideoReady();if(!ready){return;}
const{height,width}=getComputedStyle(this.videoPreviewRef.el);const divWidth=width.slice(0,-2);const divHeight=height.slice(0,-2);const tracks=this.stream.getVideoTracks();if(tracks.length){const[track]=tracks;const settings=track.getSettings();this.zoomRatio=Math.min(divWidth/settings.width,divHeight/settings.height);this.addZoomSlider(track,settings);}
this.detectorTimeout=setTimeout(this.detectCode.bind(this),100);});onWillUnmount(()=>this.cleanStreamAndTimeout());}
cleanStreamAndTimeout(){clearTimeout(this.detectorTimeout);this.detectorTimeout=null;if(this.stream){this.stream.getTracks().forEach((track)=>track.stop());this.stream=null;}}
isZXingBarcodeDetector(){return this.detector&&this.detector.__proto__.constructor.name==="ZXingBarcodeDetector";}
async isVideoReady(){while(!isVideoElementReady(this.videoPreviewRef.el)){await delay(10);if(status(this)==="destroyed"){return false;}}
this.state.isReady=true;if(this.props.onReady){this.props.onReady();}
return true;}
onResize(overlayInfo){this.overlayInfo=overlayInfo;if(this.isZXingBarcodeDetector()){this.detector.setCropArea(this.adaptValuesWithRatio(this.overlayInfo,true));}}
async detectCode(){let barcodeDetected=false;let codes=[];try{codes=await this.detector.detect(this.videoPreviewRef.el);}catch(err){this.props.onError(err);}
for(const code of codes){if(!this.isZXingBarcodeDetector()&&this.overlayInfo.x!==undefined&&this.overlayInfo.y!==undefined){const{x,y,width,height}=this.adaptValuesWithRatio(code.boundingBox);if(x<this.overlayInfo.x||x+width>this.overlayInfo.x+this.overlayInfo.width||y<this.overlayInfo.y||y+height>this.overlayInfo.y+this.overlayInfo.height){continue;}}
barcodeDetected=true;this.barcodeDetected(code.rawValue);break;}
if(this.stream&&(!barcodeDetected||!this.props.delayBetweenScan)){this.detectorTimeout=setTimeout(this.detectCode.bind(this),100);}}
barcodeDetected(barcode){if(this.props.delayBetweenScan&&!this.scanPaused){this.scanPaused=true;this.detectorTimeout=setTimeout(()=>{this.scanPaused=false;this.detectorTimeout=setTimeout(this.detectCode.bind(this),100);},this.props.delayBetweenScan);}
this.props.onResult(barcode);}
adaptValuesWithRatio(domRect,dividerRatio=false){const newObject=pick(domRect,"x","y","width","height");for(const key of Object.keys(newObject)){if(dividerRatio){newObject[key]/=this.zoomRatio;}else{newObject[key]*=this.zoomRatio;}}
return newObject;}
addZoomSlider(track,settings){const zoom=track.getCapabilities().zoom;if(zoom?.min!==undefined&&zoom?.max!==undefined){const inputElement=document.createElement("input");inputElement.type="range";inputElement.min=zoom.min;inputElement.max=zoom.max;inputElement.step=zoom.step||1;inputElement.value=settings.zoom;inputElement.classList.add("align-self-end","m-5","z-1");inputElement.addEventListener("input",async(event)=>{await track?.applyConstraints({advanced:[{zoom:inputElement.value}]});});this.videoPreviewRef.el.parentElement.appendChild(inputElement);}}}
__exports.isBarcodeScannerSupported=isBarcodeScannerSupported;function isBarcodeScannerSupported(){return Boolean(browser.navigator.mediaDevices&&browser.navigator.mediaDevices.getUserMedia);}
return __exports;});;
/* /web/static/src/core/barcode/crop_overlay.js */
odoo.define('@web/core/barcode/crop_overlay',['@odoo/owl','@web/core/browser/browser','@web/core/browser/feature_detection','@web/core/utils/numbers'],function(require){'use strict';let __exports={};const{Component,useRef,onPatched}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{isIOS}=require("@web/core/browser/feature_detection");const{clamp}=require("@web/core/utils/numbers");const CropOverlay=__exports.CropOverlay=class CropOverlay extends Component{static template="web.CropOverlay";static props={onResize:Function,isReady:Boolean,slots:{type:Object,shape:{default:{},},},};setup(){this.localStorageKey="o-barcode-scanner-overlay";this.cropContainerRef=useRef("crop-container");this.isMoving=false;this.boundaryOverlay={};this.relativePosition={x:0,y:0,};onPatched(()=>{this.setupCropRect();});this.isIOS=isIOS();}
setupCropRect(){if(!this.props.isReady){return;}
this.computeDefaultPoint();this.computeOverlayPosition();this.calculateAndSetTransparentRect();this.executeOnResizeCallback();}
boundPoint(pointValue,boundaryRect){return{x:clamp(pointValue.x,boundaryRect.left,boundaryRect.left+boundaryRect.width),y:clamp(pointValue.y,boundaryRect.top,boundaryRect.top+boundaryRect.height),};}
calculateAndSetTransparentRect(){const cropTransparentRect=this.getTransparentRec(this.relativePosition,this.boundaryOverlay);this.setCropValue(cropTransparentRect,this.relativePosition);}
computeOverlayPosition(){const cropOverlayElement=this.cropContainerRef.el.querySelector(".o_crop_overlay");this.boundaryOverlay=cropOverlayElement.getBoundingClientRect();}
executeOnResizeCallback(){const transparentRec=this.getTransparentRec(this.relativePosition,this.boundaryOverlay);browser.localStorage.setItem(this.localStorageKey,JSON.stringify(transparentRec));this.props.onResize({...transparentRec,width:this.boundaryOverlay.width-2*transparentRec.x,height:this.boundaryOverlay.height-2*transparentRec.y,});}
computeDefaultPoint(){const firstChildComputedStyle=getComputedStyle(this.cropContainerRef.el.firstChild);const elementWidth=firstChildComputedStyle.width.slice(0,-2);const elementHeight=firstChildComputedStyle.height.slice(0,-2);const stringSavedPoint=browser.localStorage.getItem(this.localStorageKey);if(stringSavedPoint){const savedPoint=JSON.parse(stringSavedPoint);this.relativePosition={x:clamp(savedPoint.x,0,elementWidth),y:clamp(savedPoint.y,0,elementHeight),};}else{const stepWidth=elementWidth/10;const width=stepWidth*8;const height=width/4;const startY=elementHeight/2-height/2;this.relativePosition={x:stepWidth+width,y:startY+height,};}}
getTransparentRec(point,rect){const middleX=rect.width/2;const middleY=rect.height/2;const newDeltaX=Math.abs(point.x-middleX);const newDeltaY=Math.abs(point.y-middleY);return{x:middleX-newDeltaX,y:middleY-newDeltaY,};}
setCropValue(point,iconPoint){if(!iconPoint){iconPoint=point;}
this.cropContainerRef.el.style.setProperty("--o-crop-x",`${point.x}px`);this.cropContainerRef.el.style.setProperty("--o-crop-y",`${point.y}px`);this.cropContainerRef.el.style.setProperty("--o-crop-icon-x",`${iconPoint.x}px`);this.cropContainerRef.el.style.setProperty("--o-crop-icon-y",`${iconPoint.y}px`);}
pointerDown(event){if(event.target.matches("input")){return;}
event.preventDefault();if(event.target.matches(".o_crop_icon")){this.computeOverlayPosition();this.isMoving=true;}}
pointerMove(event){if(!this.isMoving){return;}
let eventPosition;if(event.touches&&event.touches.length){eventPosition=event.touches[0];}else{eventPosition=event;}
const{clientX,clientY}=eventPosition;const restrictedPosition=this.boundPoint({x:clientX,y:clientY,},this.boundaryOverlay);this.relativePosition={x:restrictedPosition.x-this.boundaryOverlay.left,y:restrictedPosition.y-this.boundaryOverlay.top,};this.calculateAndSetTransparentRect(this.relativePosition);}
pointerUp(event){this.isMoving=false;this.executeOnResizeCallback();}}
return __exports;});;
/* /web/static/src/core/bottom_sheet/bottom_sheet.js */
odoo.define('@web/core/bottom_sheet/bottom_sheet',['@odoo/owl','@web/core/hotkeys/hotkey_hook','@web/core/utils/hooks','@web/core/utils/timing','@web/core/utils/scrolling','@web/core/utils/dvu','@web/core/utils/numbers','@web/core/browser/browser'],function(require){'use strict';let __exports={};const{Component,useState,useRef,onMounted,useExternalListener}=require("@odoo/owl");const{useHotkey}=require("@web/core/hotkeys/hotkey_hook");const{useForwardRefToParent}=require("@web/core/utils/hooks");const{useThrottleForAnimation}=require("@web/core/utils/timing");const{compensateScrollbar}=require("@web/core/utils/scrolling");const{getViewportDimensions,useViewportChange}=require("@web/core/utils/dvu");const{clamp}=require("@web/core/utils/numbers");const{browser}=require("@web/core/browser/browser");const BottomSheet=__exports.BottomSheet=class BottomSheet extends Component{static template="web.BottomSheet";static defaultProps={class:"",};static props={component:{type:Function},componentProps:{optional:true,type:Object},close:{type:Function},class:{optional:true},role:{optional:true,type:String},ref:{optional:true,type:Function},slots:{optional:true,type:Object},};setup(){this.maxHeightPercent=90;this.state=useState({isPositionedReady:false,isSnappingEnabled:false,isDismissing:false,progress:0,});this.measurements={viewportHeight:0,naturalHeight:0,maxHeight:0,dismissThreshold:0,};useForwardRefToParent("ref");this.containerRef=useRef("container");this.scrollRailRef=useRef("scrollRail");this.sheetRef=useRef("sheet");this.sheetBodyRef=useRef("ref");this.throttledOnScroll=useThrottleForAnimation(this.onScroll.bind(this));useViewportChange(()=>{if(this.state.isPositionedReady&&!this.state.isDismissing){this.updateDimensions();}});useHotkey("escape",()=>this.slideOut());window.history.pushState({bottomSheet:true},"");this.handlePopState=()=>{if(this.state.isPositionedReady&&!this.state.isDismissing){window.history.pushState({bottomSheet:true},"");this.slideOut();}};useExternalListener(window,"popstate",this.handlePopState);onMounted(()=>{const isReduced=browser.matchMedia(`(prefers-reduced-motion: reduce)`)===true||browser.matchMedia(`(prefers-reduced-motion: reduce)`).matches===true;this.prefersReducedMotion=isReduced||getComputedStyle(this.containerRef.el).animationName==="none";this.initializeSheet();compensateScrollbar(this.scrollRailRef.el,true,true,"padding-right");});}
initializeSheet(){if(!this.containerRef.el||!this.scrollRailRef.el||!this.sheetRef.el){return;}
this.measureDimensions();this.applyDimensions();this.positionSheet();this.setupEventHandlers();this.state.isPositionedReady=true;if(this.prefersReducedMotion){this.state.isSnappingEnabled=true;}else{this.sheetRef.el?.addEventListener("animationend",()=>(this.state.isSnappingEnabled=true),{once:true,});this.sheetRef.el?.addEventListener("animationcancel",()=>(this.state.isSnappingEnabled=true),{once:true,});}}
updateDimensions(){this.state.isSnappingEnabled=false;this.measureDimensions();this.applyDimensions();const scrollTop=this.scrollRailRef.el.scrollTop;this.updateProgressValue(scrollTop);}
measureDimensions(){const viewportHeight=getViewportDimensions().height;const maxHeightPx=(this.maxHeightPercent/100)*viewportHeight;const sheet=this.sheetRef.el;sheet.style.removeProperty("min-height");sheet.style.removeProperty("height");const naturalHeight=sheet.offsetHeight;const initialHeightPx=Math.min(naturalHeight,maxHeightPx);this.measurements={viewportHeight,naturalHeight,initialHeight:initialHeightPx,maxHeight:maxHeightPx,dismissThreshold:Math.min(initialHeightPx*0.3,100),};}
applyDimensions(){const rail=this.scrollRailRef.el;const heightPercent=Math.min((this.measurements.initialHeight/this.measurements.viewportHeight)*100,this.maxHeightPercent);rail.style.setProperty("--sheet-height",`${heightPercent}dvh`);rail.style.setProperty("--sheet-max-height",`${this.measurements.viewportHeight}px`);rail.style.setProperty("--dismiss-height",`${this.measurements.initialHeight || 0}px`);}
positionSheet(){const scrollRail=this.scrollRailRef.el;const bodyContent=this.sheetBodyRef.el;const scrollValue=this.measurements.maxHeight;if(bodyContent){bodyContent.style.overflowY="auto";}
scrollRail.scrollTop=scrollValue||0;scrollRail.style.containerType="scroll-state size";}
setupEventHandlers(){const scrollRail=this.scrollRailRef.el;scrollRail.addEventListener("scroll",this.throttledOnScroll);}
onScroll(){if(!this.scrollRailRef.el){return;}
const scrollTop=this.scrollRailRef.el.scrollTop;this.updateProgressValue(scrollTop);if(scrollTop<this.measurements.dismissThreshold){this.slideOut();}}
updateProgressValue(scrollTop){const initialPosition=this.measurements.naturalHeight;const progress=clamp(scrollTop/initialPosition,0,1);if(Math.abs(this.state.progress-progress)>0.01){this.state.progress=progress;}}
slideOut(){if(this.state.isDismissing){return;}
if(this.prefersReducedMotion){this.props.close?.();}else{this.sheetRef.el?.addEventListener("animationend",()=>this.props.close?.(),{once:true,});this.sheetRef.el?.addEventListener("animationcancel",()=>this.props.close?.(),{once:true,});}
this.state.isDismissing=true;this.state.isSnappingEnabled=false;}
close(){this.slideOut();}
back(){if(this.props.onBack){this.props.onBack();}else{this.slideOut();}}}
return __exports;});;
/* /web/static/src/core/bottom_sheet/bottom_sheet_service.js */
odoo.define('@web/core/bottom_sheet/bottom_sheet_service',['@odoo/owl','@web/core/bottom_sheet/bottom_sheet','@web/core/registry'],function(require){'use strict';let __exports={};const{markRaw}=require("@odoo/owl");const{BottomSheet}=require("@web/core/bottom_sheet/bottom_sheet");const{registry}=require("@web/core/registry");const popoverService=__exports.popoverService={dependencies:["overlay"],start(_,{overlay}){let bottomSheetCount=0;const add=(target,component,props={},options={})=>{function removeAndUpdateCount(){_remove();bottomSheetCount--;if(bottomSheetCount===0){document.body.classList.remove("bottom-sheet-open");}else if(bottomSheetCount===1){document.body.classList.remove("bottom-sheet-open-multiple");}}
const _remove=overlay.add(BottomSheet,{close:removeAndUpdateCount,component,componentProps:markRaw(props),ref:options.ref,class:options.class,role:options.role,},{env:options.env,onRemove:options.onClose,rootId:target.getRootNode()?.host?.id,});bottomSheetCount++;if(bottomSheetCount===1){document.body.classList.add("bottom-sheet-open");}else if(bottomSheetCount>1){document.body.classList.add("bottom-sheet-open-multiple");}
return removeAndUpdateCount;};return{add};},};registry.category("services").add("bottom_sheet",popoverService);return __exports;});;
/* /web/static/src/core/browser/browser.js */
odoo.define('@web/core/browser/browser',[],function(require){'use strict';let __exports={};let sessionStorage;let localStorage;try{sessionStorage=window.sessionStorage;localStorage=window.localStorage;localStorage.setItem("__localStorage__","true");localStorage.removeItem("__localStorage__");}catch{localStorage=makeRAMLocalStorage();sessionStorage=makeRAMLocalStorage();}
const browser=__exports.browser={addEventListener:window.addEventListener.bind(window),dispatchEvent:window.dispatchEvent.bind(window),AnalyserNode:window.AnalyserNode,Audio:window.Audio,AudioBufferSourceNode:window.AudioBufferSourceNode,AudioContext:window.AudioContext,AudioWorkletNode:window.AudioWorkletNode,BeforeInstallPromptEvent:window.BeforeInstallPromptEvent?.bind(window),GainNode:window.GainNode,MediaStreamAudioSourceNode:window.MediaStreamAudioSourceNode,removeEventListener:window.removeEventListener.bind(window),setTimeout:window.setTimeout.bind(window),clearTimeout:window.clearTimeout.bind(window),setInterval:window.setInterval.bind(window),clearInterval:window.clearInterval.bind(window),performance:window.performance,requestAnimationFrame:window.requestAnimationFrame.bind(window),cancelAnimationFrame:window.cancelAnimationFrame.bind(window),console:window.console,history:window.history,matchMedia:window.matchMedia.bind(window),navigator,Notification:window.Notification,open:window.open.bind(window),SharedWorker:window.SharedWorker,Worker:window.Worker,XMLHttpRequest:window.XMLHttpRequest,localStorage,sessionStorage,fetch:window.fetch.bind(window),innerHeight:window.innerHeight,innerWidth:window.innerWidth,ontouchstart:window.ontouchstart,BroadcastChannel:window.BroadcastChannel,visualViewport:window.visualViewport,};Object.defineProperty(browser,"location",{set(val){window.location=val;},get(){return window.location;},configurable:true,});Object.defineProperty(browser,"innerHeight",{get:()=>window.innerHeight,configurable:true,});Object.defineProperty(browser,"innerWidth",{get:()=>window.innerWidth,configurable:true,});__exports.makeRAMLocalStorage=makeRAMLocalStorage;function makeRAMLocalStorage(){let store={};return{setItem(key,value){const newValue=String(value);store[key]=newValue;window.dispatchEvent(new StorageEvent("storage",{key,newValue}));},getItem(key){return store[key]??null;},clear(){store={};},removeItem(key){delete store[key];window.dispatchEvent(new StorageEvent("storage",{key,newValue:null}));},get length(){return Object.keys(store).length;},key(){return"";},};}
return __exports;});;
/* /web/static/src/core/browser/feature_detection.js */
odoo.define('@web/core/browser/feature_detection',['@web/core/browser/browser'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");__exports.isBrowserChrome=isBrowserChrome;function isBrowserChrome(){return/Chrome/i.test(browser.navigator.userAgent);}
__exports.isBrowserFirefox=isBrowserFirefox;function isBrowserFirefox(){return/Firefox/i.test(browser.navigator.userAgent);}
__exports.isBrowserMicrosoftEdge=isBrowserMicrosoftEdge;function isBrowserMicrosoftEdge(){return/Edg/i.test(browser.navigator.userAgent);}
__exports.isBrowserSafari=isBrowserSafari;function isBrowserSafari(){return!isBrowserChrome()&&browser.navigator.userAgent?.includes("Safari");}
__exports.isAndroid=isAndroid;function isAndroid(){return/Android/i.test(browser.navigator.userAgent);}
__exports.isIOS=isIOS;function isIOS(){let isIOSPlatform=false;if("platform"in browser.navigator){isIOSPlatform=browser.navigator.platform==="MacIntel";}
return(/(iPad|iPhone|iPod)/i.test(browser.navigator.userAgent)||(isIOSPlatform&&maxTouchPoints()>1));}
__exports.isOtherMobileOS=isOtherMobileOS;function isOtherMobileOS(){return/(webOS|BlackBerry|Windows Phone)/i.test(browser.navigator.userAgent);}
__exports.isMacOS=isMacOS;function isMacOS(){return/Mac/i.test(browser.navigator.userAgent);}
__exports.isMobileOS=isMobileOS;function isMobileOS(){return isAndroid()||isIOS()||isOtherMobileOS();}
__exports.isIosApp=isIosApp;function isIosApp(){return/OdooMobile \(iOS\)/i.test(browser.navigator.userAgent);}
__exports.isAndroidApp=isAndroidApp;function isAndroidApp(){return/OdooMobile.+Android/i.test(browser.navigator.userAgent);}
__exports.isDisplayStandalone=isDisplayStandalone;function isDisplayStandalone(){return browser.matchMedia("(display-mode: standalone)").matches;}
__exports.hasTouch=hasTouch;function hasTouch(){return browser.ontouchstart!==undefined||browser.matchMedia("(pointer:coarse)").matches;}
__exports.maxTouchPoints=maxTouchPoints;function maxTouchPoints(){return browser.navigator.maxTouchPoints||1;}
__exports.isVirtualKeyboardSupported=isVirtualKeyboardSupported;function isVirtualKeyboardSupported(){return"virtualKeyboard"in browser.navigator;}
return __exports;});;
/* /web/static/src/core/browser/router.js */
odoo.define('@web/core/browser/router',['@odoo/owl','@web/core/utils/objects','@web/core/utils/urls','@web/core/browser/browser','@web/core/browser/feature_detection','@web/core/utils/arrays','@web/core/utils/strings'],function(require){'use strict';let __exports={};const{EventBus}=require("@odoo/owl");const{omit,pick}=require("@web/core/utils/objects");const{compareUrls,objectToUrlEncodedString}=require("@web/core/utils/urls");const{browser}=require("@web/core/browser/browser");const{isDisplayStandalone}=require("@web/core/browser/feature_detection");const{slidingWindow}=require("@web/core/utils/arrays");const{isNumeric}=require("@web/core/utils/strings");const PATH_KEYS=__exports.PATH_KEYS=["resId","action","active_id","model"];const routerBus=__exports.routerBus=new EventBus();function isScopedApp(){return browser.location.href.includes("/scoped_app")&&isDisplayStandalone();}
function cast(value){return!value||isNaN(value)?value:Number(value);}
function parseString(str){const parts=str.split("&");const result={};for(const part of parts){const[key,value]=part.split("=");const decoded=decodeURIComponent(value||"");result[key]=cast(decoded);}
return result;}
function computeNextState(values,replace){const nextState=replace?pick(state,..._lockedKeys):{...state};Object.assign(nextState,values);if(nextState.actionStack?.length){Object.assign(nextState.actionStack.at(-1),pick(nextState,...PATH_KEYS));}
return sanitizeSearch(nextState);}
function sanitize(obj,valueToRemove){return Object.fromEntries(Object.entries(obj).filter(([,v])=>v!==valueToRemove).map(([k,v])=>[k,cast(v)]));}
function sanitizeSearch(search){return sanitize(search);}
function sanitizeHash(hash){return sanitize(hash,"");}
__exports.parseHash=parseHash;function parseHash(hash){return hash&&hash!=="#"?parseString(hash.slice(1)):{};}
__exports.parseSearchQuery=parseSearchQuery;function parseSearchQuery(search){return search?parseString(search.slice(1)):{};}
function pathFromActionState(state){const path=[];const{action,model,active_id,resId}=state;if(active_id&&typeof active_id==="number"){path.push(active_id);}
if(action){if(typeof action==="number"||action.includes(".")){path.push(`action-${action}`);}else{path.push(action);}}else if(model){if(model.includes(".")){path.push(model);}else{path.push(`m-${model}`);}}
if(resId&&(typeof resId==="number"||resId==="new")){path.push(resId);}
return path.join("/");}
__exports.startUrl=startUrl;function startUrl(){return isScopedApp()?"scoped_app":"odoo";}
function stateToUrl(state){let path="";const pathKeysToOmit=[..._hiddenKeysFromUrl];const actionStack=(state.actionStack||[state]).map((a)=>({...a}));if(actionStack.at(-1)?.action!=="menu"){for(const[prevAct,currentAct]of slidingWindow(actionStack,2).reverse()){const{action:prevAction,resId:prevResId,active_id:prevActiveId}=prevAct;const{action:currentAction,active_id:currentActiveId}=currentAct;if(currentActiveId===prevResId){delete currentAct.active_id;}
if(prevAction===currentAction&&!prevResId&&currentActiveId===prevActiveId){delete currentAct.action;delete currentAct.active_id;}}
const pathSegments=actionStack.map(pathFromActionState).filter(Boolean);if(pathSegments.length){path=`/${pathSegments.join("/")}`;}}
if(state.active_id&&typeof state.active_id!=="number"){pathKeysToOmit.splice(pathKeysToOmit.indexOf("active_id"),1);}
if(state.resId&&typeof state.resId!=="number"&&state.resId!=="new"){pathKeysToOmit.splice(pathKeysToOmit.indexOf("resId"),1);}
const search=objectToUrlEncodedString(omit(state,...pathKeysToOmit));const start_url=startUrl();return`/${start_url}${path}${search ? `?${search}` : ""}`;}
function urlToState(urlObj){const{pathname,hash,search}=urlObj;const state=parseSearchQuery(search);if(pathname==="/web"){const sanitizedHash=sanitizeHash(parseHash(hash));if(sanitizedHash.id){sanitizedHash.resId=sanitizedHash.id;delete sanitizedHash.id;delete sanitizedHash.view_type;}else if(sanitizedHash.view_type==="form"){sanitizedHash.resId="new";delete sanitizedHash.view_type;}
Object.assign(state,sanitizedHash);const url=browser.location.origin+router.stateToUrl(state);urlObj.href=url;}
const[prefix,...splitPath]=urlObj.pathname.split("/").filter(Boolean);if(["odoo","scoped_app"].includes(prefix)){const actionParts=[...splitPath.entries()].filter(([_,part])=>!isNumeric(part)&&part!=="new");const actions=[];for(const[i,part]of actionParts){const action={};const[left,right]=[splitPath[i-1],splitPath[i+1]];if(isNumeric(left)){action.active_id=parseInt(left);}
if(right==="new"){action.resId="new";}else if(isNumeric(right)){action.resId=parseInt(right);}
if(part.startsWith("action-")){const actionId=part.slice(7);action.action=isNumeric(actionId)?parseInt(actionId):actionId;}else if(part.startsWith("m-")){action.model=part.slice(2);}else if(part.includes(".")){action.model=part;}else{action.action=part;}
if(action.resId&&action.action){actions.push(omit(action,"resId"));}
if(action.action||action.resId||i===splitPath.length-1){actions.push(action);}}
const activeAction=actions.at(-1);if(activeAction){Object.assign(state,activeAction);state.actionStack=actions;}
if(prefix==="scoped_app"&&!isDisplayStandalone()){const url=browser.location.origin+router.stateToUrl(state);urlObj.href=url;}}
return state;}
let state;let pushTimeout;let pushArgs;let _lockedKeys;let _hiddenKeysFromUrl=new Set();__exports.startRouter=startRouter;function startRouter(){const url=new URL(browser.location);state=router.urlToState(url);if(browser.location.pathname==="/web"){browser.history.replaceState(browser.history.state,null,url.href);}
pushTimeout=null;pushArgs={replace:false,reload:false,state:{},};_lockedKeys=new Set(["debug","lang"]);_hiddenKeysFromUrl=new Set([...PATH_KEYS,"actionStack"]);}
browser.addEventListener("popstate",(ev)=>{browser.clearTimeout(pushTimeout);if(!ev.state){browser.history.replaceState({nextState:state},"",browser.location.href);return;}
state=ev.state?.nextState||router.urlToState(new URL(browser.location));if(!ev.state?.skipRouteChange&&!router.skipLoad){routerBus.trigger("ROUTE_CHANGE");}
router.skipLoad=false;});browser.addEventListener("pageshow",(ev)=>{if(ev.persisted){browser.clearTimeout(pushTimeout);routerBus.trigger("ROUTE_CHANGE");}});browser.addEventListener("click",(ev)=>{if(ev.defaultPrevented||ev.target.closest("[contenteditable]")){return;}
const a=ev.target.closest("a");const href=a?.getAttribute("href");if(href&&!href.startsWith("#")){let url;try{url=new URL(a.href);}catch{return;}
if(browser.location.host===url.host&&browser.location.pathname.startsWith("/odoo")&&(["/web","/odoo"].includes(url.pathname)||url.pathname.startsWith("/odoo/"))&&a.target!=="_blank"){ev.preventDefault();state=router.urlToState(url);if(url.pathname.startsWith("/odoo")&&url.hash){browser.history.pushState({},"",url.href);}
new Promise((res)=>setTimeout(res,0)).then(()=>routerBus.trigger("ROUTE_CHANGE"));}}});function makeDebouncedPush(mode){function doPush(){const nextState=computeNextState(pushArgs.state,pushArgs.replace);const url=browser.location.origin+router.stateToUrl(nextState);if(!compareUrls(url+browser.location.hash,browser.location.href)){if(mode==="push"){const originalTitle=document.title;document.title=pushArgs.title;browser.history.pushState({nextState},"",url);document.title=originalTitle;}else{browser.history.replaceState({nextState},"",url);}}else{browser.history.replaceState({nextState},"",browser.location.href);}
state=nextState;if(pushArgs.reload){browser.location.reload();}}
return function pushOrReplaceState(state,options={}){pushArgs.replace||=options.replace;pushArgs.reload||=options.reload;pushArgs.title=document.title;Object.assign(pushArgs.state,state);browser.clearTimeout(pushTimeout);const push=()=>{doPush();pushTimeout=null;pushArgs={replace:false,reload:false,state:{},};};if(options.sync){push();}else{pushTimeout=browser.setTimeout(()=>{push();});}};}
const router=__exports.router={get current(){return state;},stateToUrl,urlToState,pushState:makeDebouncedPush("push"),replaceState:makeDebouncedPush("replace"),cancelPushes:()=>browser.clearTimeout(pushTimeout),addLockedKey:(key)=>_lockedKeys.add(key),hideKeyFromUrl:(key)=>_hiddenKeysFromUrl.add(key),skipLoad:false,};startRouter();__exports.objectToQuery=objectToQuery;function objectToQuery(obj){const query={};Object.entries(obj).forEach(([k,v])=>{query[k]=v?String(v):v;});return query;}
return __exports;});;
/* /web/static/src/core/browser/title_service.js */
odoo.define('@web/core/browser/title_service',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const titleService=__exports.titleService={start(){const titleCounters={};const titleParts={};function getParts(){return Object.assign({},titleParts);}
function setCounters(counters){for(const key in counters){const val=counters[key];if(!val){delete titleCounters[key];}else{titleCounters[key]=val;}}
updateTitle();}
function setParts(parts){for(const key in parts){const val=parts[key];if(!val){delete titleParts[key];}else{titleParts[key]=val;}}
updateTitle();}
function updateTitle(){const counter=Object.values(titleCounters).reduce((acc,count)=>acc+count,0);const name=Object.values(titleParts).join(" - ")||"Odoo";if(!counter){document.title=name;}else{document.title=`(${counter}) ${name}`;}}
return{get current(){return document.title;},getParts,setCounters,setParts,};},};registry.category("services").add("title",titleService);return __exports;});;
/* /web/static/src/core/checkbox/checkbox.js */
odoo.define('@web/core/checkbox/checkbox',['@web/core/hotkeys/hotkey_hook','@odoo/owl'],function(require){'use strict';let __exports={};const{useHotkey}=require("@web/core/hotkeys/hotkey_hook");const{Component,useRef}=require("@odoo/owl");const CheckBox=__exports.CheckBox=class CheckBox extends Component{static template="web.CheckBox";static nextId=1;static defaultProps={onChange:()=>{},};static props={id:{type:true,optional:true,},disabled:{type:Boolean,optional:true,},value:{type:Boolean,optional:true,},slots:{type:Object,optional:true,},onChange:{type:Function,optional:true,},className:{type:String,optional:true,},name:{type:String,optional:true,},indeterminate:{type:Boolean,optional:true,},};setup(){this.id=`checkbox-comp-${CheckBox.nextId++}`;this.rootRef=useRef("root");useHotkey("Enter",({area})=>{const oldValue=area.querySelector("input").checked;this.props.onChange(!oldValue);},{area:()=>this.rootRef.el,bypassEditableProtection:true});}
onClick(ev){if(ev.composedPath().find((el)=>["INPUT","LABEL"].includes(el.tagName))){ev.stopPropagation();return;}
const input=this.rootRef.el.querySelector("input");input.focus();if(!this.props.disabled){ev.stopPropagation();input.checked=!input.checked;this.props.onChange(input.checked);}}
onChange(ev){if(!this.props.disabled){this.props.onChange(ev.target.checked);}}}
return __exports;});;
/* /web/static/src/core/code_editor/code_editor.js */
odoo.define('@web/core/code_editor/code_editor',['@odoo/owl','@web/core/assets'],function(require){'use strict';let __exports={};const{Component,onMounted,onWillStart,useEffect,useRef,useState,status}=require("@odoo/owl");const{loadBundle}=require("@web/core/assets");const CodeEditor=__exports.CodeEditor=class CodeEditor extends Component{static template="web.CodeEditor";static components={};static props={mode:{type:String,optional:true,validate:(mode)=>CodeEditor.MODES.includes(mode),},value:{validate:(v)=>typeof v==="string",optional:true},readonly:{type:Boolean,optional:true},onChange:{type:Function,optional:true},onBlur:{type:Function,optional:true},class:{type:String,optional:true},theme:{type:String,optional:true,validate:(theme)=>CodeEditor.THEMES.includes(theme),},maxLines:{type:Number,optional:true},sessionId:{type:[Number,String],optional:true},initialCursorPosition:{type:Object,optional:true},showLineNumbers:{type:Boolean,optional:true},};static defaultProps={readonly:false,value:"",onChange:()=>{},class:"",theme:"",sessionId:1,showLineNumbers:true,};static MODES=["javascript","xml","qweb","scss","python"];static THEMES=["","monokai"];setup(){this.editorRef=useRef("editorRef");this.state=useState({activeMode:undefined,});onWillStart(async()=>await loadBundle("web.ace_lib"));const sessions={};let ignoredAceChange=false;useEffect((el)=>{if(!el){return;}
const aceEditor=window.ace.edit(el);this.aceEditor=aceEditor;this.aceEditor.setOptions({maxLines:this.props.maxLines,showPrintMargin:false,useWorker:false,});this.aceEditor.$blockScrolling=true;this.aceEditor.on("changeMode",()=>{this.state.activeMode=this.aceEditor.getSession().$modeId.split("/").at(-1);});const session=aceEditor.getSession();if(!sessions[this.props.sessionId]){sessions[this.props.sessionId]=session;}
session.setValue(this.props.value);session.on("change",()=>{if(this.props.onChange&&!ignoredAceChange){this.props.onChange(this.aceEditor.getValue(),this.aceEditor.getCursorPosition());}});this.aceEditor.on("blur",()=>{if(this.props.onBlur){this.props.onBlur();}});return()=>{aceEditor.destroy();};},()=>[this.editorRef.el]);useEffect((theme)=>this.aceEditor.setTheme(theme?`ace/theme/${theme}`:""),()=>[this.props.theme]);useEffect((readonly,showLineNumbers)=>{this.aceEditor.setOptions({readOnly:readonly,highlightActiveLine:!readonly,highlightGutterLine:!readonly,});this.aceEditor.renderer.setOptions({displayIndentGuides:!readonly,showGutter:!readonly&&showLineNumbers,});this.aceEditor.renderer.$cursorLayer.element.style.display=readonly?"none":"block";},()=>[this.props.readonly,this.props.showLineNumbers]);useEffect((sessionId,mode,value)=>{let session=sessions[sessionId];if(session){if(session.getValue()!==value){ignoredAceChange=true;session.setValue(value);ignoredAceChange=false;}}else{session=new window.ace.EditSession(value);session.setUndoManager(new window.ace.UndoManager());session.setOptions({useWorker:false,tabSize:2,useSoftTabs:true,});session.on("change",()=>{if(this.props.onChange&&!ignoredAceChange){this.props.onChange(this.aceEditor.getValue(),this.aceEditor.getCursorPosition());}});sessions[sessionId]=session;}
session.setMode(mode?`ace/mode/${mode}`:"");this.aceEditor.setSession(session);},()=>[this.props.sessionId,this.props.mode,this.props.value]);const initialCursorPosition=this.props.initialCursorPosition;if(initialCursorPosition){onMounted(()=>{window.requestAnimationFrame(()=>{if(status(this)!="destroyed"&&this.aceEditor){this.aceEditor.focus();const{row,column}=initialCursorPosition;const pos={row:row||0,column:column||0,};this.aceEditor.selection.moveToPosition(pos);this.aceEditor.renderer.scrollCursorIntoView(pos,0.5);}});});}}}
return __exports;});;
/* /web/static/src/core/color_picker/color_picker.js */
odoo.define('@web/core/color_picker/color_picker',['@odoo/owl','@web/core/color_picker/custom_color_picker/custom_color_picker','@web/core/popover/popover_hook','@web/core/utils/colors','@web/core/browser/cookie','@web/core/position/position_hook','@web/core/registry'],function(require){'use strict';let __exports={};const{Component,useEffect,useRef,useState}=require("@odoo/owl");const{CustomColorPicker}=require("@web/core/color_picker/custom_color_picker/custom_color_picker");const{usePopover}=require("@web/core/popover/popover_hook");const{isCSSColor,isColorGradient,normalizeCSSColor}=require("@web/core/utils/colors");const{cookie}=require("@web/core/browser/cookie");const{POSITION_BUS}=require("@web/core/position/position_hook");const{registry}=require("@web/core/registry");const DEFAULT_COLORS=__exports.DEFAULT_COLORS=[["#000000","#424242","#636363","#9C9C94","#CEC6CE","#EFEFEF","#F7F7F7","#FFFFFF"],["#FF0000","#FF9C00","#FFFF00","#00FF00","#00FFFF","#0000FF","#9C00FF","#FF00FF"],["#F7C6CE","#FFE7CE","#FFEFC6","#D6EFD6","#CEDEE7","#CEE7F7","#D6D6E7","#E7D6DE"],["#E79C9C","#FFC69C","#FFE79C","#B5D6A5","#A5C6CE","#9CC6EF","#B5A5D6","#D6A5BD"],["#E76363","#F7AD6B","#FFD663","#94BD7B","#73A5AD","#6BADDE","#8C7BC6","#C67BA5"],["#CE0000","#E79439","#EFC631","#6BA54A","#4A7B8C","#3984C6","#634AA5","#A54A7B"],["#9C0000","#B56308","#BD9400","#397B21","#104A5A","#085294","#311873","#731842"],["#630000","#7B3900","#846300","#295218","#083139","#003163","#21104A","#4A1031"],];const DEFAULT_GRAYSCALES=__exports.DEFAULT_GRAYSCALES={solid:["black","900","800","600","400","200","100","white"],};const DEFAULT_THEME_COLOR_VARS=__exports.DEFAULT_THEME_COLOR_VARS=["o-color-1","o-color-2","o-color-3","o-color-4","o-color-5",];const ColorPicker=__exports.ColorPicker=class ColorPicker extends Component{static template="web.ColorPicker";static components={CustomColorPicker};static props={state:{type:Object,shape:{selectedColor:String,selectedColorCombination:{type:String,optional:true},getTargetedElements:{type:Function,optional:true},defaultTab:String,selectedTab:{type:String,optional:true},mode:{type:String,optional:true},},},getUsedCustomColors:Function,applyColor:Function,applyColorPreview:Function,applyColorResetPreview:Function,editColorCombination:{type:Function,optional:true},setOnCloseCallback:{type:Function,optional:true},setOperationCallbacks:{type:Function,optional:true},enabledTabs:{type:Array,optional:true},colorPrefix:{type:String},cssVarColorPrefix:{type:String,optional:true},defaultOpacity:{type:Number,optional:true},grayscales:{type:Object,optional:true},noTransparency:{type:Boolean,optional:true},close:{type:Function,optional:true},className:{type:String,optional:true},useDefaultThemeColors:{type:Boolean,optional:true},};static defaultProps={close:()=>{},defaultOpacity:100,enabledTabs:["solid","custom"],cssVarColorPrefix:"",setOnCloseCallback:()=>{},useDefaultThemeColors:true,};setup(){this.tabs=registry.category("color_picker_tabs").getAll().filter((tab)=>this.props.enabledTabs.includes(tab.id));this.root=useRef("root");this.DEFAULT_COLORS=DEFAULT_COLORS;this.grayscales=Object.assign({},DEFAULT_GRAYSCALES,this.props.grayscales);this.DEFAULT_THEME_COLOR_VARS=this.props.useDefaultThemeColors?DEFAULT_THEME_COLOR_VARS:[];this.defaultColorSet=this.getDefaultColorSet();this.defaultColor=this.props.state.selectedColor;this.focusedBtn=null;this.onApplyCallback=()=>{};this.onPreviewRevertCallback=()=>{};this.getPreviewColor=()=>{};this.state=useState({activeTab:this.props.state.selectedTab||this.getDefaultTab(),currentCustomColor:this.props.state.selectedColor,currentColorPreview:undefined,showGradientPicker:false,});this.usedCustomColors=this.props.getUsedCustomColors();useEffect(()=>{this.env[POSITION_BUS]?.trigger("update");},()=>[this.state.activeTab]);}
getDefaultTab(){if(this.props.enabledTabs.includes(this.props.state.defaultTab)){return this.props.state.defaultTab;}
return this.props.enabledTabs[0];}
get selectedColor(){return this.props.state.selectedColor;}
get isDarkTheme(){return cookie.get("color_scheme")==="dark";}
setTab(tab){this.state.activeTab=tab;this.setOperationCallbacks({onPreviewRevertCallback:()=>{}});this.applyColorResetPreview();}
processColorFromEvent(ev){const target=this.getTarget(ev);let color=target.dataset.color||"";if(color&&isColorCombination(color)){return color;}
if(color&&!isCSSColor(color)&&!isColorGradient(color)){color=this.props.colorPrefix+color;}
return color;}
setOperationCallbacks(cbs){if(this.props.setOperationCallbacks){this.props.setOperationCallbacks(cbs);}
if(cbs.onApplyCallback){this.onApplyCallback=cbs.onApplyCallback;}
if(cbs.onPreviewRevertCallback){this.onPreviewRevertCallback=cbs.onPreviewRevertCallback;}
if(cbs.getPreviewColor){this.getPreviewColor=cbs.getPreviewColor;}}
applyColor(color){this.state.currentCustomColor=color;this.props.applyColor(color);this.defaultColorSet=this.getDefaultColorSet();this.onApplyCallback();}
onColorApply(ev){if(!this.isColorButton(this.getTarget(ev))){return;}
const color=this.processColorFromEvent(ev);this.applyColor(color);this.props.close();}
applyColorResetPreview(){this.props.applyColorResetPreview();this.state.currentColorPreview=undefined;this.onPreviewRevertCallback();}
onColorPreview(ev){const color=ev.hex||ev.gradient||this.processColorFromEvent(ev);this.props.applyColorPreview(color);this.state.currentColorPreview=this.getPreviewColor();}
onColorHover(ev){if(!this.isColorButton(this.getTarget(ev))){return;}
this.onColorPreview(ev);}
onColorHoverOut(ev){if(!this.isColorButton(this.getTarget(ev))){return;}
this.applyColorResetPreview();}
getTarget(ev){const target=ev.target.closest(`[data-color]`);return this.root.el.contains(target)?target:ev.target;}
onColorFocusin(ev){if(this.focusedBtn===ev.target){this.focusedBtn=null;return;}
this.focusedBtn=ev.target;this.onColorHover(ev);if(document.activeElement!==ev.target){ev.target.focus();}}
onColorFocusout(ev){if(!ev.relatedTarget||!this.isColorButton(ev.relatedTarget)){return;}
const activeEl=document.activeElement;this.applyColorResetPreview();if(document.activeElement!==activeEl){ev.relatedTarget.focus();}}
getDefaultColorSet(){if(!this.props.state.selectedColor){return;}
let defaultColors=this.props.enabledTabs.includes("solid")?this.DEFAULT_THEME_COLOR_VARS:[];for(const grayscale of Object.values(this.grayscales)){defaultColors=defaultColors.concat(grayscale);}
const targetedElement=this.props.state.getTargetedElements?.()[0]||document.documentElement;const selectedColor=this.props.state.selectedColor.toUpperCase();const htmlStyle=targetedElement.ownerDocument.defaultView.getComputedStyle(targetedElement);for(const color of defaultColors){const cssVar=normalizeCSSColor(htmlStyle.getPropertyValue(`--${color}`));if(cssVar?.toUpperCase()===selectedColor){return color;}}
return false;}
colorPickerNavigation(ev){const{target,key}=ev;if(!target.classList.contains("o_color_button")){return;}
if(!["ArrowRight","ArrowLeft","ArrowUp","ArrowDown"].includes(key)){return;}
let targetBtn;if(key==="ArrowRight"){targetBtn=target.nextElementSibling;}else if(key==="ArrowLeft"){targetBtn=target.previousElementSibling;}else if(key==="ArrowUp"||key==="ArrowDown"){const buttonIndex=[...target.parentElement.children].indexOf(target);const nbColumns=getComputedStyle(target).getPropertyValue("--o-color-picker-grid-columns");targetBtn=target.parentElement.children[buttonIndex+(key==="ArrowUp"?-1:1)*nbColumns];if(!targetBtn){const row=key==="ArrowUp"?target.parentElement.previousElementSibling:target.parentElement.nextElementSibling;if(row?.matches(".o_color_section, .o_colorpicker_section")){targetBtn=row.children[buttonIndex];}}}
if(targetBtn&&targetBtn.classList.contains("o_color_button")){targetBtn.focus();}}
isColorButton(targetEl){return targetEl.tagName==="BUTTON"&&!targetEl.matches(".o_colorpicker_ignore");}}
__exports.useColorPicker=useColorPicker;function useColorPicker(refName,props,options={}){let onCloseCallback=()=>{};const setOnCloseCallback=(cb)=>{onCloseCallback=cb;};props.setOnCloseCallback=setOnCloseCallback;if(options.onClose){const onClose=options.onClose;options.onClose=()=>{onCloseCallback();onClose();};}
const colorPicker=usePopover(ColorPicker,options);const root=useRef(refName);function onClick(){colorPicker.isOpen?colorPicker.close():colorPicker.open(root.el,props);}
useEffect((el)=>{if(!el){return;}
el.addEventListener("click",onClick);return()=>{el.removeEventListener("click",onClick);};},()=>[root.el]);return colorPicker;}
function isColorCombination(color){return color.startsWith("o_cc");}
return __exports;});;
/* /web/static/src/core/color_picker/custom_color_picker/custom_color_picker.js */
odoo.define('@web/core/color_picker/custom_color_picker/custom_color_picker',['@web/core/hotkeys/hotkey_service','@web/core/l10n/translation','@web/core/utils/colors','@web/core/utils/functions','@web/core/utils/numbers','@web/core/utils/timing','@odoo/owl'],function(require){'use strict';let __exports={};const{getActiveHotkey}=require("@web/core/hotkeys/hotkey_service");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{convertCSSColorToRgba,convertHslToRgb,convertRgbaToCSSColor,convertRgbToHsl,normalizeCSSColor,}=require("@web/core/utils/colors");const{uniqueId}=require("@web/core/utils/functions");const{clamp}=require("@web/core/utils/numbers");const{debounce,useThrottleForAnimation}=require("@web/core/utils/timing");const{Component,onMounted,onWillUpdateProps,useExternalListener,useRef}=require("@odoo/owl");const ARROW_KEYS=["arrowup","arrowdown","arrowleft","arrowright"];const SLIDER_KEYS=[...ARROW_KEYS,"pageup","pagedown","home","end"];const DEFAULT_COLOR="#FF0000";const CustomColorPicker=__exports.CustomColorPicker=class CustomColorPicker extends Component{static template="web.CustomColorPicker";static props={document:{type:true,optional:true},defaultColor:{type:String,optional:true},selectedColor:{type:String,optional:true},noTransparency:{type:Boolean,optional:true},stopClickPropagation:{type:Boolean,optional:true},onColorSelect:{type:Function,optional:true},onColorPreview:{type:Function,optional:true},onInputEnter:{type:Function,optional:true},defaultOpacity:{type:Number,optional:true},setOnCloseCallback:{type:Function,optional:true},setOperationCallbacks:{type:Function,optional:true},};static defaultProps={document:window.document,defaultColor:DEFAULT_COLOR,defaultOpacity:100,noTransparency:false,stopClickPropagation:false,onColorSelect:()=>{},onColorPreview:()=>{},onInputEnter:()=>{},};setup(){this.pickerFlag=false;this.sliderFlag=false;this.opacitySliderFlag=false;if(this.props.defaultOpacity>0&&this.props.defaultOpacity<=1){this.props.defaultOpacity*=100;}
if(this.props.defaultColor.length<=7){const opacityHex=Math.round((this.props.defaultOpacity/100)*255).toString(16).padStart(2,"0");this.props.defaultColor+=opacityHex;}
this.colorComponents={};this.uniqueId=uniqueId("colorpicker");this.selectedHexValue="";this.shouldSetSelectedColor=false;this.lastFocusedSliderEl=undefined;if(!this.props.selectedColor){this.props.selectedColor=this.props.defaultColor;}
this.debouncedOnChangeInputs=debounce(this.onChangeInputs.bind(this),10,true);this.elRef=useRef("el");this.colorPickerAreaRef=useRef("colorPickerArea");this.colorPickerPointerRef=useRef("colorPickerPointer");this.colorSliderRef=useRef("colorSlider");this.colorSliderPointerRef=useRef("colorSliderPointer");this.opacitySliderRef=useRef("opacitySlider");this.opacitySliderPointerRef=useRef("opacitySliderPointer");const documents=[window.top,...Array.from(window.top.frames).filter((frame)=>{try{const document=frame.document;return!!document;}catch{return false;}}),].map((w)=>w.document);this.throttleOnPointerMove=useThrottleForAnimation((ev)=>{this.onPointerMovePicker(ev);this.onPointerMoveSlider(ev);this.onPointerMoveOpacitySlider(ev);});for(const doc of documents){useExternalListener(doc,"pointermove",this.throttleOnPointerMove);useExternalListener(doc,"pointerup",this.onPointerUp.bind(this));useExternalListener(doc,"keydown",this.onEscapeKeydown.bind(this),{capture:true});}
this.props.setOnCloseCallback?.(()=>{if(this.shouldSetSelectedColor){this._colorSelected();}});this.props.setOperationCallbacks?.({getPreviewColor:()=>{if(this.shouldSetSelectedColor){return this.colorComponents.hex;}},onApplyCallback:()=>{this.shouldSetSelectedColor=false;},onPreviewRevertCallback:()=>{if(this.previewActive&&this.shouldSetSelectedColor){this.props.onColorPreview(this.colorComponents);}},});onMounted(async()=>{const rgba=convertCSSColorToRgba(this.props.selectedColor)||convertCSSColorToRgba(this.props.defaultColor);if(rgba){this._updateRgba(rgba.red,rgba.green,rgba.blue,rgba.opacity);}
this.previewActive=true;this._updateUI();});onWillUpdateProps((newProps)=>{const newSelectedColor=newProps.selectedColor?newProps.selectedColor:newProps.defaultColor;if(normalizeCSSColor(newSelectedColor)!==this.colorComponents.cssColor){this.setSelectedColor(newSelectedColor);}});}
setSelectedColor(color){const rgba=convertCSSColorToRgba(color);if(rgba){const oldPreviewActive=this.previewActive;this.previewActive=false;this._updateRgba(rgba.red,rgba.green,rgba.blue,rgba.opacity);this.previewActive=oldPreviewActive;this._updateUI();}}
getAllowedHotkeys(allowedKeys){return allowedKeys.flatMap((key)=>[key,`control+${key}`]);}
setLastFocusedSliderEl(el){this.lastFocusedSliderEl=el;document.activeElement.blur();}
get el(){return this.elRef.el;}
handleRangeKeydownValue(hotkey,value,{min=0,max=100,defaultStep=10,modifierStep=1,leap=20}={}){let step=defaultStep;if(hotkey.startsWith("control+")){step=modifierStep;}
const mainKey=hotkey.replace("control+","");if(mainKey==="pageup"||mainKey==="pagedown"){step=leap;}
if(["arrowup","arrowright","pageup"].includes(mainKey)){value+=step;}else if(["arrowdown","arrowleft","pagedown"].includes(mainKey)){value-=step;}else if(mainKey==="home"){value=min;}else if(mainKey==="end"){value=max;}
return clamp(value,min,max);}
selectColorOnEnter(hotkey){if(hotkey==="enter"&&this.shouldSetSelectedColor){this.pickerFlag=false;this.sliderFlag=false;this.opacitySliderFlag=false;this._colorSelected();}}
_updateUI(){for(const[color,value]of Object.entries(this.colorComponents)){const input=this.el.querySelector(`.o_${color}_input`);if(input){input.value=value;}}
const colorPickerArea=this.colorPickerAreaRef.el;colorPickerArea.style.backgroundColor=`hsl(${this.colorComponents.hue}, 100%, 50%)`;const top=((100-this.colorComponents.lightness)*colorPickerArea.clientHeight)/100;const left=(this.colorComponents.saturation*colorPickerArea.clientWidth)/100;const colorpickerPointer=this.colorPickerPointerRef.el;colorpickerPointer.style.top=top-5+"px";colorpickerPointer.style.left=left-5+"px";colorpickerPointer.setAttribute("aria-label",_t("Saturation: %(saturationLvl)s %. Brightness: %(brightnessLvl)s %",{saturationLvl:this.colorComponents.saturation?.toFixed(2)||"0",brightnessLvl:this.colorComponents.lightness?.toFixed(2)||"0",}));const colorSlider=this.colorSliderRef.el;const height=colorSlider.clientHeight;const y=(this.colorComponents.hue*height)/360;this.colorSliderPointerRef.el.style.bottom=`${Math.round(y - 4)}px`;this.colorSliderPointerRef.el.setAttribute("aria-valuenow",this.colorComponents.hue.toFixed(2));if(!this.props.noTransparency){const opacitySlider=this.opacitySliderRef.el;const heightOpacity=opacitySlider.clientHeight;const z=heightOpacity*(1-this.colorComponents.opacity/100.0);this.opacitySliderPointerRef.el.style.top=`${Math.round(z - 2)}px`;this.opacitySliderPointerRef.el.setAttribute("aria-valuenow",this.colorComponents.opacity.toFixed(2));const sliderColor=this.colorComponents.hex.slice(0,7);opacitySlider.style.background=`linear-gradient(${sliderColor} 0%, transparent 100%)`;}}
_updateHex(hex){const rgb=convertCSSColorToRgba(hex);if(!rgb){return;}
Object.assign(this.colorComponents,{hex:hex},rgb,convertRgbToHsl(rgb.red,rgb.green,rgb.blue));this._updateCssColor();}
_updateRgba(r,g,b,a){const opacity=a||this.colorComponents.opacity;if(opacity<0.1&&(r>0.1||g>0.1||b>0.1)){a=this.props.defaultOpacity;}
const hex=convertRgbaToCSSColor(r,g,b,a);if(!hex){return;}
Object.assign(this.colorComponents,{red:r,green:g,blue:b},a===undefined?{}:{opacity:a},{hex:hex},convertRgbToHsl(r,g,b));this._updateCssColor();}
_updateHsl(h,s,l){if(0.1<Math.abs(h-this.colorComponents.hue)){if(l<0.1||99.9<l){l=50;}
if(s<0.1){s=100;}}
let a=this.colorComponents.opacity;if(a<0.1&&l>0.1){a=this.props.defaultOpacity;}
const rgb=convertHslToRgb(h,s,l);if(!rgb){return;}
const hex=convertRgbaToCSSColor(rgb.red,rgb.green,rgb.blue,a);Object.assign(this.colorComponents,{hue:h,saturation:s,lightness:l},rgb,{hex:hex},{opacity:a});this._updateCssColor();}
_updateOpacity(a){if(a<0||a>100){return;}
Object.assign(this.colorComponents,{opacity:a});const r=this.colorComponents.red;const g=this.colorComponents.green;const b=this.colorComponents.blue;Object.assign(this.colorComponents,{hex:convertRgbaToCSSColor(r,g,b,a)});this._updateCssColor();}
_colorSelected(){this.props.onColorSelect(this.colorComponents);}
_updateCssColor(){const r=this.colorComponents.red;const g=this.colorComponents.green;const b=this.colorComponents.blue;const a=this.colorComponents.opacity;Object.assign(this.colorComponents,{cssColor:convertRgbaToCSSColor(r,g,b,a)});if(this.previewActive){this.props.onColorPreview(this.colorComponents);}}
onKeydown(ev){if(ev.key==="Enter"){if(ev.target.tagName==="INPUT"){this.onChangeInputs(ev);}
ev.preventDefault();this.props.onInputEnter(ev);}}
onClick(ev){if(this.props.stopClickPropagation){ev.stopPropagation();}
ev.__isColorpickerClick=true;if(ev.target.dataset.colorMethod==="hex"&&!this.selectedHexValue){ev.target.select();this.selectedHexValue=ev.target.value;return;}
this.selectedHexValue="";}
onPointerUp(){if(this.pickerFlag||this.sliderFlag||this.opacitySliderFlag){this.shouldSetSelectedColor=true;this._updateCssColor();}
this.pickerFlag=false;this.sliderFlag=false;this.opacitySliderFlag=false;if(this.lastFocusedSliderEl){this.lastFocusedSliderEl.focus();this.lastFocusedSliderEl=undefined;}}
onEscapeKeydown(ev){const hotkey=getActiveHotkey(ev);if(hotkey==="escape"){this.props.setOnCloseCallback?.(()=>{});}}
onPointerDownPicker(ev){this.pickerFlag=true;ev.preventDefault();this.onPointerMovePicker(ev);this.setLastFocusedSliderEl(this.colorPickerPointerRef.el);}
onPointerMovePicker(ev){if(!this.pickerFlag){return;}
const colorPickerArea=this.colorPickerAreaRef.el;const rect=colorPickerArea.getClientRects()[0];const top=ev.pageY-rect.top;const left=ev.pageX-rect.left;let saturation=Math.round((100*left)/colorPickerArea.clientWidth);let lightness=Math.round((100*(colorPickerArea.clientHeight-top))/colorPickerArea.clientHeight);saturation=clamp(saturation,0,100);lightness=clamp(lightness,0,100);this._updateHsl(this.colorComponents.hue,saturation,lightness);this._updateUI();}
onPickerKeydown(ev){const hotkey=getActiveHotkey(ev);this.selectColorOnEnter(hotkey);if(!this.getAllowedHotkeys(ARROW_KEYS).includes(hotkey)){return;}
let saturation=this.colorComponents.saturation;let lightness=this.colorComponents.lightness;let step=10;if(hotkey.startsWith("control+")){step=1;}
const mainKey=hotkey.replace("control+","");if(mainKey==="arrowup"){lightness+=step;}else if(mainKey==="arrowdown"){lightness-=step;}else if(mainKey==="arrowright"){saturation+=step;}else if(mainKey==="arrowleft"){saturation-=step;}
lightness=clamp(lightness,0,100);saturation=clamp(saturation,0,100);this._updateHsl(this.colorComponents.hue,saturation,lightness);this._updateUI();this.shouldSetSelectedColor=true;}
onPointerDownSlider(ev){this.sliderFlag=true;ev.preventDefault();this.onPointerMoveSlider(ev);this.setLastFocusedSliderEl(this.colorSliderPointerRef.el);}
onPointerMoveSlider(ev){if(!this.sliderFlag){return;}
const colorSlider=this.colorSliderRef.el;const colorSliderRects=colorSlider.getClientRects();const y=colorSliderRects[0].height-(ev.pageY-colorSliderRects[0].top);let hue=Math.round((360*y)/colorSlider.clientHeight);hue=clamp(hue,0,360);this._updateHsl(hue,this.colorComponents.saturation,this.colorComponents.lightness);this._updateUI();}
onSliderKeydown(ev){const hotkey=getActiveHotkey(ev);this.selectColorOnEnter(hotkey);if(!this.getAllowedHotkeys(SLIDER_KEYS).includes(hotkey)){return;}
const hue=this.handleRangeKeydownValue(hotkey,this.colorComponents.hue,{min:0,max:360,leap:30,});this._updateHsl(hue,this.colorComponents.saturation,this.colorComponents.lightness);this._updateUI();this.shouldSetSelectedColor=true;}
onPointerDownOpacitySlider(ev){this.opacitySliderFlag=true;ev.preventDefault();this.onPointerMoveOpacitySlider(ev);this.setLastFocusedSliderEl(this.opacitySliderPointerRef.el);}
onPointerMoveOpacitySlider(ev){if(!this.opacitySliderFlag||this.props.noTransparency){return;}
const opacitySlider=this.opacitySliderRef.el;const y=ev.pageY-opacitySlider.getClientRects()[0].top;let opacity=Math.round(100*(1-y/opacitySlider.clientHeight));opacity=clamp(opacity,0,100);this._updateOpacity(opacity);this._updateUI();}
onOpacitySliderKeydown(ev){const hotkey=getActiveHotkey(ev);this.selectColorOnEnter(hotkey);if(!this.getAllowedHotkeys(SLIDER_KEYS).includes(hotkey)){return;}
const opacity=this.handleRangeKeydownValue(hotkey,this.colorComponents.opacity);this._updateOpacity(opacity);this._updateUI();this.shouldSetSelectedColor=true;}
onChangeInputs(ev){switch(ev.target.dataset.colorMethod){case"hex":return;case"hsl":this._updateHsl(parseInt(this.el.querySelector(".o_hue_input").value),parseInt(this.el.querySelector(".o_saturation_input").value),parseInt(this.el.querySelector(".o_lightness_input").value));break;}
this._updateUI();this._colorSelected();}
onHexColorInput(ev){const hexColorValue=ev.target.value.replaceAll("#","");if(hexColorValue.length===6||hexColorValue.length===8){this._updateHex(`#${hexColorValue}`);this._updateUI();this._colorSelected();}}}
return __exports;});;
/* /web/static/src/core/color_picker/tabs/color_picker_custom_tab.js */
odoo.define('@web/core/color_picker/tabs/color_picker_custom_tab',['@odoo/owl','@web/core/l10n/translation','@web/core/registry','@web/core/utils/colors','@web/core/color_picker/custom_color_picker/custom_color_picker'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{registry}=require("@web/core/registry");const{isColorGradient}=require("@web/core/utils/colors");const{CustomColorPicker}=require("@web/core/color_picker/custom_color_picker/custom_color_picker");const ColorPickerCustomTab=__exports.ColorPickerCustomTab=class ColorPickerCustomTab extends Component{static template="web.ColorPickerCustomTab";static components={CustomColorPicker};static props={applyColor:Function,colorPickerNavigation:Function,onColorClick:Function,onColorPreview:Function,onColorPointerOver:Function,onColorPointerOut:Function,onFocusin:Function,onFocusout:Function,getUsedCustomColors:{type:Function,optional:true},currentColorPreview:{type:String,optional:true},currentCustomColor:{type:String,optional:true},defaultColorSet:{type:String|Boolean,optional:true},defaultOpacity:{type:Number,optional:true},grayscales:{type:Object,optional:true},cssVarColorPrefix:{type:String,optional:true},noTransparency:{type:Boolean,optional:true},setOnCloseCallback:{type:Function,optional:true},setOperationCallbacks:{type:Function,optional:true},"*":{optional:true},};setup(){this.usedCustomColors=this.props.getUsedCustomColors();}
isValidCustomColor(color){return color&&color.slice(7,9)!=="00"&&!isColorGradient(color);}}
registry.category("color_picker_tabs").add("web.custom",{id:"custom",name:_t("Custom"),component:ColorPickerCustomTab,});return __exports;});;
/* /web/static/src/core/color_picker/tabs/color_picker_solid_tab.js */
odoo.define('@web/core/color_picker/tabs/color_picker_solid_tab',['@odoo/owl','@web/core/l10n/translation','@web/core/registry'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{registry}=require("@web/core/registry");const ColorPickerSolidTab=__exports.ColorPickerSolidTab=class ColorPickerSolidTab extends Component{static template="web.ColorPickerSolidTab";static props={colorPickerNavigation:Function,onColorClick:Function,onColorPointerOver:Function,onColorPointerOut:Function,onFocusin:Function,onFocusout:Function,currentCustomColor:{type:String,optional:true},defaultColorSet:{type:String|Boolean,optional:true},cssVarColorPrefix:{type:String,optional:true},defaultColors:Array,defaultThemeColorVars:Array,"*":{optional:true},};}
registry.category("color_picker_tabs").add("web.solid",{id:"solid",name:_t("Solid"),component:ColorPickerSolidTab,});return __exports;});;
/* /web/static/src/core/colorlist/colorlist.js */
odoo.define('@web/core/colorlist/colorlist',['@web/core/l10n/translation','@odoo/owl'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{Component,useRef,useState,useExternalListener}=require("@odoo/owl");const ColorList=__exports.ColorList=class ColorList extends Component{static COLORS=[_t("No color"),_t("Red"),_t("Orange"),_t("Yellow"),_t("Cyan"),_t("Purple"),_t("Almond"),_t("Teal"),_t("Blue"),_t("Raspberry"),_t("Green"),_t("Violet"),];static template="web.ColorList";static defaultProps={forceExpanded:false,isExpanded:false,};static props={canToggle:{type:Boolean,optional:true},colors:Array,forceExpanded:{type:Boolean,optional:true},isExpanded:{type:Boolean,optional:true},onColorSelected:Function,selectedColor:{type:Number,optional:true},};setup(){this.colorlistRef=useRef("colorlist");this.state=useState({isExpanded:this.props.isExpanded});useExternalListener(window,"click",this.onOutsideClick);}
get colors(){return this.constructor.COLORS;}
onColorSelected(id){this.props.onColorSelected(id);if(!this.props.forceExpanded){this.state.isExpanded=false;}}
onOutsideClick(ev){if(this.colorlistRef.el.contains(ev.target)||this.props.forceExpanded){return;}
this.state.isExpanded=false;}
onToggle(ev){if(this.props.canToggle){ev.preventDefault();ev.stopPropagation();this.state.isExpanded=!this.state.isExpanded;this.colorlistRef.el.firstElementChild.focus();}}}
return __exports;});;
/* /web/static/src/core/colors/colors.js */
odoo.define('@web/core/colors/colors',['@web/core/utils/numbers'],function(require){'use strict';let __exports={};const{clamp}=require("@web/core/utils/numbers");const COLORS_ENT_BRIGHT=["#875A7B","#A5D8D7","#DCD0D9"];const COLORS_ENT_DARK=["#6B3E66","#147875","#5A395A"];const COLORS_SM=["#4EA7F2","#EA6175","#43C5B1","#F4A261","#8481DD","#FFD86D",];const COLORS_MD=["#4EA7F2","#3188E6","#43C5B1","#00A78D","#EA6175","#CE4257","#F4A261","#F48935","#8481DD","#5752D1","#FFD86D","#FFBC2C",];const COLORS_LG=["#4EA7F2","#3188E6","#056BD9","#A76DBC","#7F4295","#6D2387","#EA6175","#CE4257","#982738","#43C5B1","#00A78D","#0E8270","#F4A261","#F48935","#BE5D10","#8481DD","#5752D1","#3A3580","#A4A8B6","#7E8290","#545B70","#FFD86D","#FFBC2C","#C08A16",];const COLORS_XL=["#4EA7F2","#3188E6","#056BD9","#155193","#A76DBC","#7F4295","#6D2387","#4F1565","#EA6175","#CE4257","#982738","#791B29","#43C5B1","#00A78D","#0E8270","#105F53","#F4A261","#F48935","#BE5D10","#7D380D","#8481DD","#5752D1","#3A3580","#26235F","#A4A8B6","#7E8290","#545B70","#3F4250","#FFD86D","#FFBC2C","#C08A16","#936A12",];__exports.getColors=getColors;function getColors(colorScheme,paletteName){switch(paletteName){case"odoo":return colorScheme==="dark"?COLORS_ENT_DARK:COLORS_ENT_BRIGHT;case"sm":return COLORS_SM;case"md":return COLORS_MD;case"lg":return COLORS_LG;default:return COLORS_XL;}}
__exports.getColor=getColor;function getColor(index,colorScheme,paletteSizeOrName){let paletteName;if(paletteSizeOrName==="odoo"){paletteName="odoo";}else if(paletteSizeOrName<=6||paletteSizeOrName==="sm"){paletteName="sm";}else if(paletteSizeOrName<=12||paletteSizeOrName==="md"){paletteName="md";}else if(paletteSizeOrName<=24||paletteSizeOrName==="lg"){paletteName="lg";}else{paletteName="xl";}
const colors=getColors(colorScheme,paletteName);return colors[index%colors.length];}
const DEFAULT_BG=__exports.DEFAULT_BG="#d3d3d3";__exports.getBorderWhite=getBorderWhite;function getBorderWhite(colorScheme){return colorScheme==="dark"?"rgba(38, 42, 54, .2)":"rgba(249,250,251, .2)";}
const RGB_REGEX=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;__exports.hexToRGBA=hexToRGBA;function hexToRGBA(hex,opacity){const rgb=RGB_REGEX.exec(hex).slice(1,4).map((n)=>parseInt(n,16)).join(",");return`rgba(${rgb},${opacity})`;}
__exports.getCustomColor=getCustomColor;function getCustomColor(colorScheme,brightModeColor,darkModeColor){if(darkModeColor===undefined){return brightModeColor;}else{return colorScheme==="dark"?darkModeColor:brightModeColor;}}
__exports.lightenColor=lightenColor;function lightenColor(color,factor){factor=clamp(factor,0,1);let r=parseInt(color.substring(1,3),16);let g=parseInt(color.substring(3,5),16);let b=parseInt(color.substring(5,7),16);r=Math.round(r+(255-r)*factor);g=Math.round(g+(255-g)*factor);b=Math.round(b+(255-b)*factor);r=r.toString(16).padStart(2,"0");g=g.toString(16).padStart(2,"0");b=b.toString(16).padStart(2,"0");return`#${r}${g}${b}`;}
__exports.darkenColor=darkenColor;function darkenColor(color,factor){factor=clamp(factor,0,1);let r=parseInt(color.substring(1,3),16);let g=parseInt(color.substring(3,5),16);let b=parseInt(color.substring(5,7),16);r=Math.round(r*(1-factor));g=Math.round(g*(1-factor));b=Math.round(b*(1-factor));r=r.toString(16).padStart(2,"0");g=g.toString(16).padStart(2,"0");b=b.toString(16).padStart(2,"0");return`#${r}${g}${b}`;}
return __exports;});;
/* /web/static/src/core/confirmation_dialog/confirmation_dialog.js */
odoo.define('@web/core/confirmation_dialog/confirmation_dialog',['@web/core/dialog/dialog','@web/core/l10n/translation','@web/core/utils/hooks','@odoo/owl'],function(require){'use strict';let __exports={};const{Dialog}=require("@web/core/dialog/dialog");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{useChildRef}=require("@web/core/utils/hooks");const{Component}=require("@odoo/owl");const deleteConfirmationMessage=__exports.deleteConfirmationMessage=_t(`Ready to make your record disappear into thin air? Are you sure?
It will be gone forever!
Think twice before you click that 'Delete' button!`);const ConfirmationDialog=__exports.ConfirmationDialog=class ConfirmationDialog extends Component{static template="web.ConfirmationDialog";static components={Dialog};static props={close:Function,title:{validate:(m)=>{return(typeof m==="string"||(typeof m==="object"&&typeof m.toString==="function"));},optional:true,},body:{type:String,optional:true},confirm:{type:Function,optional:true},confirmLabel:{type:String,optional:true},confirmClass:{type:String,optional:true},cancel:{type:Function,optional:true},cancelLabel:{type:String,optional:true},dismiss:{type:Function,optional:true},};static defaultProps={confirmLabel:_t("Ok"),cancelLabel:_t("Cancel"),confirmClass:"btn-primary",title:_t("Confirmation"),};setup(){this.env.dialogData.dismiss=()=>this._dismiss();this.modalRef=useChildRef();this.isProcess=false;}
async _cancel(){return this.execButton(this.props.cancel);}
async _confirm(){return this.execButton(this.props.confirm);}
async _dismiss(){return this.execButton(this.props.dismiss||this.props.cancel);}
setButtonsDisabled(disabled){this.isProcess=disabled;if(!this.modalRef.el){return;}
for(const button of[...this.modalRef.el.querySelectorAll(".modal-footer button")]){button.disabled=disabled;}}
async execButton(callback){if(this.isProcess){return;}
this.setButtonsDisabled(true);if(callback){let shouldClose;try{shouldClose=await callback();}catch(e){this.props.close();throw e;}
if(shouldClose===false){this.setButtonsDisabled(false);return;}}
this.props.close();}}
const AlertDialog=__exports.AlertDialog=class AlertDialog extends ConfirmationDialog{static template="web.AlertDialog";static props={...ConfirmationDialog.props,contentClass:{type:String,optional:true},};static defaultProps={...ConfirmationDialog.defaultProps,title:_t("Alert"),};}
return __exports;});;
/* /web/static/src/core/context.js */
odoo.define('@web/core/context',['@web/core/py_js/py','@web/core/py_js/py_builtin','@web/core/py_js/py_interpreter'],function(require){'use strict';let __exports={};const{evaluateExpr,parseExpr}=require("@web/core/py_js/py");const{BUILTINS}=require("@web/core/py_js/py_builtin");const{evaluate}=require("@web/core/py_js/py_interpreter");__exports.makeContext=makeContext;function makeContext(contexts,initialEvaluationContext){const evaluationContext=Object.assign({},initialEvaluationContext);const context={};for(let ctx of contexts){if(ctx!==""){ctx=typeof ctx==="string"?evaluateExpr(ctx,evaluationContext):ctx;Object.assign(context,ctx);Object.assign(evaluationContext,context);}}
return context;}
function getPartialNames(ast){if(ast.type===5){return[ast.value];}
if(ast.type===6){return getPartialNames(ast.right);}
if(ast.type===14||ast.type===7){return getPartialNames(ast.left).concat(getPartialNames(ast.right));}
if(ast.type===15){return getPartialNames(ast.obj);}
return[];}
__exports.evalPartialContext=evalPartialContext;function evalPartialContext(_context,evaluationContext={}){const ast=parseExpr(_context);const context={};for(const key in ast.value){const value=ast.value[key];if(getPartialNames(value).some((name)=>!(name in evaluationContext||name in BUILTINS))){continue;}
try{context[key]=evaluate(value,evaluationContext);}catch{}}
return context;}
return __exports;});;
/* /web/static/src/core/copy_button/copy_button.js */
odoo.define('@web/core/copy_button/copy_button',['@web/core/browser/browser','@web/core/tooltip/tooltip','@web/core/popover/popover_hook','@odoo/owl'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{Tooltip}=require("@web/core/tooltip/tooltip");const{usePopover}=require("@web/core/popover/popover_hook");const{Component,useRef}=require("@odoo/owl");const CopyButton=__exports.CopyButton=class CopyButton extends Component{static template="web.CopyButton";static props={className:{type:String,optional:true},copyText:{type:String,optional:true},disabled:{type:Boolean,optional:true},successText:{type:String,optional:true},icon:{type:String,optional:true},content:{type:[String,Object,Function],optional:true},};setup(){this.button=useRef("button");this.popover=usePopover(Tooltip);}
showTooltip(){this.popover.open(this.button.el,{tooltip:this.props.successText});browser.setTimeout(this.popover.close,800);}
async onClick(){let write,content;if(typeof this.props.content==="function"){content=this.props.content();}else{content=this.props.content;}
if(typeof content==="string"||content instanceof String){write=(value)=>browser.navigator.clipboard.writeText(value);}else{write=(value)=>browser.navigator.clipboard.write(value);}
try{await write(content);}catch(error){return browser.console.warn(error);}
this.showTooltip();}}
return __exports;});;
/* /web/static/src/core/currency.js */
odoo.define('@web/core/currency',['@odoo/owl','@web/core/network/rpc','@web/core/user','@web/core/utils/numbers','@web/core/utils/strings','@web/session'],function(require){'use strict';let __exports={};const{reactive}=require("@odoo/owl");const{rpc}=require("@web/core/network/rpc");const{user}=require("@web/core/user");const{formatFloat,humanNumber}=require("@web/core/utils/numbers");const{nbsp}=require("@web/core/utils/strings");const{session}=require("@web/session");const currencies=__exports.currencies=session.currencies||{};delete session.currencies;__exports.getCurrency=getCurrency;function getCurrency(id){return currencies[id];}
__exports.getCurrencyRates=getCurrencyRates;async function getCurrencyRates(){const rates=reactive({});function recordsToRates(records){return Object.fromEntries(records.map((r)=>[r.id,r.inverse_rate]));}
const model="res.currency";const method="read";const url=`/web/dataset/call_kw/${model}/${method}`;const context={...user.context,to_currency:user.activeCompany.currency_id,};const params={model,method,args:[Object.keys(currencies).map(Number),["inverse_rate"]],kwargs:{context},};const records=await rpc(url,params,{cache:{type:"disk",update:"once",callback:(records,hasChanged)=>{if(hasChanged){Object.assign(rates,recordsToRates(records));}},},});Object.assign(rates,recordsToRates(records));return rates;}
__exports.formatCurrency=formatCurrency;function formatCurrency(amount,currencyId,options={}){const currency=getCurrency(currencyId);const digits=(options.digits!==undefined)?options.digits:(currency&&currency.digits)
let formattedAmount;if(options.humanReadable){formattedAmount=humanNumber(amount,{decimals:digits?digits[1]:2,minDigits:options.minDigits,});}else{formattedAmount=formatFloat(amount,{digits,minDigits:options.minDigits,trailingZeros:options.trailingZeros});}
if(!currency||options.noSymbol){return formattedAmount;}
const formatted=[currency.symbol,formattedAmount];if(currency.position==="after"){formatted.reverse();}
return formatted.join(nbsp);}
return __exports;});;
/* /web/static/src/core/datetime/datetime_input.js */
odoo.define('@web/core/datetime/datetime_input',['@odoo/owl','@web/core/utils/objects','@web/core/datetime/datetime_picker','@web/core/datetime/datetime_picker_hook'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{omit}=require("@web/core/utils/objects");const{DateTimePicker}=require("@web/core/datetime/datetime_picker");const{useDateTimePicker}=require("@web/core/datetime/datetime_picker_hook");const dateTimeInputOwnProps={format:{type:String,optional:true},id:{type:String,optional:true},class:{type:String,optional:true},onChange:{type:Function,optional:true},onApply:{type:Function,optional:true},placeholder:{type:String,optional:true},disabled:{type:Boolean,optional:true},};const DateTimeInput=__exports.DateTimeInput=class DateTimeInput extends Component{static props={...DateTimePicker.props,...dateTimeInputOwnProps,};static template="web.DateTimeInput";setup(){const getPickerProps=()=>omit(this.props,...Object.keys(dateTimeInputOwnProps));useDateTimePicker({format:this.props.format,showSeconds:this.props.rounding<=0,get pickerProps(){return getPickerProps();},onApply:(...args)=>this.props.onApply?.(...args),onChange:(...args)=>this.props.onChange?.(...args),});}}
return __exports;});;
/* /web/static/src/core/datetime/datetime_picker.js */
odoo.define('@web/core/datetime/datetime_picker',['@odoo/owl','@web/core/l10n/translation','@web/core/l10n/dates','@web/core/l10n/localization','@web/core/utils/arrays','@web/core/time_picker/time_picker','@web/core/l10n/time'],function(require){'use strict';let __exports={};const{Component,onWillRender,onWillUpdateProps,useState}=require("@odoo/owl");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{MAX_VALID_DATE,MIN_VALID_DATE,clampDate,isInRange,today}=require("@web/core/l10n/dates");const{localization}=require("@web/core/l10n/localization");const{ensureArray}=require("@web/core/utils/arrays");const{TimePicker}=require("@web/core/time_picker/time_picker");const{Time}=require("@web/core/l10n/time");const{DateTime,Info}=luxon;const getStartOfDecade=(date)=>Math.floor(date.year/10)*10;const getStartOfCentury=(date)=>Math.floor(date.year/100)*100;const getStartOfWeek=(date)=>{const{weekStart}=localization;return date.set({weekday:date.weekday<weekStart?weekStart-7:weekStart});};const numberRange=(min,max)=>[...Array(max-min)].map((_,i)=>i+min);const parseLimitDate=(value,defaultValue)=>clampDate(value==="today"?today():value||defaultValue,MIN_VALID_DATE,MAX_VALID_DATE);const toDateItem=({isOutOfRange=false,isValid=true,label,range,extraClass})=>({id:range[0].toISODate(),includesToday:isInRange(today(),range),isOutOfRange,isValid,label:String(range[0][label]),range,extraClass,});const toWeekItem=(weekDayItems)=>({number:weekDayItems[3].range[0].weekNumber,days:weekDayItems,});const PRECISION_LEVELS=new Map().set("days",{mainTitle:_t("Select month"),nextTitle:_t("Next month"),prevTitle:_t("Previous month"),step:{month:1},getTitle:(date)=>`${date.monthLong} ${date.year}`,getItems:(date,{maxDate,minDate,showWeekNumbers,isDateValid,dayCellClass})=>{const startDates=[date];const lastWeeks=[];let shouldAddLastWeek=false;const dayItems=startDates.map((date,i)=>{const monthRange=[date.startOf("month"),date.endOf("month")];const weeks=[];let startOfNextWeek=getStartOfWeek(monthRange[0]);for(let w=0;w<WEEKS_PER_MONTH;w++){const weekDayItems=[];for(let d=0;d<DAYS_PER_WEEK;d++){const day=startOfNextWeek.plus({day:d});const range=[day,day.endOf("day")];const dayItem=toDateItem({isOutOfRange:!isInRange(day,monthRange),isValid:isInRange(range,[minDate,maxDate])&&isDateValid?.(day),label:"day",range,extraClass:dayCellClass?.(day)||"",});weekDayItems.push(dayItem);if(d===DAYS_PER_WEEK-1){startOfNextWeek=day.plus({day:1});}
if(w===WEEKS_PER_MONTH-1){shouldAddLastWeek=true;}}
const weekItem=toWeekItem(weekDayItems);if(w===WEEKS_PER_MONTH-1){lastWeeks.push(weekItem);}else{weeks.push(weekItem);}}
const daysOfWeek=weeks[0].days.map((d)=>[d.range[0].weekdayShort,d.range[0].weekdayLong,Info.weekdays("narrow",{locale:d.range[0].locale})[d.range[0].weekday-1],]);if(showWeekNumbers){daysOfWeek.unshift(["",_t("Week numbers"),""]);}
return{id:`__month__${i}`,number:monthRange[0].month,daysOfWeek,weeks,};});if(shouldAddLastWeek){for(let i=0;i<dayItems.length;i++){dayItems[i].weeks.push(lastWeeks[i]);}}
return dayItems;},}).set("months",{mainTitle:_t("Select year"),nextTitle:_t("Next year"),prevTitle:_t("Previous year"),step:{year:1},getTitle:(date)=>String(date.year),getItems:(date,{maxDate,minDate})=>{const startOfYear=date.startOf("year");return numberRange(0,12).map((i)=>{const startOfMonth=startOfYear.plus({month:i});const range=[startOfMonth,startOfMonth.endOf("month")];return toDateItem({isValid:isInRange(range,[minDate,maxDate]),label:"monthShort",range,});});},}).set("years",{mainTitle:_t("Select decade"),nextTitle:_t("Next decade"),prevTitle:_t("Previous decade"),step:{year:10},getTitle:(date)=>`${getStartOfDecade(date) - 1} - ${getStartOfDecade(date) + 10}`,getItems:(date,{maxDate,minDate})=>{const startOfDecade=date.startOf("year").set({year:getStartOfDecade(date)});return numberRange(-GRID_MARGIN,GRID_COUNT+GRID_MARGIN).map((i)=>{const startOfYear=startOfDecade.plus({year:i});const range=[startOfYear,startOfYear.endOf("year")];return toDateItem({isOutOfRange:i<0||i>=GRID_COUNT,isValid:isInRange(range,[minDate,maxDate]),label:"year",range,});});},}).set("decades",{mainTitle:_t("Select century"),nextTitle:_t("Next century"),prevTitle:_t("Previous century"),step:{year:100},getTitle:(date)=>`${getStartOfCentury(date) - 10} - ${getStartOfCentury(date) + 100}`,getItems:(date,{maxDate,minDate})=>{const startOfCentury=date.startOf("year").set({year:getStartOfCentury(date)});return numberRange(-GRID_MARGIN,GRID_COUNT+GRID_MARGIN).map((i)=>{const startOfDecade=startOfCentury.plus({year:i*10});const range=[startOfDecade,startOfDecade.plus({year:10,millisecond:-1})];return toDateItem({label:"year",isOutOfRange:i<0||i>=GRID_COUNT,isValid:isInRange(range,[minDate,maxDate]),range,});});},});const GRID_COUNT=10;const GRID_MARGIN=1;const NULLABLE_DATETIME_PROPERTY=[DateTime,{value:false},{value:null}];const DAYS_PER_WEEK=7;const WEEKS_PER_MONTH=6;const DateTimePicker=__exports.DateTimePicker=class DateTimePicker extends Component{static props={focusedDateIndex:{type:Number,optional:true},showWeekNumbers:{type:Boolean,optional:true},daysOfWeekFormat:{type:String,optional:true},maxDate:{type:[NULLABLE_DATETIME_PROPERTY,{value:"today"}],optional:true},maxPrecision:{type:[...PRECISION_LEVELS.keys()].map((value)=>({value})),optional:true,},minDate:{type:[NULLABLE_DATETIME_PROPERTY,{value:"today"}],optional:true},minPrecision:{type:[...PRECISION_LEVELS.keys()].map((value)=>({value})),optional:true,},onReset:{type:Function,optional:true},onSelect:{type:Function,optional:true},onToggleRange:{type:Function,optional:true},range:{type:Boolean,optional:true},rounding:{type:Number,optional:true},showRangeToggler:{type:Boolean,optional:true},slots:{type:Object,shape:{buttons:{type:Object,optional:true}},optional:true,},type:{type:[{value:"date"},{value:"datetime"}],optional:true},value:{type:[NULLABLE_DATETIME_PROPERTY,{type:Array,element:NULLABLE_DATETIME_PROPERTY},],optional:true,},isDateValid:{type:Function,optional:true},dayCellClass:{type:Function,optional:true},tz:{type:String,optional:true},};static defaultProps={focusedDateIndex:0,daysOfWeekFormat:"narrow",maxPrecision:"decades",minPrecision:"days",rounding:5,showWeekNumbers:true,type:"datetime",};static template="web.DateTimePicker";static components={TimePicker};get activePrecisionLevel(){return PRECISION_LEVELS.get(this.state.precision);}
get isLastPrecisionLevel(){return(this.allowedPrecisionLevels.indexOf(this.state.precision)===this.allowedPrecisionLevels.length-1);}
get titles(){return ensureArray(this.title);}
setup(){this.allowedPrecisionLevels=[];this.items=[];this.title="";this.shouldAdjustFocusDate=false;this.state=useState({focusDate:null,hoveredDate:null,timeValues:[],precision:this.props.minPrecision,});this.onPropsUpdated(this.props);onWillUpdateProps((nextProps)=>this.onPropsUpdated(nextProps));onWillRender(()=>this.onWillRender());}
onPropsUpdated(props){this.values=ensureArray(props.value).map((value)=>value&&!value.isValid?null:value);this.allowedPrecisionLevels=this.filterPrecisionLevels(props.minPrecision,props.maxPrecision);this.maxDate=parseLimitDate(props.maxDate,MAX_VALID_DATE);this.minDate=parseLimitDate(props.minDate,MIN_VALID_DATE);if(this.props.type==="date"){this.maxDate=this.maxDate.endOf("day");this.minDate=this.minDate.startOf("day");}
if(this.maxDate<this.minDate){throw new Error(`DateTimePicker error: given "maxDate" comes before "minDate".`);}
this.state.timeValues=this.getTimeValues(props);this.shouldAdjustFocusDate=!props.range;this.adjustFocus(this.values,props.focusedDateIndex);}
onWillRender(){const{dayCellClass,focusedDateIndex,isDateValid,range,showWeekNumbers}=this.props;const{focusDate,hoveredDate}=this.state;const precision=this.activePrecisionLevel;const getterParams={maxDate:this.maxDate,minDate:this.minDate,showWeekNumbers:showWeekNumbers??!range,isDateValid,dayCellClass,};this.title=precision.getTitle(focusDate);this.items=precision.getItems(focusDate,getterParams);this.selectedRange=[...this.values];if(range&&focusedDateIndex>0&&(!this.values[1]||hoveredDate>this.values[0])){this.selectedRange[1]=hoveredDate;}}
adjustFocus(values,focusedDateIndex){if(!this.shouldAdjustFocusDate&&this.state.focusDate){return;}
const dateToFocus=values[focusedDateIndex]||values[focusedDateIndex===1?0:1]||today();this.shouldAdjustFocusDate=false;this.state.focusDate=this.clamp(dateToFocus.startOf("month"));}
clamp(value){return clampDate(value,this.minDate,this.maxDate);}
filterPrecisionLevels(minPrecision,maxPrecision){const levels=[...PRECISION_LEVELS.keys()];return levels.slice(levels.indexOf(minPrecision),levels.indexOf(maxPrecision)+1);}
getActiveRangeInfo({range}){const result={isSelected:isInRange(this.selectedRange,range),isSelectStart:false,isSelectEnd:false,isHighlighted:isInRange(this.state.hoveredDate,range),};if(this.props.range){if(result.isSelected){const[selectStart,selectEnd]=this.selectedRange.sort();result.isSelectStart=!selectStart||isInRange(selectStart,range);result.isSelectEnd=!selectEnd||isInRange(selectEnd,range);}}else{result.isSelectStart=result.isSelectEnd=result.isSelected;}
return result;}
getTimeValues(props){const timeValues=this.values.map((val,index)=>new Time({hour:index===1&&!this.values[1]?(val||DateTime.local()).hour+1:(val||DateTime.local()).hour,minute:val?.minute||0,second:val?.second||0,}));if(props.range){return timeValues;}else{const values=[];values[props.focusedDateIndex]=timeValues[props.focusedDateIndex];return values;}}
isSelectedDate({range}){return this.values.some((value)=>isInRange(value,range));}
next(ev){ev.preventDefault();const{step}=this.activePrecisionLevel;this.state.focusDate=this.clamp(this.state.focusDate.plus(step));}
previous(ev){ev.preventDefault();const{step}=this.activePrecisionLevel;this.state.focusDate=this.clamp(this.state.focusDate.minus(step));}
onTimeChange(valueIndex,newTime){this.state.timeValues[valueIndex]=newTime;const value=this.values[valueIndex]||today();this.validateAndSelect(value,valueIndex,"time");}
validateAndSelect(value,valueIndex,unit){if(!this.props.onSelect){return false;}
const result=[...this.values];result[valueIndex]=value;if(this.props.type==="datetime"){const{hour,minute,second}=this.state.timeValues[valueIndex];result[valueIndex]=result[valueIndex].set({hour,minute,second});}
if(!isInRange(result[valueIndex],[this.minDate,this.maxDate])){return false;}
this.props.onSelect(result.length===2?result:result[0],unit);return true;}
zoomIn(date){const index=this.allowedPrecisionLevels.indexOf(this.state.precision)-1;if(index in this.allowedPrecisionLevels){this.state.focusDate=this.clamp(date);this.state.precision=this.allowedPrecisionLevels[index];return true;}
return false;}
zoomOut(){const index=this.allowedPrecisionLevels.indexOf(this.state.precision)+1;if(index in this.allowedPrecisionLevels){this.state.precision=this.allowedPrecisionLevels[index];return true;}
return false;}
zoomOrSelect(dateItem){if(!dateItem.isValid){return;}
if(this.zoomIn(dateItem.range[0])){return;}
const[value]=dateItem.range;const valueIndex=this.props.focusedDateIndex;const isValid=this.validateAndSelect(value,valueIndex,"date");this.shouldAdjustFocusDate=isValid&&!this.props.range;}}
return __exports;});;
/* /web/static/src/core/datetime/datetime_picker_hook.js */
odoo.define('@web/core/datetime/datetime_picker_hook',['@odoo/owl','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{onWillDestroy,useRef}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");__exports.useDateTimePicker=useDateTimePicker;function useDateTimePicker(params){function getInputs(){return inputRefs.map((ref)=>ref.el);}
const inputRefs=[useRef(params.startDateRefName||"start-date"),useRef(params.endDateRefName||"end-date"),];const serviceParams=Object.assign(Object.create(params),{getInputs,useOwlHooks:true,});const picker=useService("datetime_picker").create(serviceParams);onWillDestroy(()=>{picker.disable();});return picker;}
return __exports;});;
/* /web/static/src/core/datetime/datetime_picker_popover.js */
odoo.define('@web/core/datetime/datetime_picker_popover',['@odoo/owl','@web/core/hotkeys/hotkey_hook','@web/core/datetime/datetime_picker'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{useHotkey}=require("@web/core/hotkeys/hotkey_hook");const{DateTimePicker}=require("@web/core/datetime/datetime_picker");const DateTimePickerPopover=__exports.DateTimePickerPopover=class DateTimePickerPopover extends Component{static components={DateTimePicker};static props={close:Function,pickerProps:{type:Object,shape:DateTimePicker.props},};static template="web.DateTimePickerPopover";setup(){useHotkey("enter",()=>this.props.close());}}
return __exports;});;
/* /web/static/src/core/datetime/datetimepicker_service.js */
odoo.define('@web/core/datetime/datetimepicker_service',['@odoo/owl','@web/core/l10n/dates','@web/core/popover/popover_hook','@web/core/registry','@web/core/utils/arrays','@web/core/utils/objects','@web/core/datetime/datetime_picker','@web/core/datetime/datetime_picker_popover'],function(require){'use strict';let __exports={};const{markRaw,onPatched,onWillRender,reactive,useEffect,useRef}=require("@odoo/owl");const{areDatesEqual,formatDate,formatDateTime,parseDate,parseDateTime}=require("@web/core/l10n/dates");const{makePopover}=require("@web/core/popover/popover_hook");const{registry}=require("@web/core/registry");const{ensureArray,zip,zipWith}=require("@web/core/utils/arrays");const{shallowEqual}=require("@web/core/utils/objects");const{DateTimePicker}=require("@web/core/datetime/datetime_picker");const{DateTimePickerPopover}=require("@web/core/datetime/datetime_picker_popover");function markValuesRaw(obj){const copy={};for(const[key,value]of Object.entries(obj)){if(value&&typeof value==="object"){copy[key]=markRaw(value);}else{copy[key]=value;}}
return copy;}
function stringifyProps(props){const copy={};for(const[key,value]of Object.entries(props)){copy[key]=JSON.stringify(value);}
return copy;}
const FOCUS_CLASSNAME="text-primary";const formatters={date:formatDate,datetime:formatDateTime,};const listenedElements=new WeakSet();const parsers={date:parseDate,datetime:parseDateTime,};const datetimePickerService=__exports.datetimePickerService={dependencies:["popover"],start(env,{popover:popoverService}){const dateTimePickerList=new Set();return{create(params={}){async function apply(){const{value}=pickerProps;const stringValue=JSON.stringify(value);if(stringValue===lastAppliedStringValue||stringValue===stringProps.value){return;}
lastAppliedStringValue=stringValue;inputsChanged=ensureArray(value).map(()=>false);await params.onApply?.(value);stringProps.value=stringValue;}
function enable(){for(const[el,value]of zip(getInputs(),ensureArray(pickerProps.value),true)){updateInput(el,value);if(el&&!el.disabled&&!el.readOnly&&!listenedElements.has(el)){listenedElements.add(el);el.addEventListener("change",onInputChange);el.addEventListener("click",onInputClick);el.addEventListener("focus",onInputFocus);el.addEventListener("keydown",onInputKeydown);}}
const calendarIconGroupEl=getInput(0)?.parentElement.querySelector(".o_input_group_date_icon");if(calendarIconGroupEl){calendarIconGroupEl.classList.add("cursor-pointer");calendarIconGroupEl.addEventListener("click",()=>open(0));}
return()=>{};}
function focusActiveInput(){const inputEl=getInput(pickerProps.focusedDateIndex);if(!inputEl){shouldFocus=true;return;}
const{activeElement}=inputEl.ownerDocument;if(activeElement!==inputEl){inputEl.focus();}
setInputFocus(inputEl);}
function getInput(valueIndex){const el=getInputs()[valueIndex];if(el?.isConnected){return el;}
return null;}
function getPopoverTarget(){const target=getTarget();if(target){return target;}
if(pickerProps.range){let parentElement=getInput(0).parentElement;const inputEls=getInputs();while(parentElement&&!inputEls.every((inputEl)=>parentElement.contains(inputEl))){parentElement=parentElement.parentElement;}
return parentElement||getInput(0);}else{return getInput(0);}}
function getTarget(){return targetRef?targetRef.el:params.target;}
function isOpen(){return popover.isOpen;}
function onInputChange(ev){updateValueFromInputs();inputsChanged[ev.target===getInput(1)?1:0]=true;if(!isOpen()||inputsChanged.every(Boolean)){saveAndClose();}}
function onInputClick({target}){open(target===getInput(1)?1:0);}
function onInputFocus({target}){pickerProps.focusedDateIndex=target===getInput(1)?1:0;setInputFocus(target);}
function onInputKeydown(ev){if(ev.key=="Enter"&&ev.ctrlKey){ev.preventDefault();updateValueFromInputs();return open(ev.target===getInput(1)?1:0);}
switch(ev.key){case"Enter":case"Escape":{return saveAndClose();}
case"Tab":{if(!getInput(0)||!getInput(1)||ev.target!==getInput(ev.shiftKey?1:0)){return saveAndClose();}}}}
function open(inputIndex){pickerProps.focusedDateIndex=inputIndex;if(!isOpen()){const popoverTarget=getPopoverTarget();if(ensureVisibility()){const{marginBottom}=popoverTarget.style;popoverTarget.style.marginBottom=`100vh`;popoverTarget.scrollIntoView(true);restoreTargetMargin=async()=>{popoverTarget.style.marginBottom=marginBottom;};}
for(const picker of dateTimePickerList){picker.close();}
popover.open(popoverTarget,{pickerProps});}
focusActiveInput();}
function safeConvert(operation,value){const{type}=pickerProps;const convertFn=(operation==="format"?formatters:parsers)[type];const options={tz:pickerProps.tz,format:params.format};if(operation==="format"){options.showSeconds=params.showSeconds??true;}
try{return[convertFn(value,options),null];}catch(error){if(error?.name==="ConversionError"){return[null,error];}else{throw error;}}}
function saveAndClose(){if(isOpen()){popover.close();}else{apply();}}
function setFocusClass(input){for(const el of getInputs()){if(el){el.classList.toggle(FOCUS_CLASSNAME,isOpen()&&el===input);}}}
function setInputFocus(inputEl){inputEl.selectionStart=0;inputEl.selectionEnd=inputEl.value.length;setFocusClass(inputEl);shouldFocus=false;}
function updateInput(el,value){if(!el){return;}
const[formattedValue]=safeConvert("format",value);el.value=formattedValue||"";}
function updateValue(value,unit,source){if(source==="input"&&areDatesEqual(pickerProps.value,value)){return;}
pickerProps.value=value;if(pickerProps.range&&unit!=="time"&&source==="picker"){if(!value[0]){pickerProps.focusedDateIndex=0;}else if(pickerProps.focusedDateIndex===0||(value[0]&&value[1]&&value[1]<value[0])){const{year,month,day}=value[pickerProps.focusedDateIndex];for(let i=0;i<value.length;i++){value[i]=value[i]&&value[i].set({year,month,day});}
pickerProps.focusedDateIndex=1;}else{pickerProps.focusedDateIndex=pickerProps.focusedDateIndex===1?0:1;}}
params.onChange?.(value);}
function updateValueFromInputs(){const values=zipWith(getInputs(),ensureArray(pickerProps.value),(el,currentValue)=>{if(!el||el.tagName?.toLowerCase()!=="input"){return currentValue;}
const[parsedValue,error]=safeConvert("parse",el.value);if(error){updateInput(el,currentValue);return currentValue;}else{return parsedValue;}});updateValue(values.length===2?values:values[0],"date","input");}
const createPopover=params.createPopover||function defaultCreatePopover(...args){return makePopover(popoverService.add,...args);};const ensureVisibility=params.ensureVisibility||function defaultEnsureVisibility(){return env.isSmall;};const getInputs=params.getInputs||function defaultGetInputs(){return[getTarget(),null];};const rawPickerProps={...DateTimePicker.defaultProps,onReset:()=>{updateValue(ensureArray(pickerProps.value).length===2?[false,false]:false,"date","picker");saveAndClose();},onSelect:(value,unit)=>{value&&=markRaw(value);updateValue(value,unit,"picker");if(!pickerProps.range&&pickerProps.type==="date"){saveAndClose();}},...markValuesRaw(params.pickerProps),};const pickerProps=reactive(rawPickerProps,()=>{for(const[el,value]of zip(getInputs(),ensureArray(pickerProps.value),true)){if(el){updateInput(el,value);if(!isOpen()){apply();}}}
shouldFocus=true;});const popover=createPopover(DateTimePickerPopover,{async onClose(){updateValueFromInputs();setFocusClass(null);restoreTargetMargin?.();restoreTargetMargin=null;await apply();params.onClose?.();},});let inputsChanged=[];let lastAppliedStringValue="";let restoreTargetMargin=null;let shouldFocus=false;let stringProps={};let targetRef=null;if(params.useOwlHooks){if(typeof params.target==="string"){targetRef=useRef(params.target);}
onWillRender(function computeBasePickerProps(){const nextProps=markValuesRaw(params.pickerProps);const oldStringProps=stringProps;stringProps=stringifyProps(nextProps);lastAppliedStringValue=stringProps.value;if(shallowEqual(oldStringProps,stringProps)){return;}
inputsChanged=ensureArray(nextProps.value).map(()=>false);for(const[key,value]of Object.entries(nextProps)){if(!areDatesEqual(pickerProps[key],value)){pickerProps[key]=value;}}});useEffect(enable,getInputs);onPatched(function focusIfNeeded(){if(isOpen()&&shouldFocus){focusActiveInput();}});}else if(typeof params.target==="string"){throw new Error(`datetime picker service error: cannot use target as ref name when not using Owl hooks`);}
const picker={enable,disable:()=>dateTimePickerList.delete(picker),isOpen,open,close:()=>popover.close(),state:pickerProps,};dateTimePickerList.add(picker);return picker;},};},};registry.category("services").add("datetime_picker",datetimePickerService);return __exports;});;
/* /web/static/src/core/debug/debug_context.js */
odoo.define('@web/core/debug/debug_context',['@web/core/user','@web/core/registry','@odoo/owl'],function(require){'use strict';let __exports={};const{user}=require("@web/core/user");const{registry}=require("@web/core/registry");const{useEffect,useEnv,useSubEnv}=require("@odoo/owl");const debugRegistry=registry.category("debug");const getAccessRights=async()=>{const rightsToCheck={"ir.ui.view":"write","ir.rule":"read","ir.model.access":"read",};const proms=Object.entries(rightsToCheck).map(([model,operation])=>{return user.checkAccessRight(model,operation);});const[canEditView,canSeeRecordRules,canSeeModelAccess]=await Promise.all(proms);const accessRights={canEditView,canSeeRecordRules,canSeeModelAccess};return accessRights;};class DebugContext{constructor(defaultCategories){this.categories=new Map(defaultCategories.map((cat)=>[cat,[{}]]));}
activateCategory(category,context){const contexts=this.categories.get(category)||new Set();contexts.add(context);this.categories.set(category,contexts);return()=>{contexts.delete(context);if(contexts.size===0){this.categories.delete(category);}};}
async getItems(env){const accessRights=await getAccessRights();return[...this.categories.entries()].flatMap(([category,contexts])=>{return debugRegistry.category(category).getAll().map((factory)=>factory(Object.assign({env,accessRights},...contexts)));}).filter(Boolean).sort((x,y)=>{const xSeq=x.sequence||1000;const ySeq=y.sequence||1000;return xSeq-ySeq;});}}
const debugContextSymbol=Symbol("debugContext");__exports.createDebugContext=createDebugContext;function createDebugContext({categories=[]}={}){return{[debugContextSymbol]:new DebugContext(categories)};}
__exports.useOwnDebugContext=useOwnDebugContext;function useOwnDebugContext({categories=[]}={}){useSubEnv(createDebugContext({categories}));}
__exports.useEnvDebugContext=useEnvDebugContext;function useEnvDebugContext(){const debugContext=useEnv()[debugContextSymbol];if(!debugContext){throw new Error("There is no debug context available in the current environment.");}
return debugContext;}
__exports.useDebugCategory=useDebugCategory;function useDebugCategory(category,context={}){const env=useEnv();if(env.debug){const debugContext=useEnvDebugContext();useEffect(()=>debugContext.activateCategory(category,context),()=>[]);}}
return __exports;});;
/* /web/static/src/core/debug/debug_menu_basic.js */
odoo.define('@web/core/debug/debug_menu_basic',['@web/core/debug/debug_context','@web/core/dropdown/dropdown','@web/core/dropdown/dropdown_item','@web/core/l10n/translation','@web/core/utils/arrays','@odoo/owl','@web/core/registry'],function(require){'use strict';let __exports={};const{useEnvDebugContext}=require("@web/core/debug/debug_context");const{Dropdown}=require("@web/core/dropdown/dropdown");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{groupBy,sortBy}=require("@web/core/utils/arrays");const{Component}=require("@odoo/owl");const{registry}=require("@web/core/registry");const debugSectionRegistry=registry.category("debug_section");debugSectionRegistry.add("record",{label:_t("Record"),sequence:10}).add("records",{label:_t("Records"),sequence:10}).add("ui",{label:_t("User Interface"),sequence:20}).add("security",{label:_t("Security"),sequence:30}).add("testing",{label:_t("Tours & Testing"),sequence:40}).add("tools",{label:_t("Tools"),sequence:50});const DebugMenuBasic=__exports.DebugMenuBasic=class DebugMenuBasic extends Component{static template="web.DebugMenu";static components={Dropdown,DropdownItem,};static props={};setup(){this.debugContext=useEnvDebugContext();}
async loadGroupedItems(){const items=await this.debugContext.getItems(this.env);const sections=groupBy(items,(item)=>item.section||"");this.sectionEntries=sortBy(Object.entries(sections),([section])=>debugSectionRegistry.get(section,{sequence:50}).sequence);}
getSectionLabel(section){return debugSectionRegistry.get(section,{label:section}).label;}}
return __exports;});;
/* /web/static/src/core/debug/debug_menu_items.js */
odoo.define('@web/core/debug/debug_menu_items',['@web/core/l10n/translation','@web/core/browser/browser','@web/core/browser/router','@web/core/registry','@web/core/user'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{browser}=require("@web/core/browser/browser");const{router}=require("@web/core/browser/router");const{registry}=require("@web/core/registry");const{user}=require("@web/core/user");function activateTestsAssetsDebugging({env}){if(String(router.current.debug).includes("tests")){return;}
return{type:"item",description:_t("Activate Test Mode"),callback:()=>{router.pushState({debug:"assets,tests"},{reload:true});},sequence:580,section:"tools",};}
__exports.regenerateAssets=regenerateAssets;function regenerateAssets({env}){return{type:"item",description:_t("Regenerate Assets"),callback:async()=>{await env.services.orm.call("ir.attachment","regenerate_assets_bundles");browser.location.reload();},sequence:550,section:"tools",};}
__exports.becomeSuperuser=becomeSuperuser;function becomeSuperuser({env}){const becomeSuperuserURL=browser.location.origin+"/web/become";if(!user.isAdmin){return false;}
return{type:"item",description:_t("Become Superuser"),href:becomeSuperuserURL,callback:()=>{browser.open(becomeSuperuserURL,"_self");},sequence:560,section:"tools",};}
function leaveDebugMode(){return{type:"item",description:_t("Leave Debug Mode"),callback:()=>{router.pushState({debug:0},{reload:true});},sequence:650,};}
registry.category("debug").category("default").add("regenerateAssets",regenerateAssets).add("becomeSuperuser",becomeSuperuser).add("activateTestsAssetsDebugging",activateTestsAssetsDebugging).add("leaveDebugMode",leaveDebugMode);return __exports;});;
/* /web/static/src/core/debug/debug_providers.js */
odoo.define('@web/core/debug/debug_providers',['@web/core/l10n/translation','@web/core/registry','@web/core/browser/browser','@web/core/browser/router'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{registry}=require("@web/core/registry");const{browser}=require("@web/core/browser/browser");const{router}=require("@web/core/browser/router");const commandProviderRegistry=registry.category("command_provider");commandProviderRegistry.add("debug",{provide:(env,options)=>{const result=[];if(env.debug){if(!env.debug.includes("assets")){result.push({action(){router.pushState({debug:"assets"},{reload:true});},category:"debug",name:_t("Activate debug mode (with assets)"),});}
result.push({action(){router.pushState({debug:0},{reload:true});},category:"debug",name:_t("Deactivate debug mode"),});result.push({action(){browser.open("/web/tests?debug=assets");},category:"debug",name:_t("Run Unit Tests"),});}else{const debugKey="debug";if(options.searchValue.toLowerCase()===debugKey){result.push({action(){router.pushState({debug:"1"},{reload:true});},category:"debug",name:`${_t("Activate debug mode")} (${debugKey})`,});result.push({action(){router.pushState({debug:"assets"},{reload:true});},category:"debug",name:`${_t("Activate debug mode (with assets)")} (${debugKey})`,});}}
return result;},});return __exports;});;
/* /web/static/src/core/debug/debug_utils.js */
odoo.define('@web/core/debug/debug_utils',[],function(require){'use strict';let __exports={};__exports.editModelDebug=editModelDebug;function editModelDebug(env,title,model,id){return env.services.action.doAction({res_model:model,res_id:id,name:title,type:"ir.actions.act_window",views:[[false,"form"]],view_mode:"form",target:"current",});}
return __exports;});;
/* /web/static/src/core/dialog/dialog.js */
odoo.define('@web/core/dialog/dialog',['@web/core/hotkeys/hotkey_hook','@web/core/ui/ui_service','@web/core/utils/hooks','@odoo/owl','@web/core/utils/timing','@web/core/utils/draggable_hook_builder_owl','@web/core/browser/feature_detection'],function(require){'use strict';let __exports={};const{useHotkey}=require("@web/core/hotkeys/hotkey_hook");const{useActiveElement}=require("@web/core/ui/ui_service");const{useForwardRefToParent}=require("@web/core/utils/hooks");const{Component,onWillDestroy,useChildSubEnv,useExternalListener,useState}=require("@odoo/owl");const{throttleForAnimation}=require("@web/core/utils/timing");const{makeDraggableHook}=require("@web/core/utils/draggable_hook_builder_owl");const{hasTouch}=require("@web/core/browser/feature_detection");const useDialogDraggable=makeDraggableHook({name:"useDialogDraggable",onWillStartDrag({ctx,addCleanup,addStyle,getRect}){const{height,width}=getRect(ctx.current.element);ctx.current.container=document.createElement("div");addStyle(ctx.current.container,{position:"fixed",top:"0",bottom:`${70 - height}px`,left:`${70 - width}px`,right:`${70 - width}px`,});ctx.current.element.after(ctx.current.container);addCleanup(()=>ctx.current.container.remove());},onDrop({ctx,getRect}){const{top,left}=getRect(ctx.current.element);return{left:left-ctx.current.elementRect.left,top:top-ctx.current.elementRect.top,};},});const Dialog=__exports.Dialog=class Dialog extends Component{static template="web.Dialog";static props={contentClass:{type:String,optional:true},bodyClass:{type:String,optional:true},fullscreen:{type:Boolean,optional:true},footer:{type:Boolean,optional:true},header:{type:Boolean,optional:true},size:{type:String,optional:true,validate:(s)=>["sm","md","lg","xl","fs","fullscreen"].includes(s),},technical:{type:Boolean,optional:true},title:{type:String,optional:true},modalRef:{type:Function,optional:true},slots:{type:Object,shape:{default:Object,header:{type:Object,optional:true},footer:{type:Object,optional:true},},},withBodyPadding:{type:Boolean,optional:true},onExpand:{type:Function,optional:true},};static defaultProps={contentClass:"",bodyClass:"",fullscreen:false,footer:true,header:true,size:"lg",technical:true,title:"Odoo",withBodyPadding:true,};setup(){this.modalRef=useForwardRefToParent("modalRef");useActiveElement("modalRef");this.data=useState(this.env.dialogData);useHotkey("escape",()=>this.onEscape());useHotkey("control+enter",()=>{const btns=document.querySelectorAll(".o_dialog:not(.o_inactive_modal) .modal-footer button");const firstVisibleBtn=Array.from(btns).find((btn)=>{const styles=getComputedStyle(btn);return styles.display!=="none";});if(firstVisibleBtn){firstVisibleBtn.click();}},{bypassEditableProtection:true});this.id=`dialog_${this.data.id}`;useChildSubEnv({inDialog:true,dialogId:this.id});this.isMovable=this.props.header;if(this.isMovable){this.position=useState({left:0,top:0});useDialogDraggable({enable:()=>!this.env.isSmall,ref:this.modalRef,elements:".modal-content",handle:".modal-header",ignore:"button, input",edgeScrolling:{enabled:false},onDrop:({top,left})=>{this.position.left+=left;this.position.top+=top;},});const throttledResize=throttleForAnimation(this.onResize.bind(this));useExternalListener(window,"resize",throttledResize);}
onWillDestroy(()=>{if(this.env.isSmall){this.data.scrollToOrigin();}});this.bodyTabIndex=hasTouch()?"0":undefined;}
get isFullscreen(){return this.props.fullscreen||this.env.isSmall;}
get contentStyle(){if(this.isMovable){return`top: ${this.position.top}px; left: ${this.position.left}px;`;}
return"";}
onResize(){this.position.left=0;this.position.top=0;}
onEscape(){return this.dismiss();}
async dismiss(){if(this.data.dismiss){await this.data.dismiss();}
return this.data.close({dismiss:true});}}
return __exports;});;
/* /web/static/src/core/dialog/dialog_service.js */
odoo.define('@web/core/dialog/dialog_service',['@odoo/owl','@web/core/registry'],function(require){'use strict';let __exports={};const{Component,markRaw,reactive,useChildSubEnv,xml}=require("@odoo/owl");const{registry}=require("@web/core/registry");class DialogWrapper extends Component{static template=xml`<t t-component="props.subComponent" t-props="props.subProps" />`;static props=["*"];setup(){useChildSubEnv({dialogData:this.props.subEnv});}}
const dialogService=__exports.dialogService={dependencies:["overlay"],start(env,{overlay}){const stack=[];let nextId=0;const deactivate=()=>{for(const subEnv of stack){subEnv.isActive=false;}};const add=(dialogClass,props,options={})=>{const id=nextId++;const close=(params)=>remove(params);const subEnv=reactive({id,close,isActive:true,});deactivate();stack.push(subEnv);document.body.classList.add("modal-open");let isBeingClosed=false;const scrollOrigin={top:window.scrollY,left:window.scrollX};subEnv.scrollToOrigin=()=>{if(!stack.length){window.scrollTo(scrollOrigin);}};const remove=overlay.add(DialogWrapper,{subComponent:dialogClass,subProps:markRaw({...props,close}),subEnv,},{onRemove:async(closeParams)=>{if(isBeingClosed){return;}
isBeingClosed=true;await options.onClose?.(closeParams);stack.splice(stack.findIndex((d)=>d.id===id),1);deactivate();if(stack.length){stack.at(-1).isActive=true;}else{document.body.classList.remove("modal-open");}},rootId:options.context?.root?.el?.getRootNode()?.host?.id,});return remove;};function closeAll(params){for(const dialog of[...stack].reverse()){dialog.close(params);}}
return{add,closeAll};},};registry.category("services").add("dialog",dialogService);return __exports;});;
/* /web/static/src/core/domain.js */
odoo.define('@web/core/domain',['@web/core/utils/arrays','@web/core/py_js/py','@web/core/py_js/py_utils','@web/core/utils/strings'],function(require){'use strict';let __exports={};const{shallowEqual}=require("@web/core/utils/arrays");const{evaluate,formatAST,parseExpr}=require("@web/core/py_js/py");const{toPyValue}=require("@web/core/py_js/py_utils");const{escapeRegExp}=require("@web/core/utils/strings");const InvalidDomainError=__exports.InvalidDomainError=class InvalidDomainError extends Error{}
const Domain=__exports.Domain=class Domain{static combine(domains,operator){if(domains.length===0){return new Domain([]);}
const domain1=domains[0]instanceof Domain?domains[0]:new Domain(domains[0]);if(domains.length===1){return domain1;}
const domain2=Domain.combine(domains.slice(1),operator);const result=new Domain([]);const astValues1=domain1.ast.value;const astValues2=domain2.ast.value;const op=operator==="AND"?"&":"|";const combinedAST={type:4,value:astValues1.concat(astValues2)};result.ast=normalizeDomainAST(combinedAST,op);return result;}
static and(domains){return Domain.combine(domains,"AND");}
static or(domains){return Domain.combine(domains,"OR");}
static not(domain){const result=new Domain(domain);result.ast.value.unshift({type:1,value:"!"});return result;}
static removeDomainLeaves(domain,keysToRemove){function processLeaf(elements,idx,operatorCtx,newDomain){const leaf=elements[idx];if(leaf.type===10){if(keysToRemove.includes(leaf.value[0].value)){if(operatorCtx==="&"){newDomain.ast.value.push(...Domain.TRUE.ast.value);}else if(operatorCtx==="|"){newDomain.ast.value.push(...Domain.FALSE.ast.value);}}else{newDomain.ast.value.push(leaf);}
return 1;}else if(leaf.type===1){if(leaf.value==="|"&&elements[idx+1].type===10&&elements[idx+2].type===10&&keysToRemove.includes(elements[idx+1].value[0].value)&&keysToRemove.includes(elements[idx+2].value[0].value)){newDomain.ast.value.push(...Domain.TRUE.ast.value);return 3;}
newDomain.ast.value.push(leaf);if(leaf.value==="!"){return 1+processLeaf(elements,idx+1,"&",newDomain);}
const firstLeafSkip=processLeaf(elements,idx+1,leaf.value,newDomain);const secondLeafSkip=processLeaf(elements,idx+1+firstLeafSkip,leaf.value,newDomain);return 1+firstLeafSkip+secondLeafSkip;}
return 0;}
domain=new Domain(domain);if(domain.ast.value.length===0){return domain;}
const newDomain=new Domain([]);processLeaf(domain.ast.value,0,"&",newDomain);return newDomain;}
constructor(descr=[]){if(descr instanceof Domain){return new Domain(descr.toString());}else{let rawAST;try{rawAST=typeof descr==="string"?parseExpr(descr):toAST(descr);}catch(error){throw new InvalidDomainError(`Invalid domain representation: ${descr.toString()}`,{cause:error,});}
this.ast=normalizeDomainAST(rawAST);}}
contains(record){const expr=evaluate(this.ast,record);return matchDomain(record,expr);}
toString(){return formatAST(this.ast);}
toList(context){return evaluate(this.ast,context);}
toJson(){try{const evaluatedAsList=this.toList({});const evaluatedDomain=new Domain(evaluatedAsList);if(evaluatedDomain.toString()===this.toString()){return evaluatedAsList;}
return this.toString();}catch{return this.toString();}}}
const TRUE_LEAF=[1,"=",1];const FALSE_LEAF=[0,"=",1];const TRUE_DOMAIN=new Domain([TRUE_LEAF]);const FALSE_DOMAIN=new Domain([FALSE_LEAF]);Domain.TRUE=TRUE_DOMAIN;Domain.FALSE=FALSE_DOMAIN;function toAST(domain){const elems=domain.map((elem)=>{switch(elem){case"!":case"&":case"|":return{type:1,value:elem};default:return{type:10,value:elem.map(toPyValue),};}});return{type:4,value:elems};}
function normalizeDomainAST(domain,op="&"){if(domain.type!==4){if(domain.type===10){const value=domain.value;if(value.findIndex((e)=>e.type===10)===-1||!value.every((e)=>e.type===10||e.type===1)){throw new InvalidDomainError("Invalid domain AST");}}else{throw new InvalidDomainError("Invalid domain AST");}}
if(domain.value.length===0){return domain;}
let expected=1;for(const child of domain.value){switch(child.type){case 1:if(child.value==="&"||child.value==="|"){expected++;}else if(child.value!=="!"){throw new InvalidDomainError("Invalid domain AST");}
break;case 4:case 10:if(child.value.length===3){expected--;break;}
throw new InvalidDomainError("Invalid domain AST");default:throw new InvalidDomainError("Invalid domain AST");}}
const values=domain.value.slice();while(expected<0){expected++;values.unshift({type:1,value:op});}
if(expected>0){throw new InvalidDomainError(`invalid domain ${formatAST(domain)} (missing ${expected} segment(s))`);}
return{type:4,value:values};}
function matchCondition(record,condition){if(typeof condition==="boolean"){return condition;}
const[field,operator,value]=condition;if(typeof field==="string"){const names=field.split(".");if(names.length>=2){return matchCondition(record[names[0]],[names.slice(1).join("."),operator,value]);}}
let likeRegexp,ilikeRegexp;if(["like","not like","ilike","not ilike"].includes(operator)){likeRegexp=new RegExp(`(.*)${escapeRegExp(value).replaceAll("%", "(.*)")}(.*)`,"g");ilikeRegexp=new RegExp(`(.*)${escapeRegExp(value).replaceAll("%", "(.*)")}(.*)`,"gi");}
const fieldValue=typeof field==="number"?field:record[field];const isNot=operator.startsWith("not ");switch(operator){case"=?":if([false,null].includes(value)){return true;}
case"=":case"==":if(Array.isArray(fieldValue)&&Array.isArray(value)){return shallowEqual(fieldValue,value);}
return fieldValue===value;case"!=":case"<>":return!matchCondition(record,[field,"=",value]);case"<":return fieldValue<value;case"<=":return fieldValue<=value;case">":return fieldValue>value;case">=":return fieldValue>=value;case"in":case"not in":{const val=Array.isArray(value)?value:[value];const fieldVal=Array.isArray(fieldValue)?fieldValue:[fieldValue];return Boolean(fieldVal.some((fv)=>val.includes(fv)))!=isNot;}
case"like":case"not like":if(fieldValue===false){return isNot;}
return Boolean(fieldValue.match(likeRegexp))!=isNot;case"=like":case"not =like":if(fieldValue===false){return isNot;}
return(Boolean(new RegExp(escapeRegExp(value).replace(/%/g,".*")).test(fieldValue))!=isNot);case"ilike":case"not ilike":if(fieldValue===false){return isNot;}
return Boolean(fieldValue.match(ilikeRegexp))!=isNot;case"=ilike":case"not =ilike":if(fieldValue===false){return isNot;}
return(Boolean(new RegExp(escapeRegExp(value).replace(/%/g,".*"),"i").test(fieldValue))!=isNot);case"any":case"not any":return true;case"child_of":case"parent_of":return true;}
throw new InvalidDomainError("could not match domain");}
function makeOperators(record){const match=matchCondition.bind(null,record);return{"!":(x)=>!match(x),"&":(a,b)=>match(a)&&match(b),"|":(a,b)=>match(a)||match(b),};}
function matchDomain(record,domain){if(domain.length===0){return true;}
const operators=makeOperators(record);const reversedDomain=Array.from(domain).reverse();const condStack=[];for(const item of reversedDomain){const operator=typeof item==="string"&&operators[item];if(operator){const operands=condStack.splice(-operator.length);condStack.push(operator(...operands));}else{condStack.push(item);}}
return matchCondition(record,condStack.pop());}
return __exports;});;
/* /web/static/src/core/domain_selector/domain_selector.js */
odoo.define('@web/core/domain_selector/domain_selector',['@odoo/owl','@web/core/checkbox/checkbox','@web/core/domain','@web/core/domain_selector/domain_selector_operator_editor','@web/core/l10n/translation','@web/core/model_field_selector/model_field_selector','@web/core/tree_editor/condition_tree','@web/core/tree_editor/domain_from_tree','@web/core/tree_editor/tree_editor','@web/core/tree_editor/tree_editor_operator_editor','@web/core/utils/hooks','@web/core/domain_selector/utils'],function(require){'use strict';let __exports={};const{Component,onWillStart,onWillUpdateProps}=require("@odoo/owl");const{CheckBox}=require("@web/core/checkbox/checkbox");const{Domain}=require("@web/core/domain");const{getDomainDisplayedOperators}=require("@web/core/domain_selector/domain_selector_operator_editor");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{ModelFieldSelector}=require("@web/core/model_field_selector/model_field_selector");const{areEqualTrees,condition,connector,formatValue,}=require("@web/core/tree_editor/condition_tree");const{domainFromTree}=require("@web/core/tree_editor/domain_from_tree");const{TreeEditor}=require("@web/core/tree_editor/tree_editor");const{getOperatorEditorInfo}=require("@web/core/tree_editor/tree_editor_operator_editor");const{useService}=require("@web/core/utils/hooks");const{getDefaultCondition}=require("@web/core/domain_selector/utils");const ARCHIVED_CONDITION=condition("active","in",[true,false]);const ARCHIVED_DOMAIN=`[("active", "in", [True, False])]`;const DomainSelector=__exports.DomainSelector=class DomainSelector extends Component{static template="web.DomainSelector";static components={TreeEditor,CheckBox};static props={domain:String,resModel:String,className:{type:String,optional:true},defaultConnector:{type:[{value:"&"},{value:"|"}],optional:true},isDebugMode:{type:Boolean,optional:true},readonly:{type:Boolean,optional:true},update:{type:Function,optional:true},debugUpdate:{type:Function,optional:true},};static defaultProps={isDebugMode:false,readonly:true,update:()=>{},};setup(){this.fieldService=useService("field");this.treeProcessor=useService("tree_processor");this.tree=null;this.showArchivedCheckbox=false;this.includeArchived=false;onWillStart(()=>this.onPropsUpdated(this.props));onWillUpdateProps((np)=>this.onPropsUpdated(np));}
async onPropsUpdated(p){let domain;let isSupported=true;try{domain=new Domain(p.domain);}catch{isSupported=false;}
if(!isSupported){this.tree=null;this.showArchivedCheckbox=false;this.includeArchived=false;return;}
const[tree,{fieldDef:activeFieldDef}]=await Promise.all([this.treeProcessor.treeFromDomain(p.resModel,domain,!p.isDebugMode),this.fieldService.loadFieldInfo(p.resModel,"active"),]);this.tree=tree;this.showArchivedCheckbox=this.getShowArchivedCheckBox(Boolean(activeFieldDef),p);this.includeArchived=false;if(this.showArchivedCheckbox){if(this.tree.type==="connector"&&this.tree.value==="&"){this.tree.children=this.tree.children.filter((child)=>{if(areEqualTrees(child,ARCHIVED_CONDITION)){this.includeArchived=true;return false;}
return true;});if(this.tree.children.length===1){this.tree=this.tree.children[0];}}else if(areEqualTrees(this.tree,ARCHIVED_CONDITION)){this.includeArchived=true;this.tree=connector("&");}}}
getShowArchivedCheckBox(hasActiveField,props){return hasActiveField;}
getDefaultCondition(fieldDefs){return getDefaultCondition(fieldDefs);}
getDefaultOperator(fieldDef){return getDomainDisplayedOperators(fieldDef)[0];}
getOperatorEditorInfo(fieldDef){const operators=getDomainDisplayedOperators(fieldDef);return getOperatorEditorInfo(operators,fieldDef);}
getPathEditorInfo(resModel,defaultCondition){const{isDebugMode}=this.props;return{component:ModelFieldSelector,extractProps:({update,value:path})=>({path,update,resModel,isDebugMode,readonly:false,}),isSupported:(path)=>[0,1].includes(path)||typeof path==="string",defaultValue:()=>defaultCondition.path,stringify:(path)=>formatValue(path),message:_t("Invalid field chain"),};}
toggleIncludeArchived(){this.includeArchived=!this.includeArchived;this.update(this.tree);}
resetDomain(){this.props.update("[]");}
onDomainInput(domain){if(this.props.debugUpdate){this.props.debugUpdate(domain);}}
onDomainChange(domain){this.props.update(domain,true);}
update(tree){const archiveDomain=this.includeArchived?ARCHIVED_DOMAIN:`[]`;const domain=tree?Domain.and([domainFromTree(tree),archiveDomain]).toString():archiveDomain;this.props.update(domain);}}
return __exports;});;
/* /web/static/src/core/domain_selector/domain_selector_operator_editor.js */
odoo.define('@web/core/domain_selector/domain_selector_operator_editor',[],function(require){'use strict';let __exports={};__exports.getDomainDisplayedOperators=getDomainDisplayedOperators;function getDomainDisplayedOperators(fieldDef){if(!fieldDef){fieldDef={};}
const{type,is_property}=fieldDef;if(is_property){switch(type){case"many2many":case"tags":return["in","not in","set","not set"];case"many2one":case"selection":return["=","!=","set","not set"];}}
switch(type){case"boolean":return["set","not set"];case"selection":return["=","!=","in","not in","set","not set"];case"char":case"text":case"html":return["=","!=","ilike","not ilike","starts with","set","not set"];case"date":case"datetime":return["in range","=","<",">","set","not set"];case"integer":case"float":case"monetary":return["=","!=","<",">","between"];case"many2one":case"many2many":case"one2many":return["in","not in","ilike","not ilike","set","not set"];case"json":return["=","!=","ilike","not ilike","set","not set"];case"binary":case"properties":return["set","not set"];case undefined:return["="];default:return["=","!=","<",">","ilike","not ilike","like","not like","=like","=ilike","in","not in","set","not set",];}}
return __exports;});;
/* /web/static/src/core/domain_selector/utils.js */
odoo.define('@web/core/domain_selector/utils',['@web/core/domain_selector/domain_selector_operator_editor','@web/core/tree_editor/condition_tree','@web/core/tree_editor/domain_from_tree','@web/core/tree_editor/tree_editor_value_editors','@web/core/tree_editor/utils','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{getDomainDisplayedOperators}=require("@web/core/domain_selector/domain_selector_operator_editor");const{condition}=require("@web/core/tree_editor/condition_tree");const{domainFromTree}=require("@web/core/tree_editor/domain_from_tree");const{getDefaultValue}=require("@web/core/tree_editor/tree_editor_value_editors");const{getDefaultPath}=require("@web/core/tree_editor/utils");const{useService}=require("@web/core/utils/hooks");__exports.getDefaultCondition=getDefaultCondition;function getDefaultCondition(fieldDefs){const defaultPath=getDefaultPath(fieldDefs);const fieldDef=fieldDefs[defaultPath];const operator=getDomainDisplayedOperators(fieldDef)[0];const value=getDefaultValue(fieldDef,operator);return condition(fieldDef.name,operator,value);}
__exports.getDefaultDomain=getDefaultDomain;function getDefaultDomain(fieldDefs){return domainFromTree(getDefaultCondition(fieldDefs));}
__exports.useGetDefaultLeafDomain=useGetDefaultLeafDomain;function useGetDefaultLeafDomain(){const fieldService=useService("field");return async(resModel)=>{const fieldDefs=await fieldService.loadFields(resModel);return getDefaultDomain(fieldDefs);};}
return __exports;});;
/* /web/static/src/core/domain_selector_dialog/domain_selector_dialog.js */
odoo.define('@web/core/domain_selector_dialog/domain_selector_dialog',['@web/core/l10n/translation','@odoo/owl','@web/core/dialog/dialog','@web/core/domain','@web/core/domain_selector/domain_selector','@web/core/network/rpc','@web/core/utils/hooks','@web/core/user'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{Component,useRef,useState}=require("@odoo/owl");const{Dialog}=require("@web/core/dialog/dialog");const{Domain}=require("@web/core/domain");const{DomainSelector}=require("@web/core/domain_selector/domain_selector");const{rpc}=require("@web/core/network/rpc");const{useService}=require("@web/core/utils/hooks");const{user}=require("@web/core/user");const DomainSelectorDialog=__exports.DomainSelectorDialog=class DomainSelectorDialog extends Component{static template="web.DomainSelectorDialog";static components={Dialog,DomainSelector,};static props={close:Function,onConfirm:Function,resModel:String,className:{type:String,optional:true},defaultConnector:{type:[{value:"&"},{value:"|"}],optional:true},domain:String,isDebugMode:{type:Boolean,optional:true},readonly:{type:Boolean,optional:true},text:{type:String,optional:true},confirmButtonText:{type:String,optional:true},disableConfirmButton:{type:Function,optional:true},discardButtonText:{type:String,optional:true},title:{type:String,optional:true},context:{type:Object,optional:true},};static defaultProps={isDebugMode:false,readonly:false,context:{},};setup(){this.notification=useService("notification");this.orm=useService("orm");this.state=useState({domain:this.props.domain});this.confirmButtonRef=useRef("confirm");}
get confirmButtonText(){return this.props.confirmButtonText||_t("Confirm");}
get dialogTitle(){return this.props.title||_t("Domain");}
get disabled(){if(this.props.disableConfirmButton){return this.props.disableConfirmButton(this.state.domain);}
return false;}
get discardButtonText(){return this.props.discardButtonText||_t("Discard");}
get domainSelectorProps(){return{className:this.props.className,resModel:this.props.resModel,readonly:this.props.readonly,isDebugMode:this.props.isDebugMode,defaultConnector:this.props.defaultConnector,domain:this.state.domain,update:(domain)=>{this.state.domain=domain;},};}
async onConfirm(){this.confirmButtonRef.el.disabled=true;let domain;let isValid;try{const evalContext={...user.context,...this.props.context};domain=new Domain(this.state.domain).toList(evalContext);}catch{isValid=false;}
if(isValid===undefined){isValid=await rpc("/web/domain/validate",{model:this.props.resModel,domain,});}
if(!isValid){if(this.confirmButtonRef.el){this.confirmButtonRef.el.disabled=false;}
this.notification.add(_t("Domain is invalid. Please correct it"),{type:"danger",});return;}
this.props.onConfirm(this.state.domain);this.props.close();}
onDiscard(){this.props.close();}}
return __exports;});;
/* /web/static/src/core/dropdown/_behaviours/dropdown_group_hook.js */
odoo.define('@web/core/dropdown/_behaviours/dropdown_group_hook',['@odoo/owl','@web/core/dropdown/dropdown_group'],function(require){'use strict';let __exports={};const{useComponent,useEffect,useEnv}=require("@odoo/owl");const{DROPDOWN_GROUP}=require("@web/core/dropdown/dropdown_group");__exports.useDropdownGroup=useDropdownGroup;function useDropdownGroup(){const env=useEnv();const group={isInGroup:DROPDOWN_GROUP in env,get isOpen(){return this.isInGroup&&[...env[DROPDOWN_GROUP]].some((dropdown)=>dropdown.isOpen);},};if(group.isInGroup){const dropdown=useComponent();useEffect(()=>{env[DROPDOWN_GROUP].add(dropdown.state);return()=>env[DROPDOWN_GROUP].delete(dropdown.state);});}
return group;}
return __exports;});;
/* /web/static/src/core/dropdown/_behaviours/dropdown_nesting.js */
odoo.define('@web/core/dropdown/_behaviours/dropdown_nesting',['@odoo/owl','@web/core/l10n/localization','@web/core/utils/hooks','@web/core/utils/reactive'],function(require){'use strict';let __exports={};const{EventBus,onWillDestroy,useChildSubEnv,useEffect,useEnv}=require("@odoo/owl");const{localization}=require("@web/core/l10n/localization");const{useBus,useService}=require("@web/core/utils/hooks");const{effect}=require("@web/core/utils/reactive");const DROPDOWN_NESTING=__exports.DROPDOWN_NESTING=Symbol("dropdownNesting");const BUS=new EventBus();class DropdownNestingState{constructor({parent,close}){this._isOpen=false;this.parent=parent;this.children=new Set();this.close=close;parent?.children.add(this);}
set isOpen(value){this._isOpen=value;if(this._isOpen){BUS.trigger("dropdown-opened",this);}}
get isOpen(){return this._isOpen;}
remove(){this.parent?.children.delete(this);}
closeAllParents(){this.close();if(this.parent){this.parent.closeAllParents();}}
closeChildren(){this.children.forEach((child)=>child.close());}
shouldIgnoreChanges(other){return(other===this||other.activeEl!==this.activeEl||[...this.children].some((child)=>child.shouldIgnoreChanges(other)));}
handleChange(other){if(this.shouldIgnoreChanges(other)){return;}
if(other.isOpen&&this.isOpen){this.close();}}}
__exports.useDropdownNesting=useDropdownNesting;function useDropdownNesting(state){const env=useEnv();const current=new DropdownNestingState({parent:env[DROPDOWN_NESTING],close:()=>state.close(),});const uiService=useService("ui");useEffect(()=>{Promise.resolve().then(()=>{current.activeEl=uiService.activeElement;});},()=>[]);useChildSubEnv({[DROPDOWN_NESTING]:current});useBus(BUS,"dropdown-opened",({detail:other})=>current.handleChange(other));effect((state)=>{current.isOpen=state.isOpen;},[state]);onWillDestroy(()=>{current.remove();});const isDropdown=(target)=>target&&target.classList.contains("o-dropdown");const isRTL=()=>localization.direction==="rtl";return{get hasParent(){return Boolean(current.parent);},navigationOptions:{onUpdated:(navigator)=>{if(current.parent&&!navigator.activeItem){navigator.items[0]?.setActive();}},hotkeys:{escape:()=>current.close(),arrowleft:{isAvailable:()=>true,callback:(navigator)=>{if(isRTL()&&isDropdown(navigator.activeItem?.target)){navigator.activeItem?.select();}else if(current.parent){current.close();}},},arrowright:{isAvailable:()=>true,callback:(navigator)=>{if(isRTL()&&current.parent){current.close();}else if(isDropdown(navigator.activeItem?.target)){navigator.activeItem?.select();}},},},},};}
return __exports;});;
/* /web/static/src/core/dropdown/_behaviours/dropdown_popover.js */
odoo.define('@web/core/dropdown/_behaviours/dropdown_popover',['@odoo/owl','@web/core/dropdown/dropdown_item'],function(require){'use strict';let __exports={};const{Component,onMounted,onRendered,onWillDestroy,onWillStart,xml}=require("@odoo/owl");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const DropdownPopover=__exports.DropdownPopover=class DropdownPopover extends Component{static components={DropdownItem};static template=xml`
<t t-if="this.props.items">
<t t-foreach="this.props.items" t-as="item" t-key="this.getKey(item, item_index)">
<DropdownItem class="item.class" onSelected="() => item.onSelected()" t-out="item.label"/>
</t>
</t>
<t t-slot="content" />
`;static props={close:{type:Function,optional:true},beforeOpen:{type:Function,optional:true},onOpened:{type:Function,optional:true},onClosed:{type:Function,optional:true},refresher:Object,slots:Object,items:{type:Array,optional:true},};setup(){onRendered(()=>{this.props.refresher.token;});onWillStart(async()=>{await this.props.beforeOpen?.();});onMounted(()=>{this.props.onOpened?.();});onWillDestroy(()=>{this.props.onClosed?.();});}
getKey(item,index){return"id"in item?item.id:index;}}
return __exports;});;
/* /web/static/src/core/dropdown/accordion_item.js */
odoo.define('@web/core/dropdown/accordion_item',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component,onPatched,useState}=require("@odoo/owl");const ACCORDION=__exports.ACCORDION=Symbol("Accordion");const AccordionItem=__exports.AccordionItem=class AccordionItem extends Component{static template="web.AccordionItem";static components={};static props={slots:{type:Object,shape:{default:{},},},description:String,selected:{type:Boolean,optional:true,},class:{type:String,optional:true,},};static defaultProps={class:"",selected:false,};setup(){this.state=useState({open:false,});this.parentComponent=this.env[ACCORDION];onPatched(()=>{this.parentComponent?.accordionStateChanged?.();});}}
return __exports;});;
/* /web/static/src/core/dropdown/checkbox_item.js */
odoo.define('@web/core/dropdown/checkbox_item',['@web/core/dropdown/dropdown_item'],function(require){'use strict';let __exports={};const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const CheckboxItem=__exports.CheckboxItem=class CheckboxItem extends DropdownItem{static template="web.CheckboxItem";static props={...DropdownItem.props,checked:{type:Boolean,optional:false,},};}
return __exports;});;
/* /web/static/src/core/dropdown/dropdown.js */
odoo.define('@web/core/dropdown/dropdown',['@odoo/owl','@web/core/dropdown/_behaviours/dropdown_group_hook','@web/core/dropdown/_behaviours/dropdown_nesting','@web/core/dropdown/_behaviours/dropdown_popover','@web/core/dropdown/dropdown_hooks','@web/core/navigation/navigation','@web/core/popover/popover_hook','@web/core/utils/classname','@web/core/utils/hooks','@web/core/utils/objects','@web/core/utils/reactive','@web/core/ui/ui_service','@web/core/browser/feature_detection'],function(require){'use strict';let __exports={};const{Component,onMounted,onRendered,onWillUpdateProps,reactive,status,useEffect,xml,}=require("@odoo/owl");const{useDropdownGroup}=require("@web/core/dropdown/_behaviours/dropdown_group_hook");const{useDropdownNesting}=require("@web/core/dropdown/_behaviours/dropdown_nesting");const{DropdownPopover}=require("@web/core/dropdown/_behaviours/dropdown_popover");const{useDropdownState}=require("@web/core/dropdown/dropdown_hooks");const{useNavigation}=require("@web/core/navigation/navigation");const{usePopover}=require("@web/core/popover/popover_hook");const{mergeClasses}=require("@web/core/utils/classname");const{useChildRef,useService}=require("@web/core/utils/hooks");const{deepMerge}=require("@web/core/utils/objects");const{effect}=require("@web/core/utils/reactive");const{utils}=require("@web/core/ui/ui_service");const{hasTouch}=require("@web/core/browser/feature_detection");__exports.getFirstElementOfNode=getFirstElementOfNode;function getFirstElementOfNode(node){if(!node){return null;}
if(node.el){return node.el.nodeType===Node.ELEMENT_NODE?node.el:null;}
if(node.bdom||node.child){return getFirstElementOfNode(node.bdom||node.child);}
if(node.children){for(const child of node.children){const el=getFirstElementOfNode(child);if(el){return el;}}}
return null;}
const Dropdown=__exports.Dropdown=class Dropdown extends Component{static template=xml`<t t-slot="default"/>`;static components={};static props={menuClass:{optional:true},position:{type:String,optional:true},slots:{type:Object,shape:{default:{optional:true},content:{optional:true},},},items:{optional:true,type:Array,elements:{type:Object,shape:{label:String,onSelected:Function,class:{optional:true},"*":true,},},},menuRef:{type:Function,optional:true},disabled:{type:Boolean,optional:true},holdOnHover:{type:Boolean,optional:true},focusToggleOnClosed:{type:Boolean,optional:true},beforeOpen:{type:Function,optional:true},onOpened:{type:Function,optional:true},onStateChanged:{type:Function,optional:true},state:{type:Object,shape:{isOpen:Boolean,close:Function,open:Function,"*":true,},optional:true,},manual:{type:Boolean,optional:true},noClasses:{type:Boolean,optional:true},navigationOptions:{type:Object,optional:true},bottomSheet:{type:Boolean,optional:true},};static defaultProps={disabled:false,holdOnHover:false,focusToggleOnClosed:true,menuClass:"",state:undefined,noClasses:false,navigationOptions:{},bottomSheet:true,};setup(){this.menuRef=this.props.menuRef||useChildRef();this.state=this.props.state||useDropdownState();this.nesting=useDropdownNesting(this.state);this.group=useDropdownGroup();this.navigation=useNavigation(this.menuRef,{shouldRegisterHotkeys:false,isNavigationAvailable:()=>this.state.isOpen,getItems:()=>{if(this.state.isOpen&&this.menuRef.el){return this.menuRef.el.querySelectorAll(":scope .o-navigable, :scope .o-dropdown");}else{return[];}},...deepMerge(this.nesting.navigationOptions,this.props.navigationOptions),});this.uiService=useService("ui");const getPosition=()=>this.position;const options={animation:false,arrow:false,closeOnClickAway:(target)=>this.popoverCloseOnClickAway(target),closeOnEscape:false,env:this.__owl__.childEnv,holdOnHover:this.props.holdOnHover,onClose:()=>this.state.close(),onPositioned:(el,{direction})=>this.setTargetDirectionClass(direction),popoverClass:mergeClasses("o-dropdown--menu dropdown-menu mx-0",{"o-dropdown--menu-submenu":this.hasParent},this.props.menuClass),role:"menu",get position(){return getPosition();},ref:this.menuRef,setActiveElement:false,};if(this.isBottomSheet){Object.assign(options,{useBottomSheet:true,class:mergeClasses("o-dropdown--menu dropdown-menu show",this.props.menuClass),});}
this.popover=usePopover(DropdownPopover,options);onRendered(()=>(this.popoverRefresher?this.popoverRefresher.token++:null));onMounted(()=>this.onStateChanged(this.state));effect((state)=>this.onStateChanged(state),[this.state]);useEffect((target)=>this.setTargetElement(target),()=>[this.target]);onWillUpdateProps(({disabled})=>{if(disabled){this.closePopover();}});}
get isBottomSheet(){return utils.isSmall()&&hasTouch()&&this.props.bottomSheet;}
get position(){return this.props.position||(this.hasParent?"right-start":"bottom-start");}
get hasParent(){return this.nesting.hasParent;}
get target(){const target=getFirstElementOfNode(this.__owl__.bdom);if(!target){throw new Error("Could not find a valid dropdown toggler, prefer a single html element and put any dynamic content inside of it.");}
return target;}
handleClick(event){if(this.props.disabled){return;}
event.stopPropagation();if(this.state.isOpen&&!this.hasParent){this.state.close();}else{this.state.open();}}
handleMouseEnter(){if(this.props.disabled){return;}
if(this.hasParent||this.group.isOpen){this.target.focus();this.state.open();}}
onStateChanged(state){if(state.isOpen){this.openPopover();}else{this.closePopover();}}
popoverCloseOnClickAway(target){const rootNode=target.getRootNode();if(rootNode instanceof ShadowRoot){target=rootNode.host;}
return this.uiService.getActiveElementOf(target)===this.activeEl;}
setTargetElement(target){if(!target){return;}
target.ariaExpanded=false;const optionalClasses=[];const requiredClasses=[];optionalClasses.push("o-dropdown");if(this.hasParent){requiredClasses.push("o-dropdown--has-parent");}
const tagName=target.tagName.toLowerCase();if(!["input","textarea","table","thead","tbody","tr","th","td"].includes(tagName)){optionalClasses.push("dropdown-toggle");if(this.hasParent){optionalClasses.push("o-dropdown-item","dropdown-item");requiredClasses.push("o-navigable");if(!target.classList.contains("o-dropdown--no-caret")){requiredClasses.push("o-dropdown-caret");}}}
target.classList.add(...requiredClasses);if(!this.props.noClasses){target.classList.add(...optionalClasses);}
this.defaultDirection=this.position.split("-")[0];this.setTargetDirectionClass(this.defaultDirection);if(!this.props.manual){target.addEventListener("click",this.handleClick.bind(this));target.addEventListener("mouseenter",this.handleMouseEnter.bind(this));return()=>{target.removeEventListener("click",this.handleClick.bind(this));target.removeEventListener("mouseenter",this.handleMouseEnter.bind(this));};}}
setTargetDirectionClass(direction){if(!this.target||this.props.noClasses){return;}
const directionClasses={bottom:"dropdown",top:"dropup",left:"dropstart",right:"dropend",};this.target.classList.remove(...Object.values(directionClasses));this.target.classList.add(directionClasses[direction]);}
openPopover(){if(this.popover.isOpen||status(this)!=="mounted"){return;}
if(!this.target||!this.target.isConnected){this.state.close();return;}
this.popoverRefresher=reactive({token:0});const props={beforeOpen:()=>this.props.beforeOpen?.(),onOpened:()=>this.onOpened(),onClosed:()=>this.onClosed(),refresher:this.popoverRefresher,items:this.props.items,slots:this.props.slots,};this.popover.open(this.target,props);}
closePopover(){this.popover.close();if(this.props.focusToggleOnClosed&&!this.group.isInGroup){this._focusedElBeforeOpen?.focus();this._focusedElBeforeOpen=undefined;}}
onOpened(){this._focusedElBeforeOpen=document.activeElement;this.activeEl=this.uiService.activeElement;this.navigation.registerHotkeys();this.navigation.update();this.props.onOpened?.();this.props.onStateChanged?.(true);if(this.target){this.target.ariaExpanded=true;this.target.classList.add("show");}
const menuEl=this.menuRef.el;if(menuEl){this.observer=new MutationObserver(()=>this.navigation.update());this.observer.observe(menuEl,{childList:true,subtree:true,});}}
onClosed(){this.navigation.unregisterHotkeys();this.navigation.update();this.props.onStateChanged?.(false);delete this.activeEl;if(this.target){this.target.ariaExpanded=false;this.target.classList.remove("show");this.setTargetDirectionClass(this.defaultDirection);}
if(this.observer){this.observer.disconnect();this.observer=null;}}}
return __exports;});;
/* /web/static/src/core/dropdown/dropdown_group.js */
odoo.define('@web/core/dropdown/dropdown_group',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component,onWillDestroy,useChildSubEnv,xml}=require("@odoo/owl");const GROUPS=new Map();function getGroup(id){if(!GROUPS.has(id)){GROUPS.set(id,{group:new Set(),count:0,});}
GROUPS.get(id).count++;return GROUPS.get(id).group;}
function removeGroup(id){const groupData=GROUPS.get(id);groupData.count--;if(groupData.count<=0){GROUPS.delete(id);}}
const DROPDOWN_GROUP=__exports.DROPDOWN_GROUP=Symbol("dropdownGroup");const DropdownGroup=__exports.DropdownGroup=class DropdownGroup extends Component{static template=xml`<t t-slot="default"/>`;static props={group:{type:String,optional:true},slots:Object,};setup(){if(this.props.group){const group=getGroup(this.props.group);onWillDestroy(()=>removeGroup(this.props.group));useChildSubEnv({[DROPDOWN_GROUP]:group});}else{useChildSubEnv({[DROPDOWN_GROUP]:new Set()});}}}
return __exports;});;
/* /web/static/src/core/dropdown/dropdown_hooks.js */
odoo.define('@web/core/dropdown/dropdown_hooks',['@odoo/owl','@web/core/dropdown/_behaviours/dropdown_nesting','@web/core/utils/reactive'],function(require){'use strict';let __exports={};const{useEnv,useState}=require("@odoo/owl");const{DROPDOWN_NESTING}=require("@web/core/dropdown/_behaviours/dropdown_nesting");const{Reactive}=require("@web/core/utils/reactive");const DropdownState=__exports.DropdownState=class DropdownState extends Reactive{isOpen=false;constructor({onOpen,onClose}={}){super();this._onOpen=onOpen;this._onClose=onClose;}
open(){this.isOpen=true;this._onOpen?.();}
close(){this.isOpen=false;this._onClose?.();}}
__exports.useDropdownState=useDropdownState;function useDropdownState({onOpen,onClose}={}){return useState(new DropdownState({onOpen,onClose}));}
__exports.useDropdownCloser=useDropdownCloser;function useDropdownCloser(){const env=useEnv();const dropdown=env[DROPDOWN_NESTING];return{close:()=>dropdown?.close(),closeChildren:()=>dropdown?.closeChildren(),closeAll:()=>dropdown?.closeAllParents(),};}
return __exports;});;
/* /web/static/src/core/dropdown/dropdown_item.js */
odoo.define('@web/core/dropdown/dropdown_item',['@odoo/owl','@web/core/dropdown/dropdown_hooks'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{useDropdownCloser}=require("@web/core/dropdown/dropdown_hooks");const ClosingMode={None:"none",ClosestParent:"closest",AllParents:"all",};const DropdownItem=__exports.DropdownItem=class DropdownItem extends Component{static template="web.DropdownItem";static props={tag:{type:String,optional:true,},class:{type:[String,Object],optional:true,},onSelected:{type:Function,optional:true,},closingMode:{type:ClosingMode,optional:true,},attrs:{type:Object,optional:true,},slots:{Object,optional:true},};static defaultProps={closingMode:ClosingMode.AllParents,attrs:{},};setup(){this.dropdownControl=useDropdownCloser();}
onClick(ev){if(this.props.attrs&&this.props.attrs.href){ev.preventDefault();}
this.props.onSelected?.(ev);switch(this.props.closingMode){case ClosingMode.ClosestParent:this.dropdownControl.close();break;case ClosingMode.AllParents:this.dropdownControl.closeAll();break;}}}
return __exports;});;
/* /web/static/src/core/dropzone/dropzone.js */
odoo.define('@web/core/dropzone/dropzone',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component,useEffect,useRef,useState}=require("@odoo/owl");const Dropzone=__exports.Dropzone=class Dropzone extends Component{static props={extraClass:{type:String,optional:true},onDrop:{type:Function,optional:true},ref:[Object,Function],slots:{type:Object,optional:true},};static template="web.Dropzone";setup(){super.setup();this.root=useRef("root");this.state=useState({isDraggingInside:false,});useEffect(()=>{const{top,left,width,height}=this.props.ref.el.getBoundingClientRect();this.root.el.style=`top:${top}px;left:${left}px;width:${width}px;height:${height}px;`;});}}
return __exports;});;
/* /web/static/src/core/dropzone/dropzone_hook.js */
odoo.define('@web/core/dropzone/dropzone_hook',['@web/core/dropzone/dropzone','@odoo/owl','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Dropzone}=require("@web/core/dropzone/dropzone");const{useEffect,useExternalListener}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");__exports.useCustomDropzone=useCustomDropzone;function useCustomDropzone(targetRef,dropzoneComponent,dropzoneComponentProps,isDropzoneEnabled=()=>true){const overlayService=useService("overlay");const uiService=useService("ui");let dragCount=0;let hasTarget=false;let removeDropzone=false;useExternalListener(document,"dragenter",onDragEnter,{capture:true});useExternalListener(document,"dragleave",onDragLeave,{capture:true});useExternalListener(window,"dragover",(ev)=>{if(ev.dataTransfer&&ev.dataTransfer.types.includes("Files")){ev.preventDefault();}});useExternalListener(window,"drop",(ev)=>{if(ev.dataTransfer&&ev.dataTransfer.types.includes("Files")){ev.preventDefault();}
dragCount=0;updateDropzone();},{capture:true});function updateDropzone(){const hasDropzone=!!removeDropzone;const isTargetInActiveElement=uiService.activeElement.contains(targetRef.el);const shouldDisplayDropzone=dragCount&&hasTarget&&isTargetInActiveElement&&isDropzoneEnabled();if(shouldDisplayDropzone&&!hasDropzone){removeDropzone=overlayService.add(dropzoneComponent,{ref:targetRef,...dropzoneComponentProps});}
if(!shouldDisplayDropzone&&hasDropzone){removeDropzone();removeDropzone=false;}}
function onDragEnter(ev){if(dragCount||(ev.dataTransfer&&ev.dataTransfer.types.includes("Files"))){dragCount++;updateDropzone();}}
function onDragLeave(){if(dragCount){dragCount--;updateDropzone();}}
useEffect((el)=>{hasTarget=!!el;updateDropzone();},()=>[targetRef.el]);}
__exports.useDropzone=useDropzone;function useDropzone(targetRef,onDrop,extraClass,isDropzoneEnabled=()=>true){const dropzoneComponent=Dropzone;const dropzoneComponentProps={extraClass,onDrop};useCustomDropzone(targetRef,dropzoneComponent,dropzoneComponentProps,isDropzoneEnabled);}
return __exports;});;
/* /web/static/src/core/effects/effect_service.js */
odoo.define('@web/core/effects/effect_service',['@web/core/l10n/translation','@web/core/registry','@web/core/user','@web/core/effects/rainbow_man'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{registry}=require("@web/core/registry");const{user}=require("@web/core/user");const{RainbowMan}=require("@web/core/effects/rainbow_man");const effectRegistry=registry.category("effects");function rainbowMan(env,params={}){let message=params.message;if(message instanceof Element){console.log("Providing an HTML element to an effect is deprecated. Note that all event handlers will be lost.");message=message.outerHTML;}else if(!message){message=_t("Well Done!");}
if(user.showEffect){const props={imgUrl:params.img_url||"/web/static/img/smile.svg",fadeout:params.fadeout||"medium",message,Component:params.Component,props:params.props,};return{Component:RainbowMan,props};}
env.services.notification.add(message);}
effectRegistry.add("rainbow_man",rainbowMan);const effectService=__exports.effectService={dependencies:["overlay"],start(env,{overlay}){const add=(params={})=>{const type=params.type||"rainbow_man";const effect=effectRegistry.get(type);const{Component,props}=effect(env,params)||{};if(Component){const remove=overlay.add(Component,{...props,close:()=>remove(),});}};return{add};},};registry.category("services").add("effect",effectService);return __exports;});;
/* /web/static/src/core/effects/rainbow_man.js */
odoo.define('@web/core/effects/rainbow_man',['@web/core/browser/browser','@odoo/owl'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{Component,useEffect,useExternalListener,useState}=require("@odoo/owl");const RainbowMan=__exports.RainbowMan=class RainbowMan extends Component{static template="web.RainbowMan";static rainbowFadeouts={slow:4500,medium:3500,fast:2000,no:false};static props={fadeout:String,close:Function,message:String,imgUrl:String,Component:{type:Function,optional:true},props:{type:Object,optional:true},};setup(){useExternalListener(document.body,"click",this.closeRainbowMan);this.state=useState({isFading:false});this.delay=RainbowMan.rainbowFadeouts[this.props.fadeout];if(this.delay){useEffect(()=>{const timeout=browser.setTimeout(()=>{this.state.isFading=true;},this.delay);return()=>browser.clearTimeout(timeout);},()=>[]);}}
onAnimationEnd(ev){if(this.delay&&ev.animationName==="reward-fading-reverse"){ev.stopPropagation();this.closeRainbowMan();}}
closeRainbowMan(){this.props.close();}}
return __exports;});;
/* /web/static/src/core/emoji_picker/emoji_picker.js */
odoo.define('@web/core/emoji_picker/emoji_picker',['@web/core/utils/misc','@odoo/owl','@web/core/assets','@web/core/l10n/translation','@web/core/popover/popover_hook','@web/core/utils/search','@web/core/utils/hooks','@web/core/browser/feature_detection','@web/core/utils/concurrency','@web/core/dialog/dialog','@web/core/templates'],function(require){'use strict';let __exports={};const{markEventHandled}=require("@web/core/utils/misc");const{App,Component,onMounted,onPatched,onWillPatch,onWillStart,onWillUnmount,reactive,useComponent,useEffect,useExternalListener,useRef,useState,xml,}=require("@odoo/owl");const{loadBundle}=require("@web/core/assets");const{__not_defined__,appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{usePopover}=require("@web/core/popover/popover_hook");const{fuzzyLookup}=require("@web/core/utils/search");const{useAutofocus,useService}=require("@web/core/utils/hooks");const{isMobileOS}=require("@web/core/browser/feature_detection");const{Deferred}=require("@web/core/utils/concurrency");const{Dialog}=require("@web/core/dialog/dialog");const{getTemplate}=require("@web/core/templates");__exports.useEmojiPicker=useEmojiPicker;function useEmojiPicker(...args){return usePicker(EmojiPicker,...args);}
const loader=__exports.loader=reactive({loadEmoji:()=>loadBundle("web.assets_emoji"),loaded:undefined,});__exports.loadEmoji=loadEmoji;async function loadEmoji(){const res={categories:[],emojis:[]};try{await loader.loadEmoji();const{getCategories,getEmojis}=odoo.loader.modules.get("@web/core/emoji_picker/emoji_data");res.categories=getCategories();res.emojis=getEmojis();return res;}catch{return res;}finally{if(!loader.loaded){const emojiValueToShortcodes={};for(const emoji of res.emojis){emojiValueToShortcodes[emoji.codepoints]=emoji.shortcodes;}
loader.loaded={emojiValueToShortcodes,emojiRegex:new RegExp(Object.keys(emojiValueToShortcodes).length?Object.keys(emojiValueToShortcodes).map((c)=>c.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&")).sort((a,b)=>b.length-a.length).join("|"):/(?!)/,"gu"),};}}}
const PICKER_PROPS=__exports.PICKER_PROPS=["PickerComponent?","close?","onClose?","onSelect","state?","storeScroll?","mobile?",];const EmojiPicker=__exports.EmojiPicker=class EmojiPicker extends Component{static props=[...PICKER_PROPS,"class?","initialSearchTerm?"];static template="web.EmojiPicker";categories=null;emojis=null;shouldScrollElem=null;lastSearchTerm;keyboardNavigated=false;setup(){this.gridRef=useRef("emoji-grid");this.navbarRef=useRef("navbar");this.ui=useService("ui");this.isMobileOS=isMobileOS();this.state=useState({activeEmojiIndex:0,categoryId:null,searchTerm:this.props.initialSearchTerm??"",hoveredEmoji:undefined,});this.frequentEmojiService=useService("web.frequent.emoji");useAutofocus();onWillStart(async()=>{const{categories,emojis}=await loadEmoji();this.categories=categories;this.emojis=emojis;this.emojiByCodepoints=Object.fromEntries(this.emojis.map((emoji)=>[emoji.codepoints,emoji]));this.recentCategory={name:"Frequently used",displayName:_t("Frequently used"),title:"🕓",sortId:0,};this.state.categoryId=this.recentEmojis.length?this.recentCategory.sortId:this.categories[0].sortId;});onMounted(()=>{if(this.emojis.length===0){return;}
this.navbarResizeObserver=new ResizeObserver(()=>this.adaptNavbar());this.navbarResizeObserver.observe(this.navbarRef.el);this.adaptNavbar();this.highlightActiveCategory();if(this.props.storeScroll){this.gridRef.el.scrollTop=this.props.storeScroll.get();}
this.state.hoveredEmoji=this.activeEmoji;});onPatched(()=>{if(this.emojis.length===0){return;}
if(this.shouldScrollElem){this.shouldScrollElem=false;const getElement=()=>this.gridRef.el.querySelector(`.o-EmojiPicker-category[data-category="${this.state.categoryId}"`);const elem=getElement();if(elem){elem.scrollIntoView();}else{this.shouldScrollElem=getElement;}}});useEffect(()=>this.updateEmojiPickerRepr(),()=>[this.state.categoryId,this.state.searchTerm]);useEffect((el)=>{const gridEl=this.gridRef.el;const activeEl=gridEl?.querySelector(".o-Emoji.o-active");if(!gridEl){return;}
if(activeEl&&this.keyboardNavigated&&!isElementVisible(activeEl,gridEl)){activeEl.scrollIntoView({block:"center",behavior:"instant"});this.keyboardNavigated=false;}
this.state.hoveredEmoji=this.activeEmoji;},()=>[this.state.activeEmojiIndex,this.gridRef.el]);useEffect(()=>{if(!this.gridRef.el){return;}
if(this.searchTerm){this.gridRef.el.scrollTop=0;this.state.categoryId=null;}else{if(this.lastSearchTerm){this.gridRef.el.scrollTop=0;}
this.highlightActiveCategory();}
this.lastSearchTerm=this.searchTerm;},()=>[this.searchTerm]);onWillUnmount(()=>{this.navbarResizeObserver?.disconnect();if(!this.gridRef.el){return;}
if(this.props.storeScroll){this.props.storeScroll.set(this.gridRef.el.scrollTop);}});}
adaptNavbar(){if(!this.navbarRef.el){return;}
const computedStyle=getComputedStyle(this.navbarRef.el);const availableWidth=this.navbarRef.el.getBoundingClientRect().width-
parseInt(computedStyle.paddingLeft)-
parseInt(computedStyle.marginLeft)-
parseInt(computedStyle.paddingLeft)-
parseInt(computedStyle.marginLeft);const itemWidth=this.navbarRef.el.querySelector(".o-Emoji").getBoundingClientRect().width;const gapWidth=parseInt(computedStyle.gap);const maxAvailableNavbarItemAmountAtOnce=Math.floor(availableWidth/(itemWidth+gapWidth));const repr=[];let panel=[];const allCategories=this.getAllCategories();for(const category of allCategories){if(panel.length===maxAvailableNavbarItemAmountAtOnce-1&&category!==allCategories.at(-1)){panel.push("next");repr.push(panel);panel=[];panel.push("previous");}
panel.push(category.sortId);}
if(panel.length>0){if(repr.length>0){panel.push(...[...Array(maxAvailableNavbarItemAmountAtOnce-panel.length)].map((_,idx)=>"empty_"+idx));}
repr.push(panel);}
this.state.emojiNavbarRepr=repr;}
get currentNavbarPanel(){if(!this.state.emojiNavbarRepr){return this.getAllCategories().map((c)=>c.sortId);}
if(this.state.categoryId===null||Number.isNaN(this.state.categoryId)){return this.state.emojiNavbarRepr[0];}
return this.state.emojiNavbarRepr.find((panel)=>panel.includes(this.state.categoryId));}
get searchTerm(){return this.props.state?this.props.state.searchTerm:this.state.searchTerm;}
set searchTerm(value){if(this.props.state){this.props.state.searchTerm=value;}else{this.state.searchTerm=value;}}
get itemsNumber(){return this.recentEmojis.length+this.getEmojis().length;}
get recentEmojis(){const recent=Object.entries(this.frequentEmojiService.all).sort(([,usage_1],[,usage_2])=>usage_2-usage_1).map(([codepoints])=>this.emojiByCodepoints[codepoints]);if(this.searchTerm&&recent.length>0){return fuzzyLookup(this.searchTerm,recent,(emoji)=>[emoji.name,...emoji.keywords,...emoji.emoticons,...emoji.shortcodes,]);}
return recent.slice(0,42);}
get placeholder(){return this.state.hoveredEmoji?.shortcodes.join(" ")??_t("Search emoji");}
onMouseenterEmoji(ev,emoji){this.state.hoveredEmoji=emoji;}
onMouseleaveEmoji(ev,emoji){this.state.hoveredEmoji=this.activeEmoji;}
onClick(ev){markEventHandled(ev,"emoji.selectEmoji");}
onClickToNextCategories(){const panelIndex=this.state.emojiNavbarRepr.findIndex((p)=>p.includes(this.state.categoryId));this.selectCategory(this.state.emojiNavbarRepr[panelIndex+1][1]);}
onClickToPreviousCategories(){const panelIndex=this.state.emojiNavbarRepr.findIndex((p)=>p.includes(this.state.categoryId));this.selectCategory(this.state.emojiNavbarRepr[panelIndex-1].at(-2));}
updateEmojiPickerRepr(){if(this.emojis.length===0){return;}
const emojiEls=Array.from(this.gridRef.el.querySelectorAll(".o-Emoji"));const emojiRects=emojiEls.map((el)=>el.getBoundingClientRect());this.emojiMatrix=[];for(const[index,pos]of emojiRects.entries()){const emojiIndex=emojiEls[index].dataset.index;if(this.emojiMatrix.length===0||pos.top>emojiRects[index-1].top){this.emojiMatrix.push([]);}
this.emojiMatrix.at(-1).push(parseInt(emojiIndex));}}
handleNavigation(key){const currentIdx=this.state.activeEmojiIndex;let currentRow=-1;let currentCol=-1;const rowIdx=this.emojiMatrix.findIndex((row)=>row.includes(currentIdx));if(rowIdx!==-1){currentRow=rowIdx;currentCol=this.emojiMatrix[currentRow].indexOf(currentIdx);}
let newIdx;switch(key){case"ArrowDown":{const rowBelow=this.emojiMatrix[currentRow+1];const rowBelowBelow=this.emojiMatrix[currentRow+2];if(rowBelow?.length<=currentCol&&rowBelowBelow?.length>=currentCol){newIdx=rowBelowBelow?.[currentCol];}else{newIdx=rowBelow?.[Math.min(currentCol,rowBelow.length-1)];}
break;}
case"ArrowUp":{const rowAbove=this.emojiMatrix[currentRow-1];const rowAboveAbove=this.emojiMatrix[currentRow-2];if(rowAbove?.length<=currentCol&&rowAboveAbove?.length>=currentCol){newIdx=rowAboveAbove?.[currentCol];}else{newIdx=rowAbove?.[Math.min(currentCol,rowAbove.length-1)];}
break;}
case"ArrowRight":{const colRight=currentCol+1;if(colRight===this.emojiMatrix[currentRow]?.length){const rowBelowRight=this.emojiMatrix[currentRow+1];newIdx=rowBelowRight?.[0];}else{newIdx=this.emojiMatrix[currentRow]?.[colRight];}
break;}
case"ArrowLeft":{const colLeft=currentCol-1;if(colLeft<0){const rowAboveLeft=this.emojiMatrix[currentRow-1];newIdx=rowAboveLeft?.[rowAboveLeft.length-1]??this.state.activeEmojiIndex;}else{newIdx=this.emojiMatrix[currentRow][colLeft];}
break;}}
this.state.activeEmojiIndex=newIdx??this.state.activeEmojiIndex;}
get activeEmoji(){const activeCodepoints=this.gridRef.el.querySelector(`.o-EmojiPicker-content .o-Emoji[data-index="${this.state.activeEmojiIndex}"]`)?.dataset.codepoints;return activeCodepoints?this.emojiByCodepoints[activeCodepoints]:undefined;}
onKeydown(ev){switch(ev.key){case"ArrowDown":case"ArrowUp":case"ArrowRight":case"ArrowLeft":this.handleNavigation(ev.key);this.keyboardNavigated=true;break;case"Enter":ev.preventDefault();this.gridRef.el?.querySelector(`.o-EmojiPicker-content .o-Emoji[data-index="${this.state.activeEmojiIndex}"]`)?.click();break;case"Escape":this.props.close?.();this.props.onClose?.();ev.stopPropagation();}}
getAllCategories(){const res=[...this.categories];if(this.recentEmojis.length>0){res.unshift(this.recentCategory);}
return res;}
getEmojis(){let emojisToDisplay=[...this.emojis];const recentEmojis=this.recentEmojis;if(recentEmojis.length>0&&this.searchTerm){emojisToDisplay=emojisToDisplay.filter((emoji)=>!recentEmojis.includes(emoji));}
if(this.searchTerm.length>0){return fuzzyLookup(this.searchTerm,emojisToDisplay,(emoji)=>[emoji.name,...emoji.keywords,...emoji.emoticons,...emoji.shortcodes,]);}
return emojisToDisplay;}
getEmojisFromSearch(){return[...this.recentEmojis,...this.getEmojis()];}
selectCategory(categoryId){this.searchTerm="";this.state.categoryId=categoryId;this.shouldScrollElem=true;}
selectEmoji(ev){const codepoints=ev.currentTarget.dataset.codepoints;let resetOnSelect=!ev.shiftKey;const res=this.props.onSelect(codepoints,resetOnSelect);if(res===false){resetOnSelect=false;}
this.frequentEmojiService.incrementEmojiUsage(codepoints);if(resetOnSelect){this.gridRef.el.scrollTop=0;this.props.close?.();this.props.onClose?.();}}
highlightActiveCategory(){if(!this.gridRef||!this.gridRef.el){return;}
const coords=this.gridRef.el.getBoundingClientRect();const res=document.elementFromPoint(coords.x+10,coords.y+10);if(!res){return;}
this.state.categoryId=parseInt(res.dataset.category);}}
__exports.usePicker=usePicker;function usePicker(PickerComponent,ref,props,options={}){const component=useComponent();const targets=[];const state=useState({isOpen:false});const ui=useService("ui");const dialog=useService("dialog");let remove;const newOptions={...options,onClose:()=>{state.isOpen=false;props.onClose?.();},};const popover=usePopover(PickerComponent,{...newOptions,animation:false,popoverClass:options.popoverClass??""+" bg-100 border border-secondary",});props.storeScroll={scrollValue:0,set:(value)=>{props.storeScroll.scrollValue=value;},get:()=>props.storeScroll.scrollValue,};function add(ref,onSelect,{show=false}={}){const toggler=()=>toggle(isMobileOS()?undefined:ref,onSelect);targets.push([ref,toggler]);if(!ref.el){return;}
ref.el.addEventListener("click",toggler);ref.el.addEventListener("mouseenter",loadEmoji);if(show){ref.el.click();}}
function open(ref,openProps){state.isOpen=true;if(ui.isSmall||isMobileOS()){const def=new Deferred();const pickerMobileProps={PickerComponent,onSelect:(...args)=>{const func=openProps?.onSelect??props?.onSelect;const res=func?.(...args);def.resolve(true);return res;},};if(ref?.el){pickerMobileProps.close=()=>remove();const app=new App(PickerMobile,{name:"Popout",env:component.env,props:pickerMobileProps,getTemplate,translatableAttributes:["data-tooltip"],translateFn:appTranslateFn,});app.mount(ref.el);remove=()=>{state.isOpen=false;props.onClose?.();app.destroy();};}else{remove=dialog.add(PickerMobileInDialog,pickerMobileProps,{context:component,onClose:()=>{state.isOpen=false;props.onClose?.();return def.resolve(false);},});}
return def;}
return popover.open(ref.el,{...props,...openProps});}
function close(){remove?.();popover.close?.();}
function toggle(ref,onSelect=props.onSelect){if(state.isOpen){close();}else{open(ref,{...props,onSelect});}}
if(ref){add(ref);}
onMounted(()=>{for(const[ref,toggle]of targets){if(!ref.el){continue;}
ref.el.addEventListener("click",toggle);ref.el.addEventListener("mouseenter",loadEmoji);}});onWillPatch(()=>{for(const[ref,toggle]of targets){if(!ref.el){continue;}
ref.el.removeEventListener("click",toggle);ref.el.removeEventListener("mouseenter",loadEmoji);}});onPatched(()=>{for(const[ref,toggle]of targets){if(!ref.el){continue;}
ref.el.addEventListener("click",toggle);ref.el.addEventListener("mouseenter",loadEmoji);}});Object.assign(state,{open,close,toggle});return state;}
class PickerMobile extends Component{static props=[...PICKER_PROPS,"onClose?"];static template=xml`
<t t-component="props.PickerComponent" t-props="pickerProps"/>
`;get pickerProps(){return{...this.props,onSelect:(...args)=>this.props.onSelect(...args),mobile:true,};}}
class PickerMobileInDialog extends PickerMobile{static components={Dialog};static props=[...PICKER_PROPS,"onClose?"];static template=xml`
<Dialog size="'lg'" header="false" footer="false" contentClass="'o-discuss-mobileContextMenu d-flex position-absolute bottom-0 rounded-0 h-50 bg-100'" bodyClass="'p-1'">
<div class="h-100" t-ref="root">
<t t-component="props.PickerComponent" t-props="pickerProps"/>
</div>
</Dialog>
`;setup(){super.setup();this.root=useRef("root");useExternalListener(window,"click",(ev)=>{if(ev.target!==this.root.el&&!this.root.el.contains(ev.target)){this.props.close?.();}},{capture:true});}}
function isElementVisible(el,holder){const offset=20;holder=holder||document.body;const{top,bottom,height}=el.getBoundingClientRect();let{top:holderTop,bottom:holderBottom}=holder.getBoundingClientRect();holderTop+=offset*2;holderBottom-=offset;return top-offset<=holderTop?holderTop-top<=height:bottom-holderBottom<=height;}
return __exports;});;
/* /web/static/src/core/emoji_picker/frequent_emoji_service.js */
odoo.define('@web/core/emoji_picker/frequent_emoji_service',['@odoo/owl','@web/core/browser/browser','@web/core/registry'],function(require){'use strict';let __exports={};const{reactive}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const frequentEmojiService=__exports.frequentEmojiService={start(){const state=reactive({all:JSON.parse(browser.localStorage.getItem("web.emoji.frequent")||"{}"),incrementEmojiUsage(codepoints){state.all[codepoints]??=0;state.all[codepoints]++;browser.localStorage.setItem("web.emoji.frequent",JSON.stringify(state.all));},getMostFrequent(limit){return Object.entries(state.all).sort(([,usage_1],[,usage_2])=>usage_2-usage_1).slice(0,limit??Infinity).map(([codepoints])=>codepoints);},});browser.addEventListener("storage",(ev)=>{if(ev.key==="web.emoji.frequent"){state.all=ev.newValue?JSON.parse(ev.newValue):{};}else if(ev.key===null){state.all={};}});return state;},};registry.category("services").add("web.frequent.emoji",frequentEmojiService);return __exports;});;
/* /web/static/src/core/ensure_jquery.js */
odoo.define('@web/core/ensure_jquery',['@web/core/assets'],function(require){'use strict';let __exports={};const{loadBundle,loadJS}=require("@web/core/assets");__exports.ensureJQuery=ensureJQuery;async function ensureJQuery(){if(!window.jQuery){await loadBundle("web._assets_jquery");const BTS_CLASSES=["Carousel","Dropdown","Modal","Popover","Tooltip","Collapse"];const $=window.jQuery;for(const CLS of BTS_CLASSES){const plugin=window[CLS];if(plugin){const name=plugin.NAME;const JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface;$.fn[name].Constructor=plugin;$.fn[name].noConflict=()=>{$.fn[name]=JQUERY_NO_CONFLICT;return plugin.jQueryInterface;};}}}else if(!window.jQuery.fn.getScrollingElement){await loadJS("/web/static/src/legacy/js/libs/jquery.js");}}
return __exports;});;
/* /web/static/src/core/errors/error_dialogs.js */
odoo.define('@web/core/errors/error_dialogs',['@web/core/browser/browser','@web/core/dialog/dialog','@web/core/l10n/translation','@web/core/registry','@web/core/tooltip/tooltip','@web/core/popover/popover_hook','@web/core/utils/hooks','@web/core/utils/strings','@odoo/owl'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{Dialog}=require("@web/core/dialog/dialog");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{registry}=require("@web/core/registry");const{Tooltip}=require("@web/core/tooltip/tooltip");const{usePopover}=require("@web/core/popover/popover_hook");const{useService}=require("@web/core/utils/hooks");const{capitalize}=require("@web/core/utils/strings");const{Component,useRef,useState,markup}=require("@odoo/owl");const{DateTime}=luxon;const standardErrorDialogProps=__exports.standardErrorDialogProps={traceback:{type:[String,{value:null}],optional:true},message:{type:String,optional:true},name:{type:String,optional:true},exceptionName:{type:[String,{value:null}],optional:true},data:{type:[Object,{value:null}],optional:true},subType:{type:[String,{value:null}],optional:true},code:{type:[Number,String,{value:null}],optional:true},type:{type:[String,{value:null}],optional:true},serverHost:{type:[String,{value:null}],optional:true},id:{type:[Number,{value:null}],optional:true},model:{type:[String,{value:null}],optional:true},close:Function,};const odooExceptionTitleMap=__exports.odooExceptionTitleMap=new Map(Object.entries({"odoo.addons.base.models.ir_mail_server.MailDeliveryException":_t("MailDeliveryException"),"odoo.exceptions.AccessDenied":_t("Access Denied"),"odoo.exceptions.MissingError":_t("Missing Record"),"odoo.addons.web.controllers.action.MissingActionError":_t("Missing Action"),"odoo.addons.base.models.ir_actions.ServerActionWithWarningsError":_t("Invalid Operation"),"odoo.exceptions.UserError":_t("Invalid Operation"),"odoo.exceptions.ValidationError":_t("Validation Error"),"odoo.exceptions.AccessError":_t("Access Error"),"odoo.exceptions.Warning":_t("Warning"),}));const ErrorDialog=__exports.ErrorDialog=class ErrorDialog extends Component{static template="web.ErrorDialog";static components={Dialog};static title=_t("Odoo Error");static showTracebackButtonText=_t("See technical details");static hideTracebackButtonText=_t("Hide technical details");static props={...standardErrorDialogProps};setup(){this.state=useState({showTraceback:false,});this.copyButtonRef=useRef("copyButton");this.popover=usePopover(Tooltip);this.contextDetails="Occured ";if(this.props.serverHost){this.contextDetails+=`on ${this.props.serverHost} `;}
if(this.props.model){this.contextDetails+=`on model ${this.props.model} `;}
this.contextDetails+=`on ${DateTime.now()
.setZone("UTC")
.toFormat("yyyy-MM-dd HH:mm:ss")} GMT`;}
showTooltip(){this.popover.open(this.copyButtonRef.el,{tooltip:_t("Copied")});browser.setTimeout(this.popover.close,800);}
onClickClipboard(){browser.navigator.clipboard.writeText(`${this.props.name}\n\n${this.props.message}\n\n${this.contextDetails}\n\n${this.props.traceback}`);this.showTooltip();}}
const ClientErrorDialog=__exports.ClientErrorDialog=class ClientErrorDialog extends ErrorDialog{}
ClientErrorDialog.title=_t("Odoo Client Error");const NetworkErrorDialog=__exports.NetworkErrorDialog=class NetworkErrorDialog extends ErrorDialog{}
NetworkErrorDialog.title=_t("Odoo Network Error");const RequestEntityTooLargeErrorDialog=__exports.RequestEntityTooLargeErrorDialog=class RequestEntityTooLargeErrorDialog extends ErrorDialog{}
RequestEntityTooLargeErrorDialog.title=_t("The request sent to the server was too large");const RPCErrorDialog=__exports.RPCErrorDialog=class RPCErrorDialog extends ErrorDialog{setup(){super.setup();this.inferTitle();this.traceback=this.props.traceback;if(this.props.data&&this.props.data.debug){this.traceback=`${this.props.data.debug}\nThe above server error caused the following client error:\n${this.traceback}`;}}
inferTitle(){if(this.props.exceptionName&&odooExceptionTitleMap.has(this.props.exceptionName)){this.title=odooExceptionTitleMap.get(this.props.exceptionName).toString();return;}
if(!this.props.type){return;}
switch(this.props.type){case"server":this.title=_t("Odoo Server Error");break;case"script":this.title=_t("Odoo Client Error");break;case"network":this.title=_t("Odoo Network Error");break;}}
onClickClipboard(){browser.navigator.clipboard.writeText(`${this.props.name}\n\n${this.props.message}\n\n${this.contextDetails}\n\n${this.traceback}`);this.showTooltip();}}
const WarningDialog=__exports.WarningDialog=class WarningDialog extends Component{static template="web.WarningDialog";static components={Dialog};static props={...standardErrorDialogProps,title:{type:String,optional:true},};setup(){this.title=this.inferTitle();const{data,message}=this.props;if(data&&data.arguments&&data.arguments.length>0){this.message=data.arguments[0];}else{this.message=message;}}
inferTitle(){if(this.props.exceptionName&&odooExceptionTitleMap.has(this.props.exceptionName)){return odooExceptionTitleMap.get(this.props.exceptionName).toString();}
return this.props.title||_t("Odoo Warning");}}
const RedirectWarningDialog=__exports.RedirectWarningDialog=class RedirectWarningDialog extends Component{static template="web.RedirectWarningDialog";static components={Dialog};static props={...standardErrorDialogProps};setup(){this.actionService=useService("action");const{data,subType}=this.props;const[message,actionId,buttonText,additionalContext]=data.arguments;this.title=capitalize(subType)||_t("Odoo Warning");this.message=message;this.actionId=actionId;this.buttonText=buttonText;this.additionalContext=additionalContext;}
async onClick(){const options={forceLeave:true};if(this.additionalContext){options.additionalContext=this.additionalContext;}
if(this.actionId.help){this.actionId.help=markup(this.actionId.help);}
await this.actionService.doAction(this.actionId,options);this.props.close();}}
const Error504Dialog=__exports.Error504Dialog=class Error504Dialog extends Component{static template="web.Error504Dialog";static components={Dialog};static props={...standardErrorDialogProps};}
const SessionExpiredDialog=__exports.SessionExpiredDialog=class SessionExpiredDialog extends Component{static template="web.SessionExpiredDialog";static components={Dialog};static props={...standardErrorDialogProps};onClick(){browser.location.reload();}}
registry.category("error_dialogs").add("odoo.exceptions.AccessDenied",WarningDialog).add("odoo.exceptions.AccessError",WarningDialog).add("odoo.exceptions.MissingError",WarningDialog).add("odoo.addons.web.controllers.action.MissingActionError",WarningDialog).add("odoo.addons.base.models.ir_actions.ServerActionWithWarningsError",WarningDialog).add("odoo.exceptions.UserError",WarningDialog).add("odoo.exceptions.ValidationError",WarningDialog).add("odoo.exceptions.RedirectWarning",RedirectWarningDialog).add("odoo.http.SessionExpiredException",SessionExpiredDialog).add("werkzeug.exceptions.Forbidden",SessionExpiredDialog).add("504",Error504Dialog);return __exports;});;
/* /web/static/src/core/errors/error_handlers.js */
odoo.define('@web/core/errors/error_handlers',['@web/core/l10n/translation','@web/core/browser/browser','@web/core/network/rpc','@web/core/registry','@web/session','@web/core/user','@web/core/errors/error_dialogs','@web/core/errors/error_service'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{browser}=require("@web/core/browser/browser");const{ConnectionLostError,RPCError,RequestEntityTooLargeError,rpc}=require("@web/core/network/rpc");const{registry}=require("@web/core/registry");const{session}=require("@web/session");const{user}=require("@web/core/user");const{ClientErrorDialog,ErrorDialog,NetworkErrorDialog,RequestEntityTooLargeErrorDialog,RPCErrorDialog,}=require("@web/core/errors/error_dialogs");const{UncaughtClientError,ThirdPartyScriptError,UncaughtPromiseError}=require("@web/core/errors/error_service");const errorHandlerRegistry=registry.category("error_handlers");const errorDialogRegistry=registry.category("error_dialogs");const errorNotificationRegistry=registry.category("error_notifications");__exports.rpcErrorHandler=rpcErrorHandler;function rpcErrorHandler(env,error,originalError){if(!(error instanceof UncaughtPromiseError)){return false;}
if(originalError instanceof RPCError){error.unhandledRejectionEvent.preventDefault();const exceptionName=originalError.exceptionName;let ErrorComponent=originalError.Component;if(!ErrorComponent&&exceptionName){if(errorNotificationRegistry.contains(exceptionName)){const notif=errorNotificationRegistry.get(exceptionName);env.services.notification.add(notif.message||originalError.data.message,notif);return true;}
if(errorDialogRegistry.contains(exceptionName)){ErrorComponent=errorDialogRegistry.get(exceptionName);}}
if(!ErrorComponent&&originalError.data.context){const exceptionClass=originalError.data.context.exception_class;if(errorDialogRegistry.contains(exceptionClass)){ErrorComponent=errorDialogRegistry.get(exceptionClass);}}
env.services.dialog.add(ErrorComponent||RPCErrorDialog,{traceback:error.traceback,message:originalError.message,name:originalError.name,exceptionName:originalError.exceptionName,data:originalError.data,subType:originalError.subType,code:originalError.code,type:originalError.type,serverHost:error.event?.target?.location.host,model:originalError.model,});return true;}}
errorHandlerRegistry.add("rpcErrorHandler",rpcErrorHandler,{sequence:97});let connectionLostNotifRemove=null;__exports.lostConnectionHandler=lostConnectionHandler;function lostConnectionHandler(env,error,originalError){if(!(error instanceof UncaughtPromiseError)){return false;}
if(originalError instanceof ConnectionLostError){if(connectionLostNotifRemove){return true;}
connectionLostNotifRemove=env.services.notification.add(_t("Connection lost. Trying to reconnect..."),{sticky:true});let delay=2000;browser.setTimeout(function checkConnection(){rpc("/web/webclient/version_info",{}).then(function(){if(connectionLostNotifRemove){connectionLostNotifRemove();connectionLostNotifRemove=null;}
env.services.notification.add(_t("Connection restored. You are back online."),{type:"info",});}).catch(()=>{delay=delay*1.5+500*Math.random();browser.setTimeout(checkConnection,delay);});},delay);return true;}}
errorHandlerRegistry.add("lostConnectionHandler",lostConnectionHandler,{sequence:98});__exports.requestEntityTooLargeHandler=requestEntityTooLargeHandler;function requestEntityTooLargeHandler(env,error,originalError){if(!(error instanceof UncaughtPromiseError)){return false;}
if(originalError instanceof RequestEntityTooLargeError){env.services.dialog.add(RequestEntityTooLargeErrorDialog);return true;}}
errorHandlerRegistry.add("requestEntityTooLargeHandler",requestEntityTooLargeHandler,{sequence:99});const defaultDialogs=new Map([[UncaughtClientError,ClientErrorDialog],[UncaughtPromiseError,ClientErrorDialog],[ThirdPartyScriptError,NetworkErrorDialog],]);__exports.defaultHandler=defaultHandler;function defaultHandler(env,error){const DialogComponent=defaultDialogs.get(error.constructor)||ErrorDialog;env.services.dialog.add(DialogComponent,{traceback:error.traceback,message:error.message,name:error.name,serverHost:error.event?.target?.location.host,});return true;}
errorHandlerRegistry.add("defaultHandler",defaultHandler,{sequence:100});__exports.swallowAllVisitorErrors=swallowAllVisitorErrors;function swallowAllVisitorErrors(env,error,originalError){if(!user.isInternalUser&&!odoo.debug&&!session.test_mode){return true;}}
if(user.isInternalUser===undefined){if(session.is_frontend){console.warn("isInternalUser information is required for this handler to work. It must be available in the page.");}}else{registry.category("error_handlers").add("swallowAllVisitorErrors",swallowAllVisitorErrors,{sequence:0});}
return __exports;});;
/* /web/static/src/core/errors/error_service.js */
odoo.define('@web/core/errors/error_service',['@web/core/browser/browser','@web/core/registry','@web/core/errors/error_utils','@web/core/browser/feature_detection'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{completeUncaughtError,getErrorTechnicalName}=require("@web/core/errors/error_utils");const{isBrowserFirefox,isBrowserChrome}=require("@web/core/browser/feature_detection");const HTMLElementLoadingError=__exports.HTMLElementLoadingError=class HTMLElementLoadingError extends Error{static message="Error loading an HTML Element";constructor(message=HTMLElementLoadingError.message,event){super(message);this.event=event;}}
const UncaughtError=__exports.UncaughtError=class UncaughtError extends Error{constructor(message){super(message);this.name=getErrorTechnicalName(this);this.traceback=null;}}
const UncaughtClientError=__exports.UncaughtClientError=class UncaughtClientError extends UncaughtError{constructor(message="Uncaught Javascript Error"){super(message);}}
const UncaughtPromiseError=__exports.UncaughtPromiseError=class UncaughtPromiseError extends UncaughtError{constructor(message="Uncaught Promise"){super(message);this.unhandledRejectionEvent=null;}}
const ThirdPartyScriptError=__exports.ThirdPartyScriptError=class ThirdPartyScriptError extends UncaughtError{constructor(message="Third-Party Script Error"){super(message);}}
const errorService=__exports.errorService={start(env){function handleError(uncaughtError,retry=true){function shouldLogError(){return(uncaughtError.event&&!uncaughtError.event.defaultPrevented&&uncaughtError.traceback);}
let originalError=uncaughtError;while(originalError instanceof Error&&"cause"in originalError){originalError=originalError.cause;}
for(const[name,handler]of registry.category("error_handlers").getEntries()){try{if(handler(env,uncaughtError,originalError)){break;}}catch(e){if(shouldLogError()){uncaughtError.event.preventDefault();console.error(`@web/core/error_service: handler "${name}" failed with "${
e.cause || e
}" while trying to handle:\n`+uncaughtError.traceback);}
return;}}
if(shouldLogError()){uncaughtError.event.preventDefault();console.error(uncaughtError.traceback);}}
browser.addEventListener("error",async(ev)=>{const{colno,error,filename,lineno,message}=ev;const resizeObserverError="ResizeObserver loop completed with undelivered notifications.";if(!(error instanceof Error)&&message===resizeObserverError){ev.preventDefault();return;}
const isRedactedError=!filename&&!lineno&&!colno;const isThirdPartyScriptError=isRedactedError||(isBrowserFirefox()&&new URL(filename).origin!==window.location.origin);if(isThirdPartyScriptError&&!odoo.debug){return;}
let uncaughtError;if(isRedactedError){uncaughtError=new ThirdPartyScriptError();uncaughtError.traceback=`An error whose details cannot be accessed by the Odoo framework has occurred.\n`+`The error probably originates from a JavaScript file served from a different origin.\n`+`The full error is available in the browser console.`;}else{uncaughtError=new UncaughtClientError();uncaughtError.event=ev;if(error instanceof Error){error.errorEvent=ev;const annotated=env.debug&&env.debug.includes("assets");await completeUncaughtError(uncaughtError,error,annotated);}}
uncaughtError.cause=error;handleError(uncaughtError);});browser.addEventListener("unhandledrejection",async(ev)=>{let error=ev.reason;if(error&&error.type==="error"&&"eventPhase"in error){if(!error.bubbles){ev.preventDefault();return;}
let message;if(error.target){message=`${HTMLElementLoadingError.message}: ${error.target.nodeName}`;}
error=new HTMLElementLoadingError(message,error);}
let traceback;if(isBrowserChrome()&&ev instanceof CustomEvent&&error===undefined){if(!odoo.debug){return;}
traceback=`Uncaught unknown Error\n`+`An unknown error occured. This may be due to a Chrome extension meddling with Odoo.\n`+`(Opening your browser console might give you a hint on the error.)`;}
const uncaughtError=new UncaughtPromiseError();uncaughtError.unhandledRejectionEvent=ev;uncaughtError.event=ev;uncaughtError.traceback=traceback;if(error instanceof Error){error.errorEvent=ev;const annotated=env.debug&&env.debug.includes("assets");await completeUncaughtError(uncaughtError,error,annotated);}
uncaughtError.cause=error;handleError(uncaughtError);});},};registry.category("services").add("error",errorService,{sequence:1});return __exports;});;
/* /web/static/src/core/errors/error_utils.js */
odoo.define('@web/core/errors/error_utils',['@web/core/assets'],function(require){'use strict';let __exports={};const{loadJS}=require("@web/core/assets");function combineErrorNames(uncaughtError,originalError){const originalErrorName=getErrorTechnicalName(originalError);const uncaughtErrorName=getErrorTechnicalName(uncaughtError);if(originalErrorName===Error.name){return uncaughtErrorName;}else{return`${uncaughtErrorName} > ${originalErrorName}`;}}
__exports.fullTraceback=fullTraceback;function fullTraceback(error){let traceback=formatTraceback(error);let current=error.cause;while(current){traceback+=`\n\nCaused by: ${
current instanceof Error ? formatTraceback(current) : current
}`;current=current.cause;}
return traceback;}
__exports.fullAnnotatedTraceback=fullAnnotatedTraceback;async function fullAnnotatedTraceback(error){if(error.annotatedTraceback){return error.annotatedTraceback;}
if(error.errorEvent){error.errorEvent.preventDefault();}
let traceback;try{traceback=await annotateTraceback(error);let current=error.cause;while(current){traceback+=`\n\nCaused by: ${
current instanceof Error ? await annotateTraceback(current) : current
}`;current=current.cause;}}catch(e){console.warn("Failed to annotate traceback for error:",error,"failure reason:",e);traceback=fullTraceback(error);}
error.annotatedTraceback=traceback;if(error.errorEvent){throw error;}
return traceback;}
__exports.completeUncaughtError=completeUncaughtError;async function completeUncaughtError(uncaughtError,originalError,annotated=false){uncaughtError.name=combineErrorNames(uncaughtError,originalError);if(annotated){uncaughtError.traceback=await fullAnnotatedTraceback(originalError);}else{uncaughtError.traceback=fullTraceback(originalError);}
if(originalError.message){uncaughtError.message=`${uncaughtError.message} > ${originalError.message}`;}
uncaughtError.cause=originalError;}
__exports.getErrorTechnicalName=getErrorTechnicalName;function getErrorTechnicalName(error){return error.name!==Error.name?error.name:error.constructor.name;}
__exports.formatTraceback=formatTraceback;function formatTraceback(error){let traceback=error.stack;const errorName=getErrorTechnicalName(error);const descriptionLine=`${errorName}: ${error.message}`;if(error.stack.split("\n")[0].trim()!==descriptionLine){traceback=`${descriptionLine}\n${error.stack}`.replace(/\n/g,"\n ");}
return traceback;}
__exports.annotateTraceback=annotateTraceback;async function annotateTraceback(error){const traceback=formatTraceback(error);try{await loadJS("/web/static/lib/stacktracejs/stacktrace.js");}catch{return traceback;}
if(error.stack){const regex=/ line (\d*) > (Function):(\d*)/gm;const subst=`:$1`;error.stack=error.stack.replace(regex,subst);}
let frames;try{frames=await StackTrace.fromError(error);}catch(e){console.warn("The following error could not be annotated:",error,e);return traceback;}
const lines=traceback.split("\n");if(lines[lines.length-1].trim()===""){lines.splice(-1);}
let lineIndex=0;let frameIndex=0;while(frameIndex<frames.length){const line=lines[lineIndex];if(!line.match(/:\d+:\d+\)?$/)){lineIndex++;continue;}
const frame=frames[frameIndex];const info=` (${frame.fileName}:${frame.lineNumber})`;lines[lineIndex]=line+info;lineIndex++;frameIndex++;}
return lines.join("\n");}
return __exports;});;
/* /web/static/src/core/errors/scss_error_dialog.js */
odoo.define('@web/core/errors/scss_error_dialog',['@web/core/browser/browser','@web/core/registry','@web/core/l10n/translation','@web/core/utils/urls'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{appTranslateFn,translationIsReady}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{getOrigin}=require("@web/core/utils/urls");const scssErrorNotificationService={dependencies:["notification"],start(env,{notification}){const origin=getOrigin();if(browser.location.origin==="null"){return;}
const assets=[...document.styleSheets].filter((sheet)=>{return(sheet.href?.includes("/web")&&sheet.href?.includes("/assets/")&&new URL(sheet.href,browser.location.origin).origin===origin);});translationIsReady.then(()=>{for(const asset of assets){let cssRules;try{cssRules=asset.cssRules;}catch{continue;}
const lastRule=cssRules?.[cssRules?.length-1];if(lastRule?.selectorText==="css_error_message"){const message=_t("The style compilation failed. This is an administrator or developer error that must be fixed for the entire database before continuing working. See browser console or server logs for details.");notification.add(message,{title:_t("Style error"),sticky:true,type:"danger",});console.log(lastRule.style.content.replaceAll("\\a","\n").replaceAll("\\*","*").replaceAll(`\\"`,`"`));}}});},};registry.category("services").add("scss_error_display",scssErrorNotificationService);return __exports;});;
/* /web/static/src/core/expression_editor/expression_editor.js */
odoo.define('@web/core/expression_editor/expression_editor',['@odoo/owl','@web/core/expression_editor/expression_editor_operator_editor','@web/core/l10n/translation','@web/core/model_field_selector/model_field_selector','@web/core/tree_editor/condition_tree','@web/core/tree_editor/expression_from_tree','@web/core/tree_editor/tree_editor','@web/core/tree_editor/tree_editor_operator_editor','@web/core/tree_editor/tree_editor_value_editors','@web/core/tree_editor/tree_from_expression','@web/core/tree_editor/utils'],function(require){'use strict';let __exports={};const{Component,onWillStart,onWillUpdateProps}=require("@odoo/owl");const{getExpressionDisplayedOperators}=require("@web/core/expression_editor/expression_editor_operator_editor");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{ModelFieldSelector}=require("@web/core/model_field_selector/model_field_selector");const{condition}=require("@web/core/tree_editor/condition_tree");const{expressionFromTree}=require("@web/core/tree_editor/expression_from_tree");const{TreeEditor}=require("@web/core/tree_editor/tree_editor");const{getOperatorEditorInfo}=require("@web/core/tree_editor/tree_editor_operator_editor");const{getDefaultValue}=require("@web/core/tree_editor/tree_editor_value_editors");const{treeFromExpression}=require("@web/core/tree_editor/tree_from_expression");const{getDefaultPath}=require("@web/core/tree_editor/utils");const ExpressionEditor=__exports.ExpressionEditor=class ExpressionEditor extends Component{static template="web.ExpressionEditor";static components={TreeEditor};static props={resModel:String,fields:Object,expression:String,update:Function,};setup(){onWillStart(()=>this.onPropsUpdated(this.props));onWillUpdateProps((nextProps)=>this.onPropsUpdated(nextProps));}
async onPropsUpdated(props){this.filteredFields=Object.fromEntries(Object.entries(props.fields).filter(([_,fieldDef])=>fieldDef.type!=="properties"));try{this.tree=treeFromExpression(props.expression,{getFieldDef:(name)=>this.getFieldDef(name,props),distributeNot:!this.isDebugMode,generateSmartDates:false,});}catch{this.tree=null;}}
getFieldDef(name,props=this.props){if(typeof name==="string"){return props.fields[name]||null;}
return null;}
getDefaultCondition(){const defaultPath=getDefaultPath(this.filteredFields);const fieldDef=this.filteredFields[defaultPath];const operator=getExpressionDisplayedOperators(fieldDef)[0];const value=getDefaultValue(fieldDef,operator);return condition(fieldDef.name,operator,value);}
getDefaultOperator(fieldDef){return getExpressionDisplayedOperators(fieldDef)[0];}
getOperatorEditorInfo(fieldDef){const operators=getExpressionDisplayedOperators(fieldDef);return getOperatorEditorInfo(operators,fieldDef);}
getPathEditorInfo(resModel,defaultCondition){if(resModel!==this.props.resModel){throw new Error(`Expression editor doesn't support tree as value so resModel has to be props.resModel`);}
return{component:ModelFieldSelector,extractProps:({value,update})=>({path:value,update,resModel:this.props.resModel,readonly:false,filter:(fieldDef)=>fieldDef.name in this.filteredFields,showDebugInput:false,followRelations:false,isDebugMode:this.isDebugMode,}),isSupported:(value)=>[0,1].includes(value)||value in this.filteredFields,stringify:(value)=>this.props.fields[value].string,defaultValue:()=>defaultCondition.path,message:_t("Field properties not supported"),};}
get isDebugMode(){return!!this.env.debug;}
onExpressionChange(expression){this.props.update(expression);}
resetExpression(){this.props.update("True");}
update(tree){const expression=expressionFromTree(tree,{getFieldDef:(name)=>this.getFieldDef(name),generateSmartDates:false,});this.props.update(expression);}}
return __exports;});;
/* /web/static/src/core/expression_editor/expression_editor_operator_editor.js */
odoo.define('@web/core/expression_editor/expression_editor_operator_editor',['@web/core/domain_selector/domain_selector_operator_editor'],function(require){'use strict';let __exports={};const{getDomainDisplayedOperators}=require("@web/core/domain_selector/domain_selector_operator_editor");const EXPRESSION_VALID_OPERATORS=["<","<=",">",">=","between","in range","in","not in","=","!=","set","not set",];__exports.getExpressionDisplayedOperators=getExpressionDisplayedOperators;function getExpressionDisplayedOperators(fieldDef){const operators=getDomainDisplayedOperators(fieldDef);return operators.filter((operator)=>EXPRESSION_VALID_OPERATORS.includes(operator));}
return __exports;});;
/* /web/static/src/core/expression_editor_dialog/expression_editor_dialog.js */
odoo.define('@web/core/expression_editor_dialog/expression_editor_dialog',['@odoo/owl','@web/core/dialog/dialog','@web/core/expression_editor/expression_editor','@web/core/py_js/py','@web/core/utils/hooks','@web/core/l10n/translation','@web/core/user'],function(require){'use strict';let __exports={};const{Component,useRef,useState}=require("@odoo/owl");const{Dialog}=require("@web/core/dialog/dialog");const{ExpressionEditor}=require("@web/core/expression_editor/expression_editor");const{evaluateExpr}=require("@web/core/py_js/py");const{useService}=require("@web/core/utils/hooks");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{user}=require("@web/core/user");const ExpressionEditorDialog=__exports.ExpressionEditorDialog=class ExpressionEditorDialog extends Component{static components={Dialog,ExpressionEditor};static template="web.ExpressionEditorDialog";static props={close:Function,resModel:String,fields:Object,expression:String,onConfirm:Function,};setup(){this.notification=useService("notification");this.state=useState({expression:this.props.expression,});this.confirmButtonRef=useRef("confirm");}
get expressionEditorProps(){return{resModel:this.props.resModel,fields:this.props.fields,expression:this.state.expression,update:(expression)=>{this.state.expression=expression;},};}
makeDefaultRecord(){const record={};for(const[name,{type}]of Object.entries(this.props.fields)){switch(type){case"integer":case"float":case"monetary":record[name]=name==="id"?false:0;break;case"one2many":case"many2many":record[name]=[];break;default:record[name]=false;}}
return record;}
async onConfirm(){this.confirmButtonRef.el.disabled=true;const record=this.makeDefaultRecord();const evalContext={...user.context,...record};try{evaluateExpr(this.state.expression,evalContext);}catch{if(this.confirmButtonRef.el){this.confirmButtonRef.el.disabled=false;}
this.notification.add(_t("Expression is invalid. Please correct it"),{type:"danger",});return;}
this.props.onConfirm(this.state.expression);this.props.close();}
onDiscard(){this.props.close();}}
return __exports;});;
/* /web/static/src/core/field_service.js */
odoo.define('@web/core/field_service',['@web/core/domain','@web/core/registry'],function(require){'use strict';let __exports={};const{Domain}=require("@web/core/domain");const{registry}=require("@web/core/registry");function getRelation(fieldDef,followRelationalProperties=false){if(fieldDef.relation){return fieldDef.relation;}
if(fieldDef.comodel&&followRelationalProperties){return fieldDef.comodel;}
return null;}
const fieldService=__exports.fieldService={dependencies:["orm"],async:["loadFieldInfo","loadFields","loadPath","loadPropertyDefinitions","loadPathDescription",],start(env,{orm}){async function loadFields(resModel,options={}){if(typeof resModel!=="string"||!resModel){throw new Error(`Invalid model name: ${resModel}`);}
return orm.cache({type:"disk"}).call(resModel,"fields_get",[options.fieldNames,options.attributes]);}
async function _loadPropertyDefinitions(resModel,fieldDefs,name,domain=[]){const{definition_record:definitionRecord,definition_record_field:definitionRecordField,}=fieldDefs[name];const definitionRecordModel=fieldDefs[definitionRecord].relation;let result;if(definitionRecordModel==="properties.base.definition"){result=await orm.call("properties.base.definition","get_properties_base_definition",[resModel,name]);}else{domain=Domain.and([[[definitionRecordField,"!=",false]],domain]).toList();result=await orm.webSearchRead(definitionRecordModel,domain,{specification:{display_name:{},[definitionRecordField]:{},},});}
const definitions={};for(const record of result.records){for(const definition of record[definitionRecordField]){definitions[definition.name]={is_property:true,searchable:true,record_id:record.id,record_name:record.display_name,...(definition.comodel?{relation:definition.comodel}:{}),...definition,};}}
return definitions;}
async function loadPropertyDefinitions(resModel,fieldName,domain){const fieldDefs=await loadFields(resModel);return _loadPropertyDefinitions(resModel,fieldDefs,fieldName,domain);}
async function _loadPath(resModel,fieldDefs,names,followRelationalProperties=false){if(!fieldDefs){return{isInvalid:"path",names,modelsInfo:[]};}
const[name,...remainingNames]=names;const modelsInfo=[{resModel,fieldDefs}];if(resModel==="*"&&remainingNames.length){return{isInvalid:"path",names,modelsInfo};}
const fieldDef=fieldDefs[name];if((name!=="*"&&!fieldDef)||(name==="*"&&remainingNames.length)){return{isInvalid:"path",names,modelsInfo};}
if(!remainingNames.length){return{names,modelsInfo};}
let subResult;const relation=getRelation(fieldDef,followRelationalProperties);if(relation){subResult=await _loadPath(relation,await loadFields(relation),remainingNames);}else if(fieldDef.type==="properties"){subResult=await _loadPath(followRelationalProperties?resModel:"*",await _loadPropertyDefinitions(resModel,fieldDefs,name),remainingNames);}
if(subResult){const result={names,modelsInfo:[...modelsInfo,...subResult.modelsInfo],};if(subResult.isInvalid){result.isInvalid="path";}
return result;}
return{isInvalid:"path",names,modelsInfo};}
async function loadPath(resModel,path="*",followRelationalProperties=false){const fieldDefs=await loadFields(resModel);if(typeof path!=="string"||!path){throw new Error(`Invalid path: ${path}`);}
return _loadPath(resModel,fieldDefs,path.split("."),followRelationalProperties);}
async function loadFieldInfo(resModel,path){if(typeof path!=="string"||!path||path==="*"){return{resModel,fieldDef:null};}
const{isInvalid,names,modelsInfo}=await loadPath(resModel,path);if(isInvalid){return{resModel,fieldDef:null};}
const name=names.at(-1);const modelInfo=modelsInfo.at(-1);return{resModel:modelInfo.resModel,fieldDef:modelInfo.fieldDefs[name]};}
function makeString(value){return String(value??"-");}
async function loadPathDescription(resModel,path,allowEmpty){if([0,1].includes(path)){return{isInvalid:false,displayNames:[makeString(path)]};}
if(allowEmpty&&!path){return{isInvalid:false,displayNames:[]};}
if(typeof path!=="string"||!path||path==="*"){return{isInvalid:true,displayNames:[makeString()]};}
const{isInvalid,modelsInfo,names}=await loadPath(resModel,path);const result={isInvalid:!!isInvalid,displayNames:[]};if(!isInvalid){const lastName=names.at(-1);const lastFieldDef=modelsInfo.at(-1).fieldDefs[lastName];if(["properties","properties_definition"].includes(lastFieldDef.type)){result.isInvalid=true;}}
for(let index=0;index<names.length;index++){const name=names[index];const fieldDef=modelsInfo[index]?.fieldDefs[name];result.displayNames.push(fieldDef?.string||makeString(name));}
return result;}
return{loadFieldInfo,loadFields,loadPath,loadPathDescription,loadPropertyDefinitions,};},};registry.category("services").add("field",fieldService);return __exports;});;
/* /web/static/src/core/file_input/file_input.js */
odoo.define('@web/core/file_input/file_input',['@odoo/owl','@web/core/utils/files'],function(require){'use strict';let __exports={};const{Component,onMounted,useRef,useState}=require("@odoo/owl");const{useFileUploader}=require("@web/core/utils/files");const FileInput=__exports.FileInput=class FileInput extends Component{static template="web.FileInput";static defaultProps={acceptedFileExtensions:"*",hidden:false,multiUpload:false,onUpload:()=>{},route:"/web/binary/upload_attachment",beforeOpen:async()=>true,};static props={acceptedFileExtensions:{type:String,optional:true},autoOpen:{type:Boolean,optional:true},hidden:{type:Boolean,optional:true},multiUpload:{type:Boolean,optional:true},onUpload:{type:Function,optional:true},beforeOpen:{type:Function,optional:true},resId:{type:Number,optional:true},resModel:{type:String,optional:true},route:{type:String,optional:true},"*":true,};setup(){this.uploadFiles=useFileUploader();this.fileInputRef=useRef("file-input");this.state=useState({isDisable:false,});onMounted(()=>{if(this.props.autoOpen){this.onTriggerClicked();}});}
get httpParams(){const{resId,resModel}=this.props;const params={csrf_token:odoo.csrf_token,ufile:[...this.fileInputRef.el.files],};if(resModel){params.model=resModel;}
if(resId!==undefined){params.id=resId;}
return params;}
async onFileInputChange(){this.state.isDisable=true;const httpParams=this.httpParams;if(this.props.onWillUploadFiles){try{const files=await this.props.onWillUploadFiles(httpParams.ufile);httpParams.ufile=files;}catch(e){this.state.isDisable=false;throw e;}}
const parsedFileData=await this.uploadFiles(this.props.route,httpParams);if(parsedFileData){this.props.onUpload(parsedFileData,this.fileInputRef.el?this.fileInputRef.el.files:[]);this.fileInputRef.el.value=null;}
this.state.isDisable=false;}
async onTriggerClicked(){if(await this.props.beforeOpen()){this.fileInputRef.el.click();}}}
return __exports;});;
/* /web/static/src/core/file_upload/file_upload_progress_bar.js */
odoo.define('@web/core/file_upload/file_upload_progress_bar',['@web/core/l10n/translation','@web/core/utils/hooks','@web/core/confirmation_dialog/confirmation_dialog','@odoo/owl'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{useService}=require("@web/core/utils/hooks");const{ConfirmationDialog}=require("@web/core/confirmation_dialog/confirmation_dialog");const{Component}=require("@odoo/owl");const FileUploadProgressBar=__exports.FileUploadProgressBar=class FileUploadProgressBar extends Component{static template="web.FileUploadProgressBar";static props={fileUpload:{type:Object},};setup(){this.dialogService=useService("dialog");}
onCancel(){if(!this.props.fileUpload.xhr){return;}
this.dialogService.add(ConfirmationDialog,{body:_t("Do you really want to cancel the upload of %s?",this.props.fileUpload.title),confirm:()=>{this.props.fileUpload.xhr.abort();},});}}
return __exports;});;
/* /web/static/src/core/file_upload/file_upload_progress_container.js */
odoo.define('@web/core/file_upload/file_upload_progress_container',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const FileUploadProgressContainer=__exports.FileUploadProgressContainer=class FileUploadProgressContainer extends Component{static template="web.FileUploadProgressContainer";static props={Component:{optional:false},shouldDisplay:{type:Function,optional:true},fileUploads:{type:Object},};}
return __exports;});;
/* /web/static/src/core/file_upload/file_upload_progress_record.js */
odoo.define('@web/core/file_upload/file_upload_progress_record',['@web/core/l10n/translation','@web/core/file_upload/file_upload_progress_bar','@odoo/owl'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{FileUploadProgressBar}=require("@web/core/file_upload/file_upload_progress_bar");const{Component}=require("@odoo/owl");const FileUploadProgressRecord=__exports.FileUploadProgressRecord=class FileUploadProgressRecord extends Component{static template="";static components={FileUploadProgressBar,};static props={fileUpload:Object,selector:{type:String,optional:true},};getProgressTexts(){const fileUpload=this.props.fileUpload;const percent=Math.round(fileUpload.progress*100);if(percent===100){return{left:_t("Processing..."),right:"",};}else{const mbLoaded=Math.round(fileUpload.loaded/1000000);const mbTotal=Math.round(fileUpload.total/1000000);return{left:_t("Uploading... (%s%)",percent),right:_t("(%(mbLoaded)s/%(mbTotal)sMB)",{mbLoaded,mbTotal}),};}}}
const FileUploadProgressKanbanRecord=__exports.FileUploadProgressKanbanRecord=class FileUploadProgressKanbanRecord extends FileUploadProgressRecord{static template="web.FileUploadProgressKanbanRecord";}
const FileUploadProgressDataRow=__exports.FileUploadProgressDataRow=class FileUploadProgressDataRow extends FileUploadProgressRecord{static template="web.FileUploadProgressDataRow";}
return __exports;});;
/* /web/static/src/core/file_upload/file_upload_service.js */
odoo.define('@web/core/file_upload/file_upload_service',['@web/core/l10n/translation','@web/core/registry','@odoo/owl'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{registry}=require("@web/core/registry");const{EventBus,reactive}=require("@odoo/owl");const fileUploadService=__exports.fileUploadService={dependencies:["notification"],createXhr(){return new window.XMLHttpRequest();},start(env,{notification:notificationService}){const uploads=reactive({});let nextId=1;const bus=new EventBus();const upload=async(route,files,params={})=>{const xhr=this.createXhr();xhr.open("POST",route);const formData=new FormData();formData.append("csrf_token",odoo.csrf_token);for(const file of files){formData.append("ufile",file);}
if(params.buildFormData){params.buildFormData(formData);}
const upload=reactive({id:nextId++,xhr,data:formData,progress:0,loaded:0,total:0,state:"pending",title:files.length===1?files[0].name:_t("%s Files",files.length),type:files.length===1?files[0].type:undefined,});uploads[upload.id]=upload;xhr.upload.addEventListener("progress",async(ev)=>{upload.progress=ev.loaded/ev.total;upload.loaded=ev.loaded;upload.total=ev.total;upload.state="loading";});xhr.addEventListener("load",()=>{try{handleResponse();}catch(e){onError(e);return;}
delete uploads[upload.id];upload.state="loaded";bus.trigger("FILE_UPLOAD_LOADED",{upload});});function handleResponse(){const resp=xhr.responseText??xhr.response;let error;let errorMessage="";if(!(xhr.status>=200&&xhr.status<300)){error=true;}
if(resp){let content=resp;if(typeof content==="string"){try{content=JSON.parse(content);}catch{try{content=new DOMParser().parseFromString(content,"text/html");}catch{}}}
if(error&&content instanceof Document){errorMessage=content.body.textContent;}else if(content instanceof Object){if(content.error){error=true;if(content.error.data){errorMessage=`${content.error.data.name}: ${content.error.data.message}`;}else{errorMessage=content.error.message||errorMessage;}}}}
if(error){throw new Error(errorMessage);}
return true;}
function onError(error){const defaultErrorMessage=_t("An error occured while uploading.");delete uploads[upload.id];upload.state="error";const displayError=params.displayErrorNotification??true;if(displayError){notificationService.add(error?.message||defaultErrorMessage,{type:"danger",sticky:true,});}
bus.trigger("FILE_UPLOAD_ERROR",{upload});}
xhr.addEventListener("error",(ev)=>onError(ev.error));xhr.addEventListener("abort",async()=>{delete uploads[upload.id];upload.state="abort";bus.trigger("FILE_UPLOAD_ERROR",{upload});});xhr.send(formData);bus.trigger("FILE_UPLOAD_ADDED",{upload});return upload;};return{bus,upload,uploads};},};registry.category("services").add("file_upload",fileUploadService);return __exports;});;
/* /web/static/src/core/file_viewer/file_model.js */
odoo.define('@web/core/file_viewer/file_model',['@web/core/utils/urls'],function(require){'use strict';let __exports={};const{url}=require("@web/core/utils/urls");const FileModelMixin=__exports.FileModelMixin=(T)=>class extends T{access_token;checksum;extension;id;mimetype;name;ownership_token;raw_access_token;type;tmpUrl;url;uploading;get defaultSource(){const route=url(this.urlRoute,this.urlQueryParams);const encodedRoute=encodeURIComponent(route);if(this.isPdf){return`/web/static/lib/pdfjs/web/viewer.html?file=${encodedRoute}#pagemode=none`;}
if(this.isUrlYoutube){const urlArr=this.url.split("/");let token=urlArr[urlArr.length-1];if(token.includes("watch")){token=token.split("v=")[1];const amp=token.indexOf("&");if(amp!==-1){token=token.substring(0,amp);}}
return`https://www.youtube.com/embed/${token}`;}
return route;}
get downloadUrl(){return url(this.urlRoute,{...this.urlQueryParams,download:true});}
get isImage(){const imageMimetypes=["image/bmp","image/gif","image/jpeg","image/png","image/svg+xml","image/tiff","image/x-icon","image/webp",];return imageMimetypes.includes(this.mimetype);}
get isPdf(){return this.mimetype&&this.mimetype.startsWith("application/pdf");}
get isText(){const textMimeType=["application/javascript","application/json","text/css","text/html","text/plain",];return textMimeType.includes(this.mimetype);}
get isUrl(){return this.type==="url"&&this.url;}
get isUrlYoutube(){return!!this.url&&this.url.includes("youtu");}
get isVideo(){const videoMimeTypes=["audio/mpeg","video/x-matroska","video/mp4","video/webm"];return videoMimeTypes.includes(this.mimetype);}
get isViewable(){return((this.isText||this.isImage||this.isVideo||this.isPdf||this.isUrlYoutube)&&!this.uploading);}
get urlQueryParams(){if(this.uploading&&this.tmpUrl){return{};}
const params={access_token:this.raw_access_token||this.access_token,filename:this.name,unique:this.checksum,};for(const prop in params){if(!params[prop]){delete params[prop];}}
return params;}
get urlRoute(){if(this.uploading&&this.tmpUrl){return this.tmpUrl;}
return this.isImage?`/web/image/${this.id}`:`/web/content/${this.id}`;}};const FileModel=__exports.FileModel=class FileModel extends FileModelMixin(Object){}
return __exports;});;
/* /web/static/src/core/file_viewer/file_viewer.js */
odoo.define('@web/core/file_viewer/file_viewer',['@odoo/owl','@web/core/utils/hooks','@web/core/utils/pdfjs'],function(require){'use strict';let __exports={};const{Component,useEffect,useRef,useState}=require("@odoo/owl");const{useAutofocus,useService}=require("@web/core/utils/hooks");const{hidePDFJSButtons}=require("@web/core/utils/pdfjs");const FileViewer=__exports.FileViewer=class FileViewer extends Component{static template="web.FileViewer";static components={};static props=["files","startIndex","close?","modal?"];static defaultProps={modal:true,};setup(){useAutofocus();this.imageRef=useRef("image");this.zoomerRef=useRef("zoomer");this.iframeViewerPdfRef=useRef("iframeViewerPdf");this.isDragging=false;this.dragStartX=0;this.dragStartY=0;this.scrollZoomStep=0.1;this.zoomStep=0.5;this.minScale=0.5;this.translate={dx:0,dy:0,x:0,y:0,};this.state=useState({index:this.props.startIndex,file:this.props.files[this.props.startIndex],imageLoaded:false,scale:1,angle:0,});this.ui=useService("ui");useEffect((el)=>{if(el){hidePDFJSButtons(this.iframeViewerPdfRef.el,{hideDownload:true,});}},()=>[this.iframeViewerPdfRef.el]);}
onImageLoaded(){this.state.imageLoaded=true;}
close(){this.props.close&&this.props.close();}
next(){const last=this.props.files.length-1;this.activateFile(this.state.index===last?0:this.state.index+1);}
previous(){const last=this.props.files.length-1;this.activateFile(this.state.index===0?last:this.state.index-1);}
activateFile(index){this.state.index=index;this.state.file=this.props.files[index];}
onKeydown(ev){switch(ev.key){case"ArrowRight":this.next();break;case"ArrowLeft":this.previous();break;case"Escape":this.close();break;case"q":this.close();break;}
if(this.state.file.isImage){switch(ev.key){case"r":this.rotate();break;case"+":this.zoomIn();break;case"-":this.zoomOut();break;case"0":this.resetZoom();break;}}}
onWheelImage(ev){if(ev.deltaY>0){this.zoomOut({scroll:true});}else{this.zoomIn({scroll:true});}}
onMousedownImage(ev){if(this.isDragging){return;}
if(ev.button!==0){return;}
this.isDragging=true;this.dragStartX=ev.clientX;this.dragStartY=ev.clientY;}
onMouseupImage(){if(!this.isDragging){return;}
this.isDragging=false;this.translate.x+=this.translate.dx;this.translate.y+=this.translate.dy;this.translate.dx=0;this.translate.dy=0;this.updateZoomerStyle();}
onMousemoveView(ev){if(!this.isDragging){return;}
this.translate.dx=ev.clientX-this.dragStartX;this.translate.dy=ev.clientY-this.dragStartY;this.updateZoomerStyle();}
resetZoom(){this.state.scale=1;this.updateZoomerStyle();}
rotate(){this.state.angle+=90;}
zoomIn({scroll=false}={}){this.state.scale=this.state.scale+(scroll?this.scrollZoomStep:this.zoomStep);this.updateZoomerStyle();}
zoomOut({scroll=false}={}){if(this.state.scale===this.minScale){return;}
const unflooredAdaptedScale=this.state.scale-(scroll?this.scrollZoomStep:this.zoomStep);this.state.scale=Math.max(this.minScale,unflooredAdaptedScale);this.updateZoomerStyle();}
updateZoomerStyle(){const tx=this.imageRef.el.offsetWidth*this.state.scale>this.zoomerRef.el.offsetWidth?this.translate.x+this.translate.dx:0;const ty=this.imageRef.el.offsetHeight*this.state.scale>this.zoomerRef.el.offsetHeight?this.translate.y+this.translate.dy:0;if(tx===0){this.translate.x=0;}
if(ty===0){this.translate.y=0;}
this.zoomerRef.el.style="transform: "+`translate(${tx}px, ${ty}px)`;}
get imageStyle(){let style="transform: "+`scale3d(${this.state.scale}, ${this.state.scale}, 1) `+`rotate(${this.state.angle}deg);`;if(this.state.angle%180!==0){style+=`max-height: ${window.innerWidth}px; max-width: ${window.innerHeight}px;`;}else{style+="max-height: 100%; max-width: 100%;";}
style+=`background: repeating-conic-gradient(#ccc 0deg 90deg, #fff 90deg 180deg) 50% / 20px 20px;`;return style;}
onClickPrint(){const printWindow=window.open("about:blank","_new");printWindow.document.open();printWindow.document.write(`
<html>
<head>
<script>
function onloadImage() {
setTimeout('printImage()', 10);
}
function printImage() {
window.print();
window.close();
}
</script>
</head>
<body onload='onloadImage()'>
<img src="${this.state.file.defaultSource}" alt=""/>
</body>
</html>`);printWindow.document.close();}}
return __exports;});;
/* /web/static/src/core/file_viewer/file_viewer_hook.js */
odoo.define('@web/core/file_viewer/file_viewer_hook',['@odoo/owl','@web/core/registry','@web/core/file_viewer/file_viewer'],function(require){'use strict';let __exports={};const{onWillDestroy}=require("@odoo/owl");const{registry}=require("@web/core/registry");const{FileViewer}=require("@web/core/file_viewer/file_viewer");let id=1;__exports.createFileViewer=createFileViewer;function createFileViewer(){const fileViewerId=`web.file_viewer${id++}`;function open(file,files=[file]){close();if(!file.isViewable){return;}
if(files.length>0){const viewableFiles=files.filter((file)=>file.isViewable);const index=viewableFiles.indexOf(file);registry.category("main_components").add(fileViewerId,{Component:FileViewer,props:{files:viewableFiles,startIndex:index,close},});}}
function close(){registry.category("main_components").remove(fileViewerId);}
return{open,close};}
__exports.useFileViewer=useFileViewer;function useFileViewer(){const{open,close}=createFileViewer();onWillDestroy(close);return{open,close};}
return __exports;});;
/* /web/static/src/core/hotkeys/hotkey_hook.js */
odoo.define('@web/core/hotkeys/hotkey_hook',['@web/core/utils/hooks','@odoo/owl'],function(require){'use strict';let __exports={};const{useService}=require("@web/core/utils/hooks");const{useEffect}=require("@odoo/owl");__exports.useHotkey=useHotkey;function useHotkey(hotkey,callback,options={}){const hotkeyService=useService("hotkey");useEffect(()=>hotkeyService.add(hotkey,callback,options),()=>[]);}
return __exports;});;
/* /web/static/src/core/hotkeys/hotkey_service.js */
odoo.define('@web/core/hotkeys/hotkey_service',['@web/core/browser/feature_detection','@web/core/registry','@web/core/browser/browser','@web/core/utils/ui'],function(require){'use strict';let __exports={};const{isMacOS}=require("@web/core/browser/feature_detection");const{registry}=require("@web/core/registry");const{browser}=require("@web/core/browser/browser");const{getVisibleElements}=require("@web/core/utils/ui");const ALPHANUM_KEYS="abcdefghijklmnopqrstuvwxyz0123456789".split("");const NAV_KEYS=["arrowleft","arrowright","arrowup","arrowdown","pageup","pagedown","home","end","backspace","enter","tab","delete","space",];const MODIFIERS=["alt","control","shift"];const AUTHORIZED_KEYS=[...ALPHANUM_KEYS,...NAV_KEYS,"escape","<",">"];__exports.getActiveHotkey=getActiveHotkey;function getActiveHotkey(ev){if(!ev.key){return"";}
if(ev.isComposing){return"";}
const hotkey=[];if(isMacOS()?ev.ctrlKey:ev.altKey){hotkey.push("alt");}
if(isMacOS()?ev.metaKey:ev.ctrlKey){hotkey.push("control");}
if(ev.shiftKey){hotkey.push("shift");}
let key=ev.key.toLowerCase();if(key===" "){key="space";}
if(ev.code&&ev.code.indexOf("Digit")===0){key=ev.code.slice(-1);}
if(!AUTHORIZED_KEYS.includes(key)&&ev.code&&ev.code.indexOf("Key")===0){key=ev.code.slice(-1).toLowerCase();}
if(!MODIFIERS.includes(key)){hotkey.push(key);}
return hotkey.join("+");}
const hotkeyService=__exports.hotkeyService={dependencies:["ui"],overlayModifier:"alt",start(env,{ui}){const registrations=new Map();let nextToken=0;let overlaysVisible=false;addListeners(browser);function addListeners(target){target.addEventListener("keydown",onKeydown);target.addEventListener("keyup",removeHotkeyOverlays);target.addEventListener("blur",removeHotkeyOverlays);target.addEventListener("click",removeHotkeyOverlays);}
function onKeydown(event){if(event.code&&event.code.indexOf("Numpad")===0&&/^\d$/.test(event.key)){return;}
const hotkey=getActiveHotkey(event);if(!hotkey){return;}
const{activeElement,isBlocked}=ui;if(isBlocked){return;}
const elementsWithAccessKey=document.querySelectorAll("[accesskey]");for(const el of elementsWithAccessKey){if(el instanceof HTMLElement){el.dataset.hotkey=el.accessKey;el.removeAttribute("accesskey");}}
if(!overlaysVisible&&hotkey===hotkeyService.overlayModifier){addHotkeyOverlays(activeElement);event.preventDefault();return;}
const singleKey=hotkey.split("+").pop();if(!AUTHORIZED_KEYS.includes(singleKey)){return;}
const targetIsEditable=event.target instanceof HTMLElement&&(/input|textarea/i.test(event.target.tagName)||event.target.isContentEditable)&&!event.target.matches("input[type=checkbox], input[type=radio]");const shouldProtectEditable=targetIsEditable&&!event.target.dataset.allowHotkeys&&singleKey!=="escape";const infos={activeElement,hotkey,isRepeated:event.repeat,target:event.target,shouldProtectEditable,};const dispatched=dispatch(infos);if(dispatched){event.preventDefault();event.stopImmediatePropagation();}
if(overlaysVisible){removeHotkeyOverlays();event.preventDefault();}}
function dispatch(infos){const{activeElement,hotkey,isRepeated,target,shouldProtectEditable}=infos;const reversedRegistrations=Array.from(registrations.values()).reverse();const domRegistrations=getDomRegistrations(hotkey,activeElement);const allRegistrations=reversedRegistrations.concat(domRegistrations);const candidates=allRegistrations.filter((reg)=>reg.hotkey===hotkey&&(reg.allowRepeat||!isRepeated)&&(reg.bypassEditableProtection||!shouldProtectEditable)&&(reg.global||reg.activeElement===activeElement)&&(!reg.isAvailable||reg.isAvailable(target))&&(!reg.area||(target&&reg.area()&&reg.area().contains(target))));let winner=candidates.shift();if(winner&&winner.area){for(const candidate of candidates.filter((c)=>Boolean(c.area))){if(candidate.area()&&winner.area().contains(candidate.area())){winner=candidate;}}}
if(winner){winner.callback({area:winner.area&&winner.area(),target,});return true;}
return false;}
function getDomRegistrations(hotkey,activeElement){const overlayModParts=hotkeyService.overlayModifier.split("+");if(!overlayModParts.every((el)=>hotkey.includes(el))){return[];}
const cleanHotkey=hotkey.split("+").filter((key)=>!overlayModParts.includes(key)).join("+");const elems=getVisibleElements(activeElement,`[data-hotkey='${cleanHotkey}' i]`);return elems.map((el)=>({hotkey,activeElement,bypassEditableProtection:true,callback:()=>{if(document.activeElement){document.activeElement.blur();}
el.focus();setTimeout(()=>el.click());},}));}
function addHotkeyOverlays(activeElement){const hotkeysFromHookToHighlight=[];for(const[,registration]of registrations){const overlayElement=registration.withOverlay?.();if(overlayElement){hotkeysFromHookToHighlight.push({hotkey:registration.hotkey.replace(`${hotkeyService.overlayModifier}+`,""),el:overlayElement,});}}
const hotkeysFromDomToHighlight=getVisibleElements(activeElement,"[data-hotkey]:not(:disabled)").map((el)=>({hotkey:el.dataset.hotkey,el}));const items=[...hotkeysFromDomToHighlight,...hotkeysFromHookToHighlight];for(const item of items){const hotkey=item.hotkey;const overlay=document.createElement("div");overlay.classList.add("o_web_hotkey_overlay","position-absolute","top-0","bottom-0","start-0","end-0","d-flex","justify-content-center","align-items-center","m-0","bg-black-50","h6");overlay.style.zIndex=1;const overlayKbd=document.createElement("kbd");overlayKbd.className="small";overlayKbd.appendChild(document.createTextNode(hotkey.toUpperCase()));overlay.appendChild(overlayKbd);let overlayParent;if(item.el.tagName.toUpperCase()==="INPUT"){overlayParent=item.el.parentElement;}else{overlayParent=item.el;}
if(overlayParent.style.position!=="absolute"){overlayParent.style.position="relative";}
overlayParent.appendChild(overlay);}
overlaysVisible=true;}
function removeHotkeyOverlays(){for(const overlay of document.querySelectorAll(".o_web_hotkey_overlay")){overlay.remove();}
overlaysVisible=false;}
function registerHotkey(hotkey,callback,options={}){if(!hotkey||hotkey.length===0){throw new Error("You must specify an hotkey when registering a registration.");}
if(!callback||typeof callback!=="function"){throw new Error("You must specify a callback function when registering a registration.");}
const keys=hotkey.toLowerCase().split("+").filter((k)=>!MODIFIERS.includes(k));if(keys.some((k)=>!AUTHORIZED_KEYS.includes(k))){throw new Error(`You are trying to subscribe for an hotkey ('${hotkey}')
that contains parts not whitelisted: ${keys.join(", ")}`);}else if(keys.length>1){throw new Error(`You are trying to subscribe for an hotkey ('${hotkey}')
that contains more than one single key part: ${keys.join("+")}`);}
const token=nextToken++;const registration={hotkey:hotkey.toLowerCase(),callback,activeElement:null,allowRepeat:options&&options.allowRepeat,bypassEditableProtection:options&&options.bypassEditableProtection,global:options&&options.global,area:options&&options.area,isAvailable:options&&options.isAvailable,withOverlay:options&&options.withOverlay,};Promise.resolve().then(()=>{registration.activeElement=ui.activeElement;});registrations.set(token,registration);return token;}
function unregisterHotkey(token){registrations.delete(token);}
return{add(hotkey,callback,options={}){const token=registerHotkey(hotkey,callback,options);return()=>{unregisterHotkey(token);};},registerIframe(iframe){addListeners(iframe.contentWindow);},};},};registry.category("services").add("hotkey",hotkeyService);return __exports;});;
/* /web/static/src/core/install_scoped_app/install_scoped_app.js */
odoo.define('@web/core/install_scoped_app/install_scoped_app',['@web/core/browser/browser','@web/core/registry','@odoo/owl','@web/core/browser/feature_detection','@web/core/utils/hooks','@web/core/dropdown/dropdown'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{Component,onMounted,useState}=require("@odoo/owl");const{isDisplayStandalone}=require("@web/core/browser/feature_detection");const{useService}=require("@web/core/utils/hooks");const{Dropdown}=require("@web/core/dropdown/dropdown");const InstallScopedApp=__exports.InstallScopedApp=class InstallScopedApp extends Component{static props={};static template="web.InstallScopedApp";static components={Dropdown};setup(){this.pwa=useService("pwa");this.state=useState({manifest:{},showInstallUI:false});this.isDisplayStandalone=isDisplayStandalone();this.isInstallationPossible=browser.BeforeInstallPromptEvent!==undefined;onMounted(async()=>{this.state.manifest=await this.pwa.getManifest();this.state.showInstallUI=true;});}
onChangeName(ev){const value=ev.target.value;if(value!==this.state.manifest.name){const url=new URL(document.location.href);url.searchParams.set("app_name",encodeURIComponent(value));browser.location.replace(url);}}
onInstall(){this.state.showInstallUI=false;this.pwa.show({onDone:(res)=>{if(res.outcome==="accepted"){browser.location.replace(this.state.manifest.start_url);}else{this.state.showInstallUI=true;}},});}}
registry.category("public_components").add("web.install_scoped_app",InstallScopedApp);return __exports;});;
/* /web/static/src/core/ir_ui_view_code_editor/code_editor.js */
odoo.define('@web/core/ir_ui_view_code_editor/code_editor',['@odoo/owl','@web/core/code_editor/code_editor','@web/core/utils/strings'],function(require){'use strict';let __exports={};const{useEffect,onMounted}=require("@odoo/owl");const{CodeEditor}=require("@web/core/code_editor/code_editor");const{escapeRegExp}=require("@web/core/utils/strings");const IrUiViewCodeEditor=__exports.IrUiViewCodeEditor=class IrUiViewCodeEditor extends CodeEditor{static props={...this.props,record:{type:Object},};setup(){super.setup(...arguments);this.markers=[];onMounted(()=>{this.aceEditor.getSession().on("change",()=>{this.clearMarkers();});});useEffect((arch,invalid_locators)=>{if(arch&&invalid_locators){this.highlightInvalidLocators(arch,invalid_locators);return()=>this.clearMarkers();}},()=>[this.props.value,this.props.record?.data.invalid_locators]);}
async highlightInvalidLocators(arch,invalid_locators){const resModel=this.env.model?.config.resModel;const resId=this.env.model?.config.resId;if(resModel==="ir.ui.view"&&resId){const{doc}=this.aceEditor.session;for(const spec of invalid_locators){if(spec.broken_hierarchy){continue}
const{tag,attrib,sourceline}=spec;const attribRegex=Object.entries(attrib).map(([key,value])=>{const escapedValue=escapeRegExp(value).replace(/"/g,'("|&quot;)');return(`(?=[^>]*?\\b${escapeRegExp(key)}\\s*=\\s*`+`(?:"[^"]*${escapedValue}[^"]*"|'[^']*${escapedValue}[^']*'))`);}).join("");const nodeRegex=new RegExp(`<${escapeRegExp(tag)}\\s+${attribRegex}[^>]*>`,"g");for(const match of arch.matchAll(nodeRegex)){const startIndex=match.index;const endIndex=startIndex+match[0].length;const startPos=doc.indexToPosition(startIndex);const endPos=doc.indexToPosition(endIndex);if(startPos.row+1===sourceline){const range=new window.ace.Range(startPos.row,startPos.column,endPos.row,endPos.column);this.markers.push(this.aceEditor.session.addMarker(range,"invalid_locator","text"));}}}}}
clearMarkers(){this.markers.forEach((marker)=>this.aceEditor.session.removeMarker(marker));this.markers=[];}}
return __exports;});;
/* /web/static/src/core/l10n/dates.js */
odoo.define('@web/core/l10n/dates',['@web/core/l10n/localization','@web/core/l10n/translation','@web/core/utils/functions','@web/core/utils/arrays'],function(require){'use strict';let __exports={};const{localization}=require("@web/core/l10n/localization");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{memoize}=require("@web/core/utils/functions");const{ensureArray}=require("@web/core/utils/arrays");const{DateTime,Settings}=luxon;const MIN_VALID_DATE=__exports.MIN_VALID_DATE=DateTime.fromObject({year:1000});const MAX_VALID_DATE=__exports.MAX_VALID_DATE=DateTime.fromObject({year:9999}).endOf("year");const SERVER_DATE_FORMAT="yyyy-MM-dd";const SERVER_TIME_FORMAT="HH:mm:ss";const SERVER_DATETIME_FORMAT=`${SERVER_DATE_FORMAT} ${SERVER_TIME_FORMAT}`;const nonAlphaRegex=/[^a-z]/gi;const nonDigitRegex=/[^\d]/g;const normalizeFormatTable={a:"ccc",A:"cccc",b:"MMM",B:"MMMM",d:"dd",H:"HH",I:"hh",j:"o",m:"MM",M:"mm",p:"a",S:"ss",W:"WW",w:"c",y:"yy",Y:"yyyy",c:"ccc MMM d HH:mm:ss yyyy",x:"MM/dd/yy",X:"HH:mm:ss",};const smartDateUnits={d:"days",m:"months",w:"weeks",y:"years",H:"hours",M:"minutes",S:"seconds",};const smartWeekdays={monday:1,tuesday:2,wednesday:3,thursday:4,friday:5,saturday:6,sunday:7,};const dateCache=new WeakMap();const dateTimeCache=new WeakMap();const ConversionError=__exports.ConversionError=class ConversionError extends Error{name="ConversionError";}
__exports.areDatesEqual=areDatesEqual;function areDatesEqual(d1,d2){if(Array.isArray(d1)||Array.isArray(d2)){d1=ensureArray(d1);d2=ensureArray(d2);return d1.length===d2.length&&d1.every((d1Val,i)=>areDatesEqual(d1Val,d2[i]));}
if(d1 instanceof DateTime&&d2 instanceof DateTime&&d1!==d2){return d1.equals(d2);}else{return d1===d2;}}
__exports.clampDate=clampDate;function clampDate(desired,minDate,maxDate){if(maxDate<desired){return maxDate;}
if(minDate>desired){return minDate;}
return desired;}
__exports.getLocalYearAndWeek=getLocalYearAndWeek;function getLocalYearAndWeek(date){if(!date.isLuxonDateTime){date=DateTime.fromJSDate(date);}
const{weekStart}=localization;const startDate=date.minus({days:(date.weekday+7-weekStart)%7});date=weekStart>1&&weekStart<5?startDate.minus({days:(startDate.weekday+6)%7}):startDate.plus({days:(8-startDate.weekday)%7});date=date.plus({days:6});const jan4=DateTime.local(date.year,1,4);const diffDays=date<jan4?date.diff(jan4.minus({years:1}),"day").days:date.diff(jan4,"day").days;return{year:date.year,week:Math.trunc(diffDays/7)+1,startDate,};}
__exports.getStartOfLocalWeek=getStartOfLocalWeek;function getStartOfLocalWeek(date){const{weekStart}=localization;const weekday=date.weekday<weekStart?weekStart-7:weekStart;return date.set({weekday}).startOf("day");}
__exports.getEndOfLocalWeek=getEndOfLocalWeek;function getEndOfLocalWeek(date){return getStartOfLocalWeek(date).plus({days:6}).endOf("day");}
__exports.isInRange=isInRange;function isInRange(value,range){if(!value||!range){return false;}
if(Array.isArray(value)){const actualValues=value.filter(Boolean).sort();if(actualValues.length<2){return isInRange(actualValues[0],range);}
return((actualValues[0]<=range[0]&&range[0]<=actualValues[1])||(range[0]<=actualValues[0]&&actualValues[0]<=range[1]));}else{return range[0]<=value&&value<=range[1];}}
function isValidDate(date){return date&&date.isValid&&isInRange(date,[MIN_VALID_DATE,MAX_VALID_DATE]);}
function parseSmartDateInput(value){const terms=value.split(/\s+/);if(!terms.length){return false;}
var now=DateTime.local().startOf("second");if(terms[0]=="today"){terms.shift();now=now.startOf("day");}else if(terms[0]=="now"){terms.shift();}else if(terms.length==1&&/^[=+-]\d+$/.test(terms[0])){terms[0]+="d";}
for(let i=0;i<terms.length;i++){const term=terms[i];const operator=term[0];if(term.length<3||!["+","-","="].includes(operator)){return false;}
const dayname=term.slice(1);if(Object.hasOwn(smartWeekdays,dayname)||dayname==="week_start"){const{weekStart}=localization;const weekdayNumber=dayname==="week_start"?weekStart:smartWeekdays[dayname];let weekdayOffset=((weekdayNumber-weekStart+7)%7)-((now.weekday-weekStart+7)%7);if(operator=="+"||operator=="-"){if(weekdayOffset>0&&operator=="-"){weekdayOffset-=7;}else if(weekdayOffset<0&&operator=="+"){weekdayOffset+=7;}}else{now=now.startOf("day");}
now=now.plus({days:weekdayOffset});continue;}
try{const field_name=smartDateUnits[term[term.length-1]];const number=parseInt(term.slice(1,-1),10);if(!field_name||isNaN(number)){return false;}
if(operator=="+"){now=now.plus({[field_name]:number});}else if(operator=="-"){now=now.minus({[field_name]:number});}else if(operator=="="){if(field_name=="seconds"||field_name=="minutes"||field_name=="hours"){now=now.startOf(field_name);}else if(field_name=="weeks"){return false;}else{now=now.startOf("day");}
now=now.set({[field_name]:number});}}catch{return false;}}
return now;}
const stripAlphaDupes=memoize(function stripAlphaDupes(str){return str.replace(/[a-z]/gi,(letter,index,str)=>letter===str[index-1]?"":letter);});const strftimeToLuxonFormat=__exports.strftimeToLuxonFormat=memoize(function strftimeToLuxonFormat(format){const output=[];let inToken=false;for(let index=0;index<format.length;++index){let character=format[index];if(character==="%"&&!inToken){inToken=true;continue;}
if(/[a-z]/gi.test(character)){if(inToken&&normalizeFormatTable[character]!==undefined){character=normalizeFormatTable[character];}else{character=`'${character}'`;}}
output.push(character);inToken=false;}
return output.join("");});__exports.today=today;function today(){return DateTime.local().startOf("day");}
__exports.formatDate=formatDate;function formatDate(value,options={}){if(!value){return"";}
const format=options.format||localization.dateFormat;return value.toFormat(format);}
__exports.formatDateTime=formatDateTime;function formatDateTime(value,options={}){if(!value){return"";}
const format=options.format||localization.dateTimeFormat;return value.setZone(options.tz||"default").toFormat(format);}
__exports.toLocaleDateString=toLocaleDateString;function toLocaleDateString(value){if(!value){return"";}
const format={...DateTime.DATE_MED};if(today().year===value.year){delete format.year;}
return value.toLocaleString(format);}
__exports.toLocaleDateTimeString=toLocaleDateTimeString;function toLocaleDateTimeString(value,options={showDate:true,showTime:true,showSeconds:false}){if(!value){return"";}
const format={...DateTime.DATETIME_MED_WITH_SECONDS};if(!options.showSeconds){delete format.second;}
if(options.showDate===false){delete format.day;delete format.month;delete format.year;}
if(options.showTime===false){delete format.hour;delete format.minute;}
if(today().year===value.year){delete format.year;}
return value.setZone(options.tz||"default").toLocaleString(format);}
__exports.formatDuration=formatDuration;function formatDuration(seconds,showFullDuration){const displayStyle=showFullDuration?"long":"narrow";const numberOfValuesToDisplay=showFullDuration?2:1;const durationKeys=["years","months","days","hours","minutes"];if(seconds<60){seconds=60;}
seconds-=seconds%60;let duration=luxon.Duration.fromObject({seconds:seconds}).shiftTo(...durationKeys);duration=duration.shiftTo(...durationKeys.filter((key)=>duration.get(key)));const durationSplit=duration.toHuman({unitDisplay:displayStyle}).split(",");if(!showFullDuration&&duration.loc.locale.includes("en")&&duration.months>0){durationSplit[0]=durationSplit[0].replace("m","M");}
return durationSplit.slice(0,numberOfValuesToDisplay).join(",");}
__exports.serializeDate=serializeDate;function serializeDate(value){if(!dateCache.has(value)){dateCache.set(value,value.toFormat(SERVER_DATE_FORMAT,{numberingSystem:"latn"}));}
return dateCache.get(value);}
__exports.serializeDateTime=serializeDateTime;function serializeDateTime(value){if(!dateTimeCache.has(value)){dateTimeCache.set(value,value.setZone("utc").toFormat(SERVER_DATETIME_FORMAT,{numberingSystem:"latn"}));}
return dateTimeCache.get(value);}
__exports.parseDate=parseDate;function parseDate(value,options={}){const parsed=parseDateTime(value,{...options,format:options.format||localization.dateFormat,});return parsed&&parsed.startOf("day");}
__exports.parseDateTime=parseDateTime;function parseDateTime(value,options={}){if(!value){return false;}
const fmt=options.format||localization.dateTimeFormat;const parseOpts={setZone:true,zone:options.tz||"default",};const switchToLatin=Settings.defaultNumberingSystem!=="latn"&&/[0-9]/.test(value);if(switchToLatin){parseOpts.numberingSystem="latn";}
let result=DateTime.fromFormat(value,fmt,parseOpts);if(!isValidDate(result)){result=parseSmartDateInput(value);}
if(!isValidDate(result)){const fmtWoZero=stripAlphaDupes(fmt);result=DateTime.fromFormat(value,fmtWoZero,parseOpts);}
if(!isValidDate(result)){const digitList=value.split(nonDigitRegex).filter(Boolean);const fmtList=fmt.split(nonAlphaRegex).filter(Boolean);const valWoSeps=digitList.join("");let carry=0;const fmtWoSeps=fmtList.map((part,i)=>{const digitLength=(digitList[i]||"").length;const actualPart=part.slice(0,digitLength+carry);carry+=digitLength-actualPart.length;return actualPart;}).join("");result=DateTime.fromFormat(valWoSeps,fmtWoSeps,parseOpts);}
if(!isValidDate(result)){const valueDigits=value.replace(nonDigitRegex,"");if(valueDigits.length>4){result=DateTime.fromISO(value,parseOpts);if(!isValidDate(result)){result=DateTime.fromSQL(value,parseOpts);}}}
if(!isValidDate(result)){throw new ConversionError(_t("'%s' is not a correct date or datetime",value));}
if(switchToLatin){result=result.reconfigure({numberingSystem:Settings.defaultNumberingSystem,});}
return result.setZone(options.tz||"default");}
__exports.deserializeDate=deserializeDate;function deserializeDate(value,options={}){options={numberingSystem:"latn",zone:"default",...options};return DateTime.fromSQL(value,options).reconfigure({numberingSystem:Settings.defaultNumberingSystem,});}
__exports.deserializeDateTime=deserializeDateTime;function deserializeDateTime(value,options={}){return DateTime.fromSQL(value,{numberingSystem:"latn",zone:"utc"}).setZone(options?.tz||"default").reconfigure({numberingSystem:Settings.defaultNumberingSystem,});}
return __exports;});;
/* /web/static/src/core/l10n/localization.js */
odoo.define('@web/core/l10n/localization',[],function(require){'use strict';let __exports={};const localization=__exports.localization=new Proxy({},{get:(target,p)=>{if(p in target||p==="then"){return Reflect.get(target,p);}
throw new Error(`could not access localization parameter "${p}": parameters are not ready yet. Maybe add 'localization' to your dependencies?`);},});return __exports;});;
/* /web/static/src/core/l10n/localization_service.js */
odoo.define('@web/core/l10n/localization_service',['@web/session','@web/core/l10n/utils','@web/core/user','@web/core/browser/browser','@web/core/registry','@web/core/l10n/dates','@web/core/l10n/localization','@web/core/network/rpc','@web/core/l10n/translation','@web/core/utils/urls','@web/core/utils/indexed_db'],function(require){'use strict';let __exports={};const{session}=require("@web/session");const{jsToPyLocale}=require("@web/core/l10n/utils");const{user}=require("@web/core/user");const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{strftimeToLuxonFormat}=require("@web/core/l10n/dates");const{localization}=require("@web/core/l10n/localization");const{rpcBus}=require("@web/core/network/rpc");const{translatedTerms,translatedTermsGlobal,translationLoaded,translationIsReady,}=require("@web/core/l10n/translation");const{objectToUrlEncodedString}=require("@web/core/utils/urls");const{IndexedDB}=require("@web/core/utils/indexed_db");const{Settings}=luxon;const NUMBERING_SYSTEMS=[[/^ar-(sa|sy|001)$/i,"arab"],[/^bn/i,"beng"],[/^bo/i,"tibt"],[/^pa-in/i,"guru"],[/^ta/i,"tamldec"],[/.*/i,"latn"],];const localizationService=__exports.localizationService={start:async()=>{const localizationDB=new IndexedDB("localization",session.registry_hash);const translationURL=session.translationURL||"/web/webclient/translations";const lang=jsToPyLocale(user.lang||document.documentElement.getAttribute("lang"));rpcBus.addEventListener("RPC:RESPONSE",(ev)=>{const{method,model}=ev.detail.data.params||{};if(method==="lang_install"&&model==="base.language.install"){rpcBus.trigger("CLEAR-CACHES");}});const fetchTranslations=async(hash)=>{let queryString=objectToUrlEncodedString({hash,lang});queryString=queryString.length>0?`?${queryString}`:queryString;const response=await browser.fetch(`${translationURL}${queryString}`,{cache:"no-store",});if(!response.ok){throw new Error("Error while fetching translations");}
const result=await response.json();if(result.hash!==hash){localizationDB.write(translationURL,JSON.stringify({lang}),result);updateTranslations(result);}};const updateTranslations=(result)=>{const terms={};for(const addon of Object.keys(result.modules)){terms[addon]={};for(const message of result.modules[addon].messages){terms[addon][message.id]=message.string;translatedTermsGlobal[message.id]=message.string;}}
Object.assign(translatedTerms,terms);const userLocalization=result.lang_parameters;const dateFormat=strftimeToLuxonFormat(userLocalization.date_format);const timeFormat=strftimeToLuxonFormat(userLocalization.time_format);Object.assign(localization,{dateFormat,timeFormat,dateTimeFormat:`${dateFormat} ${timeFormat}`,decimalPoint:userLocalization.decimal_point,direction:userLocalization.direction,grouping:JSON.parse(userLocalization.grouping),multiLang:result.multi_lang,thousandsSep:userLocalization.thousands_sep,weekStart:userLocalization.week_start,});};const storedTranslations=await localizationDB.read(translationURL,JSON.stringify({lang}));const translationProm=fetchTranslations(storedTranslations?.hash);if(storedTranslations){updateTranslations(storedTranslations);}else{await translationProm;}
translatedTerms[translationLoaded]=true;translationIsReady.resolve(true);const locale=user.lang||browser.navigator.language;Settings.defaultLocale=locale;for(const[re,numberingSystem]of NUMBERING_SYSTEMS){if(re.test(locale)){Settings.defaultNumberingSystem=numberingSystem;break;}}
localization.code=jsToPyLocale(locale);return localization;},};registry.category("services").add("localization",localizationService);return __exports;});;
/* /web/static/src/core/l10n/time.js */
odoo.define('@web/core/l10n/time',['@web/core/l10n/localization'],function(require){'use strict';let __exports={};const{localization}=require("@web/core/l10n/localization");const{DateTime}=luxon;const NUMERAL_MAPS=["٠١٢٣٤٥٦٧٨٩","۰۱۲۳۴۵۶۷۸۹","०१२३४५६७८९","๑๒๓๔๕๖๗๘๙๐","零一二三四五六七八九",];const Time=__exports.Time=class Time{static from(value){if(value===null||value===undefined||value===false){return null;}else if(value instanceof Time){return value;}else if(typeof value==="string"){return parseTime(value,true);}else if(typeof value==="object"){return new Time(value);}else{return null;}}
constructor({hour=0,minute=0,second=0}={}){this.hour=hour;this.minute=minute;this.second=second;this._is24HourFormat=is24HourFormat();this._isMeridiemFormat=isMeridiemFormat();}
roundMinutes(rounding){this.minute=Math.round(this.minute/rounding)*rounding;}
copy(){return new Time(this);}
equals(other,checkSeconds=false){return(other&&this.hour===other.hour&&this.minute===other.minute&&(!checkSeconds||this.second===other.second));}
toString(showSeconds=false){const hourFormat=this._is24HourFormat?"H":"h";const secondFormat=showSeconds?":ss":"";const meridiemFormat=this._isMeridiemFormat?"a":"";return this.toDateTime().toFormat(`${hourFormat}:mm${secondFormat}${meridiemFormat}`).toLowerCase();}
toDateTime(){return DateTime.fromObject(this.toObject());}
toObject(){return{hour:this.hour,minute:this.minute,second:this.second,};}}
__exports.is24HourFormat=is24HourFormat;function is24HourFormat(format){return/H/.test(format||localization.timeFormat);}
__exports.isMeridiemFormat=isMeridiemFormat;function isMeridiemFormat(format){return/a/.test(format||localization.timeFormat);}
__exports.parseTime=parseTime;function parseTime(value,parseSeconds){const{isPm,isAm}=meridiemCheck(value);value=normalizeTimeStr(value);if(!value){return null;}
let hour=0;let minute=0;let second=0;const parse=(str)=>{if(str.length===0){return 0;}else if(/^[\d]+$/.test(str)){return parseInt(str,10);}else{return NaN;}};const parts=value.split(/[\s:]/g);if(parts.length>3){return null;}else if(parts.length===3){if(!parseSeconds){return null;}
hour=parse(parts[0]);minute=parse(parts[1].padEnd(2,"0"));second=parse(parts[2].padEnd(2,"0"));}else if(parts.length===2){hour=parse(parts[0]);minute=parse(parts[1].padEnd(2,"0"));}else if(parts.length===1){const raw=parts[0];const pickSolution=(...solutions)=>{for(const solution of solutions){const h=parse(solution[0]);if(h<=24){hour=h;if(solution[1]){minute=parse(solution[1].padEnd(2,"0"));}
break;}}};if(raw.length==1){hour=parse(raw);}else if(raw.length==2){pickSolution([raw],[raw[0],raw[1]]);}else if(raw.length===3){pickSolution([raw.slice(0,2),raw[2]],[raw[0],raw.slice(1)]);}else if(raw.length===4){hour=parse(raw.slice(0,2));minute=parse(raw.slice(2));}else if(raw.length>4&&raw.length<=6){if(!parseSeconds){return null;}
hour=parse(raw.slice(0,2));minute=parse(raw.slice(2,4));second=parse(raw.slice(4).padEnd(2,"0"));}else{return null;}}
if(isPm&&hour<12){hour+=12;}else if(isAm&&hour===12){hour=0;}
if(hour>=0&&hour<=24&&minute>=0&&minute<60&&second>=0&&second<60){if(hour===24){hour=0;}
return new Time({hour,minute,second});}else{return null;}}
function normalizeTimeStr(timeStr){if(typeof timeStr!=="string"){return false;}
timeStr=timeStr.trim().toLowerCase();for(const map of NUMERAL_MAPS){for(let i=0;i<map.length;i++){timeStr=timeStr.replaceAll(map[i],i);}}
return timeStr.replace(/^\D+|\D+$/g,"").replace(/\D+/g,":");}
function meridiemCheck(timeStr){const amPmMatch=typeof timeStr==="string"?timeStr.toLowerCase().match(/(am|pm)/g):false;return{isPm:amPmMatch&&amPmMatch[0]==="pm",isAm:amPmMatch&&amPmMatch[0]==="am",};}
return __exports;});;
/* /web/static/src/core/l10n/translation.js */
odoo.define('@web/core/l10n/translation',['@web/core/l10n/utils','@web/core/utils/arrays','@web/core/utils/concurrency','@web/core/utils/html','@web/core/utils/strings'],function(require){'use strict';let __exports={};const{formatList}=require("@web/core/l10n/utils");const{isIterable}=require("@web/core/utils/arrays");const{Deferred}=require("@web/core/utils/concurrency");const{htmlSprintf,isMarkup}=require("@web/core/utils/html");const{mapSubstitutions,sprintf}=require("@web/core/utils/strings");function isNotBlank(value){return typeof value==="string"&&!R_BLANK.test(value);}
function translationSprintf(str,substitutions){let hasMarkup=false;function formatSubstitution(value){hasMarkup||=isMarkup(value);if(isIterable(value)&&!(value instanceof String)){return formatList(value);}else{return value;}}
const formattedSubstitutions=mapSubstitutions(substitutions,formatSubstitution);if(hasMarkup){return htmlSprintf(str,...formattedSubstitutions);}else{return sprintf(str,...formattedSubstitutions);}}
const DEFAULT_MODULE="base";const R_BLANK=/^[\s\u200B]*$/;__exports._t=_t;function _t(source,...substitutions){return appTranslateFn(source,odoo.translationContext,...substitutions);}
__exports.appTranslateFn=appTranslateFn;function appTranslateFn(source,moduleName,...substitutions){const string=new TranslatedString(source,substitutions,moduleName);return string.lazy?string:string.valueOf();}
__exports.loadLanguages=loadLanguages;async function loadLanguages(orm){if(!loadLanguages.installedLanguages){loadLanguages.installedLanguages=await orm.call("res.lang","get_installed");}
return loadLanguages.installedLanguages;}
const TranslatedString=__exports.TranslatedString=class TranslatedString extends String{context;lazy=false;substitutions;constructor(value,substitutions,context){super(value);if(!isNotBlank(value)){return new String(value);}
this.lazy=!translatedTerms[translationLoaded];this.substitutions=substitutions;this.context=context||DEFAULT_MODULE;}
toString(){return this.valueOf();}
valueOf(){const source=super.valueOf();if(this.lazy&&!translatedTerms[translationLoaded]){throw new Error(`Cannot translate string: translations have not been loaded`);}
const translation=translatedTerms[this.context]?.[source]??translatedTermsGlobal[source]??source;if(this.substitutions.length){return translationSprintf(translation,this.substitutions);}else{return translation;}}}
const translationLoaded=__exports.translationLoaded=Symbol("translationLoaded");const translatedTerms=__exports.translatedTerms={[translationLoaded]:false,};const translatedTermsGlobal=__exports.translatedTermsGlobal=Object.create(null);const translationIsReady=__exports.translationIsReady=new Deferred();return __exports;});;
/* /web/static/src/core/l10n/utils.js */
odoo.define('@web/core/l10n/utils',['@web/core/l10n/utils/format_list','@web/core/l10n/utils/locales','@web/core/l10n/utils/normalize'],function(require){'use strict';let __exports={};Object.assign(__exports,require("@web/core/l10n/utils/format_list"));Object.assign(__exports,require("@web/core/l10n/utils/locales"));Object.assign(__exports,require("@web/core/l10n/utils/normalize"));return __exports;});;
/* /web/static/src/core/l10n/utils/format_list.js */
odoo.define('@web/core/l10n/utils/format_list',['@web/core/user'],function(require){'use strict';let __exports={};const{user}=require("@web/core/user");const LIST_STYLES={standard:{type:"conjunction",style:"long",},"standard-short":{type:"conjunction",style:"short",},or:{type:"disjunction",style:"long",},"or-short":{type:"disjunction",style:"short",},unit:{type:"unit",style:"long",},"unit-short":{type:"unit",style:"short",},"unit-narrow":{type:"unit",style:"narrow",},};__exports.formatList=formatList;function formatList(values,{localeCode,style}={}){const locale=localeCode||user.lang||"en-US";const formatter=new Intl.ListFormat(locale,LIST_STYLES[style||"standard"]);return formatter.format(Array.from(values,String));}
return __exports;});;
/* /web/static/src/core/l10n/utils/locales.js */
odoo.define('@web/core/l10n/utils/locales',[],function(require){'use strict';let __exports={};__exports.jsToPyLocale=jsToPyLocale;function jsToPyLocale(locale){if(!locale){return"";}
try{var{language,script,region}=new Intl.Locale(locale);if(language==="fil"){language="tl";}}catch{return locale;}
let xpgLocale=language;if(region){xpgLocale+=`_${region}`;}
switch(script){case"Cyrl":xpgLocale+="@Cyrl";break;case"Latn":xpgLocale+="@latin";break;}
return xpgLocale;}
__exports.pyToJsLocale=pyToJsLocale;function pyToJsLocale(locale){if(!locale){return"";}
const regex=/^([a-z]+)(_[A-Z\d]+)?(@.+)?$/;const match=locale.match(regex);if(!match){return locale;}
const[,language,territory,modifier]=match;const subtags=[language];switch(modifier){case"@Cyrl":subtags.push("Cyrl");break;case"@latin":subtags.push("Latn");break;}
if(territory){subtags.push(territory.slice(1));}
return subtags.join("-");}
return __exports;});;
/* /web/static/src/core/l10n/utils/normalize.js */
odoo.define('@web/core/l10n/utils/normalize',[],function(require){'use strict';let __exports={};__exports.normalize=normalize;function normalize(str){return casefold(unaccent(expandLigatures(str.normalize("NFKC"))));}
__exports.normalizedMatch=normalizedMatch;function normalizedMatch(src,substr){if(!substr){return{start:0,end:0,match:""};}
const srcAsCodepoints=Array.from(src);const normalizedSrc=srcAsCodepoints.map(normalize);const normalizedSubstr=Array.from(normalize(substr));const flattenSrcLength=normalizedSrc.reduce((acc,x)=>acc+Math.max(x.length,1),0);for(let i=0;i<=flattenSrcLength-normalizedSubstr.length;++i){const substrStack=Array.from(normalizedSubstr).reverse();for(let j=0;i+j<normalizedSrc.length;++j){const current=normalizedSrc[i+j];if(![...current].every((c)=>substrStack.length===0||c===substrStack.pop())){break;}
if(substrStack.length===0){const start=srcAsCodepoints.slice(0,i).join("").length;const match=srcAsCodepoints.slice(i,i+j+1).join("");const end=start+match.length;return{start,end,match};}}}
return{start:-1,end:-1,match:""};}
__exports.normalizedMatches=normalizedMatches;function normalizedMatches(src,substr){const matches=[];let index=0;while(src.length){const{start,end,match}=normalizedMatch(src,substr);if(match){matches.push({start:index+start,end:index+end,match});index+=end;src=src.slice(end);}else{break;}}
return matches;}
const DECOMPOSITION_BY_LIGATURE=new Map([["Æ","Ae"],["æ","ae"],["Œ","Oe"],["œ","oe"],["IJ","IJ"],["ij","ij"],]);function expandLigatures(str){return Array.from(str,(char)=>DECOMPOSITION_BY_LIGATURE.get(char)??char).join("");}
const DIACRITIC_LIKES=new Map([["Ø","O"],["ø","o"],["Ł","L"],["ł","l"],["Ð","D"],["ð","d"],["Ħ","H"],["ħ","h"],["Ŧ","T"],["ŧ","t"],]);function unaccent(str){return Array.from(str.normalize("NFD").replace(/\p{Nonspacing_Mark}/gu,""),(char)=>DIACRITIC_LIKES.get(char)??char).join("");}
function casefold(str){return str.toLowerCase().toUpperCase().toLowerCase();}
return __exports;});;
/* /web/static/src/core/macro.js */
odoo.define('@web/core/macro',['@web/core/utils/ui','@web/core/utils/concurrency','@odoo/owl'],function(require){'use strict';let __exports={};const{isVisible}=require("@web/core/utils/ui");const{delay}=require("@web/core/utils/concurrency");const{validate}=require("@odoo/owl");const macroSchema={name:{type:String,optional:true},timeout:{type:Number,optional:true},steps:{type:Array,element:{type:Object,shape:{action:{type:[Function,String],optional:true},timeout:{type:Number,optional:true},trigger:{type:[Function,String],optional:true},},validate:(step)=>step.action||step.trigger,},},onComplete:{type:Function,optional:true},onStep:{type:Function,optional:true},onError:{type:Function,optional:true},};class MacroError extends Error{constructor(type,message,options){super(message,options);this.type=type;}}
async function performAction(trigger,action){if(!action){return;}
try{return await action(trigger);}catch(error){throw new MacroError("Action",error.stack||`ERROR during perform action: ${error.message}`,{cause:error});}}
async function waitForTrigger(trigger){if(!trigger){return;}
try{await delay(50);return await waitUntil(()=>{if(typeof trigger==="function"){return trigger();}else if(typeof trigger==="string"){const triggerEl=document.querySelector(trigger);return isVisible(triggerEl)&&triggerEl;}});}catch(error){throw new MacroError("Trigger",`ERROR during find trigger:\n${error.message}`,{cause:error,});}}
__exports.waitUntil=waitUntil;async function waitUntil(predicate){const result=predicate();if(result){return Promise.resolve(result);}
let handle;return new Promise((resolve)=>{const runCheck=()=>{const result=predicate();if(result){resolve(result);}
handle=requestAnimationFrame(runCheck);};handle=requestAnimationFrame(runCheck);}).finally(()=>{cancelAnimationFrame(handle);});}
const Macro=__exports.Macro=class Macro{currentIndex=0;isComplete=false;constructor(descr){try{validate(descr,macroSchema);}catch(error){throw new Error(`Error in schema for Macro ${JSON.stringify(descr, null, 4)}\n${error.message}`);}
Object.assign(this,descr);this.onComplete=this.onComplete||(()=>{});this.onStep=this.onStep||(()=>{});this.onError=this.onError||((error,step,index)=>{console.error(error.message,step,index);});}
async start(){await this.advance();}
async advance(){if(this.isComplete||this.currentIndex>=this.steps.length){this.stop();return;}
try{const step=this.steps[this.currentIndex];const timeoutDelay=step.timeout||this.timeout||10000;const executeStep=async()=>{const trigger=await waitForTrigger(step.trigger);const result=await performAction(trigger,step.action);await this.onStep({step,trigger,index:this.currentIndex});return result;};const launchTimer=async()=>{await delay(timeoutDelay);throw new MacroError("Timeout",`TIMEOUT step failed to complete within ${timeoutDelay} ms.`);};const actionResult=await Promise.race([executeStep(),launchTimer()]);if(actionResult){this.stop();return;}}catch(error){this.stop(error);return;}
this.currentIndex++;await this.advance();}
stop(error){if(this.isComplete){return;}
this.isComplete=true;if(error){const step=this.steps[this.currentIndex];this.onError({error,step,index:this.currentIndex});}else if(this.currentIndex===this.steps.length){this.onComplete();}}}
const MacroMutationObserver=__exports.MacroMutationObserver=class MacroMutationObserver{observerOptions={attributes:true,childList:true,subtree:true,characterData:true,};constructor(callback){this.callback=callback;this.observer=new MutationObserver((mutationList,observer)=>{callback(mutationList);mutationList.forEach((mutationRecord)=>Array.from(mutationRecord.addedNodes).forEach((node)=>{let iframes=[];if(String(node.tagName).toLowerCase()==="iframe"){iframes=[node];}else if(node instanceof HTMLElement){iframes=Array.from(node.querySelectorAll("iframe"));}
iframes.forEach((iframeEl)=>this.observeIframe(iframeEl,observer,()=>callback()));this.findAllShadowRoots(node).forEach((shadowRoot)=>observer.observe(shadowRoot,this.observerOptions));}));});}
disconnect(){this.observer.disconnect();}
findAllShadowRoots(node,shadowRoots=[]){if(node.shadowRoot){shadowRoots.push(node.shadowRoot);this.findAllShadowRoots(node.shadowRoot,shadowRoots);}
node.childNodes.forEach((child)=>{this.findAllShadowRoots(child,shadowRoots);});return shadowRoots;}
observe(target){this.observer.observe(target,this.observerOptions);target.querySelectorAll("iframe").forEach((el)=>this.observeIframe(el,this.observer,()=>this.callback()));this.findAllShadowRoots(target).forEach((shadowRoot)=>{this.observer.observe(shadowRoot,this.observerOptions);});}
observeIframe(iframeEl,observer,callback){const observerOptions={attributes:true,childList:true,subtree:true,characterData:true,};const observeIframeContent=()=>{if(iframeEl.contentDocument){iframeEl.contentDocument.addEventListener("load",(event)=>{callback();observer.observe(event.target,observerOptions);});if(!iframeEl.src||iframeEl.contentDocument.readyState==="complete"){callback();observer.observe(iframeEl.contentDocument,observerOptions);}}};observeIframeContent();iframeEl.addEventListener("load",observeIframeContent);}}
return __exports;});;
/* /web/static/src/core/main_components_container.js */
odoo.define('@web/core/main_components_container',['@odoo/owl','@web/core/registry','@web/core/registry_hook','@web/core/utils/components','@web/core/l10n/localization'],function(require){'use strict';let __exports={};const{Component,xml}=require("@odoo/owl");const{registry}=require("@web/core/registry");const{useRegistry}=require("@web/core/registry_hook");const{ErrorHandler}=require("@web/core/utils/components");const{localization}=require("@web/core/l10n/localization");const mainComponents=registry.category("main_components");mainComponents.addValidation({Component:{validate:(c)=>c.prototype instanceof Component},props:{type:Object,optional:true}});const MainComponentsContainer=__exports.MainComponentsContainer=class MainComponentsContainer extends Component{static components={ErrorHandler};static props={};static template=xml`
<div class="o-main-components-container" t-att-class="{'o_rtl': this.isRTL}">
<t t-foreach="Components.entries" t-as="C" t-key="C[0]">
<ErrorHandler onError="error => this.handleComponentError(error, C)">
<t t-component="C[1].Component" t-props="C[1].props"/>
</ErrorHandler>
</t>
</div>
`;setup(){this.Components=useRegistry(mainComponents);this.isRTL=localization.direction==="rtl";}
handleComponentError(error,C){this.Components.entries.splice(this.Components.entries.indexOf(C),1);this.render();Promise.resolve().then(()=>{throw error;});}}
return __exports;});;
/* /web/static/src/core/model_field_selector/model_field_selector.js */
odoo.define('@web/core/model_field_selector/model_field_selector',['@odoo/owl','@web/core/popover/popover_hook','@web/core/utils/concurrency','@web/core/utils/hooks','@web/core/model_field_selector/model_field_selector_popover'],function(require){'use strict';let __exports={};const{Component,onWillStart,onWillUpdateProps,useState}=require("@odoo/owl");const{usePopover}=require("@web/core/popover/popover_hook");const{KeepLast}=require("@web/core/utils/concurrency");const{useService}=require("@web/core/utils/hooks");const{ModelFieldSelectorPopover}=require("@web/core/model_field_selector/model_field_selector_popover");const ModelFieldSelector=__exports.ModelFieldSelector=class ModelFieldSelector extends Component{static template="web._ModelFieldSelector";static components={Popover:ModelFieldSelectorPopover,};static props={resModel:String,path:{optional:true},allowEmpty:{type:Boolean,optional:true},readonly:{type:Boolean,optional:true},readProperty:{type:Boolean,optional:true},showSearchInput:{type:Boolean,optional:true},isDebugMode:{type:Boolean,optional:true},update:{type:Function,optional:true},filter:{type:Function,optional:true},sort:{type:Function,optional:true},followRelations:{type:Boolean,optional:true},showDebugInput:{type:Boolean,optional:true},};static defaultProps={readonly:true,allowEmpty:false,isDebugMode:false,showSearchInput:true,update:()=>{},followRelations:true,};setup(){this.fieldService=useService("field");this.popover=usePopover(this.constructor.components.Popover,{popoverClass:"o_popover_field_selector",onClose:async()=>{if(this.newPath!==null){const fieldInfo=await this.fieldService.loadFieldInfo(this.props.resModel,this.newPath);this.props.update(this.newPath,fieldInfo);}},});this.keepLast=new KeepLast();this.state=useState({isInvalid:false,displayNames:[]});onWillStart(()=>this.updateState(this.props));onWillUpdateProps((nextProps)=>{const modelPathKeys=["resModel","path","allowEmpty"];if(modelPathKeys.some((key)=>this.props[key]!==nextProps[key])){this.updateState(nextProps);}});}
openPopover(currentTarget){if(this.props.readonly){return;}
this.newPath=null;this.popover.open(currentTarget,{resModel:this.props.resModel,path:this.props.path,readProperty:this.props.readProperty,update:(path,_fieldInfo,debug=false)=>{this.newPath=path;if(!debug){this.updateState({...this.props,path},true);}},showSearchInput:this.props.showSearchInput,isDebugMode:this.props.isDebugMode,filter:this.props.filter,sort:this.props.sort,followRelations:this.props.followRelations,showDebugInput:this.props.showDebugInput,});}
async updateState(params,isConcurrent){const{resModel,path,allowEmpty}=params;let prom=this.fieldService.loadPathDescription(resModel,path,allowEmpty);if(isConcurrent){prom=this.keepLast.add(prom);}
const state=await prom;Object.assign(this.state,state);}
clear(){if(this.popover.isOpen){this.newPath="";this.popover.close();return;}
this.props.update("",{resModel:this.props.resModel,fieldDef:null});}}
return __exports;});;
/* /web/static/src/core/model_field_selector/model_field_selector_popover.js */
odoo.define('@web/core/model_field_selector/model_field_selector_popover',['@odoo/owl','@web/core/l10n/translation','@web/core/utils/arrays','@web/core/utils/concurrency','@web/core/utils/hooks','@web/core/utils/search','@web/core/utils/timing'],function(require){'use strict';let __exports={};const{Component,onWillStart,useEffect,useRef,useState}=require("@odoo/owl");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{sortBy}=require("@web/core/utils/arrays");const{KeepLast}=require("@web/core/utils/concurrency");const{useService}=require("@web/core/utils/hooks");const{fuzzyLookup}=require("@web/core/utils/search");const{debounce}=require("@web/core/utils/timing");class Page{constructor(resModel,fieldDefs,options={}){this.resModel=resModel;this.fieldDefs=fieldDefs;const{previousPage=null,selectedName=null,isDebugMode,readProperty=false,sortFn=(fieldDefs)=>sortBy(Object.keys(fieldDefs),(key)=>fieldDefs[key].string),}=options;this.previousPage=previousPage;this.selectedName=selectedName;this.isDebugMode=isDebugMode;this.readProperty=readProperty;this.sortedFieldNames=sortFn(fieldDefs);this.fieldNames=this.sortedFieldNames;this.query="";this.focusedFieldName=null;this.resetFocusedFieldName();}
get path(){const previousPath=this.previousPage?.path||"";const name=this.selectedName;if(this.readProperty&&this.selectedField&&this.selectedField.is_property){if(this.selectedField.relation){return`${previousPath}.get('${name}', env['${this.selectedField.relation}'])`;}
return`${previousPath}.get('${name}')`;}
if(name){if(previousPath){return`${previousPath}.${name}`;}
return name;}
return previousPath;}
get selectedField(){return this.fieldDefs[this.selectedName];}
get title(){const prefix=this.previousPage?.previousPage?"... > ":"";const title=this.previousPage?.selectedField?.string||"";if(prefix.length||title.length){return`${prefix}${title}`;}
return _t("Select a field");}
focus(direction){if(!this.fieldNames.length){return;}
const index=this.fieldNames.indexOf(this.focusedFieldName);if(direction==="previous"){if(index===0){this.focusedFieldName=this.fieldNames[this.fieldNames.length-1];}else{this.focusedFieldName=this.fieldNames[index-1];}}else{if(index===this.fieldNames.length-1){this.focusedFieldName=this.fieldNames[0];}else{this.focusedFieldName=this.fieldNames[index+1];}}}
resetFocusedFieldName(){if(this.selectedName&&this.fieldNames.includes(this.selectedName)){this.focusedFieldName=this.selectedName;}else{this.focusedFieldName=this.fieldNames.length?this.fieldNames[0]:null;}}
searchFields(query=""){this.query=query;this.fieldNames=this.sortedFieldNames;if(query){this.fieldNames=fuzzyLookup(query,this.fieldNames,(key)=>{const vals=[this.fieldDefs[key].string];if(this.isDebugMode){vals.push(key);}
return vals;});}
this.resetFocusedFieldName();}}
const ModelFieldSelectorPopover=__exports.ModelFieldSelectorPopover=class ModelFieldSelectorPopover extends Component{static template="web.ModelFieldSelectorPopover";static props={close:Function,filter:{type:Function,optional:true},sort:{type:Function,optional:true},followRelations:{type:Boolean,optional:true},showDebugInput:{type:Boolean,optional:true},isDebugMode:{type:Boolean,optional:true},path:{optional:true},readProperty:{type:Boolean,optional:true},resModel:String,showSearchInput:{type:Boolean,optional:true},update:Function,};static defaultProps={filter:(value)=>value.searchable&&value.type!="json"&&value.type!=="separator",isDebugMode:false,followRelations:true,};setup(){this.fieldService=useService("field");this.state=useState({page:null});this.keepLast=new KeepLast();this.debouncedSearchFields=debounce(this.searchFields.bind(this),250);onWillStart(async()=>{this.state.page=await this.loadPages(this.props.resModel,this.props.path);});const rootRef=useRef("root");useEffect(()=>{const focusedElement=rootRef.el.querySelector(".o_model_field_selector_popover_item.active");if(focusedElement){focusedElement.scrollIntoView({block:"center"});}});useEffect(()=>{if(this.props.showSearchInput){const searchInput=rootRef.el.querySelector(".o_model_field_selector_popover_search .o_input");searchInput.focus();}},()=>[this.state.page]);}
get fieldNames(){return this.state.page.fieldNames;}
get showDebugInput(){return this.props.showDebugInput??this.props.isDebugMode;}
canFollowRelationFor(fieldDef){if(fieldDef.type==="properties"){return true;}
if(!this.props.followRelations){return false;}
return fieldDef.relation;}
filter(fieldDefs,path,resModel){const filteredKeys=Object.keys(fieldDefs).filter((k)=>this.props.filter(fieldDefs[k],path,resModel));return Object.fromEntries(filteredKeys.map((k)=>[k,fieldDefs[k]]));}
async followRelation(fieldDef){const{modelsInfo}=await this.keepLast.add(this.fieldService.loadPath(fieldDef.is_property?fieldDef.relation:this.state.page.resModel,`${fieldDef.name}.*`));this.state.page.selectedName=fieldDef.name;const{resModel,fieldDefs}=modelsInfo.at(-1);this.openPage(new Page(resModel,this.filter(fieldDefs,this.state.page.path,resModel),{previousPage:this.state.page,isDebugMode:this.props.isDebugMode,readProperty:this.props.readProperty,sortFn:this.props.sort,}));}
goToPreviousPage(){this.keepLast.add(Promise.resolve());this.openPage(this.state.page.previousPage);}
async loadNewPath(path){const newPage=await this.keepLast.add(this.loadPages(this.props.resModel,path));this.openPage(newPage);}
async loadPages(resModel,path){if(typeof path!=="string"||!path.length){const fieldDefs=await this.fieldService.loadFields(resModel);return new Page(resModel,this.filter(fieldDefs,path,resModel),{isDebugMode:this.props.isDebugMode,readProperty:this.props.readProperty,sortFn:this.props.sort,});}
const{isInvalid,modelsInfo,names}=await this.fieldService.loadPath(resModel,path);switch(isInvalid){case"model":throw new Error(`Invalid model name: ${resModel}`);case"path":{const{resModel,fieldDefs}=modelsInfo[0];return new Page(resModel,this.filter(fieldDefs,path,resModel),{selectedName:path,isDebugMode:this.props.isDebugMode,readProperty:this.props.readProperty,sortFn:this.props.sort,});}
default:{let page=null;for(let index=0;index<names.length;index++){const name=names[index];const{resModel,fieldDefs}=modelsInfo[index];page=new Page(resModel,this.filter(fieldDefs,path,resModel),{previousPage:page,selectedName:name,isDebugMode:this.props.isDebugMode,readProperty:this.props.readProperty,sortFn:this.props.sort,});}
return page;}}}
openPage(page){this.state.page=page;this.state.page.searchFields();this.props.update(page.path);}
searchFields(query){this.state.page.searchFields(query);}
selectField(field){if(field.type==="properties"){return this.followRelation(field);}
this.keepLast.add(Promise.resolve());this.state.page.selectedName=field.name;this.props.update(this.state.page.path,field);this.props.close(true);}
onDebugInputKeydown(ev){switch(ev.key){case"Enter":{ev.preventDefault();ev.stopPropagation();this.loadNewPath(ev.currentTarget.value);break;}}}
async onInputKeydown(ev){const{page}=this.state;switch(ev.key){case"ArrowUp":{if(ev.target.selectionStart===0){page.focus("previous");}
break;}
case"ArrowDown":{if(ev.target.selectionStart===page.query.length){page.focus("next");}
break;}
case"ArrowLeft":{if(ev.target.selectionStart===0&&page.previousPage){this.goToPreviousPage();}
break;}
case"ArrowRight":{if(ev.target.selectionStart===page.query.length){const focusedFieldName=this.state.page.focusedFieldName;if(focusedFieldName){const fieldDef=this.state.page.fieldDefs[focusedFieldName];if(this.canFollowRelationFor(fieldDef)){this.followRelation(fieldDef);}}}
break;}
case"Enter":{const focusedFieldName=this.state.page.focusedFieldName;if(focusedFieldName){const fieldDef=this.state.page.fieldDefs[focusedFieldName];this.selectField(fieldDef);}else{ev.preventDefault();ev.stopPropagation();}
break;}
case"Escape":{ev.preventDefault();ev.stopPropagation();this.props.close();break;}}}}
return __exports;});;
/* /web/static/src/core/model_selector/model_selector.js */
odoo.define('@web/core/model_selector/model_selector',['@web/core/autocomplete/autocomplete','@web/core/utils/hooks','@web/core/utils/search','@web/core/l10n/translation','@odoo/owl'],function(require){'use strict';let __exports={};const{AutoComplete}=require("@web/core/autocomplete/autocomplete");const{useService}=require("@web/core/utils/hooks");const{fuzzyLookup}=require("@web/core/utils/search");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{Component,onWillStart}=require("@odoo/owl");const ModelSelector=__exports.ModelSelector=class ModelSelector extends Component{static template="web.ModelSelector";static components={AutoComplete};static props={onModelSelected:Function,id:{type:String,optional:true},value:{type:String,optional:true},placeholder:{type:String,optional:true},models:{type:Array,optional:true},nbVisibleModels:{type:Number,optional:true},autofocus:{type:Boolean,optional:true},};setup(){this.orm=useService("orm");onWillStart(async()=>{if(!this.props.models){this.models=await this._fetchAvailableModels();}else{this.models=await this.orm.call("ir.model","display_name_for",[this.props.models,]);}
this.models=this.models.map((record)=>({cssClass:`o_model_selector_${record.model.replaceAll(".", "_")}`,data:{technical:record.model,},label:record.display_name,onSelect:()=>this.props.onModelSelected({label:record.display_name,technical:record.model,}),}));});}
get sources(){return[this.optionsSource];}
get placeholder(){return this.props.placeholder||_t("Type a model here...");}
get optionsSource(){return{placeholder:_t("Loading..."),options:this.loadOptionsSource.bind(this),};}
get nbVisibleModels(){return this.props.nbVisibleModels||8;}
filterModels(name){if(!name){const visibleModels=this.models.slice(0,this.nbVisibleModels);if(this.models.length-visibleModels.length>0){visibleModels.push({label:_t("Start typing..."),cssClass:"o_m2o_start_typing",});}
return visibleModels;}
return fuzzyLookup(name,this.models,(model)=>model.data.technical+model.label);}
loadOptionsSource(request){const options=this.filterModels(request);if(!options.length){options.push({label:_t("No records"),cssClass:"o_m2o_no_result",});}
return options;}
async _fetchAvailableModels(){const result=await this.orm.call("ir.model","get_available_models");return result||[];}}
return __exports;});;
/* /web/static/src/core/name_service.js */
odoo.define('@web/core/name_service',['@web/core/registry','@web/core/utils/arrays','@web/core/utils/concurrency'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{unique,zip}=require("@web/core/utils/arrays");const{Deferred}=require("@web/core/utils/concurrency");const ERROR_INACCESSIBLE_OR_MISSING=__exports.ERROR_INACCESSIBLE_OR_MISSING=Symbol("INACCESSIBLE OR MISSING RECORD ID");function isId(val){return Number.isInteger(val)&&val>=1;}
const nameService=__exports.nameService={dependencies:["orm"],async:["loadDisplayNames"],start(env,{orm}){let cache={};const batches={};function clearCache(){cache={};}
env.bus.addEventListener("ACTION_MANAGER:UPDATE",clearCache);function getMapping(resModel){if(!cache[resModel]){cache[resModel]={};}
return cache[resModel];}
function addDisplayNames(resModel,displayNames){const mapping=getMapping(resModel);for(const resId in displayNames){mapping[resId]=new Deferred();mapping[resId].resolve(displayNames[resId]);}}
async function loadDisplayNames(resModel,resIds){const mapping=getMapping(resModel);const proms=[];const resIdsToFetch=[];for(const resId of unique(resIds)){if(!isId(resId)){throw new Error(`Invalid ID: ${resId}`);}
if(!(resId in mapping)){mapping[resId]=new Deferred();resIdsToFetch.push(resId);}
proms.push(mapping[resId]);}
if(resIdsToFetch.length){if(batches[resModel]){batches[resModel].push(...resIdsToFetch);}else{batches[resModel]=resIdsToFetch;await Promise.resolve();const idsInBatch=unique(batches[resModel]);delete batches[resModel];const specification={display_name:{}};orm.silent.webSearchRead(resModel,[["id","in",idsInBatch]],{specification,context:{active_test:false},}).then(({records})=>{const displayNames=Object.fromEntries(records.map((rec)=>[rec.id,rec.display_name]));for(const resId of idsInBatch){mapping[resId].resolve(resId in displayNames?displayNames[resId]:ERROR_INACCESSIBLE_OR_MISSING);}});}}
const names=await Promise.all(proms);return Object.fromEntries(zip(resIds,names));}
return{addDisplayNames,clearCache,loadDisplayNames};},};registry.category("services").add("name",nameService);return __exports;});;
/* /web/static/src/core/navigation/navigation.js */
odoo.define('@web/core/navigation/navigation',['@odoo/owl','@web/core/utils/hooks','@web/core/utils/objects','@web/core/utils/scrolling','@web/core/utils/timing','@web/core/browser/browser'],function(require){'use strict';let __exports={};const{onWillUnmount,useEffect,useExternalListener,useRef}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{deepMerge}=require("@web/core/utils/objects");const{scrollTo}=require("@web/core/utils/scrolling");const{throttleForAnimation}=require("@web/core/utils/timing");const{browser}=require("@web/core/browser/browser");const ACTIVE_ELEMENT_CLASS=__exports.ACTIVE_ELEMENT_CLASS="focus";const throttledFocus=throttleForAnimation((el)=>el?.focus());class NavigationItem{index=-1;el=undefined;target=undefined;constructor({index,el,options,navigator}){this.index=index;this._options=options;this._navigator=navigator;this.el=el;if(this._options.shouldFocusChildInput){const subInput=el.querySelector(":scope input, :scope button, :scope textarea");this.target=subInput||el;}else{this.target=el;}
if(this.el.ariaSelected!==true){this.el.ariaSelected=false;}
const onFocus=()=>this.setActive(false);const onMouseMove=()=>this._onMouseMove();this.target.addEventListener("focus",onFocus);this.target.addEventListener("mousemove",onMouseMove);this._removeListeners=()=>{this.target.removeEventListener("focus",onFocus);this.target.removeEventListener("mousemove",onMouseMove);};}
select(){this.setActive();this.target.click();}
setActive(focus=true){scrollTo(this.target);this._navigator._setActiveItem(this.index);this.target.classList.add(ACTIVE_ELEMENT_CLASS);this.target.ariaSelected=true;if(focus&&!this._options.virtualFocus){throttledFocus.cancel();throttledFocus(this.target);}}
setInactive(blur=true){this.target.classList.remove(ACTIVE_ELEMENT_CLASS);this.target.ariaSelected=false;if(blur&&!this._options.virtualFocus){this.target.blur();}}
_onMouseMove(){if(this._navigator.activeItem!==this&&this._navigator._isNavigationAvailable(this.target)){this.setActive(false);this._options.onMouseEnter?.(this);}}}
const Navigator=__exports.Navigator=class Navigator{activeItem=undefined;activeItemIndex=-1;items=[];_hotkeyRemoves=[];_hotkeyService=undefined;constructor(options,hotkeyService){this._hotkeyService=hotkeyService;this._options=deepMerge({isNavigationAvailable:({target})=>this.contains(target)&&(this.isFocused||this._options.virtualFocus),shouldFocusChildInput:true,shouldFocusFirstItem:false,shouldRegisterHotkeys:true,virtualFocus:false,hotkeys:{home:()=>this.items[0]?.setActive(),end:()=>this.items.at(-1)?.setActive(),tab:{callback:()=>this.next(),bypassEditableProtection:true,},"shift+tab":{callback:()=>this.previous(),bypassEditableProtection:true,},arrowdown:{callback:()=>this.next(),bypassEditableProtection:true,},arrowup:{callback:()=>this.previous(),bypassEditableProtection:true,},enter:{isAvailable:({navigator})=>Boolean(navigator.activeItem),callback:()=>{const item=this.activeItem||this.items[0];item?.select();},bypassEditableProtection:true,},},},options);if(this._options.shouldRegisterHotkeys){this.registerHotkeys();}}
get hasActiveItem(){return Boolean(this.activeItem?.el.isConnected);}
get isFocused(){return this.items.some((item)=>item.target.contains(document.activeElement));}
next(){if(!this.hasActiveItem){this.items[0]?.setActive();}else{this.items[(this.activeItemIndex+1)%this.items.length]?.setActive();}}
previous(){const index=this.activeItemIndex-1;if(!this.hasActiveItem||index<0){this.items.at(-1)?.setActive();}else{this.items[index%this.items.length]?.setActive();}}
update(){const oldItems=new Map(this.items.map((item)=>[item.el,item]));const oldActiveItem=this.activeItem;const elements=this._options.getItems();this.items=[];let didUpdate=elements.length!==oldItems.size;for(let index=0;index<elements.length;index++){const element=elements[index];let item=oldItems.get(element);if(item){if(item.index!==index){item.index=index;didUpdate=true;}
oldItems.delete(element);}else{didUpdate=true;item=new NavigationItem({index,el:element,options:this._options,navigator:this,});}
this.items.push(item);}
for(const item of oldItems.values()){item._removeListeners();}
if(didUpdate){const activeItemIndex=oldActiveItem&&oldActiveItem.el.isConnected?this.items.findIndex((item)=>item.el===oldActiveItem.el):-1;const focusedElementIndex=this.items.findIndex((item)=>item.el===document.activeElement);if(activeItemIndex>-1){this._updateActiveItemIndex(activeItemIndex);}else if(this.activeItemIndex>=0){const closest=Math.min(this.activeItemIndex,elements.length-1);this._updateActiveItemIndex(closest);}else if(focusedElementIndex>=0){this._updateActiveItemIndex(focusedElementIndex);}else{this._updateActiveItemIndex(-1);}
this._options.onUpdated?.(this);if(this._options.shouldFocusFirstItem){this.items[0]?.setActive();}}}
contains(target){return this.items.some((item)=>item.target.contains(target));}
registerHotkeys(){if(this._hotkeyRemoves.length>0){return;}
for(const[hotkey,hotkeyInfo]of Object.entries(this._options.hotkeys)){if(!hotkeyInfo){continue;}
const callback=typeof hotkeyInfo=="function"?hotkeyInfo:hotkeyInfo.callback;if(!callback){continue;}
const isAvailable=hotkeyInfo?.isAvailable??(()=>true);const bypassEditableProtection=hotkeyInfo?.bypassEditableProtection??false;const allowRepeat=hotkeyInfo?.allowRepeat??true;this._hotkeyRemoves.push(this._hotkeyService.add(hotkey,async()=>await callback(this),{global:true,allowRepeat,isAvailable:(target)=>this._isNavigationAvailable(target)&&isAvailable({navigator:this,target}),bypassEditableProtection,}));}}
unregisterHotkeys(){for(const removeHotkey of this._hotkeyRemoves){removeHotkey();}
this._hotkeyRemoves=[];}
_destroy(){for(const item of this.items){item._removeListeners();}
this.items=[];this.unregisterHotkeys();}
_setActiveItem(index){this.activeItem?.setInactive(false);this.activeItemIndex=index;if(index>=0){this.activeItem=this.items[index];this._options.onItemActivated?.(this.activeItem.el);}else{this.activeItem=null;}}
_updateActiveItemIndex(index){if(this.items[index]){const shouldFocus=!this.items.some((item)=>item.target===document.activeElement);this.items[index].setActive(shouldFocus);}else{this.activeItemIndex=-1;this.activeItem=null;}}
_isNavigationAvailable(target){return this._options.isNavigationAvailable({navigator:this,target});}
_checkFocus(target){if(!(target instanceof HTMLElement)||!this._isNavigationAvailable(target)){this._setActiveItem(-1);}}}
__exports.useNavigation=useNavigation;function useNavigation(containerRef,options={}){containerRef=typeof containerRef==="string"?useRef(containerRef):containerRef;const newOptions={...options};if(!newOptions.getItems){newOptions.getItems=()=>containerRef.el?.querySelectorAll(":scope .o-navigable")??[];}
const hotkeyService=useService("hotkey");const navigator=new Navigator(newOptions,hotkeyService);const observer=new MutationObserver(()=>navigator.update());useEffect((containerEl)=>{if(containerEl){navigator.update();observer.observe(containerEl,{childList:true,subtree:true,});}
return()=>observer.disconnect();},()=>[containerRef.el]);useExternalListener(browser,"focus",({target})=>navigator._checkFocus(target),true);onWillUnmount(()=>navigator._destroy());return navigator;}
return __exports;});;
/* /web/static/src/core/network/download.js */
odoo.define('@web/core/network/download',['@web/core/l10n/translation','@web/core/network/rpc','@web/core/browser/browser'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{makeErrorFromResponse,ConnectionLostError}=require("@web/core/network/rpc");const{browser}=require("@web/core/browser/browser");const HEX_ESCAPE_REPLACE_REGEXP=/%([0-9A-Fa-f]{2})/g;const NON_LATIN1_REGEXP=/[^\x20-\x7e\xa0-\xff]/g;const QESC_REGEXP=/\\([\u0000-\u007f])/g;const PARAM_REGEXP=/;[\x09\x20]*([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*=[\x09\x20]*("(?:[\x09\x20!\x23-\x5b\x5d-\x7e\x80-\xff]|\\[\x20-\x7e])*"|[!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*/g;const EXT_VALUE_REGEXP=/^([A-Za-z0-9!#$%&+\-^_`{}~]+)'(?:[A-Za-z]{2,3}(?:-[A-Za-z]{3}){0,3}|[A-Za-z]{4,8}|)'((?:%[0-9A-Fa-f]{2}|[A-Za-z0-9!#$&+.^_`|~-])+)$/;const DISPOSITION_TYPE_REGEXP=/^([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*(?:$|;)/;function decodefield(str){const match=EXT_VALUE_REGEXP.exec(str);if(!match){throw new TypeError("invalid extended field value");}
const charset=match[1].toLowerCase();const encoded=match[2];switch(charset){case"iso-8859-1":return encoded.replace(HEX_ESCAPE_REPLACE_REGEXP,pdecode).replace(NON_LATIN1_REGEXP,"?");case"utf-8":return decodeURIComponent(encoded);default:throw new TypeError("unsupported charset in extended field");}}
__exports.parse=parse;function parse(string){if(!string||typeof string!=="string"){throw new TypeError("argument string is required");}
let match=DISPOSITION_TYPE_REGEXP.exec(string);if(!match){throw new TypeError("invalid type format");}
let index=match[0].length;const type=match[1].toLowerCase();let key;const names=[];const params={};let value;index=PARAM_REGEXP.lastIndex=match[0].substr(-1)===";"?index-1:index;while((match=PARAM_REGEXP.exec(string))){if(match.index!==index){throw new TypeError("invalid parameter format");}
index+=match[0].length;key=match[1].toLowerCase();value=match[2];if(names.indexOf(key)!==-1){throw new TypeError("invalid duplicate parameter");}
names.push(key);if(key.indexOf("*")+1===key.length){key=key.slice(0,-1);value=decodefield(value);params[key]=value;continue;}
if(typeof params[key]==="string"){continue;}
if(value[0]==='"'){value=value.substr(1,value.length-2).replace(QESC_REGEXP,"$1");}
params[key]=value;}
if(index!==-1&&index!==string.length){throw new TypeError("invalid parameter format");}
return new ContentDisposition(type,params);}
function pdecode(str,hex){return String.fromCharCode(parseInt(hex,16));}
function ContentDisposition(type,parameters){this.type=type;this.parameters=parameters;}
function _download(data,filename,mimetype){let self=window,defaultMime="application/octet-stream",mimeType=mimetype||defaultMime,payload=data,url=!filename&&!mimetype&&payload,anchor=document.createElement("a"),toString=function(a){return String(a);},myBlob=self.Blob||self.MozBlob||self.WebKitBlob||toString,fileName=filename||"download",blob,reader;myBlob=myBlob.call?myBlob.bind(self):Blob;if(String(this)==="true"){payload=[payload,mimeType];mimeType=payload[0];payload=payload[1];}
if(url&&url.length<2048){fileName=url.split("/").pop().split("?")[0];anchor.href=url;if(anchor.href.indexOf(url)!==-1){return new Promise((resolve,reject)=>{let xhr=new browser.XMLHttpRequest();xhr.open("GET",url,true);configureBlobDownloadXHR(xhr,{onSuccess:resolve,onFailure:reject,url});xhr.send();});}}
if(/^data:[\w+\-]+\/[\w+\-]+[,;]/.test(payload)){if(payload.length>1024*1024*1.999&&myBlob!==toString){payload=dataUrlToBlob(payload);mimeType=payload.type||defaultMime;}else{return navigator.msSaveBlob?navigator.msSaveBlob(dataUrlToBlob(payload),fileName):saver(payload);}}
blob=payload instanceof myBlob?payload:new myBlob([payload],{type:mimeType});function dataUrlToBlob(strUrl){let parts=strUrl.split(/[:;,]/),type=parts[1],decoder=parts[2]==="base64"?atob:decodeURIComponent,binData=decoder(parts.pop()),mx=binData.length,i=0,uiArr=new Uint8Array(mx);for(i;i<mx;++i){uiArr[i]=binData.charCodeAt(i);}
return new myBlob([uiArr],{type});}
function saver(url,winMode){if("download"in anchor){anchor.href=url;anchor.setAttribute("download",fileName);anchor.className="download-js-link";anchor.innerText=_t("downloading...");anchor.style.display="none";anchor.target="_blank";document.body.appendChild(anchor);setTimeout(()=>{anchor.click();document.body.removeChild(anchor);if(winMode===true){setTimeout(()=>{self.URL.revokeObjectURL(anchor.href);},250);}},66);return true;}
if(/(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(navigator.userAgent)){url=url.replace(/^data:([\w\/\-+]+)/,defaultMime);if(!window.open(url)){if(confirm("Displaying New Document\n\nUse Save As... to download, then click back to return to this page.")){location.href=url;}}
return true;}
let f=document.createElement("iframe");document.body.appendChild(f);if(!winMode){url=`data:${url.replace(/^data:([\w\/\-+]+)/, defaultMime)}`;}
f.src=url;setTimeout(()=>{document.body.removeChild(f);},333);}
if(navigator.msSaveBlob){return navigator.msSaveBlob(blob,fileName);}
if(self.URL){saver(self.URL.createObjectURL(blob),true);}else{if(typeof blob==="string"||blob.constructor===toString){try{return saver(`data:${mimeType};base64,${self.btoa(blob)}`);}catch{return saver(`data:${mimeType},${encodeURIComponent(blob)}`);}}
reader=new FileReader();reader.onload=function(){saver(this.result);};reader.readAsDataURL(blob);}
return true;}
__exports.downloadFile=downloadFile;function downloadFile(data,filename,mimetype){return downloadFile._download(data,filename,mimetype);}
downloadFile._download=_download;__exports.download=download;function download(options){return download._download(options);}
download._download=(options)=>{return new Promise((resolve,reject)=>{const xhr=new browser.XMLHttpRequest();let data;if(Object.prototype.hasOwnProperty.call(options,"form")){xhr.open(options.form.method,options.form.action);data=new FormData(options.form);}else{xhr.open("POST",options.url);data=new FormData();Object.entries(options.data).forEach((entry)=>{const[key,value]=entry;data.append(key,value);});}
data.append("token","dummy-because-api-expects-one");if(odoo.csrf_token){data.append("csrf_token",odoo.csrf_token);}
configureBlobDownloadXHR(xhr,{onSuccess:resolve,onFailure:reject,url:options.url,});xhr.send(data);});};__exports.configureBlobDownloadXHR=configureBlobDownloadXHR;function configureBlobDownloadXHR(xhr,{onSuccess=()=>{},onFailure=()=>{},url}={}){xhr.responseType="blob";xhr.onload=()=>{const mimetype=xhr.response.type;const header=(xhr.getResponseHeader("Content-Disposition")||"").replace(/;$/,"");const filename=header?parse(header).parameters.filename:null;if(xhr.status===200&&(mimetype!=="text/html"||filename)){_download(xhr.response,filename,mimetype);onSuccess(filename);}else if(xhr.status===502){onFailure(new ConnectionLostError(url));}else{const decoder=new FileReader();decoder.onload=()=>{const contents=decoder.result;const doc=new DOMParser().parseFromString(contents,"text/html");const nodes=doc.body.children.length===0?[doc.body]:doc.body.children;let error;try{const node=nodes[1]||nodes[0];error=JSON.parse(node.textContent);}catch{error={message:"Arbitrary Uncaught Python Exception",data:{debug:`${xhr.status}`+`\n`+`${nodes.length > 0 ? nodes[0].textContent : ""}
${nodes.length > 1 ? nodes[1].textContent : ""}`,},};}
error=makeErrorFromResponse(error);onFailure(error);};decoder.readAsText(xhr.response);}};xhr.onerror=()=>{onFailure(new ConnectionLostError(url));};}
return __exports;});;
/* /web/static/src/core/network/http_service.js */
odoo.define('@web/core/network/http_service',['@web/core/browser/browser','@web/core/registry'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");function checkResponseStatus(response){if(response.status===502){throw new Error("Failed to fetch");}
if(response.status===413){throw new Error("Content too large");}}
__exports.get=get;async function get(route,readMethod="json"){const response=await browser.fetch(route,{method:"GET"});checkResponseStatus(response);return response[readMethod]();}
__exports.post=post;async function post(route,params={},readMethod="json"){let formData=params;if(!(formData instanceof FormData)){formData=new FormData();for(const key in params){const value=params[key];if(Array.isArray(value)&&value.length){for(const val of value){formData.append(key,val);}}else{formData.append(key,value);}}}
const response=await browser.fetch(route,{body:formData,method:"POST",});checkResponseStatus(response);return response[readMethod]();}
const httpService=__exports.httpService={start(){return{get,post};},};registry.category("services").add("http",httpService);return __exports;});;
/* /web/static/src/core/network/rpc.js */
odoo.define('@web/core/network/rpc',['@odoo/owl','@web/core/browser/browser','@web/core/utils/objects'],function(require){'use strict';let __exports={};const{EventBus}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{omit}=require("@web/core/utils/objects");const rpcBus=__exports.rpcBus=new EventBus();const RPC_SETTINGS=new Set(["cache","silent","xhr","headers"]);function validateRPCSettings(settings){if(!Object.keys(settings).every((key)=>RPC_SETTINGS.has(key))){throw new Error(`The settings for rpc should be ${[...RPC_SETTINGS].join(" ")}`);}
if("cache"in settings&&"xhr"in settings){throw new Error("Can't use 'cache' and 'xhr' at the same time");}}
const RPCError=__exports.RPCError=class RPCError extends Error{constructor(){super(...arguments);this.name="RPC_ERROR";this.type="server";this.code=null;this.data=null;this.exceptionName=null;this.subType=null;}}
const ConnectionLostError=__exports.ConnectionLostError=class ConnectionLostError extends Error{constructor(url,...args){const message=url?`Connection to "${url}" couldn't be established or was interrupted`:"Connection couldn't be established or was interrupted";super(message,...args);this.url=url;}}
const ConnectionAbortedError=__exports.ConnectionAbortedError=class ConnectionAbortedError extends Error{}
const RequestEntityTooLargeError=__exports.RequestEntityTooLargeError=class RequestEntityTooLargeError extends Error{constructor(){super("The request you sent exceeded the maximum size limit configured on the server");}}
__exports.makeErrorFromResponse=makeErrorFromResponse;function makeErrorFromResponse(response){const{code,data:errorData,message,type:subType}=response;const error=new RPCError();error.exceptionName=errorData?.name;error.subType=subType;error.data=errorData;error.message=message;error.code=code;return error;}
let rpcCache;rpc.setCache=function(cache){rpcCache=cache;};rpcBus.addEventListener("CLEAR-CACHES",(event)=>{rpcCache?.invalidate(event.detail);});let rpcId=0;__exports.rpc=rpc;function rpc(url,params={},settings={}){return rpc._rpc(url,params,settings);}
rpc._rpc=function(url,params,settings){validateRPCSettings(settings);if(settings.cache&&rpcCache){return rpcCache.read(params?.method||url,JSON.stringify({url,params}),()=>rpc._rpc(url,params,omit(settings,"cache")),typeof settings.cache==="boolean"?{}:settings.cache);}
const XHR=browser.XMLHttpRequest;const data={id:rpcId++,jsonrpc:"2.0",method:"call",params:params,};const request=settings.xhr||new XHR();let rejectFn;const promise=new Promise((resolve,reject)=>{rejectFn=reject;rpcBus.trigger("RPC:REQUEST",{data,url,settings});request.addEventListener("load",()=>{let specialError=null;switch(request.status){case 502:specialError=new ConnectionLostError(url);break;case 413:specialError=new RequestEntityTooLargeError();break;}
if(specialError){rpcBus.trigger("RPC:RESPONSE",{data,settings,error:specialError});reject(specialError);return;}
let params;try{params=JSON.parse(request.response);}catch{const error=new ConnectionLostError(url);rpcBus.trigger("RPC:RESPONSE",{data,settings,error});return reject(error);}
const{error:responseError,result:responseResult}=params;if(!params.error){rpcBus.trigger("RPC:RESPONSE",{data,settings,result:params.result});return resolve(responseResult);}
const error=makeErrorFromResponse(responseError);error.model=data.params.model;rpcBus.trigger("RPC:RESPONSE",{data,settings,error});reject(error);});request.addEventListener("error",()=>{const error=new ConnectionLostError(url);rpcBus.trigger("RPC:RESPONSE",{data,settings,error});reject(error);});request.open("POST",url);const headers=settings.headers||{};headers["Content-Type"]="application/json";for(const[header,value]of Object.entries(headers)){request.setRequestHeader(header,value);}
request.send(JSON.stringify(data));});promise.abort=function(rejectError=true){if(request.abort){request.abort();}
const error=new ConnectionAbortedError("XmlHttpRequestError abort");rpcBus.trigger("RPC:RESPONSE",{data,settings,error});if(rejectError){rejectFn(error);}};return promise;};return __exports;});;
/* /web/static/src/core/network/rpc_cache.js */
odoo.define('@web/core/network/rpc_cache',['@web/core/utils/concurrency','@web/core/utils/indexed_db','@web/core/utils/objects'],function(require){'use strict';let __exports={};const{Deferred}=require("@web/core/utils/concurrency");const{IDBQuotaExceededError,IndexedDB}=require("@web/core/utils/indexed_db");const{deepCopy}=require("@web/core/utils/objects");function jsonEqual(v1,v2){return JSON.stringify(v1)===JSON.stringify(v2);}
function validateSettings({type,update}){if(!["ram","disk"].includes(type)){throw new Error(`Invalid "type" settings provided to RPCCache: ${type}`);}
if(!["always","once"].includes(update)){throw new Error(`Invalid "update" settings provided to RPCCache: ${update}`);}}
const CRYPTO_ALGO="AES-GCM";const MAX_STORAGE_SIZE=2*1024*1024*1024;class Crypto{constructor(secret){this._cryptoKey=null;this._ready=window.crypto.subtle.importKey("raw",new Uint8Array(secret.match(/../g).map((h)=>parseInt(h,16))).buffer,CRYPTO_ALGO,false,["encrypt","decrypt"]).then((encryptedKey)=>{this._cryptoKey=encryptedKey;});}
async encrypt(value){await this._ready;const iv=window.crypto.getRandomValues(new Uint8Array(12));const ciphertext=await window.crypto.subtle.encrypt({name:CRYPTO_ALGO,iv,length:64,},this._cryptoKey,new TextEncoder().encode(JSON.stringify(value)));return{ciphertext,iv};}
async decrypt({ciphertext,iv}){await this._ready;const decrypted=await window.crypto.subtle.decrypt({name:CRYPTO_ALGO,iv,length:64,},this._cryptoKey,ciphertext);return JSON.parse(new TextDecoder().decode(decrypted));}}
class RamCache{constructor(){this.ram={};}
write(table,key,value){if(!(table in this.ram)){this.ram[table]={};}
this.ram[table][key]=value;}
read(table,key){return this.ram[table]?.[key];}
delete(table,key){delete this.ram[table]?.[key];}
invalidate(tables=null){if(tables){tables=typeof tables==="string"?[tables]:tables;for(const table of tables){if(table in this.ram){this.ram[table]={};}}}else{this.ram={};}}}
const RPCCache=__exports.RPCCache=class RPCCache{constructor(name,version,secret){this.crypto=new Crypto(secret);this.indexedDB=new IndexedDB(name,version+CRYPTO_ALGO);this.ramCache=new RamCache();this.pendingRequests={};this.checkSize();}
async checkSize(){const{usage}=await navigator.storage.estimate();if(usage>MAX_STORAGE_SIZE){console.log(`Deleting indexedDB database as maximum storage size is reached`);return this.indexedDB.deleteDatabase();}}
read(table,key,fallback,{callback=()=>{},type="ram",update="once"}={}){validateSettings({type,update});let ramValue=this.ramCache.read(table,key);const requestKey=`${table}/${key}`;const hasPendingRequest=requestKey in this.pendingRequests;if(hasPendingRequest){this.pendingRequests[requestKey].callbacks.push(callback);return ramValue.then((result)=>deepCopy(result));}
if(!ramValue||update==="always"){const request={callbacks:[callback],invalidated:false};this.pendingRequests[requestKey]=request;const prom=new Promise((resolve,reject)=>{const fromCache=new Deferred();let fromCacheValue;const onFullfilled=(result)=>{resolve(result);const hasChanged=!!fromCacheValue&&!jsonEqual(fromCacheValue,result);request.callbacks.forEach((cb)=>cb(deepCopy(result),hasChanged));if(request.invalidated){return result;}
delete this.pendingRequests[requestKey];this.ramCache.write(table,key,Promise.resolve(result));if(type==="disk"){this.crypto.encrypt(result).then((encryptedResult)=>{this.indexedDB.write(table,key,encryptedResult).catch((e)=>{if(e instanceof IDBQuotaExceededError){this.indexedDB.deleteDatabase();}else{throw e;}});});}
return result;};const onRejected=async(error)=>{await fromCache;if(!request.invalidated){delete this.pendingRequests[requestKey];if(!fromCacheValue){this.ramCache.delete(table,key);}}
if(fromCacheValue){throw error;}
reject(error);};fallback().then(onFullfilled,onRejected);if(ramValue){ramValue.then((value)=>{resolve(value);fromCacheValue=value;fromCache.resolve();});}else if(type==="disk"){this.indexedDB.read(table,key).then(async(result)=>{if(result){let decrypted;try{decrypted=await this.crypto.decrypt(result);}catch{return;}
resolve(decrypted);fromCacheValue=decrypted;}}).finally(()=>fromCache.resolve());}else{fromCache.resolve();}});this.ramCache.write(table,key,prom);ramValue=prom;}
return ramValue.then((result)=>deepCopy(result));}
invalidate(tables){this.indexedDB.invalidate(tables);this.ramCache.invalidate(tables);for(const key in this.pendingRequests){this.pendingRequests[key].invalidated=true;}
this.pendingRequests={};}}
return __exports;});;
/* /web/static/src/core/notebook/notebook.js */
odoo.define('@web/core/notebook/notebook',['@odoo/owl','@web/core/utils/concurrency'],function(require){'use strict';let __exports={};const{Component,onWillRender,onWillUpdateProps,useEffect,useRef,useState}=require("@odoo/owl");const{KeepLast}=require("@web/core/utils/concurrency");const Notebook=__exports.Notebook=class Notebook extends Component{static template="web.Notebook";static defaultProps={className:"",orientation:"horizontal",onPageUpdate:()=>{},onWillActivatePage:()=>{},};static props={slots:{type:Object,optional:true},pages:{type:Object,optional:true},class:{optional:true},className:{type:String,optional:true},defaultPage:{type:String,optional:true},orientation:{type:String,optional:true},icons:{type:Object,optional:true},onPageUpdate:{type:Function,optional:true},onWillActivatePage:{type:Function,optional:true},};setup(){this.activePane=useRef("activePane");this.pages=this.computePages(this.props);this.invalidPages=new Set();this.state=useState({currentPage:null});this.state.currentPage=this.computeActivePage(this.props.defaultPage,true);this.keepLastPageTransition=new KeepLast();useEffect(()=>{this.props.onPageUpdate(this.state.currentPage);this.activePane.el?.classList.add("show");},()=>[this.state.currentPage]);onWillRender(()=>{this.computeInvalidPages();});onWillUpdateProps((nextProps)=>{const activateDefault=this.props.defaultPage!==nextProps.defaultPage||!this.defaultVisible;this.pages=this.computePages(nextProps);this.state.currentPage=this.computeActivePage(nextProps.defaultPage,activateDefault);});}
get navItems(){return this.pages.filter((e)=>e[1].isVisible);}
get page(){const page=this.pages.find((e)=>e[0]===this.state.currentPage)[1];return page.Component&&page;}
async activatePage(pageIndex){if(!this.disabledPages.includes(pageIndex)&&this.state.currentPage!==pageIndex){const prom=(async()=>this.props.onWillActivatePage(pageIndex))();const canProceed=await this.keepLastPageTransition.add(prom);if(canProceed!==false){this.activePane.el?.classList.remove("show");this.state.currentPage=pageIndex;}}}
computePages(props){if(!props.slots&&!props.pages){return[];}
if(props.pages){for(const page of props.pages){page.isVisible=true;}}
this.disabledPages=[];const pages=[];const pagesWithIndex=[];for(const[k,v]of Object.entries({...props.slots,...props.pages})){const id=v.id||k;if(v.index){pagesWithIndex.push([id,v]);}else{pages.push([id,v]);}
if(v.isDisabled){this.disabledPages.push(k);}}
for(const page of pagesWithIndex){pages.splice(page[1].index,0,page);}
return pages;}
computeActivePage(defaultPage,activateDefault){if(!this.pages.length){return null;}
const pages=this.pages.filter((e)=>e[1].isVisible).map((e)=>e[0]);if(defaultPage){if(!pages.includes(defaultPage)){this.defaultVisible=false;}else{this.defaultVisible=true;if(activateDefault){return defaultPage;}}}
const current=this.state.currentPage;if(!current||(current&&!pages.includes(current))){return pages[0];}
return current;}
computeInvalidPages(){this.invalidPages=new Set();for(const page of this.navItems){const invalid=page[1].fieldNames?.some((fieldName)=>this.env.model?.root.isFieldInvalid(fieldName));if(invalid){this.invalidPages.add(page[0]);}}}}
return __exports;});;
/* /web/static/src/core/notifications/notification.js */
odoo.define('@web/core/notifications/notification',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component,useRef,onMounted}=require("@odoo/owl");const AUTOCLOSE_DELAY=4000;const Notification=__exports.Notification=class Notification extends Component{static template="web.NotificationWowl";static props={message:{validate:(m)=>typeof m==="string"||(typeof m==="object"&&typeof m.toString==="function"),},type:{type:String,optional:true,validate:(t)=>["warning","danger","success","info"].includes(t),},title:{type:[String,Boolean,{toString:Function}],optional:true},className:{type:String,optional:true},buttons:{type:Array,element:{type:Object,shape:{name:{type:String},icon:{type:String,optional:true},primary:{type:Boolean,optional:true},onClick:Function,},},optional:true,},sticky:{type:Boolean,optional:true},autocloseDelay:{type:Number,optional:true},close:{type:Function},};static defaultProps={buttons:[],className:"",type:"warning",autocloseDelay:AUTOCLOSE_DELAY,};setup(){this.autocloseProgress=useRef("autoclose_progress_bar");onMounted(()=>this.startNotificationTimer());}
freeze(){this.startedTimestamp=false;this.autocloseProgress.el.style.width=0;}
refresh(){this.startNotificationTimer();}
close(){this.props.close();}
startNotificationTimer(){if(this.props.sticky){return;}
this.startedTimestamp=luxon.DateTime.now().ts;const cb=()=>{if(this.startedTimestamp){const currentProgress=(luxon.DateTime.now().ts-this.startedTimestamp)/this.props.autocloseDelay;if(currentProgress>1){this.close();return;}
if(this.autocloseProgress.el){this.autocloseProgress.el.style.width=`${(1 - currentProgress) * 100}%`;}
requestAnimationFrame(cb);}};cb();}}
return __exports;});;
/* /web/static/src/core/notifications/notification_container.js */
odoo.define('@web/core/notifications/notification_container',['@web/core/notifications/notification','@web/core/transition','@odoo/owl'],function(require){'use strict';let __exports={};const{Notification}=require("@web/core/notifications/notification");const{Transition}=require("@web/core/transition");const{Component,xml,useState}=require("@odoo/owl");const NotificationContainer=__exports.NotificationContainer=class NotificationContainer extends Component{static props={notifications:Object,};static template=xml`
<div class="o_notification_manager">
<t t-foreach="notifications" t-as="notification" t-key="notification">
<Transition leaveDuration="0" immediate="true" name="'o_notification_fade'" t-slot-scope="transition">
<Notification t-props="notification_value.props" className="(notification_value.props.className || '') + ' ' + transition.className"/>
</Transition>
</t>
</div>`;static components={Notification,Transition};setup(){this.notifications=useState(this.props.notifications);}}
return __exports;});;
/* /web/static/src/core/notifications/notification_service.js */
odoo.define('@web/core/notifications/notification_service',['@web/core/registry','@web/core/notifications/notification_container','@odoo/owl'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{NotificationContainer}=require("@web/core/notifications/notification_container");const{reactive}=require("@odoo/owl");const notificationService=__exports.notificationService={notificationContainer:NotificationContainer,start(){let notifId=0;const notifications=reactive({});registry.category("main_components").add(this.notificationContainer.name,{Component:this.notificationContainer,props:{notifications},},{sequence:100});function add(message,options={}){const id=++notifId;const closeFn=()=>close(id);const props=Object.assign({},options,{message,close:closeFn});delete props.onClose;const notification={id,props,onClose:options.onClose,};notifications[id]=notification;return closeFn;}
function close(id){if(notifications[id]){const notification=notifications[id];if(notification.onClose){notification.onClose();}
delete notifications[id];}}
return{add};},};registry.category("services").add("notification",notificationService);return __exports;});;
/* /web/static/src/core/orm_service.js */
odoo.define('@web/core/orm_service',['@web/core/registry','@web/core/network/rpc','@web/core/user','@web/core/domain'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{rpc}=require("@web/core/network/rpc");const{user}=require("@web/core/user");const{Domain}=require("@web/core/domain");const x2ManyCommands=__exports.x2ManyCommands={CREATE:0,create(virtualID,values){delete values.id;return[x2ManyCommands.CREATE,virtualID||false,values];},UPDATE:1,update(id,values){delete values.id;return[x2ManyCommands.UPDATE,id,values];},DELETE:2,delete(id){return[x2ManyCommands.DELETE,id,false];},UNLINK:3,unlink(id){return[x2ManyCommands.UNLINK,id,false];},LINK:4,link(id){return[x2ManyCommands.LINK,id,false];},CLEAR:5,clear(){return[x2ManyCommands.CLEAR,false,false];},SET:6,set(ids){return[x2ManyCommands.SET,false,ids];},};function validateModel(value){if(typeof value!=="string"||value.length===0){throw new Error(`Invalid model name: ${value}`);}}
function validatePrimitiveList(name,type,value){if(!Array.isArray(value)||value.some((val)=>typeof val!==type)){throw new Error(`Invalid ${name} list: ${value}`);}}
function validateObject(name,obj){if(typeof obj!=="object"||obj===null||Array.isArray(obj)){throw new Error(`${name} should be an object`);}}
function validateArray(name,array){if(!Array.isArray(array)){throw new Error(`${name} should be an array`);}}
const UPDATE_METHODS=__exports.UPDATE_METHODS=["unlink","create","write","web_save","web_save_multi","action_archive","action_unarchive",];const ORM=__exports.ORM=class ORM{constructor(){this.rpc=rpc;this._silent=false;this._cache=false;}
get silent(){return Object.assign(Object.create(this),{_silent:true});}
cache(options={}){return Object.assign(Object.create(this),{_cache:options});}
call(model,method,args=[],kwargs={}){validateModel(model);const url=`/web/dataset/call_kw/${model}/${method}`;const fullContext=Object.assign({},user.context,kwargs.context||{});const fullKwargs=Object.assign({},kwargs,{context:fullContext});const params={model,method,args,kwargs:fullKwargs,};return this.rpc(url,params,{silent:this._silent,cache:this._cache,});}
create(model,records,kwargs={}){validateArray("records",records);for(const record of records){validateObject("record",record);}
return this.call(model,"create",[records],kwargs);}
read(model,ids,fields,kwargs={}){validatePrimitiveList("ids","number",ids);if(fields){validatePrimitiveList("fields","string",fields);}
if(!ids.length){return Promise.resolve([]);}
return this.call(model,"read",[ids,fields],kwargs);}
formattedReadGroup(model,domain,groupby,aggregates,kwargs={}){validateArray("domain",domain);validatePrimitiveList("groupby","string",groupby);validatePrimitiveList("aggregates","string",aggregates);return this.call(model,"formatted_read_group",[],{domain,groupby,aggregates,...kwargs,}).then((res)=>{for(const group of res){group["__domain"]=Domain.and([domain,group["__extra_domain"]]).toList();}
return res;});}
formattedReadGroupingSets(model,domain,grouping_sets,aggregates,kwargs={}){validateArray("domain",domain);validateArray("groupby",grouping_sets);validatePrimitiveList("aggregates","string",aggregates);return this.call(model,"formatted_read_grouping_sets",[],{domain,grouping_sets,aggregates,...kwargs,}).then((res)=>{for(const groups of res){for(const group of groups){group["__domain"]=Domain.and([domain,group["__extra_domain"]]).toList();}}
return res;});}
search(model,domain,kwargs={}){validateArray("domain",domain);return this.call(model,"search",[domain],kwargs);}
searchRead(model,domain,fields,kwargs={}){validateArray("domain",domain);if(fields){validatePrimitiveList("fields","string",fields);}
return this.call(model,"search_read",[],{...kwargs,domain,fields});}
searchCount(model,domain,kwargs={}){validateArray("domain",domain);return this.call(model,"search_count",[domain],kwargs);}
unlink(model,ids,kwargs={}){validatePrimitiveList("ids","number",ids);if(!ids.length){return Promise.resolve(true);}
return this.call(model,"unlink",[ids],kwargs);}
webReadGroup(model,domain,groupby,aggregates,kwargs={}){validateArray("domain",domain);validatePrimitiveList("aggregates","string",aggregates);return this.call(model,"web_read_group",[],{domain,groupby,aggregates,...kwargs,});}
webRead(model,ids,kwargs={}){validatePrimitiveList("ids","number",ids);return this.call(model,"web_read",[ids],kwargs);}
webResequence(model,ids,kwargs={}){validatePrimitiveList("ids","number",ids);return this.call(model,"web_resequence",[ids],{...kwargs,specification:kwargs.specification||{},});}
webSearchRead(model,domain,kwargs={}){validateArray("domain",domain);return this.call(model,"web_search_read",[],{...kwargs,domain});}
write(model,ids,data,kwargs={}){validatePrimitiveList("ids","number",ids);validateObject("data",data);return this.call(model,"write",[ids,data],kwargs);}
webSave(model,ids,data,kwargs={}){validatePrimitiveList("ids","number",ids);validateObject("data",data);return this.call(model,"web_save",[ids,data],kwargs);}
async webSaveMulti(model,ids,data,kwargs={}){validatePrimitiveList("ids","number",ids);validateArray("data",data);data.forEach((d)=>{validateObject("data item",d);});return this.call(model,"web_save_multi",[ids,data],kwargs);}}
const ormService=__exports.ormService={async:["call","create","nameGet","read","formattedReadGroup","webReadGroup","search","searchRead","unlink","webResequence","webSearchRead","write",],start(){return new ORM();},};registry.category("services").add("orm",ormService);return __exports;});;
/* /web/static/src/core/overlay/overlay_container.js */
odoo.define('@web/core/overlay/overlay_container',['@odoo/owl','@web/core/utils/arrays','@web/core/utils/components'],function(require){'use strict';let __exports={};const{Component,onWillDestroy,useChildSubEnv,useRef,useState}=require("@odoo/owl");const{sortBy}=require("@web/core/utils/arrays");const{ErrorHandler}=require("@web/core/utils/components");const OVERLAY_ITEMS=[];const OVERLAY_SYMBOL=__exports.OVERLAY_SYMBOL=Symbol("Overlay");class OverlayItem extends Component{static template="web.OverlayContainer.Item";static components={};static props={component:{type:Function},props:{type:Object},env:{type:Object,optional:true},};setup(){this.rootRef=useRef("rootRef");OVERLAY_ITEMS.push(this);onWillDestroy(()=>{const index=OVERLAY_ITEMS.indexOf(this);OVERLAY_ITEMS.splice(index,1);});if(this.props.env){this.__owl__.childEnv=this.props.env;}
useChildSubEnv({[OVERLAY_SYMBOL]:{contains:(target)=>this.contains(target),},});}
get subOverlays(){return OVERLAY_ITEMS.slice(OVERLAY_ITEMS.indexOf(this));}
contains(target){return(this.rootRef.el?.contains(target)||this.subOverlays.some((oi)=>oi.rootRef.el?.contains(target)));}}
const OverlayContainer=__exports.OverlayContainer=class OverlayContainer extends Component{static template="web.OverlayContainer";static components={ErrorHandler,OverlayItem};static props={overlays:Object};setup(){this.root=useRef("root");this.state=useState({rootEl:null});}
get sortedOverlays(){return sortBy(Object.values(this.props.overlays),(overlay)=>overlay.sequence);}
isVisible(overlay){return overlay.rootId===this.env?.rootId;}
handleError(overlay,error){overlay.remove();Promise.resolve().then(()=>{throw error;});}}
return __exports;});;
/* /web/static/src/core/overlay/overlay_service.js */
odoo.define('@web/core/overlay/overlay_service',['@odoo/owl','@web/core/registry','@web/core/overlay/overlay_container'],function(require){'use strict';let __exports={};const{markRaw,reactive}=require("@odoo/owl");const{registry}=require("@web/core/registry");const{OverlayContainer}=require("@web/core/overlay/overlay_container");const mainComponents=registry.category("main_components");const services=registry.category("services");const overlayService=__exports.overlayService={start(){let nextId=0;const overlays=reactive({});mainComponents.add("OverlayContainer",{Component:OverlayContainer,props:{overlays},});const remove=async(id,onRemove=()=>{},removeParams)=>{if(id in overlays){await onRemove(removeParams);delete overlays[id];}};const add=(component,props,options={})=>{const id=++nextId;const removeCurrentOverlay=(removeParams)=>remove(id,options.onRemove,removeParams);overlays[id]={id,component,env:options.env&&markRaw(options.env),props,remove:removeCurrentOverlay,sequence:options.sequence??50,rootId:options.rootId,};return removeCurrentOverlay;};return{add,overlays};},};services.add("overlay",overlayService);return __exports;});;
/* /web/static/src/core/pager/pager.js */
odoo.define('@web/core/pager/pager',['@web/core/utils/hooks','@web/core/utils/numbers','@odoo/owl'],function(require){'use strict';let __exports={};const{useAutofocus}=require("@web/core/utils/hooks");const{clamp}=require("@web/core/utils/numbers");const{Component,EventBus,useEffect,useExternalListener,useState}=require("@odoo/owl");const PAGER_UPDATED_EVENT=__exports.PAGER_UPDATED_EVENT="PAGER:UPDATED";const pagerBus=__exports.pagerBus=new EventBus();const Pager=__exports.Pager=class Pager extends Component{static template="web.Pager";static defaultProps={isEditable:true,withAccessKey:true,};static props={offset:Number,limit:Number,total:Number,onUpdate:Function,isEditable:{type:Boolean,optional:true},withAccessKey:{type:Boolean,optional:true},updateTotal:{type:Function,optional:true},};setup(){this.state=useState({isEditing:false,isDisabled:false,});this.inputRef=useAutofocus();useExternalListener(document,"mousedown",this.onClickAway,{capture:true});let firstMount=true;useEffect(()=>{if(!firstMount&&this.env.isSmall){pagerBus.trigger(PAGER_UPDATED_EVENT,{value:this.value,total:this.props.total,});}
firstMount=false;},()=>[this.props.offset,this.props.limit,this.props.total]);}
get minimum(){return this.props.offset+1;}
get maximum(){return Math.min(this.props.offset+this.props.limit,this.props.total);}
get value(){const parts=[this.minimum];if(this.props.limit>1){parts.push(this.maximum);}
return parts.join("-");}
get isSinglePage(){return!this.props.updateTotal&&this.minimum===1&&this.maximum===this.props.total;}
async navigate(direction){let minimum=this.props.offset+this.props.limit*direction;let total=this.props.total;if(this.props.updateTotal&&minimum<0){total=await this.props.updateTotal();}
if(minimum>=total){if(!this.props.updateTotal){minimum=0;}}else if(minimum<0&&this.props.limit===1){minimum=total-1;}else if(minimum<0&&this.props.limit>1){minimum=total-(total%this.props.limit||this.props.limit);}
this.update(minimum,this.props.limit,true);}
async parse(value){let[minimum,maximum]=value.trim().split(/\s*[-\s,;]\s*/);minimum=parseInt(minimum,10);maximum=maximum?parseInt(maximum,10):minimum;if(this.props.updateTotal){return{minimum:minimum-1,maximum};}
return{minimum:clamp(minimum,1,this.props.total)-1,maximum:clamp(maximum,1,this.props.total),};}
async setValue(value){const{minimum,maximum}=await this.parse(value);if(!isNaN(minimum)&&!isNaN(maximum)&&minimum<maximum){this.update(minimum,maximum-minimum);}}
async update(offset,limit,hasNavigated){this.state.isDisabled=true;try{await this.props.onUpdate({offset,limit},hasNavigated);}finally{this.state.isDisabled=false;this.state.isEditing=false;}}
async updateTotal(){if(!this.state.isDisabled){this.state.isDisabled=true;await this.props.updateTotal();this.state.isDisabled=false;}}
onClickAway(ev){if(ev.target!==this.inputRef.el){this.state.isEditing=false;}}
onInputBlur(){this.state.isEditing=false;}
onInputChange(ev){this.setValue(ev.target.value);if(!this.state.isDisabled){ev.preventDefault();}}
onInputKeydown(ev){switch(ev.key){case"Enter":ev.preventDefault();ev.stopPropagation();this.setValue(ev.currentTarget.value);break;case"Escape":ev.preventDefault();ev.stopPropagation();this.state.isEditing=false;break;}}
onValueClick(){if(this.props.isEditable&&!this.state.isEditing&&!this.state.isDisabled){if(this.inputRef.el){this.inputRef.el.focus();}
this.state.isEditing=true;}}}
return __exports;});;
/* /web/static/src/core/pager/pager_indicator.js */
odoo.define('@web/core/pager/pager_indicator',['@web/core/browser/browser','@web/core/registry','@web/core/transition','@web/core/utils/hooks','@odoo/owl','@web/core/pager/pager'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{Transition}=require("@web/core/transition");const{useBus}=require("@web/core/utils/hooks");const{Component,useState}=require("@odoo/owl");const{PAGER_UPDATED_EVENT,pagerBus}=require("@web/core/pager/pager");const PagerIndicator=__exports.PagerIndicator=class PagerIndicator extends Component{static template="web.PagerIndicator";static components={Transition};static props={};setup(){this.state=useState({show:false,value:"-",total:0,});this.startShowTimer=null;useBus(pagerBus,PAGER_UPDATED_EVENT,this.pagerUpdate);}
pagerUpdate({detail}){this.state.value=detail.value;this.state.total=detail.total;browser.clearTimeout(this.startShowTimer);this.state.show=true;this.startShowTimer=browser.setTimeout(()=>{this.state.show=false;},1400);}}
registry.category("main_components").add("PagerIndicator",{Component:PagerIndicator,});return __exports;});;
/* /web/static/src/core/popover/popover.js */
odoo.define('@web/core/popover/popover',['@odoo/owl','@web/core/hotkeys/hotkey_hook','@web/core/overlay/overlay_container','@web/core/position/position_hook','@web/core/position/utils','@web/core/ui/ui_service','@web/core/utils/classname','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,onMounted,onWillDestroy,useRef}=require("@odoo/owl");const{useHotkey}=require("@web/core/hotkeys/hotkey_hook");const{OVERLAY_SYMBOL}=require("@web/core/overlay/overlay_container");const{usePosition}=require("@web/core/position/position_hook");const{reverseForRTL}=require("@web/core/position/utils");const{useActiveElement}=require("@web/core/ui/ui_service");const{mergeClasses}=require("@web/core/utils/classname");const{useForwardRefToParent}=require("@web/core/utils/hooks");function useEarlyExternalListener(target,eventName,handler,eventParams){target.addEventListener(eventName,handler,eventParams);onWillDestroy(()=>target.removeEventListener(eventName,handler,eventParams));}
function useClickAway(callback){function blurHandler(ev){const target=ev.relatedTarget||document.activeElement;if(target?.tagName==="IFRAME"){callback(target);}}
function navigationHandler(){callback(document.documentElement);}
function pointerDownHandler(ev){callback(ev.composedPath()[0]);}
useEarlyExternalListener(window,"pointerdown",pointerDownHandler,{capture:true});useEarlyExternalListener(window,"blur",blurHandler,{capture:true});useEarlyExternalListener(window,"popstate",navigationHandler,{capture:true});}
const POPOVERS=new WeakMap();__exports.getPopoverForTarget=getPopoverForTarget;function getPopoverForTarget(target){return POPOVERS.get(target);}
const Popover=__exports.Popover=class Popover extends Component{static template="web.Popover";static defaultProps={animation:true,arrow:true,class:"",closeOnClickAway:()=>true,closeOnEscape:true,componentProps:{},fixedPosition:false,position:"bottom",setActiveElement:false,};static props={component:{type:Function},componentProps:{optional:true,type:Object},target:{validate:(target)=>{const Element=target?.ownerDocument?.defaultView?.Element;return((Boolean(Element)&&(target instanceof Element||target instanceof window.Element))||(typeof target==="object"&&target?.constructor?.name?.endsWith("Element")));},},close:{type:Function},animation:{optional:true,type:Boolean},arrow:{optional:true,type:Boolean},class:{optional:true},role:{optional:true,type:String},fixedPosition:{optional:true,type:Boolean},extendedFlipping:{optional:true,type:Boolean},holdOnHover:{optional:true,type:Boolean},onPositioned:{optional:true,type:Function},position:{optional:true,type:String,validate:(p)=>{const[d,v="middle"]=p.split("-");return(["top","bottom","left","right"].includes(d)&&["start","middle","end","fit"].includes(v));},},closeOnClickAway:{optional:true,type:Function},closeOnEscape:{optional:true,type:Boolean},setActiveElement:{optional:true,type:Boolean},ref:{optional:true,type:Function},slots:{optional:true,type:Object},};static animationTime=200;setup(){if(this.props.setActiveElement){useActiveElement("ref");}
useForwardRefToParent("ref");this.popoverRef=useRef("ref");this.position=usePosition("ref",()=>this.props.target,this.positioningOptions);if(!this.props.animation){this.animationDone=true;}
const resizeObserver=new ResizeObserver(()=>{if(!this.props.fixedPosition&&this.animationDone){this.position.unlock();}});onMounted(()=>{POPOVERS.set(this.props.target,this.popoverRef.el);resizeObserver.observe(this.popoverRef.el);});onWillDestroy(()=>POPOVERS.delete(this.props.target));if(this.props.target.isConnected){useClickAway(this.onClickAway.bind(this));if(this.props.closeOnEscape){useHotkey("escape",()=>this.props.close());}
const targetObserver=new MutationObserver(this.onTargetMutate.bind(this));targetObserver.observe(this.props.target.parentElement,{childList:true});onWillDestroy(()=>targetObserver.disconnect());}else{this.props.close();}}
get defaultClassObj(){return mergeClasses("o_popover popover mw-100 bs-popover-auto",this.props.class);}
get positioningOptions(){return{extendedFlipping:this.props.extendedFlipping,margin:this.props.arrow?8:0,onPositioned:(el,solution)=>{this.onPositioned(solution);this.props.onPositioned?.(el,solution);},position:this.props.position,shrink:true,};}
animate(direction){const transform={top:["translateY(-5%)","translateY(0)"],right:["translateX(5%)","translateX(0)"],bottom:["translateY(5%)","translateY(0)"],left:["translateX(-5%)","translateX(0)"],}[direction];return this.popoverRef.el.animate({opacity:[0,1],transform},this.constructor.animationTime);}
isInside(target){return(this.props.target?.contains(target)||this.popoverRef?.el?.contains(target)||this.env[OVERLAY_SYMBOL]?.contains(target));}
onClickAway(target){if(this.props.closeOnClickAway(target)&&!this.isInside(target)){this.props.close();}}
onPositioned({direction,variant,variantOffset}){if(this.props.arrow){this.updateArrow(direction,variant,variantOffset);}
if(this.props.animation&&!this.animationDone){this.position.lock();this.animate(direction).finished.then(()=>{this.animationDone=true;if(!this.props.fixedPosition){this.position.unlock();}});}
if(this.props.fixedPosition){this.position.lock();}}
onTargetMutate(){if(!this.props.target.isConnected){this.props.close();}}
updateArrow(direction,variant,variantOffset){const{el}=this.popoverRef;[direction,variant]=reverseForRTL(direction,variant);el.dataset.popperPlacement=direction;const vertical=["top","bottom"].includes(direction);const placementProperty=vertical?"left":"top";const placement={start:"--position-min",middle:"--position-center",fit:"--position-center",end:"--position-max",}[variant];const arrowEl=el.querySelector(":scope > .popover-arrow");Object.assign(arrowEl.style,{top:"",left:"",[placementProperty]:`clamp(
var(--position-min),
calc(var(${placement}) - ${variantOffset}px),
var(--position-max)
)`,});const sizeProperty=vertical?"width":"height";const{[sizeProperty]:arrowSize,[placementProperty]:arrowPosition}=arrowEl.getBoundingClientRect();const{[sizeProperty]:targetSize,[placementProperty]:targetPosition}=this.props.target.getBoundingClientRect();const arrowCenter=arrowPosition+arrowSize/2;const margin=arrowSize/2-1;const hasEnoughSpace=arrowSize<targetSize-2*margin;const isOutsideSafeEdge=arrowCenter<targetPosition+margin||arrowCenter>targetPosition+targetSize-margin;arrowEl.classList.toggle("sucked",hasEnoughSpace&&isOutsideSafeEdge);}}
return __exports;});;
/* /web/static/src/core/popover/popover_hook.js */
odoo.define('@web/core/popover/popover_hook',['@odoo/owl','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{onWillUnmount,status,useComponent}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");__exports.makePopover=makePopover;function makePopover(addFn,component,options){let removeFn=null;function close(){removeFn?.();}
return{open(target,props){close();const newOptions=Object.create(options);newOptions.onClose=()=>{removeFn=null;options.onClose?.();};removeFn=addFn(target,component,props,newOptions);},close,get isOpen(){return Boolean(removeFn);},};}
__exports.usePopover=usePopover;function usePopover(component,options={}){let service;if(options.useBottomSheet){service=useService("bottom_sheet");}else{service=useService("popover");}
const owner=useComponent();const newOptions=Object.create(options);newOptions.onClose=()=>{if(status(owner)!=="destroyed"){options.onClose?.();}};const popover=makePopover(service.add,component,newOptions);onWillUnmount(popover.close);return popover;}
return __exports;});;
/* /web/static/src/core/popover/popover_service.js */
odoo.define('@web/core/popover/popover_service',['@odoo/owl','@web/core/popover/popover','@web/core/registry'],function(require){'use strict';let __exports={};const{markRaw}=require("@odoo/owl");const{Popover}=require("@web/core/popover/popover");const{registry}=require("@web/core/registry");const popoverService=__exports.popoverService={dependencies:["overlay"],start(_,{overlay}){const add=(target,component,props={},options={})=>{const closeOnClickAway=typeof options.closeOnClickAway==="function"?options.closeOnClickAway:()=>options.closeOnClickAway??true;const remove=overlay.add(Popover,{target,close:()=>remove(),closeOnClickAway,closeOnEscape:options.closeOnEscape,component,componentProps:markRaw(props),extendedFlipping:options.extendedFlipping,ref:options.ref,class:options.popoverClass,animation:options.animation,arrow:options.arrow,role:options.role,position:options.position,onPositioned:options.onPositioned,fixedPosition:options.fixedPosition,holdOnHover:options.holdOnHover,setActiveElement:options.setActiveElement??true,},{env:options.env,onRemove:options.onClose,rootId:target.getRootNode()?.host?.id,sequence:options.sequence,});return remove;};return{add};},};registry.category("services").add("popover",popoverService);return __exports;});;
/* /web/static/src/core/position/position_hook.js */
odoo.define('@web/core/position/position_hook',['@web/core/position/utils','@web/core/utils/objects','@web/core/utils/timing','@odoo/owl'],function(require){'use strict';let __exports={};const{reposition}=require("@web/core/position/utils");const{omit}=require("@web/core/utils/objects");const{useThrottleForAnimation}=require("@web/core/utils/timing");const{EventBus,onWillDestroy,useChildSubEnv,useComponent,useEffect,useRef,}=require("@odoo/owl");const POSITION_BUS=__exports.POSITION_BUS=Symbol("position-bus");__exports.usePosition=usePosition;function usePosition(refName,getTarget,options={}){const ref=useRef(refName);let lock=false;const update=()=>{const targetEl=getTarget();if(!ref.el||!targetEl?.isConnected||lock){return;}
const repositionOptions=omit(options,"onPositioned");const solution=reposition(ref.el,targetEl,repositionOptions);options.position=`${solution.direction}-${solution.variant}`;options.onPositioned?.(ref.el,solution);};const component=useComponent();const bus=component.env[POSITION_BUS]||new EventBus();let executingUpdate=false;const batchedUpdate=async()=>{if(!executingUpdate){executingUpdate=true;update();await Promise.resolve();executingUpdate=false;}};bus.addEventListener("update",batchedUpdate);onWillDestroy(()=>bus.removeEventListener("update",batchedUpdate));const isTopmost=!(POSITION_BUS in component.env);if(isTopmost){useChildSubEnv({[POSITION_BUS]:bus});}
const throttledUpdate=useThrottleForAnimation(()=>bus.trigger("update"));useEffect(()=>{bus.trigger("update");if(isTopmost){const scrollListener=(e)=>{if(ref.el?.contains(e.target)){return;}
throttledUpdate();};const documents=[];const targetDocument=getTarget()?.ownerDocument;if(targetDocument){documents.push(targetDocument);if(targetDocument.defaultView&&targetDocument.defaultView.top!==targetDocument.defaultView){try{documents.push(targetDocument.defaultView.top.document);}catch{}}}
for(const document of documents){document.addEventListener("scroll",scrollListener,{capture:true});document.addEventListener("load",throttledUpdate,{capture:true});}
window.addEventListener("resize",throttledUpdate);return()=>{for(const document of documents){document.removeEventListener("scroll",scrollListener,{capture:true});document.removeEventListener("load",throttledUpdate,{capture:true});}
window.removeEventListener("resize",throttledUpdate);};}});return{lock:()=>{lock=true;},unlock:()=>{lock=false;bus.trigger("update");},};}
return __exports;});;
/* /web/static/src/core/position/utils.js */
odoo.define('@web/core/position/utils',['@web/core/l10n/localization'],function(require){'use strict';let __exports={};const{localization}=require("@web/core/l10n/localization");const DEFAULTS={flip:true,margin:0,position:"bottom",};const DIRECTIONS={t:"top",r:"right",b:"bottom",l:"left",c:"center"};const VARIANTS={s:"start",m:"middle",e:"end",f:"fit"};const DIRECTION_FLIP_ORDER={top:"tb",right:"rl",bottom:"bt",left:"lr",center:"c"};const EXTENDED_DIRECTION_FLIP_ORDER={top:"tbrlc",right:"rlbtc",bottom:"btrlc",left:"lrbtc",center:"c",};const VARIANT_FLIP_ORDER={start:"se",middle:"m",end:"es",fit:"f"};function getIFrame(popperEl,targetEl){return[...popperEl.ownerDocument.getElementsByTagName("iframe")].find((iframe)=>iframe.contentDocument?.contains(targetEl));}
__exports.reverseForRTL=reverseForRTL;function reverseForRTL(direction,variant="middle"){if(localization.direction==="rtl"){if(["left","right"].includes(direction)){direction=direction==="left"?"right":"left";}else if(["start","end"].includes(variant)){variant=variant==="start"?"end":"start";}}
return[direction,variant];}
function computePosition(popper,target,{container,extendedFlipping,flip,margin,position,shrink}){const[direction,variant="middle"]=reverseForRTL(...position.split("-"));let directions=[direction.at(0)];if(flip){directions=extendedFlipping?EXTENDED_DIRECTION_FLIP_ORDER[direction]:DIRECTION_FLIP_ORDER[direction];}
const variants=VARIANT_FLIP_ORDER[variant];if(!container){container=popper.ownerDocument.documentElement;}else if(typeof container==="function"){container=container();}
if(variant==="fit"){const styleProperty=["top","bottom"].includes(direction)?"width":"height";popper.style[styleProperty]=getComputedStyle(target)[styleProperty];}
const popperStyle=getComputedStyle(popper);const{marginTop,marginLeft,marginRight,marginBottom}=popperStyle;const popMargins={top:parseFloat(marginTop),left:parseFloat(marginLeft),right:parseFloat(marginRight),bottom:parseFloat(marginBottom),};const shouldAccountForIFrame=popper.ownerDocument!==target.ownerDocument;const iframe=shouldAccountForIFrame?getIFrame(popper,target):null;const popBox=popper.getBoundingClientRect();const targetBox=target.getBoundingClientRect();const contBox=container.getBoundingClientRect();const iframeBox=iframe?.getBoundingClientRect()??{top:0,left:0};const containerIsHTMLNode=container===container.ownerDocument.firstElementChild;const containerIsInIframe=shouldAccountForIFrame&&target.ownerDocument===container.ownerDocument;const directionsData={t:iframeBox.top+targetBox.top-popMargins.bottom-margin-popBox.height,b:iframeBox.top+targetBox.bottom+popMargins.top+margin,r:iframeBox.left+targetBox.right+popMargins.left+margin,l:iframeBox.left+targetBox.left-popMargins.right-margin-popBox.width,c:iframeBox.top+targetBox.top+targetBox.height/2-popBox.height/2,};const variantsData={vf:iframeBox.left+targetBox.left,vs:iframeBox.left+targetBox.left+popMargins.left,vm:iframeBox.left+targetBox.left+targetBox.width/2-popBox.width/2,ve:iframeBox.left+targetBox.right-popMargins.right-popBox.width,hf:iframeBox.top+targetBox.top,hs:iframeBox.top+targetBox.top+popMargins.top,hm:iframeBox.top+targetBox.top+targetBox.height/2-popBox.height/2,he:iframeBox.top+targetBox.bottom-popMargins.bottom-popBox.height,};function getPositioningData(d,v){const[direction,variant]=reverseForRTL(DIRECTIONS[d],VARIANTS[v]);const result={direction,variant};const vertical=["t","b","c"].includes(d);const variantPrefix=vertical?"v":"h";const directionValue=directionsData[d];let variantValue=variantsData[variantPrefix+v];const[leftCompensation,topCompensation]=containerIsInIframe?[iframeBox.left,iframeBox.top]:[0,0];const[directionSize,variantSize]=vertical?[popBox.height,popBox.width]:[popBox.width,popBox.height];let[directionMin,directionMax]=vertical?[contBox.top+topCompensation,contBox.bottom+topCompensation]:[contBox.left+leftCompensation,contBox.right+leftCompensation];let[variantMin,variantMax]=vertical?[contBox.left+leftCompensation,contBox.right+leftCompensation]:[contBox.top+topCompensation,contBox.bottom+topCompensation];if(containerIsHTMLNode){if(vertical){directionMin+=container.scrollTop;directionMax+=container.scrollTop;}else{variantMin+=container.scrollTop;variantMax+=container.scrollTop;}}
let directionOverflow=0;if(Math.floor(directionValue)<Math.ceil(directionMin)){directionOverflow=Math.floor(directionValue)-Math.ceil(directionMin);}else if(Math.ceil(directionValue+directionSize)>Math.floor(directionMax)){directionOverflow=Math.ceil(directionValue+directionSize)-Math.floor(directionMax);}
let variantOverflow=0;if(Math.floor(variantValue)<Math.ceil(variantMin)){variantOverflow=Math.floor(variantValue)-Math.ceil(variantMin);}else if(Math.ceil(variantValue+variantSize)>Math.floor(variantMax)){variantOverflow=Math.ceil(variantValue+variantSize)-Math.floor(variantMax);}
let malus=Math.abs(directionOverflow)+(variantOverflow&&1);variantValue-=variantOverflow;result.variantOffset=-variantOverflow;const positioning=vertical?{top:directionValue,left:variantValue}:{top:variantValue,left:directionValue};result.top=positioning.top-popBox.top;result.left=positioning.left-popBox.left;if(d==="c"){malus=1.001;result.top-=directionOverflow;}else if(shrink&&malus){const minTop=Math.floor(!vertical&&v==="s"?targetBox.top:contBox.top);result.top=Math.max(minTop,result.top);let height;if(vertical){height=Math.abs(targetBox[direction]-(d==="t"?directionMin:directionMax));}else{height={s:variantMax-targetBox.top,m:variantMax-variantMin,e:targetBox.bottom-variantMin,}[v];}
result.maxHeight=Math.floor(height);}
return{result,malus};}
const matches=[];for(const d of directions){for(const v of variants){const match=getPositioningData(d,v);if(!match.malus){return match.result;}
matches.push(match);}
if(!flip){break;}}
return matches.sort((a,b)=>a.malus-b.malus)[0].result;}
__exports.reposition=reposition;function reposition(popper,target,options){popper.style.position="fixed";popper.style.top="0px";popper.style.left="0px";const solution=computePosition(popper,target,{...DEFAULTS,...options});const{top,left,maxHeight}=solution;popper.style.top=`${top}px`;popper.style.left=`${left}px`;if(maxHeight){const existingMaxHeight=getComputedStyle(popper).maxHeight;popper.style.maxHeight=existingMaxHeight!=="none"?`min(${existingMaxHeight}, ${maxHeight}px)`:`${maxHeight}px`;popper.style.overflowY="auto";}
return solution;}
return __exports;});;
/* /web/static/src/core/pwa/install_prompt.js */
odoo.define('@web/core/pwa/install_prompt',['@odoo/owl','@web/core/dialog/dialog','@web/core/browser/feature_detection'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{Dialog}=require("@web/core/dialog/dialog");const{isIOS}=require("@web/core/browser/feature_detection");const InstallPrompt=__exports.InstallPrompt=class InstallPrompt extends Component{static props={close:true,onClose:{type:Function},};static components={Dialog,};static template="web.InstallPrompt";get isMobileSafari(){return isIOS();}
onClose(){this.props.close();this.props.onClose();}}
return __exports;});;
/* /web/static/src/core/pwa/pwa_service.js */
odoo.define('@web/core/pwa/pwa_service',['@odoo/owl','@web/core/browser/browser','@web/core/browser/feature_detection','@web/core/network/http_service','@web/core/registry','@web/core/pwa/install_prompt'],function(require){'use strict';let __exports={};const{reactive}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{isDisplayStandalone,isIOS,isMacOS,isBrowserSafari,}=require("@web/core/browser/feature_detection");const{get}=require("@web/core/network/http_service");const{registry}=require("@web/core/registry");const{InstallPrompt}=require("@web/core/pwa/install_prompt");const serviceRegistry=registry.category("services");let BEFOREINSTALLPROMPT_EVENT;let REGISTER_BEFOREINSTALLPROMPT_EVENT;browser.addEventListener("beforeinstallprompt",(ev)=>{if(REGISTER_BEFOREINSTALLPROMPT_EVENT){return REGISTER_BEFOREINSTALLPROMPT_EVENT(ev);}else{BEFOREINSTALLPROMPT_EVENT=ev;}});const pwaService={dependencies:["dialog"],start(env,{dialog}){let _manifest;let nativePrompt;const state=reactive({canPromptToInstall:false,isAvailable:false,isScopedApp:browser.location.href.includes("/scoped_app"),isSupportedOnBrowser:false,startUrl:"/odoo",decline,getManifest,hasScopeBeenInstalled,show,});function _getInstallationState(scope=state.startUrl){const installationState=browser.localStorage.getItem("pwaService.installationState");return installationState?JSON.parse(installationState)[scope]:"";}
function _setInstallationState(value){const ls=JSON.parse(browser.localStorage.getItem("pwaService.installationState")||"{}");ls[state.startUrl]=value;browser.localStorage.setItem("pwaService.installationState",JSON.stringify(ls));}
function _removeInstallationState(){const ls=JSON.parse(browser.localStorage.getItem("pwaService.installationState"));delete ls[state.startUrl];browser.localStorage.setItem("pwaService.installationState",JSON.stringify(ls));}
if(state.isScopedApp){if(browser.location.pathname==="/scoped_app"){state.startUrl="/"+new URL(browser.location.href).searchParams.get("path");}else{state.startUrl=browser.location.pathname;}}
state.isSupportedOnBrowser=browser.BeforeInstallPromptEvent!==undefined||(isBrowserSafari()&&!isDisplayStandalone()&&(isIOS()||(isMacOS()&&browser.navigator.userAgent.match(/Version\/(\d+)/)[1]>=17)));const installationState=_getInstallationState();if(state.isSupportedOnBrowser){if(BEFOREINSTALLPROMPT_EVENT){_handleBeforeInstallPrompt(BEFOREINSTALLPROMPT_EVENT,installationState);BEFOREINSTALLPROMPT_EVENT=null;}
REGISTER_BEFOREINSTALLPROMPT_EVENT=(ev)=>{_handleBeforeInstallPrompt(ev,installationState);};if(isBrowserSafari()){state.canPromptToInstall=installationState!=="dismissed";state.isAvailable=true;}}
function _handleBeforeInstallPrompt(ev,installationState){nativePrompt=ev;if(installationState==="accepted"){if(!isDisplayStandalone()){_removeInstallationState();}}
state.canPromptToInstall=installationState!=="dismissed";state.isAvailable=true;}
async function getManifest(){if(!_manifest){const manifest=await get(document.querySelector("link[rel=manifest]")?.getAttribute("href"),"text");_manifest=JSON.parse(manifest);}
return _manifest;}
function hasScopeBeenInstalled(scope){return _getInstallationState(scope)==="accepted";}
async function show({onDone}={}){if(!state.isAvailable){return;}
if(nativePrompt){const res=await nativePrompt.prompt();_setInstallationState(res.outcome);state.canPromptToInstall=false;if(onDone){onDone(res);}}else if(isBrowserSafari()){dialog.add(InstallPrompt,{onClose:()=>{if(onDone){onDone({});}
this.decline();},});}}
function decline(){_setInstallationState("dismissed");state.canPromptToInstall=false;}
return state;},};serviceRegistry.add("pwa",pwaService);return __exports;});;
/* /web/static/src/core/py_js/py.js */
odoo.define('@web/core/py_js/py',['@web/core/py_js/py_interpreter','@web/core/py_js/py_parser','@web/core/py_js/py_tokenizer','@web/core/py_js/py_utils'],function(require){'use strict';let __exports={};const{evaluate}=require("@web/core/py_js/py_interpreter");const{parse}=require("@web/core/py_js/py_parser");const{tokenize}=require("@web/core/py_js/py_tokenizer");{const{evaluate}=require("@web/core/py_js/py_interpreter");Object.assign(__exports,{evaluate})};{const{parse}=require("@web/core/py_js/py_parser");Object.assign(__exports,{parse})};{const{tokenize}=require("@web/core/py_js/py_tokenizer");Object.assign(__exports,{tokenize})};{const{formatAST}=require("@web/core/py_js/py_utils");Object.assign(__exports,{formatAST})};__exports.parseExpr=parseExpr;function parseExpr(expr){const tokens=tokenize(expr);return parse(tokens);}
__exports.evaluateExpr=evaluateExpr;function evaluateExpr(expr,context={}){let ast;try{ast=parseExpr(expr);}catch(error){throw new EvalError(`Can not parse python expression: (${expr})\nError: ${error.message}`);}
try{return evaluate(ast,context);}catch(error){throw new EvalError(`Can not evaluate python expression: (${expr})\nError: ${error.message}`);}}
__exports.evaluateBooleanExpr=evaluateBooleanExpr;function evaluateBooleanExpr(expr,context={}){if(!expr||expr==='False'||expr==='0'){return false;}
if(expr==='True'||expr==='1'){return true;}
return evaluateExpr(`bool(${expr})`,context);}
return __exports;});;
/* /web/static/src/core/py_js/py_builtin.js */
odoo.define('@web/core/py_js/py_builtin',['@web/core/py_js/py_date'],function(require){'use strict';let __exports={};const{PyDate,PyDateTime,PyRelativeDelta,PyTime,PyTimeDelta}=require("@web/core/py_js/py_date");const EvaluationError=__exports.EvaluationError=class EvaluationError extends Error{}
__exports.execOnIterable=execOnIterable;function execOnIterable(iterable,func){if(iterable===null){throw new EvaluationError(`value not iterable`);}
if(typeof iterable==="object"&&!Array.isArray(iterable)&&!(iterable instanceof Set)){iterable=Object.keys(iterable);}
if(typeof iterable?.[Symbol.iterator]!=="function"){throw new EvaluationError(`value not iterable`);}
return func(iterable);}
const BUILTINS=__exports.BUILTINS={bool(value){switch(typeof value){case"number":return value!==0;case"string":return value!=="";case"boolean":return value;case"object":if(value===null||value===undefined){return false;}
if(value.isTrue){return value.isTrue();}
if(value instanceof Array){return!!value.length;}
if(value instanceof Set){return!!value.size;}
return Object.keys(value).length!==0;}
return true;},set(iterable){if(arguments.length>2){throw new EvaluationError(`set expected at most 1 argument, got (${arguments.length - 1}`);}
return execOnIterable(iterable,(iterable)=>{return new Set(iterable);});},max(...args){return Math.max(...args.slice(0,-1));},min(...args){return Math.min(...args.slice(0,-1));},time:{strftime(format){return PyDateTime.now().strftime(format);},},context_today(){return PyDate.today();},get current_date(){return this.today;},get today(){return PyDate.today().strftime("%Y-%m-%d");},get now(){return PyDateTime.now().strftime("%Y-%m-%d %H:%M:%S");},datetime:{time:PyTime,timedelta:PyTimeDelta,datetime:PyDateTime,date:PyDate,},relativedelta:PyRelativeDelta,true:true,false:false,};return __exports;});;
/* /web/static/src/core/py_js/py_date.js */
odoo.define('@web/core/py_js/py_date',['@web/core/py_js/py_parser'],function(require){'use strict';let __exports={};const{parseArgs}=require("@web/core/py_js/py_parser");const AssertionError=__exports.AssertionError=class AssertionError extends Error{}
const ValueError=__exports.ValueError=class ValueError extends Error{}
const NotSupportedError=__exports.NotSupportedError=class NotSupportedError extends Error{}
function fmt2(n){return String(n).padStart(2,"0");}
function fmt4(n){return String(n).padStart(4,"0");}
function divmod(a,b,fn){let mod=a%b;if((mod>0&&b<0)||(mod<0&&b>0)){mod+=b;}
return fn(Math.floor(a/b),mod);}
function assert(bool,message="AssertionError"){if(!bool){throw new AssertionError(message);}}
const DAYS_IN_MONTH=[null,31,28,31,30,31,30,31,31,30,31,30,31];const DAYS_BEFORE_MONTH=[null];for(let dbm=0,i=1;i<DAYS_IN_MONTH.length;++i){DAYS_BEFORE_MONTH.push(dbm);dbm+=DAYS_IN_MONTH[i];}
function daysInMonth(year,month){if(month===2&&isLeap(year)){return 29;}
return DAYS_IN_MONTH[month];}
function isLeap(year){return year%4===0&&(year%100!==0||year%400===0);}
function daysBeforeYear(year){const y=year-1;return y*365+Math.floor(y/4)-Math.floor(y/100)+Math.floor(y/400);}
function daysBeforeMonth(year,month){const postLeapFeb=month>2&&isLeap(year);return DAYS_BEFORE_MONTH[month]+(postLeapFeb?1:0);}
function ymd2ord(year,month,day){const dim=daysInMonth(year,month);if(!(1<=day&&day<=dim)){throw new ValueError(`day must be in 1..${dim}`);}
return daysBeforeYear(year)+daysBeforeMonth(year,month)+day;}
const DI400Y=daysBeforeYear(401);const DI100Y=daysBeforeYear(101);const DI4Y=daysBeforeYear(5);function ord2ymd(n){--n;let n400,n100,n4,n1,n0;divmod(n,DI400Y,function(_n400,n){n400=_n400;divmod(n,DI100Y,function(_n100,n){n100=_n100;divmod(n,DI4Y,function(_n4,n){n4=_n4;divmod(n,365,function(_n1,n){n1=_n1;n0=n;});});});});n=n0;const year=n400*400+1+n100*100+n4*4+n1;if(n1==4||n100==100){assert(n0===0);return{year:year-1,month:12,day:31,};}
const leapyear=n1===3&&(n4!==24||n100==3);assert(leapyear==isLeap(year));let month=(n+50)>>5;let preceding=DAYS_BEFORE_MONTH[month]+(month>2&&leapyear?1:0);if(preceding>n){--month;preceding-=DAYS_IN_MONTH[month]+(month===2&&leapyear?1:0);}
n-=preceding;return{year:year,month:month,day:n+1,};}
function tmxxx(year,month,day,hour,minute,second,microsecond){hour=hour||0;minute=minute||0;second=second||0;microsecond=microsecond||0;if(microsecond<0||microsecond>999999){divmod(microsecond,1000000,function(carry,ms){microsecond=ms;second+=carry;});}
if(second<0||second>59){divmod(second,60,function(carry,s){second=s;minute+=carry;});}
if(minute<0||minute>59){divmod(minute,60,function(carry,m){minute=m;hour+=carry;});}
if(hour<0||hour>23){divmod(hour,24,function(carry,h){hour=h;day+=carry;});}
if(month<1||month>12){divmod(month-1,12,function(carry,m){month=m+1;year+=carry;});}
const dim=daysInMonth(year,month);if(day<1||day>dim){if(day===0){--month;if(month>0){day=daysInMonth(year,month);}else{--year;month=12;day=31;}}else if(day==dim+1){++month;day=1;if(month>12){month=1;++year;}}else{const r=ord2ymd(ymd2ord(year,month,1)+(day-1));year=r.year;month=r.month;day=r.day;}}
return{year:year,month:month,day:day,hour:hour,minute:minute,second:second,microsecond:microsecond,};}
const PyDate=__exports.PyDate=class PyDate{static today(){return this.convertDate(new Date());}
static convertDate(date){const year=date.getFullYear();const month=date.getMonth()+1;const day=date.getDate();return new PyDate(year,month,day);}
constructor(year,month,day){this.year=year;this.month=month;this.day=day;}
static create(...args){const{year,month,day}=parseArgs(args,["year","month","day"]);return new PyDate(year,month,day);}
add(timedelta){const s=tmxxx(this.year,this.month,this.day+timedelta.days);return new PyDate(s.year,s.month,s.day);}
isEqual(other){if(!(other instanceof PyDate)){return false;}
return this.year===other.year&&this.month===other.month&&this.day===other.day;}
strftime(format){return format.replace(/%([A-Za-z])/g,(m,c)=>{switch(c){case"Y":return fmt4(this.year);case"m":return fmt2(this.month);case"d":return fmt2(this.day);}
throw new ValueError(`No known conversion for ${m}`);});}
substract(other){if(other instanceof PyTimeDelta){return this.add(other.negate());}
if(other instanceof PyDate){return PyTimeDelta.create(this.toordinal()-other.toordinal());}
throw new NotSupportedError();}
toJSON(){return this.strftime("%Y-%m-%d");}
toordinal(){return ymd2ord(this.year,this.month,this.day);}}
const PyDateTime=__exports.PyDateTime=class PyDateTime{static now(){return this.convertDate(new Date());}
static convertDate(date){const year=date.getFullYear();const month=date.getMonth()+1;const day=date.getDate();const hour=date.getHours();const minute=date.getMinutes();const second=date.getSeconds();return new PyDateTime(year,month,day,hour,minute,second,0);}
static create(...args){const namedArgs=parseArgs(args,["year","month","day","hour","minute","second","microsecond",]);const year=namedArgs.year;const month=namedArgs.month;const day=namedArgs.day;const hour=namedArgs.hour||0;const minute=namedArgs.minute||0;const second=namedArgs.second||0;const ms=namedArgs.micro/1000||0;return new PyDateTime(year,month,day,hour,minute,second,ms);}
static combine(...args){const{date,time}=parseArgs(args,["date","time"]);return PyDateTime.create(date.year,date.month,date.day,time.hour,time.minute,time.second);}
constructor(year,month,day,hour,minute,second,microsecond){this.year=year;this.month=month;this.day=day;this.hour=hour;this.minute=minute;this.second=second;this.microsecond=microsecond;}
add(timedelta){const s=tmxxx(this.year,this.month,this.day+timedelta.days,this.hour,this.minute,this.second+timedelta.seconds,this.microsecond+timedelta.microseconds);return new PyDateTime(s.year,s.month,s.day,s.hour,s.minute,s.second,s.microsecond);}
isEqual(other){if(!(other instanceof PyDateTime)){return false;}
return(this.year===other.year&&this.month===other.month&&this.day===other.day&&this.hour===other.hour&&this.minute===other.minute&&this.second===other.second&&this.microsecond===other.microsecond);}
strftime(format){return format.replace(/%([A-Za-z])/g,(m,c)=>{switch(c){case"Y":return fmt4(this.year);case"m":return fmt2(this.month);case"d":return fmt2(this.day);case"H":return fmt2(this.hour);case"M":return fmt2(this.minute);case"S":return fmt2(this.second);}
throw new ValueError(`No known conversion for ${m}`);});}
substract(timedelta){return this.add(timedelta.negate());}
toJSON(){return this.strftime("%Y-%m-%d %H:%M:%S");}
to_utc(){const d=new Date(this.year,this.month-1,this.day,this.hour,this.minute,this.second);const timedelta=PyTimeDelta.create({minutes:d.getTimezoneOffset()});return this.add(timedelta);}}
const PyTime=__exports.PyTime=class PyTime extends PyDate{static create(...args){const namedArgs=parseArgs(args,["hour","minute","second"]);const hour=namedArgs.hour||0;const minute=namedArgs.minute||0;const second=namedArgs.second||0;return new PyTime(hour,minute,second);}
constructor(hour,minute,second){const now=new Date();const year=now.getFullYear();const month=now.getMonth();const day=now.getDate();super(year,month,day);this.hour=hour;this.minute=minute;this.second=second;}
strftime(format){return format.replace(/%([A-Za-z])/g,(m,c)=>{switch(c){case"Y":return fmt4(this.year);case"m":return fmt2(this.month+1);case"d":return fmt2(this.day);case"H":return fmt2(this.hour);case"M":return fmt2(this.minute);case"S":return fmt2(this.second);}
throw new ValueError(`No known conversion for ${m}`);});}
toJSON(){return this.strftime("%H:%M:%S");}}
const DAYS_IN_YEAR=[31,59,90,120,151,181,212,243,273,304,334,366];const TIME_PERIODS=["hour","minute","second"];const PERIODS=["year","month","day",...TIME_PERIODS];const RELATIVE_KEYS="years months weeks days hours minutes seconds microseconds leapdays".split(" ");const ABSOLUTE_KEYS="year month day hour minute second microsecond weekday nlyearday yearday".split(" ");const argsSpec=["dt1","dt2"];const PyRelativeDelta=__exports.PyRelativeDelta=class PyRelativeDelta{static create(...args){const params=parseArgs(args,argsSpec);if("dt1"in params){throw new Error("relativedelta(dt1, dt2) is not supported for now");}
for(const period of PERIODS){if(period in params){const val=params[period];assert(val>=0,`${period} ${val} is out of range`);}}
for(const key of RELATIVE_KEYS){params[key]=params[key]||0;}
for(const key of ABSOLUTE_KEYS){params[key]=key in params?params[key]:null;}
params.days+=7*params.weeks;let yearDay=0;if(params.nlyearday){yearDay=params.nlyearday;}else if(params.yearday){yearDay=params.yearday;if(yearDay>59){params.leapDays=-1;}}
if(yearDay){for(let monthIndex=0;monthIndex<DAYS_IN_YEAR.length;monthIndex++){if(yearDay<=DAYS_IN_YEAR[monthIndex]){params.month=monthIndex+1;if(monthIndex===0){params.day=yearDay;}else{params.day=yearDay-DAYS_IN_YEAR[monthIndex-1];}
break;}}}
return new PyRelativeDelta(params);}
static add(date,delta){if(!(date instanceof PyDate||date instanceof PyDateTime)){throw new NotSupportedError();}
const s=tmxxx((delta.year||date.year)+delta.years,(delta.month||date.month)+delta.months,delta.day||date.day,delta.hour||date.hour||0,delta.minute||date.minute||0,delta.second||date.seconds||0,delta.microseconds||date.microseconds||0);const newDateTime=new PyDateTime(s.year,s.month,s.day,s.hour,s.minute,s.second,s.microsecond);let leapDays=0;if(delta.leapDays&&newDateTime.month>2&&isLeap(newDateTime.year)){leapDays=delta.leapDays;}
const temp=newDateTime.add(PyTimeDelta.create({days:delta.days+leapDays,hours:delta.hours,minutes:delta.minutes,seconds:delta.seconds,microseconds:delta.microseconds,}));const hasTime=Boolean(temp.hour||temp.minute||temp.second||temp.microsecond);const returnDate=!hasTime&&date instanceof PyDate?new PyDate(temp.year,temp.month,temp.day):temp;if(delta.weekday!==null){const wantedDow=delta.weekday+1;const _date=new Date(returnDate.year,returnDate.month-1,returnDate.day);const days=(7-_date.getDay()+wantedDow)%7;return returnDate.add(new PyTimeDelta(days,0,0));}
return returnDate;}
static substract(date,delta){return PyRelativeDelta.add(date,delta.negate());}
constructor(params={},sign=+1){this.years=sign*params.years;this.months=sign*params.months;this.days=sign*params.days;this.hours=sign*params.hours;this.minutes=sign*params.minutes;this.seconds=sign*params.seconds;this.microseconds=sign*params.microseconds;this.leapDays=params.leapDays;this.year=params.year;this.month=params.month;this.day=params.day;this.hour=params.hour;this.minute=params.minute;this.second=params.second;this.microsecond=params.microsecond;this.weekday=params.weekday;}
negate(){return new PyRelativeDelta(this,-1);}
isEqual(other){throw new NotSupportedError();}}
const TIME_DELTA_KEYS="weeks days hours minutes seconds milliseconds microseconds".split(" ");function modf(x){const mod=x%1;return[mod<0?mod+1:mod,Math.floor(x)];}
const PyTimeDelta=__exports.PyTimeDelta=class PyTimeDelta{static create(...args){const namedArgs=parseArgs(args,["days","seconds","microseconds"]);for(const key of TIME_DELTA_KEYS){namedArgs[key]=namedArgs[key]||0;}
let d=0;let s=0;let us=0;const days=namedArgs.days+namedArgs.weeks*7;let seconds=namedArgs.seconds+60*namedArgs.minutes+3600*namedArgs.hours;let microseconds=namedArgs.microseconds+1000*namedArgs.milliseconds;const[dFrac,dInt]=modf(days);d=dInt;let daysecondsfrac=0;if(dFrac){const[dsFrac,dsInt]=modf(dFrac*24*3600);s=dsInt;daysecondsfrac=dsFrac;}
const[sFrac,sInt]=modf(seconds);seconds=sInt;const secondsfrac=sFrac+daysecondsfrac;divmod(seconds,24*3600,(days,seconds)=>{d+=days;s+=seconds;});microseconds+=secondsfrac*1e6;divmod(microseconds,1000000,(seconds,microseconds)=>{divmod(seconds,24*3600,(days,seconds)=>{d+=days;s+=seconds;us+=Math.round(microseconds);});});return new PyTimeDelta(d,s,us);}
constructor(days,seconds,microseconds){this.days=days;this.seconds=seconds;this.microseconds=microseconds;}
add(other){return PyTimeDelta.create({days:this.days+other.days,seconds:this.seconds+other.seconds,microseconds:this.microseconds+other.microseconds,});}
divide(n){const us=(this.days*24*3600+this.seconds)*1e6+this.microseconds;return PyTimeDelta.create({microseconds:Math.floor(us/n)});}
isEqual(other){if(!(other instanceof PyTimeDelta)){return false;}
return(this.days===other.days&&this.seconds===other.seconds&&this.microseconds===other.microseconds);}
isTrue(){return this.days!==0||this.seconds!==0||this.microseconds!==0;}
multiply(n){return PyTimeDelta.create({days:n*this.days,seconds:n*this.seconds,microseconds:n*this.microseconds,});}
negate(){return PyTimeDelta.create({days:-this.days,seconds:-this.seconds,microseconds:-this.microseconds,});}
substract(other){return PyTimeDelta.create({days:this.days-other.days,seconds:this.seconds-other.seconds,microseconds:this.microseconds-other.microseconds,});}
total_seconds(){return this.days*86400+this.seconds+this.microseconds/1000000;}}
return __exports;});;
/* /web/static/src/core/py_js/py_interpreter.js */
odoo.define('@web/core/py_js/py_interpreter',['@web/core/py_js/py_builtin','@web/core/py_js/py_date','@web/core/py_js/py_utils','@web/core/py_js/py_parser'],function(require){'use strict';let __exports={};const{BUILTINS,EvaluationError,execOnIterable}=require("@web/core/py_js/py_builtin");const{NotSupportedError,PyDate,PyDateTime,PyRelativeDelta,PyTime,PyTimeDelta,}=require("@web/core/py_js/py_date");const{PY_DICT,toPyDict}=require("@web/core/py_js/py_utils");const{parseArgs}=require("@web/core/py_js/py_parser");const isTrue=BUILTINS.bool;function applyUnaryOp(ast,context){const value=evaluate(ast.right,context);switch(ast.op){case"-":if(value instanceof Object&&value.negate){return value.negate();}
return-value;case"+":return value;case"not":return!isTrue(value);}
throw new EvaluationError(`Unknown unary operator: ${ast.op}`);}
function pytypeIndex(val){switch(typeof val){case"object":return val===null?1:Array.isArray(val)?5:3;case"number":return 2;case"string":return 4;}
throw new EvaluationError(`Unknown type: ${typeof val}`);}
function isConstructor(obj){return!!obj.prototype&&!!obj.prototype.constructor.name;}
function isLess(left,right){if(typeof left==="number"&&typeof right==="number"){return left<right;}
if(typeof left==="boolean"){left=left?1:0;}
if(typeof right==="boolean"){right=right?1:0;}
const leftIndex=pytypeIndex(left);const rightIndex=pytypeIndex(right);if(leftIndex===rightIndex){return left<right;}
return leftIndex<rightIndex;}
function isEqual(left,right){if(typeof left!==typeof right){if(typeof left==="boolean"&&typeof right==="number"){return right===(left?1:0);}
if(typeof left==="number"&&typeof right==="boolean"){return left===(right?1:0);}
return false;}
if(left instanceof Object&&left.isEqual){return left.isEqual(right);}
return left===right;}
function isIn(left,right){if(Array.isArray(right)){return right.includes(left);}
if(typeof right==="string"&&typeof left==="string"){return right.includes(left);}
if(typeof right==="object"){return left in right;}
return false;}
function applyBinaryOp(ast,context){const left=evaluate(ast.left,context);const right=evaluate(ast.right,context);switch(ast.op){case"+":{const relativeDeltaOnLeft=left instanceof PyRelativeDelta;const relativeDeltaOnRight=right instanceof PyRelativeDelta;if(relativeDeltaOnLeft||relativeDeltaOnRight){const date=relativeDeltaOnLeft?right:left;const delta=relativeDeltaOnLeft?left:right;return PyRelativeDelta.add(date,delta);}
const timeDeltaOnLeft=left instanceof PyTimeDelta;const timeDeltaOnRight=right instanceof PyTimeDelta;if(timeDeltaOnLeft&&timeDeltaOnRight){return left.add(right);}
if(timeDeltaOnLeft){if(right instanceof PyDate||right instanceof PyDateTime){return right.add(left);}else{throw new NotSupportedError();}}
if(timeDeltaOnRight){if(left instanceof PyDate||left instanceof PyDateTime){return left.add(right);}else{throw new NotSupportedError();}}
if(left instanceof Array&&right instanceof Array){return[...left,...right];}
return left+right;}
case"-":{const isRightDelta=right instanceof PyRelativeDelta;if(isRightDelta){return PyRelativeDelta.substract(left,right);}
const timeDeltaOnRight=right instanceof PyTimeDelta;if(timeDeltaOnRight){if(left instanceof PyTimeDelta){return left.substract(right);}else if(left instanceof PyDate||left instanceof PyDateTime){return left.substract(right);}else{throw new NotSupportedError();}}
if(left instanceof PyDate){return left.substract(right);}
return left-right;}
case"*":{const timeDeltaOnLeft=left instanceof PyTimeDelta;const timeDeltaOnRight=right instanceof PyTimeDelta;if(timeDeltaOnLeft||timeDeltaOnRight){const number=timeDeltaOnLeft?right:left;const delta=timeDeltaOnLeft?left:right;return delta.multiply(number);}
return left*right;}
case"/":return left/right;case"%":return left%right;case"//":if(left instanceof PyTimeDelta){return left.divide(right);}
return Math.floor(left/right);case"**":return left**right;case"==":return isEqual(left,right);case"<>":case"!=":return!isEqual(left,right);case"<":return isLess(left,right);case">":return isLess(right,left);case">=":return isEqual(left,right)||isLess(right,left);case"<=":return isEqual(left,right)||isLess(left,right);case"in":return isIn(left,right);case"not in":return!isIn(left,right);}
throw new EvaluationError(`Unknown binary operator: ${ast.op}`);}
const DICT={get(...args){const{key,defValue}=parseArgs(args,["key","defValue"]);if(key in this){return this[key];}else if(defValue){return defValue;}
return null;},};const STRING={lower(){return this.toLowerCase();},upper(){return this.toUpperCase();},};function applyFunc(key,func,set,...args){if(args.length===1){return new Set(set);}
if(args.length>2){throw new EvaluationError(`${key}: py_js supports at most 1 argument, got (${args.length - 1})`);}
return execOnIterable(args[0],func);}
const SET={intersection(...args){return applyFunc("intersection",(iterable)=>{const intersection=new Set();for(const i of iterable){if(this.has(i)){intersection.add(i);}}
return intersection;},this,...args);},difference(...args){return applyFunc("difference",(iterable)=>{iterable=new Set(iterable);const difference=new Set();for(const e of this){if(!iterable.has(e)){difference.add(e);}}
return difference;},this,...args);},union(...args){return applyFunc("union",(iterable)=>new Set([...this,...iterable]),this,...args);},};function methods(_class){return Object.getOwnPropertyNames(_class.prototype).map((prop)=>_class.prototype[prop]);}
const allowedFns=new Set([BUILTINS.time.strftime,BUILTINS.set,BUILTINS.bool,BUILTINS.min,BUILTINS.max,BUILTINS.context_today,BUILTINS.datetime.datetime.now,BUILTINS.datetime.datetime.combine,BUILTINS.datetime.date.today,...methods(BUILTINS.relativedelta),...Object.values(BUILTINS.datetime).flatMap((obj)=>methods(obj)),...Object.values(SET),...Object.values(DICT),...Object.values(STRING),]);const unboundFn=Symbol("unbound function");__exports.evaluate=evaluate;function evaluate(ast,context={}){const dicts=new Set();let pyContext;const evalContext=Object.create(context);if(!evalContext.context){Object.defineProperty(evalContext,"context",{get(){if(!pyContext){pyContext=toPyDict(context);}
return pyContext;},});}
function _innerEvaluate(ast){switch(ast.type){case 0:case 1:return ast.value;case 5:if(ast.value in evalContext){return evalContext[ast.value];}else if(ast.value in BUILTINS){return BUILTINS[ast.value];}else{throw new EvaluationError(`Name '${ast.value}' is not defined`);}
case 3:return null;case 2:return ast.value;case 6:return applyUnaryOp(ast,evalContext);case 7:return applyBinaryOp(ast,evalContext);case 14:{const left=_evaluate(ast.left);if(ast.op==="and"){return isTrue(left)?_evaluate(ast.right):left;}else{return isTrue(left)?left:_evaluate(ast.right);}}
case 4:case 10:return ast.value.map(_evaluate);case 11:{const dict={};for(const key in ast.value){dict[key]=_evaluate(ast.value[key]);}
dicts.add(dict);return dict;}
case 8:{const fnValue=_evaluate(ast.fn);const args=ast.args.map(_evaluate);const kwargs={};for(const kwarg in ast.kwargs){kwargs[kwarg]=_evaluate(ast.kwargs[kwarg]);}
if(fnValue===PyDate||fnValue===PyDateTime||fnValue===PyTime||fnValue===PyRelativeDelta||fnValue===PyTimeDelta){return fnValue.create(...args,kwargs);}
return fnValue(...args,kwargs);}
case 12:{const dict=_evaluate(ast.target);const key=_evaluate(ast.key);return dict[key];}
case 13:{if(isTrue(_evaluate(ast.condition))){return _evaluate(ast.ifTrue);}else{return _evaluate(ast.ifFalse);}}
case 15:{let left=_evaluate(ast.obj);let result;if(dicts.has(left)||Object.isPrototypeOf.call(PY_DICT,left)){result=DICT[ast.key];}else if(typeof left==="string"){result=STRING[ast.key];}else if(left instanceof Set){result=SET[ast.key];}else if(ast.key=="get"&&typeof left==="object"){result=DICT[ast.key];left=toPyDict(left);}else{result=left[ast.key];}
if(typeof result==="function"){if(!isConstructor(result)){const bound=result.bind(left);bound[unboundFn]=result;return bound;}}
return result;}}
throw new EvaluationError(`AST of type ${ast.type} cannot be evaluated`);}
function _evaluate(ast){const val=_innerEvaluate(ast);if(typeof val==="function"&&!allowedFns.has(val)&&!allowedFns.has(val[unboundFn])){throw new Error("Invalid Function Call");}
return val;}
return _evaluate(ast);}
return __exports;});;
/* /web/static/src/core/py_js/py_parser.js */
odoo.define('@web/core/py_js/py_parser',['@web/core/py_js/py_tokenizer'],function(require){'use strict';let __exports={};const{binaryOperators,comparators}=require("@web/core/py_js/py_tokenizer");const ParserError=__exports.ParserError=class ParserError extends Error{}
const chainedOperators=new Set(comparators);const infixOperators=new Set(binaryOperators.concat(comparators));__exports.bp=bp;function bp(symbol){switch(symbol){case"=":return 10;case"if":return 20;case"in":case"not in":case"is":case"is not":case"<":case"<=":case">":case">=":case"<>":case"==":case"!=":return 60;case"or":return 30;case"and":return 40;case"not":return 50;case"|":return 70;case"^":return 80;case"&":return 90;case"<<":case">>":return 100;case"+":case"-":return 110;case"*":case"/":case"//":case"%":return 120;case"**":return 140;case".":case"(":case"[":return 150;}
return 0;}
function bindingPower(token){return token.type===2?bp(token.value):0;}
function isSymbol(token,value){return token.type===2&&token.value===value;}
function parsePrefix(current,tokens){switch(current.type){case 0:return{type:0,value:current.value};case 1:return{type:1,value:current.value};case 4:if(current.value==="None"){return{type:3};}else{return{type:2,value:current.value==="True"};}
case 3:return{type:5,value:current.value};case 2:switch(current.value){case"-":case"+":case"~":return{type:6,op:current.value,right:_parse(tokens,130),};case"not":return{type:6,op:current.value,right:_parse(tokens,50),};case"(":{const content=[];let isTuple=false;while(tokens[0]&&!isSymbol(tokens[0],")")){content.push(_parse(tokens,0));if(tokens[0]){if(tokens[0]&&isSymbol(tokens[0],",")){isTuple=true;tokens.shift();}else if(!isSymbol(tokens[0],")")){throw new ParserError("parsing error");}}else{throw new ParserError("parsing error");}}
if(!tokens[0]||!isSymbol(tokens[0],")")){throw new ParserError("parsing error");}
tokens.shift();isTuple=isTuple||content.length===0;return isTuple?{type:10,value:content}:content[0];}
case"[":{const value=[];while(tokens[0]&&!isSymbol(tokens[0],"]")){value.push(_parse(tokens,0));if(tokens[0]){if(isSymbol(tokens[0],",")){tokens.shift();}else if(!isSymbol(tokens[0],"]")){throw new ParserError("parsing error");}}}
if(!tokens[0]||!isSymbol(tokens[0],"]")){throw new ParserError("parsing error");}
tokens.shift();return{type:4,value};}
case"{":{const dict={};while(tokens[0]&&!isSymbol(tokens[0],"}")){const key=_parse(tokens,0);if((key.type!==1&&key.type!==0)||!tokens[0]||!isSymbol(tokens[0],":")){throw new ParserError("parsing error");}
tokens.shift();const value=_parse(tokens,0);dict[key.value]=value;if(isSymbol(tokens[0],",")){tokens.shift();}}
if(!tokens.shift()){throw new ParserError("parsing error");}
return{type:11,value:dict};}}}
throw new ParserError("Token cannot be parsed");}
function parseInfix(left,current,tokens){switch(current.type){case 2:if(infixOperators.has(current.value)){let right=_parse(tokens,bindingPower(current));if(current.value==="and"||current.value==="or"){return{type:14,op:current.value,left,right,};}else if(current.value==="."){if(right.type===5){return{type:15,obj:left,key:right.value,};}else{throw new ParserError("invalid obj lookup");}}
let op={type:7,op:current.value,left,right,};while(chainedOperators.has(current.value)&&tokens[0]&&tokens[0].type===2&&chainedOperators.has(tokens[0].value)){const nextToken=tokens.shift();op={type:14,op:"and",left:op,right:{type:7,op:nextToken.value,left:right,right:_parse(tokens,bindingPower(nextToken)),},};right=op.right.right;}
return op;}
switch(current.value){case"(":{const args=[];const kwargs={};while(tokens[0]&&!isSymbol(tokens[0],")")){const arg=_parse(tokens,0);if(arg.type===9){kwargs[arg.name.value]=arg.value;}else{args.push(arg);}
if(tokens[0]&&isSymbol(tokens[0],",")){tokens.shift();}}
if(!tokens[0]||!isSymbol(tokens[0],")")){throw new ParserError("parsing error");}
tokens.shift();return{type:8,fn:left,args,kwargs};}
case"=":if(left.type===5){return{type:9,name:left,value:_parse(tokens,10),};}
break;case"[":{const key=_parse(tokens);if(!tokens[0]||!isSymbol(tokens[0],"]")){throw new ParserError("parsing error");}
tokens.shift();return{type:12,target:left,key:key,};}
case"if":{const condition=_parse(tokens);if(!tokens[0]||!isSymbol(tokens[0],"else")){throw new ParserError("parsing error");}
tokens.shift();const ifFalse=_parse(tokens);return{type:13,condition,ifTrue:left,ifFalse,};}}}
throw new ParserError("Token cannot be parsed");}
function _parse(tokens,bp=0){const token=tokens.shift();let expr=parsePrefix(token,tokens);while(tokens[0]&&bindingPower(tokens[0])>bp){expr=parseInfix(expr,tokens.shift(),tokens);}
return expr;}
__exports.parse=parse;function parse(tokens){if(tokens.length){const ast=_parse(tokens,0);if(tokens.length){throw new ParserError("Token(s) unused");}
return ast;}
throw new ParserError("Missing token");}
__exports.parseArgs=parseArgs;function parseArgs(args,spec){const last=args[args.length-1];const unnamedArgs=typeof last==="object"?args.slice(0,-1):args;const kwargs=typeof last==="object"?last:{};for(const[index,val]of unnamedArgs.entries()){kwargs[spec[index]]=val;}
return kwargs;}
return __exports;});;
/* /web/static/src/core/py_js/py_tokenizer.js */
odoo.define('@web/core/py_js/py_tokenizer',[],function(require){'use strict';let __exports={};const TokenizerError=__exports.TokenizerError=class TokenizerError extends Error{}
const directMap={"\\":"\\",'"':'"',"'":"'",a:"\x07",b:"\x08",f:"\x0c",n:"\n",r:"\r",t:"\t",v:"\v",};function decodeStringLiteral(str,unicode){const out=[];let code;for(var i=0;i<str.length;++i){if(str[i]!=="\\"){out.push(str[i]);continue;}
var escape=str[i+1];if(escape in directMap){out.push(directMap[escape]);++i;continue;}
switch(escape){case"\n":++i;continue;case"N":if(!unicode){break;}
throw new TokenizerError("SyntaxError: \\N{} escape not implemented");case"u":if(!unicode){break;}
var uni=str.slice(i+2,i+6);if(!/[0-9a-f]{4}/i.test(uni)){throw new TokenizerError(["SyntaxError: (unicode error) 'unicodeescape' codec"," can't decode bytes in position ",i,"-",i+4,": truncated \\uXXXX escape",].join(""));}
code=parseInt(uni,16);out.push(String.fromCharCode(code));i+=5;continue;case"U":if(!unicode){break;}
throw new TokenizerError("SyntaxError: \\U escape not implemented");case"x":var hex=str.slice(i+2,i+4);if(!/[0-9a-f]{2}/i.test(hex)){if(!unicode){throw new TokenizerError("ValueError: invalid \\x escape");}
throw new TokenizerError(["SyntaxError: (unicode error) 'unicodeescape'"," codec can't decode bytes in position ",i,"-",i+2,": truncated \\xXX escape",].join(""));}
code=parseInt(hex,16);out.push(String.fromCharCode(code));i+=3;continue;default:if(!/[0-8]/.test(escape)){break;}
var r=/[0-8]{1,3}/g;r.lastIndex=i+1;var m=r.exec(str);var oct=m[0];code=parseInt(oct,8);out.push(String.fromCharCode(code));i+=oct.length;continue;}
out.push("\\");}
return out.join("");}
const constants=new Set(["None","False","True"]);const comparators=__exports.comparators=["in","not","not in","is","is not","<","<=",">",">=","<>","!=","==",];const binaryOperators=__exports.binaryOperators=["or","and","|","^","&","<<",">>","+","-","*","/","//","%","~","**",".",];const unaryOperators=__exports.unaryOperators=["-"];const symbols=new Set([...["(",")","[","]","{","}",":",","],...["if","else","lambda","="],...comparators,...binaryOperators,...unaryOperators,]);function group(...args){return"("+args.join("|")+")";}
const Name="[a-zA-Z_]\\w*";const Whitespace="[ \\f\\t]*";const DecNumber="\\d+(L|l)?";const IntNumber=DecNumber;const Exponent="[eE][+-]?\\d+";const PointFloat=group(`\\d+\\.\\d*(${Exponent})?`,`\\.\\d+(${Exponent})?`);const FloatNumber=group(PointFloat,`\\d+${Exponent}`);const Number=group(FloatNumber,IntNumber);const Operator=group("\\*\\*=?",">>=?","<<=?","<>","!=","//=?","[+\\-*/%&|^=<>]=?","~");const Bracket="[\\[\\]\\(\\)\\{\\}]";const Special="[:;.,`@]";const Funny=group(Operator,Bracket,Special);const ContStr=group("([uU])?'([^\n'\\\\]*(?:\\\\.[^\n'\\\\]*)*)'",'([uU])?"([^\n"\\\\]*(?:\\\\.[^\n"\\\\]*)*)"');const PseudoToken=Whitespace+group(Number,Funny,ContStr,Name);const NumberPattern=new RegExp("^"+Number+"$");const StringPattern=new RegExp("^"+ContStr+"$");const NamePattern=new RegExp("^"+Name+"$");const strip=new RegExp("^"+Whitespace);__exports.tokenize=tokenize;function tokenize(str){const tokens=[];const max=str.length;let start=0;let end=0;const pseudoprog=new RegExp(PseudoToken,"g");while(pseudoprog.lastIndex<max){const pseudomatch=pseudoprog.exec(str);if(!pseudomatch){if(/^\s+$/.test(str.slice(end))){break;}
throw new TokenizerError("Failed to tokenize <<"+
str+">> at index "+
(end||0)+"; parsed so far: "+
tokens);}
if(pseudomatch.index>end){if(str.slice(end,pseudomatch.index).trim()){throw new TokenizerError("Invalid expression");}}
start=pseudomatch.index;end=pseudoprog.lastIndex;let token=str.slice(start,end).replace(strip,"");if(NumberPattern.test(token)){tokens.push({type:0,value:parseFloat(token),});}else if(StringPattern.test(token)){var m=StringPattern.exec(token);tokens.push({type:1,value:decodeStringLiteral(m[3]!==undefined?m[3]:m[5],!!(m[2]||m[4])),});}else if(symbols.has(token)){if(token==="in"&&tokens.length>0&&tokens[tokens.length-1].value==="not"){token="not in";tokens.pop();}else if(token==="not"&&tokens.length>0&&tokens[tokens.length-1].value==="is"){token="is not";tokens.pop();}
tokens.push({type:2,value:token,});}else if(constants.has(token)){tokens.push({type:4,value:token,});}else if(NamePattern.test(token)){tokens.push({type:3,value:token,});}else{throw new TokenizerError("Invalid expression");}}
return tokens;}
return __exports;});;
/* /web/static/src/core/py_js/py_utils.js */
odoo.define('@web/core/py_js/py_utils',['@web/core/py_js/py_parser','@web/core/py_js/py_date'],function(require){'use strict';let __exports={};const{bp}=require("@web/core/py_js/py_parser");const{PyDate,PyDateTime}=require("@web/core/py_js/py_date");__exports.toPyValue=toPyValue;function toPyValue(value){switch(typeof value){case"string":return{type:1,value};case"number":return{type:0,value};case"boolean":return{type:2,value};case"object":if(Array.isArray(value)){return{type:4,value:value.map(toPyValue)};}else if(value===null){return{type:3};}else if(value instanceof Date){return{type:1,value:PyDateTime.convertDate(value)};}else if(value instanceof PyDate||value instanceof PyDateTime){return{type:1,value};}else{const content={};for(const key in value){content[key]=toPyValue(value[key]);}
return{type:11,value:content};}
default:throw new Error("Invalid type");}}
__exports.formatAST=formatAST;function formatAST(ast,lbp=0){switch(ast.type){case 3:return"None";case 1:return JSON.stringify(ast.value);case 0:return String(ast.value);case 2:return ast.value?"True":"False";case 4:return`[${ast.value.map(formatAST).join(", ")}]`;case 6:if(ast.op==="not"){return`not `+formatAST(ast.right,50);}
return ast.op+formatAST(ast.right,130);case 7:{const abp=bp(ast.op);const str=`${formatAST(ast.left, abp)} ${ast.op} ${formatAST(ast.right, abp)}`;return abp<lbp?`(${str})`:str;}
case 11:{const pairs=[];for(const k in ast.value){pairs.push(`"${k}": ${formatAST(ast.value[k])}`);}
return`{`+pairs.join(", ")+`}`;}
case 10:return`(${ast.value.map(formatAST).join(", ")})`;case 5:return ast.value;case 12:{return`${formatAST(ast.target)}[${formatAST(ast.key)}]`;}
case 13:{const{ifTrue,condition,ifFalse}=ast;return`${formatAST(ifTrue)} if ${formatAST(condition)} else ${formatAST(ifFalse)}`;}
case 14:{const abp=bp(ast.op);const str=`${formatAST(ast.left, abp)} ${ast.op} ${formatAST(ast.right, abp)}`;return abp<lbp?`(${str})`:str;}
case 15:return`${formatAST(ast.obj, 150)}.${ast.key}`;case 8:{const args=ast.args.map(formatAST);const kwargs=[];for(const kwarg in ast.kwargs){kwargs.push(`${kwarg} = ${formatAST(ast.kwargs[kwarg])}`);}
const argStr=args.concat(kwargs).join(", ");return`${formatAST(ast.fn)}(${argStr})`;}}
throw new Error("invalid expression: "+ast);}
const PY_DICT=__exports.PY_DICT=Object.create(null);__exports.toPyDict=toPyDict;function toPyDict(obj){return new Proxy(obj,{getPrototypeOf(){return PY_DICT;},});}
return __exports;});;
/* /web/static/src/core/record_selectors/multi_record_selector.js */
odoo.define('@web/core/record_selectors/multi_record_selector',['@odoo/owl','@web/core/l10n/translation','@web/core/tags_list/tags_list','@web/core/tree_editor/utils','@web/core/utils/hooks','@web/core/utils/urls','@web/core/record_selectors/record_autocomplete','@web/core/record_selectors/tag_navigation_hook'],function(require){'use strict';let __exports={};const{Component,onWillStart,onWillUpdateProps}=require("@odoo/owl");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{TagsList}=require("@web/core/tags_list/tags_list");const{isId}=require("@web/core/tree_editor/utils");const{useService}=require("@web/core/utils/hooks");const{imageUrl}=require("@web/core/utils/urls");const{RecordAutocomplete}=require("@web/core/record_selectors/record_autocomplete");const{useTagNavigation}=require("@web/core/record_selectors/tag_navigation_hook");const MultiRecordSelector=__exports.MultiRecordSelector=class MultiRecordSelector extends Component{static props={resIds:{type:Array,element:Number},resModel:String,update:Function,domain:{type:Array,optional:true},context:{type:Object,optional:true},fieldString:{type:String,optional:true},placeholder:{type:String,optional:true},};static components={RecordAutocomplete,TagsList};static template="web.MultiRecordSelector";setup(){this.nameService=useService("name");useTagNavigation("multiRecordSelector",{delete:(index)=>this.deleteTag(index),});onWillStart(()=>this.computeDerivedParams());onWillUpdateProps((nextProps)=>this.computeDerivedParams(nextProps));}
get isAvatarModel(){return["res.partner","res.users","hr.employee","hr.employee.public"].includes(this.props.resModel);}
async computeDerivedParams(props=this.props){const displayNames=await this.getDisplayNames(props);this.tags=this.getTags(props,displayNames);}
async getDisplayNames(props){const ids=this.getIds(props);return this.nameService.loadDisplayNames(props.resModel,ids);}
get placeholder(){return this.getTags(this.props,{}).length?"":this.props.placeholder;}
getIds(props=this.props){return props.resIds;}
getTags(props,displayNames){return props.resIds.map((id,index)=>{const text=typeof displayNames[id]==="string"?displayNames[id]:_t("Inaccessible/missing record ID: %s",id);return{text,onDelete:()=>{this.deleteTag(index);},img:this.isAvatarModel&&isId(id)&&imageUrl(this.props.resModel,id,"avatar_128"),};});}
deleteTag(index){this.props.update([...this.props.resIds.slice(0,index),...this.props.resIds.slice(index+1),]);}
update(resIds){this.props.update([...this.props.resIds,...resIds]);}}
return __exports;});;
/* /web/static/src/core/record_selectors/record_autocomplete.js */
odoo.define('@web/core/record_selectors/record_autocomplete',['@odoo/owl','@web/core/autocomplete/autocomplete','@web/core/l10n/translation','@web/core/domain','@web/core/registry','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{AutoComplete}=require("@web/core/autocomplete/autocomplete");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{Domain}=require("@web/core/domain");const{registry}=require("@web/core/registry");const{useOwnedDialogs,useService}=require("@web/core/utils/hooks");const SEARCH_LIMIT=7;const SEARCH_MORE_LIMIT=320;const RecordAutocomplete=__exports.RecordAutocomplete=class RecordAutocomplete extends Component{static props={resModel:String,update:Function,multiSelect:Boolean,getIds:Function,value:String,domain:{type:Array,optional:true},context:{type:Object,optional:true},className:{type:String,optional:true},fieldString:{type:String,optional:true},placeholder:{type:String,optional:true},slots:{optional:true},};static components={AutoComplete};static template="web.RecordAutocomplete";setup(){this.orm=useService("orm");this.nameService=useService("name");this.addDialog=useOwnedDialogs();this.sources=[{placeholder:_t("Loading..."),options:this.loadOptionsSource.bind(this),optionSlot:this.props.slots?.autoCompleteItem?"option":undefined,},];}
addNames(options){const displayNames=Object.fromEntries(options);this.nameService.addDisplayNames(this.props.resModel,displayNames);}
getIds(){return this.props.getIds();}
async loadOptionsSource(name){if(this.lastProm){this.lastProm.abort(false);}
this.lastProm=this.search(name,SEARCH_LIMIT+1);const nameGets=(await this.lastProm).map(([id,label])=>[id,label?label.split("\n")[0]:_t("Unnamed"),]);this.addNames(nameGets);const options=nameGets.map(([id,label])=>({data:{record:{id,display_name:label},},label,onSelect:()=>this.props.update([id]),}));if(SEARCH_LIMIT<nameGets.length){options.push({cssClass:"o_m2o_dropdown_option",label:_t("Search More..."),onSelect:this.onSearchMore.bind(this,name),});}
if(options.length===0){options.push({label:_t("(no result)")});}
return options;}
async onSearchMore(name){const{fieldString,multiSelect,resModel}=this.props;let operator;const ids=[];if(name){const nameGets=await this.search(name,SEARCH_MORE_LIMIT);this.addNames(nameGets);operator="in";ids.push(...nameGets.map((nameGet)=>nameGet[0]));}else{operator="not in";ids.push(...this.getIds());}
const dynamicFilters=ids.length?[{description:_t("Quick search: %s",name),domain:[["id",operator,ids]],},]:undefined;const SelectCreateDialog=registry.category("dialogs").get("select_create");let title=_t("Search");if(fieldString&&fieldString.trim()){title=_t("Search: %s",fieldString);}
this.addDialog(SelectCreateDialog,{title,dynamicFilters,domain:this.getDomain(),resModel,noCreate:true,multiSelect,context:this.props.context||{},onSelected:(resId)=>{const resIds=Array.isArray(resId)?resId:[resId];this.props.update([...resIds]);},});}
getDomain(){const domainIds=Domain.not([["id","in",this.getIds()]]);if(this.props.domain){return Domain.and([this.props.domain,domainIds]).toList();}
return domainIds.toList();}
search(name,limit){const domain=this.getDomain();return this.orm.call(this.props.resModel,"name_search",[],{name,domain:domain,limit,context:this.props.context||{},});}
onChange({inputValue}){if(!inputValue.length){this.props.update([]);}}}
return __exports;});;
/* /web/static/src/core/record_selectors/record_selector.js */
odoo.define('@web/core/record_selectors/record_selector',['@odoo/owl','@web/core/l10n/translation','@web/core/tree_editor/utils','@web/core/utils/hooks','@web/core/record_selectors/record_autocomplete'],function(require){'use strict';let __exports={};const{Component,onWillStart,onWillUpdateProps}=require("@odoo/owl");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{isId}=require("@web/core/tree_editor/utils");const{useService}=require("@web/core/utils/hooks");const{RecordAutocomplete}=require("@web/core/record_selectors/record_autocomplete");const RecordSelector=__exports.RecordSelector=class RecordSelector extends Component{static props={resId:[Number,{value:false}],resModel:String,update:Function,domain:{type:Array,optional:true},context:{type:Object,optional:true},fieldString:{type:String,optional:true},placeholder:{type:String,optional:true},};static components={RecordAutocomplete};static template="web.RecordSelector";setup(){this.nameService=useService("name");onWillStart(()=>this.computeDerivedParams());onWillUpdateProps((nextProps)=>this.computeDerivedParams(nextProps));}
get isAvatarModel(){return["res.partner","res.users","hr.employee","hr.employee.public"].includes(this.props.resModel);}
get hasAvatarImg(){return this.isAvatarModel&&isId(this.props.resId);}
async computeDerivedParams(props=this.props){const displayNames=await this.getDisplayNames(props);this.displayName=this.getDisplayName(props,displayNames);}
async getDisplayNames(props){const ids=this.getIds(props);return this.nameService.loadDisplayNames(props.resModel,ids);}
getDisplayName(props=this.props,displayNames){const{resId}=props;if(resId===false){return"";}
return typeof displayNames[resId]==="string"?displayNames[resId]:_t("Inaccessible/missing record ID: %s",resId);}
getIds(props=this.props){if(props.resId){return[props.resId];}
return[];}
update(resIds){this.props.update(resIds[0]||false);this.render(true);}}
return __exports;});;
/* /web/static/src/core/record_selectors/tag_navigation_hook.js */
odoo.define('@web/core/record_selectors/tag_navigation_hook',['@odoo/owl','@web/core/navigation/navigation'],function(require){'use strict';let __exports={};const{useRef}=require("@odoo/owl");const{useNavigation}=require("@web/core/navigation/navigation");__exports.useTagNavigation=useTagNavigation;function useTagNavigation(refName,options={}){const tagsContainerRef=useRef(refName);const isEnabled=options.isEnabled??(()=>true);const canRemoveTag=(target)=>options.delete&&(target.tagName.toLowerCase()!=="input"||!target.value);const onBackspaceKeydown=(navigator)=>{const el=navigator.activeItem.el;if(el.classList.contains("o-autocomplete--input")){if(!el.value&&navigator.items.length>1){options.delete(navigator.items.length-2);}}else{options.delete(navigator.activeItemIndex);}
navigator.items.at(-1).setActive();};const canNavigateFromInput=(navigator,navNext)=>{const el=navigator.activeItem.el;if(el.classList.contains("o-autocomplete--input")){const menu=tagsContainerRef.el.querySelector(".o-autocomplete--dropdown-menu");const index=navNext?el.value.length:0;if(el.selectionStart!==index||menu){return false;}}
return true;};useNavigation(tagsContainerRef,{getItems:()=>tagsContainerRef.el?.querySelectorAll(":scope .o_tag, :scope .o-autocomplete--input")??[],isNavigationAvailable:({navigator,target})=>isEnabled()&&navigator.isFocused&&navigator.contains(target),hotkeys:{tab:null,"shift+tab":null,home:null,end:null,enter:null,arrowup:null,arrowdown:null,backspace:{bypassEditableProtection:true,isAvailable:({target})=>canRemoveTag(target),callback:(navigator)=>onBackspaceKeydown(navigator),},arrowleft:{bypassEditableProtection:true,isAvailable:({navigator})=>canNavigateFromInput(navigator,false),callback:(navigator)=>navigator.previous(),},arrowright:{bypassEditableProtection:true,isAvailable:({navigator})=>canNavigateFromInput(navigator,true),callback:(navigator)=>navigator.next(),},},});}
return __exports;});;
/* /web/static/src/core/registry.js */
odoo.define('@web/core/registry',['@odoo/owl'],function(require){'use strict';let __exports={};const{EventBus,validate}=require("@odoo/owl");const KeyNotFoundError=__exports.KeyNotFoundError=class KeyNotFoundError extends Error{}
const DuplicatedKeyError=__exports.DuplicatedKeyError=class DuplicatedKeyError extends Error{}
const validateSchema=(name,key,value,schema)=>{if(!odoo.debug){return;}
try{validate(value,schema);}catch(error){throw new Error(`Validation error for key "${key}" in registry "${name}": ${error}`);}};const Registry=__exports.Registry=class Registry extends EventBus{constructor(name){super();this.content={};this.subRegistries={};this.elements=null;this.entries=null;this.name=name;this.validationSchema=null;this.addEventListener("UPDATE",()=>{this.elements=null;this.entries=null;});}
add(key,value,{force,sequence}={}){if(this.validationSchema){validateSchema(this.name,key,value,this.validationSchema);}
if(!force&&key in this.content){throw new DuplicatedKeyError(`Cannot add key "${key}" in the "${this.name}" registry: it already exists`);}
let previousSequence;if(force){const elem=this.content[key];previousSequence=elem&&elem[0];}
sequence=sequence===undefined?previousSequence||50:sequence;this.content[key]=[sequence,value];const payload={operation:"add",key,value};this.trigger("UPDATE",payload);return this;}
get(key,defaultValue){if(arguments.length<2&&!(key in this.content)){throw new KeyNotFoundError(`Cannot find key "${key}" in the "${this.name}" registry`);}
const info=this.content[key];return info?info[1]:defaultValue;}
contains(key){return key in this.content;}
getAll(){if(!this.elements){const content=Object.values(this.content).sort((el1,el2)=>el1[0]-el2[0]);this.elements=content.map((elem)=>elem[1]);}
return this.elements.slice();}
getEntries(){if(!this.entries){const entries=Object.entries(this.content).sort((el1,el2)=>el1[1][0]-el2[1][0]);this.entries=entries.map(([str,elem])=>[str,elem[1]]);}
return this.entries.slice();}
remove(key){const value=this.content[key];delete this.content[key];const payload={operation:"delete",key,value};this.trigger("UPDATE",payload);}
category(subcategory){if(!(subcategory in this.subRegistries)){this.subRegistries[subcategory]=new Registry(subcategory);}
return this.subRegistries[subcategory];}
addValidation(schema){if(this.validationSchema){throw new Error("Validation schema already set on this registry");}
this.validationSchema=schema;for(const[key,value]of this.getEntries()){validateSchema(this.name,key,value,schema);}}}
const registry=__exports.registry=new Registry();return __exports;});;
/* /web/static/src/core/registry_hook.js */
odoo.define('@web/core/registry_hook',['@odoo/owl'],function(require){'use strict';let __exports={};const{useState,onWillStart,onWillDestroy}=require("@odoo/owl");__exports.useRegistry=useRegistry;function useRegistry(registry){const state=useState({entries:registry.getEntries()});const listener=({detail})=>{const index=state.entries.findIndex(([k])=>k===detail.key);if(detail.operation==="add"&&index===-1){const newEntries=registry.getEntries();const newEntry=newEntries.find(([k])=>k===detail.key);const newIndex=newEntries.indexOf(newEntry);if(newIndex===newEntries.length-1){state.entries.push(newEntry);}else{state.entries.splice(newIndex,0,newEntry);}}else if(detail.operation==="delete"&&index>=0){state.entries.splice(index,1);}};onWillStart(()=>registry.addEventListener("UPDATE",listener));onWillDestroy(()=>registry.removeEventListener("UPDATE",listener));return state;}
return __exports;});;
/* /web/static/src/core/resizable_panel/resizable_panel.js */
odoo.define('@web/core/resizable_panel/resizable_panel',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component,onMounted,onWillUpdateProps,onWillUnmount,useEffect,useExternalListener,useRef,useComponent,}=require("@odoo/owl");function useResizable({containerRef,handleRef,initialWidth=400,getMinWidth=()=>400,onResize=()=>{},getResizeSide=()=>"end",}){containerRef=typeof containerRef=="string"?useRef(containerRef):containerRef;handleRef=typeof handleRef=="string"?useRef(handleRef):handleRef;const props=useComponent().props;let minWidth=getMinWidth(props);let resizeSide=getResizeSide(props);let isChangingSize=false;useExternalListener(document,"mouseup",()=>onMouseUp());useExternalListener(document,"mousemove",(ev)=>onMouseMove(ev));useExternalListener(window,"resize",()=>{const limit=getLimitWidth();if(getContainerRect().width>=limit){resize(computeFinalWidth(limit));}});let docDirection;useEffect((container)=>{if(container){docDirection=getComputedStyle(container).direction;}},()=>[containerRef.el]);onMounted(()=>{if(handleRef.el){resize(initialWidth);handleRef.el.addEventListener("mousedown",onMouseDown);}});onWillUpdateProps((nextProps)=>{minWidth=getMinWidth(nextProps);resizeSide=getResizeSide(nextProps);});onWillUnmount(()=>{if(handleRef.el){handleRef.el.removeEventListener("mousedown",onMouseDown);}});function onMouseDown(){isChangingSize=true;document.body.classList.add("pe-none","user-select-none");}
function onMouseUp(){isChangingSize=false;document.body.classList.remove("pe-none","user-select-none");}
function onMouseMove(ev){if(!isChangingSize||!containerRef.el){return;}
const direction=(docDirection==="ltr"&&resizeSide==="end")||(docDirection==="rtl"&&resizeSide==="start")?1:-1;const fixedSide=direction===1?"left":"right";const containerRect=getContainerRect();const newWidth=(ev.clientX-containerRect[fixedSide])*direction;resize(computeFinalWidth(newWidth));}
function computeFinalWidth(targetContainerWidth){const handlerSpacing=handleRef.el?handleRef.el.offsetWidth/2:10;const w=Math.max(minWidth,targetContainerWidth+handlerSpacing);const limit=getLimitWidth();return Math.min(w,limit-handlerSpacing);}
function getContainerRect(){const container=containerRef.el;const offsetParent=container.offsetParent;let containerRect={};if(!offsetParent){containerRect=container.getBoundingClientRect();}else{containerRect.left=container.offsetLeft;containerRect.right=container.offsetLeft+container.offsetWidth;containerRect.width=container.offsetWidth;}
return containerRect;}
function getLimitWidth(){const offsetParent=containerRef.el.offsetParent;return offsetParent?offsetParent.offsetWidth:window.innerWidth;}
function resize(width){containerRef.el.style.setProperty("width",`${width}px`);onResize(width);}}
const ResizablePanel=__exports.ResizablePanel=class ResizablePanel extends Component{static template="web_studio.ResizablePanel";static components={};static props={onResize:{type:Function,optional:true},initialWidth:{type:Number,optional:true},minWidth:{type:Number,optional:true},class:{type:String,optional:true},slots:{type:Object},handleSide:{validate:(val)=>["start","end"].includes(val),optional:true,},};static defaultProps={onResize:()=>{},width:400,minWidth:400,class:"",handleSide:"end",};setup(){useResizable({containerRef:"containerRef",handleRef:"handleRef",onResize:this.props.onResize,initialWidth:this.props.initialWidth,getMinWidth:(props)=>props.minWidth,getResizeSide:(props)=>props.handleSide,});}
get class(){const classes=this.props.class.split(" ");if(!classes.some((cls)=>cls.startsWith("position-"))){classes.push("position-relative");}
return classes.join(" ");}}
return __exports;});;
/* /web/static/src/core/select_menu/select_menu.js */
odoo.define('@web/core/select_menu/select_menu',['@odoo/owl','@web/core/dropdown/dropdown','@web/core/dropdown/dropdown_item','@web/core/dropdown/dropdown_hooks','@web/core/tags_list/tags_list','@web/core/utils/classname','@web/core/utils/hooks','@web/core/utils/scrolling','@web/core/utils/search','@web/core/utils/timing','@web/core/browser/feature_detection'],function(require){'use strict';let __exports={};const{Component,onWillUpdateProps,useEffect,useRef,useState}=require("@odoo/owl");const{Dropdown}=require("@web/core/dropdown/dropdown");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{useDropdownState}=require("@web/core/dropdown/dropdown_hooks");const{TagsList}=require("@web/core/tags_list/tags_list");const{mergeClasses}=require("@web/core/utils/classname");const{useChildRef}=require("@web/core/utils/hooks");const{scrollTo}=require("@web/core/utils/scrolling");const{fuzzyLookup}=require("@web/core/utils/search");const{useDebounced}=require("@web/core/utils/timing");const{hasTouch}=require("@web/core/browser/feature_detection");let selectMenuId=0;const DEBOUNCED_DELAY=__exports.DEBOUNCED_DELAY=250;const SelectMenu=__exports.SelectMenu=class SelectMenu extends Component{static template="web.SelectMenu";static choiceItemTemplate="web.SelectMenu.ChoiceItem";static components={Dropdown,DropdownItem,TagsList};static defaultProps={value:undefined,id:"",name:"",class:"",menuClass:"",togglerClass:"",multiSelect:false,onSelect:()=>{},onNavigated:()=>{},onOpened:()=>{},onClosed:()=>{},required:false,searchable:true,autoSort:true,searchPlaceholder:"",choices:[],groups:[],sections:[],disabled:false,};static props={choices:{optional:true,type:Array,element:{type:Object,shape:{value:true,label:{type:String},"*":true,},},},groups:{type:Array,optional:true,element:{type:Object,shape:{label:{type:String,optional:true},choices:{type:Array,element:{type:Object,shape:{value:true,label:{type:String},"*":true,},},},section:{type:String,optional:true,},},},},sections:{type:Array,optional:true,element:{label:{type:String},name:{type:String},},},id:{type:String,optional:true},name:{type:String,optional:true},class:{type:String,optional:true},menuClass:{type:String,optional:true},togglerClass:{type:String,optional:true},required:{type:Boolean,optional:true},searchable:{type:Boolean,optional:true},autoSort:{type:Boolean,optional:true},placeholder:{type:String,optional:true},searchPlaceholder:{type:String,optional:true},searchClass:{type:String,optional:true},value:{optional:true},multiSelect:{type:Boolean,optional:true},onInput:{type:Function,optional:true},onSelect:{type:Function,optional:true},onNavigated:{type:Function,optional:true},onOpened:{type:Function,optional:true},onClosed:{type:Function,optional:true},slots:{type:Object,optional:true},disabled:{type:Boolean,optional:true},menuRef:{type:Function,optional:true},};static SCROLL_SETTINGS={defaultCount:500,increaseAmount:300,distanceBeforeReload:500,};setup(){this.selectMenuId=selectMenuId++;this.state=useState({choices:[],displayedOptions:[],searchValue:null,isFocused:false,});this.inputRef=useRef("inputRef");this.menuRef=useChildRef();this.props.menuRef?.(this.menuRef);this.debouncedOnInput=useDebounced((ev)=>{if(!this.dropdownState.isOpen){this.dropdownState.open();}
const searchString=ev.target.value;this.state.searchValue=searchString;this.onInput(searchString);},DEBOUNCED_DELAY);this.dropdownState=useDropdownState();this.selectedChoice=this.getSelectedChoice(this.props);onWillUpdateProps((nextProps)=>{const choicesChanged=this.state.choices!==nextProps.choices;if(choicesChanged){this.state.choices=nextProps.choices;}
if(choicesChanged||this.props.value!==nextProps.value){this.selectedChoice=this.getSelectedChoice(nextProps);}});useEffect(()=>{if(this.dropdownState.isOpen){const groups=[{choices:this.props.choices},...this.props.groups];this.filterOptions(this.state.searchValue,groups);}},()=>[this.props.choices,this.props.groups]);this.navigationOptions={shouldFocusFirstItem:!hasTouch(),virtualFocus:this.props.searchable,hotkeys:{enter:{isAvailable:({navigator})=>navigator.items.length>0,callback:(navigator)=>{if(navigator.activeItem){return navigator.activeItem.select();}
if(document.activeElement.value){navigator.items[0].select();}},},},onItemActivated:(element)=>{const index=parseInt(element.dataset.choiceIndex);if(index>=0&&this.state.displayedOptions[index]){this.props.onNavigated(this.state.displayedOptions[index]);}else{this.props.onNavigated();}},};}
get displayValue(){return this.state.searchValue===null?this.selectedChoice?.label||"":this.state.searchValue;}
get displayInputInToggler(){return!this.props.slots||!this.props.slots.default;}
get displayInputInDropdown(){return(this.isBottomSheet||!this.displayInputInToggler)&&this.props.searchable;}
get isBottomSheet(){return this.env.isSmall&&hasTouch();}
get canDeselect(){return!this.props.required&&this.selectedChoice!==undefined;}
get multiSelectChoices(){return this.selectedChoice.map((c)=>({id:c.value,text:c.label,onDelete:()=>{const values=[...this.props.value];values.splice(values.indexOf(c.value),1);this.props.onSelect(values);},}));}
get menuClass(){return mergeClasses({"my-0":this.displayInputInToggler,o_select_menu_menu:true,o_select_menu_multi_select:this.props.multiSelect,},this.props.menuClass);}
get placeholderValue(){if(this.state.isFocused&&this.props.searchPlaceholder){return this.props.searchPlaceholder;}
return this.props.placeholder;}
async onBeforeOpen(){this.onInput("");}
onInputFocus(ev){if(!this.props.searchable){return ev.target.blur();}
if(ev.target.classList.contains("o_select_menu_input")){this.state.isFocused=true;ev.target.select();}}
onInputBlur(ev){this.state.isFocused=false;if(ev.target.value===""&&this.canDeselect&&!this.props.multiSelect){this.onInputClear();}}
onInputClick(ev){if(!ev.target.classList.contains("o_select_menu_toggler")){ev.stopPropagation();}}
onInputClear(){this.props.onSelect(null);this.dropdownState.close();}
onStateChanged(open){if(open){if(this.isBottomSheet){document.activeElement.blur();}
if(this.displayInputInDropdown&&!this.isBottomSheet){this.inputRef.el.focus();}
this.menuRef.el?.addEventListener("scroll",(ev)=>this.onScroll(ev));const selectedElement=this.menuRef.el?.querySelectorAll(".selected")[0];if(selectedElement){scrollTo(selectedElement);}
this.props.onOpened();}else{this.state.searchValue=null;this.props.onClosed();}}
isOptionSelected(choice){if(this.props.multiSelect){return this.props.value.includes(choice.value);}
return this.props.value===choice.value;}
getItemClass(choice){if(this.isOptionSelected(choice)){return"o_select_menu_item fw-bolder selected";}else{return"o_select_menu_item";}}
async onInput(searchString){this.filterOptions(searchString);if(this.props.onInput){await this.props.onInput(searchString);}}
getSelectedChoice(props){const choices=[...props.choices,...props.groups.flatMap((g)=>g.choices||[])];if(!this.props.multiSelect){return choices.find((c)=>c.value===props.value);}
const valueSet=new Set(props.value);return[...(this.selectedChoice||[]),...choices].filter((c,index,self)=>valueSet.has(c.value)&&self.findIndex((t)=>t.value===c.value)===index);}
onItemSelected(value){if(this.props.multiSelect){const values=[...this.props.value];const valueIndex=values.indexOf(value);if(valueIndex!==-1){values.splice(valueIndex,1);this.props.onSelect(values);}else{this.props.onSelect([...this.props.value,value]);}}else if(!this.selectedChoice||this.selectedChoice.value!==value){this.props.onSelect(value);if(this.inputRef.el){this.inputRef.el.value=this.state.choices.find((c)=>c.value===value).label;}}
this.state.searchValue=null;}
filterOptions(searchString="",groups){const groupsList=groups||[{choices:this.props.choices,section:""},...this.props.groups,];const _choices=[];const _sections=new Set();groupsList.sort((a,b)=>(a.section||"").localeCompare(b.section||""));for(const group of groupsList){let filteredOptions=group.choices||[];if(searchString){filteredOptions=fuzzyLookup(searchString.trim(),filteredOptions,(choice)=>choice.label);}else{if(this.props.autoSort){filteredOptions.sort((optionA,optionB)=>optionA.label.localeCompare(optionB.label));}}
if(filteredOptions.length===0){continue;}
if(group.section){const section=this.props.sections.find((e)=>e.name===group.section);if(!_sections.has(section)){_sections.add(section);_choices.push({...section,isGroup:true});}}
if(group.label){_choices.push({...group,isGroup:true});}
_choices.push(...filteredOptions);}
this.state.choices=_choices;this.sliceDisplayedOptions();}
onScroll(event){const el=event.target;const hasReachMax=this.state.displayedOptions.length>=this.state.choices.length;const remainingDistance=el.scrollHeight-el.scrollTop;const distanceToReload=el.clientHeight+this.constructor.SCROLL_SETTINGS.distanceBeforeReload;if(!hasReachMax&&remainingDistance<distanceToReload){const displayCount=this.state.displayedOptions.length+
this.constructor.SCROLL_SETTINGS.increaseAmount;this.state.displayedOptions=this.state.choices.slice(0,displayCount);}}
sliceDisplayedOptions(){const selectedIndex=this.getSelectedOptionIndex();const defaultCount=this.constructor.SCROLL_SETTINGS.defaultCount;if(selectedIndex===-1){this.state.displayedOptions=this.state.choices.slice(0,defaultCount);}else{const endIndex=Math.max(selectedIndex+this.constructor.SCROLL_SETTINGS.increaseAmount,defaultCount);this.state.displayedOptions=this.state.choices.slice(0,endIndex);}}
getSelectedOptionIndex(){let selectedIndex=-1;for(let i=0;i<this.state.choices.length;i++){if(this.isOptionSelected(this.state.choices[i])){selectedIndex=i;}}
return selectedIndex;}}
return __exports;});;
/* /web/static/src/core/signature/name_and_signature.js */
odoo.define('@web/core/signature/name_and_signature',['@web/core/assets','@web/core/browser/feature_detection','@web/core/dropdown/dropdown','@web/core/dropdown/dropdown_item','@web/core/network/rpc','@web/core/utils/hooks','@web/core/utils/render','@web/core/utils/urls','@odoo/owl'],function(require){'use strict';let __exports={};const{loadJS}=require("@web/core/assets");const{isMobileOS}=require("@web/core/browser/feature_detection");const{Dropdown}=require("@web/core/dropdown/dropdown");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{rpc}=require("@web/core/network/rpc");const{useAutofocus}=require("@web/core/utils/hooks");const{renderToString}=require("@web/core/utils/render");const{getDataURLFromFile}=require("@web/core/utils/urls");const{Component,useState,onWillStart,useRef,useEffect}=require("@odoo/owl");let htmlId=0;const NameAndSignature=__exports.NameAndSignature=class NameAndSignature extends Component{static template="web.NameAndSignature";static components={Dropdown,DropdownItem};static props={signature:{type:Object},defaultFont:{type:String,optional:true},displaySignatureRatio:{type:Number,optional:true},fontColor:{type:String,optional:true},signatureType:{type:String,optional:true},noInputName:{type:Boolean,optional:true},mode:{type:String,optional:true},onSignatureChange:{type:Function,optional:true},};static defaultProps={defaultFont:"",displaySignatureRatio:3.0,fontColor:"DarkBlue",signatureType:"signature",noInputName:false,onSignatureChange:()=>{},};setup(){this.htmlId=htmlId++;this.defaultName=this.props.signature.name||"";this.currentFont=0;this.drawTimeout=null;this.state=useState({signMode:this.props.mode||(this.props.noInputName&&!this.defaultName?"draw":"auto"),showSignatureArea:!!(this.props.noInputName||this.defaultName),showFontList:false,});this.signNameInputRef=useRef("signNameInput");this.signInputLoad=useRef("signInputLoad");useAutofocus({refName:"signNameInput"});useEffect((el)=>{if(el){el.click();}},()=>[this.signInputLoad.el]);onWillStart(async()=>{this.fonts=await rpc(`/web/sign/get_fonts/${this.props.defaultFont}`);});onWillStart(async()=>{await loadJS("/web/static/lib/signature_pad/signature_pad.umd.js");});this.signatureRef=useRef("signature");useEffect((el)=>{if(el){this.signaturePad=new SignaturePad(el,{penColor:this.props.fontColor,backgroundColor:"rgba(255,255,255,0)",minWidth:2,maxWidth:2,});this.signaturePad.addEventListener("endStroke",()=>{this.props.signature.isSignatureEmpty=this.isSignatureEmpty;this.props.onSignatureChange(this.state.signMode);});this.resetSignature();this.props.signature.getSignatureImage=()=>this.signaturePad.toDataURL();this.props.signature.resetSignature=()=>this.resetSignature();if(this.state.signMode==="auto"){this.drawCurrentName();}
if(this.props.signature.signatureImage){this.clear();this.fromDataURL(this.props.signature.signatureImage);}}},()=>[this.signatureRef.el]);}
async drawCurrentName(){const font=this.fonts[this.currentFont];const text=this.getCleanedName();if(text.trim()===""){this.clear();return;}
const canvas=this.signatureRef.el;const img=this.getSVGText(font,text,canvas.width,canvas.height);await this.printImage(img);}
focusName(){if(!isMobileOS()&&this.signNameInputRef.el){this.signNameInputRef.el.focus();}}
clear(){this.signaturePad.clear();this.props.signature.isSignatureEmpty=this.isSignatureEmpty;}
async fromDataURL(){await this.signaturePad.fromDataURL(...arguments);this.props.signature.isSignatureEmpty=this.isSignatureEmpty;this.props.onSignatureChange(this.state.signMode);}
getCleanedName(){const text=this.props.signature.name.replace(/ /g," ");if(this.props.signatureType==="initial"&&text){return(text.split(" ").map(function(w){return w[0];}).join(".")+".");}
return text;}
getSVGText(font,text,width,height){const svg=renderToString("web.sign_svg_text",{width:width,height:height,font:font,text:text,type:this.props.signatureType,color:this.props.fontColor,});return"data:image/svg+xml,"+encodeURI(svg);}
getSVGTextFont(font){const height=100;const width=parseInt(height*this.props.displaySignatureRatio);return this.getSVGText(font,this.getCleanedName(),width,height);}
uploadFile(){this.signInputLoad.el?.click();}
async onChangeSignLoadInput(ev){var file=ev.target.files[0];if(file===undefined){return false;}
if(file.type.substr(0,5)!=="image"){this.clear();this.state.loadIsInvalid=true;return false;}
this.state.loadIsInvalid=false;const result=await getDataURLFromFile(file);await this.printImage(result);}
onClickSignAutoSelectStyle(){this.state.showFontList=true;}
onClickSignDrawClear(){this.clear();this.props.onSignatureChange(this.state.signMode);}
onClickSignLoad(){this.setMode("load");}
onClickSignAuto(){this.setMode("auto");}
onInputSignName(ev){this.props.signature.name=ev.target.value;if(!this.state.showSignatureArea&&this.getCleanedName()){this.state.showSignatureArea=true;return;}
if(this.state.signMode==="auto"){this.drawCurrentName();}}
onSelectFont(index){this.currentFont=index;this.drawCurrentName();}
async printImage(imgSrc){this.clear();const c=this.signaturePad.canvas;const img=new Image();img.onload=()=>{const ctx=c.getContext("2d");var ratio=((img.width/img.height)>(c.width/c.height))?c.width/img.width:c.height/img.height;ctx.drawImage(img,(c.width/2)-(img.width*ratio/2),(c.height/2)-(img.height*ratio/2),img.width*ratio,img.height*ratio);this.props.signature.isSignatureEmpty=this.isSignatureEmpty;this.props.onSignatureChange(this.state.signMode);};img.src=imgSrc;this.signaturePad._isEmpty=false;}
resetSignature(){this.resizeSignature();this.clear();this.setMode(this.state.signMode,true);this.focusName();}
resizeSignature(){const width=this.signatureRef.el.clientWidth;const height=parseInt(width/this.props.displaySignatureRatio);Object.assign(this.signatureRef.el,{width,height});}
setMode(mode,reset){if(reset!==true&&mode===this.signMode){return;}
this.state.signMode=mode;this.signaturePad[this.state.signMode==="draw"?"on":"off"]();this.clear();if(this.state.signMode==="auto"){this.drawCurrentName();}
this.props.onSignatureChange(this.state.signMode);}
get isSignatureEmpty(){return this.signaturePad.isEmpty();}
get loadIsInvalid(){return this.state.signMode==="load"&&this.state.loadIsInvalid;}}
return __exports;});;
/* /web/static/src/core/signature/signature_dialog.js */
odoo.define('@web/core/signature/signature_dialog',['@web/core/dialog/dialog','@web/core/signature/name_and_signature','@odoo/owl'],function(require){'use strict';let __exports={};const{Dialog}=require("@web/core/dialog/dialog");const{NameAndSignature}=require("@web/core/signature/name_and_signature");const{Component,useState}=require("@odoo/owl");const SignatureDialog=__exports.SignatureDialog=class SignatureDialog extends Component{static template="web.SignatureDialog";static components={Dialog,NameAndSignature};static props={defaultName:{type:String,optional:true},nameAndSignatureProps:Object,uploadSignature:Function,close:Function,};static defaultProps={defaultName:"",};setup(){this.signature=useState({name:this.props.defaultName,isSignatureEmpty:true,});}
onClickConfirm(){this.props.uploadSignature({name:this.signature.name,signatureImage:this.signature.getSignatureImage(),});this.props.close();}
get nameAndSignatureProps(){return{...this.props.nameAndSignatureProps,signature:this.signature,};}}
return __exports;});;
/* /web/static/src/core/tags_list/tags_list.js */
odoo.define('@web/core/tags_list/tags_list',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const TagsList=__exports.TagsList=class TagsList extends Component{static template="web.TagsList";static defaultProps={displayText:true,};static props={displayText:{type:Boolean,optional:true},visibleItemsLimit:{type:Number,optional:true},tags:{type:Array,element:Object},};get visibleTagsCount(){return this.props.visibleItemsLimit-1;}
get visibleTags(){if(this.props.visibleItemsLimit&&this.props.tags.length>this.props.visibleItemsLimit){return this.props.tags.slice(0,this.visibleTagsCount);}
return this.props.tags;}
get otherTags(){if(this.props.visibleItemsLimit&&this.props.tags.length>this.props.visibleItemsLimit){return this.props.tags.slice(this.visibleTagsCount);}
return[];}
get tooltipInfo(){return JSON.stringify({tags:this.otherTags.map((tag)=>({text:tag.text,id:tag.id,})),});}}
return __exports;});;
/* /web/static/src/core/template_inheritance.js */
odoo.define('@web/core/template_inheritance',[],function(require){'use strict';let __exports={};const RSTRIP_REGEXP=/(?=\n[ \t]*$)/;let translationContext=null;const TCTX="t-translation-context";function getTranslationContext(node){if(node.hasAttribute(TCTX)){return node.getAttribute(TCTX);}
return getTranslationContext(node.parentElement);}
const contextByTextNode=new Map();function setTranslationContext(node){switch(node.nodeType){case Node.TEXT_NODE:if(node.nodeValue.trim()!=""){contextByTextNode.set(node,translationContext);}
break;case Node.ELEMENT_NODE:node.setAttribute(TCTX,translationContext);break;}}
__exports.applyContextToTextNode=applyContextToTextNode;function applyContextToTextNode(){for(const[textNode,context]of contextByTextNode){const wrapper=document.createElement("t");wrapper.setAttribute(TCTX,context);textNode.before(wrapper);wrapper.appendChild(textNode);}
contextByTextNode.clear();}
__exports.deepClone=deepClone;function deepClone(node){const clone=node.cloneNode();if(node.nodeType===Node.TEXT_NODE){if(contextByTextNode.has(node)){contextByTextNode.set(clone,contextByTextNode.get(node));}}
if(node.childNodes?.length){for(const childNode of[...node.childNodes]){clone.append(deepClone(childNode));}}
return clone;}
function addBefore(target,operation){const nodes=getNodes(target,operation);if(nodes.length===0){return;}
const{previousSibling}=target;target.before(...nodes);if(previousSibling?.nodeType===Node.TEXT_NODE){const[text1,text2]=previousSibling.data.split(RSTRIP_REGEXP);previousSibling.data=text1.trimEnd();if(text2&&nodes.some((n)=>n.nodeType!==Node.TEXT_NODE)){const textNode=document.createTextNode(text2);target.before(textNode);if(textNode.previousSibling.nodeType===Node.TEXT_NODE){textNode.previousSibling.data=textNode.previousSibling.data.trimEnd();}}}}
function getRoot(element){while(element.parentElement){element=element.parentElement;}
return element;}
const HASCLASS_REGEXP=/hasclass\(([^)]*)\)/g;const CLASS_CONTAINS_REGEX=/contains\(@class.*\)/g;function getXpath(operation){const xpath=operation.getAttribute("expr");if(odoo.debug){if(CLASS_CONTAINS_REGEX.test(xpath)){const parent=operation.closest("t[t-inherit]");const templateName=parent.getAttribute("t-name")||parent.getAttribute("t-inherit");console.warn(`Error-prone use of @class in template "${templateName}" (or one of its inheritors).`+" Use the hasclass(*classes) function to filter elements by their classes");}}
return xpath.replaceAll(HASCLASS_REGEXP,(_,capturedGroup)=>capturedGroup.split(",").map((c)=>`contains(concat(' ', @class, ' '), ' ${c.trim().slice(1, -1)} ')`).join(" and "));}
function getNode(element,operation){const root=getRoot(element);const doc=new Document();doc.appendChild(root);if(operation.tagName==="xpath"){const xpath=getXpath(operation);const result=doc.evaluate(xpath,root,null,XPathResult.FIRST_ORDERED_NODE_TYPE);return result.singleNodeValue;}
const attributes=[...operation.attributes].filter((attr)=>!attr.name.startsWith(TCTX));for(const elem of root.querySelectorAll(operation.tagName)){if(attributes.every(({name,value})=>name==="position"||elem.getAttribute(name)===value)){return elem;}}
return null;}
function getElement(element,operation){const node=getNode(element,operation);if(!node){throw new Error(`Element '${operation.outerHTML}' cannot be located in element tree`);}
if(!(node instanceof Element)){throw new Error(`Found node ${node} instead of an element`);}
return node;}
function getNodes(element,operation){const nodes=[];for(const childNode of operation.childNodes){if(childNode.tagName==="xpath"&&childNode.getAttribute?.("position")==="move"){const node=getElement(element,childNode);node.setAttribute(TCTX,getTranslationContext(node));removeNode(node);nodes.push(node);}else{setTranslationContext(childNode);nodes.push(childNode);}}
return nodes;}
function splitAndTrim(str,separator){return str.split(separator).map((s)=>s.trim());}
function modifyAttributes(target,operation){for(const child of operation.children){if(child.tagName!=="attribute"){continue;}
const attributeName=child.getAttribute("name");const firstNode=child.childNodes[0];let value=firstNode?.nodeType===Node.TEXT_NODE?firstNode.data:"";const add=child.getAttribute("add")||"";const remove=child.getAttribute("remove")||"";if(add||remove){if(firstNode?.nodeType===Node.TEXT_NODE){throw new Error(`Useless element content ${firstNode.outerHTML}`);}
const separator=child.getAttribute("separator")||",";const toRemove=new Set(splitAndTrim(remove,separator));const values=splitAndTrim(target.getAttribute(attributeName)||"",separator).filter((s)=>!toRemove.has(s));values.push(...splitAndTrim(add,separator).filter((s)=>s));value=values.join(separator);}
if(value){target.setAttribute(attributeName,value);if(!(add||remove)){target.setAttribute(`t-translation-context-${attributeName}`,translationContext);}}else{target.removeAttribute(attributeName);}}}
function removeNode(node){const{nextSibling,previousSibling}=node;node.remove();if(nextSibling?.nodeType===Node.TEXT_NODE&&previousSibling?.nodeType===Node.TEXT_NODE&&previousSibling.parentElement.firstChild===previousSibling){previousSibling.data=previousSibling.data.trimEnd();}}
function replace(root,target,operation){const mode=operation.getAttribute("mode")||"outer";switch(mode){case"outer":{const result=operation.ownerDocument.evaluate(".//*[text()='$0']",operation,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);target.setAttribute(TCTX,getTranslationContext(target));for(let i=0;i<result.snapshotLength;i++){const loc=result.snapshotItem(i);loc.firstChild.replaceWith(deepClone(target));}
if(target.parentElement){const nodes=getNodes(target,operation);target.replaceWith(...nodes);}else{let operationContent=null;let comment=null;for(const child of operation.childNodes){if(child.nodeType===Node.ELEMENT_NODE){setTranslationContext(child);operationContent=child;break;}
if(child.nodeType===Node.COMMENT_NODE){comment=child;}}
root=deepClone(operationContent);if(target.hasAttribute("t-name")){root.setAttribute("t-name",target.getAttribute("t-name"));}
if(comment){root.prepend(comment);}}
break;}
case"inner":while(target.firstChild){target.removeChild(target.lastChild);}
for(const node of[...operation.childNodes]){setTranslationContext(node);target.append(node);}
break;default:throw new Error(`Invalid mode attribute: '${mode}'`);}
return root;}
__exports.applyInheritance=applyInheritance;function applyInheritance(root,operations,url=""){translationContext=url.split("/")[1]??"";for(const operation of operations.children){const target=getElement(root,operation);const position=operation.getAttribute("position")||"inside";if(odoo.debug&&url){const attributes=[...operation.attributes].map(({name,value})=>`${name}=${JSON.stringify(name === "position" ? position : value)}`);const comment=document.createComment(` From file: ${url} ; ${attributes.join(" ; ")} `);if(position==="attributes"){target.before(comment);}else{operation.prepend(comment);}}
switch(position){case"replace":{root=replace(root,target,operation);break;}
case"attributes":{modifyAttributes(target,operation);break;}
case"inside":{const sentinel=document.createElement("sentinel");target.append(sentinel);addBefore(sentinel,operation);removeNode(sentinel);break;}
case"after":{const sentinel=document.createElement("sentinel");target.after(sentinel);addBefore(sentinel,operation);removeNode(sentinel);break;}
case"before":{addBefore(target,operation);break;}
default:throw new Error(`Invalid position attribute: '${position}'`);}}
translationContext=null;return root;}
return __exports;});;
/* /web/static/src/core/templates.js */
odoo.define('@web/core/templates',['@web/core/template_inheritance'],function(require){'use strict';let __exports={};const{applyContextToTextNode,applyInheritance,deepClone,}=require("@web/core/template_inheritance");function getClone(template){const c=deepClone(template);new Document().append(c);return c;}
function getKey(args){return JSON.stringify([...args]);}
function getParsedTemplate(templateString){const doc=parser.parseFromString(templateString,"text/xml");for(const processor of templateProcessors){processor(doc);}
return doc.firstChild;}
function _getTemplate(name,blockId=null){if(!(name in parsedTemplates)){if(!(name in templates)){return null;}
const templateString=templates[name];parsedTemplates[name]=getParsedTemplate(templateString);const inheritFrom=parsedTemplates[name].getAttribute("t-inherit");if(!inheritFrom){const addon=info[name].url.split("/")[1];parsedTemplates[name].setAttribute("t-translation-context",addon);}}
let processedTemplate=parsedTemplates[name];const inheritFrom=processedTemplate.getAttribute("t-inherit");if(inheritFrom){const parentTemplate=_getTemplate(inheritFrom,blockId||info[name].blockId);if(!parentTemplate){throw new Error(`Constructing template ${name}: template parent ${inheritFrom} not found`);}
const element=getClone(processedTemplate);processedTemplate=applyInheritance(getClone(parentTemplate),element,info[name].url);if(processedTemplate.tagName!==element.tagName){const temp=processedTemplate;processedTemplate=new Document().createElement(element.tagName);processedTemplate.append(...temp.childNodes);}
for(const{name,value}of element.attributes){if(!["t-inherit","t-inherit-mode"].includes(name)){processedTemplate.setAttribute(name,value);}}}
let cloned=false;for(const otherBlockId in templateExtensions[name]||{}){if(blockId&&otherBlockId>blockId){break;}
if(!(name in parsedTemplateExtensions)){parsedTemplateExtensions[name]={};}
if(!(otherBlockId in parsedTemplateExtensions[name])){parsedTemplateExtensions[name][otherBlockId]=[];for(const{templateString,url}of templateExtensions[name][otherBlockId]){parsedTemplateExtensions[name][otherBlockId].push({template:getParsedTemplate(templateString),url,});}}
for(const{template,url}of parsedTemplateExtensions[name][otherBlockId]){if(!urlFilters.every((filter)=>filter(url))){continue;}
if(!inheritFrom&&!cloned){cloned=true;processedTemplate=getClone(processedTemplate);}
processedTemplate=applyInheritance(processedTemplate,getClone(template),url);}}
return processedTemplate;}
const info=Object.create(null);const parsedTemplateExtensions=Object.create(null);const parsedTemplates=Object.create(null);const parser=new DOMParser();const processedTemplates=new Map();const registered=new Set();const templateExtensions=Object.create(null);const templateProcessors=[];const templates=Object.create(null);let blockType=null;let blockId=0;let urlFilters=[];__exports.checkPrimaryTemplateParents=checkPrimaryTemplateParents;function checkPrimaryTemplateParents(namesToCheck){const missing=new Set(namesToCheck.filter((name)=>!(name in templates)));if(missing.size){console.error(`Missing (primary) parent templates: ${[...missing].join(", ")}`);}}
__exports.clearProcessedTemplates=clearProcessedTemplates;function clearProcessedTemplates(){processedTemplates.clear();}
__exports.getTemplate=getTemplate;function getTemplate(name){if(!processedTemplates.has(name)){processedTemplates.set(name,_getTemplate(name));applyContextToTextNode();}
return processedTemplates.get(name);}
__exports.registerTemplate=registerTemplate;function registerTemplate(name,url,templateString){const key=getKey(arguments);if(registered.has(key)){return;}
registered.add(key);if(blockType!=="templates"){blockType="templates";blockId++;}
if(name in templates&&(info[name].url!==url||templates[name]!==templateString)){throw new Error(`Template ${name} already exists`);}
templates[name]=templateString;info[name]={blockId,url};return function unregisterTemplate(){delete templates[name];delete info[name];delete parsedTemplates[name];delete parsedTemplateExtensions[name];processedTemplates.delete(name);registered.delete(key);};}
__exports.registerTemplateExtension=registerTemplateExtension;function registerTemplateExtension(inheritFrom,url,templateString){const key=getKey(arguments);if(registered.has(key)){return;}
registered.add(key);if(blockType!=="extensions"){blockType="extensions";blockId++;}
if(!templateExtensions[inheritFrom]){templateExtensions[inheritFrom]=[];}
if(!templateExtensions[inheritFrom][blockId]){templateExtensions[inheritFrom][blockId]=[];}
templateExtensions[inheritFrom][blockId].push({templateString,url,});return function unregisterTemplateExtension(){const index=templateExtensions[inheritFrom]?.[blockId]?.findIndex((ext)=>ext.templateString===templateString&&ext.url===url);if(Number.isInteger(index)&&index>-1){templateExtensions[inheritFrom][blockId].splice(index,1);}
registered.delete(key);};}
__exports.registerTemplateProcessor=registerTemplateProcessor;function registerTemplateProcessor(processor){templateProcessors.push(processor);}
__exports.setUrlFilters=setUrlFilters;function setUrlFilters(filters){const prev=urlFilters;urlFilters=filters;return function restoreUrlFilters(){urlFilters=prev;};}
return __exports;});;
/* /web/static/src/core/time_picker/time_picker.js */
odoo.define('@web/core/time_picker/time_picker',['@odoo/owl','@web/core/dropdown/dropdown','@web/core/dropdown/dropdown_hooks','@web/core/dropdown/dropdown_item','@web/core/hotkeys/hotkey_service','@web/core/l10n/time','@web/core/utils/classname','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,onWillUpdateProps,useRef,useState}=require("@odoo/owl");const{Dropdown}=require("@web/core/dropdown/dropdown");const{useDropdownState}=require("@web/core/dropdown/dropdown_hooks");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{getActiveHotkey}=require("@web/core/hotkeys/hotkey_service");const{Time,parseTime}=require("@web/core/l10n/time");const{mergeClasses}=require("@web/core/utils/classname");const{useChildRef}=require("@web/core/utils/hooks");const HOURS=[...Array(24)].map((_,i)=>i);const MINUTES=[...Array(60)].map((_,i)=>i);const TimePicker=__exports.TimePicker=class TimePicker extends Component{static template="web.TimePicker";static components={Dropdown,DropdownItem,};static props={cssClass:{type:[String,Array,Object],optional:true},inputCssClass:{type:[String,Array,Object],optional:true},value:{type:[String,Time,{value:false},{value:null}],optional:true},onChange:{type:Function,optional:true},onInvalid:{type:Function,optional:true},showSeconds:{type:Boolean,optional:true},minutesRounding:{type:Number,optional:true},placeholder:{type:String,optional:true},};static defaultProps={cssClass:{},inputCssClass:{},value:"00:00",onChange:()=>{},onInvalid:()=>{},showSeconds:false,minutesRounding:5,};setup(){this.inputRef=useRef("inputRef");this.menuRef=useChildRef();this.dropdownState=useDropdownState();this.state=useState({value:null,inputValue:"",isValid:true,});this.suggestions=[];this.isNavigating=false;this.navigationOptions=this.getNavigationOptions();this.onPropsUpdated(this.props);onWillUpdateProps((nextProps)=>this.onPropsUpdated(nextProps));}
get cssClass(){return mergeClasses(this.props.cssClass,{o_time_picker_seconds:this.props.showSeconds,});}
get inputCssClass(){return mergeClasses(this.props.inputCssClass,{o_invalid:!this.state.isValid,});}
getNavigationOptions(){const handleArrow=(navigator)=>{const value=this.suggestions[navigator.activeItemIndex];if(value){this.state.inputValue=value.toString(this.props.showSeconds);}};return{virtualFocus:true,onUpdated:(navigator)=>(this.navigator=navigator),hotkeys:{enter:{bypassEditableProtection:true,callback:(navigator)=>{if(!this.isNavigating){const value=parseTime(this.inputRef.el.value,this.props.showSeconds);if(value){this.setValue(value);this.close();}}else if(navigator.activeItem){navigator.activeItem.select();}},},tab:{bypassEditableProtection:true,callback:(navigator)=>{if(navigator.activeItemIndex>=0){this.setValue(this.suggestions[navigator.activeItemIndex]);this.close();}},},arrowdown:{callback:(navigator)=>{navigator.next();handleArrow(navigator);},},arrowup:{callback:(navigator)=>{navigator.previous();handleArrow(navigator);},},},};}
onPropsUpdated(props){if(this.suggestions.length===0){this.suggestions=this.getSuggestions(props);}
this.updateStateValue(Time.from(props.value));}
getSuggestions(props){const suggestions=[];const rounding=props.minutesRounding<=5?15:props.minutesRounding;const minutes=MINUTES.filter((m)=>!(m%rounding));for(const hour of HOURS){for(const minute of minutes){suggestions.push(new Time({hour,minute}));}}
return suggestions;}
setValue(newValue,cleanValue=true){if(newValue&&cleanValue){if(this.props.minutesRounding>1){newValue.roundMinutes(this.props.minutesRounding);}
if(!this.props.showSeconds&&this.state.value){newValue.second=this.state.value.second;}}
const lastValue=this.lastValue;this.updateStateValue(newValue);if(newValue&&!newValue.equals(lastValue,this.props.showSeconds)){this.props.onChange(newValue.copy());}}
updateStateValue(newValue){if(newValue===this.lastValue||newValue?.equals(this.lastValue,this.props.showSeconds)){return;}
this.lastValue=newValue?.copy()??newValue;this.state.value=newValue;this.state.inputValue=newValue?newValue.toString(this.props.showSeconds):"";this.state.isValid=true;}
onItemSelected(value){this.setValue(value);this.close();}
onInput(event){this.ensureOpen();const value=parseTime(this.inputRef.el.value,this.props.showSeconds);this.state.isValid=value!==null;if(!this.navigator){return;}
let index=-1;if(this.state.isValid){index=this.suggestions.findIndex((s)=>s.equals(value));}
if(index===-1){this.navigator.activeItem?.setInactive();}else{this.navigator.items[index]?.setActive();}}
onChange(){const value=parseTime(this.inputRef.el.value,this.props.showSeconds);this.state.isValid=value!==null;if(this.state.isValid){this.setValue(value);this.close();}else{this.props.onInvalid();}}
onKeydown(event){this.isNavigating=["arrowup","arrowdown"].includes(getActiveHotkey(event));}
ensureOpen(){if(!this.dropdownState.isOpen){this.isNavigating=false;this.dropdownState.open();this.inputRef.el.select();}}
close(){this.dropdownState.close();}
getPlaceholder(){if(typeof this.props.placeholder==="string"){return this.props.placeholder;}
const seconds=this.props.showSeconds?":ss":"";return`hh:mm${seconds}`;}
onDropdownOpened(){if(this.navigator){const index=this.state.value?this.suggestions.findIndex((s)=>s.equals(this.state.value,this.props.showSeconds)):0;this.navigator.items[index]?.setActive();}}}
return __exports;});;
/* /web/static/src/core/tooltip/tooltip.js */
odoo.define('@web/core/tooltip/tooltip',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const Tooltip=__exports.Tooltip=class Tooltip extends Component{static template="web.Tooltip";static props={close:Function,tooltip:{type:String,optional:true},template:{type:String,optional:true},info:{optional:true},};}
return __exports;});;
/* /web/static/src/core/tooltip/tooltip_hook.js */
odoo.define('@web/core/tooltip/tooltip_hook',['@web/core/utils/hooks','@odoo/owl'],function(require){'use strict';let __exports={};const{useService}=require("@web/core/utils/hooks");const{useEffect,useRef}=require("@odoo/owl");__exports.useTooltip=useTooltip;function useTooltip(refName,params){const tooltip=useService("tooltip");const ref=useRef(refName);useEffect((el)=>tooltip.add(el,params),()=>[ref.el]);}
return __exports;});;
/* /web/static/src/core/tooltip/tooltip_service.js */
odoo.define('@web/core/tooltip/tooltip_service',['@web/core/browser/browser','@web/core/registry','@web/core/tooltip/tooltip','@web/core/browser/feature_detection','@odoo/owl'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{Tooltip}=require("@web/core/tooltip/tooltip");const{hasTouch}=require("@web/core/browser/feature_detection");const{whenReady}=require("@odoo/owl");const OPEN_DELAY=__exports.OPEN_DELAY=400;const CLOSE_DELAY=__exports.CLOSE_DELAY=200;const SHOW_AFTER_DELAY=__exports.SHOW_AFTER_DELAY=250;const tooltipService=__exports.tooltipService={dependencies:["popover"],start(env,{popover}){let openTooltipTimeout;let closeTooltip;let showTimer;let target=null;const elementsWithTooltips=new WeakMap();function isHelpNode(el){return(el.textContent==="?"&&(el.hasAttribute("data-tooltip")||el.hasAttribute("data-tooltip-template")));}
function cleanup(){target=null;browser.clearTimeout(openTooltipTimeout);openTooltipTimeout=null;if(closeTooltip){closeTooltip();closeTooltip=null;}}
function shouldCleanup(){if(!target){return false;}
if(!document.body.contains(target)){return true;}
return false;}
function openTooltip(el,{tooltip="",template,info,position,delay=OPEN_DELAY}){cleanup();if(!tooltip&&!template){return;}
target=el;target.title="";const timeoutDelay=isHelpNode(el)?0:delay;openTooltipTimeout=browser.setTimeout(()=>{if(target.isConnected){closeTooltip=popover.add(target,Tooltip,{tooltip,template,info},{position});}},timeoutDelay);}
function openElementsTooltip(el){if(el.nodeType===Node.TEXT_NODE){return;}
const element=el.closest("[data-tooltip], [data-tooltip-template]");if(element&&element===target){return;}
if(elementsWithTooltips.has(el)){openTooltip(el,elementsWithTooltips.get(el));}else if(element){const dataset=element.dataset;const params={tooltip:dataset.tooltip,template:dataset.tooltipTemplate,position:dataset.tooltipPosition,};if(dataset.tooltipInfo){params.info=JSON.parse(dataset.tooltipInfo);}
if(dataset.tooltipDelay){params.delay=parseInt(dataset.tooltipDelay,10);}
openTooltip(element,params);}}
function onMouseenter(ev){openElementsTooltip(ev.target);}
function onClick(ev){if(isHelpNode(ev.target)){ev.preventDefault();}
cleanupTooltip(ev);}
function cleanupTooltip(ev){if(target==ev.target){cleanup();}}
function onTouchStart(ev){cleanup();const timeoutDelay=isHelpNode(ev.target)?0:SHOW_AFTER_DELAY;showTimer=browser.setTimeout(()=>{openElementsTooltip(ev.target);},timeoutDelay);}
whenReady(()=>{browser.setInterval(()=>{if(shouldCleanup()){cleanup();}},CLOSE_DELAY);if(hasTouch()){document.body.addEventListener("touchstart",onTouchStart);document.body.addEventListener("touchend",(ev)=>{if(isHelpNode(ev.target)){ev.preventDefault();return;}
if(ev.target.closest("[data-tooltip], [data-tooltip-template]")){if(!ev.target.dataset.tooltipTouchTapToShow){browser.clearTimeout(showTimer);browser.clearTimeout(openTooltipTimeout);}}});document.body.addEventListener("touchcancel",(ev)=>{if(isHelpNode(ev.target)){ev.preventDefault();return;}
if(ev.target.closest("[data-tooltip], [data-tooltip-template]")){if(!ev.target.dataset.tooltipTouchTapToShow){browser.clearTimeout(showTimer);browser.clearTimeout(openTooltipTimeout);}}});}
document.body.addEventListener("mouseenter",onMouseenter,{capture:true});document.body.addEventListener("mouseleave",cleanupTooltip,{capture:true});document.body.addEventListener("click",onClick,{capture:true});});return{add(el,params){elementsWithTooltips.set(el,params);return()=>{elementsWithTooltips.delete(el);if(target===el){cleanup();}};},};},};registry.category("services").add("tooltip",tooltipService);return __exports;});;
/* /web/static/src/core/transition.js */
odoo.define('@web/core/transition',['@web/core/browser/browser','@odoo/owl'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{Component,onWillUpdateProps,status,useComponent,useEffect,useState,xml,}=require("@odoo/owl");const config=__exports.config={disabled:false,};__exports.useTransition=useTransition;function useTransition({name,initialVisibility=true,immediate=false,leaveDuration=500,onLeave=()=>{},}){const component=useComponent();const state=useState({shouldMount:initialVisibility,stage:initialVisibility?"enter":"leave",});if(config.disabled){return{get shouldMount(){return state.shouldMount;},set shouldMount(val){state.shouldMount=val;},get className(){return`${name} ${name}-enter-active`;},get stage(){return"enter-active";},};}
let onNextPatch=null;useEffect(()=>{if(onNextPatch){onNextPatch();onNextPatch=null;}});let prevState,timer;const transition={get shouldMount(){return state.shouldMount;},set shouldMount(newState){if(newState===prevState){return;}
browser.clearTimeout(timer);prevState=newState;if(newState){if(status(component)==="mounted"||immediate){state.stage="enter";component.render();onNextPatch=()=>{state.stage="enter-active";};}else{state.stage="enter-active";}
state.shouldMount=true;}else{state.stage="leave";timer=browser.setTimeout(()=>{state.shouldMount=false;onLeave();},leaveDuration);}},get className(){return`${name} ${name}-${state.stage}`;},get stage(){return state.stage;},};transition.shouldMount=initialVisibility;return transition;}
const Transition=__exports.Transition=class Transition extends Component{static template=xml`<t t-slot="default" t-if="transition.shouldMount" className="transition.className"/>`;static props={name:String,visible:{type:Boolean,optional:true},immediate:{type:Boolean,optional:true},leaveDuration:{type:Number,optional:true},onLeave:{type:Function,optional:true},slots:Object,};setup(){const{immediate,visible,leaveDuration,name,onLeave}=this.props;this.transition=useTransition({initialVisibility:visible,immediate,leaveDuration,name,onLeave,});onWillUpdateProps(({visible=true})=>{this.transition.shouldMount=visible;});}}
return __exports;});;
/* /web/static/src/core/tree_editor/ast_utils.js */
odoo.define('@web/core/tree_editor/ast_utils',['@web/core/tree_editor/operators'],function(require){'use strict';let __exports={};const{COMPARATORS,TERM_OPERATORS_NEGATION_EXTENDED}=require("@web/core/tree_editor/operators");__exports.isBool=isBool;function isBool(ast){return ast.type===8&&ast.fn.type===5&&ast.fn.value==="bool"&&ast.args.length===1;}
__exports.isNot=isNot;function isNot(ast){return ast.type===6&&ast.op==="not";}
__exports.not=not;function not(ast){if(isNot(ast)){return ast.right;}
if(ast.type===2){return{...ast,value:!ast.value};}
if(ast.type===7&&COMPARATORS.includes(ast.op)){return{...ast,op:TERM_OPERATORS_NEGATION_EXTENDED[ast.op]};}
return{type:6,op:"not",right:isBool(ast)?ast.args[0]:ast};}
__exports.isValidPath=isValidPath;function isValidPath(ast,options){const getFieldDef=options.getFieldDef||(()=>null);if(ast.type===5){return getFieldDef(ast.value)!==null;}
return false;}
return __exports;});;
/* /web/static/src/core/tree_editor/condition_tree.js */
odoo.define('@web/core/tree_editor/condition_tree',['@web/core/domain','@web/core/py_js/py','@web/core/py_js/py_utils'],function(require){'use strict';let __exports={};const{Domain}=require("@web/core/domain");const{formatAST,parseExpr}=require("@web/core/py_js/py");const{toPyValue}=require("@web/core/py_js/py_utils");const Expression=__exports.Expression=class Expression{constructor(ast){if(typeof ast==="string"){ast=parseExpr(ast);}
this._ast=ast;this._expr=formatAST(ast);}
toAST(){return this._ast;}
toString(){return this._expr;}}
__exports.expression=expression;function expression(expr){return new Expression(expr);}
__exports.connector=connector;function connector(value,children=[],negate=false){return{type:"connector",value,children,negate};}
__exports.complexCondition=complexCondition;function complexCondition(value){parseExpr(value);return{type:"complex_condition",value};}
__exports.condition=condition;function condition(path,operator,value,negate=false,isProperty=false){return{type:"condition",path,operator,value,negate,isProperty};}
const TRUE_TREE=__exports.TRUE_TREE=condition(1,"=",1);const FALSE_TREE=__exports.FALSE_TREE=condition(0,"=",1);function cloneValue(value){if(value instanceof Expression){return new Expression(value.toAST());}
if(Array.isArray(value)){return value.map(cloneValue);}
return value;}
__exports.cloneTree=cloneTree;function cloneTree(tree){const clone={};for(const key in tree){clone[key]=cloneValue(tree[key]);}
return clone;}
const areEqualValues=(value,otherValue)=>formatValue(value)===formatValue(otherValue);const areEqualArraysOfTrees=(array,otherArray)=>{if(array.length!==otherArray.length){return false;}
for(let i=0;i<array.length;i++){const elem=array[i];const otherElem=otherArray[i];if(!areEqualTrees(elem,otherElem)){return false;}}
return true;};const areEqualTrees=__exports.areEqualTrees=(tree,otherTree)=>{if(tree.type!==otherTree.type){return false;}
if(tree.negate!==otherTree.negate){return false;}
if(tree.type==="condition"){if(!areEqualValues(tree.path,otherTree.path)){return false;}
if(!areEqualValues(tree.operator,otherTree.operator)){return false;}
if(isTree(tree.value)){if(isTree(otherTree.value)){return areEqualTrees(tree.value,otherTree.value);}
return false;}else if(isTree(otherTree.value)){return false;}
if(!areEqualValues(tree.value,otherTree.value)){return false;}
return true;}
if(!areEqualValues(tree.value,otherTree.value)){return false;}
if(tree.type==="complex_condition"){return true;}
return areEqualArraysOfTrees(tree.children,otherTree.children);};__exports.toValue=toValue;function toValue(ast,isWithinArray=false){if([4,10].includes(ast.type)&&!isWithinArray){return ast.value.map((v)=>toValue(v,true));}else if([0,1,2].includes(ast.type)){return ast.value;}else if(ast.type===6&&ast.op==="-"&&ast.right.type===0){return-ast.right.value;}else if(ast.type===5&&["false","true"].includes(ast.value)){return JSON.parse(ast.value);}else{return new Expression(ast);}}
__exports.astFromValue=astFromValue;function astFromValue(value){if(value instanceof Expression){return value.toAST();}
if(Array.isArray(value)){return{type:4,value:value.map(astFromValue)};}
return toPyValue(value);}
__exports.formatValue=formatValue;function formatValue(value){return formatAST(astFromValue(value));}
__exports.normalizeValue=normalizeValue;function normalizeValue(value){return toValue(astFromValue(value));}
__exports.isTree=isTree;function isTree(value){return(typeof value==="object"&&!(value instanceof Domain)&&!(value instanceof Expression)&&!Array.isArray(value)&&value!==null);}
__exports.addChild=addChild;function addChild(parent,child){if(child.type==="connector"&&!child.negate&&child.value===parent.value){parent.children.push(...child.children);}else{parent.children.push(child);}}
__exports.applyTransformations=applyTransformations;function applyTransformations(transformations,transformed,...fixedParams){for(let i=transformations.length-1;i>=0;i--){const fn=transformations[i];transformed=fn(transformed,...fixedParams);}
return transformed;}
function normalizeConnector(connector){const newTree={...connector,children:[]};for(const child of connector.children){addChild(newTree,child);}
if(newTree.children.length===1){const child=newTree.children[0];if(newTree.negate){const newChild={...child,negate:!child.negate};if(newChild.type==="condition"){return newChild;}
return newChild;}
return child;}
return newTree;}
function makeOptions(path,options){return{...options,getFieldDef:(p)=>{if(typeof path==="string"&&typeof p==="string"){return options.getFieldDef?.(`${path}.${p}`)||null;}
return null;},};}
__exports.operate=operate;function operate(transformation,tree,options={},treeType="condition",traverseSubTrees=true){if(tree.type==="connector"){const newTree={...tree,children:tree.children.map((c)=>operate(transformation,c,options,treeType,traverseSubTrees)),};if(treeType==="connector"){return normalizeConnector(transformation(newTree,options)||newTree);}
return normalizeConnector(newTree);}
const clone=cloneTree(tree);if(traverseSubTrees&&tree.type==="condition"&&isTree(tree.value)){clone.value=operate(transformation,tree.value,makeOptions(tree.path,options),treeType,traverseSubTrees);}
if(treeType===tree.type){return transformation(clone,options)||clone;}
return clone;}
__exports.rewriteNConsecutiveChildren=rewriteNConsecutiveChildren;function rewriteNConsecutiveChildren(transformation,N=2){return(c,options)=>{const children=[];const currentChildren=c.children;for(let i=0;i<currentChildren.length;i++){const NconsecutiveChildren=currentChildren.slice(i,i+N);let replacement=null;if(NconsecutiveChildren.length===N){replacement=transformation(connector(c.value,NconsecutiveChildren),options);}
if(replacement){children.push(replacement);i+=N-1;}else{children.push(NconsecutiveChildren[0]);}}
return{...c,children};};}
return __exports;});;
/* /web/static/src/core/tree_editor/construct_domain_from_tree.js */
odoo.define('@web/core/tree_editor/construct_domain_from_tree',['@web/core/py_js/py','@web/core/tree_editor/ast_utils','@web/core/tree_editor/condition_tree'],function(require){'use strict';let __exports={};const{formatAST,parseExpr}=require("@web/core/py_js/py");const{isBool,isNot}=require("@web/core/tree_editor/ast_utils");const{astFromValue,condition,Expression,FALSE_TREE,isTree,TRUE_TREE,}=require("@web/core/tree_editor/condition_tree");function bool(ast){if(isBool(ast)||isNot(ast)||ast.type===2){return ast;}
return{type:8,fn:{type:5,value:"bool"},args:[ast],kwargs:{}};}
function getASTs(tree,isSubTree=false){const ASTs=[];if(tree.type==="condition"){if(tree.negate){ASTs.push(toAST("!"));}
ASTs.push({type:10,value:[tree.path,tree.operator,tree.value].map(toAST),});return ASTs;}
if(tree.type==="complex_condition"){const ast=parseExpr(tree.value);return getASTs(condition(new Expression(bool(ast)),"=",1));}
const length=tree.children.length;if(length===0){if(tree.value==="|"){return tree.negate?getASTs(TRUE_TREE):getASTs(FALSE_TREE);}else{return tree.negate?getASTs(FALSE_TREE):isSubTree?getASTs(TRUE_TREE):[];}}
if(tree.negate){ASTs.push(toAST("!"));}
for(let i=0;i<length-1;i++){ASTs.push(toAST(tree.value));}
for(const child of tree.children){ASTs.push(...getASTs(child,true));}
return ASTs;}
function toAST(value){if(isTree(value)){return{type:4,value:getASTs(value)};}
return astFromValue(value);}
__exports.constructDomainFromTree=constructDomainFromTree;function constructDomainFromTree(tree){return formatAST(toAST(tree));}
return __exports;});;
/* /web/static/src/core/tree_editor/construct_expression_from_tree.js */
odoo.define('@web/core/tree_editor/construct_expression_from_tree',['@web/core/py_js/py','@web/core/tree_editor/ast_utils','@web/core/tree_editor/condition_tree','@web/core/tree_editor/operators'],function(require){'use strict';let __exports={};const{formatAST}=require("@web/core/py_js/py");const{isValidPath,not}=require("@web/core/tree_editor/ast_utils");const{Expression,astFromValue,isTree}=require("@web/core/tree_editor/condition_tree");const{COMPARATORS,TERM_OPERATORS_NEGATION}=require("@web/core/tree_editor/operators");function getNormalizedCondition(condition){let{operator,negate}=condition;if(negate&&typeof operator==="string"&&TERM_OPERATORS_NEGATION[operator]){operator=TERM_OPERATORS_NEGATION[operator];negate=false;}
return{...condition,operator,negate};}
function isX2Many(ast,options){if(isValidPath(ast,options)){const fieldDef=options.getFieldDef(ast.value);return["many2many","one2many"].includes(fieldDef.type);}
return false;}
function _constructExpressionFromTree(tree,options,isRoot=false){if(tree.type==="connector"&&tree.value==="|"&&tree.children.length===2){const isSimpleAnd=(tree)=>tree.type==="connector"&&tree.value==="&"&&tree.children.length===2;if(tree.children.every((c)=>isSimpleAnd(c))){const[c1,c2]=tree.children;for(let i=0;i<2;i++){const c1Child=c1.children[i];const str1=_constructExpressionFromTree({...c1Child},options);for(let j=0;j<2;j++){const c2Child=c2.children[j];const str2=_constructExpressionFromTree(c2Child,options);if(str1===`not ${str2}`||`not ${str1}`===str2){const others=[c1.children[1-i],c2.children[1-j]];const str=_constructExpressionFromTree(c1Child,options);const strs=others.map((c)=>_constructExpressionFromTree(c,options));return`${strs[0]} if ${str} else ${strs[1]}`;}}}}}
if(tree.type==="connector"){const connector=tree.value==="&"?"and":"or";const subExpressions=tree.children.map((c)=>_constructExpressionFromTree(c,options));if(!subExpressions.length){return connector==="and"?"1":"0";}
let expression=subExpressions.join(` ${connector} `);if(!isRoot||tree.negate){expression=`( ${expression} )`;}
if(tree.negate){expression=`not ${expression}`;}
return expression;}
if(tree.type==="complex_condition"){return tree.value;}
tree=getNormalizedCondition(tree);const{path,operator,value}=tree;if(path instanceof Expression&&operator==="="&&value===1){return path.toString();}
const op=operator==="="?"==":operator;if(typeof op!=="string"||!COMPARATORS.includes(op)){throw new Error("Invalid operator");}
if([0,1].includes(path)){if(operator!=="="||value!==1){return new Error("Invalid condition");}
return formatAST({type:2,value:Boolean(path)});}
const pathAST=astFromValue(path);if(typeof path=="string"&&isValidPath({type:5,value:path},options)){pathAST.type=5;}
if(value===false&&["=","!="].includes(operator)){return formatAST(operator==="="?not(pathAST):pathAST);}
if(isTree(value)){throw new Error("Invalid value");}
let valueAST=astFromValue(value);if(["in","not in"].includes(operator)&&!(value instanceof Expression)&&![4,10].includes(valueAST.type)){valueAST={type:4,value:[valueAST]};}
if(pathAST.type===5&&isX2Many(pathAST,options)&&["in","not in"].includes(operator)){const ast={type:8,fn:{type:15,obj:{args:[pathAST],type:8,fn:{type:5,value:"set",},},key:"intersection",},args:[valueAST],};return formatAST(operator==="not in"?not(ast):ast);}
return formatAST({type:7,op,left:pathAST,right:valueAST,});}
__exports.constructExpressionFromTree=constructExpressionFromTree;function constructExpressionFromTree(tree,options={}){return _constructExpressionFromTree(tree,options,true);}
return __exports;});;
/* /web/static/src/core/tree_editor/construct_tree_from_domain.js */
odoo.define('@web/core/tree_editor/construct_tree_from_domain',['@web/core/domain','@web/core/py_js/py','@web/core/tree_editor/condition_tree'],function(require){'use strict';let __exports={};const{Domain}=require("@web/core/domain");const{formatAST}=require("@web/core/py_js/py");const{addChild,connector,toValue}=require("@web/core/tree_editor/condition_tree");function _constructTree(ASTs,distributeNot=false,negate=false){const[firstAST,...tailASTs]=ASTs;if(firstAST.type===1&&firstAST.value==="!"){return _constructTree(tailASTs,distributeNot,!negate);}
const tree={type:firstAST.type===1?"connector":"condition"};if(tree.type==="connector"){tree.value=firstAST.value;if(distributeNot&&negate){tree.value=tree.value==="&"?"|":"&";tree.negate=false;}else{tree.negate=negate;}
tree.children=[];}else{const[pathAST,operatorAST,valueAST]=firstAST.value;tree.path=toValue(pathAST);tree.negate=negate;tree.operator=toValue(operatorAST);tree.value=toValue(valueAST);tree.isProperty=false;if(["any","not any"].includes(tree.operator)){try{tree.value=constructTreeFromDomain(formatAST(valueAST),distributeNot);}catch{tree.value=Array.isArray(tree.value)?tree.value:[tree.value];}}}
let remaimingASTs=tailASTs;if(tree.type==="connector"){for(let i=0;i<2;i++){const{tree:child,remaimingASTs:otherASTs}=_constructTree(remaimingASTs,distributeNot,distributeNot&&negate);remaimingASTs=otherASTs;addChild(tree,child);}}
return{tree,remaimingASTs};}
__exports.constructTreeFromDomain=constructTreeFromDomain;function constructTreeFromDomain(domain,distributeNot=false){domain=new Domain(domain);const domainAST=domain.ast;const initialASTs=domainAST.value;if(!initialASTs.length){return connector("&");}
const{tree}=_constructTree(initialASTs,distributeNot);return tree;}
return __exports;});;
/* /web/static/src/core/tree_editor/construct_tree_from_expression.js */
odoo.define('@web/core/tree_editor/construct_tree_from_expression',['@web/core/py_js/py','@web/core/tree_editor/ast_utils','@web/core/tree_editor/condition_tree','@web/core/tree_editor/operators'],function(require){'use strict';let __exports={};const{formatAST,parseExpr}=require("@web/core/py_js/py");const{isNot,isValidPath,not}=require("@web/core/tree_editor/ast_utils");const{addChild,complexCondition,condition,connector,toValue}=require("@web/core/tree_editor/condition_tree");const{COMPARATORS}=require("@web/core/tree_editor/operators");const EXCHANGE={"<":">","<=":">=",">":"<",">=":"<=","=":"=","!=":"!=",};function or(left,right){return{type:14,op:"or",left,right};}
function and(left,right){return{type:14,op:"and",left,right};}
function isSet(ast){return ast.type===8&&ast.fn.type===5&&ast.fn.value==="set"&&ast.args.length<=1;}
function isValidPath2(ast,options){if(!ast){return null;}
if([4,10].includes(ast.type)&&ast.value.length===1){return isValidPath(ast.value[0],options);}
return isValidPath(ast,options);}
function _getConditionFromComparator(ast,options){if(["is","is not"].includes(ast.op)){return null;}
let operator=ast.op;if(operator==="=="){operator="=";}
let left=ast.left;let right=ast.right;if(isValidPath(left,options)==isValidPath(right,options)){return null;}
if(!isValidPath(left,options)){if(operator in EXCHANGE){const temp=left;left=right;right=temp;operator=EXCHANGE[operator];}else{return null;}}
return condition(left.value,operator,toValue(right));}
function _getConditionFromIntersection(ast,options,negate=false){let left=ast.fn.obj.args[0];let right=ast.args[0];if(!left){return condition(negate?1:0,"=",1);}
if(isValidPath2(left,options)==isValidPath2(right,options)){return null;}
if(!isValidPath2(left,options)){const temp=left;left=right;right=temp;}
if([4,10].includes(left.type)&&left.value.length===1){left=left.value[0];}
if(!right){return condition(left.value,negate?"=":"!=",false);}
if(isSet(right)){if(!right.args[0]){right={type:4,value:[]};}
if([4,10].includes(right.args[0].type)){right=right.args[0];}}
if(![4,10].includes(right.type)){return null;}
return condition(left.value,negate?"not in":"in",toValue(right));}
function _leafFromAST(ast,options,negate=false){if(isNot(ast)){return _treeFromAST(ast.right,options,!negate);}
if(ast.type===5&&isValidPath(ast,options)){return condition(ast.value,negate?"=":"!=",false);}
const astValue=toValue(ast);if(["boolean","number","string"].includes(typeof astValue)){return condition(astValue?1:0,"=",1);}
if(ast.type===8&&ast.fn.type===15&&isSet(ast.fn.obj)&&ast.fn.key==="intersection"){const tree=_getConditionFromIntersection(ast,options,negate);if(tree){return tree;}}
if(ast.type===7&&COMPARATORS.includes(ast.op)){if(negate){return _leafFromAST(not(ast),options);}
const tree=_getConditionFromComparator(ast,options);if(tree){return tree;}}
return complexCondition(formatAST(negate?not(ast):ast));}
function _treeFromAST(ast,options,negate=false){if(isNot(ast)){return _treeFromAST(ast.right,options,!negate);}
if(ast.type===14){const tree=connector(ast.op==="and"?"&":"|");if(options.distributeNot&&negate){tree.value=tree.value==="&"?"|":"&";}else{tree.negate=negate;}
const subASTs=[ast.left,ast.right];for(const subAST of subASTs){const child=_treeFromAST(subAST,options,options.distributeNot&&negate);addChild(tree,child);}
return tree;}
if(ast.type===13){const newAST=or(and(ast.condition,ast.ifTrue),and(not(ast.condition),ast.ifFalse));return _treeFromAST(newAST,options,negate);}
return _leafFromAST(ast,options,negate);}
__exports.constructTreeFromExpression=constructTreeFromExpression;function constructTreeFromExpression(expression,options={}){const ast=parseExpr(expression);return _treeFromAST(ast,options);}
return __exports;});;
/* /web/static/src/core/tree_editor/domain_contains_expressions.js */
odoo.define('@web/core/tree_editor/domain_contains_expressions',['@web/core/tree_editor/condition_tree','@web/core/tree_editor/construct_tree_from_domain'],function(require){'use strict';let __exports={};const{Expression,isTree}=require("@web/core/tree_editor/condition_tree");const{constructTreeFromDomain}=require("@web/core/tree_editor/construct_tree_from_domain");function treeContainsExpressions(tree){if(tree.type==="condition"){const{path,operator,value}=tree;if(isTree(value)&&treeContainsExpressions(value)){return true;}
return[path,operator,value].some((v)=>v instanceof Expression||(Array.isArray(v)&&v.some((w)=>w instanceof Expression)));}
for(const child of tree.children){if(treeContainsExpressions(child)){return true;}}
return false;}
__exports.domainContainsExpressions=domainContainsExpressions;function domainContainsExpressions(domain){let tree;try{tree=constructTreeFromDomain(domain);}catch{return null;}
return treeContainsExpressions(tree);}
return __exports;});;
/* /web/static/src/core/tree_editor/domain_from_tree.js */
odoo.define('@web/core/tree_editor/domain_from_tree',['@web/core/tree_editor/construct_domain_from_tree','@web/core/tree_editor/virtual_operators'],function(require){'use strict';let __exports={};const{constructDomainFromTree}=require("@web/core/tree_editor/construct_domain_from_tree");const{eliminateVirtualOperators}=require("@web/core/tree_editor/virtual_operators");__exports.domainFromTree=domainFromTree;function domainFromTree(tree){const simplifiedTree=eliminateVirtualOperators(tree);return constructDomainFromTree(simplifiedTree);}
return __exports;});;
/* /web/static/src/core/tree_editor/expression_from_tree.js */
odoo.define('@web/core/tree_editor/expression_from_tree',['@web/core/tree_editor/construct_expression_from_tree','@web/core/tree_editor/virtual_operators'],function(require){'use strict';let __exports={};const{constructExpressionFromTree}=require("@web/core/tree_editor/construct_expression_from_tree");const{eliminateVirtualOperators}=require("@web/core/tree_editor/virtual_operators");__exports.expressionFromTree=expressionFromTree;function expressionFromTree(tree,options={}){const simplifiedTree=eliminateVirtualOperators(tree,options);return constructExpressionFromTree(simplifiedTree,options);}
return __exports;});;
/* /web/static/src/core/tree_editor/operators.js */
odoo.define('@web/core/tree_editor/operators',[],function(require){'use strict';let __exports={};const TERM_OPERATORS_NEGATION=__exports.TERM_OPERATORS_NEGATION={"<":">=",">":"<=","<=":">",">=":"<","=":"!=","!=":"=",in:"not in",like:"not like",ilike:"not ilike","not in":"in","not like":"like","not ilike":"ilike",};const TERM_OPERATORS_NEGATION_EXTENDED=__exports.TERM_OPERATORS_NEGATION_EXTENDED={...TERM_OPERATORS_NEGATION,is:"is not","is not":"is","==":"!=","!=":"==",};const COMPARATORS=__exports.COMPARATORS=["<","<=",">",">=","in","not in","==","is","!=","is not"];return __exports;});;
/* /web/static/src/core/tree_editor/tree_editor.js */
odoo.define('@web/core/tree_editor/tree_editor',['@odoo/owl','@web/core/dropdown/dropdown','@web/core/dropdown/dropdown_item','@web/core/tree_editor/condition_tree','@web/core/tree_editor/tree_editor_value_editors','@web/core/tree_editor/utils','@web/core/tree_editor/virtual_operators','@web/core/utils/hooks','@web/core/utils/objects'],function(require){'use strict';let __exports={};const{Component,onWillStart,onWillUpdateProps}=require("@odoo/owl");const{Dropdown}=require("@web/core/dropdown/dropdown");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{cloneTree,connector,isTree,TRUE_TREE}=require("@web/core/tree_editor/condition_tree");const{getDefaultValue,getValueEditorInfo,}=require("@web/core/tree_editor/tree_editor_value_editors");const{getResModel}=require("@web/core/tree_editor/utils");const{areEquivalentTrees}=require("@web/core/tree_editor/virtual_operators");const{useService}=require("@web/core/utils/hooks");const{shallowEqual}=require("@web/core/utils/objects");const TreeEditor=__exports.TreeEditor=class TreeEditor extends Component{static template="web.TreeEditor";static components={Dropdown,DropdownItem,TreeEditor,};static props={tree:Object,resModel:String,update:Function,getDefaultCondition:Function,getPathEditorInfo:Function,getOperatorEditorInfo:Function,getDefaultOperator:Function,readonly:{type:Boolean,optional:true},slots:{type:Object,optional:true},isDebugMode:{type:Boolean,optional:true},defaultConnector:{type:[{value:"&"},{value:"|"}],optional:true},isSubTree:{type:Boolean,optional:true},};static defaultProps={defaultConnector:"&",readonly:false,isSubTree:false,};setup(){this.isTree=isTree;this.fieldService=useService("field");this.treeProcessor=useService("tree_processor");onWillStart(()=>this.onPropsUpdated(this.props));onWillUpdateProps((nextProps)=>this.onPropsUpdated(nextProps));}
async onPropsUpdated(props){if(this.tree){this.previousTree=this.tree;}
this.tree=cloneTree(props.tree);if(shallowEqual(this.tree,TRUE_TREE)){this.tree=connector(props.defaultConnector);}else if(this.tree.type!=="connector"){this.tree=connector(props.defaultConnector,[this.tree]);}
if(this.previousTree&&areEquivalentTrees(this.tree,this.previousTree)){this.tree=this.previousTree;this.previousTree=null;}
await this.prepareInfo(props);}
async prepareInfo(props){const[fieldDefs,getFieldDef]=await Promise.all([this.fieldService.loadFields(props.resModel),this.treeProcessor.makeGetFieldDef(props.resModel,this.tree),]);this.getFieldDef=getFieldDef;this.defaultCondition=props.getDefaultCondition(fieldDefs);if(props.readonly){this.getConditionDescription=await this.treeProcessor.makeGetConditionDescription(props.resModel,this.tree);}}
get className(){return`${this.props.readonly ? "o_read_mode" : "o_edit_mode"}`;}
get isDebugMode(){return this.props.isDebugMode!==undefined?this.props.isDebugMode:!!this.env.debug;}
notifyChanges(){this.props.update(this.tree);}
_updateConnector(node){node.value=node.value==="&"?"|":"&";node.negate=false;}
updateConnector(node){this.updateNode(node,()=>this._updateConnector(node));}
_updateComplexCondition(node,value){node.value=value;}
updateComplexCondition(node,value){this.updateNode(node,()=>this._updateComplexCondition(node,value));}
makeCondition(parent,condition){condition||=parent.children.findLast((c)=>c.type==="condition");return cloneTree(condition||this.defaultCondition);}
_addNewCondition(parent,node){if(node){const index=parent.children.indexOf(node);parent.children.splice(index+1,0,this.makeCondition(parent,node));}else{parent.children.push(this.makeCondition(parent));}}
addNewCondition(parent,node){this.updateNode(parent,()=>this._addNewCondition(parent,node));}
_addNewConnector(parent,node){const index=parent.children.indexOf(node);const nextConnector=parent.value==="&"?"|":"&";parent.children.splice(index+1,0,connector(nextConnector,[this.makeCondition(parent,node)]));}
addNewConnector(parent,node){this.updateNode(parent,()=>this._addNewConnector(parent,node));}
_delete(ancestors,node){if(ancestors.length===0){return;}
const parent=ancestors.at(-1);const index=parent.children.indexOf(node);parent.children.splice(index,1);ancestors=ancestors.slice(0,ancestors.length-1);if(parent.children.length===0){this._delete(ancestors,parent);}}
delete(ancestors,node){const upperNode=ancestors[0]||node;this.updateNode(upperNode,()=>this._delete(ancestors,node));}
getResModel(node){const fieldDef=this.getFieldDef(node.path);const resModel=getResModel(fieldDef);return resModel;}
getPathEditorInfo(){return this.props.getPathEditorInfo(this.props.resModel,this.defaultCondition);}
getOperatorEditorInfo(node){const fieldDef=this.getFieldDef(node.path);return this.props.getOperatorEditorInfo(fieldDef);}
getValueEditorInfo(node){const fieldDef=this.getFieldDef(node.path);return getValueEditorInfo(fieldDef,node.operator);}
async _updatePath(node,path){const{fieldDef}=await this.fieldService.loadFieldInfo(this.props.resModel,path);node.path=path;node.negate=false;node.operator=this.props.getDefaultOperator(fieldDef);node.value=getDefaultValue(fieldDef,node.operator);node.isProperty=fieldDef?.is_property;}
async updatePath(node,path){this.updateNode(node,()=>this._updatePath(node,path));}
_updateLeafOperator(node,operator,negate){const fieldDef=this.getFieldDef(node.path);node.negate=negate;node.operator=operator;node.value=getDefaultValue(fieldDef,operator,node.value);}
updateLeafOperator(node,operator,negate){this.updateNode(node,()=>this._updateLeafOperator(node,operator,negate));}
_updateLeafValue(node,value){node.value=value;}
updateLeafValue(node,value){this.updateNode(node,()=>this._updateLeafValue(node,value));}
async updateNode(node,operation){const previousNode=cloneTree(node);await operation();if(areEquivalentTrees(node,previousNode)){await this.prepareInfo(this.props);this.render();}
this.notifyChanges();}
highlightNode(target){const nodeEl=target.closest(".o_tree_editor_node");nodeEl.classList.toggle("o_hovered_button");}}
return __exports;});;
/* /web/static/src/core/tree_editor/tree_editor_autocomplete.js */
odoo.define('@web/core/tree_editor/tree_editor_autocomplete',['@web/core/l10n/translation','@web/core/py_js/py_utils','@web/core/record_selectors/multi_record_selector','@web/core/record_selectors/record_selector','@web/core/tree_editor/condition_tree','@web/core/tree_editor/utils','@web/core/utils/urls'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{formatAST,toPyValue}=require("@web/core/py_js/py_utils");const{MultiRecordSelector}=require("@web/core/record_selectors/multi_record_selector");const{RecordSelector}=require("@web/core/record_selectors/record_selector");const{Expression}=require("@web/core/tree_editor/condition_tree");const{isId}=require("@web/core/tree_editor/utils");const{imageUrl}=require("@web/core/utils/urls");const getFormat=__exports.getFormat=(val,displayNames)=>{let text;let colorIndex;if(isId(val)){text=typeof displayNames[val]==="string"?displayNames[val]:_t("Inaccessible/missing record ID: %s",val);colorIndex=typeof displayNames[val]==="string"?0:2;}else{text=val instanceof Expression?String(val):_t("Invalid record ID: %s",formatAST(toPyValue(val)));colorIndex=val instanceof Expression?2:1;}
return{text,colorIndex};};const DomainSelectorAutocomplete=__exports.DomainSelectorAutocomplete=class DomainSelectorAutocomplete extends MultiRecordSelector{static props={...MultiRecordSelector.props,resIds:true,};getIds(props=this.props){return props.resIds.filter((val)=>isId(val));}
getTags(props,displayNames){return props.resIds.map((val,index)=>{const{text,colorIndex}=getFormat(val,displayNames);return{text,colorIndex,onDelete:()=>{this.props.update([...this.props.resIds.slice(0,index),...this.props.resIds.slice(index+1),]);},img:this.isAvatarModel&&isId(val)&&imageUrl(this.props.resModel,val,"avatar_128"),};});}}
const DomainSelectorSingleAutocomplete=__exports.DomainSelectorSingleAutocomplete=class DomainSelectorSingleAutocomplete extends RecordSelector{static props={...RecordSelector.props,resId:true,};getDisplayName(props=this.props,displayNames){const{resId}=props;if(resId===false){return"";}
const{text}=getFormat(resId,displayNames);return text;}
getIds(props=this.props){if(isId(props.resId)){return[props.resId];}
return[];}}
return __exports;});;
/* /web/static/src/core/tree_editor/tree_editor_components.js */
odoo.define('@web/core/tree_editor/tree_editor_components',['@odoo/owl','@web/core/tags_list/tags_list','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{TagsList}=require("@web/core/tags_list/tags_list");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const Input=__exports.Input=class Input extends Component{static props=["value","update","placeholder?","startEmpty?"];static template="web.TreeEditor.Input";}
const Select=__exports.Select=class Select extends Component{static props=["value","update","options","placeholder?","addBlankOption?"];static template="web.TreeEditor.Select";deserialize(value){return JSON.parse(value);}
serialize(value){return JSON.stringify(value);}}
const Range=__exports.Range=class Range extends Component{static props=["value","update","editorInfo"];static template="web.TreeEditor.Range";update(index,newValue){const result=[...this.props.value];result[index]=newValue;return this.props.update(result);}}
const InRange=__exports.InRange=class InRange extends Component{static props=["value","update","valueTypeEditorInfo","betweenEditorInfo"];static template="web.TreeEditor.InRange";static options=[["today",_t("Today")],["last 7 days",_t("Last 7 days")],["last 30 days",_t("Last 30 days")],["month to date",_t("Month to date")],["last month",_t("Last month")],["year to date",_t("Year to date")],["last 12 months",_t("Last 12 months")],["custom range",_t("Custom range")],];updateValueType(newValueType){const[fieldType,currentValueType]=this.props.value;if(currentValueType!==newValueType){const values=newValueType==="custom range"?this.props.betweenEditorInfo.defaultValue():[false,false];return this.props.update([fieldType,newValueType,...values]);}}
updateValues(values){const[fieldType,currentValueType]=this.props.value;return this.props.update([fieldType,currentValueType,...values]);}}
const List=__exports.List=class List extends Component{static components={TagsList};static props=["value","update","editorInfo"];static template="web.TreeEditor.List";get tags(){const{isSupported,stringify}=this.props.editorInfo;return this.props.value.map((val,index)=>({text:stringify(val),colorIndex:isSupported(val)?0:2,onDelete:()=>{this.props.update([...this.props.value.slice(0,index),...this.props.value.slice(index+1),]);},}));}
update(newValue){return this.props.update([...this.props.value,newValue]);}}
return __exports;});;
/* /web/static/src/core/tree_editor/tree_editor_operator_editor.js */
odoo.define('@web/core/tree_editor/tree_editor_operator_editor',['@web/core/l10n/translation','@web/core/py_js/py','@web/core/tree_editor/condition_tree','@web/core/tree_editor/tree_editor_components'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{parseExpr}=require("@web/core/py_js/py");const{formatValue,toValue}=require("@web/core/tree_editor/condition_tree");const{Select}=require("@web/core/tree_editor/tree_editor_components");const OPERATOR_DESCRIPTIONS={"=":(fieldDefType)=>{switch(fieldDefType){case"many2one":case"many2many":case"one2many":return _t("=");default:return _t("is equal to");}},"!=":(fieldDefType)=>{switch(fieldDefType){case"many2one":case"many2many":case"one2many":return _t("!=");default:return _t("is not equal to");}},"<=":_t("lower or equal to"),"<":(fieldDefType)=>{switch(fieldDefType){case"date":case"datetime":return _t("before");default:return _t("lower than");}},">":(fieldDefType)=>{switch(fieldDefType){case"date":case"datetime":return _t("after");default:return _t("greater than");}},">=":_t("greater or equal to"),"=?":"=?","=like":_t("=like"),"=ilike":_t("=ilike"),like:_t("like"),"not like":_t("not like"),ilike:_t("contains"),"not ilike":_t("does not contain"),in:(fieldDefType)=>{switch(fieldDefType){case"many2one":case"many2many":case"one2many":return _t("is equal to");default:return _t("is in");}},"not in":(fieldDefType)=>{switch(fieldDefType){case"many2one":case"many2many":case"one2many":return _t("is not equal to");default:return _t("is not in");}},child_of:_t("child of"),parent_of:_t("parent of"),any:(fieldDefType)=>{switch(fieldDefType){case"many2one":return _t("matches");default:return _t("match");}},"not any":(fieldDefType)=>{switch(fieldDefType){case"many2one":return _t("matches none of");default:return _t("match none of");}},set:_t("is set"),"not set":_t("is not set"),"starts with":_t("starts with"),between:_t("between"),"in range":_t("is in"),};function toKey(operator,negate=false){if(!negate&&typeof operator==="string"&&operator in OPERATOR_DESCRIPTIONS){return operator;}
return JSON.stringify([formatValue(operator),negate]);}
function toOperator(key){if(!key.includes("[")){return[key,false];}
const[expr,negate]=JSON.parse(key);return[toValue(parseExpr(expr)),negate];}
function getOperatorDescription(operator,fieldDefType){const description=OPERATOR_DESCRIPTIONS[operator];if(typeof description==="function"&&description.constructor?.name!=="LazyTranslatedString"){return description(fieldDefType);}
return description;}
__exports.getOperatorLabel=getOperatorLabel;function getOperatorLabel(operator,fieldDefType,negate=false,getDescr=(operator,fieldDefType)=>null){let label;if(typeof operator==="string"&&operator in OPERATOR_DESCRIPTIONS){label=getDescr(operator,fieldDefType)||getOperatorDescription(operator,fieldDefType);}else{label=formatValue(operator);}
if(negate){return _t(`not %(operator_label)s`,{operator_label:label});}
return label;}
function getOperatorInfo(operator,fieldDefType,negate=false){const key=toKey(operator,negate);const label=getOperatorLabel(operator,fieldDefType,negate);return[key,label];}
__exports.getOperatorEditorInfo=getOperatorEditorInfo;function getOperatorEditorInfo(operators,fieldDef){const defaultOperator=operators[0];const operatorsInfo=operators.map((operator)=>getOperatorInfo(operator,fieldDef?.type));return{component:Select,extractProps:({update,value:[operator,negate]})=>{const[operatorKey,operatorLabel]=getOperatorInfo(operator,fieldDef?.type,negate);const options=[...operatorsInfo];if(!options.some(([key])=>key===operatorKey)){options.push([operatorKey,operatorLabel]);}
return{value:operatorKey,update:(operatorKey)=>update(...toOperator(operatorKey)),options,};},defaultValue:()=>defaultOperator,isSupported:([operator])=>typeof operator==="string"&&operator in OPERATOR_DESCRIPTIONS,message:_t("Operator not supported"),stringify:([operator,negate])=>getOperatorLabel(operator,fieldDef?.type,negate),};}
return __exports;});;
/* /web/static/src/core/tree_editor/tree_editor_value_editors.js */
odoo.define('@web/core/tree_editor/tree_editor_value_editors',['@web/core/datetime/datetime_input','@web/core/domain','@web/core/l10n/dates','@web/core/l10n/translation','@web/core/registry','@web/core/tree_editor/condition_tree','@web/core/tree_editor/tree_editor_autocomplete','@web/core/tree_editor/tree_editor_components','@web/core/tree_editor/utils','@web/core/utils/arrays'],function(require){'use strict';let __exports={};const{DateTimeInput}=require("@web/core/datetime/datetime_input");const{Domain}=require("@web/core/domain");const{deserializeDate,deserializeDateTime,serializeDate,serializeDateTime,}=require("@web/core/l10n/dates");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{registry}=require("@web/core/registry");const{connector,formatValue,isTree}=require("@web/core/tree_editor/condition_tree");const{DomainSelectorAutocomplete,DomainSelectorSingleAutocomplete,}=require("@web/core/tree_editor/tree_editor_autocomplete");const{Input,InRange,List,Range,Select}=require("@web/core/tree_editor/tree_editor_components");const{disambiguate,getResModel,isId}=require("@web/core/tree_editor/utils");const{unique}=require("@web/core/utils/arrays");const{DateTime}=luxon;const formatters=registry.category("formatters");const parsers=registry.category("parsers");function parseValue(fieldType,value){const parser=parsers.get(fieldType,(value)=>value);try{return parser(value);}catch{return value;}}
function isParsable(fieldType,value){const parser=parsers.get(fieldType,(value)=>value);try{parser(value);}catch{return false;}
return true;}
function genericSerializeDate(type,value){return type==="date"?serializeDate(value):serializeDateTime(value);}
function genericDeserializeDate(type,value){return type==="date"?deserializeDate(value):deserializeDateTime(value);}
function placeholderForSelect(displayPlaceholder){if(displayPlaceholder){return _t(`Select one or several criteria`);}}
function placeholderForInput(displayPlaceholder){if(displayPlaceholder){return _t(`Press "Enter" to add criterion`);}}
const STRING_EDITOR={component:Input,extractProps:({value,update,displayPlaceholder})=>({value,update,placeholder:placeholderForInput(displayPlaceholder),}),isSupported:(value)=>typeof value==="string",defaultValue:()=>"",};function makeSelectEditor(options,params={}){const getOption=(value)=>options.find(([v])=>v===value)||null;return{component:Select,extractProps:({value,update,displayPlaceholder})=>({value,update,options,addBlankOption:params.addBlankOption,placeholder:placeholderForSelect(displayPlaceholder),}),isSupported:(value)=>Boolean(getOption(value)),defaultValue:()=>options[0]?.[0]??false,stringify:(value,disambiguate)=>{const option=getOption(value);return option?option[1]:disambiguate?formatValue(value):String(value);},message:_t("Value not in selection"),};}
function getDomain(fieldDef){if(fieldDef.type==="many2one"){return[];}
try{return new Domain(fieldDef.domain||[]).toList();}catch{return[];}}
function makeAutoCompleteEditor(fieldDef){return{component:DomainSelectorAutocomplete,extractProps:({value,update})=>({resModel:getResModel(fieldDef),fieldString:fieldDef.string,domain:getDomain(fieldDef),update:(value)=>update(unique(value)),resIds:unique(value),placeholder:placeholderForSelect(true),}),isSupported:(value)=>Array.isArray(value),defaultValue:()=>[],};}
function isLitteralObject(value){return typeof value==="object"&&!Array.isArray(value)&&value!==null;}
function getPartialValueEditorInfo(fieldDef,operator,params={}){switch(operator){case"set":case"not set":return{component:null,extractProps:null,isSupported:(value)=>value===false||(fieldDef.type==="boolean"&&value===true),defaultValue:()=>false,};case"=like":case"=ilike":case"like":case"not like":case"ilike":case"not ilike":return STRING_EDITOR;case"between":{const editorInfo=getValueEditorInfo(fieldDef,"=",params);const{defaultValue}=getValueEditorInfo(fieldDef,"=",{...params,forBetween:true,});return{component:Range,extractProps:({value,update})=>({value,update,editorInfo,}),isSupported:(value)=>Array.isArray(value)&&value.length===2,defaultValue:()=>{const value=defaultValue();return isLitteralObject(value)?[value.start,value.end]:[value,value];},shouldResetValue:(value)=>!editorInfo.isSupported(value[0])||!editorInfo.isSupported(value[1]),};}
case"in range":{return{component:InRange,extractProps:({value,update})=>({value,update,valueTypeEditorInfo:makeSelectEditor(InRange.options,params),betweenEditorInfo:getValueEditorInfo(fieldDef,"between",params),}),isSupported:(value)=>Array.isArray(value)&&value.length===4&&value[0]===fieldDef.type&&InRange.options.some(([t])=>t===value[1]),defaultValue:()=>[fieldDef.type,"today",false,false],};}
case"in":case"not in":{switch(fieldDef.type){case"tags":return STRING_EDITOR;case"many2one":case"many2many":case"one2many":return makeAutoCompleteEditor(fieldDef);default:{const editorInfo=getValueEditorInfo(fieldDef,"=",{...params,addBlankOption:true,startEmpty:true,});return{component:List,extractProps:({value,update})=>{if(!disambiguate(value)){const{stringify}=editorInfo;editorInfo.stringify=(val)=>stringify(val,false);}
return{value,update,editorInfo,};},isSupported:(value)=>Array.isArray(value),defaultValue:()=>[],shouldResetValue:(value)=>!value.every(editorInfo.isSupported),};}}}
case"any":case"not any":{switch(fieldDef.type){case"many2one":case"many2many":case"one2many":{return{component:null,extractProps:null,isSupported:isTree,defaultValue:()=>connector("&"),};}}}}
const{type}=fieldDef;switch(type){case"integer":case"float":case"monetary":{const formatType=type==="integer"?"integer":"float";const typeFormatter=formatters.get(formatType,null);const formatter=(value)=>{let v=value;if(typeFormatter){try{v=typeFormatter(value);}catch{}}
return String(v);};return{component:Input,extractProps:({value,update,displayPlaceholder})=>({value:formatter(value),update:(value)=>update(parseValue(formatType,value)),startEmpty:params.startEmpty,placeholder:placeholderForInput(displayPlaceholder),}),isSupported:()=>true,defaultValue:()=>1,shouldResetValue:(value)=>parseValue(formatType,value)===value,};}
case"date":case"datetime":return{component:DateTimeInput,extractProps:({value,update,displayPlaceholder})=>({value:params.startEmpty||value===false?false:genericDeserializeDate(type,value),type,onApply:(value)=>{if(!params.startEmpty||value){update(genericSerializeDate(type,value||DateTime.local().startOf("day")));}},placeholder:placeholderForSelect(displayPlaceholder),}),isSupported:(value)=>typeof value==="string"&&isParsable(type,value),defaultValue:(operator)=>{const datetime=DateTime.local();if(operator===">"){return genericSerializeDate(type,datetime.endOf("day"));}
const start=genericSerializeDate(type,datetime.startOf("day"));if(params.forBetween){return{start,end:genericSerializeDate(type,datetime.endOf("day"))};}
return start;},shouldResetValue:()=>true,stringify:(value)=>{if(value===false){return _t("False");}
if(typeof value==="string"&&isParsable(type,value)){const formatter=formatters.get(type,formatValue);return formatter(genericDeserializeDate(type,value));}
return formatValue(value);},message:_t("Not a valid %s",type),};case"char":case"html":case"text":return STRING_EDITOR;case"many2one":{if(["=","!="].includes(operator)){return{component:DomainSelectorSingleAutocomplete,extractProps:({value,update})=>({resModel:getResModel(fieldDef),fieldString:fieldDef.string,update,resId:value,}),isSupported:()=>true,defaultValue:()=>false,shouldResetValue:(value)=>value!==false&&!isId(value),};}else if(["parent_of","child_of"].includes(operator)){return makeAutoCompleteEditor(fieldDef);}
break;}
case"many2many":case"one2many":if(["=","!="].includes(operator)){return makeAutoCompleteEditor(fieldDef);}
break;case"selection":{const options=fieldDef.selection||[];return makeSelectEditor(options,params);}
case undefined:{const options=[[1,"1"]];return makeSelectEditor(options,params);}}
return{component:Input,extractProps:({value,update})=>({value:String(value),update,}),isSupported:()=>true,defaultValue:()=>"",};}
__exports.getValueEditorInfo=getValueEditorInfo;function getValueEditorInfo(fieldDef,operator,options={}){const info=getPartialValueEditorInfo(fieldDef||{},operator,options);return{extractProps:({value,update})=>({value,update}),message:_t("Value not supported"),stringify:(val,disambiguate=true)=>{if(disambiguate){return formatValue(val);}
return String(val);},...info,};}
__exports.getDefaultValue=getDefaultValue;function getDefaultValue(fieldDef,operator,value=null){const{isSupported,shouldResetValue,defaultValue}=getValueEditorInfo(fieldDef,operator);if(value===null||!isSupported(value)||shouldResetValue?.(value)){return defaultValue(operator);}
return value;}
return __exports;});;
/* /web/static/src/core/tree_editor/tree_from_domain.js */
odoo.define('@web/core/tree_editor/tree_from_domain',['@web/core/tree_editor/construct_tree_from_domain','@web/core/tree_editor/virtual_operators'],function(require){'use strict';let __exports={};const{constructTreeFromDomain}=require("@web/core/tree_editor/construct_tree_from_domain");const{introduceVirtualOperators}=require("@web/core/tree_editor/virtual_operators");__exports.treeFromDomain=treeFromDomain;function treeFromDomain(domain,options={}){const tree=constructTreeFromDomain(domain,options.distributeNot);return introduceVirtualOperators(tree,options);}
return __exports;});;
/* /web/static/src/core/tree_editor/tree_from_expression.js */
odoo.define('@web/core/tree_editor/tree_from_expression',['@web/core/tree_editor/construct_tree_from_expression','@web/core/tree_editor/virtual_operators'],function(require){'use strict';let __exports={};const{constructTreeFromExpression}=require("@web/core/tree_editor/construct_tree_from_expression");const{introduceVirtualOperators}=require("@web/core/tree_editor/virtual_operators");__exports.treeFromExpression=treeFromExpression;function treeFromExpression(expression,options={}){const tree=constructTreeFromExpression(expression,options);return introduceVirtualOperators(tree,options);}
return __exports;});;
/* /web/static/src/core/tree_editor/tree_processor.js */
odoo.define('@web/core/tree_editor/tree_processor',['@web/core/l10n/dates','@web/core/l10n/translation','@web/core/registry','@web/core/tree_editor/tree_editor_operator_editor','@web/core/utils/arrays','@web/core/tree_editor/condition_tree','@web/core/tree_editor/construct_tree_from_domain','@web/core/tree_editor/utils','@web/core/tree_editor/virtual_operators','@web/core/tree_editor/tree_editor_components'],function(require){'use strict';let __exports={};const{deserializeDate,deserializeDateTime,formatDate,formatDateTime,}=require("@web/core/l10n/dates");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{registry}=require("@web/core/registry");const{getOperatorLabel}=require("@web/core/tree_editor/tree_editor_operator_editor");const{unique,zip}=require("@web/core/utils/arrays");const{condition,Expression,isTree,normalizeValue}=require("@web/core/tree_editor/condition_tree");const{constructTreeFromDomain}=require("@web/core/tree_editor/construct_tree_from_domain");const{disambiguate,getResModel,isId}=require("@web/core/tree_editor/utils");const{introduceVirtualOperators}=require("@web/core/tree_editor/virtual_operators");const{InRange}=require("@web/core/tree_editor/tree_editor_components");function formatValue(val,disambiguate,fieldDef,displayNames){if(val instanceof Expression){return val.toString();}
if(displayNames&&isId(val)){if(typeof displayNames[val]==="string"){val=displayNames[val];}else{return _t("Inaccessible/missing record ID: %s",val);}}
if(fieldDef?.type==="selection"){const[,label]=(fieldDef.selection||[]).find(([v])=>v===val)||[];if(label!==undefined){val=label;}}
if(typeof val==="string"){if(fieldDef?.type==="datetime"){return formatDateTime(deserializeDateTime(val));}
if(fieldDef?.type==="date"){return formatDate(deserializeDate(val));}}
if(disambiguate&&typeof val==="string"){return JSON.stringify(val);}
return val;}
function getPathsInTree(tree,lookInSubTrees=false){const paths=[];if(tree.type==="condition"){paths.push(tree.path);if(typeof tree.path==="string"&&lookInSubTrees&&isTree(tree.value)){const subTreePaths=getPathsInTree(tree.value,lookInSubTrees);for(const p of subTreePaths){if(typeof p==="string"){paths.push(`${tree.path}.${p}`);}}}}
if(tree.type==="connector"&&tree.children){for(const child of tree.children){paths.push(...getPathsInTree(child,lookInSubTrees));}}
return unique(paths);}
function simplifyTree(tree){if(tree.type==="condition"){return tree;}
const processedChildren=tree.children.map(simplifyTree);if(tree.value==="&"){return{...tree,children:processedChildren};}
const children=[];const childrenByPath={};for(let index=0;index<processedChildren.length;index++){const child=processedChildren[index];if(child.type==="connector"||typeof child.path!=="string"||!["=","in"].includes(child.operator)){children.push(child);}else{if(!childrenByPath[child.path]){childrenByPath[child.path]={elems:[],index};children.push(child);}
childrenByPath[child.path].elems.push(child);}}
for(const path in childrenByPath){if(childrenByPath[path].elems.length===1){continue;}
const value=[];for(const child of childrenByPath[path].elems){if(child.operator==="="){value.push(child.value);}else{value.push(...child.value);}}
children[childrenByPath[path].index]=condition(path,"in",normalizeValue(unique(value)));}
if(children.length===1){return{...children[0]};}
return{...tree,children};}
function _extractIdsRecursive(tree,getFieldDef,idsByModel){if(tree.type==="condition"){const fieldDef=getFieldDef(tree.path);if(["many2one","many2many","one2many"].includes(fieldDef?.type)){const value=tree.value;const values=Array.isArray(value)?value:[value];const ids=values.filter((val)=>isId(val));const resModel=getResModel(fieldDef);if(ids.length){if(!idsByModel[resModel]){idsByModel[resModel]=[];}
idsByModel[resModel].push(...ids);}}}
if(tree.type==="connector"){for(const child of tree.children){_extractIdsRecursive(child,getFieldDef,idsByModel);}}
return idsByModel;}
function extractIdsFromTree(tree,getFieldDef){const idsByModel=_extractIdsRecursive(tree,getFieldDef,{});for(const resModel in idsByModel){idsByModel[resModel]=unique(idsByModel[resModel]);}
return idsByModel;}
const treeProcessorService=__exports.treeProcessorService={dependencies:["field","name"],async:["getDomainTreeDescription","getDomainTreeTooltip","makeGetConditionDescription","makeGetFieldDef","treeFromDomain",],start(_,{field:fieldService,name:nameService}){async function getDisplayNames(tree,getFieldDef){const resIdsByModel=extractIdsFromTree(tree,getFieldDef);const proms=[];const resModels=[];for(const[resModel,resIds]of Object.entries(resIdsByModel)){resModels.push(resModel);proms.push(nameService.loadDisplayNames(resModel,resIds));}
return Object.fromEntries(zip(resModels,await Promise.all(proms)));}
async function makeGetPathDescriptions(resModel,tree,limit){const paths=getPathsInTree(tree);const promises=[];const pathDescriptions=new Map();for(const path of paths){promises.push(fieldService.loadPathDescription(resModel,path).then(({displayNames})=>{pathDescriptions.set(path,`${displayNames.slice(0, limit).join(" \u2794 ")}${
displayNames.length > limit ? "..." : ""
}`);}));}
await Promise.all(promises);return(path)=>pathDescriptions.get(path);}
async function makeGetConditionDescription(resModel,tree,limit,pathLimit){tree=simplifyTree(tree);const[getFieldDef,getPathDescription]=await Promise.all([makeGetFieldDef(resModel,tree),makeGetPathDescriptions(resModel,tree,pathLimit),]);const displayNames=await getDisplayNames(tree,getFieldDef);return(node)=>_getConditionDescription(node,getFieldDef,getPathDescription,displayNames,limit);}
function _getConditionDescription(node,getFieldDef,getPathDescription,displayNames,limit=5){let{operator,negate,value,path}=node;if(operator==="in range"&&value[1]==="custom range"){operator="between";value=value.slice(2);}
if(["=","!="].includes(operator)&&value===false){operator=operator==="="?"not set":"set";}
const fieldDef=getFieldDef(path);const operatorLabel=getOperatorLabel(operator,fieldDef?.type,negate,(operator)=>{switch(operator){case"=":case"in":return"=";case"!=":case"not in":return _t("not =");case"any":return":";case"not any":return _t(": not");}});const pathDescription=getPathDescription(path);const description={pathDescription,operatorDescription:operatorLabel,valueDescription:null,};if(isTree(node.value)){return description;}
if(["set","not set"].includes(operator)){return description;}
const coModeldisplayNames=displayNames[getResModel(fieldDef)];const dis=disambiguate(value,coModeldisplayNames);let values;if(operator==="in range"){const valueType=value[1];values=[InRange.options.find(([t])=>t===valueType)[1].toString()];}else{values=(Array.isArray(value)?value:[value]).slice(0,limit).map((val,index)=>index<limit-1?formatValue(val,dis,fieldDef,coModeldisplayNames):"...");}
let join;let addParenthesis=Array.isArray(value);switch(operator){case"between":join=_t("and");addParenthesis=false;break;case"in range":join=_t(" ");addParenthesis=false;break;case"in":case"not in":addParenthesis=values.length===0;default:join=_t("or");}
description.valueDescription={values,join,addParenthesis};return description;}
async function getDomainTreeDescription(resModel,tree,isSubExpression=false,limit=undefined,pathLimit=undefined){tree=simplifyTree(tree);if(tree.type==="connector"){const childDescriptions=tree.children.map((node)=>getDomainTreeDescription(resModel,node,true));const separator=tree.value==="&"?_t("and"):_t("or");let description=await Promise.all(childDescriptions);description=description.join(` ${separator} `);if(isSubExpression||tree.negate){description=`( ${description} )`;}
if(tree.negate){description=`! ${description}`;}
return description;}
const getFieldDef=await makeGetFieldDef(resModel,tree);const getConditionDescription=await makeGetConditionDescription(resModel,tree,limit,pathLimit);const{pathDescription,operatorDescription,valueDescription}=getConditionDescription(tree);const stringDescription=[pathDescription,operatorDescription];if(valueDescription){const{values,join,addParenthesis}=valueDescription;const jointedValues=values.join(` ${join} `);stringDescription.push(addParenthesis?`( ${jointedValues} )`:jointedValues);}else if(isTree(tree.value)){const _fieldDef=getFieldDef(tree.path);const _resModel=getResModel(_fieldDef);const _tree=tree.value;const description=await getDomainTreeDescription(_resModel,_tree);stringDescription.push(`( ${description} )`);}
return stringDescription.join(" ");}
async function getTooltipLines(resModel,tree,depth=0){const tabs=" ".repeat(depth*4);tree=simplifyTree(tree);if(tree.type==="connector"){let connector=tree.value==="&"?_t("all"):_t("any");if(tree.negate){connector=tree.value==="&"?_t("not all"):_t("none");}
connector=`${tabs}${connector}`;const childrenTooltipLines=await Promise.all(tree.children.map((node)=>getTooltipLines(resModel,node,depth+1)));return[connector,...childrenTooltipLines].flat();}
const getFieldDef=await makeGetFieldDef(resModel,tree);const getConditionDescription=await makeGetConditionDescription(resModel,tree,20);const{pathDescription,operatorDescription,valueDescription}=getConditionDescription(tree);const descr=[];const stringDescriptions=[pathDescription,operatorDescription];if(valueDescription){const{values,join,addParenthesis}=valueDescription;const jointedValues=values.join(` ${join} `);stringDescriptions.push(addParenthesis?`( ${jointedValues} )`:jointedValues);}
descr.push(`${tabs}${stringDescriptions.join(" ")}`);if(isTree(tree.value)){const _fieldDef=getFieldDef(tree.path);const _resModel=getResModel(_fieldDef);const _tree=tree.value;const tooltipLines=await getTooltipLines(_resModel,_tree,depth+1);descr.push(...tooltipLines);}
return descr;}
async function getDomainTreeTooltip(resModel,tree){const descriptions=await getTooltipLines(resModel,tree);return descriptions.join("\n");}
async function makeGetFieldDef(resModel,tree){const paths=new Set(getPathsInTree(tree,true));const promises=[];const fieldDefs={};for(const path of paths){promises.push(fieldService.loadFieldInfo(resModel,path).then(({fieldDef})=>{fieldDefs[path]=fieldDef;}));}
await Promise.all(promises);return(path)=>{if(typeof path==="string"){return fieldDefs[path];}
return null;};}
async function treeFromDomain(resModel,domain,distributeNot=true){const tree=constructTreeFromDomain(domain,distributeNot);const getFieldDef=await makeGetFieldDef(resModel,tree);return introduceVirtualOperators(tree,{getFieldDef});}
return{getDomainTreeDescription,getDomainTreeTooltip,makeGetConditionDescription,makeGetFieldDef,treeFromDomain,};},};registry.category("services").add("tree_processor",treeProcessorService);return __exports;});;
/* /web/static/src/core/tree_editor/utils.js */
odoo.define('@web/core/tree_editor/utils',[],function(require){'use strict';let __exports={};__exports.disambiguate=disambiguate;function disambiguate(value,displayNames){if(!Array.isArray(value)){return value==="";}
let hasSomeString=false;let hasSomethingElse=false;for(const val of value){if(val===""){return true;}
if(typeof val==="string"||(displayNames&&isId(val))){hasSomeString=true;}else{hasSomethingElse=true;}}
return hasSomeString&&hasSomethingElse;}
__exports.isId=isId;function isId(value){return Number.isInteger(value)&&value>=1;}
__exports.getResModel=getResModel;function getResModel(fieldDef){if(fieldDef){return fieldDef.is_property?fieldDef.comodel:fieldDef.relation;}
return null;}
const SPECIAL_FIELDS=["country_id","user_id","partner_id","stage_id","id"];__exports.getDefaultPath=getDefaultPath;function getDefaultPath(fieldDefs){for(const name of SPECIAL_FIELDS){const fieldDef=fieldDefs[name];if(fieldDef){return fieldDef.name;}}
const name=Object.keys(fieldDefs)[0];if(name){return name;}
throw new Error(`No field found`);}
return __exports;});;
/* /web/static/src/core/tree_editor/virtual_operators.js */
odoo.define('@web/core/tree_editor/virtual_operators',['@web/core/tree_editor/condition_tree'],function(require){'use strict';let __exports={};const{applyTransformations,areEqualTrees,cloneTree,condition,connector,expression,FALSE_TREE,isTree,normalizeValue,operate,rewriteNConsecutiveChildren,TRUE_TREE,}=require("@web/core/tree_editor/condition_tree");function splitPath(path,is_property){if(typeof path!=="string"||path===""){return{initialPath:"",lastPart:""};}
const pathParts=path.split(".");if(is_property&&pathParts.length>=2){return{initialPath:pathParts.slice(0,-2).join("."),lastPart:pathParts.slice(-2).join("."),};}
const lastPart=pathParts.pop()||"";const initialPath=pathParts.join(".");return{initialPath,lastPart};}
function isSimplePath(path,isProperty){return typeof path==="string"&&!splitPath(path,isProperty).initialPath;}
function wrapInAny(tree,initialPath,negate){let con=cloneTree(tree);if(initialPath){con=condition(initialPath,"any",con);}
con.negate=negate;return con;}
function introduceSetOperators(tree,options={}){function _introduceSetOperator(c,options={}){const{negate,path,operator,value}=c;const fieldType=options.getFieldDef?.(path)?.type;if(["=","!="].includes(operator)){if(fieldType){if(fieldType==="boolean"&&value===true){return condition(path,operator==="="?"set":"not set",value,negate);}else if(!["many2one","date","datetime"].includes(fieldType)&&value===false){return condition(path,operator==="="?"not set":"set",value,negate);}}}}
return operate(_introduceSetOperator,tree,options);}
function eliminateSetOperators(tree){function _removeSetOperator(c){const{negate,path,operator,value,isProperty}=c;if(["set","not set"].includes(operator)){if(value===true){return condition(path,operator==="set"?"=":"!=",value,negate,isProperty);}
return condition(path,operator==="set"?"!=":"=",value,negate,isProperty);}}
return operate(_removeSetOperator,tree);}
function introduceStartsWithOperators(tree,options){function _introduceStartsWithOperator(c,options){const{negate,path,operator,value,isProperty}=c;const fieldType=options.getFieldDef?.(path)?.type;if(["char","text","html"].includes(fieldType)&&operator==="=ilike"&&typeof value==="string"){if(value.endsWith("%")){return condition(path,"starts with",value.slice(0,-1),negate,isProperty);}}}
return operate(_introduceStartsWithOperator,tree,options);}
function eliminateStartsWithOperators(tree){function _eliminateStartsWithOperator(c){const{negate,path,operator,value,isProperty}=c;if(operator==="starts with"){return condition(path,"=ilike",`${value}%`,negate,isProperty);}}
return operate(_eliminateStartsWithOperator,tree);}
function isSimpleAnd(c){if(c.type==="connector"&&c.value==="&"&&!c.negate&&c.children.length===2&&c.children.every((child)=>child.type==="condition"&&!child.negate)){return true;}
return false;}
function isBetween(c){if(isSimpleAnd(c)){const[{path:p1,operator:op1,value:value1},{path:p2,operator:op2,value:value2},]=c.children;if(p1===p2&&op1===">="&&op2==="<="){return{path:p1,value1,value2};}}
return false;}
function makeBetween(path,value1,value2,isProperty){return connector("&",[condition(path,">=",value1,false,isProperty),condition(path,"<=",value2,false,isProperty),]);}
function isStrictBetween(c){if(isSimpleAnd(c)){const[{path:p1,operator:op1,value:value1},{path:p2,operator:op2,value:value2},]=c.children;if(p1===p2&&op1===">="&&op2==="<"){return{path:p1,value1,value2};}}
return false;}
function makeStrictBetween(path,value1,value2,isProperty){return connector("&",[condition(path,">=",value1,false,isProperty),condition(path,"<",value2,false,isProperty),]);}
function boundDate(delta){if(!delta){return expression(`context_today().strftime("%Y-%m-%d")`);}
return expression(`(context_today() + relativedelta(${delta})).strftime('%Y-%m-%d')`);}
function boundDatetime(delta){if(!delta){return expression(`datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc().strftime("%Y-%m-%d %H:%M:%S")`);}
return expression(`datetime.datetime.combine(context_today() + relativedelta(${delta}), datetime.time(0, 0, 0)).to_utc().strftime("%Y-%m-%d %H:%M:%S")`);}
const BOUNDS_SMART_DATES=[["today","today","today +1d"],["last 7 days","today -7d","today"],["last 30 days","today -30d","today"],["month to date","today =1d","today +1d"],["last month","today =1d -1m","today =1d"],["year to date","today =1m =1d","today +1d"],["last 12 months","today =1d -12m","today =1d"],];const DELTAS=[["today","","days = 1"],["last 7 days","days = -7",""],["last 30 days","days = -30",""],["month to date","day = 1","days = 1"],["last month","day = 1, months = -1","day = 1"],["year to date","day = 1, month = 1","days = 1"],["last 12 months","day = 1, months = -12","day = 1"],];const BOUNDS_DATE=DELTAS.map(([k,l,r])=>[k,boundDate(l),boundDate(r)]);const BOUNDS_DATETIME=DELTAS.map(([k,l,r])=>[k,boundDatetime(l),boundDatetime(r)]);function getBounds(generateSmartDates,fieldType){return generateSmartDates?BOUNDS_SMART_DATES:fieldType==="date"?BOUNDS_DATE:BOUNDS_DATETIME;}
function introduceInRangeOperators(tree,options={}){function _introduceInRangeOperator(c,options){const res1=isStrictBetween(c);if(res1){const generateSmartDates="generateSmartDates"in options?options.generateSmartDates:true;const{path,value1,value2}=res1;const fieldDef=options.getFieldDef?.(path);const fieldType=fieldDef?.type;const isProperty=fieldDef?.is_property;if(["date","datetime"].includes(fieldType)&&isSimplePath(path,isProperty)){const bounds=getBounds(generateSmartDates,fieldType);for(const[valueType,leftBound,rightBound]of bounds){if(generateSmartDates?value1===leftBound&&value2===rightBound:value1._expr===leftBound._expr&&value2._expr===rightBound._expr){return condition(path,"in range",[fieldType,valueType,false,false],false,isProperty);}}}}
const res2=isBetween(c);if(res2){const{path,value1,value2}=res2;const fieldDef=options.getFieldDef?.(path);const fieldType=fieldDef?.type;const isProperty=fieldDef?.is_property;if(["date","datetime"].includes(fieldType)&&isSimplePath(path,isProperty)){return condition(path,"in range",[fieldType,"custom range",...normalizeValue([value1,value2]),],false,isProperty);}}}
return operate(rewriteNConsecutiveChildren(_introduceInRangeOperator),tree,options,"connector");}
function eliminateInRangeOperators(tree,options={}){function _eliminateInRangeOperator(c,options){const{negate,path,operator,value,isProperty}=c;if(operator!=="in range"){return;}
const{initialPath,lastPart}=splitPath(path,isProperty);const[fieldType,valueType,value1,value2]=value;let tree;if(valueType==="custom range"){tree=makeBetween(lastPart,value1,value2,isProperty);}else{const generateSmartDates="generateSmartDates"in options?options.generateSmartDates:true;const bounds=getBounds(generateSmartDates,fieldType);const[,leftBound,rightBound]=bounds.find(([v])=>v===valueType);tree=makeStrictBetween(lastPart,leftBound,rightBound,isProperty);}
return wrapInAny(tree,initialPath,negate);}
return operate(_eliminateInRangeOperator,tree,options);}
function introduceBetweenOperators(tree,options={}){function _introduceBetweenOperator(c,options){const res=isBetween(c);if(!res){return;}
const{path,value1,value2}=res;const fieldType=options.getFieldDef?.(path)?.type;if(["integer","float","monetary"].includes(fieldType)&&isSimplePath(path)){return condition(path,"between",normalizeValue([value1,value2]));}}
return operate(rewriteNConsecutiveChildren(_introduceBetweenOperator),tree,options,"connector");}
function eliminateBetweenOperators(tree){function _eliminateBetweenOperator(c){const{negate,path,operator,value,isProperty}=c;if(operator!=="between"){return;}
const{initialPath,lastPart}=splitPath(path,isProperty);return wrapInAny(makeBetween(lastPart,value[0],value[1],isProperty),initialPath,negate);}
return operate(_eliminateBetweenOperator,tree);}
function _eliminateAnyOperator(c){const{path,operator,value,negate}=c;if(operator==="any"&&isTree(value)&&value.type==="condition"&&typeof path==="string"&&typeof value.path==="string"&&!negate&&!value.negate&&["between","in range"].includes(value.operator)){return condition(`${path}.${value.path}`,value.operator,value.value,false,value.isProperty);}}
function eliminateAnyOperators(tree){return operate(_eliminateAnyOperator,tree);}
function removeFalseTrueLeaves(tree){function _removeFalseTrueLeave(c){const{path,operator,value,negate,isProperty}=c;if(areEqualTrees(condition(path,operator,value,false,isProperty),FALSE_TREE)){return connector(negate?"&":"|",[]);}
if(areEqualTrees(condition(path,operator,value,false,isProperty),TRUE_TREE)){return connector(negate?"|":"&",[]);}}
return operate(_removeFalseTrueLeave,tree);}
__exports.introduceVirtualOperators=introduceVirtualOperators;function introduceVirtualOperators(tree,options={}){return applyTransformations([eliminateAnyOperators,introduceSetOperators,introduceStartsWithOperators,introduceBetweenOperators,introduceInRangeOperators,],tree,options);}
__exports.eliminateVirtualOperators=eliminateVirtualOperators;function eliminateVirtualOperators(tree,options={}){return applyTransformations([eliminateInRangeOperators,eliminateBetweenOperators,eliminateStartsWithOperators,eliminateSetOperators,],tree,options);}
__exports.areEquivalentTrees=areEquivalentTrees;function areEquivalentTrees(tree,otherTree){const simplifiedTree=removeFalseTrueLeaves(eliminateVirtualOperators(tree));const otherSimplifiedTree=removeFalseTrueLeaves(eliminateVirtualOperators(otherTree));return areEqualTrees(simplifiedTree,otherSimplifiedTree);}
return __exports;});;
/* /web/static/src/core/ui/block_ui.js */
odoo.define('@web/core/ui/block_ui',['@web/core/l10n/translation','@web/core/browser/browser','@odoo/owl'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{browser}=require("@web/core/browser/browser");const{EventBus,Component,useState}=require("@odoo/owl");const BlockUI=__exports.BlockUI=class BlockUI extends Component{static props={bus:EventBus,};static template="web.BlockUI";setup(){this.messagesByDuration=[{time:20,l1:_t("Loading...")},{time:40,l1:_t("Still loading...")},{time:60,l1:_t("Still loading..."),l2:_t("Please be patient."),},{time:180,l1:_t("Don't leave yet,"),l2:_t("it's still loading..."),},{time:120,l1:_t("You may not believe it,"),l2:_t("but the application is actually loading..."),},{time:3180,l1:_t("Take a minute to get a coffee,"),l2:_t("because it's loading..."),},{time:null,l1:_t("Maybe you should consider reloading the application by pressing F5..."),},];this.BLOCK_STATES={UNBLOCKED:0,BLOCKED:1,VISIBLY_BLOCKED:2};this.state=useState({blockState:this.BLOCK_STATES.UNBLOCKED,line1:"",line2:"",});this.props.bus.addEventListener("BLOCK",this.block.bind(this));this.props.bus.addEventListener("UNBLOCK",this.unblock.bind(this));}
replaceMessage(index){const message=this.messagesByDuration[index];this.state.line1=message.l1;this.state.line2=message.l2||"";if(message.time!==null){this.msgTimer=browser.setTimeout(()=>{this.replaceMessage(index+1);},message.time*1000);}}
block(ev){const showBlockedUI=()=>(this.state.blockState=this.BLOCK_STATES.VISIBLY_BLOCKED);const delay=ev.detail?.delay;if(delay){this.state.blockState=this.BLOCK_STATES.BLOCKED;this.showBlockedUITimer=setTimeout(showBlockedUI,delay);}else{showBlockedUI();}
if(ev.detail?.message){this.state.line1=ev.detail.message;}else{this.replaceMessage(0);}}
unblock(){this.state.blockState=this.BLOCK_STATES.UNBLOCKED;clearTimeout(this.showBlockedUITimer);clearTimeout(this.msgTimer);this.state.line1="";this.state.line2="";}}
return __exports;});;
/* /web/static/src/core/ui/ui_service.js */
odoo.define('@web/core/ui/ui_service',['@web/core/utils/hooks','@web/core/registry','@web/core/utils/timing','@web/core/ui/block_ui','@web/core/browser/browser','@web/core/utils/ui','@web/core/hotkeys/hotkey_service','@odoo/owl'],function(require){'use strict';let __exports={};const{useService}=require("@web/core/utils/hooks");const{registry}=require("@web/core/registry");const{throttleForAnimation}=require("@web/core/utils/timing");const{BlockUI}=require("@web/core/ui/block_ui");const{browser}=require("@web/core/browser/browser");const{getTabableElements,isFocusable}=require("@web/core/utils/ui");const{getActiveHotkey}=require("@web/core/hotkeys/hotkey_service");const{EventBus,reactive,useEffect,useRef}=require("@odoo/owl");const SIZES=__exports.SIZES={XS:0,SM:1,MD:2,LG:3,XL:4,XXL:5};__exports.getFirstAndLastTabableElements=getFirstAndLastTabableElements;function getFirstAndLastTabableElements(el){const tabableEls=getTabableElements(el);return[tabableEls[0],tabableEls[tabableEls.length-1]];}
__exports.useActiveElement=useActiveElement;function useActiveElement(refName){if(!refName){throw new Error("refName not given to useActiveElement");}
const uiService=useService("ui");const ref=useRef(refName);function trapFocus(e){const hotkey=getActiveHotkey(e);if(!["tab","shift+tab"].includes(hotkey)){return;}
const el=e.currentTarget;const[firstTabableEl,lastTabableEl]=getFirstAndLastTabableElements(el);if(!firstTabableEl&&!lastTabableEl){e.preventDefault();e.stopPropagation();return;}
switch(hotkey){case"tab":if(document.activeElement===lastTabableEl){firstTabableEl.focus();e.preventDefault();e.stopPropagation();}
break;case"shift+tab":if(document.activeElement===firstTabableEl){lastTabableEl.focus();e.preventDefault();e.stopPropagation();}
break;}}
useEffect((el)=>{if(el){const[firstTabableEl]=getFirstAndLastTabableElements(el);if(!firstTabableEl&&!isFocusable(el)){return;}
const oldActiveElement=document.activeElement;uiService.activateElement(el);el.addEventListener("keydown",trapFocus);if(firstTabableEl){if(!el.contains(document.activeElement)){firstTabableEl.focus();}}else if(el!==document.activeElement){el.focus();}
return async()=>{await Promise.resolve();uiService.deactivateElement(el);el.removeEventListener("keydown",trapFocus);if(el.contains(document.activeElement)||document.activeElement===document.body){oldActiveElement.focus();}};}},()=>[ref.el]);}
const MEDIAS_BREAKPOINTS=__exports.MEDIAS_BREAKPOINTS=[{maxWidth:575},{minWidth:576,maxWidth:767},{minWidth:768,maxWidth:991},{minWidth:992,maxWidth:1199},{minWidth:1200,maxWidth:1399},{minWidth:1400},];__exports.getMediaQueryLists=getMediaQueryLists;function getMediaQueryLists(){return MEDIAS_BREAKPOINTS.map(({minWidth,maxWidth})=>{if(!maxWidth){return window.matchMedia(`(min-width: ${minWidth}px)`);}
if(!minWidth){return window.matchMedia(`(max-width: ${maxWidth}px)`);}
return window.matchMedia(`(min-width: ${minWidth}px) and (max-width: ${maxWidth}px)`);});}
const MEDIAS=getMediaQueryLists();const utils=__exports.utils={getSize(){return MEDIAS.findIndex((media)=>media.matches);},isSmall(ui={}){return(ui.size||utils.getSize())<=SIZES.SM;},};const bus=new EventBus();__exports.listenSizeChange=listenSizeChange;function listenSizeChange(callback){bus.addEventListener("resize",callback);return()=>bus.removeEventListener("resize",callback);}
const uiService=__exports.uiService={start(env){registry.category("main_components").add("BlockUI",{Component:BlockUI,props:{bus}});let blockCount=0;function block(data){blockCount++;if(blockCount===1){bus.trigger("BLOCK",{message:data?.message,delay:data?.delay,});}}
function unblock(){blockCount--;if(blockCount<0){console.warn("Unblock ui was called more times than block, you should only unblock the UI if you have previously blocked it.");blockCount=0;}
if(blockCount===0){bus.trigger("UNBLOCK");}}
let activeElems=[document];function activateElement(el){activeElems.push(el);bus.trigger("active-element-changed",el);}
function deactivateElement(el){activeElems=activeElems.filter((x)=>x!==el);bus.trigger("active-element-changed",ui.activeElement);}
function getActiveElementOf(el){for(const activeElement of[...activeElems].reverse()){if(activeElement.contains(el)){return activeElement;}}}
const ui=reactive({bus,size:utils.getSize(),get activeElement(){return activeElems[activeElems.length-1];},get isBlocked(){return blockCount>0;},isSmall:utils.isSmall(),block,unblock,activateElement,deactivateElement,getActiveElementOf,});const updateSize=()=>{const prevSize=ui.size;ui.size=utils.getSize();if(ui.size!==prevSize){ui.isSmall=utils.isSmall(ui);bus.trigger("resize");}};browser.addEventListener("resize",throttleForAnimation(updateSize));Object.defineProperty(env,"isSmall",{get(){return ui.isSmall;},});return ui;},};registry.category("services").add("ui",uiService);return __exports;});;
/* /web/static/src/core/user.js */
odoo.define('@web/core/user',['@web/core/browser/browser','@web/core/l10n/utils/locales','@web/core/network/rpc','@web/core/utils/cache','@web/session','@web/core/utils/arrays','@web/core/browser/cookie','@odoo/owl'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{pyToJsLocale}=require("@web/core/l10n/utils/locales");const{rpc}=require("@web/core/network/rpc");const{Cache}=require("@web/core/utils/cache");const{session}=require("@web/session");const{ensureArray,sortBy}=require("@web/core/utils/arrays");const{cookie}=require("@web/core/browser/cookie");const{EventBus}=require("@odoo/owl");const userBus=__exports.userBus=new EventBus();function getCookieCompanyIds(){if(cookie.get("cids")){const cids=cookie.get("cids");if(typeof cids==="string"){return cids.split("-").map(Number);}
if(typeof cids==="number"){return[cids];}}
return[];}
__exports._makeUser=_makeUser;function _makeUser(session){const{home_action_id:homeActionId,is_admin:isAdmin,is_internal_user:isInternalUser,is_system:isSystem,is_public:isPublic,name,partner_id:partnerId,show_effect:showEffect,uid:userId,username:login,user_context:context,user_settings,partner_write_date:writeDate,user_companies:userCompanies,groups={},}=session;const settings=user_settings||{};function updateActiveCompanies(cids,allowedCompanies,defaultCompanyId){activeCompanies=[];cids.forEach((cid)=>{activeCompanies.push(allowedCompanies.find((c)=>c.id===cid));});if(activeCompanies.length===0||activeCompanies.length!==activeCompanies.filter(Boolean).length){activeCompanies=[defaultCompanyId];}
activeCompanies=[activeCompanies[0]].concat(sortBy(activeCompanies.slice(1),(c)=>c.id));cookie.set("cids",activeCompanies.map((c)=>c.id).join("-"));Object.assign(context,{allowed_company_ids:activeCompanies.map((c)=>c.id)});userBus.trigger("ACTIVE_COMPANIES_CHANGED");}
let allowedCompanies=[];const allowedCompaniesWithAncestors=[];let activeCompanies=[];let defaultCompany;if(userCompanies){allowedCompanies=Object.values(userCompanies.allowed_companies);allowedCompaniesWithAncestors.push(...Object.values(userCompanies.allowed_companies));if(userCompanies.disallowed_ancestor_companies){allowedCompaniesWithAncestors.push(...Object.values(userCompanies.disallowed_ancestor_companies));}
defaultCompany=allowedCompanies.find((c)=>c.id===userCompanies.current_company);updateActiveCompanies(getCookieCompanyIds(),allowedCompanies,defaultCompany);}
delete session.home_action_id;delete session.is_admin;delete session.is_internal_user;delete session.is_system;delete session.name;delete session.partner_id;delete session.show_effect;delete session.uid;delete session.username;delete session.user_context;delete session.user_settings;delete session.partner_write_date;delete session.user_companies;delete session.groups;const getGroupCacheValue=(group,context)=>{if(!userId){return Promise.resolve(false);}
return rpc("/web/dataset/call_kw/res.users/has_group",{model:"res.users",method:"has_group",args:[userId,group],kwargs:{context},});};const getGroupCacheKey=(group)=>group;const groupCache=new Cache(getGroupCacheValue,getGroupCacheKey);if(isInternalUser!==undefined){groupCache.cache["base.group_user"]=Promise.resolve(isInternalUser);}
if(isSystem!==undefined){groupCache.cache["base.group_system"]=Promise.resolve(isSystem);}
if(isAdmin!==undefined){groupCache.cache["base.group_erp_manager"]=Promise.resolve(isAdmin);}
if(isPublic!==undefined){groupCache.cache["base.group_public"]=Promise.resolve(isPublic);}
for(const group in groups){groupCache.cache[group]=Promise.resolve(!!groups[group]);}
const getAccessRightCacheValue=(model,operation,ids,context)=>{const url=`/web/dataset/call_kw/${model}/has_access`;return rpc(url,{model,method:"has_access",args:[ids,operation],kwargs:{context},});};const getAccessRightCacheKey=(model,operation,ids)=>JSON.stringify([model,operation,ids]);const accessRightCache=new Cache(getAccessRightCacheValue,getAccessRightCacheKey);const lang=pyToJsLocale(context?.lang);return{name,login,isAdmin,isSystem,isInternalUser,partnerId,homeActionId,showEffect,userId,writeDate,get context(){return Object.assign({},context,{uid:this.userId});},get lang(){return lang;},get tz(){return this.context.tz;},get settings(){return Object.assign({},settings);},updateContext(update){Object.assign(context,update);},hasGroup(group){return groupCache.read(group,this.context);},checkAccessRight(model,operation,ids=[]){return accessRightCache.read(model,operation,ensureArray(ids),this.context);},async setUserSettings(key,value){const model="res.users.settings";const method="set_res_users_settings";const changedSettings=await rpc(`/web/dataset/call_kw/${model}/${method}`,{model,method,args:[[this.settings.id]],kwargs:{new_settings:{[key]:value,},context:this.context,},});Object.assign(settings,changedSettings);},updateUserSettings(key,value){settings[key]=value;},defaultCompany,allowedCompanies,allowedCompaniesWithAncestors,get activeCompanies(){return activeCompanies;},get activeCompany(){return activeCompanies?.[0];},async activateCompanies(companyIds,options={includeChildCompanies:true,reload:true}){const newCompanyIds=companyIds.length?companyIds:[activeCompanies[0].id];function addCompanies(companyIds){for(const companyId of companyIds){if(!newCompanyIds.includes(companyId)){newCompanyIds.push(companyId);addCompanies(allowedCompanies.find((c)=>c.id===companyId).child_ids);}}}
if(options.includeChildCompanies){addCompanies(companyIds.flatMap((companyId)=>allowedCompanies.find((c)=>c.id===companyId).child_ids));}
updateActiveCompanies(newCompanyIds,allowedCompanies,defaultCompany);if(options.reload){browser.location.reload();}},};}
const user=__exports.user=_makeUser(session);const LAST_CONNECTED_USER_KEY="web.lastConnectedUser";const getLastConnectedUsers=__exports.getLastConnectedUsers=()=>{const lastConnectedUsers=browser.localStorage.getItem(LAST_CONNECTED_USER_KEY);return lastConnectedUsers?JSON.parse(lastConnectedUsers):[];};const setLastConnectedUsers=__exports.setLastConnectedUsers=(users)=>{browser.localStorage.setItem(LAST_CONNECTED_USER_KEY,JSON.stringify(users.slice(0,5)));};if(!session.quick_login){browser.localStorage.removeItem(LAST_CONNECTED_USER_KEY);}else if(user.login&&user.login!=="__system__"){const users=getLastConnectedUsers();const lastConnectedUsers=[{login:user.login,name:user.name,partnerId:user.partnerId,partnerWriteDate:user.writeDate,userId:user.userId,},...users.filter((u)=>u.userId!==user.userId),];setLastConnectedUsers(lastConnectedUsers);}
delete session.quick_login;return __exports;});;
/* /web/static/src/core/user_switch/user_switch.js */
odoo.define('@web/core/user_switch/user_switch',['@odoo/owl','@web/core/registry','@web/core/user','@web/core/utils/urls'],function(require){'use strict';let __exports={};const{Component,useRef,useState,useEffect}=require("@odoo/owl");const{registry}=require("@web/core/registry");const{getLastConnectedUsers,setLastConnectedUsers}=require("@web/core/user");const{imageUrl}=require("@web/core/utils/urls");const UserSwitch=__exports.UserSwitch=class UserSwitch extends Component{static template="web.login_user_switch";static props={};setup(){const users=getLastConnectedUsers();this.root=useRef("root");this.state=useState({users,displayUserChoice:users.length>1,});this.form=document.querySelector("form.oe_login_form");this.form.classList.toggle("d-none",users.length>1);this.form.querySelector(":placeholder-shown")?.focus();useEffect((el)=>el?.querySelector("button.list-group-item-action")?.focus(),()=>[this.root.el]);}
toggleFormDisplay(){this.state.displayUserChoice=!this.state.displayUserChoice&&this.state.users.length;this.form.classList.toggle("d-none",this.state.displayUserChoice);this.form.querySelector(":placeholder-shown")?.focus();}
getAvatarUrl({partnerId,partnerWriteDate:unique}){return imageUrl("res.partner",partnerId,"avatar_128",{unique});}
remove(deletedUser){this.state.users=this.state.users.filter((user)=>user!==deletedUser);setLastConnectedUsers(this.state.users);if(!this.state.users.length){this.fillForm();}}
fillForm(login=""){this.form.querySelector("input#login").value=login;this.form.querySelector("input#password").value="";this.toggleFormDisplay();}}
registry.category("public_components").add("web.user_switch",UserSwitch);return __exports;});;
/* /web/static/src/core/utils/arrays.js */
odoo.define('@web/core/utils/arrays',['@web/core/utils/objects'],function(require){'use strict';let __exports={};const{shallowEqual:_shallowEqual}=require("@web/core/utils/objects");function _cartesian(...args){if(args.length===0){return[undefined];}
const firstArray=args.shift().map((elem)=>[elem]);if(args.length===0){return firstArray;}
const result=[];const productOfOtherArrays=_cartesian(...args);for(const array of firstArray){for(const tuple of productOfOtherArrays){result.push([...array,...tuple]);}}
return result;}
function _getExtractorFrom(criterion){if(criterion){switch(typeof criterion){case"string":return(element)=>element[criterion];case"function":return criterion;default:throw new Error(`Expected criterion of type 'string' or 'function' and got '${typeof criterion}'`);}}else{return(element)=>element;}}
__exports.ensureArray=ensureArray;function ensureArray(value){return isIterable(value)?[...value]:[value];}
__exports.intersection=intersection;function intersection(iter1,iter2){const set2=new Set(iter2);return unique(iter1).filter((v)=>set2.has(v));}
__exports.isIterable=isIterable;function isIterable(value){return Boolean(value&&typeof value==="object"&&value[Symbol.iterator]);}
__exports.groupBy=groupBy;function groupBy(iterable,criterion){const extract=_getExtractorFrom(criterion);const groups={};for(const element of iterable){const group=String(extract(element));if(!(group in groups)){groups[group]=[];}
groups[group].push(element);}
return groups;}
__exports.sortBy=sortBy;function sortBy(iterable,criterion,order="asc"){const extract=_getExtractorFrom(criterion);return[...iterable].sort((elA,elB)=>{const a=extract(elA);const b=extract(elB);let result;if(isNaN(a)&&isNaN(b)){result=a>b?1:a<b?-1:0;}else{result=a-b;}
return order==="asc"?result:-result;});}
__exports.symmetricalDifference=symmetricalDifference;function symmetricalDifference(iter1,iter2){const array1=[...iter1];const array2=[...iter2];return[...array1.filter((value)=>!array2.includes(value)),...array2.filter((value)=>!array1.includes(value)),];}
__exports.cartesian=cartesian;function cartesian(...args){if(args.length===0){return[undefined];}else if(args.length===1){return args[0];}else{return _cartesian(...args);}}
const shallowEqual=__exports.shallowEqual=_shallowEqual;__exports.sections=sections;function sections(iterable){const array=[...iterable];const sections=[];for(let i=0;i<array.length+1;i++){sections.push(array.slice(0,i));}
return sections;}
__exports.unique=unique;function unique(iterable){return[...new Set(iterable)];}
__exports.zip=zip;function zip(iter1,iter2,fill=false){const array1=[...iter1];const array2=[...iter2];const result=[];const getLength=fill?Math.max:Math.min;for(let i=0;i<getLength(array1.length,array2.length);i++){result.push([array1[i],array2[i]]);}
return result;}
__exports.zipWith=zipWith;function zipWith(iter1,iter2,mapFn){return zip(iter1,iter2).map(([e1,e2])=>mapFn(e1,e2));}
__exports.slidingWindow=slidingWindow;function slidingWindow(arr,width){const res=[];for(let i=0;i<=arr.length-width;i++){res.push(arr.slice(i,i+width));}
return res;}
__exports.rotate=rotate;function rotate(i,arr,inc=1){return(arr.length+i+inc)%arr.length;}
return __exports;});;
/* /web/static/src/core/utils/autoresize.js */
odoo.define('@web/core/utils/autoresize',['@odoo/owl','@web/core/utils/functions'],function(require){'use strict';let __exports={};const{useEffect}=require("@odoo/owl");const{memoize}=require("@web/core/utils/functions");__exports.useAutoresize=useAutoresize;function useAutoresize(ref,options={}){let wasProgrammaticallyResized=false;let resize=null;useEffect((el)=>{if(el){resize=(programmaticResize=false)=>{wasProgrammaticallyResized=programmaticResize;if(options.ignoreIfEmpty&&!el.value){return;}
if(el instanceof HTMLInputElement){resizeInput(el);}else{resizeTextArea(el,options);}
options.onResize?.(el,options);};el.addEventListener("input",()=>resize(true));const resizeObserver=new ResizeObserver(()=>{if(wasProgrammaticallyResized){wasProgrammaticallyResized=false;return;}
resize();});resizeObserver.observe(el);return()=>{el.removeEventListener("input",resize);resizeObserver.unobserve(el);resizeObserver.disconnect();resize=null;};}},()=>[ref.el]);useEffect(()=>{if(resize){resize(true);}});}
const doesScrollWidthExcludePadding=memoize(()=>{const input=document.createElement("input");input.style.cssText=`
position: absolute;
visibility: hidden;
padding: 0;
border: 0;
width: auto;
`;document.body.appendChild(input);const widthWithoutPadding=input.scrollWidth;input.style.padding="10px";const widthWithPadding=input.scrollWidth;input.remove();return widthWithPadding===widthWithoutPadding;});function resizeInput(input){const style=window.getComputedStyle(input);input.style.width="100%";const maxWidth=input.clientWidth;input.style.width="10px";if(input.value===""&&input.placeholder!==""){input.style.width="auto";return;}
let boxExtraWidth=parseFloat(style.borderLeftWidth)+parseFloat(style.borderRightWidth);if(doesScrollWidthExcludePadding()){const padding=parseFloat(style.paddingLeft)+parseFloat(style.paddingRight);boxExtraWidth+=padding;}
const desiredWidth=input.scrollWidth+boxExtraWidth+1;if(desiredWidth>maxWidth){input.style.width="100%";return;}
input.style.width=`${desiredWidth}px`;}
__exports.resizeTextArea=resizeTextArea;function resizeTextArea(textarea,options={}){const minimumHeight=options.minimumHeight||0;let heightOffset=0;const style=window.getComputedStyle(textarea);if(style.boxSizing==="border-box"){const paddingHeight=parseFloat(style.paddingTop)+parseFloat(style.paddingBottom);const borderHeight=parseFloat(style.borderTopWidth)+parseFloat(style.borderBottomWidth);heightOffset=borderHeight+paddingHeight;}
const previousStyle={borderTopWidth:style.borderTopWidth,borderBottomWidth:style.borderBottomWidth,padding:style.padding,};Object.assign(textarea.style,{height:"auto",borderTopWidth:0,borderBottomWidth:0,paddingTop:0,paddingBottom:0,});textarea.style.height="auto";const height=Math.max(minimumHeight,textarea.scrollHeight+heightOffset);Object.assign(textarea.style,previousStyle,{height:`${height}px`});textarea.parentElement.style.height=`${height}px`;}
return __exports;});;
/* /web/static/src/core/utils/binary.js */
odoo.define('@web/core/utils/binary',['@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);__exports.isBinarySize=isBinarySize;function isBinarySize(value){return/^\d+(\.\d*)? [^0-9]+$/.test(value);}
__exports.toBase64Length=toBase64Length;function toBase64Length(maxBytes){return Math.ceil(maxBytes*4/3);}
__exports.humanSize=humanSize;function humanSize(size){const units=_t("Bytes|Kb|Mb|Gb|Tb|Pb|Eb|Zb|Yb").split("|");let i=0;while(size>=1024){size/=1024;++i;}
return`${size.toFixed(2)} ${units[i].trim()}`;}
return __exports;});;
/* /web/static/src/core/utils/cache.js */
odoo.define('@web/core/utils/cache',[],function(require){'use strict';let __exports={};const Cache=__exports.Cache=class Cache{constructor(getValue,getKey){this.cache={};this.getKey=getKey;this.getValue=getValue;}
_getCacheAndKey(...path){let cache=this.cache;let key;if(this.getKey){key=this.getKey(...path);}else{for(let i=0;i<path.length-1;i++){cache=cache[path[i]]=cache[path[i]]||{};}
key=path[path.length-1];}
return{cache,key};}
clear(...path){const{cache,key}=this._getCacheAndKey(...path);delete cache[key];}
invalidate(){this.cache={};}
read(...path){const{cache,key}=this._getCacheAndKey(...path);if(!(key in cache)){cache[key]=this.getValue(...path);}
return cache[key];}}
return __exports;});;
/* /web/static/src/core/utils/classname.js */
odoo.define('@web/core/utils/classname',[],function(require){'use strict';let __exports={};__exports.addClassesToElement=addClassesToElement;function addClassesToElement(el,...classes){for(const classDefinition of classes){const classObj=toClassObj(classDefinition);for(const className in classObj){if(classObj[className]){el.classList.add(className.trim());}}}}
__exports.mergeClasses=mergeClasses;function mergeClasses(...classes){const classObj={};for(const classDefinition of classes){Object.assign(classObj,toClassObj(classDefinition));}
return classObj;}
function toClassObj(classDefinition){if(!classDefinition){return{};}else if(typeof classDefinition==="object"){return classDefinition;}else if(typeof classDefinition==="string"){const classObj={};classDefinition.trim().split(/\s+/).forEach((s)=>{classObj[s]=true;});return classObj;}else{console.warn(`toClassObj only supports strings, objects and undefined className (got ${typeof classProp})`);return{};}}
return __exports;});;
/* /web/static/src/core/utils/colors.js */
odoo.define('@web/core/utils/colors',[],function(require){'use strict';let __exports={};__exports.applyOpacityToGradient=applyOpacityToGradient;function applyOpacityToGradient(gradient,opacity=100){if(opacity===100){return gradient;}
return gradient.replace(/rgb\(([^)]+)\)/g,`rgba($1, ${opacity / 100.0})`);}
__exports.convertRgbToHsl=convertRgbToHsl;function convertRgbToHsl(r,g,b){if(typeof r!=="number"||isNaN(r)||r<0||r>255||typeof g!=="number"||isNaN(g)||g<0||g>255||typeof b!=="number"||isNaN(b)||b<0||b>255){return false;}
var red=r/255;var green=g/255;var blue=b/255;var maxColor=Math.max(red,green,blue);var minColor=Math.min(red,green,blue);var delta=maxColor-minColor;var hue=0;var saturation=0;var lightness=(maxColor+minColor)/2;if(delta){if(maxColor===red){hue=(green-blue)/delta;}
if(maxColor===green){hue=2+(blue-red)/delta;}
if(maxColor===blue){hue=4+(red-green)/delta;}
if(maxColor){saturation=delta/(1-Math.abs(2*lightness-1));}}
hue=60*hue;return{hue:hue<0?hue+360:hue,saturation:saturation*100,lightness:lightness*100,};}
__exports.convertHslToRgb=convertHslToRgb;function convertHslToRgb(h,s,l){if(typeof h!=="number"||isNaN(h)||h<0||h>360||typeof s!=="number"||isNaN(s)||s<0||s>100||typeof l!=="number"||isNaN(l)||l<0||l>100){return false;}
var huePrime=h/60;var saturation=s/100;var lightness=l/100;var chroma=saturation*(1-Math.abs(2*lightness-1));var secondComponent=chroma*(1-Math.abs((huePrime%2)-1));var lightnessAdjustment=lightness-chroma/2;var precision=255;chroma=Math.round((chroma+lightnessAdjustment)*precision);secondComponent=Math.round((secondComponent+lightnessAdjustment)*precision);lightnessAdjustment=Math.round(lightnessAdjustment*precision);if(huePrime>=0&&huePrime<1){return{red:chroma,green:secondComponent,blue:lightnessAdjustment,};}
if(huePrime>=1&&huePrime<2){return{red:secondComponent,green:chroma,blue:lightnessAdjustment,};}
if(huePrime>=2&&huePrime<3){return{red:lightnessAdjustment,green:chroma,blue:secondComponent,};}
if(huePrime>=3&&huePrime<4){return{red:lightnessAdjustment,green:secondComponent,blue:chroma,};}
if(huePrime>=4&&huePrime<5){return{red:secondComponent,green:lightnessAdjustment,blue:chroma,};}
if(huePrime>=5&&huePrime<=6){return{red:chroma,green:lightnessAdjustment,blue:secondComponent,};}
return false;}
__exports.convertRgbaToCSSColor=convertRgbaToCSSColor;function convertRgbaToCSSColor(r,g,b,a){if(typeof r!=="number"||isNaN(r)||r<0||r>255||typeof g!=="number"||isNaN(g)||g<0||g>255||typeof b!=="number"||isNaN(b)||b<0||b>255){return false;}
const rr=r<16?"0"+r.toString(16):r.toString(16);const gg=g<16?"0"+g.toString(16):g.toString(16);const bb=b<16?"0"+b.toString(16):b.toString(16);if(typeof a!=="number"||isNaN(a)||a<0||a>100||Math.abs(a-100)<Number.EPSILON){return`#${rr}${gg}${bb}`.toUpperCase();}
const alpha=Math.round((a/100)*255);const aa=alpha<16?"0"+alpha.toString(16):alpha.toString(16);return`#${rr}${gg}${bb}${aa}`.toUpperCase();}
__exports.convertCSSColorToRgba=convertCSSColorToRgba;function convertCSSColorToRgba(cssColor=""){const rgba=cssColor.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d*(?:\.\d+)?))?\)$/);if(rgba){if(rgba[4]===undefined){rgba[4]=1;}
return{red:parseInt(rgba[1]),green:parseInt(rgba[2]),blue:parseInt(rgba[3]),opacity:Math.round(parseFloat(rgba[4])*100),};}
if(/^#([0-9a-f]{3})$/i.test(cssColor)){return{red:parseInt(cssColor[1]+cssColor[1],16),green:parseInt(cssColor[2]+cssColor[2],16),blue:parseInt(cssColor[3]+cssColor[3],16),opacity:100,};}
if(/^#([0-9A-F]{6}|[0-9A-F]{8})$/i.test(cssColor)){return{red:parseInt(cssColor.substr(1,2),16),green:parseInt(cssColor.substr(3,2),16),blue:parseInt(cssColor.substr(5,2),16),opacity:(cssColor.length===9?parseInt(cssColor.substr(7,2),16)/255:1)*100,};}
if(/color\(.+\)/.test(cssColor)){const canvasEl=document.createElement("canvas");canvasEl.height=1;canvasEl.width=1;const ctx=canvasEl.getContext("2d");ctx.fillStyle=cssColor;ctx.fillRect(0,0,1,1);const data=ctx.getImageData(0,0,1,1).data;return{red:data[0],green:data[1],blue:data[2],opacity:data[3]/2.55,};}
return false;}
__exports.normalizeCSSColor=normalizeCSSColor;function normalizeCSSColor(cssColor){const rgba=convertCSSColorToRgba(cssColor);if(!rgba){return cssColor;}
return convertRgbaToCSSColor(rgba.red,rgba.green,rgba.blue,rgba.opacity);}
__exports.isCSSColor=isCSSColor;function isCSSColor(cssColor){return convertCSSColorToRgba(cssColor)!==false;}
__exports.mixCssColors=mixCssColors;function mixCssColors(cssColor1,cssColor2,weight){const rgba1=convertCSSColorToRgba(cssColor1);const rgba2=convertCSSColorToRgba(cssColor2);const rgb1=[rgba1.red,rgba1.green,rgba1.blue];const rgb2=[rgba2.red,rgba2.green,rgba2.blue];const[r,g,b]=rgb1.map((_,idx)=>Math.round(rgb2[idx]+(rgb1[idx]-rgb2[idx])*weight));return convertRgbaToCSSColor(r,g,b);}
__exports.isColorGradient=isColorGradient;function isColorGradient(value){return value&&value.includes("-gradient(");}
__exports.standardizeGradient=standardizeGradient;function standardizeGradient(gradient){if(isColorGradient(gradient)){const el=document.createElement("div");el.style.setProperty("background-image",gradient);gradient=el.style.getPropertyValue("background-image");}
return gradient;}
const RGBA_REGEX=__exports.RGBA_REGEX=/[\d.]{1,5}/g;__exports.rgbToHex=rgbToHex;function rgbToHex(rgb="",node=null){if(rgb.startsWith("#")){return rgb;}else if(rgb.startsWith("rgba")){const values=rgb.match(RGBA_REGEX)||[];const alpha=parseFloat(values.pop());let bgRgbValues=[];if(node){let bgColor=getComputedStyle(node).backgroundColor;if(bgColor.startsWith("rgba")){bgColor=rgbToHex(bgColor,node.parentElement);}
if(bgColor&&bgColor.startsWith("#")){bgRgbValues=(bgColor.match(/[\da-f]{2}/gi)||[]).map((val)=>parseInt(val,16));}else if(bgColor&&bgColor.startsWith("rgb")){bgRgbValues=(bgColor.match(RGBA_REGEX)||[]).map((val)=>parseInt(val));}}
bgRgbValues=bgRgbValues.length?bgRgbValues:[255,255,255];return("#"+
values.map((value,index)=>{const converted=Math.floor(alpha*parseInt(value)+(1-alpha)*bgRgbValues[index]);const hex=parseInt(converted).toString(16);return hex.length===1?"0"+hex:hex;}).join(""));}else{return("#"+
(rgb.match(/\d{1,3}/g)||[]).map((x)=>{x=parseInt(x).toString(16);return x.length===1?"0"+x:x;}).join(""));}}
__exports.rgbaToHex=rgbaToHex;function rgbaToHex(rgba=""){if(rgba.startsWith("#")){return rgba;}else if(rgba.startsWith("rgba")){const values=rgba.match(RGBA_REGEX)||[];return convertRgbaToCSSColor(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]),parseFloat(values[3])*100);}else{return rgbToHex(rgba);}}
__exports.blendColors=blendColors;function blendColors(color,node){if(!color.startsWith("rgba")){return rgbaToHex(color);}
let bgRgbValues=[255,255,255];if(node){let bgColor=getComputedStyle(node).backgroundColor;if(bgColor.startsWith("rgba")){bgColor=blendColors(bgColor,node.parentElement);}
if(bgColor.startsWith("#")){bgRgbValues=(bgColor.match(/[\da-f]{2}/gi)||[]).map((val)=>parseInt(val,16));}else if(bgColor.startsWith("rgb")){bgRgbValues=(bgColor.match(/[\d.]{1,5}/g)||[]).map((val)=>parseInt(val));}}
const values=color.match(/[\d.]{1,5}/g)||[];const alpha=values.length===4?parseFloat(values.pop()):1;return("#"+
values.map((value,index)=>{const converted=Math.round(alpha*parseInt(value)+(1-alpha)*bgRgbValues[index]);const hex=parseInt(converted).toString(16);return hex.length===1?"0"+hex:hex;}).join(""));}
return __exports;});;
/* /web/static/src/core/utils/components.js */
odoo.define('@web/core/utils/components',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component,onError,xml}=require("@odoo/owl");const ErrorHandler=__exports.ErrorHandler=class ErrorHandler extends Component{static template=xml`<t t-slot="default" />`;static props=["onError","slots"];setup(){onError((error)=>{this.props.onError(error);});}}
return __exports;});;
/* /web/static/src/core/utils/concurrency.js */
odoo.define('@web/core/utils/concurrency',[],function(require){'use strict';let __exports={};__exports.delay=delay;function delay(wait){return new Promise(function(resolve){setTimeout(resolve,wait);});}
const KeepLast=__exports.KeepLast=class KeepLast{constructor(){this._id=0;}
add(promise){this._id++;const currentId=this._id;return new Promise((resolve,reject)=>{promise.then((value)=>{if(this._id===currentId){resolve(value);}}).catch((reason)=>{if(this._id===currentId){reject(reason);}});});}}
const Mutex=__exports.Mutex=class Mutex{constructor(){this._lock=Promise.resolve();this._queueSize=0;this._unlockedProm=undefined;this._unlock=undefined;}
async exec(action){this._queueSize++;if(!this._unlockedProm){this._unlockedProm=new Promise((resolve)=>{this._unlock=()=>{resolve();this._unlockedProm=undefined;};});}
const always=()=>{return Promise.resolve(action()).finally(()=>{if(--this._queueSize===0){this._unlock();}});};this._lock=this._lock.then(always,always);return this._lock;}
getUnlockedDef(){return this._unlockedProm||Promise.resolve();}}
const Race=__exports.Race=class Race{constructor(){this.currentProm=null;this.currentPromResolver=null;this.currentPromRejecter=null;}
add(promise){if(!this.currentProm){this.currentProm=new Promise((resolve,reject)=>{this.currentPromResolver=(value)=>{this.currentProm=null;this.currentPromResolver=null;this.currentPromRejecter=null;resolve(value);};this.currentPromRejecter=(error)=>{this.currentProm=null;this.currentPromResolver=null;this.currentPromRejecter=null;reject(error);};});}
promise.then(this.currentPromResolver).catch(this.currentPromRejecter);return this.currentProm;}
getCurrentProm(){return this.currentProm;}}
const Deferred=__exports.Deferred=class Deferred extends Promise{constructor(){let resolve;let reject;const prom=new Promise((res,rej)=>{resolve=res;reject=rej;});return Object.assign(prom,{resolve,reject});}}
return __exports;});;
/* /web/static/src/core/utils/draggable.js */
odoo.define('@web/core/utils/draggable',['@web/core/utils/draggable_hook_builder_owl','@web/core/utils/objects'],function(require){'use strict';let __exports={};const{makeDraggableHook}=require("@web/core/utils/draggable_hook_builder_owl");const{pick}=require("@web/core/utils/objects");const useDraggable=__exports.useDraggable=makeDraggableHook({name:"useDraggable",onWillStartDrag:({ctx})=>pick(ctx.current,"element"),onDragStart:({ctx})=>pick(ctx.current,"element"),onDrag:({ctx})=>pick(ctx.current,"element"),onDragEnd:({ctx})=>pick(ctx.current,"element"),onDrop:({ctx})=>pick(ctx.current,"element"),});return __exports;});;
/* /web/static/src/core/utils/draggable_hook_builder.js */
odoo.define('@web/core/utils/draggable_hook_builder',['@web/core/utils/numbers','@web/core/utils/objects','@web/core/utils/scrolling','@web/core/utils/timing','@web/core/browser/browser','@web/core/browser/feature_detection'],function(require){'use strict';let __exports={};const{clamp}=require("@web/core/utils/numbers");const{omit}=require("@web/core/utils/objects");const{closestScrollableX,closestScrollableY}=require("@web/core/utils/scrolling");const{setRecurringAnimationFrame}=require("@web/core/utils/timing");const{browser}=require("@web/core/browser/browser");const{hasTouch,isBrowserFirefox,isIOS}=require("@web/core/browser/feature_detection");const DRAGGABLE_CLASS="o_draggable";const DRAGGED_CLASS=__exports.DRAGGED_CLASS="o_dragged";const DEFAULT_ACCEPTED_PARAMS={allowDisconnected:[Boolean],enable:[Boolean,Function],preventDrag:[Function],ref:[Object],elements:[String],handle:[String,Function],ignore:[String,Function],cursor:[String],edgeScrolling:[Object,Function],delay:[Number],tolerance:[Number],touchDelay:[Number],iframeWindow:[Object,Function],};const DEFAULT_DEFAULT_PARAMS={allowDisconnected:false,elements:`.${DRAGGABLE_CLASS}`,enable:true,preventDrag:()=>false,edgeScrolling:{speed:10,threshold:30,},delay:0,tolerance:10,touchDelay:300,};const LEFT_CLICK=0;const MANDATORY_PARAMS=["ref"];const WHITE_LISTED_KEYS=["Alt","Control","Meta","Shift"];const elCache={};function camelToKebab(str){return str.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();}
function getReturnValue(valueOrFn){if(typeof valueOrFn==="function"){return valueOrFn();}
return valueOrFn;}
function getScrollParents(el){return[closestScrollableX(el),closestScrollableY(el)];}
function makeCleanupManager(defaultCleanupFn){const add=(cleanupFn)=>typeof cleanupFn==="function"&&cleanups.push(cleanupFn);const cleanup=()=>{while(cleanups.length){cleanups.pop()();}
add(defaultCleanupFn);};const cleanups=[];add(defaultCleanupFn);return{add,cleanup};}
function makeDOMHelpers(cleanup){const addClass=(el,...classNames)=>{if(!el||!classNames.length){return;}
cleanup.add(()=>el.classList.remove(...classNames));el.classList.add(...classNames);};const addListener=(el,event,callback,options={})=>{if(!el||!event||!callback){return;}
const{noAddedStyle}=options;delete options.noAddedStyle;el.addEventListener(event,callback,options);if(!noAddedStyle&&/mouse|pointer|touch/.test(event)){addStyle(el,{pointerEvents:"auto"});}
cleanup.add(()=>el.removeEventListener(event,callback,options));};const addStyle=(el,style)=>{if(!el||!style||!Object.keys(style).length){return;}
cleanup.add(saveAttribute(el,"style"));for(const key in style){const[value,priority]=String(style[key]).split(/\s*!\s*/);el.style.setProperty(camelToKebab(key),value,priority);}};const getRect=(el,options={})=>{if(!el){return{};}
const rect=el.getBoundingClientRect();rect.height=el.offsetHeight;if(options.adjust){const style=getComputedStyle(el);const[pl,pr,pt,pb]=["padding-left","padding-right","padding-top","padding-bottom",].map((prop)=>pixelValueToNumber(style.getPropertyValue(prop)));rect.x+=pl;rect.y+=pt;rect.width-=pl+pr;rect.height-=pt+pb;}
return rect;};const removeAttribute=(el,attribute)=>{if(!el||!attribute){return;}
cleanup.add(saveAttribute(el,attribute));el.removeAttribute(attribute);};const removeClass=(el,...classNames)=>{if(!el||!classNames.length){return;}
cleanup.add(saveAttribute(el,"class"));el.classList.remove(...classNames);};const removeStyle=(el,...properties)=>{if(!el||!properties.length){return;}
cleanup.add(saveAttribute(el,"style"));for(const key of properties){el.style.removeProperty(camelToKebab(key));}};const setAttribute=(el,attribute,value)=>{if(!el||!attribute){return;}
cleanup.add(saveAttribute(el,attribute));el.setAttribute(attribute,String(value));};return{addClass,addListener,addStyle,getRect,removeAttribute,removeClass,removeStyle,setAttribute,};}
function pixelValueToNumber(val){return Number(val.endsWith("px")?val.slice(0,-2):val);}
function safePrevent(ev,{stop}={}){if(ev.cancelable){ev.preventDefault();if(stop){ev.stopPropagation();}}}
function saveAttribute(el,attribute){const restoreAttribute=()=>{cache.delete(el);if(hasAttribute){el.setAttribute(attribute,originalValue);}else{el.removeAttribute(attribute);}};if(!(attribute in elCache)){elCache[attribute]=new Set();}
const cache=elCache[attribute];if(cache.has(el)){return;}
cache.add(el);const hasAttribute=el.hasAttribute(attribute);const originalValue=el.getAttribute(attribute);return restoreAttribute;}
function toFunction(value){return typeof value==="function"?value:()=>value;}
__exports.makeDraggableHook=makeDraggableHook;function makeDraggableHook(hookParams){hookParams=getReturnValue(hookParams);const hookName=hookParams.name||"useAnonymousDraggable";const{setupHooks}=hookParams;const allAcceptedParams={...DEFAULT_ACCEPTED_PARAMS,...hookParams.acceptedParams};const defaultParams={...DEFAULT_DEFAULT_PARAMS,...hookParams.defaultParams};const computeParams=(params)=>{const computedParams={enable:()=>true};for(const prop in allAcceptedParams){if(prop in params){if(prop==="enable"){computedParams[prop]=toFunction(params[prop]);}else if(allAcceptedParams[prop].length===1&&allAcceptedParams[prop][0]===Function){computedParams[prop]=params[prop];}else{computedParams[prop]=getReturnValue(params[prop]);}}}
return Object.entries(computedParams);};const makeError=(reason)=>new Error(`Error in hook ${hookName}: ${reason}.`);let preventClick=false;return{[hookName](params){const callBuildHandler=(hookHandlerName,arg)=>{if(typeof hookParams[hookHandlerName]!=="function"){return;}
const returnValue=hookParams[hookHandlerName]({ctx,...helpers,...arg});if(returnValue){callHandler(hookHandlerName,returnValue);}};const callHandler=(handlerName,arg)=>{if(typeof params[handlerName]!=="function"){return;}
try{params[handlerName]({...dom,...ctx.pointer,...arg});}catch(err){dragEnd(null,true);throw err;}};const canStartDrag=()=>{const{pointer,current:{initialPosition},}=ctx;return(!ctx.tolerance||Math.hypot(pointer.x-initialPosition.x,pointer.y-initialPosition.y)>=ctx.tolerance);};const dragStart=()=>{state.dragging=true;state.willDrag=false;const isDocumentScrollingElement=ctx.current.container===ctx.current.container.ownerDocument.scrollingElement;[ctx.current.scrollParentX,ctx.current.scrollParentY]=isDocumentScrollingElement?[ctx.current.container,ctx.current.container]:getScrollParents(ctx.current.container);updateRects();const{x,y,width,height}=ctx.current.elementRect;ctx.current.offset={x:ctx.current.initialPosition.x-x,y:ctx.current.initialPosition.y-y,};if(ctx.followCursor){dom.addStyle(ctx.current.element,{width:`${width}px`,height:`${height}px`,"max-width":`${width}px`,"max-height":`${height}px`,position:"fixed !important",});updateElementPosition();}
dom.addClass(document.body,"pe-none","user-select-none");if(params.iframeWindow){for(const iframe of document.getElementsByTagName("iframe")){if(iframe.contentWindow===params.iframeWindow){dom.addClass(iframe,"pe-none","user-select-none");}}}
if(ctx.cursor){dom.addStyle(document.body,{cursor:ctx.cursor});}
if((ctx.current.scrollParentX||ctx.current.scrollParentY)&&ctx.edgeScrolling.enabled){const cleanupFn=setRecurringAnimationFrame(handleEdgeScrolling);cleanup.add(cleanupFn);}
dom.addClass(ctx.current.element,DRAGGED_CLASS);callBuildHandler("onDragStart");};const dragEnd=(target,inErrorState)=>{if(state.dragging){preventClick=true;if(!inErrorState){if(target&&(params.allowDisconnected||ctx.current.element.isConnected)){callBuildHandler("onDrop",{target});}
callBuildHandler("onDragEnd");}}
cleanup.cleanup();};const handleEdgeScrolling=(deltaTime)=>{updateRects();const{x:pointerX,y:pointerY}=ctx.pointer;const xRect=ctx.current.scrollParentXRect;const yRect=ctx.current.scrollParentYRect;const scrollParentYEl=ctx.current.scrollParentY;if(scrollParentYEl===ctx.current.container.ownerDocument.scrollingElement){yRect.y+=scrollParentYEl.scrollTop;}
const{direction,speed,threshold}=ctx.edgeScrolling;const correctedSpeed=(speed/16)*deltaTime;const diff={};ctx.current.scrollingEdge=null;if(xRect){const maxWidth=xRect.x+xRect.width;if(pointerX-xRect.x<threshold){diff.x=[pointerX-xRect.x,-1];ctx.current.scrollingEdge="left";}else if(maxWidth-pointerX<threshold){diff.x=[maxWidth-pointerX,1];ctx.current.scrollingEdge="right";}}
if(yRect){const maxHeight=yRect.y+yRect.height;if(pointerY-yRect.y<threshold){diff.y=[pointerY-yRect.y,-1];ctx.current.scrollingEdge="top";}else if(maxHeight-pointerY<threshold){diff.y=[maxHeight-pointerY,1];ctx.current.scrollingEdge="bottom";}}
const diffToScroll=([delta,sign])=>(1-Math.max(delta,0)/threshold)*correctedSpeed*sign;if((!direction||direction==="vertical")&&diff.y){ctx.current.scrollParentY.scrollBy({top:diffToScroll(diff.y)});}
if((!direction||direction==="horizontal")&&diff.x){ctx.current.scrollParentX.scrollBy({left:diffToScroll(diff.x)});}
callBuildHandler("onDrag");};const onClick=(ev)=>{if(preventClick){safePrevent(ev,{stop:true});}};const onKeyDown=(ev)=>{if(!state.dragging||!ctx.enable()){return;}
if(!WHITE_LISTED_KEYS.includes(ev.key)){safePrevent(ev,{stop:true});dragEnd(null);}};const onPointerCancel=()=>{dragEnd(null);};const onPointerDown=(ev)=>{preventClick=false;updatePointerPosition(ev);const initiationDelay=ev.pointerType==="touch"?ctx.touchDelay:ctx.delay;dragEnd(null);const fullSelectorEl=ev.target.closest(ctx.fullSelector);if(ev.button!==LEFT_CLICK||!ctx.enable()||!fullSelectorEl||(ctx.ignoreSelector&&ev.target.closest(ctx.ignoreSelector))||ctx.preventDrag(fullSelectorEl)){return;}
safePrevent(ev);ev.target.focus();let activeElement=document.activeElement;while(activeElement?.nodeName==="IFRAME"){activeElement=activeElement.contentDocument?.activeElement;}
if(activeElement&&!activeElement.contains(ev.target)){activeElement.blur();}
const{currentTarget,pointerId,target}=ev;ctx.current.initialPosition={...ctx.pointer};if(target.hasPointerCapture(pointerId)){target.releasePointerCapture(pointerId);}
if(initiationDelay){if(hasTouch()){if(ev.pointerType==="touch"){dom.addClass(target.closest(ctx.elementSelector),"o_touch_bounce");}
if(isBrowserFirefox()){const links=[...currentTarget.querySelectorAll("[href]")];if(currentTarget.hasAttribute("href")){links.unshift(currentTarget);}
for(const link of links){dom.removeAttribute(link,"href");}}
if(isIOS()){for(const image of currentTarget.getElementsByTagName("img")){dom.setAttribute(image,"draggable",false);}}}
ctx.current.timeout=browser.setTimeout(()=>{ctx.current.initialPosition={...ctx.pointer};willStartDrag(target);const{x:px,y:py}=ctx.pointer;const{x,y,width,height}=dom.getRect(ctx.current.element);if(px<x||x+width<px||py<y||y+height<py){dragEnd(null);}},initiationDelay);cleanup.add(()=>browser.clearTimeout(ctx.current.timeout));}else{willStartDrag(target);}};const onPointerMove=(ev)=>{updatePointerPosition(ev);if(!ctx.current.element||!ctx.enable()){return;}
safePrevent(ev);if(!state.dragging){if(!canStartDrag()){return;}
dragStart();}else if(!params.allowDisconnected&&!ctx.current.element.isConnected){return dragEnd(null);}
if(ctx.followCursor){updateElementPosition();}
callBuildHandler("onDrag");};const onPointerUp=(ev)=>{updatePointerPosition(ev);dragEnd(ev.target);};const updateElementPosition=()=>{const{containerRect,element,elementRect,offset}=ctx.current;const{width:ew,height:eh}=elementRect;const{x:cx,y:cy,width:cw,height:ch}=containerRect;dom.addStyle(element,{left:`${clamp(ctx.pointer.x - offset.x, cx, cx + cw - ew)}px`,top:`${clamp(ctx.pointer.y - offset.y, cy, cy + ch - eh)}px`,});};const updatePointerPosition=(ev)=>{ctx.pointer.x=ev.clientX;ctx.pointer.y=ev.clientY;};const updateRects=()=>{const{current}=ctx;const{container,element,scrollParentX,scrollParentY}=current;current.containerRect=dom.getRect(container,{adjust:true});let iframeOffsetX=0;let iframeOffsetY=0;const iframeEl=container.ownerDocument.defaultView.frameElement;if(iframeEl&&!iframeEl.contentDocument?.contains(element)){const{x,y}=dom.getRect(iframeEl);iframeOffsetX=x;iframeOffsetY=y;current.containerRect.x+=iframeOffsetX;current.containerRect.y+=iframeOffsetY;}
current.containerRect.width=container.scrollWidth;current.containerRect.height=container.scrollHeight;current.scrollParentXRect=null;current.scrollParentYRect=null;if(ctx.edgeScrolling.enabled){if(scrollParentX){current.scrollParentXRect=dom.getRect(scrollParentX,{adjust:true});current.scrollParentXRect.x+=iframeOffsetX;current.scrollParentXRect.y+=iframeOffsetY;const right=Math.min(current.containerRect.left+container.scrollWidth,current.scrollParentXRect.right);current.containerRect.x=Math.max(current.containerRect.x,current.scrollParentXRect.x);current.containerRect.width=right-current.containerRect.x;}
if(scrollParentY){current.scrollParentYRect=dom.getRect(scrollParentY,{adjust:true});current.scrollParentYRect.x+=iframeOffsetX;current.scrollParentYRect.y+=iframeOffsetY;const bottom=Math.min(current.containerRect.top+container.scrollHeight,current.scrollParentYRect.bottom);current.containerRect.y=Math.max(current.containerRect.y,current.scrollParentYRect.y);current.containerRect.height=bottom-current.containerRect.y;}}
ctx.current.elementRect=dom.getRect(element);};const willStartDrag=(target)=>{ctx.current.element=target.closest(ctx.elementSelector);ctx.current.container=ctx.ref.el;cleanup.add(()=>(ctx.current={}));state.willDrag=true;callBuildHandler("onWillStartDrag");if(hasTouch()){dom.addListener(window,"touchmove",safePrevent,{passive:false,noAddedStyle:true,});if(params.iframeWindow){dom.addListener(params.iframeWindow,"touchmove",safePrevent,{passive:false,noAddedStyle:true,});}}};const cleanup=makeCleanupManager(()=>(state.dragging=false));const effectCleanup=makeCleanupManager();const dom=makeDOMHelpers(cleanup);const helpers={...dom,addCleanup:cleanup.add,addEffectCleanup:effectCleanup.add,callHandler,};const state=setupHooks.wrapState({dragging:false});for(const prop in allAcceptedParams){const type=typeof params[prop];const acceptedTypes=allAcceptedParams[prop].map((t)=>t.name.toLowerCase());if(params[prop]){if(!acceptedTypes.includes(type)){throw makeError(`invalid type for property "${prop}" in parameters: expected { ${acceptedTypes.join(
", "
)} } and got ${type}`);}}else if(MANDATORY_PARAMS.includes(prop)&&!defaultParams[prop]){throw makeError(`missing required property "${prop}" in parameters`);}}
const ctx={enable:()=>false,preventDrag:()=>false,ref:params.ref,ignoreSelector:null,fullSelector:null,followCursor:true,cursor:null,pointer:{x:0,y:0},edgeScrolling:{enabled:true},get dragging(){return state.dragging;},get willDrag(){return state.willDrag;},current:{},};setupHooks.setup((...deps)=>{const params=Object.fromEntries(deps);const actualParams={...defaultParams,...omit(params,"edgeScrolling")};if(params.edgeScrolling){actualParams.edgeScrolling={...actualParams.edgeScrolling,...params.edgeScrolling,};}
if(!ctx.ref.el){return;}
ctx.enable=actualParams.enable;if(actualParams.preventDrag){ctx.preventDrag=actualParams.preventDrag;}
ctx.elementSelector=actualParams.elements;if(!ctx.elementSelector){throw makeError(`no value found by "elements" selector: ${ctx.elementSelector}`);}
const allSelectors=[ctx.elementSelector];ctx.cursor=actualParams.cursor||null;if(actualParams.handle){allSelectors.push(actualParams.handle);}
if(actualParams.ignore){ctx.ignoreSelector=actualParams.ignore;}
ctx.fullSelector=allSelectors.join(" ");Object.assign(ctx.edgeScrolling,actualParams.edgeScrolling);ctx.delay=actualParams.delay;ctx.touchDelay=actualParams.delay||actualParams.touchDelay;ctx.tolerance=actualParams.tolerance;callBuildHandler("onComputeParams",{params:actualParams});return effectCleanup.cleanup;},()=>computeParams(params));const useMouseEvents=isBrowserFirefox()&&!hasTouch()&&params.iframeWindow;setupHooks.setup((el)=>{if(el){const{add,cleanup}=makeCleanupManager();const{addListener}=makeDOMHelpers({add});const event=useMouseEvents?"mousedown":"pointerdown";addListener(el,event,onPointerDown,{noAddedStyle:true});addListener(el,"click",onClick);if(hasTouch()){addListener(el,"contextmenu",safePrevent);addListener(el,"touchstart",()=>{},{passive:false,noAddedStyle:true,});}
return cleanup;}},()=>[ctx.ref.el]);const addWindowListener=(type,listener,options)=>{if(params.iframeWindow){setupHooks.addListener(params.iframeWindow,type,listener,options);}
setupHooks.addListener(window,type,listener,options);};const throttledOnPointerMove=setupHooks.throttle(onPointerMove);addWindowListener(useMouseEvents?"mousemove":"pointermove",throttledOnPointerMove,{passive:false});addWindowListener(useMouseEvents?"mouseup":"pointerup",onPointerUp);addWindowListener("pointercancel",onPointerCancel);addWindowListener("keydown",onKeyDown,{capture:true});setupHooks.teardown(()=>dragEnd(null));return state;},}[hookName];}
return __exports;});;
/* /web/static/src/core/utils/draggable_hook_builder_owl.js */
odoo.define('@web/core/utils/draggable_hook_builder_owl',['@odoo/owl','@web/core/utils/timing','@web/core/utils/draggable_hook_builder'],function(require){'use strict';let __exports={};const{onWillUnmount,reactive,useEffect,useExternalListener}=require("@odoo/owl");const{useThrottleForAnimation}=require("@web/core/utils/timing");const{makeDraggableHook:nativeMakeDraggableHook}=require("@web/core/utils/draggable_hook_builder");__exports.makeDraggableHook=makeDraggableHook;function makeDraggableHook(params){return nativeMakeDraggableHook({...params,setupHooks:{addListener:useExternalListener,setup:useEffect,teardown:onWillUnmount,throttle:useThrottleForAnimation,wrapState:reactive,},});}
return __exports;});;
/* /web/static/src/core/utils/dvu.js */
odoo.define('@web/core/utils/dvu',['@web/core/utils/timing','@odoo/owl','@web/core/browser/browser','@web/core/browser/feature_detection'],function(require){'use strict';let __exports={};const{throttleForAnimation}=require("@web/core/utils/timing");const{onWillUnmount}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{isVirtualKeyboardSupported}=require("@web/core/browser/feature_detection");const viewport={listeners:[],addListener(listener){this.listeners.push(listener);return()=>{const index=this.listeners.indexOf(listener);if(index!==-1){this.listeners.splice(index,1);}};},notifyListeners(){this.listeners.forEach((listener)=>listener());},};if(typeof window!=="undefined"){const throttledUpdate=throttleForAnimation(()=>viewport.notifyListeners());if(browser.visualViewport){browser.visualViewport.addEventListener("resize",throttledUpdate);}
if(isVirtualKeyboardSupported()){browser.navigator.virtualKeyboard.addEventListener("geometrychange",throttledUpdate);}
browser.addEventListener("resize",throttledUpdate);}
__exports.getViewportDimensions=getViewportDimensions;function getViewportDimensions(){return{width:browser.visualViewport?.width||browser.innerWidth,height:browser.visualViewport?.height||browser.innerHeight,};}
__exports.onViewportChange=onViewportChange;function onViewportChange(callback){return viewport.addListener(callback);}
__exports.useViewportChange=useViewportChange;function useViewportChange(callback){const removeListener=onViewportChange(callback);onWillUnmount(()=>removeListener());}
return __exports;});;
/* /web/static/src/core/utils/files.js */
odoo.define('@web/core/utils/files',['@web/core/utils/numbers','@web/core/utils/hooks','@web/session','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{humanNumber}=require("@web/core/utils/numbers");const{useService}=require("@web/core/utils/hooks");const{session}=require("@web/session");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const DEFAULT_MAX_FILE_SIZE=__exports.DEFAULT_MAX_FILE_SIZE=128*1024*1024;__exports.checkFileSize=checkFileSize;function checkFileSize(fileSize,notificationService){const maxUploadSize=session.max_file_upload_size||DEFAULT_MAX_FILE_SIZE;if(fileSize>maxUploadSize){notificationService.add(_t("The selected file (%(size)sB) is larger than the maximum allowed file size (%(maxSize)sB).",{size:humanNumber(fileSize),maxSize:humanNumber(maxUploadSize)}),{type:"danger",});return false;}
return true;}
__exports.useFileUploader=useFileUploader;function useFileUploader(){const http=useService("http");const notification=useService("notification");return async(route,params)=>{if((params.ufile&&params.ufile.length)||params.file){const fileSize=(params.ufile&&params.ufile[0].size)||params.file.size;if(!checkFileSize(fileSize,notification)){return null;}}
const fileData=await http.post(route,params,"text");const parsedFileData=JSON.parse(fileData);if(parsedFileData.error){throw new Error(parsedFileData.error);}
return parsedFileData;};}
__exports.resizeBlobImg=resizeBlobImg;function resizeBlobImg(blob,params={}){if(!blob.type||!blob.type.startsWith("image/")){return Promise.reject(new Error(_t("The file is not an image, resizing is not possible")));}
const{width,height,offsetX,offsetY}={width:256,height:256,offsetX:0.5,offsetY:0.5,...params,};return new Promise((resolve,reject)=>{const img=new Image();img.onload=()=>{if(width<img.width||height<img.height){const canvas=document.createElement("canvas");canvas.width=width;canvas.height=height;const ctx=canvas.getContext("2d");ctx.imageSmoothingQuality="high";ctx.mozImageSmoothingEnabled=true;ctx.webkitImageSmoothingEnabled=true;ctx.msImageSmoothingEnabled=true;ctx.imageSmoothingEnabled=true;const srcRatio=img.width/img.height;const dWidth=Math.min(Math.floor(height*srcRatio),width);const dHeight=Math.min(Math.floor(width/srcRatio),height);const dx=Math.round((width-dWidth)*offsetX);const dy=Math.round((height-dHeight)*offsetY);ctx.drawImage(img,0,0,img.width,img.height,dx,dy,dWidth,dHeight);canvas.toBlob(resolve);}else{resolve(blob);}};img.onerror=()=>{reject(new Error(_t("The resizing of the image failed")));};img.src=URL.createObjectURL(blob);});}
return __exports;});;
/* /web/static/src/core/utils/functions.js */
odoo.define('@web/core/utils/functions',[],function(require){'use strict';let __exports={};__exports.memoize=memoize;function memoize(func){const cache=new Map();const funcName=func.name?func.name+" (memoized)":"memoized";return{[funcName](...args){if(!cache.has(args[0])){cache.set(args[0],func(...args));}
return cache.get(...args);},}[funcName];}
__exports.uniqueId=uniqueId;function uniqueId(prefix=""){return`${prefix}${++uniqueId.nextId}`;}
uniqueId.nextId=0;return __exports;});;
/* /web/static/src/core/utils/hooks.js */
odoo.define('@web/core/utils/hooks',['@web/core/browser/feature_detection','@odoo/owl'],function(require){'use strict';let __exports={};const{hasTouch,isMobileOS}=require("@web/core/browser/feature_detection");const{status,useComponent,useEffect,useRef,onWillUnmount,useState,toRaw}=require("@odoo/owl");__exports.useAutofocus=useAutofocus;function useAutofocus({refName,selectAll,mobile}={}){const ref=useRef(refName||"autofocus");const uiService=useService("ui");if(!mobile&&hasTouch()){return ref;}
if(!mobile&&isMobileOS()){return ref;}
function isFocusable(el){if(!el){return;}
if(!uiService.activeElement||uiService.activeElement.contains(el)){return true;}
const rootNode=el.getRootNode();return rootNode instanceof ShadowRoot&&uiService.activeElement.contains(rootNode.host);}
useEffect((el)=>{if(isFocusable(el)){el.focus();if(["INPUT","TEXTAREA"].includes(el.tagName)&&el.type!=="number"){el.selectionEnd=el.value.length;el.selectionStart=selectAll?0:el.value.length;}}},()=>[ref.el]);return ref;}
__exports.useBus=useBus;function useBus(bus,eventName,callback){const component=useComponent();useEffect(()=>{const listener=callback.bind(component);bus.addEventListener(eventName,listener);return()=>bus.removeEventListener(eventName,listener);},()=>[]);}
const useServiceProtectMethodHandling=__exports.useServiceProtectMethodHandling={fn(){return this.original();},mocked(){return new Promise(()=>{});},original(){return Promise.reject(new Error("Component is destroyed"));},};function _protectMethod(component,fn){return function(...args){if(status(component)==="destroyed"){return useServiceProtectMethodHandling.fn();}
const prom=Promise.resolve(fn.call(this,...args));const protectedProm=prom.then((result)=>status(component)==="destroyed"?new Promise(()=>{}):result);return Object.assign(protectedProm,{abort:prom.abort,cancel:prom.cancel,});};}
const SERVICES_METADATA=__exports.SERVICES_METADATA={};__exports.useService=useService;function useService(serviceName){const component=useComponent();const{services}=component.env;if(!(serviceName in services)){throw new Error(`Service ${serviceName} is not available`);}
const service=services[serviceName];if(SERVICES_METADATA[serviceName]){if(service instanceof Function){return _protectMethod(component,service);}else{const methods=SERVICES_METADATA[serviceName]??[];const result=Object.create(service);for(const method of methods){result[method]=_protectMethod(component,service[method]);}
return result;}}
if(toRaw(service)!==service){return useState(service);}
return service;}
__exports.useSpellCheck=useSpellCheck;function useSpellCheck({refName}={}){const elements=[];const ref=useRef(refName||"spellcheck");function toggleSpellcheck(ev){ev.target.spellcheck=document.activeElement===ev.target;}
useEffect((el)=>{if(el){const inputs=["INPUT","TEXTAREA"].includes(el.nodeName)||el.isContentEditable?[el]:el.querySelectorAll("input, textarea, [contenteditable=true]");inputs.forEach((input)=>{if(input.spellcheck!==false){elements.push(input);input.addEventListener("focus",toggleSpellcheck);input.addEventListener("blur",toggleSpellcheck);}});}
return()=>{elements.forEach((input)=>{input.removeEventListener("focus",toggleSpellcheck);input.removeEventListener("blur",toggleSpellcheck);});};},()=>[ref.el]);}
__exports.useChildRef=useChildRef;function useChildRef(){let defined=false;let value;return function ref(v){value=v;if(defined){return;}
Object.defineProperty(ref,"el",{get(){return value.el;},});defined=true;};}
__exports.useForwardRefToParent=useForwardRefToParent;function useForwardRefToParent(refName){const component=useComponent();const ref=useRef(refName);if(component.props[refName]){component.props[refName](ref);}
return ref;}
__exports.useOwnedDialogs=useOwnedDialogs;function useOwnedDialogs(){const dialogService=useService("dialog");const cbs=[];onWillUnmount(()=>{cbs.forEach((cb)=>cb());});const addDialog=(...args)=>{const close=dialogService.add(...args);cbs.push(close);return close;};return addDialog;}
__exports.useRefListener=useRefListener;function useRefListener(ref,...listener){useEffect((el)=>{el?.addEventListener(...listener);return()=>el?.removeEventListener(...listener);},()=>[ref.el]);}
return __exports;});;
/* /web/static/src/core/utils/html.js */
odoo.define('@web/core/utils/html',['@odoo/owl','@web/core/l10n/utils','@web/core/utils/arrays','@web/core/utils/strings'],function(require){'use strict';let __exports={};const{htmlEscape,markup}=require("@odoo/owl");const{formatList,normalizedMatches}=require("@web/core/l10n/utils");const{unique}=require("@web/core/utils/arrays");const{escapeRegExp,mapSubstitutions,sprintf}=require("@web/core/utils/strings");const Markup=markup().constructor;__exports.createDocumentFragmentFromContent=createDocumentFragmentFromContent;function createDocumentFragmentFromContent(content){return new document.defaultView.DOMParser().parseFromString(htmlEscape(content),"text/html");}
__exports.createElementWithContent=createElementWithContent;function createElementWithContent(elementName,content){const element=document.createElement(elementName);setElementContent(element,content);return element;}
__exports.highlightText=highlightText;function highlightText(query,text,classes){if(!query||!text){return text;}
let result=text;const isQueryMarkup=isMarkup(query);const matches=unique(normalizedMatches(result,query).map((m)=>isQueryMarkup?markup(m.match.toLowerCase()):m.match.toLowerCase()));for(const match of matches){const regex=new RegExp(`(?<!&[^;]{0,5})(${escapeRegExp(htmlEscape(match))})(?=(?:[^>]*<[^<]*>)*[^<>]*$)`,"ig");result=htmlReplace(result,regex,(_,match)=>{match=markup(match);return markup`<span class="${classes}">${match}</span>`;});}
return result;}
__exports.htmlFormatList=htmlFormatList;function htmlFormatList(values,options){return markup(formatList(Array.from(values,htmlEscape),options));}
__exports.htmlJoin=htmlJoin;function htmlJoin(list,separator=""){return markup(Array.from(list,htmlEscape).join(htmlEscape(separator)));}
__exports.htmlReplace=htmlReplace;function htmlReplace(content,search,replacer){const isReplacerFn=typeof replacer==="function";if(search instanceof RegExp&&!isReplacerFn){throw new TypeError("htmlReplace: replacer must be a function when search is a RegExp.");}
content=htmlEscape(content);if(typeof search==="string"||search instanceof String){search=htmlEscape(search);}
const safeReplacement=isReplacerFn?(...args)=>htmlEscape(replacer(...args)):htmlEscape(replacer);return markup(content.replace(search,safeReplacement));}
__exports.htmlReplaceAll=htmlReplaceAll;function htmlReplaceAll(content,search,replacer){const isReplacerFn=typeof replacer==="function";if(search instanceof RegExp&&!isReplacerFn){throw new TypeError("htmlReplaceAll: replacer must be a function when search is a RegExp.");}
content=htmlEscape(content);if(typeof search==="string"||search instanceof String){search=htmlEscape(search);}
const safeReplacement=isReplacerFn?(...args)=>htmlEscape(replacer(...args)):htmlEscape(replacer);return markup(content.replaceAll(search,safeReplacement));}
__exports.htmlSprintf=htmlSprintf;function htmlSprintf(str,...substitutions){const replaced=sprintf(htmlEscape(str),...mapSubstitutions(substitutions,htmlEscape));return markup(replaced);}
__exports.htmlTrim=htmlTrim;function htmlTrim(content){content=htmlEscape(content);return markup(content.trim());}
__exports.isHtmlEmpty=isHtmlEmpty;function isHtmlEmpty(content=""){return createElementWithContent("div",content).textContent.trim()==="";}
__exports.isMarkup=isMarkup;function isMarkup(content){return content instanceof Markup;}
__exports.odoomark=odoomark;function odoomark(text){const replacers=[["\n",markup`<br>`],["\t",markup`<span style="margin-left: 2em"></span>`],[/\*\*(.+?)\*\*/g,(_,content)=>markup(`<b>${content}</b>`)],[/--(.+?)--/g,(_,content)=>markup(`<span class="text-muted">${content}</span>`)],[/&#x60;(.+?)&#x60;/g,(_,content)=>markup(`<span class="o_tag position-relative d-inline-flex align-items-center mw-100 o_badge badge rounded-pill lh-1 o_tag_color_0">${content}</span>`),],];for(const[pattern,replacer]of replacers){text=htmlReplaceAll(text,pattern,replacer);}
return text;}
__exports.setElementContent=setElementContent;function setElementContent(element,content){if(isMarkup(content)){element.innerHTML=content;}else{element.textContent=content;}}
return __exports;});;
/* /web/static/src/core/utils/indexed_db.js */
odoo.define('@web/core/utils/indexed_db',['@web/core/utils/concurrency'],function(require){'use strict';let __exports={};const{Mutex}=require("@web/core/utils/concurrency");const VERSION_TABLE="__DBVersion__";const VERSION_KEY="__version__";const IDBQuotaExceededError=__exports.IDBQuotaExceededError=class IDBQuotaExceededError extends Error{}
function formatStorageSize(size){const units=["b","Kb","Mb","Gb"];while(size>=1000&&units.length>1){size/=1000;units.splice(0,1);}
return`${size.toFixed(2)}${units[0]}`;}
const IndexedDB=__exports.IndexedDB=class IndexedDB{constructor(name,version){this.name=name;this._tables=new Set([VERSION_TABLE]);this.mutex=new Mutex();this.mutex.exec(()=>this._checkVersion(version));}
async read(table,key){this._tables.add(table);return this.execute((db)=>{if(db){return this._read(db,table,key);}});}
async write(table,key,value){this._tables.add(table);return this.execute((db)=>{if(db){return this._write(db,table,key,value);}});}
async invalidate(tables=null){return this.execute((db)=>{if(db){return this._invalidate(db,typeof tables==="string"?[tables]:tables);}});}
async deleteDatabase(){return this.mutex.exec(()=>this._deleteDatabase(()=>{}));}
async execute(callback){return this.mutex.exec(()=>this._execute(callback));}
async _deleteDatabase(callback){return new Promise((resolve)=>{const request=indexedDB.deleteDatabase(this.name);request.onsuccess=()=>{Promise.resolve(callback()).then(resolve);};request.onerror=(event)=>{console.error(`IndexedDB delete error: ${event.target.error?.message}`);Promise.resolve(callback()).then(resolve);};});}
async _checkVersion(version){return new Promise((resolve)=>{this._execute((db)=>{if(db){return this._read(db,VERSION_TABLE,VERSION_KEY);}}).then((currentVersion)=>{if(!currentVersion){this._execute((db)=>{if(db){this._write(db,VERSION_TABLE,VERSION_KEY,version);}}).then(resolve);}else if(currentVersion!==version){this._deleteDatabase(()=>{this._execute((db)=>{if(db){this._write(db,VERSION_TABLE,VERSION_KEY,version);}});}).then(resolve);}else{resolve();}});});}
async _execute(callback,idbVersion){return new Promise((resolve,reject)=>{const request=indexedDB.open(this.name,idbVersion);request.onupgradeneeded=(event)=>{const db=event.target.result;const dbTables=new Set(db.objectStoreNames);const newTables=this._tables.difference(dbTables);newTables.forEach((table)=>db.createObjectStore(table));};request.onsuccess=(event)=>{const db=event.target.result;const dbTables=new Set(db.objectStoreNames);const newTables=this._tables.difference(dbTables);if(newTables.size!==0){db.close();const version=db.version+1;return this._execute(callback,version).then(resolve);}
Promise.resolve(callback(db)).then(resolve).catch(async(e)=>{if(e.name==="QuotaExceededError"){const{quota,usage}=await navigator.storage.estimate();console.error(`IndexedDB error: Quota Exceeded (${formatStorageSize(
usage
)} out of ${formatStorageSize(quota)} used)`);reject(new IDBQuotaExceededError());}else{reject(e);}}).finally(()=>db.close());};request.onerror=(event)=>{console.error(`IndexedDB error: ${event.target.error?.message}`);Promise.resolve(callback()).then(resolve);};});}
async _write(db,table,key,record){return new Promise((resolve,reject)=>{const transaction=db.transaction(table,"readwrite",{durability:"relaxed"});transaction.objectStore(table).put(record,key);transaction.onerror=(ev)=>reject(ev.target.error);transaction.onabort=(ev)=>reject(ev.target.error);transaction.oncomplete=resolve;transaction.commit();});}
async _invalidate(db,tables){return new Promise((resolve,reject)=>{const objectStoreNames=[...db.objectStoreNames].filter((table)=>table!==VERSION_TABLE);tables=tables?objectStoreNames.filter((t)=>tables.includes(t)):objectStoreNames;if(tables.length===0){return resolve();}
const transaction=db.transaction(tables,"readwrite",{durability:"relaxed"});const proms=tables.map((table)=>new Promise((resolve)=>{const objectStore=transaction.objectStore(table);const request=objectStore.clear();request.onsuccess=resolve;}));transaction.onerror=()=>reject(transaction.error);Promise.all(proms).then(resolve);transaction.commit();});}
async _read(db,table,key){return new Promise((resolve,reject)=>{const transaction=db.transaction(table,"readonly");const objectStore=transaction.objectStore(table);const r=objectStore.get(key);r.onsuccess=()=>resolve(r.result);transaction.onerror=()=>reject(transaction.error);});}}
return __exports;});;
/* /web/static/src/core/utils/misc.js */
odoo.define('@web/core/utils/misc',[],function(require){'use strict';let __exports={};const eventHandledWeakMap=new WeakMap();__exports.isEventHandled=isEventHandled;function isEventHandled(ev,markName){if(!eventHandledWeakMap.get(ev)){return false;}
return eventHandledWeakMap.get(ev).includes(markName);}
__exports.markEventHandled=markEventHandled;function markEventHandled(ev,markName){if(!eventHandledWeakMap.get(ev)){eventHandledWeakMap.set(ev,[]);}
eventHandledWeakMap.get(ev).push(markName);}
return __exports;});;
/* /web/static/src/core/utils/nested_sortable.js */
odoo.define('@web/core/utils/nested_sortable',['@web/core/l10n/localization','@web/core/utils/draggable_hook_builder_owl'],function(require){'use strict';let __exports={};const{localization}=require("@web/core/l10n/localization");const{makeDraggableHook}=require("@web/core/utils/draggable_hook_builder_owl");const useNestedSortable=__exports.useNestedSortable=makeDraggableHook({name:"useNestedSortable",acceptedParams:{groups:[String,Function],connectGroups:[Boolean,Function],nest:[Boolean],listTagName:[String],nestInterval:[Number],maxLevels:[Number],isAllowed:[Function],useElementSize:[Boolean],},defaultParams:{connectGroups:false,currentGroup:null,cursor:"grabbing",edgeScrolling:{speed:20,threshold:60},elements:"li",groupSelector:null,nest:false,listTagName:"ul",nestInterval:15,maxLevels:0,isAllowed:(ctx)=>true,useElementSize:false,},onComputeParams({ctx,params}){ctx.groupSelector=params.groups||null;if(ctx.groupSelector){ctx.fullSelector=[ctx.groupSelector,ctx.fullSelector].join(" ");}
ctx.connectGroups=params.connectGroups;ctx.nest=params.nest;ctx.listTagName=params.listTagName;ctx.nestInterval=params.nestInterval;ctx.isRTL=localization.direction==="rtl";ctx.maxLevels=params.maxLevels||0;ctx.isAllowed=params.isAllowed??(()=>true);ctx.useElementSize=params.useElementSize;},onWillStartDrag({ctx,addCleanup}){if(ctx.groupSelector){ctx.currentGroup=ctx.current.element.closest(ctx.groupSelector);if(!ctx.connectGroups){ctx.current.container=ctx.currentGroup;}}
if(ctx.nest){ctx.prevNestX=ctx.pointer.x;}
ctx.current.placeHolder=ctx.current.element.cloneNode(false);ctx.current.placeHolder.removeAttribute("id");ctx.current.placeHolder.classList.add("w-100","d-block");if(ctx.useElementSize){ctx.current.placeHolder.style.height=getComputedStyle(ctx.current.element).height;ctx.current.placeHolder.classList.add("o_nested_sortable_placeholder_realsize");}else{ctx.current.placeHolder.classList.add("o_nested_sortable_placeholder");}
addCleanup(()=>ctx.current.placeHolder.remove());},onDragStart({ctx,addStyle}){ctx.selectorX=ctx.isRTL?ctx.current.elementRect.left+1:ctx.current.elementRect.right-1;ctx.current.element.after(ctx.current.placeHolder);addStyle(ctx.current.element,{opacity:0.5});addStyle(document.body,{"pointer-events":"auto"});addStyle(document.querySelector(".o_navbar"),{"pointer-events":"none"});addStyle(document.querySelector(".o_action_manager"),{"pointer-events":"none"});addStyle(ctx.current.container,{"pointer-events":"auto"});return{element:ctx.current.element,group:ctx.currentGroup,};},_getDeepestChildLevel(ctx,node,depth=0){let result=0;const childSelector=`${ctx.listTagName} ${ctx.elementSelector}`;for(const childNode of node.querySelectorAll(childSelector)){result=Math.max(this._getDeepestChildLevel(ctx,childNode,depth+1),result);}
return depth?result+1:result;},_hasReachMaxAllowedLevel(ctx){if(!ctx.nest||ctx.maxLevels<1){return false;}
let level=this._getDeepestChildLevel(ctx,ctx.current.element);let list=ctx.current.placeHolder.closest(ctx.listTagName);while(list){level++;list=list.parentNode.closest(ctx.listTagName);}
return level>ctx.maxLevels;},_isAllowedNodeMove(ctx){return(!this._hasReachMaxAllowedLevel(ctx)&&ctx.isAllowed(ctx.current,ctx.elementSelector));},onDrag({ctx,callHandler}){const onMove=(prevPos)=>{if(!ctx.isAllowed(ctx.current,ctx.elementSelector)){ctx.current.placeHolder.classList.add("d-none");return;}else if(this._hasReachMaxAllowedLevel(ctx)){const previousSiblingEl=ctx.current.placeHolder.closest(ctx.listTagName).closest(ctx.elementSelector);previousSiblingEl.after(ctx.current.placeHolder);return;}
ctx.current.placeHolder.classList.remove("d-none");callHandler("onMove",{element:ctx.current.element,previous:ctx.current.placeHolder.previousElementSibling,next:ctx.current.placeHolder.nextElementSibling,parent:ctx.nest?ctx.current.placeHolder.parentElement.closest(ctx.elementSelector):false,group:ctx.currentGroup,newGroup:ctx.connectGroups?ctx.current.placeHolder.closest(ctx.groupSelector):ctx.currentGroup,prevPos,placeholder:ctx.current.placeHolder,});};const getChildList=(el)=>{let list=el.querySelector(ctx.listTagName);if(!list){list=document.createElement(ctx.listTagName);el.appendChild(list);}
return list;};const getPosition=(el)=>{return{previous:el.previousElementSibling,next:el.nextElementSibling,parent:el.parentElement?.closest(ctx.elementSelector)||null,group:ctx.groupSelector?el.closest(ctx.groupSelector):false,};};const position=getPosition(ctx.current.placeHolder);if(ctx.nest){const xInterval=ctx.prevNestX-ctx.pointer.x;if(ctx.nestInterval-(-1)**ctx.isRTL*xInterval<1){let nextElement=position.next;if(nextElement===ctx.current.element){nextElement=nextElement.nextElementSibling;}
if(!nextElement){const newSibling=position.parent;if(newSibling){newSibling.after(ctx.current.placeHolder);onMove(position);}}
ctx.prevNestX=ctx.pointer.x;return;}else if(ctx.nestInterval+(-1)**ctx.isRTL*xInterval<1){let parent=position.previous;if(parent===ctx.current.element){parent=parent.previousElementSibling;}
if(parent&&parent.matches(ctx.elementSelector)){getChildList(parent).appendChild(ctx.current.placeHolder);onMove(position);}
ctx.prevNestX=ctx.pointer.x;return;}}
const currentTop=ctx.pointer.y-ctx.current.offset.y;const closestEl=document.elementFromPoint(ctx.selectorX,currentTop);if(!closestEl){return;}
const element=closestEl.closest(ctx.elementSelector);if(element&&element!==ctx.current.placeHolder){const elementPosition=getPosition(element);const eRect=element.getBoundingClientRect();const pos=ctx.current.placeHolder.compareDocumentPosition(element);if(currentTop-eRect.y<10){if(pos&Node.DOCUMENT_POSITION_PRECEDING&&(ctx.nest||elementPosition.parent===position.parent)){element.before(ctx.current.placeHolder);onMove(position);ctx.prevNestX=ctx.pointer.x;}}else if(currentTop-eRect.y>15&&pos===Node.DOCUMENT_POSITION_FOLLOWING){if(ctx.nest){const elementChildList=getChildList(element);if(elementChildList.querySelector(ctx.elementSelector)){elementChildList.prepend(ctx.current.placeHolder);onMove(position);}else{element.after(ctx.current.placeHolder);onMove(position);}
ctx.prevNestX=ctx.pointer.x;}else if(elementPosition.parent===position.parent){element.after(ctx.current.placeHolder);onMove(position);}}}else{const group=closestEl.closest(ctx.groupSelector);if(group&&group!==position.group&&(ctx.nest||!position.parent)){if(group.compareDocumentPosition(position.group)===Node.DOCUMENT_POSITION_PRECEDING){getChildList(group).prepend(ctx.current.placeHolder);onMove(position);}else{getChildList(group).appendChild(ctx.current.placeHolder);onMove(position);}
ctx.prevNestX=ctx.pointer.x;callHandler("onGroupEnter",{group,placeholder:ctx.current.placeHolder});callHandler("onGroupLeave",{group:position.group,placeholder:ctx.current.placeHolder,});}}},onDrop({ctx}){if(!this._isAllowedNodeMove(ctx)){return;}
const previous=ctx.current.placeHolder.previousElementSibling;const next=ctx.current.placeHolder.nextElementSibling;if(previous!==ctx.current.element&&next!==ctx.current.element){return{element:ctx.current.element,group:ctx.currentGroup,previous,next,newGroup:ctx.groupSelector&&ctx.current.placeHolder.closest(ctx.groupSelector),parent:ctx.current.placeHolder.parentElement.closest(ctx.elementSelector),placeholder:ctx.current.placeHolder,};}},onDragEnd({ctx}){return{element:ctx.current.element,group:ctx.currentGroup,};},});return __exports;});;
/* /web/static/src/core/utils/numbers.js */
odoo.define('@web/core/utils/numbers',['@web/core/l10n/localization','@web/core/l10n/translation','@web/core/utils/strings'],function(require){'use strict';let __exports={};const{localization:l10n}=require("@web/core/l10n/localization");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{intersperse}=require("@web/core/utils/strings");__exports.clamp=clamp;function clamp(num,min,max){return Math.max(Math.min(num,max),min);}
__exports.range=range;function range(start,stop,step=1){const array=[];const nsteps=Math.floor((stop-start)/step);for(let i=0;i<nsteps;i++){array.push(start+step*i);}
return array;}
__exports.roundPrecision=roundPrecision;function roundPrecision(value,precision,method="HALF-UP"){if(!value){return 0;}else if(!precision||precision<0){precision=1;}
let roundingFactor=precision;let normalize=(val)=>val/roundingFactor;let denormalize=(val)=>val*roundingFactor;if(roundingFactor<1){roundingFactor=invertFloat(roundingFactor);[normalize,denormalize]=[denormalize,normalize];}
const normalizedValue=normalize(value);const sign=Math.sign(normalizedValue);const epsilonMagnitude=Math.log2(Math.abs(normalizedValue));const epsilon=Math.pow(2,epsilonMagnitude-50);let roundedValue;switch(method){case"DOWN":{roundedValue=Math.trunc(normalizedValue+sign*epsilon);break;}
case"HALF-DOWN":{roundedValue=Math.round(normalizedValue-sign*epsilon);break;}
case"HALF-UP":{roundedValue=Math.round(normalizedValue+sign*epsilon);break;}
case"HALF-EVEN":{const integral=Math.floor(normalizedValue);const remainder=Math.abs(normalizedValue-integral);const isHalf=Math.abs(0.5-remainder)<epsilon;roundedValue=isHalf?integral+(integral&1):Math.round(normalizedValue);break;}
case"UP":{roundedValue=Math.trunc(normalizedValue+sign*(1-epsilon));break;}
default:{throw new Error(`Unknown rounding method: ${method}`);}}
return denormalize(roundedValue);}
function formatFixedDecimals(value,decimals){const rounded=roundDecimals(value,decimals);const[intPart,decPart=""]=rounded.toString().split(".");const paddedDecimals=decPart.padEnd(decimals,"0").slice(0,decimals);return decimals===0?intPart:`${intPart}.${paddedDecimals}`;}
__exports.roundDecimals=roundDecimals;function roundDecimals(value,decimals){return roundPrecision(value,parseFloat("1e"+-decimals));}
__exports.floatIsZero=floatIsZero;function floatIsZero(value,decimals){return value===0||roundDecimals(value,decimals)===0;}
__exports.insertThousandsSep=insertThousandsSep;function insertThousandsSep(number,thousandsSep=",",grouping=[]){const negative=number[0]==="-";number=negative?number.slice(1):number;return(negative?"-":"")+intersperse(number,grouping,thousandsSep);}
__exports.humanNumber=humanNumber;function humanNumber(number,options={decimals:0,minDigits:1}){const decimals=options.decimals||0;const minDigits=options.minDigits||1;const d2=Math.pow(10,decimals);const numberMagnitude=+number.toExponential().split("e+")[1];number=Math.round(number*d2)/d2;if(numberMagnitude>=21){number=Math.round(number*Math.pow(10,decimals-numberMagnitude))/d2;return`${number}e+${numberMagnitude}`;}
const unitSymbols=_t("kMGTPE").toString();const sign=Math.sign(number);number=Math.abs(number);let symbol="";for(let i=unitSymbols.length;i>0;i--){const s=Math.pow(10,i*3);if(s<=number/Math.pow(10,minDigits-1)){number=Math.round((number*d2)/s)/d2;symbol=unitSymbols[i-1];break;}}
const{decimalPoint,grouping,thousandsSep}=l10n;const decimalsToKeep=number>=1000?0:decimals;number=sign*number;const[integerPart,decimalPart]=formatFixedDecimals(number,decimalsToKeep).split(".");const int=insertThousandsSep(integerPart,thousandsSep,grouping);if(!decimalPart){return int+symbol;}
return int+decimalPoint+decimalPart+symbol;}
__exports.formatFloat=formatFloat;function formatFloat(value,options={}){let precision;if(options.digits&&options.digits[1]!==undefined){precision=options.digits[1];}else if(options.minDigits){const intDigitsCount=(value!==0)?Math.floor(Math.log10(Math.abs(value)))+1:1;const maxDecDigits=Math.max(14-intDigitsCount,0);precision=Math.min(6,maxDecDigits);}else{precision=2;}
const minPrecision=options.minDigits||precision;if(floatIsZero(value,precision)){value=0.0;}
if(options.humanReadable){return humanNumber(value,options);}
const grouping=options.grouping||l10n.grouping;const thousandsSep="thousandsSep"in options?options.thousandsSep:l10n.thousandsSep;const decimalPoint="decimalPoint"in options?options.decimalPoint:l10n.decimalPoint;const formatted=formatFixedDecimals(value,precision).split(".");formatted[0]=insertThousandsSep(formatted[0],thousandsSep,grouping);if(formatted[1]){formatted[1]=formatted[1].replace(/0+$/,"");if(options.trailingZeros!==false){formatted[1]=formatted[1].padEnd(minPrecision,"0");}}
return formatted[1]?formatted.join(decimalPoint):formatted[0];}
const _INVERTDICT=Object.freeze({1e-1:1e1,1e-2:1e2,1e-3:1e3,1e-4:1e4,1e-5:1e5,1e-6:1e6,1e-7:1e7,1e-8:1e8,1e-9:1e9,1e-10:1e10,2e-1:5,2e-2:5e1,2e-3:5e2,2e-4:5e3,2e-5:5e4,2e-6:5e5,2e-7:5e6,2e-8:5e7,2e-9:5e8,2e-10:5e9,5e-1:2,5e-2:2e1,5e-3:2e2,5e-4:2e3,5e-5:2e4,5e-6:2e5,5e-7:2e6,5e-8:2e7,5e-9:2e8,5e-10:2e9,});__exports.invertFloat=invertFloat;function invertFloat(value){let res=_INVERTDICT[value];if(res===undefined){const[coeff,expt]=value.toExponential().split("e").map(Number.parseFloat);res=Number.parseFloat(`${coeff}e${-expt}`)/Math.pow(coeff,2);}
return res;}
return __exports;});;
/* /web/static/src/core/utils/objects.js */
odoo.define('@web/core/utils/objects',[],function(require){'use strict';let __exports={};__exports.shallowEqual=shallowEqual;function shallowEqual(obj1,obj2,comparisonFn=(a,b)=>a===b){if(obj1!==Object(obj1)||obj2!==Object(obj2)){return obj1===obj2;}
const obj1Keys=Reflect.ownKeys(obj1);return(obj1Keys.length===Reflect.ownKeys(obj2).length&&obj1Keys.every((key)=>comparisonFn(obj1[key],obj2[key])));}
const deepEqual=__exports.deepEqual=(obj1,obj2)=>shallowEqual(obj1,obj2,deepEqual);__exports.deepCopy=deepCopy;function deepCopy(object){return object&&JSON.parse(JSON.stringify(object));}
__exports.isObject=isObject;function isObject(value){return Object.prototype.toString.call(value)==="[object Object]";}
__exports.omit=omit;function omit(object,...properties){const result={};const propertiesSet=new Set(properties);for(const key in object){if(!propertiesSet.has(key)){result[key]=object[key];}}
return result;}
__exports.pick=pick;function pick(object,...properties){return Object.fromEntries(properties.filter((prop)=>prop in object).map((prop)=>[prop,object[prop]]));}
__exports.deepMerge=deepMerge;function deepMerge(target,extension){if(!isObject(target)&&!isObject(extension)){return;}
target=target||{};const output=Object.assign({},target);if(isObject(extension)){for(const key of Reflect.ownKeys(extension)){if(key in target&&isObject(extension[key])&&!Array.isArray(extension[key])&&typeof extension[key]!=="function"){output[key]=deepMerge(target[key],extension[key]);}else{Object.assign(output,{[key]:extension[key]});}}}
return output;}
return __exports;});;
/* /web/static/src/core/utils/patch.js */
odoo.define('@web/core/utils/patch',[],function(require){'use strict';let __exports={};const patchDescriptions=new WeakMap();function getPatchDescription(objToPatch){if(!patchDescriptions.has(objToPatch)){patchDescriptions.set(objToPatch,{originalProperties:new Map(),skeleton:Object.create(Object.getPrototypeOf(objToPatch)),extensions:new Set(),});}
return patchDescriptions.get(objToPatch);}
function isClassPrototype(objToPatch){return(Object.hasOwn(objToPatch,"constructor")&&objToPatch.constructor?.prototype===objToPatch);}
function findAncestorPropertyDescriptor(objToPatch,key){let descriptor=null;let prototype=objToPatch;do{descriptor=Object.getOwnPropertyDescriptor(prototype,key);prototype=Object.getPrototypeOf(prototype);}while(!descriptor&&prototype);return descriptor;}
__exports.patch=patch;function patch(objToPatch,extension){if(typeof extension==="string"){throw new Error(`Patch "${extension}": Second argument is not the patch name anymore, it should be the object containing the patched properties`);}
const description=getPatchDescription(objToPatch);description.extensions.add(extension);const properties=Object.getOwnPropertyDescriptors(extension);for(const[key,newProperty]of Object.entries(properties)){const oldProperty=Object.getOwnPropertyDescriptor(objToPatch,key);if(oldProperty){Object.defineProperty(description.skeleton,key,oldProperty);}
if(!description.originalProperties.has(key)){description.originalProperties.set(key,oldProperty);}
if(isClassPrototype(objToPatch)){newProperty.enumerable=false;}
if((newProperty.get&&1)^(newProperty.set&&1)){const ancestorProperty=findAncestorPropertyDescriptor(objToPatch,key);newProperty.get=newProperty.get??ancestorProperty?.get;newProperty.set=newProperty.set??ancestorProperty?.set;}
Object.defineProperty(objToPatch,key,newProperty);}
description.skeleton=Object.setPrototypeOf(extension,description.skeleton);return()=>{patchDescriptions.delete(objToPatch);for(const[key,property]of description.originalProperties){if(property){Object.defineProperty(objToPatch,key,property);}else{delete objToPatch[key];}}
description.extensions.delete(extension);for(const extension of description.extensions){patch(objToPatch,extension);}};}
return __exports;});;
/* /web/static/src/core/utils/pdfjs.js */
odoo.define('@web/core/utils/pdfjs',['@web/core/browser/feature_detection','@web/core/assets'],function(require){'use strict';let __exports={};const{isMobileOS}=require("@web/core/browser/feature_detection");const{loadJS}=require("@web/core/assets");__exports.hidePDFJSButtons=hidePDFJSButtons;function hidePDFJSButtons(rootElement,options={}){const hiddenElements=["#editorModeButtons","button#openFile","button#secondaryOpenFile","a#viewBookmark","a#secondaryViewBookmark",];if(options.hideDownload||isMobileOS()){hiddenElements.push(["button#downloadButton","button#secondaryDownload"]);}
if(options.hidePrint||isMobileOS()){hiddenElements.push(["button#printButton","button#secondaryPrint"]);}
if(options.hidePresentation){hiddenElements.push("button#presentationMode");}
if(options.hideRotation){hiddenElements.push("button#pageRotateCw");hiddenElements.push("button#pageRotateCcw");}
const cssStyle=document.createElement("style");cssStyle.rel="stylesheet";cssStyle.textContent=`${hiddenElements.join(", ")} {
display: none !important;
}`;const iframe=rootElement.tagName==="IFRAME"?rootElement:rootElement.querySelector("iframe");if(iframe){if(!iframe.dataset.hideButtons){iframe.dataset.hideButtons="true";iframe.addEventListener("load",(event)=>{if(iframe.contentDocument&&iframe.contentDocument.head){iframe.contentDocument.head.appendChild(cssStyle);}});}}else{console.warn("No IFRAME found");}}
__exports.loadPDFJSAssets=loadPDFJSAssets;async function loadPDFJSAssets(){return Promise.all([loadJS("/web/static/lib/pdfjs/build/pdf.js"),loadJS("/web/static/lib/pdfjs/build/pdf.worker.js"),]);}
return __exports;});;
/* /web/static/src/core/utils/reactive.js */
odoo.define('@web/core/utils/reactive',['@odoo/owl'],function(require){'use strict';let __exports={};const{reactive}=require("@odoo/owl");const Reactive=__exports.Reactive=class Reactive{constructor(){return reactive(this);}}
__exports.effect=effect;function effect(cb,deps){const reactiveDeps=reactive(deps,()=>{cb(...reactiveDeps);});cb(...reactiveDeps);}
__exports.withComputedProperties=withComputedProperties;function withComputedProperties(obj,sources,descriptor){for(const[key,compute]of Object.entries(descriptor)){effect((obj,sources)=>{obj[key]=compute.call(obj,...sources);},[obj,sources]);}
return obj;}
return __exports;});;
/* /web/static/src/core/utils/render.js */
odoo.define('@web/core/utils/render',['@odoo/owl','@web/core/templates','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{App,blockDom,Component,markup}=require("@odoo/owl");const{getTemplate}=require("@web/core/templates");const{appTranslateFn}=require("@web/core/l10n/translation");__exports.renderToElement=renderToElement;function renderToElement(template,context={}){const el=render(template,context).firstElementChild;if(el?.nextElementSibling){throw new Error(`The rendered template '${template}' contains multiple root `+`nodes that will be ignored using renderToElement, you should `+`consider using renderToFragment or refactoring the template.`);}
el?.remove();return el;}
__exports.renderToFragment=renderToFragment;function renderToFragment(template,context={}){const frag=document.createDocumentFragment();for(const el of[...render(template,context).children]){frag.appendChild(el);}
return frag;}
__exports.renderToString=renderToString;function renderToString(template,context={}){return render(template,context).innerHTML;}
let app;Object.defineProperty(renderToString,"app",{get:()=>{if(!app){app=new App(Component,{name:"renderToString",getTemplate,translatableAttributes:["data-tooltip"],translateFn:appTranslateFn,});}
return app;},});function render(template,context={}){const app=renderToString.app;const templateFn=app.getTemplate(template);const bdom=templateFn(context,{});const div=document.createElement("div");blockDom.mount(bdom,div);return div;}
__exports.renderToMarkup=renderToMarkup;function renderToMarkup(template,context={}){return markup(renderToString(template,context));}
return __exports;});;
/* /web/static/src/core/utils/scrolling.js */
odoo.define('@web/core/utils/scrolling',[],function(require){'use strict';let __exports={};__exports.isScrollableX=isScrollableX;function isScrollableX(el){if(el.scrollWidth>el.clientWidth&&el.clientWidth>0){return couldBeScrollableX(el);}
return false;}
__exports.couldBeScrollableX=couldBeScrollableX;function couldBeScrollableX(el){if(el){const overflow=getComputedStyle(el).getPropertyValue("overflow-x");if(/\bauto\b|\bscroll\b/.test(overflow)){return true;}}
return false;}
__exports.closestScrollableX=closestScrollableX;function closestScrollableX(el){if(!el){return null;}
if(isScrollableX(el)){return el;}
return closestScrollableX(el.parentElement);}
__exports.isScrollableY=isScrollableY;function isScrollableY(el){if(el&&el.scrollHeight>el.clientHeight&&el.clientHeight>0){return couldBeScrollableY(el);}
return false;}
__exports.couldBeScrollableY=couldBeScrollableY;function couldBeScrollableY(el){if(el){const overflow=getComputedStyle(el).getPropertyValue("overflow-y");if(/\bauto\b|\bscroll\b/.test(overflow)){return true;}}
return false;}
__exports.closestScrollableY=closestScrollableY;function closestScrollableY(el){if(!el){return null;}
if(isScrollableY(el)){return el;}
return closestScrollableY(el.parentElement);}
__exports.scrollTo=scrollTo;function scrollTo(element,options={}){const{behavior="auto",isAnchor=false,offset=0}=options;const scrollable=closestScrollableY(options.scrollable||element.parentElement);if(!scrollable){return;}
const scrollBottom=scrollable.getBoundingClientRect().bottom;const scrollTop=scrollable.getBoundingClientRect().top;const elementBottom=element.getBoundingClientRect().bottom;const elementTop=element.getBoundingClientRect().top;const scrollPromises=[];if(elementBottom>scrollBottom&&!isAnchor){scrollPromises.push(new Promise((resolve)=>{scrollable.addEventListener("scrollend",()=>resolve(),{once:true});}));scrollable.scrollTo({top:scrollable.scrollTop+
elementTop-
scrollBottom+
Math.ceil(element.getBoundingClientRect().height)+
offset,behavior,});}else if(elementTop<scrollTop||isAnchor){scrollPromises.push(new Promise((resolve)=>{scrollable.addEventListener("scrollend",()=>resolve(),{once:true});}));scrollable.scrollTo({top:scrollable.scrollTop-scrollTop+elementTop+offset,behavior,});if(options.isAnchor){const parentScrollable=closestScrollableY(scrollable.parentElement);if(parentScrollable){scrollPromises.push(scrollTo(scrollable,{behavior,isAnchor:true,scrollable:parentScrollable,}));}}}
return Promise.all(scrollPromises);}
__exports.compensateScrollbar=compensateScrollbar;function compensateScrollbar(el,add=true,isScrollElement=true,cssProperty="padding-right"){if(!el){return;}
const scrollableEl=isScrollElement?el:closestScrollableY(el.parentElement);if(!scrollableEl){return;}
const isRTL=scrollableEl.classList.contains(".o_rtl");if(isRTL){cssProperty=cssProperty.replace("right","left");}
el.style.removeProperty(cssProperty);if(!add){return;}
const style=window.getComputedStyle(el);const borderLeftWidth=Math.ceil(parseFloat(style.borderLeftWidth.replace("px","")));const borderRightWidth=Math.ceil(parseFloat(style.borderRightWidth.replace("px","")));const bordersWidth=borderLeftWidth+borderRightWidth;const newValue=parseInt(style[cssProperty])+
scrollableEl.offsetWidth-
scrollableEl.clientWidth-
bordersWidth;el.style.setProperty(cssProperty,`${newValue}px`,"important");}
__exports.getScrollingElement=getScrollingElement;function getScrollingElement(document=window.document){const baseScrollingElement=document.scrollingElement;if(isScrollableY(baseScrollingElement)){return baseScrollingElement;}
const bodyHeight=window.getComputedStyle(document.body).height;for(const el of document.body.children){if(bodyHeight-el.scrollHeight>1.5){continue;}
if(isScrollableY(el)){return el;}}
return baseScrollingElement;}
__exports.getScrollingTarget=getScrollingTarget;function getScrollingTarget(scrollingElement=window.document){const document=scrollingElement.ownerDocument;return scrollingElement===document.scrollingElement?document.defaultView:scrollingElement;}
return __exports;});;
/* /web/static/src/core/utils/search.js */
odoo.define('@web/core/utils/search',['@web/core/l10n/utils'],function(require){'use strict';let __exports={};const{normalize}=require("@web/core/l10n/utils");function match(pattern,strs){if(!Array.isArray(strs)){strs=[strs];}
let globalScore=0;for(const str of strs){globalScore=Math.max(globalScore,_match(pattern,str));}
return globalScore;}
function _match(pattern,str){let totalScore=0;let currentScore=0;let patternIndex=0;pattern=normalize(pattern);str=normalize(str);const len=str.length;for(let i=0;i<len;i++){if(str[i]===pattern[patternIndex]){patternIndex++;currentScore+=100+currentScore-i/200;}else{currentScore=0;}
totalScore=totalScore+currentScore;}
return patternIndex===pattern.length?totalScore:0;}
__exports.fuzzyLookup=fuzzyLookup;function fuzzyLookup(pattern,list,fn){const results=[];list.forEach((data)=>{const score=match(pattern,fn(data));if(score>0){results.push({score,elem:data});}});results.sort((a,b)=>b.score-a.score);return results.map((r)=>r.elem);}
__exports.fuzzyTest=fuzzyTest;function fuzzyTest(pattern,string){return _match(pattern,string)!==0;}
__exports.fuzzyLevenshteinLookup=fuzzyLevenshteinLookup;function fuzzyLevenshteinLookup(pattern,list,errorRatio=3){const maxNbrCorrection=Math.round(pattern.length/errorRatio);const results=[];list.forEach((candidate)=>{let score=-1;if(candidate.includes(pattern)){score=0;results.push({score,elem:pattern});}else{score=getLevenshteinScore(pattern,candidate);if(score>=0&&score<=maxNbrCorrection){results.push({score,elem:candidate});}}});results.sort((a,b)=>a.score-b.score);return results.map((r)=>r.elem);}
function getLevenshteinScore(a,b){let aLength=a.length;let bLength=b.length;let distanceMatrix=[];for(let i=0;i<=aLength;i++){distanceMatrix[i]=[];for(let j=0;j<=bLength;j++){distanceMatrix[i][j]=0;}}
for(let i=0;i<=aLength;i++){for(let j=0;j<=bLength;j++){if(Math.min(i,j)===0){distanceMatrix[i][j]=Math.max(i,j);}else{if(a[i-1]===b[j-1]){distanceMatrix[i][j]=distanceMatrix[i-1][j-1];}else{distanceMatrix[i][j]=Math.min(distanceMatrix[i-1][j]+1,distanceMatrix[i][j-1]+1,distanceMatrix[i-1][j-1]+1);}}}}
return distanceMatrix[aLength][bLength];}
return __exports;});;
/* /web/static/src/core/utils/sortable.js */
odoo.define('@web/core/utils/sortable',['@web/core/utils/draggable_hook_builder','@web/core/utils/objects'],function(require){'use strict';let __exports={};const{DRAGGED_CLASS,makeDraggableHook:nativeMakeDraggableHook,}=require("@web/core/utils/draggable_hook_builder");const{pick}=require("@web/core/utils/objects");const hookParams={name:"useSortable",acceptedParams:{groups:[String,Function],connectGroups:[Boolean,Function],clone:[Boolean],placeholderClasses:[Object],applyChangeOnDrop:[Boolean],followingElementClasses:[Object],},defaultParams:{connectGroups:false,edgeScrolling:{speed:20,threshold:60},groupSelector:null,clone:true,placeholderClasses:[],applyChangeOnDrop:false,followingElementClasses:[],},onComputeParams({ctx,params}){ctx.groupSelector=params.groups||null;if(ctx.groupSelector){ctx.fullSelector=[ctx.groupSelector,ctx.fullSelector].join(" ");}
ctx.connectGroups=params.connectGroups;ctx.placeholderClone=params.clone;ctx.placeholderClasses=params.placeholderClasses;ctx.applyChangeOnDrop=params.applyChangeOnDrop;ctx.followingElementClasses=params.followingElementClasses;},onDragStart({ctx,addListener,addStyle,callHandler}){const onElementPointerEnter=(ev)=>{const element=ev.currentTarget;if(connectGroups||!groupSelector||current.group===element.closest(groupSelector)){const pos=current.placeHolder.compareDocumentPosition(element);if(pos===Node.DOCUMENT_POSITION_PRECEDING){element.before(current.placeHolder);}else if(pos===Node.DOCUMENT_POSITION_FOLLOWING){element.after(current.placeHolder);}}
callHandler("onElementEnter",{element});};const onElementPointerLeave=(ev)=>{const element=ev.currentTarget;callHandler("onElementLeave",{element});};const onElementComplexPointerEnter=(ev)=>{if(ctx.haveAlreadyChanged){return;}
const element=ev.currentTarget;const siblingArray=[...element.parentElement.children].filter((el)=>el===current.placeHolder||(el.matches(elementSelector)&&!el.classList.contains(DRAGGED_CLASS)));const elementIndex=siblingArray.indexOf(element);const placeholderIndex=siblingArray.indexOf(current.placeHolder);const isDirectSibling=Math.abs(elementIndex-placeholderIndex)===1;if(connectGroups||!groupSelector||current.group===element.closest(groupSelector)){const pos=current.placeHolder.compareDocumentPosition(element);if(isDirectSibling){if(pos===Node.DOCUMENT_POSITION_PRECEDING){element.before(current.placeHolder);ctx.haveAlreadyChanged=true;}else if(pos===Node.DOCUMENT_POSITION_FOLLOWING){element.after(current.placeHolder);ctx.haveAlreadyChanged=true;}}else{if(pos===Node.DOCUMENT_POSITION_FOLLOWING){element.before(current.placeHolder);ctx.haveAlreadyChanged=true;}else if(pos===Node.DOCUMENT_POSITION_PRECEDING){element.after(current.placeHolder);ctx.haveAlreadyChanged=true;}}}
callHandler("onElementEnter",{element});};const onElementComplexPointerLeave=(ev)=>{if(ctx.haveAlreadyChanged){return;}
const element=ev.currentTarget;const elementRect=element.getBoundingClientRect();const relatedElement=ev.relatedTarget;const relatedElementRect=element.getBoundingClientRect();const siblingArray=[...element.parentElement.children].filter((el)=>el===current.placeHolder||(el.matches(elementSelector)&&!el.classList.contains(DRAGGED_CLASS)));const pointerOnSiblings=siblingArray.indexOf(relatedElement)>-1;const elementIndex=siblingArray.indexOf(element);const isFirst=elementIndex===0;const isAbove=relatedElementRect.top<=elementRect.top;const isLast=elementIndex===siblingArray.length-1;const isBelow=relatedElementRect.bottom>=elementRect.bottom;const pos=current.placeHolder.compareDocumentPosition(element);if(!pointerOnSiblings){if(isFirst&&isAbove&&pos===Node.DOCUMENT_POSITION_PRECEDING){element.before(current.placeHolder);ctx.haveAlreadyChanged=true;}else if(isLast&&isBelow&&pos===Node.DOCUMENT_POSITION_FOLLOWING){element.after(current.placeHolder);ctx.haveAlreadyChanged=true;}}
callHandler("onElementLeave",{element});};const onGroupPointerEnter=(ev)=>{const group=ev.currentTarget;group.appendChild(current.placeHolder);callHandler("onGroupEnter",{group});};const onGroupPointerLeave=(ev)=>{const group=ev.currentTarget;callHandler("onGroupLeave",{group});};const{connectGroups,current,elementSelector,groupSelector,ref}=ctx;if(ctx.placeholderClone){const{width,height}=current.elementRect;addStyle(current.placeHolder,{visibility:"hidden",display:"block",width:`${width}px`,height:`${height}px`,});}
if(connectGroups&&groupSelector){for(const siblingGroup of ref.el.querySelectorAll(groupSelector)){addListener(siblingGroup,"pointerenter",onGroupPointerEnter);addListener(siblingGroup,"pointerleave",onGroupPointerLeave);}}
for(const siblingEl of ref.el.querySelectorAll(elementSelector)){if(siblingEl!==current.element&&siblingEl!==current.placeHolder){if(ctx.placeholderClone){addListener(siblingEl,"pointerenter",onElementPointerEnter);addListener(siblingEl,"pointerleave",onElementPointerLeave);}else{addListener(siblingEl,"pointerenter",onElementComplexPointerEnter);addListener(siblingEl,"pointerleave",onElementComplexPointerLeave);}}}
current.element.after(current.placeHolder);return pick(current,"element","group");},onDrag({ctx}){ctx.haveAlreadyChanged=false;},onDragEnd({ctx}){return pick(ctx.current,"element","group");},onDrop({ctx}){const{current,groupSelector}=ctx;const previous=current.placeHolder.previousElementSibling;const next=current.placeHolder.nextElementSibling;if(previous!==current.element&&next!==current.element){const element=current.element;if(ctx.applyChangeOnDrop){if(previous){previous.after(element);}else if(next){next.before(element);}}
return{element,group:current.group,previous,next,parent:groupSelector&&current.placeHolder.closest(groupSelector),};}},onWillStartDrag({ctx,addCleanup}){const{connectGroups,current,groupSelector}=ctx;if(groupSelector){current.group=current.element.closest(groupSelector);if(!connectGroups){current.container=current.group;}}
if(ctx.placeholderClone){current.placeHolder=current.element.cloneNode(false);}else{current.placeHolder=document.createElement("div");}
current.placeHolder.classList.add(...ctx.placeholderClasses);current.element.classList.add(...ctx.followingElementClasses);addCleanup(()=>current.element.classList.remove(...ctx.followingElementClasses));addCleanup(()=>current.placeHolder.remove());return pick(current,"element","group");},};const useSortable=__exports.useSortable=(sortableParams)=>{const{setupHooks}=sortableParams;delete sortableParams.setupHooks;return nativeMakeDraggableHook({...hookParams,setupHooks})(sortableParams);};return __exports;});;
/* /web/static/src/core/utils/sortable_owl.js */
odoo.define('@web/core/utils/sortable_owl',['@odoo/owl','@web/core/utils/timing','@web/core/utils/sortable'],function(require){'use strict';let __exports={};const{onWillUnmount,reactive,useEffect,useExternalListener}=require("@odoo/owl");const{useThrottleForAnimation}=require("@web/core/utils/timing");const{useSortable:nativeUseSortable}=require("@web/core/utils/sortable");__exports.useSortable=useSortable;function useSortable(params){return nativeUseSortable({...params,setupHooks:{addListener:useExternalListener,setup:useEffect,teardown:onWillUnmount,throttle:useThrottleForAnimation,wrapState:reactive,},});}
return __exports;});;
/* /web/static/src/core/utils/sortable_service.js */
odoo.define('@web/core/utils/sortable_service',['@web/core/registry','@web/core/utils/sortable','@web/core/utils/timing','@odoo/owl'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{useSortable}=require("@web/core/utils/sortable");const{throttleForAnimation}=require("@web/core/utils/timing");const{reactive}=require("@odoo/owl");const DEFAULT_SORTABLE_ID=Symbol.for("defaultSortable");const sortableService=__exports.sortableService={start(){const boundElements=new Map();return{create:(hookParams)=>{const element=hookParams.ref.el;const sortableId=hookParams.sortableId??DEFAULT_SORTABLE_ID;if(boundElements.has(element)){const boundElement=boundElements.get(element);if(sortableId in boundElement){return{enable(){return{cleanup:boundElement[sortableId],};},};}}
const setupFunctions=new Map();const cleanupFunctions=[];const cleanup=()=>{const boundElement=boundElements.get(element);if(sortableId in boundElement){delete boundElement[sortableId];if(boundElement.length===0){boundElements.delete(element);}}
cleanupFunctions.forEach((fn)=>fn());};const setupHooks={wrapState:reactive,throttle:throttleForAnimation,addListener:(el,type,listener)=>{el.addEventListener(type,listener);cleanupFunctions.push(()=>el.removeEventListener(type,listener));},setup:(setupFn,dependenciesFn)=>setupFunctions.set(setupFn,dependenciesFn),teardown:(fn)=>cleanupFunctions.push(fn),};useSortable({setupHooks,...hookParams});const boundElement=boundElements.get(element);if(boundElement){boundElement[sortableId]=cleanup;}else{boundElements.set(element,{[sortableId]:cleanup});}
return{enable(){setupFunctions.forEach((dependenciesFn,setupFn)=>setupFn(...dependenciesFn()));return{cleanup,};},};},};},};registry.category("services").add("sortable",sortableService);return __exports;});;
/* /web/static/src/core/utils/strings.js */
odoo.define('@web/core/utils/strings',['@web/core/utils/objects'],function(require){'use strict';let __exports={};const{isObject}=require("@web/core/utils/objects");function hasSubstitutionDict(substitutions){return substitutions.length===1&&isObject(substitutions[0]);}
const HTML_ESCAPED_CHARACTERS=[["&","&amp;"],["<","&lt;"],[">","&gt;"],["'","&#x27;"],['"',"&quot;"],["`","&#x60;"],];const R_EMAIL=/^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i;const R_FALSY=/^false|0$/i;const R_KEYED_SUBSTITUTION=/%\((?<key>[^)]+)\)s/g;const R_NUMERIC=/^\d+$/;const R_REGEX_SPECIAL_CHARS=/[.*+?^${}()|[\]\\]/g;const nbsp=__exports.nbsp="\u00a0";__exports.capitalize=capitalize;function capitalize(str){return str?str[0].toUpperCase()+str.slice(1):"";}
__exports.escape=escape;function escape(value){if(typeof value!=="string"){return String(value??"");}
for(const[char,replacer]of HTML_ESCAPED_CHARACTERS){value=value.replaceAll(char,replacer);}
return value;}
__exports.escapeRegExp=escapeRegExp;function escapeRegExp(pattern){return pattern.replaceAll(R_REGEX_SPECIAL_CHARS,"\\$&");}
__exports.exprToBoolean=exprToBoolean;function exprToBoolean(str,trueIfEmpty=false){return str?!R_FALSY.test(str):trueIfEmpty;}
__exports.hashCode=hashCode;function hashCode(...strings){const str=strings.join("\x1C");let hash=0;for(let i=0;i<str.length;i++){hash=(hash<<5)-hash+str.charCodeAt(i);hash|=0;}
return(hash+16**8).toString(16).slice(-8);}
__exports.intersperse=intersperse;function intersperse(str,indices,separator){const result=[];let last=str.length;for(let i=0;i<indices.length;++i){let section=indices[i];if(section===-1||last<=0){break;}else if(section===0&&i===0){break;}else if(section===0){section=indices[--i];}
result.unshift(str.substring(last-section,last));last-=section;}
const substr=str.substring(0,last);if(substr){result.unshift(substr);}
return result.join(separator||"");}
__exports.isEmail=isEmail;function isEmail(value){return R_EMAIL.test(value);}
__exports.isNumeric=isNumeric;function isNumeric(value){return R_NUMERIC.test(value);}
__exports.mapSubstitutions=mapSubstitutions;function mapSubstitutions(substitutions,mapFn){if(hasSubstitutionDict(substitutions)){const substitutionDict={};for(const[key,value]of Object.entries(substitutions[0])){substitutionDict[key]=mapFn(value);}
return[substitutionDict];}else{return substitutions.map(mapFn);}}
__exports.sprintf=sprintf;function sprintf(str,...substitutions){if(!substitutions.length){return str;}
if(hasSubstitutionDict(substitutions)){const dict=substitutions[0];return str.replaceAll(R_KEYED_SUBSTITUTION,(_match,key)=>dict[key]??"");}else{const raw=[""];for(let i=0;i<str.length;i++){if(str[i]==="%"){if(str[i+1]==="%"){raw[raw.length-1]+=str[++i];continue;}
if(str[i+1]==="s"){i++;raw.push("");continue;}}
raw[raw.length-1]+=str[i];}
return String.raw({raw},...substitutions);}}
__exports.uuid=uuid;function uuid(){let id="";for(const b of crypto.getRandomValues(new Uint8Array(8))){id+=b.toString(16).padStart(2,"0");}
return id;}
return __exports;});;
/* /web/static/src/core/utils/timing.js */
odoo.define('@web/core/utils/timing',['@web/core/browser/browser','@odoo/owl'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{onWillUnmount,useComponent}=require("@odoo/owl");__exports.batched=batched;function batched(callback,synchronize=()=>Promise.resolve()){let scheduled=false;return async(...args)=>{if(!scheduled){scheduled=true;await synchronize();scheduled=false;callback(...args);}};}
__exports.debounce=debounce;function debounce(func,delay,options){let handle;const funcName=func.name?func.name+" (debounce)":"debounce";const useAnimationFrame=delay==="animationFrame";const setFnName=useAnimationFrame?"requestAnimationFrame":"setTimeout";const clearFnName=useAnimationFrame?"cancelAnimationFrame":"clearTimeout";let lastArgs;let leading=false;let trailing=true;if(typeof options==="boolean"){leading=options;trailing=!options;}else if(options){leading=options.leading??leading;trailing=options.trailing??trailing;}
return Object.assign({[funcName](...args){return new Promise((resolve)=>{if(leading&&!handle){Promise.resolve(func.apply(this,args)).then(resolve);}else{lastArgs=args;}
browser[clearFnName](handle);handle=browser[setFnName](()=>{handle=null;if(trailing&&lastArgs){Promise.resolve(func.apply(this,lastArgs)).then(resolve);lastArgs=null;}},delay);});},}[funcName],{cancel(execNow=false){browser[clearFnName](handle);if(execNow&&lastArgs){func.apply(this,lastArgs);}},});}
__exports.setRecurringAnimationFrame=setRecurringAnimationFrame;function setRecurringAnimationFrame(callback){const handler=(timestamp)=>{callback(timestamp-lastTimestamp);lastTimestamp=timestamp;handle=browser.requestAnimationFrame(handler);};const stop=()=>{browser.cancelAnimationFrame(handle);};let lastTimestamp=browser.performance.now();let handle=browser.requestAnimationFrame(handler);return stop;}
__exports.throttleForAnimation=throttleForAnimation;function throttleForAnimation(func){let handle=null;const calls=new Set();const funcName=func.name?`${func.name} (throttleForAnimation)`:"throttleForAnimation";const pending=()=>{if(calls.size){handle=browser.requestAnimationFrame(pending);const{args,resolve}=[...calls].pop();calls.clear();Promise.resolve(func.apply(this,args)).then(resolve);}else{handle=null;}};return Object.assign({[funcName](...args){return new Promise((resolve)=>{const isNew=handle===null;if(isNew){handle=browser.requestAnimationFrame(pending);Promise.resolve(func.apply(this,args)).then(resolve);}else{calls.add({args,resolve});}});},}[funcName],{cancel(){browser.cancelAnimationFrame(handle);calls.clear();handle=null;},});}
__exports.useDebounced=useDebounced;function useDebounced(callback,delay,{execBeforeUnmount=false,immediate=false,trailing=!immediate}={}){const component=useComponent();const debounced=debounce(callback.bind(component),delay,{leading:immediate,trailing});onWillUnmount(()=>debounced.cancel(execBeforeUnmount));return debounced;}
__exports.useThrottleForAnimation=useThrottleForAnimation;function useThrottleForAnimation(func){const component=useComponent();const throttledForAnimation=throttleForAnimation(func.bind(component));onWillUnmount(()=>throttledForAnimation.cancel());return throttledForAnimation;}
return __exports;});;
/* /web/static/src/core/utils/urls.js */
odoo.define('@web/core/utils/urls',['@web/session','@web/core/browser/browser','@web/core/utils/objects'],function(require){'use strict';let __exports={};const{session}=require("@web/session");const{browser}=require("@web/core/browser/browser");const{shallowEqual}=require("@web/core/utils/objects");const{DateTime}=luxon;const RedirectionError=__exports.RedirectionError=class RedirectionError extends Error{}
__exports.objectToUrlEncodedString=objectToUrlEncodedString;function objectToUrlEncodedString(obj){return Object.entries(obj).map(([k,v])=>`${encodeURIComponent(k)}=${encodeURIComponent(v || "")}`).join("&");}
__exports.getOrigin=getOrigin;function getOrigin(origin){if(origin){origin=origin.replace(/\/+$/,"");}else{const{host,protocol}=browser.location;origin=`${protocol}//${host}`;}
return origin;}
__exports.url=url;function url(route,queryParams,options={}){const origin=getOrigin(options.origin??session.origin);if(!route){return origin;}
let queryString=objectToUrlEncodedString(queryParams||{});queryString=queryString.length>0?`?${queryString}`:queryString;let prefix=["http://","https://","//"].some((el)=>route.length>=el.length&&route.slice(0,el.length)===el);prefix=prefix?"":origin;return`${prefix}${route}${queryString}`;}
__exports.imageUrl=imageUrl;function imageUrl(model,id,field,{access_token,crop,filename,height,unique,width}={}){let route=`/web/image/${model}/${id}/${field}`;if(width&&height){route=`${route}/${width}x${height}`;}
if(filename){route=`${route}/${filename}`;}
const urlParams={};if(access_token){Object.assign(urlParams,{access_token});}
if(crop){Object.assign(urlParams,{crop});}
if(unique){if(unique instanceof DateTime){urlParams.unique=unique.ts;}else{const dateTimeFromUnique=DateTime.fromSQL(unique);if(dateTimeFromUnique.isValid){urlParams.unique=dateTimeFromUnique.ts;}else if(typeof unique==="string"&&unique.length>0){urlParams.unique=unique;}}}
return url(route,urlParams);}
__exports.getDataURLFromFile=getDataURLFromFile;function getDataURLFromFile(file){if(!file){return Promise.reject();}
return new Promise((resolve,reject)=>{const reader=new FileReader();reader.addEventListener("load",()=>{if(reader.result==="data:"){resolve(`data:${file.type};base64,`);}else{resolve(reader.result);}});reader.addEventListener("abort",reject);reader.addEventListener("error",reject);reader.readAsDataURL(file);});}
__exports.redirect=redirect;function redirect(url){const{origin,pathname}=browser.location;const _url=new URL(url,`${origin}${pathname}`);if(_url.origin!==origin){throw new RedirectionError("Can't redirect to another origin");}
browser.location.assign(_url.href);}
__exports.compareUrls=compareUrls;function compareUrls(_url1,_url2){const url1=new URL(_url1);const url2=new URL(_url2);return(url1.origin===url2.origin&&url1.pathname===url2.pathname&&shallowEqual(Object.fromEntries(url1.searchParams),Object.fromEntries(url2.searchParams))&&url1.hash===url2.hash);}
return __exports;});;
/* /web/static/src/core/utils/xml.js */
odoo.define('@web/core/utils/xml',['@web/core/utils/arrays'],function(require){'use strict';let __exports={};const{isIterable}=require("@web/core/utils/arrays");const serializer=new XMLSerializer();const parser=new DOMParser();const xmlDocument=parser.parseFromString("<templates/>","text/xml");function hasParsingError(parsedDocument){return parsedDocument.getElementsByTagName("parsererror").length>0;}
__exports.parseXML=parseXML;function parseXML(str){const xml=parser.parseFromString(str,"text/xml");if(hasParsingError(xml)){throw new Error(`An error occured while parsing ${str}: ${xml.getElementsByTagName("parsererror")}`);}
return xml.documentElement;}
__exports.serializeXML=serializeXML;function serializeXML(xml){return serializer.serializeToString(xml);}
__exports.visitXML=visitXML;function visitXML(xml,callback){const visit=(el)=>{if(el){let didVisitChildren=false;const visitChildren=()=>{for(const child of el.children){visit(child);}
didVisitChildren=true;};const shouldVisitChildren=callback(el,visitChildren);if(shouldVisitChildren!==false&&!didVisitChildren){visitChildren();}}};const xmlDoc=typeof xml==="string"?parseXML(xml):xml;visit(xmlDoc);}
__exports.append=append;function append(parent,node){const nodes=Array.isArray(node)?node:[node];parent.append(...nodes.filter(Boolean));return parent;}
__exports.combineAttributes=combineAttributes;function combineAttributes(el,attr,parts,glue=" "){const allValues=[];if(el.hasAttribute(attr)){allValues.push(el.getAttribute(attr));}
parts=Array.isArray(parts)?parts:[parts];parts=parts.filter((part)=>!!part);allValues.push(...parts);el.setAttribute(attr,allValues.join(glue));}
__exports.createElement=createElement;function createElement(tagName,...args){const el=xmlDocument.createElement(tagName);for(const arg of args){if(!arg){continue;}
if(isIterable(arg)){el.append(...arg);}else if(typeof arg==="object"){for(const name in arg){el.setAttribute(name,arg[name]);}}}
return el;}
__exports.createTextNode=createTextNode;function createTextNode(data){return xmlDocument.createTextNode(data);}
__exports.extractAttributes=extractAttributes;function extractAttributes(el,attributes){const attrs=Object.create(null);for(const attr of attributes){attrs[attr]=el.getAttribute(attr)||"";el.removeAttribute(attr);}
return attrs;}
__exports.getTag=getTag;function getTag(node,lower=false){const tag=(node&&node.nodeName)||"";return lower?tag.toLowerCase():tag;}
__exports.setAttributes=setAttributes;function setAttributes(node,attributes){for(const[name,value]of Object.entries(attributes)){node.setAttribute(name,value);}}
return __exports;});;
/* /web/static/src/core/virtual_grid_hook.js */
odoo.define('@web/core/virtual_grid_hook',['@odoo/owl','@web/core/utils/objects','@web/core/utils/timing'],function(require){'use strict';let __exports={};const{useComponent,useEffect,useExternalListener}=require("@odoo/owl");const{pick,shallowEqual}=require("@web/core/utils/objects");const{useThrottleForAnimation}=require("@web/core/utils/timing");const BUFFER_COEFFICIENT=1;function getIndexes({sizes,start,span,prevStartIndex,bufferCoef=BUFFER_COEFFICIENT}){if(!sizes||!sizes.length){return[];}
if(sizes.at(-1)<span){return[0,sizes.length-1];}
const bufferSize=Math.round(span*bufferCoef);const bufferStart=start-bufferSize;const bufferEnd=start+span+bufferSize;let startIndex=prevStartIndex??0;while(startIndex>0&&sizes[startIndex]>bufferStart){startIndex--;}
while(startIndex<sizes.length-1&&sizes[startIndex]<=bufferStart){startIndex++;}
let endIndex=startIndex;while(endIndex<sizes.length-1&&(sizes[endIndex-1]??0)<bufferEnd){endIndex++;}
while(endIndex>startIndex&&(sizes[endIndex-1]??0)>=bufferEnd){endIndex--;}
return[startIndex,endIndex];}
__exports.useVirtualGrid=useVirtualGrid;function useVirtualGrid({scrollableRef,initialScroll,onChange,bufferCoef}){const comp=useComponent();onChange||=()=>comp.render();const current={scroll:{left:0,top:0,...initialScroll}};const computeColumnsIndexes=()=>{return getIndexes({sizes:current.summedColumnsWidths,start:Math.abs(current.scroll.left),span:window.innerWidth,prevStartIndex:current.columnsIndexes?.[0],bufferCoef,});};const computeRowsIndexes=()=>{return getIndexes({sizes:current.summedRowsHeights,start:current.scroll.top,span:window.innerHeight,prevStartIndex:current.rowsIndexes?.[0],bufferCoef,});};const throttledCompute=useThrottleForAnimation(()=>{const changed=[];const columnsVisibleIndexes=computeColumnsIndexes();if(!shallowEqual(columnsVisibleIndexes,current.columnsIndexes)){current.columnsIndexes=columnsVisibleIndexes;changed.push("columnsIndexes");}
const rowsVisibleIndexes=computeRowsIndexes();if(!shallowEqual(rowsVisibleIndexes,current.rowsIndexes)){current.rowsIndexes=rowsVisibleIndexes;changed.push("rowsIndexes");}
if(changed.length){onChange(pick(current,...changed));}});const scrollListener=(ev)=>{current.scroll.left=ev.target.scrollLeft;current.scroll.top=ev.target.scrollTop;throttledCompute();};useEffect((el)=>{el?.addEventListener("scroll",scrollListener);return()=>el?.removeEventListener("scroll",scrollListener);},()=>[scrollableRef.el]);useExternalListener(window,"resize",()=>throttledCompute());return{get columnsIndexes(){return current.columnsIndexes;},get rowsIndexes(){return current.rowsIndexes;},setColumnsWidths(widths){let acc=0;current.summedColumnsWidths=widths.map((w)=>(acc+=w));delete current.columnsIndexes;current.columnsIndexes=computeColumnsIndexes();},setRowsHeights(heights){let acc=0;current.summedRowsHeights=heights.map((h)=>(acc+=h));delete current.rowsIndexes;current.rowsIndexes=computeRowsIndexes();},};}
return __exports;});;
/* /web/static/src/core/commands/default_providers.js */
odoo.define('@web/core/commands/default_providers',['@web/core/browser/feature_detection','@web/core/hotkeys/hotkey_hook','@web/core/l10n/translation','@web/core/registry','@web/core/utils/strings','@web/core/utils/ui','@web/core/commands/command_palette','@odoo/owl'],function(require){'use strict';let __exports={};const{isMacOS}=require("@web/core/browser/feature_detection");const{useHotkey}=require("@web/core/hotkeys/hotkey_hook");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{registry}=require("@web/core/registry");const{capitalize}=require("@web/core/utils/strings");const{getVisibleElements}=require("@web/core/utils/ui");const{DefaultCommandItem}=require("@web/core/commands/command_palette");const{Component}=require("@odoo/owl");const commandSetupRegistry=registry.category("command_setup");commandSetupRegistry.add("default",{emptyMessage:_t("No command found"),placeholder:_t("Search for a command..."),});const HotkeyCommandItem=__exports.HotkeyCommandItem=class HotkeyCommandItem extends Component{static template="web.HotkeyCommandItem";static props=["hotkey","hotkeyOptions?","name?","searchValue?","executeCommand","slots"];setup(){useHotkey(this.props.hotkey,this.props.executeCommand);}
getKeysToPress(command){const{hotkey}=command;let result=hotkey.split("+");if(isMacOS()){result=result.map((x)=>x.replace("control","command")).map((x)=>x.replace("alt","control"));}
return result.map((key)=>key.toUpperCase());}}
const commandCategoryRegistry=registry.category("command_categories");const commandProviderRegistry=registry.category("command_provider");commandProviderRegistry.add("command",{provide:(env,options={})=>{const commands=env.services.command.getCommands(options.activeElement).map((cmd)=>{cmd.category=commandCategoryRegistry.contains(cmd.category)?cmd.category:"default";return cmd;}).filter((command)=>command.isAvailable===undefined||command.isAvailable());const uniqueCommands=commands.filter((obj,index)=>{return(index===commands.findIndex((o)=>obj.name===o.name&&obj.category===o.category));});return uniqueCommands.map((command)=>({Component:command.hotkey?HotkeyCommandItem:DefaultCommandItem,action:command.action,category:command.category,name:command.name,props:{hotkey:command.hotkey,hotkeyOptions:command.hotkeyOptions,},}));},});commandProviderRegistry.add("data-hotkeys",{provide:(env,options={})=>{const commands=[];const overlayModifier=registry.category("services").get("hotkey").overlayModifier;for(const el of getVisibleElements(options.activeElement,"[data-hotkey]:not(:disabled)")){const closest=el.closest("[data-command-category]");const category=closest?closest.dataset.commandCategory:"default";if(category==="disabled"){continue;}
const description=el.title||el.dataset.bsOriginalTitle||el.dataset.tooltip||el.placeholder||(el.innerText&&`${el.innerText.slice(0, 50)}${el.innerText.length > 50 ? "..." : ""}`)||_t("no description provided");commands.push({Component:HotkeyCommandItem,action:()=>{el.focus();el.click();},category,name:capitalize(description.trim().toLowerCase()),props:{hotkey:`${overlayModifier}+${el.dataset.hotkey}`,},});}
return commands;},});return __exports;});;
/* /web/static/src/core/commands/command_palette.js */
odoo.define('@web/core/commands/command_palette',['@web/core/dialog/dialog','@web/core/hotkeys/hotkey_hook','@web/core/l10n/translation','@web/core/utils/concurrency','@web/core/utils/hooks','@web/core/utils/scrolling','@web/core/utils/search','@web/core/utils/timing','@web/core/browser/feature_detection','@web/core/utils/html','@odoo/owl'],function(require){'use strict';let __exports={};const{Dialog}=require("@web/core/dialog/dialog");const{useHotkey}=require("@web/core/hotkeys/hotkey_hook");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);const{KeepLast,Race}=require("@web/core/utils/concurrency");const{useAutofocus,useService}=require("@web/core/utils/hooks");const{scrollTo}=require("@web/core/utils/scrolling");const{fuzzyLookup}=require("@web/core/utils/search");const{debounce}=require("@web/core/utils/timing");const{isMacOS,isMobileOS}=require("@web/core/browser/feature_detection");const{highlightText}=require("@web/core/utils/html");const{Component,onWillStart,onWillDestroy,EventBus,useRef,useState,markRaw,useExternalListener,}=require("@odoo/owl");const DEFAULT_PLACEHOLDER=_t("Search...");const DEFAULT_EMPTY_MESSAGE=_t("No result found");const FUZZY_NAMESPACES=["default"];function commandsWithinCategory(categoryName,categories){return(cmd)=>{const inCurrentCategory=categoryName===cmd.category;const fallbackCategory=categoryName==="default"&&!categories.includes(cmd.category);return inCurrentCategory||fallbackCategory;};}
const DefaultCommandItem=__exports.DefaultCommandItem=class DefaultCommandItem extends Component{static template="web.DefaultCommandItem";static props={slots:{type:Object,optional:true},hotkey:{type:String,optional:true},hotkeyOptions:{type:String,optional:true},name:{type:String,optional:true},searchValue:{type:String,optional:true},executeCommand:{type:Function,optional:true},};}
const CommandPalette=__exports.CommandPalette=class CommandPalette extends Component{static template="web.CommandPalette";static components={Dialog};static lastSessionId=0;static props={bus:{type:EventBus,optional:true},close:Function,config:Object,closeMe:{type:Function,optional:true},};setup(){if(this.props.bus){const setConfig=({detail})=>this.setCommandPaletteConfig(detail);this.props.bus.addEventListener(`SET-CONFIG`,setConfig);onWillDestroy(()=>this.props.bus.removeEventListener(`SET-CONFIG`,setConfig));}
this.keyId=1;this.race=new Race();this.keepLast=new KeepLast();this._sessionId=CommandPalette.lastSessionId++;this.DefaultCommandItem=DefaultCommandItem;this.activeElement=useService("ui").activeElement;this.inputRef=useAutofocus();useHotkey("Enter",()=>this.executeSelectedCommand(),{bypassEditableProtection:true});useHotkey("Control+Enter",()=>this.executeSelectedCommand(true),{bypassEditableProtection:true,});useHotkey("ArrowUp",()=>this.selectCommandAndScrollTo("PREV"),{bypassEditableProtection:true,allowRepeat:true,});useHotkey("ArrowDown",()=>this.selectCommandAndScrollTo("NEXT"),{bypassEditableProtection:true,allowRepeat:true,});useExternalListener(window,"mousedown",this.onWindowMouseDown);this.state=useState({});this.root=useRef("root");this.listboxRef=useRef("listbox");onWillStart(()=>this.setCommandPaletteConfig(this.props.config));}
get commandsByCategory(){const categories=[];for(const category of this.categoryKeys){const commands=this.state.commands.filter(commandsWithinCategory(category,this.categoryKeys));if(commands.length){categories.push({commands,name:this.categoryNames[category],keyId:category,});}}
return categories;}
async setCommandPaletteConfig(config){this.configByNamespace=config.configByNamespace||{};this.state.FooterComponent=config.FooterComponent;this.providersByNamespace={default:[]};for(const provider of config.providers){const namespace=provider.namespace||"default";if(namespace in this.providersByNamespace){this.providersByNamespace[namespace].push(provider);}else{this.providersByNamespace[namespace]=[provider];}}
const{namespace,searchValue}=this.processSearchValue(config.searchValue||"");this.switchNamespace(namespace);this.state.searchValue=searchValue;await this.race.add(this.search(searchValue));}
async setCommands(namespace,options={}){this.categoryKeys=["default"];this.categoryNames={};const proms=this.providersByNamespace[namespace].map((provider)=>{const{provide}=provider;const result=provide(this.env,options);return result;});let commands=(await this.keepLast.add(Promise.all(proms))).flat();const namespaceConfig=this.configByNamespace[namespace]||{};if(options.searchValue&&FUZZY_NAMESPACES.includes(namespace)){commands=fuzzyLookup(options.searchValue,commands,(c)=>c.name);}else{if(namespaceConfig.categories){let commandsSorted=[];this.categoryKeys=namespaceConfig.categories;this.categoryNames=namespaceConfig.categoryNames||{};if(!this.categoryKeys.includes("default")){this.categoryKeys.push("default");}
for(const category of this.categoryKeys){commandsSorted=commandsSorted.concat(commands.filter(commandsWithinCategory(category,this.categoryKeys)));}
commands=commandsSorted;}}
this.state.commands=markRaw(commands.slice(0,100).map((command)=>({...command,keyId:this.keyId++,text:highlightText(options.searchValue,command.name,"fw-bolder text-primary"),})));this.selectCommand(this.state.commands.length?0:-1);this.mouseSelectionActive=false;this.state.emptyMessage=(namespaceConfig.emptyMessage||DEFAULT_EMPTY_MESSAGE).toString();}
selectCommand(index){if(index===-1||index>=this.state.commands.length){this.state.selectedCommand=null;return;}
this.state.selectedCommand=markRaw(this.state.commands[index]);}
selectCommandAndScrollTo(type){this.mouseSelectionActive=false;const index=this.state.commands.indexOf(this.state.selectedCommand);if(index===-1){return;}
let nextIndex;if(type==="NEXT"){nextIndex=index<this.state.commands.length-1?index+1:0;}else if(type==="PREV"){nextIndex=index>0?index-1:this.state.commands.length-1;}
this.selectCommand(nextIndex);const command=this.listboxRef.el.querySelector(`#o_command_${nextIndex}`);scrollTo(command,{scrollable:this.listboxRef.el});}
onCommandClicked(event,index){event.preventDefault();this.selectCommand(index);const ctrlKey=isMacOS()?event.metaKey:event.ctrlKey;this.executeSelectedCommand(ctrlKey);}
async executeCommand(command){const config=await command.action();if(config){this.setCommandPaletteConfig(config);}else{this.props.close();}}
async executeSelectedCommand(ctrlKey){await this.searchValuePromise;const selectedCommand=this.state.selectedCommand;if(selectedCommand){if(!ctrlKey){this.executeCommand(selectedCommand);}else if(selectedCommand.href){window.open(selectedCommand.href,"_blank");}}}
onCommandMouseEnter(index){if(this.mouseSelectionActive){this.selectCommand(index);}else{this.mouseSelectionActive=true;}}
async search(searchValue){this.state.isLoading=true;try{await this.setCommands(this.state.namespace,{searchValue,activeElement:this.activeElement,sessionId:this._sessionId,});}finally{this.state.isLoading=false;}
if(this.inputRef.el){this.inputRef.el.focus();}}
debounceSearch(value){const{namespace,searchValue}=this.processSearchValue(value);if(namespace!=="default"&&this.state.namespace!==namespace){this.switchNamespace(namespace);}
this.state.searchValue=searchValue;this.searchValuePromise=this.lastDebounceSearch(searchValue).catch(()=>{this.searchValuePromise=null;});}
onSearchInput(ev){this.debounceSearch(ev.target.value);}
onKeyDown(ev){if(ev.key.toLowerCase()==="backspace"&&!ev.target.value.length&&!ev.repeat){this.switchNamespace("default");this.state.searchValue="";this.searchValuePromise=this.lastDebounceSearch("").catch(()=>{this.searchValuePromise=null;});}}
onWindowMouseDown(ev){if(!this.root.el.contains(ev.target)){this.props.close();}}
switchNamespace(namespace){if(this.lastDebounceSearch){this.lastDebounceSearch.cancel();}
const namespaceConfig=this.configByNamespace[namespace]||{};this.lastDebounceSearch=debounce((value)=>this.search(value),namespaceConfig.debounceDelay||0);this.state.namespace=namespace;this.state.placeholder=namespaceConfig.placeholder||DEFAULT_PLACEHOLDER.toString();}
processSearchValue(searchValue){let namespace="default";if(searchValue.length&&this.providersByNamespace[searchValue[0]]){namespace=searchValue[0];searchValue=searchValue.slice(1);}
return{namespace,searchValue};}
get isMacOS(){return isMacOS();}
get isMobileOS(){return isMobileOS();}}
return __exports;});;
/* /web/static/src/public/caps_lock_warning.js */
odoo.define('@web/public/caps_lock_warning',['@web/public/interaction','@web/core/registry'],function(require){'use strict';let __exports={};const{Interaction}=require("@web/public/interaction");const{registry}=require("@web/core/registry");const CapsLockWarning=__exports.CapsLockWarning=class CapsLockWarning extends Interaction{static selector=".o_caps_lock_warning";dynamicContent={".o_caps_lock_warning_text":{"t-att-class":()=>({"d-none":this.isWarningHidden}),},".o_caps_lock_warning input[type='password']":{"t-on-keydown":this._onInputKeyDown,},};setup(){this.isWarningHidden=true;this.renderAt("web.caps_lock_warning");}
_onInputKeyDown(ev){const state=ev.getModifierState?.("CapsLock");this.isWarningHidden=ev.key==="CapsLock"?state:!state;}}
registry.category("public.interactions").add("web.caps_lock_warning",CapsLockWarning);return __exports;});;
/* /web/static/src/public/colibri.js */
odoo.define('@web/public/colibri',[],function(require){'use strict';let __exports={};let owl=null;let Markup=null;const INITIAL_VALUE=__exports.INITIAL_VALUE=Symbol("initial value");const SKIP_IMPLICIT_UPDATE=__exports.SKIP_IMPLICIT_UPDATE=Symbol();const Colibri=__exports.Colibri=class Colibri{constructor(core,I,el){this.el=el;this.isReady=false;this.hasStarted=false;this.isUpdating=false;this.isDestroyed=false;this.dynamicAttrs=[];this.tOuts=[];this.cleanups=[];this.listeners=new Map();this.dynamicNodes=new Map();this.core=core;this.interaction=new I(el,core.env,this);this.setupInteraction();}
setupInteraction(){this.interaction.setup();}
destroyInteraction(){for(const cleanup of this.cleanups.reverse()){cleanup();}
this.cleanups=[];this.interaction.destroy();}
startInteraction(content){if(content){this.processContent(content);this.updateContent();}
this.interaction.start();this.hasStarted=true;}
async start(){await this.interaction.willStart();if(this.isDestroyed){return;}
this.isReady=true;const content=this.interaction.dynamicContent;this.startInteraction(content);}
addListener(nodes,event,fn,options){if(typeof fn!=="function"){throw new Error(`Invalid listener for event '${event}' (not a function)`);}
if(!this.isReady){throw new Error("this.addListener can only be called after the interaction is started. Maybe move the call in the start method.");}
const re=/^(?<event>.*)\.(?<suffix>prevent|stop|capture|once|noUpdate|withTarget)$/;let groups=re.exec(event)?.groups;while(groups){fn={prevent:(f)=>(ev,...args)=>{ev.preventDefault();return f.call(this.interaction,ev,...args);},stop:(f)=>(ev,...args)=>{ev.stopPropagation();return f.call(this.interaction,ev,...args);},capture:(f)=>{options||={};options.capture=true;return f;},once:(f)=>{options||={};options.once=true;return f;},noUpdate:(f)=>(...args)=>{f.call(this.interaction,...args);return SKIP_IMPLICIT_UPDATE;},withTarget:(f)=>(ev,...args)=>{const currentTarget=ev.currentTarget;return f.call(this.interaction,ev,currentTarget,...args);},}[groups.suffix](fn);event=groups.event;groups=re.exec(event)?.groups;}
const handler=fn.isHandler?fn:async(...args)=>{if(SKIP_IMPLICIT_UPDATE!==(await fn.call(this.interaction,...args))){if(!this.isDestroyed){this.updateContent();}}};handler.isHandler=true;for(const node of nodes){node.addEventListener(event,handler,options);this.cleanups.push(()=>node.removeEventListener(event,handler,options));}
return[event,handler,options];}
refreshNodes(){for(const sel of this.dynamicNodes.keys()){const nodes=this.getNodes(sel);if(this.listeners.has(sel)){const newNodes=new Set(nodes);const oldNodes=this.dynamicNodes.get(sel);const events=this.listeners.get(sel);const toRemove=new Set();for(const node of oldNodes){if(newNodes.has(node)){newNodes.delete(node);}else{toRemove.add(node);}}
for(const event of Object.keys(events)){const[handler,options]=events[event];for(const node of toRemove){node.removeEventListener(event,handler,options);}
if(newNodes.size){this.addListener(newNodes,event,handler,options);}}}
this.dynamicNodes.set(sel,nodes);}}
mapSelectorToListeners(sel,event,handler,options){if(this.listeners.has(sel)){this.listeners.get(sel)[event]=[handler,options];}else{this.listeners.set(sel,{[event]:[handler,options]});}}
mountComponent(node,C,props,position="beforeend"){const root=this.core.prepareRoot(node,C,props,position);root.mount();this.cleanups.push(()=>root.destroy());return root.destroy;}
applyTOut(el,value,initialValue){if(value===INITIAL_VALUE){value=initialValue;}
if(!Markup){if(owl){Markup=owl.markup("").constructor;}}
if(Markup&&value instanceof Markup){let nodes=el===this.interaction.el?el.children:[el];for(const node of nodes){this.core.env.services["public.interactions"].stopInteractions(node);}
el.innerHTML=value;if(el===this.interaction.el){nodes=el.children;}
for(const node of nodes){this.core.env.services["public.interactions"].startInteractions(node);}
this.refreshNodes();}else{el.textContent=value;}}
applyAttr(el,attr,value,initialValue){if(attr==="class"){if(typeof value!=="object"){throw new Error("t-att-class directive expects an object");}
for(const cl in value){let toApply=value[cl];for(const c of cl.trim().split(" ")){if(toApply===INITIAL_VALUE){toApply=initialValue[cl];}
el.classList.toggle(c,toApply||false);}}}else if(attr==="style"){if(typeof value!=="object"){throw new Error("t-att-style directive expects an object");}
for(const prop in value){let style=value[prop];if(style===INITIAL_VALUE){style=initialValue[prop];}
if(style===undefined){el.style.removeProperty(prop);}else{style=String(style);if(style.endsWith(" !important")){el.style.setProperty(prop,style.substring(0,style.length-11),"important");}else{el.style.setProperty(prop,style);}}}}else{if(value===INITIAL_VALUE){value=initialValue;}
if([false,undefined,null].includes(value)){el.removeAttribute(attr);}else{if(value===true){value=attr;}
el.setAttribute(attr,value);}}}
getNodes(sel){const selectors=this.interaction.dynamicSelectors;if(sel in selectors){const elems=selectors[sel]();if(elems){if(elems.nodeName&&["FORM","SELECT"].includes(elems.nodeName)){return[elems];}
return elems[Symbol.iterator]?elems:[elems];}else{return[];}}
return this.interaction.el.querySelectorAll(sel);}
processContent(content){for(const sel in content){if(sel.startsWith("t-")){throw new Error(`Selector missing for key ${sel} in dynamicContent (interaction '${this.interaction.constructor.name}').`);}
let nodes;if(this.dynamicNodes.has(sel)){nodes=this.dynamicNodes.get(sel);}else{nodes=this.getNodes(sel);this.dynamicNodes.set(sel,nodes);}
const descr=content[sel];for(const directive in descr){const value=descr[directive];if(directive.startsWith("t-on-")){const ev=directive.slice(5);const[event,handler,options]=this.addListener(nodes,ev,value);this.mapSelectorToListeners(sel,event,handler,options);}else if(directive.startsWith("t-att-")){const attr=directive.slice(6);this.dynamicAttrs.push({sel,attr,definition:value,initialValues:null,});}else if(directive==="t-out"){this.tOuts.push({sel,definition:value,initialValue:null});}else if(directive==="t-component"){const{Component}=odoo.loader.modules.get("@odoo/owl");if(Object.prototype.isPrototypeOf.call(Component,value)){for(const node of nodes){this.mountComponent(node,value);}}else{for(const node of nodes){this.mountComponent(node,...value(node));}}}else{const suffix=directive.startsWith("t-")?"":" (should start with t-)";throw new Error(`Invalid directive: '${directive}'${suffix}`);}}}}
updateContent(){if(this.isDestroyed||!this.isReady){throw new Error("Cannot update content of an interaction that is not ready or is destroyed");}
if(this.isUpdating){throw new Error("Updatecontent should not be called while interaction is updating");}
this.isUpdating=true;if(this.hasStarted){this.refreshNodes();}
const errors=[];const interaction=this.interaction;for(const dynamicAttr of this.dynamicAttrs){let{sel,attr,definition,initialValues}=dynamicAttr;const nodes=this.dynamicNodes.get(sel)||[];if(!initialValues&&nodes.length){initialValues=new Map();dynamicAttr.initialValues=initialValues;}
for(const node of nodes){try{const value=definition.call(interaction,node);if(!initialValues||!initialValues.has(node)){let attrValue;switch(attr){case"class":attrValue={};for(const classNames of Object.keys(value)){attrValue[classNames]=node.classList.contains(classNames);}
break;case"style":attrValue={};for(const property of Object.keys(value)){const propertyValue=node.style.getPropertyValue(property);const priority=node.style.getPropertyPriority(property);attrValue[property]=propertyValue?propertyValue+(priority?` !${priority}`:""):undefined;}
break;default:attrValue=node.getAttribute(attr);}
initialValues.set(node,attrValue);}
this.applyAttr(node,attr,value,dynamicAttr.initialValues.get(node));}catch(e){errors.push({error:e,attribute:attr});}}}
for(const tOut of this.tOuts){let{sel,definition,initialValue}=tOut;const nodes=this.dynamicNodes.get(sel)||[];if(!initialValue&&nodes.length){initialValue=new Map();tOut.initialValue=initialValue;}
for(const node of nodes){if(!initialValue||!initialValue.has(node)){if(!owl){owl=odoo.loader.modules.get("@odoo/owl");}
const value=node.children.length?owl.markup(node.innerHTML):node.textContent;initialValue.set(node,value);}
this.applyTOut(node,definition.call(interaction,node),tOut.initialValue.get(node));}}
this.isUpdating=false;if(errors.length){const{attribute,error}=errors[0];throw Error(`An error occured while updating dynamic attribute '${attribute}' (in interaction '${this.interaction.constructor.name}')`,{cause:error});}}
destroy(){for(const dynAttrs of this.dynamicAttrs){const{sel,attr,initialValues}=dynAttrs;if(!initialValues){continue;}
for(const node of this.dynamicNodes.get(sel)||[]){if(initialValues.has(node)){const initialValue=initialValues.get(node);this.applyAttr(node,attr,initialValue);}}}
for(const tOut of this.tOuts){const{sel,initialValue}=tOut;if(!initialValue){continue;}
for(const node of this.dynamicNodes.get(sel)||[]){if(initialValue.has(node)){const value=initialValue.get(node);this.applyTOut(node,value);}}}
this.listeners.clear();this.dynamicNodes.clear();this.destroyInteraction();this.core=null;this.isDestroyed=true;this.isReady=false;}
protectSyncAfterAsync(interaction,name,fn){return fn.bind(interaction);}}
return __exports;});;
/* /web/static/src/public/datetime_picker.js */
odoo.define('@web/public/datetime_picker',['@web/core/l10n/dates','@web/core/registry','@web/public/interaction'],function(require){'use strict';let __exports={};const{deserializeDate,deserializeDateTime,parseDate,parseDateTime,}=require("@web/core/l10n/dates");const{registry}=require("@web/core/registry");const{Interaction}=require("@web/public/interaction");const DatetimePicker=__exports.DatetimePicker=class DatetimePicker extends Interaction{static selector="[data-widget='datetime-picker']";setup(){this.minDate=this.el.dataset.minDate;this.maxDate=this.el.dataset.maxDate;this.type=this.el.dataset.widgetType||"datetime";}
start(){const parseFunction=this.type==="date"?parseDate:parseDateTime;const deserializeFunction=this.type==="date"?deserializeDate:deserializeDateTime;this.registerCleanup(this.services.datetime_picker.create({target:this.el,pickerProps:{type:this.type,minDate:this.minDate&&deserializeFunction(this.minDate),maxDate:this.maxDate&&deserializeFunction(this.maxDate),value:parseFunction(this.el.value),},}).enable());}}
registry.category("public.interactions").add("web.datetime_picker",DatetimePicker);return __exports;});;
/* /web/static/src/public/error_notifications.js */
odoo.define('@web/public/error_notifications',['@web/core/registry','@web/core/errors/error_dialogs','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{odooExceptionTitleMap}=require("@web/core/errors/error_dialogs");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web",...args);odooExceptionTitleMap.forEach((title,exceptionName)=>{registry.category("error_notifications").add(exceptionName,{title:title,type:"warning",sticky:true,});});const sessionExpired={title:_t("Odoo Session Expired"),message:_t("Your Odoo session expired. The current page is about to be refreshed."),buttons:[{text:_t("Ok"),click:()=>window.location.reload(true),close:true,},],};registry.category("error_notifications").add("odoo.http.SessionExpiredException",sessionExpired).add("werkzeug.exceptions.Forbidden",sessionExpired).add("504",{title:_t("Request timeout"),message:_t("The operation was interrupted. This usually means that the current operation is taking too much time."),});return __exports;});;
/* /web/static/src/public/interaction.js */
odoo.define('@web/public/interaction',['@web/core/utils/render','@web/core/utils/timing','@web/public/colibri','@web/public/utils'],function(require){'use strict';let __exports={};const{renderToFragment}=require("@web/core/utils/render");const{debounce,throttleForAnimation}=require("@web/core/utils/timing");const{INITIAL_VALUE,SKIP_IMPLICIT_UPDATE}=require("@web/public/colibri");const{makeAsyncHandler,makeButtonHandler}=require("@web/public/utils");const Interaction=__exports.Interaction=class Interaction{static selector="";static selectorHas="";static selectorNotHas="";static INITIAL_VALUE=INITIAL_VALUE;dynamicSelectors={_root:()=>this.el,_body:()=>this.el.ownerDocument.body,_window:()=>window,_document:()=>this.el.ownerDocument,};dynamicContent={};constructor(el,env,metadata){this.__colibri__=metadata;this.el=el;this.env=env;this.services=env.services;}
get isReady(){return this.__colibri__.isReady;}
get isDestroyed(){return this.__colibri__.isDestroyed;}
setup(){}
async willStart(){}
start(){}
destroy(){}
updateContent(){this.__colibri__.updateContent();}
waitFor(promise=Promise.resolve()){const prom=new Promise((resolve,reject)=>{promise.then((result)=>{if(!this.isDestroyed){resolve(result);prom.then(()=>{if(this.isReady){this.updateContent();}});}}).catch((e)=>{reject(e);prom.catch(()=>{if(this.isReady&&!this.isDestroyed){this.updateContent();}});});});return prom;}
protectSyncAfterAsync(fn){return this.__colibri__.protectSyncAfterAsync(this,"protectSyncAfterAsync",fn);}
waitForTimeout(fn,delay){fn=this.__colibri__.protectSyncAfterAsync(this,"waitForTimeout",fn);return setTimeout(()=>{if(!this.isDestroyed){fn.call(this);if(this.isReady){this.updateContent();}}},parseInt(delay));}
waitForAnimationFrame(fn){fn=this.__colibri__.protectSyncAfterAsync(this,"waitForAnimationFrame",fn);return window.requestAnimationFrame(()=>{if(!this.isDestroyed){fn.call(this);if(this.isReady){this.updateContent();}}});}
debounced(fn,delay,options){fn=this.__colibri__.protectSyncAfterAsync(this,"debounced",fn);const debouncedFn=debounce(async(...args)=>{await fn.apply(this,args);if(this.isReady&&!this.isDestroyed){this.updateContent();}},delay,options);this.registerCleanup(()=>{debouncedFn.cancel();});return Object.assign({[debouncedFn.name]:(...args)=>{debouncedFn(...args);return SKIP_IMPLICIT_UPDATE;},}[debouncedFn.name],{cancel:debouncedFn.cancel,});}
throttled(fn){fn=this.__colibri__.protectSyncAfterAsync(this,"throttled",fn);const throttledFn=throttleForAnimation(async(...args)=>{await fn.apply(this,args);if(this.isReady&&!this.isDestroyed){this.updateContent();}});this.registerCleanup(()=>{throttledFn.cancel();});return Object.assign({[throttledFn.name]:(...args)=>{throttledFn(...args);return SKIP_IMPLICIT_UPDATE;},}[throttledFn.name],{cancel:throttledFn.cancel,});}
locked(fn,useLoadingAnimation=false){fn=this.__colibri__.protectSyncAfterAsync(this,"locked",fn);if(useLoadingAnimation){return makeButtonHandler(fn);}
return makeAsyncHandler(fn);}
addListener(target,event,fn,options){let nodes;if(target.nodeName&&["FORM","SELECT"].includes(target.nodeName)){nodes=[target];}else{nodes=target[Symbol.iterator]?target:[target];}
const[ev,handler,opts]=this.__colibri__.addListener(nodes,event,fn,options);return()=>nodes.forEach((node)=>node.removeEventListener(ev,handler,opts));}
insert(el,locationEl=this.el,position="beforeend",removeOnClean=true){locationEl.insertAdjacentElement(position,el);if(removeOnClean){this.registerCleanup(()=>el.remove());}
this.services["public.interactions"].startInteractions(el);this.__colibri__.refreshNodes();}
removeChildren(el,insertBackOnClean=true){for(const child of el.children){this.services["public.interactions"].stopInteractions(child);}
const children=[...el.childNodes];el.replaceChildren();if(insertBackOnClean){this.registerCleanup(()=>el.replaceChildren(...children));}}
renderAt(template,renderContext,locationEl,position="beforeend",callback,removeOnClean=true){const fragment=renderToFragment(template,renderContext);const result=[...fragment.children];const els=[...fragment.children];callback?.(els);if(["afterend","afterbegin"].includes(position)){els.reverse();}
for(const el of els){this.insert(el,locationEl,position,removeOnClean);}
return result;}
registerCleanup(fn){this.__colibri__.cleanups.push(fn.bind(this));}
mountComponent(el,C,props=null,position="beforeend"){return this.__colibri__.mountComponent(el,C,props,position);}}
return __exports;});;
/* /web/static/src/public/interaction_service.js */
odoo.define('@web/public/interaction_service',['@web/core/registry','@web/core/l10n/translation','@web/public/interaction','@web/core/templates','@web/public/utils','@web/public/colibri'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{appTranslateFn}=require("@web/core/l10n/translation");const{Interaction}=require("@web/public/interaction");const{getTemplate}=require("@web/core/templates");const{PairSet}=require("@web/public/utils");const{Colibri}=require("@web/public/colibri");class InteractionService{constructor(el,env){this.Interactions=[];this.el=el;this.isActive=false;this.activeInteractions=new PairSet();this.env=env;this.interactions=[];this.roots=[];this.owlApp=null;this.proms=[];this.registry=null;}
activate(Interactions,target){this.Interactions=Interactions;const startProm=this.env.isReady.then(()=>this.startInteractions(target));this.proms.push(startProm);}
prepareRoot(el,C,props,position="beforeend"){if(!this.owlApp){const{App}=odoo.loader.modules.get("@odoo/owl");const appConfig={name:"Odoo Website",getTemplate,env:this.env,dev:this.env.debug,translateFn:appTranslateFn,warnIfNoStaticProps:this.env.debug,translatableAttributes:["data-tooltip"],};this.owlApp=new App(null,appConfig);}
const root=this.owlApp.createRoot(C,{props,env:this.env});const rootEl=document.createElement("owl-root");rootEl.setAttribute("contenteditable","false");rootEl.dataset.oeProtected="true";rootEl.style.display="contents";el.insertAdjacentElement(position,rootEl);return{C,root,el:rootEl,mount:()=>root.mount(rootEl),destroy:()=>{root.destroy();rootEl.remove();},};}
async _mountComponent(el,C){const root=this.prepareRoot(el,C);this.roots.push(root);return root.mount();}
startInteractions(el=this.el){if(!el.isConnected){return Promise.resolve();}
const proms=[];for(const I of this.Interactions){if(I.selector===""){throw new Error(`The selector should be defined as a static property on the class ${I.name}, not on the instance`);}
if(I.dynamicContent){throw new Error(`The dynamic content object should be defined on the instance, not on the class (${I.name})`);}
let targets;try{const isMatch=el.matches(I.selector);targets=isMatch?[el,...el.querySelectorAll(I.selector)]:el.querySelectorAll(I.selector);if(I.selectorHas){targets=[...targets].filter((el)=>!!el.querySelector(I.selectorHas));}
if(I.selectorNotHas){targets=[...targets].filter((el)=>!el.querySelector(I.selectorNotHas));}}catch{const selectorHasError=I.selectorHas?` or selectorHas: '${I.selectorHas}'`:"";const selectorNotHasError=I.selectorNotHas?` or selectorNotHas: '${I.selectorNotHas}'`:"";const error=new Error(`Could not start interaction ${I.name} (invalid selector: '${I.selector}'${selectorHasError}${selectorNotHasError})`);proms.push(Promise.reject(error));continue;}
for(const _el of targets){this._startInteraction(_el,I,proms);}}
if(el===this.el){this.isActive=true;}
const prom=Promise.all(proms);this.proms.push(prom);return prom;}
_startInteraction(el,I,proms){if(this.activeInteractions.has(el,I)){return;}
this.activeInteractions.add(el,I);if(I.prototype instanceof Interaction){try{const interaction=new Colibri(this,I,el);this.interactions.push(interaction);proms.push(interaction.start());}catch(e){this.proms.push(Promise.reject(e));}}else{proms.push(this._mountComponent(el,I));}}
shouldStop(el,interaction){const{selectorNotHas,selectorHas}=interaction.interaction.constructor;if(!interaction.el){return true;}
return(el===interaction.el||el.contains(interaction.el)||(selectorHas&&!interaction.el.querySelector(selectorHas))||(selectorNotHas&&!!interaction.el.querySelector(selectorNotHas)));}
stopInteractions(el=this.el){const interactions=[];const errors=[];for(const interaction of this.interactions.slice().reverse()){if(this.shouldStop(el,interaction)){try{interaction.destroy();}catch(error){errors.push([interaction.interaction.constructor.name,error]);}
this.activeInteractions.delete(interaction.el,interaction.interaction.constructor);}else{interactions.push(interaction);}}
this.interactions=interactions;const roots=[];for(const root of this.roots.slice().reverse()){if(el===root.el||el.contains(root.el)){root.destroy();this.activeInteractions.delete(root.el,root.C);}else{roots.push(root);}}
this.roots=roots;if(el===this.el){this.isActive=false;}
for(const[interaction,error]of errors){throw new Error(`Could not destroy interaction ${interaction}`,error);}}
get isReady(){const proms=this.proms.slice();return Promise.all(proms);}}
const publicInteractionService=__exports.publicInteractionService={dependencies:["localization"],async start(env){const el=document.querySelector("#wrapwrap")||document.querySelector("body");const Interactions=registry.category("public.interactions").getAll();const service=new InteractionService(el,env);service.activate(Interactions);return service;},};registry.category("services").add("public.interactions",publicInteractionService);return __exports;});;
/* /web/static/src/public/login.js */
odoo.define('@web/public/login',['@web/public/interaction','@web/core/registry','@web/core/utils/ui'],function(require){'use strict';let __exports={};const{Interaction}=require("@web/public/interaction");const{registry}=require("@web/core/registry");const{addLoadingEffect}=require("@web/core/utils/ui");const Login=__exports.Login=class Login extends Interaction{static selector=".oe_login_form";dynamicContent={_root:{"t-on-submit":this.onSubmit},};onSubmit(ev){if(!ev.defaultPrevented){const submitEl=ev.currentTarget.querySelector("button[type='submit']");const removeLoadingEffect=addLoadingEffect(submitEl);const oldPreventDefault=ev.preventDefault.bind(ev);ev.preventDefault=()=>{removeLoadingEffect();oldPreventDefault();};}}}
registry.category("public.interactions").add("public.login",Login);return __exports;});;
/* /web/static/src/public/public_component_interaction.js */
odoo.define('@web/public/public_component_interaction',['@web/core/registry','@web/public/interaction'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{Interaction}=require("@web/public/interaction");const PublicComponentInteraction=__exports.PublicComponentInteraction=class PublicComponentInteraction extends Interaction{static selector="owl-component[name]";setup(){const props=JSON.parse(this.el.getAttribute("props")||"{}");this.el.replaceChildren();this.mountComponent(this.el,this.Component,props);}
get Component(){const name=this.el.getAttribute("name");return registry.category("public_components").get(name);}}
registry.category("public.interactions").add("public_components",PublicComponentInteraction);return __exports;});;
/* /web/static/src/public/show_password.js */
odoo.define('@web/public/show_password',['@web/public/interaction','@web/core/registry'],function(require){'use strict';let __exports={};const{Interaction}=require("@web/public/interaction");const{registry}=require("@web/core/registry");const ShowPassword=__exports.ShowPassword=class ShowPassword extends Interaction{static selector=".input-group";static selectorHas=":scope > .o_show_password";dynamicContent={".o_show_password":{"t-on-click":()=>this.showPassword=!this.showPassword,},"input[type='text'], input[type='password']":{"t-att-type":()=>this.showPassword?"text":"password",},".o_show_password > i":{"t-att-class":()=>({"fa-eye":!this.showPassword,"fa-eye-slash":!!this.showPassword,}),},};}
registry.category("public.interactions").add("web.show_password",ShowPassword);return __exports;});;
/* /web/static/src/public/utils.js */
odoo.define('@web/public/utils',['@web/core/utils/ui'],function(require){'use strict';let __exports={};const PairSet=__exports.PairSet=class PairSet{constructor(){this.map=new Map();}
add(elem1,elem2){if(!this.map.has(elem1)){this.map.set(elem1,new Set());}
this.map.get(elem1).add(elem2);}
has(elem1,elem2){if(!this.map.has(elem1)){return false;}
return this.map.get(elem1).has(elem2);}
delete(elem1,elem2){if(!this.map.has(elem1)){return;}
const s=this.map.get(elem1);s.delete(elem2);if(!s.size){this.map.delete(elem1);}}}
const{addLoadingEffect}=require("@web/core/utils/ui");const DEBOUNCE=__exports.DEBOUNCE=400;const BUTTON_HANDLER_SELECTOR=__exports.BUTTON_HANDLER_SELECTOR='a, button, input[type="submit"], input[type="button"], .btn';__exports.makeAsyncHandler=makeAsyncHandler;function makeAsyncHandler(fct){let pending=false;function _isLocked(){return pending;}
function _lock(){pending=true;}
function _unlock(){pending=false;}
return function(){if(_isLocked()){return;}
_lock();const result=fct.apply(this,arguments);Promise.resolve(result).finally(_unlock);return result;};}
__exports.makeButtonHandler=makeButtonHandler;function makeButtonHandler(fct){fct=makeAsyncHandler(fct);return function(ev){const handlerResult=fct.apply(this,arguments);const buttonEl=ev.target.closest(BUTTON_HANDLER_SELECTOR);if(!(buttonEl instanceof HTMLElement)){return handlerResult;}
buttonEl.classList.add("pe-none");let showDebouncedLoading=false;const addLoadingIfPending=()=>{buttonEl.classList.remove("pe-none");if(showDebouncedLoading){const restore=addLoadingEffect(buttonEl);Promise.resolve(handlerResult).then(restore,restore);}};Promise.race([handlerResult,new Promise((resolve)=>setTimeout(resolve,DEBOUNCE)).then(()=>{showDebouncedLoading=true;}),]).then(addLoadingIfPending,addLoadingIfPending);return handlerResult;};}
__exports.patchDynamicContentEntry=patchDynamicContentEntry;function patchDynamicContentEntry(dynamicContent,selector,t,replacement){dynamicContent[selector]=dynamicContent[selector]||{};const forSelector=dynamicContent[selector];if(replacement===undefined){delete forSelector[t];}else if(typeof replacement==="function"&&t!=="t-component"){if(!forSelector[t]){forSelector[t]=()=>{};}
const oldFn=forSelector[t];if(["t-att-class","t-att-style"].includes(t)){forSelector[t]=(el,oldResult)=>{const result=oldResult||{};Object.assign(result,oldFn(el,result));Object.assign(result,replacement(el,result));return result;};}else if(t.startsWith("t-on-")){forSelector[t]=(el,...args)=>replacement(el,oldFn,...args);}else{forSelector[t]=(el,oldResult)=>{let result=oldResult;result=oldFn(el,result);result=replacement(el,result);return result;};}}else{forSelector[t]=replacement;}}
__exports.patchDynamicContent=patchDynamicContent;function patchDynamicContent(dynamicContent,replacement){for(const[selector,forSelector]of Object.entries(replacement)){for(const[t,forT]of Object.entries(forSelector)){patchDynamicContentEntry(dynamicContent,selector,t,forT);}}}
return __exports;});;
/* /web/static/src/legacy/js/public/public_root.js */
odoo.define('@web/legacy/js/public/public_root',['@web/core/browser/cookie','@web/legacy/js/public/public_widget','@web/legacy/js/public/lazyloader','@web/env','@web/core/templates','@web/core/main_components_container','@web/core/browser/browser','@web/core/l10n/translation','@web/core/l10n/utils','@odoo/owl','@web/core/network/rpc','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{cookie}=require("@web/core/browser/cookie");const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const lazyloader=require("@web/legacy/js/public/lazyloader")[Symbol.for("default")];const{makeEnv,startServices}=require("@web/env");const{getTemplate}=require('@web/core/templates');const{MainComponentsContainer}=require("@web/core/main_components_container");const{browser}=require('@web/core/browser/browser');const{appTranslateFn}=require("@web/core/l10n/translation");const{jsToPyLocale,pyToJsLocale}=require("@web/core/l10n/utils");const{App,Component,whenReady}=require("@odoo/owl");const{RPCError}=require('@web/core/network/rpc');const{patch}=require("@web/core/utils/patch");const{Settings}=luxon;function getLang(){var html=document.documentElement;return jsToPyLocale(html.getAttribute('lang'))||'en_US';}
const lang=cookie.get('frontend_lang')||getLang();const PublicRoot=__exports.PublicRoot=publicWidget.Widget.extend({events:{'submit .js_website_submit_form':'_onWebsiteFormSubmit','click .js_disable_on_click':'_onDisableOnClick',},custom_events:{call_service:'_onCallService',context_get:'_onContextGet',main_object_request:'_onMainObjectRequest',widgets_start_request:'_onWidgetsStartRequest',widgets_stop_request:'_onWidgetsStopRequest',},init:function(_,env){this._super.apply(this,arguments);this.env=env;this.publicWidgets=[];const interactionsService=this.env.services["public.interactions"];const publicRoot=this;if(interactionsService){patch(interactionsService.constructor.prototype,{startInteractions(el){super.startInteractions(el);if(!publicRoot.startFromEventHandler){publicRoot._startWidgets($(el||this.el),{fromInteractionPatch:true,editableMode:this.editMode})}},stopInteractions(el){super.stopInteractions(el);if(!publicRoot.stopFromEventHandler){publicRoot._stopWidgets($(el||this.el));}},});}},start:function(){var defs=[this._super.apply(this,arguments),this._startWidgets(undefined,{starting:true})];this.$(".o_image[data-mimetype^='image']").each(function(){var $img=$(this);if(/gif|jpe|jpg|png|webp/.test($img.data('mimetype'))&&$img.data('src')){$img.css('background-image',"url('"+$img.data('src')+"')");}});if(window.location.hash.indexOf("scrollTop=")>-1){this.el.scrollTop=+window.location.hash.match(/scrollTop=([0-9]+)/)[1];}
return Promise.all(defs);},_getContext:function(context){return Object.assign({'lang':getLang(),},context||{});},_getExtraContext:function(context){return this._getContext(context);},_getPublicWidgetsRegistry:function(options){return publicWidget.registry;},_restartInteractions(targetEl,options){const publicInteractions=this.bindService("public.interactions");publicInteractions.stopInteractions(targetEl);publicInteractions.startInteractions(targetEl);},_startWidgets:function($from,options){var self=this;if($from===undefined){$from=this.$('#wrapwrap');if(!$from.length){$from=this.$el;}}
options=Object.assign({},options,{wysiwyg:$('#wrapwrap').data('wysiwyg'),});this._stopWidgets($from);if(!options?.starting&&!options?.fromInteractionPatch){if($from){for(const fromEl of $from){this._restartInteractions(fromEl,options);}}else{this._restartInteractions(undefined,options);}}
var defs=Object.values(this._getPublicWidgetsRegistry(options)).map((PublicWidget)=>{const selector=PublicWidget.prototype.selector;if(!selector){return;}
const selectorHas=PublicWidget.prototype.selectorHas;const selectorFunc=typeof selector==='function'?selector:fromEl=>{const els=[...fromEl.querySelectorAll(selector)];if(fromEl.matches(selector)){els.push(fromEl);}
return els;};let targetEls=[];for(const fromEl of $from){targetEls.push(...selectorFunc(fromEl));}
if(selectorHas){targetEls=targetEls.filter(el=>!!el.querySelector(selectorHas));}
const proms=targetEls.map(el=>{var widget=new PublicWidget(self,options);self.publicWidgets.push(widget);return widget.attachTo(el);});return Promise.all(proms);});return Promise.all(defs);},_stopWidgets:function($from){var removedWidgets=this.publicWidgets.map((widget)=>{if(!$from||$from.filter(widget.el).length||$from.find(widget.el).length){widget.destroy();return widget;}
return null;});this.publicWidgets=this.publicWidgets.filter((x)=>removedWidgets.indexOf(x)<0);},_onCallService:function(ev){const payload=ev.data;const service=this.env.services[payload.service];const result=service[payload.method].apply(service,payload.args||[]);payload.callback(result);ev.stopPropagation();},_onContextGet:function(ev){if(ev.data.extra){ev.data.callback(this._getExtraContext(ev.data.context));}else{ev.data.callback(this._getContext(ev.data.context));}},_onMainObjectRequest:function(ev){var repr=$('html').data('main-object');var m=repr.match(/(.+)\((-?\d+),(.*)\)/);ev.data.callback({model:m[1],id:m[2]|0,});},async _onWidgetsStartRequest(ev){this.startFromEventHandler=true;try{await this._startWidgets(ev.data.$target,ev.data.options);ev.data.onSuccess?.();}catch(e){ev.data.onFailure?.(e);if(!(e instanceof RPCError)){throw e;}}finally{this.stopFromEventHandler=true;}},_onWidgetsStopRequest:function(ev){this._stopWidgets(ev.data.$target);const targetEl=ev.data.$target?ev.data.$target[0]:undefined;const publicInteractions=this.bindService("public.interactions");this.stopFromEventHandler=true;try{publicInteractions.stopInteractions(targetEl);}finally{this.stopFromEventHandler=false;}},_onWebsiteFormSubmit:function(ev){var $buttons=$(ev.currentTarget).find('button[type="submit"], a.a-submit').toArray();$buttons.forEach((btn)=>{var $btn=$(btn);$btn.prepend('<i class="fa fa-circle-o-notch fa-spin"></i> ');$btn.prop('disabled',true);});},_onDisableOnClick:function(ev){$(ev.currentTarget).addClass('disabled');},_onDateTimePickerError:function(ev){return false;},});__exports.createPublicRoot=createPublicRoot;async function createPublicRoot(RootWidget){await lazyloader.allScriptsLoaded;await whenReady();const env=makeEnv();await startServices(env);env.services["public.interactions"].isReady.then(()=>{document.body.setAttribute("is-ready","true");});Component.env=env;const publicRoot=new RootWidget(null,env);const app=new App(MainComponentsContainer,{getTemplate,env,dev:env.debug,translateFn:appTranslateFn,translatableAttributes:["data-tooltip"],});const locale=pyToJsLocale(lang)||browser.navigator.language;Settings.defaultLocale=locale;const[root]=await Promise.all([app.mount(document.body),publicRoot.attachTo(document.body),]);odoo.__WOWL_DEBUG__={root};return publicRoot;}
__exports[Symbol.for("default")]={PublicRoot,createPublicRoot};return __exports;});;
/* /web/static/src/legacy/js/public/public_root_instance.js */
odoo.define('@web/legacy/js/public/public_root_instance',['@web/legacy/js/public/public_root','@web/legacy/js/public/lazyloader'],function(require){'use strict';let __exports={};const{PublicRoot,createPublicRoot}=require("@web/legacy/js/public/public_root");const lazyloader=require("@web/legacy/js/public/lazyloader")[Symbol.for("default")];const prom=createPublicRoot(PublicRoot);lazyloader.registerPageReadinessDelay(prom);__exports[Symbol.for("default")]=prom;return __exports;});odoo.define(`root.widget`,['@web/legacy/js/public/public_root_instance'],function(require){return require('@web/legacy/js/public/public_root_instance')[Symbol.for("default")];});;
/* /web/static/src/legacy/js/public/public_widget.js */
odoo.define('@web/legacy/js/public/public_widget',['@odoo/owl','@web/legacy/js/core/class','@web/core/assets','@web/core/utils/hooks','@web/core/utils/render','@web/legacy/js/public/minimal_dom'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const Class=require("@web/legacy/js/core/class")[Symbol.for("default")];const{loadBundle,loadCSS,loadJS}=require('@web/core/assets');const{SERVICES_METADATA}=require("@web/core/utils/hooks");const{renderToElement}=require("@web/core/utils/render");const{makeAsyncHandler,makeButtonHandler}=require("@web/legacy/js/public/minimal_dom");const ParentedMixin={__parentedMixin:true,init:function(){this.__parentedDestroyed=false;this.__parentedChildren=[];this.__parentedParent=null;},setParent(parent){if(this.getParent()){if(this.getParent().__parentedMixin){const children=this.getParent().getChildren();this.getParent().__parentedChildren=children.filter((child)=>child.$el!==this.$el);}}
this.__parentedParent=parent;if(parent&&parent.__parentedMixin){parent.__parentedChildren.push(this);}},getParent(){return this.__parentedParent;},getChildren(){return[...this.__parentedChildren];},isDestroyed(){return this.__parentedDestroyed;},destroy(){this.getChildren().forEach(function(child){child.destroy();});this.setParent(undefined);this.__parentedDestroyed=true;},};function OdooEvent(target,name,data){this.target=target;this.name=name;this.data=Object.create(null);Object.assign(this.data,data);this.stopped=false;}
OdooEvent.prototype.stopPropagation=function(){this.stopped=true;};OdooEvent.prototype.is_stopped=function(){return this.stopped;};class Events{on(events,callback,context){var ev;events=events.split(/\s+/);var calls=this._callbacks||(this._callbacks={});while((ev=events.shift())){var list=calls[ev]||(calls[ev]={});var tail=list.tail||(list.tail=list.next={});tail.callback=callback;tail.context=context;list.tail=tail.next={};}
return this;}
off(events,callback,context){var ev,calls,node;if(!events){delete this._callbacks;}else if((calls=this._callbacks)){events=events.split(/\s+/);while((ev=events.shift())){node=calls[ev];delete calls[ev];if(!callback||!node){continue;}
while((node=node.next)&&node.next){if(node.callback===callback&&(!context||node.context===context)){continue;}
this.on(ev,node.callback,node.context);}}}
return this;}
callbackList(){var lst=[];for(const[eventName,el]of Object.entries(this._callbacks||{})){var node=el;while((node=node.next)&&node.next){lst.push([eventName,node.callback,node.context]);}}
return lst;}
trigger(events){var event,node,calls,tail,args,all,rest;if(!(calls=this._callbacks)){return this;}
all=calls.all;(events=events.split(/\s+/)).push(null);while((event=events.shift())){if(all){events.push({next:all.next,tail:all.tail,event:event});}
if(!(node=calls[event])){continue;}
events.push({next:node.next,tail:node.tail});}
rest=Array.prototype.slice.call(arguments,1);while((node=events.pop())){tail=node.tail;args=node.event?[node.event].concat(rest):rest;while((node=node.next)!==tail){node.callback.apply(node.context||this,args);}}
return this;}}
const EventDispatcherMixin=Object.assign({},ParentedMixin,{__eventDispatcherMixin:true,"custom_events":{},init(){ParentedMixin.init.call(this);this.__edispatcherEvents=new Events();this.__edispatcherRegisteredEvents=[];this._delegateCustomEvents();},proxy(method){var self=this;return function(){var fn=(typeof method==='string')?self[method]:method;if(fn===void 0){throw new Error("Couldn't find method '"+method+"' in widget "+self);}
return fn.apply(self,arguments);};},_delegateCustomEvents(){if(Object.keys(this.custom_events||{}).length===0){return;}
for(var key in this.custom_events){if(!Object.prototype.hasOwnProperty.call(this.custom_events,key)){continue;}
var method=this.proxy(this.custom_events[key]);this.on(key,this,method);}},on(events,dest,func){var self=this;if(typeof func!=="function"){throw new Error("Event handler must be a function.");}
events=events.split(/\s+/);events.forEach((eventName)=>{self.__edispatcherEvents.on(eventName,func,dest);if(dest&&dest.__eventDispatcherMixin){dest.__edispatcherRegisteredEvents.push({name:eventName,func:func,source:self});}});return this;},off(events,dest,func){var self=this;events=events.split(/\s+/);events.forEach((eventName)=>{self.__edispatcherEvents.off(eventName,func,dest);if(dest&&dest.__eventDispatcherMixin){dest.__edispatcherRegisteredEvents=dest.__edispatcherRegisteredEvents.filter(el=>{return!(el.name===eventName&&el.func===func&&el.source===self);});}});return this;},trigger(){this.__edispatcherEvents.trigger.apply(this.__edispatcherEvents,arguments);return this;},"trigger_up":function(name,info){var event=new OdooEvent(this,name,info);this._trigger_up(event);return event;},"_trigger_up":function(event){var parent;this.__edispatcherEvents.trigger(event.name,event);if(!event.is_stopped()&&(parent=this.getParent())){parent._trigger_up(event);}},destroy(){var self=this;this.__edispatcherRegisteredEvents.forEach((event)=>{event.source.__edispatcherEvents.off(event.name,event.func,self);});this.__edispatcherRegisteredEvents=[];this.__edispatcherEvents.callbackList().forEach(((cal)=>{this.off(cal[0],cal[2],cal[1]);}).bind(this));this.__edispatcherEvents.off();ParentedMixin.destroy.call(this);},});function protectMethod(widget,fn){return function(...args){return new Promise((resolve,reject)=>{Promise.resolve(fn.call(this,...args)).then((result)=>{if(!widget.isDestroyed()){resolve(result);}}).catch((reason)=>{if(!widget.isDestroyed()){reject(reason);}});});};}
const ServicesMixin={bindService:function(serviceName){const{services}=Component.env;const service=services[serviceName];if(!service){throw new Error(`Service ${serviceName} is not available`);}
if(serviceName in SERVICES_METADATA){if(service instanceof Function){return protectMethod(this,service);}else{const methods=SERVICES_METADATA[serviceName];const result=Object.create(service);for(const method of methods){result[method]=protectMethod(this,service[method]);}
return result;}}
return service;},call:function(service,method){var args=Array.prototype.slice.call(arguments,2);var result;this.trigger_up('call_service',{service:service,method:method,args:args,callback:function(r){result=r;},});return result;},};const PublicWidget=__exports.PublicWidget=Class.extend(EventDispatcherMixin,ServicesMixin,{tagName:'div',id:null,className:null,attributes:{},template:null,cssLibs:null,jsLibs:null,assetLibs:null,selector:false,selectorHas:false,events:{},init:function(parent,options){EventDispatcherMixin.init.call(this);this.setParent(parent);this.options=options||{};},willStart:function(){var proms=[];if(this.jsLibs||this.cssLibs||this.assetLibs){var assetsPromise=Promise.all([...(this.cssLibs||[]).map(loadCSS),...(this.jsLibs||[]).map(loadJS),]);for(const bundleName of this.assetLibs||[]){if(typeof bundleName==="string"){assetsPromise=assetsPromise.then(()=>{return loadBundle(bundleName);});}else{assetsPromise=assetsPromise.then(()=>{return Promise.all([...bundleName.map(loadBundle)]);});}}
proms.push(assetsPromise);}
return Promise.all(proms);},start:function(){return Promise.resolve();},destroy:function(){EventDispatcherMixin.destroy.call(this);if(this.$el){this._undelegateEvents();if(!this.selector){this.$el.remove();}}},appendTo:function(target){var self=this;return this._widgetRenderAndInsert(function(t){self.$el.appendTo(t);},target);},attachTo:function(target){var self=this;this.setElement(target.$el||target);return this.willStart().then(function(){if(self.__parentedDestroyed){return;}
return self.start();});},insertAfter:function(target){var self=this;return this._widgetRenderAndInsert(function(t){self.$el.insertAfter(t);},target);},insertBefore:function(target){var self=this;return this._widgetRenderAndInsert(function(t){self.$el.insertBefore(t);},target);},prependTo:function(target){var self=this;return this._widgetRenderAndInsert(function(t){self.$el.prependTo(t);},target);},renderElement:function(){var $el;if(this.template){$el=$(renderToElement(this.template,{widget:this}));}else{$el=this._makeDescriptive();}
this._replaceElement($el);},replace:function(target){return this._widgetRenderAndInsert((t)=>{this.$el.replaceAll(t);},target);},setElement:function(element){if(this.$el){this._undelegateEvents();}
this.$el=(element instanceof $)?element:$(element);this.el=this.$el[0];this._delegateEvents();if(this.selector){this.$target=this.$el;this.target=this.el;}
return this;},$:function(selector){if(selector===undefined){return this.$el;}
return this.$el.find(selector);},_delegateEvents:function(){var self=this;const _delegateEvent=(method,key)=>{var match=/^(\S+)(\s+(.*))?$/.exec(key);var event=match[1];var selector=match[3];event+='.widget_events';if(!selector){self.$el.on(event,method);}else{self.$el.on(event,selector,method);}};Object.entries(this.events||{}).forEach(([event,method])=>{if(typeof method!=='string'){_delegateEvent(self.proxy(method),event);return;}
var methodOptions=method.split(' ');if(methodOptions.length<=1){_delegateEvent(self.proxy(method),event);return;}
var isAsync=methodOptions.includes('async');if(!isAsync){_delegateEvent(self.proxy(method),event);return;}
method=self.proxy(methodOptions[methodOptions.length-1]);if(String(event).startsWith("click")){method=makeButtonHandler(method);}else{method=makeAsyncHandler(method);}
_delegateEvent(method,event);});},_getContext:function(extra,extraContext){var context;this.trigger_up('context_get',{extra:extra||false,context:extraContext,callback:function(ctx){context=ctx;},});return context;},_makeDescriptive:function(){var attrs=Object.assign({},this.attributes||{});if(this.id){attrs.id=this.id;}
if(this.className){attrs['class']=this.className;}
var $el=$(document.createElement(this.tagName));if(Object.keys(attrs||{}).length>0){$el.attr(attrs);}
return $el;},_replaceElement:function($el){var $oldel=this.$el;this.setElement($el);if($oldel&&!$oldel.is(this.$el)){if($oldel.length>1){$oldel.wrapAll('<div/>');$oldel.parent().replaceWith(this.$el);}else{$oldel.replaceWith(this.$el);}}
return this;},_undelegateEvents:function(){this.$el.off('.widget_events');},_widgetRenderAndInsert:function(insertion,target){var self=this;return this.willStart().then(function(){if(self.__parentedDestroyed){return;}
self.renderElement();insertion(target);return self.start();});},});var registry={};__exports[Symbol.for("default")]={Widget:PublicWidget,registry:registry,ParentedMixin:ParentedMixin,EventDispatcherMixin:EventDispatcherMixin,ServicesMixin:ServicesMixin,};return __exports;});;
/* /auth_passkey/static/lib/simplewebauthn.js */
odoo.define('@auth_passkey/../lib/simplewebauthn',[],function(require){'use strict';let __exports={};function utf8StringToBuffer(value){return new TextEncoder().encode(value);}
function bufferToBase64URLString(buffer){const bytes=new Uint8Array(buffer);let str='';for(const charCode of bytes){str+=String.fromCharCode(charCode);}
const base64String=btoa(str);return base64String.replace(/\+/g,'-').replace(/\//g,'_').replace(/=/g,'');}
function base64URLStringToBuffer(base64URLString){const base64=base64URLString.replace(/-/g,'+').replace(/_/g,'/');const padLength=(4-(base64.length%4))%4;const padded=base64.padEnd(base64.length+padLength,'=');const binary=atob(padded);const buffer=new ArrayBuffer(binary.length);const bytes=new Uint8Array(buffer);for(let i=0;i<binary.length;i++){bytes[i]=binary.charCodeAt(i);}
return buffer;}
function browserSupportsWebAuthn(){return(window?.PublicKeyCredential!==undefined&&typeof window.PublicKeyCredential==='function');}
function toPublicKeyCredentialDescriptor(descriptor){const{id}=descriptor;return{...descriptor,id:base64URLStringToBuffer(id),transports:descriptor.transports,};}
function isValidDomain(hostname){return(hostname==='localhost'||/^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(hostname));}
class WebAuthnError extends Error{constructor({message,code,cause,name,}){super(message,{cause});this.name=name??cause.name;this.code=code;}}
function identifyRegistrationError({error,options,}){const{publicKey}=options;if(!publicKey){throw Error('options was missing required publicKey property');}
if(error.name==='AbortError'){if(options.signal instanceof AbortSignal){return new WebAuthnError({message:'Registration ceremony was sent an abort signal',code:'ERROR_CEREMONY_ABORTED',cause:error,});}}
else if(error.name==='ConstraintError'){if(publicKey.authenticatorSelection?.requireResidentKey===true){return new WebAuthnError({message:'Discoverable credentials were required but no available authenticator supported it',code:'ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT',cause:error,});}
else if(publicKey.authenticatorSelection?.userVerification==='required'){return new WebAuthnError({message:'User verification was required but no available authenticator supported it',code:'ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT',cause:error,});}}
else if(error.name==='InvalidStateError'){return new WebAuthnError({message:'The authenticator was previously registered',code:'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED',cause:error,});}
else if(error.name==='NotAllowedError'){return new WebAuthnError({message:error.message,code:'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY',cause:error,});}
else if(error.name==='NotSupportedError'){const validPubKeyCredParams=publicKey.pubKeyCredParams.filter((param)=>param.type==='public-key');if(validPubKeyCredParams.length===0){return new WebAuthnError({message:'No entry in pubKeyCredParams was of type "public-key"',code:'ERROR_MALFORMED_PUBKEYCREDPARAMS',cause:error,});}
return new WebAuthnError({message:'No available authenticator supported any of the specified pubKeyCredParams algorithms',code:'ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG',cause:error,});}
else if(error.name==='SecurityError'){const effectiveDomain=window.location.hostname;if(!isValidDomain(effectiveDomain)){return new WebAuthnError({message:`${window.location.hostname} is an invalid domain`,code:'ERROR_INVALID_DOMAIN',cause:error,});}
else if(publicKey.rp.id!==effectiveDomain){return new WebAuthnError({message:`The RP ID "${publicKey.rp.id}" is invalid for this domain`,code:'ERROR_INVALID_RP_ID',cause:error,});}}
else if(error.name==='TypeError'){if(publicKey.user.id.byteLength<1||publicKey.user.id.byteLength>64){return new WebAuthnError({message:'User ID was not between 1 and 64 characters',code:'ERROR_INVALID_USER_ID_LENGTH',cause:error,});}}
else if(error.name==='UnknownError'){return new WebAuthnError({message:'The authenticator was unable to process the specified options, or could not create a new credential',code:'ERROR_AUTHENTICATOR_GENERAL_ERROR',cause:error,});}
return error;}
class BaseWebAuthnAbortService{createNewAbortSignal(){if(this.controller){const abortError=new Error('Cancelling existing WebAuthn API call for new one');abortError.name='AbortError';this.controller.abort(abortError);}
const newController=new AbortController();this.controller=newController;return newController.signal;}
cancelCeremony(){if(this.controller){const abortError=new Error('Manually cancelling existing WebAuthn API call');abortError.name='AbortError';this.controller.abort(abortError);this.controller=undefined;}}}
const WebAuthnAbortService=new BaseWebAuthnAbortService();const attachments=['cross-platform','platform'];function toAuthenticatorAttachment(attachment){if(!attachment){return;}
if(attachments.indexOf(attachment)<0){return;}
return attachment;}
async function startRegistration(creationOptionsJSON){if(!browserSupportsWebAuthn()){throw new Error('WebAuthn is not supported in this browser');}
const publicKey={...creationOptionsJSON,challenge:base64URLStringToBuffer(creationOptionsJSON.challenge),user:{...creationOptionsJSON.user,id:utf8StringToBuffer(creationOptionsJSON.user.id),},excludeCredentials:creationOptionsJSON.excludeCredentials?.map(toPublicKeyCredentialDescriptor),};const options={publicKey};options.signal=WebAuthnAbortService.createNewAbortSignal();let credential;try{credential=(await navigator.credentials.create(options));}
catch(err){throw identifyRegistrationError({error:err,options});}
if(!credential){throw new Error('Registration was not completed');}
const{id,rawId,response,type}=credential;let transports=undefined;if(typeof response.getTransports==='function'){transports=response.getTransports();}
let responsePublicKeyAlgorithm=undefined;if(typeof response.getPublicKeyAlgorithm==='function'){try{responsePublicKeyAlgorithm=response.getPublicKeyAlgorithm();}
catch(error){warnOnBrokenImplementation('getPublicKeyAlgorithm()',error);}}
let responsePublicKey=undefined;if(typeof response.getPublicKey==='function'){try{const _publicKey=response.getPublicKey();if(_publicKey!==null){responsePublicKey=bufferToBase64URLString(_publicKey);}}
catch(error){warnOnBrokenImplementation('getPublicKey()',error);}}
let responseAuthenticatorData;if(typeof response.getAuthenticatorData==='function'){try{responseAuthenticatorData=bufferToBase64URLString(response.getAuthenticatorData());}
catch(error){warnOnBrokenImplementation('getAuthenticatorData()',error);}}
return{id,rawId:bufferToBase64URLString(rawId),response:{attestationObject:bufferToBase64URLString(response.attestationObject),clientDataJSON:bufferToBase64URLString(response.clientDataJSON),transports,publicKeyAlgorithm:responsePublicKeyAlgorithm,publicKey:responsePublicKey,authenticatorData:responseAuthenticatorData,},type,clientExtensionResults:credential.getClientExtensionResults(),authenticatorAttachment:toAuthenticatorAttachment(credential.authenticatorAttachment),};}
function warnOnBrokenImplementation(methodName,cause){console.warn(`The browser extension that intercepted this WebAuthn API call incorrectly implemented ${methodName}. You should report this error to them.\n`,cause);}
function bufferToUTF8String(value){return new TextDecoder('utf-8').decode(value);}
function browserSupportsWebAuthnAutofill(){const globalPublicKeyCredential=window.PublicKeyCredential;if(globalPublicKeyCredential.isConditionalMediationAvailable===undefined){return new Promise((resolve)=>resolve(false));}
return globalPublicKeyCredential.isConditionalMediationAvailable();}
function identifyAuthenticationError({error,options,}){const{publicKey}=options;if(!publicKey){throw Error('options was missing required publicKey property');}
if(error.name==='AbortError'){if(options.signal instanceof AbortSignal){return new WebAuthnError({message:'Authentication ceremony was sent an abort signal',code:'ERROR_CEREMONY_ABORTED',cause:error,});}}
else if(error.name==='NotAllowedError'){return new WebAuthnError({message:error.message,code:'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY',cause:error,});}
else if(error.name==='SecurityError'){const effectiveDomain=window.location.hostname;if(!isValidDomain(effectiveDomain)){return new WebAuthnError({message:`${window.location.hostname} is an invalid domain`,code:'ERROR_INVALID_DOMAIN',cause:error,});}
else if(publicKey.rpId!==effectiveDomain){return new WebAuthnError({message:`The RP ID "${publicKey.rpId}" is invalid for this domain`,code:'ERROR_INVALID_RP_ID',cause:error,});}}
else if(error.name==='UnknownError'){return new WebAuthnError({message:'The authenticator was unable to process the specified options, or could not create a new assertion signature',code:'ERROR_AUTHENTICATOR_GENERAL_ERROR',cause:error,});}
return error;}
async function startAuthentication(requestOptionsJSON,useBrowserAutofill=false){if(!browserSupportsWebAuthn()){throw new Error('WebAuthn is not supported in this browser');}
let allowCredentials;if(requestOptionsJSON.allowCredentials?.length!==0){allowCredentials=requestOptionsJSON.allowCredentials?.map(toPublicKeyCredentialDescriptor);}
const publicKey={...requestOptionsJSON,challenge:base64URLStringToBuffer(requestOptionsJSON.challenge),allowCredentials,};const options={};if(useBrowserAutofill){if(!(await browserSupportsWebAuthnAutofill())){throw Error('Browser does not support WebAuthn autofill');}
const eligibleInputs=document.querySelectorAll('input[autocomplete$=\'webauthn\']');if(eligibleInputs.length<1){throw Error('No <input> with "webauthn" as the only or last value in its `autocomplete` attribute was detected');}
options.mediation='conditional';publicKey.allowCredentials=[];}
options.publicKey=publicKey;options.signal=WebAuthnAbortService.createNewAbortSignal();let credential;try{credential=(await navigator.credentials.get(options));}
catch(err){throw identifyAuthenticationError({error:err,options});}
if(!credential){throw new Error('Authentication was not completed');}
const{id,rawId,response,type}=credential;let userHandle=undefined;if(response.userHandle){userHandle=bufferToUTF8String(response.userHandle);}
return{id,rawId:bufferToBase64URLString(rawId),response:{authenticatorData:bufferToBase64URLString(response.authenticatorData),clientDataJSON:bufferToBase64URLString(response.clientDataJSON),signature:bufferToBase64URLString(response.signature),userHandle,},type,clientExtensionResults:credential.getClientExtensionResults(),authenticatorAttachment:toAuthenticatorAttachment(credential.authenticatorAttachment),};}
function platformAuthenticatorIsAvailable(){if(!browserSupportsWebAuthn()){return new Promise((resolve)=>resolve(false));}
return PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();}
Object.assign(__exports,{WebAuthnAbortService,WebAuthnError,base64URLStringToBuffer,browserSupportsWebAuthn,browserSupportsWebAuthnAutofill,bufferToBase64URLString,platformAuthenticatorIsAvailable,startAuthentication,startRegistration});return __exports;});;
/* /auth_passkey/static/src/interactions/passkey_login.js */
odoo.define('@auth_passkey/interactions/passkey_login',['@web/public/interaction','@web/core/registry','@web/core/network/rpc','@auth_passkey/../lib/simplewebauthn'],function(require){'use strict';let __exports={};const{Interaction}=require("@web/public/interaction");const{registry}=require("@web/core/registry");const{rpc}=require("@web/core/network/rpc");const passkeyLib=require("@auth_passkey/../lib/simplewebauthn");const PasskeyLogin=__exports.PasskeyLogin=class PasskeyLogin extends Interaction{static selector=".passkey_login_link";dynamicContent={_root:{"t-on-click":this.onClick},};async onClick(){const serverOptions=await this.waitFor(rpc("/auth/passkey/start-auth"));const auth=await this.waitFor(passkeyLib.startAuthentication(serverOptions).catch(e=>console.error(e)));if(!auth){return false;}
const form=document.querySelector("form.oe_login_form");form.querySelector("input[name='webauthn_response']").value=JSON.stringify(auth);form.querySelector("input[name='type']").value="webauthn";form.submit();}}
registry.category("public.interactions").add("auth_passkey.passkey_login",PasskeyLogin);return __exports;});;
/* /bus/static/src/bus_parameters_service.js */
odoo.define('@bus/bus_parameters_service',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const busParametersService=__exports.busParametersService={start(){return{serverURL:window.origin,};},};registry.category("services").add("bus.parameters",busParametersService);return __exports;});;
/* /bus/static/src/legacy_multi_tab_service.js */
odoo.define('@bus/legacy_multi_tab_service',['@web/core/registry','@web/core/browser/browser','@odoo/owl'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{browser}=require("@web/core/browser/browser");const{EventBus}=require("@odoo/owl");const legacyMultiTabService=__exports.legacyMultiTabService={start(){const bus=new EventBus();const sanitizedOrigin=location.origin.replace(/:\/{0,2}/g,"_");const localStoragePrefix=`${this.name}.${sanitizedOrigin}.`;function generateLocalStorageKey(baseKey){return localStoragePrefix+baseKey;}
function getItemFromStorage(key,defaultValue){const item=browser.localStorage.getItem(generateLocalStorageKey(key));try{return item?JSON.parse(item):defaultValue;}catch{return item;}}
function setItemInStorage(key,value){browser.localStorage.setItem(generateLocalStorageKey(key),JSON.stringify(value));}
function onStorage({key,newValue}){if(key&&key.includes(localStoragePrefix)){const baseKey=key.replace(localStoragePrefix,"");bus.trigger("shared_value_updated",{key:baseKey,newValue});}}
browser.addEventListener("storage",onStorage);return{bus,generateLocalStorageKey,getItemFromStorage,setItemInStorage,getSharedValue(key,defaultValue){return getItemFromStorage(key,defaultValue);},setSharedValue(key,value){if(value===undefined){return this.removeSharedValue(key);}
setItemInStorage(key,value);},removeSharedValue(key){browser.localStorage.removeItem(generateLocalStorageKey(key));},};},};registry.category("services").add("legacy_multi_tab",legacyMultiTabService);return __exports;});;
/* /bus/static/src/misc.js */
odoo.define('@bus/misc',['@web/core/browser/browser'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");function throttle(func,wait,options){let timeout,context,args,result;let previous=0;if(!options){options={};}
const later=function(){previous=options.leading===false?0:luxon.DateTime.now().ts;timeout=null;result=func.apply(context,args);if(!timeout){context=args=null;}};const throttled=function(){const _now=luxon.DateTime.now().ts;if(!previous&&options.leading===false){previous=_now;}
const remaining=wait-(_now-previous);context=this;args=arguments;if(remaining<=0||remaining>wait){if(timeout){browser.clearTimeout(timeout);timeout=null;}
previous=_now;result=func.apply(context,args);if(!timeout){context=args=null;}}else if(!timeout&&options.trailing!==false){timeout=browser.setTimeout(later,remaining);}
return result;};throttled.cancel=function(){browser.clearTimeout(timeout);previous=0;timeout=context=args=null;};return throttled;}
const timings=__exports.timings={throttle,};return __exports;});;
/* /bus/static/src/multi_tab_fallback_service.js */
odoo.define('@bus/multi_tab_fallback_service',['@web/core/browser/browser','@odoo/owl'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{EventBus}=require("@odoo/owl");let multiTabId=0;const multiTabFallbackService=__exports.multiTabFallbackService={start(env){const bus=new EventBus();const TAB_HEARTBEAT_PERIOD=10000;const MAIN_TAB_HEARTBEAT_PERIOD=1500;const HEARTBEAT_OUT_OF_DATE_PERIOD=5000;const HEARTBEAT_KILL_OLD_PERIOD=15000;let _isOnMainTab=false;let lastHeartbeat=0;let heartbeatTimeout;const now=new Date().getTime();const tabId=`${this.name}${multiTabId++}:${now}`;function startElection(){if(_isOnMainTab){return;}
const now=new Date().getTime();const lastPresenceByTab=JSON.parse(localStorage.getItem("multi_tab_service.lastPresenceByTab"))??{};const heartbeatKillOld=now-HEARTBEAT_KILL_OLD_PERIOD;let newMain;for(const[tab,lastPresence]of Object.entries(lastPresenceByTab)){if(lastPresence<heartbeatKillOld){continue;}
newMain=tab;break;}
if(newMain===tabId){lastHeartbeat=now;localStorage.setItem("multi_tab_service.heartbeat",lastHeartbeat);localStorage.setItem("multi_tab_service.main",true);_isOnMainTab=true;bus.trigger("become_main_tab");delete lastPresenceByTab[newMain];localStorage.setItem("multi_tab_service.lastPresenceByTab",JSON.stringify(lastPresenceByTab));}}
function heartbeat(){const now=new Date().getTime();let heartbeatValue=parseInt(localStorage.getItem("multi_tab_service.heartbeat")??0);const lastPresenceByTab=JSON.parse(localStorage.getItem("multi_tab_service.lastPresenceByTab"))??{};if(heartbeatValue+HEARTBEAT_OUT_OF_DATE_PERIOD<now){startElection();heartbeatValue=parseInt(localStorage.getItem("multi_tab_service.heartbeat")??0);}
if(_isOnMainTab){const cleanedTabs={};for(const[tabId,lastPresence]of Object.entries(lastPresenceByTab)){if(lastPresence+HEARTBEAT_KILL_OLD_PERIOD>now){cleanedTabs[tabId]=lastPresence;}}
if(heartbeatValue!==lastHeartbeat){_isOnMainTab=false;lastHeartbeat=0;lastPresenceByTab[tabId]=now;localStorage.setItem("multi_tab_service.lastPresenceByTab",JSON.stringify(lastPresenceByTab));bus.trigger("no_longer_main_tab");}else{lastHeartbeat=now;localStorage.setItem("multi_tab_service.heartbeat",now);localStorage.setItem("multi_tab_service.lastPresenceByTab",JSON.stringify(cleanedTabs));}}else{lastPresenceByTab[tabId]=now;localStorage.setItem("multi_tab_service.lastPresenceByTab",JSON.stringify(lastPresenceByTab));}
const hbPeriod=_isOnMainTab?MAIN_TAB_HEARTBEAT_PERIOD:TAB_HEARTBEAT_PERIOD;heartbeatTimeout=browser.setTimeout(heartbeat,hbPeriod);}
function onStorage({key,newValue}){if(key==="multi_tab_service.main"&&!newValue){startElection();}}
function unregister(){clearTimeout(heartbeatTimeout);const lastPresenceByTab=JSON.parse(localStorage.getItem("multi_tab_service.lastPresenceByTab"))??{};delete lastPresenceByTab[tabId];localStorage.setItem("multi_tab_service.lastPresenceByTab",JSON.stringify(lastPresenceByTab));if(_isOnMainTab){_isOnMainTab=false;bus.trigger("no_longer_main_tab");browser.localStorage.removeItem("multi_tab_service.main");}}
browser.addEventListener("pagehide",unregister);browser.addEventListener("storage",onStorage);const lastPresenceByTab=JSON.parse(localStorage.getItem("multi_tab_service.lastPresenceByTab"))??{};lastPresenceByTab[tabId]=now;localStorage.setItem("multi_tab_service.lastPresenceByTab",JSON.stringify(lastPresenceByTab));if(!localStorage.getItem("multi_tab_service.main")){startElection();}
heartbeat();return{bus,async isOnMainTab(){return _isOnMainTab;},unregister,};},};return __exports;});;
/* /bus/static/src/multi_tab_service.js */
odoo.define('@bus/multi_tab_service',['@web/core/browser/browser','@web/core/registry','@bus/multi_tab_fallback_service','@bus/multi_tab_shared_worker_service'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{multiTabFallbackService}=require("@bus/multi_tab_fallback_service");const{multiTabSharedWorkerService}=require("@bus/multi_tab_shared_worker_service");const multiTabService=__exports.multiTabService=browser.SharedWorker?multiTabSharedWorkerService:multiTabFallbackService;registry.category("services").add("multi_tab",multiTabService);return __exports;});;
/* /bus/static/src/multi_tab_shared_worker_service.js */
odoo.define('@bus/multi_tab_shared_worker_service',['@web/core/browser/browser','@web/core/utils/concurrency','@odoo/owl'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{Deferred}=require("@web/core/utils/concurrency");const{EventBus}=require("@odoo/owl");const STATE=Object.freeze({INIT:"INIT",MASTER:"MASTER",REGISTERED:"REGISTERED",UNREGISTERED:"UNREGISTERED",});const multiTabSharedWorkerService=__exports.multiTabSharedWorkerService={dependencies:["worker_service"],start(env,{worker_service:workerService}){const bus=new EventBus();let responseDeferred=null;let state=STATE.INIT;browser.addEventListener("pagehide",unregister);function messageHandler(messageEv){const{type,data}=messageEv.data;if(!type?.startsWith("ELECTION:")){return;}
switch(type){case"ELECTION:IS_MASTER_RESPONSE":responseDeferred?.resolve(data.answer);responseDeferred=null;break;case"ELECTION:HEARTBEAT_REQUEST":workerService.send("ELECTION:HEARTBEAT");break;case"ELECTION:ASSIGN_MASTER":state=STATE.MASTER;bus.trigger("become_main_tab");break;case"ELECTION:UNASSIGN_MASTER":if(state!==STATE.UNREGISTERED){state=STATE.REGISTERED;}
bus.trigger("no_longer_main_tab");break;default:console.warn("multiTabSharedWorkerService received unknown message type:",type);}}
async function startWorker(){await workerService.ensureWorkerStarted();await workerService.registerHandler(messageHandler);workerService.send("ELECTION:REGISTER");state=STATE.REGISTERED;}
function unregister(){workerService.send("ELECTION:UNREGISTER");state=STATE.UNREGISTERED;}
return{bus,isOnMainTab:async()=>{if(state===STATE.UNREGISTERED){return false;}
if(state===STATE.INIT){await startWorker();}
if(!responseDeferred){responseDeferred=new Deferred();workerService.send("ELECTION:IS_MASTER?");}
return responseDeferred;},unregister,};},};return __exports;});;
/* /bus/static/src/outdated_page_watcher_service.js */
odoo.define('@bus/outdated_page_watcher_service',['@web/core/browser/browser','@web/core/l10n/translation','@web/core/network/rpc','@web/core/registry'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"bus",...args);const{rpc}=require("@web/core/network/rpc");const{registry}=require("@web/core/registry");const OutdatedPageWatcherService=__exports.OutdatedPageWatcherService=class OutdatedPageWatcherService{constructor(env,services){this.setup(env,services);}
setup(env,{bus_service,multi_tab,legacy_multi_tab,notification}){this.notification=notification;this.multi_tab=multi_tab;this.legacy_multi_tab=legacy_multi_tab;this.lastNotificationId=legacy_multi_tab.getSharedValue("last_notification_id");this.closeNotificationFn;let wasBusAlreadyConnected;bus_service.addEventListener("BUS:WORKER_STATE_UPDATED",({detail:state})=>{wasBusAlreadyConnected=state!=="IDLE";},{once:true});bus_service.addEventListener("BUS:DISCONNECT",()=>(this.lastNotificationId=legacy_multi_tab.getSharedValue("last_notification_id")));bus_service.addEventListener("BUS:CONNECT",async()=>{if(wasBusAlreadyConnected){this.checkHasMissedNotifications();}
wasBusAlreadyConnected=true;});bus_service.addEventListener("BUS:RECONNECT",()=>this.checkHasMissedNotifications());legacy_multi_tab.bus.addEventListener("shared_value_updated",({detail:{key}})=>{if(key==="bus.has_missed_notifications"){this.showOutdatedPageNotification();}});}
async checkHasMissedNotifications(){if(!this.lastNotificationId||!(await this.multi_tab.isOnMainTab())){return;}
const hasMissedNotifications=await rpc("/bus/has_missed_notifications",{last_notification_id:this.lastNotificationId},{silent:true});if(hasMissedNotifications){this.showOutdatedPageNotification();this.legacy_multi_tab.setSharedValue("bus.has_missed_notifications",Date.now());}}
showOutdatedPageNotification(){this.closeNotificationFn?.();this.closeNotificationFn=this.notification.add(_t("Save your work and refresh to get the latest updates and avoid potential issues."),{title:_t("The page is out of date"),type:"warning",sticky:true,buttons:[{name:_t("Refresh"),primary:true,onClick:()=>browser.location.reload(),},],});}}
const outdatedPageWatcherService=__exports.outdatedPageWatcherService={dependencies:["bus_service","multi_tab","legacy_multi_tab","notification"],start(env,services){return new OutdatedPageWatcherService(env,services);},};registry.category("services").add("bus.outdated_page_watcher",outdatedPageWatcherService);return __exports;});;
/* /bus/static/src/services/bus_monitoring_service.js */
odoo.define('@bus/services/bus_monitoring_service',['@bus/workers/websocket_worker','@odoo/owl','@web/core/browser/browser','@web/core/registry'],function(require){'use strict';let __exports={};const{WORKER_STATE}=require("@bus/workers/websocket_worker");const{reactive}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const BusMonitoringService=__exports.BusMonitoringService=class BusMonitoringService{isConnectionLost=false;constructor(env,services){const reactiveThis=reactive(this);reactiveThis.setup(env,services);return reactiveThis;}
setup(env,{bus_service}){bus_service.addEventListener("BUS:WORKER_STATE_UPDATED",({detail})=>this.workerStateOnChange(detail));browser.addEventListener("offline",()=>(this.isReconnecting=false));}
workerStateOnChange(state){switch(state){case WORKER_STATE.CONNECTING:{this.isReconnecting=true;break;}
case WORKER_STATE.CONNECTED:{this.isReconnecting=false;this.isConnectionLost=false;break;}
case WORKER_STATE.DISCONNECTED:{if(this.isReconnecting){this.isConnectionLost=true;this.isReconnecting=false;}
break;}}}}
const busMonitoringservice=__exports.busMonitoringservice={dependencies:["bus_service"],start(env,services){return new BusMonitoringService(env,services);},};registry.category("services").add("bus.monitoring_service",busMonitoringservice);return __exports;});;
/* /bus/static/src/services/bus_service.js */
odoo.define('@bus/services/bus_service',['@web/core/browser/browser','@web/core/l10n/translation','@web/core/utils/concurrency','@web/core/registry','@web/session','@odoo/owl','@web/core/user'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"bus",...args);const{Deferred}=require("@web/core/utils/concurrency");const{registry}=require("@web/core/registry");const{session}=require("@web/session");const{EventBus,reactive}=require("@odoo/owl");const{user}=require("@web/core/user");const INTERNAL_EVENTS=new Set(["BUS:INITIALIZED","BUS:OUTDATED","BUS:NOTIFICATION","BUS:PROVIDE_LOGS",]);const BACK_ONLINE_RECONNECT_DELAY=__exports.BACK_ONLINE_RECONNECT_DELAY=5000;const busService=__exports.busService={dependencies:["bus.parameters","localization","multi_tab","legacy_multi_tab","notification","worker_service",],start(env,{multi_tab:multiTab,legacy_multi_tab:legacyMultiTab,notification,"bus.parameters":params,worker_service:workerService,}){const bus=new EventBus();const notificationBus=new EventBus();const subscribeFnToWrapper=new Map();let backOnlineTimeout;const startedAt=luxon.DateTime.now().set({milliseconds:0});let connectionInitializedDeferred;function handleMessage(messageEv){const{type,data}=messageEv.data;switch(type){case"BUS:PROVIDE_LOGS":{const blob=new Blob([JSON.stringify(data,null,2)],{type:"application/json",});const url=URL.createObjectURL(blob);const a=document.createElement("a");a.href=url;a.download=`bus_logs_${luxon.DateTime.now().toFormat(
"yyyy-LL-dd-HH-mm-ss"
)}.json`;a.click();URL.revokeObjectURL(url);break;}
case"BUS:NOTIFICATION":{const notifications=data.map(({id,message})=>({id,...message}));state.lastNotificationId=notifications.at(-1).id;legacyMultiTab.setSharedValue("last_notification_id",state.lastNotificationId);for(const{id,type,payload}of notifications){notificationBus.trigger(type,{id,payload});busService._onMessage(env,id,type,payload);}
break;}
case"BUS:INITIALIZED":{connectionInitializedDeferred.resolve();break;}
case"BUS:WORKER_STATE_UPDATED":state.workerState=data;break;case"BUS:OUTDATED":{multiTab.unregister();notification.add(_t("Save your work and refresh to get the latest updates and avoid potential issues."),{title:_t("The page is out of date"),type:"warning",sticky:true,buttons:[{name:_t("Refresh"),primary:true,onClick:()=>{browser.location.reload();},},],});break;}}
if(!INTERNAL_EVENTS.has(type)){bus.trigger(type,data);}}
async function ensureWorkerStarted(){if(!connectionInitializedDeferred){connectionInitializedDeferred=new Deferred();let uid=Array.isArray(session.user_id)?session.user_id[0]:user.userId;if(!uid&&uid!==undefined){uid=false;}
await workerService.ensureWorkerStarted();await workerService.registerHandler(handleMessage);workerService.send("BUS:INITIALIZE_CONNECTION",{websocketURL:`${params.serverURL.replace("http", "ws")}/websocket?version=${
session.websocket_worker_version
}`,db:session.db,debug:odoo.debug,lastNotificationId:legacyMultiTab.getSharedValue("last_notification_id",0),uid,startTs:startedAt.valueOf(),});}
await connectionInitializedDeferred;}
browser.addEventListener("pagehide",({persisted})=>{if(!persisted){workerService.send("BUS:LEAVE");}});browser.addEventListener("online",()=>{backOnlineTimeout=browser.setTimeout(()=>{if(state.isActive){workerService.send("BUS:START");}},BACK_ONLINE_RECONNECT_DELAY);},{capture:true});browser.addEventListener("offline",()=>{clearTimeout(backOnlineTimeout);workerService.send("BUS:STOP");},{capture:true,});const state=reactive({addEventListener:bus.addEventListener.bind(bus),addChannel:async(channel)=>{await ensureWorkerStarted();workerService.send("BUS:ADD_CHANNEL",channel);workerService.send("BUS:START");state.isActive=true;},deleteChannel:(channel)=>{workerService.send("BUS:DELETE_CHANNEL",channel);},setLoggingEnabled:(isEnabled)=>workerService.send("BUS:SET_LOGGING_ENABLED",isEnabled),downloadLogs:()=>workerService.send("BUS:REQUEST_LOGS"),forceUpdateChannels:()=>workerService.send("BUS:FORCE_UPDATE_CHANNELS"),trigger:bus.trigger.bind(bus),removeEventListener:bus.removeEventListener.bind(bus),send:(eventName,data)=>workerService.send("BUS:SEND",{event_name:eventName,data}),start:async()=>{await ensureWorkerStarted();workerService.send("BUS:START");state.isActive=true;},stop:()=>{workerService.send("BUS:LEAVE");state.isActive=false;},isActive:false,subscribe(notificationType,callback){const wrapper=({detail})=>{const{id,payload}=detail;callback(JSON.parse(JSON.stringify(payload)),{id});};subscribeFnToWrapper.set(callback,wrapper);notificationBus.addEventListener(notificationType,wrapper);},unsubscribe(notificationType,callback){notificationBus.removeEventListener(notificationType,subscribeFnToWrapper.get(callback));subscribeFnToWrapper.delete(callback);},startedAt,workerState:null,lastNotificationId:null,});return state;},_onMessage(env,id,type,payload){},};registry.category("services").add("bus_service",busService);return __exports;});;
/* /bus/static/src/services/presence_service.js */
odoo.define('@bus/services/presence_service',['@odoo/owl','@web/core/browser/browser','@web/core/registry'],function(require){'use strict';let __exports={};const{EventBus}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const presenceService=__exports.presenceService={start(env){const LOCAL_STORAGE_PREFIX="presence";const bus=new EventBus();let isOdooFocused=true;let lastPresenceTime=browser.localStorage.getItem(`${LOCAL_STORAGE_PREFIX}.lastPresence`)||luxon.DateTime.now().ts;function onPresence(){lastPresenceTime=luxon.DateTime.now().ts;browser.localStorage.setItem(`${LOCAL_STORAGE_PREFIX}.lastPresence`,lastPresenceTime);bus.trigger("presence");}
function onFocusChange(isFocused){try{isFocused=parent.document.hasFocus();}catch{}
isOdooFocused=isFocused;browser.localStorage.setItem(`${LOCAL_STORAGE_PREFIX}.focus`,isOdooFocused);if(isOdooFocused){lastPresenceTime=luxon.DateTime.now().ts;env.bus.trigger("window_focus",isOdooFocused);}}
function onStorage({key,newValue}){if(key===`${LOCAL_STORAGE_PREFIX}.focus`){isOdooFocused=JSON.parse(newValue);env.bus.trigger("window_focus",newValue);}
if(key===`${LOCAL_STORAGE_PREFIX}.lastPresence`){lastPresenceTime=JSON.parse(newValue);bus.trigger("presence");}}
browser.addEventListener("storage",onStorage);browser.addEventListener("focus",()=>onFocusChange(true));browser.addEventListener("blur",()=>onFocusChange(false));browser.addEventListener("pagehide",()=>onFocusChange(false));browser.addEventListener("click",onPresence,true);browser.addEventListener("keydown",onPresence,true);return{bus,getLastPresence(){return lastPresenceTime;},isOdooFocused(){return isOdooFocused;},getInactivityPeriod(){return luxon.DateTime.now().ts-this.getLastPresence();},};},};registry.category("services").add("presence",presenceService);return __exports;});;
/* /bus/static/src/services/worker_service.js */
odoo.define('@bus/services/worker_service',['@web/core/browser/browser','@web/core/registry','@web/core/utils/concurrency','@web/session'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{Deferred}=require("@web/core/utils/concurrency");const{session}=require("@web/session");const WORKER_STATE=__exports.WORKER_STATE=Object.freeze({UNINITIALIZED:"UNINITIALIZED",INITIALIZING:"INITIALIZING",INITIALIZED:"INITIALIZED",FAILED:"FAILED",});const WorkerService=__exports.WorkerService=class WorkerService{constructor(env,services){this.params=services["bus.parameters"];this.worker=null;this.isUsingSharedWorker=Boolean(browser.SharedWorker);this._state=WORKER_STATE.UNINITIALIZED;this.connectionInitializedDeferred=new Deferred();}
startWorker(){this._state=WORKER_STATE.INITIALIZING;let workerURL=`${this.params.serverURL}/bus/websocket_worker_bundle?v=${session.websocket_worker_version}`;if(this.params.serverURL!==window.origin){const source=`importScripts("${workerURL}");`;workerURL="data:application/javascript;base64,"+window.btoa(source);}
const workerClass=this.isUsingSharedWorker?browser.SharedWorker:browser.Worker;this.worker=new workerClass(workerURL,{name:this.isUsingSharedWorker?"odoo:bus_shared_worker":"odoo:bus_worker",});this.worker.onerror=(e)=>this.onInitError(e);this._registerHandler((ev)=>{if(ev.data.type==="BASE:INITIALIZED"){this._state=WORKER_STATE.INITIALIZED;this.connectionInitializedDeferred.resolve();}});if(this.isUsingSharedWorker){this.worker.port.start();}
this._send("BASE:INIT");}
async ensureWorkerStarted(){if(this._state===WORKER_STATE.UNINITIALIZED){this.startWorker();}
await this.connectionInitializedDeferred;}
onInitError(e){if(this._state===WORKER_STATE.INITIALIZING&&this.isUsingSharedWorker){console.warn("Error while loading SharedWorker, fallback on Worker: ",e);this.isUsingSharedWorker=false;this.worker?.port?.close?.();this.startWorker();}else if(this._state===WORKER_STATE.INITIALIZING){this._state=WORKER_STATE.FAILED;this.connectionInitializedDeferred.resolve();console.warn("Worker service failed to initialize: ",e);}}
_registerHandler(handler){if(this.isUsingSharedWorker){this.worker.port.addEventListener("message",handler);}else{this.worker.addEventListener("message",handler);}}
_send(action,data){const message={action,data};if(this.isUsingSharedWorker){this.worker.port.postMessage(message);}else{this.worker.postMessage(message);}}
async send(action,data){if(this._state===WORKER_STATE.UNINITIALIZED){return;}
await this.connectionInitializedDeferred;if(this._state===WORKER_STATE.FAILED){console.warn("Worker service failed to initialize, cannot send message.");}
this._send(action,data);}
async registerHandler(handler){if(this._state===WORKER_STATE.UNINITIALIZED){this.startWorker();}
await this.connectionInitializedDeferred;if(this._state===WORKER_STATE.FAILED){console.warn("Worker service failed to initialize, cannot register handler.");}
this._registerHandler(handler);}
get state(){return this._state;}}
const workerService=__exports.workerService={dependencies:["bus.parameters"],start(env,services){return new WorkerService(env,services);},};registry.category("services").add("worker_service",workerService);return __exports;});;
/* /bus/static/src/workers/base_worker.js */
odoo.define('@bus/workers/base_worker',[],function(require){'use strict';let __exports={};const BaseWorker=__exports.BaseWorker=class BaseWorker{constructor(name){this.name=name;this.client=null;}
handleMessage(event){const{action}=event.data;if(action==="BASE:INIT"){if(this.name.includes("shared")){event.target.postMessage({type:"BASE:INITIALIZED"});}else{(this.client||globalThis).postMessage({type:"BASE:INITIALIZED"});}}}}
return __exports;});;
/* /bus/static/src/workers/bus_worker_utils.js */
odoo.define('@bus/workers/bus_worker_utils',[],function(require){'use strict';let __exports={};__exports.debounce=debounce;function debounce(func,wait,immediate){let timeout;return function(){const context=this;const args=arguments;function later(){timeout=null;if(!immediate){func.apply(context,args);}}
const callNow=immediate&&!timeout;clearTimeout(timeout);timeout=setTimeout(later,wait);if(callNow){func.apply(context,args);}};}
const Deferred=__exports.Deferred=class Deferred extends Promise{constructor(){let resolve;let reject;const prom=new Promise((res,rej)=>{resolve=res;reject=rej;});return Object.assign(prom,{resolve,reject});}}
const Logger=__exports.Logger=class Logger{static LOG_TTL=24*60*60*1000;static gcInterval=null;static instances=[];_db;static async gcOutdatedLogs(){const threshold=Date.now()-Logger.LOG_TTL;for(const logger of this.instances){try{await logger._ensureDatabaseAvailable();await new Promise((res,rej)=>{const transaction=logger._db.transaction("logs","readwrite");const store=transaction.objectStore("logs");const req=store.index("timestamp").openCursor(IDBKeyRange.upperBound(threshold));req.onsuccess=(event)=>{const cursor=event.target.result;if(cursor){cursor.delete();cursor.continue();}};req.onerror=(e)=>rej(e.target.error);transaction.oncomplete=res;transaction.onerror=(e)=>rej(e.target.error);});}catch(error){console.error(`Failed to clear logs for logger "${logger._name}":`,error);}}}
constructor(name){this._name=name;Logger.instances.push(this);Logger.gcOutdatedLogs();clearInterval(Logger.gcInterval);Logger.gcInterval=setInterval(()=>Logger.gcOutdatedLogs(),Logger.LOG_TTL);}
async _ensureDatabaseAvailable(){if(this._db){return;}
return new Promise((res,rej)=>{const request=indexedDB.open(this._name,1);request.onsuccess=(event)=>{this._db=event.target.result;res();};request.onupgradeneeded=(event)=>{if(!event.target.result.objectStoreNames.contains("logs")){const store=event.target.result.createObjectStore("logs",{autoIncrement:true,});store.createIndex("timestamp","timestamp",{unique:false});}};request.onerror=rej;});}
async log(message){await this._ensureDatabaseAvailable();const transaction=this._db.transaction("logs","readwrite");const store=transaction.objectStore("logs");const addRequest=store.add({timestamp:Date.now(),message});return new Promise((res,rej)=>{addRequest.onsuccess=res;addRequest.onerror=rej;});}
async getLogs(){await Logger.gcOutdatedLogs();await this._ensureDatabaseAvailable();const transaction=this._db.transaction("logs","readonly");const store=transaction.objectStore("logs");const request=store.getAll();return new Promise((res,rej)=>{request.onsuccess=(ev)=>res(ev.target.result.map(({message})=>message));request.onerror=rej;});}}
return __exports;});;
/* /bus/static/src/workers/election_worker.js */
odoo.define('@bus/workers/election_worker',['@bus/workers/bus_worker_utils'],function(require){'use strict';let __exports={};const{Deferred}=require("@bus/workers/bus_worker_utils");const ElectionWorker=__exports.ElectionWorker=class ElectionWorker{MAIN_TAB_TIMEOUT_PERIOD=3000;candidates=new Set();electionDeferred=null;heartbeatRequestInterval=null;lastHeartbeat=Date.now();masterReplyDeferred=null;masterTab=null;constructor(){setInterval(()=>{if(Date.now()-this.lastHeartbeat>this.MAIN_TAB_TIMEOUT_PERIOD){this.startElection();}},this.MAIN_TAB_TIMEOUT_PERIOD);}
requestHeartbeat(messagePort){if(messagePort){messagePort.postMessage({type:"ELECTION:HEARTBEAT_REQUEST"});return;}
for(const candidate of this.candidates){candidate.postMessage({type:"ELECTION:HEARTBEAT_REQUEST"});}}
async ensureMasterPresence(){this.masterReplyDeferred??=new Deferred();if(this.masterTab){this.requestHeartbeat(this.masterTab);}else{this.startElection();}
await this.masterReplyDeferred;}
startElection(){clearInterval(this.heartbeatRequestInterval);this.masterTab?.postMessage({type:"ELECTION:UNASSIGN_MASTER"});this.masterTab=null;this.electionDeferred??=new Deferred();this.requestHeartbeat();}
finishElection(messagePort){this.masterTab=messagePort;messagePort.postMessage({type:"ELECTION:ASSIGN_MASTER"});this.electionDeferred.resolve();this.electionDeferred=null;this.heartbeatRequestInterval=setInterval(()=>this.requestHeartbeat(this.masterTab),this.MAIN_TAB_TIMEOUT_PERIOD/2);}
async handleMessage(event){const{action}=event.data;if(!action?.startsWith("ELECTION:")){return;}
switch(action){case"ELECTION:REGISTER":this.candidates.add(event.target);await this.electionDeferred;if(!this.masterTab){this.startElection();}
break;case"ELECTION:UNREGISTER":this.candidates.delete(event.target);if(this.masterTab===event.target){this.startElection();}
break;case"ELECTION:IS_MASTER?":await this.ensureMasterPresence();event.target.postMessage({type:"ELECTION:IS_MASTER_RESPONSE",data:{answer:this.masterTab===event.target},});break;case"ELECTION:HEARTBEAT":if(this.electionDeferred){this.finishElection(event.target);}
if(this.masterTab===event.target){this.lastHeartbeat=Date.now();this.masterReplyDeferred?.resolve();this.masterReplyDeferred=null;}
break;default:console.warn("Unknown message action:",action);}}}
return __exports;});;
/* /bus/static/src/workers/websocket_worker.js */
odoo.define('@bus/workers/websocket_worker',['@bus/workers/bus_worker_utils'],function(require){'use strict';let __exports={};const{debounce,Deferred,Logger}=require("@bus/workers/bus_worker_utils");const WEBSOCKET_CLOSE_CODES=__exports.WEBSOCKET_CLOSE_CODES=Object.freeze({CLEAN:1000,GOING_AWAY:1001,PROTOCOL_ERROR:1002,INCORRECT_DATA:1003,ABNORMAL_CLOSURE:1006,INCONSISTENT_DATA:1007,MESSAGE_VIOLATING_POLICY:1008,MESSAGE_TOO_BIG:1009,EXTENSION_NEGOTIATION_FAILED:1010,SERVER_ERROR:1011,RESTART:1012,TRY_LATER:1013,BAD_GATEWAY:1014,SESSION_EXPIRED:4001,KEEP_ALIVE_TIMEOUT:4002,RECONNECTING:4003,CLOSING_HANDSHAKE_ABORTED:4004,});const WORKER_STATE=__exports.WORKER_STATE=Object.freeze({CONNECTED:"CONNECTED",DISCONNECTED:"DISCONNECTED",IDLE:"IDLE",CONNECTING:"CONNECTING",});const MAXIMUM_RECONNECT_DELAY=60000;const UUID=Date.now().toString(36)+Math.random().toString(36).substring(2);const logger=new Logger("bus_websocket_worker");const WebsocketWorker=__exports.WebsocketWorker=class WebsocketWorker{INITIAL_RECONNECT_DELAY=1000;RECONNECT_JITTER=1000;CONNECTION_CHECK_DELAY=60_000;constructor(name){this.name=name;this.newestStartTs=undefined;this.websocketURL="";this.currentUID=null;this.currentDB=null;this.isWaitingForNewUID=true;this.channelsByClient=new Map();this.connectRetryDelay=this.INITIAL_RECONNECT_DELAY;this.connectTimeout=null;this.debugModeByClient=new Map();this.isDebug=false;this.active=true;this.state=WORKER_STATE.IDLE;this.isReconnecting=false;this.lastChannelSubscription=null;this.loggingEnabled=null;this.firstSubscribeDeferred=new Deferred();this.lastNotificationId=0;this.messageWaitQueue=[];this._forceUpdateChannels=debounce(this._forceUpdateChannels,300);this._debouncedUpdateChannels=debounce(this._updateChannels,300);this._debouncedSendToServer=debounce(this._sendToServer,300);this._onWebsocketClose=this._onWebsocketClose.bind(this);this._onWebsocketError=this._onWebsocketError.bind(this);this._onWebsocketMessage=this._onWebsocketMessage.bind(this);this._onWebsocketOpen=this._onWebsocketOpen.bind(this);globalThis.addEventListener("error",({error})=>{const params=error instanceof Error?[error.constructor.name,error.stack]:[error];this._logDebug("Unhandled error",...params);});globalThis.addEventListener("unhandledrejection",({reason})=>{const params=reason instanceof Error?[reason.constructor.name,reason.stack]:[reason];this._logDebug("Unhandled rejection",params);});}
broadcast(type,data){this._logDebug("broadcast",type,data);for(const client of this.channelsByClient.keys()){client.postMessage({type,data:data?JSON.parse(JSON.stringify(data)):undefined});}}
registerClient(messagePort){messagePort.addEventListener("message",(ev)=>{this._onClientMessage(messagePort,ev.data);});this.channelsByClient.set(messagePort,[]);}
sendToClient(client,type,data){if(type!=="BUS:PROVIDE_LOGS"){this._logDebug("sendToClient",type,data);}
client.postMessage({type,data:data?JSON.parse(JSON.stringify(data)):undefined});}
_onClientMessage(client,{action,data}){this._logDebug("_onClientMessage",action,data);switch(action){case"BUS:SEND":{if(data["event_name"]==="update_presence"){this._debouncedSendToServer(data);}else{this._sendToServer(data);}
return;}
case"BUS:START":return this._start();case"BUS:STOP":return this._stop();case"BUS:LEAVE":return this._unregisterClient(client);case"BUS:ADD_CHANNEL":return this._addChannel(client,data);case"BUS:DELETE_CHANNEL":return this._deleteChannel(client,data);case"BUS:FORCE_UPDATE_CHANNELS":return this._forceUpdateChannels();case"BUS:SET_LOGGING_ENABLED":this.loggingEnabled=data;break;case"BUS:REQUEST_LOGS":logger.getLogs().then((logs)=>{const workerInfo={UUID,active:this.active,channels:[...new Set([].concat.apply([],[...this.channelsByClient.values()])),].sort(),db:this.currentDB,is_reconnecting:this.isReconnecting,last_subscription:this.lastChannelSubscription,name:this.name,number_of_clients:this.channelsByClient.size,reconnect_delay:this.connectRetryDelay,uid:this.currentUID,websocket_url:this.websocketURL,};this.sendToClient(client,"BUS:PROVIDE_LOGS",{workerInfo,logs});});break;case"BUS:INITIALIZE_CONNECTION":return this._initializeConnection(client,data);}}
_addChannel(client,channel){this.channelsByClient.get(client).push(channel);this._debouncedUpdateChannels();}
_deleteChannel(client,channel){const clientChannels=this.channelsByClient.get(client);if(!clientChannels){return;}
const channelIndex=clientChannels.indexOf(channel);if(channelIndex!==-1){clientChannels.splice(channelIndex,1);this._debouncedUpdateChannels();}}
_forceUpdateChannels(){this._updateChannels({force:true});}
_unregisterClient(client){this.channelsByClient.delete(client);this.debugModeByClient.delete(client);this.isDebug=[...this.debugModeByClient.values()].some(Boolean);this._debouncedUpdateChannels();}
_initializeConnection(client,{db,debug,lastNotificationId,uid,websocketURL,startTs}){if(this.newestStartTs&&this.newestStartTs>startTs){this.debugModeByClient.set(client,debug);this.isDebug=[...this.debugModeByClient.values()].some(Boolean);this.sendToClient(client,"BUS:WORKER_STATE_UPDATED",this.state);this.sendToClient(client,"BUS:INITIALIZED");return;}
this.newestStartTs=startTs;this.websocketURL=websocketURL;this.lastNotificationId=lastNotificationId;this.debugModeByClient.set(client,debug);this.isDebug=[...this.debugModeByClient.values()].some(Boolean);const isCurrentUserKnown=uid!==undefined;if(this.isWaitingForNewUID&&isCurrentUserKnown){this.isWaitingForNewUID=false;this.currentUID=uid;}
this.currentDB||=db;if((this.currentUID!==uid&&isCurrentUserKnown)||(db&&this.currentDB!==db)){this.currentUID=uid;this.currentDB=db||this.currentDB;if(this.websocket){this.websocket.close(WEBSOCKET_CLOSE_CODES.CLEAN);}
this.channelsByClient.forEach((_,key)=>this.channelsByClient.set(key,[]));}
this.sendToClient(client,"BUS:WORKER_STATE_UPDATED",this.state);this.sendToClient(client,"BUS:INITIALIZED");if(!this.active){this.sendToClient(client,"BUS:OUTDATED");}}
_isWebsocketConnected(){return this.websocket&&this.websocket.readyState===1;}
_isWebsocketConnecting(){return this.websocket&&this.websocket.readyState===0;}
_isWebsocketClosing(){return this.websocket&&this.websocket.readyState===2;}
_onWebsocketClose({code,reason}){clearInterval(this._connectionCheckInterval);this._logDebug("_onWebsocketClose",code,reason);this._updateState(WORKER_STATE.DISCONNECTED);this.lastChannelSubscription=null;this.firstSubscribeDeferred=new Deferred();if(this.isReconnecting){return;}
this.broadcast("BUS:DISCONNECT",{code,reason});if(code===WEBSOCKET_CLOSE_CODES.CLEAN){if(reason==="OUTDATED_VERSION"){console.warn("Worker deactivated due to an outdated version.");this.active=false;this.broadcast("BUS:OUTDATED");}
return;}
this.broadcast("BUS:RECONNECTING",{closeCode:code});this.isReconnecting=true;if([WEBSOCKET_CLOSE_CODES.KEEP_ALIVE_TIMEOUT,WEBSOCKET_CLOSE_CODES.CLOSING_HANDSHAKE_ABORTED,].includes(code)){this.connectRetryDelay=0;}
if(code===WEBSOCKET_CLOSE_CODES.SESSION_EXPIRED){this.isWaitingForNewUID=true;}
this._retryConnectionWithDelay();}
_onWebsocketError(){this._logDebug("_onWebsocketError");this._retryConnectionWithDelay();}
_onWebsocketMessage(messageEv){this._restartConnectionCheckInterval();const notifications=JSON.parse(messageEv.data);this._logDebug("_onWebsocketMessage",notifications);this.lastNotificationId=notifications[notifications.length-1].id;this.broadcast("BUS:NOTIFICATION",notifications);}
async _logDebug(title,...args){if(this.loggingEnabled){try{await logger.log({dt:new Date().toISOString(),event:title,args,worker:UUID,});}catch(e){console.error(e);}}}
_onWebsocketOpen(){this._logDebug("_onWebsocketOpen");this._updateState(WORKER_STATE.CONNECTED);this.broadcast(this.isReconnecting?"BUS:RECONNECT":"BUS:CONNECT");this._debouncedUpdateChannels();this.connectRetryDelay=this.INITIAL_RECONNECT_DELAY;this.connectTimeout=null;this.isReconnecting=false;this.firstSubscribeDeferred.then(()=>{if(!this.websocket){return;}
this.messageWaitQueue.forEach((msg)=>this.websocket.send(msg));this.messageWaitQueue=[];});this._restartConnectionCheckInterval();}
_restartConnectionCheckInterval(){clearInterval(this._connectionCheckInterval);this._connectionCheckInterval=setInterval(()=>{if(this._isWebsocketConnected()){this.websocket.send(new Uint8Array([0x00]));this._logDebug("connection_checked");}},this.CONNECTION_CHECK_DELAY);}
_retryConnectionWithDelay(){this.connectRetryDelay=Math.min(this.connectRetryDelay*1.5,MAXIMUM_RECONNECT_DELAY)+
this.RECONNECT_JITTER*Math.random();this._logDebug("_retryConnectionWithDelay",this.connectRetryDelay);this.connectTimeout=setTimeout(this._start.bind(this),this.connectRetryDelay);}
_sendToServer(message){this._logDebug("_sendToServer",message);const payload=JSON.stringify(message);if(!this._isWebsocketConnected()){if(message["event_name"]==="subscribe"){this.messageWaitQueue=this.messageWaitQueue.filter((msg)=>JSON.parse(msg).event_name!=="subscribe");this.messageWaitQueue.unshift(payload);}else{this.messageWaitQueue.push(payload);}}else{if(message["event_name"]==="subscribe"){this.websocket.send(payload);}else{this.firstSubscribeDeferred.then(()=>this.websocket.send(payload));}
this._restartConnectionCheckInterval();}}
_removeWebsocketListeners(){this.websocket?.removeEventListener("open",this._onWebsocketOpen);this.websocket?.removeEventListener("message",this._onWebsocketMessage);this.websocket?.removeEventListener("error",this._onWebsocketError);this.websocket?.removeEventListener("close",this._onWebsocketClose);}
_start(){this._logDebug("_start");if(!this.active||this._isWebsocketConnected()||this._isWebsocketConnecting()){return;}
this._removeWebsocketListeners();if(this._isWebsocketClosing()){this._onWebsocketClose(new CloseEvent("close",{code:WEBSOCKET_CLOSE_CODES.CLOSING_HANDSHAKE_ABORTED}));this.websocket=null;return;}
this._updateState(WORKER_STATE.CONNECTING);this.websocket=new WebSocket(this.websocketURL);this.websocket.addEventListener("open",this._onWebsocketOpen);this.websocket.addEventListener("error",this._onWebsocketError);this.websocket.addEventListener("message",this._onWebsocketMessage);this.websocket.addEventListener("close",this._onWebsocketClose);}
_stop(){this._logDebug("_stop");clearTimeout(this.connectTimeout);this.connectRetryDelay=this.INITIAL_RECONNECT_DELAY;this.isReconnecting=false;this.lastChannelSubscription=null;const shouldBroadcastClose=this.websocket&&this.websocket.readyState!==WebSocket.CLOSED;this.websocket?.close();this._removeWebsocketListeners();this.websocket=null;if(shouldBroadcastClose){this.broadcast("BUS:DISCONNECT",{code:WEBSOCKET_CLOSE_CODES.CLEAN});}}
_updateChannels({force=false}={}){const allTabsChannels=[...new Set([].concat.apply([],[...this.channelsByClient.values()])),].sort();const allTabsChannelsString=JSON.stringify(allTabsChannels);const shouldUpdateChannelSubscription=allTabsChannelsString!==this.lastChannelSubscription;if(force||shouldUpdateChannelSubscription){this.lastChannelSubscription=allTabsChannelsString;this._sendToServer({event_name:"subscribe",data:{channels:allTabsChannels,last:this.lastNotificationId},});this.firstSubscribeDeferred.resolve();}}
_updateState(newState){this.state=newState;this.broadcast("BUS:WORKER_STATE_UPDATED",newState);}}
return __exports;});;
/* /html_editor/static/src/components/switch/switch.js */
odoo.define('@html_editor/components/switch/switch',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component,xml}=require("@odoo/owl");const NO_OP=()=>{};const Switch=__exports.Switch=class Switch extends Component{static props={value:{type:Boolean,optional:true},extraClasses:String,disabled:{type:Boolean,optional:true},label:{type:String,optional:true},description:{type:String,optional:true},onChange:{Function,optional:true},};static defaultProps={onChange:NO_OP,};static template=xml`
<label t-att-class="'o_switch' + extraClasses">
<input type="checkbox"
name="switch"
class="visually-hidden"
t-att-checked="props.value"
t-att-disabled="props.disabled"
t-on-change="(ev) => props.onChange(ev.target.checked)"
t-on-keyup="onKeyup"/>
<span/>
<span t-if="props.label" t-esc="props.label" class="ms-2"/>
<span t-if="props.description" class="text-muted ms-2" t-esc="props.description"/>
</label>
`;setup(){this.extraClasses=this.props.extraClasses?` ${this.props.extraClasses}`:"";}
onKeyup(ev){if(ev.key==="Enter"){ev.currentTarget.checked=!ev.currentTarget.checked;}}}
return __exports;});;
/* /html_editor/static/src/main/media/media_dialog/document_selector.js */
odoo.define('@html_editor/main/media/media_dialog/document_selector',['@web/core/l10n/translation','@html_editor/main/media/media_dialog/file_selector','@web/core/utils/render'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"html_editor",...args);const{Attachment,FileSelector,IMAGE_MIMETYPES}=require("@html_editor/main/media/media_dialog/file_selector");const{renderToElement}=require("@web/core/utils/render");const DocumentAttachment=__exports.DocumentAttachment=class DocumentAttachment extends Attachment{static template="html_editor.DocumentAttachment";}
const DocumentSelector=__exports.DocumentSelector=class DocumentSelector extends FileSelector{static mediaSpecificClasses=["o_file_box"];static mediaSpecificStyles=[];static mediaExtraClasses=[];static tagNames=["SPAN"];static attachmentsListTemplate="html_editor.DocumentsListTemplate";static components={...FileSelector.components,DocumentAttachment,};setup(){super.setup();this.uploadText=_t("Upload a document");this.urlPlaceholder="https://www.odoo.com/mydocument";this.addText=_t("Add URL");this.searchPlaceholder=_t("Search a document");this.allLoadedText=_t("All documents have been loaded");}
get attachmentsDomain(){const domain=super.attachmentsDomain;domain.push(["mimetype","not in",IMAGE_MIMETYPES]);domain.unshift("&","|",["url","=",null],"!",["url","=like","/web/assets/%"]);return domain;}
async onClickDocument(document){this.selectAttachment(document);await this.props.save();}
async fetchAttachments(...args){const attachments=await super.fetchAttachments(...args);if(this.selectInitialMedia()){for(const attachment of attachments){if(`/web/content/${attachment.id}`===this.props.media.querySelector("a").getAttribute("href").replace(/[?].*/,"")){this.selectAttachment(attachment);}}}
return attachments;}
static async createElements(selectedMedia,{orm}){return Promise.all(selectedMedia.map(async(attachment)=>{let url=`/web/content/${encodeURIComponent(
attachment.id
)}?unique=${encodeURIComponent(attachment.checksum)}&download=true`;if(!attachment.public){let accessToken=attachment.access_token;if(!accessToken){[accessToken]=await orm.call("ir.attachment","generate_access_token",[attachment.id,]);}
url+=`&access_token=${encodeURIComponent(accessToken)}`;}
return this.renderFileElement(attachment,url);}));}
static renderFileElement(attachment,downloadUrl){return renderStaticFileBox(attachment.name,attachment.mimetype,downloadUrl,attachment.id);}}
__exports.renderStaticFileBox=renderStaticFileBox;function renderStaticFileBox(filename,mimetype,downloadUrl,id){const rootSpan=document.createElement("span");rootSpan.classList.add("o_file_box","o-contenteditable-false");rootSpan.contentEditable=false;rootSpan.dataset.attachmentId=id;const bannerElement=renderToElement("html_editor.StaticFileBox",{fileModel:{filename,mimetype,downloadUrl},});rootSpan.append(bannerElement);return rootSpan;}
return __exports;});;
/* /html_editor/static/src/main/media/media_dialog/file_selector.js */
odoo.define('@html_editor/main/media/media_dialog/file_selector',['@web/core/l10n/translation','@web/core/network/rpc','@web/core/utils/hooks','@web/core/confirmation_dialog/confirmation_dialog','@web/core/dialog/dialog','@web/core/utils/concurrency','@web/core/utils/timing','@html_editor/main/media/media_dialog/search_media','@odoo/owl'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"html_editor",...args);const{rpc}=require("@web/core/network/rpc");const{useService}=require("@web/core/utils/hooks");const{ConfirmationDialog}=require("@web/core/confirmation_dialog/confirmation_dialog");const{Dialog}=require("@web/core/dialog/dialog");const{KeepLast}=require("@web/core/utils/concurrency");const{useDebounced}=require("@web/core/utils/timing");const{SearchMedia}=require("@html_editor/main/media/media_dialog/search_media");const{Component,xml,useState,useRef,onWillStart,useEffect}=require("@odoo/owl");const IMAGE_MIMETYPES=__exports.IMAGE_MIMETYPES=["image/jpg","image/jpeg","image/jpe","image/png","image/svg+xml","image/gif","image/webp",];const IMAGE_EXTENSIONS=__exports.IMAGE_EXTENSIONS=[".jpg",".jpeg",".jpe",".png",".svg",".gif",".webp"];class RemoveButton extends Component{static template=xml`<i class="fa fa-trash o_existing_attachment_remove position-absolute top-0 end-0 p-2 bg-white-25 cursor-pointer opacity-0 opacity-100-hover z-1 transition-base" t-att-title="removeTitle" role="img" t-att-aria-label="removeTitle" t-on-click="this.remove"/>`;static props=["model?","remove"];setup(){this.removeTitle=_t("This file is attached to the current record.");if(this.props.model==="ir.ui.view"){this.removeTitle=_t("This file is a public view attachment.");}}
remove(ev){ev.stopPropagation();this.props.remove();}}
const AttachmentError=__exports.AttachmentError=class AttachmentError extends Component{static components={Dialog};static template="html_editor.AttachmentError";static props=["views","close"];setup(){this.title=_t("Alert");}}
const Attachment=__exports.Attachment=class Attachment extends Component{static template="";static components={RemoveButton,};static props=["*"];setup(){this.dialogs=useService("dialog");}
remove(){this.dialogs.add(ConfirmationDialog,{body:_t("Are you sure you want to delete this file?"),confirm:async()=>{const prevented=await rpc("/html_editor/attachment/remove",{ids:[this.props.id],});if(!Object.keys(prevented).length){this.props.onRemoved(this.props.id);}else{this.dialogs.add(AttachmentError,{views:prevented[this.props.id],});}},});}}
const FileSelectorControlPanel=__exports.FileSelectorControlPanel=class FileSelectorControlPanel extends Component{static template="html_editor.FileSelectorControlPanel";static components={SearchMedia,};static props={uploadUrl:Function,validateUrl:Function,uploadFiles:Function,changeSearchService:Function,changeShowOptimized:Function,search:Function,accept:{type:String,optional:true},addText:{type:String,optional:true},multiSelect:{type:true,optional:true},needle:{type:String,optional:true},searchPlaceholder:{type:String,optional:true},searchService:{type:String,optional:true},showOptimized:{type:Boolean,optional:true},showOptimizedOption:{type:String,optional:true},uploadText:{type:String,optional:true},urlPlaceholder:{type:String,optional:true},urlWarningTitle:{type:String,optional:true},useMediaLibrary:{type:Boolean,optional:true},useUnsplash:{type:Boolean,optional:true},};setup(){this.state=useState({showUrlInput:false,urlInput:"",isValidUrl:false,isValidFileFormat:false,isValidatingUrl:false,});this.debouncedValidateUrl=useDebounced(this.props.validateUrl,500);this.fileInput=useRef("file-input");const urlInputRef=useRef("urlInput");useEffect(()=>{if(this.state.showUrlInput){urlInputRef.el.focus();}},()=>[this.state.showUrlInput]);}
get showSearchServiceSelect(){return this.props.searchService&&this.props.needle;}
get enableUrlUploadClick(){return(!this.state.showUrlInput||(this.state.urlInput&&this.state.isValidUrl&&this.state.isValidFileFormat));}
async onUrlUploadClick(){if(!this.state.showUrlInput){this.state.showUrlInput=true;}else{await this.props.uploadUrl(this.state.urlInput);this.state.urlInput="";}}
async onUrlInput(ev){this.state.isValidatingUrl=true;const{isValidUrl,isValidFileFormat}=await this.debouncedValidateUrl(ev.target.value);this.state.isValidFileFormat=isValidFileFormat;this.state.isValidUrl=isValidUrl;this.state.isValidatingUrl=false;}
onClickUpload(){this.fileInput.el.click();}
async onChangeFileInput(){const inputFiles=this.fileInput.el.files;if(!inputFiles.length){return;}
await this.props.uploadFiles(inputFiles);const fileInputEl=this.fileInput.el;if(fileInputEl){fileInputEl.value="";}}}
const FileSelector=__exports.FileSelector=class FileSelector extends Component{static template="html_editor.FileSelector";static components={FileSelectorControlPanel,};static props=["*"];setup(){this.notificationService=useService("notification");this.orm=useService("orm");this.uploadService=useService("upload");this.keepLast=new KeepLast();this.loadMoreButtonRef=useRef("load-more-button");this.existingAttachmentsRef=useRef("existing-attachments");this.state=useState({attachments:[],canScrollAttachments:false,canLoadMoreAttachments:false,isFetchingAttachments:false,needle:"",});this.NUMBER_OF_ATTACHMENTS_TO_DISPLAY=30;onWillStart(async()=>{this.state.attachments=await this.fetchAttachments(this.NUMBER_OF_ATTACHMENTS_TO_DISPLAY,0);});this.debouncedOnScroll=useDebounced(this.updateScroll,15);this.debouncedScrollUpdate=useDebounced(this.updateScroll,500);useEffect((modalEl)=>{if(modalEl){modalEl.addEventListener("scroll",this.debouncedOnScroll);return()=>{modalEl.removeEventListener("scroll",this.debouncedOnScroll);};}},()=>[this.props.modalRef.el?.querySelector("main.modal-body")]);useEffect(()=>{this.loadMoreButtonRef.el.classList.add("o_hide_loading");this.state.canScrollAttachments=false;this.debouncedScrollUpdate();},()=>[this.allAttachments.length]);}
get canLoadMore(){return this.state.canLoadMoreAttachments;}
get hasContent(){return this.state.attachments.length;}
get isFetching(){return this.state.isFetchingAttachments;}
get selectedAttachmentIds(){return this.props.selectedMedia[this.props.id].filter((media)=>media.mediaType==="attachment").map(({id})=>id);}
get attachmentsDomain(){const domain=["&",["res_model","=",this.props.resModel],["res_id","=",this.props.resId||0],];domain.unshift("|",["public","=",true]);domain.push(["name","ilike",this.state.needle]);return domain;}
get allAttachments(){return this.state.attachments;}
validateUrl(url){const path=url.split("?")[0];const isValidUrl=/^.+\..+$/.test(path);const isValidFileFormat=true;return{isValidUrl,isValidFileFormat,path};}
async fetchAttachments(limit,offset){this.state.isFetchingAttachments=true;let attachments=[];try{attachments=await this.orm.call("ir.attachment","search_read",[],{domain:this.attachmentsDomain,fields:["name","mimetype","description","checksum","url","type","res_id","res_model","public","access_token","image_src","image_width","image_height","original_id",],order:"id desc",limit,offset,});attachments.forEach((attachment)=>(attachment.mediaType="attachment"));}catch(e){if(e.exceptionName!=="odoo.exceptions.AccessError"){throw e;}}
this.state.canLoadMoreAttachments=attachments.length>=this.NUMBER_OF_ATTACHMENTS_TO_DISPLAY;this.state.isFetchingAttachments=false;return attachments;}
async handleLoadMore(){await this.loadMore();}
async loadMore(){return this.keepLast.add(this.fetchAttachments(this.NUMBER_OF_ATTACHMENTS_TO_DISPLAY,this.state.attachments.length)).then((newAttachments)=>{this.state.attachments.push(...newAttachments);});}
async handleSearch(needle){await this.search(needle);}
async search(needle){this.state.attachments=[];this.state.needle=needle;return this.keepLast.add(this.fetchAttachments(this.NUMBER_OF_ATTACHMENTS_TO_DISPLAY,0)).then((attachments)=>{this.state.attachments=attachments;});}
async uploadFiles(files){await this.uploadService.uploadFiles(files,{resModel:this.props.resModel,resId:this.props.resId},(attachment)=>this.onUploaded(attachment));}
async uploadUrl(url){await fetch(url).then(async(result)=>{const blob=await result.blob();blob.id=new Date().getTime();blob.name=new URL(url,window.location.href).pathname.split("/").findLast((s)=>s);await this.uploadFiles([blob]);}).catch(async()=>{await new Promise((resolve)=>{const imageEl=document.createElement("img");imageEl.onerror=()=>{this.notificationService.add(_t("An error occurred while fetching the entered URL."),{type:"danger",sticky:true,});resolve();};imageEl.onload=()=>{this.onLoadUploadedUrl(url,resolve);};imageEl.src=url;});});}
async onLoadUploadedUrl(url,resolve){await this.uploadService.uploadUrl(url,{resModel:this.props.resModel,resId:this.props.resId,},(attachment)=>this.onUploaded(attachment));resolve();}
async onUploaded(attachment){this.state.attachments=[attachment,...this.state.attachments.filter((attach)=>attach.id!==attachment.id),];this.selectAttachment(attachment);if(!this.props.multiSelect){await this.props.save();}
if(this.props.onAttachmentChange){this.props.onAttachmentChange(attachment);}}
onRemoved(attachmentId){this.state.attachments=this.state.attachments.filter((attachment)=>attachment.id!==attachmentId);}
selectAttachment(attachment){this.props.selectMedia({...attachment,mediaType:"attachment"});}
selectInitialMedia(){return(this.props.media&&this.constructor.tagNames.includes(this.props.media.tagName)&&!this.selectedAttachmentIds.length);}
updateScroll(){const loadMoreTop=this.loadMoreButtonRef.el.getBoundingClientRect().top;const modalEl=this.props.modalRef.el.querySelector("main.modal-body");const modalBottom=modalEl.getBoundingClientRect().bottom;this.state.canScrollAttachments=loadMoreTop>=modalBottom;this.loadMoreButtonRef.el.classList.remove("o_hide_loading");}
isAttachmentHidden(attachmentEl){const attachmentBottom=Math.round(attachmentEl.getBoundingClientRect().bottom);const modalEl=this.props.modalRef.el.querySelector("main.modal-body");const modalBottom=modalEl.getBoundingClientRect().bottom;return attachmentBottom>modalBottom;}
handleScrollAttachments(){let scrollToEl=this.loadMoreButtonRef.el;const attachmentEls=[...this.existingAttachmentsRef.el.querySelectorAll(".o_existing_attachment_cell"),];const firstHiddenAttachmentEl=attachmentEls.find((el)=>this.isAttachmentHidden(el));if(firstHiddenAttachmentEl){const attachmentBottom=firstHiddenAttachmentEl.getBoundingClientRect().bottom;const attachmentIndex=attachmentEls.indexOf(firstHiddenAttachmentEl);const firstNextRowAttachmentEl=attachmentEls.slice(attachmentIndex).find((el)=>el.getBoundingClientRect().bottom>attachmentBottom);scrollToEl=firstNextRowAttachmentEl||scrollToEl;}
scrollToEl.scrollIntoView({block:"end",inline:"nearest",behavior:"smooth"});}}
return __exports;});;
/* /html_editor/static/src/main/media/media_dialog/icon_selector.js */
odoo.define('@html_editor/main/media/media_dialog/icon_selector',['@html_editor/main/media/media_dialog/search_media','@html_editor/utils/fonts','@odoo/owl'],function(require){'use strict';let __exports={};const{SearchMedia}=require("@html_editor/main/media/media_dialog/search_media");const{fonts}=require("@html_editor/utils/fonts");const{Component,useState}=require("@odoo/owl");const IconSelector=__exports.IconSelector=class IconSelector extends Component{static mediaSpecificClasses=["fa"];static mediaSpecificStyles=["color","background-color"];static mediaExtraClasses=[/^text-\S+$/,/^bg-\S+$/,/^fa-\S+$/];static tagNames=["SPAN","I"];static template="html_editor.IconSelector";static components={SearchMedia,};static props=["*"];setup(){this.state=useState({fonts:this.props.fonts,needle:"",});}
get selectedMediaIds(){return this.props.selectedMedia[this.props.id].map(({id})=>id);}
search(needle){this.state.needle=needle;if(!this.state.needle){this.state.fonts=this.props.fonts;}else{this.state.fonts=this.props.fonts.map((font)=>{const icons=font.icons.filter((icon)=>icon.alias.indexOf(this.state.needle.toLowerCase())>=0);return{...font,icons};});}}
async onClickIcon(font,icon){this.props.selectMedia({...icon,fontBase:font.base,initialIconChanged:this.props.media&&!icon.names.some((name)=>this.props.media.classList.contains(name)),});await this.props.save();}
static createElements(selectedMedia){return selectedMedia.map((icon)=>{const iconEl=document.createElement("span");iconEl.classList.add(icon.fontBase,icon.names[0]);return iconEl;});}
static initFonts(){fonts.computeFonts();const allFonts=fonts.fontIcons.map(({cssData,base})=>{const uniqueIcons=Array.from(new Map(cssData.map((icon)=>{const alias=icon.names.join(",");const id=`${base}_${alias}`;return[id,{...icon,alias,id}];})).values());return{base,icons:uniqueIcons};});return allFonts;}}
return __exports;});;
/* /html_editor/static/src/main/media/media_dialog/image_selector.js */
odoo.define('@html_editor/main/media/media_dialog/image_selector',['@odoo/owl','@web/core/l10n/translation','@web/core/network/rpc','@web/core/utils/concurrency','@html_editor/utils/color','@html_editor/utils/formatting','@html_editor/main/media/media_dialog/file_selector','@html_editor/utils/image'],function(require){'use strict';let __exports={};const{useRef,useState}=require("@odoo/owl");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"html_editor",...args);const{rpc}=require("@web/core/network/rpc");const{KeepLast}=require("@web/core/utils/concurrency");const{DEFAULT_PALETTE}=require("@html_editor/utils/color");const{getCSSVariableValue,getHtmlStyle}=require("@html_editor/utils/formatting");const{Attachment,FileSelector,IMAGE_EXTENSIONS,IMAGE_MIMETYPES}=require("@html_editor/main/media/media_dialog/file_selector");const{isSrcCorsProtected}=require("@html_editor/utils/image");const AutoResizeImage=__exports.AutoResizeImage=class AutoResizeImage extends Attachment{static template="html_editor.AutoResizeImage";setup(){super.setup();this.image=useRef("auto-resize-image");this.container=useRef("auto-resize-image-container");this.state=useState({loaded:false,});}
async onImageLoaded(){if(!this.image.el){return;}
if(this.props.onLoaded){await this.props.onLoaded(this.image.el);if(!this.image.el){return;}}
const aspectRatio=this.image.el.offsetWidth/this.image.el.offsetHeight;const width=aspectRatio*this.props.minRowHeight;this.container.el.style.flexGrow=width;this.container.el.style.flexBasis=`${width}px`;this.state.loaded=true;}}
const newLocal="img-fluid";const ImageSelector=__exports.ImageSelector=class ImageSelector extends FileSelector{static mediaSpecificClasses=["img",newLocal,"o_we_custom_image"];static mediaSpecificStyles=["transform","width"];static mediaExtraClasses=["rounded-circle","rounded","img-thumbnail","shadow","w-25","w-50","w-75","w-100",];static tagNames=["IMG"];static attachmentsListTemplate="html_editor.ImagesListTemplate";static components={...FileSelector.components,AutoResizeImage,};setup(){super.setup();this.keepLastLibraryMedia=new KeepLast();this.state.libraryMedia=[];this.state.libraryResults=null;this.state.isFetchingLibrary=false;this.state.searchService="all";this.state.showOptimized=false;this.NUMBER_OF_MEDIA_TO_DISPLAY=10;this.uploadText=_t("Upload an image");this.urlPlaceholder="https://www.odoo.com/logo.png";this.addText=_t("Add URL");this.searchPlaceholder=_t("Search an image");this.urlWarningTitle=_t("Uploaded image's format is not supported. Try with: "+IMAGE_EXTENSIONS.join(", "));this.allLoadedText=_t("All images have been loaded");this.showOptimizedOption=this.env.debug;this.MIN_ROW_HEIGHT=128;this.fileMimetypes=IMAGE_MIMETYPES.join(",");this.isImageField=!!this.props.media?.closest("[data-oe-type=image]")||!!this.props.addFieldImage;}
get canLoadMore(){if(this.state.searchService==="media-library"){return(this.state.libraryResults&&this.state.libraryMedia.length<this.state.libraryResults);}
return super.canLoadMore;}
get hasContent(){if(this.state.searchService==="all"){return super.hasContent||!!this.state.libraryMedia.length;}else if(this.state.searchService==="media-library"){return!!this.state.libraryMedia.length;}
return super.hasContent;}
get isFetching(){return super.isFetching||this.state.isFetchingLibrary;}
get selectedMediaIds(){return this.props.selectedMedia[this.props.id].filter((media)=>media.mediaType==="libraryMedia").map(({id})=>id);}
get allAttachments(){return[...super.allAttachments,...this.state.libraryMedia];}
get attachmentsDomain(){const domain=super.attachmentsDomain;domain.push(["mimetype","in",IMAGE_MIMETYPES]);if(!this.props.useMediaLibrary){domain.push("|",["url","=",false],"!","|",["url","=ilike","/html_editor/shape/%"],["url","=ilike","/web_editor/shape/%"]);}
domain.push("!",["name","=like","%.crop"]);domain.push("|",["type","=","binary"],"!",["url","=like","/%/static/%"]);if(!this.env.debug){const subDomain=[false];const originalId=this.props.media&&this.props.media.dataset.originalId;if(originalId){subDomain.push(originalId);}
domain.push(["original_id","in",subDomain]);}
return domain;}
async uploadFiles(files){let abortFn;const uploadPromise=this.uploadService.uploadFiles(files,{resModel:this.props.resModel,resId:this.props.resId,isImage:true,},(attachment)=>this.onUploaded(attachment),(abort)=>{abortFn=abort;});this.props.setAbortUploadsCallback(()=>abortFn?.());await uploadPromise;}
async validateUrl(...args){const{isValidUrl,path}=super.validateUrl(...args);const isValidFileFormat=isValidUrl&&(await new Promise((resolve)=>{const img=new Image();img.src=path;img.onload=()=>resolve(true);img.onerror=()=>resolve(false);}));return{isValidFileFormat,isValidUrl};}
async onLoadUploadedUrl(url,resolve){const urlPathname=new URL(url,window.location.href).pathname;const imageExtension=IMAGE_EXTENSIONS.find((format)=>urlPathname.endsWith(format));if(this.isImageField&&imageExtension===".webp"){this.notificationService.add(_t("You can not replace a field by this image. If you want to use this image, first save it on your computer and then upload it here."),{type:"danger",sticky:true,});return resolve();}
super.onLoadUploadedUrl(url,resolve);}
isInitialMedia(attachment){if(this.props.media.dataset.originalSrc){return this.props.media.dataset.originalSrc===attachment.image_src;}
return this.props.media.getAttribute("src")===attachment.image_src;}
async fetchAttachments(limit,offset){const attachments=await super.fetchAttachments(limit,offset);if(this.isImageField){for(const attachment of attachments){if(attachment.mimetype==="image/webp"&&(await isSrcCorsProtected(attachment.image_src))){attachment.unselectable=true;}}}
const primaryColors={};const htmlStyle=getHtmlStyle(document);for(let color=1;color<=5;color++){primaryColors[color]=getCSSVariableValue("o-color-"+color,htmlStyle);}
return attachments.map((attachment)=>{if(attachment.image_src.startsWith("/")){const newURL=new URL(attachment.image_src,window.location.origin);if(attachment.image_src.startsWith("/html_editor/shape/")||attachment.image_src.startsWith("/web_editor/shape/")){newURL.searchParams.forEach((value,key)=>{const match=key.match(/^c([1-5])$/);if(match){newURL.searchParams.set(key,primaryColors[match[1]]);}});}else{newURL.searchParams.set("height",2*this.MIN_ROW_HEIGHT);}
attachment.thumbnail_src=newURL.pathname+newURL.search;}
if(this.selectInitialMedia()&&this.isInitialMedia(attachment)){this.selectAttachment(attachment);}
return attachment;});}
async fetchLibraryMedia(offset){if(!this.state.needle){return{media:[],results:null};}
this.state.isFetchingLibrary=true;try{const response=await rpc("/html_editor/media_library_search",{query:this.state.needle,offset:offset,},{silent:true,});this.state.isFetchingLibrary=false;const media=(response.media||[]).slice(0,this.NUMBER_OF_MEDIA_TO_DISPLAY);media.forEach((record)=>(record.mediaType="libraryMedia"));return{media,results:response.results};}catch{console.error(`Couldn't reach API endpoint.`);this.state.isFetchingLibrary=false;return{media:[],results:null};}}
async loadMore(...args){await super.loadMore(...args);if(!this.props.useMediaLibrary||this.state.searchService!=="media-library"){return;}
return this.keepLastLibraryMedia.add(this.fetchLibraryMedia(this.state.libraryMedia.length)).then(({media})=>{this.state.libraryMedia.push(...media);});}
async search(...args){await super.search(...args);if(!this.props.useMediaLibrary){return;}
if(!this.state.needle){this.state.searchService="all";}
this.state.libraryMedia=[];this.state.libraryResults=0;return this.keepLastLibraryMedia.add(this.fetchLibraryMedia(0)).then(({media,results})=>{this.state.libraryMedia=media;this.state.libraryResults=results;});}
async onClickAttachment(attachment){if(attachment.unselectable){this.notificationService.add(_t("You can not replace a field by this image. If you want to use this image, first save it on your computer and then upload it here."),{type:"danger",sticky:true,});return;}
this.selectAttachment(attachment);if(!this.props.multiSelect){await this.props.save();}}
async onClickMedia(media){this.props.selectMedia({...media,mediaType:"libraryMedia"});if(!this.props.multiSelect){await this.props.save();}}
static async createElements(selectedMedia,{orm}){const toSave=Object.fromEntries(selectedMedia.filter((media)=>media.mediaType==="libraryMedia").map((media)=>[media.id,{query:media.query||"",is_dynamic_svg:!!media.isDynamicSVG,dynamic_colors:media.dynamicColors,},]));let savedMedia=[];if(Object.keys(toSave).length!==0){savedMedia=await rpc("/html_editor/save_library_media",{media:toSave});}
const selected=selectedMedia.filter((media)=>media.mediaType==="attachment").concat(savedMedia).map((attachment)=>{if(attachment.image_src&&(attachment.image_src.startsWith("/html_editor/shape/")||attachment.image_src.startsWith("/web_editor/shape/"))){const colorCustomizedURL=new URL(attachment.image_src,window.location.origin);const htmlStyle=getHtmlStyle(document);colorCustomizedURL.searchParams.forEach((value,key)=>{const match=key.match(/^c([1-5])$/);if(match){colorCustomizedURL.searchParams.set(key,getCSSVariableValue(`o-color-${match[1]}`,htmlStyle));}});attachment.image_src=colorCustomizedURL.pathname+colorCustomizedURL.search;}
return attachment;});return Promise.all(selected.map(async(attachment)=>{const imageEl=document.createElement("img");let src=attachment.image_src;if(!attachment.public&&!attachment.url){let accessToken=attachment.access_token;if(!accessToken){[accessToken]=await orm.call("ir.attachment","generate_access_token",[attachment.id,]);}
src+=`?access_token=${encodeURIComponent(accessToken)}`;}
imageEl.src=src;imageEl.alt=attachment.description||"";imageEl.dataset.attachmentId=attachment.id;return imageEl;}));}
async onImageLoaded(imgEl,attachment){this.debouncedScrollUpdate();if(attachment.mediaType==="libraryMedia"&&!imgEl.src.startsWith("blob")){await this.onLibraryImageLoaded(imgEl,attachment);}}
async onLibraryImageLoaded(imgEl,media){const mediaUrl=imgEl.src;try{const response=await fetch(mediaUrl);if(response.headers.get("content-type").startsWith("image/svg+xml")){let svg=await response.text();const dynamicColors={};const combinedColorsRegex=new RegExp(Object.values(DEFAULT_PALETTE).join("|"),"gi");const htmlStyle=getHtmlStyle(document);svg=svg.replace(combinedColorsRegex,(match)=>{const colorId=Object.keys(DEFAULT_PALETTE).find((key)=>DEFAULT_PALETTE[key]===match.toUpperCase());const colorKey="c"+colorId;dynamicColors[colorKey]=getCSSVariableValue("o-color-"+colorId,htmlStyle);return dynamicColors[colorKey];});const fileName=mediaUrl.split("/").pop();const file=new File([svg],fileName,{type:"image/svg+xml",});imgEl.src=URL.createObjectURL(file);if(Object.keys(dynamicColors).length){media.isDynamicSVG=true;media.dynamicColors=dynamicColors;}}}catch{console.error("CORS is misconfigured on the API server, image will be treated as non-dynamic.");}}}
return __exports;});;
/* /html_editor/static/src/main/media/media_dialog/media_dialog.js */
odoo.define('@html_editor/main/media/media_dialog/media_dialog',['@web/core/l10n/translation','@web/core/utils/hooks','@web/core/dialog/dialog','@web/core/notebook/notebook','@html_editor/main/media/media_dialog/image_selector','@html_editor/main/media/media_dialog/icon_selector','@odoo/owl','@html_editor/utils/dom_info'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"html_editor",...args);const{useService,useChildRef}=require("@web/core/utils/hooks");const{Dialog}=require("@web/core/dialog/dialog");const{Notebook}=require("@web/core/notebook/notebook");const{ImageSelector}=require("@html_editor/main/media/media_dialog/image_selector");const{IconSelector}=require("@html_editor/main/media/media_dialog/icon_selector");const{Component,useState,useRef,useEffect}=require("@odoo/owl");const{iconClasses}=require("@html_editor/utils/dom_info");const TABS=__exports.TABS={IMAGES:{id:"IMAGES",title:_t("Images"),Component:ImageSelector,sequence:10,},ICONS:{id:"ICONS",title:_t("Icons"),Component:IconSelector,sequence:20,},};const DEFAULT_SEQUENCE=50;const sequence=(tab)=>tab.sequence??DEFAULT_SEQUENCE;const MediaDialog=__exports.MediaDialog=class MediaDialog extends Component{static template="html_editor.MediaDialog";static defaultProps={useMediaLibrary:true,extraTabs:[],};static components={Dialog,Notebook,};static props={extraTabs:{type:Array,optional:true,element:Object},visibleTabs:{type:Array,optional:true,element:String},activeTab:{type:String,optional:true},"*":true,};setup(){this.size="xl";this.contentClass="o_select_media_dialog h-100";this.title=_t("Select a media");this.modalRef=useChildRef();this.orm=useService("orm");this.notificationService=useService("notification");this.selectedMedia=useState({});this.addButtonRef=useRef("add-button");this.initialIconClasses=[];this.notebookPages=[];this.addTabs();this.notebookPages.sort((a,b)=>sequence(a)-sequence(b));this.tabs=Object.fromEntries(this.notebookPages.map((tab)=>[tab.id,tab]));this.errorMessages={};this.state=useState({activeTab:this.initialActiveTab,isSaving:false,});useEffect((nbSelectedAttachments)=>{this.addButtonRef.el.toggleAttribute("disabled",!nbSelectedAttachments||this.state.isSaving);},()=>[this.selectedMedia[this.state.activeTab].length,this.state.isSaving]);this.abortUploads=null;}
get initialActiveTab(){if(this.props.activeTab){return this.props.activeTab;}
if(this.props.media){const correspondingTab=Object.keys(this.tabs).find((id)=>this.tabs[id].Component.mediaSpecificClasses.some((cls)=>[...this.props.media.classList].includes(cls)))||Object.keys(this.tabs).find((id)=>this.tabs[id].Component.tagNames.includes(this.props.media.tagName));if(correspondingTab){return correspondingTab;}}
return this.notebookPages[0].id;}
addTab(tab,additionalProps={}){if(this.props.visibleTabs&&!this.props.visibleTabs.includes(tab.id)){return;}
this.selectedMedia[tab.id]=[];this.notebookPages.push({...tab,props:{...tab.props,...additionalProps,id:tab.id,resModel:this.props.resModel,resId:this.props.resId,media:this.props.media,selectedMedia:this.selectedMedia,selectMedia:(...args)=>this.selectMedia(...args,tab.id,additionalProps.multiSelect),save:this.save.bind(this),setAbortUploadsCallback:(abortFunc)=>(this.abortUploads=abortFunc),onAttachmentChange:this.props.onAttachmentChange,errorMessages:(errorMessage)=>(this.errorMessages[tab.id]=errorMessage),modalRef:this.modalRef,},});}
addTabs(){const onlyImages=this.props.onlyImages||(this.props.media&&this.props.media.parentElement&&(this.props.media.parentElement.dataset.oeField==="image"||this.props.media.parentElement.dataset.oeType==="image"));if(!this.props.noImages){this.addTab(TABS.IMAGES,{useMediaLibrary:this.props.useMediaLibrary,multiSelect:this.props.multiImages,addFieldImage:this.props.addFieldImage,});}
if(onlyImages){return;}
const addIcons=!this.props.visibleTabs||this.props.visibleTabs.includes(TABS.ICONS.id);if(addIcons){const fonts=TABS.ICONS.Component.initFonts();this.addTab(TABS.ICONS,{fonts,});if(this.props.media&&TABS.ICONS.Component.tagNames.includes(this.props.media.tagName)){const classes=this.props.media.className.split(/\s+/);const predefinedMediaFont=fonts.find((font)=>classes.includes(font.base));if(predefinedMediaFont){const selectedIcon=predefinedMediaFont.icons.find((icon)=>icon.names.some((name)=>classes.includes(name)));if(selectedIcon){this.initialIconClasses.push(...selectedIcon.names);this.selectMedia(selectedIcon,TABS.ICONS.id);}}else{const iconRegex=new RegExp(`\\b(?:${iconClasses.join("|")})(?:-\\S+)?\\b`);const fallbackIconClasses=classes.filter((cls)=>iconRegex.test(cls));this.initialIconClasses.push(...fallbackIconClasses);}}}
this.props.extraTabs.forEach((tab)=>this.addTab(tab));}
async renderMedia(selectedMedia){const elements=await this.tabs[this.state.activeTab].Component.createElements(selectedMedia,{orm:this.orm});elements.forEach((element)=>{if(this.props.media){element.classList.add(...this.props.media.classList);const style=this.props.media.getAttribute("style");if(style){element.setAttribute("style",style);}}
for(const otherTab of Object.keys(this.tabs).filter((key)=>key!==this.state.activeTab)){for(const property of this.tabs[otherTab].Component.mediaSpecificStyles){element.style.removeProperty(property);}
element.classList.remove(...this.tabs[otherTab].Component.mediaSpecificClasses);const extraClassesToRemove=[];for(const name of this.tabs[otherTab].Component.mediaExtraClasses){if(typeof name==="string"){extraClassesToRemove.push(name);}else{for(const className of element.classList){if(className.match(name)){extraClassesToRemove.push(className);}}}}
element.classList.remove(...extraClassesToRemove.filter((candidateName)=>{for(const name of this.tabs[this.state.activeTab].Component.mediaExtraClasses){if(typeof name==="string"){if(candidateName===name){return false;}}else{if(candidateName.match(name)){return false;}}}
return true;}));}
element.classList.remove(...this.initialIconClasses);element.classList.remove("o_modified_image_to_save");element.classList.remove("oe_edited_link");element.classList.add(...this.tabs[this.state.activeTab].Component.mediaSpecificClasses);});return elements;}
selectMedia(media,tabId,multiSelect){if(media&&!Object.keys(media).length){this.selectedMedia[tabId]=[];return;}
if(multiSelect){const isMediaSelected=this.selectedMedia[tabId].map(({id})=>id).includes(media.id);if(!isMediaSelected){this.selectedMedia[tabId].push(media);}else{this.selectedMedia[tabId]=this.selectedMedia[tabId].filter((m)=>m.id!==media.id);}}else{this.selectedMedia[tabId]=[media];}}
async save(){if(this.errorMessages[this.state.activeTab]){this.notificationService.add(this.errorMessages[this.state.activeTab],{type:"danger",});return;}
const selectedMedia=this.selectedMedia[this.state.activeTab];const saveSelectedMedia=selectedMedia.length&&(this.state.activeTab!==TABS.ICONS.id||selectedMedia[0].initialIconChanged||!this.props.media);this.state.isSaving=true;if(saveSelectedMedia){const elements=await this.renderMedia(selectedMedia);if(this.props.multiImages){await this.props.save(elements,selectedMedia,this.state.activeTab);}else{await this.props.save(elements[0],selectedMedia,this.state.activeTab);}}
this.props.close();this.state.isSaving=false;}
onTabChange(tab){this.state.activeTab=tab;}
async close(){if(this.abortUploads){this.abortUploads();delete this.abortUploads;}
this.state.isSaving=false;await this.props.close();}}
return __exports;});;
/* /html_editor/static/src/main/media/media_dialog/search_media.js */
odoo.define('@html_editor/main/media/media_dialog/search_media',['@web/core/utils/timing','@web/core/utils/hooks','@odoo/owl'],function(require){'use strict';let __exports={};const{useDebounced}=require("@web/core/utils/timing");const{useAutofocus}=require("@web/core/utils/hooks");const{Component,useEffect,useState}=require("@odoo/owl");const SearchMedia=__exports.SearchMedia=class SearchMedia extends Component{static template="html_editor.SearchMedia";static props=["searchPlaceholder","search","needle"];setup(){useAutofocus({mobile:true});this.debouncedSearch=useDebounced(this.props.search,1000);this.state=useState({input:this.props.needle||"",});useEffect((input)=>{if(this.hasRendered){this.debouncedSearch(input);}else{this.hasRendered=true;}},()=>[this.state.input]);}}
return __exports;});;
/* /html_editor/static/src/main/media/media_dialog/upload_progress_toast/upload_progress_toast.js */
odoo.define('@html_editor/main/media/media_dialog/upload_progress_toast/upload_progress_toast',['@web/core/l10n/translation','@web/core/utils/hooks','@odoo/owl'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"html_editor",...args);const{useService}=require("@web/core/utils/hooks");const{Component,useState}=require("@odoo/owl");const ProgressBar=__exports.ProgressBar=class ProgressBar extends Component{static template="html_editor.ProgressBar";static props={progress:{type:Number,optional:true},hasError:{type:Boolean,optional:true},uploaded:{type:Boolean,optional:true},name:String,size:{type:String,optional:true},errorMessage:{type:String,optional:true},};static defaultProps={progress:0,hasError:false,uploaded:false,size:"",errorMessage:"",};get errorMessage(){return this.props.errorMessage||_t("File could not be saved");}
get progress(){return Math.round(this.props.progress);}}
const UploadProgressToast=__exports.UploadProgressToast=class UploadProgressToast extends Component{static template="html_editor.UploadProgressToast";static components={ProgressBar,};static props={close:Function,};setup(){this.uploadService=useService("upload");this.state=useState(this.uploadService.progressToast);}}
return __exports;});;
/* /html_editor/static/src/main/media/media_dialog/upload_progress_toast/upload_service.js */
odoo.define('@html_editor/main/media/media_dialog/upload_progress_toast/upload_service',['@web/core/network/rpc','@web/core/registry','@html_editor/main/media/media_dialog/upload_progress_toast/upload_progress_toast','@web/core/l10n/translation','@web/core/utils/files','@web/core/utils/numbers','@web/core/utils/urls','@odoo/owl'],function(require){'use strict';let __exports={};const{rpc}=require("@web/core/network/rpc");const{registry}=require("@web/core/registry");const{UploadProgressToast}=require("@html_editor/main/media/media_dialog/upload_progress_toast/upload_progress_toast");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"html_editor",...args);const{checkFileSize}=require("@web/core/utils/files");const{humanNumber}=require("@web/core/utils/numbers");const{getDataURLFromFile}=require("@web/core/utils/urls");const{reactive}=require("@odoo/owl");const AUTOCLOSE_DELAY=__exports.AUTOCLOSE_DELAY=3000;const AUTOCLOSE_DELAY_LONG=__exports.AUTOCLOSE_DELAY_LONG=8000;const uploadService=__exports.uploadService={dependencies:["notification"],start(env,{notification}){let fileId=0;const progressToast=reactive({files:{},isVisible:false,});registry.category("main_components").add("UploadProgressToast",{Component:UploadProgressToast,props:{close:()=>(progressToast.isVisible=false),},});const addFile=(file)=>{progressToast.files[file.id]=file;progressToast.isVisible=true;return progressToast.files[file.id];};const deleteFile=(fileId)=>{delete progressToast.files[fileId];if(!Object.keys(progressToast.files).length){progressToast.isVisible=false;}};const convertWebpToJpeg=async(dataURL,name,attachmentId)=>{const image=document.createElement("img");image.src=`data:image/webp;base64,${dataURL.split(",")[1]}`;await new Promise((res,rej)=>{image.onload=res;image.onerror=rej;});const canvas=document.createElement("canvas");canvas.width=image.width;canvas.height=image.height;const ctx=canvas.getContext("2d");ctx.fillStyle="white";ctx.fillRect(0,0,canvas.width,canvas.height);ctx.drawImage(image,0,0);const altDataURL=canvas.toDataURL("image/jpeg",0.75);await rpc("/web_editor/attachment/add_data",{name:name.replace(/\.webp$/,".jpg"),data:altDataURL.split(",")[1],res_id:attachmentId,res_model:"ir.attachment",is_image:true,width:0,quality:0,});};return{get progressToast(){return progressToast;},get fileId(){return fileId;},addFile,deleteFile,incrementId(){fileId++;},uploadUrl:async(url,{resModel,resId},onUploaded)=>{const attachment=await rpc("/html_editor/attachment/add_url",{url,res_model:resModel,res_id:resId,});await onUploaded(attachment);},uploadFiles:async(files,{resModel,resId,isImage},onUploaded,setAbortCallback)=>{const sortedFiles=Array.from(files).sort((a,b)=>a.size-b.size);const controller=new AbortController();const{signal}=controller;let currentXHR=null;let addAttachmentRpc=null;setAbortCallback?.(()=>{controller.abort();addAttachmentRpc?.abort?.();currentXHR?.abort?.();});for(const file of sortedFiles){if(signal.aborted){return;}
let fileSize=file.size;if(!checkFileSize(fileSize,notification)){return null;}
if(!fileSize){fileSize="";}else{fileSize=humanNumber(fileSize)+"B";}
const id=++fileId;file.progressToastId=id;addFile({id,name:file.name,size:fileSize,});}
for(const sortedFile of sortedFiles){if(signal.aborted){break;}
const file=progressToast.files[sortedFile.progressToastId];let dataURL;try{dataURL=await getDataURLFromFile(sortedFile);if(signal.aborted){break;}}catch{deleteFile(file.id);env.services.notification.add(_t('Could not load the file "%s".',sortedFile.name),{type:"danger"});continue;}
currentXHR=new XMLHttpRequest();addAttachmentRpc=null;const onProgress=(ev)=>{if(ev.lengthComputable){file.progress=(ev.loaded/ev.total)*100;}};const onLoad=()=>(file.progress=100);currentXHR.upload.addEventListener("progress",onProgress);currentXHR.upload.addEventListener("load",onLoad);try{addAttachmentRpc=rpc("/html_editor/attachment/add_data",{name:file.name,data:dataURL.split(",")[1],res_id:resId,res_model:resModel,is_image:!!isImage,width:0,quality:0,},{xhr:currentXHR});const attachment=await addAttachmentRpc;if(signal.aborted){break;}
if(attachment.error){file.hasError=true;file.errorMessage=attachment.error;}else{if(attachment.mimetype==="image/webp"){try{await convertWebpToJpeg(dataURL,file.name,attachment.id);}catch(convErr){console.warn("[uploadService] webp conversion failed:",convErr);}}
file.uploaded=true;await onUploaded(attachment);}}catch(err){if(signal.aborted){break;}
file.hasError=true;console.error("Upload error:",err);throw err;}finally{currentXHR.upload.removeEventListener("progress",onProgress);currentXHR.upload.removeEventListener("load",onLoad);const message_autoclose_delay=file.hasError?AUTOCLOSE_DELAY_LONG:AUTOCLOSE_DELAY;setTimeout(()=>deleteFile(file.id),message_autoclose_delay);dataURL=null;}}
currentXHR=null;addAttachmentRpc=null;},};},};registry.category("services").add("upload",uploadService);return __exports;});;
/* /html_editor/static/src/main/media/media_dialog/video_selector.js */
odoo.define('@html_editor/main/media/media_dialog/video_selector',['@web/core/l10n/translation','@web/core/network/rpc','@web/core/utils/hooks','@web/core/utils/timing','@odoo/owl','@html_editor/components/switch/switch'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"html_editor",...args);const{rpc}=require("@web/core/network/rpc");const{useAutofocus,useService}=require("@web/core/utils/hooks");const{debounce}=require("@web/core/utils/timing");const{Component,useState,useRef,onMounted,status}=require("@odoo/owl");const{Switch}=require("@html_editor/components/switch/switch");class VideoOption extends Component{static template="html_editor.VideoOption";static components={Switch,};static props={description:{type:String,optional:true},label:{type:String,optional:true},onChangeOption:Function,onChangeStartAt:Function,value:{type:String,optional:true},name:{type:String,optional:true},};get showStartAtInput(){return this.props.name==="start_from";}}
class VideoIframe extends Component{static template="html_editor.VideoIframe";static props={src:{type:String},};}
const VideoSelector=__exports.VideoSelector=class VideoSelector extends Component{static mediaSpecificClasses=["media_iframe_video"];static mediaSpecificStyles=[];static mediaExtraClasses=[];static tagNames=["IFRAME","DIV"];static template="html_editor.VideoSelector";static components={VideoIframe,VideoOption,};static props={selectMedia:Function,errorMessages:Function,vimeoPreviewIds:{type:Array,optional:true},isForBgVideo:{type:Boolean,optional:true},media:{validate:(p)=>p.nodeType===Node.ELEMENT_NODE,optional:true},"*":true,};static defaultProps={vimeoPreviewIds:[],isForBgVideo:false,};setup(){this.http=useService("http");this.state=useState({options:[],src:"",urlInput:"",platform:null,vimeoPreviews:[],errorMessage:"",});this.PLATFORMS={youtube:"youtube",dailymotion:"dailymotion",vimeo:"vimeo",};this.platformParams={youtube:"start",dailymotion:"startTime",vimeo:"#t=",};this.OPTIONS={autoplay:{label:_t("Autoplay"),description:_t("Videos are muted when autoplay is enabled"),platforms:[this.PLATFORMS.youtube,this.PLATFORMS.vimeo,],urlParameter:()=>"autoplay=1",},loop:{label:_t("Loop"),platforms:[this.PLATFORMS.youtube,this.PLATFORMS.vimeo],urlParameter:()=>"loop=1",},hide_controls:{label:_t("Hide player controls"),platforms:[this.PLATFORMS.youtube,this.PLATFORMS.vimeo,],urlParameter:()=>"controls=0",},hide_fullscreen:{label:_t("Hide fullscreen button"),platforms:[this.PLATFORMS.youtube],urlParameter:()=>"fs=0",isHidden:()=>this.state.options.filter((option)=>option.id==="hide_controls")[0].value,},start_from:{label:_t("Start at"),platforms:[this.PLATFORMS.youtube,this.PLATFORMS.vimeo,this.PLATFORMS.dailymotion,],urlParameter:()=>this.platformParams[this.state.platform],},};this.urlInputRef=useRef("url-input");onMounted(async()=>{if(this.props.media){const src=this.props.media.dataset.oeExpression||this.props.media.dataset.src||(this.props.media.tagName==="IFRAME"&&this.props.media.getAttribute("src"))||"";if(src){this.state.urlInput=src;if(!src.startsWith("https:")&&!src.startsWith("http:")){this.state.urlInput="https:"+this.state.urlInput;}
await this.syncOptionsWithUrl();if(status(this)==="destroyed"){return;}}}
await this.prepareVimeoPreviews();});useAutofocus();this.onChangeUrl=debounce(()=>this.syncOptionsWithUrl(),500);this.onChangeStartAt=debounce(async(ev,optionId)=>{const start_from=this.convertTimestampToSeconds(ev.target.value);this.state.options=this.state.options.map((option)=>{if(option.id===optionId){return{...option,value:start_from==="0"?"00:00":start_from};}
return option;});await this.updateVideo();this.state.urlInput="https:"+this.state.src;},1000);}
get shownOptions(){if(this.props.isForBgVideo){return[];}
return this.state.options.filter((option)=>!this.OPTIONS[option.id].isHidden||!this.OPTIONS[option.id].isHidden());}
get value(){if(this.option.id==="start_from"&&this.option.value!=="00:00"){return this.convertSecondsToTimestamp(this.option.value);}
return this.option.value;}
async onChangeOption(optionId){this.state.options=this.state.options.map((option)=>{if(option.id===optionId){return{...option,value:!option.value&&"00:00"};}
return option;});await this.updateVideo();this.state.urlInput="https:"+this.state.src;}
async onClickSuggestion(src){this.state.urlInput=src;await this.updateVideo();}
async updateVideo(){if(!this.state.urlInput){this.state.src="";this.state.urlInput="";this.state.options=[];this.state.platform=null;this.state.errorMessage="";this.props.selectMedia({});return;}
const embedMatch=this.state.urlInput.match(/(src|href)=["']?([^"']+)?/);if(embedMatch&&embedMatch[2].length>0&&embedMatch[2].indexOf("instagram")){embedMatch[1]=embedMatch[2];}
const url=embedMatch?embedMatch[1]:this.state.urlInput;const options={};if(this.props.isForBgVideo&&URL.canParse(url)){const parsedUrl=new URL(url);const urlParams=parsedUrl.searchParams;const startFrom=urlParams.get("start")||urlParams.get("startTime")||urlParams.get("t");Object.keys(this.OPTIONS).forEach((key)=>{options[key]=key==="start_from"?startFrom:true;});}else{for(const option of this.shownOptions){options[option.id]=option.value;}}
const{embed_url:src,video_id:videoId,params,platform,}=await this._getVideoURLData(url,options);if(!src){this.state.errorMessage=_t("The provided url is not valid");}else if(!platform){this.state.errorMessage=_t("The provided url does not reference any supported video");}else{this.state.errorMessage="";}
this.props.errorMessages(this.state.errorMessage);const newOptions=[];if(platform&&platform!==this.state.platform){Object.keys(this.OPTIONS).forEach((key)=>{if(this.OPTIONS[key].platforms.includes(platform)){const{label,description}=this.OPTIONS[key];newOptions.push({id:key,label,description});}});}
this.state.src=src;this.props.selectMedia({id:src,src,platform,videoId,params,});if(platform!==this.state.platform){this.state.platform=platform;this.state.options=newOptions;}}
async _getVideoURLData(url,options){return await rpc("/html_editor/video_url/data",{video_url:url,...options,});}
static createElements(selectedMedia){return selectedMedia.map((video)=>{const div=document.createElement("div");div.dataset.oeExpression=video.src;div.innerHTML='<div class="css_editable_mode_display"></div>'+'<div class="media_iframe_video_size" contenteditable="false"></div>'+'<iframe frameborder="0" contenteditable="false" allowfullscreen="allowfullscreen"></iframe>';div.querySelector("iframe").src=video.src;return div;});}
async prepareVimeoPreviews(){await Promise.all(this.props.vimeoPreviewIds.map(async(videoId)=>{try{const{thumbnail_url:thumbnailSrc}=await this.http.get(`https://vimeo.com/api/oembed.json?url=http%3A//vimeo.com/${encodeURIComponent(
videoId
)}`);this.state.vimeoPreviews.push({id:videoId,thumbnailSrc,src:`https://player.vimeo.com/video/${encodeURIComponent(videoId)}`,});}catch(err){console.warn(`Could not get video #${videoId} from vimeo: ${err}`);}}));}
async syncOptionsWithUrl(){await this.updateVideo();if(!URL.canParse(this.state.urlInput)){return;}
const parsedUrl=new URL(this.state.urlInput);const urlParams=parsedUrl.searchParams;this.state.options=this.state.options.map((option)=>{const urlParameter=this.OPTIONS[option.id].urlParameter();let value="";switch(urlParameter){case"#t=":value=this.parseTimeToSeconds(this.state.urlInput.split("#t=")[1]);break;case"start":value=urlParams.get("start")||urlParams.get("t");break;case"startTime":value=urlParams.get("startTime")||urlParams.get("start");break;default:value=this.state.urlInput.includes(urlParameter);}
if(option.id==="start_from"&&value==="0"){return{...option,value:"00:00"};}
return{...option,value:value||""};});await this.updateVideo();}
convertTimestampToSeconds(timestamp){timestamp=timestamp.trim();const timeRegex=/^(?:(\d+):)?([0-5]?\d):([0-5]?\d)$/;if(timeRegex.test(timestamp)){return(timestamp=timestamp.split(":").reduce((acc,time)=>acc*60+ +time,0)+"");}
if(isNaN(timestamp)){return"0";}
return timestamp;}
convertSecondsToTimestamp(value){if(!value){return"";}
const match=value.match(/^\d+s?$/);if(!match){return"";}
const totalSeconds=parseInt(match[0],10);if(!Number.isFinite(totalSeconds)||totalSeconds<=0){return value;}
const hours=Math.floor(totalSeconds/3600);const minutes=Math.floor((totalSeconds%3600)/60);const seconds=totalSeconds%60;const pad=(n)=>String(n).padStart(2,"0");if(hours>0){return`${hours}:${pad(minutes)}:${pad(seconds)}`;}
return`${minutes}:${pad(seconds)}`;}
parseTimeToSeconds(value){const match=value?.match(/^(?:(\d+)m(\d+)s|(\d+)m|(\d+)s|(\d+))$/);if(!match){return value;}
let minutes=match[1]||match[3];minutes=parseInt(minutes||"0",10);let seconds=match[2]||match[4]||match[5];seconds=parseInt(seconds||"0",10);return String(minutes*60+seconds);}}
return __exports;});;
/* /web_unsplash/static/src/media_dialog/image_selector_patch.js */
odoo.define('@web_unsplash/media_dialog/image_selector_patch',['@web/core/l10n/translation','@web/core/utils/patch','@web/core/utils/concurrency','@web/core/network/rpc','@web/core/utils/hooks','@html_editor/main/media/media_dialog/image_selector','@web_unsplash/unsplash_error/unsplash_error','@odoo/owl'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web_unsplash",...args);const{patch}=require("@web/core/utils/patch");const{KeepLast}=require("@web/core/utils/concurrency");const{rpc}=require("@web/core/network/rpc");const{useService}=require("@web/core/utils/hooks");const{ImageSelector}=require("@html_editor/main/media/media_dialog/image_selector");const{UnsplashError}=require("@web_unsplash/unsplash_error/unsplash_error");const{useState}=require("@odoo/owl");patch(ImageSelector.prototype,{setup(){super.setup();this.unsplash=useService("unsplash");this.keepLastUnsplash=new KeepLast();this.unsplashState=useState({unsplashRecords:[],isFetchingUnsplash:false,isMaxed:false,unsplashError:null,useUnsplash:true,});this.NUMBER_OF_RECORDS_TO_DISPLAY=30;this.errorMessages={key_not_found:{title:_t("Setup Unsplash to access royalty free photos."),subtitle:"",},401:{title:_t("Unauthorized Key"),subtitle:_t("Please check your Unsplash access key and application ID."),},403:{title:_t("Search is temporarily unavailable"),subtitle:_t("The max number of searches is exceeded. Please retry in an hour or extend to a better account."),},};},get canLoadMore(){if(this.state.searchService==="all"){return(super.canLoadMore||(this.state.needle&&!this.unsplashState.isMaxed&&!this.unsplashState.unsplashError));}else if(this.state.searchService==="unsplash"){return(this.state.needle&&!this.unsplashState.isMaxed&&!this.unsplashState.unsplashError);}
return super.canLoadMore;},get hasContent(){if(this.state.searchService==="all"){return super.hasContent||!!this.unsplashState.unsplashRecords.length;}else if(this.state.searchService==="unsplash"){return!!this.unsplashState.unsplashRecords.length;}
return super.hasContent;},get errorTitle(){if(this.errorMessages[this.unsplashState.unsplashError]){return this.errorMessages[this.unsplashState.unsplashError].title;}
return _t("Something went wrong");},get errorSubtitle(){if(this.errorMessages[this.unsplashState.unsplashError]){return this.errorMessages[this.unsplashState.unsplashError].subtitle;}
return _t("Please check your internet connection or contact administrator.");},get selectedRecordIds(){return this.props.selectedMedia[this.props.id].filter((media)=>media.mediaType==="unsplashRecord").map(({id})=>id);},get isFetching(){return super.isFetching||this.unsplashState.isFetchingUnsplash;},get combinedRecords(){function alternate(a,b){return[a.map((v,i)=>(i<b.length?[v,b[i]]:v)),b.slice(a.length)].flat(2);}
return alternate(this.unsplashState.unsplashRecords,this.state.libraryMedia);},get allAttachments(){return[...super.allAttachments,...this.unsplashState.unsplashRecords];},async fetchUnsplashRecords(offset){if(!this.state.needle){return{records:[],isMaxed:false};}
this.unsplashState.isFetchingUnsplash=true;try{const{isMaxed,images}=await this.unsplash.getImages(this.state.needle,offset,this.NUMBER_OF_RECORDS_TO_DISPLAY,this.props.orientation);this.unsplashState.isFetchingUnsplash=false;this.unsplashState.unsplashError=false;const existingIds=new Set(this.unsplashState.unsplashRecords.map(r=>r.id));const newImages=images.filter(record=>{if(existingIds.has(record.id)){return false;}
existingIds.add(record.id);return true;});const records=newImages.map((record)=>{const url=new URL(record.urls.regular);url.searchParams.set("h",2*this.MIN_ROW_HEIGHT);url.searchParams.delete("w");return Object.assign({},record,{url:url.toString(),mediaType:"unsplashRecord",});});return{isMaxed,records};}catch(e){this.unsplashState.isFetchingUnsplash=false;if(e==="no_access"){this.unsplashState.useUnsplash=false;}else{this.unsplashState.unsplashError=e;}
return{records:[],isMaxed:true};}},async loadMore(...args){await super.loadMore(...args);return this.keepLastUnsplash.add(this.fetchUnsplashRecords(this.unsplashState.unsplashRecords.length)).then(({records,isMaxed})=>{this.unsplashState.unsplashRecords.push(...records);this.unsplashState.isMaxed=isMaxed;});},async search(...args){await super.search(...args);await this.searchUnsplash();},async searchUnsplash(){if(!this.state.needle){this.unsplashState.unsplashError=false;this.unsplashState.unsplashRecords=[];this.unsplashState.isMaxed=false;}
return this.keepLastUnsplash.add(this.fetchUnsplashRecords(0)).then(({records,isMaxed})=>{this.unsplashState.unsplashRecords=records;this.unsplashState.isMaxed=isMaxed;});},async onClickRecord(media){this.props.selectMedia({...media,mediaType:"unsplashRecord",query:this.state.needle});if(!this.props.multiSelect){await this.props.save();}},async submitCredentials(key,appId){this.unsplashState.unsplashError=null;await rpc("/web_unsplash/save_unsplash",{key,appId});await this.searchUnsplash();},});ImageSelector.components={...ImageSelector.components,UnsplashError,};return __exports;});;
/* /web_unsplash/static/src/media_dialog/media_dialog_patch.js */
odoo.define('@web_unsplash/media_dialog/media_dialog_patch',['@html_editor/main/media/media_dialog/media_dialog','@web/core/utils/patch','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{MediaDialog,TABS}=require("@html_editor/main/media/media_dialog/media_dialog");const{patch}=require("@web/core/utils/patch");const{useService}=require("@web/core/utils/hooks");patch(MediaDialog.prototype,{setup(){super.setup();this.unsplashService=useService("unsplash");},async save(){const selectedImages=this.selectedMedia[TABS.IMAGES.id];if(selectedImages){const unsplashRecords=selectedImages.filter((media)=>media.mediaType==="unsplashRecord");if(unsplashRecords.length){await this.unsplashService.uploadUnsplashRecords(unsplashRecords,{resModel:this.props.resModel,resId:this.props.resId},(attachments)=>{this.selectedMedia[TABS.IMAGES.id]=this.selectedMedia[TABS.IMAGES.id].filter((media)=>media.mediaType!=="unsplashRecord");this.selectedMedia[TABS.IMAGES.id]=this.selectedMedia[TABS.IMAGES.id].concat(attachments.map((attachment)=>({...attachment,mediaType:"attachment",})));});}}
return super.save(...arguments);},});return __exports;});;
/* /web_unsplash/static/src/unsplash_credentials/unsplash_credentials.js */
odoo.define('@web_unsplash/unsplash_credentials/unsplash_credentials',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component,useState}=require("@odoo/owl");const UnsplashCredentials=__exports.UnsplashCredentials=class UnsplashCredentials extends Component{static template="web_unsplash.UnsplashCredentials";static props={submitCredentials:Function,hasCredentialsError:Boolean,};setup(){this.state=useState({key:"",appId:"",hasKeyError:this.props.hasCredentialsError,hasAppIdError:this.props.hasCredentialsError,});}
submitCredentials(){if(this.state.key===""){this.state.hasKeyError=true;}else if(this.state.appId===""){this.state.hasAppIdError=true;}else{this.props.submitCredentials(this.state.key,this.state.appId);}}}
return __exports;});;
/* /web_unsplash/static/src/unsplash_error/unsplash_error.js */
odoo.define('@web_unsplash/unsplash_error/unsplash_error',['@odoo/owl','@web_unsplash/unsplash_credentials/unsplash_credentials'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{UnsplashCredentials}=require("@web_unsplash/unsplash_credentials/unsplash_credentials");const UnsplashError=__exports.UnsplashError=class UnsplashError extends Component{static template="web_unsplash.UnsplashError";static components={UnsplashCredentials,};static props={title:String,subtitle:String,showCredentials:Boolean,submitCredentials:{type:Function,optional:true},hasCredentialsError:{type:Boolean,optional:true},};}
return __exports;});;
/* /web_unsplash/static/src/unsplash_service.js */
odoo.define('@web_unsplash/unsplash_service',['@web/core/network/rpc','@web/core/registry','@web/core/l10n/translation','@html_editor/main/media/media_dialog/upload_progress_toast/upload_service'],function(require){'use strict';let __exports={};const{rpc}=require("@web/core/network/rpc");const{registry}=require("@web/core/registry");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web_unsplash",...args);const{AUTOCLOSE_DELAY}=require("@html_editor/main/media/media_dialog/upload_progress_toast/upload_service");const unsplashService=__exports.unsplashService={dependencies:["upload"],async start(env,{upload}){const _cache={};return{async uploadUnsplashRecords(records,{resModel,resId},onUploaded){upload.incrementId();const file=upload.addFile({id:upload.fileId,name:records.length>1?_t("Uploading %(count)s '%(query)s' images.",{count:records.length,query:records[0].query,}):_t("Uploading '%s' image.",records[0].query),});try{const urls={};for(const record of records){const _1920Url=new URL(record.urls.regular);_1920Url.searchParams.set("w","1920");urls[record.id]={url:_1920Url.href,download_url:record.links.download_location,description:record.alt_description,};}
const xhr=new XMLHttpRequest();xhr.upload.addEventListener("progress",(ev)=>{const rpcComplete=(ev.loaded/ev.total)*100;file.progress=rpcComplete;});xhr.upload.addEventListener("load",function(){file.progress=100;});const attachments=await rpc("/web_unsplash/attachment/add",{res_id:resId,res_model:resModel,unsplashurls:urls,query:records[0].query,},{xhr});if(attachments.error){file.hasError=true;file.errorMessage=attachments.error;}else{file.uploaded=true;await onUploaded(attachments);}
setTimeout(()=>upload.deleteFile(file.id),AUTOCLOSE_DELAY);}catch(error){file.hasError=true;setTimeout(()=>upload.deleteFile(file.id),AUTOCLOSE_DELAY);throw error;}},async getImages(query,offset=0,pageSize=30,orientation){const from=offset;const to=offset+pageSize;let cachedData=orientation?_cache[query+orientation]:_cache[query];if(cachedData&&(cachedData.images.length>=to||(cachedData.totalImages!==0&&cachedData.totalImages<to))){return{images:cachedData.images.slice(from,to),isMaxed:to>cachedData.totalImages,};}
cachedData=await this._fetchImages(query,orientation);return{images:cachedData.images.slice(from,to),isMaxed:to>cachedData.totalImages,};},async _fetchImages(query,orientation){const key=orientation?query+orientation:query;if(!_cache[key]){_cache[key]={images:[],maxPages:0,totalImages:0,pageCached:0,};}
const cachedData=_cache[key];const payload={query:query,page:cachedData.pageCached+1,per_page:30,};if(orientation){payload.orientation=orientation;}
const result=await rpc("/web_unsplash/fetch_images",payload);if(result.error){return Promise.reject(result.error);}
cachedData.pageCached++;cachedData.images.push(...result.results);cachedData.maxPages=result.total_pages;cachedData.totalImages=result.total;return cachedData;},};},};registry.category("services").add("unsplash",unsplashService);return __exports;});;
/* /html_editor/static/src/components/html_viewer/html_viewer.js */
odoo.define('@html_editor/components/html_viewer/html_viewer',['@odoo/owl','@web/core/assets','@web/core/utils/functions','@html_editor/utils/clipboard','@html_editor/utils/sanitize','@html_editor/html_migrations/html_upgrade_manager','@html_editor/others/embedded_components/core/table_of_content/table_of_content_manager','@html_editor/utils/url','@web/core/browser/browser'],function(require){'use strict';let __exports={};const{Component,markup,onMounted,onWillStart,onWillUnmount,onWillUpdateProps,useEffect,useRef,useState,}=require("@odoo/owl");const{getBundle}=require("@web/core/assets");const{memoize}=require("@web/core/utils/functions");const{fillHtmlTransferData}=require("@html_editor/utils/clipboard");const{fixInvalidHTML,instanceofMarkup}=require("@html_editor/utils/sanitize");const{HtmlUpgradeManager}=require("@html_editor/html_migrations/html_upgrade_manager");const{TableOfContentManager}=require("@html_editor/others/embedded_components/core/table_of_content/table_of_content_manager");const{scrollAndHighlightHeading}=require("@html_editor/utils/url");const{browser}=require("@web/core/browser/browser");const HtmlViewer=__exports.HtmlViewer=class HtmlViewer extends Component{static template="html_editor.HtmlViewer";static props={config:{type:Object},migrateHTML:{type:Boolean,optional:true},};static defaultProps={migrateHTML:true,};setup(){this._cleanups=[];this.htmlUpgradeManager=new HtmlUpgradeManager();this.iframeRef=useRef("iframe");this.state=useState({iframeVisible:false,value:this.formatValue(this.props.config.value),});this.components=new Set();onWillUpdateProps((newProps)=>{const newValue=this.formatValue(newProps.config.value);if(newValue.toString()!==this.state.value.toString()){this.state.value=this.formatValue(newProps.config.value);if(this.props.config.embeddedComponents){this.destroyComponents();}
if(this.showIframe){this.updateIframeContent(this.state.value);}}});onWillUnmount(()=>{this.destroyComponents();});if(this.showIframe){onMounted(()=>{const onLoadIframe=()=>this.onLoadIframe(this.state.value);this.iframeRef.el.addEventListener("load",onLoadIframe,{once:true});this.iframeRef.el.after(this.iframeRef.el);});}else{this.readonlyElementRef=useRef("readonlyContent");useEffect(()=>{this.processReadonlyContent(this.readonlyElementRef.el);},()=>[this.props.config.value.toString(),this.readonlyElementRef?.el]);}
onMounted(()=>{scrollAndHighlightHeading(this.readonlyElementRef?.el||this.iframeRef?.el);});if(this.props.config.cssAssetId){onWillStart(async()=>{this.cssAsset=await getBundle(this.props.config.cssAssetId);});}
if(this.props.config.embeddedComponents){this.embeddedComponents=memoize((embeddedComponents=[])=>{const result={};for(const embedding of embeddedComponents){result[embedding.name]=embedding;}
return result;});useEffect(()=>{if(this.readonlyElementRef?.el){this.mountComponents();}},()=>[this.props.config.value.toString(),this.readonlyElementRef?.el]);this.tocManager=new TableOfContentManager(this.readonlyElementRef);}}
addDomListener(target,eventName,fn,capture=false){const handler=(ev)=>{fn?.call(this,ev);};target.addEventListener(eventName,handler,capture);this._cleanups.push(()=>target.removeEventListener(eventName,handler,capture));}
get showIframe(){return this.props.config.hasFullHtml||this.props.config.cssAssetId;}
formatValue(value){let newVal=fixInvalidHTML(value);if(this.props.migrateHTML){newVal=this.htmlUpgradeManager.processForUpgrade(newVal,{containsComplexHTML:this.props.config.hasFullHtml,env:this.env,});}
if(instanceofMarkup(value)){return markup(newVal);}
return newVal;}
processReadonlyContent(container){this.retargetLinks(container);this.applyAccessibilityAttributes(container);this.addDomListener(container,"copy",this.onCopy);}
onCopy(ev){ev.preventDefault();const selection=ev.target.ownerDocument.defaultView.getSelection();const clonedContents=selection.getRangeAt(0).cloneContents();fillHtmlTransferData(ev,"clipboardData",clonedContents,{textContent:selection.toString(),});}
applyAccessibilityAttributes(container){for(const el of container.querySelectorAll("[data-oe-role]")){el.setAttribute("role",el.dataset.oeRole);}
for(const el of container.querySelectorAll("[data-oe-aria-label]")){el.setAttribute("aria-label",el.dataset.oeAriaLabel);}}
retargetLinks(container){const isInsideIframe=container.ownerDocument!==document;const retargetSelector=isInsideIframe?"a":`a:not([href^="${browser.location.origin}"]):not([href^="/"])`;for(const link of container.querySelectorAll(retargetSelector)){this.retargetLink(link);}}
retargetLink(link){link.setAttribute("target","_blank");link.setAttribute("rel","noreferrer");}
updateIframeContent(content){const contentWindow=this.iframeRef.el.contentWindow;const iframeTarget=this.props.config.hasFullHtml?contentWindow.document.documentElement:contentWindow.document.querySelector("#iframe_target");iframeTarget.innerHTML=content;this.processReadonlyContent(iframeTarget);}
onLoadIframe(value){const contentWindow=this.iframeRef.el.contentWindow;if(!this.props.config.hasFullHtml){contentWindow.document.open("text/html","replace").write(`<!DOCTYPE html><html>
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
</head>
<body class="o_in_iframe o_readonly" style="overflow: hidden;">
<div id="iframe_target"></div>
</body>
</html>`);}
if(this.cssAsset){for(const cssLib of this.cssAsset.cssLibs){const link=contentWindow.document.createElement("link");link.setAttribute("type","text/css");link.setAttribute("rel","stylesheet");link.setAttribute("href",cssLib);contentWindow.document.head.append(link);}}
this.updateIframeContent(this.state.value);this.state.iframeVisible=true;}
destroyComponent({root,host}){const{getEditableDescendants}=this.getEmbedding(host);const editableDescendants=getEditableDescendants?.(host)||{};root.destroy();this.components.delete(arguments[0]);host.append(...Object.values(editableDescendants));}
destroyComponents(){for(const cleanup of this._cleanups){cleanup();}
for(const info of[...this.components]){this.destroyComponent(info);}}
forEachEmbeddedComponentHost(elem,callback){const selector=`[data-embedded]`;const targets=[...elem.querySelectorAll(selector)];if(elem.matches(selector)){targets.unshift(elem);}
for(const host of targets){const embedding=this.getEmbedding(host);if(!embedding){continue;}
callback(host,embedding);}}
getEmbedding(host){return this.embeddedComponents(this.props.config.embeddedComponents)[host.dataset.embedded];}
setupNewComponent({name,env,props}){if(name==="tableOfContent"){Object.assign(props,{manager:this.tocManager,});}}
mountComponent(host,{Component,getEditableDescendants,getProps,name}){const props=getProps?.(host)||{};const env=Object.create(this.env);if(getEditableDescendants){env.getEditableDescendants=getEditableDescendants;}
this.setupNewComponent({name,env,props,});const root=this.__owl__.app.createRoot(Component,{props,env,});const promise=root.mount(host);promise.catch();const fiber=root.node.fiber;const fiberComplete=fiber.complete;fiber.complete=function(){host.replaceChildren();fiberComplete.call(this);};const info={root,host,};this.components.add(info);}
mountComponents(){this.forEachEmbeddedComponentHost(this.readonlyElementRef.el,(host,embedding)=>{this.mountComponent(host,embedding);});}}
return __exports;});;
/* /html_editor/static/src/local_overlay_container.js */
odoo.define('@html_editor/local_overlay_container',['@odoo/owl','@web/core/main_components_container','@web/core/utils/hooks','@web/core/registry','@web/core/registry_hook'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{MainComponentsContainer}=require("@web/core/main_components_container");const{useForwardRefToParent}=require("@web/core/utils/hooks");const{registry}=require("@web/core/registry");const{useRegistry}=require("@web/core/registry_hook");const LocalOverlayContainer=__exports.LocalOverlayContainer=class LocalOverlayContainer extends MainComponentsContainer{static template="html_editor.LocalOverlayContainer";static props={localOverlay:{type:Function,optional:true},identifier:{type:String,optional:true},};static defaultProps={identifier:"overlay_components",};setup(){const overlayComponents=registry.category(this.props.identifier);if(!overlayComponents.validationSchema){overlayComponents.addValidation({Component:{validate:(c)=>c.prototype instanceof Component},props:{type:Object,optional:true},});}
this.Components=useRegistry(overlayComponents);useForwardRefToParent("localOverlay");}}
return __exports;});;
/* /html_editor/static/src/position_hook.js */
odoo.define('@html_editor/position_hook',['@html_editor/utils/dom_traversal','@web/core/utils/timing','@web/core/utils/scrolling','@odoo/owl'],function(require){'use strict';let __exports={};const{ancestors}=require("@html_editor/utils/dom_traversal");const{throttleForAnimation}=require("@web/core/utils/timing");const{couldBeScrollableX,couldBeScrollableY}=require("@web/core/utils/scrolling");const{useComponent,useEffect}=require("@odoo/owl");__exports.usePositionHook=usePositionHook;function usePositionHook(containerRef,document,callback){const comp=useComponent();const onLayoutGeometryChange=throttleForAnimation(callback.bind(comp));const resizeObserver=new ResizeObserver(onLayoutGeometryChange);const cleanups=[];const addDomListener=(target,eventName,capture)=>{target.addEventListener(eventName,onLayoutGeometryChange,capture);cleanups.push(()=>target.removeEventListener(eventName,onLayoutGeometryChange,capture));};useEffect(()=>{if(containerRef.el){resizeObserver.observe(document.body);resizeObserver.observe(containerRef.el);addDomListener(window,"resize");if(document.defaultView!==window){addDomListener(document.defaultView,"resize");}
addDomListener(document,"scroll");const scrollableElements=[containerRef.el,...ancestors(containerRef.el)].filter((node)=>couldBeScrollableX(node)||couldBeScrollableY(node));for(const scrollableElement of scrollableElements){addDomListener(scrollableElement,"scroll");resizeObserver.observe(scrollableElement);}}
return()=>{resizeObserver.disconnect();for(const cleanup of cleanups.toReversed()){cleanup();cleanups.pop();}};},()=>[containerRef.el]);}
return __exports;});;
/* /html_editor/static/src/html_migrations/html_migrations_utils.js */
odoo.define('@html_editor/html_migrations/html_migrations_utils',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");__exports.htmlEditorVersions=htmlEditorVersions;function htmlEditorVersions(){return Object.keys(registry.category("html_editor_upgrade").subRegistries).sort(compareVersions);}
const VERSION_SELECTOR=__exports.VERSION_SELECTOR="[data-oe-version]";__exports.stripVersion=stripVersion;function stripVersion(element){element.querySelectorAll(VERSION_SELECTOR).forEach((el)=>{delete el.dataset.oeVersion;});}
__exports.compareVersions=compareVersions;function compareVersions(version1,version2){version1=version1.split(".").map((v)=>parseInt(v));version2=version2.split(".").map((v)=>parseInt(v));if(version1[0]<version2[0]||(version1[0]===version2[0]&&version1[1]<version2[1])){return-1;}else if(version1[0]===version2[0]&&version1[1]===version2[1]){return 0;}else{return 1;}}
return __exports;});;
/* /html_editor/static/src/html_migrations/html_upgrade_manager.js */
odoo.define('@html_editor/html_migrations/html_upgrade_manager',['@odoo/owl','@html_editor/html_migrations/html_migrations_utils','@web/core/registry','@html_editor/utils/sanitize'],function(require){'use strict';let __exports={};const{markup}=require("@odoo/owl");const{compareVersions,VERSION_SELECTOR,htmlEditorVersions,}=require("@html_editor/html_migrations/html_migrations_utils");const{registry}=require("@web/core/registry");const{fixInvalidHTML}=require("@html_editor/utils/sanitize");const HtmlUpgradeManager=__exports.HtmlUpgradeManager=class HtmlUpgradeManager{constructor(){this.upgradeRegistry=registry.category("html_editor_upgrade");this.parser=new DOMParser();this.originalValue=undefined;this.upgradedValue=undefined;this.element=undefined;this.env={};}
get value(){return this.upgradedValue;}
processForUpgrade(value,{containsComplexHTML,env}={}){this.env=env||{};this.containsComplexHTML=containsComplexHTML;const strValue=value.toString();if(strValue===this.originalValue?.toString()||strValue===this.upgradedValue?.toString()){return this.value;}
this.originalValue=value;this.upgradedValue=value;this.element=this.parser.parseFromString(fixInvalidHTML(value),"text/html")[this.containsComplexHTML?"documentElement":"body"];const versionNode=this.element.querySelector(VERSION_SELECTOR);const version=versionNode?.dataset.oeVersion||"0.0";const VERSIONS=htmlEditorVersions();const currentVersion=VERSIONS.at(-1);if(!currentVersion||version===currentVersion){return this.value;}
try{const upgradeSequence=VERSIONS.filter((subVersion)=>compareVersions(subVersion,version)>0);this.upgradedValue=this.upgrade(upgradeSequence);}catch{}
return this.value;}
upgrade(upgradeSequence){for(const version of upgradeSequence){const modules=this.upgradeRegistry.category(version);for(const[key,module]of modules.getEntries()){const migrate=odoo.loader.modules.get(module).migrate;if(!migrate){console.error(`A "${key}" migrate function could not be found at "${module}" or it did not load.`);}
migrate(this.element,this.env);}}
return markup(this.element[this.containsComplexHTML?"outerHTML":"innerHTML"]);}}
return __exports;});;
/* /html_editor/static/src/html_migrations/manifest.js */
odoo.define('@html_editor/html_migrations/manifest',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const html_upgrade=registry.category("html_editor_upgrade");html_upgrade.category("1.0");html_upgrade.category("1.1").add("html_editor","@html_editor/html_migrations/migration-1.1");html_upgrade.category("1.2").add("html_editor","@html_editor/html_migrations/migration-1.2");html_upgrade.category("2.0");return __exports;});;
/* /html_editor/static/src/html_migrations/migration-1.1.js */
odoo.define('@html_editor/html_migrations/migration-1.1',[],function(require){'use strict';let __exports={};__exports.migrate=migrate;function migrate(container){const excalidrawContainers=container.querySelectorAll("[data-embedded='draw']");for(const excalidrawContainer of excalidrawContainers){const source=JSON.parse(excalidrawContainer.dataset.embeddedProps).source;const newParagraph=document.createElement("P");const anchor=document.createElement("A");newParagraph.append(anchor);anchor.append(document.createTextNode(source));anchor.href=source;excalidrawContainer.after(newParagraph);excalidrawContainer.remove();}}
return __exports;});;
/* /html_editor/static/src/html_migrations/migration-1.2.js */
odoo.define('@html_editor/html_migrations/migration-1.2',['@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"html_editor",...args);const ARIA_LABELS={".o_editor_banner.alert-danger":_t("Banner Danger"),".o_editor_banner.alert-info":_t("Banner Info"),".o_editor_banner.alert-success":_t("Banner Success"),".o_editor_banner.alert-warning":_t("Banner Warning"),};function getAriaLabel(element){for(const[selector,ariaLabel]of Object.entries(ARIA_LABELS)){if(element.matches(selector)){return ariaLabel;}}}
__exports.migrate=migrate;function migrate(container){const bannerContainers=container.querySelectorAll(".o_editor_banner");for(const bannerContainer of bannerContainers){bannerContainer.classList.remove("o_not_editable");bannerContainer.classList.add("o-contenteditable-false");bannerContainer.dataset.oeRole="status";const icon=bannerContainer.querySelector(".o_editor_banner_icon");if(icon){const ariaLabel=getAriaLabel(bannerContainer);if(ariaLabel){icon.dataset.oeAriaLabel=ariaLabel;}}
const bannerContent=bannerContainer.querySelector(".o_editor_banner_icon ~ div");if(bannerContent){bannerContent.classList.remove("o_editable");bannerContent.classList.add("o_editor_banner_content");bannerContent.classList.add("o-contenteditable-true");}}}
return __exports;});;
/* /html_editor/static/src/others/embedded_component_utils.js */
odoo.define('@html_editor/others/embedded_component_utils',['@odoo/owl'],function(require){'use strict';let __exports={};const{onMounted,onRendered,onPatched,onWillDestroy,reactive,toRaw,useComponent,useRef,useState,}=require("@odoo/owl");__exports.getEditableDescendants=getEditableDescendants;function getEditableDescendants(host){const editableDescendants={};for(const candidate of host.querySelectorAll("[data-embedded-editable]")){if(candidate.closest("[data-embedded]")===host){editableDescendants[candidate.dataset.embeddedEditable]=candidate;}}
return editableDescendants;}
__exports.useEditableDescendants=useEditableDescendants;function useEditableDescendants(host){const component=useComponent();if(!component.env.getEditableDescendants){throw new Error("Missing `getEditableDescendants` function in the `embedding` provided to the `EmbeddedComponentPlugin`.");}
const editableDescendants=Object.freeze(component.env.getEditableDescendants(host));const refs={};const renders={};for(const name of Object.keys(editableDescendants)){refs[name]=useRef(name);renders[name]=()=>refs[name].el.replaceChildren(editableDescendants[name]);}
let _restoreSelection;const restoreSelection=()=>{if(_restoreSelection){_restoreSelection();_restoreSelection=undefined;}};if(component.env.editorShared?.selection){onRendered(()=>{_restoreSelection=component.env.editorShared.selection.preserveSelection().restore;});}
onMounted(()=>{for(const render of Object.values(renders)){render();}
restoreSelection();});onPatched(()=>{for(const[name,render]of Object.entries(renders)){if(!host.contains(editableDescendants[name])){render();}}
restoreSelection();});return editableDescendants;}
function embeddedStateProxyHandler(state,stateChangeManager){return{set(target,key,value,receiver){if(value!==Reflect.get(target,key,receiver)&&!stateChangeManager.previousEmbeddedState){stateChangeManager.previousEmbeddedState=JSON.parse(JSON.stringify(stateChangeManager.embeddedState));}
return Reflect.set(target,key,value,receiver);},deleteProperty(target,key){if(Reflect.has(target,key)&&!stateChangeManager.previousEmbeddedState){stateChangeManager.previousEmbeddedState=JSON.parse(JSON.stringify(stateChangeManager.embeddedState));}
return Reflect.deleteProperty(target,key);},get(target,key,receiver){Reflect.get(state,key,state);return Reflect.get(target,key,receiver);},ownKeys(target){Reflect.ownKeys(state);return Reflect.ownKeys(target);},has(target,key){Reflect.has(state,key);return Reflect.has(target,key);},};}
function observeAllKeys(reactive){for(const key in reactive){const prop=reactive[key];if(prop instanceof Object){observeAllKeys(prop);}}}
__exports.getEmbeddedProps=getEmbeddedProps;function getEmbeddedProps(host){return host.dataset.embeddedProps?JSON.parse(host.dataset.embeddedProps):{};}
function sortedCopy(obj){const result={};const propNames=Object.keys(obj).sort();for(const propName of propNames){result[propName]=obj[propName];}
return result;}
__exports.applyObjectPropertyDifference=applyObjectPropertyDifference;function applyObjectPropertyDifference(container,key,previous,next){if(!container[key]){container[key]={};}
const obj1={...(previous||{})};const obj2={...(next||{})};const dest=container[key];for(const key in obj2){if(JSON.stringify(obj1[key])!==JSON.stringify(obj2[key])){dest[key]=obj2[key];}
delete obj1[key];}
for(const key in obj1){delete dest[key];}
if(!Object.keys(dest).length&&!next){delete container[key];}}
__exports.replaceProperty=replaceProperty;function replaceProperty(container,key,value){if(value===undefined){delete container[key];}else{container[key]=value;}}
const StateChangeManager=__exports.StateChangeManager=class StateChangeManager{constructor(config){this.config=config;}
setup(){const defaultState=sortedCopy(this.getEmbeddedState());const defaultStateChange={stateChangeId:null,previous:defaultState,next:defaultState,};this.defaultStateChange=defaultStateChange;this.previousStateChange=defaultStateChange;this.batchId=0;this.setupUnmounted();}
setupUnmounted(){this.previousEmbeddedState=null;this.state=null;this.embeddedState=null;this.embeddedStateProxy=null;this.isLiveComponent=false;this.batchId+=1;}
constructEmbeddedState(state){this.state=state;this.embeddedState=reactive(this.assignDeepProxyCopy({},state),this.batchedChangeState());this.embeddedStateProxy=new Proxy(this.embeddedState,embeddedStateProxyHandler(state,this));observeAllKeys(this.embeddedStateProxy);this.isLiveComponent=true;return this.embeddedStateProxy;}
getState(){let state=this.state;if(!this.isLiveComponent){state=this.getEmbeddedState();}
return state;}
onStateChanged(attrState,{reverse=false,forNewStep=false}={}){const stateChange=attrState?JSON.parse(attrState):this.defaultStateChange;const state=this.getState();if(reverse){this.reverseStateChange(stateChange);}
if(!this.areStateChangesEqual(this.previousStateChange,stateChange)){const previous=JSON.stringify(sortedCopy(state));this.commitStateChange(state,stateChange.previous,stateChange.next);const sortedState=sortedCopy(state);this.config.host.dataset.embeddedProps=JSON.stringify(this.stateToEmbeddedProps(this.config.host,sortedState));if(this.isLiveComponent&&!this.previousEmbeddedState){this.assignDeepProxyCopy(toRaw(this.embeddedState),sortedState);}
if(!forNewStep){this.previousStateChange=stateChange;}else{const next=JSON.stringify(sortedState);if(previous!==next){this.previousStateChange={stateChangeId:this.generateId(),previous:JSON.parse(previous),next:JSON.parse(next),};return JSON.stringify(this.previousStateChange);}}}}
batchedChangeState(){let scheduled=false;const batchId=this.batchId;return async()=>{if(this.isLiveComponent&&!scheduled){scheduled=true;await Promise.resolve();scheduled=false;if(batchId===this.batchId){this.changeState();}}};}
changeState(){if(!this.previousEmbeddedState){return;}
const previousEmbeddedState=this.previousEmbeddedState;this.previousEmbeddedState=null;const previous=JSON.stringify(sortedCopy(this.state));this.commitStateChange(this.state,previousEmbeddedState,JSON.parse(JSON.stringify(this.embeddedState)));const sortedState=sortedCopy(this.state);const next=JSON.stringify(sortedState);this.assignDeepProxyCopy(toRaw(this.embeddedState),sortedState);if(previous!==next){this.previousStateChange={stateChangeId:this.generateId(),previous:JSON.parse(previous),next:JSON.parse(next),};this.config.host.dataset.embeddedState=JSON.stringify(this.previousStateChange);this.config.host.dataset.embeddedProps=JSON.stringify(this.stateToEmbeddedProps(this.config.host,sortedState));this.config.commitStateChanges();}
observeAllKeys(this.embeddedStateProxy);}
areStateChangesEqual(sc1,sc2){return(sc1.stateChangeId===sc2.stateChangeId&&JSON.stringify(sc1.previous)===JSON.stringify(sc2.previous)&&JSON.stringify(sc1.next)===JSON.stringify(sc2.next));}
reverseStateChange(stateChange){const previous=stateChange.previous;stateChange.previous=stateChange.next;stateChange.next=previous;}
assignDeepProxyCopy(target,source){for(const key of Object.keys(target)){delete target[key];}
for(const key of Object.keys(source)){target[key]=this.deepProxyCopy(source[key]);}
return target;}
deepProxyCopy(value){if(value instanceof Object){const copy=value instanceof Array?[]:{};for(const prop in value){copy[prop]=this.deepProxyCopy(value[prop]);}
return new Proxy(copy,embeddedStateProxyHandler(value,this));}
return value;}
generateId(){return Math.floor(Math.random()*Math.pow(2,52));}
commitStateChange(state,previous,next){const currentKeys=new Set([...Object.keys(state),...Object.keys(previous),...Object.keys(next),]);for(const key of currentKeys){if(key in(this.config.propertyUpdater||{})){this.config.propertyUpdater[key](state,previous,next);}else if(JSON.stringify(previous[key])!==JSON.stringify(next[key])){replaceProperty(state,key,next[key]);}}}
getEmbeddedState(){const host=this.config.host;return this.config.getEmbeddedState?.(host)||getEmbeddedProps(host);}
stateToEmbeddedProps(host,state){const props=this.config.stateToEmbeddedProps?.(host,state)||state;for(const key of Object.keys(props)){if(props[key]===undefined){delete props[key];}}
return props;}}
__exports.useEmbeddedState=useEmbeddedState;function useEmbeddedState(host){const component=useComponent();if(!component.env.getStateChangeManager){throw new Error("Missing `getStateChangeManager` function in the `embedding` provided to the `EmbeddedComponentPlugin`.");}
const stateChangeManager=component.env.getStateChangeManager(host);onWillDestroy(()=>stateChangeManager.setupUnmounted());const state=useState(stateChangeManager.getEmbeddedState());return stateChangeManager.constructEmbeddedState(state);}
return __exports;});;
/* /html_editor/static/src/others/embedded_components/core/embedded_component_toolbar/embedded_component_toolbar.js */
odoo.define('@html_editor/others/embedded_components/core/embedded_component_toolbar/embedded_component_toolbar',['@odoo/owl','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{useForwardRefToParent}=require("@web/core/utils/hooks");const EmbeddedComponentToolbar=__exports.EmbeddedComponentToolbar=class EmbeddedComponentToolbar extends Component{static props={buttonsGroupClass:{type:String,optional:true},slots:Object,};static template="html_editor.EmbeddedComponentToolbar";}
const EmbeddedComponentToolbarButton=__exports.EmbeddedComponentToolbarButton=class EmbeddedComponentToolbarButton extends Component{static props={buttonRef:{type:Function,optional:true},hidden:{type:Boolean,optional:true},icon:{type:String,optional:true},label:String,name:{type:String,optional:true},onClick:Function,title:{type:String,optional:true},};static template="html_editor.EmbeddedComponentToolbarButton";setup(){useForwardRefToParent("buttonRef");}}
return __exports;});;
/* /html_editor/static/src/others/embedded_components/core/file/readonly_file.js */
odoo.define('@html_editor/others/embedded_components/core/file/readonly_file',['@web/core/l10n/translation','@web/core/network/download','@web/core/file_viewer/file_viewer_hook','@web/core/utils/hooks','@web/core/confirmation_dialog/confirmation_dialog','@html_editor/others/embedded_components/core/embedded_component_toolbar/embedded_component_toolbar','@html_editor/others/embedded_components/core/file/state_file_model','@html_editor/others/embedded_component_utils','@odoo/owl'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"html_editor",...args);const{downloadFile}=require("@web/core/network/download");const{useFileViewer}=require("@web/core/file_viewer/file_viewer_hook");const{useService}=require("@web/core/utils/hooks");const{AlertDialog}=require("@web/core/confirmation_dialog/confirmation_dialog");const{EmbeddedComponentToolbar,EmbeddedComponentToolbarButton,}=require("@html_editor/others/embedded_components/core/embedded_component_toolbar/embedded_component_toolbar");const{StateFileModel}=require("@html_editor/others/embedded_components/core/file/state_file_model");const{getEmbeddedProps}=require("@html_editor/others/embedded_component_utils");const{Component,useState}=require("@odoo/owl");const ReadonlyEmbeddedFileComponent=__exports.ReadonlyEmbeddedFileComponent=class ReadonlyEmbeddedFileComponent extends Component{static components={EmbeddedComponentToolbar,EmbeddedComponentToolbarButton,};static props={fileData:{type:Object},host:{type:Object},};static template="html_editor.ReadonlyEmbeddedFile";setup(){this.dialogService=useService("dialog");this.state=useState({fileData:{...this.props.fileData},});this.fileModel=new StateFileModel(this.state);this.attachmentViewer=useFileViewer();}
async download(){try{await downloadFile(this.fileModel.downloadUrl);}catch{this.dialogService.add(AlertDialog,{body:_t("Oops, the file %s could not be found. Please replace this file box by a new one to re-upload the file.",this.fileModel.name),title:_t("Missing File"),confirm:()=>{},confirmLabel:_t("Close"),});}}
onClickFileImage(){if(this.fileModel.isViewable){this.attachmentViewer.open(this.fileModel);}else{this.download();}}}
const readonlyFileEmbedding=__exports.readonlyFileEmbedding={name:"file",Component:ReadonlyEmbeddedFileComponent,getProps:(host)=>({host,...getEmbeddedProps(host)}),};return __exports;});;
/* /html_editor/static/src/others/embedded_components/core/file/state_file_model.js */
odoo.define('@html_editor/others/embedded_components/core/file/state_file_model',['@web/core/file_viewer/file_model'],function(require){'use strict';let __exports={};const{FileModel}=require("@web/core/file_viewer/file_model");const StateFileModel=__exports.StateFileModel=class StateFileModel extends FileModel{constructor(state){super();this.state=state;for(const property of["access_token","checksum","extension","filename","id","mimetype","name","type","tmpUrl","url","uploading",]){Object.defineProperty(this,property,{get(){return this.state.fileData[property];},set(value){this.state.fileData[property]=value;},configurable:true,enumerable:true,});}}
get urlRoute(){if(this.isUrl&&!this.id){return this.url;}
return super.urlRoute;}}
return __exports;});;
/* /html_editor/static/src/others/embedded_components/core/syntax_highlighting/readonly_syntax_highlighting.js */
odoo.define('@html_editor/others/embedded_components/core/syntax_highlighting/readonly_syntax_highlighting',['@odoo/owl','@web/core/assets','@web/core/browser/cookie','@html_editor/others/embedded_components/core/syntax_highlighting/syntax_highlighting_utils'],function(require){'use strict';let __exports={};const{Component,onMounted,onWillStart,xml}=require("@odoo/owl");const{loadBundle}=require("@web/core/assets");const{cookie}=require("@web/core/browser/cookie");const{DEFAULT_LANGUAGE_ID,getPreValue,highlightPre}=require("@html_editor/others/embedded_components/core/syntax_highlighting/syntax_highlighting_utils");const ReadonlySyntaxHighlightingComponent=__exports.ReadonlySyntaxHighlightingComponent=class ReadonlySyntaxHighlightingComponent extends Component{static props={value:{type:String},languageId:{type:String},host:{type:Object},};static template=xml`<span/>`;setup(){onWillStart(()=>loadBundle(`html_editor.assets_prism${cookie.get("color_scheme") === "dark" ? "_dark" : ""}`,{targetDoc:this.props.host.ownerDocument}));onMounted(()=>{const owlRoot=[...(this.props.host.children||[])].find((child)=>child.nodeName==="OWL-ROOT");highlightPre(owlRoot||this.props.host,this.props.value,this.props.languageId);});}}
const readonlySyntaxHighlightingEmbedding=__exports.readonlySyntaxHighlightingEmbedding={name:"readonlySyntaxHighlighting",Component:ReadonlySyntaxHighlightingComponent,getProps:(host)=>({host,languageId:host.dataset.languageId||DEFAULT_LANGUAGE_ID,value:getPreValue(host),}),};return __exports;});;
/* /html_editor/static/src/others/embedded_components/core/syntax_highlighting/syntax_highlighting_utils.js */
odoo.define('@html_editor/others/embedded_components/core/syntax_highlighting/syntax_highlighting_utils',['@html_editor/utils/dom','@html_editor/utils/dom_traversal'],function(require){'use strict';let __exports={};const{fillEmpty}=require("@html_editor/utils/dom");const{descendants,lastLeaf}=require("@html_editor/utils/dom_traversal");const DEFAULT_LANGUAGE_ID=__exports.DEFAULT_LANGUAGE_ID="plaintext";const newlinesToLineBreaks=__exports.newlinesToLineBreaks=(element,doc=element.ownerDocument||document)=>{for(const node of descendants(element).filter((node)=>node.nodeType===Node.TEXT_NODE)){let newline=node.textContent.indexOf("\n");while(newline!==-1){node.before(doc.createTextNode(node.textContent.slice(0,newline)));node.before(doc.createElement("BR"));node.textContent=node.textContent.slice(newline+1);newline=node.textContent.indexOf("\n");}
if(!node.textContent){node.remove();}}
const trailingBr=lastLeaf(element);if(trailingBr?.nodeName==="BR"){element.append(trailingBr);trailingBr.after(doc.createElement("BR"));}
fillEmpty(element);};const getPreValue=__exports.getPreValue=(pre)=>{const html=pre.innerHTML;const hasTrailingBr=/<br\s*\/?>$/i.test(html);let text=html.replace(/<br\s*\/?>/gi,"\n").replace(/<[^>]+>|[\u200B\uFEFF]/g,"").replace(/&(amp|lt|gt|#x27|quot|#x60);/g,(_,entity)=>({amp:"&",lt:"<",gt:">","#x27":"'",quot:'"',"#x60":"`"}[entity]));if(hasTrailingBr&&text.endsWith("\n")){text=text.slice(0,-1);}
return text;};const highlightPre=__exports.highlightPre=(pre,value,languageId)=>{const fakeElement=pre.ownerDocument.createElement("pre");if(window.Prism){fakeElement.innerHTML=Prism.highlight(value,Prism.languages[languageId],languageId);}else{fakeElement.innerHTML=value;}
newlinesToLineBreaks(fakeElement,pre.ownerDocument);[...pre.childNodes].forEach((child)=>child.remove());[...fakeElement.childNodes].forEach((child)=>pre.append(child));};return __exports;});;
/* /html_editor/static/src/others/embedded_components/core/table_of_content/table_of_content.js */
odoo.define('@html_editor/others/embedded_components/core/table_of_content/table_of_content',['@odoo/owl','@html_editor/others/embedded_components/core/table_of_content/table_of_content_manager'],function(require){'use strict';let __exports={};const{Component,onWillStart,useState}=require("@odoo/owl");const{TableOfContentManager}=require("@html_editor/others/embedded_components/core/table_of_content/table_of_content_manager");const EmbeddedTableOfContentComponent=__exports.EmbeddedTableOfContentComponent=class EmbeddedTableOfContentComponent extends Component{static template="html_editor.EmbeddedTableOfContent";static props={manager:{type:TableOfContentManager},readonly:{type:Boolean,optional:true},};setup(){this.state=useState({toc:this.props.manager.structure,folded:false});onWillStart(async()=>{await this.props.manager.batchedUpdateStructure();});}
displayTocHint(){return this.state.toc.headings.length<2&&!this.props.readonly;}
onTocLinkClick(heading){this.props.manager.scrollIntoView(heading);}}
const tableOfContentEmbedding=__exports.tableOfContentEmbedding={name:"tableOfContent",Component:EmbeddedTableOfContentComponent,};const readonlyTableOfContentEmbedding=__exports.readonlyTableOfContentEmbedding={name:"tableOfContent",Component:EmbeddedTableOfContentComponent,getProps:(host)=>({readonly:true,}),};return __exports;});;
/* /html_editor/static/src/others/embedded_components/core/table_of_content/table_of_content_manager.js */
odoo.define('@html_editor/others/embedded_components/core/table_of_content/table_of_content_manager',['@odoo/owl'],function(require){'use strict';let __exports={};const{batched,reactive}=require("@odoo/owl");const HEADINGS=__exports.HEADINGS=["H1","H2","H3","H4","H5","H6"];const TableOfContentManager=__exports.TableOfContentManager=class TableOfContentManager{constructor(containerRef){this.containerRef=containerRef;this.structure=reactive({headings:[],});this.batchedUpdateStructure=batched(this.updateStructure.bind(this));}
getContainerEl(){return this.containerRef.el;}
fetchValidHeadings(element){const inEmbeddedHeadings=new Set(element.querySelectorAll(HEADINGS.map((heading)=>`[data-embedded] ${heading}`).join(",")));return Array.from(element.querySelectorAll(HEADINGS.join(","))).filter((heading)=>heading.innerText.trim().replaceAll("\u200B","").length>0).filter((heading)=>!inEmbeddedHeadings.has(heading));}
scrollIntoView(heading){if(!heading){return;}
const{target}=heading;target.scrollIntoView({behavior:"smooth"});target.classList.add("o_embedded_toc_header_highlight");window.setTimeout(()=>{target.classList.remove("o_embedded_toc_header_highlight");},2000);}
updateStructure(){const container=this.getContainerEl();if(!container){return;}
const tagDepthStack=[];this.structure.headings=this.fetchValidHeadings(container).map((heading)=>{while(tagDepthStack.at(-1)>=heading.tagName){tagDepthStack.pop();}
const depth=tagDepthStack.length;tagDepthStack.push(heading.tagName);return{depth,name:heading.innerText,target:heading,};});}}
return __exports;});;
/* /html_editor/static/src/others/embedded_components/core/toggle_block/toggle_block.js */
odoo.define('@html_editor/others/embedded_components/core/toggle_block/toggle_block',['@html_editor/others/embedded_component_utils','@web/core/browser/browser','@odoo/owl'],function(require){'use strict';let __exports={};const{getEditableDescendants,getEmbeddedProps,useEditableDescendants,}=require("@html_editor/others/embedded_component_utils");const{browser}=require("@web/core/browser/browser");const{Component,useEffect,useExternalListener,useState}=require("@odoo/owl");const sessionStorage=browser.sessionStorage;const EmbeddedToggleBlockComponent=__exports.EmbeddedToggleBlockComponent=class EmbeddedToggleBlockComponent extends Component{static template="html_editor.EmbeddedToggleBlock";static props={host:{type:Object},toggleBlockId:{type:String},};setup(){useEditableDescendants(this.props.host);this.state=useState({showContent:sessionStorage.getItem(this.toggleStorageKey)==="true",});this.neutralRestoreSelection=()=>{};this.restoreSelection=this.neutralRestoreSelection;useExternalListener(this.props.host,"forceToggle",this.onToggle);useEffect(()=>{this.restoreSelection();this.restoreSelection=this.neutralRestoreSelection;},()=>[this.restoreSelection]);}
get toggleStorageKey(){return`html_editor.ToggleBlock${this.props.toggleBlockId}.showContent`;}
onToggle(ev){let{showContent,restoreSelection}=ev.detail??{};showContent??=!this.state.showContent;restoreSelection??=this.neutralRestoreSelection;if(this.state.showContent!==showContent){this.restoreSelection=restoreSelection;this.state.showContent=showContent;sessionStorage.setItem(this.toggleStorageKey,this.state.showContent);}else{restoreSelection();}}}
const toggleBlockEmbedding=__exports.toggleBlockEmbedding={name:"toggleBlock",Component:EmbeddedToggleBlockComponent,getProps:(host)=>({host,...getEmbeddedProps(host)}),getEditableDescendants:getEditableDescendants,};return __exports;});;
/* /html_editor/static/src/others/embedded_components/core/video/readonly_video.js */
odoo.define('@html_editor/others/embedded_components/core/video/readonly_video',['@html_editor/others/embedded_component_utils','@html_editor/utils/url','@odoo/owl'],function(require){'use strict';let __exports={};const{getEmbeddedProps}=require("@html_editor/others/embedded_component_utils");const{getVideoUrl}=require("@html_editor/utils/url");const{Component}=require("@odoo/owl");const ReadonlyEmbeddedVideoComponent=__exports.ReadonlyEmbeddedVideoComponent=class ReadonlyEmbeddedVideoComponent extends Component{static template="html_editor.EmbeddedVideo";static props={platform:{type:String},videoId:{type:String},params:{type:Object,optional:true},};get url(){return getVideoUrl(this.props.platform,this.props.videoId,this.props.params).toString();}}
const readonlyVideoEmbedding=__exports.readonlyVideoEmbedding={name:"video",Component:ReadonlyEmbeddedVideoComponent,getProps:(host)=>({...getEmbeddedProps(host)}),};return __exports;});;
/* /html_editor/static/src/utils/base_container.js */
odoo.define('@html_editor/utils/base_container',[],function(require){'use strict';let __exports={};const BASE_CONTAINER_CLASS=__exports.BASE_CONTAINER_CLASS="o-paragraph";const SUPPORTED_BASE_CONTAINER_NAMES=__exports.SUPPORTED_BASE_CONTAINER_NAMES=["P","DIV"];__exports.getBaseContainerSelector=getBaseContainerSelector;function getBaseContainerSelector(nodeName){if(!nodeName){return baseContainerGlobalSelector;}
nodeName=SUPPORTED_BASE_CONTAINER_NAMES.includes(nodeName)?nodeName:"P";let suffix="";if(nodeName!=="P"){suffix=`.${BASE_CONTAINER_CLASS}`;}
return`${nodeName}${suffix}`;}
const baseContainerGlobalSelector=__exports.baseContainerGlobalSelector=`:is(${SUPPORTED_BASE_CONTAINER_NAMES.map((name) =>
getBaseContainerSelector(name)
).join(",")})`;__exports.createBaseContainer=createBaseContainer;function createBaseContainer(nodeName,document){if(!document&&window){document=window.document;}
nodeName=nodeName&&SUPPORTED_BASE_CONTAINER_NAMES.includes(nodeName)?nodeName:"P";const el=document.createElement(nodeName);if(nodeName!=="P"){el.className=BASE_CONTAINER_CLASS;}
return el;}
return __exports;});;
/* /html_editor/static/src/utils/blocks.js */
odoo.define('@html_editor/utils/blocks',['@html_editor/utils/dom_traversal'],function(require){'use strict';let __exports={};const{closestPath,findNode}=require("@html_editor/utils/dom_traversal");const blockTagNames=["ADDRESS","ARTICLE","ASIDE","BLOCKQUOTE","DETAILS","DIALOG","DD","DIV","DL","DT","FIELDSET","FIGCAPTION","FIGURE","FOOTER","FORM","H1","H2","H3","H4","H5","H6","HEADER","HGROUP","HR","LI","MAIN","NAV","OL","P","PRE","SECTION","TABLE","UL","SELECT","OPTION","TR","TD","TBODY","THEAD","TH",];const computedStyleDisplayCache=new WeakMap();__exports.isBlock=isBlock;function isBlock(node){if(!node||node.nodeType!==Node.ELEMENT_NODE){return false;}
const tagName=node.nodeName.toUpperCase();if(tagName==="BR"){return false;}
if(!node.isConnected){return blockTagNames.includes(tagName);}
let display=computedStyleDisplayCache.get(node);if(display===undefined){const style=node.ownerDocument.defaultView.getComputedStyle(node);display=style.display;computedStyleDisplayCache.set(node,display);}
if(display&&display!=="none"){return!display.includes("inline")&&display!=="contents";}
return blockTagNames.includes(tagName);}
__exports.closestBlock=closestBlock;function closestBlock(node){return findNode(closestPath(node),(node)=>isBlock(node));}
return __exports;});;
/* /html_editor/static/src/utils/clipboard.js */
odoo.define('@html_editor/utils/clipboard',[],function(require){'use strict';let __exports={};function prependOriginToImages(doc,origin){doc.querySelectorAll("img").forEach((img)=>{const src=img.getAttribute("src");if(src&&!/^(http|\/\/|data:)/.test(src)){img.src=origin+(src.startsWith("/")?src:"/"+src);}});}
__exports.fillHtmlTransferData=fillHtmlTransferData;function fillHtmlTransferData(ev,transferObjectProperty,clonedContents,{setEditorTransferData=true,textContent}={}){const doc=ev.target.ownerDocument;const dataHtmlElement=doc.createElement("data");dataHtmlElement.append(clonedContents);prependOriginToImages(dataHtmlElement,doc.defaultView.location.origin);const htmlContent=dataHtmlElement.innerHTML;if(textContent){ev[transferObjectProperty].setData("text/plain",textContent);}
ev[transferObjectProperty].setData("text/html",htmlContent);if(setEditorTransferData){ev[transferObjectProperty].setData("application/vnd.odoo.odoo-editor",htmlContent);}}
return __exports;});;
/* /html_editor/static/src/utils/color.js */
odoo.define('@html_editor/utils/color',['@html_editor/utils/dom_traversal','@web/core/utils/colors','@html_editor/utils/dom_info'],function(require){'use strict';let __exports={};const{closestElement}=require("@html_editor/utils/dom_traversal");const{isColorGradient}=require("@web/core/utils/colors");const{isElement}=require("@html_editor/utils/dom_info");const COLOR_PALETTE_COMPATIBILITY_COLOR_NAMES=__exports.COLOR_PALETTE_COMPATIBILITY_COLOR_NAMES=["primary","secondary","alpha","beta","gamma","delta","epsilon","success","info","warning","danger",];const DEFAULT_PALETTE=__exports.DEFAULT_PALETTE={1:"#3AADAA",2:"#7C6576",3:"#F6F6F6",4:"#FFFFFF",5:"#383E45",};const EDITOR_COLOR_CSS_VARIABLES=__exports.EDITOR_COLOR_CSS_VARIABLES=[...COLOR_PALETTE_COMPATIBILITY_COLOR_NAMES];for(let i=1;i<=5;i++){EDITOR_COLOR_CSS_VARIABLES.push(`o-color-${i}`);EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-bg`);EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-bg-gradient`);EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-headings`);EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-text`);EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-btn-primary`);EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-btn-primary-text`);EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-btn-secondary`);EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-btn-secondary-text`);EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-btn-primary-border`);EDITOR_COLOR_CSS_VARIABLES.push(`o-cc${i}-btn-secondary-border`);}
for(let i=100;i<=900;i+=100){EDITOR_COLOR_CSS_VARIABLES.push(`${i}`);}
EDITOR_COLOR_CSS_VARIABLES.push("black","black-15","black-25","black-50","black-75","white","white-25","white-50","white-75","white-85");__exports.isColorCombinationName=isColorCombinationName;function isColorCombinationName(name){const number=parseInt(name);return!isNaN(number)&&number%100!==0;}
const TEXT_CLASSES_REGEX=__exports.TEXT_CLASSES_REGEX=/\btext-(primary|secondary|success|danger|warning|info|light|dark|body|muted|white|black|reset|gradient|opacity-\d{1,3}|o-[^\s]+|\d+)\b/;const BG_CLASSES_REGEX=__exports.BG_CLASSES_REGEX=/\bbg-[^\s]*\b/;const COLOR_COMBINATION_CLASSES_REGEX=__exports.COLOR_COMBINATION_CLASSES_REGEX=/\bo_cc[0-9]+\b/g;__exports.hasTextColorClass=hasTextColorClass;function hasTextColorClass(element,mode){if(!element||!isElement(element)){return false;}
const classRegex=mode==="color"?TEXT_CLASSES_REGEX:BG_CLASSES_REGEX;const parent=element.parentNode;return(classRegex.test(element.className)&&(!parent||getComputedStyle(element)[mode]!==getComputedStyle(parent)[mode]));}
__exports.hasColor=hasColor;function hasColor(element,mode){const style=element.style;const parent=element.parentNode;if(element.classList.contains("btn")||element.tagName==="A"){return false;}
if(isColorGradient(style["background-image"])){if(element.classList.contains("text-gradient")){if(mode==="color"){return true;}}else{if(mode!=="color"){return true;}}}
return((style[mode]&&style[mode]!=="inherit"&&(!parent||style[mode]!==parent.style[mode]))||hasTextColorClass(element,mode));}
__exports.hasAnyNodesColor=hasAnyNodesColor;function hasAnyNodesColor(nodes,mode){for(const node of nodes){if(hasColor(closestElement(node),mode)){return true;}}
return false;}
__exports.getTextColorOrClass=getTextColorOrClass;function getTextColorOrClass(node){if(!node){return null;}
if(node.style.color){return{type:"style",value:node.style.color};}
const textColorClass=[...node.classList].find((cls)=>TEXT_CLASSES_REGEX.test(cls));if(textColorClass){return{type:"class",value:textColorClass};}
return null;}
return __exports;});;
/* /html_editor/static/src/utils/content_types.js */
odoo.define('@html_editor/utils/content_types',[],function(require){'use strict';let __exports={};const CTYPES=__exports.CTYPES={CONTENT:1,SPACE:2,BLOCK_OUTSIDE:4,BLOCK_INSIDE:8,BR:16,};__exports.ctypeToString=ctypeToString;function ctypeToString(ctype){return Object.keys(CTYPES).find((key)=>CTYPES[key]===ctype);}
const CTGROUPS=__exports.CTGROUPS={INLINE:CTYPES.CONTENT|CTYPES.SPACE,BLOCK:CTYPES.BLOCK_OUTSIDE|CTYPES.BLOCK_INSIDE,BR:CTYPES.BR,};return __exports;});;
/* /html_editor/static/src/utils/dom.js */
odoo.define('@html_editor/utils/dom',['@html_editor/utils/blocks','@html_editor/utils/dom_info','@html_editor/utils/selection','@html_editor/utils/dom_traversal','@html_editor/utils/position','@html_editor/utils/base_container'],function(require){'use strict';let __exports={};const{closestBlock,isBlock}=require("@html_editor/utils/blocks");const{isElement,isEmptyTextNode,isParagraphRelatedElement,isShrunkBlock,isTextNode,isVisible,nextLeaf,previousLeaf,}=require("@html_editor/utils/dom_info");const{callbacksForCursorUpdate}=require("@html_editor/utils/selection");const{isEmptyBlock,isPhrasingContent}=require("@html_editor/utils/dom_info");const{childNodes,descendants}=require("@html_editor/utils/dom_traversal");const{childNodeIndex,DIRECTIONS,nodeSize}=require("@html_editor/utils/position");const{baseContainerGlobalSelector,createBaseContainer,}=require("@html_editor/utils/base_container");__exports.makeContentsInline=makeContentsInline;function makeContentsInline(node){const document=node.ownerDocument;let currentNode=node.firstChild;while(currentNode){if(isBlock(currentNode)){if(currentNode.previousSibling&&isParagraphRelatedElement(currentNode)){currentNode.before(document.createElement("br"));}
currentNode=unwrapContents(currentNode)[0];}else{currentNode=currentNode.nextSibling;}}}
__exports.wrapInlinesInBlocks=wrapInlinesInBlocks;function wrapInlinesInBlocks(element,{baseContainerNodeName="P",cursors={update:()=>{}}}={}){const wrapInBlock=(node,cursors)=>{const block=isPhrasingContent(node)?createBaseContainer(baseContainerNodeName,node.ownerDocument):node.ownerDocument.createElement("DIV");cursors.update(callbacksForCursorUpdate.append(block,node));cursors.update(callbacksForCursorUpdate.before(node,block));if(node.nextSibling){const sibling=node.nextSibling;node.remove();sibling.before(block);}else{const parent=node.parentElement;node.remove();parent.append(block);}
block.append(node);return block;};const appendToCurrentBlock=(currentBlock,node,cursors)=>{if(currentBlock.matches(baseContainerGlobalSelector)&&!isPhrasingContent(node)){const block=currentBlock.ownerDocument.createElement("DIV");cursors.update(callbacksForCursorUpdate.before(currentBlock,block));currentBlock.before(block);for(const child of childNodes(currentBlock)){cursors.update(callbacksForCursorUpdate.append(block,child));block.append(child);}
cursors.update(callbacksForCursorUpdate.remove(currentBlock));currentBlock.remove();currentBlock=block;}
cursors.update(callbacksForCursorUpdate.append(currentBlock,node));currentBlock.append(node);return currentBlock;};const removeNode=(node,cursors)=>{cursors.update(callbacksForCursorUpdate.remove(node));node.remove();};const children=childNodes(element);const visibleNodes=new Set(children.filter(isVisible));let currentBlock;let shouldBreakLine=true;for(const node of children){if(isBlock(node)){shouldBreakLine=true;}else if(!visibleNodes.has(node)){removeNode(node,cursors);}else if(node.nodeName==="BR"){if(shouldBreakLine){wrapInBlock(node,cursors);}else{removeNode(node,cursors);shouldBreakLine=true;}}else if(shouldBreakLine){currentBlock=wrapInBlock(node,cursors);shouldBreakLine=false;}else{currentBlock=appendToCurrentBlock(currentBlock,node,cursors);}}}
__exports.unwrapContents=unwrapContents;function unwrapContents(node){const contents=childNodes(node);for(const child of contents){node.parentNode.insertBefore(child,node);}
node.parentNode.removeChild(node);return contents;}
__exports.removeClass=removeClass;function removeClass(element,...classNames){const classNamesSet=new Set(classNames);if([...element.classList].every((className)=>classNamesSet.has(className))){element.removeAttribute("class");}else{element.classList.remove(...classNames);}}
__exports.removeStyle=removeStyle;function removeStyle(element,...styleProperties){const propsToRemoveSet=new Set(styleProperties);if([...element.style].every((prop)=>propsToRemoveSet.has(prop))){element.removeAttribute("style");}else{styleProperties.forEach((prop)=>element.style.removeProperty(prop));}}
__exports.fillEmpty=fillEmpty;function fillEmpty(el){const document=el.ownerDocument;if(!isVisible(el)&&!el.hasAttribute("data-oe-zws-empty-inline")&&!isBlock(el)){const zws=document.createTextNode("\u200B");el.appendChild(zws);el.setAttribute("data-oe-zws-empty-inline","");const previousSibling=el.previousSibling;if(previousSibling&&previousSibling.nodeName==="BR"){previousSibling.remove();}
return{zws};}else{return fillShrunkPhrasingParent(el);}}
__exports.fillShrunkPhrasingParent=fillShrunkPhrasingParent;function fillShrunkPhrasingParent(el){const document=el.ownerDocument;const fillers={};const blockEl=closestBlock(el);if(isShrunkBlock(blockEl)){const br=document.createElement("br");blockEl.appendChild(br);fillers.br=br;}
return fillers;}
__exports.cleanTrailingBR=cleanTrailingBR;function cleanTrailingBR(el,predicates=[]){const candidate=el?.lastChild;if(candidate?.nodeName==="BR"&&candidate.previousSibling?.nodeName!=="BR"&&!isEmptyBlock(el)&&!predicates.some((predicate)=>predicate(candidate))){candidate.remove();return candidate;}}
__exports.toggleClass=toggleClass;function toggleClass(element,className,force){element.classList.toggle(className,force);if(!element.className){element.removeAttribute("class");}}
__exports.cleanEmptyAncestors=cleanEmptyAncestors;function cleanEmptyAncestors(node,cursors,exclude=()=>false){let currentNode=node;while(currentNode&&!nodeSize(currentNode)&&!exclude(currentNode)){cursors?.update(callbacksForCursorUpdate.remove(currentNode));const parent=currentNode.parentNode;currentNode.remove();currentNode=parent;}}
__exports.cleanTextNode=cleanTextNode;function cleanTextNode(node,char,cursors){const removedIndexes=[];node.textContent=node.textContent.replaceAll(char,(_,offset)=>{removedIndexes.push(offset);return"";});if(isEmptyTextNode(node)){cursors?.update(callbacksForCursorUpdate.remove(node));node.remove();}else{cursors?.update((cursor)=>{if(cursor.node===node){cursor.offset-=removedIndexes.filter((index)=>cursor.offset>index).length;}});}}
__exports.removeEmptyTextNodes=removeEmptyTextNodes;function removeEmptyTextNodes(root,cursors){for(const node of childNodes(root).filter((n)=>isEmptyTextNode(n))){cursors?.update(callbacksForCursorUpdate.remove(node));node.remove();}}
__exports.splitTextNode=splitTextNode;function splitTextNode(textNode,offset,originalNodeSide=DIRECTIONS.RIGHT){const document=textNode.ownerDocument;let parentOffset=childNodeIndex(textNode);if(offset>0){parentOffset++;if(offset<textNode.length){const left=textNode.nodeValue.substring(0,offset);const right=textNode.nodeValue.substring(offset);if(originalNodeSide===DIRECTIONS.LEFT){const newTextNode=document.createTextNode(right);textNode.after(newTextNode);textNode.nodeValue=left;}else{const newTextNode=document.createTextNode(left);textNode.before(newTextNode);textNode.nodeValue=right;}}}
return parentOffset;}
__exports.removeInvisibleWhitespace=removeInvisibleWhitespace;function removeInvisibleWhitespace(el,cursors){const[countLeadingWhitespace,countTrailingWhitespace]=[/^\s+/,/\s+$/].map((regex)=>(node)=>node?.textContent.match(regex)?.[0]?.length||0);const isInlineElement=(node)=>node?.nodeType===Node.ELEMENT_NODE&&!isBlock(node);const textChildren=descendants(el).filter((child)=>child.nodeType===Node.TEXT_NODE);let removedTrailingSpaceBefore=false;let index=0;for(const child of textChildren){let leadingWhitespace=countLeadingWhitespace(child);let trailingWhitespace=countTrailingWhitespace(child);const previous=previousLeaf(child,el);if(leadingWhitespace&&previous&&(isInlineElement(child.previousSibling)||removedTrailingSpaceBefore)){leadingWhitespace-=1;}else if(trailingWhitespace&&index!==textChildren.length-1&&isInlineElement(child.nextSibling)&&!countTrailingWhitespace(nextLeaf(child,el))){trailingWhitespace-=1;}
removedTrailingSpaceBefore=!!trailingWhitespace;cursors?.shiftOffset(child,-leadingWhitespace);child.textContent=child.textContent.substring(leadingWhitespace,child.textContent.length-trailingWhitespace||leadingWhitespace).replace(/^\s+/," ").replace(/\s+$/," ");if(!child.textContent){child.remove();}
index+=1;}}
__exports.mergeAdjacentTextNodes=mergeAdjacentTextNodes;function mergeAdjacentTextNodes(node,cursor){let child=node.firstChild;while(child){if(isElement(child)){mergeAdjacentTextNodes(child,cursor);}
const next=child.nextSibling;if(isTextNode(child)&&next&&isTextNode(next)){if(cursor.anchor.node===next){cursor.anchor.node=child;cursor.anchor.offset=child.textContent.length+cursor.anchor.offset;}
if(cursor.focus.node===next){cursor.focus.node=child;cursor.focus.offset=child.textContent.length+cursor.focus.offset;}
child.textContent+=next.textContent;next.remove();}else{child=next;}}}
return __exports;});;
/* /html_editor/static/src/utils/dom_info.js */
odoo.define('@html_editor/utils/dom_info',['@html_editor/utils/base_container','@html_editor/utils/blocks','@html_editor/utils/dom_traversal','@html_editor/utils/position'],function(require){'use strict';let __exports={};const{baseContainerGlobalSelector}=require("@html_editor/utils/base_container");const{closestBlock,isBlock}=require("@html_editor/utils/blocks");const{childNodes,closestElement,firstLeaf,lastLeaf}=require("@html_editor/utils/dom_traversal");const{childNodeIndex,DIRECTIONS,nodeSize}=require("@html_editor/utils/position");__exports.isEmpty=isEmpty;function isEmpty(el){if(isProtecting(el)||isProtected(el)){return false;}
const content=el.innerHTML.trim();if(content===""||content==="<br>"){return true;}
return false;}
__exports.isEmptyTextNode=isEmptyTextNode;function isEmptyTextNode(node){if(node.nodeType!==Node.TEXT_NODE){return false;}
if(!node.textContent){return true;}
const trimmedContent=node.textContent.trim();if(!trimmedContent){if(node.textContent.includes("\n")){return true;}
if(node.textContent){return false;}}
return!trimmedContent;}
__exports.isBold=isBold;function isBold(node){const fontWeight=+getComputedStyle(closestElement(node)).fontWeight;const referenceElement=closestElement(node,(el)=>isBlock(el)||+getComputedStyle(el).fontWeight!==fontWeight);return fontWeight>500||fontWeight>+getComputedStyle(referenceElement).fontWeight;}
__exports.isItalic=isItalic;function isItalic(node){return getComputedStyle(closestElement(node)).fontStyle==="italic";}
__exports.isUnderline=isUnderline;function isUnderline(node){let parent=closestElement(node);while(parent){if(getComputedStyle(parent).textDecorationLine.includes("underline")){return true;}
parent=parent.parentElement;}
return false;}
__exports.isStrikeThrough=isStrikeThrough;function isStrikeThrough(node){let parent=closestElement(node);while(parent){if(!parent.classList.contains("o_checked")&&getComputedStyle(parent).textDecorationLine.includes("line-through")){return true;}
parent=parent.parentElement;}
return false;}
__exports.isFontSize=isFontSize;function isFontSize(node,props){const element=closestElement(node);return getComputedStyle(element)["font-size"]===props.size;}
__exports.hasClass=hasClass;function hasClass(node,props){const element=closestElement(node);return element.classList.contains(props.className);}
__exports.isDirectionSwitched=isDirectionSwitched;function isDirectionSwitched(node,editable){const defaultDirection=editable.getAttribute("dir")||"ltr";return getComputedStyle(closestElement(node)).direction!==defaultDirection;}
__exports.isRow=isRow;function isRow(node){return["TH","TD"].includes(node.tagName);}
__exports.isZWS=isZWS;function isZWS(node){return node&&node.textContent==="\u200B";}
__exports.isInPre=isInPre;function isInPre(node){const element=node.nodeType===Node.TEXT_NODE?node.parentElement:node;return(!!element&&(!!element.closest("pre")||getComputedStyle(element).getPropertyValue("white-space")==="pre"));}
const ZERO_WIDTH_CHARS=__exports.ZERO_WIDTH_CHARS=["\u200b","\ufeff"];const whitespace=__exports.whitespace=`[^\\S\\u00A0\\u0009\\ufeff]`;const whitespaceRegex=new RegExp(`^${whitespace}*$`);__exports.isWhitespace=isWhitespace;function isWhitespace(value){const str=typeof value==="string"?value:value.nodeValue;return whitespaceRegex.test(str);}
const visibleCharRegex=/[^\s\u200b]|[\u00A0\u0009]$/;__exports.isVisibleTextNode=isVisibleTextNode;function isVisibleTextNode(testedNode){if(!testedNode||!testedNode.length||testedNode.nodeType!==Node.TEXT_NODE){return false;}
if(isProtected(testedNode)){return true;}
if(visibleCharRegex.test(testedNode.textContent)||(isInPre(testedNode)&&isWhitespace(testedNode))){return true;}
if(ZERO_WIDTH_CHARS.includes(testedNode.textContent)){return false;}
let preceding;let following;let foundTestedNode;const currentNodeParentBlock=closestBlock(testedNode);if(!currentNodeParentBlock){return false;}
const nodeIterator=document.createNodeIterator(currentNodeParentBlock);for(let node=nodeIterator.nextNode();node;node=nodeIterator.nextNode()){if(node.nodeType===Node.TEXT_NODE){if(foundTestedNode){following=node;break;}else if(testedNode===node){foundTestedNode=true;}else{preceding=node;}}else if(isBlock(node)){if(foundTestedNode){break;}else{preceding=null;}}else if(foundTestedNode&&!isWhitespace(node)){following=node;break;}}
while(following&&!visibleCharRegex.test(following.textContent)){following=following.nextSibling;}
if(!(preceding&&following)||currentNodeParentBlock!==closestBlock(preceding)||currentNodeParentBlock!==closestBlock(following)){return false;}
return visibleCharRegex.test(preceding.textContent);}
const selfClosingElementTags=["BR","IMG","INPUT","T","HR"];__exports.isSelfClosingElement=isSelfClosingElement;function isSelfClosingElement(node){return node&&selfClosingElementTags.includes(node.nodeName);}
__exports.isVisible=isVisible;function isVisible(node){return(!!node&&((node.nodeType===Node.TEXT_NODE&&isVisibleTextNode(node))||isSelfClosingElement(node)||isMediaElement(node)||hasVisibleContent(node)||isProtecting(node)||isEmbeddedComponent(node)||(node.nodeName==="TD"&&!!closestElement(node,"table.o_table"))));}
__exports.hasVisibleContent=hasVisibleContent;function hasVisibleContent(node){return(node?childNodes(node):[]).some((n)=>isVisible(n));}
__exports.isButton=isButton;function isButton(node){if(!node||node.nodeType!==Node.ELEMENT_NODE){return false;}
return node.nodeName==="BUTTON"||node.classList.contains("btn");}
__exports.isZwnbsp=isZwnbsp;function isZwnbsp(node){return node?.nodeType===Node.TEXT_NODE&&node.textContent==="\ufeff";}
__exports.isTangible=isTangible;function isTangible(node){return isVisible(node)||isZwnbsp(node)||hasTangibleContent(node);}
__exports.hasTangibleContent=hasTangibleContent;function hasTangibleContent(node){return(node?childNodes(node):[]).some((n)=>isTangible(n));}
const isNotEditableNode=__exports.isNotEditableNode=(node)=>node.getAttribute&&node.getAttribute("contenteditable")&&node.getAttribute("contenteditable").toLowerCase()==="false";const iconTags=["I","SPAN"];const iconClasses=__exports.iconClasses=["fa","fab","fad","far","oi"];const ICON_SELECTOR=__exports.ICON_SELECTOR=iconTags.map((tag)=>iconClasses.map((cls)=>`${tag}.${cls}`).join(", ")).join(", ");const MEDIA_SELECTOR=__exports.MEDIA_SELECTOR=`${ICON_SELECTOR}, .media_iframe_video, .o_file_box`;const EDITABLE_MEDIA_CLASS=__exports.EDITABLE_MEDIA_CLASS="o_editable_media";__exports.isIconElement=isIconElement;function isIconElement(node){return!!(node&&iconTags.includes(node.nodeName)&&iconClasses.some((cls)=>node.classList.contains(cls)));}
__exports.isMediaElement=isMediaElement;function isMediaElement(node){return(isIconElement(node)||(node.classList&&(node.classList.contains("o_file_box")||node.classList.contains("media_iframe_video")))||node.nodeName==="CANVAS");}
__exports.hasMediaOnly=hasMediaOnly;function hasMediaOnly(mediaContainerEl,requiresSingleMedia=false){const nonEmptyContent=[...mediaContainerEl.childNodes].filter((node)=>node.tagName!=="BR"&&(node.nodeType!==Node.TEXT_NODE||node.textContent.replaceAll(/\s+/g,"")));if(requiresSingleMedia&&nonEmptyContent.length!==1){return false;}
return nonEmptyContent.every((el)=>{if(isMediaElement(el)||el.tagName==="IMG"){return true;}
if(el.tagName==="A"){return hasMediaOnly(el,requiresSingleMedia);}});}
const phrasingTagNames=new Set(["ABBR","AUDIO","B","BDI","BDO","BR","BUTTON","CANVAS","CITE","CODE","DATA","DATALIST","DFN","EM","EMBED","I","IFRAME","IMG","INPUT","KBD","LABEL","MARK","MATH","METER","NOSCRIPT","OBJECT","OUTPUT","PICTURE","PROGRESS","Q","RUBY","S","SAMP","SCRIPT","SELECT","SLOT","SMALL","SPAN","STRONG","SUB","SUP","SVG","TEMPLATE","TEXTAREA","TIME","U","VAR","VIDEO","WBR","FONT","A","AREA","DEL","INS","LINK","MAP","META",]);__exports.isPhrasingContent=isPhrasingContent;function isPhrasingContent(node){if(node&&(node.nodeType===Node.TEXT_NODE||(node.nodeType===Node.ELEMENT_NODE&&phrasingTagNames.has(node.tagName)))){return true;}
return false;}
__exports.containsAnyInline=containsAnyInline;function containsAnyInline(element){if(!element){return false;}
let child=element.firstChild;while(child){if((!isBlock(child)&&child.nodeType===Node.ELEMENT_NODE)||(child.nodeType===Node.TEXT_NODE&&child.textContent.trim()!=="")){return true;}
child=child.nextSibling;}
return false;}
__exports.containsAnyNonPhrasingContent=containsAnyNonPhrasingContent;function containsAnyNonPhrasingContent(element){if(!element){return false;}
let child=element.firstChild;while(child){if(!isPhrasingContent(child)){return true;}
child=child.nextSibling;}
return false;}
__exports.isEmbeddedComponent=isEmbeddedComponent;function isEmbeddedComponent(node){return node.nodeType===Node.ELEMENT_NODE&&node.matches("[data-embedded]");}
__exports.isProtected=isProtected;function isProtected(node){if(!node){return false;}
const candidate=node.parentElement?closestElement(node.parentElement,"[data-oe-protected]"):null;if(!candidate||candidate.dataset.oeProtected==="false"){return false;}
return true;}
__exports.isProtecting=isProtecting;function isProtecting(node){if(!node){return false;}
return(node.nodeType===Node.ELEMENT_NODE&&node.dataset.oeProtected!=="false"&&node.dataset.oeProtected!==undefined);}
__exports.isUnprotecting=isUnprotecting;function isUnprotecting(node){if(!node){return false;}
return node.nodeType===Node.ELEMENT_NODE&&node.dataset.oeProtected==="false";}
const paragraphRelatedElements=__exports.paragraphRelatedElements=["P","H1","H2","H3","H4","H5","H6","PRE"];__exports.allowsParagraphRelatedElements=allowsParagraphRelatedElements;function allowsParagraphRelatedElements(node){return!isParagraphRelatedElement(node)&&isBlock(node);}
const phrasingContent=__exports.phrasingContent=new Set(["#text",...phrasingTagNames]);const flowContent=new Set([...phrasingContent,...paragraphRelatedElements,"DIV","HR"]);const listItem=__exports.listItem=new Set(["LI"]);const listContainers=new Set(["UL","OL"]);const allowedContent={BLOCKQUOTE:flowContent,DIV:flowContent,H1:phrasingContent,H2:phrasingContent,H3:phrasingContent,H4:phrasingContent,H5:phrasingContent,H6:phrasingContent,HR:new Set(),LI:flowContent,OL:listItem,UL:listItem,P:phrasingContent,PRE:phrasingContent,TD:flowContent,TR:new Set(["TD"]),};__exports.isParagraphRelatedElement=isParagraphRelatedElement;function isParagraphRelatedElement(node){if(!node){return false;}
return(paragraphRelatedElements.includes(node.nodeName)||(node.nodeType===Node.ELEMENT_NODE&&node.matches(baseContainerGlobalSelector)));}
const paragraphRelatedElementsSelector=__exports.paragraphRelatedElementsSelector=[...paragraphRelatedElements,baseContainerGlobalSelector,].join(",");__exports.isListItemElement=isListItemElement;function isListItemElement(node){return[...listItem].includes(node.nodeName);}
const listItemElementSelector=__exports.listItemElementSelector=[...listItem].join(",");__exports.isListElement=isListElement;function isListElement(node){return[...listContainers].includes(node.nodeName);}
const listElementSelector=__exports.listElementSelector=[...listContainers].join(",");__exports.isTableCell=isTableCell;function isTableCell(node){return["TH","TD"].includes(node.nodeName);}
__exports.isAllowedContent=isAllowedContent;function isAllowedContent(parentBlock,nodes){let allowedContentSet=allowedContent[parentBlock.nodeName];if(!allowedContentSet){return true;}
if(parentBlock.matches(baseContainerGlobalSelector)){allowedContentSet=phrasingContent;}
return nodes.every((node)=>allowedContentSet.has(node.nodeName));}
__exports.isEmptyBlock=isEmptyBlock;function isEmptyBlock(blockEl){if(!blockEl||blockEl.nodeType!==Node.ELEMENT_NODE){return false;}
if(visibleCharRegex.test(blockEl.textContent)){return false;}
if(blockEl.querySelectorAll("br").length>=2){return false;}
if(isProtecting(blockEl)||isProtected(blockEl)){return false;}
const nodes=blockEl.querySelectorAll("*");for(const node of nodes){if(node.nodeName!="BR"&&(isSelfClosingElement(node)||isMediaElement(node)||isProtecting(node)||isButton(node))){return false;}}
return isBlock(blockEl);}
__exports.isShrunkBlock=isShrunkBlock;function isShrunkBlock(blockEl){return(isElement(blockEl)&&!blockEl.querySelector("br")&&!isSelfClosingElement(blockEl)&&isEmptyBlock(blockEl));}
__exports.isEditorTab=isEditorTab;function isEditorTab(node){return node&&node.nodeName==="SPAN"&&node.classList.contains("oe-tabs");}
__exports.getDeepestPosition=getDeepestPosition;function getDeepestPosition(node,offset){let direction=DIRECTIONS.RIGHT;let next=node;while(next){if(isTangible(next)||(isZWS(next)&&isContentEditable(next))){if(next!==node){[node,offset]=[next,direction?0:nodeSize(next)];}
const childrenNodes=childNodes(node);direction=offset<childrenNodes.length;next=childrenNodes[direction?offset:offset-1];}else if(direction&&next.nextSibling&&closestBlock(node).contains(next.nextSibling)){next=next.nextSibling;}else{direction=DIRECTIONS.LEFT;next=closestBlock(node).contains(next.previousSibling)&&next.previousSibling;}
next=!isSelfClosingElement(next)&&next;}
return[node,offset];}
__exports.getDeepestEditablePosition=getDeepestEditablePosition;function getDeepestEditablePosition(node,offset){const[deepNode,deepOffset]=getDeepestPosition(node,offset);if(isContentEditable(deepNode)){return[deepNode,deepOffset];}
const nodeLevelAncestor=isTextNode(deepNode)&&deepNode.parentElement===node?deepNode:closestElement(deepNode,(el)=>el.parentElement===node);const closestNonEditable=closestElement(deepNode,(el)=>!isContentEditable(el)&&isContentEditable(el.parentElement));const nodeLevelAncestorIndex=childNodeIndex(nodeLevelAncestor);const closestNonEditableIndex=childNodeIndex(closestNonEditable);const deepEditableNode=closestNonEditable.parentElement;const deepEditableOffset=nodeLevelAncestorIndex<offset?closestNonEditableIndex+1:closestNonEditableIndex;if(deepEditableOffset===closestNonEditableIndex){const previousSiblingOfNonEditable=closestNonEditable.previousSibling;if(previousSiblingOfNonEditable){if(isTextNode(previousSiblingOfNonEditable)){return[previousSiblingOfNonEditable,nodeSize(previousSiblingOfNonEditable)];}else if(isElement(previousSiblingOfNonEditable)&&previousSiblingOfNonEditable.childNodes.length){return getDeepestEditablePosition(previousSiblingOfNonEditable,nodeSize(previousSiblingOfNonEditable));}}}
return[deepEditableNode,deepEditableOffset];}
__exports.previousLeaf=previousLeaf;function previousLeaf(node,editable,skipInvisible=false){let ancestor=node;while(ancestor&&!ancestor.previousSibling&&ancestor!==editable){ancestor=ancestor.parentElement;}
if(ancestor&&ancestor!==editable){if(skipInvisible&&!isVisible(ancestor.previousSibling)){return previousLeaf(ancestor.previousSibling,editable,skipInvisible);}else{const last=lastLeaf(ancestor.previousSibling);if(skipInvisible&&!isVisible(last)){return previousLeaf(last,editable,skipInvisible);}else{return last;}}}}
__exports.nextLeaf=nextLeaf;function nextLeaf(node,editable,skipInvisible=false){let ancestor=node;while(ancestor&&!ancestor.nextSibling&&ancestor!==editable){ancestor=ancestor.parentElement;}
if(ancestor&&ancestor!==editable){if(skipInvisible&&ancestor.nextSibling&&!isVisible(ancestor.nextSibling)){return nextLeaf(ancestor.nextSibling,editable,skipInvisible);}else{const first=firstLeaf(ancestor.nextSibling);if(skipInvisible&&!isVisible(first)){return nextLeaf(first,editable,skipInvisible);}else{return first;}}}}
function hasPseudoElementContent(node,pseudoSelector){const content=getComputedStyle(node,pseudoSelector).getPropertyValue("content");return content&&content!=="none";}
const NOT_A_NUMBER=/[^\d]/g;__exports.areSimilarElements=areSimilarElements;function areSimilarElements(node,node2){if(![node,node2].every((n)=>n?.nodeType===Node.ELEMENT_NODE)){return false;}
if(node.nodeName!==node2.nodeName){return false;}
for(const name of new Set([...node.getAttributeNames(),...node2.getAttributeNames()])){if(name==="style"){if(!hasSameStyleAttributes(node,node2)){return false;}}else if(name==="class"){if(!hasSameClasses(node,node2)){return false;}}else if(node.getAttribute(name)!==node2.getAttribute(name)){return false;}}
if([node,node2].some((n)=>hasPseudoElementContent(n,":before")||hasPseudoElementContent(n,":after"))){return false;}
if(isBlock(node)){return false;}
const nodeStyle=getComputedStyle(node);const node2Style=getComputedStyle(node2);if(node.matches("code.o_inline_code")){if(nodeStyle.padding===node2Style.padding&&nodeStyle.margin===node2Style.margin){return true;}}
return(!+nodeStyle.padding.replace(NOT_A_NUMBER,"")&&!+node2Style.padding.replace(NOT_A_NUMBER,"")&&!+nodeStyle.margin.replace(NOT_A_NUMBER,"")&&!+node2Style.margin.replace(NOT_A_NUMBER,""));}
__exports.hasSameStyleAttributes=hasSameStyleAttributes;function hasSameStyleAttributes(node,node2){const getNodeStyles=(node)=>(node.getAttribute("style")||"").split(";").map((style)=>style.trim()).filter(Boolean);const[nodeStyles,node2Styles]=[node,node2].map(getNodeStyles);return(nodeStyles.length===node2Styles.length&&nodeStyles.every((style)=>node2Styles.includes(style)));}
__exports.hasSameClasses=hasSameClasses;function hasSameClasses(node,node2){const getNodeClasses=(node)=>(node.getAttribute("class")||"").split(/\s+/).map((c)=>c.trim()).filter(Boolean);const[nodeClasses,node2Classes]=[node,node2].map(getNodeClasses);return(nodeClasses.length===node2Classes.length&&nodeClasses.every((cls)=>node2Classes.includes(cls)));}
__exports.isTextNode=isTextNode;function isTextNode(node){return node.nodeType===Node.TEXT_NODE;}
__exports.isElement=isElement;function isElement(node){return node.nodeType===Node.ELEMENT_NODE;}
__exports.isContentEditable=isContentEditable;function isContentEditable(node){const element=isTextNode(node)?node.parentElement:node;return element&&element.isContentEditable;}
__exports.isContentEditableAncestor=isContentEditableAncestor;function isContentEditableAncestor(node){if(node.nodeType!==Node.ELEMENT_NODE){return false;}
return node.isContentEditable&&node.matches("[contenteditable]");}
function hasClassesSubset(node,node2){const getNodeClasses=(n)=>(n||"").trim().split(/\s+/).filter(Boolean);const[nodeClasses,node2Classes]=[node,node2].map(getNodeClasses);return nodeClasses.every((cls)=>node2Classes.includes(cls));}
function hasStylesSubset(node,node2){const getNodeStyles=(n)=>(n||"").split(";").map((s)=>s.trim()).filter(Boolean);const[nodeStyles,node2Styles]=[node,node2].map(getNodeStyles);return nodeStyles.every((style)=>node2Styles.includes(style));}
__exports.isRedundantElement=isRedundantElement;function isRedundantElement(node){if(!node||node.nodeType!==Node.ELEMENT_NODE||!node.parentElement){return false;}
const closestEl=closestElement(node.parentElement,node.tagName);if(!closestEl){return false;}
for(const{name:attrName,value:nodeAttrVal}of node.attributes){const closestElAttrVal=closestEl.getAttribute(attrName);if(!closestElAttrVal){return false;}
if(attrName==="class"){if(!hasClassesSubset(nodeAttrVal,closestElAttrVal)){return false;}}else if(attrName==="style"){if(!hasStylesSubset(nodeAttrVal,closestElAttrVal)){return false;}}else{if(nodeAttrVal!==closestElAttrVal){return false;}}}
return true;}
const PROTECTED_QWEB_SELECTOR=__exports.PROTECTED_QWEB_SELECTOR="[t-esc], [t-raw], [t-out], [t-field]";return __exports;});;
/* /html_editor/static/src/utils/dom_state.js */
odoo.define('@html_editor/utils/dom_state',['@html_editor/utils/blocks','@html_editor/utils/content_types','@html_editor/utils/dom_info','@html_editor/utils/dom_traversal','@html_editor/utils/position'],function(require){'use strict';let __exports={};const{isBlock}=require("@html_editor/utils/blocks");const{CTGROUPS,CTYPES,ctypeToString}=require("@html_editor/utils/content_types");const{isInPre,isVisible,isWhitespace,whitespace}=require("@html_editor/utils/dom_info");const{PATH_END_REASONS,ancestors,closestElement,closestPath,createDOMPathGenerator,}=require("@html_editor/utils/dom_traversal");const{DIRECTIONS,leftPos,rightPos}=require("@html_editor/utils/position");const prepareUpdateLockedEditables=new Set();__exports.prepareUpdate=prepareUpdate;function prepareUpdate(...args){const closestRoot=args.length&&ancestors(args[0]).find((ancestor)=>ancestor.classList.contains("odoo-editor-editable"));const isPrepareUpdateLocked=closestRoot&&prepareUpdateLockedEditables.has(closestRoot);const hash=(Math.random()+1).toString(36).substring(7);const options={allowReenter:true,label:hash,debug:false,...(args.length&&args[args.length-1]instanceof Object?args.pop():{}),};if(options.debug){console.log("%cPreparing%c update: "+
options.label+
(options.label===hash?"":` (${hash})`)+"%c"+
(isPrepareUpdateLocked?" LOCKED":""),"color: cyan;","color: white;","color: red; font-weight: bold;");}
if(isPrepareUpdateLocked){return()=>{if(options.debug){console.log("%cRestoring%c update: "+
options.label+
(options.label===hash?"":` (${hash})`)+"%c LOCKED","color: lightgreen;","color: white;","color: red; font-weight: bold;");}};}
if(!options.allowReenter&&closestRoot){prepareUpdateLockedEditables.add(closestRoot);}
const positions=[...args];const restoreData=[];let el,offset;while(positions.length){offset=positions.pop();el=positions.pop();const left=getState(el,offset,DIRECTIONS.LEFT);const right=getState(el,offset,DIRECTIONS.RIGHT,left.cType);if(options.debug){const editable=el&&closestElement(el,".odoo-editor-editable");const oldEditableHTML=(editable&&editable.innerHTML.replaceAll(" ","_").replaceAll("\u200B","ZWS"))||"";left.oldEditableHTML=oldEditableHTML;right.oldEditableHTML=oldEditableHTML;}
restoreData.push(left,right);}
return function restoreStates(){if(options.debug){console.log("%cRestoring%c update: "+
options.label+
(options.label===hash?"":` (${hash})`),"color: lightgreen;","color: white;");}
for(const data of restoreData){restoreState(data,options.debug);}
if(!options.allowReenter&&closestRoot){prepareUpdateLockedEditables.delete(closestRoot);}};}
const leftLeafOnlyNotBlockPath=__exports.leftLeafOnlyNotBlockPath=createDOMPathGenerator(DIRECTIONS.LEFT,{leafOnly:true,stopTraverseFunction:isBlock,stopFunction:isBlock,});const rightLeafOnlyNotBlockPath=createDOMPathGenerator(DIRECTIONS.RIGHT,{leafOnly:true,stopTraverseFunction:isBlock,stopFunction:isBlock,});__exports.getState=getState;function getState(el,offset,direction,leftCType){const leftDOMPath=leftLeafOnlyNotBlockPath;const rightDOMPath=rightLeafOnlyNotBlockPath;let domPath;let inverseDOMPath;const whitespaceAtStartRegex=new RegExp("^"+whitespace+"+");const whitespaceAtEndRegex=new RegExp(whitespace+"+$");const reasons=[];if(direction===DIRECTIONS.LEFT){domPath=leftDOMPath(el,offset,reasons);inverseDOMPath=rightDOMPath(el,offset);}else{domPath=rightDOMPath(el,offset,reasons);inverseDOMPath=leftDOMPath(el,offset);}
const boundaryNode=inverseDOMPath.next().value;let cType=undefined;let lastSpace=null;for(const node of domPath){if(node.nodeType===Node.TEXT_NODE){const value=node.nodeValue;if(direction===DIRECTIONS.LEFT){if(!isWhitespace(value)){if(lastSpace){cType=CTYPES.SPACE;}else{const rightLeaf=rightLeafOnlyNotBlockPath(node).next().value;const hasContentRight=rightLeaf&&!whitespaceAtStartRegex.test(rightLeaf.textContent);cType=!hasContentRight&&whitespaceAtEndRegex.test(node.textContent)?CTYPES.SPACE:CTYPES.CONTENT;}
break;}
if(value.length){lastSpace=node;}}else{leftCType=leftCType||getState(el,offset,DIRECTIONS.LEFT).cType;if(whitespaceAtStartRegex.test(value)){const leftLeaf=leftLeafOnlyNotBlockPath(node).next().value;const hasContentLeft=leftLeaf&&!whitespaceAtEndRegex.test(leftLeaf.textContent);const rct=!isWhitespace(value)?CTYPES.CONTENT:getState(...rightPos(node),DIRECTIONS.RIGHT).cType;cType=leftCType&CTYPES.CONTENT&&rct&(CTYPES.CONTENT|CTYPES.BR)&&!hasContentLeft?CTYPES.SPACE:rct;break;}
if(!isWhitespace(value)){cType=CTYPES.CONTENT;break;}}}else if(node.nodeName==="BR"){cType=CTYPES.BR;break;}else if(isVisible(node)){cType=CTYPES.CONTENT;break;}}
if(cType===undefined){cType=reasons.includes(PATH_END_REASONS.BLOCK_HIT)?CTYPES.BLOCK_OUTSIDE:CTYPES.BLOCK_INSIDE;}
return{node:boundaryNode,direction:direction,cType:cType,};}
const priorityRestoreStateRules=[[{cType1:CTYPES.CONTENT,cType2:CTYPES.SPACE|CTGROUPS.BLOCK},{spaceVisibility:true},],[{direction:DIRECTIONS.LEFT,cType1:CTGROUPS.INLINE,cType2:CTGROUPS.BR},{spaceVisibility:true},],[{direction:DIRECTIONS.RIGHT,cType1:CTGROUPS.CONTENT,cType2:CTGROUPS.BR},{spaceVisibility:true},],[{direction:DIRECTIONS.RIGHT,cType1:CTGROUPS.BR,cType2:CTYPES.SPACE},{spaceVisibility:true},],[{direction:DIRECTIONS.RIGHT,cType1:CTGROUPS.BR,cType2:CTGROUPS.BLOCK},{spaceVisibility:true,brVisibility:true},],[{cType1:CTYPES.SPACE},{spaceVisibility:false},],[{direction:DIRECTIONS.LEFT,cType1:CTGROUPS.BR},{spaceVisibility:false},],[{cType1:CTGROUPS.BLOCK,cType2:CTGROUPS.INLINE|CTGROUPS.BR},{spaceVisibility:false},],[{direction:DIRECTIONS.RIGHT,cType1:CTGROUPS.INLINE,cType2:CTGROUPS.BLOCK},{brVisibility:true},],[{direction:DIRECTIONS.RIGHT,cType1:CTGROUPS.BLOCK,cType2:CTGROUPS.INLINE|CTGROUPS.BR,},{brVisibility:false},],[{direction:DIRECTIONS.LEFT,cType1:CTGROUPS.BR|CTGROUPS.BLOCK,cType2:CTGROUPS.INLINE,},{brVisibility:false,extraBRRemovalCondition:(brNode)=>isFakeLineBreak(brNode)},],];function restoreStateRuleHashCode(direction,cType1,cType2){return`${direction}-${cType1}-${cType2}`;}
const allRestoreStateRules=(function(){const map=new Map();const keys=["direction","cType1","cType2"];for(const direction of Object.values(DIRECTIONS)){for(const cType1 of Object.values(CTYPES)){for(const cType2 of Object.values(CTYPES)){const rule={direction:direction,cType1:cType1,cType2:cType2};const matchedRules=[];for(const entry of priorityRestoreStateRules){let priority=0;for(const key of keys){const entryKeyValue=entry[0][key];if(entryKeyValue!==undefined){if(typeof entryKeyValue==="boolean"?rule[key]===entryKeyValue:rule[key]&entryKeyValue){priority++;}else{priority=-1;break;}}}
if(priority>=0){matchedRules.push([priority,entry[1]]);}}
const finalRule={};for(let p=0;p<=keys.length;p++){for(const entry of matchedRules){if(entry[0]===p){Object.assign(finalRule,entry[1]);}}}
const hashCode=restoreStateRuleHashCode(direction,cType1,cType2);map.set(hashCode,finalRule);}}}
return map;})();__exports.restoreState=restoreState;function restoreState(prevStateData,debug=false){const{node,direction,cType:cType1,oldEditableHTML}=prevStateData;if(!node||!node.parentNode){return;}
const[el,offset]=direction===DIRECTIONS.LEFT?leftPos(node):rightPos(node);const{cType:cType2}=getState(el,offset,direction);const ruleHashCode=restoreStateRuleHashCode(direction,cType1,cType2);const rule=allRestoreStateRules.get(ruleHashCode);if(debug){const editable=closestElement(node,".odoo-editor-editable");console.log("%c"+
node.textContent.replaceAll(" ","_").replaceAll("\u200B","ZWS")+"\n"+"%c"+
(direction===DIRECTIONS.LEFT?"left":"right")+"\n"+"%c"+
ctypeToString(cType1)+"\n"+"%c"+
ctypeToString(cType2)+"\n"+"%c"+"BEFORE: "+
(oldEditableHTML||"(unavailable)")+"\n"+"%c"+"AFTER: "+
(editable?editable.innerHTML.replaceAll(" ","_").replaceAll("\u200B","ZWS"):"(unavailable)")+"\n","color: white; display: block; width: 100%;","color: "+
(direction===DIRECTIONS.LEFT?"magenta":"lightgreen")+"; display: block; width: 100%;","color: pink; display: block; width: 100%;","color: lightblue; display: block; width: 100%;","color: white; display: block; width: 100%;","color: white; display: block; width: 100%;",rule);}
if(Object.values(rule).filter((x)=>x!==undefined).length){const inverseDirection=direction===DIRECTIONS.LEFT?DIRECTIONS.RIGHT:DIRECTIONS.LEFT;enforceWhitespace(el,offset,inverseDirection,rule);}
return rule;}
__exports.isFakeLineBreak=isFakeLineBreak;function isFakeLineBreak(brEl){return!(getState(...rightPos(brEl),DIRECTIONS.RIGHT).cType&(CTYPES.CONTENT|CTGROUPS.BR));}
__exports.enforceWhitespace=enforceWhitespace;function enforceWhitespace(el,offset,direction,rule){const document=el.ownerDocument;let domPath,whitespaceAtEdgeRegex;if(direction===DIRECTIONS.LEFT){domPath=leftLeafOnlyNotBlockPath(el,offset);whitespaceAtEdgeRegex=new RegExp(whitespace+"+$");}else{domPath=rightLeafOnlyNotBlockPath(el,offset);whitespaceAtEdgeRegex=new RegExp("^"+whitespace+"+");}
const invisibleSpaceTextNodes=[];let foundVisibleSpaceTextNode=null;for(const node of domPath){if(node.nodeName==="BR"){if(rule.brVisibility===undefined){break;}
if(rule.brVisibility){node.before(document.createElement("br"));}else{if(!rule.extraBRRemovalCondition||rule.extraBRRemovalCondition(node)){node.remove();}}
break;}else if(node.nodeType===Node.TEXT_NODE&&!isInPre(node)){if(whitespaceAtEdgeRegex.test(node.nodeValue)){if(!isWhitespace(node)){foundVisibleSpaceTextNode=node;break;}else{invisibleSpaceTextNodes.push(node);}}else if(!isWhitespace(node)){break;}}else{break;}}
if(rule.spaceVisibility===undefined){return;}
if(!rule.spaceVisibility){for(const node of invisibleSpaceTextNodes){node.nodeValue="";const ancestorPath=closestPath(node.parentNode);let toRemove=null;for(const pNode of ancestorPath){if(toRemove){toRemove.remove();}
if(pNode.childNodes.length===1&&!isBlock(pNode)){pNode.after(node);toRemove=pNode;}else{break;}}}}
const spaceNode=foundVisibleSpaceTextNode||invisibleSpaceTextNodes[0];if(spaceNode){let spaceVisibility=rule.spaceVisibility;if(spaceVisibility&&!foundVisibleSpaceTextNode&&getState(...rightPos(spaceNode),DIRECTIONS.RIGHT).cType&CTGROUPS.BLOCK&&getState(...leftPos(spaceNode),DIRECTIONS.LEFT).cType!==CTYPES.CONTENT){spaceVisibility=false;}
spaceNode.nodeValue=spaceNode.nodeValue.replace(whitespaceAtEdgeRegex,spaceVisibility?"\u00A0":"");}}
__exports.observeMutations=observeMutations;function observeMutations(target,observerOptions){const records=[];const observerCallback=(mutations)=>records.push(...mutations);const observer=new MutationObserver(observerCallback);observer.observe(target,observerOptions);return()=>{observerCallback(observer.takeRecords());observer.disconnect();return records;};}
return __exports;});;
/* /html_editor/static/src/utils/dom_traversal.js */
odoo.define('@html_editor/utils/dom_traversal',['@html_editor/utils/position'],function(require){'use strict';let __exports={};const{DIRECTIONS}=require("@html_editor/utils/position");const closestPath=__exports.closestPath=function*(node){while(node){yield node;node=node.parentNode;}};__exports.findNode=findNode;function findNode(domPath,findCallback=()=>true,stopCallback=()=>false){for(const node of domPath){if(findCallback(node)){return node;}
if(stopCallback(node)){break;}}
return null;}
__exports.findUpTo=findUpTo;function findUpTo(node,limitAncestor,predicate){while(node!==limitAncestor){if(predicate(node)){return node;}
node=node.parentElement;}
return null;}
__exports.findFurthest=findFurthest;function findFurthest(node,limitAncestor,predicate){const nodes=[];while(node!==limitAncestor){nodes.push(node);node=node.parentNode;}
return nodes.findLast(predicate);}
__exports.closestElement=closestElement;function closestElement(node,predicate="*"){let element=node.nodeType===Node.ELEMENT_NODE?node:node.parentElement;const editable=element?.closest(".odoo-editor-editable");if(typeof predicate==="function"){while(element&&!predicate(element)){element=element.parentElement;}}else{element=element?.closest(predicate);}
if((editable&&editable.contains(element))||!node.isConnected){return element;}
return null;}
__exports.ancestors=ancestors;function ancestors(node,editable){const result=[];while(node&&node.parentElement&&node!==editable){result.push(node.parentElement);node=node.parentElement;}
return result;}
__exports.children=children;function children(elem){const children=[];let child=elem.firstElementChild;while(child){children.push(child);child=child.nextElementSibling;}
return children;}
__exports.childNodes=childNodes;function childNodes(node){const childNodes=[];let child=node.firstChild;while(child){childNodes.push(child);child=child.nextSibling;}
return childNodes;}
__exports.descendants=descendants;function descendants(node,posterity=[]){let child=node.firstChild;while(child){posterity.push(child);descendants(child,posterity);child=child.nextSibling;}
return posterity;}
const PATH_END_REASONS=__exports.PATH_END_REASONS={NO_NODE:0,BLOCK_OUT:1,BLOCK_HIT:2,OUT_OF_SCOPE:3,};__exports.createDOMPathGenerator=createDOMPathGenerator;function createDOMPathGenerator(direction,{leafOnly=false,inScope=false,stopTraverseFunction,stopFunction}={}){const nextDeepest=direction===DIRECTIONS.LEFT?(node)=>lastLeaf(node.previousSibling,stopTraverseFunction):(node)=>firstLeaf(node.nextSibling,stopTraverseFunction);const firstNode=direction===DIRECTIONS.LEFT?(node,offset)=>lastLeaf(node.childNodes[offset-1],stopTraverseFunction):(node,offset)=>firstLeaf(node.childNodes[offset],stopTraverseFunction);return function*(node,offset,reasons=[]){let movedUp=false;let currentNode=firstNode(node,offset);if(!currentNode){movedUp=true;currentNode=node;}
while(currentNode){if(stopFunction&&stopFunction(currentNode)){reasons.push(movedUp?PATH_END_REASONS.BLOCK_OUT:PATH_END_REASONS.BLOCK_HIT);break;}
if(inScope&&currentNode===node){reasons.push(PATH_END_REASONS.OUT_OF_SCOPE);break;}
if(!(leafOnly&&movedUp)){yield currentNode;}
movedUp=false;let nextNode=nextDeepest(currentNode);if(!nextNode){movedUp=true;nextNode=currentNode.parentNode;}
currentNode=nextNode;}
reasons.push(PATH_END_REASONS.NO_NODE);};}
__exports.lastLeaf=lastLeaf;function lastLeaf(node,stopTraverseFunction){while(node&&node.lastChild&&!(stopTraverseFunction&&stopTraverseFunction(node))){node=node.lastChild;}
return node;}
__exports.firstLeaf=firstLeaf;function firstLeaf(node,stopTraverseFunction){while(node&&node.firstChild&&!(stopTraverseFunction&&stopTraverseFunction(node))){node=node.firstChild;}
return node;}
__exports.getAdjacentPreviousSiblings=getAdjacentPreviousSiblings;function getAdjacentPreviousSiblings(node,predicate=(n)=>!!n){let previous=node.previousSibling;const list=[];while(previous&&predicate(previous)){list.push(previous);previous=previous.previousSibling;}
return list;}
__exports.getAdjacentNextSiblings=getAdjacentNextSiblings;function getAdjacentNextSiblings(node,predicate=(n)=>!!n){let next=node.nextSibling;const list=[];while(next&&predicate(next)){list.push(next);next=next.nextSibling;}
return list;}
__exports.getAdjacents=getAdjacents;function getAdjacents(node,predicate=(n)=>!!n){const previous=getAdjacentPreviousSiblings(node,predicate);const next=getAdjacentNextSiblings(node,predicate);return predicate(node)?[...previous.reverse(),node,...next]:[];}
__exports.getCommonAncestor=getCommonAncestor;function getCommonAncestor(nodes,root=undefined){const pathsToRoot=nodes.map((node)=>[node,...ancestors(node,root)]);let candidate=pathsToRoot[0]?.at(-1);if(root&&candidate!==root){return null;}
let commonAncestor=null;while(candidate&&pathsToRoot.every((path)=>path.at(-1)===candidate)){commonAncestor=candidate;pathsToRoot.forEach((path)=>path.pop());candidate=pathsToRoot[0].at(-1);}
return commonAncestor;}
const selectElements=__exports.selectElements=function*(root,selector){if(root.matches(selector)){yield root;}
for(const elem of root.querySelectorAll(selector)){yield elem;}};return __exports;});;
/* /html_editor/static/src/utils/drag_and_drop.js */
odoo.define('@html_editor/utils/drag_and_drop',['@web/core/utils/draggable_hook_builder','@web/core/utils/objects','@odoo/owl','@web/core/utils/timing','@web/core/utils/ui'],function(require){'use strict';let __exports={};const{makeDraggableHook}=require("@web/core/utils/draggable_hook_builder");const{pick}=require("@web/core/utils/objects");const{reactive}=require("@odoo/owl");const{throttleForAnimation}=require("@web/core/utils/timing");const{closest,touching}=require("@web/core/utils/ui");__exports.useNativeDraggable=useNativeDraggable;function useNativeDraggable(hookParams,initialParams){const setupFunctions=new Map();const cleanupFunctions=[];const currentParams={...initialParams};const setupHooks={wrapState:reactive,throttle:throttleForAnimation,addListener:(el,type,callback,options)=>{el.addEventListener(type,callback,options);cleanupFunctions.push(()=>el.removeEventListener(type,callback));},setup:(setupFn,depsFn)=>setupFunctions.set(setupFn,depsFn),teardown:(cleanupFn)=>{cleanupFunctions.push(cleanupFn);},};const el=initialParams.ref.el;el.classList.add("o_draggable");cleanupFunctions.push(()=>el.classList.remove("o_draggable"));const draggableState=makeDraggableHook({setupHooks,...hookParams})(currentParams);draggableState.enable=true;const draggableComponent={state:draggableState,update:(newParams)=>{Object.assign(currentParams,newParams);setupFunctions.forEach((depsFn,setupFn)=>setupFn(...depsFn()));},destroy:()=>{cleanupFunctions.forEach((cleanupFn)=>cleanupFn());},};draggableComponent.update({});return draggableComponent;}
function updateElementPosition(el,{x,y},styleFn,offset={x:0,y:0}){return styleFn(el,{top:`${y - offset.y}px`,left:`${x - offset.x}px`});}
const dragAndDropHookParams={name:"useDragAndDrop",acceptedParams:{dropzones:[Function],scrollingElement:[Function],helper:[Function],extraWindow:[Object,Function],},edgeScrolling:{enabled:true},onComputeParams({ctx,params}){ctx.followCursor=false;ctx.getScrollingElement=params.scrollingElement;ctx.getHelper=params.helper;ctx.getDropZones=params.dropzones;},onWillStartDrag:({ctx})=>{ctx.current.container=ctx.getScrollingElement();ctx.current.helperOffset={x:0,y:0};},onDragStart:({ctx,addStyle,addCleanup})=>{ctx.current.helper=ctx.getHelper({...ctx.current,...ctx.pointer});ctx.current.helper.style.position="fixed";ctx.current.element.classList.remove("o_dragged");ctx.current.helper.style.cursor=ctx.cursor;ctx.current.helper.style.pointerEvents="auto";const frameElement=ctx.current.helper.ownerDocument.defaultView.frameElement;if(frameElement){addStyle(frameElement,{pointerEvents:"auto"});}
addCleanup(()=>ctx.current.helper.remove());updateElementPosition(ctx.current.helper,ctx.pointer,addStyle,ctx.current.helperOffset);return pick(ctx.current,"element","helper");},onDrag:({ctx,addStyle,callHandler})=>{ctx.current.helper.classList.add("o_draggable_dragging");updateElementPosition(ctx.current.helper,ctx.pointer,addStyle,ctx.current.helperOffset);let helperRect=ctx.current.helper.getBoundingClientRect();helperRect={x:helperRect.x,y:helperRect.y,width:helperRect.width,height:helperRect.height,};const dropzoneEl=closest(touching(ctx.getDropZones(),helperRect),helperRect);if(ctx.current.dropzone?.el&&ctx.current.dropzone.el.classList.contains("oe_grid_zone")){ctx.current.dropzone.rect=ctx.current.dropzone.el.getBoundingClientRect();}
if(ctx.current.dropzone&&(ctx.current.dropzone.el===dropzoneEl||(!dropzoneEl&&touching([ctx.current.helper],ctx.current.dropzone.rect).length>0))){return pick(ctx.current,"element","dropzone","helper");}
if(ctx.current.dropzone&&dropzoneEl!==ctx.current.dropzone.el){callHandler("dropzoneOut",{dropzone:ctx.current.dropzone,helper:ctx.current.helper,});delete ctx.current.dropzone;}
if(dropzoneEl){const rect=DOMRect.fromRect(dropzoneEl.getBoundingClientRect());ctx.current.dropzone={el:dropzoneEl,rect:{x:rect.x,y:rect.y,width:rect.width,height:rect.height,},};callHandler("dropzoneOver",{dropzone:ctx.current.dropzone,helper:ctx.current.helper,});}
return pick(ctx.current,"element","dropzone","helper");},onDragEnd({ctx}){return pick(ctx.current,"element","dropzone","helper");},};__exports.useDragAndDrop=useDragAndDrop;function useDragAndDrop(initialParams){return useNativeDraggable(dragAndDropHookParams,initialParams);}
return __exports;});;
/* /html_editor/static/src/utils/fonts.js */
odoo.define('@html_editor/utils/fonts',[],function(require){'use strict';let __exports={};const fonts=__exports.fonts={cacheCssSelectors:{},getCssSelectors:function(filter){if(this.cacheCssSelectors[filter]){return this.cacheCssSelectors[filter];}
this.cacheCssSelectors[filter]=[];var sheets=document.styleSheets;for(var i=0;i<sheets.length;i++){var rules;try{rules=sheets[i].rules||sheets[i].cssRules;}catch{continue;}
if(!rules){continue;}
for(var r=0;r<rules.length;r++){var selectorText=rules[r].selectorText;if(!selectorText){continue;}
var selectors=selectorText.split(/\s*,\s*/);var data=null;for(var s=0;s<selectors.length;s++){var match=selectors[s].trim().match(filter);if(!match){continue;}
if(!data){data={selector:match[0],css:rules[r].cssText.replace(/(^.*\{\s*)|(\s*\}\s*$)/g,""),names:[match[1]],};}else{data.selector+=", "+match[0];data.names.push(match[1]);}}
if(data){this.cacheCssSelectors[filter].push(data);}}}
return this.cacheCssSelectors[filter];},fontIcons:[{base:"fa",parser:/\.(fa-(?:\w|-)+)::?before/i}],computedFonts:false,computeFonts:function(){if(!this.computedFonts){var self=this;this.fontIcons.forEach((data)=>{data.cssData=self.getCssSelectors(data.parser);data.alias=data.cssData.map((x)=>x.names).flat();});this.computedFonts=true;}},};return __exports;});;
/* /html_editor/static/src/utils/formatting.js */
odoo.define('@html_editor/utils/formatting',['@web/core/utils/colors','@html_editor/utils/dom','@html_editor/utils/dom_info','@html_editor/utils/dom_traversal','@html_editor/utils/blocks'],function(require){'use strict';let __exports={};const{normalizeCSSColor}=require("@web/core/utils/colors");const{removeClass}=require("@html_editor/utils/dom");const{isBold,isDirectionSwitched,isItalic,isStrikeThrough,isUnderline}=require("@html_editor/utils/dom_info");const{closestElement,closestPath,findNode,findUpTo}=require("@html_editor/utils/dom_traversal");const{closestBlock,isBlock}=require("@html_editor/utils/blocks");const FONT_SIZE_CLASSES=__exports.FONT_SIZE_CLASSES=["display-1-fs","display-2-fs","display-3-fs","display-4-fs","h1-fs","h2-fs","h3-fs","h4-fs","h5-fs","h6-fs","base-fs","small","o_small-fs",];const TEXT_STYLE_CLASSES=__exports.TEXT_STYLE_CLASSES=["display-1","display-2","display-3","display-4","lead"];const DEFAULT_FONT_SIZE_CLASSES=__exports.DEFAULT_FONT_SIZE_CLASSES=["h1","h2","h3","h4","h5","h6","o_default_font_size",];const FORMATTABLE_TAGS=__exports.FORMATTABLE_TAGS=["SPAN","FONT","B","STRONG","I","EM","U","S","CODE"];const formatsSpecs=__exports.formatsSpecs={italic:{tagName:"em",isFormatted:isItalic,isTag:(node)=>["EM","I"].includes(node.tagName),hasStyle:(node)=>Boolean(node.style&&node.style["font-style"]),addStyle:(node)=>(node.style["font-style"]="italic"),addNeutralStyle:(node)=>(node.style["font-style"]="normal"),removeStyle:(node)=>removeStyle(node,"font-style"),},bold:{tagName:"strong",isFormatted:isBold,isTag:(node)=>["STRONG","B"].includes(node.tagName),hasStyle:(node)=>Boolean(node.style&&node.style["font-weight"]),addStyle:(node)=>(node.style["font-weight"]="bolder"),addNeutralStyle:(node)=>{node.style["font-weight"]="normal";},removeStyle:(node)=>removeStyle(node,"font-weight"),},underline:{tagName:"u",isFormatted:isUnderline,isTag:(node)=>node.tagName==="U",hasStyle:(node)=>node.style&&(node.style["text-decoration"].includes("underline")||node.style["text-decoration-line"].includes("underline")),addStyle:(node)=>(node.style["text-decoration-line"]+=" underline"),removeStyle:(node)=>removeStyle(node,node.style["text-decoration"].includes("underline")?"text-decoration":"text-decoration-line","underline"),},strikeThrough:{tagName:"s",isFormatted:isStrikeThrough,isTag:(node)=>node.tagName==="S",hasStyle:(node)=>node.style&&(node.style["text-decoration"].includes("line-through")||node.style["text-decoration-line"].includes("line-through")),addStyle:(node)=>(node.style["text-decoration-line"]+=" line-through"),removeStyle:(node)=>removeStyle(node,node.style["text-decoration"].includes("line-through")?"text-decoration":"text-decoration-line","line-through"),},fontFamily:{isFormatted:(node)=>!!closestElement(node,(el)=>el.style["font-family"]),hasStyle:(node)=>node.style&&node.style["font-family"],addStyle:(node,props)=>{removeStyle(node,"font-family");if(props.fontFamily){node.style["font-family"]=props.fontFamily;}},removeStyle:(node)=>removeStyle(node,"font-family"),},fontSize:{isFormatted:(node,props)=>{const fontSize=(findNode(closestPath(node),(el)=>el.style?.["font-size"],isBlock)||closestElement(node,"li"))?.style["font-size"];return props?.size?fontSize===props.size:fontSize;},hasStyle:(node)=>node.style&&node.style["font-size"],addStyle:(node,props)=>{node.style["font-size"]=props.size;removeClass(node,...FONT_SIZE_CLASSES);},removeStyle:(node)=>removeStyle(node,"font-size"),},setFontSizeClassName:{isFormatted:(node,props)=>props?.className?FONT_SIZE_CLASSES.includes(props.className)&&!!(findNode(closestPath(node),(el)=>el.classList?.contains(props.className),(el)=>el===closestBlock(node).parentElement)||closestElement(node,"li")?.classList?.contains(props.className)):!!findNode(closestPath(node),(el)=>FONT_SIZE_CLASSES.find((cls)=>el.classList?.contains(cls)),(el)=>el===closestBlock(node).parentElement)||FONT_SIZE_CLASSES.find((cls)=>closestElement(node,"li")?.classList.contains(cls)),hasStyle:(node,props)=>[...FONT_SIZE_CLASSES,...TEXT_STYLE_CLASSES,...DEFAULT_FONT_SIZE_CLASSES].find((cls)=>node.classList.contains(cls)),addStyle:(node,props)=>{node.style.removeProperty("font-size");node.classList.add(props.className);},removeStyle:(node)=>{removeStyle(node,"font-size");removeClass(node,...FONT_SIZE_CLASSES);if(!isBlock(node)){removeClass(node,...TEXT_STYLE_CLASSES,...DEFAULT_FONT_SIZE_CLASSES);}},addNeutralStyle:function(node){const block=closestBlock(node);if(["H1","H2","H3","H4","H5","H6"].includes(block.nodeName)){node.classList.add(block.nodeName.toLowerCase());}else{node.classList.add("o_default_font_size");}},},switchDirection:{isFormatted:(node,props)=>isDirectionSwitched(node,props.editable),},};function removeStyle(node,styleName,item){if(item){const newStyle=node.style[styleName].split(" ").filter((x)=>x!==item).join(" ");node.style[styleName]=newStyle||null;}else{node.style[styleName]=null;}
if(node.getAttribute("style")===""){node.removeAttribute("style");}}
__exports.getCSSVariableValue=getCSSVariableValue;function getCSSVariableValue(key,htmlStyle){let value=htmlStyle.getPropertyValue(`--${key}`).trim();value=normalizeCSSColor(value);return value.replace(/"/g,"'");}
const CSS_UNITS_CONVERSION={"s-ms":()=>1000,"ms-s":()=>0.001,"rem-px":(htmlStyle)=>parseFloat(htmlStyle["font-size"]),"px-rem":(htmlStyle)=>1/parseFloat(htmlStyle["font-size"]),"%-px":()=>-1,"px-%":()=>-1,};__exports.convertNumericToUnit=convertNumericToUnit;function convertNumericToUnit(value,unitFrom,unitTo,htmlStyle){if(Math.abs(value)<Number.EPSILON||unitFrom===unitTo){return value;}
const converter=CSS_UNITS_CONVERSION[`${unitFrom}-${unitTo}`];if(converter===undefined){throw new Error(`Cannot convert '${unitFrom}' units into '${unitTo}' units !`);}
return value*converter(htmlStyle);}
__exports.getHtmlStyle=getHtmlStyle;function getHtmlStyle(document){return document.defaultView.getComputedStyle(document.documentElement);}
__exports.getFontSizeDisplayValue=getFontSizeDisplayValue;function getFontSizeDisplayValue(sel,document){const tagNameRelatedToFontSize=["h1","h2","h3","h4","h5","h6"];const closestStartContainerEl=closestElement(sel.startContainer);const closestFontSizedEl=findUpTo(closestStartContainerEl,closestStartContainerEl.closest(".o_default_font_size"),(n)=>n.matches(`
[style*='font-size'],
${FONT_SIZE_CLASSES.map((className) => `.${className}`)},
${TEXT_STYLE_CLASSES.map((className) => `.${className}`)},
${tagNameRelatedToFontSize}
`));let remValue;const htmlStyle=getHtmlStyle(document);if(closestFontSizedEl){const useFontSizeInput=closestFontSizedEl.style.fontSize;if(useFontSizeInput){return parseFloat(getComputedStyle(closestStartContainerEl).fontSize);}
const fontSizeClass=FONT_SIZE_CLASSES.find((className)=>closestFontSizedEl.classList.contains(className));let fsName;if(fontSizeClass){fsName=fontSizeClass.substring(0,fontSizeClass.length-3);}else{fsName=TEXT_STYLE_CLASSES.find((className)=>closestFontSizedEl.classList.contains(className))||closestFontSizedEl.tagName.toLowerCase();}
remValue=parseFloat(getCSSVariableValue(`${fsName}-font-size`,htmlStyle));}
const pxValue=remValue&&convertNumericToUnit(remValue,"rem","px",htmlStyle);return pxValue||parseFloat(getComputedStyle(closestStartContainerEl).fontSize);}
__exports.getFontSizeOrClass=getFontSizeOrClass;function getFontSizeOrClass(node){if(!node){return null;}
if(node.style.fontSize){return{type:"font-size",value:node.style.fontSize};}
const fontSizeClass=FONT_SIZE_CLASSES.find((cls)=>node.classList.contains(cls));if(fontSizeClass){return{type:"class",value:fontSizeClass};}
return null;}
return __exports;});;
/* /html_editor/static/src/utils/functions.js */
odoo.define('@html_editor/utils/functions',[],function(require){'use strict';let __exports={};__exports.weakMemoize=weakMemoize;function weakMemoize(func){const cache=new WeakMap();const funcName=func.name?func.name+" (memoized)":"memoized";return{[funcName](firstArg,...args){if(!cache.has(firstArg)){cache.set(firstArg,func(firstArg,...args));}
return cache.get(firstArg);},}[funcName];}
return __exports;});;
/* /html_editor/static/src/utils/html.js */
odoo.define('@html_editor/utils/html',[],function(require){'use strict';let __exports={};__exports.parseHTML=parseHTML;function parseHTML(document,html){const fragment=document.createDocumentFragment();const parser=new document.defaultView.DOMParser();const parsedDocument=parser.parseFromString(html,"text/html");fragment.replaceChildren(...parsedDocument.body.childNodes);return fragment;}
__exports.normalizeHTML=normalizeHTML;function normalizeHTML(content,cleanup=()=>{}){const parser=new document.defaultView.DOMParser();const body=parser.parseFromString(content,"text/html").body;cleanup(body);return body.innerHTML;}
return __exports;});;
/* /html_editor/static/src/utils/image.js */
odoo.define('@html_editor/utils/image',['@web/core/utils/cache','@web/core/utils/colors'],function(require){'use strict';let __exports={};const{Cache}=require("@web/core/utils/cache");const{isColorGradient}=require("@web/core/utils/colors");const SUPPORTED_MIMETYPES=["image/gif","image/jpe","image/jpeg","image/jpg","image/png","image/svg+xml","image/webp",];const headResponseCache=new Cache(async(src)=>await fetch(src,{method:"HEAD"}),JSON.stringify);__exports.backgroundImageCssToParts=backgroundImageCssToParts;function backgroundImageCssToParts(css=""){const parts={};if(css.startsWith("url(")){const urlEnd=css.indexOf(")")+1;parts.url=css.substring(0,urlEnd).trim();const commaPos=css.indexOf(",",urlEnd);css=commaPos>0?css.substring(commaPos+1):"";}
if(isColorGradient(css)){parts.gradient=css.trim();}
return parts;}
__exports.backgroundImagePartsToCss=backgroundImagePartsToCss;function backgroundImagePartsToCss(parts){return[parts.url,parts.gradient].filter(Boolean).join(", ")||"";}
__exports.getMimetype=getMimetype;function getMimetype(image,data=image.dataset){const src=getImageSrc(image);return(data.mimetype||data.mimetypeBeforeConversion||(src&&((src.endsWith(".png")&&"image/png")||(src.endsWith(".webp")&&"image/webp")||(src.endsWith(".jpg")&&"image/jpeg")||(src.endsWith(".jpeg")&&"image/jpeg")))||null);}
__exports.getFetchedMimetype=getFetchedMimetype;async function getFetchedMimetype(image,data=image.dataset){const mimetypeOnData=data.mimetype||data.mimetypeBeforeConversion;if(mimetypeOnData){return mimetypeOnData;}
const src=getImageSrc(image);try{const response=await headResponseCache.read(src);if(!response.ok){return null;}
const contentType=response.headers.get("content-type");if(!SUPPORTED_MIMETYPES.some((mimetype)=>contentType.startsWith(mimetype))){return null;}
if(contentType.startsWith("image/svg+xml")){return"image/svg+xml";}
return contentType;}catch{return null;}}
__exports.isImageCorsProtected=isImageCorsProtected;async function isImageCorsProtected(img){const src=img.getAttribute("src");if(!src){return false;}
let isCorsProtected=false;if(!src.startsWith("/")||/\/web\/image\/\d+-redirect\//.test(src)){isCorsProtected=await headResponseCache.read(src).then(()=>false).catch(()=>true);}
return isCorsProtected;}
__exports.isSrcCorsProtected=isSrcCorsProtected;async function isSrcCorsProtected(src){const dummyImg=document.createElement("img");dummyImg.src=src;return isImageCorsProtected(dummyImg);}
__exports.getImageSrc=getImageSrc;function getImageSrc(el){if(el.tagName==="IMG"){return el.getAttribute("src");}
if(el.querySelector(".s_parallax_bg")){el=el.querySelector(".s_parallax_bg");}
const url=backgroundImageCssToParts(el.style.backgroundImage).url;return url&&getBgImageURLFromURL(url);}
__exports.getBgImageURLFromURL=getBgImageURLFromURL;function getBgImageURLFromURL(url){const match=url.match(/^url\((['"])(.*?)\1\)$/);if(!match){return"";}
const matchedURL=match[2];const fullURL=new URL(matchedURL,window.location.origin);if(fullURL.origin===window.location.origin){return fullURL.href.slice(fullURL.origin.length);}
return matchedURL;}
return __exports;});;
/* /html_editor/static/src/utils/image_processing.js */
odoo.define('@html_editor/utils/image_processing',['@web/core/network/rpc','@web/core/utils/objects','@web/core/assets','@html_editor/utils/image'],function(require){'use strict';let __exports={};const{rpc}=require("@web/core/network/rpc");const{pick}=require("@web/core/utils/objects");const{loadBundle}=require("@web/core/assets");const{getImageSrc}=require("@html_editor/utils/image");const cropperDataFields=__exports.cropperDataFields=["x","y","width","height","rotate","scaleX","scaleY"];const cropperDataFieldsWithAspectRatio=__exports.cropperDataFieldsWithAspectRatio=[...cropperDataFields,"aspectRatio"];const isGif=__exports.isGif=(mimetype)=>mimetype==="image/gif";let _isWebGLEnabled;__exports.isWebGLEnabled=isWebGLEnabled;function isWebGLEnabled(){if(_isWebGLEnabled!==undefined){return _isWebGLEnabled;}
try{const canvas=document.createElement("canvas");_isWebGLEnabled=!!(window.WebGLRenderingContext&&(canvas.getContext("webgl")||canvas.getContext("experimental-webgl")));}catch{_isWebGLEnabled=false;}
return _isWebGLEnabled;}
const modifierFields=["filter","quality","mimetype","glFilter","originalId","originalSrc","resizeWidth","aspectRatio","mimetypeBeforeConversion",];const removeOnImageChangeAttrs=__exports.removeOnImageChangeAttrs=[...cropperDataFields,...modifierFields];const cache={};const placeholderHref="/web/image/__odoo__unknown__src__/";function _getValidSrc(src){if(src in cache){return cache[src];}
const prom=new Promise((resolve)=>{fetch(src).then((response)=>{resolve(response.ok?src:placeholderHref);}).catch(()=>{resolve(placeholderHref);});});cache[src]=prom;return prom;}
__exports.loadImage=loadImage;async function loadImage(src,img=new Image()){const source=await _getValidSrc(src);return new Promise((resolve,reject)=>{img.addEventListener("load",()=>resolve(img),{once:true});img.addEventListener("error",reject,{once:true});img.src=source;});}
const imageCache=new Map();function _loadImageObjectURL(src){return _updateImageData(src);}
__exports.loadImageDataURL=loadImageDataURL;function loadImageDataURL(src){return _updateImageData(src,"dataURL");}
async function _updateImageData(src,key="objectURL"){const currentImageData=imageCache.get(src);if(currentImageData&&currentImageData[key]){return currentImageData[key];}
let value="";const blob=await fetch(src).then((res)=>res.blob());if(key==="dataURL"){value=await createDataURL(blob);}else{value=URL.createObjectURL(blob);}
imageCache.set(src,Object.assign(currentImageData||{},{[key]:value,size:blob.size}));return value;}
__exports.getImageSizeFromCache=getImageSizeFromCache;function getImageSizeFromCache(src){return imageCache.get(src).size;}
__exports.activateCropper=activateCropper;async function activateCropper(image,aspectRatio,dataset,{onReady}={}){await loadBundle("html_editor.assets_image_cropper");const oldSrc=image.src;const newSrc=await _loadImageObjectURL(image.getAttribute("src"));image.src=newSrc;let readyResolve;const readyPromise=new Promise((resolve)=>(readyResolve=resolve));const cropper=new Cropper(image,{viewMode:2,dragMode:"move",autoCropArea:1.0,aspectRatio:aspectRatio,data:Object.fromEntries(Object.entries(pick(dataset,...cropperDataFields)).map(([key,value])=>[key,parseFloat(value),])),minContainerWidth:1,minContainerHeight:1,ready:()=>{readyResolve();if(onReady){onReady(cropper);}},});if(oldSrc===newSrc&&image.complete){return;}
await readyPromise;return cropper;}
__exports.loadImageInfo=loadImageInfo;async function loadImageInfo(el,attachmentSrc=""){const newDataset={};const elSrc=getImageSrc(el);const src=attachmentSrc||elSrc;if((el.dataset.originalSrc&&el.dataset.mimetypeBeforeConversion)||!src){return newDataset;}
let docHref=el.ownerDocument.defaultView.location.href;if(docHref.startsWith("about:")){docHref=window.location.href;}
const srcUrl=new URL(src,docHref);let relativeSrc=decodeURI(srcUrl.pathname);let match=relativeSrc.match(/\/(?:web_editor|html_editor)\/image_shape\/(\w+\.\w+)/);if(el.dataset.shape&&match){match=match[1];if(match.endsWith("_perspective")){match=match.slice(0,-12);}
relativeSrc=`/web/image/${encodeURIComponent(match)}`;}
const{original}=await rpc("/html_editor/get_image_info",{src:relativeSrc},{cache:true});if(original&&original.image_src&&!/\/web\/image\/\d+-redirect\//.test(original.image_src)){newDataset.originalId=original.id;newDataset.originalSrc=original.image_src;newDataset.mimetypeBeforeConversion=original.mimetype;}
return newDataset;}
__exports.createDataURL=createDataURL;function createDataURL(blob){return new Promise((resolve,reject)=>{const reader=new FileReader();reader.addEventListener("load",()=>resolve(reader.result));reader.addEventListener("abort",reject);reader.addEventListener("error",reject);reader.readAsDataURL(blob);});}
__exports.getDataURLBinarySize=getDataURLBinarySize;function getDataURLBinarySize(dataURL){return(dataURL.split(",")[1].length/4)*3;}
__exports.getAspectRatio=getAspectRatio;function getAspectRatio(ratio){if(typeof ratio==="number"){return ratio;}
const[a,b]=ratio.split(/[:/]/).map((n)=>parseFloat(n));if(!b){return a;}
return a/b;}
return __exports;});;
/* /html_editor/static/src/utils/perspective_utils.js */
odoo.define('@html_editor/utils/perspective_utils',[],function(require){'use strict';let __exports={};__exports.transform=transform;function transform([[a,b,c],[d,e,f],[g,h,i]],[x,y]){const z=g*x+h*y+i;return[(a*x+b*y+c)/z,(d*x+e*y+f)/z];}
function invert([[a,b,c],[d,e,f],[g,h,i]]){const determinant=a*e*i-a*f*h-b*d*i+b*f*g+c*d*h-c*e*g;return[[(e*i-h*f)/determinant,(h*c-b*i)/determinant,(b*f-e*c)/determinant,],[(g*f-d*i)/determinant,(a*i-g*c)/determinant,(d*c-a*f)/determinant,],[(d*h-g*e)/determinant,(g*b-a*h)/determinant,(a*e-d*b)/determinant,],];}
function multiply(a,b){const[[a0,a1,a2],[a3,a4,a5],[a6,a7,a8]]=a;const[[b0,b1,b2],[b3,b4,b5],[b6,b7,b8]]=b;return[[a0*b0+a1*b3+a2*b6,a0*b1+a1*b4+a2*b7,a0*b2+a1*b5+a2*b8],[a3*b0+a4*b3+a5*b6,a3*b1+a4*b4+a5*b7,a3*b2+a4*b5+a5*b8],[a6*b0+a7*b3+a8*b6,a6*b1+a7*b4+a8*b7,a6*b2+a7*b5+a8*b8],];}
__exports.getProjective=getProjective;function getProjective(width,height,[[x0,y0],[x1,y1],[x2,y2],[x3,y3]]){const denominator=x3*(y1-y2)+x1*(y2-y3)+x2*(y3-y1);const a=(x0*(y2-y3)+x2*(y3-y0)+x3*(y0-y2))/denominator;const b=(x0*(y3-y1)+x3*(y1-y0)+x1*(y0-y3))/denominator;const c=(x0*(y1-y2)+x1*(y2-y0)+x2*(y0-y1))/denominator;const reverse=invert([[width,-width,0],[0,-height,height],[1,-1,1],]);const forward=[[a*x1,b*x2,c*x3],[a*y1,b*y2,c*y3],[a,b,c],];return multiply(forward,reverse);}
__exports.getAffineApproximation=getAffineApproximation;function getAffineApproximation(projective,[[x0,y0],[x1,y1],[x2,y2]]){const a=transform(projective,[x0,y0]);const b=transform(projective,[x1,y1]);const c=transform(projective,[x2,y2]);return multiply([[a[0],b[0],c[0]],[a[1],b[1],c[1]],[1,1,1],],invert([[x0,x1,x2],[y0,y1,y2],[1,1,1],]));}
return __exports;});;
/* /html_editor/static/src/utils/position.js */
odoo.define('@html_editor/utils/position',[],function(require){'use strict';let __exports={};const DIRECTIONS=__exports.DIRECTIONS={LEFT:false,RIGHT:true,};__exports.leftPos=leftPos;function leftPos(node){return[node.parentElement,childNodeIndex(node)];}
__exports.rightPos=rightPos;function rightPos(node){return[node.parentElement,childNodeIndex(node)+1];}
__exports.boundariesOut=boundariesOut;function boundariesOut(node){const index=childNodeIndex(node);return[node.parentElement,index,node.parentElement,index+1];}
__exports.boundariesIn=boundariesIn;function boundariesIn(node){return[node,0,node,nodeSize(node)];}
__exports.startPos=startPos;function startPos(node){return[node,0];}
__exports.endPos=endPos;function endPos(node){return[node,nodeSize(node)];}
__exports.childNodeIndex=childNodeIndex;function childNodeIndex(node){let i=0;while(node.previousSibling){i++;node=node.previousSibling;}
return i;}
__exports.nodeSize=nodeSize;function nodeSize(node){const isTextNode=node.nodeType===Node.TEXT_NODE;if(isTextNode){return node.length;}else{const child=node.lastChild;return child?childNodeIndex(child)+1:0;}}
return __exports;});;
/* /html_editor/static/src/utils/regex.js */
odoo.define('@html_editor/utils/regex',[],function(require){'use strict';let __exports={};const tldWhitelist=['com','net','org','ac','ad','ae','af','ag','ai','al','am','an','ao','aq','ar','as','at','au','aw','ax','az','ba','bb','bd','be','bf','bg','bh','bi','bj','bl','bm','bn','bo','br','bq','bs','bt','bv','bw','by','bz','ca','cc','cd','cf','cg','ch','ci','ck','cl','cm','cn','co','cr','cs','cu','cv','cw','cx','cy','cz','dd','de','dj','dk','dm','do','dz','ec','ee','eg','eh','er','es','et','eu','fi','fj','fk','fm','fo','fr','ga','gb','gd','ge','gf','gg','gh','gi','gl','gm','gn','gp','gq','gr','gs','gt','gu','gw','gy','hk','hm','hn','hr','ht','hu','id','ie','il','im','in','io','iq','ir','is','it','je','jm','jo','jp','ke','kg','kh','ki','km','kn','kp','kr','kw','ky','kz','la','lb','lc','li','lk','lr','ls','lt','lu','lv','ly','ma','mc','md','me','mf','mg','mh','mk','ml','mm','mn','mo','mp','mq','mr','ms','mt','mu','mv','mw','mx','my','mz','na','nc','ne','nf','ng','ni','nl','no','np','nr','nu','nz','om','pa','pe','pf','pg','ph','pk','pl','pm','pn','pr','ps','pt','pw','py','qa','re','ro','rs','ru','rw','sa','sb','sc','sd','se','sg','sh','si','sj','sk','sl','sm','sn','so','sr','ss','st','su','sv','sx','sy','sz','tc','td','tf','tg','th','tj','tk','tl','tm','tn','to','tp','tr','tt','tv','tw','tz','ua','ug','uk','um','us','uy','uz','va','vc','ve','vg','vi','vn','vu','wf','ws','ye','yt','yu','za','zm','zr','zw','co\\.uk'];const urlRegexBase=`|(?:www.))[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-zA-Z][a-zA-Z0-9]{1,62}|(?:[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.(?:${tldWhitelist.join('|')})\\b))(?:(?:[/?#])[^\\s]*[^!.,})\\]'"\\s]|(?:[^!(){}.,[\\]'"\\s]+))?`;const httpCapturedRegex=`(https?:\\/\\/)`;const URL_REGEX=__exports.URL_REGEX=new RegExp(`((?:(?:${httpCapturedRegex}${urlRegexBase})`,'i');return __exports;});;
/* /html_editor/static/src/utils/resource.js */
odoo.define('@html_editor/utils/resource',[],function(require){'use strict';let __exports={};const resourceSequenceSymbol=__exports.resourceSequenceSymbol=Symbol("resourceSequence");const READ=__exports.READ=0;__exports.withSequence=withSequence;function withSequence(sequenceNumber,object){if(typeof sequenceNumber!=="number"){throw new Error(`sequenceNumber must be a number. Got ${sequenceNumber} (${typeof sequenceNumber}).`);}
return{[resourceSequenceSymbol]:sequenceNumber,object,};}
return __exports;});;
/* /html_editor/static/src/utils/sanitize.js */
odoo.define('@html_editor/utils/sanitize',['@html_editor/utils/dom_info','@html_editor/utils/dom','@odoo/owl','@web/core/utils/html'],function(require){'use strict';let __exports={};const{containsAnyInline}=require("@html_editor/utils/dom_info");const{wrapInlinesInBlocks}=require("@html_editor/utils/dom");const{markup}=require("@odoo/owl");const{htmlReplace}=require("@web/core/utils/html");__exports.initElementForEdition=initElementForEdition;function initElementForEdition(element,options={}){if(element?.nodeType===Node.ELEMENT_NODE&&containsAnyInline(element)&&!options.allowInlineAtRoot){wrapInlinesInBlocks(element,{baseContainerNodeName:"DIV",});}
for(const img of element.querySelectorAll("img[width], img[height]")){const width=img.getAttribute("width");const height=img.getAttribute("height");img.removeAttribute("height");img.removeAttribute("width");img.style.setProperty("width",isNaN(width)?width:`${width}px`);img.style.setProperty("height",isNaN(height)?height:`${height}px`);}}
__exports.fixInvalidHTML=fixInvalidHTML;function fixInvalidHTML(content){if(!content){return content;}
const regex=/<\s*(?!area\b|base\b|br\b|col\b|embed\b|hr\b|img\b|input\b|link\b|meta\b|param\b|v:image\b|v:fill\b|source\b|track\b|wbr\b)([a-zA-Z0-9:-]+)\s*((?:(?:\s+[\w:-]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s"'=<>`]+))?)*))\s*\/>/g;return htmlReplace(content,regex,(match,tag,attributes)=>{attributes=markup(attributes);return markup`<${tag}${attributes}></${tag}>`;});}
let Markup=null;__exports.instanceofMarkup=instanceofMarkup;function instanceofMarkup(value){if(!Markup){Markup=markup("").constructor;}
return value instanceof Markup;}
return __exports;});;
/* /html_editor/static/src/utils/selection.js */
odoo.define('@html_editor/utils/selection',['@html_editor/utils/blocks','@html_editor/utils/dom_info','@html_editor/utils/dom_state','@html_editor/utils/dom_traversal','@html_editor/utils/position'],function(require){'use strict';let __exports={};const{closestBlock,isBlock}=require("@html_editor/utils/blocks");const{getDeepestPosition,isContentEditable,isNotEditableNode,isSelfClosingElement,nextLeaf,previousLeaf,}=require("@html_editor/utils/dom_info");const{isFakeLineBreak}=require("@html_editor/utils/dom_state");const{closestElement,createDOMPathGenerator}=require("@html_editor/utils/dom_traversal");const{DIRECTIONS,childNodeIndex,endPos,leftPos,nodeSize,rightPos,startPos,}=require("@html_editor/utils/position");__exports.getCursorDirection=getCursorDirection;function getCursorDirection(anchorNode,anchorOffset,focusNode,focusOffset){if(anchorNode===focusNode){if(anchorOffset===focusOffset){return false;}
return anchorOffset<focusOffset?DIRECTIONS.RIGHT:DIRECTIONS.LEFT;}
return anchorNode.compareDocumentPosition(focusNode)&Node.DOCUMENT_POSITION_FOLLOWING?DIRECTIONS.RIGHT:DIRECTIONS.LEFT;}
__exports.findInSelection=findInSelection;function findInSelection(selection,selector){const selectorInStartAncestors=closestElement(selection.startContainer,selector);if(selectorInStartAncestors){return selectorInStartAncestors;}else{const commonElementAncestor=closestElement(selection.commonAncestorContainer);return(commonElementAncestor&&[...commonElementAncestor.querySelectorAll(selector)].find((node)=>selection.intersectsNode(node)));}}
const leftLeafOnlyInScopeNotBlockEditablePath=createDOMPathGenerator(DIRECTIONS.LEFT,{leafOnly:true,inScope:true,stopTraverseFunction:(node)=>isNotEditableNode(node)||isBlock(node),stopFunction:(node)=>isNotEditableNode(node)||isBlock(node),});const rightLeafOnlyInScopeNotBlockEditablePath=createDOMPathGenerator(DIRECTIONS.RIGHT,{leafOnly:true,inScope:true,stopTraverseFunction:(node)=>isNotEditableNode(node)||isBlock(node),stopFunction:(node)=>isNotEditableNode(node)||isBlock(node),});__exports.normalizeSelfClosingElement=normalizeSelfClosingElement;function normalizeSelfClosingElement(node,offset){if(isSelfClosingElement(node)){[node,offset]=rightPos(node);}
return[node,offset];}
__exports.normalizeNotEditableNode=normalizeNotEditableNode;function normalizeNotEditableNode(node,offset,position="right"){const editable=closestElement(node,".odoo-editor-editable");let closest=closestElement(node);while(closest&&closest!==editable&&!closest.isContentEditable){[node,offset]=position==="right"?rightPos(node):leftPos(node);closest=node;}
return[node,offset];}
__exports.normalizeCursorPosition=normalizeCursorPosition;function normalizeCursorPosition(node,offset,position="right"){[node,offset]=normalizeSelfClosingElement(node,offset);[node,offset]=normalizeNotEditableNode(node,offset,position);return[node,offset];}
__exports.normalizeFakeBR=normalizeFakeBR;function normalizeFakeBR(node,offset){const prevNode=node.nodeType===Node.ELEMENT_NODE&&node.childNodes[offset-1];if(prevNode&&prevNode.nodeName==="BR"&&isFakeLineBreak(prevNode)){offset--;}
return[node,offset];}
__exports.normalizeDeepCursorPosition=normalizeDeepCursorPosition;function normalizeDeepCursorPosition(node,offset){let el;let elOffset;if(node.nodeType===Node.ELEMENT_NODE){el=node;elOffset=offset;}else if(node.nodeType===Node.TEXT_NODE){if(offset===0){el=node.parentNode;elOffset=childNodeIndex(node);}else if(offset===node.length){el=node.parentNode;elOffset=childNodeIndex(node)+1;}}
if(el){const leftInlineNode=leftLeafOnlyInScopeNotBlockEditablePath(el,elOffset).next().value;let leftVisibleEmpty=false;if(leftInlineNode){leftVisibleEmpty=isSelfClosingElement(leftInlineNode)||!isContentEditable(leftInlineNode);[node,offset]=leftVisibleEmpty?rightPos(leftInlineNode):endPos(leftInlineNode);}
if(!leftInlineNode||leftVisibleEmpty){const rightInlineNode=rightLeafOnlyInScopeNotBlockEditablePath(el,elOffset).next().value;if(rightInlineNode){const closest=closestElement(rightInlineNode);const rightVisibleEmpty=isSelfClosingElement(rightInlineNode)||!closest||!closest.isContentEditable;if(!(leftVisibleEmpty&&rightVisibleEmpty)){[node,offset]=rightVisibleEmpty?leftPos(rightInlineNode):startPos(rightInlineNode);}}}}
return[node,offset];}
function updateCursorBeforeMove(destParent,destIndex,node,cursor){if(cursor.node===destParent&&cursor.offset>=destIndex){cursor.offset+=1;}else if(cursor.node===node.parentNode){const childIndex=childNodeIndex(node);if(cursor.offset===childIndex&&cursor.offset===0){[cursor.node,cursor.offset]=[destParent,destIndex];}else if(cursor.offset===childIndex+1&&cursor.offset===nodeSize(cursor.node)){[cursor.node,cursor.offset]=[destParent,destIndex+1];}else if(cursor.offset>childIndex){cursor.offset-=1;}}}
function updateCursorBeforeRemove(node,cursor){if(node.contains(cursor.node)){[cursor.node,cursor.offset]=[node.parentNode,childNodeIndex(node)];}else if(cursor.node===node.parentNode&&cursor.offset>childNodeIndex(node)){cursor.offset-=1;}}
function updateCursorBeforeUnwrap(node,cursor){if(cursor.node===node){[cursor.node,cursor.offset]=[node.parentNode,cursor.offset+childNodeIndex(node)];}else if(cursor.node===node.parentNode&&cursor.offset>childNodeIndex(node)){cursor.offset+=nodeSize(node)-1;}}
function updateCursorBeforeMergeIntoPreviousSibling(node,cursor){if(cursor.node===node){cursor.node=node.previousSibling;cursor.offset+=node.previousSibling.childNodes.length;}else if(cursor.node===node.parentNode){const childIndex=childNodeIndex(node);if(cursor.offset===childIndex){cursor.node=node.previousSibling;cursor.offset=node.previousSibling.childNodes.length;}else if(cursor.offset>childIndex){cursor.offset--;}}}
const callbacksForCursorUpdate=__exports.callbacksForCursorUpdate={remove:(node)=>(cursor)=>updateCursorBeforeRemove(node,cursor),before:(ref,node)=>(cursor)=>updateCursorBeforeMove(ref.parentNode,childNodeIndex(ref),node,cursor),after:(ref,node)=>(cursor)=>updateCursorBeforeMove(ref.parentNode,childNodeIndex(ref)+1,node,cursor),append:(to,node)=>(cursor)=>updateCursorBeforeMove(to,to.childNodes.length,node,cursor),prepend:(to,node)=>(cursor)=>updateCursorBeforeMove(to,0,node,cursor),unwrap:(node)=>(cursor)=>updateCursorBeforeUnwrap(node,cursor),merge:(node)=>(cursor)=>updateCursorBeforeMergeIntoPreviousSibling(node,cursor),};__exports.getAdjacentCharacter=getAdjacentCharacter;function getAdjacentCharacter(selection,side,editable){let{focusNode,focusOffset}=selection;[focusNode,focusOffset]=getDeepestPosition(focusNode,focusOffset);const originalBlock=closestBlock(focusNode);let adjacentCharacter;while(!adjacentCharacter&&focusNode){if(side==="previous"){adjacentCharacter=focusOffset>0&&focusNode.textContent[focusOffset-1];}else{adjacentCharacter=focusNode.textContent[focusOffset];}
if(!adjacentCharacter){if(side==="previous"){focusNode=previousLeaf(focusNode,editable);focusOffset=focusNode&&nodeSize(focusNode);}else{focusNode=nextLeaf(focusNode,editable);focusOffset=0;}
const characterIndex=side==="previous"?focusOffset-1:focusOffset;adjacentCharacter=focusNode&&focusNode.textContent[characterIndex];}}
if(!focusNode||!isContentEditable(focusNode)||closestBlock(focusNode)!==originalBlock){return undefined;}
return adjacentCharacter;}
return __exports;});;
/* /html_editor/static/src/utils/table.js */
odoo.define('@html_editor/utils/table',['@html_editor/utils/dom_traversal'],function(require){'use strict';let __exports={};const{closestElement}=require("@html_editor/utils/dom_traversal");__exports.getRowIndex=getRowIndex;function getRowIndex(trOrTd){const tr=closestElement(trOrTd,"tr");return tr.rowIndex;}
__exports.getColumnIndex=getColumnIndex;function getColumnIndex(td){return td.cellIndex;}
__exports.getTableCells=getTableCells;function getTableCells(table){return[...table.querySelectorAll("td, th")].filter((cell)=>closestElement(cell,"table")===table);}
return __exports;});;
/* /html_editor/static/src/utils/tracking.js */
odoo.define('@html_editor/utils/tracking',[],function(require){'use strict';let __exports={};__exports.trackOccurrences=trackOccurrences;function trackOccurrences(){const visited=new Set();return function isFirstOccurrence(key){if(visited.has(key)){return false;}
visited.add(key);return true;};}
__exports.trackOccurrencesPair=trackOccurrencesPair;function trackOccurrencesPair(){const visited=new Map();return function isFirstOccurrence(a,b){if(!visited.has(a)){visited.set(a,trackOccurrences());}
return visited.get(a)(b);};}
return __exports;});;
/* /html_editor/static/src/utils/url.js */
odoo.define('@html_editor/utils/url',['@web/core/browser/browser','@web/session'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{session}=require("@web/session");const ODOO_DOMAIN_REGEX=new RegExp(`^https?://${session.db}\\.odoo\\.com(/.*)?$`);__exports.checkURL=checkURL;function checkURL(url,hostnameList){if(url){let potentialURL;try{potentialURL=new URL(url);}catch{return false;}
if(hostnameList.includes(potentialURL.hostname)){return`https://${potentialURL.hostname}${potentialURL.pathname}`;}}
return false;}
__exports.isImageUrl=isImageUrl;function isImageUrl(url){const urlFileExtention=url.split(".").pop();return["jpg","jpeg","png","gif","svg","webp"].includes(urlFileExtention.toLowerCase());}
__exports.getVideoUrl=getVideoUrl;function getVideoUrl(platform,videoId,params){let url;switch(platform){case"youtube":url=new URL(`https://www.youtube.com/embed/${videoId}`);break;case"vimeo":url=new URL(`https://player.vimeo.com/video/${videoId}`);break;case"dailymotion":url=new URL(`https://www.dailymotion.com/embed/video/${videoId}`);break;case"instagram":url=new URL(`https://www.instagram.com/p/${videoId}/embed`);break;default:throw new Error(`Unsupported platform: ${platform}`);}
url.search=new URLSearchParams(params);return url;}
__exports.isAbsoluteURLInCurrentDomain=isAbsoluteURLInCurrentDomain;function isAbsoluteURLInCurrentDomain(url,env=null){let hasProtocol;try{hasProtocol=!!new URL(url).protocol;}catch{hasProtocol=false;}
if(!hasProtocol){return false;}
const urlObj=new URL(url,window.location.origin);return(urlObj.origin===window.location.origin||ODOO_DOMAIN_REGEX.test(urlObj.origin));}
__exports.scrollAndHighlightHeading=scrollAndHighlightHeading;function scrollAndHighlightHeading(content,headingId=browser?.location?.hash?.replace?.(/^#/,"")){if(content&&headingId){setTimeout(()=>{const heading=content.querySelector(`[data-heading-link-id="${headingId}"]`);if(heading){heading.scrollIntoView({behavior:"smooth"});heading.classList.add("o-highlight-heading");setTimeout(()=>{heading.classList.remove("o-highlight-heading");},2000);}},500);}}
return __exports;});;
/* /html_editor/static/src/public/embedded_components/embedded_component_interaction.js */
odoo.define('@html_editor/public/embedded_components/embedded_component_interaction',['@html_editor/others/embedded_components/core/table_of_content/table_of_content_manager','@odoo/owl','@web/core/registry','@web/core/utils/functions','@web/public/interaction','@html_editor/public/embedding_sets'],function(require){'use strict';let __exports={};const{TableOfContentManager}=require("@html_editor/others/embedded_components/core/table_of_content/table_of_content_manager");const{Component,onMounted,onWillDestroy,useSubEnv,xml}=require("@odoo/owl");const{registry}=require("@web/core/registry");const{memoize}=require("@web/core/utils/functions");const{Interaction}=require("@web/public/interaction");const{PUBLIC_EMBEDDINGS}=require("@html_editor/public/embedding_sets");class EmbeddedDummy extends Component{static template=xml``;static props=["*"];}
const getEmbeddingMap=__exports.getEmbeddingMap=memoize((embeddings)=>new Map(embeddings.map((embedding)=>[embedding.name,embedding])));const getTocManager=memoize((element)=>new TableOfContentManager({el:element}));const EmbeddedComponentInteraction=__exports.EmbeddedComponentInteraction=class EmbeddedComponentInteraction extends Interaction{static selector="[data-embedded]";dynamicContent={_root:{"t-component":()=>{const embedding=this.getEmbedding(this.el.dataset.embedded)??{Component:EmbeddedDummy,};return this.getComponentInfo(embedding);},},};getComponentInfo({Component:ComponentClass,getEditableDescendants,getProps,name}){if(ComponentClass===EmbeddedDummy){return[ComponentClass,{}];}
const host=this.el;const interactionsService=this.services["public.interactions"];ComponentClass=class extends ComponentClass{setup(){useSubEnv(subEnv);super.setup();onMounted(()=>{for(const node of[...host.childNodes]){if(node.nodeName!=="OWL-ROOT"){if(node.nodeType===Node.ELEMENT_NODE){interactionsService.stopInteractions(node);}
node.remove();}}});onWillDestroy(()=>{const editableDescendants=getEditableDescendants?.(host)??{};host.append(...Object.values(editableDescendants));});}};const subEnv={};if(getEditableDescendants){subEnv.getEditableDescendants=getEditableDescendants;}
const props={...(getProps?.(host)||{}),};this.setupNewComponent({name:name,env:subEnv,props});return[ComponentClass,props];}
getEmbedding(name){return getEmbeddingMap(PUBLIC_EMBEDDINGS).get(name);}
setupNewComponent({name,env,props}){if(name==="tableOfContent"){Object.assign(props,{manager:getTocManager(this.el.parentElement),});}}}
registry.category("public.interactions").add("html_editor.embedded_component",EmbeddedComponentInteraction);return __exports;});;
/* /html_editor/static/src/public/embedding_sets.js */
odoo.define('@html_editor/public/embedding_sets',['@html_editor/others/embedded_components/core/syntax_highlighting/readonly_syntax_highlighting','@html_editor/others/embedded_components/core/file/readonly_file','@html_editor/others/embedded_components/core/table_of_content/table_of_content','@html_editor/others/embedded_components/core/toggle_block/toggle_block','@html_editor/others/embedded_components/core/video/readonly_video'],function(require){'use strict';let __exports={};const{readonlySyntaxHighlightingEmbedding}=require("@html_editor/others/embedded_components/core/syntax_highlighting/readonly_syntax_highlighting");const{readonlyFileEmbedding}=require("@html_editor/others/embedded_components/core/file/readonly_file");const{readonlyTableOfContentEmbedding}=require("@html_editor/others/embedded_components/core/table_of_content/table_of_content");const{toggleBlockEmbedding}=require("@html_editor/others/embedded_components/core/toggle_block/toggle_block");const{readonlyVideoEmbedding}=require("@html_editor/others/embedded_components/core/video/readonly_video");const PUBLIC_EMBEDDINGS=__exports.PUBLIC_EMBEDDINGS=[readonlyFileEmbedding,readonlyTableOfContentEmbedding,toggleBlockEmbedding,readonlyVideoEmbedding,readonlySyntaxHighlightingEmbedding,];return __exports;});;
/* /html_editor/static/src/public/html_migrations/html_migrations_interaction.js */
odoo.define('@html_editor/public/html_migrations/html_migrations_interaction',['@web/core/registry','@web/public/interaction','@html_editor/html_migrations/html_migrations_utils','@html_editor/html_migrations/html_upgrade_manager','@odoo/owl'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{Interaction}=require("@web/public/interaction");const{VERSION_SELECTOR}=require("@html_editor/html_migrations/html_migrations_utils");const{HtmlUpgradeManager}=require("@html_editor/html_migrations/html_upgrade_manager");const{markup}=require("@odoo/owl");const upgradeElementToInteractionMap=new Map();const HtmlMigrationsInteraction=__exports.HtmlMigrationsInteraction=class HtmlMigrationsInteraction extends Interaction{static selector=VERSION_SELECTOR;setup(){const parentElement=this.el.parentElement;if(!parentElement){this.isComplete=true;return;}
for(const el of[...upgradeElementToInteractionMap.keys()]){if(el.contains(parentElement)){this.isComplete=true;return;}else if(parentElement.contains(el)){const interaction=upgradeElementToInteractionMap.get(el);interaction.isComplete=true;interaction.container=undefined;upgradeElementToInteractionMap.delete(el);}}
this.container=parentElement;upgradeElementToInteractionMap.set(this.container,this);}
start(){if(this.isComplete||this.isUpgrading||!this.container.isConnected){return;}
this.isUpgrading=true;this.services["public.interactions"].stopInteractions(this.container);const htmlUpgradeManager=new HtmlUpgradeManager();const initialValue=markup(this.container.innerHTML);const upgradedValue=htmlUpgradeManager.processForUpgrade(initialValue);if(initialValue!==upgradedValue){this.container.innerHTML=upgradedValue;}
for(const el of this.container.querySelectorAll(VERSION_SELECTOR)){delete el.dataset.oeVersion;}
this.services["public.interactions"].startInteractions(this.container);this.isUpgrading=false;this.isComplete=true;}
destroy(){if(this.isComplete&&this.container){upgradeElementToInteractionMap.delete(this.container);}}}
registry.category("public.interactions").add("html_editor.html_migrations",HtmlMigrationsInteraction);return __exports;});;
/* /web_tour/static/src/js/tour_pointer/tour_pointer.js */
odoo.define('@web_tour/js/tour_pointer/tour_pointer',['@odoo/owl','@web/core/utils/hooks','@web/core/browser/browser','@web/core/position/position_hook'],function(require){'use strict';let __exports={};const{Component,useEffect,useRef,useState}=require("@odoo/owl");const{useBus,useService}=require("@web/core/utils/hooks");const{browser}=require("@web/core/browser/browser");const{usePosition}=require("@web/core/position/position_hook");const TourPointer=__exports.TourPointer=class TourPointer extends Component{static props={pointerState:{type:Object,shape:{anchor:{type:HTMLElement,optional:true},content:{type:String,optional:true},isOpen:{type:Boolean,optional:true},isVisible:{type:Boolean,optional:true},isZone:{type:Boolean,optional:true},onClick:{type:[Function,{value:null}],optional:true},onMouseEnter:{type:[Function,{value:null}],optional:true},onMouseLeave:{type:[Function,{value:null}],optional:true},position:{type:[{value:"left"},{value:"right"},{value:"top"},{value:"bottom"},],optional:true,},rev:{type:Number,optional:true},},},bounce:{type:Boolean,optional:true},};static defaultProps={bounce:true,};static template="web_tour.TourPointer";static width=28;static height=28;setup(){this.orm=useService("orm");const positionOptions={margin:6,onPositioned:(pointer,position)=>{const popperRect=pointer.getBoundingClientRect();const{top,left,direction}=position;if(direction==="top"){pointer.style.bottom=`${window.innerHeight - top - popperRect.height}px`;pointer.style.removeProperty("top");}else if(direction==="left"){pointer.style.right=`${window.innerWidth - left - popperRect.width}px`;pointer.style.removeProperty("left");}},};Object.defineProperty(positionOptions,"position",{get:()=>this.position,set:()=>{},enumerable:true,});const position=usePosition("pointer",()=>this.props.pointerState.anchor,positionOptions);const rootRef=useRef("pointer");const zoneRef=useRef("zone");let dimensions=null;let lastMeasuredContent=null;let lastOpenState=this.isOpen;let lastAnchor;let[anchorX,anchorY]=[0,0];useEffect(()=>{const{el:pointer}=rootRef;const{el:zone}=zoneRef;if(pointer){const hasContentChanged=lastMeasuredContent!==this.content;const hasOpenStateChanged=lastOpenState!==this.isOpen;lastOpenState=this.isOpen;if(this.props.pointerState.isZone){const{anchor}=this.props.pointerState;let offsetLeft=0;let offsetTop=0;if(document!==anchor.ownerDocument){const iframe=[...document.querySelectorAll("iframe")].filter((e)=>e.contentDocument===anchor.ownerDocument)[0];offsetLeft=iframe.getBoundingClientRect().left;offsetTop=iframe.getBoundingClientRect().top;}
const{left,top,width,height}=anchor.getBoundingClientRect();zone.style.minWidth=width+"px";zone.style.minHeight=height+"px";zone.style.left=left+offsetLeft+"px";zone.style.top=top+offsetTop+"px";}
if(hasContentChanged){lastMeasuredContent=this.content;pointer.style.removeProperty("width");pointer.style.removeProperty("height");dimensions=pointer.getBoundingClientRect();}
if(hasContentChanged||hasOpenStateChanged){const[width,height]=this.isOpen?[dimensions.width,dimensions.height]:[this.constructor.width,this.constructor.height];if(this.isOpen){pointer.style.removeProperty("transition");}else{pointer.style.setProperty("transition","none");}
pointer.style.setProperty("width",`${width}px`);pointer.style.setProperty("height",`${height}px`);}
if(!this.isOpen){const{anchor}=this.props.pointerState;if(anchor===lastAnchor){const{x,y,width}=anchor.getBoundingClientRect();const[lastAnchorX,lastAnchorY]=[anchorX,anchorY];[anchorX,anchorY]=[x,y];const delta=Math.sqrt(Math.pow(x-lastAnchorX,2)+Math.pow(y-lastAnchorY,2));if(delta<1){position.lock();return;}
const wouldOverflow=window.innerWidth-x-width/2<dimensions?.width;pointer.classList.toggle("o_expand_left",wouldOverflow);}
lastAnchor=anchor;pointer.style.bottom="";pointer.style.right="";position.unlock();}}else{lastMeasuredContent=null;lastOpenState=false;lastAnchor=null;dimensions=null;}});this.state=useState({triggerBelow:false});this.ui=useService("ui");const onActiveElementChanged=()=>{const activeEl=this.ui.activeElement;const pointerAnchor=this.props.pointerState.anchor;if(pointerAnchor){this.state.triggerBelow=!activeEl.contains(pointerAnchor);}};useBus(this.ui.bus,"active-element-changed",onActiveElementChanged);}
get isVisible(){return(this.props.pointerState.isVisible&&(this.ui.activeElement.contains(this.props.pointerState.anchor)||!this.state.triggerBelow));}
get content(){return this.props.pointerState.content||"";}
get isOpen(){return this.props.pointerState.isOpen&&this.content;}
get position(){return this.props.pointerState.position||"top";}
async onStopClicked(){await this.orm.call("res.users","switch_tour_enabled",[false]);browser.location.reload();}}
return __exports;});;
/* /web_tour/static/src/js/tour_pointer/tour_pointer_state.js */
odoo.define('@web_tour/js/tour_pointer/tour_pointer_state',['@odoo/owl','@web/core/l10n/translation','@web_tour/js/tour_pointer/tour_pointer','@web_tour/js/utils/tour_utils'],function(require){'use strict';let __exports={};const{reactive}=require("@odoo/owl");const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web_tour",...args);const{TourPointer}=require("@web_tour/js/tour_pointer/tour_pointer");const{getScrollParent}=require("@web_tour/js/utils/tour_utils");class Intersection{constructor(){this.currentTarget=null;this.rootBounds=null;this._targetPosition="unknown";this._observer=new IntersectionObserver((observations)=>this._handleObservations(observations));}
_handleObservations(observations){if(observations.length<1){return;}
const observation=observations[observations.length-1];this.rootBounds=observation.rootBounds;if(this.rootBounds&&this.currentTarget){if(observation.isIntersecting){this._targetPosition="in";}else{const scrollParentElement=getScrollParent(this.currentTarget)||document.documentElement;const targetBounds=this.currentTarget.getBoundingClientRect();if(targetBounds.bottom>scrollParentElement.clientHeight){this._targetPosition="out-below";}else if(targetBounds.top<0){this._targetPosition="out-above";}else if(targetBounds.left<0){this._targetPosition="out-left";}else if(targetBounds.right>scrollParentElement.clientWidth){this._targetPosition="out-right";}}}else{this._targetPosition="unknown";}}
get targetPosition(){if(!this.rootBounds){return this.currentTarget?"in":"unknown";}else{return this._targetPosition;}}
setTarget(newTarget){if(this.currentTarget!==newTarget){if(this.currentTarget){this._observer.unobserve(this.currentTarget);}
if(newTarget){this._observer.observe(newTarget);}
this.currentTarget=newTarget;}}
stop(){this._observer.disconnect();}}
__exports.createPointerState=createPointerState;function createPointerState(){const setState=(newState)=>{Object.assign(state,newState);};const pointTo=(anchor,step,isZone)=>{intersection.setTarget(anchor);if(anchor){let{tooltipPosition,content}=step;switch(intersection.targetPosition){case"unknown":{break;}
case"in":{if(document.body.contains(floatingAnchor)){floatingAnchor.remove();}
setState({anchor,content,isZone,onClick:null,position:tooltipPosition,isVisible:true,});break;}
default:{const onClick=()=>{anchor.scrollIntoView({behavior:"smooth",block:"nearest"});hide();};const scrollParent=getScrollParent(anchor);if(!scrollParent){setState({anchor,content,isZone,onClick:null,position:tooltipPosition,isVisible:true,});return;}
let{x,y,width,height}=scrollParent.getBoundingClientRect();const iframeEl=scrollParent.ownerDocument.defaultView.frameElement;if(iframeEl){const iframeOffset=iframeEl.getBoundingClientRect();x+=iframeOffset.x;y+=iframeOffset.y;}
if(intersection.targetPosition==="out-below"){tooltipPosition="top";content=_t("Scroll down to reach the next step.");floatingAnchor.style.top=`${y + height - TourPointer.height}px`;floatingAnchor.style.left=`${x + width / 2}px`;}else if(intersection.targetPosition==="out-above"){tooltipPosition="bottom";content=_t("Scroll up to reach the next step.");floatingAnchor.style.top=`${y + TourPointer.height}px`;floatingAnchor.style.left=`${x + width / 2}px`;}
if(intersection.targetPosition==="out-left"){tooltipPosition="right";content=_t("Scroll left to reach the next step.");floatingAnchor.style.top=`${y + height / 2}px`;floatingAnchor.style.left=`${x + TourPointer.width}px`;}else if(intersection.targetPosition==="out-right"){tooltipPosition="left";content=_t("Scroll right to reach the next step.");floatingAnchor.style.top=`${y + height / 2}px`;floatingAnchor.style.left=`${x + width - TourPointer.width}px`;}
if(!document.contains(floatingAnchor)){document.body.appendChild(floatingAnchor);}
setState({anchor:floatingAnchor,content,onClick,position:tooltipPosition,isZone,isVisible:true,});}}}else{hide();}};function hide(){setState({content:"",isVisible:false,isOpen:false});}
function showContent(isOpen){setState({isOpen});}
function destroy(){intersection.stop();if(document.body.contains(floatingAnchor)){floatingAnchor.remove();}}
const state=reactive({});const intersection=new Intersection();const floatingAnchor=document.createElement("div");floatingAnchor.className="position-fixed";return{state,setState,showContent,pointTo,hide,destroy};}
return __exports;});;
/* /web_tour/static/src/js/utils/tour_utils.js */
odoo.define('@web_tour/js/utils/tour_utils',[],function(require){'use strict';let __exports={};__exports.callWithUnloadCheck=callWithUnloadCheck;function callWithUnloadCheck(func,...args){let willUnload=false;const beforeunload=()=>(willUnload=true);window.addEventListener("beforeunload",beforeunload);const result=func(...args);if(result instanceof Promise){return result.then(()=>{window.removeEventListener("beforeunload",beforeunload);return willUnload;});}else{window.removeEventListener("beforeunload",beforeunload);return willUnload;}}
function formatValue(key,value,maxLength=200){if(!value){return"(empty)";}
return value.length>maxLength?value.slice(0,maxLength)+"...":value;}
function serializeNode(node){if(node.nodeType===Node.TEXT_NODE){return`"${node.nodeValue.trim()}"`;}
return node.outerHTML?formatValue("node",node.outerHTML,500):"[Unknown Node]";}
__exports.serializeChanges=serializeChanges;function serializeChanges(snapshot,current){const changes={node:serializeNode(current),};function pushChanges(key,obj){changes[key]=changes[key]||[];changes[key].push(obj);}
if(snapshot.textContent!==current.textContent){pushChanges("modifiedText",{before:snapshot.textContent,after:current.textContent});}
const oldChildren=[...snapshot.childNodes].filter((node)=>node.nodeType!==Node.TEXT_NODE);const newChildren=[...current.childNodes].filter((node)=>node.nodeType!==Node.TEXT_NODE);oldChildren.forEach((oldNode,index)=>{if(!newChildren[index]||!oldNode.isEqualNode(newChildren[index])){pushChanges("removedNodes",{oldNode:serializeNode(oldNode)});}});newChildren.forEach((newNode,index)=>{if(!oldChildren[index]||!newNode.isEqualNode(oldChildren[index])){pushChanges("addedNodes",{newNode:serializeNode(newNode)});}});const oldAttrNames=new Set([...snapshot.attributes].map((attr)=>attr.name));const newAttrNames=new Set([...current.attributes].map((attr)=>attr.name));new Set([...oldAttrNames,...newAttrNames]).forEach((attributeName)=>{const oldValue=snapshot.getAttribute(attributeName);const newValue=current.getAttribute(attributeName);const before=oldValue!==newValue||!newAttrNames.has(attributeName)?oldValue:null;const after=oldValue!==newValue||!oldAttrNames.has(attributeName)?newValue:null;if(before||after){pushChanges("modifiedAttributes",{attributeName,before,after});}});return changes;}
__exports.serializeMutation=serializeMutation;function serializeMutation(mutation){const{type,attributeName}=mutation;if(type==="attributes"&&attributeName){return`attribute: ${attributeName}`;}else{return type;}}
__exports.getScrollParent=getScrollParent;function getScrollParent(element){if(!element){return null;}
const overflowY=window.getComputedStyle(element).overflowY;const isScrollable=overflowY==="auto"||overflowY==="scroll"||(overflowY==="visible"&&element===element.ownerDocument.scrollingElement);if(isScrollable){return element;}else{return getScrollParent(element.parentNode);}}
return __exports;});;
/* /web_tour/static/src/js/tour_state.js */
odoo.define('@web_tour/js/tour_state',['@web/core/browser/browser'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const CURRENT_TOUR_LOCAL_STORAGE="current_tour";const CURRENT_TOUR_CONFIG_LOCAL_STORAGE="current_tour.config";const CURRENT_TOUR_INDEX_LOCAL_STORAGE="current_tour.index";const CURRENT_TOUR_ON_ERROR_LOCAL_STORAGE="current_tour.on_error";const tourState=__exports.tourState={getCurrentTour(){return browser.localStorage.getItem(CURRENT_TOUR_LOCAL_STORAGE);},setCurrentTour(tourName){browser.localStorage.setItem(CURRENT_TOUR_LOCAL_STORAGE,tourName);},getCurrentIndex(){const index=browser.localStorage.getItem(CURRENT_TOUR_INDEX_LOCAL_STORAGE,"0");return parseInt(index,10);},setCurrentIndex(index){browser.localStorage.setItem(CURRENT_TOUR_INDEX_LOCAL_STORAGE,index.toString());},getCurrentConfig(){const config=browser.localStorage.getItem(CURRENT_TOUR_CONFIG_LOCAL_STORAGE,"{}");return JSON.parse(config);},setCurrentConfig(config){config=JSON.stringify(config);browser.localStorage.setItem(CURRENT_TOUR_CONFIG_LOCAL_STORAGE,config);},getCurrentTourOnError(){return browser.localStorage.getItem(CURRENT_TOUR_ON_ERROR_LOCAL_STORAGE);},setCurrentTourOnError(){browser.localStorage.setItem(CURRENT_TOUR_ON_ERROR_LOCAL_STORAGE,"1");},clear(){browser.localStorage.removeItem(CURRENT_TOUR_ON_ERROR_LOCAL_STORAGE);browser.localStorage.removeItem(CURRENT_TOUR_CONFIG_LOCAL_STORAGE);browser.localStorage.removeItem(CURRENT_TOUR_INDEX_LOCAL_STORAGE);browser.localStorage.removeItem(CURRENT_TOUR_LOCAL_STORAGE);},};return __exports;});;
/* /web_tour/static/src/js/tour_service.js */
odoo.define('@web_tour/js/tour_service',['@odoo/owl','@web/core/browser/browser','@web/core/dropdown/dropdown_item','@web/core/registry','@web/session','@web/core/assets','@web_tour/js/tour_pointer/tour_pointer_state','@web_tour/js/tour_state','@web_tour/js/utils/tour_utils','@web_tour/js/tour_recorder/tour_recorder_state','@web/core/utils/urls'],function(require){'use strict';let __exports={};const{Component,markup,whenReady,validate}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{registry}=require("@web/core/registry");const{session}=require("@web/session");const{loadBundle}=require("@web/core/assets");const{createPointerState}=require("@web_tour/js/tour_pointer/tour_pointer_state");const{tourState}=require("@web_tour/js/tour_state");const{callWithUnloadCheck}=require("@web_tour/js/utils/tour_utils");const{tourRecorderState,TOUR_RECORDER_ACTIVE_LOCAL_STORAGE_KEY,}=require("@web_tour/js/tour_recorder/tour_recorder_state");const{redirect}=require("@web/core/utils/urls");class OnboardingItem extends Component{static components={DropdownItem};static template="web_tour.OnboardingItem";static props={toursEnabled:{type:Boolean},toggleItem:{type:Function},};setup(){}}
const StepSchema={id:{type:[String],optional:true},content:{type:[String,Object],optional:true},debugHelp:{type:String,optional:true},isActive:{type:Array,element:String,optional:true},run:{type:[String,Function,Boolean],optional:true},timeout:{optional:true,validate(value){return value>=0&&value<=60000;},},tooltipPosition:{optional:true,validate(value){return["top","bottom","left","right"].includes(value);},},trigger:{type:String},expectUnloadPage:{type:Boolean,optional:true},pause:{type:Boolean,optional:true},break:{type:Boolean,optional:true},};const TourSchema={name:{type:String,optional:true},steps:Function,url:{type:String,optional:true},wait_for:{type:[Function,Object],optional:true},};registry.category("web_tour.tours").addValidation(TourSchema);const debugMenuRegistry=registry.category("debug").category("default");const tourService=__exports.tourService={dependencies:["orm","effect","overlay","localization"],start:async(env,{orm,effect,overlay})=>{await whenReady();let toursEnabled=session?.tour_enabled;const tourRegistry=registry.category("web_tour.tours");const pointer=createPointerState();pointer.stop=()=>{};debugMenuRegistry.add("onboardingItem",()=>({type:"component",Component:OnboardingItem,props:{toursEnabled:toursEnabled||false,toggleItem:async()=>{tourState.clear();toursEnabled=await orm.call("res.users","switch_tour_enabled",[!toursEnabled,]);browser.location.reload();},},sequence:500,section:"testing",}));function getTourFromRegistry(tourName){if(!tourRegistry.contains(tourName)){return;}
const tour=tourRegistry.get(tourName);return{...tour,steps:tour.steps(),name:tourName,wait_for:tour.wait_for||Promise.resolve(),};}
async function getTourFromDB(tourName){const tour=await orm.call("web_tour.tour","get_tour_json_by_name",[tourName]);if(!tour){throw new Error(`Tour '${tourName}' is not found in the database.`);}
if(!tour.steps.length&&tourRegistry.contains(tour.name)){tour.steps=tourRegistry.get(tour.name).steps();}
return tour;}
function validateStep(step){try{validate(step,StepSchema);}catch(error){console.error(`Error in schema for TourStep ${JSON.stringify(step, null, 4)}\n${
error.message
}`);}}
async function startTour(tourName,options={}){pointer.stop();const tourFromRegistry=getTourFromRegistry(tourName);if(!tourFromRegistry&&!options.fromDB){return;}
const tour=options.fromDB?{name:tourName,url:options.url}:tourFromRegistry;if(!session.is_public&&!toursEnabled&&options.mode==="manual"){toursEnabled=await orm.call("res.users","switch_tour_enabled",[!toursEnabled]);}
let tourConfig={delayToCheckUndeterminisms:0,stepDelay:0,keepWatchBrowser:false,mode:"auto",showPointerDuration:0,debug:false,redirect:true,};tourConfig=Object.assign(tourConfig,options);tourState.setCurrentConfig(tourConfig);tourState.setCurrentTour(tour.name);tourState.setCurrentIndex(0);const willUnload=callWithUnloadCheck(()=>{if(tour.url&&tourConfig.startUrl!=tour.url&&tourConfig.redirect){redirect(tour.url);}});if(!willUnload){await resumeTour();}}
async function resumeTour(){const tourName=tourState.getCurrentTour();const tourConfig=tourState.getCurrentConfig();let tour=getTourFromRegistry(tourName);if(tourConfig.fromDB){tour=await getTourFromDB(tourName);}
if(!tour||!tour.steps.length){return;}
tour.steps.forEach((step)=>validateStep(step));if(tourConfig.mode==="auto"){if(!odoo.loader.modules.get("@web_tour/js/tour_automatic/tour_automatic")){await loadBundle("web_tour.automatic",{css:false});}
const{TourAutomatic}=odoo.loader.modules.get("@web_tour/js/tour_automatic/tour_automatic");new TourAutomatic(tour).start();}else{await loadBundle("web_tour.interactive");const{TourPointer}=odoo.loader.modules.get("@web_tour/js/tour_pointer/tour_pointer");pointer.stop=overlay.add(TourPointer,{pointerState:pointer.state,bounce:!(tourConfig.mode==="auto"&&tourConfig.keepWatchBrowser),},{sequence:1100,});const{TourInteractive}=odoo.loader.modules.get("@web_tour/js/tour_interactive/tour_interactive");new TourInteractive(tour).start(env,pointer,async()=>{pointer.stop();tourState.clear();browser.console.log("tour succeeded");let message=tourConfig.rainbowManMessage||tour.rainbowManMessage;if(message){message=window.DOMPurify.sanitize(tourConfig.rainbowManMessage);effect.add({type:"rainbow_man",message:markup(message),});}
const nextTour=await orm.call("web_tour.tour","consume",[tour.name]);if(nextTour){startTour(nextTour.name,{mode:"manual",redirect:false,rainbowManMessage:nextTour.rainbowManMessage,});}});}}
async function tourRecorder(){await loadBundle("web_tour.recorder");const{TourRecorder}=odoo.loader.modules.get("@web_tour/js/tour_recorder/tour_recorder");const remove=overlay.add(TourRecorder,{onClose:()=>{remove();browser.localStorage.removeItem(TOUR_RECORDER_ACTIVE_LOCAL_STORAGE_KEY);tourRecorderState.clear();},},{sequence:99999});}
async function startTourRecorder(){if(!browser.localStorage.getItem(TOUR_RECORDER_ACTIVE_LOCAL_STORAGE_KEY)){await tourRecorder();}
browser.localStorage.setItem(TOUR_RECORDER_ACTIVE_LOCAL_STORAGE_KEY,"1");}
if(!window.frameElement){const paramsTourName=new URLSearchParams(browser.location.search).get("tour");if(paramsTourName){startTour(paramsTourName,{mode:"manual",fromDB:true});}
if(tourState.getCurrentTour()){if(tourState.getCurrentConfig().mode==="auto"||toursEnabled){resumeTour();}else{tourState.clear();}}else if(session.current_tour){startTour(session.current_tour.name,{mode:"manual",redirect:false,rainbowManMessage:session.current_tour.rainbowManMessage,});}
if(browser.localStorage.getItem(TOUR_RECORDER_ACTIVE_LOCAL_STORAGE_KEY)&&!session.is_public){await tourRecorder();}}
odoo.startTour=startTour;odoo.isTourReady=(tourName)=>getTourFromRegistry(tourName).wait_for.then(()=>true);return{startTour,startTourRecorder,};},};registry.category("services").add("tour_service",tourService);return __exports;});;
/* /web_tour/static/src/js/tour_recorder/tour_recorder_state.js */
odoo.define('@web_tour/js/tour_recorder/tour_recorder_state',['@web/core/browser/browser'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const CURRENT_TOUR_RECORDER_LOCAL_STORAGE="current_tour_recorder";const CURRENT_TOUR_RECORDER_RECORD_LOCAL_STORAGE="current_tour_recorder.record";const TOUR_RECORDER_ACTIVE_LOCAL_STORAGE_KEY=__exports.TOUR_RECORDER_ACTIVE_LOCAL_STORAGE_KEY="tour_recorder_active";const tourRecorderState=__exports.tourRecorderState={isRecording(){return browser.localStorage.getItem(CURRENT_TOUR_RECORDER_RECORD_LOCAL_STORAGE)||"0";},setIsRecording(isRecording){browser.localStorage.setItem(CURRENT_TOUR_RECORDER_RECORD_LOCAL_STORAGE,isRecording?"1":"0");},setCurrentTourRecorder(tour){tour=JSON.stringify(tour);browser.localStorage.setItem(CURRENT_TOUR_RECORDER_LOCAL_STORAGE,tour);},getCurrentTourRecorder(){const tour=browser.localStorage.getItem(CURRENT_TOUR_RECORDER_LOCAL_STORAGE)||"[]";return JSON.parse(tour);},clear(){browser.localStorage.removeItem(CURRENT_TOUR_RECORDER_LOCAL_STORAGE);browser.localStorage.removeItem(CURRENT_TOUR_RECORDER_RECORD_LOCAL_STORAGE);},};return __exports;});;
/* /web_tour/static/src/tour_utils.js */
odoo.define('@web_tour/tour_utils',['@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{appTranslateFn}=require("@web/core/l10n/translation");const _t=(str,...args)=>appTranslateFn(str,"web_tour",...args);const stepUtils=__exports.stepUtils={_getHelpMessage(functionName,...args){return`Generated by function tour utils ${functionName}(${args.join(", ")})`;},addDebugHelp(helpMessage,step){if(typeof step.debugHelp==="string"){step.debugHelp=step.debugHelp+"\n"+helpMessage;}else{step.debugHelp=helpMessage;}
return step;},editSelectMenuInput(trigger,value){return[{content:"Make sure a SelectMenu has been opened",trigger:`.o_select_menu_menu`,},{trigger,async run({queryFirst}){const input=queryFirst(trigger);input.focus();input.value=value;input.dispatchEvent(new Event("input",{bubbles:true}));input.dispatchEvent(new Event("change",{bubbles:true}));},},];},showAppsMenuItem(){return{isActive:["auto","community","desktop"],trigger:".o_navbar_apps_menu button:enabled",tooltipPosition:"bottom",run:"click",};},toggleHomeMenu(){return[{isActive:[".o_main_navbar .o_menu_toggle"],trigger:".o_main_navbar .o_menu_toggle",content:_t("Click the top left corner to navigate across apps."),tooltipPosition:"bottom",run:"click",},{isActive:["mobile"],trigger:".o_sidebar_topbar a.btn-primary",tooltipPosition:"right",run:"click",},];},autoExpandMoreButtons(isActiveMobile=false){const isActive=["auto"];if(isActiveMobile){isActive.push("mobile");}
return{isActive,content:`autoExpandMoreButtons`,trigger:".o-form-buttonbox",async run({queryFirst,click}){const more=queryFirst(".o-form-buttonbox .o_button_more");if(more){await click(more);}},};},goToAppSteps(dataMenuXmlid,description){return[this.showAppsMenuItem(),{isActive:["community"],trigger:`.o_app[data-menu-xmlid="${dataMenuXmlid}"]`,content:description,tooltipPosition:"right",run:"click",},{isActive:["enterprise"],trigger:`.o_app[data-menu-xmlid="${dataMenuXmlid}"]`,content:description,tooltipPosition:"bottom",run:"click",},].map((step)=>this.addDebugHelp(this._getHelpMessage("goToApp",dataMenuXmlid,description),step));},statusbarButtonsSteps(innerTextButton,description,trigger){const steps=[];if(trigger){steps.push({isActive:["auto","mobile"],trigger,});}
steps.push({isActive:["auto","mobile"],trigger:".o_statusbar_buttons",async run({queryFirst,click}){const buttonOutSideDropdownMenu=queryFirst(`.o_statusbar_buttons button:enabled:contains('${innerTextButton}')`);const node=queryFirst(".o_statusbar_buttons button:has(.oi-ellipsis-v)");if(!buttonOutSideDropdownMenu&&node){await click(node);}},},{trigger:`.o_statusbar_buttons button:enabled:contains('${innerTextButton}'), .dropdown-item button:enabled:contains('${innerTextButton}')`,content:description,tooltipPosition:"bottom",run:"click",});return steps.map((step)=>this.addDebugHelp(this._getHelpMessage("statusbarButtonsSteps",innerTextButton,description),step));},mobileKanbanSearchMany2X(modalTitle,valueSearched){return[{isActive:["mobile"],trigger:`.modal:not(.o_inactive_modal) .o_control_panel_navigation .btn .fa-search`,tooltipPosition:"bottom",run:"click",},{isActive:["mobile"],trigger:".o_searchview_input",tooltipPosition:"bottom",run:`edit ${valueSearched}`,},{isActive:["mobile"],trigger:".dropdown-menu.o_searchview_autocomplete",},{isActive:["mobile"],trigger:".o_searchview_input",tooltipPosition:"bottom",run:"press Enter",},{isActive:["mobile"],trigger:`.o_kanban_record:contains('${valueSearched}')`,tooltipPosition:"bottom",run:"click",},].map((step)=>this.addDebugHelp(this._getHelpMessage("mobileKanbanSearchMany2X",modalTitle,valueSearched),step));},saveForm(){return[{isActive:["auto"],content:"save form",trigger:".o_form_button_save:enabled",run:"click",},{content:"wait for save completion",trigger:".o_form_readonly, .o_form_saved",},];},discardForm(){return[{isActive:["auto"],content:"discard the form",trigger:".o_form_button_cancel",run:"click",},{content:"wait for cancellation to complete",trigger:".o_view_controller.o_list_view, .o_form_view > div > main > .o_form_readonly, .o_form_view > div > main > .o_form_saved",},];},waitIframeIsReady(){return{content:"Wait until the iframe is ready",trigger:`:iframe body[is-ready=true]`,};},goToUrl(url){return{isActive:["auto"],content:`Navigate to ${url}`,trigger:"body",run:`goToUrl ${url}`,expectUnloadPage:true,};},};return __exports;});;
/* /web_unsplash/static/src/frontend/unsplash_beacon.js */
odoo.define('@web_unsplash/frontend/unsplash_beacon',['@web/public/interaction','@web/core/registry','@web/core/network/rpc'],function(require){'use strict';let __exports={};const{Interaction}=require("@web/public/interaction");const{registry}=require("@web/core/registry");const{rpc}=require("@web/core/network/rpc");const UnsplashBeacon=__exports.UnsplashBeacon=class UnsplashBeacon extends Interaction{static selector="#wrapwrap";async willStart(){const unsplashImageEls=this.el.querySelectorAll("img[src*='/unsplash/']");const unsplashImageIds=[];for(const unsplashImageEl of unsplashImageEls){unsplashImageIds.push(unsplashImageEl.src.split("/unsplash/")[1].split("/")[0]);}
if(unsplashImageIds.length){const appID=await this.waitFor(rpc("/web_unsplash/get_app_id"));if(appID){const fetchURL=new URL("https://views.unsplash.com/v");fetchURL.search=new URLSearchParams({"photo_id":unsplashImageIds.join(","),"app_id":appID,});fetch(fetchURL);}}}}
registry.category("public.interactions").add("web_unsplash.unsplash_beacon",UnsplashBeacon);return __exports;});
/*******************************************
* Templates *
*******************************************/
odoo.define("web.assets_frontend_lazy.bundle.xml", ["@web/core/templates"], function(require) {
"use strict";
const { checkPrimaryTemplateParents, registerTemplate, registerTemplateExtension } = require("@web/core/templates");
/* web.assets_frontend_lazy */
registerTemplate("web.ActionSwiper", `/web/static/src/core/action_swiper/action_swiper.xml`, `<t t-name="web.ActionSwiper" xml:space="preserve">
<t t-if="props.onRightSwipe || props.onLeftSwipe">
<div class="o_actionswiper" t-on-touchend="_onTouchEndSwipe" t-on-touchmove="_onTouchMoveSwipe" t-on-touchstart="_onTouchStartSwipe" t-ref="root">
<div class="o_actionswiper_overflow_container position-relative overflow-hidden">
<div class="o_actionswiper_target_container" t-ref="targetContainer" t-att-style="state.containerStyle" t-att-class="{ o_actionswiper_swiping: state.isSwiping }">
<t t-slot="default"/>
<t t-if="localizedProps.onRightSwipe and (localizedProps.onRightSwipe.icon or localizedProps.onRightSwipe.bgColor)">
<div t-att-style="'max-width: ' + swipedDistance + 'px;'" class="o_actionswiper_right_swipe_area position-absolute overflow-hidden w-100 h-100 d-flex align-items-center justify-content-center rounded-end" t-att-class="localizedProps.onRightSwipe.bgColor">
<span><i class="fa fa-2x" t-att-class="localizedProps.onRightSwipe.icon"/></span>
</div>
</t>
<t t-if="localizedProps.onLeftSwipe and (localizedProps.onLeftSwipe.icon or localizedProps.onLeftSwipe.bgColor)">
<div t-att-style="'max-width: ' + -swipedDistance + 'px;'" class="o_actionswiper_left_swipe_area position-absolute overflow-hidden w-100 h-100 d-flex align-items-center justify-content-center rounded-start" t-att-class="localizedProps.onLeftSwipe.bgColor">
<span><i class="fa fa-2x" t-att-class="localizedProps.onLeftSwipe.icon"/></span>
</div>
</t>
</div>
</div>
</div>
</t>
<t t-else="">
<t t-slot="default"/>
</t>
</t>
`);
registerTemplate("web.AutoComplete", `/web/static/src/core/autocomplete/autocomplete.xml`, `<t t-name="web.AutoComplete" xml:space="preserve">
<div class="o-autocomplete" t-ref="root" t-att-class="autoCompleteRootClass">
<input type="text" t-att-id="props.id" class="o-autocomplete--input o_input pe-3 text-truncate" t-att-autocomplete="props.autocomplete" t-att-placeholder="props.placeholder" t-att-title="props.title" role="combobox" t-att-aria-activedescendant="activeSourceOptionId" t-att-aria-expanded="displayOptions ? 'true' : 'false'" aria-autocomplete="list" aria-haspopup="listbox" t-model="state.value" t-on-blur="onInputBlur" t-on-click="onInputClick" t-on-change="onInputChange" t-on-input="onInput" t-on-keydown="onInputKeydown" t-on-focus="onInputFocus" t-ref="input"/>
<t t-if="displayOptions">
<ul role="menu" class="o-autocomplete--dropdown-menu ui-widget show" t-att-class="ulDropdownClass" t-ref="sourcesList">
<t t-foreach="sources" t-as="source" t-key="source.id">
<t t-if="source.isLoading">
<li class="ui-menu-item" t-att-class="{ 'o-autocomplete--dropdown-item': props.dropdown, 'd-block': !props.dropdown }">
<a t-attf-id="{{props.id or 'autocomplete'}}_{{source_index}}_loading" role="option" href="#" class="o_loading dropdown-item ui-menu-item-wrapper" aria-selected="true">
<i class="fa fa-spin fa-circle-o-notch"/> <t t-esc="source.placeholder"/>
</a>
</li>
</t>
<t t-else="">
<t t-foreach="source.options" t-as="option" t-key="option.id">
<li class="o-autocomplete--dropdown-item ui-menu-item d-block" t-att-class="option.cssClass" t-on-mouseenter="() =&gt; this.onOptionMouseEnter([source_index, option_index])" t-on-mouseleave="() =&gt; this.onOptionMouseLeave([source_index, option_index])" t-on-click="() =&gt; this.onOptionClick(option)" t-on-pointerdown="(ev) =&gt; this.onOptionPointerDown(option, ev)">
<t t-tag="option.unselectable ? 'span' : 'a'" class="dropdown-item ui-menu-item-wrapper text-truncate" t-attf-id="{{props.id or 'autocomplete'}}_{{source_index}}_{{option_index}}" t-att-role="!option.unselectable and 'option'" t-att-href="!option.unselectable and '#'" t-att-class="{ 'ui-state-active': isActiveSourceOption([source_index, option_index]) }" t-att-aria-selected="isActiveSourceOption([source_index, option_index]) ? 'true' : 'false'">
<t t-slot="{{ source.optionSlot }}" label="option.label" data="option.data">
<t t-if="!option.labelTermOrder" t-out="option.label"/>
<t t-else="">
<t t-foreach="option.labelTermOrder.labelBits" t-as="bit" t-key="bit.id">
<t t-if="!option.labelTermOrder.searchTermIndexes.includes(bit.id)" t-esc="bit.bit"/>
<mark t-else="" class="o-autocomplete--mark" t-esc="bit.bit"/>
</t>
</t>
</t>
</t>
</li>
</t>
</t>
</t>
</ul>
</t>
</div>
</t>
`);
registerTemplate("web.BarcodeDialog", `/web/static/src/core/barcode/barcode_dialog.xml`, `<t t-name="web.BarcodeDialog" xml:space="preserve">
<Dialog title.translate="Barcode Scanner" fullscreen="true" footer="false" contentClass="'o-barcode-modal'">
<BarcodeVideoScanner t-if="state.barcodeScannerSupported" t-props="props" onError.bind="onError" onResult.bind="onResult"/>
<div t-else="" t-ref="videoPreview" class="h-100 d-flex flex-column justify-content-center align-items-center gap-1">
<i class="fa fa-2x fa-camera text-muted"/>
<strong>Unable to access camera</strong>
<span class="text-muted" t-out="state.errorMessage"/>
</div>
</Dialog>
</t>
`);
registerTemplate("web.BarcodeVideoScanner", `/web/static/src/core/barcode/barcode_video_scanner.xml`, `<t t-name="web.BarcodeVideoScanner" xml:space="preserve">
<CropOverlay onResize.bind="this.onResize" isReady="state.isReady">
<video t-ref="videoPreview" muted="true" autoplay="true" playsinline="true" t-att-class="props.cssClass"/>
</CropOverlay>
</t>
`);
registerTemplate("web.CropOverlay", `/web/static/src/core/barcode/crop_overlay.xml`, `<t t-name="web.CropOverlay" xml:space="preserve">
<div t-ref="crop-container" t-on-mousedown="pointerDown" t-on-touchstart="pointerDown" t-on-mousemove="pointerMove" t-on-touchmove="pointerMove" t-on-mouseup="pointerUp" t-on-touchend="pointerUp" class="d-grid align-content-center justify-content-center h-100 o_crop_container">
<t t-slot="default"/>
<t t-if="props.isReady">
<div class="o_crop_overlay" t-att-class="{'o_crop_overlay_ios': isIOS}"/>
<img class="o_crop_icon" src="/web/static/img/transform.svg" draggable="false"/>
</t>
</div>
</t>
`);
registerTemplate("web.BottomSheet", `/web/static/src/core/bottom_sheet/bottom_sheet.xml`, `<t t-name="web.BottomSheet" xml:space="preserve">
<div class="o_bottom_sheet" t-att-class="{ 'o_bottom_sheet_ready': state.isPositionedReady, 'o_bottom_sheet_dismissing': state.isDismissing, 'o_bottom_sheet_snapping': state.isSnappingEnabled, }" t-attf-style="--BottomSheet-progress: {{state.progress}}" t-ref="container">
<div class="o_bottom_sheet_rail" t-att-class="{ o_bottom_sheet_rail_prevent_overscroll : props.preventDismissOnContentScroll }" t-ref="scrollRail">
<div class="o_bottom_sheet_backdrop" t-on-click="slideOut"/>
<div class="o_bottom_sheet_dismiss"/>
<div class="o_bottom_sheet_spacer"/>
<div class="o_bottom_sheet_sheet offcanvas position-relative overflow-hidden" role="dialog" t-ref="sheet">
<div tabindex="-1" role="button" class="o_bottom_sheet_handle text-center d-flex align-items-center justify-content-center opacity-50 py-2" t-on-click.stop="slideOut">
<div class="o_bottom_sheet_handle_bar pt-1 mx-auto rounded-pill d-inline-block px-5 bg-dark"/>
</div>
<div class="o_bottom_sheet_body offcanvas-body" role="menu" t-att-class="props.class" t-ref="ref">
<t t-if="props.component">
<t t-component="props.component" t-props="props.componentProps || {}"/>
</t>
<t t-else="">
<t t-slot="default" close="close" back="back"/>
</t>
</div>
</div>
</div>
</div>
</t>
`);
registerTemplate("web.CheckBox", `/web/static/src/core/checkbox/checkbox.xml`, `<t t-name="web.CheckBox" xml:space="preserve">
<div class="o-checkbox form-check" t-attf-class="{{ props.slots ? 'form-check' : '' }}" t-att-class="props.className" t-on-click="onClick" t-ref="root">
<input t-att-id="props.id or id" type="checkbox" class="form-check-input" t-att-disabled="props.disabled" t-att-checked="props.value" t-att-name="props.name" t-att-indeterminate="props.indeterminate" t-on-change="onChange"/>
<label t-att-for="props.id or id" class="form-check-label">
<t t-slot="default"/>
</label>
</div>
</t>
`);
registerTemplate("web.CodeEditor", `/web/static/src/core/code_editor/code_editor.xml`, `<t t-name="web.CodeEditor" xml:space="preserve">
<div t-ref="editorRef" class="w-100" t-att-class="props.class" t-att-data-mode="state.activeMode"/>
</t>
`);
registerTemplate("web.ColorPicker", `/web/static/src/core/color_picker/color_picker.xml`, `<t t-name="web.ColorPicker" xml:space="preserve">
<div t-attf-class="o_font_color_selector user-select-none {{this.props.className}}" t-on-pointerdown.stop="() =&gt; {}" data-prevent-closing-overlay="true" t-ref="root">
<div class="px-1 mb-1 pt-2 d-flex">
<t t-foreach="this.tabs" t-as="tab" t-key="tab.id">
<button t-attf-class="btn btn-sm text-truncate btn-tab #{tab.id}-tab #{ isDarkTheme ? 'btn-secondary' : 'btn-light'} #{state.activeTab === tab.id ? 'active' : ''}" t-on-click="() =&gt; this.setTab(tab.id)">
<t t-out="tab.name"/>
</button>
</t>
<div class="flex-grow-1"/>
<button t-attf-class="btn btn-sm fa fa-trash #{ isDarkTheme ? 'btn-secondary' : 'btn-light'}" title="Reset" t-on-click="onColorApply" t-on-mouseover="onColorHover" t-on-mouseout="onColorHoverOut" t-on-focusin="onColorFocusin" t-on-focusout="onColorFocusout"/>
</div>
<t t-set="activeTab" t-value="this.tabs.find((tab) =&gt; state.activeTab === tab.id)"/>
<t t-component="activeTab.component" t-props="{ applyColor: this.applyColor.bind(this), onColorClick: this.onColorApply.bind(this), onColorPointerOver: this.onColorHover.bind(this), onColorPointerOut: this.onColorHoverOut.bind(this), onColorPointerLeave: this.applyColorResetPreview.bind(this), onFocusin: this.onColorFocusin.bind(this), onFocusout: this.onColorFocusout.bind(this), colorPickerNavigation: this.colorPickerNavigation.bind(this), onColorPreview: this.onColorPreview.bind(this), setOnCloseCallback: this.props.setOnCloseCallback.bind(this), setOperationCallbacks: this.setOperationCallbacks.bind(this), editColorCombination: this.props.editColorCombination, selectedColorCombination: this.props.state.selectedColorCombination, defaultOpacity: this.props.defaultOpacity, noTransparency: this.props.noTransparency, defaultThemeColorVars: this.DEFAULT_THEME_COLOR_VARS, defaultColorSet: this.defaultColorSet, cssVarColorPrefix: this.props.cssVarColorPrefix, defaultColors: this.DEFAULT_COLORS, getUsedCustomColors: this.props.getUsedCustomColors, grayscales: this.grayscales, currentCustomColor: this.state.currentCustomColor, currentColorPreview: this.state.currentColorPreview, selectedColor: this.props.state.selectedColor, }"/>
</div>
</t>
`);
registerTemplate("web.CustomColorPicker", `/web/static/src/core/color_picker/custom_color_picker/custom_color_picker.xml`, `<t t-name="web.CustomColorPicker" xml:space="preserve">
<div class="o_colorpicker_widget" t-ref="el" t-on-click="onClick" t-on-keydown="onKeydown">
<div class="d-flex justify-content-between align-items-stretch mb-2">
<div t-ref="colorPickerArea" role="application" aria-label="Saturation and brightness color picker." aria-roledescription="Use up and down arrow keys to adapt the brightness. Use left and right arrow keys to adapt the saturation. Press the Control or Command key at the same time to have finer control." aria-activedescendant="picker_pointer" class="o_color_pick_area position-relative w-75" t-att-style="props.noTransparency ? 'width: 89%;' : None" t-on-pointerdown="onPointerDownPicker">
<div t-ref="colorPickerPointer" id="picker_pointer" class="o_picker_pointer rounded-circle p-1 position-absolute" tabindex="0" t-on-keydown="onPickerKeydown"/>
</div>
<div t-ref="colorSlider" class="o_color_slider position-relative" t-on-pointerdown="onPointerDownSlider">
<div t-ref="colorSliderPointer" class="o_slider_pointer" tabindex="0" t-on-keydown="onSliderKeydown" role="slider" aria-label="Hue" aria-orientation="vertical" aria-valuemin="0" aria-valuemax="360"/>
</div>
<div t-ref="opacitySlider" class="o_opacity_slider position-relative" t-if="!props.noTransparency" t-on-pointerdown="onPointerDownOpacitySlider">
<div t-ref="opacitySliderPointer" class="o_opacity_pointer" tabindex="0" t-on-keydown="onOpacitySliderKeydown" role="slider" aria-label="Opacity" aria-orientation="vertical" aria-valuemin="0" aria-valuemax="100"/>
</div>
</div>
<div class="o_color_picker_inputs d-flex justify-content-between mb-2" t-on-change="debouncedOnChangeInputs">
<t t-set="input_classes" t-value="'p-0 border-0 text-center font-monospace bg-transparent'"/>
<div class="o_hex_div d-flex align-items-baseline me-1">
<input type="text" t-attf-class="o_hex_input {{input_classes}}" data-color-method="hex" size="1" t-on-input="onHexColorInput"/>
<label class="flex-grow-0 ms-1 mb-0">hex</label>
</div>
</div>
</div>
</t>
`);
registerTemplate("web.ColorPickerCustomTab", `/web/static/src/core/color_picker/tabs/color_picker_custom_tab.xml`, `<t t-name="web.ColorPickerCustomTab" xml:space="preserve">
<div class="d-flex flex-column align-items-start p-2 pb-0" t-on-keydown="props.colorPickerNavigation">
<div class="o_colorpicker_section" t-on-click="props.onColorClick" t-on-mouseover="props.onColorPointerOver" t-on-mouseout="props.onColorPointerOut" t-on-focusin="props.onFocusin" t-on-focusout="props.onColorPointerOut">
<t t-foreach="usedCustomColors" t-as="color" t-key="color_index">
<button t-if="color.toLowerCase() !== props.currentCustomColor?.toLowerCase()" class="o_color_button o_color_picker_button btn p-0" t-att-data-color="color" t-attf-style="background-color: {{color}}"/>
</t>
<button t-if="!props.defaultColorSet and isValidCustomColor(props.currentCustomColor)" class="o_color_button o_color_picker_button btn p-0" t-att-class="{'selected': props.defaultColorSet === false and !props.currentColorPreview}" t-attf-style="background-color: {{props.currentCustomColor}}" t-att-data-color="props.currentCustomColor"/>
<button t-if="!!props.currentColorPreview" class="o_color_button o_color_picker_button btn p-0" t-att-class="{ 'selected': !!props.currentColorPreview }" t-attf-style="background-color: {{props.currentColorPreview}}" t-att-data-color="props.currentColorPreview"/>
</div>
<t t-foreach="Object.values(props.grayscales)" t-as="grayscaleColors" t-key="grayscaleColors">
<div class="o_colorpicker_section" t-on-click="props.onColorClick" t-on-mouseover="props.onColorPointerOver" t-on-mouseout="props.onColorPointerOut" t-on-focusin="props.onFocusin" t-on-focusout="props.onColorPointerOut">
<t t-foreach="grayscaleColors" t-as="color" t-key="color">
<button t-att-data-color="color" class="o_color_button o_color_picker_button btn p-0" t-att-class="{'selected': color === props.defaultColorSet and !props.currentColorPreview}" t-attf-style="background-color: var(--{{props.cssVarColorPrefix+color}})"/>
</t>
</div>
</t>
<CustomColorPicker selectedColor="props.currentCustomColor" setOnCloseCallback.bind="props.setOnCloseCallback" setOperationCallbacks.bind="props.setOperationCallbacks" onColorSelect.bind="(color) =&gt; this.props.applyColor(color.hex)" onColorPreview.bind="props.onColorPreview" noTransparency="props.noTransparency" defaultOpacity="props.defaultOpacity"/>
</div>
</t>
`);
registerTemplate("web.ColorPickerSolidTab", `/web/static/src/core/color_picker/tabs/color_picker_solid_tab.xml`, `<t t-name="web.ColorPickerSolidTab" xml:space="preserve">
<div class="d-flex flex-column align-items-center p-1" t-on-click="props.onColorClick" t-on-mouseover="props.onColorPointerOver" t-on-mouseout="props.onColorPointerOut" t-on-focusin="props.onFocusin" t-on-focusout="props.onFocusout" t-ref="solidTabRef" t-on-keydown="props.colorPickerNavigation">
<div class="o_colorpicker_section">
<t t-foreach="props.defaultThemeColorVars" t-as="color" t-key="color">
<button t-att-data-color="color" t-att-class="{'selected': color === props.defaultColorSet}" t-att-style="\`background-color: var(--\${props.cssVarColorPrefix + color})\` + (color_index === 3 ? '; grid-column: 5' : '')" class="btn p-0 o_color_button o_color_picker_button"/>
</t>
</div>
<div class="o_color_section">
<t t-foreach="props.defaultColors" t-as="line" t-key="line_index">
<t t-foreach="line" t-as="color" t-key="color_index">
<button class="o_color_button o_color_picker_button btn p-0" t-att-class="{'selected': color === props.currentCustomColor.toUpperCase() and !props.defaultColorSet}" t-att-data-color="color" t-attf-style="background-color: {{color}}"/>
</t>
</t>
</div>
</div>
</t>
`);
registerTemplate("web.ColorList", `/web/static/src/core/colorlist/colorlist.xml`, `<t t-name="web.ColorList" xml:space="preserve">
<div class="o_colorlist d-grid gap-3 gap-md-2" aria-atomic="true" t-ref="colorlist">
<t t-if="!props.forceExpanded and !state.isExpanded">
<button t-on-click="onToggle" role="menuitem" t-att-title="colors[props.selectedColor]" t-att-data-color="props.selectedColor" t-att-aria-label="colors[props.selectedColor]" t-attf-class="border-0 rounded-circle o_colorlist_toggler o_colorlist_item_color_{{ props.selectedColor }}"/>
</t>
<t t-else="" t-foreach="props.colors" t-as="colorId" t-key="colorId">
<button t-on-click.prevent.stop="() =&gt; this.onColorSelected(colorId)" role="menuitem" t-att-title="colors[colorId]" t-att-data-color="colorId" t-att-aria-label="colors[colorId]" t-attf-class="border-0 rounded-circle o_colorlist_item_color_{{ colorId }} {{ colorId === props.selectedColor ? 'active' : '' }}"/>
</t>
</div>
</t>
`);
registerTemplate("web.ConfirmationDialog", `/web/static/src/core/confirmation_dialog/confirmation_dialog.xml`, `<t t-name="web.ConfirmationDialog" xml:space="preserve">
<Dialog size="'md'" title="props.title" modalRef="modalRef">
<p t-out="props.body" class="text-prewrap"/>
<t t-set-slot="footer">
<button class="btn" t-att-class="props.confirmClass" t-on-click="_confirm" t-esc="props.confirmLabel" data-hotkey="q"/>
<button t-if="props.cancel" class="btn btn-secondary" t-on-click="_cancel" t-esc="props.cancelLabel" data-hotkey="x"/>
</t>
</Dialog>
</t>
`);
registerTemplate("web.AlertDialog", `/web/static/src/core/confirmation_dialog/confirmation_dialog.xml`, `<t t-name="web.AlertDialog" xml:space="preserve">
<Dialog size="'sm'" title="props.title" contentClass="props.contentClass">
<p t-out="props.body" class="text-prewrap"/>
<t t-set-slot="footer">
<button class="btn" t-att-class="props.confirmClass" t-on-click="_confirm" t-esc="props.confirmLabel"/>
<button t-if="props.cancel" class="btn btn-secondary" t-on-click="_cancel" t-esc="props.cancelLabel"/>
</t>
</Dialog>
</t>
`);
registerTemplate("web.CopyButton", `/web/static/src/core/copy_button/copy_button.xml`, `<t t-name="web.CopyButton" xml:space="preserve">
<button type="button" class="text-nowrap" t-ref="button" t-att-disabled="props.disabled" t-attf-class="btn o_clipboard_button {{ props.className || '' }}" t-on-click.stop="onClick">
<span class="mx-1" t-attf-class="fa {{ props.icon || 'fa-clipboard' }}"/>
<span t-if="props.copyText" t-esc="props.copyText"/>
</button>
</t>
`);
registerTemplate("web.DateTimeInput", `/web/static/src/core/datetime/datetime_input.xml`, `<t t-name="web.DateTimeInput" xml:space="preserve">
<input type="text" t-ref="start-date" t-att-id="props.id" class="o_datetime_input o_input cursor-pointer" t-att-class="props.class" autocomplete="off" t-att-placeholder="props.placeholder" t-att-disabled="props.disabled"/>
</t>
`);
registerTemplate("web.DateTimePicker.Days", `/web/static/src/core/datetime/datetime_picker.xml`, `<t t-name="web.DateTimePicker.Days" xml:space="preserve">
<div class="d-flex gap-3">
<t t-foreach="items" t-as="month" t-key="month.id">
<div class="o_date_picker d-grid flex-grow-1 rounded overflow-auto" t-on-pointerleave="() =&gt; (state.hoveredDate = null)">
<t t-foreach="month.daysOfWeek" t-as="dayOfWeek" t-key="dayOfWeek[0]">
<div class="o_day_of_week_cell fw-bolder d-flex align-items-center justify-content-center" t-att-title="dayOfWeek[1]">
<div class="text-nowrap overflow-hidden" t-esc="props.daysOfWeekFormat === 'narrow' ? dayOfWeek[2] : dayOfWeek[0]"/>
</div>
</t>
<t t-foreach="month.weeks" t-as="week" t-key="week.number">
<t t-if="props.showWeekNumbers">
<div class="o_week_number_cell d-flex justify-content-end align-items-center pe-3 fw-bolder" t-esc="week.number"/>
</t>
<t t-foreach="week.days" t-as="itemInfo" t-key="itemInfo.id">
<t t-set="arInfo" t-value="getActiveRangeInfo(itemInfo)"/>
<div class="o_date_item_cell o_datetime_button o_center" t-att-class="{ 'o_out_of_range text-muted': itemInfo.isOutOfRange, o_selected: arInfo.isSelected, o_select_start: arInfo.isSelectStart, o_select_end: arInfo.isSelectEnd, o_highlighted: arInfo.isHighlighted, 'o_today fw-bolder': itemInfo.includesToday, [itemInfo.extraClass]: true, 'opacity-50': !itemInfo.isValid, 'cursor-pointer': itemInfo.isValid, }" t-att-disabled="!itemInfo.isValid" t-on-pointerenter="() =&gt; (state.hoveredDate = itemInfo.range[0])" t-on-click="() =&gt; this.zoomOrSelect(itemInfo)">
<div t-att-class="{'w-75 align-content-center text-center rounded-circle': itemInfo.includesToday}">
<t t-esc="itemInfo.label"/>
</div>
</div>
</t>
</t>
</div>
</t>
</div>
<div t-if="props.type === 'datetime'" class="d-flex gap-3 justify-content-between">
<div class="d-flex gap-1 align-items-center">
<TimePicker t-if="state.timeValues[0]" value="state.timeValues[0]" onChange="(newTime) =&gt; this.onTimeChange(0, newTime)" minutesRounding="props.rounding" showSeconds="props.rounding === 0" inputCssClass="'o_input'"/>
<i t-if="state.timeValues[0] and state.timeValues[1]" class="fa fa-long-arrow-right"/>
<TimePicker t-if="state.timeValues[1]" value="state.timeValues[1]" onChange="(newTime) =&gt; this.onTimeChange(1, newTime)" minutesRounding="props.rounding" showSeconds="props.rounding === 0" inputCssClass="'o_input'"/>
</div>
<t t-slot="buttons"/>
</div>
</t>
`);
registerTemplate("web.DateTimePicker.Grid", `/web/static/src/core/datetime/datetime_picker.xml`, `<t t-name="web.DateTimePicker.Grid" xml:space="preserve">
<div class="o_date_item_picker d-grid">
<t t-foreach="items" t-as="itemInfo" t-key="itemInfo.id">
<t t-set="arInfo" t-value="getActiveRangeInfo(itemInfo)"/>
<div class="o_date_item_cell o_datetime_button o_center cursor-pointer" t-att-class="{ o_selected: arInfo.isSelected, o_select_start: arInfo.isSelectStart, o_select_end: arInfo.isSelectEnd, o_highlighted: arInfo.isHighlighted, o_today: itemInfo.includesToday, 'opacity-50': !itemInfo.isValid, }" t-att-disabled="!itemInfo.isValid" t-on-click="() =&gt; this.zoomOrSelect(itemInfo)">
<t t-esc="itemInfo.label"/>
</div>
</t>
</div>
</t>
`);
registerTemplate("web.DateTimePicker", `/web/static/src/core/datetime/datetime_picker.xml`, `<t t-name="web.DateTimePicker" xml:space="preserve">
<div class="o_datetime_picker d-flex flex-column gap-2 user-select-none p-2" t-attf-style="--DateTimePicker__Day-template-columns: {{ props.showWeekNumbers ? 8 : 7 }}">
<nav class="o_datetime_picker_header d-flex">
<button class="o_previous btn btn-sm opacity-75 opacity-100-hover" t-on-click="previous" tabindex="-1">
<i class="oi oi-chevron-left" t-att-title="activePrecisionLevel.prevTitle"/>
</button>
<button class="o_next btn btn-sm opacity-75 opacity-100-hover" t-on-click="next" tabindex="-1">
<i class="oi oi-chevron-right" t-att-title="activePrecisionLevel.nextTitle"/>
</button>
<button class="o_zoom_out o_datetime_button btn opacity-75 opacity-100-hover text-truncate" tabindex="-1" t-att-class="{ 'disabled': isLastPrecisionLevel }" t-att-title="!isLastPrecisionLevel and activePrecisionLevel.mainTitle" t-on-click="zoomOut">
<t t-foreach="titles" t-as="title" t-key="title">
<strong class="o_header_part" t-esc="title"/>
</t>
</button>
<button t-if="props.showRangeToggler" class="o_toggle_range btn btn-secondary btn-sm ms-auto" tabindex="-1" title="Toggle date range mode" t-on-click="props.onToggleRange" t-att-class="{'active': props.range}">
<i class="fa fa-calendar-plus-o"/>
</button>
</nav>
<t t-if="state.precision === 'days'">
<t t-call="web.DateTimePicker.Days"/>
</t>
<t t-else="">
<t t-call="web.DateTimePicker.Grid"/>
</t>
</div>
</t>
`);
registerTemplate("web.DateTimePickerPopover", `/web/static/src/core/datetime/datetime_picker_popover.xml`, `<t t-name="web.DateTimePickerPopover" xml:space="preserve">
<DateTimePicker t-props="props.pickerProps">
<t t-set-slot="buttons">
<div class="o_datetime_buttons d-flex gap-2">
<button class="btn btn-sm btn-secondary" title="Clear" tabindex="-1" t-on-click="props.pickerProps.onReset">
<i class="fa fa-eraser"/>
</button>
<button class="btn btn-sm btn-primary" tabindex="-1" t-on-click="props.close">
<span>Apply</span>
</button>
</div>
</t>
</DateTimePicker>
</t>
`);
registerTemplate("web.DebugMenu", `/web/static/src/core/debug/debug_menu.xml`, `<t t-name="web.DebugMenu" xml:space="preserve">
<div class="o_debug_manager">
<Dropdown beforeOpen.bind="loadGroupedItems" position="'bottom-end'">
<button t-att-class="\`o-dropdown--narrow \${env.inDialog?'btn btn-link':''}\`">
<i class="fa fa-bug" role="img" aria-label="Open developer tools"/>
</button>
<t t-set-slot="content">
<t t-foreach="sectionEntries" t-as="entry" t-key="entry[0]">
<div class="dropdown-menu_group dropdown-header">
<t t-esc="getSectionLabel(entry[0])"/>
</div>
<t t-foreach="entry[1]" t-as="element" t-key="element_index">
<DropdownItem t-if="element.type == 'item'" onSelected="element.callback" attrs="{ href: element.href }">
<span t-att-class="entry[0] and 'ps-3'" t-esc="element.description"/>
</DropdownItem>
<t t-if="element.type == 'component'" t-component="element.Component" t-props="element.props"/>
</t>
</t>
</t>
</Dropdown>
</div>
</t>
`);
registerTemplate("web.DebugMenu.SetDefaultDialog", `/web/static/src/core/debug/debug_menu_items.xml`, `<t t-name="web.DebugMenu.SetDefaultDialog" xml:space="preserve">
<Dialog title.translate="Set Default Values">
<table style="width: 100%">
<tr>
<td>
<label for="formview_default_fields" class="oe_label oe_align_right">
Default:
</label>
</td>
<td class="oe_form_required">
<select id="formview_default_fields" class="o_input" t-model="state.fieldToSet">
<option value=""/>
<option t-foreach="defaultFields" t-as="field" t-att-value="field.name" t-key="field.name">
<t t-esc="field.string"/> = <t t-esc="field.displayed"/>
</option>
</select>
</td>
</tr>
<tr t-if="conditions.length">
<td>
<label for="formview_default_conditions" class="oe_label oe_align_right">
Condition:
</label>
</td>
<td>
<select id="formview_default_conditions" class="o_input" t-model="state.condition">
<option value=""/>
<option t-foreach="conditions" t-as="cond" t-att-value="cond.name + '=' + cond.value" t-key="cond.name">
<t t-esc="cond.string"/>=<t t-esc="cond.displayed"/>
</option>
</select>
</td>
</tr>
<tr>
<td colspan="2">
<input type="radio" id="formview_default_self" value="self" name="scope" t-model="state.scope"/>
<label for="formview_default_self" class="oe_label" style="display: inline;">
Only you
</label>
<br/>
<input type="radio" id="formview_default_all" value="all" name="scope" t-model="state.scope"/>
<label for="formview_default_all" class="oe_label" style="display: inline;">
All users
</label>
</td>
</tr>
</table>
<t t-set-slot="footer">
<button class="btn btn-secondary" t-on-click="props.close">Close</button>
<button class="btn btn-secondary" t-on-click="saveDefault">Save default</button>
</t>
</Dialog>
</t>
`);
registerTemplate("web.DebugMenu.GetMetadataDialog", `/web/static/src/core/debug/debug_menu_items.xml`, `<t t-name="web.DebugMenu.GetMetadataDialog" xml:space="preserve">
<Dialog title.translate="Metadata">
<table class="table table-sm table-striped">
<tr>
<th>ID:</th>
<td><t t-esc="state.id"/></td>
</tr>
<tr>
<th>XML ID:</th>
<td>
<t t-if="state.xmlids.length &gt; 1">
<t t-foreach="state.xmlids" t-as="imd" t-key="imd['xmlid']">
<div t-att-class="&quot;p-0 &quot; + (imd[&quot;xmlid&quot;] === state.xmlid ? &quot;fw-bolder &quot; : &quot;&quot;) + (imd[&quot;noupdate&quot;] === true ? &quot;fst-italic &quot; : &quot;&quot;)" t-esc="imd['xmlid']"/>
</t>
</t>
<t t-elif="state.xmlid" t-esc="state.xmlid"/>
<t t-else="">
/ <a t-on-click="onClickCreateXmlid"> (create)</a>
</t>
</td>
</tr>
<tr>
<th>No Update:</th>
<td>
<t t-esc="state.noupdate"/>
<t t-if="state.xmlid">
<a t-on-click="toggleNoupdate"> (change)</a>
</t>
</td>
</tr>
<tr>
<th>Creation User:</th>
<td><t t-esc="state.creator"/></td>
</tr>
<tr>
<th>Creation Date:</th>
<td><t t-esc="state.createDate"/></td>
</tr>
<tr>
<th>Latest Modification by:</th>
<td><t t-esc="state.lastModifiedBy"/></td>
</tr>
<tr>
<th>Latest Modification Date:</th>
<td><t t-esc="state.writeDate"/></td>
</tr>
</table>
</Dialog>
</t>
`);
registerTemplate("web.DebugMenu.GetViewDialog", `/web/static/src/core/debug/debug_menu_items.xml`, `<t t-name="web.DebugMenu.GetViewDialog" xml:space="preserve">
<Dialog title.translate="Computed Arch">
<pre t-esc="props.arch"/>
<t t-set-slot="footer">
<button class="btn btn-primary o-default-button" t-on-click="() =&gt; props.close()">Close</button>
</t>
</Dialog>
</t>
`);
registerTemplate("web.Dialog", `/web/static/src/core/dialog/dialog.xml`, `<t t-name="web.Dialog" xml:space="preserve">
<div class="o_dialog" t-att-id="id" t-att-class="{ o_inactive_modal: !data.isActive }">
<div role="dialog" class="modal d-block" tabindex="-1" t-att-class="{ o_technical_modal: props.technical, o_modal_full: isFullscreen, o_inactive_modal: !data.isActive }" t-ref="modalRef">
<div class="modal-dialog modal-dialog-centered" t-attf-class="modal-{{props.size}}">
<div class="modal-content" t-att-class="props.contentClass" t-att-style="contentStyle">
<header t-if="props.header" class="modal-header">
<t t-slot="header" close="data.close" isFullscreen="isFullscreen">
<t t-call="web.Dialog.header">
<t t-set="fullscreen" t-value="isFullscreen"/>
<t t-set="onExpand" t-value="props.onExpand"/>
</t>
</t>
</header>
<main class="modal-body" t-attf-class="{{ props.bodyClass }} {{ !props.withBodyPadding ? 'p-0': '' }}" t-att-tabindex="this.bodyTabIndex">
<t t-slot="default" close="() =&gt; this.data.close()"/>
</main>
<footer t-if="props.footer" class="modal-footer d-empty-none justify-content-around justify-content-md-start flex-wrap gap-1 w-100">
<t t-slot="footer" close="() =&gt; this.data.close()"/>
</footer>
</div>
</div>
</div>
</div>
</t>
`);
registerTemplate("web.Dialog.header", `/web/static/src/core/dialog/dialog.xml`, `<t t-name="web.Dialog.header" xml:space="preserve">
<t t-if="fullscreen">
<button class="btn oi oi-arrow-left" aria-label="Close" tabindex="-1" t-on-click="dismiss"/>
</t>
<h4 class="modal-title text-break flex-grow-1" t-att-class="{ 'me-auto': fullscreen }">
<t t-esc="props.title"/>
</h4>
<t t-if="onExpand">
<button type="button" class="fa fa-expand btn opacity-75 opacity-100-hover o_expand_button" aria-label="Expand" tabindex="-1" t-on-click="onExpand"/>
</t>
<t t-if="!fullscreen">
<button type="button" class="btn-close" aria-label="Close" tabindex="-1" t-on-click="dismiss"/>
</t>
</t>
`);
registerTemplate("web.DomainSelector", `/web/static/src/core/domain_selector/domain_selector.xml`, `<t t-name="web.DomainSelector" xml:space="preserve">
<div class="o_domain_selector w-100" aria-atomic="true" t-att-class="props.className">
<t t-if="tree">
<TreeEditor resModel="props.resModel" tree="tree" update.bind="update" readonly="props.readonly" isDebugMode="props.isDebugMode" defaultConnector="props.defaultConnector" getDefaultCondition.bind="getDefaultCondition" getOperatorEditorInfo.bind="getOperatorEditorInfo" getDefaultOperator.bind="getDefaultOperator" getPathEditorInfo.bind="getPathEditorInfo">
<CheckBox t-if="showArchivedCheckbox" value="includeArchived" disabled="props.readonly" className="'form-switch'" onChange.bind="toggleIncludeArchived">
Include archived
</CheckBox>
</TreeEditor>
</t>
<t t-else="">
<div class="o_domain_selector_row d-flex align-items-center">
This domain is not supported.
<t t-if="!props.readonly">
<button class="btn btn-sm btn-primary ms-2" t-on-click="() =&gt; this.resetDomain()">Reset domain</button>
</t>
</div>
</t>
<t t-if="props.isDebugMode and (!tree or !props.readonly)">
<label class="o_domain_selector_debug_container d-block mt-3 border rounded p-3 bg-100 text-muted font-monospace">
<span class="small"># Code editor</span>
<textarea class="pt-2 border-0 bg-transparent text-body" type="text" t-att-readonly="props.readonly" spellcheck="false" t-att-value="props.domain" t-on-input="(ev) =&gt; this.onDomainInput(ev.target.value)" t-on-change="(ev) =&gt; this.onDomainChange(ev.target.value)"/>
</label>
</t>
</div>
</t>
`);
registerTemplate("web.DomainSelectorDialog", `/web/static/src/core/domain_selector_dialog/domain_selector_dialog.xml`, `<t t-name="web.DomainSelectorDialog" xml:space="preserve">
<Dialog title="dialogTitle" size="'xl'">
<div t-if="props.text" class="mb-3" t-out="props.text"/>
<DomainSelector t-props="domainSelectorProps"/>
<t t-set-slot="footer">
<t t-if="props.readonly">
<button class="btn btn-secondary" t-on-click="() =&gt; props.close()">Close</button>
</t>
<t t-else="">
<button class="btn btn-primary" t-att-disabled="disabled" t-on-click="onConfirm" t-ref="confirm"><t t-esc="confirmButtonText"/></button>
<button class="btn btn-secondary" t-on-click="onDiscard"><t t-esc="discardButtonText"/></button>
</t>
</t>
</Dialog>
</t>
`);
registerTemplate("web.AccordionItem", `/web/static/src/core/dropdown/accordion_item.xml`, `<t t-name="web.AccordionItem" xml:space="preserve">
<div class="o_accordion position-relative">
<button class="o_menu_item o_accordion_toggle dropdown-item o-navigable" tabindex="0" t-att-class="{'selected': props.selected, 'open': state.open}" t-attf-class="{{ props.class }}" t-att-aria-expanded="state.open ? 'true' : 'false'" t-esc="props.description" t-on-click="() =&gt; state.open = !state.open"/>
<t t-if="state.open">
<div class="o_accordion_values ms-4 border-start">
<t t-slot="default"/>
</div>
</t>
</div>
</t>
`);
registerTemplate("web.DropdownItem", `/web/static/src/core/dropdown/dropdown_item.xml`, `<t t-name="web.DropdownItem" xml:space="preserve">
<t t-tag="props.tag ?? (props.attrs and props.attrs.href ? 'a' : 'span')" class="o-dropdown-item dropdown-item o-navigable" t-att-class="props.class" t-on-click.stop="onClick" t-on-mouseenter="() =&gt; this.dropdownControl.closeChildren()" role="menuitem" tabindex="0" t-att="props.attrs">
<t t-slot="default"/>
</t>
</t>
`);
registerTemplate("web.CheckboxItem", `/web/static/src/core/dropdown/dropdown_item.xml`, `<t t-name="web.CheckboxItem" t-inherit="web.DropdownItem" t-inherit-mode="primary" xml:space="preserve">
<xpath expr="//t[@role='menuitem']" position="attributes">
<attribute name="role">menuitemcheckbox</attribute>
<attribute name="t-att-aria-checked">props.checked ? 'true' : 'false'</attribute>
</xpath>
</t>
`);
registerTemplate("web.Dropzone", `/web/static/src/core/dropzone/dropzone.xml`, `<t t-name="web.Dropzone" xml:space="preserve">
<div class="o-Dropzone position-fixed align-items-center justify-content-center d-flex border-primary bg-100 text-primary opacity-75" t-att-class="{ 'o-dragging-inside': state.isDraggingInside }" t-attf-class="{{ props.extraClass }}" t-on-dragenter="() =&gt; state.isDraggingInside = true" t-on-dragleave="() =&gt; state.isDraggingInside = false" t-on-drop="props.onDrop" t-ref="root">
<t t-slot="default">
<h4>Drag Files Here <i class="fa fa-download"/></h4>
</t>
</div>
</t>
`);
registerTemplate("web.RainbowMan", `/web/static/src/core/effects/rainbow_man.xml`, `<t t-name="web.RainbowMan" xml:space="preserve">
<div class="o_reward position-fixed top-0 start-0 w-100 h-100" t-att-class="{ o_reward_fading: state.isFading }" t-on-animationend="onAnimationEnd">
<svg class="o_reward_rainbow_man position-absolute top-0 bottom-0 start-0 end-0 m-auto overflow-visible" viewBox="0 0 400 400">
<defs>
<radialGradient id="o_reward_gradient_bg" cx="200" cy="200" r="200" gradientUnits="userSpaceOnUse">
<stop offset="0.3" stop-color="#edeff4"/>
<stop offset="1" stop-color="#edeff4" stop-opacity="0"/>
</radialGradient>
<symbol id="o_reward_star">
<path d="M33 15.9C26.3558 13.6951 21.1575 8.4597 19 1.8 19 1.2477 18.5523.8 18 .8 17.4477.8 17 1.2477 17 1.8 14.6431 8.6938 9.0262 13.9736 2 15.9 1.3649 15.9.85 16.4149.85 17.05.85 17.6851 1.3649 18.2 2 18.2 8.6215 20.3845 13.8155 25.5785 16 32.2 16 32.7523 16.4477 33.2 17 33.2 17.5523 33.2 18 32.7523 18 32.2 20.3569 25.3062 25.9738 20.0264 33 18.1 33.6351 18.1 34.15 17.5851 34.15 16.95 34.15 16.3149 33.6351 15.8 33 15.8" fill="#FFFFFF"/>
</symbol>
<symbol id="o_reward_thumb">
<path d="M10 52C6 51 3 48 3 44 2 42 3 39 5 38 3 36 2 34 2 32 2 29 3 27 5 26 3 24 2 21 2 19 2 15 7 12 10 12L23 12C23 11 23 11 23 11L23 10C23 8 24 6 25 4 27 2 29 2 31 2 33 2 35 2 36 4 38 5 39 7 39 10L39 38C39 41 37 45 35 47 32 50 28 51 25 52L10 52 10 52Z" fill="#FBFBFC"/>
<polygon fill="#ECF1FF" points="25 11 25 51 5 52 5 12"/>
<path d="M31 0C28 0 26 1 24 3 22 5 21 7 21 10L10 10C8 10 6 11 4 12 2 14 1 16 1 19 1 21 1 24 2 26 1 27 1 29 1 32 1 34 1 36 2 38 1 40 0 42 1 45 1 50 5 53 10 54L25 54C29 54 33 52 36 49 39 46 41 42 41 38L41 10C41 4 36 0 31 0M31 4C34 4 37 6 37 10L37 38C37 41 35 44 33 46 31 48 28 49 25 50L10 50C7 49 5 47 5 44 4 41 6 38 9 37L9 37C6 37 5 35 5 32 5 28 6 26 9 26L9 26C6 26 5 22 5 19 5 16 8 14 11 14L23 14C24 14 25 12 25 11L25 10C25 7 28 4 31 4" fill="#A1ACBA"/>
</symbol>
</defs>
<rect width="400" height="400" fill="url(#o_reward_gradient_bg)"/>
<g transform="translate(47 45) scale(0.9)" class="o_reward_rainbow">
<path d="M270,170a100,100,0,0,0-200,0" class="o_reward_rainbow_line" stroke="#FF9E80" stroke-linecap="round" stroke-width="21" fill="none" stroke-dasharray="600 600" stroke-dashoffset="-600"/>
<path d="M290,170a120,120,0,0,0-240,0" class="o_reward_rainbow_line" stroke="#FFE57F" stroke-linecap="round" stroke-width="21" fill="none" stroke-dasharray="600 600" stroke-dashoffset="-600"/>
<path d="M310,170a140,140,0,0,0-280,0" class="o_reward_rainbow_line" stroke="#80D8FF" stroke-linecap="round" stroke-width="21" fill="none" stroke-dasharray="600 600" stroke-dashoffset="-600"/>
<path d="M330,170a160,160,0,0,0-320,0" class="o_reward_rainbow_line" stroke="#C794BA" stroke-linecap="round" stroke-width="21" fill="none" stroke-dasharray="600 600" stroke-dashoffset="-600"/>
</g>
<g transform="translate(80 125)">
<use href="#o_reward_star" transform-origin="center" class="o_reward_box o_reward_star_01"/>
</g>
<g transform="translate(140 75)">
<use href="#o_reward_star" transform-origin="center" class="o_reward_box o_reward_star_02"/>
</g>
<g transform="translate(230 90)">
<use href="#o_reward_star" transform-origin="center" class="o_reward_box o_reward_star_03"/>
</g>
<g transform="translate(275 120)">
<use href="#o_reward_star" transform-origin="center" class="o_reward_box o_reward_star_04"/>
</g>
<g class="o_reward_face_group o_reward_box" transform-origin="center top">
<g class="o_reward_shadow_container o_reward_box">
<ellipse class="o_reward_shadow o_reward_box" cx="200" cy="105%" rx="100" ry="6" fill="#000" opacity="0.25" transform-origin="center"/>
</g>
<g class="o_reward_face_wrap o_reward_box" transform-origin="center">
<image class="o_reward_face" x="132" y="125" width="136" height="136" t-attf-href="{{props.imgUrl}}"/>
</g>
<g transform="translate(258 174)">
<use href="#o_reward_thumb" class="o_reward_box o_reward_thumbup" transform-origin="center"/>
</g>
</g>
</svg>
<div class="o_reward_rainbow_man o_reward_msg_container position-absolute top-0 bottom-0 start-0 end-0 m-auto">
<div class="o_reward_face_group h-100 w-75 mx-auto">
<svg viewBox="0 0 42 60" preserveAspectRatio="xMinYMax meet" width="37" height="65%" class="overflow-visible position-relative ms-5">
<g class="o_reward_box">
<use href="#o_reward_thumb" x="-60%" y="0" transform="rotate(-90) scale(1 -1)" transform-origin="center"/>
</g>
</svg>
<div class="o_reward_msg mx-4">
<div class="o_reward_msg_card">
<div class="o_reward_msg_content text-muted px-3 py-4 bg-view d-inline-block border border-light border-top-0">
<t t-if="!props.Component">
<t t-out="props.message"/>
</t>
<t t-else="" t-component="props.Component" t-props="props.props"/>
</div>
</div>
</div>
</div>
</div>
</div>
</t>
`);
registerTemplate("web.EmojiPicker", `/web/static/src/core/emoji_picker/emoji_picker.xml`, `<t t-name="web.EmojiPicker" xml:space="preserve">
<div class="o-EmojiPicker bg-100 d-flex flex-column justify-content-center rounded-3" t-att-class="{ 'align-items-center': emojis.length === 0, 'h-100': props.mobile }" t-attf-class="{{props.class}}" t-on-click="onClick" t-on-keydown="onKeydown">
<t t-if="emojis.length === 0">
<span class="o-EmojiPicker-empty">😵‍💫</span>
<span class="fs-5 text-muted">Failed to load emojis...</span>
</t>
<t t-else="">
<div class="o-EmojiPicker-search d-flex align-items-center mx-2 mt-2 rounded">
<span class="o-EmojiPicker-searchContour d-flex mx-1 w-100 rounded o-active align-items-center justify-content-center border border-secondary bg-view">
<t t-call="web.EmojiPicker.searchInput">
<t t-if="props.state" t-set="localState" t-value="props.state"/>
<t t-else="" t-set="localState" t-value="state"/>
</t>
<i class="oi oi-search px-2 py-1 fs-7 rounded-start-0 rounded-3 o-active opacity-50" title="Search..." role="img" aria-label="Search..."/>
</span>
</div>
<t t-set="itemIndex" t-value="0"/>
<t t-set="emojisFromSearch" t-value="getEmojisFromSearch()"/>
<div class="o-EmojiPicker-content overflow-auto d-flex flex-grow-1 w-100 flex-wrap align-items-center user-select-none mt-1" t-att-class="emojisFromSearch.length === 0 ? 'flex-column justify-content-center' : 'align-content-start'" t-ref="emoji-grid" t-on-scroll="highlightActiveCategory">
<t t-if="searchTerm and emojisFromSearch.length === 0" class="d-flex flex-column">
<span class="o-EmojiPicker-empty">😢</span>
<span class="fs-5 text-muted">No emojis match your search</span>
</t>
<t t-if="recentEmojis.length &gt; 0">
<t t-if="!searchTerm" t-call="web.EmojiPicker.section">
<t t-set="category" t-value="recentCategory"/>
</t>
<t t-foreach="recentEmojis" t-as="emoji" t-key="'recent_' + emoji_index">
<t t-call="web.EmojiPicker.emoji">
<t t-set="inRecent" t-value="true"/>
<t t-set="emoji" t-value="emoji"/>
</t>
<t t-set="itemIndex" t-value="itemIndex + 1"/>
</t>
</t>
<t t-set="current" t-value=""/>
<t t-foreach="getEmojis()" t-as="emoji" t-key="emoji_index">
<t t-if="!searchTerm and current !== emoji.category">
<t t-set="current" t-value="emoji.category"/>
<t t-set="category" t-value="categories.find(c =&gt; c.name === current)"/>
<t t-call="web.EmojiPicker.section">
<t t-set="category" t-value="category"/>
</t>
</t>
<t t-elif="searchTerm" t-set="categorySortId" t-value="null"/>
<t t-call="web.EmojiPicker.emoji">
<t t-set="emoji" t-value="emoji"/>
</t>
<t t-set="itemIndex" t-value="itemIndex + 1"/>
</t>
</div>
<div class="o-EmojiPicker-navbar d-flex flex-shrink-0 w-100 align-items-center justify-content-center overflow-auto px-1 gap-1 border-top border-secondary" t-att-class="{ 'opacity-0': !state.emojiNavbarRepr }" t-ref="navbar">
<t t-if="currentNavbarPanel">
<t t-set="allCategories" t-value="getAllCategories()"/>
<t t-foreach="currentNavbarPanel" t-as="navbarItemId" t-key="navbarItemId">
<t t-if="navbarItemId === 'next'" t-call="web.EmojiPicker.tabNext"/>
<t t-elif="navbarItemId === 'previous'" t-call="web.EmojiPicker.tabPrev"/>
<t t-elif="typeof navbarItemId === 'string' and navbarItemId.startsWith('empty')" t-call="web.EmojiPicker.tabEmpty"/>
<t t-else="">
<t t-set="category" t-value="allCategories.find(cat =&gt; cat.sortId === navbarItemId)"/>
<t t-if="category" t-call="web.EmojiPicker.tab">
<t t-set="category" t-value="category"/>
</t>
</t>
</t>
</t>
</div>
</t>
</div>
</t>
`);
registerTemplate("web.EmojiPicker.tab", `/web/static/src/core/emoji_picker/emoji_picker.xml`, `<t t-name="web.EmojiPicker.tab" xml:space="preserve">
<span class="o-Emoji text-center fs-5 rounded-3 cursor-pointer d-flex align-items-center align-self-stretch" t-att-class="{'o-active': category.sortId === state.categoryId}" t-att-title="category.name" t-att-data-id="category.sortId" t-on-click="() =&gt; this.selectCategory(category.sortId)">
<span t-esc="category.title"/>
</span>
</t>
`);
registerTemplate("web.EmojiPicker.tabNext", `/web/static/src/core/emoji_picker/emoji_picker.xml`, `<t t-name="web.EmojiPicker.tabNext" xml:space="preserve">
<span class="o-Emoji text-center fs-5 rounded-3 cursor-pointer d-flex align-items-center align-self-stretch" title="To previous categories" t-on-click="onClickToNextCategories">
<span class="position-relative">
<i class="oi oi-chevron-right fa-fw smaller opacity-0"/>
<i class="oi oi-chevron-right fa-fw smaller position-absolute opacity-75" style="left: 3px; transform: translateY(75%);"/>
<i class="oi oi-chevron-right fa-fw smaller position-absolute opacity-75" style="left: -3px; transform: translateY(75%);"/>
</span>
</span>
</t>
`);
registerTemplate("web.EmojiPicker.tabPrev", `/web/static/src/core/emoji_picker/emoji_picker.xml`, `<t t-name="web.EmojiPicker.tabPrev" xml:space="preserve">
<span class="o-Emoji text-center fs-5 rounded-3 cursor-pointer d-flex align-items-center align-self-stretch" title="To next categories" t-on-click="onClickToPreviousCategories">
<span class="position-relative">
<i class="oi oi-chevron-left fa-fw smaller opacity-0"/>
<i class="oi oi-chevron-left fa-fw smaller position-absolute opacity-75" style="left: 3px; transform: translateY(75%);"/>
<i class="oi oi-chevron-left fa-fw smaller position-absolute opacity-75" style="left: -3px; transform: translateY(75%);"/>
</span>
</span>
</t>
`);
registerTemplate("web.EmojiPicker.tabEmpty", `/web/static/src/core/emoji_picker/emoji_picker.xml`, `<t t-name="web.EmojiPicker.tabEmpty" xml:space="preserve">
<span class="o-Emoji text-center fs-5 rounded-3 cursor-pointer d-flex align-items-center align-self-stretch opacity-0">
<span>🫥</span>
</span>
</t>
`);
registerTemplate("web.EmojiPicker.section", `/web/static/src/core/emoji_picker/emoji_picker.xml`, `<t t-name="web.EmojiPicker.section" xml:space="preserve">
<span class="w-100 fs-7 px-2 py-1 position-sticky top-0 bg-100 align-self-stretch" t-att-data-category="category.sortId"><span class="o-EmojiPicker-sectionIcon fs-5 opacity-50" t-esc="category.title"/><span class="ms-2 text-muted text-uppercase fs-7 opacity-50" t-esc="category.displayName"/></span>
<span class="o-EmojiPicker-category opacity-100 fs-7 py-2" t-att-data-category="category.sortId"/>
</t>
`);
registerTemplate("web.EmojiPicker.emoji", `/web/static/src/core/emoji_picker/emoji_picker.xml`, `<t t-name="web.EmojiPicker.emoji" xml:space="preserve">
<span class="o-Emoji cursor-pointer d-flex justify-content-center rounded-3 align-items-center align-self-stretch" t-att-class="{ 'o-active': state.activeEmojiIndex === itemIndex, 'fs-2': !ui.isSmall, 'fs-1': ui.isSmall }" t-att-title="emoji.name" t-att-data-codepoints="emoji.codepoints" t-att-data-index="itemIndex" t-att-data-category="inRecent ? recentCategory.sortId : categories.find(c =&gt; c.name === emoji.category).sortId" t-on-click="selectEmoji" t-on-mouseenter="(ev) =&gt; this.onMouseenterEmoji(ev, emoji)" t-on-mouseleave="(ev) =&gt; this.onMouseleaveEmoji(ev, emoji)">
<span t-esc="emoji.codepoints"/>
</span>
</t>
`);
registerTemplate("web.EmojiPicker.searchInput", `/web/static/src/core/emoji_picker/emoji_picker.xml`, `<t t-name="web.EmojiPicker.searchInput" xml:space="preserve">
<input class="form-control border-0 flex-grow-1 rounded-3 rounded-end-0 o-active lh-1" t-att-placeholder="placeholder" t-model="localState.searchTerm" t-ref="autofocus" t-att-model="localState.searchTerm" t-on-input="() =&gt; this.state.activeEmojiIndex = 0" t-att-tabindex="isMobileOS ? -1 : 0"/>
</t>
`);
registerTemplate("web.WarningDialog", `/web/static/src/core/errors/error_dialogs.xml`, `<t t-name="web.WarningDialog" xml:space="preserve">
<Dialog title="title" size="'xl'" contentClass="'o_error_dialog'">
<div role="alert">
<p t-esc="message" class="text-prewrap"/>
</div>
<t t-set-slot="footer">
<button class="btn btn-primary o-default-button" t-on-click="props.close">Close</button>
</t>
</Dialog>
</t>
`);
registerTemplate("web.RedirectWarningDialog", `/web/static/src/core/errors/error_dialogs.xml`, `<t t-name="web.RedirectWarningDialog" xml:space="preserve">
<Dialog title="title" size="'xl'" contentClass="'o_error_dialog'">
<div role="alert">
<p t-esc="message" class="text-prewrap"/>
</div>
<t t-set-slot="footer">
<button class="btn btn-primary" t-on-click="onClick" t-esc="buttonText"/>
<button class="btn btn-secondary" t-on-click="props.close">Close</button>
</t>
</Dialog>
</t>
`);
registerTemplate("web.Error504Dialog", `/web/static/src/core/errors/error_dialogs.xml`, `<t t-name="web.Error504Dialog" xml:space="preserve">
<Dialog title.translate="Request timeout" size="'xl'" contentClass="'o_error_dialog'">
<div role="alert">
<p class="text-prewrap">
The operation was interrupted. This usually means that the current operation is taking too much time.
</p>
</div>
<t t-set-slot="footer">
<button class="btn btn-primary o-default-button" t-on-click="props.close">Close</button>
</t>
</Dialog>
</t>
`);
registerTemplate("web.SessionExpiredDialog", `/web/static/src/core/errors/error_dialogs.xml`, `<t t-name="web.SessionExpiredDialog" xml:space="preserve">
<Dialog title.translate="Odoo Session Expired" size="'xl'" contentClass="'o_error_dialog'">
<div role="alert">
<p class="text-prewrap">
Your Odoo session expired. The current page is about to be refreshed.
</p>
</div>
<t t-set-slot="footer">
<button class="btn btn-primary o-default-button" t-on-click="onClick">Close</button>
</t>
</Dialog>
</t>
`);
registerTemplate("web.ErrorDialog", `/web/static/src/core/errors/error_dialogs.xml`, `<t t-name="web.ErrorDialog" xml:space="preserve">
<Dialog title.translate="Oops!" size="'xl'" contentClass="'o_error_dialog'">
<div role="alert">
<p class="text-prewrap">
Something went wrong... If you really are stuck, share the report with your friendly support service
</p>
<button class="btn btn-link p-0" t-on-click="() =&gt; { state.showTraceback = !state.showTraceback }" t-esc="state.showTraceback ? this.constructor.hideTracebackButtonText : this.constructor.showTracebackButtonText"/>
<div t-if="state.showTraceback" class="bg-100 mb-0 clearfix mt-3 position-relative o_error_detail">
<button class="btn position-absolute bg-100" t-ref="copyButton" t-on-click="onClickClipboard">
<span class="fa fa-clipboard"/>
</button>
<div class="ps-3 pt-3">
<p class="m-0"><b t-esc="title or this.constructor.title"/></p>
<code t-if="props.name" t-esc="props.name"/>
<p class="m-0" t-if="props.message" t-esc="props.message"/>
<p class="m-0" t-if="contextDetails" t-esc="contextDetails"/>
<pre class="m-0 p-0 mt-2" t-esc="traceback or props.traceback"/>
</div>
</div>
</div>
<t t-set-slot="footer">
<button class="btn btn-primary o-default-button" t-on-click="props.close">Close</button>
</t>
</Dialog>
</t>
`);
registerTemplate("web.ExpressionEditor", `/web/static/src/core/expression_editor/expression_editor.xml`, `<t t-name="web.ExpressionEditor" xml:space="preserve">
<div class="o_expression_editor w-100" aria-atomic="true">
<t t-if="tree">
<TreeEditor resModel="props.resModel" tree="tree" isDebugMode="isDebugMode" update.bind="update" getDefaultCondition.bind="getDefaultCondition" getDefaultOperator.bind="getDefaultOperator" getOperatorEditorInfo.bind="getOperatorEditorInfo" getPathEditorInfo.bind="getPathEditorInfo"/>
</t>
<t t-else="">
This expression is not supported.
<button t-on-click="() =&gt; this.resetExpression()">Reset expression</button>
</t>
<t t-if="isDebugMode">
<div class="o_expression_editor_debug_container d-block mt-3 border rounded p-3 bg-100 text-muted font-monospace">
<span class="small"># Code editor</span>
<textarea class="pt-2 border-0 bg-transparent text-body" type="text" spellcheck="false" t-att-value="props.expression" t-on-change="(ev) =&gt; this.onExpressionChange(ev.target.value)"/>
</div>
</t>
</div>
</t>
`);
registerTemplate("web.ExpressionEditorDialog", `/web/static/src/core/expression_editor_dialog/expression_editor_dialog.xml`, `<t t-name="web.ExpressionEditorDialog" xml:space="preserve">
<Dialog title.translate="Edit Condition" size="'xl'">
<ExpressionEditor t-props="expressionEditorProps"/>
<t t-set-slot="footer">
<button class="btn btn-primary" t-on-click="onConfirm" t-ref="confirm">Confirm</button>
<button class="btn btn-secondary" t-on-click="onDiscard">Discard</button>
</t>
</Dialog>
</t>
`);
registerTemplate("web.FileInput", `/web/static/src/core/file_input/file_input.xml`, `<t t-name="web.FileInput" xml:space="preserve">
<span class="o_file_input" t-att-class="{ 'd-none': props.hidden, 'show opacity-50 pe-none': state.isDisable}" aria-atomic="true">
<span t-if="!props.hidden" class="o_file_input_trigger" t-on-click.prevent="onTriggerClicked">
<t t-slot="default">
<button class="btn btn-primary">Choose File</button>
</t>
</span>
<input type="file" name="ufile" class="o_input_file d-none" t-att-multiple="props.multiUpload" t-att-accept="props.acceptedFileExtensions" t-ref="file-input" t-att-disabled="state.isDisable" t-on-change="onFileInputChange"/>
</span>
</t>
`);
registerTemplate("web.FileUploadProgressBar", `/web/static/src/core/file_upload/file_upload_progress_bar.xml`, `<t t-name="web.FileUploadProgressBar" xml:space="preserve">
<div class="position-absolute top-0 start-0 h-100 w-100">
<div class="o-file-upload-progress-bar-value h-100" t-ref="bar" t-att-style="'width: ' + (this.props.fileUpload.progress * 100) + '%;'"/>
<span class="position-absolute top-0 end-0 cursor-pointer o-file-upload-progress-bar-abort fa fa-times-circle" title="Cancel Upload" aria-label="Cancel Upload" t-on-click.stop.prevent="onCancel"/>
</div>
</t>
`);
registerTemplate("web.FileUploadProgressContainer", `/web/static/src/core/file_upload/file_upload_progress_container.xml`, `<t t-name="web.FileUploadProgressContainer" xml:space="preserve">
<t t-foreach="Object.values(props.fileUploads)" t-as="fileUpload" t-key="fileUpload.id">
<t t-if="!props.shouldDisplay || props.shouldDisplay(fileUpload)" t-component="props.Component" fileUpload="fileUpload" selector="props.selector"/>
</t>
</t>
`);
registerTemplate("web.FileUploadProgressKanbanRecord", `/web/static/src/core/file_upload/file_upload_progress_record.xml`, `<t t-name="web.FileUploadProgressKanbanRecord" xml:space="preserve">
<t t-set="progressTexts" t-value="getProgressTexts()"/>
<div class="o_kanban_record d-flex flex-grow-1 flex-md-shrink-1 flex-shrink-0">
<div class="o_kanban_progress_card o_kanban_attachment position-relative p-0 cursor-pointer">
<div class="o_kanban_image_wrapper">
<div class="o_image o_image_thumbnail" t-att-data-mimetype="props.fileUpload.type"/>
</div>
<div t-att-title="props.fileUpload.title" t-att-aria-label="props.fileUpload.title" class="fw-bold fs-5 mb-2 p-2">
<span t-esc="props.fileUpload.title"/>
</div>
<div class="o_kanban_record_body"/>
<div class="d-flex p-2 text-dark">
<div class="o_file_upload_progress_text_left" t-esc="progressTexts.left"/>
<span class="o_file_upload_progress_text_right ms-auto" t-esc="progressTexts.right"/>
</div>
<FileUploadProgressBar fileUpload="props.fileUpload"/>
</div>
</div>
</t>
`);
registerTemplate("web.FileUploadProgressDataRow", `/web/static/src/core/file_upload/file_upload_progress_record.xml`, `<t t-name="web.FileUploadProgressDataRow" xml:space="preserve">
<t t-set="progressTexts" t-value="getProgressTexts()"/>
<div class="o_data_row o_list_progress_card position-relative align-middle p-0">
<span class="o_file_upload_upload_title" t-esc="props.fileUpload.title"/>
<span class="o_file_upload_progress_text_left" t-esc="progressTexts.left"/>
<span class="o_file_upload_progress_text_right" t-esc="progressTexts.right"/>
<FileUploadProgressBar fileUpload="props.fileUpload"/>
</div>
</t>
`);
registerTemplate("web.FileViewer", `/web/static/src/core/file_viewer/file_viewer.xml`, `<t t-name="web.FileViewer" xml:space="preserve">
<div class="d-flex justify-content-center" t-att-class="{ 'modal modal-fullscreen': props.modal }">
<div class="o-FileViewer flex-column align-items-center d-flex w-100 h-100" tabindex="0" t-ref="autofocus" t-on-keydown.stop="(ev) =&gt; this.onKeydown(ev)">
<div class="o-FileViewer-header position-absolute top-0 d-flex w-100" t-on-click.stop="">
<div t-if="isViewable" class="d-flex align-items-center ms-4 me-2">
<i t-if="state.file.isImage" class="fa fa-picture-o" role="img" title="Image"/>
<i t-if="state.file.isPdf" class="fa fa-file-text" role="img" title="PDF file"/>
<i t-if="state.file.isText" class="fa fa-file-text" role="img" title="Text file"/>
<i t-if="state.file.isVideo" class="fa fa-video-camera" role="img" title="Video"/>
</div>
<div class="d-flex align-items-center ms-4 overflow-auto">
<span class="text-truncate" t-out="state.file.name"/>
</div>
<div class="flex-grow-1"/>
<div class="o-FileViewer-download o-FileViewer-headerButton d-flex align-items-center px-3 cursor-pointer" role="button" title="Download" t-on-click.stop="">
<a t-att-href="state.file.downloadUrl" class="text-reset d-flex align-items-baseline" download="">
<i class="fa fa-download fa-fw me-1" role="img"/>
<span>Download</span>
</a>
</div>
<div t-on-click.stop="close" class="o-FileViewer-headerButton d-flex align-items-center mb-0 px-3 h4 text-reset cursor-pointer" role="button" title="Close (Esc)" aria-label="Close">
<i class="fa fa-fw fa-times" role="img"/>
</div>
</div>
<div t-on-click.stop="close" t-on-mousemove="onMousemoveView" class="o-FileViewer-main position-absolute top-0 bottom-0 start-0 end-0 align-items-center justify-content-center d-flex" t-att-class="{ 'o_with_img overflow-hidden': state.file.isImage }">
<div t-if="state.file.isImage" class="o-FileViewer-zoomer position-absolute align-items-center justify-content-center d-flex w-100 h-100" t-ref="zoomer">
<div t-if="!state.imageLoaded" class="position-absolute">
<i class="fa fa-3x fa-circle-o-notch fa-fw fa-spin text-white" role="img" title="Loading"/>
</div>
<img t-on-click.stop="" t-on-load="onImageLoaded" t-on-wheel="onWheelImage" t-on-mousedown.stop="onMousedownImage" t-on-mouseup.stop="onMouseupImage" class="o-FileViewer-view o-FileViewer-viewImage mw-100 mh-100 transition-base" t-att-src="state.file.defaultSource" t-att-style="imageStyle" draggable="false" alt="Viewer" t-ref="image"/>
</div>
<iframe t-if="state.file.isPdf" class="o-FileViewer-view w-75 h-100 border-0" t-ref="iframeViewerPdf" t-att-class="{ 'w-100': ui.isSmall }" t-att-src="state.file.defaultSource"/>
<iframe t-if="state.file.isText" class="o-FileViewer-view o-isText o_text w-75 h-100 border-0" t-att-src="state.file.defaultSource"/>
<iframe t-if="state.file.isUrlYoutube" allow="autoplay; encrypted-media" class="o-FileViewer-view w-75 h-100 border-0" t-att-src="state.file.defaultSource" height="315" width="560"/>
<video t-if="state.file.isVideo" class="o-FileViewer-view w-75 h-75" t-att-class="{ 'w-100 h-100': ui.isSmall }" t-on-click.stop="" controls="controls">
<source t-att-data-type="state.file.mimetype" t-att-src="state.file.defaultSource"/>
</video>
</div>
<div t-if="state.file.isImage" class="position-absolute bottom-0 d-flex" role="toolbar">
<div class="o-FileViewer-toolbarButton p-3 rounded-0" t-on-click.stop="zoomIn" title="Zoom In (+)" role="button">
<i class="fa fa-fw fa-plus" role="img"/>
</div>
<div class="o-FileViewer-toolbarButton p-3 rounded-0" t-att-class="{ 'o_disabled opacity-50': state.scale === 1 }" t-on-click.stop="resetZoom" role="button" title="Reset Zoom (0)">
<i class="fa fa-fw fa-search" role="img"/>
</div>
<div class="o-FileViewer-toolbarButton p-3 rounded-0" t-att-class="{ 'o_disabled opacity-50': state.scale === minScale }" t-on-click.stop="zoomOut" title="Zoom Out (-)" role="button">
<i class="fa fa-fw fa-minus" role="img"/>
</div>
<div class="o-FileViewer-toolbarButton p-3 rounded-0" t-on-click.stop="rotate" title="Rotate (r)" role="button">
<i class="fa fa-fw fa-repeat" role="img"/>
</div>
<div class="o-FileViewer-toolbarButton p-3 rounded-0" t-on-click.stop="onClickPrint" title="Print" role="button">
<i class="fa fa-fw fa-print" role="img"/>
</div>
<div class="o-FileViewer-download o-FileViewer-toolbarButton p-3 rounded-0 cursor-pointer" title="Download" role="button" t-on-click.stop="">
<a t-att-href="state.file.downloadUrl" class="text-reset" download="">
<i class="fa fa-download fa-fw" role="img"/>
</a>
</div>
</div>
<t t-if="props.files.length &gt; 1">
<div class="o-FileViewer-navigation position-absolute top-0 bottom-0 start-0 align-items-center justify-content-center d-flex my-auto ms-3 rounded-circle bg-dark text-white" t-on-click.stop="previous" title="Previous (Left-Arrow)" aria-label="Previous" role="button">
<span class="oi oi-chevron-left" role="img"/>
</div>
<div class="o-FileViewer-navigation position-absolute top-0 bottom-0 end-0 align-items-center justify-content-center d-flex my-auto me-3 rounded-circle bg-dark text-white" t-on-click.stop="next" title="Next (Right-Arrow)" aria-label="Next" role="button">
<span class="oi oi-chevron-right" role="img"/>
</div>
</t>
</div>
</div>
</t>
`);
registerTemplate("web.InstallScopedApp", `/web/static/src/core/install_scoped_app/install_scoped_app.xml`, `<t t-name="web.InstallScopedApp" xml:space="preserve">
<div class="o_install_scoped_app o_home_menu_background h-100 w-100 d-flex align-items-center justify-content-center user-select-none">
<button class="btn btn-link m-1 position-absolute start-0 top-0" t-on-click="() =&gt; window.close()">
<svg xmlns="http://www.w3.org/2000/svg" style="transform:rotate(135deg);" width="28" height="28" viewBox="-7 -7 24 24" preserveAspectRatio="xMinYMin">
<path fill="#000" d="M8 8V1a1 1 0 1 1 2 0v8a1 1 0 0 1-1 1H1a1 1 0 1 1 0-2h7z"/>
</svg>
</button>
<i t-if="!state.showInstallUI" class="fa fa-circle-o-notch fa-spin fa-2x text-primary position-absolute"/>
<div t-attf-class="h-100 w-100 d-flex align-items-center justify-content-center flex-column fade {{state.showInstallUI ? 'show': ''}}">
<div class="d-flex align-items-center justify-content-center flex-wrap gap-3 m-4 mw-75 mw-md-50">
<img style="height:100px;width:100px;" class="rounded-4 p-4 bg-white shadow" t-att-src="state.manifest.icons?.[0]?.src"/>
<div class="d-inline-block">
<div class="d-flex align-items-center">
<h1 class="mb-0" t-esc="state.manifest.name"/>
<Dropdown t-if="pwa.isAvailable" menuClass="'p-2'">
<button class="btn btn-link fa fa-pencil"/>
<t t-set-slot="content">
<label class="mb-1">Application name</label>
<input class="form-control" t-att-value="state.manifest.name" t-on-change="onChangeName"/>
</t>
</Dropdown>
</div>
<a class="text-primary text-decoration-none" href="https://odoo.com" alt="Odoo" target="_blank">Odoo S.A.</a>
</div>
</div>
<button t-if="pwa.isAvailable" class="btn btn-primary btn-lg rounded-5 shadow py-2 px-3" t-on-click="onInstall">Install</button>
<div t-else="" class="p-2 px-4 overflow-hidden rounded-2 mw-75 bg-info text-white">
<t t-if="pwa.isSupportedOnBrowser">
<span t-if="pwa.hasScopeBeenInstalled()">The app seems to be installed on your device</span>
<span t-else="">You can install the app from the browser menu</span>
</t>
<span t-else="">The app cannot be installed with this browser</span>
</div>
</div>
</div>
</t>
`);
registerTemplate("web._ModelFieldSelector", `/web/static/src/core/model_field_selector/model_field_selector.xml`, `<t t-name="web._ModelFieldSelector" xml:space="preserve">
<div class="o_model_field_selector d-flex" aria-atomic="true" t-att-class="props.readonly ? 'o_read_mode' : 'o_edit_mode o_input'" t-on-click="(ev) =&gt; this.openPopover(ev.currentTarget)">
<div class="o_model_field_selector_value flex-grow-1 h-100" tabindex="0" t-att-data-tooltip="state.displayNames.join(' &gt; ')" data-tooltip-position="top">
<t t-foreach="state.displayNames" t-as="displayName" t-key="displayName_index">
<t t-if="!displayName_first">
<i class="oi oi-chevron-right m-1" role="img" aria-label="Followed by" data-tooltip="Followed by"/>
</t>
<span t-attf-class="o_model_field_selector_chain_part mb-1 #{props.readonly ? 'border-0 fw-bolder' : 'px-1'} text-nowrap">
<t t-esc="displayName"/>
</span>
</t>
</div>
<div t-if="!props.readonly and state.isInvalid" class="o_model_field_selector_controls ms-2" tabindex="0">
<i class="fa fa-exclamation-triangle text-warning o_model_field_selector_warning" role="alert" aria-label="Invalid field chain" data-tooltip="Invalid field chain"/>
</div>
<div t-if="!props.readonly and props.allowEmpty and state.displayNames.length" class="o_model_field_selector_controls ms-2" tabindex="0">
<i class="fa fa-times" t-on-click.stop="clear" aria-label="Clear" data-tooltip="Clear"/>
</div>
</div>
</t>
`);
registerTemplate("web.ModelFieldSelectorPopover", `/web/static/src/core/model_field_selector/model_field_selector_popover.xml`, `<t t-name="web.ModelFieldSelectorPopover" xml:space="preserve">
<div class="o_model_field_selector_popover d-flex flex-column" tabindex="-1" t-ref="root" t-on-keydown="onInputKeydown">
<div class="border-bottom p-2 text-dark fw-bolder">
<div class="d-flex justify-content-between align-items-center">
<t t-if="state.page.previousPage">
<i class="o_model_field_selector_popover_prev_page btn btn-link oi oi-arrow-left ms-n2 text-dark" data-tooltip="Previous" role="img" aria-label="Previous" t-on-click="() =&gt; this.goToPreviousPage()"/>
</t>
<div class="o_model_field_selector_popover_title px-2 text-truncate">
<t t-esc="state.page.title"/>
</div>
<i class="o_model_field_selector_popover_close btn btn-link me-n2 fa fa-times text-dark" data-tooltip="Close" role="img" aria-label="Close" t-on-click="() =&gt; props.close()"/>
</div>
<t t-if="props.showSearchInput">
<div class="o_model_field_selector_popover_search mt-1">
<input type="text" placeholder="Search..." class="o_input p-1 border rounded-1 bg-view" t-att-value="state.page.query" t-on-input="(ev) =&gt; this.debouncedSearchFields(ev.target.value)"/>
</div>
</t>
</div>
<div class="o_model_field_selector_popover_body overflow-auto">
<ul class="o_model_field_selector_popover_page list-unstyled mb-0">
<t t-foreach="fieldNames" t-as="fieldName" t-key="fieldName">
<t t-set="fieldDef" t-value="state.page.fieldDefs[fieldName]"/>
<li class="o_model_field_selector_popover_item d-flex border-bottom" t-att-class="{ 'active': fieldName === state.page.focusedFieldName }" t-att-data-name="fieldName">
<button t-attf-class="o_model_field_selector_popover_item_name btn btn-light flex-fill border-0 rounded-0 text-break text-start fw-normal" t-on-click="() =&gt; this.selectField(fieldDef)">
<t t-esc="fieldDef.string"/>
<t t-if="fieldDef.record_name"> (<t t-esc="fieldDef.record_name"/>)</t>
<div t-if="props.isDebugMode" class="o_model_field_selector_popover_item_title text-break text-muted small"><t t-esc="fieldName"/> (<t t-esc="fieldDef.type"/>)</div>
</button>
<t t-if="this.canFollowRelationFor(fieldDef)">
<t t-set="label">
<t t-if="fieldDef.relation">Relation to follow</t>
<t t-else="">Show options</t>
</t>
<button class="o_model_field_selector_popover_item_relation btn btn-light border-0 border-start rounded-0" t-att-data-tooltip="label" t-att-aria-label="label" t-on-click.stop="() =&gt; this.followRelation(fieldDef)">
<i class="oi oi-chevron-right o_model_field_selector_popover_relation_icon" role="img"/>
</button>
</t>
</li>
</t>
</ul>
</div>
<div t-if="showDebugInput" class="o_model_field_selector_popover_footer border-top py-1 px-2">
<input type="text" class="o_model_field_selector_debug o_input" t-att-value="state.page.path" t-on-change="(ev) =&gt; this.loadNewPath(ev.target.value)" t-on-keydown="onDebugInputKeydown" t-on-input="(ev) =&gt; this.props.update(ev.target.value, null, true)"/>
</div>
</div>
</t>
`);
registerTemplate("web.ModelSelector", `/web/static/src/core/model_selector/model_selector.xml`, `<t t-name="web.ModelSelector" xml:space="preserve">
<div class="o_model_selector" t-ref="autocomplete_container">
<input t-if="env.isSmall" type="text" class="o_input" readonly="" t-att-id="props.id" t-att-value="props.value"/>
<AutoComplete t-else="" id="props.id" value="props.value || ''" sources="sources" placeholder="this.placeholder" autoSelect="props.autoSelect" autofocus="props.autofocus"/>
<span class="o_dropdown_button"/>
</div>
</t>
`);
registerTemplate("web.Notebook", `/web/static/src/core/notebook/notebook.xml`, `<t t-name="web.Notebook" xml:space="preserve">
<div t-attf-class="o_notebook d-flex w-100 {{ props.orientation === 'horizontal' ? 'horizontal flex-column' : 'vertical flex-row' }} {{ props.className }}" t-if="state.currentPage">
<div class="o_notebook_headers" t-att-class="{ 'm-0': props.orientation === 'vertical' }">
<ul t-attf-class="nav nav-tabs {{ props.orientation === 'horizontal' ? 'flex-row flex-nowrap' : 'flex-column p-0' }}">
<li t-foreach="navItems" t-as="navItem" t-key="navItem[0]" class="nav-item flex-nowrap" t-if="navItem[1].isVisible" t-attf-class="{{ navItem[1].isDisabled ? 'disabled' : '' }}">
<a class="nav-link" t-att-class="{'active position-relative cursor-default z-1': navItem[0] === state.currentPage, 'p-3 rounded-0': props.orientation === 'vertical', 'o_page_invalid': invalidPages.has(navItem[0])}" t-attf-class="{{ navItem[1].className || '' }}" t-att-name="navItem[1].name" t-on-click.prevent="() =&gt; this.activatePage(navItem[0])" href="#" role="tab" tabindex="0">
<i t-if="props.icons and props.icons[navItem[0]]" t-attf-class="fa {{ props.icons[navItem[0]] }} me-2"/>
<t t-esc="navItem[1].title"/>
</a>
</li>
</ul>
</div>
<div class="o_notebook_content tab-content">
<div class="tab-pane active fade" t-ref="activePane">
<t t-if="page" t-component="page.Component" t-key="state.currentPage" t-props="page.props"/>
<t t-else="" t-slot="{{ state.currentPage }}"/>
</div>
</div>
</div>
</t>
`);
registerTemplate("web.NotificationWowl", `/web/static/src/core/notifications/notification.xml`, `<t t-name="web.NotificationWowl" xml:space="preserve">
<div t-on-mouseenter="freeze" t-on-mouseleave="refresh" t-attf-class="o_notification {{props.className}} d-flex mb-2 position-relative rounded shadow-lg" role="alert" aria-live="assertive" aria-atomic="true">
<span t-attf-class="o_notification_bar bg-{{props.type}} rounded-start"/>
<div class="w-100 py-2 ps-3 pe-5 border border-start-0 rounded-end text-break">
<button type="button" class="o_notification_close btn-close position-absolute top-0 end-0 mt-2 me-2" aria-label="Close" t-on-click="close"/>
<div class="o_notification_body d-flex align-items-center">
<span class="me-auto o_notification_content w-100">
<t t-if="props.title"><t t-out="props.title"/>. </t>
<t t-out="props.message"/>
</span>
<div t-if="props.buttons.length" class="o_notification_buttons justify-content-end w-50">
<button t-foreach="props.buttons" t-as="button" type="button" t-key="button_index" t-attf-class="btn btn-link" t-on-click="button.onClick">
<t t-if="button.icon">
<i t-if="button.icon.indexOf('fa-') === 0" role="img" t-att-aria-label="button.name" t-att-title="button.name" t-attf-class="fa fa-fw {{button.icon}} me-1"/>
<img t-else="" t-att-src="button.icon" t-att-alt="button.name"/>
</t>
<span class="fw-bolder" t-esc="button.name"/>
</button>
</div>
</div>
<div t-ref="autoclose_progress_bar" t-attf-class="o_notification_progress opacity-75 bg-{{props.type}}"/>
</div>
</div>
</t>
`);
registerTemplate("web.OverlayContainer", `/web/static/src/core/overlay/overlay_container.xml`, `<t t-name="web.OverlayContainer" xml:space="preserve">
<div class="o-overlay-container" t-ref="root">
<t t-foreach="sortedOverlays" t-as="overlay" t-key="overlay.id">
<ErrorHandler t-if="isVisible(overlay)" onError="(error) =&gt; this.handleError(overlay, error)">
<OverlayItem env="overlay.env" component="overlay.component" props="overlay.props"/>
</ErrorHandler>
</t>
</div>
</t>
`);
registerTemplate("web.OverlayContainer.Item", `/web/static/src/core/overlay/overlay_container.xml`, `<t t-name="web.OverlayContainer.Item" xml:space="preserve">
<div t-ref="rootRef" class="o-overlay-item">
<t t-component="props.component" t-props="props.props"/>
</div>
</t>
`);
registerTemplate("web.Pager", `/web/static/src/core/pager/pager.xml`, `<t t-name="web.Pager" xml:space="preserve">
<nav class="o_pager d-flex gap-2 h-100" aria-label="Pager">
<span t-if="!env.isSmall" class="o_pager_counter align-self-center" t-on-click.stop="">
<t t-if="state.isEditing">
<input type="text" class="o_pager_value o_input d-inline-block w-auto text-end mb-n1" size="7" t-ref="autofocus" t-att-value="value" t-on-blur="onInputBlur" t-on-change="onInputChange" t-on-keydown.stop="onInputKeydown"/>
</t>
<t t-else="">
<span class="o_pager_value d-inline-block border-bottom border-transparent mb-n1" t-esc="value" t-on-click="onValueClick"/>
</t>
<span> / </span>
<t t-if="props.updateTotal">
<span class="o_pager_limit o_pager_limit_fetch" t-att-class="{ 'disabled': state.isDisabled }" t-on-click.stop="updateTotal"><t t-esc="props.total"/>+</span>
</t>
<t t-else="">
<span class="o_pager_limit" t-esc="props.total"/>
</t>
</span>
<span class="btn-group d-print-none" aria-atomic="true">
<button type="button" class="btn btn-secondary o_pager_previous px-2 rounded-start" aria-label="Previous" data-tooltip="Previous" tabindex="-1" t-att-data-hotkey="props.withAccessKey ? 'p' : false" t-att-disabled="state.isDisabled or isSinglePage" t-on-click.stop="() =&gt; this.navigate(-1)">
<i class="oi oi-chevron-left"/>
</button>
<button type="button" class="btn btn-secondary o_pager_next px-2 rounded-end" aria-label="Next" data-tooltip="Next" tabindex="-1" t-att-data-hotkey="props.withAccessKey ? 'n' : false" t-att-disabled="state.isDisabled or isSinglePage" t-on-click.stop="() =&gt; this.navigate(1)">
<i class="oi oi-chevron-right"/>
</button>
</span>
</nav>
</t>
`);
registerTemplate("web.PagerIndicator", `/web/static/src/core/pager/pager_indicator.xml`, `<t t-name="web.PagerIndicator" xml:space="preserve">
<Transition visible="state.show" name="'o-fade'" t-slot-scope="transition" leaveDuration="400">
<div class="o_pager_indicator position-fixed top-0 end-0 m-1 d-flex" t-att-class="transition.className">
<span class="o_pager_indicator_inner m-1 px-1 text-center shadow">
<span class="o_pager_value" t-esc="state.value"/>
<span> / </span>
<span class="o_pager_limit" t-esc="state.total"/>
</span>
</div>
</Transition>
</t>
`);
registerTemplate("web.Popover", `/web/static/src/core/popover/popover.xml`, `<t t-name="web.Popover" xml:space="preserve">
<div t-ref="ref" t-att-class="defaultClassObj" t-attf-style="--animation-time: {{ constructor.animationTime }}ms" t-att-role="props.role" t-on-pointerenter="() =&gt; props.holdOnHover and position.lock()" t-on-pointerleave="() =&gt; props.holdOnHover and position.unlock()">
<t t-component="props.component" t-props="props.componentProps" close="props.close"/>
<div t-if="props.arrow" class="popover-arrow position-absolute z-n1"/>
</div>
</t>
`);
registerTemplate("web.InstallPrompt", `/web/static/src/core/pwa/install_prompt.xml`, `<t t-name="web.InstallPrompt" xml:space="preserve">
<Dialog contentClass="'o_install_prompt position-fixed px-2 py-3 m-2 user-select-none'" size="'md'" footer="false">
<t t-set-slot="header">
<div class="d-flex w-100">
<h4>How to get the application</h4>
<div t-on-click="onClose" type="button" class="btn-close" aria-label="Close"/>
</div>
</t>
<p>Install the app on your device to access it easily. Here are the steps to follow:</p>
<t t-call="web.InstallStepsSafari"/>
</Dialog>
</t>
`);
registerTemplate("web.InstallStepsSafari", `/web/static/src/core/pwa/install_prompt.xml`, `<t t-name="web.InstallStepsSafari" xml:space="preserve">
<t t-if="isMobileSafari">
<ul class="mb-0">
<li>
Tap on the share icon
</li>
<li>
Select "Add to home screen"
</li>
</ul>
</t>
<t t-else="">
<ul class="mb-0">
<li>
Open "File" menu from your browser
</li>
<li>
Select "Add to dock"
</li>
</ul>
</t>
</t>
`);
registerTemplate("web.MultiRecordSelector", `/web/static/src/core/record_selectors/multi_record_selector.xml`, `<t t-name="web.MultiRecordSelector" xml:space="preserve">
<div class="o_input d-flex flex-wrap gap-1 o_multi_record_selector" t-ref="multiRecordSelector">
<TagsList tags="tags"/>
<RecordAutocomplete resModel="props.resModel" value="''" domain="props.domain" context="props.context" className="'o_record_autocomplete_with_caret flex-grow-1'" fieldString="props.fieldString" placeholder="placeholder" multiSelect="true" getIds.bind="getIds" update.bind="update">
<t t-set-slot="autoCompleteItem" t-slot-scope="autoCompleteItemScope">
<span t-if="isAvatarModel" class="o_avatar_many2x_autocomplete o_avatar d-flex align-items-center">
<img class="rounded me-1" t-attf-src="/web/image/{{props.resModel}}/{{autoCompleteItemScope.data.record.id}}/avatar_128"/>
<t t-esc="autoCompleteItemScope.label"/>
</span>
<t t-else="" t-esc="autoCompleteItemScope.label"/>
</t>
</RecordAutocomplete>
</div>
</t>
`);
registerTemplate("web.RecordAutocomplete", `/web/static/src/core/record_selectors/record_autocomplete.xml`, `<t t-name="web.RecordAutocomplete" xml:space="preserve">
<AutoComplete placeholder="props.placeholder" value="props.value" autoSelect="true" resetOnSelect="props.multiSelect" class="props.className" sources="sources" onChange.bind="onChange">
<t t-set-slot="option" t-slot-scope="optionScope">
<t t-if="optionScope.data.record">
<t t-slot="autoCompleteItem" label="optionScope.label" data="optionScope.data"/>
</t>
<t t-else="">
<t t-esc="optionScope.label"/>
</t>
</t>
</AutoComplete>
</t>
`);
registerTemplate("web.RecordSelector", `/web/static/src/core/record_selectors/record_selector.xml`, `<t t-name="web.RecordSelector" xml:space="preserve">
<div class="o_input d-flex flex-wrap gap-1 o_record_selector">
<span t-if="hasAvatarImg" class="o_avatar o_m2o_avatar">
<img class="rounded" t-attf-src="/web/image/{{props.resModel}}/{{props.resId}}/avatar_128"/>
</span>
<RecordAutocomplete resModel="props.resModel" value="displayName" domain="props.domain" context="props.context" className="'h-100 flex-grow-1'" fieldString="props.fieldString" placeholder="props.placeholder" multiSelect="false" getIds="() =&gt; []" update.bind="update">
<t t-set-slot="autoCompleteItem" t-slot-scope="autoCompleteItemScope">
<span t-if="isAvatarModel" class="o_avatar_many2x_autocomplete o_avatar d-flex align-items-center">
<img class="rounded me-1" t-attf-src="/web/image/{{props.resModel}}/{{autoCompleteItemScope.data.record.id}}/avatar_128"/>
<t t-esc="autoCompleteItemScope.label"/>
</span>
<t t-else="" t-esc="autoCompleteItemScope.label"/>
</t>
</RecordAutocomplete>
<span class="o_dropdown_button"/>
</div>
</t>
`);
registerTemplate("web_studio.ResizablePanel", `/web/static/src/core/resizable_panel/resizable_panel.xml`, `<t t-name="web_studio.ResizablePanel" xml:space="preserve">
<div class="o_resizable_panel d-flex flex-column" t-att-class="class" t-ref="containerRef">
<t t-slot="default"/>
<div class="o_resizable_panel_handle position-absolute top-0 bottom-0 end-0" t-att-class="props.handleSide === 'start' ? 'start-0' : 'end-0'" t-ref="handleRef"/>
</div>
</t>
`);
registerTemplate("web.SelectMenu.search", `/web/static/src/core/select_menu/select_menu.xml`, `<t t-name="web.SelectMenu.search" xml:space="preserve">
<input type="text" t-attf-class="o_input {{inputClass}}" t-ref="inputRef" t-on-input="debouncedOnInput" t-on-focus="onInputFocus" t-on-blur="onInputBlur" t-att-placeholder="placeholderValue" t-att-value="displayValue" t-att-id="props.id" t-att-name="props.name" t-att-disabled="props.disabled" t-on-click="onInputClick" autocomplete="selectMenuAutocompleteOff" autocorrect="off" spellcheck="false"/>
</t>
`);
registerTemplate("web.SelectMenu", `/web/static/src/core/select_menu/select_menu.xml`, `<t t-name="web.SelectMenu" xml:space="preserve">
<div t-att-class="\`o_select_menu w-auto position-relative \${props.multiSelect ? 'o_select_menu_multi_select' : ''} \${displayInputInToggler ? 'o_input_dropdown' : ''} \${props.class || ''}\`" t-att-data-id="selectMenuId">
<Dropdown menuClass="this.menuClass" menuRef="this.menuRef" position="'bottom-fit'" beforeOpen.bind="onBeforeOpen" focusToggleOnClosed="!isBottomSheet" onStateChanged.bind="onStateChanged" navigationOptions="navigationOptions" state="dropdownState">
<t t-if="displayInputInToggler">
<t t-set="inputClass" t-value="'o_select_menu_toggler ' + (!displayInputInDropdown ? 'o_select_menu_input ' : '') + props.togglerClass"/>
<div class="w-100 d-flex flex-wrap">
<t t-if="props.multiSelect">
<TagsList t-if="props.value.length" tags="multiSelectChoices"/>
</t>
<t t-call="web.SelectMenu.search"/>
<span class="o_select_menu_caret align-self-center"/>
</div>
</t>
<t t-else="">
<button type="button" t-attf-class="o_select_menu_toggler d-flex border btn btn-light w-100 bg-light {{ props.togglerClass }}" t-att-disabled="props.disabled">
<span class="o_select_menu_toggler_slot text-start text-truncate">
<span t-if="props.placeholder and !props.value" class="text-muted" t-out="props.placeholder"/>
<t t-slot="default"/>
</span>
<span t-if="canDeselect" t-on-click.stop="onInputClear" class="o_select_menu_toggler_clear position-absolute top-50 end-0 me-3">
<i class="fa fa-times"/>
</span>
<span class="o_select_menu_caret align-self-center"/>
</button>
</t>
<t t-set-slot="content">
<button t-if="isBottomSheet and canDeselect" class="btn o_clear_button px-4 d-block ms-auto" t-on-click="onInputClear">Clear</button>
<div class="o_select_menu_searchbox position-sticky start-0 d-empty-none" t-att-data-id="selectMenuId">
<t t-if="displayInputInDropdown">
<t t-set="inputClass" t-value="'o_select_menu_input dropdown-item'"/>
<t t-call="web.SelectMenu.search"/>
</t>
</div>
<t t-if="state.choices.length === 0">
<p class="text-muted fst-italic mx-4 my-1">No results</p>
</t>
<t t-foreach="state.displayedOptions" t-as="choice" t-key="choice_index">
<t t-call="{{ this.constructor.choiceItemTemplate }}">
<t t-set="choice" t-value="choice"/>
<t t-set="choice_index" t-value="choice_index"/>
</t>
</t>
<t t-if="props.slots and props.slots.bottomArea" t-slot="bottomArea" data="state"/>
</t>
</Dropdown>
</div>
</t>
`);
registerTemplate("web.SelectMenu.ChoiceItem", `/web/static/src/core/select_menu/select_menu.xml`, `<t t-name="web.SelectMenu.ChoiceItem" xml:space="preserve">
<div t-if="choice.isGroup and choice.label" class="o_select_menu_group position-sticky start-0 px-1 fw-bolder user-select-none" t-att-class="{'o_select_menu_searchable_group': displayInputInDropdown, 'ms-2': !!choice.section }">
<span t-esc="choice.label"/>
</div>
<DropdownItem t-if="!choice.isGroup" onSelected="() =&gt; this.onItemSelected(choice.value)" class="getItemClass(choice) + ' text-wrap'" attrs="{ 'data-choice-index': choice_index }">
<t t-if="props.slots and props.slots.choice" t-slot="choice" data="choice"/>
<t t-else="">
<div t-esc="choice.label || choice.value"/>
</t>
</DropdownItem>
</t>
`);
registerTemplate("web.sign_svg_text", `/web/static/src/core/signature/name_and_signature.xml`, `<t t-name="web.sign_svg_text" name="SVG Signature Text" xml:space="preserve">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" t-att-width="width" t-att-height="height">
<defs>
<style type="text/css">
@font-face {
font-family: "font";
src: url(data:font/ttf;base64,<t t-esc="font"/>) format("woff");
font-weight: normal;
font-style: normal;
}
</style>
</defs>
<text t-esc="text" x="50%" t-att-y="height * 3 / 5" t-att-font-size="height * 3 / 5" t-att-textLength="width * 4 / 5 * (type === 'signature' ? Math.min(1, text.length / 7) : 1)" t-att-lengthAdjust="'spacing' + (type === 'signature' ? 'AndGlyphs' : '')" t-attf-style="font-family:'font'; stroke: none; fill: {{color}};" text-anchor="middle"/>
</svg>
</t>
`);
registerTemplate("web.NameAndSignature", `/web/static/src/core/signature/name_and_signature.xml`, `<t t-name="web.NameAndSignature" xml:space="preserve">
<div class="o_web_sign_name_and_signature">
<div t-if="!props.noInputName" class="o_web_sign_name_group">
<label class="col-form-label" t-att-for="'o_web_sign_name_input_' + htmlId">Full Name</label>
<input type="text" name="signer" t-att-id="'o_web_sign_name_input_' + htmlId" class="o_web_sign_name_input form-control" t-on-input="onInputSignName" t-att-value="props.signature.name" t-ref="signNameInput" placeholder="Type your name to sign" required=""/>
</div>
<div t-if="state.showSignatureArea" class="o_web_sign_signature_group bg-100 card mt-3" style="overflow: hidden;">
<div class="card-header bg-transparent">
<div class="row g-0">
<div t-if="!props.noInputName or defaultName" class="col-auto">
<a role="button" href="#" t-on-click.prevent="onClickSignAuto" t-attf-class="o_web_sign_auto_button me-2 btn btn-light {{ state.signMode === 'auto' ? 'active': '' }}">
Auto
</a>
</div>
<div class="col-auto">
<a role="button" href="#" t-on-click.prevent="() =&gt; this.setMode('draw')" t-attf-class="o_web_sign_draw_button me-2 btn btn-light {{ state.signMode === 'draw' ? 'active': '' }}">
Draw
</a>
</div>
<div class="col-auto">
<a role="button" href="#" t-on-click.prevent="onClickSignLoad" t-attf-class="o_web_sign_load_button me-2 btn btn-light {{ state.signMode === 'load' ? 'active': '' }}">
Load
</a>
</div>
<div class="col-auto division ms-auto"/>
<div t-if="state.signMode === 'auto'" class="o_web_sign_auto_select_style col-auto">
<Dropdown>
<button type="button" class="btn btn-link fa fa-font o-dropdown-caret"/>
<t t-set-slot="content">
<t t-foreach="fonts" t-as="font" t-key="font_index">
<DropdownItem onSelected="() =&gt; this.onSelectFont(font_index)">
<img class="img-fluid" t-att-src="getSVGTextFont(font)"/>
</DropdownItem>
</t>
</t>
</Dropdown>
</div>
<div t-if="state.signMode === 'draw'" t-attf-class="o_web_sign_draw_clear col-auto">
<a role="button" href="#" t-on-click.prevent="onClickSignDrawClear" class="btn btn-link fa fa-trash"/>
</div>
<div t-if="state.signMode === 'load'" class="o_web_sign_load_file col-auto">
<button type="button" id="loadFileXml" t-on-click="uploadFile" class="btn btn-link fa fa-upload"/>
<input t-ref="signInputLoad" type="file" role="button" name="files[]" class="d-none" t-on-change="onChangeSignLoadInput"/>
</div>
</div>
</div>
<div class="o_web_sign_signature_container position-relative">
<div class="o_signature_stroke position-absolute"/>
<canvas t-if="state.showSignatureArea" t-ref="signature" class="o_web_sign_signature z-1"/>
</div>
<div t-if="loadIsInvalid" t-attf-class="o_web_sign_load_invalid card-footer d-none">
<div class="alert alert-danger mb-0" role="alert">
This file is invalid. Please select an image.
</div>
</div>
</div>
</div>
</t>
`);
registerTemplate("web.SignatureDialog", `/web/static/src/core/signature/signature_dialog.xml`, `<t t-name="web.SignatureDialog" xml:space="preserve">
<Dialog title.translate="Adopt Your Signature">
<div>
<NameAndSignature t-props="nameAndSignatureProps"/>
<div class="mt16 small">By clicking Adopt &amp; Sign, I agree that the chosen signature/initials will be a valid electronic representation of my hand-written signature/initials for all purposes when it is used on documents, including legally binding contracts.</div>
</div>
<t t-set-slot="footer">
<button class="btn btn-primary" t-att-disabled="signature.isSignatureEmpty" t-on-click="onClickConfirm">Adopt &amp; Sign</button>
<button class="btn btn-secondary" t-on-click="props.close">Cancel</button>
</t>
</Dialog>
</t>
`);
registerTemplate("web.TagsList", `/web/static/src/core/tags_list/tags_list.xml`, `<t t-name="web.TagsList" xml:space="preserve">
<t t-foreach="visibleTags" t-as="tag" t-key="tag.id or tag_index">
<span class="o_tag position-relative d-inline-flex align-items-center user-select-none mw-100" t-att-class="{ 'o_avatar opacity-trigger-hover' : tag.img, 'o_badge badge rounded-pill': !tag.img, 'cursor-pointer': tag.canEdit, }" t-attf-class="{{ !tag.img ? 'o_tag_color_' + (tag.colorIndex ? tag.colorIndex : '0') : '' }}" tabindex="-1" t-att-data-color="tag.colorIndex" t-att-aria-label="tag.title || tag.text" t-att-data-tooltip="tag.title || tag.text" t-on-click="(ev) =&gt; tag.onClick and tag.onClick(ev)">
<span t-if="tag.img and props.displayText and tag.onDelete" class="o_avatar_backdrop position-absolute top-0 end-0 bottom-0 start-0 ms-n2 mt-n1 mb-n1 bg-view rounded border shadow opacity-0 opacity-100-hover"/>
<img t-if="tag.img" t-att-src="tag.img" class="o_avatar o_m2m_avatar position-relative rounded" t-att-class="tag.imageClass"/>
<i t-if="tag.icon" t-attf-class="p-1 fa {{ tag.icon }}" t-att-class="tag.className"/>
<div t-if="props.displayText" class="o_tag_badge_text text-truncate" t-att-class="{'position-relative ms-1' : tag.img}" t-out="tag.text"/>
<a t-if="tag.onDelete" t-on-click.stop.prevent="(ev) =&gt; tag.onDelete and tag.onDelete(ev)" class="o_delete d-flex align-items-center opacity-100-hover" t-att-class="{ 'btn btn-link position-relative py-0 px-1 text-danger opacity-0': tag.img, 'ps-1 opacity-75': !tag.img }" data-tooltip="Delete" aria-label="Delete" tabIndex="-1" href="#">
<i class="oi oi-close align-text-top"/>
</a>
</span>
</t>
<span t-if="otherTags.length" class="o_m2m_avatar_empty rounded text-center fw-bold cursor-default" data-tooltip-template="web.TagsList.Tooltip" data-tooltip-position="right" t-att-data-tooltip-info="tooltipInfo" t-on-click.stop="">
<span t-if="otherTags.length &gt; 9" t-esc="'9+'"/>
<span t-else="" t-esc="'+' + otherTags.length"/>
</span>
</t>
`);
registerTemplate("web.TagsList.Tooltip", `/web/static/src/core/tags_list/tags_list.xml`, `<t t-name="web.TagsList.Tooltip" xml:space="preserve">
<t t-foreach="tags" t-as="tag" t-key="tag.id or tag_index">
<div t-esc="tag.text"/>
</t>
</t>
`);
registerTemplate("web.TimePicker", `/web/static/src/core/time_picker/time_picker.xml`, `<t t-name="web.TimePicker" xml:space="preserve">
<div class="o_time_picker d-flex align-items-center justify-content-center" t-att-class="cssClass">
<Dropdown state="dropdownState" menuRef="menuRef" manual="true" focusToggleOnClosed="false" position="'bottom-start'" menuClass="'o_time_picker_dropdown pt-0 mt-0'" navigationOptions="navigationOptions" onOpened.bind="onDropdownOpened">
<input type="text" t-ref="inputRef" class="o_time_picker_input form-control px-0" t-att-class="inputCssClass" t-model="state.inputValue" t-on-input="onInput" t-on-focus="ensureOpen" t-on-click="ensureOpen" t-on-change="onChange" t-on-keydown.capture="onKeydown" t-att-placeholder="getPlaceholder()" tabindex="-1"/>
<t t-set-slot="content">
<t t-foreach="suggestions" t-as="value" t-key="value_index">
<DropdownItem class="'o_time_picker_option'" t-out="value.toString()" onSelected="() =&gt; this.onItemSelected(value)" closingMode="'none'"/>
</t>
</t>
</Dropdown>
</div>
</t>
`);
registerTemplate("web.Tooltip", `/web/static/src/core/tooltip/tooltip.xml`, `<t t-name="web.Tooltip" xml:space="preserve">
<div class="o-tooltip tooltip-inner d-print-none text-start">
<t t-if="props.template" t-call="{{props.template}}" t-call-context="{ env, ...props.info }"/>
<span t-else="" t-esc="props.tooltip"/>
</div>
</t>
`);
registerTemplate("web.TreeEditor", `/web/static/src/core/tree_editor/tree_editor.xml`, `<t t-name="web.TreeEditor" xml:space="preserve">
<div class="o_tree_editor w-100" aria-atomic="true" t-att-class="className">
<div t-attf-class="o_tree_editor_node d-flex flex-column #{props.readonly ? (props.isSubTree ? 'gap-0' : 'gap-2') : 'gap-1'}">
<t t-set="ancestors" t-value="[]"/>
<t t-set="node" t-value="tree"/>
<div class="o_tree_editor_row o_tree_editor_connector d-flex align-items-center flex-wrap" t-att-class="{'ps-4': props.isSubTree}">
<div class="d-flex flex-grow-1 align-items-center">
<t t-if="node.children.length">
<span t-if="!props.isSubTree">Match</span>
<t t-call="web.TreeEditor.connector.value"/>
<span t-if="props.isSubTree">of:</span>
<span t-else="">of the following rules:</span>
</t>
<t t-elif="node.value === '|' ? node.negate : !node.negate">
<span><span t-if="!props.isSubTree">Match </span><strong>all records</strong></span>
</t>
<t t-else="">
<span><span t-if="!props.isSubTree">Match </span><strong>no records</strong></span>
</t>
</div>
<t t-slot="default"/>
</div>
<t t-if="node.children.length" t-call="web.TreeEditor.connector.children"/>
<t t-if="!props.readonly">
<div class="o_tree_editor_row d-flex align-items-center" t-att-class="{ 'ps-4': addPadding || props.isSubTree }">
<a href="#" role="button" t-on-click="() =&gt; this.addNewCondition(node)">New Rule</a>
</div>
</t>
</div>
</div>
</t>
`);
registerTemplate("web.TreeEditor.controls", `/web/static/src/core/tree_editor/tree_editor.xml`, `<t t-name="web.TreeEditor.controls" xml:space="preserve">
<div class="o_tree_editor_node_control_panel d-flex" role="toolbar" aria-label="Domain node">
<t t-if="node.type !== 'connector'">
<button t-if="ancestors.length === 1" class="btn px-2 fs-4" role="button" data-tooltip="Add nested rule" aria-label="Add nested rule" t-on-click="() =&gt; this.addNewConnector(parent, node)" t-on-mouseenter="(ev) =&gt; this.highlightNode(ev.target, true)" t-on-mouseleave="(ev) =&gt; this.highlightNode(ev.target, false)">
<i class="fa fa-sitemap"/>
</button>
<button t-else="" class="btn px-2 fs-4" role="button" data-tooltip="Add rule" aria-label="Add rule" t-on-click="() =&gt; this.addNewCondition(parent, node)" t-on-mouseenter="(ev) =&gt; this.highlightNode(ev.target, true)" t-on-mouseleave="(ev) =&gt; this.highlightNode(ev.target, false)">
<i class="fa fa-plus"/>
</button>
</t>
<button class="btn btn-link px-2 text-danger fs-4" role="button" data-tooltip="Delete rule" aria-label="Delete rule" t-on-click="() =&gt; this.delete(ancestors, node)" t-on-mouseenter="(ev) =&gt; this.highlightNode(ev.target, true)" t-on-mouseleave="(ev) =&gt; this.highlightNode(ev.target, false)">
<i class="fa fa-trash"/>
</button>
</div>
</t>
`);
registerTemplate("web.TreeEditor.connector.value", `/web/static/src/core/tree_editor/tree_editor.xml`, `<t t-name="web.TreeEditor.connector.value" xml:space="preserve">
<t t-set="title">
<t t-if="node.value === '|'">
<t t-if="node.negate">none</t>
<t t-else="">any</t>
</t>
<t t-else="">
<t t-if="node.negate">not all</t>
<t t-else="">all</t>
</t>
</t>
<t t-if="props.readonly">
<div class="o_tree_editor_connector_value px-1">
<strong class="text-primary" t-esc="title"/>
</div>
</t>
<t t-else="">
<div class="o_tree_editor_connector_value px-1" aria-atomic="true">
<button class="btn o-dropdown o-dropdown-caret p-0 opacity-75" t-on-click="() =&gt; this.updateConnector(node)">
<strong class="text-primary" t-esc="title"/>
</button>
</div>
</t>
</t>
`);
registerTemplate("web.TreeEditor.connector.children", `/web/static/src/core/tree_editor/tree_editor.xml`, `<t t-name="web.TreeEditor.connector.children" xml:space="preserve">
<t t-foreach="node.children" t-as="child" t-key="child.type + '_' + child_index">
<div class="o_tree_editor_node" t-att-class="{ 'ps-4': addPadding || props.isSubTree }">
<t t-call="web.TreeEditor.{{ child.type }}">
<t t-set="ancestors" t-value="[...ancestors, node]"/>
<t t-set="parent" t-value="node"/>
<t t-set="node" t-value="child"/>
</t>
</div>
</t>
</t>
`);
registerTemplate("web.TreeEditor.connector", `/web/static/src/core/tree_editor/tree_editor.xml`, `<t t-name="web.TreeEditor.connector" xml:space="preserve">
<div class="o_tree_editor_row o_tree_editor_connector d-flex align-items-center">
<div class="d-flex flex-grow-1">
<t t-call="web.TreeEditor.connector.value"/>
<span>of:</span>
</div>
<t t-if="!props.readonly">
<t t-call="web.TreeEditor.controls"/>
</t>
</div>
<t t-call="web.TreeEditor.connector.children">
<t t-set="addPadding" t-value="true"/>
</t>
</t>
`);
registerTemplate("web.TreeEditor.condition", `/web/static/src/core/tree_editor/tree_editor.xml`, `<t t-name="web.TreeEditor.condition" xml:space="preserve">
<div class="o_tree_editor_row d-flex align-items-center">
<t t-if="props.readonly">
<t t-call="web.TreeEditor.condition:readonly"/>
</t>
<t t-else="">
<t t-call="web.TreeEditor.condition:editable"/>
<t t-call="web.TreeEditor.controls"/>
</t>
</div>
<t t-if="isTree(node.value)">
<TreeEditor t-props="props" update="(value) =&gt; this.updateLeafValue(node, value)" slots="{}" isSubTree="true" tree="node.value" resModel="getResModel(node)"/>
</t>
</t>
`);
registerTemplate("web.TreeEditor.condition:readonly", `/web/static/src/core/tree_editor/tree_editor.xml`, `<t t-name="web.TreeEditor.condition:readonly" xml:space="preserve">
<t t-set="description" t-value="getConditionDescription(node)"/>
<div class="o_tree_editor_condition d-flex gap-1 px-2 border bg-100">
<div class="fw-bolder text-nowrap" t-esc="description.pathDescription"/>
<div class="fst-italic text-nowrap" t-esc="description.operatorDescription"/>
<t t-if="description.valueDescription">
<t t-set="values" t-value="description.valueDescription.values"/>
<t t-set="join" t-value="description.valueDescription.join"/>
<t t-set="addParenthesis" t-value="description.valueDescription.addParenthesis"/>
<t t-if="addParenthesis">( </t>
<t t-foreach="values" t-as="val" t-key="val_index">
<span class="text-primary fw-bolder"><t t-esc="val"/></span>
<t t-if="!val_last"> <t t-esc="join"/> </t>
</t>
<t t-if="addParenthesis"> )</t>
</t>
</div>
</t>
`);
registerTemplate("web.TreeEditor.Editor", `/web/static/src/core/tree_editor/tree_editor.xml`, `<t t-name="web.TreeEditor.Editor" xml:space="preserve">
<t t-if="!info.isSupported(value)">
<div t-attf-class="o_tree_editor_editor #{_classes}">
<div class="o_input d-flex align-items-center">
<span class="flex-grow-1 text-truncate" t-esc="info.stringify(value)"/>
<i role="alert" class="fa fa-exclamation-triangle text-warning mx-2" t-att-data-tooltip="(typeof info.message === 'function') ? info.message(value) : info.message"/>
<i class="fa fa-times" data-tooltip="Clear" t-on-click="() =&gt; update(info.defaultValue())"/>
</div>
</div>
</t>
<t t-elif="info.component">
<div t-attf-class="o_tree_editor_editor #{_classes}">
<t t-component="info.component" t-props="info.extractProps({ update, value, displayPlaceholder })"/>
</div>
</t>
</t>
`);
registerTemplate("web.TreeEditor.condition:editable", `/web/static/src/core/tree_editor/tree_editor.xml`, `<t t-name="web.TreeEditor.condition:editable" xml:space="preserve">
<div class="o_tree_editor_condition d-flex flex-grow-1 align-items-end gap-2">
<t t-call="web.TreeEditor.Editor">
<t t-set="_classes" t-value="'col col-md-4 pe-0'"/>
<t t-set="info" t-value="getPathEditorInfo()"/>
<t t-set="value" t-value="node.path"/>
<t t-set="update" t-value="(path) =&gt; this.updatePath(node, path)"/>
</t>
<t t-call="web.TreeEditor.Editor">
<t t-set="_classes" t-value="'col col-md-2 px-3'"/>
<t t-set="info" t-value="getOperatorEditorInfo(node)"/>
<t t-set="value" t-value="[node.operator, node.negate]"/>
<t t-set="update" t-value="(operator, negate) =&gt; this.updateLeafOperator(node, operator, negate)"/>
</t>
<t t-call="web.TreeEditor.Editor">
<t t-set="_classes" t-value="'col ps-0 overflow-hidden'"/>
<t t-set="info" t-value="getValueEditorInfo(node)"/>
<t t-set="value" t-value="node.value"/>
<t t-set="update" t-value="(value) =&gt; this.updateLeafValue(node, value)"/>
</t>
</div>
</t>
`);
registerTemplate("web.TreeEditor.complex_condition", `/web/static/src/core/tree_editor/tree_editor.xml`, `<t t-name="web.TreeEditor.complex_condition" xml:space="preserve">
<div class="o_tree_editor_row d-flex align-items-center">
<div class="o_tree_editor_complex_condition flex-grow-1">
<input class="o_input w-100" t-att-value="node.value" t-att-readonly="props.readonly or !isDebugMode" t-on-change="(ev) =&gt; this.updateComplexCondition(node, ev.target.value)"/>
</div>
<t t-call="web.TreeEditor.controls"/>
</div>
</t>
`);
registerTemplate("web.TreeEditor.Input", `/web/static/src/core/tree_editor/tree_editor_components.xml`, `<t t-name="web.TreeEditor.Input" xml:space="preserve">
<input type="text" class="o_input" t-att-value="props.startEmpty ? '' : props.value" t-att-placeholder="props.placeholder" t-on-change="(ev) =&gt; props.update(ev.target.value)"/>
</t>
`);
registerTemplate("web.TreeEditor.Select", `/web/static/src/core/tree_editor/tree_editor_components.xml`, `<t t-name="web.TreeEditor.Select" xml:space="preserve">
<select class="o_input pe-3 text-truncate" t-on-change="(ev) =&gt; props.update(deserialize(ev.target.value))">
<option class="o_select_placeholder" t-if="props.addBlankOption" hidden="true" t-esc="props.placeholder ? props.placeholder : ''"/>
<t t-foreach="props.options" t-as="option" t-key="serialize(option[0])">
<option class="text-black" t-att-value="serialize(option[0])" t-att-selected="!props.addBlankOption and option[0] === props.value" t-esc="option[1]"/>
</t>
</select>
</t>
`);
registerTemplate("web.TreeEditor.Range", `/web/static/src/core/tree_editor/tree_editor_components.xml`, `<t t-name="web.TreeEditor.Range" xml:space="preserve">
<div class="d-flex align-items-center">
<t t-call="web.TreeEditor.Editor">
<t t-set="_classes" t-value="'overflow-hidden flex-grow-1'"/>
<t t-set="info" t-value="props.editorInfo"/>
<t t-set="value" t-value="props.value[0]"/>
<t t-set="update" t-value="(val) =&gt; this.update(0, val)"/>
</t>
<i class="fa fa-long-arrow-right mx-2" aria-label="Arrow icon" title="Arrow"/>
<t t-call="web.TreeEditor.Editor">
<t t-set="_classes" t-value="'overflow-hidden flex-grow-1'"/>
<t t-set="info" t-value="props.editorInfo"/>
<t t-set="value" t-value="props.value[1]"/>
<t t-set="update" t-value="(val) =&gt; this.update(1, val)"/>
</t>
</div>
</t>
`);
registerTemplate("web.TreeEditor.InRange", `/web/static/src/core/tree_editor/tree_editor_components.xml`, `<t t-name="web.TreeEditor.InRange" xml:space="preserve">
<div class="d-flex flex-column gap-2">
<t t-call="web.TreeEditor.Editor">
<t t-set="_classes" t-value="'overflow-hidden flex-grow-1'"/>
<t t-set="info" t-value="props.valueTypeEditorInfo"/>
<t t-set="value" t-value="props.value[1]"/>
<t t-set="update" t-value="(val) =&gt; this.updateValueType(val)"/>
</t>
<t t-if="props.value[1] === 'custom range'">
<t t-call="web.TreeEditor.Editor">
<t t-set="_classes" t-value="'overflow-hidden flex-grow-1'"/>
<t t-set="info" t-value="props.betweenEditorInfo"/>
<t t-set="value" t-value="props.value.slice(2)"/>
<t t-set="update" t-value="(val) =&gt; this.updateValues(val)"/>
</t>
</t>
</div>
</t>
`);
registerTemplate("web.TreeEditor.List", `/web/static/src/core/tree_editor/tree_editor_components.xml`, `<t t-name="web.TreeEditor.List" xml:space="preserve">
<div class="o_input d-flex flex-wrap gap-1">
<TagsList tags="tags"/>
<div class="flex-grow-1">
<t t-call="web.TreeEditor.Editor">
<t t-set="info" t-value="props.editorInfo"/>
<t t-set="value" t-value="props.editorInfo.defaultValue()"/>
<t t-set="update" t-value="(val) =&gt; this.update(val)"/>
<t t-set="displayPlaceholder" t-value="!tags.length"/>
</t>
</div>
</div>
</t>
`);
registerTemplate("web.BlockUI", `/web/static/src/core/ui/block_ui.xml`, `<t t-name="web.BlockUI" xml:space="preserve">
<t t-if="state.blockState === BLOCK_STATES.UNBLOCKED">
<div/>
</t>
<t t-else="">
<t t-set="visiblyBlocked" t-value="state.blockState === BLOCK_STATES.VISIBLY_BLOCKED"/>
<div class="o_blockUI fixed-top d-flex justify-content-center align-items-center flex-column vh-100" t-att-class="visiblyBlocked ? '' : 'o_blockUI_invisible'">
<t t-if="visiblyBlocked">
<div class="o_spinner mb-4">
<img src="/web/static/img/spin.svg" alt="Loading..."/>
</div>
<div class="o_message text-center px-4">
<t t-esc="state.line1"/><br/>
<t t-esc="state.line2"/>
</div>
</t>
</div>
</t>
</t>
`);
registerTemplate("web.login_user_switch", `/web/static/src/core/user_switch/user_switch.xml`, `<t t-name="web.login_user_switch" xml:space="preserve">
<t t-if="state.users.length">
<t t-if="state.displayUserChoice">
<div class="oe_login_form o_user_switch user-select-none my-4" t-ref="root">
<p>Choose a user</p>
<div class="list-group my-3">
<t t-foreach="state.users" t-as="user" t-key="user_index">
<button type="button" class="list-group-item list-group-item-action d-flex justify-content-between align-items-center" t-on-click="() =&gt; this.fillForm(user.login)">
<span class="d-flex justify-content-begin align-items-center">
<img class="o_avatar o_user_avatar rounded me-2" t-attf-src="{{getAvatarUrl(user)}}" t-att-alt="user.login"/>
<t t-esc="user.name"/>
</span>
<i class="fa fa-times" title="Remove user from switcher" t-on-click.stop="() =&gt; this.remove(user)"/>
</button>
</t>
</div>
<button type="button" class="btn btn-link btn-sm w-100" t-on-click="() =&gt; this.fillForm()">
<i class="fa fa-user-circle-o"/> <span class="ms-1">Use another user</span>
</button>
</div>
</t>
<t t-else="" t-portal="'label.form-label'">
<button type="button" class="o_user_switch_btn btn btn-sm btn-link m-0 p-0" tabindex="1" t-on-click="() =&gt; this.toggleFormDisplay()">
Choose a user
</button>
</t>
</t>
</t>
`);
registerTemplate("web.caps_lock_warning", `/web/static/src/public/caps_lock_warning.xml`, `<t t-name="web.caps_lock_warning" xml:space="preserve">
<span class="o_caps_lock_warning_text text-danger">
Caps Lock is on!
</span>
</t>
`);
registerTemplate("html_editor.AttachmentError", `/html_editor/static/src/main/media/media_dialog/attachment_error.xml`, `<t t-name="html_editor.AttachmentError" xml:space="preserve">
<Dialog title="title">
<div class="form-text">
<p>The image could not be deleted because it is used in the
following pages or views:</p>
<ul t-foreach="props.views" t-as="view" t-key="view.id">
<li>
<a t-att-href="'/odoo/ir.ui.view/' + window.encodeURIComponent(view.id)">
<t t-esc="view.name"/>
</a>
</li>
</ul>
</div>
<t t-set-slot="footer">
<button class="btn btn-primary" t-on-click="() =&gt; this.props.close()">
Ok
</button>
</t>
</Dialog>
</t>
`);
registerTemplate("html_editor.DocumentAttachment", `/html_editor/static/src/main/media/media_dialog/document_selector.xml`, `<t t-name="html_editor.DocumentAttachment" xml:space="preserve">
<div class="o_existing_attachment_cell o_we_attachment_highlight card col-2 position-relative mb-2 p-2 opacity-trigger-hover" t-att-class="{ o_we_attachment_selected: props.selected }">
<RemoveButton remove="() =&gt; this.remove()"/>
<div t-att-data-url="props.url" role="img" t-att-aria-label="props.name" t-att-title="props.name" t-att-data-mimetype="props.mimetype" class="o_image d-flex align-items-center justify-content-center"/>
<button class="o_btn_reset o_button_area cursor-pointer" t-on-click="props.selectAttachment" t-att-aria-label="props.name"/>
<small class="o_file_name d-block text-truncate" t-esc="props.name"/>
</div>
</t>
`);
registerTemplate("html_editor.DocumentsListTemplate", `/html_editor/static/src/main/media/media_dialog/document_selector.xml`, `<t t-name="html_editor.DocumentsListTemplate" xml:space="preserve">
<div class="o_we_existing_attachments o_we_documents" t-ref="existing-attachments">
<div t-if="!hasContent" class="o_nocontent_help">
<p class="o_empty_folder_image">No documents found.</p>
<p class="o_empty_folder_subtitle">You can upload documents with the button located in the top left of the screen.</p>
</div>
<div t-else="" class="d-flex flex-wrap gap-2">
<t t-foreach="state.attachments" t-as="attachment" t-key="attachment.id">
<DocumentAttachment url="attachment.url" name="attachment.name" mimetype="attachment.mimetype" id="attachment.id" onRemoved="(attachmentId) =&gt; this.onRemoved(attachmentId)" selected="this.selectedAttachmentIds.includes(attachment.id)" selectAttachment="() =&gt; this.onClickDocument(attachment)"/>
</t>
</div>
</div>
</t>
`);
registerTemplate("html_editor.FileSelectorControlPanel", `/html_editor/static/src/main/media/media_dialog/file_selector.xml`, `<t t-name="html_editor.FileSelectorControlPanel" xml:space="preserve">
<div class="o_we_file_selector_control_panel sticky-top d-flex flex-wrap gap-2 mb-1 p-3 align-items-end">
<SearchMedia searchPlaceholder="props.searchPlaceholder" needle="props.needle" search="props.search"/>
<div class="d-flex gap-3 justify-content-start align-items-center">
<div t-if="props.showOptimizedOption" class="flex-shrink-0 form-check form-switch align-items-center" t-on-change="props.changeShowOptimized">
<input class="o_we_show_optimized form-check-input" type="checkbox" t-att-checked="props.showOptimized" id="o_we_show_optimized_switch"/>
<label class="form-check-label" for="o_we_show_optimized_switch">
Show optimized images
</label>
</div>
<select t-if="showSearchServiceSelect" class="o_input o_we_search_select form-select pe-5" t-on-change="ev =&gt; props.changeSearchService(ev.target.value)">
<option t-att-selected="props.searchService === 'all'" value="all">All</option>
<option t-att-selected="props.searchService === 'database'" value="database">My Images</option>
<option t-if="props.useMediaLibrary" t-att-selected="props.searchService === 'media-library'" value="media-library">Illustrations</option>
</select>
</div>
<div class="col justify-content-end flex-nowrap input-group has-validation">
<input type="text" class="form-control o_input o_we_url_input o_we_transition_ease flex-grow-0" t-att-class="{ o_we_horizontal_collapse: !state.showUrlInput, 'w-auto': state.showUrlInput }" name="url" t-att-placeholder="props.urlPlaceholder" t-model="state.urlInput" t-on-input="onUrlInput" t-if="state.showUrlInput" t-ref="urlInput"/>
<button type="button" class="btn o_upload_media_url_button text-nowrap" t-att-class="{ 'btn-primary': state.urlInput, 'btn-secondary': !state.urlInput}" t-on-click="onUrlUploadClick" t-att-disabled="!enableUrlUploadClick">
<t t-esc="props.addText"/>
</button>
<div class="d-flex align-items-center">
<span t-if="state.urlInput and state.isValidatingUrl" class="o_we_url_loading mx-2 fa fa-lg fa-circle-o-notch fa-spin" title="Loading..."/>
<span t-elif="state.urlInput and state.isValidUrl and state.isValidFileFormat" class="o_we_url_success text-success mx-2 fa fa-lg fa-check" title="The URL seems valid."/>
<span t-elif="state.urlInput and !state.isValidUrl" class="o_we_url_error text-danger mx-2 oi oi-large oi-close" title="The URL does not seem to work."/>
<span t-elif="props.urlWarningTitle and state.urlInput and state.isValidUrl and !state.isValidFileFormat" class="o_we_url_warning text-warning mx-2 fa fa-lg fa-warning" t-att-title="props.urlWarningTitle"/>
</div>
</div>
<input type="file" class="d-none o_file_input" t-on-change="onChangeFileInput" t-ref="file-input" t-att-accept="props.accept" t-att-multiple="props.multiSelect and 'multiple'"/>
<div class="col-auto btn-group">
<button type="button" class="btn btn-secondary o_upload_media_button" t-on-click="onClickUpload">
<t t-esc="props.uploadText"/>
</button>
</div>
</div>
</t>
`);
registerTemplate("html_editor.FileSelector", `/html_editor/static/src/main/media/media_dialog/file_selector.xml`, `<t t-name="html_editor.FileSelector" xml:space="preserve">
<div>
<FileSelectorControlPanel uploadText="uploadText" accept="fileMimetypes" urlPlaceholder="urlPlaceholder" addText="addText" searchPlaceholder="searchPlaceholder" urlWarningTitle="urlWarningTitle" uploadUrl="(url) =&gt; this.uploadUrl(url)" uploadFiles="(files) =&gt; this.uploadFiles(files)" showOptimizedOption="showOptimizedOption" showOptimized="state.showOptimized" changeShowOptimized="showOptimized =&gt; this.state.showOptimized = !this.state.showOptimized" changeSearchService="service =&gt; this.state.searchService = service" searchService="state.searchService" needle="state.needle" search="(needle) =&gt; this.handleSearch(needle)" useMediaLibrary="props.useMediaLibrary" validateUrl="validateUrl" multiSelect="props.multiSelect"/>
<t t-call="{{ constructor.attachmentsListTemplate }}"/>
<div name="load_more_attachments" class="pt-3 pb-1 text-center mx-auto o_we_load_more" t-ref="load-more-button">
<button t-if="canLoadMore" class="btn btn-primary o_load_more" type="button" t-on-click="handleLoadMore">
Load more...
</button>
<div t-elif="hasContent" class="mt-2 o_load_done_msg">
<span><i t-esc="allLoadedText"/></span>
</div>
</div>
<div t-if="this.state.canScrollAttachments" class="position-sticky d-flex align-items-center mx-auto btn btn-primary rounded-circle oi oi-chevron-down o_scroll_attachments" t-on-click="handleScrollAttachments"/>
</div>
</t>
`);
registerTemplate("html_editor.IconSelector", `/html_editor/static/src/main/media/media_dialog/icon_selector.xml`, `<t t-name="html_editor.IconSelector" xml:space="preserve">
<div>
<div class="o_we_file_selector_control_panel sticky-top d-flex gap-2 align-items-center mb-1 py-4 px-3">
<SearchMedia searchPlaceholder.translate="Search a pictogram" search.bind="this.search" needle="state.needle"/>
</div>
<div class="font-icons-icons">
<t t-foreach="state.fonts" t-as="font" t-key="font.base">
<div t-if="!font.icons.length" class="o_nocontent_help">
<p class="o_empty_folder_image">No pictograms found.</p>
<p class="o_empty_folder_subtitle">Try searching with other keywords.</p>
</div>
<span t-foreach="font.icons" t-as="icon" t-key="icon.id" t-att-title="icon.names[0]" t-att-aria-label="icon.names[0]" role="img" class="font-icons-icon m-2 fs-2 p-3 cursor-pointer text-center" t-att-class="{ o_we_attachment_selected: this.selectedMediaIds.includes(icon.id) }" t-attf-class="{{ font.base }} {{ icon.names[0] }}" t-on-click="() =&gt; this.onClickIcon(font, icon)"/>
</t>
</div>
</div>
</t>
`);
registerTemplate("html_editor.AutoResizeImage", `/html_editor/static/src/main/media/media_dialog/image_selector.xml`, `<t t-name="html_editor.AutoResizeImage" xml:space="preserve">
<div t-ref="auto-resize-image-container" class="o_existing_attachment_cell o_we_image align-items-center justify-content-center me-1 mb-1 opacity-trigger-hover opacity-0" t-att-class="{ o_we_attachment_optimized: props.isOptimized, 'o_loaded position-relative opacity-100': state.loaded, o_we_attachment_selected: props.selected, 'position-fixed': !state.loaded, }">
<RemoveButton t-if="props.isRemovable" model="props.model" remove="() =&gt; this.remove()"/>
<div class="o_we_media_dialog_img_wrapper" t-att-class="{ 'bg-light': props.unselectable }">
<t t-set="unselectable_attachment_title">You can not use this image in a field</t>
<img t-ref="auto-resize-image" class="o_we_attachment_highlight img img-fluid w-100" t-att-class="{ 'opacity-25': props.unselectable}" t-att-src="props.src" t-att-alt="props.altDescription" loading="lazy" t-att-title="props.unselectable ? unselectable_attachment_title : props.title" t-on-load="onImageLoaded"/>
<a t-if="props.author" class="o_we_media_author position-absolute start-0 bottom-0 end-0 text-truncate text-center text-primary fs-6 bg-white-50" t-att-href="props.authorLink" target="_blank" t-esc="props.author"/>
</div>
<button class="o_btn_reset o_button_area" t-att-class="{ 'cursor-pointer': !props.unselectable }" t-on-click="props.onImageClick" t-att-aria-label="props.unselectable ? unselectable_attachment_title : props.title"/>
<span t-if="props.isOptimized" class="badge position-absolute bottom-0 end-0 m-1 text-bg-success">Optimized</span>
</div>
</t>
`);
registerTemplate("html_editor.ExternalImage", `/html_editor/static/src/main/media/media_dialog/image_selector.xml`, `<t t-name="html_editor.ExternalImage" xml:space="preserve">
<t t-if="record.mediaType == 'libraryMedia'">
<AutoResizeImage author="record.author" src="record.thumbnail_url" authorLink="record.author_link" title="record.tooltip" altDescription="record.tooltip" minRowHeight="MIN_ROW_HEIGHT" selected="this.selectedMediaIds.includes(record.id)" onImageClick="() =&gt; this.onClickMedia(record)" onLoaded="(imgEl) =&gt; this.onImageLoaded(imgEl, record)"/>
</t>
</t>
`);
registerTemplate("html_editor.ImagesListTemplate", `/html_editor/static/src/main/media/media_dialog/image_selector.xml`, `<t t-name="html_editor.ImagesListTemplate" xml:space="preserve">
<div class="o_we_existing_attachments o_we_images d-flex flex-wrap my-0" t-ref="existing-attachments">
<t t-if="!hasContent and !isFetching">
<div t-if="state.needle" class="o_nocontent_help">
<p class="o_empty_folder_image">No images found.</p>
<p class="o_empty_folder_subtitle">Wow, it feels a bit empty in here. Upload from the button in the top right corner!</p>
</div>
<div t-else="" class="o_we_search_prompt">
<h2>Search the web for royalty-free images</h2>
</div>
</t>
<t t-else="">
<t t-if="['all', 'database'].includes(state.searchService)">
<t t-foreach="state.attachments" t-as="attachment" t-key="attachment.id">
<AutoResizeImage t-if="!attachment.original_id or state.showOptimized" id="attachment.id" isOptimized="!!attachment.original_id" isRemovable="true" onRemoved="(attachmentId) =&gt; this.onRemoved(attachmentId)" selected="this.selectedAttachmentIds.includes(attachment.id)" src="attachment.thumbnail_src or attachment.image_src" name="attachment.name" title="attachment.name" unselectable="!!attachment.unselectable" altDescription="attachment.altDescription" model="attachment.res_model" minRowHeight="MIN_ROW_HEIGHT" onImageClick="() =&gt; this.onClickAttachment(attachment)" onLoaded="(imgEl) =&gt; this.onImageLoaded(imgEl, attachment)"/>
</t>
</t>
<t id="o_we_media_library_images" t-if="['all', 'media-library'].includes(state.searchService)">
<t t-foreach="state.libraryMedia" t-as="record" t-key="record.id">
<t t-call="html_editor.ExternalImage"/>
</t>
</t>
<t t-foreach="[...Array(20).keys()]" t-as="i" t-key="i">
<div class="o_we_attachment_placeholder"/>
</t>
</t>
</div>
</t>
`);
registerTemplate("html_editor.MediaDialog", `/html_editor/static/src/main/media/media_dialog/media_dialog.xml`, `<t t-name="html_editor.MediaDialog" xml:space="preserve">
<Dialog contentClass="contentClass" size="size" title="title" modalRef="modalRef">
<Notebook pages="notebookPages" onPageUpdate.bind="onTabChange" defaultPage="state.activeTab"/>
<t t-set-slot="footer">
<button class="btn btn-primary" t-on-click="() =&gt; this.save()" t-ref="add-button">Add</button>
<button class="btn btn-secondary" t-on-click="() =&gt; this.close()">Discard</button>
</t>
</Dialog>
</t>
`);
registerTemplate("html_editor.SearchMedia", `/html_editor/static/src/main/media/media_dialog/search_media.xml`, `<t t-name="html_editor.SearchMedia" xml:space="preserve">
<div class="position-relative mw-lg-25 flex-grow-1 me-auto">
<input type="text" class="o_we_search o_input form-control pe-4" t-att-placeholder="props.searchPlaceholder.trim()" t-model="state.input" t-ref="autofocus"/>
<i class="oi oi-search input-group-text position-absolute end-0 top-50 me-n3 px-2 py-1 translate-middle bg-transparent border-0" title="Search" role="img" aria-label="Search"/>
</div>
</t>
`);
registerTemplate("html_editor.ProgressBar", `/html_editor/static/src/main/media/media_dialog/upload_progress_toast/upload_progress_toast.xml`, `<t t-name="html_editor.ProgressBar" xml:space="preserve">
<small class="text-info d-flex align-items-center me-2">
<span t-if="!props.hasError and !props.uploaded"><i class="fa fa-circle-o-notch fa-spin me-2"/></span>
<span class="fst-italic fw-bold text-truncate flex-grow-1 me-2" t-esc="props.name"/>
<span class="fw-bold text-nowrap" t-esc="props.size"/>
</small>
<small t-if="props.uploaded or props.hasError" class="d-flex align-items-center mt-1">
<span t-if="props.uploaded" class="text-success"><i class="fa fa-check my-1 me-1"/> File has been uploaded</span>
<span t-else="" class="text-danger"><i class="oi oi-close float-start my-1 me-1"/> <span class="o_we_error_text" t-esc="errorMessage"/></span>
</small>
<div t-else="" class="progress mt-2">
<div class="progress-bar bg-info progress-bar-striped progress-bar-animated" role="progressbar" t-attf-style="width: {{this.progress}}%;" aria-label="Progress bar"><span t-esc="this.progress + '%'"/></div>
</div>
<hr/>
</t>
`);
registerTemplate("html_editor.UploadProgressToast", `/html_editor/static/src/main/media/media_dialog/upload_progress_toast/upload_progress_toast.xml`, `<t t-name="html_editor.UploadProgressToast" xml:space="preserve">
<div class="editor_notification_manager o_notification_manager o_upload_progress_toast">
<div t-if="state.isVisible" class="o_notification position-relative show fade mb-2 border border-info bg-white d-flex justify-content-between" role="alert" aria-live="assertive" aria-atomic="true">
<div class="editor_notification_body o_notification_body ps-2 py-2">
<div class="me-auto o_notification_content">
<div t-foreach="state.files" t-as="file" t-key="file" class="o_we_progressbar">
<ProgressBar progress="file_value.progress" errorMessage="file_value.errorMessage" hasError="file_value.hasError" name="file_value.name" uploaded="file_value.uploaded" size="file_value.size"/>
</div>
</div>
</div>
<button type="button" class="btn btn-close o_notification_close p-2" aria-label="Close" t-on-click="props.close"/>
</div>
</div>
</t>
`);
registerTemplate("html_editor.VideoOption", `/html_editor/static/src/main/media/media_dialog/video_selector.xml`, `<t t-name="html_editor.VideoOption" xml:space="preserve">
<div class="mb-1" t-attf-class="{{ showStartAtInput ? 'd-flex align-items-start gap-2 cursor-pointer' : ''}}">
<Switch value="!!props.value" onChange="props.onChangeOption" label="props.label" description="props.description" extraClasses="'d-flex align-items-start cursor-pointer flex-shrink-0'"/>
<t t-if="showStartAtInput">
<input type="text" placeholder="MM:SS" class="o_input w-lg-auto" t-att-value="props.value" t-on-input="props.onChangeStartAt"/>
</t>
</div>
</t>
`);
registerTemplate("html_editor.VideoIframe", `/html_editor/static/src/main/media/media_dialog/video_selector.xml`, `<t t-name="html_editor.VideoIframe" xml:space="preserve">
<iframe t-att-src="this.props.src" class="o_video_dialog_iframe mw-100 mh-100 overflow-hidden shadow" width="1280" height="720" allowfullscreen="allowfullscreen" frameborder="0"/>
</t>
`);
registerTemplate("html_editor.VideoSelector", `/html_editor/static/src/main/media/media_dialog/video_selector.xml`, `<t t-name="html_editor.VideoSelector" xml:space="preserve">
<div class="row">
<div class="col mt-4 o_video_dialog_form">
<div class="mb-2">
<label for="o_video_text">
<b>Video code </b>(URL or Embed)
</label>
<div class="text-start">
<small class="text-muted">Accepts <b><i>Youtube</i></b>, <b><i>Vimeo</i></b>, <b><i>Dailymotion</i></b> and <b><i>Instagram</i></b> videos</small>
</div>
<textarea t-ref="autofocus" t-model="state.urlInput" class="form-control" id="o_video_text" placeholder="Copy-paste your URL or embed code here" t-on-input="onChangeUrl" t-att-class="{ 'is-valid': state.urlInput and !this.state.errorMessage, 'is-invalid': state.urlInput and this.state.errorMessage }"/>
</div>
<div t-if="shownOptions.length" class="o_video_dialog_options">
<VideoOption t-foreach="shownOptions" t-as="option" t-key="option.id" name="option.id" value="value" onChangeOption="() =&gt; this.onChangeOption(option.id)" onChangeStartAt="(ev) =&gt; this.onChangeStartAt(ev, option.id)" label="option.label" description="option.description"/>
</div>
<t t-if="state.vimeoPreviews.length">
<span class="fw-bold">Suggestions</span>
<div id="video-suggestion" class="mt-4 d-flex flex-wrap mh-75 overflow-auto">
<t t-foreach="state.vimeoPreviews" t-as="vimeoPreview" t-key="vimeoPreview.id">
<div class="o_sample_video w-25 mh-100 cursor-pointer" t-on-click="() =&gt; this.onClickSuggestion(vimeoPreview.src)">
<img class="mw-100 mh-100 p-1" t-att-src="vimeoPreview.thumbnailSrc"/>
</div>
</t>
</div>
</t>
</div>
<div class="col-md-6">
<div class="o_video_preview position-relative border-0 p-3">
<div t-if="this.state.src and !this.state.errorMessage" class="o_video_dialog_preview_text mb-2">Preview</div>
<div class="media_iframe_video">
<div class="media_iframe_video_size"/>
<VideoIframe t-if="this.state.src and !this.state.errorMessage" src="this.state.src"/>
<div t-if="this.state.errorMessage" class="alert alert-warning o_video_dialog_iframe mw-100 mh-100 mb-2 mt-2" t-esc="this.state.errorMessage"/>
</div>
</div>
</div>
</div>
</t>
`);
registerTemplateExtension("html_editor.ExternalImage", `/web_unsplash/static/src/media_dialog/media_dialog.xml`, `<t t-inherit="html_editor.ExternalImage" t-inherit-mode="extension" xml:space="preserve">
<xpath expr="//t[@t-if]" position="after">
<t t-elif="record.mediaType === 'unsplashRecord'">
<AutoResizeImage src="record.url" author="record.user.name" authorLink="record.user.links.html" name="record.user.name" title="record.user.name" altDescription="record.alt_description" selected="this.selectedRecordIds.includes(record.id)" onImageClick="() =&gt; this.onClickRecord(record)" minRowHeight="MIN_ROW_HEIGHT" onLoaded="(imgEl) =&gt; this.onImageLoaded(imgEl, record)"/>
</t>
</xpath>
</t>
`);
registerTemplateExtension("html_editor.ImagesListTemplate", `/web_unsplash/static/src/media_dialog/media_dialog.xml`, `<t t-inherit="html_editor.ImagesListTemplate" t-inherit-mode="extension" xml:space="preserve">
<xpath expr="//t[@id='o_we_media_library_images']" position="replace">
<t id="o_we_media_library_images" t-if="['all', 'unsplash', 'media-library'].includes(state.searchService)">
<t t-foreach="combinedRecords" t-as="record" t-key="record.id">
<t t-call="html_editor.ExternalImage"/>
</t>
</t>
</xpath>
</t>
`);
registerTemplateExtension("html_editor.FileSelector", `/web_unsplash/static/src/media_dialog/media_dialog.xml`, `<t t-inherit="html_editor.FileSelector" t-inherit-mode="extension" xml:space="preserve">
<xpath expr="//div[@name='load_more_attachments']" position="before">
<div t-if="unsplashState?.unsplashError" class="d-flex mt-2 unsplash_error">
<UnsplashError title="errorTitle" subtitle="errorSubtitle" showCredentials="['key_not_found', 401].includes(unsplashState.unsplashError)" submitCredentials="(key, appId) =&gt; this.submitCredentials(key, appId)" hasCredentialsError="unsplashState.unsplashError === 401"/>
</div>
</xpath>
</t>
`);
registerTemplateExtension("html_editor.FileSelector", `/web_unsplash/static/src/media_dialog/media_dialog.xml`, `<t t-inherit="html_editor.FileSelector" t-inherit-mode="extension" xml:space="preserve">
<xpath expr="//FileSelectorControlPanel" position="attributes">
<attribute name="useUnsplash">unsplashState?.useUnsplash</attribute>
</xpath>
</t>
`);
registerTemplateExtension("html_editor.FileSelectorControlPanel", `/web_unsplash/static/src/media_dialog/media_dialog.xml`, `<t t-inherit="html_editor.FileSelectorControlPanel" t-inherit-mode="extension" xml:space="preserve">
<xpath expr="//option[@value='media-library']" position="after">
<option t-if="props.useUnsplash" t-att-selected="props.searchService === 'unsplash'" value="unsplash">Photos (via Unsplash)</option>
</xpath>
</t>
`);
registerTemplate("web_unsplash.UnsplashCredentials", `/web_unsplash/static/src/unsplash_credentials/unsplash_credentials.xml`, `<t t-name="web_unsplash.UnsplashCredentials" xml:space="preserve">
<div class="d-flex align-items-center flex-wrap">
<a href="https://www.odoo.com/documentation/latest/applications/websites/website/optimize/unsplash.html#generate-an-unsplash-access-key" class="me-1" target="_blank">Get an Access key</a>
and paste it here:
<input type="text" class="o_input o_required_modifier form-control w-auto mx-2" id="accessKeyInput" placeholder="Paste your access key here" t-model="state.key" t-on-input="() =&gt; this.state.hasKeyError = false" t-att-class="{ 'is-invalid': state.hasKeyError }"/>
and paste
<a href="https://www.odoo.com/documentation/latest/applications/websites/website/optimize/unsplash.html#generate-an-unsplash-application-id" class="mx-1" target="_blank">Application ID</a>
here:
<input type="text" class="o_input o_required_modifier form-control w-auto ms-2" placeholder="Paste your application ID here" t-model="state.appId" t-on-input="() =&gt; this.state.hasAppIdError = false" t-att-class="{ 'is-invalid': state.hasAppIdError }"/>
<button type="button" class="btn btn-primary w-auto ms-3 p-auto save_unsplash" t-on-click="() =&gt; this.submitCredentials()">Apply</button>
</div>
</t>
`);
registerTemplate("web_unsplash.UnsplashError", `/web_unsplash/static/src/unsplash_error/unsplash_error.xml`, `<t t-name="web_unsplash.UnsplashError" xml:space="preserve">
<div class="alert alert-info w-100">
<h4><t t-esc="props.title"/></h4>
<p><t t-esc="props.subtitle"/></p>
<UnsplashCredentials t-if="props.showCredentials" submitCredentials="props.submitCredentials" hasCredentialsError="props.hasCredentialsError"/>
</div>
</t>
`);
registerTemplate("html_editor.HtmlViewer", `/html_editor/static/src/components/html_viewer/html_viewer.xml`, `<t t-name="html_editor.HtmlViewer" xml:space="preserve">
<t t-if="this.showIframe">
<iframe t-ref="iframe" t-att-class="{'d-none': !this.state.iframeVisible, 'o_readonly': true}" t-att-sandbox="props.config.hasFullHtml ? 'allow-same-origin allow-popups allow-popups-to-escape-sandbox' : false"/>
</t>
<t t-else="">
<div t-ref="readonlyContent" class="o_readonly" t-out="state.value"/>
</t>
</t>
`);
registerTemplate("html_editor.LocalOverlayContainer", `/html_editor/static/src/local_overlay_container.xml`, `<t t-name="html_editor.LocalOverlayContainer" xml:space="preserve">
<div class="o-wysiwyg-local-overlay position-relative h-0 w-0" t-ref="localOverlay"/>
<div class="o-wysiwyg-local-overlay position-relative h-0 w-0">
<t t-foreach="Components.entries" t-as="C" t-key="C[0]">
<div class="oe-local-overlay" t-att-data-oe-local-overlay-id="C[0]">
<ErrorHandler onError="error =&gt; this.handleComponentError(error, C)">
<t t-component="C[1].Component" t-props="C[1].props"/>
</ErrorHandler>
</div>
</t>
</div>
</t>
`);
registerTemplate("html_editor.EmbeddedComponentToolbar", `/html_editor/static/src/others/embedded_components/core/embedded_component_toolbar/embedded_component_toolbar.xml`, `<t t-name="html_editor.EmbeddedComponentToolbar" xml:space="preserve">
<span class="o_embedded_toolbar d-flex justify-content-end align-items-center">
<span t-attf-class="btn-group d-flex flex-wrap #{ props.buttonsGroupClass ? props.buttonsGroupClass : '' }">
<t t-slot="buttons"/>
</span>
</span>
</t>
`);
registerTemplate("html_editor.EmbeddedComponentToolbarButton", `/html_editor/static/src/others/embedded_components/core/embedded_component_toolbar/embedded_component_toolbar.xml`, `<t t-name="html_editor.EmbeddedComponentToolbarButton" xml:space="preserve">
<button t-if="!props.hidden" t-ref="buttonRef" t-on-click="props.onClick" t-att-name="props.name" t-att-title="props.title" class="btn btn-primary btn-link btn-sm border-0 py-0 text-break text-start text-o-color-2 text-capitalize fw-bold border-transparent bg-transparent">
<i t-if="props.icon" t-attf-class="fa #{props.icon} me-1"/>
<span class="o_embedded_toolbar_button_text" t-out="props.label"/>
</button>
</t>
`);
registerTemplate("html_editor.ReadonlyEmbeddedFile", `/html_editor/static/src/others/embedded_components/core/file/readonly_file.xml`, `<t t-name="html_editor.ReadonlyEmbeddedFile" t-inherit="html_editor.StaticFileBox" t-inherit-mode="primary" xml:space="preserve">
<xpath expr="//span[hasclass('o_file_image')]" position="inside">
<a t-att-href="fileModel.downloadUrl" t-on-click.prevent.stop="onClickFileImage" class="w-100"/>
</xpath>
<xpath expr="//span[hasclass('o_file_name_container')]/a" position="replace">
<span class="o_file_name" t-out="fileModel.filename"/>
</xpath>
<xpath expr="//span[hasclass('o_file_name_container')]" position="after">
<span class="flex-grow-1 d-flex justify-content-end">
<EmbeddedComponentToolbar>
<t t-set-slot="buttons"/>
</EmbeddedComponentToolbar>
</span>
</xpath>
</t>
`);
registerTemplate("html_editor.StaticFileBox", `/html_editor/static/src/others/embedded_components/core/file/static_file.xml`, `<t t-name="html_editor.StaticFileBox" xml:space="preserve">
<span class="d-flex flex-grow-1 align-items-center alert alert-info">
<span class="o_file_image d-flex o_image user-select-none" t-att-title="fileModel.filename" t-att-data-mimetype="fileModel.mimetype"/>
<span class="o_file_name_container mx-2 d-flex flex-grow-1">
<a class="o_link_readonly w-100" t-att-href="fileModel.downloadUrl" t-out="fileModel.filename" contenteditable="false"/>
</span>
</span>
</t>
`);
registerTemplate("html_editor.EmbeddedTableOfContent", `/html_editor/static/src/others/embedded_components/core/table_of_content/table_of_content.xml`, `<t t-name="html_editor.EmbeddedTableOfContent" xml:space="preserve">
<div class="px-1" t-att-class="{ 'pb-1' : !state.folded and state.toc.headings.length }">
<div class="d-flex align-items-center cursor-pointer user-select-none" t-on-click="() =&gt; { this.state.folded = !this.state.folded; }">
<div class="o_embedded_toc_label p-1 fw-bold">
Table of Contents
<i t-attf-class="align-self-center fa fa-fw fa-caret-#{ state.folded ? 'right' : 'down' }"/>
</div>
</div>
<div t-if="!state.folded" class="o_embedded_toc_content">
<t t-foreach="this.state.toc.headings" t-as="heading" t-key="heading_index">
<a href="#" contenteditable="false" t-out="heading.name" t-on-click.prevent="() =&gt; this.onTocLinkClick(heading)" t-attf-class="o_no_link_popover py-1 pe-1 d-block text-reset o_embedded_toc_link #{'o_embedded_toc_link_depth_' + heading.depth}"/>
</t>
</div>
</div>
<div class="p-1" t-if="displayTocHint()">
<i class="o_embedded_toc_hint px-1">
Add headings to fill the Table of Contents
</i>
</div>
</t>
`);
registerTemplate("html_editor.EmbeddedToggleBlock", `/html_editor/static/src/others/embedded_components/core/toggle_block/toggle_block.xml`, `<t t-name="html_editor.EmbeddedToggleBlock" xml:space="preserve">
<div class="d-flex flex-row align-items-center">
<button class="btn p-0 border-0 align-items-center justify-content-center btn-light" t-on-click="onToggle" t-on-pointerdown.prevent="" type="button">
<i t-attf-class="fa align-self-center fa-caret-{{this.state.showContent ? 'down' : 'right'}}"/>
</button>
<div class="flex-fill ms-1" t-ref="title"/>
</div>
<div class="ps-4 ms-1" t-att-class="{ 'd-none': !state.showContent }" t-ref="content"/>
</t>
`);
registerTemplate("html_editor.EmbeddedVideo", `/html_editor/static/src/others/embedded_components/core/video/readonly_video.xml`, `<t t-name="html_editor.EmbeddedVideo" xml:space="preserve">
<iframe t-ref="iframeRef" t-att-src="url" title="Video player" frameborder="0" allowfullscreen="allowfullscreen" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share">
Your browser does not support iframe.
</iframe>
</t>
`);
registerTemplate("web_tour.TourPointer", `/web_tour/static/src/js/tour_pointer/tour_pointer.xml`, `<t t-name="web_tour.TourPointer" xml:space="preserve">
<div t-if="this.isVisible" t-ref="pointer" t-attf-class=" o_tour_pointer o_{{ position }} {{ isOpen ? 'o_open' : (props.bounce ? 'o_bouncing' : '') }} {{ props.pointerState.onClick ? 'cursor-pointer' : '' }} " t-attf-style=" --TourPointer__width: {{ constructor.width }}px; --TourPointer__height: {{ constructor.height }}px; " t-on-mouseenter="props.pointerState.onMouseEnter or (() =&gt; {})" t-on-mouseleave="props.pointerState.onMouseLeave or (() =&gt; {})" t-on-click="props.pointerState.onClick or (() =&gt; {})">
<div class="o_tour_pointer_tip position-absolute"/>
<div class="o_tour_pointer_content rounded overflow-hidden px-3 py-2 w-100 h-100 position-relative" t-att-class="{ 'invisible': !isOpen }">
<span>
<t t-out="content"/>
</span>
<div class="d-flex justify-content-end">
<button class="btn btn-link" t-on-click="onStopClicked">Stop Tour</button>
</div>
</div>
</div>
<div class="o_tour_dropzone position-fixed pe-none" t-if="props.pointerState.isVisible and props.pointerState.isZone" t-ref="zone" style="border: 3px dashed #714b67;"/>
</t>
`);
registerTemplate("web_tour.OnboardingItem", `/web_tour/static/src/js/onboarding_item.xml`, `<t t-name="web_tour.OnboardingItem" xml:space="preserve">
<DropdownItem>
<div class="d-flex justify-content-between ps-3">
<div class="align-self-center">
<span class="form-check form-switch" t-on-click.stop.prevent="() =&gt; this.props.toggleItem()">
<input type="checkbox" class="form-check-input" id="onboarding" t-att-checked="this.props.toursEnabled"/>
<label class="form-check-label">Onboarding</label>
</span>
</div>
</div>
</DropdownItem>
</t>
`);
});