/* /web/static/lib/luxon/luxon.js */ var luxon=(function(exports){'use strict';function _defineProperties(target,props){for(var i=0;i=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=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=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=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 iweeksInWeekYear(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;i0){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;i3?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(enddateTime;};_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?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?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.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=e){return null;}else{return Interval.fromDateTimes(s,e);}};_proto.union=function union(other){if(!this.isValid)return this;var s=this.sother.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(highWater0){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(weekdaythis.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?thisthis.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{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&¤t.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));} [["&","&"],["<","<"],[">",">"],["'","'"],['"',"""],["`","`"],].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(;inativeToSyntheticEvent(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(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(`${str}`,"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;iv.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;ifn(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;iendIdx1){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;ic.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=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!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;iArray.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(icompileExpr(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 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 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 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;ithis.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(`${xml}`).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 , ";support.noCloneChecked=!!div.cloneNode(true).lastChild.defaultValue;div.innerHTML="";support.option=!!div.lastChild;})();var wrapMap={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};wrapMap.tbody=wrapMap.tfoot=wrapMap.colgroup=wrapMap.caption=wrapMap.thead;wrapMap.th=wrapMap.td;if(!support.option){wrapMap.optgroup=wrapMap.option=[1,""];} 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-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=1)){for(;cur!==this;cur=cur.parentNode||this){if(cur.nodeType===1&&!(event.type==="click"&&cur.disabled===true)){matchedHandlers=[];matchedSelectors={};for(i=0;i-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\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;i1&&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(;i0){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=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(;i1);}});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(;index1);},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-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-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-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(" `);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&®.area()&®.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,'("|")');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(maxDatedesired){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=date0&&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;indexduration.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;iacc+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+jsubstrStack.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`
`;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;indexappTranslateFn(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;indexitem.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{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`
`;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{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=arrowSizetargetPosition+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.floor(directionMax)){directionOverflow=Math.ceil(directionValue+directionSize)-Math.floor(directionMax);} let variantOverflow=0;if(Math.floor(variantValue)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;i2&&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;monthIndex2&&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":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",">=","<>","!=","==",];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> 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 abpappTranslateFn(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_LIMITnameGet[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{},};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`${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``;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{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;itree.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;indexisId(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)=>indexgetDomainTreeDescription(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!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;imapFn(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{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)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``;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(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(pxbrowser.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()&¶ms.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&¶ms.ufile.length)||params.file){const fileSize=(params.ufile&¶ms.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{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(`(?]*<[^<]*>)*[^<>]*$)`,"ig");result=htmlReplace(result,regex,(_,match)=>{match=markup(match);return markup`${match}`;});} 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`
`],["\t",markup``],[/\*\*(.+?)\*\*/g,(_,content)=>markup(`${content}`)],[/--(.+?)--/g,(_,content)=>markup(`${content}`)],[/`(.+?)`/g,(_,content)=>markup(`${content}`),],];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;ival/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)=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{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{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&¤t.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=[["&","&"],["<","<"],[">",">"],["'","'"],['"',"""],["`","`"],];const R_EMAIL=/^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i;const R_FALSY=/^false|0$/i;const R_KEYED_SUBSTITUTION=/%\((?[^)]+)\)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;idict[key]??"");}else{const raw=[""];for(let i=0;iPromise.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("","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)0&&sizes[startIndex]>bufferStart){startIndex--;} while(startIndexstartIndex&&(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=index0?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=/^(?.*)\.(?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(' ');$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('
');$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;iparam.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 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(lastPresencenow){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` `;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``;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.lengthmedia.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.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)=>(ir.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.totalImagescachedData.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(`
`);} 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]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``;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=/$/i.test(html);let text=html.replace(//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(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==="
"){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=offsetel.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=nodeLevelAncestorIndexn?.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&¤tNode===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{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)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&¤tImageData[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}>`;});} 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 anchorOffsetselection.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{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`, `
`); registerTemplate("web.AutoComplete", `/web/static/src/core/autocomplete/autocomplete.xml`, ` `); registerTemplate("web.BarcodeDialog", `/web/static/src/core/barcode/barcode_dialog.xml`, `
Unable to access camera
`); registerTemplate("web.BarcodeVideoScanner", `/web/static/src/core/barcode/barcode_video_scanner.xml`, ` `); registerTemplate("web.CropOverlay", `/web/static/src/core/barcode/crop_overlay.xml`, `
`); registerTemplate("web.BottomSheet", `/web/static/src/core/bottom_sheet/bottom_sheet.xml`, `
`); registerTemplate("web.CheckBox", `/web/static/src/core/checkbox/checkbox.xml`, `
`); registerTemplate("web.CodeEditor", `/web/static/src/core/code_editor/code_editor.xml`, `
`); registerTemplate("web.ColorPicker", `/web/static/src/core/color_picker/color_picker.xml`, `
`); registerTemplate("web.CustomColorPicker", `/web/static/src/core/color_picker/custom_color_picker/custom_color_picker.xml`, `
`); registerTemplate("web.ColorPickerCustomTab", `/web/static/src/core/color_picker/tabs/color_picker_custom_tab.xml`, `
`); registerTemplate("web.ColorPickerSolidTab", `/web/static/src/core/color_picker/tabs/color_picker_solid_tab.xml`, `
`); registerTemplate("web.ColorList", `/web/static/src/core/colorlist/colorlist.xml`, `
`); registerTemplate("web.ConfirmationDialog", `/web/static/src/core/confirmation_dialog/confirmation_dialog.xml`, `

`); registerTemplate("web.AlertDialog", `/web/static/src/core/confirmation_dialog/confirmation_dialog.xml`, `

`); registerTemplate("web.CopyButton", `/web/static/src/core/copy_button/copy_button.xml`, ` `); registerTemplate("web.DateTimeInput", `/web/static/src/core/datetime/datetime_input.xml`, ` `); registerTemplate("web.DateTimePicker.Days", `/web/static/src/core/datetime/datetime_picker.xml`, `
`); registerTemplate("web.DateTimePicker.Grid", `/web/static/src/core/datetime/datetime_picker.xml`, `
`); registerTemplate("web.DateTimePicker", `/web/static/src/core/datetime/datetime_picker.xml`, `
`); registerTemplate("web.DateTimePickerPopover", `/web/static/src/core/datetime/datetime_picker_popover.xml`, `
`); registerTemplate("web.DebugMenu", `/web/static/src/core/debug/debug_menu.xml`, `
`); registerTemplate("web.DebugMenu.SetDefaultDialog", `/web/static/src/core/debug/debug_menu_items.xml`, `

`); registerTemplate("web.DebugMenu.GetMetadataDialog", `/web/static/src/core/debug/debug_menu_items.xml`, `
ID:
XML ID:
No Update: (change)
Creation User:
Creation Date:
Latest Modification by:
Latest Modification Date:
`); registerTemplate("web.DebugMenu.GetViewDialog", `/web/static/src/core/debug/debug_menu_items.xml`, `
            
                
            
        
`); registerTemplate("web.Dialog", `/web/static/src/core/dialog/dialog.xml`, `
`); registerTemplate("web.Dialog.header", `/web/static/src/core/dialog/dialog.xml`, `