
/* /web/static/lib/luxon/luxon.js */
var luxon=(function(exports){'use strict';class LuxonError extends Error{}
class InvalidDateTimeError extends LuxonError{constructor(reason){super(`Invalid DateTime: ${reason.toMessage()}`);}}
class InvalidIntervalError extends LuxonError{constructor(reason){super(`Invalid Interval: ${reason.toMessage()}`);}}
class InvalidDurationError extends LuxonError{constructor(reason){super(`Invalid Duration: ${reason.toMessage()}`);}}
class ConflictingSpecificationError extends LuxonError{}
class InvalidUnitError extends LuxonError{constructor(unit){super(`Invalid unit ${unit}`);}}
class InvalidArgumentError extends LuxonError{}
class ZoneIsAbstractError extends LuxonError{constructor(){super("Zone is an abstract class");}}
const n="numeric",s="short",l="long";const DATE_SHORT={year:n,month:n,day:n,};const DATE_MED={year:n,month:s,day:n,};const DATE_MED_WITH_WEEKDAY={year:n,month:s,day:n,weekday:s,};const DATE_FULL={year:n,month:l,day:n,};const DATE_HUGE={year:n,month:l,day:n,weekday:l,};const TIME_SIMPLE={hour:n,minute:n,};const TIME_WITH_SECONDS={hour:n,minute:n,second:n,};const TIME_WITH_SHORT_OFFSET={hour:n,minute:n,second:n,timeZoneName:s,};const TIME_WITH_LONG_OFFSET={hour:n,minute:n,second:n,timeZoneName:l,};const TIME_24_SIMPLE={hour:n,minute:n,hourCycle:"h23",};const TIME_24_WITH_SECONDS={hour:n,minute:n,second:n,hourCycle:"h23",};const TIME_24_WITH_SHORT_OFFSET={hour:n,minute:n,second:n,hourCycle:"h23",timeZoneName:s,};const TIME_24_WITH_LONG_OFFSET={hour:n,minute:n,second:n,hourCycle:"h23",timeZoneName:l,};const DATETIME_SHORT={year:n,month:n,day:n,hour:n,minute:n,};const DATETIME_SHORT_WITH_SECONDS={year:n,month:n,day:n,hour:n,minute:n,second:n,};const DATETIME_MED={year:n,month:s,day:n,hour:n,minute:n,};const DATETIME_MED_WITH_SECONDS={year:n,month:s,day:n,hour:n,minute:n,second:n,};const DATETIME_MED_WITH_WEEKDAY={year:n,month:s,day:n,weekday:s,hour:n,minute:n,};const DATETIME_FULL={year:n,month:l,day:n,hour:n,minute:n,timeZoneName:s,};const DATETIME_FULL_WITH_SECONDS={year:n,month:l,day:n,hour:n,minute:n,second:n,timeZoneName:s,};const DATETIME_HUGE={year:n,month:l,day:n,weekday:l,hour:n,minute:n,timeZoneName:l,};const DATETIME_HUGE_WITH_SECONDS={year:n,month:l,day:n,weekday:l,hour:n,minute:n,second:n,timeZoneName:l,};class Zone{get type(){throw new ZoneIsAbstractError();}
get name(){throw new ZoneIsAbstractError();}
get ianaName(){return this.name;}
get isUniversal(){throw new ZoneIsAbstractError();}
offsetName(ts,opts){throw new ZoneIsAbstractError();}
formatOffset(ts,format){throw new ZoneIsAbstractError();}
offset(ts){throw new ZoneIsAbstractError();}
equals(otherZone){throw new ZoneIsAbstractError();}
get isValid(){throw new ZoneIsAbstractError();}}
let singleton$1=null;class SystemZone extends Zone{static get instance(){if(singleton$1===null){singleton$1=new SystemZone();}
return singleton$1;}
get type(){return"system";}
get name(){return new Intl.DateTimeFormat().resolvedOptions().timeZone;}
get isUniversal(){return false;}
offsetName(ts,{format,locale}){return parseZoneInfo(ts,format,locale);}
formatOffset(ts,format){return formatOffset(this.offset(ts),format);}
offset(ts){return-new Date(ts).getTimezoneOffset();}
equals(otherZone){return otherZone.type==="system";}
get isValid(){return true;}}
let 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];}
const typeToPos={year:0,month:1,day:2,era:3,hour:4,minute:5,second:6,};function hackyOffset(dtf,date){const formatted=dtf.format(date).replace(/\u200E/g,""),parsed=/(\d+)\/(\d+)\/(\d+) (AD|BC),? (\d+):(\d+):(\d+)/.exec(formatted),[,fMonth,fDay,fYear,fadOrBc,fHour,fMinute,fSecond]=parsed;return[fYear,fMonth,fDay,fadOrBc,fHour,fMinute,fSecond];}
function partsOffset(dtf,date){const formatted=dtf.formatToParts(date);const filled=[];for(let i=0;i<formatted.length;i++){const{type,value}=formatted[i];const pos=typeToPos[type];if(type==="era"){filled[pos]=value;}else if(!isUndefined(pos)){filled[pos]=parseInt(value,10);}}
return filled;}
let ianaZoneCache={};class IANAZone extends Zone{static create(name){if(!ianaZoneCache[name]){ianaZoneCache[name]=new IANAZone(name);}
return ianaZoneCache[name];}
static resetCache(){ianaZoneCache={};dtfCache={};}
static isValidSpecifier(s){return this.isValidZone(s);}
static isValidZone(zone){if(!zone){return false;}
try{new Intl.DateTimeFormat("en-US",{timeZone:zone}).format();return true;}catch(e){return false;}}
constructor(name){super();this.zoneName=name;this.valid=IANAZone.isValidZone(name);}
get type(){return"iana";}
get name(){return this.zoneName;}
get isUniversal(){return false;}
offsetName(ts,{format,locale}){return parseZoneInfo(ts,format,locale,this.name);}
formatOffset(ts,format){return formatOffset(this.offset(ts),format);}
offset(ts){const date=new Date(ts);if(isNaN(date))return NaN;const dtf=makeDTF(this.name);let[year,month,day,adOrBc,hour,minute,second]=dtf.formatToParts?partsOffset(dtf,date):hackyOffset(dtf,date);if(adOrBc==="BC"){year=-Math.abs(year)+1;}
const adjustedHour=hour===24?0:hour;const asUTC=objToLocalTS({year,month,day,hour:adjustedHour,minute,second,millisecond:0,});let asTS=+date;const over=asTS%1000;asTS-=over>=0?over:1000+over;return(asUTC-asTS)/(60*1000);}
equals(otherZone){return otherZone.type==="iana"&&otherZone.name===this.name;}
get isValid(){return this.valid;}}
let intlLFCache={};function getCachedLF(locString,opts={}){const key=JSON.stringify([locString,opts]);let dtf=intlLFCache[key];if(!dtf){dtf=new Intl.ListFormat(locString,opts);intlLFCache[key]=dtf;}
return dtf;}
let intlDTCache={};function getCachedDTF(locString,opts={}){const key=JSON.stringify([locString,opts]);let dtf=intlDTCache[key];if(!dtf){dtf=new Intl.DateTimeFormat(locString,opts);intlDTCache[key]=dtf;}
return dtf;}
let intlNumCache={};function getCachedINF(locString,opts={}){const key=JSON.stringify([locString,opts]);let inf=intlNumCache[key];if(!inf){inf=new Intl.NumberFormat(locString,opts);intlNumCache[key]=inf;}
return inf;}
let intlRelCache={};function getCachedRTF(locString,opts={}){const{base,...cacheKeyOpts}=opts;const key=JSON.stringify([locString,cacheKeyOpts]);let inf=intlRelCache[key];if(!inf){inf=new Intl.RelativeTimeFormat(locString,opts);intlRelCache[key]=inf;}
return inf;}
let sysLocaleCache=null;function systemLocale(){if(sysLocaleCache){return sysLocaleCache;}else{sysLocaleCache=new Intl.DateTimeFormat().resolvedOptions().locale;return sysLocaleCache;}}
function parseLocaleString(localeStr){const xIndex=localeStr.indexOf("-x-");if(xIndex!==-1){localeStr=localeStr.substring(0,xIndex);}
const uIndex=localeStr.indexOf("-u-");if(uIndex===-1){return[localeStr];}else{let options;let selectedStr;try{options=getCachedDTF(localeStr).resolvedOptions();selectedStr=localeStr;}catch(e){const smaller=localeStr.substring(0,uIndex);options=getCachedDTF(smaller).resolvedOptions();selectedStr=smaller;}
const{numberingSystem,calendar}=options;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){const ms=[];for(let i=1;i<=12;i++){const dt=DateTime.utc(2009,i,1);ms.push(f(dt));}
return ms;}
function mapWeekdays(f){const ms=[];for(let i=1;i<=7;i++){const dt=DateTime.utc(2016,11,13+i);ms.push(f(dt));}
return ms;}
function listStuff(loc,length,englishFn,intlFn){const 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");}}
class PolyNumberFormatter{constructor(intl,forceSimple,opts){this.padTo=opts.padTo||0;this.floor=opts.floor||false;const{padTo,floor,...otherOpts}=opts;if(!forceSimple||Object.keys(otherOpts).length>0){const intlOpts={useGrouping:false,...opts};if(opts.padTo>0)intlOpts.minimumIntegerDigits=opts.padTo;this.inf=getCachedINF(intl,intlOpts);}}
format(i){if(this.inf){const fixed=this.floor?Math.floor(i):i;return this.inf.format(fixed);}else{const fixed=this.floor?Math.floor(i):roundTo(i,3);return padStart(fixed,this.padTo);}}}
class PolyDateFormatter{constructor(dt,intl,opts){this.opts=opts;this.originalZone=undefined;let z=undefined;if(this.opts.timeZone){this.dt=dt;}else if(dt.zone.type==="fixed"){const gmtOffset=-1*(dt.offset/60);const 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;}
const intlOpts={...this.opts};intlOpts.timeZone=intlOpts.timeZone||z;this.dtf=getCachedDTF(intl,intlOpts);}
format(){if(this.originalZone){return this.formatToParts().map(({value})=>value).join("");}
return this.dtf.format(this.dt.toJSDate());}
formatToParts(){const parts=this.dtf.formatToParts(this.dt.toJSDate());if(this.originalZone){return parts.map((part)=>{if(part.type==="timeZoneName"){const offsetName=this.originalZone.offsetName(this.dt.ts,{locale:this.dt.locale,format:this.opts.timeZoneName,});return{...part,value:offsetName,};}else{return part;}});}
return parts;}
resolvedOptions(){return this.dtf.resolvedOptions();}}
class PolyRelFormatter{constructor(intl,isEnglish,opts){this.opts={style:"long",...opts};if(!isEnglish&&hasRelative()){this.rtf=getCachedRTF(intl,opts);}}
format(count,unit){if(this.rtf){return this.rtf.format(count,unit);}else{return formatRelativeTime(unit,count,this.opts.numeric,this.opts.style!=="long");}}
formatToParts(count,unit){if(this.rtf){return this.rtf.formatToParts(count,unit);}else{return[];}}}
class Locale{static fromOpts(opts){return Locale.create(opts.locale,opts.numberingSystem,opts.outputCalendar,opts.defaultToEN);}
static create(locale,numberingSystem,outputCalendar,defaultToEN=false){const specifiedLocale=locale||Settings.defaultLocale;const localeR=specifiedLocale||(defaultToEN?"en-US":systemLocale());const numberingSystemR=numberingSystem||Settings.defaultNumberingSystem;const outputCalendarR=outputCalendar||Settings.defaultOutputCalendar;return new Locale(localeR,numberingSystemR,outputCalendarR,specifiedLocale);}
static resetCache(){sysLocaleCache=null;intlDTCache={};intlNumCache={};intlRelCache={};}
static fromObject({locale,numberingSystem,outputCalendar}={}){return Locale.create(locale,numberingSystem,outputCalendar);}
constructor(locale,numbering,outputCalendar,specifiedLocale){const[parsedLocale,parsedNumberingSystem,parsedOutputCalendar]=parseLocaleString(locale);this.locale=parsedLocale;this.numberingSystem=numbering||parsedNumberingSystem||null;this.outputCalendar=outputCalendar||parsedOutputCalendar||null;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;}
get fastNumbers(){if(this.fastNumbersCached==null){this.fastNumbersCached=supportsFastNumbers(this);}
return this.fastNumbersCached;}
listingMode(){const isActuallyEn=this.isEnglish();const hasNoWeirdness=(this.numberingSystem===null||this.numberingSystem==="latn")&&(this.outputCalendar===null||this.outputCalendar==="gregory");return isActuallyEn&&hasNoWeirdness?"en":"intl";}
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,alts.defaultToEN||false);}}
redefaultToEN(alts={}){return this.clone({...alts,defaultToEN:true});}
redefaultToSystem(alts={}){return this.clone({...alts,defaultToEN:false});}
months(length,format=false){return listStuff(this,length,months,()=>{const intl=format?{month:length,day:"numeric"}:{month:length},formatStr=format?"format":"standalone";if(!this.monthsCache[formatStr][length]){this.monthsCache[formatStr][length]=mapMonths((dt)=>this.extract(dt,intl,"month"));}
return this.monthsCache[formatStr][length];});}
weekdays(length,format=false){return listStuff(this,length,weekdays,()=>{const intl=format?{weekday:length,year:"numeric",month:"long",day:"numeric"}:{weekday:length},formatStr=format?"format":"standalone";if(!this.weekdaysCache[formatStr][length]){this.weekdaysCache[formatStr][length]=mapWeekdays((dt)=>this.extract(dt,intl,"weekday"));}
return this.weekdaysCache[formatStr][length];});}
meridiems(){return listStuff(this,undefined,()=>meridiems,()=>{if(!this.meridiemCache){const intl={hour:"numeric",hourCycle:"h12"};this.meridiemCache=[DateTime.utc(2016,11,13,9),DateTime.utc(2016,11,13,19)].map((dt)=>this.extract(dt,intl,"dayperiod"));}
return this.meridiemCache;});}
eras(length){return listStuff(this,length,eras,()=>{const intl={era:length};if(!this.eraCache[length]){this.eraCache[length]=[DateTime.utc(-40,1,1),DateTime.utc(2017,1,1)].map((dt)=>this.extract(dt,intl,"era"));}
return this.eraCache[length];});}
extract(dt,intlOpts,field){const df=this.dtFormatter(dt,intlOpts),results=df.formatToParts(),matching=results.find((m)=>m.type.toLowerCase()===field);return matching?matching.value:null;}
numberFormatter(opts={}){return new PolyNumberFormatter(this.intl,opts.forceSimple||this.fastNumbers,opts);}
dtFormatter(dt,intlOpts={}){return new PolyDateFormatter(dt,this.intl,intlOpts);}
relFormatter(opts={}){return new PolyRelFormatter(this.intl,this.isEnglish(),opts);}
listFormatter(opts={}){return getCachedLF(this.intl,opts);}
isEnglish(){return(this.locale==="en"||this.locale.toLowerCase()==="en-us"||new Intl.DateTimeFormat(this.intl).resolvedOptions().locale.startsWith("en-us"));}
equals(other){return(this.locale===other.locale&&this.numberingSystem===other.numberingSystem&&this.outputCalendar===other.outputCalendar);}}
let singleton=null;class FixedOffsetZone extends Zone{static get utcInstance(){if(singleton===null){singleton=new FixedOffsetZone(0);}
return singleton;}
static instance(offset){return offset===0?FixedOffsetZone.utcInstance:new FixedOffsetZone(offset);}
static parseSpecifier(s){if(s){const r=s.match(/^utc(?:([+-]\d{1,2})(?::(\d{2}))?)?$/i);if(r){return new FixedOffsetZone(signedOffset(r[1],r[2]));}}
return null;}
constructor(offset){super();this.fixed=offset;}
get type(){return"fixed";}
get name(){return this.fixed===0?"UTC":`UTC${formatOffset(this.fixed, "narrow")}`;}
get ianaName(){if(this.fixed===0){return"Etc/UTC";}else{return`Etc/GMT${formatOffset(-this.fixed, "narrow")}`;}}
offsetName(){return this.name;}
formatOffset(ts,format){return formatOffset(this.fixed,format);}
get isUniversal(){return true;}
offset(){return this.fixed;}
equals(otherZone){return otherZone.type==="fixed"&&otherZone.fixed===this.fixed;}
get isValid(){return true;}}
class InvalidZone extends Zone{constructor(zoneName){super();this.zoneName=zoneName;}
get type(){return"invalid";}
get name(){return this.zoneName;}
get isUniversal(){return false;}
offsetName(){return null;}
formatOffset(){return"";}
offset(){return NaN;}
equals(){return false;}
get isValid(){return false;}}
function normalizeZone(input,defaultZone){if(isUndefined(input)||input===null){return defaultZone;}else if(input instanceof Zone){return input;}else if(isString(input)){const 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);}}
let now=()=>Date.now(),defaultZone="system",defaultLocale=null,defaultNumberingSystem=null,defaultOutputCalendar=null,twoDigitCutoffYear=60,throwOnInvalid;class Settings{static get now(){return now;}
static set now(n){now=n;}
static set defaultZone(zone){defaultZone=zone;}
static get defaultZone(){return normalizeZone(defaultZone,SystemZone.instance);}
static get defaultLocale(){return defaultLocale;}
static set defaultLocale(locale){defaultLocale=locale;}
static get defaultNumberingSystem(){return defaultNumberingSystem;}
static set defaultNumberingSystem(numberingSystem){defaultNumberingSystem=numberingSystem;}
static get defaultOutputCalendar(){return defaultOutputCalendar;}
static set defaultOutputCalendar(outputCalendar){defaultOutputCalendar=outputCalendar;}
static get twoDigitCutoffYear(){return twoDigitCutoffYear;}
static set twoDigitCutoffYear(cutoffYear){twoDigitCutoffYear=cutoffYear%100;}
static get throwOnInvalid(){return throwOnInvalid;}
static set throwOnInvalid(t){throwOnInvalid=t;}
static resetCaches(){Locale.resetCache();IANAZone.resetCache();}}
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 maybeArray(thing){return Array.isArray(thing)?thing:[thing];}
function bestBy(arr,by,compare){if(arr.length===0){return undefined;}
return arr.reduce((best,next)=>{const 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((a,k)=>{a[k]=obj[k];return a;},{});}
function hasOwnProperty(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop);}
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=2){const isNeg=input<0;let 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{const f=parseFloat("0."+fraction)*1000;return Math.floor(f);}}
function roundTo(number,digits,towardZero=false){const factor=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){const 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){let 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 weeksInWeekYear(weekYear){const p1=(weekYear+
Math.floor(weekYear/4)-
Math.floor(weekYear/100)+
Math.floor(weekYear/400))%7,last=weekYear-1,p2=(last+Math.floor(last/4)-Math.floor(last/100)+Math.floor(last/400))%7;return p1===4||p2===3?53:52;}
function untruncateYear(year){if(year>99){return year;}else return year>Settings.twoDigitCutoffYear?1900+year:2000+year;}
function parseZoneInfo(ts,offsetFormat,locale,timeZone=null){const 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;}
const modified={timeZoneName:offsetFormat,...intlOpts};const parsed=new Intl.DateTimeFormat(locale,modified).formatToParts(date).find((m)=>m.type.toLowerCase()==="timezonename");return parsed?parsed.value:null;}
function signedOffset(offHourStr,offMinuteStr){let offHour=parseInt(offHourStr,10);if(Number.isNaN(offHour)){offHour=0;}
const offMin=parseInt(offMinuteStr,10)||0,offMinSigned=offHour<0||Object.is(offHour,-0)?-offMin:offMin;return offHour*60+offMinSigned;}
function asNumber(value){const numericValue=Number(value);if(typeof value==="boolean"||value===""||Number.isNaN(numericValue))
throw new InvalidArgumentError(`Invalid unit value ${value}`);return numericValue;}
function normalizeObject(obj,normalizer){const normalized={};for(const u in obj){if(hasOwnProperty(obj,u)){const v=obj[u];if(v===undefined||v===null)continue;normalized[normalizer(u)]=asNumber(v);}}
return normalized;}
function formatOffset(offset,format){const 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"]);}
const monthsLong=["January","February","March","April","May","June","July","August","September","October","November","December",];const monthsShort=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",];const monthsNarrow=["J","F","M","A","M","J","J","A","S","O","N","D"];function months(length){switch(length){case"narrow":return[...monthsNarrow];case"short":return[...monthsShort];case"long":return[...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;}}
const weekdaysLong=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday",];const weekdaysShort=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];const weekdaysNarrow=["M","T","W","T","F","S","S"];function weekdays(length){switch(length){case"narrow":return[...weekdaysNarrow];case"short":return[...weekdaysShort];case"long":return[...weekdaysLong];case"numeric":return["1","2","3","4","5","6","7"];default:return null;}}
const meridiems=["AM","PM"];const erasLong=["Before Christ","Anno Domini"];const erasShort=["BC","AD"];const erasNarrow=["B","A"];function eras(length){switch(length){case"narrow":return[...erasNarrow];case"short":return[...erasShort];case"long":return[...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="always",narrow=false){const 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."],};const lastable=["hours","minutes","seconds"].indexOf(unit)===-1;if(numeric==="auto"&&lastable){const 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]}`;}}
const 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){let s="";for(const token of splits){if(token.literal){s+=token.val;}else{s+=tokenToString(token.val);}}
return s;}
const 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,};class Formatter{static create(locale,opts={}){return new Formatter(locale,opts);}
static parseFormat(fmt){let current=null,currentFull="",bracketed=false;const splits=[];for(let i=0;i<fmt.length;i++){const c=fmt.charAt(i);if(c==="'"){if(currentFull.length>0){splits.push({literal:bracketed||/^\s+$/.test(currentFull),val:currentFull});}
current=null;currentFull="";bracketed=!bracketed;}else if(bracketed){currentFull+=c;}else if(c===current){currentFull+=c;}else{if(currentFull.length>0){splits.push({literal:/^\s+$/.test(currentFull),val:currentFull});}
currentFull=c;current=c;}}
if(currentFull.length>0){splits.push({literal:bracketed||/^\s+$/.test(currentFull),val:currentFull});}
return splits;}
static macroTokenToFormatOpts(token){return macroTokenToFormatOpts[token];}
constructor(locale,formatOpts){this.opts=formatOpts;this.loc=locale;this.systemLoc=null;}
formatWithSystemDefault(dt,opts){if(this.systemLoc===null){this.systemLoc=this.loc.redefaultToSystem();}
const df=this.systemLoc.dtFormatter(dt,{...this.opts,...opts});return df.format();}
dtFormatter(dt,opts={}){return this.loc.dtFormatter(dt,{...this.opts,...opts});}
formatDateTime(dt,opts){return this.dtFormatter(dt,opts).format();}
formatDateTimeParts(dt,opts){return this.dtFormatter(dt,opts).formatToParts();}
formatInterval(interval,opts){const df=this.dtFormatter(interval.start,opts);return df.dtf.formatRange(interval.start.toJSDate(),interval.end.toJSDate());}
resolvedOptions(dt,opts){return this.dtFormatter(dt,opts).resolvedOptions();}
num(n,p=0){if(this.opts.forceSimple){return padStart(n,p);}
const opts={...this.opts};if(p>0){opts.padTo=p;}
return this.loc.numberFormatter(opts).format(n);}
formatDateTimeFromString(dt,fmt){const knownEnglish=this.loc.listingMode()==="en",useDateTimeFormatter=this.loc.outputCalendar&&this.loc.outputCalendar!=="gregory",string=(opts,extract)=>this.loc.extract(dt,opts,extract),formatOffset=(opts)=>{if(dt.isOffsetFixed&&dt.offset===0&&opts.allowZ){return"Z";}
return dt.isValid?dt.zone.formatOffset(dt.ts,opts.format):"";},meridiem=()=>knownEnglish?meridiemForDateTime(dt):string({hour:"numeric",hourCycle:"h12"},"dayperiod"),month=(length,standalone)=>knownEnglish?monthForDateTime(dt,length):string(standalone?{month:length}:{month:length,day:"numeric"},"month"),weekday=(length,standalone)=>knownEnglish?weekdayForDateTime(dt,length):string(standalone?{weekday:length}:{weekday:length,month:"long",day:"numeric"},"weekday"),maybeMacro=(token)=>{const formatOpts=Formatter.macroTokenToFormatOpts(token);if(formatOpts){return this.formatWithSystemDefault(dt,formatOpts);}else{return token;}},era=(length)=>knownEnglish?eraForDateTime(dt,length):string({era:length},"era"),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"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);}
formatDurationFromString(dur,fmt){const 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=(lildur)=>(token)=>{const mapped=tokenToField(token);if(mapped){return this.num(lildur.get(mapped),token.length);}else{return token;}},tokens=Formatter.parseFormat(fmt),realTokens=tokens.reduce((found,{literal,val})=>(literal?found:found.concat(val)),[]),collapsed=dur.shiftTo(...realTokens.map(tokenToField).filter((t)=>t));return stringifyTokens(tokens,tokenToString(collapsed));}}
class Invalid{constructor(reason,explanation){this.reason=reason;this.explanation=explanation;}
toMessage(){if(this.explanation){return`${this.reason}: ${this.explanation}`;}else{return this.reason;}}}
const ianaRegex=/[A-Za-z_+-]{1,256}(?::?\/[A-Za-z0-9_+-]{1,256}(?:\/[A-Za-z0-9_+-]{1,256})?)?/;function combineRegexes(...regexes){const full=regexes.reduce((f,r)=>f+r.source,"");return RegExp(`^${full}$`);}
function combineExtractors(...extractors){return(m)=>extractors.reduce(([mergedVals,mergedZone,cursor],ex)=>{const[val,zone,next]=ex(m,cursor);return[{...mergedVals,...val},zone||mergedZone,next];},[{},null,1]).slice(0,2);}
function parse(s,...patterns){if(s==null){return[null,null];}
for(const[regex,extractor]of patterns){const m=regex.exec(s);if(m){return extractor(m);}}
return[null,null];}
function simpleParse(...keys){return(match,cursor)=>{const ret={};let i;for(i=0;i<keys.length;i++){ret[keys[i]]=parseInteger(match[cursor+i]);}
return[ret,null,cursor+i];};}
const offsetRegex=/(?:(Z)|([+-]\d\d)(?::?(\d\d))?)/;const isoExtendedZone=`(?:${offsetRegex.source}?(?:\\[(${ianaRegex.source})\\])?)?`;const isoTimeBaseRegex=/(\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d{1,30}))?)?)?/;const isoTimeRegex=RegExp(`${isoTimeBaseRegex.source}${isoExtendedZone}`);const isoTimeExtensionRegex=RegExp(`(?:T${isoTimeRegex.source})?`);const isoYmdRegex=/([+-]\d{6}|\d{4})(?:-?(\d\d)(?:-?(\d\d))?)?/;const isoWeekRegex=/(\d{4})-?W(\d\d)(?:-?(\d))?/;const isoOrdinalRegex=/(\d{4})-?(\d{3})/;const extractISOWeekData=simpleParse("weekYear","weekNumber","weekDay");const extractISOOrdinalData=simpleParse("year","ordinal");const sqlYmdRegex=/(\d{4})-(\d\d)-(\d\d)/;const sqlTimeRegex=RegExp(`${isoTimeBaseRegex.source} ?(?:${offsetRegex.source}|(${ianaRegex.source}))?`);const sqlTimeExtensionRegex=RegExp(`(?: ${sqlTimeRegex.source})?`);function int(match,pos,fallback){const m=match[pos];return isUndefined(m)?fallback:parseInteger(m);}
function extractISOYmd(match,cursor){const item={year:int(match,cursor),month:int(match,cursor+1,1),day:int(match,cursor+2,1),};return[item,null,cursor+3];}
function extractISOTime(match,cursor){const item={hours:int(match,cursor,0),minutes:int(match,cursor+1,0),seconds:int(match,cursor+2,0),milliseconds:parseMillis(match[cursor+3]),};return[item,null,cursor+4];}
function extractISOOffset(match,cursor){const local=!match[cursor]&&!match[cursor+1],fullOffset=signedOffset(match[cursor+1],match[cursor+2]),zone=local?null:FixedOffsetZone.instance(fullOffset);return[{},zone,cursor+3];}
function extractIANAZone(match,cursor){const zone=match[cursor]?IANAZone.create(match[cursor]):null;return[{},zone,cursor+1];}
const isoTimeOnly=RegExp(`^T?${isoTimeBaseRegex.source}$`);const isoDuration=/^-?P(?:(?:(-?\d{1,20}(?:\.\d{1,20})?)Y)?(?:(-?\d{1,20}(?:\.\d{1,20})?)M)?(?:(-?\d{1,20}(?:\.\d{1,20})?)W)?(?:(-?\d{1,20}(?:\.\d{1,20})?)D)?(?:T(?:(-?\d{1,20}(?:\.\d{1,20})?)H)?(?:(-?\d{1,20}(?:\.\d{1,20})?)M)?(?:(-?\d{1,20})(?:[.,](-?\d{1,20}))?S)?)?)$/;function extractISODuration(match){const[s,yearStr,monthStr,weekStr,dayStr,hourStr,minuteStr,secondStr,millisecondsStr]=match;const hasNegativePrefix=s[0]==="-";const negativeSeconds=secondStr&&secondStr[0]==="-";const maybeNegate=(num,force=false)=>num!==undefined&&(force||(num&&hasNegativePrefix))?-num:num;return[{years:maybeNegate(parseFloating(yearStr)),months:maybeNegate(parseFloating(monthStr)),weeks:maybeNegate(parseFloating(weekStr)),days:maybeNegate(parseFloating(dayStr)),hours:maybeNegate(parseFloating(hourStr)),minutes:maybeNegate(parseFloating(minuteStr)),seconds:maybeNegate(parseFloating(secondStr),secondStr==="-0"),milliseconds:maybeNegate(parseMillis(millisecondsStr),negativeSeconds),},];}
const obsOffsets={GMT:0,EDT:-4*60,EST:-5*60,CDT:-5*60,CST:-6*60,MDT:-6*60,MST:-7*60,PDT:-7*60,PST:-8*60,};function fromStrings(weekdayStr,yearStr,monthStr,dayStr,hourStr,minuteStr,secondStr){const result={year:yearStr.length===2?untruncateYear(parseInteger(yearStr)):parseInteger(yearStr),month:monthsShort.indexOf(monthStr)+1,day:parseInteger(dayStr),hour:parseInteger(hourStr),minute:parseInteger(minuteStr),};if(secondStr)result.second=parseInteger(secondStr);if(weekdayStr){result.weekday=weekdayStr.length>3?weekdaysLong.indexOf(weekdayStr)+1:weekdaysShort.indexOf(weekdayStr)+1;}
return result;}
const 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){const[,weekdayStr,dayStr,monthStr,yearStr,hourStr,minuteStr,secondStr,obsOffset,milOffset,offHourStr,offMinuteStr,]=match,result=fromStrings(weekdayStr,yearStr,monthStr,dayStr,hourStr,minuteStr,secondStr);let 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();}
const 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){const[,weekdayStr,dayStr,monthStr,yearStr,hourStr,minuteStr,secondStr]=match,result=fromStrings(weekdayStr,yearStr,monthStr,dayStr,hourStr,minuteStr,secondStr);return[result,FixedOffsetZone.utcInstance];}
function extractASCII(match){const[,weekdayStr,monthStr,dayStr,hourStr,minuteStr,secondStr,yearStr]=match,result=fromStrings(weekdayStr,yearStr,monthStr,dayStr,hourStr,minuteStr,secondStr);return[result,FixedOffsetZone.utcInstance];}
const isoYmdWithTimeExtensionRegex=combineRegexes(isoYmdRegex,isoTimeExtensionRegex);const isoWeekWithTimeExtensionRegex=combineRegexes(isoWeekRegex,isoTimeExtensionRegex);const isoOrdinalWithTimeExtensionRegex=combineRegexes(isoOrdinalRegex,isoTimeExtensionRegex);const isoTimeCombinedRegex=combineRegexes(isoTimeRegex);const extractISOYmdTimeAndOffset=combineExtractors(extractISOYmd,extractISOTime,extractISOOffset,extractIANAZone);const extractISOWeekTimeAndOffset=combineExtractors(extractISOWeekData,extractISOTime,extractISOOffset,extractIANAZone);const extractISOOrdinalDateAndTime=combineExtractors(extractISOOrdinalData,extractISOTime,extractISOOffset,extractIANAZone);const 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]);}
const extractISOTimeOnly=combineExtractors(extractISOTime);function parseISOTimeOnly(s){return parse(s,[isoTimeOnly,extractISOTimeOnly]);}
const sqlYmdWithTimeExtensionRegex=combineRegexes(sqlYmdRegex,sqlTimeExtensionRegex);const sqlTimeCombinedRegex=combineRegexes(sqlTimeRegex);const extractISOTimeOffsetAndIANAZone=combineExtractors(extractISOTime,extractISOOffset,extractIANAZone);function parseSQL(s){return parse(s,[sqlYmdWithTimeExtensionRegex,extractISOYmdTimeAndOffset],[sqlTimeCombinedRegex,extractISOTimeOffsetAndIANAZone]);}
const INVALID$2="Invalid Duration";const 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={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={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,};const orderedUnits$1=["years","quarters","months","weeks","days","hours","minutes","seconds","milliseconds",];const reverseUnits=orderedUnits$1.slice(0).reverse();function clone$1(dur,alts,clear=false){const conf={values:clear?alts.values:{...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){let sum=vals.milliseconds??0;for(const unit of reverseUnits.slice(1)){if(vals[unit]){sum+=vals[unit]*matrix[unit]["milliseconds"];}}
return sum;}
function normalizeValues(matrix,vals){const factor=durationToMillis(matrix,vals)<0?-1:1;reverseUnits.reduce((previous,current)=>{if(!isUndefined(vals[current])){if(previous){const previousVal=vals[previous]*factor;const conv=matrix[current][previous];const rollUp=Math.floor(previousVal/conv);vals[current]+=rollUp*factor;vals[previous]-=rollUp*conv*factor;}
return current;}else{return previous;}},null);}
function removeZeroes(vals){const newVals={};for(const[key,value]of Object.entries(vals)){if(value!==0){newVals[key]=value;}}
return newVals;}
class Duration{constructor(config){const accurate=config.conversionAccuracy==="longterm"||false;let 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;}
static fromMillis(count,opts){return Duration.fromObject({milliseconds:count},opts);}
static fromObject(obj,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,});}
static 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}`);}}
static fromISO(text,opts){const[parsed]=parseISODuration(text);if(parsed){return Duration.fromObject(parsed,opts);}else{return Duration.invalid("unparsable",`the input "${text}" can't be parsed as ISO 8601`);}}
static fromISOTime(text,opts){const[parsed]=parseISOTimeOnly(text);if(parsed){return Duration.fromObject(parsed,opts);}else{return Duration.invalid("unparsable",`the input "${text}" can't be parsed as ISO 8601`);}}
static invalid(reason,explanation=null){if(!reason){throw new InvalidArgumentError("need to specify a reason the Duration is invalid");}
const invalid=reason instanceof Invalid?reason:new Invalid(reason,explanation);if(Settings.throwOnInvalid){throw new InvalidDurationError(invalid);}else{return new Duration({invalid});}}
static normalizeUnit(unit){const 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;}
static isDuration(o){return(o&&o.isLuxonDuration)||false;}
get locale(){return this.isValid?this.loc.locale:null;}
get numberingSystem(){return this.isValid?this.loc.numberingSystem:null;}
toFormat(fmt,opts={}){const fmtOpts={...opts,floor:opts.round!==false&&opts.floor!==false,};return this.isValid?Formatter.create(this.loc,fmtOpts).formatDurationFromString(this,fmt):INVALID$2;}
toHuman(opts={}){if(!this.isValid)return INVALID$2;const l=orderedUnits$1.map((unit)=>{const val=this.values[unit];if(isUndefined(val)){return null;}
return this.loc.numberFormatter({style:"unit",unitDisplay:"long",...opts,unit:unit.slice(0,-1)}).format(val);}).filter((n)=>n);return this.loc.listFormatter({type:"conjunction",style:opts.listStyle||"narrow",...opts}).format(l);}
toObject(){if(!this.isValid)return{};return{...this.values};}
toISO(){if(!this.isValid)return null;let 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;}
toISOTime(opts={}){if(!this.isValid)return null;const millis=this.toMillis();if(millis<0||millis>=86400000)return null;opts={suppressMilliseconds:false,suppressSeconds:false,includePrefix:false,format:"extended",...opts,includeOffset:false,};const dateTime=DateTime.fromMillis(millis,{zone:"UTC"});return dateTime.toISOTime(opts);}
toJSON(){return this.toISO();}
toString(){return this.toISO();}
toMillis(){if(!this.isValid)return NaN;return durationToMillis(this.matrix,this.values);}
valueOf(){return this.toMillis();}
plus(duration){if(!this.isValid)return this;const dur=Duration.fromDurationLike(duration),result={};for(const k of orderedUnits$1){if(hasOwnProperty(dur.values,k)||hasOwnProperty(this.values,k)){result[k]=dur.get(k)+this.get(k);}}
return clone$1(this,{values:result},true);}
minus(duration){if(!this.isValid)return this;const dur=Duration.fromDurationLike(duration);return this.plus(dur.negate());}
mapUnits(fn){if(!this.isValid)return this;const result={};for(const k of Object.keys(this.values)){result[k]=asNumber(fn(this.values[k],k));}
return clone$1(this,{values:result},true);}
get(unit){return this[Duration.normalizeUnit(unit)];}
set(values){if(!this.isValid)return this;const mixed={...this.values,...normalizeObject(values,Duration.normalizeUnit)};return clone$1(this,{values:mixed});}
reconfigure({locale,numberingSystem,conversionAccuracy,matrix}={}){const loc=this.loc.clone({locale,numberingSystem});const opts={loc,matrix,conversionAccuracy};return clone$1(this,opts);}
as(unit){return this.isValid?this.shiftTo(unit).get(unit):NaN;}
normalize(){if(!this.isValid)return this;const vals=this.toObject();normalizeValues(this.matrix,vals);return clone$1(this,{values:vals},true);}
rescale(){if(!this.isValid)return this;const vals=removeZeroes(this.normalize().shiftToAll().toObject());return clone$1(this,{values:vals},true);}
shiftTo(...units){if(!this.isValid)return this;if(units.length===0){return this;}
units=units.map((u)=>Duration.normalizeUnit(u));const built={},accumulated={},vals=this.toObject();let lastUnit;for(const k of orderedUnits$1){if(units.indexOf(k)>=0){lastUnit=k;let own=0;for(const ak in accumulated){own+=this.matrix[ak][k]*accumulated[ak];accumulated[ak]=0;}
if(isNumber(vals[k])){own+=vals[k];}
const i=Math.trunc(own);built[k]=i;accumulated[k]=(own*1000-i*1000)/1000;}else if(isNumber(vals[k])){accumulated[k]=vals[k];}}
for(const 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);}
shiftToAll(){if(!this.isValid)return this;return this.shiftTo("years","months","weeks","days","hours","minutes","seconds","milliseconds");}
negate(){if(!this.isValid)return this;const negated={};for(const k of Object.keys(this.values)){negated[k]=this.values[k]===0?0:-this.values[k];}
return clone$1(this,{values:negated},true);}
get years(){return this.isValid?this.values.years||0:NaN;}
get quarters(){return this.isValid?this.values.quarters||0:NaN;}
get months(){return this.isValid?this.values.months||0:NaN;}
get weeks(){return this.isValid?this.values.weeks||0:NaN;}
get days(){return this.isValid?this.values.days||0:NaN;}
get hours(){return this.isValid?this.values.hours||0:NaN;}
get minutes(){return this.isValid?this.values.minutes||0:NaN;}
get seconds(){return this.isValid?this.values.seconds||0:NaN;}
get milliseconds(){return this.isValid?this.values.milliseconds||0:NaN;}
get isValid(){return this.invalid===null;}
get invalidReason(){return this.invalid?this.invalid.reason:null;}
get invalidExplanation(){return this.invalid?this.invalid.explanation:null;}
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(const u of orderedUnits$1){if(!eq(this.values[u],other.values[u])){return false;}}
return true;}}
const INVALID$1="Invalid Interval";function validateStartEnd(start,end){if(!start||!start.isValid){return Interval.invalid("missing or invalid start");}else if(!end||!end.isValid){return Interval.invalid("missing or invalid end");}else if(end<start){return Interval.invalid("end before start",`The end of an interval must be after its start, but you had start=${start.toISO()} and end=${end.toISO()}`);}else{return null;}}
class Interval{constructor(config){this.s=config.start;this.e=config.end;this.invalid=config.invalid||null;this.isLuxonInterval=true;}
static invalid(reason,explanation=null){if(!reason){throw new InvalidArgumentError("need to specify a reason the Interval is invalid");}
const invalid=reason instanceof Invalid?reason:new Invalid(reason,explanation);if(Settings.throwOnInvalid){throw new InvalidIntervalError(invalid);}else{return new Interval({invalid});}}
static fromDateTimes(start,end){const builtStart=friendlyDateTime(start),builtEnd=friendlyDateTime(end);const validateError=validateStartEnd(builtStart,builtEnd);if(validateError==null){return new Interval({start:builtStart,end:builtEnd,});}else{return validateError;}}
static after(start,duration){const dur=Duration.fromDurationLike(duration),dt=friendlyDateTime(start);return Interval.fromDateTimes(dt,dt.plus(dur));}
static before(end,duration){const dur=Duration.fromDurationLike(duration),dt=friendlyDateTime(end);return Interval.fromDateTimes(dt.minus(dur),dt);}
static fromISO(text,opts){const[s,e]=(text||"").split("/",2);if(s&&e){let start,startIsValid;try{start=DateTime.fromISO(s,opts);startIsValid=start.isValid;}catch(e){startIsValid=false;}
let end,endIsValid;try{end=DateTime.fromISO(e,opts);endIsValid=end.isValid;}catch(e){endIsValid=false;}
if(startIsValid&&endIsValid){return Interval.fromDateTimes(start,end);}
if(startIsValid){const dur=Duration.fromISO(e,opts);if(dur.isValid){return Interval.after(start,dur);}}else if(endIsValid){const dur=Duration.fromISO(s,opts);if(dur.isValid){return Interval.before(end,dur);}}}
return Interval.invalid("unparsable",`the input "${text}" can't be parsed as ISO 8601`);}
static isInterval(o){return(o&&o.isLuxonInterval)||false;}
get start(){return this.isValid?this.s:null;}
get end(){return this.isValid?this.e:null;}
get isValid(){return this.invalidReason===null;}
get invalidReason(){return this.invalid?this.invalid.reason:null;}
get invalidExplanation(){return this.invalid?this.invalid.explanation:null;}
length(unit="milliseconds"){return this.isValid?this.toDuration(...[unit]).get(unit):NaN;}
count(unit="milliseconds"){if(!this.isValid)return NaN;const start=this.start.startOf(unit),end=this.end.startOf(unit);return Math.floor(end.diff(start,unit).get(unit))+(end.valueOf()!==this.end.valueOf());}
hasSame(unit){return this.isValid?this.isEmpty()||this.e.minus(1).hasSame(this.s,unit):false;}
isEmpty(){return this.s.valueOf()===this.e.valueOf();}
isAfter(dateTime){if(!this.isValid)return false;return this.s>dateTime;}
isBefore(dateTime){if(!this.isValid)return false;return this.e<=dateTime;}
contains(dateTime){if(!this.isValid)return false;return this.s<=dateTime&&this.e>dateTime;}
set({start,end}={}){if(!this.isValid)return this;return Interval.fromDateTimes(start||this.s,end||this.e);}
splitAt(...dateTimes){if(!this.isValid)return[];const sorted=dateTimes.map(friendlyDateTime).filter((d)=>this.contains(d)).sort(),results=[];let{s}=this,i=0;while(s<this.e){const added=sorted[i]||this.e,next=+added>+this.e?this.e:added;results.push(Interval.fromDateTimes(s,next));s=next;i+=1;}
return results;}
splitBy(duration){const dur=Duration.fromDurationLike(duration);if(!this.isValid||!dur.isValid||dur.as("milliseconds")===0){return[];}
let{s}=this,idx=1,next;const results=[];while(s<this.e){const added=this.start.plus(dur.mapUnits((x)=>x*idx));next=+added>+this.e?this.e:added;results.push(Interval.fromDateTimes(s,next));s=next;idx+=1;}
return results;}
divideEqually(numberOfParts){if(!this.isValid)return[];return this.splitBy(this.length()/numberOfParts).slice(0,numberOfParts);}
overlaps(other){return this.e>other.s&&this.s<other.e;}
abutsStart(other){if(!this.isValid)return false;return+this.e===+other.s;}
abutsEnd(other){if(!this.isValid)return false;return+other.e===+this.s;}
engulfs(other){if(!this.isValid)return false;return this.s<=other.s&&this.e>=other.e;}
equals(other){if(!this.isValid||!other.isValid){return false;}
return this.s.equals(other.s)&&this.e.equals(other.e);}
intersection(other){if(!this.isValid)return this;const s=this.s>other.s?this.s:other.s,e=this.e<other.e?this.e:other.e;if(s>=e){return null;}else{return Interval.fromDateTimes(s,e);}}
union(other){if(!this.isValid)return this;const s=this.s<other.s?this.s:other.s,e=this.e>other.e?this.e:other.e;return Interval.fromDateTimes(s,e);}
static merge(intervals){const[found,final]=intervals.sort((a,b)=>a.s-b.s).reduce(([sofar,current],item)=>{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]);if(final){found.push(final);}
return found;}
static xor(intervals){let start=null,currentCount=0;const results=[],ends=intervals.map((i)=>[{time:i.s,type:"s"},{time:i.e,type:"e"},]),flattened=Array.prototype.concat(...ends),arr=flattened.sort((a,b)=>a.time-b.time);for(const i of arr){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);}
difference(...intervals){return Interval.xor([this].concat(intervals)).map((i)=>this.intersection(i)).filter((i)=>i&&!i.isEmpty());}
toString(){if(!this.isValid)return INVALID$1;return`[${this.s.toISO()} – ${this.e.toISO()})`;}
toLocaleString(formatOpts=DATE_SHORT,opts={}){return this.isValid?Formatter.create(this.s.loc.clone(opts),formatOpts).formatInterval(this):INVALID$1;}
toISO(opts){if(!this.isValid)return INVALID$1;return`${this.s.toISO(opts)}/${this.e.toISO(opts)}`;}
toISODate(){if(!this.isValid)return INVALID$1;return`${this.s.toISODate()}/${this.e.toISODate()}`;}
toISOTime(opts){if(!this.isValid)return INVALID$1;return`${this.s.toISOTime(opts)}/${this.e.toISOTime(opts)}`;}
toFormat(dateFormat,{separator=" – "}={}){if(!this.isValid)return INVALID$1;return`${this.s.toFormat(dateFormat)}${separator}${this.e.toFormat(dateFormat)}`;}
toDuration(unit,opts){if(!this.isValid){return Duration.invalid(this.invalidReason);}
return this.e.diff(this.s,unit,opts);}
mapEndpoints(mapFn){return Interval.fromDateTimes(mapFn(this.s),mapFn(this.e));}}
class Info{static hasDST(zone=Settings.defaultZone){const proto=DateTime.now().setZone(zone).set({month:12});return!zone.isUniversal&&proto.offset!==proto.set({month:6}).offset;}
static isValidIANAZone(zone){return IANAZone.isValidZone(zone);}
static normalizeZone(input){return normalizeZone(input,Settings.defaultZone);}
static months(length="long",{locale=null,numberingSystem=null,locObj=null,outputCalendar="gregory"}={}){return(locObj||Locale.create(locale,numberingSystem,outputCalendar)).months(length);}
static monthsFormat(length="long",{locale=null,numberingSystem=null,locObj=null,outputCalendar="gregory"}={}){return(locObj||Locale.create(locale,numberingSystem,outputCalendar)).months(length,true);}
static weekdays(length="long",{locale=null,numberingSystem=null,locObj=null}={}){return(locObj||Locale.create(locale,numberingSystem,null)).weekdays(length);}
static weekdaysFormat(length="long",{locale=null,numberingSystem=null,locObj=null}={}){return(locObj||Locale.create(locale,numberingSystem,null)).weekdays(length,true);}
static meridiems({locale=null}={}){return Locale.create(locale).meridiems();}
static eras(length="short",{locale=null}={}){return Locale.create(locale,null,"gregory").eras(length);}
static features(){return{relative:hasRelative()};}}
function dayDiff(earlier,later){const utcDayStart=(dt)=>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){const differs=[["years",(a,b)=>b.year-a.year],["quarters",(a,b)=>b.quarter-a.quarter+(b.year-a.year)*4],["months",(a,b)=>b.month-a.month+(b.year-a.year)*12],["weeks",(a,b)=>{const days=dayDiff(a,b);return(days-(days%7))/7;},],["days",dayDiff],];const results={};const earlier=cursor;let lowestOrder,highWater;for(const[unit,differ]of differs){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){let[cursor,results,highWater,lowestOrder]=highOrderDiffs(earlier,later,units);const remainingMillis=later-cursor;const lowerOrderUnits=units.filter((u)=>["hours","minutes","seconds","milliseconds"].indexOf(u)>=0);if(lowerOrderUnits.length===0){if(highWater<later){highWater=cursor.plus({[lowestOrder]:1});}
if(highWater!==cursor){results[lowestOrder]=(results[lowestOrder]||0)+remainingMillis/(highWater-cursor);}}
const duration=Duration.fromObject(results,opts);if(lowerOrderUnits.length>0){return Duration.fromMillis(remainingMillis,opts).shiftTo(...lowerOrderUnits).plus(duration);}else{return duration;}}
const 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",};const 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],};const hanidecChars=numberingSystems.hanidec.replace(/[\[|\]]/g,"").split("");function parseDigits(str){let value=parseInt(str,10);if(isNaN(value)){value="";for(let i=0;i<str.length;i++){const code=str.charCodeAt(i);if(str[i].search(numberingSystems.hanidec)!==-1){value+=hanidecChars.indexOf(str[i]);}else{for(const key in numberingSystemsUTF16){const[min,max]=numberingSystemsUTF16[key];if(code>=min&&code<=max){value+=code-min;}}}}
return parseInt(value,10);}else{return value;}}
function digitRegex({numberingSystem},append=""){return new RegExp(`${numberingSystems[numberingSystem || "latn"]}${append}`);}
const MISSING_FTP="missing Intl.DateTimeFormat.formatToParts support";function intUnit(regex,post=(i)=>i){return{regex,deser:([s])=>post(parseDigits(s))};}
const NBSP=String.fromCharCode(160);const spaceOrNBSP=`[ ${NBSP}]`;const 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:([s])=>strings.findIndex((i)=>stripInsensitivities(s)===stripInsensitivities(i))+startIndex,};}}
function offset(regex,groups){return{regex,deser:([,h,m])=>signedOffset(h,m),groups};}
function simple(regex){return{regex,deser:([s])=>s};}
function escapeToken(value){return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&");}
function unitForToken(token,loc){const 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=(t)=>({regex:RegExp(escapeToken(t.val)),deser:([s])=>s,literal:true}),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);}};const unit=unitate(token)||{invalidReason:MISSING_FTP,};unit.token=token;return unit;}
const 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){const{type,value}=part;if(type==="literal"){const isSpace=/^\s+$/.test(value);return{literal:!isSpace,val:isSpace?" ":value,};}
const style=formatOpts[type];let 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";}}
let val=partTypeStyleToTokenVal[actualType];if(typeof val==="object"){val=val[style];}
if(val){return{literal:false,val,};}
return undefined;}
function buildRegex(units){const re=units.map((u)=>u.regex).reduce((f,r)=>`${f}(${r.source})`,"");return[`^${re}$`,units];}
function match(input,regex,handlers){const matches=input.match(regex);if(matches){const all={};let matchIndex=1;for(const i in handlers){if(hasOwnProperty(handlers,i)){const 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){const 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;}};let zone=null;let 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);}
const vals=Object.keys(matches).reduce((r,k)=>{const f=toField(k);if(f){r[f]=matches[k];}
return r;},{});return[vals,zone,specificOffset];}
let dummyDateTimeCache=null;function getDummyDateTime(){if(!dummyDateTimeCache){dummyDateTimeCache=DateTime.fromMillis(1555555555555);}
return dummyDateTimeCache;}
function maybeExpandMacroToken(token,locale){if(token.literal){return token;}
const formatOpts=Formatter.macroTokenToFormatOpts(token.val);const tokens=formatOptsToTokens(formatOpts,locale);if(tokens==null||tokens.includes(undefined)){return token;}
return tokens;}
function expandMacroTokens(tokens,locale){return Array.prototype.concat(...tokens.map((t)=>maybeExpandMacroToken(t,locale)));}
function explainFromTokens(locale,input,format){const tokens=expandMacroTokens(Formatter.parseFormat(format),locale),units=tokens.map((t)=>unitForToken(t,locale)),disqualifyingUnit=units.find((t)=>t.invalidReason);if(disqualifyingUnit){return{input,tokens,invalidReason:disqualifyingUnit.invalidReason};}else{const[regexString,handlers]=buildRegex(units),regex=RegExp(regexString,"i"),[rawMatches,matches]=match(input,regex,handlers),[result,zone,specificOffset]=matches?dateTimeFromMatches(matches):[null,null,undefined];if(hasOwnProperty(matches,"a")&&hasOwnProperty(matches,"H")){throw new ConflictingSpecificationError("Can't include meridiem when specifying 24-hour format");}
return{input,tokens,regex,rawMatches,matches,result,zone,specificOffset};}}
function parseFromTokens(locale,input,format){const{result,zone,specificOffset,invalidReason}=explainFromTokens(locale,input,format);return[result,zone,specificOffset,invalidReason];}
function formatOptsToTokens(formatOpts,locale){if(!formatOpts){return null;}
const formatter=Formatter.create(locale,formatOpts);const df=formatter.dtFormatter(getDummyDateTime());const parts=df.formatToParts();const resolvedOpts=df.resolvedOptions();return parts.map((p)=>tokenForPart(p,formatOpts,resolvedOpts));}
const 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){const d=new Date(Date.UTC(year,month-1,day));if(year<100&&year>=0){d.setUTCFullYear(d.getUTCFullYear()-1900);}
const 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){const table=isLeapYear(year)?leapLadder:nonLeapLadder,month0=table.findIndex((i)=>i<ordinal),day=ordinal-table[month0];return{month:month0+1,day};}
function gregorianToWeek(gregObj){const{year,month,day}=gregObj,ordinal=computeOrdinal(year,month,day),weekday=dayOfWeek(year,month,day);let weekNumber=Math.floor((ordinal-weekday+10)/7),weekYear;if(weekNumber<1){weekYear=year-1;weekNumber=weeksInWeekYear(weekYear);}else if(weekNumber>weeksInWeekYear(year)){weekYear=year+1;weekNumber=1;}else{weekYear=year;}
return{weekYear,weekNumber,weekday,...timeObject(gregObj)};}
function weekToGregorian(weekData){const{weekYear,weekNumber,weekday}=weekData,weekdayOfJan4=dayOfWeek(weekYear,1,4),yearInDays=daysInYear(weekYear);let ordinal=weekNumber*7+weekday-weekdayOfJan4-3,year;if(ordinal<1){year=weekYear-1;ordinal+=daysInYear(year);}else if(ordinal>yearInDays){year=weekYear+1;ordinal-=daysInYear(weekYear);}else{year=weekYear;}
const{month,day}=uncomputeOrdinal(year,ordinal);return{year,month,day,...timeObject(weekData)};}
function gregorianToOrdinal(gregData){const{year,month,day}=gregData;const ordinal=computeOrdinal(year,month,day);return{year,ordinal,...timeObject(gregData)};}
function ordinalToGregorian(ordinalData){const{year,ordinal}=ordinalData;const{month,day}=uncomputeOrdinal(year,ordinal);return{year,month,day,...timeObject(ordinalData)};}
function hasInvalidWeekData(obj){const validYear=isInteger(obj.weekYear),validWeek=integerBetween(obj.weekNumber,1,weeksInWeekYear(obj.weekYear)),validWeekday=integerBetween(obj.weekday,1,7);if(!validYear){return unitOutOfRange("weekYear",obj.weekYear);}else if(!validWeek){return unitOutOfRange("week",obj.week);}else if(!validWeekday){return unitOutOfRange("weekday",obj.weekday);}else return false;}
function hasInvalidOrdinalData(obj){const 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){const 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){const{hour,minute,second,millisecond}=obj;const 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;}
const INVALID="Invalid DateTime";const 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 clone(inst,alts){const current={ts:inst.ts,zone:inst.zone,c:inst.c,o:inst.o,loc:inst.loc,invalid:inst.invalid,};return new DateTime({...current,...alts,old:current});}
function fixOffset(localTS,o,tz){let utcGuess=localTS-o*60*1000;const o2=tz.offset(utcGuess);if(o===o2){return[utcGuess,o];}
utcGuess-=(o2-o)*60*1000;const 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;const 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){const 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={...inst.c,year,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);let[ts,o]=fixOffset(localTS,oPre,inst.zone);if(millisToAdd!==0){ts+=millisToAdd;o=inst.zone.offset(ts);}
return{ts,o};}
function parseDataToDateTime(parsed,parsedZone,opts,format,text,specificOffset){const{setZone,zone}=opts;if((parsed&&Object.keys(parsed).length!==0)||parsedZone){const interpretationZone=parsedZone||zone,inst=DateTime.fromObject(parsed,{...opts,zone:interpretationZone,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=true){return dt.isValid?Formatter.create(Locale.create("en-US"),{allowZ,forceSimple:true,}).formatDateTimeFromString(dt,format):null;}
function toISODate(o,extended){const longFormat=o.c.year>9999||o.c.year<0;let 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){let 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;}
const 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,};const 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){const 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 quickDT(obj,opts){const zone=normalizeZone(opts.zone,Settings.defaultZone),loc=Locale.fromObject(opts),tsNow=Settings.now();let ts,o;if(!isUndefined(obj.year)){for(const u of orderedUnits){if(isUndefined(obj[u])){obj[u]=defaultUnitValues[u];}}
const invalid=hasInvalidGregorianData(obj)||hasInvalidTimeData(obj);if(invalid){return DateTime.invalid(invalid);}
const offsetProvis=zone.offset(tsNow);[ts,o]=objToTS(obj,offsetProvis,zone);}else{ts=tsNow;}
return new DateTime({ts,zone,loc,o});}
function diffRelative(start,end,opts){const round=isUndefined(opts.round)?true:opts.round,format=(c,unit)=>{c=roundTo(c,round||opts.calendary?0:2,true);const formatter=end.loc.clone(opts).relFormatter(opts);return formatter.format(c,unit);},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(const unit of opts.units){const 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){let 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];}
class DateTime{constructor(config){const zone=config.zone||Settings.defaultZone;let 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;let c=null,o=null;if(!invalid){const unchanged=config.old&&config.old.ts===this.ts&&config.old.zone.equals(zone);if(unchanged){[c,o]=[config.old.c,config.old.o];}else{const ot=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.c=c;this.o=o;this.isLuxonDateTime=true;}
static now(){return new DateTime({});}
static local(){const[opts,args]=lastOpts(arguments),[year,month,day,hour,minute,second,millisecond]=args;return quickDT({year,month,day,hour,minute,second,millisecond},opts);}
static utc(){const[opts,args]=lastOpts(arguments),[year,month,day,hour,minute,second,millisecond]=args;opts.zone=FixedOffsetZone.utcInstance;return quickDT({year,month,day,hour,minute,second,millisecond},opts);}
static fromJSDate(date,options={}){const ts=isDate(date)?date.valueOf():NaN;if(Number.isNaN(ts)){return DateTime.invalid("invalid input");}
const 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),});}
static fromMillis(milliseconds,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),});}}
static fromSeconds(seconds,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),});}}
static fromObject(obj,opts={}){obj=obj||{};const zoneToUse=normalizeZone(opts.zone,Settings.defaultZone);if(!zoneToUse.isValid){return DateTime.invalid(unsupportedZone(zoneToUse));}
const tsNow=Settings.now(),offsetProvis=!isUndefined(opts.specificOffset)?opts.specificOffset:zoneToUse.offset(tsNow),normalized=normalizeObject(obj,normalizeUnit),containsOrdinal=!isUndefined(normalized.ordinal),containsGregorYear=!isUndefined(normalized.year),containsGregorMD=!isUndefined(normalized.month)||!isUndefined(normalized.day),containsGregor=containsGregorYear||containsGregorMD,definiteWeekDef=normalized.weekYear||normalized.weekNumber,loc=Locale.fromObject(opts);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");}
const useWeekData=definiteWeekDef||(normalized.weekday&&!containsGregor);let units,defaultValues,objNow=tsToObj(tsNow,offsetProvis);if(useWeekData){units=orderedWeekUnits;defaultValues=defaultWeekUnitValues;objNow=gregorianToWeek(objNow);}else if(containsOrdinal){units=orderedOrdinalUnits;defaultValues=defaultOrdinalUnitValues;objNow=gregorianToOrdinal(objNow);}else{units=orderedUnits;defaultValues=defaultUnitValues;}
let foundFirst=false;for(const u of units){const v=normalized[u];if(!isUndefined(v)){foundFirst=true;}else if(foundFirst){normalized[u]=defaultValues[u];}else{normalized[u]=objNow[u];}}
const higherOrderInvalid=useWeekData?hasInvalidWeekData(normalized):containsOrdinal?hasInvalidOrdinalData(normalized):hasInvalidGregorianData(normalized),invalid=higherOrderInvalid||hasInvalidTimeData(normalized);if(invalid){return DateTime.invalid(invalid);}
const gregorian=useWeekData?weekToGregorian(normalized):containsOrdinal?ordinalToGregorian(normalized):normalized,[tsFinal,offsetFinal]=objToTS(gregorian,offsetProvis,zoneToUse),inst=new DateTime({ts:tsFinal,zone:zoneToUse,o:offsetFinal,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()}`);}
return inst;}
static fromISO(text,opts={}){const[vals,parsedZone]=parseISODate(text);return parseDataToDateTime(vals,parsedZone,opts,"ISO 8601",text);}
static fromRFC2822(text,opts={}){const[vals,parsedZone]=parseRFC2822Date(text);return parseDataToDateTime(vals,parsedZone,opts,"RFC 2822",text);}
static fromHTTP(text,opts={}){const[vals,parsedZone]=parseHTTPDate(text);return parseDataToDateTime(vals,parsedZone,opts,"HTTP",opts);}
static fromFormat(text,fmt,opts={}){if(isUndefined(text)||isUndefined(fmt)){throw new InvalidArgumentError("fromFormat requires an input string and a format");}
const{locale=null,numberingSystem=null}=opts,localeToUse=Locale.fromOpts({locale,numberingSystem,defaultToEN:true,}),[vals,parsedZone,specificOffset,invalid]=parseFromTokens(localeToUse,text,fmt);if(invalid){return DateTime.invalid(invalid);}else{return parseDataToDateTime(vals,parsedZone,opts,`format ${fmt}`,text,specificOffset);}}
static fromString(text,fmt,opts={}){return DateTime.fromFormat(text,fmt,opts);}
static fromSQL(text,opts={}){const[vals,parsedZone]=parseSQL(text);return parseDataToDateTime(vals,parsedZone,opts,"SQL",text);}
static invalid(reason,explanation=null){if(!reason){throw new InvalidArgumentError("need to specify a reason the DateTime is invalid");}
const invalid=reason instanceof Invalid?reason:new Invalid(reason,explanation);if(Settings.throwOnInvalid){throw new InvalidDateTimeError(invalid);}else{return new DateTime({invalid});}}
static isDateTime(o){return(o&&o.isLuxonDateTime)||false;}
static parseFormatForOpts(formatOpts,localeOpts={}){const tokenList=formatOptsToTokens(formatOpts,Locale.fromObject(localeOpts));return!tokenList?null:tokenList.map((t)=>(t?t.val:null)).join("");}
static expandFormat(fmt,localeOpts={}){const expanded=expandMacroTokens(Formatter.parseFormat(fmt),Locale.fromObject(localeOpts));return expanded.map((t)=>t.val).join("");}
get(unit){return this[unit];}
get isValid(){return this.invalid===null;}
get invalidReason(){return this.invalid?this.invalid.reason:null;}
get invalidExplanation(){return this.invalid?this.invalid.explanation:null;}
get locale(){return this.isValid?this.loc.locale:null;}
get numberingSystem(){return this.isValid?this.loc.numberingSystem:null;}
get outputCalendar(){return this.isValid?this.loc.outputCalendar:null;}
get zone(){return this._zone;}
get zoneName(){return this.isValid?this.zone.name:null;}
get year(){return this.isValid?this.c.year:NaN;}
get quarter(){return this.isValid?Math.ceil(this.c.month/3):NaN;}
get month(){return this.isValid?this.c.month:NaN;}
get day(){return this.isValid?this.c.day:NaN;}
get hour(){return this.isValid?this.c.hour:NaN;}
get minute(){return this.isValid?this.c.minute:NaN;}
get second(){return this.isValid?this.c.second:NaN;}
get millisecond(){return this.isValid?this.c.millisecond:NaN;}
get weekYear(){return this.isValid?possiblyCachedWeekData(this).weekYear:NaN;}
get weekNumber(){return this.isValid?possiblyCachedWeekData(this).weekNumber:NaN;}
get weekday(){return this.isValid?possiblyCachedWeekData(this).weekday:NaN;}
get ordinal(){return this.isValid?gregorianToOrdinal(this.c).ordinal:NaN;}
get monthShort(){return this.isValid?Info.months("short",{locObj:this.loc})[this.month-1]:null;}
get monthLong(){return this.isValid?Info.months("long",{locObj:this.loc})[this.month-1]:null;}
get weekdayShort(){return this.isValid?Info.weekdays("short",{locObj:this.loc})[this.weekday-1]:null;}
get weekdayLong(){return this.isValid?Info.weekdays("long",{locObj:this.loc})[this.weekday-1]:null;}
get offset(){return this.isValid?+this.o:NaN;}
get offsetNameShort(){if(this.isValid){return this.zone.offsetName(this.ts,{format:"short",locale:this.locale,});}else{return null;}}
get offsetNameLong(){if(this.isValid){return this.zone.offsetName(this.ts,{format:"long",locale:this.locale,});}else{return null;}}
get isOffsetFixed(){return this.isValid?this.zone.isUniversal:null;}
get isInDST(){if(this.isOffsetFixed){return false;}else{return(this.offset>this.set({month:1,day:1}).offset||this.offset>this.set({month:5}).offset);}}
getPossibleOffsets(){if(!this.isValid||this.isOffsetFixed){return[this];}
const dayMs=86400000;const minuteMs=60000;const localTS=objToLocalTS(this.c);const oEarlier=this.zone.offset(localTS-dayMs);const oLater=this.zone.offset(localTS+dayMs);const o1=this.zone.offset(localTS-oEarlier*minuteMs);const o2=this.zone.offset(localTS-oLater*minuteMs);if(o1===o2){return[this];}
const ts1=localTS-o1*minuteMs;const ts2=localTS-o2*minuteMs;const c1=tsToObj(ts1,o1);const 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];}
get isInLeapYear(){return isLeapYear(this.year);}
get daysInMonth(){return daysInMonth(this.year,this.month);}
get daysInYear(){return this.isValid?daysInYear(this.year):NaN;}
get weeksInWeekYear(){return this.isValid?weeksInWeekYear(this.weekYear):NaN;}
resolvedLocaleOptions(opts={}){const{locale,numberingSystem,calendar}=Formatter.create(this.loc.clone(opts),opts).resolvedOptions(this);return{locale,numberingSystem,outputCalendar:calendar};}
toUTC(offset=0,opts={}){return this.setZone(FixedOffsetZone.instance(offset),opts);}
toLocal(){return this.setZone(Settings.defaultZone);}
setZone(zone,{keepLocalTime=false,keepCalendarTime=false}={}){zone=normalizeZone(zone,Settings.defaultZone);if(zone.equals(this.zone)){return this;}else if(!zone.isValid){return DateTime.invalid(unsupportedZone(zone));}else{let newTS=this.ts;if(keepLocalTime||keepCalendarTime){const offsetGuess=zone.offset(this.ts);const asObj=this.toObject();[newTS]=objToTS(asObj,offsetGuess,zone);}
return clone(this,{ts:newTS,zone});}}
reconfigure({locale,numberingSystem,outputCalendar}={}){const loc=this.loc.clone({locale,numberingSystem,outputCalendar});return clone(this,{loc});}
setLocale(locale){return this.reconfigure({locale});}
set(values){if(!this.isValid)return this;const normalized=normalizeObject(values,normalizeUnit),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");}
let mixed;if(settingWeekStuff){mixed=weekToGregorian({...gregorianToWeek(this.c),...normalized});}else if(!isUndefined(normalized.ordinal)){mixed=ordinalToGregorian({...gregorianToOrdinal(this.c),...normalized});}else{mixed={...this.toObject(),...normalized};if(isUndefined(normalized.day)){mixed.day=Math.min(daysInMonth(mixed.year,mixed.month),mixed.day);}}
const[ts,o]=objToTS(mixed,this.o,this.zone);return clone(this,{ts,o});}
plus(duration){if(!this.isValid)return this;const dur=Duration.fromDurationLike(duration);return clone(this,adjustTime(this,dur));}
minus(duration){if(!this.isValid)return this;const dur=Duration.fromDurationLike(duration).negate();return clone(this,adjustTime(this,dur));}
startOf(unit){if(!this.isValid)return this;const 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"){o.weekday=1;}
if(normalizedUnit==="quarters"){const q=Math.ceil(this.month/3);o.month=(q-1)*3+1;}
return this.set(o);}
endOf(unit){return this.isValid?this.plus({[unit]:1}).startOf(unit).minus(1):this;}
toFormat(fmt,opts={}){return this.isValid?Formatter.create(this.loc.redefaultToEN(opts)).formatDateTimeFromString(this,fmt):INVALID;}
toLocaleString(formatOpts=DATE_SHORT,opts={}){return this.isValid?Formatter.create(this.loc.clone(opts),formatOpts).formatDateTime(this):INVALID;}
toLocaleParts(opts={}){return this.isValid?Formatter.create(this.loc.clone(opts),opts).formatDateTimeParts(this):[];}
toISO({format="extended",suppressSeconds=false,suppressMilliseconds=false,includeOffset=true,extendedZone=false,}={}){if(!this.isValid){return null;}
const ext=format==="extended";let c=toISODate(this,ext);c+="T";c+=toISOTime(this,ext,suppressSeconds,suppressMilliseconds,includeOffset,extendedZone);return c;}
toISODate({format="extended"}={}){if(!this.isValid){return null;}
return toISODate(this,format==="extended");}
toISOWeekDate(){return toTechFormat(this,"kkkk-'W'WW-c");}
toISOTime({suppressMilliseconds=false,suppressSeconds=false,includeOffset=true,includePrefix=false,extendedZone=false,format="extended",}={}){if(!this.isValid){return null;}
let c=includePrefix?"T":"";return(c+
toISOTime(this,format==="extended",suppressSeconds,suppressMilliseconds,includeOffset,extendedZone));}
toRFC2822(){return toTechFormat(this,"EEE, dd LLL yyyy HH:mm:ss ZZZ",false);}
toHTTP(){return toTechFormat(this.toUTC(),"EEE, dd LLL yyyy HH:mm:ss 'GMT'");}
toSQLDate(){if(!this.isValid){return null;}
return toISODate(this,true);}
toSQLTime({includeOffset=true,includeZone=false,includeOffsetSpace=true}={}){let fmt="HH:mm:ss.SSS";if(includeZone||includeOffset){if(includeOffsetSpace){fmt+=" ";}
if(includeZone){fmt+="z";}else if(includeOffset){fmt+="ZZ";}}
return toTechFormat(this,fmt,true);}
toSQL(opts={}){if(!this.isValid){return null;}
return`${this.toSQLDate()} ${this.toSQLTime(opts)}`;}
toString(){return this.isValid?this.toISO():INVALID;}
valueOf(){return this.toMillis();}
toMillis(){return this.isValid?this.ts:NaN;}
toSeconds(){return this.isValid?this.ts/1000:NaN;}
toUnixInteger(){return this.isValid?Math.floor(this.ts/1000):NaN;}
toJSON(){return this.toISO();}
toBSON(){return this.toJSDate();}
toObject(opts={}){if(!this.isValid)return{};const base={...this.c};if(opts.includeConfig){base.outputCalendar=this.outputCalendar;base.numberingSystem=this.loc.numberingSystem;base.locale=this.loc.locale;}
return base;}
toJSDate(){return new Date(this.isValid?this.ts:NaN);}
diff(otherDateTime,unit="milliseconds",opts={}){if(!this.isValid||!otherDateTime.isValid){return Duration.invalid("created by diffing an invalid DateTime");}
const durOpts={locale:this.locale,numberingSystem:this.numberingSystem,...opts};const units=maybeArray(unit).map(Duration.normalizeUnit),otherIsLater=otherDateTime.valueOf()>this.valueOf(),earlier=otherIsLater?this:otherDateTime,later=otherIsLater?otherDateTime:this,diffed=diff(earlier,later,units,durOpts);return otherIsLater?diffed.negate():diffed;}
diffNow(unit="milliseconds",opts={}){return this.diff(DateTime.now(),unit,opts);}
until(otherDateTime){return this.isValid?Interval.fromDateTimes(this,otherDateTime):this;}
hasSame(otherDateTime,unit){if(!this.isValid)return false;const inputMs=otherDateTime.valueOf();const adjustedToZone=this.setZone(otherDateTime.zone,{keepLocalTime:true});return adjustedToZone.startOf(unit)<=inputMs&&inputMs<=adjustedToZone.endOf(unit);}
equals(other){return(this.isValid&&other.isValid&&this.valueOf()===other.valueOf()&&this.zone.equals(other.zone)&&this.loc.equals(other.loc));}
toRelative(options={}){if(!this.isValid)return null;const base=options.base||DateTime.fromObject({},{zone:this.zone}),padding=options.padding?(this<base?-options.padding:options.padding):0;let units=["years","months","days","hours","minutes","seconds"];let unit=options.unit;if(Array.isArray(options.unit)){units=options.unit;unit=undefined;}
return diffRelative(base,this.plus(padding),{...options,numeric:"always",units,unit,});}
toRelativeCalendar(options={}){if(!this.isValid)return null;return diffRelative(options.base||DateTime.fromObject({},{zone:this.zone}),this,{...options,numeric:"auto",units:["years","months","days"],calendary:true,});}
static min(...dateTimes){if(!dateTimes.every(DateTime.isDateTime)){throw new InvalidArgumentError("min requires all arguments be DateTimes");}
return bestBy(dateTimes,(i)=>i.valueOf(),Math.min);}
static max(...dateTimes){if(!dateTimes.every(DateTime.isDateTime)){throw new InvalidArgumentError("max requires all arguments be DateTimes");}
return bestBy(dateTimes,(i)=>i.valueOf(),Math.max);}
static fromFormatExplain(text,fmt,options={}){const{locale=null,numberingSystem=null}=options,localeToUse=Locale.fromOpts({locale,numberingSystem,defaultToEN:true,});return explainFromTokens(localeToUse,text,fmt);}
static fromStringExplain(text,fmt,options={}){return DateTime.fromFormatExplain(text,fmt,options);}
static get DATE_SHORT(){return DATE_SHORT;}
static get DATE_MED(){return DATE_MED;}
static get DATE_MED_WITH_WEEKDAY(){return DATE_MED_WITH_WEEKDAY;}
static get DATE_FULL(){return DATE_FULL;}
static get DATE_HUGE(){return DATE_HUGE;}
static get TIME_SIMPLE(){return TIME_SIMPLE;}
static get TIME_WITH_SECONDS(){return TIME_WITH_SECONDS;}
static get TIME_WITH_SHORT_OFFSET(){return TIME_WITH_SHORT_OFFSET;}
static get TIME_WITH_LONG_OFFSET(){return TIME_WITH_LONG_OFFSET;}
static get TIME_24_SIMPLE(){return TIME_24_SIMPLE;}
static get TIME_24_WITH_SECONDS(){return TIME_24_WITH_SECONDS;}
static get TIME_24_WITH_SHORT_OFFSET(){return TIME_24_WITH_SHORT_OFFSET;}
static get TIME_24_WITH_LONG_OFFSET(){return TIME_24_WITH_LONG_OFFSET;}
static get DATETIME_SHORT(){return DATETIME_SHORT;}
static get DATETIME_SHORT_WITH_SECONDS(){return DATETIME_SHORT_WITH_SECONDS;}
static get DATETIME_MED(){return DATETIME_MED;}
static get DATETIME_MED_WITH_SECONDS(){return DATETIME_MED_WITH_SECONDS;}
static get DATETIME_MED_WITH_WEEKDAY(){return DATETIME_MED_WITH_WEEKDAY;}
static get DATETIME_FULL(){return DATETIME_FULL;}
static get DATETIME_FULL_WITH_SECONDS(){return DATETIME_FULL_WITH_SECONDS;}
static get DATETIME_HUGE(){return DATETIME_HUGE;}
static get DATETIME_HUGE_WITH_SECONDS(){return DATETIME_HUGE_WITH_SECONDS;}}
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}`);}}
const VERSION="3.4.2";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/module_loader.js */
(function(){"use strict";class ModuleLoader{factories=new Map();jobs=new Set();failed=new Set();modules=new Map();bus=new EventTarget();checkErrorProm=null;define(name,deps,factory){if(typeof name!=="string"){throw new Error(`Invalid name definition: ${name} (should be a string)"`);}
if(!(deps instanceof Array)){throw new Error(`Dependencies should be defined by an array: ${deps}`);}
if(typeof factory!=="function"){throw new Error(`Factory should be defined by a function ${factory}`);}
if(!this.factories.has(name)){this.factories.set(name,{deps,fn:factory,ignoreMissingDeps:globalThis.__odooIgnoreMissingDependencies,});this.addJob(name);this.checkErrorProm||=Promise.resolve().then(()=>{this.checkAndReportErrors();this.checkErrorProm=null;});}}
addJob(name){this.jobs.add(name);this.startModules();}
findJob(){for(const job of this.jobs){if(this.factories.get(job).deps.every((dep)=>this.modules.has(dep))){return job;}}
return null;}
startModules(){let job;while((job=this.findJob())){this.startModule(job);}}
startModule(name){const require=(name)=>this.modules.get(name);this.jobs.delete(name);const factory=this.factories.get(name);let value=null;try{value=factory.fn(require);}catch(error){this.failed.add(name);throw new Error(`Error while loading "${name}":\n${error}`);}
this.modules.set(name,value);this.bus.dispatchEvent(new CustomEvent("module-started",{detail:{moduleName:name,module:value}}));}
findErrors(){const dependencyGraph=new Map();for(const job of this.jobs){dependencyGraph.set(job,this.factories.get(job).deps);}
function visitJobs(jobs,visited=new Set()){for(const job of jobs){const result=visitJob(job,visited);if(result){return result;}}
return null;}
function visitJob(job,visited){if(visited.has(job)){const jobs=Array.from(visited).concat([job]);const index=jobs.indexOf(job);return jobs.slice(index).map((j)=>`"${j}"`).join(" => ");}
const deps=dependencyGraph.get(job);return deps?visitJobs(deps,new Set(visited).add(job)):null;}
const missing=new Set();for(const job of this.jobs){const factory=this.factories.get(job);if(factory.ignoreMissingDeps){continue;}
for(const dep of factory.deps){if(!this.factories.has(dep)){missing.add(dep);}}}
return{failed:[...this.failed],cycle:visitJobs(this.jobs),missing:[...missing],unloaded:[...this.jobs].filter((j)=>!this.factories.get(j).ignoreMissingDeps),};}
async checkAndReportErrors(){const{failed,cycle,missing,unloaded}=this.findErrors();if(!failed.length&&!unloaded.length){return;}
function domReady(cb){if(document.readyState==="complete"){cb();}else{document.addEventListener("DOMContentLoaded",cb);}}
function list(heading,names){const frag=document.createDocumentFragment();if(!names||!names.length){return frag;}
frag.textContent=heading;const ul=document.createElement("ul");for(const el of names){const li=document.createElement("li");li.textContent=el;ul.append(li);}
frag.appendChild(ul);return frag;}
domReady(()=>{while(document.body.childNodes.length){document.body.childNodes[0].remove();}
const container=document.createElement("div");container.className="o_module_error position-fixed w-100 h-100 d-flex align-items-center flex-column bg-white overflow-auto modal";container.style.zIndex="10000";const alert=document.createElement("div");alert.className="alert alert-danger o_error_detail fw-bold m-auto";container.appendChild(alert);alert.appendChild(list("The following modules failed to load because of an error, you may find more information in the devtools console:",failed));alert.appendChild(list("The following modules could not be loaded because they form a dependency cycle:",cycle&&[cycle]));alert.appendChild(list("The following modules are needed by other modules but have not been defined, they may not be present in the correct asset bundle:",missing));alert.appendChild(list("The following modules could not be loaded because they have unmet dependencies, this is a secondary error which is likely caused by one of the above problems:",unloaded));document.body.appendChild(container);});}}
if(!globalThis.odoo){globalThis.odoo={};}
const odoo=globalThis.odoo;if(odoo.debug&&!new URLSearchParams(location.search).has("debug")){odoo.debug="";}
const loader=new ModuleLoader();odoo.define=loader.define.bind(loader);odoo.loader=loader;})();;

/* /web/static/src/session.js */
odoo.define('@web/session',[],function(require){'use strict';let __exports={};const session=__exports.session=odoo.__session_info__||{};delete odoo.__session_info__;return __exports;});;

/* /web/static/src/core/browser/cookie.js */
odoo.define('@web/core/browser/cookie',[],function(require){'use strict';let __exports={};const COOKIE_TTL=24*60*60*365;const cookie=__exports.cookie={get _cookieMonster(){return document.cookie;},set _cookieMonster(value){document.cookie=value;},get(str){const parts=this._cookieMonster.split("; ");for(const part of parts){const[key,value]=part.split(/=(.*)/);if(key===str){return value||"";}}},set(key,value,ttl=COOKIE_TTL){let fullCookie=[];if(value!==undefined){fullCookie.push(`${key}=${value}`);}
fullCookie=fullCookie.concat(["path=/",`max-age=${ttl}`]);this._cookieMonster=fullCookie.join("; ");},delete(key){this.set(key,"kill",0);},};return __exports;});;

/* /web/static/src/legacy/js/core/minimal_dom.js */
odoo.define('@web/legacy/js/core/minimal_dom',[],function(require){'use strict';let __exports={};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,preventDefault,stopPropagation){const stopImmediatePropagation=this&&this.__makeAsyncHandler_stopImmediatePropagation;let pending=false;function _isLocked(){return pending;}
function _lock(){pending=true;}
function _unlock(){pending=false;}
return function(ev){if(preventDefault===true||preventDefault&&preventDefault()){ev.preventDefault();}
if(stopPropagation===true||stopPropagation&&stopPropagation()){ev.stopPropagation();}
if(stopImmediatePropagation===true||stopImmediatePropagation&&stopImmediatePropagation()){ev.stopImmediatePropagation();}
if(_isLocked()){return;}
_lock();const result=fct.apply(this,arguments);Promise.resolve(result).finally(_unlock);return result;};}
__exports.makeButtonHandler=makeButtonHandler;function makeButtonHandler(fct){const preventDefault=this&&this.__makeButtonHandler_preventDefault;const stopPropagation=this&&this.__makeButtonHandler_stopPropagation;const stopImmediatePropagation=this&&this.__makeButtonHandler_stopImmediatePropagation;fct=makeAsyncHandler.call({'__makeAsyncHandler_stopImmediatePropagation':stopImmediatePropagation,},fct,preventDefault,stopPropagation);return function(ev){const result=fct.apply(this,arguments);const buttonEl=ev.target&&ev.target.closest&&ev.target.closest(BUTTON_HANDLER_SELECTOR);if(!(buttonEl instanceof HTMLElement)){return result;}
buttonEl.classList.add('pe-none');Promise.resolve(DEBOUNCE&&new Promise(r=>setTimeout(r,DEBOUNCE))).then(function(){buttonEl.classList.remove('pe-none');const restore=addButtonLoadingEffect(buttonEl);return Promise.resolve(result).then(restore,restore);});return result;};}
__exports.addButtonLoadingEffect=addButtonLoadingEffect;function addButtonLoadingEffect(btnEl){if(!(btnEl instanceof HTMLElement)){return()=>{};}
btnEl.classList.add('o_website_btn_loading','disabled','pe-none');btnEl.disabled=true;const loaderEl=document.createElement('span');loaderEl.classList.add('fa','fa-refresh','fa-spin','me-2');btnEl.prepend(loaderEl);return()=>{btnEl.classList.remove('o_website_btn_loading','disabled','pe-none');btnEl.disabled=false;loaderEl.remove();};}
return __exports;});;

/* /web/static/src/legacy/js/public/lazyloader.js */
odoo.define('@web/legacy/js/public/lazyloader',['@web/legacy/js/core/minimal_dom'],function(require){'use strict';let __exports={};const{BUTTON_HANDLER_SELECTOR,makeAsyncHandler,makeButtonHandler,}=require('@web/legacy/js/core/minimal_dom');let allScriptsLoadedResolve=null;const _allScriptsLoaded=new Promise(resolve=>{allScriptsLoadedResolve=resolve;}).then(stopWaitingLazy);const retriggeringWaitingProms=[];async function waitForLazyAndRetrigger(ev){const targetEl=ev.target;await _allScriptsLoaded;await Promise.all(retriggeringWaitingProms);setTimeout(()=>{if(targetEl.isConnected){targetEl.dispatchEvent(new ev.constructor(ev.type,ev));}},0);}
const loadingEffectHandlers=[];function registerLoadingEffectHandler(el,type,handler){el.addEventListener(type,handler,{capture:true});loadingEffectHandlers.push({el,type,handler});}
let waitingLazy=false;function waitLazy(){if(waitingLazy){return;}
waitingLazy=true;document.body.classList.add('o_lazy_js_waiting');const mainEl=document.getElementById('wrapwrap')||document.body;const loadingEffectButtonEls=[...mainEl.querySelectorAll(BUTTON_HANDLER_SELECTOR)].filter(el=>{return!el.classList.contains('o_no_wait_lazy_js')&&!(el.nodeName==='A'&&el.href&&el.getAttribute('href')!=='#');});const loadingEffectEventTypes=['mouseover','mouseenter','mousedown','mouseup','click','mouseout','mouseleave'];for(const buttonEl of loadingEffectButtonEls){for(const eventType of loadingEffectEventTypes){const loadingEffectHandler=eventType==='click'?makeButtonHandler.call({'__makeButtonHandler_preventDefault':true,'__makeButtonHandler_stopImmediatePropagation':true,},waitForLazyAndRetrigger):makeAsyncHandler.call({'__makeAsyncHandler_stopImmediatePropagation':true,},waitForLazyAndRetrigger,true);registerLoadingEffectHandler(buttonEl,eventType,loadingEffectHandler);}}
for(const formEl of document.querySelectorAll('form:not(.o_no_wait_lazy_js)')){registerLoadingEffectHandler(formEl,'submit',ev=>{ev.preventDefault();ev.stopImmediatePropagation();});}}
function stopWaitingLazy(){if(!waitingLazy){return;}
waitingLazy=false;document.body.classList.remove('o_lazy_js_waiting');for(const{el,type,handler}of loadingEffectHandlers){el.removeEventListener(type,handler,{capture:true});}}
if(document.readyState!=='loading'){waitLazy();}else{document.addEventListener('DOMContentLoaded',function(){waitLazy();});}
if(document.readyState==='complete'){setTimeout(_loadScripts,0);}else{window.addEventListener('load',function(){setTimeout(_loadScripts,0);});}
function _loadScripts(scripts,index){if(scripts===undefined){scripts=document.querySelectorAll('script[data-src]');}
if(index===undefined){index=0;}
if(index>=scripts.length){allScriptsLoadedResolve();return;}
const script=scripts[index];script.addEventListener('load',_loadScripts.bind(this,scripts,index+1));script.setAttribute('defer','defer');script.src=script.dataset.src;script.removeAttribute('data-src');}
__exports[Symbol.for("default")]={loadScripts:_loadScripts,allScriptsLoaded:_allScriptsLoaded,registerPageReadinessDelay:retriggeringWaitingProms.push.bind(retriggeringWaitingProms),};return __exports;});;

/* /web_editor/static/src/js/frontend/loader_loading.js */
(function(){'use strict';document.addEventListener('DOMContentLoaded',()=>{var textareaEls=document.querySelectorAll('textarea.o_wysiwyg_loader');for(var i=0;i<textareaEls.length;i++){var textarea=textareaEls[i];var wrapper=document.createElement('div');wrapper.classList.add('position-relative','o_wysiwyg_textarea_wrapper');var loadingElement=document.createElement('div');loadingElement.classList.add('o_wysiwyg_loading');var loadingIcon=document.createElement('i');loadingIcon.classList.add('text-600','text-center','fa','fa-circle-o-notch','fa-spin','fa-2x');loadingElement.appendChild(loadingIcon);wrapper.appendChild(loadingElement);textarea.parentNode.insertBefore(wrapper,textarea);wrapper.insertBefore(textarea,loadingElement);}});})();;

/* /website/static/src/js/content/inject_dom.js */
odoo.define('@website/js/content/inject_dom',['@web/core/browser/cookie','@web/session'],function(require){'use strict';let __exports={};const{cookie:cookieManager}=require("@web/core/browser/cookie");const{session}=require("@web/session");__exports.unhideConditionalElements=unhideConditionalElements;function unhideConditionalElements(){const styleEl=document.createElement('style');styleEl.id="conditional_visibility";document.head.appendChild(styleEl);const conditionalEls=document.querySelectorAll('[data-visibility="conditional"]');for(const conditionalEl of conditionalEls){const selectors=conditionalEl.dataset.visibilitySelectors;styleEl.sheet.insertRule(`${selectors} { display: none !important; }`);}
for(const conditionalEl of conditionalEls){conditionalEl.classList.remove('o_conditional_hidden');}}
__exports.setUtmsHtmlDataset=setUtmsHtmlDataset;function setUtmsHtmlDataset(){const htmlEl=document.documentElement;const cookieNamesToDataNames={'utm_source':'utmSource','utm_medium':'utmMedium','utm_campaign':'utmCampaign',};for(const[name,dsName]of Object.entries(cookieNamesToDataNames)){const cookie=cookieManager.get(`odoo_${name}`);if(cookie){htmlEl.dataset[dsName]=cookie.replace(/(^["']|["']$)/g,'');}}}
document.addEventListener('DOMContentLoaded',()=>{setUtmsHtmlDataset();const htmlEl=document.documentElement;const country=session.geoip_country_code;if(country){htmlEl.dataset.country=country;}
htmlEl.dataset.logged=!session.is_website_user;unhideConditionalElements();});return __exports;});;

/* /website/static/src/js/content/auto_hide_menu.js */
odoo.define('@website/js/content/auto_hide_menu',[],function(require){'use strict';let __exports={};const BREAKPOINT_SIZES={sm:'575',md:'767',lg:'991',xl:'1199',xxl:'1399'};async function autoHideMenu(el,options){if(!el){return;}
const navbar=el.closest('.navbar');const[breakpoint='md']=navbar?Object.keys(BREAKPOINT_SIZES).filter(suffix=>navbar.classList.contains(`navbar-expand-${suffix}`)):[];const isNoHamburgerMenu=!!navbar&&navbar.classList.contains('navbar-expand');const minSize=BREAKPOINT_SIZES[breakpoint];let isExtraMenuOpen=false;options=Object.assign({unfoldable:'none',images:[],loadingStyleClasses:[],autoClose:()=>true,},options||{});const isUserNavbar=el.parentElement.classList.contains('o_main_navbar');const dropdownSubMenuClasses=['show','border-0','position-static'];const dropdownToggleClasses=['h-auto','py-2','text-secondary'];const autoMarginLeftRegex=/\bm[sx]?(?:-(?:sm|md|lg|xl|xxl))?-auto\b/;const autoMarginRightRegex=/\bm[ex]?(?:-(?:sm|md|lg|xl|xxl))?-auto\b/;var extraItemsToggle=null;const afterFontsloading=new Promise((resolve)=>{if(document.fonts){document.fonts.ready.then(resolve);}else{setTimeout(resolve,150);}});afterFontsloading.then(_adapt);if(options.images.length){await _afterImagesLoading(options.images);_adapt();}
let pending=false;let refreshId=null;const onRefresh=()=>{if(pending){refreshId=window.requestAnimationFrame(onRefresh);_adapt();pending=false;}else{refreshId=null;}};const throttleAdapt=()=>{if(refreshId===null){refreshId=window.requestAnimationFrame(onRefresh);_adapt();}else{pending=true;}};window.addEventListener('resize',throttleAdapt);function _restore(){if(!extraItemsToggle){return;}
[...extraItemsToggle.querySelector('.dropdown-menu').children].forEach((item)=>{if(!isUserNavbar){item.classList.add('nav-item');const itemLink=item.querySelector('.dropdown-item');if(itemLink){itemLink.classList.remove('dropdown-item');itemLink.classList.add('nav-link');}}else{item.classList.remove('dropdown-item');const dropdownSubMenu=item.querySelector('.dropdown-menu');const dropdownSubMenuButton=item.querySelector('.dropdown-toggle');if(dropdownSubMenu){dropdownSubMenu.classList.remove(...dropdownSubMenuClasses);}
if(dropdownSubMenuButton){dropdownSubMenuButton.classList.remove(...dropdownToggleClasses);}}
el.insertBefore(item,extraItemsToggle);});extraItemsToggle.remove();extraItemsToggle=null;}
function _adapt(){const wysiwyg=window.$&&$('#wrapwrap').data('wysiwyg');const odooEditor=wysiwyg&&wysiwyg.odooEditor;if(odooEditor){odooEditor.observerUnactive("adapt");odooEditor.withoutRollback(__adapt);odooEditor.observerActive("adapt");return;}
__adapt();}
function __adapt(){if(options.loadingStyleClasses.length){el.classList.add(...options.loadingStyleClasses);}
const extraMenuEl=_getExtraMenuEl();isExtraMenuOpen=extraMenuEl&&extraMenuEl.classList.contains("show");_restore();if(!el.getClientRects().length||el.closest('.show')||(window.matchMedia(`(max-width: ${minSize}px)`).matches&&!isNoHamburgerMenu)){return _endAutoMoreMenu();}
let unfoldableItems=[];const items=[...el.children].filter((node)=>{if(node.matches&&!node.matches(options.unfoldable)){return true;}
unfoldableItems.push(node);return false;});var nbItems=items.length;var menuItemsWidth=items.reduce((sum,el)=>sum+computeFloatOuterWidthWithMargins(el,true,true,false),0);let maxWidth=0;if(!maxWidth){maxWidth=computeFloatOuterWidthWithMargins(el,true,true,true);var style=window.getComputedStyle(el);maxWidth-=(parseFloat(style.paddingLeft)+parseFloat(style.paddingRight)+parseFloat(style.borderLeftWidth)+parseFloat(style.borderRightWidth));maxWidth-=unfoldableItems.reduce((sum,el)=>sum+computeFloatOuterWidthWithMargins(el,true,true,false),0);}
if(maxWidth-menuItemsWidth>=-0.001){return _endAutoMoreMenu();}
const dropdownMenu=_addExtraItemsButton(items[nbItems-1].nextElementSibling);menuItemsWidth+=computeFloatOuterWidthWithMargins(extraItemsToggle,true,true,false);do{menuItemsWidth-=computeFloatOuterWidthWithMargins(items[--nbItems],true,true,false);}while(!(maxWidth-menuItemsWidth>=-0.001)&&(nbItems>0));const extraItems=items.slice(nbItems);extraItems.forEach((el)=>{if(!isUserNavbar){const navLink=el.querySelector('.nav-link, a');el.classList.remove('nav-item');if(navLink){navLink.classList.remove('nav-link');navLink.classList.add('dropdown-item');navLink.classList.toggle('active',el.classList.contains('active'));}}else{const dropdownSubMenu=el.querySelector('.dropdown-menu');const dropdownSubMenuButton=el.querySelector('.dropdown-toggle');el.classList.add('dropdown-item','p-0');if(dropdownSubMenu){dropdownSubMenu.classList.add(...dropdownSubMenuClasses);}
if(dropdownSubMenuButton){dropdownSubMenuButton.classList.add(...dropdownToggleClasses);}}
dropdownMenu.appendChild(el);});_endAutoMoreMenu();}
function computeFloatOuterWidthWithMargins(el,mLeft,mRight,considerAutoMargins){var rect=el.getBoundingClientRect();var style=window.getComputedStyle(el);var outerWidth=rect.right-rect.left;const isRTL=style.direction==='rtl';if(mLeft!==false&&(considerAutoMargins||!(isRTL?autoMarginRightRegex:autoMarginLeftRegex).test(el.getAttribute('class')))){outerWidth+=parseFloat(style.marginLeft);}
if(mRight!==false&&(considerAutoMargins||!(isRTL?autoMarginLeftRegex:autoMarginRightRegex).test(el.getAttribute('class')))){outerWidth+=parseFloat(style.marginRight);}
return isNaN(outerWidth)?0:outerWidth;}
function _addExtraItemsButton(target){let dropdownMenu=document.createElement('div');extraItemsToggle=dropdownMenu.cloneNode();const extraItemsToggleIcon=document.createElement('i');const extraItemsToggleLink=document.createElement('a');dropdownMenu.className='dropdown-menu';extraItemsToggle.className='nav-item dropdown o_extra_menu_items';extraItemsToggle.setAttribute("role","presentation");extraItemsToggleIcon.className='fa fa-plus';const extraItemsToggleAriaLabel=el.closest("[data-extra-items-toggle-aria-label]")?.dataset.extraItemsToggleAriaLabel;Object.entries({role:'menuitem',href:'#',class:'nav-link dropdown-toggle o-no-caret','data-bs-toggle':'dropdown','aria-expanded':false,'aria-label':extraItemsToggleAriaLabel||" ",}).forEach(([key,value])=>{extraItemsToggleLink.setAttribute(key,value);});extraItemsToggleLink.appendChild(extraItemsToggleIcon);extraItemsToggle.appendChild(extraItemsToggleLink);extraItemsToggle.appendChild(dropdownMenu);el.insertBefore(extraItemsToggle,target);if(!options.autoClose()){extraItemsToggleLink.setAttribute("data-bs-auto-close","outside");}
return dropdownMenu;}
function _afterImagesLoading(images){const defs=images.map((image)=>{if(image.complete||!image.getClientRects().length){return null;}
return new Promise(function(resolve,reject){if(!image.width){image.classList.add('o_menu_image_placeholder');}
image.addEventListener('load',()=>{image.classList.remove('o_menu_image_placeholder');resolve();});});});return Promise.all(defs);}
function _getExtraMenuEl(){return el.querySelector(".o_extra_menu_items .dropdown-toggle");}
function _endAutoMoreMenu(){const extraMenuEl=_getExtraMenuEl();if(extraMenuEl&&isExtraMenuOpen){extraMenuEl.click();}
el.classList.remove(...options.loadingStyleClasses);}}
document.addEventListener('DOMContentLoaded',async()=>{const header=document.querySelector('header#top');if(header){const topMenu=header.querySelector("#top_menu, .top_menu");if(header.classList.contains('o_no_autohide_menu')){topMenu.classList.remove('o_menu_loading');return;}
const unfoldable='.divider, .divider ~ li, .o_no_autohide_item, .js_language_selector';const excludedImagesSelector='.o_mega_menu, .o_offcanvas_logo_container, .o_lang_flag';const excludedImages=[...header.querySelectorAll(excludedImagesSelector)];const images=[...header.querySelectorAll('img')].filter((img)=>{excludedImages.forEach(node=>{if(node.contains(img)){return false;}});return img.matches&&!img.matches(excludedImagesSelector);});autoHideMenu(topMenu,{unfoldable:unfoldable,images:images,loadingStyleClasses:['o_menu_loading'],autoClose:()=>!document.body.classList.contains("editor_enable"),});}});return __exports;});;

/* /website/static/src/js/content/redirect.js */
odoo.define('@website/js/content/redirect',['@web/session'],function(require){'use strict';let __exports={};const{session}=require('@web/session');document.addEventListener('DOMContentLoaded',()=>{if(session.is_website_user){return;}
if(!window.frameElement){const frontendToBackendNavEl=document.querySelector('.o_frontend_to_backend_nav');if(frontendToBackendNavEl){frontendToBackendNavEl.classList.add('d-flex');frontendToBackendNavEl.classList.remove('d-none');}
const currentUrl=new URL(window.location.href);currentUrl.pathname=`/@${currentUrl.pathname}`;if(currentUrl.searchParams.get('enable_editor')||currentUrl.searchParams.get('edit_translations')){document.body.innerHTML='';window.location.replace(currentUrl.href);return;}
const backendEditBtnEl=document.querySelector('.o_frontend_to_backend_edit_btn');if(backendEditBtnEl){backendEditBtnEl.href=currentUrl.href;document.addEventListener("keydown",ev=>{if(ev.key==="a"&&ev.altKey){currentUrl.searchParams.set('enable_editor',1);window.location.replace(currentUrl.href);}},true);}}else{const backendUserDropdownLinkEl=document.getElementById('o_backend_user_dropdown_link');if(backendUserDropdownLinkEl){backendUserDropdownLinkEl.classList.add('d-none');backendUserDropdownLinkEl.classList.remove('d-flex');}
window.frameElement.dispatchEvent(new CustomEvent('OdooFrameContentLoaded'));}});return __exports;});;

/* /website/static/src/js/content/adapt_content.js */
odoo.define('@website/js/content/adapt_content',[],function(require){'use strict';let __exports={};document.addEventListener('DOMContentLoaded',()=>{const htmlEl=document.documentElement;const editTranslations=!!htmlEl.dataset.edit_translations;if(editTranslations){[...document.querySelectorAll('textarea')].map(textarea=>{if(textarea.value.indexOf('data-oe-translation-initial-sha')!==-1){textarea.classList.add('o_text_content_invisible');}});}
const searchModalEl=document.querySelector("header#top .modal#o_search_modal");if(searchModalEl){const mainEl=document.querySelector("main");const searchDivEl=document.createElement('div');searchDivEl.id="o_search_modal_block";searchDivEl.appendChild(searchModalEl);mainEl.appendChild(searchDivEl);}});return __exports;});;

/* /web/static/lib/owl/owl.js */
(function(exports){'use strict';function filterOutModifiersFromData(dataList){dataList=dataList.slice();const modifiers=[];let elm;while((elm=dataList[0])&&typeof elm==="string"){modifiers.push(dataList.shift());}
return{modifiers,data:dataList};}
const config={shouldNormalizeDom:true,mainEventHandler:(data,ev,currentTarget)=>{if(typeof data==="function"){data(ev);}
else if(Array.isArray(data)){data=filterOutModifiersFromData(data).data;data[0](data[1],ev);}
return false;},};class VToggler{constructor(key,child){this.key=key;this.child=child;}
mount(parent,afterNode){this.parentEl=parent;this.child.mount(parent,afterNode);}
moveBeforeDOMNode(node,parent){this.child.moveBeforeDOMNode(node,parent);}
moveBeforeVNode(other,afterNode){this.moveBeforeDOMNode((other&&other.firstNode())||afterNode);}
patch(other,withBeforeRemove){if(this===other){return;}
let child1=this.child;let child2=other.child;if(this.key===other.key){child1.patch(child2,withBeforeRemove);}
else{child2.mount(this.parentEl,child1.firstNode());if(withBeforeRemove){child1.beforeRemove();}
child1.remove();this.child=child2;this.key=other.key;}}
beforeRemove(){this.child.beforeRemove();}
remove(){this.child.remove();}
firstNode(){return this.child.firstNode();}
toString(){return this.child.toString();}}
function toggler(key,child){return new VToggler(key,child);}
class OwlError extends Error{}
const{setAttribute:elemSetAttribute,removeAttribute}=Element.prototype;const tokenList=DOMTokenList.prototype;const tokenListAdd=tokenList.add;const tokenListRemove=tokenList.remove;const isArray=Array.isArray;const{split,trim}=String.prototype;const wordRegexp=/\s+/;function setAttribute(key,value){switch(value){case false:case undefined:removeAttribute.call(this,key);break;case true:elemSetAttribute.call(this,key,"");break;default:elemSetAttribute.call(this,key,value);}}
function createAttrUpdater(attr){return function(value){setAttribute.call(this,attr,value);};}
function attrsSetter(attrs){if(isArray(attrs)){if(attrs[0]==="class"){setClass.call(this,attrs[1]);}
else{setAttribute.call(this,attrs[0],attrs[1]);}}
else{for(let k in attrs){if(k==="class"){setClass.call(this,attrs[k]);}
else{setAttribute.call(this,k,attrs[k]);}}}}
function attrsUpdater(attrs,oldAttrs){if(isArray(attrs)){const name=attrs[0];const val=attrs[1];if(name===oldAttrs[0]){if(val===oldAttrs[1]){return;}
if(name==="class"){updateClass.call(this,val,oldAttrs[1]);}
else{setAttribute.call(this,name,val);}}
else{removeAttribute.call(this,oldAttrs[0]);setAttribute.call(this,name,val);}}
else{for(let k in oldAttrs){if(!(k in attrs)){if(k==="class"){updateClass.call(this,"",oldAttrs[k]);}
else{removeAttribute.call(this,k);}}}
for(let k in attrs){const val=attrs[k];if(val!==oldAttrs[k]){if(k==="class"){updateClass.call(this,val,oldAttrs[k]);}
else{setAttribute.call(this,k,val);}}}}}
function toClassObj(expr){const result={};switch(typeof expr){case"string":const str=trim.call(expr);if(!str){return{};}
let words=split.call(str,wordRegexp);for(let i=0,l=words.length;i<l;i++){result[words[i]]=true;}
return result;case"object":for(let key in expr){const value=expr[key];if(value){key=trim.call(key);if(!key){continue;}
const words=split.call(key,wordRegexp);for(let word of words){result[word]=value;}}}
return result;case"undefined":return{};case"number":return{[expr]:true};default:return{[expr]:true};}}
function setClass(val){val=val===""?{}:toClassObj(val);const cl=this.classList;for(let c in val){tokenListAdd.call(cl,c);}}
function updateClass(val,oldVal){oldVal=oldVal===""?{}:toClassObj(oldVal);val=val===""?{}:toClassObj(val);const cl=this.classList;for(let c in oldVal){if(!(c in val)){tokenListRemove.call(cl,c);}}
for(let c in val){if(!(c in oldVal)){tokenListAdd.call(cl,c);}}}
function batched(callback){let scheduled=false;return async(...args)=>{if(!scheduled){scheduled=true;await Promise.resolve();scheduled=false;callback(...args);}};}
function inOwnerDocument(el){if(!el){return false;}
if(el.ownerDocument.contains(el)){return true;}
const rootNode=el.getRootNode();return rootNode instanceof ShadowRoot&&el.ownerDocument.contains(rootNode.host);}
function validateTarget(target){const document=target&&target.ownerDocument;if(document){const HTMLElement=document.defaultView.HTMLElement;if(target instanceof HTMLElement||target instanceof ShadowRoot){if(!document.body.contains(target instanceof HTMLElement?target:target.host)){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 markup(value){return new Markup(value);}
function createEventHandler(rawEvent){const eventName=rawEvent.split(".")[0];const capture=rawEvent.includes(".capture");if(rawEvent.includes(".synthetic")){return createSyntheticHandler(eventName,capture);}
else{return createElementHandler(eventName,capture);}}
let nextNativeEventId=1;function createElementHandler(evName,capture=false){let eventKey=`__event__${evName}_${nextNativeEventId++}`;if(capture){eventKey=`${eventKey}_capture`;}
function listener(ev){const currentTarget=ev.currentTarget;if(!currentTarget||!inOwnerDocument(currentTarget))
return;const data=currentTarget[eventKey];if(!data)
return;config.mainEventHandler(data,ev,currentTarget);}
function setup(data){this[eventKey]=data;this.addEventListener(evName,listener,{capture});}
function remove(){delete this[eventKey];this.removeEventListener(evName,listener,{capture});}
function update(data){this[eventKey]=data;}
return{setup,update,remove};}
let nextSyntheticEventId=1;function createSyntheticHandler(evName,capture=false){let eventKey=`__event__synthetic_${evName}`;if(capture){eventKey=`${eventKey}_capture`;}
setupSyntheticEvent(evName,eventKey,capture);const currentId=nextSyntheticEventId++;function setup(data){const _data=this[eventKey]||{};_data[currentId]=data;this[eventKey]=_data;}
function remove(){delete this[eventKey];}
return{setup,update:setup,remove};}
function nativeToSyntheticEvent(eventKey,event){let dom=event.target;while(dom!==null){const _data=dom[eventKey];if(_data){for(const data of Object.values(_data)){const stopped=config.mainEventHandler(data,event,dom);if(stopped)
return;}}
dom=dom.parentNode;}}
const CONFIGURED_SYNTHETIC_EVENTS={};function setupSyntheticEvent(evName,eventKey,capture=false){if(CONFIGURED_SYNTHETIC_EVENTS[eventKey]){return;}
document.addEventListener(evName,(event)=>nativeToSyntheticEvent(eventKey,event),{capture,});CONFIGURED_SYNTHETIC_EVENTS[eventKey]=true;}
const getDescriptor$3=(o,p)=>Object.getOwnPropertyDescriptor(o,p);const nodeProto$4=Node.prototype;const nodeInsertBefore$3=nodeProto$4.insertBefore;const nodeSetTextContent$1=getDescriptor$3(nodeProto$4,"textContent").set;const nodeRemoveChild$3=nodeProto$4.removeChild;class VMulti{constructor(children){this.children=children;}
mount(parent,afterNode){const children=this.children;const l=children.length;const anchors=new Array(l);for(let i=0;i<l;i++){let child=children[i];if(child){child.mount(parent,afterNode);}
else{const childAnchor=document.createTextNode("");anchors[i]=childAnchor;nodeInsertBefore$3.call(parent,childAnchor,afterNode);}}
this.anchors=anchors;this.parentEl=parent;}
moveBeforeDOMNode(node,parent=this.parentEl){this.parentEl=parent;const children=this.children;const anchors=this.anchors;for(let i=0,l=children.length;i<l;i++){let child=children[i];if(child){child.moveBeforeDOMNode(node,parent);}
else{const anchor=anchors[i];nodeInsertBefore$3.call(parent,anchor,node);}}}
moveBeforeVNode(other,afterNode){if(other){const next=other.children[0];afterNode=(next?next.firstNode():other.anchors[0])||null;}
const children=this.children;const parent=this.parentEl;const anchors=this.anchors;for(let i=0,l=children.length;i<l;i++){let child=children[i];if(child){child.moveBeforeVNode(null,afterNode);}
else{const anchor=anchors[i];nodeInsertBefore$3.call(parent,anchor,afterNode);}}}
patch(other,withBeforeRemove){if(this===other){return;}
const children1=this.children;const children2=other.children;const anchors=this.anchors;const parentEl=this.parentEl;for(let i=0,l=children1.length;i<l;i++){const vn1=children1[i];const vn2=children2[i];if(vn1){if(vn2){vn1.patch(vn2,withBeforeRemove);}
else{const afterNode=vn1.firstNode();const anchor=document.createTextNode("");anchors[i]=anchor;nodeInsertBefore$3.call(parentEl,anchor,afterNode);if(withBeforeRemove){vn1.beforeRemove();}
vn1.remove();children1[i]=undefined;}}
else if(vn2){children1[i]=vn2;const anchor=anchors[i];vn2.mount(parentEl,anchor);nodeRemoveChild$3.call(parentEl,anchor);}}}
beforeRemove(){const children=this.children;for(let i=0,l=children.length;i<l;i++){const child=children[i];if(child){child.beforeRemove();}}}
remove(){const parentEl=this.parentEl;if(this.isOnlyChild){nodeSetTextContent$1.call(parentEl,"");}
else{const children=this.children;const anchors=this.anchors;for(let i=0,l=children.length;i<l;i++){const child=children[i];if(child){child.remove();}
else{nodeRemoveChild$3.call(parentEl,anchors[i]);}}}}
firstNode(){const child=this.children[0];return child?child.firstNode():this.anchors[0];}
toString(){return this.children.map((c)=>(c?c.toString():"")).join("");}}
function multi(children){return new VMulti(children);}
const getDescriptor$2=(o,p)=>Object.getOwnPropertyDescriptor(o,p);const nodeProto$3=Node.prototype;const characterDataProto$1=CharacterData.prototype;const nodeInsertBefore$2=nodeProto$3.insertBefore;const characterDataSetData$1=getDescriptor$2(characterDataProto$1,"data").set;const nodeRemoveChild$2=nodeProto$3.removeChild;class VSimpleNode{constructor(text){this.text=text;}
mountNode(node,parent,afterNode){this.parentEl=parent;nodeInsertBefore$2.call(parent,node,afterNode);this.el=node;}
moveBeforeDOMNode(node,parent=this.parentEl){this.parentEl=parent;nodeInsertBefore$2.call(parent,this.el,node);}
moveBeforeVNode(other,afterNode){nodeInsertBefore$2.call(this.parentEl,this.el,other?other.el:afterNode);}
beforeRemove(){}
remove(){nodeRemoveChild$2.call(this.parentEl,this.el);}
firstNode(){return this.el;}
toString(){return this.text;}}
class VText$1 extends VSimpleNode{mount(parent,afterNode){this.mountNode(document.createTextNode(toText(this.text)),parent,afterNode);}
patch(other){const text2=other.text;if(this.text!==text2){characterDataSetData$1.call(this.el,toText(text2));this.text=text2;}}}
class VComment extends VSimpleNode{mount(parent,afterNode){this.mountNode(document.createComment(toText(this.text)),parent,afterNode);}
patch(){}}
function text(str){return new VText$1(str);}
function comment(str){return new VComment(str);}
function toText(value){switch(typeof value){case"string":return value;case"number":return String(value);case"boolean":return value?"true":"false";default:return value||"";}}
const getDescriptor$1=(o,p)=>Object.getOwnPropertyDescriptor(o,p);const nodeProto$2=Node.prototype;const elementProto=Element.prototype;const characterDataProto=CharacterData.prototype;const characterDataSetData=getDescriptor$1(characterDataProto,"data").set;const nodeGetFirstChild=getDescriptor$1(nodeProto$2,"firstChild").get;const nodeGetNextSibling=getDescriptor$1(nodeProto$2,"nextSibling").get;const NO_OP=()=>{};function makePropSetter(name){return function setProp(value){this[name]=value===0?0:value?value.valueOf():"";};}
const cache$1={};function createBlock(str){if(str in cache$1){return cache$1[str];}
const doc=new DOMParser().parseFromString(`<t>${str}</t>`,"text/xml");const node=doc.firstChild.firstChild;if(config.shouldNormalizeDom){normalizeNode(node);}
const tree=buildTree(node);const context=buildContext(tree);const template=tree.el;const Block=buildBlock(template,context);cache$1[str]=Block;return Block;}
function normalizeNode(node){if(node.nodeType===Node.TEXT_NODE){if(!/\S/.test(node.textContent)){node.remove();return;}}
if(node.nodeType===Node.ELEMENT_NODE){if(node.tagName==="pre"){return;}}
for(let i=node.childNodes.length-1;i>=0;--i){normalizeNode(node.childNodes.item(i));}}
function buildTree(node,parent=null,domParentTree=null){switch(node.nodeType){case Node.ELEMENT_NODE:{let currentNS=domParentTree&&domParentTree.currentNS;const tagName=node.tagName;let el=undefined;const info=[];if(tagName.startsWith("block-text-")){const index=parseInt(tagName.slice(11),10);info.push({type:"text",idx:index});el=document.createTextNode("");}
if(tagName.startsWith("block-child-")){if(!domParentTree.isRef){addRef(domParentTree);}
const index=parseInt(tagName.slice(12),10);info.push({type:"child",idx:index});el=document.createTextNode("");}
currentNS||(currentNS=node.namespaceURI);if(!el){el=currentNS?document.createElementNS(currentNS,tagName):document.createElement(tagName);}
if(el instanceof Element){if(!domParentTree){const fragment=document.createElement("template").content;fragment.appendChild(el);}
const attrs=node.attributes;for(let i=0;i<attrs.length;i++){const attrName=attrs[i].name;const attrValue=attrs[i].value;if(attrName.startsWith("block-handler-")){const idx=parseInt(attrName.slice(14),10);info.push({type:"handler",idx,event:attrValue,});}
else if(attrName.startsWith("block-attribute-")){const idx=parseInt(attrName.slice(16),10);info.push({type:"attribute",idx,name:attrValue,tag:tagName,});}
else if(attrName.startsWith("block-property-")){const idx=parseInt(attrName.slice(15),10);info.push({type:"property",idx,name:attrValue,tag:tagName,});}
else if(attrName==="block-attributes"){info.push({type:"attributes",idx:parseInt(attrValue,10),});}
else if(attrName==="block-ref"){info.push({type:"ref",idx:parseInt(attrValue,10),});}
else{el.setAttribute(attrs[i].name,attrValue);}}}
const tree={parent,firstChild:null,nextSibling:null,el,info,refN:0,currentNS,};if(node.firstChild){const childNode=node.childNodes[0];if(node.childNodes.length===1&&childNode.nodeType===Node.ELEMENT_NODE&&childNode.tagName.startsWith("block-child-")){const tagName=childNode.tagName;const index=parseInt(tagName.slice(12),10);info.push({idx:index,type:"child",isOnlyChild:true});}
else{tree.firstChild=buildTree(node.firstChild,tree,tree);el.appendChild(tree.firstChild.el);let curNode=node.firstChild;let curTree=tree.firstChild;while((curNode=curNode.nextSibling)){curTree.nextSibling=buildTree(curNode,curTree,tree);el.appendChild(curTree.nextSibling.el);curTree=curTree.nextSibling;}}}
if(tree.info.length){addRef(tree);}
return tree;}
case Node.TEXT_NODE:case Node.COMMENT_NODE:{const el=node.nodeType===Node.TEXT_NODE?document.createTextNode(node.textContent):document.createComment(node.textContent);return{parent:parent,firstChild:null,nextSibling:null,el,info:[],refN:0,currentNS:null,};}}
throw new OwlError("boom");}
function addRef(tree){tree.isRef=true;do{tree.refN++;}while((tree=tree.parent));}
function parentTree(tree){let parent=tree.parent;while(parent&&parent.nextSibling===tree){tree=parent;parent=parent.parent;}
return parent;}
function buildContext(tree,ctx,fromIdx){if(!ctx){const children=new Array(tree.info.filter((v)=>v.type==="child").length);ctx={collectors:[],locations:[],children,cbRefs:[],refN:tree.refN,refList:[]};fromIdx=0;}
if(tree.refN){const initialIdx=fromIdx;const isRef=tree.isRef;const firstChild=tree.firstChild?tree.firstChild.refN:0;const nextSibling=tree.nextSibling?tree.nextSibling.refN:0;if(isRef){for(let info of tree.info){info.refIdx=initialIdx;}
tree.refIdx=initialIdx;updateCtx(ctx,tree);fromIdx++;}
if(nextSibling){const idx=fromIdx+firstChild;ctx.collectors.push({idx,prevIdx:initialIdx,getVal:nodeGetNextSibling});buildContext(tree.nextSibling,ctx,idx);}
if(firstChild){ctx.collectors.push({idx:fromIdx,prevIdx:initialIdx,getVal:nodeGetFirstChild});buildContext(tree.firstChild,ctx,fromIdx);}}
return ctx;}
function updateCtx(ctx,tree){for(let info of tree.info){switch(info.type){case"text":ctx.locations.push({idx:info.idx,refIdx:info.refIdx,setData:setText,updateData:setText,});break;case"child":if(info.isOnlyChild){ctx.children[info.idx]={parentRefIdx:info.refIdx,isOnlyChild:true,};}
else{ctx.children[info.idx]={parentRefIdx:parentTree(tree).refIdx,afterRefIdx:info.refIdx,};}
break;case"property":{const refIdx=info.refIdx;const setProp=makePropSetter(info.name);ctx.locations.push({idx:info.idx,refIdx,setData:setProp,updateData:setProp,});break;}
case"attribute":{const refIdx=info.refIdx;let updater;let setter;if(info.name==="class"){setter=setClass;updater=updateClass;}
else{setter=createAttrUpdater(info.name);updater=setter;}
ctx.locations.push({idx:info.idx,refIdx,setData:setter,updateData:updater,});break;}
case"attributes":ctx.locations.push({idx:info.idx,refIdx:info.refIdx,setData:attrsSetter,updateData:attrsUpdater,});break;case"handler":{const{setup,update}=createEventHandler(info.event);ctx.locations.push({idx:info.idx,refIdx:info.refIdx,setData:setup,updateData:update,});break;}
case"ref":const index=ctx.cbRefs.push(info.idx)-1;ctx.locations.push({idx:info.idx,refIdx:info.refIdx,setData:makeRefSetter(index,ctx.refList),updateData:NO_OP,});}}}
function buildBlock(template,ctx){let B=createBlockClass(template,ctx);if(ctx.cbRefs.length){const cbRefs=ctx.cbRefs;const refList=ctx.refList;let cbRefsNumber=cbRefs.length;B=class extends B{mount(parent,afterNode){refList.push(new Array(cbRefsNumber));super.mount(parent,afterNode);for(let cbRef of refList.pop()){cbRef();}}
remove(){super.remove();for(let cbRef of cbRefs){let fn=this.data[cbRef];fn(null);}}};}
if(ctx.children.length){B=class extends B{constructor(data,children){super(data);this.children=children;}};B.prototype.beforeRemove=VMulti.prototype.beforeRemove;return(data,children=[])=>new B(data,children);}
return(data)=>new B(data);}
function createBlockClass(template,ctx){const{refN,collectors,children}=ctx;const colN=collectors.length;ctx.locations.sort((a,b)=>a.idx-b.idx);const locations=ctx.locations.map((loc)=>({refIdx:loc.refIdx,setData:loc.setData,updateData:loc.updateData,}));const locN=locations.length;const childN=children.length;const childrenLocs=children;const isDynamic=refN>0;const nodeCloneNode=nodeProto$2.cloneNode;const nodeInsertBefore=nodeProto$2.insertBefore;const elementRemove=elementProto.remove;class Block{constructor(data){this.data=data;}
beforeRemove(){}
remove(){elementRemove.call(this.el);}
firstNode(){return this.el;}
moveBeforeDOMNode(node,parent=this.parentEl){this.parentEl=parent;nodeInsertBefore.call(parent,this.el,node);}
moveBeforeVNode(other,afterNode){nodeInsertBefore.call(this.parentEl,this.el,other?other.el:afterNode);}
toString(){const div=document.createElement("div");this.mount(div,null);return div.innerHTML;}
mount(parent,afterNode){const el=nodeCloneNode.call(template,true);nodeInsertBefore.call(parent,el,afterNode);this.el=el;this.parentEl=parent;}
patch(other,withBeforeRemove){}}
if(isDynamic){Block.prototype.mount=function mount(parent,afterNode){const el=nodeCloneNode.call(template,true);const refs=new Array(refN);this.refs=refs;refs[0]=el;for(let i=0;i<colN;i++){const w=collectors[i];refs[w.idx]=w.getVal.call(refs[w.prevIdx]);}
if(locN){const data=this.data;for(let i=0;i<locN;i++){const loc=locations[i];loc.setData.call(refs[loc.refIdx],data[i]);}}
nodeInsertBefore.call(parent,el,afterNode);if(childN){const children=this.children;for(let i=0;i<childN;i++){const child=children[i];if(child){const loc=childrenLocs[i];const afterNode=loc.afterRefIdx?refs[loc.afterRefIdx]:null;child.isOnlyChild=loc.isOnlyChild;child.mount(refs[loc.parentRefIdx],afterNode);}}}
this.el=el;this.parentEl=parent;};Block.prototype.patch=function patch(other,withBeforeRemove){if(this===other){return;}
const refs=this.refs;if(locN){const data1=this.data;const data2=other.data;for(let i=0;i<locN;i++){const val1=data1[i];const val2=data2[i];if(val1!==val2){const loc=locations[i];loc.updateData.call(refs[loc.refIdx],val2,val1);}}
this.data=data2;}
if(childN){let children1=this.children;const children2=other.children;for(let i=0;i<childN;i++){const child1=children1[i];const child2=children2[i];if(child1){if(child2){child1.patch(child2,withBeforeRemove);}
else{if(withBeforeRemove){child1.beforeRemove();}
child1.remove();children1[i]=undefined;}}
else if(child2){const loc=childrenLocs[i];const afterNode=loc.afterRefIdx?refs[loc.afterRefIdx]:null;child2.mount(refs[loc.parentRefIdx],afterNode);children1[i]=child2;}}}};}
return Block;}
function setText(value){characterDataSetData.call(this,toText(value));}
function makeRefSetter(index,refs){return function setRef(fn){refs[refs.length-1][index]=()=>fn(this);};}
const getDescriptor=(o,p)=>Object.getOwnPropertyDescriptor(o,p);const nodeProto$1=Node.prototype;const nodeInsertBefore$1=nodeProto$1.insertBefore;const nodeAppendChild=nodeProto$1.appendChild;const nodeRemoveChild$1=nodeProto$1.removeChild;const nodeSetTextContent=getDescriptor(nodeProto$1,"textContent").set;class VList{constructor(children){this.children=children;}
mount(parent,afterNode){const children=this.children;const _anchor=document.createTextNode("");this.anchor=_anchor;nodeInsertBefore$1.call(parent,_anchor,afterNode);const l=children.length;if(l){const mount=children[0].mount;for(let i=0;i<l;i++){mount.call(children[i],parent,_anchor);}}
this.parentEl=parent;}
moveBeforeDOMNode(node,parent=this.parentEl){this.parentEl=parent;const children=this.children;for(let i=0,l=children.length;i<l;i++){children[i].moveBeforeDOMNode(node,parent);}
parent.insertBefore(this.anchor,node);}
moveBeforeVNode(other,afterNode){if(other){const next=other.children[0];afterNode=(next?next.firstNode():other.anchor)||null;}
const children=this.children;for(let i=0,l=children.length;i<l;i++){children[i].moveBeforeVNode(null,afterNode);}
this.parentEl.insertBefore(this.anchor,afterNode);}
patch(other,withBeforeRemove){if(this===other){return;}
const ch1=this.children;const ch2=other.children;if(ch2.length===0&&ch1.length===0){return;}
this.children=ch2;const proto=ch2[0]||ch1[0];const{mount:cMount,patch:cPatch,remove:cRemove,beforeRemove,moveBeforeVNode:cMoveBefore,firstNode:cFirstNode,}=proto;const _anchor=this.anchor;const isOnlyChild=this.isOnlyChild;const parent=this.parentEl;if(ch2.length===0&&isOnlyChild){if(withBeforeRemove){for(let i=0,l=ch1.length;i<l;i++){beforeRemove.call(ch1[i]);}}
nodeSetTextContent.call(parent,"");nodeAppendChild.call(parent,_anchor);return;}
let startIdx1=0;let startIdx2=0;let startVn1=ch1[0];let startVn2=ch2[0];let endIdx1=ch1.length-1;let endIdx2=ch2.length-1;let endVn1=ch1[endIdx1];let endVn2=ch2[endIdx2];let mapping=undefined;while(startIdx1<=endIdx1&&startIdx2<=endIdx2){if(startVn1===null){startVn1=ch1[++startIdx1];continue;}
if(endVn1===null){endVn1=ch1[--endIdx1];continue;}
let startKey1=startVn1.key;let startKey2=startVn2.key;if(startKey1===startKey2){cPatch.call(startVn1,startVn2,withBeforeRemove);ch2[startIdx2]=startVn1;startVn1=ch1[++startIdx1];startVn2=ch2[++startIdx2];continue;}
let endKey1=endVn1.key;let endKey2=endVn2.key;if(endKey1===endKey2){cPatch.call(endVn1,endVn2,withBeforeRemove);ch2[endIdx2]=endVn1;endVn1=ch1[--endIdx1];endVn2=ch2[--endIdx2];continue;}
if(startKey1===endKey2){cPatch.call(startVn1,endVn2,withBeforeRemove);ch2[endIdx2]=startVn1;const nextChild=ch2[endIdx2+1];cMoveBefore.call(startVn1,nextChild,_anchor);startVn1=ch1[++startIdx1];endVn2=ch2[--endIdx2];continue;}
if(endKey1===startKey2){cPatch.call(endVn1,startVn2,withBeforeRemove);ch2[startIdx2]=endVn1;const nextChild=ch1[startIdx1];cMoveBefore.call(endVn1,nextChild,_anchor);endVn1=ch1[--endIdx1];startVn2=ch2[++startIdx2];continue;}
mapping=mapping||createMapping(ch1,startIdx1,endIdx1);let idxInOld=mapping[startKey2];if(idxInOld===undefined){cMount.call(startVn2,parent,cFirstNode.call(startVn1)||null);}
else{const elmToMove=ch1[idxInOld];cMoveBefore.call(elmToMove,startVn1,null);cPatch.call(elmToMove,startVn2,withBeforeRemove);ch2[startIdx2]=elmToMove;ch1[idxInOld]=null;}
startVn2=ch2[++startIdx2];}
if(startIdx1<=endIdx1||startIdx2<=endIdx2){if(startIdx1>endIdx1){const nextChild=ch2[endIdx2+1];const anchor=nextChild?cFirstNode.call(nextChild)||null:_anchor;for(let i=startIdx2;i<=endIdx2;i++){cMount.call(ch2[i],parent,anchor);}}
else{for(let i=startIdx1;i<=endIdx1;i++){let ch=ch1[i];if(ch){if(withBeforeRemove){beforeRemove.call(ch);}
cRemove.call(ch);}}}}}
beforeRemove(){const children=this.children;const l=children.length;if(l){const beforeRemove=children[0].beforeRemove;for(let i=0;i<l;i++){beforeRemove.call(children[i]);}}}
remove(){const{parentEl,anchor}=this;if(this.isOnlyChild){nodeSetTextContent.call(parentEl,"");}
else{const children=this.children;const l=children.length;if(l){const remove=children[0].remove;for(let i=0;i<l;i++){remove.call(children[i]);}}
nodeRemoveChild$1.call(parentEl,anchor);}}
firstNode(){const child=this.children[0];return child?child.firstNode():undefined;}
toString(){return this.children.map((c)=>c.toString()).join("");}}
function list(children){return new VList(children);}
function createMapping(ch1,startIdx1,endIdx2){let mapping={};for(let i=startIdx1;i<=endIdx2;i++){mapping[ch1[i].key]=i;}
return mapping;}
const nodeProto=Node.prototype;const nodeInsertBefore=nodeProto.insertBefore;const nodeRemoveChild=nodeProto.removeChild;class VHtml{constructor(html){this.content=[];this.html=html;}
mount(parent,afterNode){this.parentEl=parent;const template=document.createElement("template");template.innerHTML=this.html;this.content=[...template.content.childNodes];for(let elem of this.content){nodeInsertBefore.call(parent,elem,afterNode);}
if(!this.content.length){const textNode=document.createTextNode("");this.content.push(textNode);nodeInsertBefore.call(parent,textNode,afterNode);}}
moveBeforeDOMNode(node,parent=this.parentEl){this.parentEl=parent;for(let elem of this.content){nodeInsertBefore.call(parent,elem,node);}}
moveBeforeVNode(other,afterNode){const target=other?other.content[0]:afterNode;this.moveBeforeDOMNode(target);}
patch(other){if(this===other){return;}
const html2=other.html;if(this.html!==html2){const parent=this.parentEl;const afterNode=this.content[0];const template=document.createElement("template");template.innerHTML=html2;const content=[...template.content.childNodes];for(let elem of content){nodeInsertBefore.call(parent,elem,afterNode);}
if(!content.length){const textNode=document.createTextNode("");content.push(textNode);nodeInsertBefore.call(parent,textNode,afterNode);}
this.remove();this.content=content;this.html=other.html;}}
beforeRemove(){}
remove(){const parent=this.parentEl;for(let elem of this.content){nodeRemoveChild.call(parent,elem);}}
firstNode(){return this.content[0];}
toString(){return this.html;}}
function html(str){return new VHtml(str);}
function createCatcher(eventsSpec){const n=Object.keys(eventsSpec).length;class VCatcher{constructor(child,handlers){this.handlerFns=[];this.afterNode=null;this.child=child;this.handlerData=handlers;}
mount(parent,afterNode){this.parentEl=parent;this.child.mount(parent,afterNode);this.afterNode=document.createTextNode("");parent.insertBefore(this.afterNode,afterNode);this.wrapHandlerData();for(let name in eventsSpec){const index=eventsSpec[name];const handler=createEventHandler(name);this.handlerFns[index]=handler;handler.setup.call(parent,this.handlerData[index]);}}
wrapHandlerData(){for(let i=0;i<n;i++){let handler=this.handlerData[i];let idx=handler.length-2;let origFn=handler[idx];const self=this;handler[idx]=function(ev){const target=ev.target;let currentNode=self.child.firstNode();const afterNode=self.afterNode;while(currentNode&&currentNode!==afterNode){if(currentNode.contains(target)){return origFn.call(this,ev);}
currentNode=currentNode.nextSibling;}};}}
moveBeforeDOMNode(node,parent=this.parentEl){this.parentEl=parent;this.child.moveBeforeDOMNode(node,parent);parent.insertBefore(this.afterNode,node);}
moveBeforeVNode(other,afterNode){if(other){afterNode=other.firstNode()||afterNode;}
this.child.moveBeforeVNode(other?other.child:null,afterNode);this.parentEl.insertBefore(this.afterNode,afterNode);}
patch(other,withBeforeRemove){if(this===other){return;}
this.handlerData=other.handlerData;this.wrapHandlerData();for(let i=0;i<n;i++){this.handlerFns[i].update.call(this.parentEl,this.handlerData[i]);}
this.child.patch(other.child,withBeforeRemove);}
beforeRemove(){this.child.beforeRemove();}
remove(){for(let i=0;i<n;i++){this.handlerFns[i].remove.call(this.parentEl);}
this.child.remove();this.afterNode.remove();}
firstNode(){return this.child.firstNode();}
toString(){return this.child.toString();}}
return function(child,handlers){return new VCatcher(child,handlers);};}
function mount$1(vnode,fixture,afterNode=null){vnode.mount(fixture,afterNode);}
function patch(vnode1,vnode2,withBeforeRemove=false){vnode1.patch(vnode2,withBeforeRemove);}
function remove(vnode,withBeforeRemove=false){if(withBeforeRemove){vnode.beforeRemove();}
vnode.remove();}
const fibersInError=new WeakMap();const nodeErrorHandlers=new WeakMap();function _handleError(node,error){if(!node){return false;}
const fiber=node.fiber;if(fiber){fibersInError.set(fiber,error);}
const errorHandlers=nodeErrorHandlers.get(node);if(errorHandlers){let handled=false;for(let i=errorHandlers.length-1;i>=0;i--){try{errorHandlers[i](error);handled=true;break;}
catch(e){error=e;}}
if(handled){return true;}}
return _handleError(node.parent,error);}
function handleError(params){let{error}=params;if(!(error instanceof OwlError)){error=Object.assign(new OwlError(`An error occured in the owl lifecycle (see this Error's "cause" property)`),{cause:error});}
const node="node"in params?params.node:params.fiber.node;const fiber="fiber"in params?params.fiber:node.fiber;if(fiber){let current=fiber;do{current.node.fiber=current;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;}
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;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;let mountedFibers=this.mounted;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){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 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){render=batched(node.render.bind(node,false));batchedRenderFunctions.set(node,render);node.willDestroy.push(clearReactivesForCallback.bind(null,render));}
return reactive(state,render);}
class ComponentNode{constructor(C,props,app,parent,parentKey){this.fiber=null;this.bdom=null;this.status=0;this.forceNextRender=false;this.nextProps=null;this.children=Object.create(null);this.refs={};this.willStart=[];this.willUpdateProps=[];this.willUnmount=[];this.mounted=[];this.willPatch=[];this.patched=[];this.willDestroy=[];currentNode=this;this.app=app;this.parent=parent;this.props=props;this.parentKey=parentKey;const defaultProps=C.defaultProps;props=Object.assign({},props);if(defaultProps){applyDefaultProps(props,defaultProps);}
const env=(parent&&parent.childEnv)||app.env;this.childEnv=env;for(const key in props){const prop=props[key];if(prop&&typeof prop==="object"&&targets.has(prop)){props[key]=useState(prop);}}
this.component=new C(props,env,this);const ctx=Object.assign(Object.create(this.component),{this:this.component});this.renderFn=app.getTemplate(C.template).bind(this.component,ctx,this);this.component.setup();currentNode=null;}
mountComponent(target,options){const fiber=new MountFiber(this,target,options);this.app.scheduler.addFiber(fiber);this.initiateRender(fiber);}
async initiateRender(fiber){this.fiber=fiber;if(this.mounted.length){fiber.root.mounted.push(fiber);}
const component=this.component;try{await Promise.all(this.willStart.map((f)=>f.call(component)));}
catch(e){this.app.handleError({node:this,error:e});return;}
if(this.status===0&&this.fiber===fiber){fiber.render();}}
async render(deep){if(this.status>=2){return;}
let current=this.fiber;if(current&&(current.root.locked||current.bdom===true)){await Promise.resolve();current=this.fiber;}
if(current){if(!current.bdom&&!fibersInError.has(current)){if(deep){current.deep=deep;}
return;}
deep=deep||current.deep;}
else if(!this.bdom){return;}
const fiber=makeRootFiber(this);fiber.deep=deep;this.fiber=fiber;this.app.scheduler.addFiber(fiber);await Promise.resolve();if(this.status>=2){return;}
if(this.fiber===fiber&&(current||!fiber.parent)){fiber.render();}}
cancel(){this._cancel();delete this.parent.children[this.parentKey];this.app.scheduler.scheduleDestroy(this);}
_cancel(){this.status=2;const children=this.children;for(let childKey in children){children[childKey]._cancel();}}
destroy(){let shouldRemove=this.status===1;this._destroy();if(shouldRemove){this.bdom.remove();}}
_destroy(){const component=this.component;if(this.status===1){for(let cb of this.willUnmount){cb.call(component);}}
for(let child of Object.values(this.children)){child._destroy();}
if(this.willDestroy.length){try{for(let cb of this.willDestroy){cb.call(component);}}
catch(e){this.app.handleError({error:e,node:this});}}
this.status=3;}
async updateAndRender(props,parentFiber){this.nextProps=props;props=Object.assign({},props);const fiber=makeChildFiber(this,parentFiber);this.fiber=fiber;const component=this.component;const defaultProps=component.constructor.defaultProps;if(defaultProps){applyDefaultProps(props,defaultProps);}
currentNode=this;for(const key in props){const prop=props[key];if(prop&&typeof prop==="object"&&targets.has(prop)){props[key]=useState(prop);}}
currentNode=null;const prom=Promise.all(this.willUpdateProps.map((f)=>f.call(component,props)));await prom;if(fiber!==this.fiber){return;}
component.props=props;fiber.render();const parentRoot=parentFiber.root;if(this.willPatch.length){parentRoot.willPatch.push(fiber);}
if(this.patched.length){parentRoot.patched.push(fiber);}}
updateDom(){if(!this.fiber){return;}
if(this.bdom===this.fiber.bdom){for(let k in this.children){const child=this.children[k];child.updateDom();}}
else{this.bdom.patch(this.fiber.bdom,false);this.fiber.appliedToDom=true;this.fiber=null;}}
setRef(name,el){if(el){this.refs[name]=el;}}
firstNode(){const bdom=this.bdom;return bdom?bdom.firstNode():undefined;}
mount(parent,anchor){const bdom=this.fiber.bdom;this.bdom=bdom;bdom.mount(parent,anchor);this.status=1;this.fiber.appliedToDom=true;this.children=this.fiber.childrenMap;this.fiber=null;}
moveBeforeDOMNode(node,parent){this.bdom.moveBeforeDOMNode(node,parent);}
moveBeforeVNode(other,afterNode){this.bdom.moveBeforeVNode(other?other.bdom:null,afterNode);}
patch(){if(this.fiber&&this.fiber.parent){this._patch();this.props=this.nextProps;}}
_patch(){let hasChildren=false;for(let _k in this.children){hasChildren=true;break;}
const fiber=this.fiber;this.children=fiber.childrenMap;this.bdom.patch(fiber.bdom,hasChildren);fiber.appliedToDom=true;this.fiber=null;}
beforeRemove(){this._destroy();}
remove(){this.bdom.remove();}
get name(){return this.component.constructor.name;}
get subscriptions(){const render=batchedRenderFunctions.get(this);return render?getSubscriptions(render):[];}}
const TIMEOUT=Symbol("timeout");const HOOK_TIMEOUT={onWillStart:3000,onWillUpdateProps:3000,};function wrapError(fn,hookName){const error=new OwlError();const timeoutError=new OwlError();const node=getCurrent();return(...args)=>{const onError=(cause)=>{error.cause=cause;error.message=cause instanceof Error?`The following error occurred in ${hookName}: "${cause.message}"`:`Something that is not an Error was thrown in ${hookName} (see this Error's "cause" property)`;throw error;};let result;try{result=fn(...args);}
catch(cause){onError(cause);}
if(!(result instanceof Promise)){return result;}
const timeout=HOOK_TIMEOUT[hookName];if(timeout){const fiber=node.fiber;Promise.race([result.catch(()=>{}),new Promise((resolve)=>setTimeout(()=>resolve(TIMEOUT),timeout)),]).then((res)=>{if(res===TIMEOUT&&node.fiber===fiber&&node.status<=2){timeoutError.message=`${hookName}'s promise hasn't resolved after ${timeout / 1000} seconds`;console.log(timeoutError);}});}
return result.catch(onError);};}
function onWillStart(fn){const node=getCurrent();const decorate=node.app.dev?wrapError:(fn)=>fn;node.willStart.push(decorate(fn.bind(node.component),"onWillStart"));}
function onWillUpdateProps(fn){const node=getCurrent();const decorate=node.app.dev?wrapError:(fn)=>fn;node.willUpdateProps.push(decorate(fn.bind(node.component),"onWillUpdateProps"));}
function onMounted(fn){const node=getCurrent();const decorate=node.app.dev?wrapError:(fn)=>fn;node.mounted.push(decorate(fn.bind(node.component),"onMounted"));}
function onWillPatch(fn){const node=getCurrent();const decorate=node.app.dev?wrapError:(fn)=>fn;node.willPatch.unshift(decorate(fn.bind(node.component),"onWillPatch"));}
function onPatched(fn){const node=getCurrent();const decorate=node.app.dev?wrapError:(fn)=>fn;node.patched.push(decorate(fn.bind(node.component),"onPatched"));}
function onWillUnmount(fn){const node=getCurrent();const decorate=node.app.dev?wrapError:(fn)=>fn;node.willUnmount.unshift(decorate(fn.bind(node.component),"onWillUnmount"));}
function onWillDestroy(fn){const node=getCurrent();const decorate=node.app.dev?wrapError:(fn)=>fn;node.willDestroy.push(decorate(fn.bind(node.component),"onWillDestroy"));}
function onWillRender(fn){const node=getCurrent();const renderFn=node.renderFn;const decorate=node.app.dev?wrapError:(fn)=>fn;fn=decorate(fn.bind(node.component),"onWillRender");node.renderFn=()=>{fn();return renderFn();};}
function onRendered(fn){const node=getCurrent();const renderFn=node.renderFn;const decorate=node.app.dev?wrapError:(fn)=>fn;fn=decorate(fn.bind(node.component),"onRendered");node.renderFn=()=>{const result=renderFn();fn();return result;};}
function onError(callback){const node=getCurrent();let handlers=nodeErrorHandlers.get(node);if(!handlers){handlers=[];nodeErrorHandlers.set(node,handlers);}
handlers.push(callback.bind(node.component));}
class Component{constructor(props,env,node){this.props=props;this.env=env;this.__owl__=node;}
setup(){}
render(deep=false){this.__owl__.render(deep===true);}}
Component.template="";const VText=text("").constructor;class VPortal extends VText{constructor(selector,content){super("");this.target=null;this.selector=selector;this.content=content;}
mount(parent,anchor){super.mount(parent,anchor);this.target=document.querySelector(this.selector);if(this.target){this.content.mount(this.target,null);}
else{this.content.mount(parent,anchor);}}
beforeRemove(){this.content.beforeRemove();}
remove(){if(this.content){super.remove();this.content.remove();this.content=null;}}
patch(other){super.patch(other);if(this.content){this.content.patch(other.content,true);}
else{this.content=other.content;this.content.mount(this.target,null);}}}
function portalTemplate(app,bdom,helpers){let{callSlot}=helpers;return function template(ctx,node,key=""){return new VPortal(ctx.props.target,callSlot(ctx,node,key,"default",false,null));};}
class Portal extends Component{setup(){const node=this.__owl__;onMounted(()=>{const portal=node.bdom;if(!portal.target){const target=document.querySelector(this.props.target);if(target){portal.content.moveBeforeDOMNode(target.firstChild,target);}
else{throw new OwlError("invalid portal target");}}});onWillUnmount(()=>{const portal=node.bdom;portal.remove();});}}
Portal.template="__portal__";Portal.props={target:{type:String,},slots:true,};const isUnionType=(t)=>Array.isArray(t);const isBaseType=(t)=>typeof t!=="object";const isValueType=(t)=>typeof t==="object"&&t&&"value"in t;function isOptional(t){return typeof t==="object"&&"optional"in t?t.optional||false:false;}
function describeType(type){return type==="*"||type===true?"value":type.name.toLowerCase();}
function describe(info){if(isBaseType(info)){return describeType(info);}
else if(isUnionType(info)){return info.map(describe).join(" or ");}
else if(isValueType(info)){return String(info.value);}
if("element"in info){return`list of ${describe({ type: info.element, optional: false })}s`;}
if("shape"in info){return`object`;}
return describe(info.type||"*");}
function toSchema(spec){return Object.fromEntries(spec.map((e)=>e.endsWith("?")?[e.slice(0,-1),{optional:true}]:[e,{type:"*",optional:false}]));}
function validate(obj,spec){let errors=validateSchema(obj,spec);if(errors.length){throw new OwlError("Invalid object: "+errors.join(", "));}}
function validateSchema(obj,schema){if(Array.isArray(schema)){schema=toSchema(schema);}
obj=toRaw(obj);let errors=[];for(let key in obj){if(key in schema){let result=validateType(key,obj[key],schema[key]);if(result){errors.push(result);}}
else if(!("*"in schema)){errors.push(`unknown key '${key}'`);}}
for(let key in schema){const spec=schema[key];if(key!=="*"&&!isOptional(spec)&&!(key in obj)){const isObj=typeof spec==="object"&&!Array.isArray(spec);const isAny=spec==="*"||(isObj&&"type"in spec?spec.type==="*":isObj);let detail=isAny?"":` (should be a ${describe(spec)})`;errors.push(`'${key}' is missing${detail}`);}}
return errors;}
function validateBaseType(key,value,type){if(typeof type==="function"){if(typeof value==="object"){if(!(value instanceof type)){return`'${key}' is not a ${describeType(type)}`;}}
else if(typeof value!==type.name.toLowerCase()){return`'${key}' is not a ${describeType(type)}`;}}
return null;}
function validateArrayType(key,value,descr){if(!Array.isArray(value)){return`'${key}' is not a list of ${describe(descr)}s`;}
for(let i=0;i<value.length;i++){const error=validateType(`${key}[${i}]`,value[i],descr);if(error){return error;}}
return null;}
function validateType(key,value,descr){if(value===undefined){return isOptional(descr)?null:`'${key}' is undefined (should be a ${describe(descr)})`;}
else if(isBaseType(descr)){return validateBaseType(key,value,descr);}
else if(isValueType(descr)){return value===descr.value?null:`'${key}' is not equal to '${descr.value}'`;}
else if(isUnionType(descr)){let validDescr=descr.find((p)=>!validateType(key,value,p));return validDescr?null:`'${key}' is not a ${describe(descr)}`;}
let result=null;if("element"in descr){result=validateArrayType(key,value,descr.element);}
else if("shape"in descr){if(typeof value!=="object"||Array.isArray(value)){result=`'${key}' is not an object`;}
else{const errors=validateSchema(value,descr.shape);if(errors.length){result=`'${key}' doesn't have the correct shape (${errors.join(", ")})`;}}}
else if("values"in descr){if(typeof value!=="object"||Array.isArray(value)){result=`'${key}' is not an object`;}
else{const errors=Object.entries(value).map(([key,value])=>validateType(key,value,descr.values)).filter(Boolean);if(errors.length){result=`some of the values in '${key}' are invalid (${errors.join(", ")})`;}}}
if("type"in descr&&!result){result=validateType(key,value,descr.type);}
if("validate"in descr&&!result){result=!descr.validate(value)?`'${key}' is not valid`:null;}
return result;}
const ObjectCreate=Object.create;function withDefault(value,defaultValue){return value===undefined||value===null||value===false?defaultValue:value;}
function callSlot(ctx,parent,key,name,dynamic,extra,defaultContent){key=key+"__slot_"+name;const slots=ctx.props.slots||{};const{__render,__ctx,__scope}=slots[name]||{};const slotScope=ObjectCreate(__ctx||{});if(__scope){slotScope[__scope]=extra;}
const slotBDom=__render?__render(slotScope,parent,key):null;if(defaultContent){let child1=undefined;let child2=undefined;if(slotBDom){child1=dynamic?toggler(name,slotBDom):slotBDom;}
else{child2=defaultContent(ctx,parent,key);}
return multi([child1,child2]);}
return slotBDom||text("");}
function capture(ctx){const result=ObjectCreate(ctx);for(let k in ctx){result[k]=ctx[k];}
return result;}
function withKey(elem,k){elem.key=k;return elem;}
function prepareList(collection){let keys;let values;if(Array.isArray(collection)){keys=collection;values=collection;}
else if(collection instanceof Map){keys=[...collection.keys()];values=[...collection.values()];}
else if(Symbol.iterator in Object(collection)){keys=[...collection];values=keys;}
else if(collection&&typeof collection==="object"){values=Object.values(collection);keys=Object.keys(collection);}
else{throw new OwlError(`Invalid loop expression: "${collection}" is not iterable`);}
const n=values.length;return[keys,values,n,new Array(n)];}
const isBoundary=Symbol("isBoundary");function setContextValue(ctx,key,value){const ctx0=ctx;while(!ctx.hasOwnProperty(key)&&!ctx.hasOwnProperty(isBoundary)){const newCtx=ctx.__proto__;if(!newCtx){ctx=ctx0;break;}
ctx=newCtx;}
ctx[key]=value;}
function toNumber(val){const n=parseFloat(val);return isNaN(n)?val:n;}
function shallowEqual(l1,l2){for(let i=0,l=l1.length;i<l;i++){if(l1[i]!==l2[i]){return false;}}
return true;}
class LazyValue{constructor(fn,ctx,component,node,key){this.fn=fn;this.ctx=capture(ctx);this.component=component;this.node=node;this.key=key;}
evaluate(){return this.fn.call(this.component,this.ctx,this.node,this.key);}
toString(){return this.evaluate().toString();}}
function safeOutput(value,defaultValue){if(value===undefined||value===null){return defaultValue?toggler("default",defaultValue):toggler("undefined",text(""));}
let safeKey;let block;switch(typeof value){case"object":if(value instanceof Markup){safeKey=`string_safe`;block=html(value);}
else if(value instanceof LazyValue){safeKey=`lazy_value`;block=value.evaluate();}
else if(value instanceof String){safeKey="string_unsafe";block=text(value);}
else{safeKey="block_safe";block=value;}
break;case"string":safeKey="string_unsafe";block=text(value);break;default:safeKey="string_unsafe";block=text(String(value));}
return toggler(safeKey,block);}
function validateProps(name,props,comp){const ComponentClass=typeof name!=="string"?name:comp.constructor.components[name];if(!ComponentClass){return;}
const schema=ComponentClass.props;if(!schema){if(comp.__owl__.app.warnIfNoStaticProps){console.warn(`Component '${ComponentClass.name}' does not have a static props description`);}
return;}
const defaultProps=ComponentClass.defaultProps;if(defaultProps){let isMandatory=(name)=>Array.isArray(schema)?schema.includes(name):name in schema&&!("*"in schema)&&!isOptional(schema[name]);for(let p in defaultProps){if(isMandatory(p)){throw new OwlError(`A default value cannot be defined for a mandatory prop (name: '${p}', component: ${ComponentClass.name})`);}}}
const errors=validateSchema(props,schema);if(errors.length){throw new OwlError(`Invalid props for component '${ComponentClass.name}': `+errors.join(", "));}}
function makeRefWrapper(node){let refNames=new Set();return(name,fn)=>{if(refNames.has(name)){throw new OwlError(`Cannot set the same ref more than once in the same component, ref "${name}" was set multiple times in ${node.name}`);}
refNames.add(name);return fn;};}
const helpers={withDefault,zero:Symbol("zero"),isBoundary,callSlot,capture,withKey,prepareList,setContextValue,shallowEqual,toNumber,validateProps,LazyValue,safeOutput,createCatcher,markRaw,OwlError,makeRefWrapper,};function parseXML(xml){const parser=new DOMParser();const doc=parser.parseFromString(xml,"text/xml");if(doc.getElementsByTagName("parsererror").length){let msg="Invalid XML in template.";const parsererrorText=doc.getElementsByTagName("parsererror")[0].textContent;if(parsererrorText){msg+="\nThe parser has produced the following error message:\n"+parsererrorText;const re=/\d+/g;const firstMatch=re.exec(parsererrorText);if(firstMatch){const lineNumber=Number(firstMatch[0]);const line=xml.split("\n")[lineNumber-1];const secondMatch=re.exec(parsererrorText);if(line&&secondMatch){const columnIndex=Number(secondMatch[0])-1;if(line[columnIndex]){msg+=`\nThe error might be located at xml line ${lineNumber} column ${columnIndex}\n`+`${line}\n${"-".repeat(columnIndex - 1)}^`;}}}}
throw new OwlError(msg);}
return doc;}
const bdom={text,createBlock,list,multi,html,toggler,comment};class TemplateSet{constructor(config={}){this.rawTemplates=Object.create(globalTemplates);this.templates={};this.Portal=Portal;this.dev=config.dev||false;this.translateFn=config.translateFn;this.translatableAttributes=config.translatableAttributes;if(config.templates){if(config.templates instanceof Document||typeof config.templates==="string"){this.addTemplates(config.templates);}
else{for(const name in config.templates){this.addTemplate(name,config.templates[name]);}}}
this.getRawTemplate=config.getTemplate;}
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,helpers);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".split(",");const WORD_REPLACEMENT=Object.assign(Object.create(null),{and:"&&",or:"||",gt:">",gte:">=",lt:"<",lte:"<=",});const STATIC_TOKEN_MAP=Object.assign(Object.create(null),{"{":"LEFT_BRACE","}":"RIGHT_BRACE","[":"LEFT_BRACKET","]":"RIGHT_BRACKET",":":"COLON",",":"COMMA","(":"LEFT_PAREN",")":"RIGHT_PAREN",});const OPERATORS="...,.,===,==,+,!==,!=,!,||,&&,>=,>,<=,<,?,-,*,/,%,typeof ,=>,=,;,in ,new ,|,&,^,~".split(",");let tokenizeString=function(expr){let s=expr[0];let start=s;if(s!=="'"&&s!=='"'&&s!=="`"){return false;}
let i=1;let cur;while(expr[i]&&expr[i]!==start){cur=expr[i];s+=cur;if(cur==="\\"){i++;cur=expr[i];if(!cur){throw new OwlError("Invalid expression");}
s+=cur;}
i++;}
if(expr[i]!==start){throw new OwlError("Invalid expression");}
s+=start;if(start==="`"){return{type:"TEMPLATE_STRING",value:s,replace(replacer){return s.replace(/\$\{(.*?)\}/g,(match,group)=>{return"${"+replacer(group)+"}";});},};}
return{type:"VALUE",value:s};};let tokenizeNumber=function(expr){let s=expr[0];if(s&&s.match(/[0-9]/)){let i=1;while(expr[i]&&expr[i].match(/[0-9]|\./)){s+=expr[i];i++;}
return{type:"VALUE",value:s};}
else{return false;}};let tokenizeSymbol=function(expr){let s=expr[0];if(s&&s.match(/[a-zA-Z_\$]/)){let i=1;while(expr[i]&&expr[i].match(/\w/)){s+=expr[i];i++;}
if(s in WORD_REPLACEMENT){return{type:"OPERATOR",value:WORD_REPLACEMENT[s],size:s.length};}
return{type:"SYMBOL",value:s};}
else{return false;}};const tokenizeStatic=function(expr){const char=expr[0];if(char&&char in STATIC_TOKEN_MAP){return{type:STATIC_TOKEN_MAP[char],value:char};}
return false;};const tokenizeOperator=function(expr){for(let op of OPERATORS){if(expr.startsWith(op)){return{type:"OPERATOR",value:op};}}
return false;};const TOKENIZERS=[tokenizeString,tokenizeNumber,tokenizeOperator,tokenizeSymbol,tokenizeStatic,];function tokenize(expr){const result=[];let token=true;let error;let current=expr;try{while(token){current=current.trim();if(current){for(let tokenizer of TOKENIZERS){token=tokenizer(current);if(token){result.push(token);current=current.slice(token.size||token.value.length);break;}}}
else{token=false;}}}
catch(e){error=e;}
if(current.length||error){throw new OwlError(`Tokenizer error: could not tokenize \`${expr}\``);}
return result;}
const isLeftSeparator=(token)=>token&&(token.type==="LEFT_BRACE"||token.type==="COMMA");const isRightSeparator=(token)=>token&&(token.type==="RIGHT_BRACE"||token.type==="COMMA");function compileExprToArray(expr){const localVars=new Set();const tokens=tokenize(expr);let i=0;let stack=[];while(i<tokens.length){let token=tokens[i];let prevToken=tokens[i-1];let nextToken=tokens[i+1];let groupType=stack[stack.length-1];switch(token.type){case"LEFT_BRACE":case"LEFT_BRACKET":case"LEFT_PAREN":stack.push(token.type);break;case"RIGHT_BRACE":case"RIGHT_BRACKET":case"RIGHT_PAREN":stack.pop();}
let isVar=token.type==="SYMBOL"&&!RESERVED_WORDS.includes(token.value);if(token.type==="SYMBOL"&&!RESERVED_WORDS.includes(token.value)){if(prevToken){if(groupType==="LEFT_BRACE"&&isLeftSeparator(prevToken)&&isRightSeparator(nextToken)){tokens.splice(i+1,0,{type:"COLON",value:":"},{...token});nextToken=tokens[i+1];}
if(prevToken.type==="OPERATOR"&&prevToken.value==="."){isVar=false;}
else if(prevToken.type==="LEFT_BRACE"||prevToken.type==="COMMA"){if(nextToken&&nextToken.type==="COLON"){isVar=false;}}}}
if(token.type==="TEMPLATE_STRING"){token.value=token.replace((expr)=>compileExpr(expr));}
if(nextToken&&nextToken.type==="OPERATOR"&&nextToken.value==="=>"){if(token.type==="RIGHT_PAREN"){let j=i-1;while(j>0&&tokens[j].type!=="LEFT_PAREN"){if(tokens[j].type==="SYMBOL"&&tokens[j].originalValue){tokens[j].value=tokens[j].originalValue;localVars.add(tokens[j].value);}
j--;}}
else{localVars.add(token.value);}}
if(isVar){token.varName=token.value;if(!localVars.has(token.value)){token.originalValue=token.value;token.value=`ctx['${token.value}']`;}}
i++;}
for(const token of tokens){if(token.type==="SYMBOL"&&token.varName&&localVars.has(token.value)){token.originalValue=token.value;token.value=`_${token.value}`;token.isLocal=true;}}
return tokens;}
const paddedValues=new Map([["in "," in "]]);function compileExpr(expr){return compileExprToArray(expr).map((t)=>paddedValues.get(t.value)||t.value).join("");}
const INTERP_REGEXP=/\{\{.*?\}\}|\#\{.*?\}/g;function replaceDynamicParts(s,replacer){let matches=s.match(INTERP_REGEXP);if(matches&&matches[0].length===s.length){return`(${replacer(s.slice(2, matches[0][0] === "{" ? -2 : -1))})`;}
let r=s.replace(INTERP_REGEXP,(s)=>"${"+replacer(s.slice(2,s[0]==="{"?-2:-1))+"}");return"`"+r+"`";}
function interpolate(s){return replaceDynamicParts(s,compileExpr);}
const whitespaceRE=/\s+/g;const xmlDoc=document.implementation.createDocument(null,null,null);const MODS=new Set(["stop","capture","prevent","self","synthetic"]);let nextDataIds={};function generateId(prefix=""){nextDataIds[prefix]=(nextDataIds[prefix]||0)+1;return prefix+nextDataIds[prefix];}
function isProp(tag,key){switch(tag){case"input":return(key==="checked"||key==="indeterminate"||key==="value"||key==="readonly"||key==="readOnly"||key==="disabled");case"option":return key==="selected"||key==="disabled";case"textarea":return key==="value"||key==="readonly"||key==="readOnly"||key==="disabled";case"select":return key==="value"||key==="disabled";case"button":case"optgroup":return key==="disabled";}
return false;}
function toStringExpression(str){return`\`${str.replace(/\\/g, "\\\\").replace(/`/g,"\\`").replace(/\$\{/,"\\${")}\``;}
class BlockDescription{constructor(target,type){this.dynamicTagName=null;this.isRoot=false;this.hasDynamicChildren=false;this.children=[];this.data=[];this.childNumber=0;this.parentVar="";this.id=BlockDescription.nextBlockId++;this.varName="b"+this.id;this.blockName="block"+this.id;this.target=target;this.type=type;}
insertData(str,prefix="d"){const id=generateId(prefix);this.target.addLine(`let ${id} = ${str};`);return this.data.push(id)-1;}
insert(dom){if(this.currentDom){this.currentDom.appendChild(dom);}
else{this.dom=dom;}}
generateExpr(expr){if(this.type==="block"){const hasChildren=this.children.length;let params=this.data.length?`[${this.data.join(", ")}]`:hasChildren?"[]":"";if(hasChildren){params+=", ["+this.children.map((c)=>c.varName).join(", ")+"]";}
if(this.dynamicTagName){return`toggler(${this.dynamicTagName}, ${this.blockName}(${this.dynamicTagName})(${params}))`;}
return`${this.blockName}(${params})`;}
else if(this.type==="list"){return`list(c_block${this.id})`;}
return expr;}
asXmlString(){const t=xmlDoc.createElement("t");t.appendChild(this.dom);return t.innerHTML;}}
BlockDescription.nextBlockId=1;function createContext(parentCtx,params){return Object.assign({block:null,index:0,forceNewBlock:true,translate:parentCtx.translate,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=["label","title","placeholder","alt"];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;}
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,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){const match=translationRE.exec(str);return match[1]+this.translateFn(match[2])+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.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);}
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){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)){attrs[key]=this.translateFn(ast.attrs[key]);}
else{expr=`"${ast.attrs[key]}"`;attrName=key;attrs[key]=ast.attrs[key];}
if(attrName==="value"&&ctx.tModelSelectedExpr){let selectedId=block.insertData(`${ctx.tModelSelectedExpr} === ${expr}`,"attr");attrs[`block-attribute-${selectedId}`]="selected";}}
let tModelSelectedExpr;if(ast.model){const{hasDynamicChildren,baseExpr,expr,eventType,shouldNumberize,shouldTrim,targetAttr,specialInitTargetAttr,}=ast.model;const baseExpression=compileExpr(baseExpr);const bExprId=generateId("bExpr");this.define(bExprId,baseExpression);const expression=compileExpr(expr);const exprId=generateId("expr");this.define(exprId,expression);const fullExpression=`${bExprId}[${exprId}]`;let idx;if(specialInitTargetAttr){let targetExpr=targetAttr in attrs&&`'${attrs[targetAttr]}'`;if(!targetExpr&&ast.attrs){const dynamicTgExpr=ast.attrs[`t-att-${targetAttr}`];if(dynamicTgExpr){targetExpr=compileExpr(dynamicTgExpr);}}
idx=block.insertData(`${fullExpression} === ${targetExpr}`,"prop");attrs[`block-property-${idx}`]=specialInitTargetAttr;}
else if(hasDynamicChildren){const bValueId=generateId("bValue");tModelSelectedExpr=`${bValueId}`;this.define(tModelSelectedExpr,fullExpression);}
else{idx=block.insertData(`${fullExpression}`,"prop");attrs[`block-property-${idx}`]=targetAttr;}
this.helpers.add("toNumber");let valueCode=`ev.target.${targetAttr}`;valueCode=shouldTrim?`${valueCode}.trim()`:valueCode;valueCode=shouldNumberize?`toNumber(${valueCode})`:valueCode;const handler=`[(ev) => { ${fullExpression} = ${valueCode}; }]`;idx=block.insertData(handler,"hdlr");attrs[`block-handler-${idx}`]=eventType;}
for(let ev in ast.on){const name=this.generateHandlerCode(ev,ast.on[ev]);const idx=block.insertData(name,"hdlr");attrs[`block-handler-${idx}`]=ev;}
if(ast.ref){if(this.dev){this.helpers.add("makeRefWrapper");this.target.hasRefWrapper=true;}
const isDynamic=INTERP_REGEXP.test(ast.ref);let name=`\`${ast.ref}\``;if(isDynamic){name=replaceDynamicParts(ast.ref,(expr)=>this.captureExpression(expr,true));}
let setRefStr=`(el) => this.__owl__.setRef((${name}), el)`;if(this.dev){setRefStr=`refWrapper(${name}, ${setRefStr})`;}
const idx=block.insertData(setRefStr,"ref");attrs["block-ref"]=String(idx);}
const nameSpace=ast.ns||ctx.nameSpace;const dom=nameSpace?xmlDoc.createElementNS(nameSpace,ast.tag):xmlDoc.createElement(ast.tag);for(const[attr,val]of Object.entries(attrs)){if(!(attr==="class"&&val==="")){dom.setAttribute(attr,val);}}
block.insert(dom);if(ast.content.length){const initialDom=block.currentDom;block.currentDom=dom;const children=ast.content;for(let i=0;i<children.length;i++){const child=ast.content[i];const subCtx=createContext(ctx,{block,index:block.childNumber,forceNewBlock:false,isLast:ctx.isLast&&i===children.length-1,tKeyExpr:ctx.tKeyExpr,nameSpace,tModelSelectedExpr,inPreTag:ctx.inPreTag||ast.tag==="pre",});this.compileAST(child,subCtx);}
block.currentDom=initialDom;}
if(isNewBlock){this.insertBlock(`${block.blockName}(ddd)`,block,ctx);if(block.children.length&&block.hasDynamicChildren){const code=this.target.code;const children=block.children.slice();let current=children.shift();for(let i=codeIdx;i<code.length;i++){if(code[i].trimStart().startsWith(`const ${current.varName} `)){code[i]=code[i].replace(`const ${current.varName}`,current.varName);current=children.shift();if(!current)
break;}}
this.addLine(`let ${block.children.map((c) => c.varName).join(", ")};`,codeIdx);}}
return block.varName;}
compileTEsc(ast,ctx){let{block,forceNewBlock}=ctx;let expr;if(ast.expr==="0"){this.helpers.add("zero");expr=`ctx[zero]`;}
else{expr=compileExpr(ast.expr);if(ast.defaultValue){this.helpers.add("withDefault");expr=`withDefault(${expr}, ${toStringExpression(ast.defaultValue)})`;}}
if(!block||forceNewBlock){block=this.createBlock(block,"text",ctx);this.insertBlock(`text(${expr})`,block,{...ctx,forceNewBlock:forceNewBlock&&!block});}
else{const idx=block.insertData(expr,"txt");const text=xmlDoc.createElement(`block-text-${idx}`);block.insert(text);}
return block.varName;}
compileTOut(ast,ctx){let{block}=ctx;if(block){this.insertAnchor(block);}
block=this.createBlock(block,"html",ctx);let blockStr;if(ast.expr==="0"){this.helpers.add("zero");blockStr=`ctx[zero]`;}
else if(ast.body){let bodyValue=null;bodyValue=BlockDescription.nextBlockId;const subCtx=createContext(ctx);this.compileAST({type:3,content:ast.body},subCtx);this.helpers.add("safeOutput");blockStr=`safeOutput(${compileExpr(ast.expr)}, b${bodyValue})`;}
else{this.helpers.add("safeOutput");blockStr=`safeOutput(${compileExpr(ast.expr)})`;}
this.insertBlock(blockStr,block,ctx);return block.varName;}
compileTIfBranch(content,block,ctx){this.target.indentLevel++;let childN=block.children.length;this.compileAST(content,createContext(ctx,{block,index:ctx.index}));if(block.children.length>childN){this.insertAnchor(block,childN);}
this.target.indentLevel--;}
compileTIf(ast,ctx,nextNode){let{block,forceNewBlock}=ctx;const codeIdx=this.target.code.length;const isNewBlock=!block||(block.type!=="multi"&&forceNewBlock);if(block){block.hasDynamicChildren=true;}
if(!block||(block.type!=="multi"&&forceNewBlock)){block=this.createBlock(block,"multi",ctx);}
this.addLine(`if (${compileExpr(ast.condition)}) {`);this.compileTIfBranch(ast.content,block,ctx);if(ast.tElif){for(let clause of ast.tElif){this.addLine(`} else if (${compileExpr(clause.condition)}) {`);this.compileTIfBranch(clause.content,block,ctx);}}
if(ast.tElse){this.addLine(`} else {`);this.compileTIfBranch(ast.tElse,block,ctx);}
this.addLine("}");if(isNewBlock){if(block.children.length){const code=this.target.code;const children=block.children.slice();let current=children.shift();for(let i=codeIdx;i<code.length;i++){if(code[i].trimStart().startsWith(`const ${current.varName} `)){code[i]=code[i].replace(`const ${current.varName}`,current.varName);current=children.shift();if(!current)
break;}}
this.addLine(`let ${block.children.map((c) => c.varName).join(", ")};`,codeIdx);}
const args=block.children.map((c)=>c.varName).join(", ");this.insertBlock(`multi([${args}])`,block,ctx);}
return block.varName;}
compileTForeach(ast,ctx){let{block}=ctx;if(block){this.insertAnchor(block);}
block=this.createBlock(block,"list",ctx);this.target.loopLevel++;const loopVar=`i${this.target.loopLevel}`;this.addLine(`ctx = Object.create(ctx);`);const vals=`v_block${block.id}`;const keys=`k_block${block.id}`;const l=`l_block${block.id}`;const c=`c_block${block.id}`;this.helpers.add("prepareList");this.define(`[${keys}, ${vals}, ${l}, ${c}]`,`prepareList(${compileExpr(ast.collection)});`);if(this.dev){this.define(`keys${block.id}`,`new Set()`);}
this.addLine(`for (let ${loopVar} = 0; ${loopVar} < ${l}; ${loopVar}++) {`);this.target.indentLevel++;this.addLine(`ctx[\`${ast.elem}\`] = ${keys}[${loopVar}];`);if(!ast.hasNoFirst){this.addLine(`ctx[\`${ast.elem}_first\`] = ${loopVar} === 0;`);}
if(!ast.hasNoLast){this.addLine(`ctx[\`${ast.elem}_last\`] = ${loopVar} === ${keys}.length - 1;`);}
if(!ast.hasNoIndex){this.addLine(`ctx[\`${ast.elem}_index\`] = ${loopVar};`);}
if(!ast.hasNoValue){this.addLine(`ctx[\`${ast.elem}_value\`] = ${vals}[${loopVar}];`);}
this.define(`key${this.target.loopLevel}`,ast.key?compileExpr(ast.key):loopVar);if(this.dev){this.helpers.add("OwlError");this.addLine(`if (keys${block.id}.has(String(key${this.target.loopLevel}))) { throw new OwlError(\`Got duplicate key in t-foreach: \${key${this.target.loopLevel}}\`)}`);this.addLine(`keys${block.id}.add(String(key${this.target.loopLevel}));`);}
let id;if(ast.memo){this.target.hasCache=true;id=generateId();this.define(`memo${id}`,compileExpr(ast.memo));this.define(`vnode${id}`,`cache[key${this.target.loopLevel}];`);this.addLine(`if (vnode${id}) {`);this.target.indentLevel++;this.addLine(`if (shallowEqual(vnode${id}.memo, memo${id})) {`);this.target.indentLevel++;this.addLine(`${c}[${loopVar}] = vnode${id};`);this.addLine(`nextCache[key${this.target.loopLevel}] = vnode${id};`);this.addLine(`continue;`);this.target.indentLevel--;this.addLine("}");this.target.indentLevel--;this.addLine("}");}
const subCtx=createContext(ctx,{block,index:loopVar});this.compileAST(ast.body,subCtx);if(ast.memo){this.addLine(`nextCache[key${this.target.loopLevel}] = Object.assign(${c}[${loopVar}], {memo: memo${id}});`);}
this.target.indentLevel--;this.target.loopLevel--;this.addLine(`}`);if(!ctx.isLast){this.addLine(`ctx = ctx.__proto__;`);}
this.insertBlock("l",block,ctx);return block.varName;}
compileTKey(ast,ctx){const tKeyExpr=generateId("tKey_");this.define(tKeyExpr,compileExpr(ast.expr));ctx=createContext(ctx,{tKeyExpr,block:ctx.block,index:ctx.index,});return this.compileAST(ast.content,ctx);}
compileMulti(ast,ctx){let{block,forceNewBlock}=ctx;const isNewBlock=!block||forceNewBlock;let codeIdx=this.target.code.length;if(isNewBlock){const n=ast.content.filter((c)=>c.type!==6).length;let result=null;if(n<=1){for(let child of ast.content){const blockName=this.compileAST(child,ctx);result=result||blockName;}
return result;}
block=this.createBlock(block,"multi",ctx);}
let index=0;for(let i=0,l=ast.content.length;i<l;i++){const child=ast.content[i];const isTSet=child.type===6;const subCtx=createContext(ctx,{block,index,forceNewBlock:!isTSet,isLast:ctx.isLast&&i===l-1,});this.compileAST(child,subCtx);if(!isTSet){index++;}}
if(isNewBlock){if(block.hasDynamicChildren&&block.children.length){const code=this.target.code;const children=block.children.slice();let current=children.shift();for(let i=codeIdx;i<code.length;i++){if(code[i].trimStart().startsWith(`const ${current.varName} `)){code[i]=code[i].replace(`const ${current.varName}`,current.varName);current=children.shift();if(!current)
break;}}
this.addLine(`let ${block.children.map((c) => c.varName).join(", ")};`,codeIdx);}
const args=block.children.map((c)=>c.varName).join(", ");this.insertBlock(`multi([${args}])`,block,ctx);}
return block.varName;}
compileTCall(ast,ctx){let{block,forceNewBlock}=ctx;let ctxVar=ctx.ctxVar||"ctx";if(ast.context){ctxVar=generateId("ctx");this.addLine(`let ${ctxVar} = ${compileExpr(ast.context)};`);}
const isDynamic=INTERP_REGEXP.test(ast.name);const subTemplate=isDynamic?interpolate(ast.name):"`"+ast.name+"`";if(block&&!forceNewBlock){this.insertAnchor(block);}
block=this.createBlock(block,"multi",ctx);if(ast.body){this.addLine(`${ctxVar} = Object.create(${ctxVar});`);this.addLine(`${ctxVar}[isBoundary] = 1;`);this.helpers.add("isBoundary");const subCtx=createContext(ctx,{ctxVar});const bl=this.compileMulti({type:3,content:ast.body},subCtx);if(bl){this.helpers.add("zero");this.addLine(`${ctxVar}[zero] = ${bl};`);}}
const key=this.generateComponentKey();if(isDynamic){const templateVar=generateId("template");if(!this.staticDefs.find((d)=>d.id==="call")){this.staticDefs.push({id:"call",expr:`app.callTemplate.bind(app)`});}
this.define(templateVar,subTemplate);this.insertBlock(`call(this, ${templateVar}, ${ctxVar}, node, ${key})`,block,{...ctx,forceNewBlock:!block,});}
else{const id=generateId(`callTemplate_`);this.staticDefs.push({id,expr:`app.getTemplate(${subTemplate})`});this.insertBlock(`${id}.call(this, ${ctxVar}, node, ${key})`,block,{...ctx,forceNewBlock:!block,});}
if(ast.body&&!ctx.isLast){this.addLine(`${ctxVar} = ${ctxVar}.__proto__;`);}
return block.varName;}
compileTCallBlock(ast,ctx){let{block,forceNewBlock}=ctx;if(block){if(!forceNewBlock){this.insertAnchor(block);}}
block=this.createBlock(block,"multi",ctx);this.insertBlock(compileExpr(ast.name),block,{...ctx,forceNewBlock:!block});return block.varName;}
compileTSet(ast,ctx){this.target.shouldProtectScope=true;this.helpers.add("isBoundary").add("withDefault");const expr=ast.value?compileExpr(ast.value||""):"null";if(ast.body){this.helpers.add("LazyValue");const bodyAst={type:3,content:ast.body};const name=this.compileInNewTarget("value",bodyAst,ctx);let key=this.target.currentKey(ctx);let value=`new LazyValue(${name}, ctx, this, node, ${key})`;value=ast.value?(value?`withDefault(${expr}, ${value})`:expr):value;this.addLine(`ctx[\`${ast.name}\`] = ${value};`);}
else{let value;if(ast.defaultValue){const defaultValue=toStringExpression(ctx.translate?this.translate(ast.defaultValue):ast.defaultValue);if(ast.value){value=`withDefault(${expr}, ${defaultValue})`;}
else{value=defaultValue;}}
else{value=expr;}
this.helpers.add("setContextValue");this.addLine(`setContextValue(${ctx.ctxVar || "ctx"}, "${ast.name}", ${value});`);}
return null;}
generateComponentKey(currentKey="key"){const parts=[generateId("__")];for(let i=0;i<this.target.loopLevel;i++){parts.push(`\${key${i + 1}}`);}
return`${currentKey} + \`${parts.join("__")}\``;}
formatProp(name,value){if(name.endsWith(".translate")){value=toStringExpression(this.translateFn(value));}
else{value=this.captureExpression(value);}
if(name.includes(".")){let[_name,suffix]=name.split(".");name=_name;switch(suffix){case"bind":value=`(${value}).bind(this)`;break;case"alike":case"translate":break;default:throw new OwlError("Invalid prop suffix");}}
name=/^[a-z_]+$/i.test(name)?name:`'${name}'`;return`${name}: ${value || undefined}`;}
formatPropObject(obj){return Object.entries(obj).map(([k,v])=>this.formatProp(k,v));}
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):[];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));}
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 dynProps=ast.attrs?ast.attrs["t-props"]:null;if(ast.attrs){delete ast.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(ast.attrs):[];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;}
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){if(typeof xml==="string"){const elem=parseXML(`<t>${xml}</t>`).firstChild;return _parse(elem);}
let ast=cache.get(xml);if(!ast){ast=_parse(xml.cloneNode(true));cache.set(xml,ast);}
return ast;}
function _parse(xml){normalizeXML(xml);const ctx={inPreTag:false};return parseNode(xml,ctx)||{type:0,value:""};}
function parseNode(node,ctx){if(!(node instanceof Element)){return parseTextCommentNode(node,ctx);}
return(parseTDebugLog(node,ctx)||parseTForEach(node,ctx)||parseTIf(node,ctx)||parseTPortal(node,ctx)||parseTCall(node,ctx)||parseTCallBlock(node)||parseTEscNode(node,ctx)||parseTOutNode(node,ctx)||parseTKey(node,ctx)||parseTTranslation(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 parseTDebugLog(node,ctx){if(node.hasAttribute("t-debug")){node.removeAttribute("t-debug");return{type:12,content:parseNode(node,ctx),};}
if(node.hasAttribute("t-log")){const expr=node.getAttribute("t-log");node.removeAttribute("t-log");return{type:13,expr,content:parseNode(node,ctx),};}
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 on=null;let model=null;for(let attr of nodeAttrsNames){const value=node.getAttribute(attr);if(attr==="t-on"||attr==="t-on-"){throw new OwlError("Missing event name with t-on directive");}
if(attr.startsWith("t-on-")){on=on||{};on[attr.slice(5)]=value;}
else if(attr.startsWith("t-model")){if(!["input","select","textarea"].includes(tagName)){throw new OwlError("The t-model directive only works with <input>, <textarea> and <select>");}
let baseExpr,expr;if(hasDotAtTheEnd.test(value)){const index=value.lastIndexOf(".");baseExpr=value.slice(0,index);expr=`'${value.slice(index + 1)}'`;}
else if(hasBracketsAtTheEnd.test(value)){const index=value.lastIndexOf("[");baseExpr=value.slice(0,index);expr=value.slice(index+1,-1);}
else{throw new OwlError(`Invalid t-model expression: "${value}" (it should be assignable)`);}
const typeAttr=node.getAttribute("type");const isInput=tagName==="input";const isSelect=tagName==="select";const isCheckboxInput=isInput&&typeAttr==="checkbox";const isRadioInput=isInput&&typeAttr==="radio";const hasTrimMod=attr.includes(".trim");const hasLazyMod=hasTrimMod||attr.includes(".lazy");const hasNumberMod=attr.includes(".number");const eventType=isRadioInput?"click":isSelect||hasLazyMod?"change":"input";model={baseExpr,expr,targetAttr:isCheckboxInput?"checked":"value",specialInitTargetAttr:isRadioInput?"checked":null,eventType,hasDynamicChildren:false,shouldTrim:hasTrimMod,shouldNumberize:hasNumberMod,};if(isSelect){ctx=Object.assign({},ctx);ctx.tModelInfo=model;}}
else if(attr.startsWith("block-")){throw new OwlError(`Invalid attribute: '${attr}'`);}
else if(attr==="xmlns"){ns=value;}
else if(attr!=="t-name"){if(attr.startsWith("t-")&&!attr.startsWith("t-att")){throw new OwlError(`Unknown QWeb directive: '${attr}'`);}
const tModel=ctx.tModelInfo;if(tModel&&["t-att-value","t-attf-value"].includes(attr)){tModel.hasDynamicChildren=true;}
attrs=attrs||{};attrs[attr]=value;}}
if(ns){ctx.nameSpace=ns;}
const children=parseChildren(node,ctx);return{type:2,tag:tagName,dynamicTag,attrs,on,ref,content:children,model,ns,};}
function parseTEscNode(node,ctx){if(!node.hasAttribute("t-esc")){return null;}
const escValue=node.getAttribute("t-esc");node.removeAttribute("t-esc");const tesc={type:4,expr:escValue,defaultValue:node.textContent||"",};let ref=node.getAttribute("t-ref");node.removeAttribute("t-ref");const ast=parseNode(node,ctx);if(!ast){return tesc;}
if(ast.type===2){return{...ast,ref,content:[tesc],};}
return tesc;}
function parseTOutNode(node,ctx){if(!node.hasAttribute("t-out")&&!node.hasAttribute("t-raw")){return null;}
if(node.hasAttribute("t-raw")){console.warn(`t-raw has been deprecated in favor of t-out. If the value to render is not wrapped by the "markup" function, it will be escaped`);}
const expr=(node.getAttribute("t-out")||node.getAttribute("t-raw"));node.removeAttribute("t-out");node.removeAttribute("t-raw");const tOut={type:8,expr,body:null};const ref=node.getAttribute("t-ref");node.removeAttribute("t-ref");const ast=parseNode(node,ctx);if(!ast){return tOut;}
if(ast.type===2){tOut.body=ast.content.length?ast.content:null;return{...ast,ref,content:[tOut],};}
return tOut;}
function parseTForEach(node,ctx){if(!node.hasAttribute("t-foreach")){return null;}
const html=node.outerHTML;const collection=node.getAttribute("t-foreach");node.removeAttribute("t-foreach");const elem=node.getAttribute("t-as")||"";node.removeAttribute("t-as");const key=node.getAttribute("t-key");if(!key){throw new OwlError(`"Directive t-foreach should always be used with a t-key!" (expression: t-foreach="${collection}" t-as="${elem}")`);}
node.removeAttribute("t-key");const memo=node.getAttribute("t-memo")||"";node.removeAttribute("t-memo");const body=parseNode(node,ctx);if(!body){return null;}
const hasNoTCall=!html.includes("t-call");const hasNoFirst=hasNoTCall&&!html.includes(`${elem}_first`);const hasNoLast=hasNoTCall&&!html.includes(`${elem}_last`);const hasNoIndex=hasNoTCall&&!html.includes(`${elem}_index`);const hasNoValue=hasNoTCall&&!html.includes(`${elem}_value`);return{type:9,collection,elem,body,memo,key,hasNoFirst,hasNoLast,hasNoIndex,hasNoValue,};}
function parseTKey(node,ctx){if(!node.hasAttribute("t-key")){return null;}
const key=node.getAttribute("t-key");node.removeAttribute("t-key");const body=parseNode(node,ctx);if(!body){return null;}
return{type:10,expr:key,content:body};}
function parseTCall(node,ctx){if(!node.hasAttribute("t-call")){return null;}
const subTemplate=node.getAttribute("t-call");const context=node.getAttribute("t-call-context");node.removeAttribute("t-call");node.removeAttribute("t-call-context");if(node.tagName!=="t"){const ast=parseNode(node,ctx);const tcall={type:7,name:subTemplate,body:null,context};if(ast&&ast.type===2){ast.content=[tcall];return ast;}
if(ast&&ast.type===11){return{...ast,slots:{default:{content:tcall,scope:null,on:null,attrs:null}},};}}
const body=parseChildren(node,ctx);return{type:7,name:subTemplate,body:body.length?body:null,context,};}
function parseTCallBlock(node,ctx){if(!node.hasAttribute("t-call-block")){return null;}
const name=node.getAttribute("t-call-block");return{type:15,name,};}
function parseTIf(node,ctx){if(!node.hasAttribute("t-if")){return null;}
const condition=node.getAttribute("t-if");node.removeAttribute("t-if");const content=parseNode(node,ctx)||{type:0,value:""};let nextElement=node.nextElementSibling;const tElifs=[];while(nextElement&&nextElement.hasAttribute("t-elif")){const condition=nextElement.getAttribute("t-elif");nextElement.removeAttribute("t-elif");const tElif=parseNode(nextElement,ctx);const next=nextElement.nextElementSibling;nextElement.remove();nextElement=next;if(tElif){tElifs.push({condition,content:tElif});}}
let tElse=null;if(nextElement&&nextElement.hasAttribute("t-else")){nextElement.removeAttribute("t-else");tElse=parseNode(nextElement,ctx);nextElement.remove();}
return{type:5,condition,content,tElif:tElifs.length?tElifs:null,tElse,};}
function parseTSetNode(node,ctx){if(!node.hasAttribute("t-set")){return null;}
const name=node.getAttribute("t-set");const value=node.getAttribute("t-value")||null;const defaultValue=node.innerHTML===node.textContent?node.textContent||null:null;let body=null;if(node.textContent!==node.innerHTML){body=parseChildren(node,ctx);}
return{type:6,name,value,defaultValue,body};}
const directiveErrorMap=new Map([["t-ref","t-ref is no longer supported on components. Consider exposing only the public part of the component's API through a callback prop.",],["t-att","t-att makes no sense on component: props are already treated as expressions"],["t-attf","t-attf is not supported on components: use template strings for string interpolation in props",],]);function parseComponent(node,ctx){let name=node.tagName;const firstLetter=name[0];let isDynamic=node.hasAttribute("t-component");if(isDynamic&&name!=="t"){throw new OwlError(`Directive 't-component' can only be used on <t> nodes (used on a <${name}>)`);}
if(!(firstLetter===firstLetter.toUpperCase()||isDynamic)){return null;}
if(isDynamic){name=node.getAttribute("t-component");node.removeAttribute("t-component");}
const dynamicProps=node.getAttribute("t-props");node.removeAttribute("t-props");const defaultSlotScope=node.getAttribute("t-slot-scope");node.removeAttribute("t-slot-scope");let on=null;let props=null;for(let name of node.getAttributeNames()){const value=node.getAttribute(name);if(name.startsWith("t-")){if(name.startsWith("t-on-")){on=on||{};on[name.slice(5)]=value;}
else{const message=directiveErrorMap.get(name.split("-").slice(0,2).join("-"));throw new OwlError(message||`unsupported directive on Component: ${name}`);}}
else{props=props||{};props[name]=value;}}
let slots=null;if(node.hasChildNodes()){const clone=node.cloneNode(true);const slotNodes=Array.from(clone.querySelectorAll("[t-set-slot]"));for(let slotNode of slotNodes){if(slotNode.tagName!=="t"){throw new OwlError(`Directive 't-set-slot' can only be used on <t> nodes (used on a <${slotNode.tagName}>)`);}
const name=slotNode.getAttribute("t-set-slot");let el=slotNode.parentElement;let isInSubComponent=false;while(el&&el!==clone){if(el.hasAttribute("t-component")||el.tagName[0]===el.tagName[0].toUpperCase()){isInSubComponent=true;break;}
el=el.parentElement;}
if(isInSubComponent||!el){continue;}
slotNode.removeAttribute("t-set-slot");slotNode.remove();const slotAst=parseNode(slotNode,ctx);let on=null;let attrs=null;let scope=null;for(let attributeName of slotNode.getAttributeNames()){const value=slotNode.getAttribute(attributeName);if(attributeName==="t-slot-scope"){scope=value;continue;}
else if(attributeName.startsWith("t-on-")){on=on||{};on[attributeName.slice(5)]=value;}
else{attrs=attrs||{};attrs[attributeName]=value;}}
slots=slots||{};slots[name]={content:slotAst,on,attrs,scope};}
const defaultContent=parseChildNodes(clone,ctx);slots=slots||{};if(defaultContent&&!slots.default){slots.default={content:defaultContent,on,attrs:null,scope:defaultSlotScope};}}
return{type:11,name,isDynamic,dynamicProps,props,slots,on};}
function parseTSlot(node,ctx){if(!node.hasAttribute("t-slot")){return null;}
const name=node.getAttribute("t-slot");node.removeAttribute("t-slot");let attrs=null;let on=null;for(let attributeName of node.getAttributeNames()){const value=node.getAttribute(attributeName);if(attributeName.startsWith("t-on-")){on=on||{};on[attributeName.slice(5)]=value;}
else{attrs=attrs||{};attrs[attributeName]=value;}}
return{type:14,name,attrs,on,defaultContent:parseChildNodes(node,ctx),};}
function parseTTranslation(node,ctx){if(node.getAttribute("t-translation")!=="off"){return null;}
node.removeAttribute("t-translation");return{type:16,content:parseNode(node,ctx),};}
function parseTPortal(node,ctx){if(!node.hasAttribute("t-portal")){return null;}
const target=node.getAttribute("t-portal");node.removeAttribute("t-portal");const content=parseNode(node,ctx);if(!content){return{type:0,value:"",};}
return{type:17,target,content,};}
function parseChildren(node,ctx){const children=[];for(let child of node.childNodes){const childAst=parseNode(child,ctx);if(childAst){if(childAst.type===3){children.push(...childAst.content);}
else{children.push(childAst);}}}
return children;}
function parseChildNodes(node,ctx){const children=parseChildren(node,ctx);switch(children.length){case 0:return null;case 1:return children[0];default:return{type:3,content:children};}}
function normalizeTIf(el){let tbranch=el.querySelectorAll("[t-elif], [t-else]");for(let i=0,ilen=tbranch.length;i<ilen;i++){let node=tbranch[i];let prevElem=node.previousElementSibling;let pattr=(name)=>prevElem.getAttribute(name);let nattr=(name)=>+!!node.getAttribute(name);if(prevElem&&(pattr("t-if")||pattr("t-elif"))){if(pattr("t-foreach")){throw new OwlError("t-if cannot stay at the same level as t-foreach when using t-elif or t-else");}
if(["t-if","t-elif","t-else"].map(nattr).reduce(function(a,b){return a+b;})>1){throw new OwlError("Only one conditional branching directive is allowed per node");}
let textNode;while((textNode=node.previousSibling)!==prevElem){if(textNode.nodeValue.trim().length&&textNode.nodeType!==8){throw new OwlError("text is not allowed between branching directives");}
textNode.remove();}}
else{throw new OwlError("t-elif and t-else directives must be preceded by a t-if or t-elif directive");}}}
function normalizeTEscTOut(el){for(const d of["t-esc","t-out"]){const elements=[...el.querySelectorAll(`[${d}]`)].filter((el)=>el.tagName[0]===el.tagName[0].toUpperCase()||el.hasAttribute("t-component"));for(const el of elements){if(el.childNodes.length){throw new OwlError(`Cannot have ${d} on a component that already has content`);}
const value=el.getAttribute(d);el.removeAttribute(d);const t=el.ownerDocument.createElement("t");if(value!=null){t.setAttribute(d,value);}
el.appendChild(t);}}}
function normalizeXML(el){normalizeTIf(el);normalizeTEscTOut(el);}
function compile(template,options={}){const ast=parse(template);const hasSafeContext=template instanceof Node?!(template instanceof Element)||template.querySelector("[t-set], [t-call]")===null:!template.includes("t-set")&&!template.includes("t-call");const codeGenerator=new CodeGenerator(ast,{...options,hasSafeContext});const code=codeGenerator.generateCode();try{return new Function("app, bdom, helpers",code);}
catch(originalError){const{name}=options;const nameStr=name?`template "${name}"`:"anonymous template";const err=new OwlError(`Failed to compile ${nameStr}: ${originalError.message}\n\ngenerated code:\nfunction(app, bdom, helpers) {\n${code}\n}`);err.cause=originalError;throw err;}}
const version="2.4.0";class Scheduler{constructor(){this.tasks=new Set();this.frame=0;this.delayedRenders=[];this.cancelledNodes=new Set();this.requestAnimationFrame=Scheduler.requestAnimationFrame;}
addFiber(fiber){this.tasks.add(fiber.root);}
scheduleDestroy(node){this.cancelledNodes.add(node);if(this.frame===0){this.frame=this.requestAnimationFrame(()=>this.processTasks());}}
flush(){if(this.delayedRenders.length){let renders=this.delayedRenders;this.delayedRenders=[];for(let f of renders){if(f.root&&f.node.status!==3&&f.node.fiber===f){f.render();}}}
if(this.frame===0){this.frame=this.requestAnimationFrame(()=>this.processTasks());}}
processTasks(){this.frame=0;for(let node of this.cancelledNodes){node._destroy();}
this.cancelledNodes.clear();for(let task of this.tasks){this.processFiber(task);}
for(let task of this.tasks){if(task.node.status===3){this.tasks.delete(task);}}}
processFiber(fiber){if(fiber.root!==fiber){this.tasks.delete(fiber);return;}
const hasError=fibersInError.has(fiber);if(hasError&&fiber.counter!==0){this.tasks.delete(fiber);return;}
if(fiber.node.status===3){this.tasks.delete(fiber);return;}
if(fiber.counter===0){if(!hasError){fiber.complete();}
this.tasks.delete(fiber);}}}
Scheduler.requestAnimationFrame=window.requestAnimationFrame.bind(window);let hasBeenLogged=false;const DEV_MSG=()=>{const hash=window.owl?window.owl.__info__.hash:"master";return`Owl is running in 'dev' mode.

This is not suitable for production use.
See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration for more information.`;};const apps=new Set();window.__OWL_DEVTOOLS__||(window.__OWL_DEVTOOLS__={apps,Fiber,RootFiber,toRaw,reactive});class App extends TemplateSet{constructor(Root,config={}){super(config);this.scheduler=new Scheduler();this.subRoots=new Set();this.root=null;this.name=config.name||"";this.Root=Root;apps.add(this);if(config.test){this.dev=true;}
this.warnIfNoStaticProps=config.warnIfNoStaticProps||false;if(this.dev&&!config.test&&!hasBeenLogged){console.info(DEV_MSG());hasBeenLogged=true;}
const env=config.env||{};const descrs=Object.getOwnPropertyDescriptors(env);this.env=Object.freeze(Object.create(Object.getPrototypeOf(env),descrs));this.props=config.props||{};}
mount(target,options){const root=this.createRoot(this.Root,{props:this.props});this.root=root.node;this.subRoots.delete(root.node);return root.mount(target,options);}
createRoot(Root,config={}){const props=config.props||{};const env=this.env;if(config.env){this.env=config.env;}
const node=this.makeNode(Root,props);if(config.env){this.env=env;}
this.subRoots.add(node);return{node,mount:(target,options)=>{App.validateTarget(target);if(this.dev){validateProps(Root,props,{__owl__:{app:this}});}
const prom=this.mountNode(node,target,options);return prom;},destroy:()=>{this.subRoots.delete(node);node.destroy();this.scheduler.processTasks();},};}
makeNode(Component,props){return new ComponentNode(Component,props,this,null,null);}
mountNode(node,target,options){const promise=new Promise((resolve,reject)=>{let isResolved=false;node.mounted.push(()=>{resolve(node.component);isResolved=true;});let handlers=nodeErrorHandlers.get(node);if(!handlers){handlers=[];nodeErrorHandlers.set(node,handlers);}
handlers.unshift((e)=>{if(!isResolved){reject(e);}
throw e;});});node.mountComponent(target,options);return promise;}
destroy(){if(this.root){for(let subroot of this.subRoots){subroot.destroy();}
this.root.destroy();this.scheduler.processTasks();}
apps.delete(this);}
createComponent(name,isStatic,hasSlotsProp,hasDynamicPropList,propList){const isDynamic=!isStatic;let arePropsDifferent;const hasNoProp=propList.length===0;if(hasSlotsProp){arePropsDifferent=(_1,_2)=>true;}
else if(hasDynamicPropList){arePropsDifferent=function(props1,props2){for(let k in props1){if(props1[k]!==props2[k]){return true;}}
return Object.keys(props1).length!==Object.keys(props2).length;};}
else if(hasNoProp){arePropsDifferent=(_1,_2)=>false;}
else{arePropsDifferent=function(props1,props2){for(let p of propList){if(props1[p]!==props2[p]){return true;}}
return false;};}
const updateAndRender=ComponentNode.prototype.updateAndRender;const initiateRender=ComponentNode.prototype.initiateRender;return(props,key,ctx,parent,C)=>{let children=ctx.children;let node=children[key];if(isDynamic&&node&&node.component.constructor!==C){node=undefined;}
const parentFiber=ctx.fiber;if(node){if(arePropsDifferent(node.props,props)||parentFiber.deep||node.forceNextRender){node.forceNextRender=false;updateAndRender.call(node,props,parentFiber);}}
else{if(isStatic){const components=parent.constructor.components;if(!components){throw new OwlError(`Cannot find the definition of component "${name}", missing static components key in parent`);}
C=components[name];if(!C){throw new OwlError(`Cannot find the definition of component "${name}"`);}
else if(!(C.prototype instanceof Component)){throw new OwlError(`"${name}" is not a Component. It must inherit from the Component class`);}}
node=new ComponentNode(C,props,this,ctx,key);children[key]=node;initiateRender.call(node,new Fiber(node,parentFiber));}
parentFiber.childrenMap[key]=node;return node;};}
handleError(...args){return handleError(...args);}}
App.validateTarget=validateTarget;App.apps=apps;App.version=version;async function mount(C,target,config={}){return new App(C,config).mount(target,config);}
const mainEventHandler=(data,ev,currentTarget)=>{const{data:_data,modifiers}=filterOutModifiersFromData(data);data=_data;let stopped=false;if(modifiers.length){let selfMode=false;const isSelf=ev.target===currentTarget;for(const mod of modifiers){switch(mod){case"self":selfMode=true;if(isSelf){continue;}
else{return stopped;}
case"prevent":if((selfMode&&isSelf)||!selfMode)
ev.preventDefault();continue;case"stop":if((selfMode&&isSelf)||!selfMode)
ev.stopPropagation();stopped=true;continue;}}}
if(Object.hasOwnProperty.call(data,0)){const handler=data[0];if(typeof handler!=="function"){throw new OwlError(`Invalid handler (expected a function, received: '${handler}')`);}
let node=data[1]?data[1].__owl__:null;if(node?node.status===1:true){handler.call(node?node.component:null,ev);}}
return stopped;};function status(component){switch(component.__owl__.status){case 0:return"new";case 2:return"cancelled";case 1:return"mounted";case 3:return"destroyed";}}
function useRef(name){const node=getCurrent();const refs=node.refs;return{get el(){const el=refs[name];return inOwnerDocument(el)?el:null;},};}
function useEnv(){return getCurrent().component.env;}
function extendEnv(currentEnv,extension){const env=Object.create(currentEnv);const descrs=Object.getOwnPropertyDescriptors(extension);return Object.freeze(Object.defineProperties(env,descrs));}
function useSubEnv(envExtension){const node=getCurrent();node.component.env=extendEnv(node.component.env,envExtension);useChildSubEnv(envExtension);}
function useChildSubEnv(envExtension){const node=getCurrent();node.childEnv=extendEnv(node.childEnv,envExtension);}
function useEffect(effect,computeDependencies=()=>[NaN]){let cleanup;let dependencies;onMounted(()=>{dependencies=computeDependencies();cleanup=effect(...dependencies);});onPatched(()=>{const newDeps=computeDependencies();const shouldReapply=newDeps.some((val,i)=>val!==dependencies[i]);if(shouldReapply){dependencies=newDeps;if(cleanup){cleanup();}
cleanup=effect(...dependencies);}});onWillUnmount(()=>cleanup&&cleanup());}
function useExternalListener(target,eventName,handler,eventParams){const node=getCurrent();const boundHandler=handler.bind(node.component);onMounted(()=>target.addEventListener(eventName,boundHandler,eventParams));onWillUnmount(()=>target.removeEventListener(eventName,boundHandler,eventParams));}
config.shouldNormalizeDom=false;config.mainEventHandler=mainEventHandler;const blockDom={config,mount:mount$1,patch,remove,list,multi,text,toggler,createBlock,html,comment,};const __info__={version:App.version,};TemplateSet.prototype._compileTemplate=function _compileTemplate(name,template){return compile(template,{name,dev:this.dev,translateFn:this.translateFn,translatableAttributes:this.translatableAttributes,});};exports.App=App;exports.Component=Component;exports.EventBus=EventBus;exports.OwlError=OwlError;exports.__info__=__info__;exports.batched=batched;exports.blockDom=blockDom;exports.loadFile=loadFile;exports.markRaw=markRaw;exports.markup=markup;exports.mount=mount;exports.onError=onError;exports.onMounted=onMounted;exports.onPatched=onPatched;exports.onRendered=onRendered;exports.onWillDestroy=onWillDestroy;exports.onWillPatch=onWillPatch;exports.onWillRender=onWillRender;exports.onWillStart=onWillStart;exports.onWillUnmount=onWillUnmount;exports.onWillUpdateProps=onWillUpdateProps;exports.reactive=reactive;exports.status=status;exports.toRaw=toRaw;exports.useChildSubEnv=useChildSubEnv;exports.useComponent=useComponent;exports.useEffect=useEffect;exports.useEnv=useEnv;exports.useExternalListener=useExternalListener;exports.useRef=useRef;exports.useState=useState;exports.useSubEnv=useSubEnv;exports.validate=validate;exports.validateType=validateType;exports.whenReady=whenReady;exports.xml=xml;Object.defineProperty(exports,'__esModule',{value:true});__info__.date='2024-09-30T08:49:29.420Z';__info__.hash='eb2b32a';__info__.url='https://github.com/odoo/owl';})(this.owl=this.owl||{});;

/* /web/static/lib/owl/odoo_module.js */
odoo.define("@odoo/owl",[],function(){"use strict";return owl;});;

/* /web/static/lib/jquery/jquery.js */
(function(global,factory){"use strict";if(typeof module==="object"&&typeof module.exports==="object"){module.exports=global.document?factory(global,true):function(w){if(!w.document){throw new Error("jQuery requires a window with a document");}
return factory(w);};}else{factory(global);}})(typeof window!=="undefined"?window:this,function(window,noGlobal){"use strict";var arr=[];var getProto=Object.getPrototypeOf;var slice=arr.slice;var flat=arr.flat?function(array){return arr.flat.call(array);}:function(array){return arr.concat.apply([],array);};var push=arr.push;var indexOf=arr.indexOf;var class2type={};var toString=class2type.toString;var hasOwn=class2type.hasOwnProperty;var fnToString=hasOwn.toString;var ObjectFunctionString=fnToString.call(Object);var support={};var isFunction=function isFunction(obj){return typeof obj==="function"&&typeof obj.nodeType!=="number"&&typeof obj.item!=="function";};var isWindow=function isWindow(obj){return obj!=null&&obj===obj.window;};var document=window.document;var preservedScriptAttributes={type:true,src:true,nonce:true,noModule:true};function DOMEval(code,node,doc){doc=doc||document;var i,val,script=doc.createElement("script");script.text=code;if(node){for(i in preservedScriptAttributes){val=node[i]||node.getAttribute&&node.getAttribute(i);if(val){script.setAttribute(i,val);}}}
doc.head.appendChild(script).parentNode.removeChild(script);}
function toType(obj){if(obj==null){return obj+"";}
return typeof obj==="object"||typeof obj==="function"?class2type[toString.call(obj)]||"object":typeof obj;}
var
version="3.6.3",jQuery=function(selector,context){return new jQuery.fn.init(selector,context);};jQuery.fn=jQuery.prototype={jquery:version,constructor:jQuery,length:0,toArray:function(){return slice.call(this);},get:function(num){if(num==null){return slice.call(this);}
return num<0?this[num+this.length]:this[num];},pushStack:function(elems){var ret=jQuery.merge(this.constructor(),elems);ret.prevObject=this;return ret;},each:function(callback){return jQuery.each(this,callback);},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},slice:function(){return this.pushStack(slice.apply(this,arguments));},first:function(){return this.eq(0);},last:function(){return this.eq(-1);},even:function(){return this.pushStack(jQuery.grep(this,function(_elem,i){return(i+1)%2;}));},odd:function(){return this.pushStack(jQuery.grep(this,function(_elem,i){return i%2;}));},eq:function(i){var len=this.length,j=+i+(i<0?len:0);return this.pushStack(j>=0&&j<len?[this[j]]:[]);},end:function(){return this.prevObject||this.constructor();},push:push,sort:arr.sort,splice:arr.splice};jQuery.extend=jQuery.fn.extend=function(){var options,name,src,copy,copyIsArray,clone,target=arguments[0]||{},i=1,length=arguments.length,deep=false;if(typeof target==="boolean"){deep=target;target=arguments[i]||{};i++;}
if(typeof target!=="object"&&!isFunction(target)){target={};}
if(i===length){target=this;i--;}
for(;i<length;i++){if((options=arguments[i])!=null){for(name in options){copy=options[name];if(name==="__proto__"||target===copy){continue;}
if(deep&&copy&&(jQuery.isPlainObject(copy)||(copyIsArray=Array.isArray(copy)))){src=target[name];if(copyIsArray&&!Array.isArray(src)){clone=[];}else if(!copyIsArray&&!jQuery.isPlainObject(src)){clone={};}else{clone=src;}
copyIsArray=false;target[name]=jQuery.extend(deep,clone,copy);}else if(copy!==undefined){target[name]=copy;}}}}
return target;};jQuery.extend({expando:"jQuery"+(version+Math.random()).replace(/\D/g,""),isReady:true,error:function(msg){throw new Error(msg);},noop:function(){},isPlainObject:function(obj){var proto,Ctor;if(!obj||toString.call(obj)!=="[object Object]"){return false;}
proto=getProto(obj);if(!proto){return true;}
Ctor=hasOwn.call(proto,"constructor")&&proto.constructor;return typeof Ctor==="function"&&fnToString.call(Ctor)===ObjectFunctionString;},isEmptyObject:function(obj){var name;for(name in obj){return false;}
return true;},globalEval:function(code,options,doc){DOMEval(code,{nonce:options&&options.nonce},doc);},each:function(obj,callback){var length,i=0;if(isArrayLike(obj)){length=obj.length;for(;i<length;i++){if(callback.call(obj[i],i,obj[i])===false){break;}}}else{for(i in obj){if(callback.call(obj[i],i,obj[i])===false){break;}}}
return obj;},makeArray:function(arr,results){var ret=results||[];if(arr!=null){if(isArrayLike(Object(arr))){jQuery.merge(ret,typeof arr==="string"?[arr]:arr);}else{push.call(ret,arr);}}
return ret;},inArray:function(elem,arr,i){return arr==null?-1:indexOf.call(arr,elem,i);},merge:function(first,second){var len=+second.length,j=0,i=first.length;for(;j<len;j++){first[i++]=second[j];}
first.length=i;return first;},grep:function(elems,callback,invert){var callbackInverse,matches=[],i=0,length=elems.length,callbackExpect=!invert;for(;i<length;i++){callbackInverse=!callback(elems[i],i);if(callbackInverse!==callbackExpect){matches.push(elems[i]);}}
return matches;},map:function(elems,callback,arg){var length,value,i=0,ret=[];if(isArrayLike(elems)){length=elems.length;for(;i<length;i++){value=callback(elems[i],i,arg);if(value!=null){ret.push(value);}}}else{for(i in elems){value=callback(elems[i],i,arg);if(value!=null){ret.push(value);}}}
return flat(ret);},guid:1,support:support});if(typeof Symbol==="function"){jQuery.fn[Symbol.iterator]=arr[Symbol.iterator];}
jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(_i,name){class2type["[object "+name+"]"]=name.toLowerCase();});function isArrayLike(obj){var length=!!obj&&"length"in obj&&obj.length,type=toType(obj);if(isFunction(obj)||isWindow(obj)){return false;}
return type==="array"||length===0||typeof length==="number"&&length>0&&(length-1)in obj;}
var Sizzle=(function(window){var i,support,Expr,getText,isXML,tokenize,compile,select,outermostContext,sortInput,hasDuplicate,setDocument,document,docElem,documentIsHTML,rbuggyQSA,rbuggyMatches,matches,contains,expando="sizzle"+1*new Date(),preferredDoc=window.document,dirruns=0,done=0,classCache=createCache(),tokenCache=createCache(),compilerCache=createCache(),nonnativeSelectorCache=createCache(),sortOrder=function(a,b){if(a===b){hasDuplicate=true;}
return 0;},hasOwn=({}).hasOwnProperty,arr=[],pop=arr.pop,pushNative=arr.push,push=arr.push,slice=arr.slice,indexOf=function(list,elem){var i=0,len=list.length;for(;i<len;i++){if(list[i]===elem){return i;}}
return-1;},booleans="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|"+"ismap|loop|multiple|open|readonly|required|scoped",whitespace="[\\x20\\t\\r\\n\\f]",identifier="(?:\\\\[\\da-fA-F]{1,6}"+whitespace+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",attributes="\\["+whitespace+"*("+identifier+")(?:"+whitespace+"*([*^$|!~]?=)"+whitespace+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+identifier+"))|)"+
whitespace+"*\\]",pseudos=":("+identifier+")(?:\\(("+"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|"+"((?:\\\\.|[^\\\\()[\\]]|"+attributes+")*)|"+".*"+")\\)|)",rwhitespace=new RegExp(whitespace+"+","g"),rtrim=new RegExp("^"+whitespace+"+|((?:^|[^\\\\])(?:\\\\.)*)"+
whitespace+"+$","g"),rcomma=new RegExp("^"+whitespace+"*,"+whitespace+"*"),rcombinators=new RegExp("^"+whitespace+"*([>+~]|"+whitespace+")"+whitespace+"*"),rdescend=new RegExp(whitespace+"|>"),rpseudo=new RegExp(pseudos),ridentifier=new RegExp("^"+identifier+"$"),matchExpr={"ID":new RegExp("^#("+identifier+")"),"CLASS":new RegExp("^\\.("+identifier+")"),"TAG":new RegExp("^("+identifier+"|[*])"),"ATTR":new RegExp("^"+attributes),"PSEUDO":new RegExp("^"+pseudos),"CHILD":new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+
whitespace+"*(even|odd|(([+-]|)(\\d*)n|)"+whitespace+"*(?:([+-]|)"+
whitespace+"*(\\d+)|))"+whitespace+"*\\)|)","i"),"bool":new RegExp("^(?:"+booleans+")$","i"),"needsContext":new RegExp("^"+whitespace+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+whitespace+"*((?:-\\d)?\\d*)"+whitespace+"*\\)|)(?=[^-]|$)","i")},rhtml=/HTML$/i,rinputs=/^(?:input|select|textarea|button)$/i,rheader=/^h\d$/i,rnative=/^[^{]+\{\s*\[native \w/,rquickExpr=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,rsibling=/[+~]/,runescape=new RegExp("\\\\[\\da-fA-F]{1,6}"+whitespace+"?|\\\\([^\\r\\n\\f])","g"),funescape=function(escape,nonHex){var high="0x"+escape.slice(1)-0x10000;return nonHex?nonHex:high<0?String.fromCharCode(high+0x10000):String.fromCharCode(high>>10|0xD800,high&0x3FF|0xDC00);},rcssescape=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,fcssescape=function(ch,asCodePoint){if(asCodePoint){if(ch==="\0"){return"\uFFFD";}
return ch.slice(0,-1)+"\\"+
ch.charCodeAt(ch.length-1).toString(16)+" ";}
return"\\"+ch;},unloadHandler=function(){setDocument();},inDisabledFieldset=addCombinator(function(elem){return elem.disabled===true&&elem.nodeName.toLowerCase()==="fieldset";},{dir:"parentNode",next:"legend"});try{push.apply((arr=slice.call(preferredDoc.childNodes)),preferredDoc.childNodes);arr[preferredDoc.childNodes.length].nodeType;}catch(e){push={apply:arr.length?function(target,els){pushNative.apply(target,slice.call(els));}:function(target,els){var j=target.length,i=0;while((target[j++]=els[i++])){}
target.length=j-1;}};}
function Sizzle(selector,context,results,seed){var m,i,elem,nid,match,groups,newSelector,newContext=context&&context.ownerDocument,nodeType=context?context.nodeType:9;results=results||[];if(typeof selector!=="string"||!selector||nodeType!==1&&nodeType!==9&&nodeType!==11){return results;}
if(!seed){setDocument(context);context=context||document;if(documentIsHTML){if(nodeType!==11&&(match=rquickExpr.exec(selector))){if((m=match[1])){if(nodeType===9){if((elem=context.getElementById(m))){if(elem.id===m){results.push(elem);return results;}}else{return results;}}else{if(newContext&&(elem=newContext.getElementById(m))&&contains(context,elem)&&elem.id===m){results.push(elem);return results;}}}else if(match[2]){push.apply(results,context.getElementsByTagName(selector));return results;}else if((m=match[3])&&support.getElementsByClassName&&context.getElementsByClassName){push.apply(results,context.getElementsByClassName(m));return results;}}
if(support.qsa&&!nonnativeSelectorCache[selector+" "]&&(!rbuggyQSA||!rbuggyQSA.test(selector))&&(nodeType!==1||context.nodeName.toLowerCase()!=="object")){newSelector=selector;newContext=context;if(nodeType===1&&(rdescend.test(selector)||rcombinators.test(selector))){newContext=rsibling.test(selector)&&testContext(context.parentNode)||context;if(newContext!==context||!support.scope){if((nid=context.getAttribute("id"))){nid=nid.replace(rcssescape,fcssescape);}else{context.setAttribute("id",(nid=expando));}}
groups=tokenize(selector);i=groups.length;while(i--){groups[i]=(nid?"#"+nid:":scope")+" "+
toSelector(groups[i]);}
newSelector=groups.join(",");}
try{if(support.cssSupportsSelector&&!CSS.supports("selector(:is("+newSelector+"))")){throw new Error();}
push.apply(results,newContext.querySelectorAll(newSelector));return results;}catch(qsaError){nonnativeSelectorCache(selector,true);}finally{if(nid===expando){context.removeAttribute("id");}}}}}
return select(selector.replace(rtrim,"$1"),context,results,seed);}
function createCache(){var keys=[];function cache(key,value){if(keys.push(key+" ")>Expr.cacheLength){delete cache[keys.shift()];}
return(cache[key+" "]=value);}
return cache;}
function markFunction(fn){fn[expando]=true;return fn;}
function assert(fn){var el=document.createElement("fieldset");try{return!!fn(el);}catch(e){return false;}finally{if(el.parentNode){el.parentNode.removeChild(el);}
el=null;}}
function addHandle(attrs,handler){var arr=attrs.split("|"),i=arr.length;while(i--){Expr.attrHandle[arr[i]]=handler;}}
function siblingCheck(a,b){var cur=b&&a,diff=cur&&a.nodeType===1&&b.nodeType===1&&a.sourceIndex-b.sourceIndex;if(diff){return diff;}
if(cur){while((cur=cur.nextSibling)){if(cur===b){return-1;}}}
return a?1:-1;}
function createInputPseudo(type){return function(elem){var name=elem.nodeName.toLowerCase();return name==="input"&&elem.type===type;};}
function createButtonPseudo(type){return function(elem){var name=elem.nodeName.toLowerCase();return(name==="input"||name==="button")&&elem.type===type;};}
function createDisabledPseudo(disabled){return function(elem){if("form"in elem){if(elem.parentNode&&elem.disabled===false){if("label"in elem){if("label"in elem.parentNode){return elem.parentNode.disabled===disabled;}else{return elem.disabled===disabled;}}
return elem.isDisabled===disabled||elem.isDisabled!==!disabled&&inDisabledFieldset(elem)===disabled;}
return elem.disabled===disabled;}else if("label"in elem){return elem.disabled===disabled;}
return false;};}
function createPositionalPseudo(fn){return markFunction(function(argument){argument=+argument;return markFunction(function(seed,matches){var j,matchIndexes=fn([],seed.length,argument),i=matchIndexes.length;while(i--){if(seed[(j=matchIndexes[i])]){seed[j]=!(matches[j]=seed[j]);}}});});}
function testContext(context){return context&&typeof context.getElementsByTagName!=="undefined"&&context;}
support=Sizzle.support={};isXML=Sizzle.isXML=function(elem){var namespace=elem&&elem.namespaceURI,docElem=elem&&(elem.ownerDocument||elem).documentElement;return!rhtml.test(namespace||docElem&&docElem.nodeName||"HTML");};setDocument=Sizzle.setDocument=function(node){var hasCompare,subWindow,doc=node?node.ownerDocument||node:preferredDoc;if(doc==document||doc.nodeType!==9||!doc.documentElement){return document;}
document=doc;docElem=document.documentElement;documentIsHTML=!isXML(document);if(preferredDoc!=document&&(subWindow=document.defaultView)&&subWindow.top!==subWindow){if(subWindow.addEventListener){subWindow.addEventListener("unload",unloadHandler,false);}else if(subWindow.attachEvent){subWindow.attachEvent("onunload",unloadHandler);}}
support.scope=assert(function(el){docElem.appendChild(el).appendChild(document.createElement("div"));return typeof el.querySelectorAll!=="undefined"&&!el.querySelectorAll(":scope fieldset div").length;});support.cssSupportsSelector=assert(function(){return CSS.supports("selector(*)")&&document.querySelectorAll(":is(:jqfake)")&&!CSS.supports("selector(:is(*,:jqfake))");});support.attributes=assert(function(el){el.className="i";return!el.getAttribute("className");});support.getElementsByTagName=assert(function(el){el.appendChild(document.createComment(""));return!el.getElementsByTagName("*").length;});support.getElementsByClassName=rnative.test(document.getElementsByClassName);support.getById=assert(function(el){docElem.appendChild(el).id=expando;return!document.getElementsByName||!document.getElementsByName(expando).length;});if(support.getById){Expr.filter["ID"]=function(id){var attrId=id.replace(runescape,funescape);return function(elem){return elem.getAttribute("id")===attrId;};};Expr.find["ID"]=function(id,context){if(typeof context.getElementById!=="undefined"&&documentIsHTML){var elem=context.getElementById(id);return elem?[elem]:[];}};}else{Expr.filter["ID"]=function(id){var attrId=id.replace(runescape,funescape);return function(elem){var node=typeof elem.getAttributeNode!=="undefined"&&elem.getAttributeNode("id");return node&&node.value===attrId;};};Expr.find["ID"]=function(id,context){if(typeof context.getElementById!=="undefined"&&documentIsHTML){var node,i,elems,elem=context.getElementById(id);if(elem){node=elem.getAttributeNode("id");if(node&&node.value===id){return[elem];}
elems=context.getElementsByName(id);i=0;while((elem=elems[i++])){node=elem.getAttributeNode("id");if(node&&node.value===id){return[elem];}}}
return[];}};}
Expr.find["TAG"]=support.getElementsByTagName?function(tag,context){if(typeof context.getElementsByTagName!=="undefined"){return context.getElementsByTagName(tag);}else if(support.qsa){return context.querySelectorAll(tag);}}:function(tag,context){var elem,tmp=[],i=0,results=context.getElementsByTagName(tag);if(tag==="*"){while((elem=results[i++])){if(elem.nodeType===1){tmp.push(elem);}}
return tmp;}
return results;};Expr.find["CLASS"]=support.getElementsByClassName&&function(className,context){if(typeof context.getElementsByClassName!=="undefined"&&documentIsHTML){return context.getElementsByClassName(className);}};rbuggyMatches=[];rbuggyQSA=[];if((support.qsa=rnative.test(document.querySelectorAll))){assert(function(el){var input;docElem.appendChild(el).innerHTML="<a id='"+expando+"'></a>"+"<select id='"+expando+"-\r\\' msallowcapture=''>"+"<option selected=''></option></select>";if(el.querySelectorAll("[msallowcapture^='']").length){rbuggyQSA.push("[*^$]="+whitespace+"*(?:''|\"\")");}
if(!el.querySelectorAll("[selected]").length){rbuggyQSA.push("\\["+whitespace+"*(?:value|"+booleans+")");}
if(!el.querySelectorAll("[id~="+expando+"-]").length){rbuggyQSA.push("~=");}
input=document.createElement("input");input.setAttribute("name","");el.appendChild(input);if(!el.querySelectorAll("[name='']").length){rbuggyQSA.push("\\["+whitespace+"*name"+whitespace+"*="+
whitespace+"*(?:''|\"\")");}
if(!el.querySelectorAll(":checked").length){rbuggyQSA.push(":checked");}
if(!el.querySelectorAll("a#"+expando+"+*").length){rbuggyQSA.push(".#.+[+~]");}});assert(function(el){el.innerHTML="<a href='' disabled='disabled'></a>"+"<select disabled='disabled'><option/></select>";var input=document.createElement("input");input.setAttribute("type","hidden");el.appendChild(input).setAttribute("name","D");if(el.querySelectorAll("[name=d]").length){rbuggyQSA.push("name"+whitespace+"*[*^$|!~]?=");}
if(el.querySelectorAll(":enabled").length!==2){rbuggyQSA.push(":enabled",":disabled");}
docElem.appendChild(el).disabled=true;if(el.querySelectorAll(":disabled").length!==2){rbuggyQSA.push(":enabled",":disabled");}});}
if((support.matchesSelector=rnative.test((matches=docElem.matches||docElem.webkitMatchesSelector||docElem.mozMatchesSelector||docElem.oMatchesSelector||docElem.msMatchesSelector)))){assert(function(el){support.disconnectedMatch=matches.call(el,"*");});}
if(!support.cssSupportsSelector){rbuggyQSA.push(":has");}
rbuggyQSA=rbuggyQSA.length&&new RegExp(rbuggyQSA.join("|"));rbuggyMatches=rbuggyMatches.length&&new RegExp(rbuggyMatches.join("|"));hasCompare=rnative.test(docElem.compareDocumentPosition);contains=hasCompare||rnative.test(docElem.contains)?function(a,b){var adown=a.nodeType===9&&a.documentElement||a,bup=b&&b.parentNode;return a===bup||!!(bup&&bup.nodeType===1&&(adown.contains?adown.contains(bup):a.compareDocumentPosition&&a.compareDocumentPosition(bup)&16));}:function(a,b){if(b){while((b=b.parentNode)){if(b===a){return true;}}}
return false;};sortOrder=hasCompare?function(a,b){if(a===b){hasDuplicate=true;return 0;}
var compare=!a.compareDocumentPosition-!b.compareDocumentPosition;if(compare){return compare;}
compare=(a.ownerDocument||a)==(b.ownerDocument||b)?a.compareDocumentPosition(b):1;if(compare&1||(!support.sortDetached&&b.compareDocumentPosition(a)===compare)){if(a==document||a.ownerDocument==preferredDoc&&contains(preferredDoc,a)){return-1;}
if(b==document||b.ownerDocument==preferredDoc&&contains(preferredDoc,b)){return 1;}
return sortInput?(indexOf(sortInput,a)-indexOf(sortInput,b)):0;}
return compare&4?-1:1;}:function(a,b){if(a===b){hasDuplicate=true;return 0;}
var cur,i=0,aup=a.parentNode,bup=b.parentNode,ap=[a],bp=[b];if(!aup||!bup){return a==document?-1:b==document?1:aup?-1:bup?1:sortInput?(indexOf(sortInput,a)-indexOf(sortInput,b)):0;}else if(aup===bup){return siblingCheck(a,b);}
cur=a;while((cur=cur.parentNode)){ap.unshift(cur);}
cur=b;while((cur=cur.parentNode)){bp.unshift(cur);}
while(ap[i]===bp[i]){i++;}
return i?siblingCheck(ap[i],bp[i]):ap[i]==preferredDoc?-1:bp[i]==preferredDoc?1:0;};return document;};Sizzle.matches=function(expr,elements){return Sizzle(expr,null,null,elements);};Sizzle.matchesSelector=function(elem,expr){setDocument(elem);if(support.matchesSelector&&documentIsHTML&&!nonnativeSelectorCache[expr+" "]&&(!rbuggyMatches||!rbuggyMatches.test(expr))&&(!rbuggyQSA||!rbuggyQSA.test(expr))){try{var ret=matches.call(elem,expr);if(ret||support.disconnectedMatch||elem.document&&elem.document.nodeType!==11){return ret;}}catch(e){nonnativeSelectorCache(expr,true);}}
return Sizzle(expr,document,null,[elem]).length>0;};Sizzle.contains=function(context,elem){if((context.ownerDocument||context)!=document){setDocument(context);}
return contains(context,elem);};Sizzle.attr=function(elem,name){if((elem.ownerDocument||elem)!=document){setDocument(elem);}
var fn=Expr.attrHandle[name.toLowerCase()],val=fn&&hasOwn.call(Expr.attrHandle,name.toLowerCase())?fn(elem,name,!documentIsHTML):undefined;return val!==undefined?val:support.attributes||!documentIsHTML?elem.getAttribute(name):(val=elem.getAttributeNode(name))&&val.specified?val.value:null;};Sizzle.escape=function(sel){return(sel+"").replace(rcssescape,fcssescape);};Sizzle.error=function(msg){throw new Error("Syntax error, unrecognized expression: "+msg);};Sizzle.uniqueSort=function(results){var elem,duplicates=[],j=0,i=0;hasDuplicate=!support.detectDuplicates;sortInput=!support.sortStable&&results.slice(0);results.sort(sortOrder);if(hasDuplicate){while((elem=results[i++])){if(elem===results[i]){j=duplicates.push(i);}}
while(j--){results.splice(duplicates[j],1);}}
sortInput=null;return results;};getText=Sizzle.getText=function(elem){var node,ret="",i=0,nodeType=elem.nodeType;if(!nodeType){while((node=elem[i++])){ret+=getText(node);}}else if(nodeType===1||nodeType===9||nodeType===11){if(typeof elem.textContent==="string"){return elem.textContent;}else{for(elem=elem.firstChild;elem;elem=elem.nextSibling){ret+=getText(elem);}}}else if(nodeType===3||nodeType===4){return elem.nodeValue;}
return ret;};Expr=Sizzle.selectors={cacheLength:50,createPseudo:markFunction,match:matchExpr,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:true}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:true},"~":{dir:"previousSibling"}},preFilter:{"ATTR":function(match){match[1]=match[1].replace(runescape,funescape);match[3]=(match[3]||match[4]||match[5]||"").replace(runescape,funescape);if(match[2]==="~="){match[3]=" "+match[3]+" ";}
return match.slice(0,4);},"CHILD":function(match){match[1]=match[1].toLowerCase();if(match[1].slice(0,3)==="nth"){if(!match[3]){Sizzle.error(match[0]);}
match[4]=+(match[4]?match[5]+(match[6]||1):2*(match[3]==="even"||match[3]==="odd"));match[5]=+((match[7]+match[8])||match[3]==="odd");}else if(match[3]){Sizzle.error(match[0]);}
return match;},"PSEUDO":function(match){var excess,unquoted=!match[6]&&match[2];if(matchExpr["CHILD"].test(match[0])){return null;}
if(match[3]){match[2]=match[4]||match[5]||"";}else if(unquoted&&rpseudo.test(unquoted)&&(excess=tokenize(unquoted,true))&&(excess=unquoted.indexOf(")",unquoted.length-excess)-unquoted.length)){match[0]=match[0].slice(0,excess);match[2]=unquoted.slice(0,excess);}
return match.slice(0,3);}},filter:{"TAG":function(nodeNameSelector){var nodeName=nodeNameSelector.replace(runescape,funescape).toLowerCase();return nodeNameSelector==="*"?function(){return true;}:function(elem){return elem.nodeName&&elem.nodeName.toLowerCase()===nodeName;};},"CLASS":function(className){var pattern=classCache[className+" "];return pattern||(pattern=new RegExp("(^|"+whitespace+")"+className+"("+whitespace+"|$)"))&&classCache(className,function(elem){return pattern.test(typeof elem.className==="string"&&elem.className||typeof elem.getAttribute!=="undefined"&&elem.getAttribute("class")||"");});},"ATTR":function(name,operator,check){return function(elem){var result=Sizzle.attr(elem,name);if(result==null){return operator==="!=";}
if(!operator){return true;}
result+="";return operator==="="?result===check:operator==="!="?result!==check:operator==="^="?check&&result.indexOf(check)===0:operator==="*="?check&&result.indexOf(check)>-1:operator==="$="?check&&result.slice(-check.length)===check:operator==="~="?(" "+result.replace(rwhitespace," ")+" ").indexOf(check)>-1:operator==="|="?result===check||result.slice(0,check.length+1)===check+"-":false;};},"CHILD":function(type,what,_argument,first,last){var simple=type.slice(0,3)!=="nth",forward=type.slice(-4)!=="last",ofType=what==="of-type";return first===1&&last===0?function(elem){return!!elem.parentNode;}:function(elem,_context,xml){var cache,uniqueCache,outerCache,node,nodeIndex,start,dir=simple!==forward?"nextSibling":"previousSibling",parent=elem.parentNode,name=ofType&&elem.nodeName.toLowerCase(),useCache=!xml&&!ofType,diff=false;if(parent){if(simple){while(dir){node=elem;while((node=node[dir])){if(ofType?node.nodeName.toLowerCase()===name:node.nodeType===1){return false;}}
start=dir=type==="only"&&!start&&"nextSibling";}
return true;}
start=[forward?parent.firstChild:parent.lastChild];if(forward&&useCache){node=parent;outerCache=node[expando]||(node[expando]={});uniqueCache=outerCache[node.uniqueID]||(outerCache[node.uniqueID]={});cache=uniqueCache[type]||[];nodeIndex=cache[0]===dirruns&&cache[1];diff=nodeIndex&&cache[2];node=nodeIndex&&parent.childNodes[nodeIndex];while((node=++nodeIndex&&node&&node[dir]||(diff=nodeIndex=0)||start.pop())){if(node.nodeType===1&&++diff&&node===elem){uniqueCache[type]=[dirruns,nodeIndex,diff];break;}}}else{if(useCache){node=elem;outerCache=node[expando]||(node[expando]={});uniqueCache=outerCache[node.uniqueID]||(outerCache[node.uniqueID]={});cache=uniqueCache[type]||[];nodeIndex=cache[0]===dirruns&&cache[1];diff=nodeIndex;}
if(diff===false){while((node=++nodeIndex&&node&&node[dir]||(diff=nodeIndex=0)||start.pop())){if((ofType?node.nodeName.toLowerCase()===name:node.nodeType===1)&&++diff){if(useCache){outerCache=node[expando]||(node[expando]={});uniqueCache=outerCache[node.uniqueID]||(outerCache[node.uniqueID]={});uniqueCache[type]=[dirruns,diff];}
if(node===elem){break;}}}}}
diff-=last;return diff===first||(diff%first===0&&diff/first>=0);}};},"PSEUDO":function(pseudo,argument){var args,fn=Expr.pseudos[pseudo]||Expr.setFilters[pseudo.toLowerCase()]||Sizzle.error("unsupported pseudo: "+pseudo);if(fn[expando]){return fn(argument);}
if(fn.length>1){args=[pseudo,pseudo,"",argument];return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase())?markFunction(function(seed,matches){var idx,matched=fn(seed,argument),i=matched.length;while(i--){idx=indexOf(seed,matched[i]);seed[idx]=!(matches[idx]=matched[i]);}}):function(elem){return fn(elem,0,args);};}
return fn;}},pseudos:{"not":markFunction(function(selector){var input=[],results=[],matcher=compile(selector.replace(rtrim,"$1"));return matcher[expando]?markFunction(function(seed,matches,_context,xml){var elem,unmatched=matcher(seed,null,xml,[]),i=seed.length;while(i--){if((elem=unmatched[i])){seed[i]=!(matches[i]=elem);}}}):function(elem,_context,xml){input[0]=elem;matcher(input,null,xml,results);input[0]=null;return!results.pop();};}),"has":markFunction(function(selector){return function(elem){return Sizzle(selector,elem).length>0;};}),"contains":markFunction(function(text){text=text.replace(runescape,funescape);return function(elem){return(elem.textContent||getText(elem)).indexOf(text)>-1;};}),"lang":markFunction(function(lang){if(!ridentifier.test(lang||"")){Sizzle.error("unsupported lang: "+lang);}
lang=lang.replace(runescape,funescape).toLowerCase();return function(elem){var elemLang;do{if((elemLang=documentIsHTML?elem.lang:elem.getAttribute("xml:lang")||elem.getAttribute("lang"))){elemLang=elemLang.toLowerCase();return elemLang===lang||elemLang.indexOf(lang+"-")===0;}}while((elem=elem.parentNode)&&elem.nodeType===1);return false;};}),"target":function(elem){var hash=window.location&&window.location.hash;return hash&&hash.slice(1)===elem.id;},"root":function(elem){return elem===docElem;},"focus":function(elem){return elem===document.activeElement&&(!document.hasFocus||document.hasFocus())&&!!(elem.type||elem.href||~elem.tabIndex);},"enabled":createDisabledPseudo(false),"disabled":createDisabledPseudo(true),"checked":function(elem){var nodeName=elem.nodeName.toLowerCase();return(nodeName==="input"&&!!elem.checked)||(nodeName==="option"&&!!elem.selected);},"selected":function(elem){if(elem.parentNode){elem.parentNode.selectedIndex;}
return elem.selected===true;},"empty":function(elem){for(elem=elem.firstChild;elem;elem=elem.nextSibling){if(elem.nodeType<6){return false;}}
return true;},"parent":function(elem){return!Expr.pseudos["empty"](elem);},"header":function(elem){return rheader.test(elem.nodeName);},"input":function(elem){return rinputs.test(elem.nodeName);},"button":function(elem){var name=elem.nodeName.toLowerCase();return name==="input"&&elem.type==="button"||name==="button";},"text":function(elem){var attr;return elem.nodeName.toLowerCase()==="input"&&elem.type==="text"&&((attr=elem.getAttribute("type"))==null||attr.toLowerCase()==="text");},"first":createPositionalPseudo(function(){return[0];}),"last":createPositionalPseudo(function(_matchIndexes,length){return[length-1];}),"eq":createPositionalPseudo(function(_matchIndexes,length,argument){return[argument<0?argument+length:argument];}),"even":createPositionalPseudo(function(matchIndexes,length){var i=0;for(;i<length;i+=2){matchIndexes.push(i);}
return matchIndexes;}),"odd":createPositionalPseudo(function(matchIndexes,length){var i=1;for(;i<length;i+=2){matchIndexes.push(i);}
return matchIndexes;}),"lt":createPositionalPseudo(function(matchIndexes,length,argument){var i=argument<0?argument+length:argument>length?length:argument;for(;--i>=0;){matchIndexes.push(i);}
return matchIndexes;}),"gt":createPositionalPseudo(function(matchIndexes,length,argument){var i=argument<0?argument+length:argument;for(;++i<length;){matchIndexes.push(i);}
return matchIndexes;})}};Expr.pseudos["nth"]=Expr.pseudos["eq"];for(i in{radio:true,checkbox:true,file:true,password:true,image:true}){Expr.pseudos[i]=createInputPseudo(i);}
for(i in{submit:true,reset:true}){Expr.pseudos[i]=createButtonPseudo(i);}
function setFilters(){}
setFilters.prototype=Expr.filters=Expr.pseudos;Expr.setFilters=new setFilters();tokenize=Sizzle.tokenize=function(selector,parseOnly){var matched,match,tokens,type,soFar,groups,preFilters,cached=tokenCache[selector+" "];if(cached){return parseOnly?0:cached.slice(0);}
soFar=selector;groups=[];preFilters=Expr.preFilter;while(soFar){if(!matched||(match=rcomma.exec(soFar))){if(match){soFar=soFar.slice(match[0].length)||soFar;}
groups.push((tokens=[]));}
matched=false;if((match=rcombinators.exec(soFar))){matched=match.shift();tokens.push({value:matched,type:match[0].replace(rtrim," ")});soFar=soFar.slice(matched.length);}
for(type in Expr.filter){if((match=matchExpr[type].exec(soFar))&&(!preFilters[type]||(match=preFilters[type](match)))){matched=match.shift();tokens.push({value:matched,type:type,matches:match});soFar=soFar.slice(matched.length);}}
if(!matched){break;}}
return parseOnly?soFar.length:soFar?Sizzle.error(selector):tokenCache(selector,groups).slice(0);};function toSelector(tokens){var i=0,len=tokens.length,selector="";for(;i<len;i++){selector+=tokens[i].value;}
return selector;}
function addCombinator(matcher,combinator,base){var dir=combinator.dir,skip=combinator.next,key=skip||dir,checkNonElements=base&&key==="parentNode",doneName=done++;return combinator.first?function(elem,context,xml){while((elem=elem[dir])){if(elem.nodeType===1||checkNonElements){return matcher(elem,context,xml);}}
return false;}:function(elem,context,xml){var oldCache,uniqueCache,outerCache,newCache=[dirruns,doneName];if(xml){while((elem=elem[dir])){if(elem.nodeType===1||checkNonElements){if(matcher(elem,context,xml)){return true;}}}}else{while((elem=elem[dir])){if(elem.nodeType===1||checkNonElements){outerCache=elem[expando]||(elem[expando]={});uniqueCache=outerCache[elem.uniqueID]||(outerCache[elem.uniqueID]={});if(skip&&skip===elem.nodeName.toLowerCase()){elem=elem[dir]||elem;}else if((oldCache=uniqueCache[key])&&oldCache[0]===dirruns&&oldCache[1]===doneName){return(newCache[2]=oldCache[2]);}else{uniqueCache[key]=newCache;if((newCache[2]=matcher(elem,context,xml))){return true;}}}}}
return false;};}
function elementMatcher(matchers){return matchers.length>1?function(elem,context,xml){var i=matchers.length;while(i--){if(!matchers[i](elem,context,xml)){return false;}}
return true;}:matchers[0];}
function multipleContexts(selector,contexts,results){var i=0,len=contexts.length;for(;i<len;i++){Sizzle(selector,contexts[i],results);}
return results;}
function condense(unmatched,map,filter,context,xml){var elem,newUnmatched=[],i=0,len=unmatched.length,mapped=map!=null;for(;i<len;i++){if((elem=unmatched[i])){if(!filter||filter(elem,context,xml)){newUnmatched.push(elem);if(mapped){map.push(i);}}}}
return newUnmatched;}
function setMatcher(preFilter,selector,matcher,postFilter,postFinder,postSelector){if(postFilter&&!postFilter[expando]){postFilter=setMatcher(postFilter);}
if(postFinder&&!postFinder[expando]){postFinder=setMatcher(postFinder,postSelector);}
return markFunction(function(seed,results,context,xml){var temp,i,elem,preMap=[],postMap=[],preexisting=results.length,elems=seed||multipleContexts(selector||"*",context.nodeType?[context]:context,[]),matcherIn=preFilter&&(seed||!selector)?condense(elems,preMap,preFilter,context,xml):elems,matcherOut=matcher?postFinder||(seed?preFilter:preexisting||postFilter)?[]:results:matcherIn;if(matcher){matcher(matcherIn,matcherOut,context,xml);}
if(postFilter){temp=condense(matcherOut,postMap);postFilter(temp,[],context,xml);i=temp.length;while(i--){if((elem=temp[i])){matcherOut[postMap[i]]=!(matcherIn[postMap[i]]=elem);}}}
if(seed){if(postFinder||preFilter){if(postFinder){temp=[];i=matcherOut.length;while(i--){if((elem=matcherOut[i])){temp.push((matcherIn[i]=elem));}}
postFinder(null,(matcherOut=[]),temp,xml);}
i=matcherOut.length;while(i--){if((elem=matcherOut[i])&&(temp=postFinder?indexOf(seed,elem):preMap[i])>-1){seed[temp]=!(results[temp]=elem);}}}}else{matcherOut=condense(matcherOut===results?matcherOut.splice(preexisting,matcherOut.length):matcherOut);if(postFinder){postFinder(null,results,matcherOut,xml);}else{push.apply(results,matcherOut);}}});}
function matcherFromTokens(tokens){var checkContext,matcher,j,len=tokens.length,leadingRelative=Expr.relative[tokens[0].type],implicitRelative=leadingRelative||Expr.relative[" "],i=leadingRelative?1:0,matchContext=addCombinator(function(elem){return elem===checkContext;},implicitRelative,true),matchAnyContext=addCombinator(function(elem){return indexOf(checkContext,elem)>-1;},implicitRelative,true),matchers=[function(elem,context,xml){var ret=(!leadingRelative&&(xml||context!==outermostContext))||((checkContext=context).nodeType?matchContext(elem,context,xml):matchAnyContext(elem,context,xml));checkContext=null;return ret;}];for(;i<len;i++){if((matcher=Expr.relative[tokens[i].type])){matchers=[addCombinator(elementMatcher(matchers),matcher)];}else{matcher=Expr.filter[tokens[i].type].apply(null,tokens[i].matches);if(matcher[expando]){j=++i;for(;j<len;j++){if(Expr.relative[tokens[j].type]){break;}}
return setMatcher(i>1&&elementMatcher(matchers),i>1&&toSelector(tokens.slice(0,i-1).concat({value:tokens[i-2].type===" "?"*":""})).replace(rtrim,"$1"),matcher,i<j&&matcherFromTokens(tokens.slice(i,j)),j<len&&matcherFromTokens((tokens=tokens.slice(j))),j<len&&toSelector(tokens));}
matchers.push(matcher);}}
return elementMatcher(matchers);}
function matcherFromGroupMatchers(elementMatchers,setMatchers){var bySet=setMatchers.length>0,byElement=elementMatchers.length>0,superMatcher=function(seed,context,xml,results,outermost){var elem,j,matcher,matchedCount=0,i="0",unmatched=seed&&[],setMatched=[],contextBackup=outermostContext,elems=seed||byElement&&Expr.find["TAG"]("*",outermost),dirrunsUnique=(dirruns+=contextBackup==null?1:Math.random()||0.1),len=elems.length;if(outermost){outermostContext=context==document||context||outermost;}
for(;i!==len&&(elem=elems[i])!=null;i++){if(byElement&&elem){j=0;if(!context&&elem.ownerDocument!=document){setDocument(elem);xml=!documentIsHTML;}
while((matcher=elementMatchers[j++])){if(matcher(elem,context||document,xml)){results.push(elem);break;}}
if(outermost){dirruns=dirrunsUnique;}}
if(bySet){if((elem=!matcher&&elem)){matchedCount--;}
if(seed){unmatched.push(elem);}}}
matchedCount+=i;if(bySet&&i!==matchedCount){j=0;while((matcher=setMatchers[j++])){matcher(unmatched,setMatched,context,xml);}
if(seed){if(matchedCount>0){while(i--){if(!(unmatched[i]||setMatched[i])){setMatched[i]=pop.call(results);}}}
setMatched=condense(setMatched);}
push.apply(results,setMatched);if(outermost&&!seed&&setMatched.length>0&&(matchedCount+setMatchers.length)>1){Sizzle.uniqueSort(results);}}
if(outermost){dirruns=dirrunsUnique;outermostContext=contextBackup;}
return unmatched;};return bySet?markFunction(superMatcher):superMatcher;}
compile=Sizzle.compile=function(selector,match){var i,setMatchers=[],elementMatchers=[],cached=compilerCache[selector+" "];if(!cached){if(!match){match=tokenize(selector);}
i=match.length;while(i--){cached=matcherFromTokens(match[i]);if(cached[expando]){setMatchers.push(cached);}else{elementMatchers.push(cached);}}
cached=compilerCache(selector,matcherFromGroupMatchers(elementMatchers,setMatchers));cached.selector=selector;}
return cached;};select=Sizzle.select=function(selector,context,results,seed){var i,tokens,token,type,find,compiled=typeof selector==="function"&&selector,match=!seed&&tokenize((selector=compiled.selector||selector));results=results||[];if(match.length===1){tokens=match[0]=match[0].slice(0);if(tokens.length>2&&(token=tokens[0]).type==="ID"&&context.nodeType===9&&documentIsHTML&&Expr.relative[tokens[1].type]){context=(Expr.find["ID"](token.matches[0].replace(runescape,funescape),context)||[])[0];if(!context){return results;}else if(compiled){context=context.parentNode;}
selector=selector.slice(tokens.shift().value.length);}
i=matchExpr["needsContext"].test(selector)?0:tokens.length;while(i--){token=tokens[i];if(Expr.relative[(type=token.type)]){break;}
if((find=Expr.find[type])){if((seed=find(token.matches[0].replace(runescape,funescape),rsibling.test(tokens[0].type)&&testContext(context.parentNode)||context))){tokens.splice(i,1);selector=seed.length&&toSelector(tokens);if(!selector){push.apply(results,seed);return results;}
break;}}}}
(compiled||compile(selector,match))(seed,context,!documentIsHTML,results,!context||rsibling.test(selector)&&testContext(context.parentNode)||context);return results;};support.sortStable=expando.split("").sort(sortOrder).join("")===expando;support.detectDuplicates=!!hasDuplicate;setDocument();support.sortDetached=assert(function(el){return el.compareDocumentPosition(document.createElement("fieldset"))&1;});if(!assert(function(el){el.innerHTML="<a href='#'></a>";return el.firstChild.getAttribute("href")==="#";})){addHandle("type|href|height|width",function(elem,name,isXML){if(!isXML){return elem.getAttribute(name,name.toLowerCase()==="type"?1:2);}});}
if(!support.attributes||!assert(function(el){el.innerHTML="<input/>";el.firstChild.setAttribute("value","");return el.firstChild.getAttribute("value")==="";})){addHandle("value",function(elem,_name,isXML){if(!isXML&&elem.nodeName.toLowerCase()==="input"){return elem.defaultValue;}});}
if(!assert(function(el){return el.getAttribute("disabled")==null;})){addHandle(booleans,function(elem,name,isXML){var val;if(!isXML){return elem[name]===true?name.toLowerCase():(val=elem.getAttributeNode(name))&&val.specified?val.value:null;}});}
return Sizzle;})(window);jQuery.find=Sizzle;jQuery.expr=Sizzle.selectors;jQuery.expr[":"]=jQuery.expr.pseudos;jQuery.uniqueSort=jQuery.unique=Sizzle.uniqueSort;jQuery.text=Sizzle.getText;jQuery.isXMLDoc=Sizzle.isXML;jQuery.contains=Sizzle.contains;jQuery.escapeSelector=Sizzle.escape;var dir=function(elem,dir,until){var matched=[],truncate=until!==undefined;while((elem=elem[dir])&&elem.nodeType!==9){if(elem.nodeType===1){if(truncate&&jQuery(elem).is(until)){break;}
matched.push(elem);}}
return matched;};var siblings=function(n,elem){var matched=[];for(;n;n=n.nextSibling){if(n.nodeType===1&&n!==elem){matched.push(n);}}
return matched;};var rneedsContext=jQuery.expr.match.needsContext;function nodeName(elem,name){return elem.nodeName&&elem.nodeName.toLowerCase()===name.toLowerCase();}
var rsingleTag=(/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i);function winnow(elements,qualifier,not){if(isFunction(qualifier)){return jQuery.grep(elements,function(elem,i){return!!qualifier.call(elem,i,elem)!==not;});}
if(qualifier.nodeType){return jQuery.grep(elements,function(elem){return(elem===qualifier)!==not;});}
if(typeof qualifier!=="string"){return jQuery.grep(elements,function(elem){return(indexOf.call(qualifier,elem)>-1)!==not;});}
return jQuery.filter(qualifier,elements,not);}
jQuery.filter=function(expr,elems,not){var elem=elems[0];if(not){expr=":not("+expr+")";}
if(elems.length===1&&elem.nodeType===1){return jQuery.find.matchesSelector(elem,expr)?[elem]:[];}
return jQuery.find.matches(expr,jQuery.grep(elems,function(elem){return elem.nodeType===1;}));};jQuery.fn.extend({find:function(selector){var i,ret,len=this.length,self=this;if(typeof selector!=="string"){return this.pushStack(jQuery(selector).filter(function(){for(i=0;i<len;i++){if(jQuery.contains(self[i],this)){return true;}}}));}
ret=this.pushStack([]);for(i=0;i<len;i++){jQuery.find(selector,self[i],ret);}
return len>1?jQuery.uniqueSort(ret):ret;},filter:function(selector){return this.pushStack(winnow(this,selector||[],false));},not:function(selector){return this.pushStack(winnow(this,selector||[],true));},is:function(selector){return!!winnow(this,typeof selector==="string"&&rneedsContext.test(selector)?jQuery(selector):selector||[],false).length;}});var rootjQuery,rquickExpr=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,init=jQuery.fn.init=function(selector,context,root){var match,elem;if(!selector){return this;}
root=root||rootjQuery;if(typeof selector==="string"){if(selector[0]==="<"&&selector[selector.length-1]===">"&&selector.length>=3){match=[null,selector,null];}else{match=rquickExpr.exec(selector);}
if(match&&(match[1]||!context)){if(match[1]){context=context instanceof jQuery?context[0]:context;jQuery.merge(this,jQuery.parseHTML(match[1],context&&context.nodeType?context.ownerDocument||context:document,true));if(rsingleTag.test(match[1])&&jQuery.isPlainObject(context)){for(match in context){if(isFunction(this[match])){this[match](context[match]);}else{this.attr(match,context[match]);}}}
return this;}else{elem=document.getElementById(match[2]);if(elem){this[0]=elem;this.length=1;}
return this;}}else if(!context||context.jquery){return(context||root).find(selector);}else{return this.constructor(context).find(selector);}}else if(selector.nodeType){this[0]=selector;this.length=1;return this;}else if(isFunction(selector)){return root.ready!==undefined?root.ready(selector):selector(jQuery);}
return jQuery.makeArray(selector,this);};init.prototype=jQuery.fn;rootjQuery=jQuery(document);var rparentsprev=/^(?:parents|prev(?:Until|All))/,guaranteedUnique={children:true,contents:true,next:true,prev:true};jQuery.fn.extend({has:function(target){var targets=jQuery(target,this),l=targets.length;return this.filter(function(){var i=0;for(;i<l;i++){if(jQuery.contains(this,targets[i])){return true;}}});},closest:function(selectors,context){var cur,i=0,l=this.length,matched=[],targets=typeof selectors!=="string"&&jQuery(selectors);if(!rneedsContext.test(selectors)){for(;i<l;i++){for(cur=this[i];cur&&cur!==context;cur=cur.parentNode){if(cur.nodeType<11&&(targets?targets.index(cur)>-1:cur.nodeType===1&&jQuery.find.matchesSelector(cur,selectors))){matched.push(cur);break;}}}}
return this.pushStack(matched.length>1?jQuery.uniqueSort(matched):matched);},index:function(elem){if(!elem){return(this[0]&&this[0].parentNode)?this.first().prevAll().length:-1;}
if(typeof elem==="string"){return indexOf.call(jQuery(elem),this[0]);}
return indexOf.call(this,elem.jquery?elem[0]:elem);},add:function(selector,context){return this.pushStack(jQuery.uniqueSort(jQuery.merge(this.get(),jQuery(selector,context))));},addBack:function(selector){return this.add(selector==null?this.prevObject:this.prevObject.filter(selector));}});function sibling(cur,dir){while((cur=cur[dir])&&cur.nodeType!==1){}
return cur;}
jQuery.each({parent:function(elem){var parent=elem.parentNode;return parent&&parent.nodeType!==11?parent:null;},parents:function(elem){return dir(elem,"parentNode");},parentsUntil:function(elem,_i,until){return dir(elem,"parentNode",until);},next:function(elem){return sibling(elem,"nextSibling");},prev:function(elem){return sibling(elem,"previousSibling");},nextAll:function(elem){return dir(elem,"nextSibling");},prevAll:function(elem){return dir(elem,"previousSibling");},nextUntil:function(elem,_i,until){return dir(elem,"nextSibling",until);},prevUntil:function(elem,_i,until){return dir(elem,"previousSibling",until);},siblings:function(elem){return siblings((elem.parentNode||{}).firstChild,elem);},children:function(elem){return siblings(elem.firstChild);},contents:function(elem){if(elem.contentDocument!=null&&getProto(elem.contentDocument)){return elem.contentDocument;}
if(nodeName(elem,"template")){elem=elem.content||elem;}
return jQuery.merge([],elem.childNodes);}},function(name,fn){jQuery.fn[name]=function(until,selector){var matched=jQuery.map(this,fn,until);if(name.slice(-5)!=="Until"){selector=until;}
if(selector&&typeof selector==="string"){matched=jQuery.filter(selector,matched);}
if(this.length>1){if(!guaranteedUnique[name]){jQuery.uniqueSort(matched);}
if(rparentsprev.test(name)){matched.reverse();}}
return this.pushStack(matched);};});var rnothtmlwhite=(/[^\x20\t\r\n\f]+/g);function createOptions(options){var object={};jQuery.each(options.match(rnothtmlwhite)||[],function(_,flag){object[flag]=true;});return object;}
jQuery.Callbacks=function(options){options=typeof options==="string"?createOptions(options):jQuery.extend({},options);var
firing,memory,fired,locked,list=[],queue=[],firingIndex=-1,fire=function(){locked=locked||options.once;fired=firing=true;for(;queue.length;firingIndex=-1){memory=queue.shift();while(++firingIndex<list.length){if(list[firingIndex].apply(memory[0],memory[1])===false&&options.stopOnFalse){firingIndex=list.length;memory=false;}}}
if(!options.memory){memory=false;}
firing=false;if(locked){if(memory){list=[];}else{list="";}}},self={add:function(){if(list){if(memory&&!firing){firingIndex=list.length-1;queue.push(memory);}
(function add(args){jQuery.each(args,function(_,arg){if(isFunction(arg)){if(!options.unique||!self.has(arg)){list.push(arg);}}else if(arg&&arg.length&&toType(arg)!=="string"){add(arg);}});})(arguments);if(memory&&!firing){fire();}}
return this;},remove:function(){jQuery.each(arguments,function(_,arg){var index;while((index=jQuery.inArray(arg,list,index))>-1){list.splice(index,1);if(index<=firingIndex){firingIndex--;}}});return this;},has:function(fn){return fn?jQuery.inArray(fn,list)>-1:list.length>0;},empty:function(){if(list){list=[];}
return this;},disable:function(){locked=queue=[];list=memory="";return this;},disabled:function(){return!list;},lock:function(){locked=queue=[];if(!memory&&!firing){list=memory="";}
return this;},locked:function(){return!!locked;},fireWith:function(context,args){if(!locked){args=args||[];args=[context,args.slice?args.slice():args];queue.push(args);if(!firing){fire();}}
return this;},fire:function(){self.fireWith(this,arguments);return this;},fired:function(){return!!fired;}};return self;};function Identity(v){return v;}
function Thrower(ex){throw ex;}
function adoptValue(value,resolve,reject,noValue){var method;try{if(value&&isFunction((method=value.promise))){method.call(value).done(resolve).fail(reject);}else if(value&&isFunction((method=value.then))){method.call(value,resolve,reject);}else{resolve.apply(undefined,[value].slice(noValue));}}catch(value){reject.apply(undefined,[value]);}}
jQuery.extend({Deferred:function(func){var tuples=[["notify","progress",jQuery.Callbacks("memory"),jQuery.Callbacks("memory"),2],["resolve","done",jQuery.Callbacks("once memory"),jQuery.Callbacks("once memory"),0,"resolved"],["reject","fail",jQuery.Callbacks("once memory"),jQuery.Callbacks("once memory"),1,"rejected"]],state="pending",promise={state:function(){return state;},always:function(){deferred.done(arguments).fail(arguments);return this;},"catch":function(fn){return promise.then(null,fn);},pipe:function(){var fns=arguments;return jQuery.Deferred(function(newDefer){jQuery.each(tuples,function(_i,tuple){var fn=isFunction(fns[tuple[4]])&&fns[tuple[4]];deferred[tuple[1]](function(){var returned=fn&&fn.apply(this,arguments);if(returned&&isFunction(returned.promise)){returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject);}else{newDefer[tuple[0]+"With"](this,fn?[returned]:arguments);}});});fns=null;}).promise();},then:function(onFulfilled,onRejected,onProgress){var maxDepth=0;function resolve(depth,deferred,handler,special){return function(){var that=this,args=arguments,mightThrow=function(){var returned,then;if(depth<maxDepth){return;}
returned=handler.apply(that,args);if(returned===deferred.promise()){throw new TypeError("Thenable self-resolution");}
then=returned&&(typeof returned==="object"||typeof returned==="function")&&returned.then;if(isFunction(then)){if(special){then.call(returned,resolve(maxDepth,deferred,Identity,special),resolve(maxDepth,deferred,Thrower,special));}else{maxDepth++;then.call(returned,resolve(maxDepth,deferred,Identity,special),resolve(maxDepth,deferred,Thrower,special),resolve(maxDepth,deferred,Identity,deferred.notifyWith));}}else{if(handler!==Identity){that=undefined;args=[returned];}
(special||deferred.resolveWith)(that,args);}},process=special?mightThrow:function(){try{mightThrow();}catch(e){if(jQuery.Deferred.exceptionHook){jQuery.Deferred.exceptionHook(e,process.stackTrace);}
if(depth+1>=maxDepth){if(handler!==Thrower){that=undefined;args=[e];}
deferred.rejectWith(that,args);}}};if(depth){process();}else{if(jQuery.Deferred.getStackHook){process.stackTrace=jQuery.Deferred.getStackHook();}
window.setTimeout(process);}};}
return jQuery.Deferred(function(newDefer){tuples[0][3].add(resolve(0,newDefer,isFunction(onProgress)?onProgress:Identity,newDefer.notifyWith));tuples[1][3].add(resolve(0,newDefer,isFunction(onFulfilled)?onFulfilled:Identity));tuples[2][3].add(resolve(0,newDefer,isFunction(onRejected)?onRejected:Thrower));}).promise();},promise:function(obj){return obj!=null?jQuery.extend(obj,promise):promise;}},deferred={};jQuery.each(tuples,function(i,tuple){var list=tuple[2],stateString=tuple[5];promise[tuple[1]]=list.add;if(stateString){list.add(function(){state=stateString;},tuples[3-i][2].disable,tuples[3-i][3].disable,tuples[0][2].lock,tuples[0][3].lock);}
list.add(tuple[3].fire);deferred[tuple[0]]=function(){deferred[tuple[0]+"With"](this===deferred?undefined:this,arguments);return this;};deferred[tuple[0]+"With"]=list.fireWith;});promise.promise(deferred);if(func){func.call(deferred,deferred);}
return deferred;},when:function(singleValue){var
remaining=arguments.length,i=remaining,resolveContexts=Array(i),resolveValues=slice.call(arguments),primary=jQuery.Deferred(),updateFunc=function(i){return function(value){resolveContexts[i]=this;resolveValues[i]=arguments.length>1?slice.call(arguments):value;if(!(--remaining)){primary.resolveWith(resolveContexts,resolveValues);}};};if(remaining<=1){adoptValue(singleValue,primary.done(updateFunc(i)).resolve,primary.reject,!remaining);if(primary.state()==="pending"||isFunction(resolveValues[i]&&resolveValues[i].then)){return primary.then();}}
while(i--){adoptValue(resolveValues[i],updateFunc(i),primary.reject);}
return primary.promise();}});var rerrorNames=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;jQuery.Deferred.exceptionHook=function(error,stack){if(window.console&&window.console.warn&&error&&rerrorNames.test(error.name)){window.console.warn("jQuery.Deferred exception: "+error.message,error.stack,stack);}};jQuery.readyException=function(error){window.setTimeout(function(){throw error;});};var readyList=jQuery.Deferred();jQuery.fn.ready=function(fn){readyList.then(fn).catch(function(error){jQuery.readyException(error);});return this;};jQuery.extend({isReady:false,readyWait:1,ready:function(wait){if(wait===true?--jQuery.readyWait:jQuery.isReady){return;}
jQuery.isReady=true;if(wait!==true&&--jQuery.readyWait>0){return;}
readyList.resolveWith(document,[jQuery]);}});jQuery.ready.then=readyList.then;function completed(){document.removeEventListener("DOMContentLoaded",completed);window.removeEventListener("load",completed);jQuery.ready();}
if(document.readyState==="complete"||(document.readyState!=="loading"&&!document.documentElement.doScroll)){window.setTimeout(jQuery.ready);}else{document.addEventListener("DOMContentLoaded",completed);window.addEventListener("load",completed);}
var access=function(elems,fn,key,value,chainable,emptyGet,raw){var i=0,len=elems.length,bulk=key==null;if(toType(key)==="object"){chainable=true;for(i in key){access(elems,fn,i,key[i],true,emptyGet,raw);}}else if(value!==undefined){chainable=true;if(!isFunction(value)){raw=true;}
if(bulk){if(raw){fn.call(elems,value);fn=null;}else{bulk=fn;fn=function(elem,_key,value){return bulk.call(jQuery(elem),value);};}}
if(fn){for(;i<len;i++){fn(elems[i],key,raw?value:value.call(elems[i],i,fn(elems[i],key)));}}}
if(chainable){return elems;}
if(bulk){return fn.call(elems);}
return len?fn(elems[0],key):emptyGet;};var rmsPrefix=/^-ms-/,rdashAlpha=/-([a-z])/g;function fcamelCase(_all,letter){return letter.toUpperCase();}
function camelCase(string){return string.replace(rmsPrefix,"ms-").replace(rdashAlpha,fcamelCase);}
var acceptData=function(owner){return owner.nodeType===1||owner.nodeType===9||!(+owner.nodeType);};function Data(){this.expando=jQuery.expando+Data.uid++;}
Data.uid=1;Data.prototype={cache:function(owner){var value=owner[this.expando];if(!value){value={};if(acceptData(owner)){if(owner.nodeType){owner[this.expando]=value;}else{Object.defineProperty(owner,this.expando,{value:value,configurable:true});}}}
return value;},set:function(owner,data,value){var prop,cache=this.cache(owner);if(typeof data==="string"){cache[camelCase(data)]=value;}else{for(prop in data){cache[camelCase(prop)]=data[prop];}}
return cache;},get:function(owner,key){return key===undefined?this.cache(owner):owner[this.expando]&&owner[this.expando][camelCase(key)];},access:function(owner,key,value){if(key===undefined||((key&&typeof key==="string")&&value===undefined)){return this.get(owner,key);}
this.set(owner,key,value);return value!==undefined?value:key;},remove:function(owner,key){var i,cache=owner[this.expando];if(cache===undefined){return;}
if(key!==undefined){if(Array.isArray(key)){key=key.map(camelCase);}else{key=camelCase(key);key=key in cache?[key]:(key.match(rnothtmlwhite)||[]);}
i=key.length;while(i--){delete cache[key[i]];}}
if(key===undefined||jQuery.isEmptyObject(cache)){if(owner.nodeType){owner[this.expando]=undefined;}else{delete owner[this.expando];}}},hasData:function(owner){var cache=owner[this.expando];return cache!==undefined&&!jQuery.isEmptyObject(cache);}};var dataPriv=new Data();var dataUser=new Data();var rbrace=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,rmultiDash=/[A-Z]/g;function getData(data){if(data==="true"){return true;}
if(data==="false"){return false;}
if(data==="null"){return null;}
if(data===+data+""){return+data;}
if(rbrace.test(data)){return JSON.parse(data);}
return data;}
function dataAttr(elem,key,data){var name;if(data===undefined&&elem.nodeType===1){name="data-"+key.replace(rmultiDash,"-$&").toLowerCase();data=elem.getAttribute(name);if(typeof data==="string"){try{data=getData(data);}catch(e){}
dataUser.set(elem,key,data);}else{data=undefined;}}
return data;}
jQuery.extend({hasData:function(elem){return dataUser.hasData(elem)||dataPriv.hasData(elem);},data:function(elem,name,data){return dataUser.access(elem,name,data);},removeData:function(elem,name){dataUser.remove(elem,name);},_data:function(elem,name,data){return dataPriv.access(elem,name,data);},_removeData:function(elem,name){dataPriv.remove(elem,name);}});jQuery.fn.extend({data:function(key,value){var i,name,data,elem=this[0],attrs=elem&&elem.attributes;if(key===undefined){if(this.length){data=dataUser.get(elem);if(elem.nodeType===1&&!dataPriv.get(elem,"hasDataAttrs")){i=attrs.length;while(i--){if(attrs[i]){name=attrs[i].name;if(name.indexOf("data-")===0){name=camelCase(name.slice(5));dataAttr(elem,name,data[name]);}}}
dataPriv.set(elem,"hasDataAttrs",true);}}
return data;}
if(typeof key==="object"){return this.each(function(){dataUser.set(this,key);});}
return access(this,function(value){var data;if(elem&&value===undefined){data=dataUser.get(elem,key);if(data!==undefined){return data;}
data=dataAttr(elem,key);if(data!==undefined){return data;}
return;}
this.each(function(){dataUser.set(this,key,value);});},null,value,arguments.length>1,null,true);},removeData:function(key){return this.each(function(){dataUser.remove(this,key);});}});jQuery.extend({queue:function(elem,type,data){var queue;if(elem){type=(type||"fx")+"queue";queue=dataPriv.get(elem,type);if(data){if(!queue||Array.isArray(data)){queue=dataPriv.access(elem,type,jQuery.makeArray(data));}else{queue.push(data);}}
return queue||[];}},dequeue:function(elem,type){type=type||"fx";var queue=jQuery.queue(elem,type),startLength=queue.length,fn=queue.shift(),hooks=jQuery._queueHooks(elem,type),next=function(){jQuery.dequeue(elem,type);};if(fn==="inprogress"){fn=queue.shift();startLength--;}
if(fn){if(type==="fx"){queue.unshift("inprogress");}
delete hooks.stop;fn.call(elem,next,hooks);}
if(!startLength&&hooks){hooks.empty.fire();}},_queueHooks:function(elem,type){var key=type+"queueHooks";return dataPriv.get(elem,key)||dataPriv.access(elem,key,{empty:jQuery.Callbacks("once memory").add(function(){dataPriv.remove(elem,[type+"queue",key]);})});}});jQuery.fn.extend({queue:function(type,data){var setter=2;if(typeof type!=="string"){data=type;type="fx";setter--;}
if(arguments.length<setter){return jQuery.queue(this[0],type);}
return data===undefined?this:this.each(function(){var queue=jQuery.queue(this,type,data);jQuery._queueHooks(this,type);if(type==="fx"&&queue[0]!=="inprogress"){jQuery.dequeue(this,type);}});},dequeue:function(type){return this.each(function(){jQuery.dequeue(this,type);});},clearQueue:function(type){return this.queue(type||"fx",[]);},promise:function(type,obj){var tmp,count=1,defer=jQuery.Deferred(),elements=this,i=this.length,resolve=function(){if(!(--count)){defer.resolveWith(elements,[elements]);}};if(typeof type!=="string"){obj=type;type=undefined;}
type=type||"fx";while(i--){tmp=dataPriv.get(elements[i],type+"queueHooks");if(tmp&&tmp.empty){count++;tmp.empty.add(resolve);}}
resolve();return defer.promise(obj);}});var pnum=(/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;var rcssNum=new RegExp("^(?:([+-])=|)("+pnum+")([a-z%]*)$","i");var cssExpand=["Top","Right","Bottom","Left"];var documentElement=document.documentElement;var isAttached=function(elem){return jQuery.contains(elem.ownerDocument,elem);},composed={composed:true};if(documentElement.getRootNode){isAttached=function(elem){return jQuery.contains(elem.ownerDocument,elem)||elem.getRootNode(composed)===elem.ownerDocument;};}
var isHiddenWithinTree=function(elem,el){elem=el||elem;return elem.style.display==="none"||elem.style.display===""&&isAttached(elem)&&jQuery.css(elem,"display")==="none";};function adjustCSS(elem,prop,valueParts,tween){var adjusted,scale,maxIterations=20,currentValue=tween?function(){return tween.cur();}:function(){return jQuery.css(elem,prop,"");},initial=currentValue(),unit=valueParts&&valueParts[3]||(jQuery.cssNumber[prop]?"":"px"),initialInUnit=elem.nodeType&&(jQuery.cssNumber[prop]||unit!=="px"&&+initial)&&rcssNum.exec(jQuery.css(elem,prop));if(initialInUnit&&initialInUnit[3]!==unit){initial=initial/2;unit=unit||initialInUnit[3];initialInUnit=+initial||1;while(maxIterations--){jQuery.style(elem,prop,initialInUnit+unit);if((1-scale)*(1-(scale=currentValue()/initial||0.5))<=0){maxIterations=0;}
initialInUnit=initialInUnit/scale;}
initialInUnit=initialInUnit*2;jQuery.style(elem,prop,initialInUnit+unit);valueParts=valueParts||[];}
if(valueParts){initialInUnit=+initialInUnit||+initial||0;adjusted=valueParts[1]?initialInUnit+(valueParts[1]+1)*valueParts[2]:+valueParts[2];if(tween){tween.unit=unit;tween.start=initialInUnit;tween.end=adjusted;}}
return adjusted;}
var defaultDisplayMap={};function getDefaultDisplay(elem){var temp,doc=elem.ownerDocument,nodeName=elem.nodeName,display=defaultDisplayMap[nodeName];if(display){return display;}
temp=doc.body.appendChild(doc.createElement(nodeName));display=jQuery.css(temp,"display");temp.parentNode.removeChild(temp);if(display==="none"){display="block";}
defaultDisplayMap[nodeName]=display;return display;}
function showHide(elements,show){var display,elem,values=[],index=0,length=elements.length;for(;index<length;index++){elem=elements[index];if(!elem.style){continue;}
display=elem.style.display;if(show){if(display==="none"){values[index]=dataPriv.get(elem,"display")||null;if(!values[index]){elem.style.display="";}}
if(elem.style.display===""&&isHiddenWithinTree(elem)){values[index]=getDefaultDisplay(elem);}}else{if(display!=="none"){values[index]="none";dataPriv.set(elem,"display",display);}}}
for(index=0;index<length;index++){if(values[index]!=null){elements[index].style.display=values[index];}}
return elements;}
jQuery.fn.extend({show:function(){return showHide(this,true);},hide:function(){return showHide(this);},toggle:function(state){if(typeof state==="boolean"){return state?this.show():this.hide();}
return this.each(function(){if(isHiddenWithinTree(this)){jQuery(this).show();}else{jQuery(this).hide();}});}});var rcheckableType=(/^(?:checkbox|radio)$/i);var rtagName=(/<([a-z][^\/\0>\x20\t\r\n\f]*)/i);var rscriptType=(/^$|^module$|\/(?:java|ecma)script/i);(function(){var fragment=document.createDocumentFragment(),div=fragment.appendChild(document.createElement("div")),input=document.createElement("input");input.setAttribute("type","radio");input.setAttribute("checked","checked");input.setAttribute("name","t");div.appendChild(input);support.checkClone=div.cloneNode(true).cloneNode(true).lastChild.checked;div.innerHTML="<textarea>x</textarea>";support.noCloneChecked=!!div.cloneNode(true).lastChild.defaultValue;div.innerHTML="<option></option>";support.option=!!div.lastChild;})();var wrapMap={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};wrapMap.tbody=wrapMap.tfoot=wrapMap.colgroup=wrapMap.caption=wrapMap.thead;wrapMap.th=wrapMap.td;if(!support.option){wrapMap.optgroup=wrapMap.option=[1,"<select multiple='multiple'>","</select>"];}
function getAll(context,tag){var ret;if(typeof context.getElementsByTagName!=="undefined"){ret=context.getElementsByTagName(tag||"*");}else if(typeof context.querySelectorAll!=="undefined"){ret=context.querySelectorAll(tag||"*");}else{ret=[];}
if(tag===undefined||tag&&nodeName(context,tag)){return jQuery.merge([context],ret);}
return ret;}
function setGlobalEval(elems,refElements){var i=0,l=elems.length;for(;i<l;i++){dataPriv.set(elems[i],"globalEval",!refElements||dataPriv.get(refElements[i],"globalEval"));}}
var rhtml=/<|&#?\w+;/;function buildFragment(elems,context,scripts,selection,ignored){var elem,tmp,tag,wrap,attached,j,fragment=context.createDocumentFragment(),nodes=[],i=0,l=elems.length;for(;i<l;i++){elem=elems[i];if(elem||elem===0){if(toType(elem)==="object"){jQuery.merge(nodes,elem.nodeType?[elem]:elem);}else if(!rhtml.test(elem)){nodes.push(context.createTextNode(elem));}else{tmp=tmp||fragment.appendChild(context.createElement("div"));tag=(rtagName.exec(elem)||["",""])[1].toLowerCase();wrap=wrapMap[tag]||wrapMap._default;tmp.innerHTML=wrap[1]+jQuery.htmlPrefilter(elem)+wrap[2];j=wrap[0];while(j--){tmp=tmp.lastChild;}
jQuery.merge(nodes,tmp.childNodes);tmp=fragment.firstChild;tmp.textContent="";}}}
fragment.textContent="";i=0;while((elem=nodes[i++])){if(selection&&jQuery.inArray(elem,selection)>-1){if(ignored){ignored.push(elem);}
continue;}
attached=isAttached(elem);tmp=getAll(fragment.appendChild(elem),"script");if(attached){setGlobalEval(tmp);}
if(scripts){j=0;while((elem=tmp[j++])){if(rscriptType.test(elem.type||"")){scripts.push(elem);}}}}
return fragment;}
var rtypenamespace=/^([^.]*)(?:\.(.+)|)/;function returnTrue(){return true;}
function returnFalse(){return false;}
function expectSync(elem,type){return(elem===safeActiveElement())===(type==="focus");}
function safeActiveElement(){try{return document.activeElement;}catch(err){}}
function on(elem,types,selector,data,fn,one){var origFn,type;if(typeof types==="object"){if(typeof selector!=="string"){data=data||selector;selector=undefined;}
for(type in types){on(elem,type,selector,data,types[type],one);}
return elem;}
if(data==null&&fn==null){fn=selector;data=selector=undefined;}else if(fn==null){if(typeof selector==="string"){fn=data;data=undefined;}else{fn=data;data=selector;selector=undefined;}}
if(fn===false){fn=returnFalse;}else if(!fn){return elem;}
if(one===1){origFn=fn;fn=function(event){jQuery().off(event);return origFn.apply(this,arguments);};fn.guid=origFn.guid||(origFn.guid=jQuery.guid++);}
return elem.each(function(){jQuery.event.add(this,types,fn,data,selector);});}
jQuery.event={global:{},add:function(elem,types,handler,data,selector){var handleObjIn,eventHandle,tmp,events,t,handleObj,special,handlers,type,namespaces,origType,elemData=dataPriv.get(elem);if(!acceptData(elem)){return;}
if(handler.handler){handleObjIn=handler;handler=handleObjIn.handler;selector=handleObjIn.selector;}
if(selector){jQuery.find.matchesSelector(documentElement,selector);}
if(!handler.guid){handler.guid=jQuery.guid++;}
if(!(events=elemData.events)){events=elemData.events=Object.create(null);}
if(!(eventHandle=elemData.handle)){eventHandle=elemData.handle=function(e){return typeof jQuery!=="undefined"&&jQuery.event.triggered!==e.type?jQuery.event.dispatch.apply(elem,arguments):undefined;};}
types=(types||"").match(rnothtmlwhite)||[""];t=types.length;while(t--){tmp=rtypenamespace.exec(types[t])||[];type=origType=tmp[1];namespaces=(tmp[2]||"").split(".").sort();if(!type){continue;}
special=jQuery.event.special[type]||{};type=(selector?special.delegateType:special.bindType)||type;special=jQuery.event.special[type]||{};handleObj=jQuery.extend({type:type,origType:origType,data:data,handler:handler,guid:handler.guid,selector:selector,needsContext:selector&&jQuery.expr.match.needsContext.test(selector),namespace:namespaces.join(".")},handleObjIn);if(!(handlers=events[type])){handlers=events[type]=[];handlers.delegateCount=0;if(!special.setup||special.setup.call(elem,data,namespaces,eventHandle)===false){if(elem.addEventListener){elem.addEventListener(type,eventHandle);}}}
if(special.add){special.add.call(elem,handleObj);if(!handleObj.handler.guid){handleObj.handler.guid=handler.guid;}}
if(selector){handlers.splice(handlers.delegateCount++,0,handleObj);}else{handlers.push(handleObj);}
jQuery.event.global[type]=true;}},remove:function(elem,types,handler,selector,mappedTypes){var j,origCount,tmp,events,t,handleObj,special,handlers,type,namespaces,origType,elemData=dataPriv.hasData(elem)&&dataPriv.get(elem);if(!elemData||!(events=elemData.events)){return;}
types=(types||"").match(rnothtmlwhite)||[""];t=types.length;while(t--){tmp=rtypenamespace.exec(types[t])||[];type=origType=tmp[1];namespaces=(tmp[2]||"").split(".").sort();if(!type){for(type in events){jQuery.event.remove(elem,type+types[t],handler,selector,true);}
continue;}
special=jQuery.event.special[type]||{};type=(selector?special.delegateType:special.bindType)||type;handlers=events[type]||[];tmp=tmp[2]&&new RegExp("(^|\\.)"+namespaces.join("\\.(?:.*\\.|)")+"(\\.|$)");origCount=j=handlers.length;while(j--){handleObj=handlers[j];if((mappedTypes||origType===handleObj.origType)&&(!handler||handler.guid===handleObj.guid)&&(!tmp||tmp.test(handleObj.namespace))&&(!selector||selector===handleObj.selector||selector==="**"&&handleObj.selector)){handlers.splice(j,1);if(handleObj.selector){handlers.delegateCount--;}
if(special.remove){special.remove.call(elem,handleObj);}}}
if(origCount&&!handlers.length){if(!special.teardown||special.teardown.call(elem,namespaces,elemData.handle)===false){jQuery.removeEvent(elem,type,elemData.handle);}
delete events[type];}}
if(jQuery.isEmptyObject(events)){dataPriv.remove(elem,"handle events");}},dispatch:function(nativeEvent){var i,j,ret,matched,handleObj,handlerQueue,args=new Array(arguments.length),event=jQuery.event.fix(nativeEvent),handlers=(dataPriv.get(this,"events")||Object.create(null))[event.type]||[],special=jQuery.event.special[event.type]||{};args[0]=event;for(i=1;i<arguments.length;i++){args[i]=arguments[i];}
event.delegateTarget=this;if(special.preDispatch&&special.preDispatch.call(this,event)===false){return;}
handlerQueue=jQuery.event.handlers.call(this,event,handlers);i=0;while((matched=handlerQueue[i++])&&!event.isPropagationStopped()){event.currentTarget=matched.elem;j=0;while((handleObj=matched.handlers[j++])&&!event.isImmediatePropagationStopped()){if(!event.rnamespace||handleObj.namespace===false||event.rnamespace.test(handleObj.namespace)){event.handleObj=handleObj;event.data=handleObj.data;ret=((jQuery.event.special[handleObj.origType]||{}).handle||handleObj.handler).apply(matched.elem,args);if(ret!==undefined){if((event.result=ret)===false){event.preventDefault();event.stopPropagation();}}}}}
if(special.postDispatch){special.postDispatch.call(this,event);}
return event.result;},handlers:function(event,handlers){var i,handleObj,sel,matchedHandlers,matchedSelectors,handlerQueue=[],delegateCount=handlers.delegateCount,cur=event.target;if(delegateCount&&cur.nodeType&&!(event.type==="click"&&event.button>=1)){for(;cur!==this;cur=cur.parentNode||this){if(cur.nodeType===1&&!(event.type==="click"&&cur.disabled===true)){matchedHandlers=[];matchedSelectors={};for(i=0;i<delegateCount;i++){handleObj=handlers[i];sel=handleObj.selector+" ";if(matchedSelectors[sel]===undefined){matchedSelectors[sel]=handleObj.needsContext?jQuery(sel,this).index(cur)>-1:jQuery.find(sel,this,null,[cur]).length;}
if(matchedSelectors[sel]){matchedHandlers.push(handleObj);}}
if(matchedHandlers.length){handlerQueue.push({elem:cur,handlers:matchedHandlers});}}}}
cur=this;if(delegateCount<handlers.length){handlerQueue.push({elem:cur,handlers:handlers.slice(delegateCount)});}
return handlerQueue;},addProp:function(name,hook){Object.defineProperty(jQuery.Event.prototype,name,{enumerable:true,configurable:true,get:isFunction(hook)?function(){if(this.originalEvent){return hook(this.originalEvent);}}:function(){if(this.originalEvent){return this.originalEvent[name];}},set:function(value){Object.defineProperty(this,name,{enumerable:true,configurable:true,writable:true,value:value});}});},fix:function(originalEvent){return originalEvent[jQuery.expando]?originalEvent:new jQuery.Event(originalEvent);},special:{load:{noBubble:true},click:{setup:function(data){var el=this||data;if(rcheckableType.test(el.type)&&el.click&&nodeName(el,"input")){leverageNative(el,"click",returnTrue);}
return false;},trigger:function(data){var el=this||data;if(rcheckableType.test(el.type)&&el.click&&nodeName(el,"input")){leverageNative(el,"click");}
return true;},_default:function(event){var target=event.target;return rcheckableType.test(target.type)&&target.click&&nodeName(target,"input")&&dataPriv.get(target,"click")||nodeName(target,"a");}},beforeunload:{postDispatch:function(event){if(event.result!==undefined&&event.originalEvent){event.originalEvent.returnValue=event.result;}}}}};function leverageNative(el,type,expectSync){if(!expectSync){if(dataPriv.get(el,type)===undefined){jQuery.event.add(el,type,returnTrue);}
return;}
dataPriv.set(el,type,false);jQuery.event.add(el,type,{namespace:false,handler:function(event){var notAsync,result,saved=dataPriv.get(this,type);if((event.isTrigger&1)&&this[type]){if(!saved.length){saved=slice.call(arguments);dataPriv.set(this,type,saved);notAsync=expectSync(this,type);this[type]();result=dataPriv.get(this,type);if(saved!==result||notAsync){dataPriv.set(this,type,false);}else{result={};}
if(saved!==result){event.stopImmediatePropagation();event.preventDefault();return result&&result.value;}}else if((jQuery.event.special[type]||{}).delegateType){event.stopPropagation();}}else if(saved.length){dataPriv.set(this,type,{value:jQuery.event.trigger(jQuery.extend(saved[0],jQuery.Event.prototype),saved.slice(1),this)});event.stopImmediatePropagation();}}});}
jQuery.removeEvent=function(elem,type,handle){if(elem.removeEventListener){elem.removeEventListener(type,handle);}};jQuery.Event=function(src,props){if(!(this instanceof jQuery.Event)){return new jQuery.Event(src,props);}
if(src&&src.type){this.originalEvent=src;this.type=src.type;this.isDefaultPrevented=src.defaultPrevented||src.defaultPrevented===undefined&&src.returnValue===false?returnTrue:returnFalse;this.target=(src.target&&src.target.nodeType===3)?src.target.parentNode:src.target;this.currentTarget=src.currentTarget;this.relatedTarget=src.relatedTarget;}else{this.type=src;}
if(props){jQuery.extend(this,props);}
this.timeStamp=src&&src.timeStamp||Date.now();this[jQuery.expando]=true;};jQuery.Event.prototype={constructor:jQuery.Event,isDefaultPrevented:returnFalse,isPropagationStopped:returnFalse,isImmediatePropagationStopped:returnFalse,isSimulated:false,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=returnTrue;if(e&&!this.isSimulated){e.preventDefault();}},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=returnTrue;if(e&&!this.isSimulated){e.stopPropagation();}},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=returnTrue;if(e&&!this.isSimulated){e.stopImmediatePropagation();}
this.stopPropagation();}};jQuery.each({altKey:true,bubbles:true,cancelable:true,changedTouches:true,ctrlKey:true,detail:true,eventPhase:true,metaKey:true,pageX:true,pageY:true,shiftKey:true,view:true,"char":true,code:true,charCode:true,key:true,keyCode:true,button:true,buttons:true,clientX:true,clientY:true,offsetX:true,offsetY:true,pointerId:true,pointerType:true,screenX:true,screenY:true,targetTouches:true,toElement:true,touches:true,which:true},jQuery.event.addProp);jQuery.each({focus:"focusin",blur:"focusout"},function(type,delegateType){jQuery.event.special[type]={setup:function(){leverageNative(this,type,expectSync);return false;},trigger:function(){leverageNative(this,type);return true;},_default:function(event){return dataPriv.get(event.target,type);},delegateType:delegateType};});jQuery.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(orig,fix){jQuery.event.special[orig]={delegateType:fix,bindType:fix,handle:function(event){var ret,target=this,related=event.relatedTarget,handleObj=event.handleObj;if(!related||(related!==target&&!jQuery.contains(target,related))){event.type=handleObj.origType;ret=handleObj.handler.apply(this,arguments);event.type=fix;}
return ret;}};});jQuery.fn.extend({on:function(types,selector,data,fn){return on(this,types,selector,data,fn);},one:function(types,selector,data,fn){return on(this,types,selector,data,fn,1);},off:function(types,selector,fn){var handleObj,type;if(types&&types.preventDefault&&types.handleObj){handleObj=types.handleObj;jQuery(types.delegateTarget).off(handleObj.namespace?handleObj.origType+"."+handleObj.namespace:handleObj.origType,handleObj.selector,handleObj.handler);return this;}
if(typeof types==="object"){for(type in types){this.off(type,selector,types[type]);}
return this;}
if(selector===false||typeof selector==="function"){fn=selector;selector=undefined;}
if(fn===false){fn=returnFalse;}
return this.each(function(){jQuery.event.remove(this,types,fn,selector);});}});var
rnoInnerhtml=/<script|<style|<link/i,rchecked=/checked\s*(?:[^=]|=\s*.checked.)/i,rcleanScript=/^\s*<!\[CDATA\[|\]\]>\s*$/g;function manipulationTarget(elem,content){if(nodeName(elem,"table")&&nodeName(content.nodeType!==11?content:content.firstChild,"tr")){return jQuery(elem).children("tbody")[0]||elem;}
return elem;}
function disableScript(elem){elem.type=(elem.getAttribute("type")!==null)+"/"+elem.type;return elem;}
function restoreScript(elem){if((elem.type||"").slice(0,5)==="true/"){elem.type=elem.type.slice(5);}else{elem.removeAttribute("type");}
return elem;}
function cloneCopyEvent(src,dest){var i,l,type,pdataOld,udataOld,udataCur,events;if(dest.nodeType!==1){return;}
if(dataPriv.hasData(src)){pdataOld=dataPriv.get(src);events=pdataOld.events;if(events){dataPriv.remove(dest,"handle events");for(type in events){for(i=0,l=events[type].length;i<l;i++){jQuery.event.add(dest,type,events[type][i]);}}}}
if(dataUser.hasData(src)){udataOld=dataUser.access(src);udataCur=jQuery.extend({},udataOld);dataUser.set(dest,udataCur);}}
function fixInput(src,dest){var nodeName=dest.nodeName.toLowerCase();if(nodeName==="input"&&rcheckableType.test(src.type)){dest.checked=src.checked;}else if(nodeName==="input"||nodeName==="textarea"){dest.defaultValue=src.defaultValue;}}
function domManip(collection,args,callback,ignored){args=flat(args);var fragment,first,scripts,hasScripts,node,doc,i=0,l=collection.length,iNoClone=l-1,value=args[0],valueIsFunction=isFunction(value);if(valueIsFunction||(l>1&&typeof value==="string"&&!support.checkClone&&rchecked.test(value))){return collection.each(function(index){var self=collection.eq(index);if(valueIsFunction){args[0]=value.call(this,index,self.html());}
domManip(self,args,callback,ignored);});}
if(l){fragment=buildFragment(args,collection[0].ownerDocument,false,collection,ignored);first=fragment.firstChild;if(fragment.childNodes.length===1){fragment=first;}
if(first||ignored){scripts=jQuery.map(getAll(fragment,"script"),disableScript);hasScripts=scripts.length;for(;i<l;i++){node=fragment;if(i!==iNoClone){node=jQuery.clone(node,true,true);if(hasScripts){jQuery.merge(scripts,getAll(node,"script"));}}
callback.call(collection[i],node,i);}
if(hasScripts){doc=scripts[scripts.length-1].ownerDocument;jQuery.map(scripts,restoreScript);for(i=0;i<hasScripts;i++){node=scripts[i];if(rscriptType.test(node.type||"")&&!dataPriv.access(node,"globalEval")&&jQuery.contains(doc,node)){if(node.src&&(node.type||"").toLowerCase()!=="module"){if(jQuery._evalUrl&&!node.noModule){jQuery._evalUrl(node.src,{nonce:node.nonce||node.getAttribute("nonce")},doc);}}else{DOMEval(node.textContent.replace(rcleanScript,""),node,doc);}}}}}}
return collection;}
function remove(elem,selector,keepData){var node,nodes=selector?jQuery.filter(selector,elem):elem,i=0;for(;(node=nodes[i])!=null;i++){if(!keepData&&node.nodeType===1){jQuery.cleanData(getAll(node));}
if(node.parentNode){if(keepData&&isAttached(node)){setGlobalEval(getAll(node,"script"));}
node.parentNode.removeChild(node);}}
return elem;}
jQuery.extend({htmlPrefilter:function(html){return html;},clone:function(elem,dataAndEvents,deepDataAndEvents){var i,l,srcElements,destElements,clone=elem.cloneNode(true),inPage=isAttached(elem);if(!support.noCloneChecked&&(elem.nodeType===1||elem.nodeType===11)&&!jQuery.isXMLDoc(elem)){destElements=getAll(clone);srcElements=getAll(elem);for(i=0,l=srcElements.length;i<l;i++){fixInput(srcElements[i],destElements[i]);}}
if(dataAndEvents){if(deepDataAndEvents){srcElements=srcElements||getAll(elem);destElements=destElements||getAll(clone);for(i=0,l=srcElements.length;i<l;i++){cloneCopyEvent(srcElements[i],destElements[i]);}}else{cloneCopyEvent(elem,clone);}}
destElements=getAll(clone,"script");if(destElements.length>0){setGlobalEval(destElements,!inPage&&getAll(elem,"script"));}
return clone;},cleanData:function(elems){var data,elem,type,special=jQuery.event.special,i=0;for(;(elem=elems[i])!==undefined;i++){if(acceptData(elem)){if((data=elem[dataPriv.expando])){if(data.events){for(type in data.events){if(special[type]){jQuery.event.remove(elem,type);}else{jQuery.removeEvent(elem,type,data.handle);}}}
elem[dataPriv.expando]=undefined;}
if(elem[dataUser.expando]){elem[dataUser.expando]=undefined;}}}}});jQuery.fn.extend({detach:function(selector){return remove(this,selector,true);},remove:function(selector){return remove(this,selector);},text:function(value){return access(this,function(value){return value===undefined?jQuery.text(this):this.empty().each(function(){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){this.textContent=value;}});},null,value,arguments.length);},append:function(){return domManip(this,arguments,function(elem){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){var target=manipulationTarget(this,elem);target.appendChild(elem);}});},prepend:function(){return domManip(this,arguments,function(elem){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){var target=manipulationTarget(this,elem);target.insertBefore(elem,target.firstChild);}});},before:function(){return domManip(this,arguments,function(elem){if(this.parentNode){this.parentNode.insertBefore(elem,this);}});},after:function(){return domManip(this,arguments,function(elem){if(this.parentNode){this.parentNode.insertBefore(elem,this.nextSibling);}});},empty:function(){var elem,i=0;for(;(elem=this[i])!=null;i++){if(elem.nodeType===1){jQuery.cleanData(getAll(elem,false));elem.textContent="";}}
return this;},clone:function(dataAndEvents,deepDataAndEvents){dataAndEvents=dataAndEvents==null?false:dataAndEvents;deepDataAndEvents=deepDataAndEvents==null?dataAndEvents:deepDataAndEvents;return this.map(function(){return jQuery.clone(this,dataAndEvents,deepDataAndEvents);});},html:function(value){return access(this,function(value){var elem=this[0]||{},i=0,l=this.length;if(value===undefined&&elem.nodeType===1){return elem.innerHTML;}
if(typeof value==="string"&&!rnoInnerhtml.test(value)&&!wrapMap[(rtagName.exec(value)||["",""])[1].toLowerCase()]){value=jQuery.htmlPrefilter(value);try{for(;i<l;i++){elem=this[i]||{};if(elem.nodeType===1){jQuery.cleanData(getAll(elem,false));elem.innerHTML=value;}}
elem=0;}catch(e){}}
if(elem){this.empty().append(value);}},null,value,arguments.length);},replaceWith:function(){var ignored=[];return domManip(this,arguments,function(elem){var parent=this.parentNode;if(jQuery.inArray(this,ignored)<0){jQuery.cleanData(getAll(this));if(parent){parent.replaceChild(elem,this);}}},ignored);}});jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(name,original){jQuery.fn[name]=function(selector){var elems,ret=[],insert=jQuery(selector),last=insert.length-1,i=0;for(;i<=last;i++){elems=i===last?this:this.clone(true);jQuery(insert[i])[original](elems);push.apply(ret,elems.get());}
return this.pushStack(ret);};});var rnumnonpx=new RegExp("^("+pnum+")(?!px)[a-z%]+$","i");var rcustomProp=/^--/;var getStyles=function(elem){var view=elem.ownerDocument.defaultView;if(!view||!view.opener){view=window;}
return view.getComputedStyle(elem);};var swap=function(elem,options,callback){var ret,name,old={};for(name in options){old[name]=elem.style[name];elem.style[name]=options[name];}
ret=callback.call(elem);for(name in options){elem.style[name]=old[name];}
return ret;};var rboxStyle=new RegExp(cssExpand.join("|"),"i");var whitespace="[\\x20\\t\\r\\n\\f]";var rtrimCSS=new RegExp("^"+whitespace+"+|((?:^|[^\\\\])(?:\\\\.)*)"+whitespace+"+$","g");(function(){function computeStyleTests(){if(!div){return;}
container.style.cssText="position:absolute;left:-11111px;width:60px;"+"margin-top:1px;padding:0;border:0";div.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;"+"margin:auto;border:1px;padding:1px;"+"width:60%;top:1%";documentElement.appendChild(container).appendChild(div);var divStyle=window.getComputedStyle(div);pixelPositionVal=divStyle.top!=="1%";reliableMarginLeftVal=roundPixelMeasures(divStyle.marginLeft)===12;div.style.right="60%";pixelBoxStylesVal=roundPixelMeasures(divStyle.right)===36;boxSizingReliableVal=roundPixelMeasures(divStyle.width)===36;div.style.position="absolute";scrollboxSizeVal=roundPixelMeasures(div.offsetWidth/3)===12;documentElement.removeChild(container);div=null;}
function roundPixelMeasures(measure){return Math.round(parseFloat(measure));}
var pixelPositionVal,boxSizingReliableVal,scrollboxSizeVal,pixelBoxStylesVal,reliableTrDimensionsVal,reliableMarginLeftVal,container=document.createElement("div"),div=document.createElement("div");if(!div.style){return;}
div.style.backgroundClip="content-box";div.cloneNode(true).style.backgroundClip="";support.clearCloneStyle=div.style.backgroundClip==="content-box";jQuery.extend(support,{boxSizingReliable:function(){computeStyleTests();return boxSizingReliableVal;},pixelBoxStyles:function(){computeStyleTests();return pixelBoxStylesVal;},pixelPosition:function(){computeStyleTests();return pixelPositionVal;},reliableMarginLeft:function(){computeStyleTests();return reliableMarginLeftVal;},scrollboxSize:function(){computeStyleTests();return scrollboxSizeVal;},reliableTrDimensions:function(){var table,tr,trChild,trStyle;if(reliableTrDimensionsVal==null){table=document.createElement("table");tr=document.createElement("tr");trChild=document.createElement("div");table.style.cssText="position:absolute;left:-11111px;border-collapse:separate";tr.style.cssText="border:1px solid";tr.style.height="1px";trChild.style.height="9px";trChild.style.display="block";documentElement.appendChild(table).appendChild(tr).appendChild(trChild);trStyle=window.getComputedStyle(tr);reliableTrDimensionsVal=(parseInt(trStyle.height,10)+
parseInt(trStyle.borderTopWidth,10)+
parseInt(trStyle.borderBottomWidth,10))===tr.offsetHeight;documentElement.removeChild(table);}
return reliableTrDimensionsVal;}});})();function curCSS(elem,name,computed){var width,minWidth,maxWidth,ret,isCustomProp=rcustomProp.test(name),style=elem.style;computed=computed||getStyles(elem);if(computed){ret=computed.getPropertyValue(name)||computed[name];if(isCustomProp&&ret){ret=ret.replace(rtrimCSS,"$1")||undefined;}
if(ret===""&&!isAttached(elem)){ret=jQuery.style(elem,name);}
if(!support.pixelBoxStyles()&&rnumnonpx.test(ret)&&rboxStyle.test(name)){width=style.width;minWidth=style.minWidth;maxWidth=style.maxWidth;style.minWidth=style.maxWidth=style.width=ret;ret=computed.width;style.width=width;style.minWidth=minWidth;style.maxWidth=maxWidth;}}
return ret!==undefined?ret+"":ret;}
function addGetHookIf(conditionFn,hookFn){return{get:function(){if(conditionFn()){delete this.get;return;}
return(this.get=hookFn).apply(this,arguments);}};}
var cssPrefixes=["Webkit","Moz","ms"],emptyStyle=document.createElement("div").style,vendorProps={};function vendorPropName(name){var capName=name[0].toUpperCase()+name.slice(1),i=cssPrefixes.length;while(i--){name=cssPrefixes[i]+capName;if(name in emptyStyle){return name;}}}
function finalPropName(name){var final=jQuery.cssProps[name]||vendorProps[name];if(final){return final;}
if(name in emptyStyle){return name;}
return vendorProps[name]=vendorPropName(name)||name;}
var
rdisplayswap=/^(none|table(?!-c[ea]).+)/,cssShow={position:"absolute",visibility:"hidden",display:"block"},cssNormalTransform={letterSpacing:"0",fontWeight:"400"};function setPositiveNumber(_elem,value,subtract){var matches=rcssNum.exec(value);return matches?Math.max(0,matches[2]-(subtract||0))+(matches[3]||"px"):value;}
function boxModelAdjustment(elem,dimension,box,isBorderBox,styles,computedVal){var i=dimension==="width"?1:0,extra=0,delta=0;if(box===(isBorderBox?"border":"content")){return 0;}
for(;i<4;i+=2){if(box==="margin"){delta+=jQuery.css(elem,box+cssExpand[i],true,styles);}
if(!isBorderBox){delta+=jQuery.css(elem,"padding"+cssExpand[i],true,styles);if(box!=="padding"){delta+=jQuery.css(elem,"border"+cssExpand[i]+"Width",true,styles);}else{extra+=jQuery.css(elem,"border"+cssExpand[i]+"Width",true,styles);}}else{if(box==="content"){delta-=jQuery.css(elem,"padding"+cssExpand[i],true,styles);}
if(box!=="margin"){delta-=jQuery.css(elem,"border"+cssExpand[i]+"Width",true,styles);}}}
if(!isBorderBox&&computedVal>=0){delta+=Math.max(0,Math.ceil(elem["offset"+dimension[0].toUpperCase()+dimension.slice(1)]-
computedVal-
delta-
extra-
0.5))||0;}
return delta;}
function getWidthOrHeight(elem,dimension,extra){var styles=getStyles(elem),boxSizingNeeded=!support.boxSizingReliable()||extra,isBorderBox=boxSizingNeeded&&jQuery.css(elem,"boxSizing",false,styles)==="border-box",valueIsBorderBox=isBorderBox,val=curCSS(elem,dimension,styles),offsetProp="offset"+dimension[0].toUpperCase()+dimension.slice(1);if(rnumnonpx.test(val)){if(!extra){return val;}
val="auto";}
if((!support.boxSizingReliable()&&isBorderBox||!support.reliableTrDimensions()&&nodeName(elem,"tr")||val==="auto"||!parseFloat(val)&&jQuery.css(elem,"display",false,styles)==="inline")&&elem.getClientRects().length){isBorderBox=jQuery.css(elem,"boxSizing",false,styles)==="border-box";valueIsBorderBox=offsetProp in elem;if(valueIsBorderBox){val=elem[offsetProp];}}
val=parseFloat(val)||0;return(val+
boxModelAdjustment(elem,dimension,extra||(isBorderBox?"border":"content"),valueIsBorderBox,styles,val))+"px";}
jQuery.extend({cssHooks:{opacity:{get:function(elem,computed){if(computed){var ret=curCSS(elem,"opacity");return ret===""?"1":ret;}}}},cssNumber:{"animationIterationCount":true,"columnCount":true,"fillOpacity":true,"flexGrow":true,"flexShrink":true,"fontWeight":true,"gridArea":true,"gridColumn":true,"gridColumnEnd":true,"gridColumnStart":true,"gridRow":true,"gridRowEnd":true,"gridRowStart":true,"lineHeight":true,"opacity":true,"order":true,"orphans":true,"widows":true,"zIndex":true,"zoom":true},cssProps:{},style:function(elem,name,value,extra){if(!elem||elem.nodeType===3||elem.nodeType===8||!elem.style){return;}
var ret,type,hooks,origName=camelCase(name),isCustomProp=rcustomProp.test(name),style=elem.style;if(!isCustomProp){name=finalPropName(origName);}
hooks=jQuery.cssHooks[name]||jQuery.cssHooks[origName];if(value!==undefined){type=typeof value;if(type==="string"&&(ret=rcssNum.exec(value))&&ret[1]){value=adjustCSS(elem,name,ret);type="number";}
if(value==null||value!==value){return;}
if(type==="number"&&!isCustomProp){value+=ret&&ret[3]||(jQuery.cssNumber[origName]?"":"px");}
if(!support.clearCloneStyle&&value===""&&name.indexOf("background")===0){style[name]="inherit";}
if(!hooks||!("set"in hooks)||(value=hooks.set(elem,value,extra))!==undefined){if(isCustomProp){style.setProperty(name,value);}else{style[name]=value;}}}else{if(hooks&&"get"in hooks&&(ret=hooks.get(elem,false,extra))!==undefined){return ret;}
return style[name];}},css:function(elem,name,extra,styles){var val,num,hooks,origName=camelCase(name),isCustomProp=rcustomProp.test(name);if(!isCustomProp){name=finalPropName(origName);}
hooks=jQuery.cssHooks[name]||jQuery.cssHooks[origName];if(hooks&&"get"in hooks){val=hooks.get(elem,true,extra);}
if(val===undefined){val=curCSS(elem,name,styles);}
if(val==="normal"&&name in cssNormalTransform){val=cssNormalTransform[name];}
if(extra===""||extra){num=parseFloat(val);return extra===true||isFinite(num)?num||0:val;}
return val;}});jQuery.each(["height","width"],function(_i,dimension){jQuery.cssHooks[dimension]={get:function(elem,computed,extra){if(computed){return rdisplayswap.test(jQuery.css(elem,"display"))&&(!elem.getClientRects().length||!elem.getBoundingClientRect().width)?swap(elem,cssShow,function(){return getWidthOrHeight(elem,dimension,extra);}):getWidthOrHeight(elem,dimension,extra);}},set:function(elem,value,extra){var matches,styles=getStyles(elem),scrollboxSizeBuggy=!support.scrollboxSize()&&styles.position==="absolute",boxSizingNeeded=scrollboxSizeBuggy||extra,isBorderBox=boxSizingNeeded&&jQuery.css(elem,"boxSizing",false,styles)==="border-box",subtract=extra?boxModelAdjustment(elem,dimension,extra,isBorderBox,styles):0;if(isBorderBox&&scrollboxSizeBuggy){subtract-=Math.ceil(elem["offset"+dimension[0].toUpperCase()+dimension.slice(1)]-
parseFloat(styles[dimension])-
boxModelAdjustment(elem,dimension,"border",false,styles)-
0.5);}
if(subtract&&(matches=rcssNum.exec(value))&&(matches[3]||"px")!=="px"){elem.style[dimension]=value;value=jQuery.css(elem,dimension);}
return setPositiveNumber(elem,value,subtract);}};});jQuery.cssHooks.marginLeft=addGetHookIf(support.reliableMarginLeft,function(elem,computed){if(computed){return(parseFloat(curCSS(elem,"marginLeft"))||elem.getBoundingClientRect().left-
swap(elem,{marginLeft:0},function(){return elem.getBoundingClientRect().left;}))+"px";}});jQuery.each({margin:"",padding:"",border:"Width"},function(prefix,suffix){jQuery.cssHooks[prefix+suffix]={expand:function(value){var i=0,expanded={},parts=typeof value==="string"?value.split(" "):[value];for(;i<4;i++){expanded[prefix+cssExpand[i]+suffix]=parts[i]||parts[i-2]||parts[0];}
return expanded;}};if(prefix!=="margin"){jQuery.cssHooks[prefix+suffix].set=setPositiveNumber;}});jQuery.fn.extend({css:function(name,value){return access(this,function(elem,name,value){var styles,len,map={},i=0;if(Array.isArray(name)){styles=getStyles(elem);len=name.length;for(;i<len;i++){map[name[i]]=jQuery.css(elem,name[i],false,styles);}
return map;}
return value!==undefined?jQuery.style(elem,name,value):jQuery.css(elem,name);},name,value,arguments.length>1);}});function Tween(elem,options,prop,end,easing){return new Tween.prototype.init(elem,options,prop,end,easing);}
jQuery.Tween=Tween;Tween.prototype={constructor:Tween,init:function(elem,options,prop,end,easing,unit){this.elem=elem;this.prop=prop;this.easing=easing||jQuery.easing._default;this.options=options;this.start=this.now=this.cur();this.end=end;this.unit=unit||(jQuery.cssNumber[prop]?"":"px");},cur:function(){var hooks=Tween.propHooks[this.prop];return hooks&&hooks.get?hooks.get(this):Tween.propHooks._default.get(this);},run:function(percent){var eased,hooks=Tween.propHooks[this.prop];if(this.options.duration){this.pos=eased=jQuery.easing[this.easing](percent,this.options.duration*percent,0,1,this.options.duration);}else{this.pos=eased=percent;}
this.now=(this.end-this.start)*eased+this.start;if(this.options.step){this.options.step.call(this.elem,this.now,this);}
if(hooks&&hooks.set){hooks.set(this);}else{Tween.propHooks._default.set(this);}
return this;}};Tween.prototype.init.prototype=Tween.prototype;Tween.propHooks={_default:{get:function(tween){var result;if(tween.elem.nodeType!==1||tween.elem[tween.prop]!=null&&tween.elem.style[tween.prop]==null){return tween.elem[tween.prop];}
result=jQuery.css(tween.elem,tween.prop,"");return!result||result==="auto"?0:result;},set:function(tween){if(jQuery.fx.step[tween.prop]){jQuery.fx.step[tween.prop](tween);}else if(tween.elem.nodeType===1&&(jQuery.cssHooks[tween.prop]||tween.elem.style[finalPropName(tween.prop)]!=null)){jQuery.style(tween.elem,tween.prop,tween.now+tween.unit);}else{tween.elem[tween.prop]=tween.now;}}}};Tween.propHooks.scrollTop=Tween.propHooks.scrollLeft={set:function(tween){if(tween.elem.nodeType&&tween.elem.parentNode){tween.elem[tween.prop]=tween.now;}}};jQuery.easing={linear:function(p){return p;},swing:function(p){return 0.5-Math.cos(p*Math.PI)/2;},_default:"swing"};jQuery.fx=Tween.prototype.init;jQuery.fx.step={};var
fxNow,inProgress,rfxtypes=/^(?:toggle|show|hide)$/,rrun=/queueHooks$/;function schedule(){if(inProgress){if(document.hidden===false&&window.requestAnimationFrame){window.requestAnimationFrame(schedule);}else{window.setTimeout(schedule,jQuery.fx.interval);}
jQuery.fx.tick();}}
function createFxNow(){window.setTimeout(function(){fxNow=undefined;});return(fxNow=Date.now());}
function genFx(type,includeWidth){var which,i=0,attrs={height:type};includeWidth=includeWidth?1:0;for(;i<4;i+=2-includeWidth){which=cssExpand[i];attrs["margin"+which]=attrs["padding"+which]=type;}
if(includeWidth){attrs.opacity=attrs.width=type;}
return attrs;}
function createTween(value,prop,animation){var tween,collection=(Animation.tweeners[prop]||[]).concat(Animation.tweeners["*"]),index=0,length=collection.length;for(;index<length;index++){if((tween=collection[index].call(animation,prop,value))){return tween;}}}
function defaultPrefilter(elem,props,opts){var prop,value,toggle,hooks,oldfire,propTween,restoreDisplay,display,isBox="width"in props||"height"in props,anim=this,orig={},style=elem.style,hidden=elem.nodeType&&isHiddenWithinTree(elem),dataShow=dataPriv.get(elem,"fxshow");if(!opts.queue){hooks=jQuery._queueHooks(elem,"fx");if(hooks.unqueued==null){hooks.unqueued=0;oldfire=hooks.empty.fire;hooks.empty.fire=function(){if(!hooks.unqueued){oldfire();}};}
hooks.unqueued++;anim.always(function(){anim.always(function(){hooks.unqueued--;if(!jQuery.queue(elem,"fx").length){hooks.empty.fire();}});});}
for(prop in props){value=props[prop];if(rfxtypes.test(value)){delete props[prop];toggle=toggle||value==="toggle";if(value===(hidden?"hide":"show")){if(value==="show"&&dataShow&&dataShow[prop]!==undefined){hidden=true;}else{continue;}}
orig[prop]=dataShow&&dataShow[prop]||jQuery.style(elem,prop);}}
propTween=!jQuery.isEmptyObject(props);if(!propTween&&jQuery.isEmptyObject(orig)){return;}
if(isBox&&elem.nodeType===1){opts.overflow=[style.overflow,style.overflowX,style.overflowY];restoreDisplay=dataShow&&dataShow.display;if(restoreDisplay==null){restoreDisplay=dataPriv.get(elem,"display");}
display=jQuery.css(elem,"display");if(display==="none"){if(restoreDisplay){display=restoreDisplay;}else{showHide([elem],true);restoreDisplay=elem.style.display||restoreDisplay;display=jQuery.css(elem,"display");showHide([elem]);}}
if(display==="inline"||display==="inline-block"&&restoreDisplay!=null){if(jQuery.css(elem,"float")==="none"){if(!propTween){anim.done(function(){style.display=restoreDisplay;});if(restoreDisplay==null){display=style.display;restoreDisplay=display==="none"?"":display;}}
style.display="inline-block";}}}
if(opts.overflow){style.overflow="hidden";anim.always(function(){style.overflow=opts.overflow[0];style.overflowX=opts.overflow[1];style.overflowY=opts.overflow[2];});}
propTween=false;for(prop in orig){if(!propTween){if(dataShow){if("hidden"in dataShow){hidden=dataShow.hidden;}}else{dataShow=dataPriv.access(elem,"fxshow",{display:restoreDisplay});}
if(toggle){dataShow.hidden=!hidden;}
if(hidden){showHide([elem],true);}
anim.done(function(){if(!hidden){showHide([elem]);}
dataPriv.remove(elem,"fxshow");for(prop in orig){jQuery.style(elem,prop,orig[prop]);}});}
propTween=createTween(hidden?dataShow[prop]:0,prop,anim);if(!(prop in dataShow)){dataShow[prop]=propTween.start;if(hidden){propTween.end=propTween.start;propTween.start=0;}}}}
function propFilter(props,specialEasing){var index,name,easing,value,hooks;for(index in props){name=camelCase(index);easing=specialEasing[name];value=props[index];if(Array.isArray(value)){easing=value[1];value=props[index]=value[0];}
if(index!==name){props[name]=value;delete props[index];}
hooks=jQuery.cssHooks[name];if(hooks&&"expand"in hooks){value=hooks.expand(value);delete props[name];for(index in value){if(!(index in props)){props[index]=value[index];specialEasing[index]=easing;}}}else{specialEasing[name]=easing;}}}
function Animation(elem,properties,options){var result,stopped,index=0,length=Animation.prefilters.length,deferred=jQuery.Deferred().always(function(){delete tick.elem;}),tick=function(){if(stopped){return false;}
var currentTime=fxNow||createFxNow(),remaining=Math.max(0,animation.startTime+animation.duration-currentTime),temp=remaining/animation.duration||0,percent=1-temp,index=0,length=animation.tweens.length;for(;index<length;index++){animation.tweens[index].run(percent);}
deferred.notifyWith(elem,[animation,percent,remaining]);if(percent<1&&length){return remaining;}
if(!length){deferred.notifyWith(elem,[animation,1,0]);}
deferred.resolveWith(elem,[animation]);return false;},animation=deferred.promise({elem:elem,props:jQuery.extend({},properties),opts:jQuery.extend(true,{specialEasing:{},easing:jQuery.easing._default},options),originalProperties:properties,originalOptions:options,startTime:fxNow||createFxNow(),duration:options.duration,tweens:[],createTween:function(prop,end){var tween=jQuery.Tween(elem,animation.opts,prop,end,animation.opts.specialEasing[prop]||animation.opts.easing);animation.tweens.push(tween);return tween;},stop:function(gotoEnd){var index=0,length=gotoEnd?animation.tweens.length:0;if(stopped){return this;}
stopped=true;for(;index<length;index++){animation.tweens[index].run(1);}
if(gotoEnd){deferred.notifyWith(elem,[animation,1,0]);deferred.resolveWith(elem,[animation,gotoEnd]);}else{deferred.rejectWith(elem,[animation,gotoEnd]);}
return this;}}),props=animation.props;propFilter(props,animation.opts.specialEasing);for(;index<length;index++){result=Animation.prefilters[index].call(animation,elem,props,animation.opts);if(result){if(isFunction(result.stop)){jQuery._queueHooks(animation.elem,animation.opts.queue).stop=result.stop.bind(result);}
return result;}}
jQuery.map(props,createTween,animation);if(isFunction(animation.opts.start)){animation.opts.start.call(elem,animation);}
animation.progress(animation.opts.progress).done(animation.opts.done,animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always);jQuery.fx.timer(jQuery.extend(tick,{elem:elem,anim:animation,queue:animation.opts.queue}));return animation;}
jQuery.Animation=jQuery.extend(Animation,{tweeners:{"*":[function(prop,value){var tween=this.createTween(prop,value);adjustCSS(tween.elem,prop,rcssNum.exec(value),tween);return tween;}]},tweener:function(props,callback){if(isFunction(props)){callback=props;props=["*"];}else{props=props.match(rnothtmlwhite);}
var prop,index=0,length=props.length;for(;index<length;index++){prop=props[index];Animation.tweeners[prop]=Animation.tweeners[prop]||[];Animation.tweeners[prop].unshift(callback);}},prefilters:[defaultPrefilter],prefilter:function(callback,prepend){if(prepend){Animation.prefilters.unshift(callback);}else{Animation.prefilters.push(callback);}}});jQuery.speed=function(speed,easing,fn){var opt=speed&&typeof speed==="object"?jQuery.extend({},speed):{complete:fn||!fn&&easing||isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&!isFunction(easing)&&easing};if(jQuery.fx.off){opt.duration=0;}else{if(typeof opt.duration!=="number"){if(opt.duration in jQuery.fx.speeds){opt.duration=jQuery.fx.speeds[opt.duration];}else{opt.duration=jQuery.fx.speeds._default;}}}
if(opt.queue==null||opt.queue===true){opt.queue="fx";}
opt.old=opt.complete;opt.complete=function(){if(isFunction(opt.old)){opt.old.call(this);}
if(opt.queue){jQuery.dequeue(this,opt.queue);}};return opt;};jQuery.fn.extend({fadeTo:function(speed,to,easing,callback){return this.filter(isHiddenWithinTree).css("opacity",0).show().end().animate({opacity:to},speed,easing,callback);},animate:function(prop,speed,easing,callback){var empty=jQuery.isEmptyObject(prop),optall=jQuery.speed(speed,easing,callback),doAnimation=function(){var anim=Animation(this,jQuery.extend({},prop),optall);if(empty||dataPriv.get(this,"finish")){anim.stop(true);}};doAnimation.finish=doAnimation;return empty||optall.queue===false?this.each(doAnimation):this.queue(optall.queue,doAnimation);},stop:function(type,clearQueue,gotoEnd){var stopQueue=function(hooks){var stop=hooks.stop;delete hooks.stop;stop(gotoEnd);};if(typeof type!=="string"){gotoEnd=clearQueue;clearQueue=type;type=undefined;}
if(clearQueue){this.queue(type||"fx",[]);}
return this.each(function(){var dequeue=true,index=type!=null&&type+"queueHooks",timers=jQuery.timers,data=dataPriv.get(this);if(index){if(data[index]&&data[index].stop){stopQueue(data[index]);}}else{for(index in data){if(data[index]&&data[index].stop&&rrun.test(index)){stopQueue(data[index]);}}}
for(index=timers.length;index--;){if(timers[index].elem===this&&(type==null||timers[index].queue===type)){timers[index].anim.stop(gotoEnd);dequeue=false;timers.splice(index,1);}}
if(dequeue||!gotoEnd){jQuery.dequeue(this,type);}});},finish:function(type){if(type!==false){type=type||"fx";}
return this.each(function(){var index,data=dataPriv.get(this),queue=data[type+"queue"],hooks=data[type+"queueHooks"],timers=jQuery.timers,length=queue?queue.length:0;data.finish=true;jQuery.queue(this,type,[]);if(hooks&&hooks.stop){hooks.stop.call(this,true);}
for(index=timers.length;index--;){if(timers[index].elem===this&&timers[index].queue===type){timers[index].anim.stop(true);timers.splice(index,1);}}
for(index=0;index<length;index++){if(queue[index]&&queue[index].finish){queue[index].finish.call(this);}}
delete data.finish;});}});jQuery.each(["toggle","show","hide"],function(_i,name){var cssFn=jQuery.fn[name];jQuery.fn[name]=function(speed,easing,callback){return speed==null||typeof speed==="boolean"?cssFn.apply(this,arguments):this.animate(genFx(name,true),speed,easing,callback);};});jQuery.each({slideDown:genFx("show"),slideUp:genFx("hide"),slideToggle:genFx("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(name,props){jQuery.fn[name]=function(speed,easing,callback){return this.animate(props,speed,easing,callback);};});jQuery.timers=[];jQuery.fx.tick=function(){var timer,i=0,timers=jQuery.timers;fxNow=Date.now();for(;i<timers.length;i++){timer=timers[i];if(!timer()&&timers[i]===timer){timers.splice(i--,1);}}
if(!timers.length){jQuery.fx.stop();}
fxNow=undefined;};jQuery.fx.timer=function(timer){jQuery.timers.push(timer);jQuery.fx.start();};jQuery.fx.interval=13;jQuery.fx.start=function(){if(inProgress){return;}
inProgress=true;schedule();};jQuery.fx.stop=function(){inProgress=null;};jQuery.fx.speeds={slow:600,fast:200,_default:400};jQuery.fn.delay=function(time,type){time=jQuery.fx?jQuery.fx.speeds[time]||time:time;type=type||"fx";return this.queue(type,function(next,hooks){var timeout=window.setTimeout(next,time);hooks.stop=function(){window.clearTimeout(timeout);};});};(function(){var input=document.createElement("input"),select=document.createElement("select"),opt=select.appendChild(document.createElement("option"));input.type="checkbox";support.checkOn=input.value!=="";support.optSelected=opt.selected;input=document.createElement("input");input.value="t";input.type="radio";support.radioValue=input.value==="t";})();var boolHook,attrHandle=jQuery.expr.attrHandle;jQuery.fn.extend({attr:function(name,value){return access(this,jQuery.attr,name,value,arguments.length>1);},removeAttr:function(name){return this.each(function(){jQuery.removeAttr(this,name);});}});jQuery.extend({attr:function(elem,name,value){var ret,hooks,nType=elem.nodeType;if(nType===3||nType===8||nType===2){return;}
if(typeof elem.getAttribute==="undefined"){return jQuery.prop(elem,name,value);}
if(nType!==1||!jQuery.isXMLDoc(elem)){hooks=jQuery.attrHooks[name.toLowerCase()]||(jQuery.expr.match.bool.test(name)?boolHook:undefined);}
if(value!==undefined){if(value===null){jQuery.removeAttr(elem,name);return;}
if(hooks&&"set"in hooks&&(ret=hooks.set(elem,value,name))!==undefined){return ret;}
elem.setAttribute(name,value+"");return value;}
if(hooks&&"get"in hooks&&(ret=hooks.get(elem,name))!==null){return ret;}
ret=jQuery.find.attr(elem,name);return ret==null?undefined:ret;},attrHooks:{type:{set:function(elem,value){if(!support.radioValue&&value==="radio"&&nodeName(elem,"input")){var val=elem.value;elem.setAttribute("type",value);if(val){elem.value=val;}
return value;}}}},removeAttr:function(elem,value){var name,i=0,attrNames=value&&value.match(rnothtmlwhite);if(attrNames&&elem.nodeType===1){while((name=attrNames[i++])){elem.removeAttribute(name);}}}});boolHook={set:function(elem,value,name){if(value===false){jQuery.removeAttr(elem,name);}else{elem.setAttribute(name,name);}
return name;}};jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g),function(_i,name){var getter=attrHandle[name]||jQuery.find.attr;attrHandle[name]=function(elem,name,isXML){var ret,handle,lowercaseName=name.toLowerCase();if(!isXML){handle=attrHandle[lowercaseName];attrHandle[lowercaseName]=ret;ret=getter(elem,name,isXML)!=null?lowercaseName:null;attrHandle[lowercaseName]=handle;}
return ret;};});var rfocusable=/^(?:input|select|textarea|button)$/i,rclickable=/^(?:a|area)$/i;jQuery.fn.extend({prop:function(name,value){return access(this,jQuery.prop,name,value,arguments.length>1);},removeProp:function(name){return this.each(function(){delete this[jQuery.propFix[name]||name];});}});jQuery.extend({prop:function(elem,name,value){var ret,hooks,nType=elem.nodeType;if(nType===3||nType===8||nType===2){return;}
if(nType!==1||!jQuery.isXMLDoc(elem)){name=jQuery.propFix[name]||name;hooks=jQuery.propHooks[name];}
if(value!==undefined){if(hooks&&"set"in hooks&&(ret=hooks.set(elem,value,name))!==undefined){return ret;}
return(elem[name]=value);}
if(hooks&&"get"in hooks&&(ret=hooks.get(elem,name))!==null){return ret;}
return elem[name];},propHooks:{tabIndex:{get:function(elem){var tabindex=jQuery.find.attr(elem,"tabindex");if(tabindex){return parseInt(tabindex,10);}
if(rfocusable.test(elem.nodeName)||rclickable.test(elem.nodeName)&&elem.href){return 0;}
return-1;}}},propFix:{"for":"htmlFor","class":"className"}});if(!support.optSelected){jQuery.propHooks.selected={get:function(elem){var parent=elem.parentNode;if(parent&&parent.parentNode){parent.parentNode.selectedIndex;}
return null;},set:function(elem){var parent=elem.parentNode;if(parent){parent.selectedIndex;if(parent.parentNode){parent.parentNode.selectedIndex;}}}};}
jQuery.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){jQuery.propFix[this.toLowerCase()]=this;});function stripAndCollapse(value){var tokens=value.match(rnothtmlwhite)||[];return tokens.join(" ");}
function getClass(elem){return elem.getAttribute&&elem.getAttribute("class")||"";}
function classesToArray(value){if(Array.isArray(value)){return value;}
if(typeof value==="string"){return value.match(rnothtmlwhite)||[];}
return[];}
jQuery.fn.extend({addClass:function(value){var classNames,cur,curValue,className,i,finalValue;if(isFunction(value)){return this.each(function(j){jQuery(this).addClass(value.call(this,j,getClass(this)));});}
classNames=classesToArray(value);if(classNames.length){return this.each(function(){curValue=getClass(this);cur=this.nodeType===1&&(" "+stripAndCollapse(curValue)+" ");if(cur){for(i=0;i<classNames.length;i++){className=classNames[i];if(cur.indexOf(" "+className+" ")<0){cur+=className+" ";}}
finalValue=stripAndCollapse(cur);if(curValue!==finalValue){this.setAttribute("class",finalValue);}}});}
return this;},removeClass:function(value){var classNames,cur,curValue,className,i,finalValue;if(isFunction(value)){return this.each(function(j){jQuery(this).removeClass(value.call(this,j,getClass(this)));});}
if(!arguments.length){return this.attr("class","");}
classNames=classesToArray(value);if(classNames.length){return this.each(function(){curValue=getClass(this);cur=this.nodeType===1&&(" "+stripAndCollapse(curValue)+" ");if(cur){for(i=0;i<classNames.length;i++){className=classNames[i];while(cur.indexOf(" "+className+" ")>-1){cur=cur.replace(" "+className+" "," ");}}
finalValue=stripAndCollapse(cur);if(curValue!==finalValue){this.setAttribute("class",finalValue);}}});}
return this;},toggleClass:function(value,stateVal){var classNames,className,i,self,type=typeof value,isValidValue=type==="string"||Array.isArray(value);if(isFunction(value)){return this.each(function(i){jQuery(this).toggleClass(value.call(this,i,getClass(this),stateVal),stateVal);});}
if(typeof stateVal==="boolean"&&isValidValue){return stateVal?this.addClass(value):this.removeClass(value);}
classNames=classesToArray(value);return this.each(function(){if(isValidValue){self=jQuery(this);for(i=0;i<classNames.length;i++){className=classNames[i];if(self.hasClass(className)){self.removeClass(className);}else{self.addClass(className);}}}else if(value===undefined||type==="boolean"){className=getClass(this);if(className){dataPriv.set(this,"__className__",className);}
if(this.setAttribute){this.setAttribute("class",className||value===false?"":dataPriv.get(this,"__className__")||"");}}});},hasClass:function(selector){var className,elem,i=0;className=" "+selector+" ";while((elem=this[i++])){if(elem.nodeType===1&&(" "+stripAndCollapse(getClass(elem))+" ").indexOf(className)>-1){return true;}}
return false;}});var rreturn=/\r/g;jQuery.fn.extend({val:function(value){var hooks,ret,valueIsFunction,elem=this[0];if(!arguments.length){if(elem){hooks=jQuery.valHooks[elem.type]||jQuery.valHooks[elem.nodeName.toLowerCase()];if(hooks&&"get"in hooks&&(ret=hooks.get(elem,"value"))!==undefined){return ret;}
ret=elem.value;if(typeof ret==="string"){return ret.replace(rreturn,"");}
return ret==null?"":ret;}
return;}
valueIsFunction=isFunction(value);return this.each(function(i){var val;if(this.nodeType!==1){return;}
if(valueIsFunction){val=value.call(this,i,jQuery(this).val());}else{val=value;}
if(val==null){val="";}else if(typeof val==="number"){val+="";}else if(Array.isArray(val)){val=jQuery.map(val,function(value){return value==null?"":value+"";});}
hooks=jQuery.valHooks[this.type]||jQuery.valHooks[this.nodeName.toLowerCase()];if(!hooks||!("set"in hooks)||hooks.set(this,val,"value")===undefined){this.value=val;}});}});jQuery.extend({valHooks:{option:{get:function(elem){var val=jQuery.find.attr(elem,"value");return val!=null?val:stripAndCollapse(jQuery.text(elem));}},select:{get:function(elem){var value,option,i,options=elem.options,index=elem.selectedIndex,one=elem.type==="select-one",values=one?null:[],max=one?index+1:options.length;if(index<0){i=max;}else{i=one?index:0;}
for(;i<max;i++){option=options[i];if((option.selected||i===index)&&!option.disabled&&(!option.parentNode.disabled||!nodeName(option.parentNode,"optgroup"))){value=jQuery(option).val();if(one){return value;}
values.push(value);}}
return values;},set:function(elem,value){var optionSet,option,options=elem.options,values=jQuery.makeArray(value),i=options.length;while(i--){option=options[i];if(option.selected=jQuery.inArray(jQuery.valHooks.option.get(option),values)>-1){optionSet=true;}}
if(!optionSet){elem.selectedIndex=-1;}
return values;}}}});jQuery.each(["radio","checkbox"],function(){jQuery.valHooks[this]={set:function(elem,value){if(Array.isArray(value)){return(elem.checked=jQuery.inArray(jQuery(elem).val(),value)>-1);}}};if(!support.checkOn){jQuery.valHooks[this].get=function(elem){return elem.getAttribute("value")===null?"on":elem.value;};}});support.focusin="onfocusin"in window;var rfocusMorph=/^(?:focusinfocus|focusoutblur)$/,stopPropagationCallback=function(e){e.stopPropagation();};jQuery.extend(jQuery.event,{trigger:function(event,data,elem,onlyHandlers){var i,cur,tmp,bubbleType,ontype,handle,special,lastElement,eventPath=[elem||document],type=hasOwn.call(event,"type")?event.type:event,namespaces=hasOwn.call(event,"namespace")?event.namespace.split("."):[];cur=lastElement=tmp=elem=elem||document;if(elem.nodeType===3||elem.nodeType===8){return;}
if(rfocusMorph.test(type+jQuery.event.triggered)){return;}
if(type.indexOf(".")>-1){namespaces=type.split(".");type=namespaces.shift();namespaces.sort();}
ontype=type.indexOf(":")<0&&"on"+type;event=event[jQuery.expando]?event:new jQuery.Event(type,typeof event==="object"&&event);event.isTrigger=onlyHandlers?2:3;event.namespace=namespaces.join(".");event.rnamespace=event.namespace?new RegExp("(^|\\.)"+namespaces.join("\\.(?:.*\\.|)")+"(\\.|$)"):null;event.result=undefined;if(!event.target){event.target=elem;}
data=data==null?[event]:jQuery.makeArray(data,[event]);special=jQuery.event.special[type]||{};if(!onlyHandlers&&special.trigger&&special.trigger.apply(elem,data)===false){return;}
if(!onlyHandlers&&!special.noBubble&&!isWindow(elem)){bubbleType=special.delegateType||type;if(!rfocusMorph.test(bubbleType+type)){cur=cur.parentNode;}
for(;cur;cur=cur.parentNode){eventPath.push(cur);tmp=cur;}
if(tmp===(elem.ownerDocument||document)){eventPath.push(tmp.defaultView||tmp.parentWindow||window);}}
i=0;while((cur=eventPath[i++])&&!event.isPropagationStopped()){lastElement=cur;event.type=i>1?bubbleType:special.bindType||type;handle=(dataPriv.get(cur,"events")||Object.create(null))[event.type]&&dataPriv.get(cur,"handle");if(handle){handle.apply(cur,data);}
handle=ontype&&cur[ontype];if(handle&&handle.apply&&acceptData(cur)){event.result=handle.apply(cur,data);if(event.result===false){event.preventDefault();}}}
event.type=type;if(!onlyHandlers&&!event.isDefaultPrevented()){if((!special._default||special._default.apply(eventPath.pop(),data)===false)&&acceptData(elem)){if(ontype&&isFunction(elem[type])&&!isWindow(elem)){tmp=elem[ontype];if(tmp){elem[ontype]=null;}
jQuery.event.triggered=type;if(event.isPropagationStopped()){lastElement.addEventListener(type,stopPropagationCallback);}
elem[type]();if(event.isPropagationStopped()){lastElement.removeEventListener(type,stopPropagationCallback);}
jQuery.event.triggered=undefined;if(tmp){elem[ontype]=tmp;}}}}
return event.result;},simulate:function(type,elem,event){var e=jQuery.extend(new jQuery.Event(),event,{type:type,isSimulated:true});jQuery.event.trigger(e,null,elem);}});jQuery.fn.extend({trigger:function(type,data){return this.each(function(){jQuery.event.trigger(type,data,this);});},triggerHandler:function(type,data){var elem=this[0];if(elem){return jQuery.event.trigger(type,data,elem,true);}}});if(!support.focusin){jQuery.each({focus:"focusin",blur:"focusout"},function(orig,fix){var handler=function(event){jQuery.event.simulate(fix,event.target,jQuery.event.fix(event));};jQuery.event.special[fix]={setup:function(){var doc=this.ownerDocument||this.document||this,attaches=dataPriv.access(doc,fix);if(!attaches){doc.addEventListener(orig,handler,true);}
dataPriv.access(doc,fix,(attaches||0)+1);},teardown:function(){var doc=this.ownerDocument||this.document||this,attaches=dataPriv.access(doc,fix)-1;if(!attaches){doc.removeEventListener(orig,handler,true);dataPriv.remove(doc,fix);}else{dataPriv.access(doc,fix,attaches);}}};});}
var location=window.location;var nonce={guid:Date.now()};var rquery=(/\?/);jQuery.parseXML=function(data){var xml,parserErrorElem;if(!data||typeof data!=="string"){return null;}
try{xml=(new window.DOMParser()).parseFromString(data,"text/xml");}catch(e){}
parserErrorElem=xml&&xml.getElementsByTagName("parsererror")[0];if(!xml||parserErrorElem){jQuery.error("Invalid XML: "+(parserErrorElem?jQuery.map(parserErrorElem.childNodes,function(el){return el.textContent;}).join("\n"):data));}
return xml;};var
rbracket=/\[\]$/,rCRLF=/\r?\n/g,rsubmitterTypes=/^(?:submit|button|image|reset|file)$/i,rsubmittable=/^(?:input|select|textarea|keygen)/i;function buildParams(prefix,obj,traditional,add){var name;if(Array.isArray(obj)){jQuery.each(obj,function(i,v){if(traditional||rbracket.test(prefix)){add(prefix,v);}else{buildParams(prefix+"["+(typeof v==="object"&&v!=null?i:"")+"]",v,traditional,add);}});}else if(!traditional&&toType(obj)==="object"){for(name in obj){buildParams(prefix+"["+name+"]",obj[name],traditional,add);}}else{add(prefix,obj);}}
jQuery.param=function(a,traditional){var prefix,s=[],add=function(key,valueOrFunction){var value=isFunction(valueOrFunction)?valueOrFunction():valueOrFunction;s[s.length]=encodeURIComponent(key)+"="+
encodeURIComponent(value==null?"":value);};if(a==null){return"";}
if(Array.isArray(a)||(a.jquery&&!jQuery.isPlainObject(a))){jQuery.each(a,function(){add(this.name,this.value);});}else{for(prefix in a){buildParams(prefix,a[prefix],traditional,add);}}
return s.join("&");};jQuery.fn.extend({serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){var elements=jQuery.prop(this,"elements");return elements?jQuery.makeArray(elements):this;}).filter(function(){var type=this.type;return this.name&&!jQuery(this).is(":disabled")&&rsubmittable.test(this.nodeName)&&!rsubmitterTypes.test(type)&&(this.checked||!rcheckableType.test(type));}).map(function(_i,elem){var val=jQuery(this).val();if(val==null){return null;}
if(Array.isArray(val)){return jQuery.map(val,function(val){return{name:elem.name,value:val.replace(rCRLF,"\r\n")};});}
return{name:elem.name,value:val.replace(rCRLF,"\r\n")};}).get();}});var
r20=/%20/g,rhash=/#.*$/,rantiCache=/([?&])_=[^&]*/,rheaders=/^(.*?):[ \t]*([^\r\n]*)$/mg,rlocalProtocol=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,rnoContent=/^(?:GET|HEAD)$/,rprotocol=/^\/\//,prefilters={},transports={},allTypes="*/".concat("*"),originAnchor=document.createElement("a");originAnchor.href=location.href;function addToPrefiltersOrTransports(structure){return function(dataTypeExpression,func){if(typeof dataTypeExpression!=="string"){func=dataTypeExpression;dataTypeExpression="*";}
var dataType,i=0,dataTypes=dataTypeExpression.toLowerCase().match(rnothtmlwhite)||[];if(isFunction(func)){while((dataType=dataTypes[i++])){if(dataType[0]==="+"){dataType=dataType.slice(1)||"*";(structure[dataType]=structure[dataType]||[]).unshift(func);}else{(structure[dataType]=structure[dataType]||[]).push(func);}}}};}
function inspectPrefiltersOrTransports(structure,options,originalOptions,jqXHR){var inspected={},seekingTransport=(structure===transports);function inspect(dataType){var selected;inspected[dataType]=true;jQuery.each(structure[dataType]||[],function(_,prefilterOrFactory){var dataTypeOrTransport=prefilterOrFactory(options,originalOptions,jqXHR);if(typeof dataTypeOrTransport==="string"&&!seekingTransport&&!inspected[dataTypeOrTransport]){options.dataTypes.unshift(dataTypeOrTransport);inspect(dataTypeOrTransport);return false;}else if(seekingTransport){return!(selected=dataTypeOrTransport);}});return selected;}
return inspect(options.dataTypes[0])||!inspected["*"]&&inspect("*");}
function ajaxExtend(target,src){var key,deep,flatOptions=jQuery.ajaxSettings.flatOptions||{};for(key in src){if(src[key]!==undefined){(flatOptions[key]?target:(deep||(deep={})))[key]=src[key];}}
if(deep){jQuery.extend(true,target,deep);}
return target;}
function ajaxHandleResponses(s,jqXHR,responses){var ct,type,finalDataType,firstDataType,contents=s.contents,dataTypes=s.dataTypes;while(dataTypes[0]==="*"){dataTypes.shift();if(ct===undefined){ct=s.mimeType||jqXHR.getResponseHeader("Content-Type");}}
if(ct){for(type in contents){if(contents[type]&&contents[type].test(ct)){dataTypes.unshift(type);break;}}}
if(dataTypes[0]in responses){finalDataType=dataTypes[0];}else{for(type in responses){if(!dataTypes[0]||s.converters[type+" "+dataTypes[0]]){finalDataType=type;break;}
if(!firstDataType){firstDataType=type;}}
finalDataType=finalDataType||firstDataType;}
if(finalDataType){if(finalDataType!==dataTypes[0]){dataTypes.unshift(finalDataType);}
return responses[finalDataType];}}
function ajaxConvert(s,response,jqXHR,isSuccess){var conv2,current,conv,tmp,prev,converters={},dataTypes=s.dataTypes.slice();if(dataTypes[1]){for(conv in s.converters){converters[conv.toLowerCase()]=s.converters[conv];}}
current=dataTypes.shift();while(current){if(s.responseFields[current]){jqXHR[s.responseFields[current]]=response;}
if(!prev&&isSuccess&&s.dataFilter){response=s.dataFilter(response,s.dataType);}
prev=current;current=dataTypes.shift();if(current){if(current==="*"){current=prev;}else if(prev!=="*"&&prev!==current){conv=converters[prev+" "+current]||converters["* "+current];if(!conv){for(conv2 in converters){tmp=conv2.split(" ");if(tmp[1]===current){conv=converters[prev+" "+tmp[0]]||converters["* "+tmp[0]];if(conv){if(conv===true){conv=converters[conv2];}else if(converters[conv2]!==true){current=tmp[0];dataTypes.unshift(tmp[1]);}
break;}}}}
if(conv!==true){if(conv&&s.throws){response=conv(response);}else{try{response=conv(response);}catch(e){return{state:"parsererror",error:conv?e:"No conversion from "+prev+" to "+current};}}}}}}
return{state:"success",data:response};}
jQuery.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:location.href,type:"GET",isLocal:rlocalProtocol.test(location.protocol),global:true,processData:true,async:true,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":allTypes,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":true,"text json":JSON.parse,"text xml":jQuery.parseXML},flatOptions:{url:true,context:true}},ajaxSetup:function(target,settings){return settings?ajaxExtend(ajaxExtend(target,jQuery.ajaxSettings),settings):ajaxExtend(jQuery.ajaxSettings,target);},ajaxPrefilter:addToPrefiltersOrTransports(prefilters),ajaxTransport:addToPrefiltersOrTransports(transports),ajax:function(url,options){if(typeof url==="object"){options=url;url=undefined;}
options=options||{};var transport,cacheURL,responseHeadersString,responseHeaders,timeoutTimer,urlAnchor,completed,fireGlobals,i,uncached,s=jQuery.ajaxSetup({},options),callbackContext=s.context||s,globalEventContext=s.context&&(callbackContext.nodeType||callbackContext.jquery)?jQuery(callbackContext):jQuery.event,deferred=jQuery.Deferred(),completeDeferred=jQuery.Callbacks("once memory"),statusCode=s.statusCode||{},requestHeaders={},requestHeadersNames={},strAbort="canceled",jqXHR={readyState:0,getResponseHeader:function(key){var match;if(completed){if(!responseHeaders){responseHeaders={};while((match=rheaders.exec(responseHeadersString))){responseHeaders[match[1].toLowerCase()+" "]=(responseHeaders[match[1].toLowerCase()+" "]||[]).concat(match[2]);}}
match=responseHeaders[key.toLowerCase()+" "];}
return match==null?null:match.join(", ");},getAllResponseHeaders:function(){return completed?responseHeadersString:null;},setRequestHeader:function(name,value){if(completed==null){name=requestHeadersNames[name.toLowerCase()]=requestHeadersNames[name.toLowerCase()]||name;requestHeaders[name]=value;}
return this;},overrideMimeType:function(type){if(completed==null){s.mimeType=type;}
return this;},statusCode:function(map){var code;if(map){if(completed){jqXHR.always(map[jqXHR.status]);}else{for(code in map){statusCode[code]=[statusCode[code],map[code]];}}}
return this;},abort:function(statusText){var finalText=statusText||strAbort;if(transport){transport.abort(finalText);}
done(0,finalText);return this;}};deferred.promise(jqXHR);s.url=((url||s.url||location.href)+"").replace(rprotocol,location.protocol+"//");s.type=options.method||options.type||s.method||s.type;s.dataTypes=(s.dataType||"*").toLowerCase().match(rnothtmlwhite)||[""];if(s.crossDomain==null){urlAnchor=document.createElement("a");try{urlAnchor.href=s.url;urlAnchor.href=urlAnchor.href;s.crossDomain=originAnchor.protocol+"//"+originAnchor.host!==urlAnchor.protocol+"//"+urlAnchor.host;}catch(e){s.crossDomain=true;}}
if(s.data&&s.processData&&typeof s.data!=="string"){s.data=jQuery.param(s.data,s.traditional);}
inspectPrefiltersOrTransports(prefilters,s,options,jqXHR);if(completed){return jqXHR;}
fireGlobals=jQuery.event&&s.global;if(fireGlobals&&jQuery.active++===0){jQuery.event.trigger("ajaxStart");}
s.type=s.type.toUpperCase();s.hasContent=!rnoContent.test(s.type);cacheURL=s.url.replace(rhash,"");if(!s.hasContent){uncached=s.url.slice(cacheURL.length);if(s.data&&(s.processData||typeof s.data==="string")){cacheURL+=(rquery.test(cacheURL)?"&":"?")+s.data;delete s.data;}
if(s.cache===false){cacheURL=cacheURL.replace(rantiCache,"$1");uncached=(rquery.test(cacheURL)?"&":"?")+"_="+(nonce.guid++)+
uncached;}
s.url=cacheURL+uncached;}else if(s.data&&s.processData&&(s.contentType||"").indexOf("application/x-www-form-urlencoded")===0){s.data=s.data.replace(r20,"+");}
if(s.ifModified){if(jQuery.lastModified[cacheURL]){jqXHR.setRequestHeader("If-Modified-Since",jQuery.lastModified[cacheURL]);}
if(jQuery.etag[cacheURL]){jqXHR.setRequestHeader("If-None-Match",jQuery.etag[cacheURL]);}}
if(s.data&&s.hasContent&&s.contentType!==false||options.contentType){jqXHR.setRequestHeader("Content-Type",s.contentType);}
jqXHR.setRequestHeader("Accept",s.dataTypes[0]&&s.accepts[s.dataTypes[0]]?s.accepts[s.dataTypes[0]]+
(s.dataTypes[0]!=="*"?", "+allTypes+"; q=0.01":""):s.accepts["*"]);for(i in s.headers){jqXHR.setRequestHeader(i,s.headers[i]);}
if(s.beforeSend&&(s.beforeSend.call(callbackContext,jqXHR,s)===false||completed)){return jqXHR.abort();}
strAbort="abort";completeDeferred.add(s.complete);jqXHR.done(s.success);jqXHR.fail(s.error);transport=inspectPrefiltersOrTransports(transports,s,options,jqXHR);if(!transport){done(-1,"No Transport");}else{jqXHR.readyState=1;if(fireGlobals){globalEventContext.trigger("ajaxSend",[jqXHR,s]);}
if(completed){return jqXHR;}
if(s.async&&s.timeout>0){timeoutTimer=window.setTimeout(function(){jqXHR.abort("timeout");},s.timeout);}
try{completed=false;transport.send(requestHeaders,done);}catch(e){if(completed){throw e;}
done(-1,e);}}
function done(status,nativeStatusText,responses,headers){var isSuccess,success,error,response,modified,statusText=nativeStatusText;if(completed){return;}
completed=true;if(timeoutTimer){window.clearTimeout(timeoutTimer);}
transport=undefined;responseHeadersString=headers||"";jqXHR.readyState=status>0?4:0;isSuccess=status>=200&&status<300||status===304;if(responses){response=ajaxHandleResponses(s,jqXHR,responses);}
if(!isSuccess&&jQuery.inArray("script",s.dataTypes)>-1&&jQuery.inArray("json",s.dataTypes)<0){s.converters["text script"]=function(){};}
response=ajaxConvert(s,response,jqXHR,isSuccess);if(isSuccess){if(s.ifModified){modified=jqXHR.getResponseHeader("Last-Modified");if(modified){jQuery.lastModified[cacheURL]=modified;}
modified=jqXHR.getResponseHeader("etag");if(modified){jQuery.etag[cacheURL]=modified;}}
if(status===204||s.type==="HEAD"){statusText="nocontent";}else if(status===304){statusText="notmodified";}else{statusText=response.state;success=response.data;error=response.error;isSuccess=!error;}}else{error=statusText;if(status||!statusText){statusText="error";if(status<0){status=0;}}}
jqXHR.status=status;jqXHR.statusText=(nativeStatusText||statusText)+"";if(isSuccess){deferred.resolveWith(callbackContext,[success,statusText,jqXHR]);}else{deferred.rejectWith(callbackContext,[jqXHR,statusText,error]);}
jqXHR.statusCode(statusCode);statusCode=undefined;if(fireGlobals){globalEventContext.trigger(isSuccess?"ajaxSuccess":"ajaxError",[jqXHR,s,isSuccess?success:error]);}
completeDeferred.fireWith(callbackContext,[jqXHR,statusText]);if(fireGlobals){globalEventContext.trigger("ajaxComplete",[jqXHR,s]);if(!(--jQuery.active)){jQuery.event.trigger("ajaxStop");}}}
return jqXHR;},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},getScript:function(url,callback){return jQuery.get(url,undefined,callback,"script");}});jQuery.each(["get","post"],function(_i,method){jQuery[method]=function(url,data,callback,type){if(isFunction(data)){type=type||callback;callback=data;data=undefined;}
return jQuery.ajax(jQuery.extend({url:url,type:method,dataType:type,data:data,success:callback},jQuery.isPlainObject(url)&&url));};});jQuery.ajaxPrefilter(function(s){var i;for(i in s.headers){if(i.toLowerCase()==="content-type"){s.contentType=s.headers[i]||"";}}});jQuery._evalUrl=function(url,options,doc){return jQuery.ajax({url:url,type:"GET",dataType:"script",cache:true,async:false,global:false,converters:{"text script":function(){}},dataFilter:function(response){jQuery.globalEval(response,options,doc);}});};jQuery.fn.extend({wrapAll:function(html){var wrap;if(this[0]){if(isFunction(html)){html=html.call(this[0]);}
wrap=jQuery(html,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){wrap.insertBefore(this[0]);}
wrap.map(function(){var elem=this;while(elem.firstElementChild){elem=elem.firstElementChild;}
return elem;}).append(this);}
return this;},wrapInner:function(html){if(isFunction(html)){return this.each(function(i){jQuery(this).wrapInner(html.call(this,i));});}
return this.each(function(){var self=jQuery(this),contents=self.contents();if(contents.length){contents.wrapAll(html);}else{self.append(html);}});},wrap:function(html){var htmlIsFunction=isFunction(html);return this.each(function(i){jQuery(this).wrapAll(htmlIsFunction?html.call(this,i):html);});},unwrap:function(selector){this.parent(selector).not("body").each(function(){jQuery(this).replaceWith(this.childNodes);});return this;}});jQuery.expr.pseudos.hidden=function(elem){return!jQuery.expr.pseudos.visible(elem);};jQuery.expr.pseudos.visible=function(elem){return!!(elem.offsetWidth||elem.offsetHeight||elem.getClientRects().length);};jQuery.ajaxSettings.xhr=function(){try{return new window.XMLHttpRequest();}catch(e){}};var xhrSuccessStatus={0:200,1223:204},xhrSupported=jQuery.ajaxSettings.xhr();support.cors=!!xhrSupported&&("withCredentials"in xhrSupported);support.ajax=xhrSupported=!!xhrSupported;jQuery.ajaxTransport(function(options){var callback,errorCallback;if(support.cors||xhrSupported&&!options.crossDomain){return{send:function(headers,complete){var i,xhr=options.xhr();xhr.open(options.type,options.url,options.async,options.username,options.password);if(options.xhrFields){for(i in options.xhrFields){xhr[i]=options.xhrFields[i];}}
if(options.mimeType&&xhr.overrideMimeType){xhr.overrideMimeType(options.mimeType);}
if(!options.crossDomain&&!headers["X-Requested-With"]){headers["X-Requested-With"]="XMLHttpRequest";}
for(i in headers){xhr.setRequestHeader(i,headers[i]);}
callback=function(type){return function(){if(callback){callback=errorCallback=xhr.onload=xhr.onerror=xhr.onabort=xhr.ontimeout=xhr.onreadystatechange=null;if(type==="abort"){xhr.abort();}else if(type==="error"){if(typeof xhr.status!=="number"){complete(0,"error");}else{complete(xhr.status,xhr.statusText);}}else{complete(xhrSuccessStatus[xhr.status]||xhr.status,xhr.statusText,(xhr.responseType||"text")!=="text"||typeof xhr.responseText!=="string"?{binary:xhr.response}:{text:xhr.responseText},xhr.getAllResponseHeaders());}}};};xhr.onload=callback();errorCallback=xhr.onerror=xhr.ontimeout=callback("error");if(xhr.onabort!==undefined){xhr.onabort=errorCallback;}else{xhr.onreadystatechange=function(){if(xhr.readyState===4){window.setTimeout(function(){if(callback){errorCallback();}});}};}
callback=callback("abort");try{xhr.send(options.hasContent&&options.data||null);}catch(e){if(callback){throw e;}}},abort:function(){if(callback){callback();}}};}});jQuery.ajaxPrefilter(function(s){if(s.crossDomain){s.contents.script=false;}});jQuery.ajaxSetup({accepts:{script:"text/javascript, application/javascript, "+"application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(text){jQuery.globalEval(text);return text;}}});jQuery.ajaxPrefilter("script",function(s){if(s.cache===undefined){s.cache=false;}
if(s.crossDomain){s.type="GET";}});jQuery.ajaxTransport("script",function(s){if(s.crossDomain||s.scriptAttrs){var script,callback;return{send:function(_,complete){script=jQuery("<script>").attr(s.scriptAttrs||{}).prop({charset:s.scriptCharset,src:s.url}).on("load error",callback=function(evt){script.remove();callback=null;if(evt){complete(evt.type==="error"?404:200,evt.type);}});document.head.appendChild(script[0]);},abort:function(){if(callback){callback();}}};}});var oldCallbacks=[],rjsonp=/(=)\?(?=&|$)|\?\?/;jQuery.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var callback=oldCallbacks.pop()||(jQuery.expando+"_"+(nonce.guid++));this[callback]=true;return callback;}});jQuery.ajaxPrefilter("json jsonp",function(s,originalSettings,jqXHR){var callbackName,overwritten,responseContainer,jsonProp=s.jsonp!==false&&(rjsonp.test(s.url)?"url":typeof s.data==="string"&&(s.contentType||"").indexOf("application/x-www-form-urlencoded")===0&&rjsonp.test(s.data)&&"data");if(jsonProp||s.dataTypes[0]==="jsonp"){callbackName=s.jsonpCallback=isFunction(s.jsonpCallback)?s.jsonpCallback():s.jsonpCallback;if(jsonProp){s[jsonProp]=s[jsonProp].replace(rjsonp,"$1"+callbackName);}else if(s.jsonp!==false){s.url+=(rquery.test(s.url)?"&":"?")+s.jsonp+"="+callbackName;}
s.converters["script json"]=function(){if(!responseContainer){jQuery.error(callbackName+" was not called");}
return responseContainer[0];};s.dataTypes[0]="json";overwritten=window[callbackName];window[callbackName]=function(){responseContainer=arguments;};jqXHR.always(function(){if(overwritten===undefined){jQuery(window).removeProp(callbackName);}else{window[callbackName]=overwritten;}
if(s[callbackName]){s.jsonpCallback=originalSettings.jsonpCallback;oldCallbacks.push(callbackName);}
if(responseContainer&&isFunction(overwritten)){overwritten(responseContainer[0]);}
responseContainer=overwritten=undefined;});return"script";}});support.createHTMLDocument=(function(){var body=document.implementation.createHTMLDocument("").body;body.innerHTML="<form></form><form></form>";return body.childNodes.length===2;})();jQuery.parseHTML=function(data,context,keepScripts){if(typeof data!=="string"){return[];}
if(typeof context==="boolean"){keepScripts=context;context=false;}
var base,parsed,scripts;if(!context){if(support.createHTMLDocument){context=document.implementation.createHTMLDocument("");base=context.createElement("base");base.href=document.location.href;context.head.appendChild(base);}else{context=document;}}
parsed=rsingleTag.exec(data);scripts=!keepScripts&&[];if(parsed){return[context.createElement(parsed[1])];}
parsed=buildFragment([data],context,scripts);if(scripts&&scripts.length){jQuery(scripts).remove();}
return jQuery.merge([],parsed.childNodes);};jQuery.fn.load=function(url,params,callback){var selector,type,response,self=this,off=url.indexOf(" ");if(off>-1){selector=stripAndCollapse(url.slice(off));url=url.slice(0,off);}
if(isFunction(params)){callback=params;params=undefined;}else if(params&&typeof params==="object"){type="POST";}
if(self.length>0){jQuery.ajax({url:url,type:type||"GET",dataType:"html",data:params}).done(function(responseText){response=arguments;self.html(selector?jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector):responseText);}).always(callback&&function(jqXHR,status){self.each(function(){callback.apply(this,response||[jqXHR.responseText,status,jqXHR]);});});}
return this;};jQuery.expr.pseudos.animated=function(elem){return jQuery.grep(jQuery.timers,function(fn){return elem===fn.elem;}).length;};jQuery.offset={setOffset:function(elem,options,i){var curPosition,curLeft,curCSSTop,curTop,curOffset,curCSSLeft,calculatePosition,position=jQuery.css(elem,"position"),curElem=jQuery(elem),props={};if(position==="static"){elem.style.position="relative";}
curOffset=curElem.offset();curCSSTop=jQuery.css(elem,"top");curCSSLeft=jQuery.css(elem,"left");calculatePosition=(position==="absolute"||position==="fixed")&&(curCSSTop+curCSSLeft).indexOf("auto")>-1;if(calculatePosition){curPosition=curElem.position();curTop=curPosition.top;curLeft=curPosition.left;}else{curTop=parseFloat(curCSSTop)||0;curLeft=parseFloat(curCSSLeft)||0;}
if(isFunction(options)){options=options.call(elem,i,jQuery.extend({},curOffset));}
if(options.top!=null){props.top=(options.top-curOffset.top)+curTop;}
if(options.left!=null){props.left=(options.left-curOffset.left)+curLeft;}
if("using"in options){options.using.call(elem,props);}else{curElem.css(props);}}};jQuery.fn.extend({offset:function(options){if(arguments.length){return options===undefined?this:this.each(function(i){jQuery.offset.setOffset(this,options,i);});}
var rect,win,elem=this[0];if(!elem){return;}
if(!elem.getClientRects().length){return{top:0,left:0};}
rect=elem.getBoundingClientRect();win=elem.ownerDocument.defaultView;return{top:rect.top+win.pageYOffset,left:rect.left+win.pageXOffset};},position:function(){if(!this[0]){return;}
var offsetParent,offset,doc,elem=this[0],parentOffset={top:0,left:0};if(jQuery.css(elem,"position")==="fixed"){offset=elem.getBoundingClientRect();}else{offset=this.offset();doc=elem.ownerDocument;offsetParent=elem.offsetParent||doc.documentElement;while(offsetParent&&(offsetParent===doc.body||offsetParent===doc.documentElement)&&jQuery.css(offsetParent,"position")==="static"){offsetParent=offsetParent.parentNode;}
if(offsetParent&&offsetParent!==elem&&offsetParent.nodeType===1){parentOffset=jQuery(offsetParent).offset();parentOffset.top+=jQuery.css(offsetParent,"borderTopWidth",true);parentOffset.left+=jQuery.css(offsetParent,"borderLeftWidth",true);}}
return{top:offset.top-parentOffset.top-jQuery.css(elem,"marginTop",true),left:offset.left-parentOffset.left-jQuery.css(elem,"marginLeft",true)};},offsetParent:function(){return this.map(function(){var offsetParent=this.offsetParent;while(offsetParent&&jQuery.css(offsetParent,"position")==="static"){offsetParent=offsetParent.offsetParent;}
return offsetParent||documentElement;});}});jQuery.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(method,prop){var top="pageYOffset"===prop;jQuery.fn[method]=function(val){return access(this,function(elem,method,val){var win;if(isWindow(elem)){win=elem;}else if(elem.nodeType===9){win=elem.defaultView;}
if(val===undefined){return win?win[prop]:elem[method];}
if(win){win.scrollTo(!top?val:win.pageXOffset,top?val:win.pageYOffset);}else{elem[method]=val;}},method,val,arguments.length);};});jQuery.each(["top","left"],function(_i,prop){jQuery.cssHooks[prop]=addGetHookIf(support.pixelPosition,function(elem,computed){if(computed){computed=curCSS(elem,prop);return rnumnonpx.test(computed)?jQuery(elem).position()[prop]+"px":computed;}});});jQuery.each({Height:"height",Width:"width"},function(name,type){jQuery.each({padding:"inner"+name,content:type,"":"outer"+name},function(defaultExtra,funcName){jQuery.fn[funcName]=function(margin,value){var chainable=arguments.length&&(defaultExtra||typeof margin!=="boolean"),extra=defaultExtra||(margin===true||value===true?"margin":"border");return access(this,function(elem,type,value){var doc;if(isWindow(elem)){return funcName.indexOf("outer")===0?elem["inner"+name]:elem.document.documentElement["client"+name];}
if(elem.nodeType===9){doc=elem.documentElement;return Math.max(elem.body["scroll"+name],doc["scroll"+name],elem.body["offset"+name],doc["offset"+name],doc["client"+name]);}
return value===undefined?jQuery.css(elem,type,extra):jQuery.style(elem,type,value,extra);},type,chainable?margin:undefined,chainable);};});});jQuery.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(_i,type){jQuery.fn[type]=function(fn){return this.on(type,fn);};});jQuery.fn.extend({bind:function(types,data,fn){return this.on(types,null,data,fn);},unbind:function(types,fn){return this.off(types,null,fn);},delegate:function(selector,types,data,fn){return this.on(types,selector,data,fn);},undelegate:function(selector,types,fn){return arguments.length===1?this.off(selector,"**"):this.off(types,selector||"**",fn);},hover:function(fnOver,fnOut){return this.mouseenter(fnOver).mouseleave(fnOut||fnOver);}});jQuery.each(("blur focus focusin focusout resize scroll click dblclick "+"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave "+"change select submit keydown keypress keyup contextmenu").split(" "),function(_i,name){jQuery.fn[name]=function(data,fn){return arguments.length>0?this.on(name,null,data,fn):this.trigger(name);};});var rtrim=/^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;jQuery.proxy=function(fn,context){var tmp,args,proxy;if(typeof context==="string"){tmp=fn[context];context=fn;fn=tmp;}
if(!isFunction(fn)){return undefined;}
args=slice.call(arguments,2);proxy=function(){return fn.apply(context||this,args.concat(slice.call(arguments)));};proxy.guid=fn.guid=fn.guid||jQuery.guid++;return proxy;};jQuery.holdReady=function(hold){if(hold){jQuery.readyWait++;}else{jQuery.ready(true);}};jQuery.isArray=Array.isArray;jQuery.parseJSON=JSON.parse;jQuery.nodeName=nodeName;jQuery.isFunction=isFunction;jQuery.isWindow=isWindow;jQuery.camelCase=camelCase;jQuery.type=toType;jQuery.now=Date.now;jQuery.isNumeric=function(obj){var type=jQuery.type(obj);return(type==="number"||type==="string")&&!isNaN(obj-parseFloat(obj));};jQuery.trim=function(text){return text==null?"":(text+"").replace(rtrim,"$1");};if(typeof define==="function"&&define.amd){define("jquery",[],function(){return jQuery;});}
var
_jQuery=window.jQuery,_$=window.$;jQuery.noConflict=function(deep){if(window.$===jQuery){window.$=_$;}
if(deep&&window.jQuery===jQuery){window.jQuery=_jQuery;}
return jQuery;};if(typeof noGlobal==="undefined"){window.jQuery=window.$=jQuery;}
return jQuery;});;

/* /web/static/lib/popper/popper.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?factory(exports):typeof define==='function'&&define.amd?define(['exports'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,factory(global.Popper={}));}(this,(function(exports){'use strict';function getWindow(node){if(node==null){return window;}
if(node.toString()!=='[object Window]'){var ownerDocument=node.ownerDocument;return ownerDocument?ownerDocument.defaultView||window:window;}
return node;}
function isElement(node){var OwnElement=getWindow(node).Element;return node instanceof OwnElement||node.nodeType===Node.ELEMENT_NODE;}
function isHTMLElement(node){var OwnElement=getWindow(node).HTMLElement;return node instanceof OwnElement||node.nodeType===Node.ELEMENT_NODE;}
function isShadowRoot(node){if(typeof ShadowRoot==='undefined'){return false;}
var OwnElement=getWindow(node).ShadowRoot;return node instanceof OwnElement||node instanceof ShadowRoot;}
var max=Math.max;var min=Math.min;var round=Math.round;function getBoundingClientRect(element,includeScale){if(includeScale===void 0){includeScale=false;}
var rect=element.getBoundingClientRect();var scaleX=1;var scaleY=1;if(isHTMLElement(element)&&includeScale){var offsetHeight=element.offsetHeight;var offsetWidth=element.offsetWidth;if(offsetWidth>0){scaleX=round(rect.width)/offsetWidth||1;}
if(offsetHeight>0){scaleY=round(rect.height)/offsetHeight||1;}}
return{width:rect.width/scaleX,height:rect.height/scaleY,top:rect.top/scaleY,right:rect.right/scaleX,bottom:rect.bottom/scaleY,left:rect.left/scaleX,x:rect.left/scaleX,y:rect.top/scaleY};}
function getWindowScroll(node){var win=getWindow(node);var scrollLeft=win.pageXOffset;var scrollTop=win.pageYOffset;return{scrollLeft:scrollLeft,scrollTop:scrollTop};}
function getHTMLElementScroll(element){return{scrollLeft:element.scrollLeft,scrollTop:element.scrollTop};}
function getNodeScroll(node){if(node===getWindow(node)||!isHTMLElement(node)){return getWindowScroll(node);}else{return getHTMLElementScroll(node);}}
function getNodeName(element){return element?(element.nodeName||'').toLowerCase():null;}
function getDocumentElement(element){return((isElement(element)?element.ownerDocument:element.document)||window.document).documentElement;}
function getWindowScrollBarX(element){return getBoundingClientRect(getDocumentElement(element)).left+getWindowScroll(element).scrollLeft;}
function getComputedStyle(element){return getWindow(element).getComputedStyle(element);}
function isScrollParent(element){var _getComputedStyle=getComputedStyle(element),overflow=_getComputedStyle.overflow,overflowX=_getComputedStyle.overflowX,overflowY=_getComputedStyle.overflowY;return/auto|scroll|overlay|hidden/.test(overflow+overflowY+overflowX);}
function isElementScaled(element){var rect=element.getBoundingClientRect();var scaleX=round(rect.width)/element.offsetWidth||1;var scaleY=round(rect.height)/element.offsetHeight||1;return scaleX!==1||scaleY!==1;}
function getCompositeRect(elementOrVirtualElement,offsetParent,isFixed){if(isFixed===void 0){isFixed=false;}
var isOffsetParentAnElement=isHTMLElement(offsetParent);var offsetParentIsScaled=isHTMLElement(offsetParent)&&isElementScaled(offsetParent);var documentElement=getDocumentElement(offsetParent);var rect=getBoundingClientRect(elementOrVirtualElement,offsetParentIsScaled);var scroll={scrollLeft:0,scrollTop:0};var offsets={x:0,y:0};if(isOffsetParentAnElement||!isOffsetParentAnElement&&!isFixed){if(getNodeName(offsetParent)!=='body'||isScrollParent(documentElement)){scroll=getNodeScroll(offsetParent);}
if(isHTMLElement(offsetParent)){offsets=getBoundingClientRect(offsetParent,true);offsets.x+=offsetParent.clientLeft;offsets.y+=offsetParent.clientTop;}else if(documentElement){offsets.x=getWindowScrollBarX(documentElement);}}
return{x:rect.left+scroll.scrollLeft-offsets.x,y:rect.top+scroll.scrollTop-offsets.y,width:rect.width,height:rect.height};}
function getLayoutRect(element){var clientRect=getBoundingClientRect(element);var width=element.offsetWidth;var height=element.offsetHeight;if(Math.abs(clientRect.width-width)<=1){width=clientRect.width;}
if(Math.abs(clientRect.height-height)<=1){height=clientRect.height;}
return{x:element.offsetLeft,y:element.offsetTop,width:width,height:height};}
function getParentNode(element){if(getNodeName(element)==='html'){return element;}
return(element.assignedSlot||element.parentNode||(isShadowRoot(element)?element.host:null)||getDocumentElement(element));}
function getScrollParent(node){if(['html','body','#document'].indexOf(getNodeName(node))>=0){return node.ownerDocument.body;}
if(isHTMLElement(node)&&isScrollParent(node)){return node;}
return getScrollParent(getParentNode(node));}
function listScrollParents(element,list){var _element$ownerDocumen;if(list===void 0){list=[];}
var scrollParent=getScrollParent(element);var isBody=scrollParent===((_element$ownerDocumen=element.ownerDocument)==null?void 0:_element$ownerDocumen.body);var win=getWindow(scrollParent);var target=isBody?[win].concat(win.visualViewport||[],isScrollParent(scrollParent)?scrollParent:[]):scrollParent;var updatedList=list.concat(target);return isBody?updatedList:updatedList.concat(listScrollParents(getParentNode(target)));}
function isTableElement(element){return['table','td','th'].indexOf(getNodeName(element))>=0;}
function getTrueOffsetParent(element){if(!isHTMLElement(element)||getComputedStyle(element).position==='fixed'){return null;}
return element.offsetParent;}
function getContainingBlock(element){var isFirefox=navigator.userAgent.toLowerCase().indexOf('firefox')!==-1;var isIE=navigator.userAgent.indexOf('Trident')!==-1;if(isIE&&isHTMLElement(element)){var elementCss=getComputedStyle(element);if(elementCss.position==='fixed'){return null;}}
var currentNode=getParentNode(element);while(isHTMLElement(currentNode)&&['html','body'].indexOf(getNodeName(currentNode))<0){var css=getComputedStyle(currentNode);if(css.transform!=='none'||css.perspective!=='none'||css.contain==='paint'||['transform','perspective'].indexOf(css.willChange)!==-1||isFirefox&&css.willChange==='filter'||isFirefox&&css.filter&&css.filter!=='none'){return currentNode;}else{currentNode=currentNode.parentNode;}}
return null;}
function getOffsetParent(element){var window=getWindow(element);var offsetParent=getTrueOffsetParent(element);while(offsetParent&&isTableElement(offsetParent)&&getComputedStyle(offsetParent).position==='static'){offsetParent=getTrueOffsetParent(offsetParent);}
if(offsetParent&&(getNodeName(offsetParent)==='html'||getNodeName(offsetParent)==='body'&&getComputedStyle(offsetParent).position==='static')){return window;}
return offsetParent||getContainingBlock(element)||window;}
var top='top';var bottom='bottom';var right='right';var left='left';var auto='auto';var basePlacements=[top,bottom,right,left];var start='start';var end='end';var clippingParents='clippingParents';var viewport='viewport';var popper='popper';var reference='reference';var variationPlacements=basePlacements.reduce(function(acc,placement){return acc.concat([placement+"-"+start,placement+"-"+end]);},[]);var placements=[].concat(basePlacements,[auto]).reduce(function(acc,placement){return acc.concat([placement,placement+"-"+start,placement+"-"+end]);},[]);var beforeRead='beforeRead';var read='read';var afterRead='afterRead';var beforeMain='beforeMain';var main='main';var afterMain='afterMain';var beforeWrite='beforeWrite';var write='write';var afterWrite='afterWrite';var modifierPhases=[beforeRead,read,afterRead,beforeMain,main,afterMain,beforeWrite,write,afterWrite];function order(modifiers){var map=new Map();var visited=new Set();var result=[];modifiers.forEach(function(modifier){map.set(modifier.name,modifier);});function sort(modifier){visited.add(modifier.name);var requires=[].concat(modifier.requires||[],modifier.requiresIfExists||[]);requires.forEach(function(dep){if(!visited.has(dep)){var depModifier=map.get(dep);if(depModifier){sort(depModifier);}}});result.push(modifier);}
modifiers.forEach(function(modifier){if(!visited.has(modifier.name)){sort(modifier);}});return result;}
function orderModifiers(modifiers){var orderedModifiers=order(modifiers);return modifierPhases.reduce(function(acc,phase){return acc.concat(orderedModifiers.filter(function(modifier){return modifier.phase===phase;}));},[]);}
function debounce(fn){var pending;return function(){if(!pending){pending=new Promise(function(resolve){Promise.resolve().then(function(){pending=undefined;resolve(fn());});});}
return pending;};}
function format(str){for(var _len=arguments.length,args=new Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){args[_key-1]=arguments[_key];}
return[].concat(args).reduce(function(p,c){return p.replace(/%s/,c);},str);}
var INVALID_MODIFIER_ERROR='Popper: modifier "%s" provided an invalid %s property, expected %s but got %s';var MISSING_DEPENDENCY_ERROR='Popper: modifier "%s" requires "%s", but "%s" modifier is not available';var VALID_PROPERTIES=['name','enabled','phase','fn','effect','requires','options'];function validateModifiers(modifiers){modifiers.forEach(function(modifier){[].concat(Object.keys(modifier),VALID_PROPERTIES).filter(function(value,index,self){return self.indexOf(value)===index;}).forEach(function(key){switch(key){case'name':if(typeof modifier.name!=='string'){console.error(format(INVALID_MODIFIER_ERROR,String(modifier.name),'"name"','"string"',"\""+String(modifier.name)+"\""));}
break;case'enabled':if(typeof modifier.enabled!=='boolean'){console.error(format(INVALID_MODIFIER_ERROR,modifier.name,'"enabled"','"boolean"',"\""+String(modifier.enabled)+"\""));}
break;case'phase':if(modifierPhases.indexOf(modifier.phase)<0){console.error(format(INVALID_MODIFIER_ERROR,modifier.name,'"phase"',"either "+modifierPhases.join(', '),"\""+String(modifier.phase)+"\""));}
break;case'fn':if(typeof modifier.fn!=='function'){console.error(format(INVALID_MODIFIER_ERROR,modifier.name,'"fn"','"function"',"\""+String(modifier.fn)+"\""));}
break;case'effect':if(modifier.effect!=null&&typeof modifier.effect!=='function'){console.error(format(INVALID_MODIFIER_ERROR,modifier.name,'"effect"','"function"',"\""+String(modifier.fn)+"\""));}
break;case'requires':if(modifier.requires!=null&&!Array.isArray(modifier.requires)){console.error(format(INVALID_MODIFIER_ERROR,modifier.name,'"requires"','"array"',"\""+String(modifier.requires)+"\""));}
break;case'requiresIfExists':if(!Array.isArray(modifier.requiresIfExists)){console.error(format(INVALID_MODIFIER_ERROR,modifier.name,'"requiresIfExists"','"array"',"\""+String(modifier.requiresIfExists)+"\""));}
break;case'options':case'data':break;default:console.error("PopperJS: an invalid property has been provided to the \""+modifier.name+"\" modifier, valid properties are "+VALID_PROPERTIES.map(function(s){return"\""+s+"\"";}).join(', ')+"; but \""+key+"\" was provided.");}
modifier.requires&&modifier.requires.forEach(function(requirement){if(modifiers.find(function(mod){return mod.name===requirement;})==null){console.error(format(MISSING_DEPENDENCY_ERROR,String(modifier.name),requirement,requirement));}});});});}
function uniqueBy(arr,fn){var identifiers=new Set();return arr.filter(function(item){var identifier=fn(item);if(!identifiers.has(identifier)){identifiers.add(identifier);return true;}});}
function getBasePlacement(placement){return placement.split('-')[0];}
function mergeByName(modifiers){var merged=modifiers.reduce(function(merged,current){var existing=merged[current.name];merged[current.name]=existing?Object.assign({},existing,current,{options:Object.assign({},existing.options,current.options),data:Object.assign({},existing.data,current.data)}):current;return merged;},{});return Object.keys(merged).map(function(key){return merged[key];});}
function getViewportRect(element){var win=getWindow(element);var html=getDocumentElement(element);var visualViewport=win.visualViewport;var width=html.clientWidth;var height=html.clientHeight;var x=0;var y=0;if(visualViewport){width=visualViewport.width;height=visualViewport.height;if(!/^((?!chrome|android).)*safari/i.test(navigator.userAgent)){x=visualViewport.offsetLeft;y=visualViewport.offsetTop;}}
return{width:width,height:height,x:x+getWindowScrollBarX(element),y:y};}
function getDocumentRect(element){var _element$ownerDocumen;var html=getDocumentElement(element);var winScroll=getWindowScroll(element);var body=(_element$ownerDocumen=element.ownerDocument)==null?void 0:_element$ownerDocumen.body;var width=max(html.scrollWidth,html.clientWidth,body?body.scrollWidth:0,body?body.clientWidth:0);var height=max(html.scrollHeight,html.clientHeight,body?body.scrollHeight:0,body?body.clientHeight:0);var x=-winScroll.scrollLeft+getWindowScrollBarX(element);var y=-winScroll.scrollTop;if(getComputedStyle(body||html).direction==='rtl'){x+=max(html.clientWidth,body?body.clientWidth:0)-width;}
return{width:width,height:height,x:x,y:y};}
function contains(parent,child){var rootNode=child.getRootNode&&child.getRootNode();if(parent.contains(child)){return true;}
else if(rootNode&&isShadowRoot(rootNode)){var next=child;do{if(next&&parent.isSameNode(next)){return true;}
next=next.parentNode||next.host;}while(next);}
return false;}
function rectToClientRect(rect){return Object.assign({},rect,{left:rect.x,top:rect.y,right:rect.x+rect.width,bottom:rect.y+rect.height});}
function getInnerBoundingClientRect(element){var rect=getBoundingClientRect(element);rect.top=rect.top+element.clientTop;rect.left=rect.left+element.clientLeft;rect.bottom=rect.top+element.clientHeight;rect.right=rect.left+element.clientWidth;rect.width=element.clientWidth;rect.height=element.clientHeight;rect.x=rect.left;rect.y=rect.top;return rect;}
function getClientRectFromMixedType(element,clippingParent){return clippingParent===viewport?rectToClientRect(getViewportRect(element)):isElement(clippingParent)?getInnerBoundingClientRect(clippingParent):rectToClientRect(getDocumentRect(getDocumentElement(element)));}
function getClippingParents(element){var clippingParents=listScrollParents(getParentNode(element));var canEscapeClipping=['absolute','fixed'].indexOf(getComputedStyle(element).position)>=0;var clipperElement=canEscapeClipping&&isHTMLElement(element)?getOffsetParent(element):element;if(!isElement(clipperElement)){return[];}
return clippingParents.filter(function(clippingParent){return isElement(clippingParent)&&contains(clippingParent,clipperElement)&&getNodeName(clippingParent)!=='body';});}
function getClippingRect(element,boundary,rootBoundary){var mainClippingParents=boundary==='clippingParents'?getClippingParents(element):[].concat(boundary);var clippingParents=[].concat(mainClippingParents,[rootBoundary]);var firstClippingParent=clippingParents[0];var clippingRect=clippingParents.reduce(function(accRect,clippingParent){var rect=getClientRectFromMixedType(element,clippingParent);accRect.top=max(rect.top,accRect.top);accRect.right=min(rect.right,accRect.right);accRect.bottom=min(rect.bottom,accRect.bottom);accRect.left=max(rect.left,accRect.left);return accRect;},getClientRectFromMixedType(element,firstClippingParent));clippingRect.width=clippingRect.right-clippingRect.left;clippingRect.height=clippingRect.bottom-clippingRect.top;clippingRect.x=clippingRect.left;clippingRect.y=clippingRect.top;return clippingRect;}
function getVariation(placement){return placement.split('-')[1];}
function getMainAxisFromPlacement(placement){return['top','bottom'].indexOf(placement)>=0?'x':'y';}
function computeOffsets(_ref){var reference=_ref.reference,element=_ref.element,placement=_ref.placement;var basePlacement=placement?getBasePlacement(placement):null;var variation=placement?getVariation(placement):null;var commonX=reference.x+reference.width/2-element.width/2;var commonY=reference.y+reference.height/2-element.height/2;var offsets;switch(basePlacement){case top:offsets={x:commonX,y:reference.y-element.height};break;case bottom:offsets={x:commonX,y:reference.y+reference.height};break;case right:offsets={x:reference.x+reference.width,y:commonY};break;case left:offsets={x:reference.x-element.width,y:commonY};break;default:offsets={x:reference.x,y:reference.y};}
var mainAxis=basePlacement?getMainAxisFromPlacement(basePlacement):null;if(mainAxis!=null){var len=mainAxis==='y'?'height':'width';switch(variation){case start:offsets[mainAxis]=offsets[mainAxis]-(reference[len]/2-element[len]/2);break;case end:offsets[mainAxis]=offsets[mainAxis]+(reference[len]/2-element[len]/2);break;}}
return offsets;}
function getFreshSideObject(){return{top:0,right:0,bottom:0,left:0};}
function mergePaddingObject(paddingObject){return Object.assign({},getFreshSideObject(),paddingObject);}
function expandToHashMap(value,keys){return keys.reduce(function(hashMap,key){hashMap[key]=value;return hashMap;},{});}
function detectOverflow(state,options){if(options===void 0){options={};}
var _options=options,_options$placement=_options.placement,placement=_options$placement===void 0?state.placement:_options$placement,_options$boundary=_options.boundary,boundary=_options$boundary===void 0?clippingParents:_options$boundary,_options$rootBoundary=_options.rootBoundary,rootBoundary=_options$rootBoundary===void 0?viewport:_options$rootBoundary,_options$elementConte=_options.elementContext,elementContext=_options$elementConte===void 0?popper:_options$elementConte,_options$altBoundary=_options.altBoundary,altBoundary=_options$altBoundary===void 0?false:_options$altBoundary,_options$padding=_options.padding,padding=_options$padding===void 0?0:_options$padding;var paddingObject=mergePaddingObject(typeof padding!=='number'?padding:expandToHashMap(padding,basePlacements));var altContext=elementContext===popper?reference:popper;var popperRect=state.rects.popper;var element=state.elements[altBoundary?altContext:elementContext];var clippingClientRect=getClippingRect(isElement(element)?element:element.contextElement||getDocumentElement(state.elements.popper),boundary,rootBoundary);var referenceClientRect=getBoundingClientRect(state.elements.reference);var popperOffsets=computeOffsets({reference:referenceClientRect,element:popperRect,strategy:'absolute',placement:placement});var popperClientRect=rectToClientRect(Object.assign({},popperRect,popperOffsets));var elementClientRect=elementContext===popper?popperClientRect:referenceClientRect;var overflowOffsets={top:clippingClientRect.top-elementClientRect.top+paddingObject.top,bottom:elementClientRect.bottom-clippingClientRect.bottom+paddingObject.bottom,left:clippingClientRect.left-elementClientRect.left+paddingObject.left,right:elementClientRect.right-clippingClientRect.right+paddingObject.right};var offsetData=state.modifiersData.offset;if(elementContext===popper&&offsetData){var offset=offsetData[placement];Object.keys(overflowOffsets).forEach(function(key){var multiply=[right,bottom].indexOf(key)>=0?1:-1;var axis=[top,bottom].indexOf(key)>=0?'y':'x';overflowOffsets[key]+=offset[axis]*multiply;});}
return overflowOffsets;}
var INVALID_ELEMENT_ERROR='Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.';var INFINITE_LOOP_ERROR='Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.';var DEFAULT_OPTIONS={placement:'bottom',modifiers:[],strategy:'absolute'};function areValidElements(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}
return!args.some(function(element){return!(element&&typeof element.getBoundingClientRect==='function');});}
function popperGenerator(generatorOptions){if(generatorOptions===void 0){generatorOptions={};}
var _generatorOptions=generatorOptions,_generatorOptions$def=_generatorOptions.defaultModifiers,defaultModifiers=_generatorOptions$def===void 0?[]:_generatorOptions$def,_generatorOptions$def2=_generatorOptions.defaultOptions,defaultOptions=_generatorOptions$def2===void 0?DEFAULT_OPTIONS:_generatorOptions$def2;return function createPopper(reference,popper,options){if(options===void 0){options=defaultOptions;}
var state={placement:'bottom',orderedModifiers:[],options:Object.assign({},DEFAULT_OPTIONS,defaultOptions),modifiersData:{},elements:{reference:reference,popper:popper},attributes:{},styles:{}};var effectCleanupFns=[];var isDestroyed=false;var instance={state:state,setOptions:function setOptions(setOptionsAction){var options=typeof setOptionsAction==='function'?setOptionsAction(state.options):setOptionsAction;cleanupModifierEffects();state.options=Object.assign({},defaultOptions,state.options,options);state.scrollParents={reference:isElement(reference)?listScrollParents(reference):reference.contextElement?listScrollParents(reference.contextElement):[],popper:listScrollParents(popper)};var orderedModifiers=orderModifiers(mergeByName([].concat(defaultModifiers,state.options.modifiers)));state.orderedModifiers=orderedModifiers.filter(function(m){return m.enabled;});{var modifiers=uniqueBy([].concat(orderedModifiers,state.options.modifiers),function(_ref){var name=_ref.name;return name;});validateModifiers(modifiers);if(getBasePlacement(state.options.placement)===auto){var flipModifier=state.orderedModifiers.find(function(_ref2){var name=_ref2.name;return name==='flip';});if(!flipModifier){console.error(['Popper: "auto" placements require the "flip" modifier be','present and enabled to work.'].join(' '));}}
var _getComputedStyle=getComputedStyle(popper),marginTop=_getComputedStyle.marginTop,marginRight=_getComputedStyle.marginRight,marginBottom=_getComputedStyle.marginBottom,marginLeft=_getComputedStyle.marginLeft;if([marginTop,marginRight,marginBottom,marginLeft].some(function(margin){return parseFloat(margin);})){console.warn(['Popper: CSS "margin" styles cannot be used to apply padding','between the popper and its reference element or boundary.','To replicate margin, use the `offset` modifier, as well as','the `padding` option in the `preventOverflow` and `flip`','modifiers.'].join(' '));}}
runModifierEffects();return instance.update();},forceUpdate:function forceUpdate(){if(isDestroyed){return;}
var _state$elements=state.elements,reference=_state$elements.reference,popper=_state$elements.popper;if(!areValidElements(reference,popper)){{console.error(INVALID_ELEMENT_ERROR);}
return;}
state.rects={reference:getCompositeRect(reference,getOffsetParent(popper),state.options.strategy==='fixed'),popper:getLayoutRect(popper)};state.reset=false;state.placement=state.options.placement;state.orderedModifiers.forEach(function(modifier){return state.modifiersData[modifier.name]=Object.assign({},modifier.data);});var __debug_loops__=0;for(var index=0;index<state.orderedModifiers.length;index++){{__debug_loops__+=1;if(__debug_loops__>100){console.error(INFINITE_LOOP_ERROR);break;}}
if(state.reset===true){state.reset=false;index=-1;continue;}
var _state$orderedModifie=state.orderedModifiers[index],fn=_state$orderedModifie.fn,_state$orderedModifie2=_state$orderedModifie.options,_options=_state$orderedModifie2===void 0?{}:_state$orderedModifie2,name=_state$orderedModifie.name;if(typeof fn==='function'){state=fn({state:state,options:_options,name:name,instance:instance})||state;}}},update:debounce(function(){return new Promise(function(resolve){instance.forceUpdate();resolve(state);});}),destroy:function destroy(){cleanupModifierEffects();isDestroyed=true;}};if(!areValidElements(reference,popper)){{console.error(INVALID_ELEMENT_ERROR);}
return instance;}
instance.setOptions(options).then(function(state){if(!isDestroyed&&options.onFirstUpdate){options.onFirstUpdate(state);}});function runModifierEffects(){state.orderedModifiers.forEach(function(_ref3){var name=_ref3.name,_ref3$options=_ref3.options,options=_ref3$options===void 0?{}:_ref3$options,effect=_ref3.effect;if(typeof effect==='function'){var cleanupFn=effect({state:state,name:name,instance:instance,options:options});var noopFn=function noopFn(){};effectCleanupFns.push(cleanupFn||noopFn);}});}
function cleanupModifierEffects(){effectCleanupFns.forEach(function(fn){return fn();});effectCleanupFns=[];}
return instance;};}
var passive={passive:true};function effect$2(_ref){var state=_ref.state,instance=_ref.instance,options=_ref.options;var _options$scroll=options.scroll,scroll=_options$scroll===void 0?true:_options$scroll,_options$resize=options.resize,resize=_options$resize===void 0?true:_options$resize;var window=getWindow(state.elements.popper);var scrollParents=[].concat(state.scrollParents.reference,state.scrollParents.popper);if(scroll){scrollParents.forEach(function(scrollParent){scrollParent.addEventListener('scroll',instance.update,passive);});}
if(resize){window.addEventListener('resize',instance.update,passive);}
return function(){if(scroll){scrollParents.forEach(function(scrollParent){scrollParent.removeEventListener('scroll',instance.update,passive);});}
if(resize){window.removeEventListener('resize',instance.update,passive);}};}
var eventListeners={name:'eventListeners',enabled:true,phase:'write',fn:function fn(){},effect:effect$2,data:{}};function popperOffsets(_ref){var state=_ref.state,name=_ref.name;state.modifiersData[name]=computeOffsets({reference:state.rects.reference,element:state.rects.popper,strategy:'absolute',placement:state.placement});}
var popperOffsets$1={name:'popperOffsets',enabled:true,phase:'read',fn:popperOffsets,data:{}};var unsetSides={top:'auto',right:'auto',bottom:'auto',left:'auto'};function roundOffsetsByDPR(_ref){var x=_ref.x,y=_ref.y;var win=window;var dpr=win.devicePixelRatio||1;return{x:round(x*dpr)/dpr||0,y:round(y*dpr)/dpr||0};}
function mapToStyles(_ref2){var _Object$assign2;var popper=_ref2.popper,popperRect=_ref2.popperRect,placement=_ref2.placement,variation=_ref2.variation,offsets=_ref2.offsets,position=_ref2.position,gpuAcceleration=_ref2.gpuAcceleration,adaptive=_ref2.adaptive,roundOffsets=_ref2.roundOffsets,isFixed=_ref2.isFixed;var _offsets$x=offsets.x,x=_offsets$x===void 0?0:_offsets$x,_offsets$y=offsets.y,y=_offsets$y===void 0?0:_offsets$y;var _ref3=typeof roundOffsets==='function'?roundOffsets({x:x,y:y}):{x:x,y:y};x=_ref3.x;y=_ref3.y;var hasX=offsets.hasOwnProperty('x');var hasY=offsets.hasOwnProperty('y');var sideX=left;var sideY=top;var win=window;if(adaptive){var offsetParent=getOffsetParent(popper);var heightProp='clientHeight';var widthProp='clientWidth';if(offsetParent===getWindow(popper)){offsetParent=getDocumentElement(popper);if(getComputedStyle(offsetParent).position!=='static'&&position==='absolute'){heightProp='scrollHeight';widthProp='scrollWidth';}}
offsetParent=offsetParent;if(placement===top||(placement===left||placement===right)&&variation===end){sideY=bottom;var offsetY=isFixed&&win.visualViewport?win.visualViewport.height:offsetParent[heightProp];y-=offsetY-popperRect.height;y*=gpuAcceleration?1:-1;}
if(placement===left||(placement===top||placement===bottom)&&variation===end){sideX=right;var offsetX=isFixed&&win.visualViewport?win.visualViewport.width:offsetParent[widthProp];x-=offsetX-popperRect.width;x*=gpuAcceleration?1:-1;}}
var commonStyles=Object.assign({position:position},adaptive&&unsetSides);var _ref4=roundOffsets===true?roundOffsetsByDPR({x:x,y:y}):{x:x,y:y};x=_ref4.x;y=_ref4.y;if(gpuAcceleration){var _Object$assign;return Object.assign({},commonStyles,(_Object$assign={},_Object$assign[sideY]=hasY?'0':'',_Object$assign[sideX]=hasX?'0':'',_Object$assign.transform=(win.devicePixelRatio||1)<=1?"translate("+x+"px, "+y+"px)":"translate3d("+x+"px, "+y+"px, 0)",_Object$assign));}
return Object.assign({},commonStyles,(_Object$assign2={},_Object$assign2[sideY]=hasY?y+"px":'',_Object$assign2[sideX]=hasX?x+"px":'',_Object$assign2.transform='',_Object$assign2));}
function computeStyles(_ref5){var state=_ref5.state,options=_ref5.options;var _options$gpuAccelerat=options.gpuAcceleration,gpuAcceleration=_options$gpuAccelerat===void 0?true:_options$gpuAccelerat,_options$adaptive=options.adaptive,adaptive=_options$adaptive===void 0?true:_options$adaptive,_options$roundOffsets=options.roundOffsets,roundOffsets=_options$roundOffsets===void 0?true:_options$roundOffsets;{var transitionProperty=getComputedStyle(state.elements.popper).transitionProperty||'';if(adaptive&&['transform','top','right','bottom','left'].some(function(property){return transitionProperty.indexOf(property)>=0;})){console.warn(['Popper: Detected CSS transitions on at least one of the following','CSS properties: "transform", "top", "right", "bottom", "left".','\n\n','Disable the "computeStyles" modifier\'s `adaptive` option to allow','for smooth transitions, or remove these properties from the CSS','transition declaration on the popper element if only transitioning','opacity or background-color for example.','\n\n','We recommend using the popper element as a wrapper around an inner','element that can have any CSS property transitioned for animations.'].join(' '));}}
var commonStyles={placement:getBasePlacement(state.placement),variation:getVariation(state.placement),popper:state.elements.popper,popperRect:state.rects.popper,gpuAcceleration:gpuAcceleration,isFixed:state.options.strategy==='fixed'};if(state.modifiersData.popperOffsets!=null){state.styles.popper=Object.assign({},state.styles.popper,mapToStyles(Object.assign({},commonStyles,{offsets:state.modifiersData.popperOffsets,position:state.options.strategy,adaptive:adaptive,roundOffsets:roundOffsets})));}
if(state.modifiersData.arrow!=null){state.styles.arrow=Object.assign({},state.styles.arrow,mapToStyles(Object.assign({},commonStyles,{offsets:state.modifiersData.arrow,position:'absolute',adaptive:false,roundOffsets:roundOffsets})));}
state.attributes.popper=Object.assign({},state.attributes.popper,{'data-popper-placement':state.placement});}
var computeStyles$1={name:'computeStyles',enabled:true,phase:'beforeWrite',fn:computeStyles,data:{}};function applyStyles(_ref){var state=_ref.state;Object.keys(state.elements).forEach(function(name){var style=state.styles[name]||{};var attributes=state.attributes[name]||{};var element=state.elements[name];if(!isHTMLElement(element)||!getNodeName(element)){return;}
Object.assign(element.style,style);Object.keys(attributes).forEach(function(name){var value=attributes[name];if(value===false){element.removeAttribute(name);}else{element.setAttribute(name,value===true?'':value);}});});}
function effect$1(_ref2){var state=_ref2.state;var initialStyles={popper:{position:state.options.strategy,left:'0',top:'0',margin:'0'},arrow:{position:'absolute'},reference:{}};Object.assign(state.elements.popper.style,initialStyles.popper);state.styles=initialStyles;if(state.elements.arrow){Object.assign(state.elements.arrow.style,initialStyles.arrow);}
return function(){Object.keys(state.elements).forEach(function(name){var element=state.elements[name];var attributes=state.attributes[name]||{};var styleProperties=Object.keys(state.styles.hasOwnProperty(name)?state.styles[name]:initialStyles[name]);var style=styleProperties.reduce(function(style,property){style[property]='';return style;},{});if(!isHTMLElement(element)||!getNodeName(element)){return;}
Object.assign(element.style,style);Object.keys(attributes).forEach(function(attribute){element.removeAttribute(attribute);});});};}
var applyStyles$1={name:'applyStyles',enabled:true,phase:'write',fn:applyStyles,effect:effect$1,requires:['computeStyles']};function distanceAndSkiddingToXY(placement,rects,offset){var basePlacement=getBasePlacement(placement);var invertDistance=[left,top].indexOf(basePlacement)>=0?-1:1;var _ref=typeof offset==='function'?offset(Object.assign({},rects,{placement:placement})):offset,skidding=_ref[0],distance=_ref[1];skidding=skidding||0;distance=(distance||0)*invertDistance;return[left,right].indexOf(basePlacement)>=0?{x:distance,y:skidding}:{x:skidding,y:distance};}
function offset(_ref2){var state=_ref2.state,options=_ref2.options,name=_ref2.name;var _options$offset=options.offset,offset=_options$offset===void 0?[0,0]:_options$offset;var data=placements.reduce(function(acc,placement){acc[placement]=distanceAndSkiddingToXY(placement,state.rects,offset);return acc;},{});var _data$state$placement=data[state.placement],x=_data$state$placement.x,y=_data$state$placement.y;if(state.modifiersData.popperOffsets!=null){state.modifiersData.popperOffsets.x+=x;state.modifiersData.popperOffsets.y+=y;}
state.modifiersData[name]=data;}
var offset$1={name:'offset',enabled:true,phase:'main',requires:['popperOffsets'],fn:offset};var hash$1={left:'right',right:'left',bottom:'top',top:'bottom'};function getOppositePlacement(placement){return placement.replace(/left|right|bottom|top/g,function(matched){return hash$1[matched];});}
var hash={start:'end',end:'start'};function getOppositeVariationPlacement(placement){return placement.replace(/start|end/g,function(matched){return hash[matched];});}
function computeAutoPlacement(state,options){if(options===void 0){options={};}
var _options=options,placement=_options.placement,boundary=_options.boundary,rootBoundary=_options.rootBoundary,padding=_options.padding,flipVariations=_options.flipVariations,_options$allowedAutoP=_options.allowedAutoPlacements,allowedAutoPlacements=_options$allowedAutoP===void 0?placements:_options$allowedAutoP;var variation=getVariation(placement);var placements$1=variation?flipVariations?variationPlacements:variationPlacements.filter(function(placement){return getVariation(placement)===variation;}):basePlacements;var allowedPlacements=placements$1.filter(function(placement){return allowedAutoPlacements.indexOf(placement)>=0;});if(allowedPlacements.length===0){allowedPlacements=placements$1;{console.error(['Popper: The `allowedAutoPlacements` option did not allow any','placements. Ensure the `placement` option matches the variation','of the allowed placements.','For example, "auto" cannot be used to allow "bottom-start".','Use "auto-start" instead.'].join(' '));}}
var overflows=allowedPlacements.reduce(function(acc,placement){acc[placement]=detectOverflow(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,padding:padding})[getBasePlacement(placement)];return acc;},{});return Object.keys(overflows).sort(function(a,b){return overflows[a]-overflows[b];});}
function getExpandedFallbackPlacements(placement){if(getBasePlacement(placement)===auto){return[];}
var oppositePlacement=getOppositePlacement(placement);return[getOppositeVariationPlacement(placement),oppositePlacement,getOppositeVariationPlacement(oppositePlacement)];}
function flip(_ref){var state=_ref.state,options=_ref.options,name=_ref.name;if(state.modifiersData[name]._skip){return;}
var _options$mainAxis=options.mainAxis,checkMainAxis=_options$mainAxis===void 0?true:_options$mainAxis,_options$altAxis=options.altAxis,checkAltAxis=_options$altAxis===void 0?true:_options$altAxis,specifiedFallbackPlacements=options.fallbackPlacements,padding=options.padding,boundary=options.boundary,rootBoundary=options.rootBoundary,altBoundary=options.altBoundary,_options$flipVariatio=options.flipVariations,flipVariations=_options$flipVariatio===void 0?true:_options$flipVariatio,allowedAutoPlacements=options.allowedAutoPlacements;var preferredPlacement=state.options.placement;var basePlacement=getBasePlacement(preferredPlacement);var isBasePlacement=basePlacement===preferredPlacement;var fallbackPlacements=specifiedFallbackPlacements||(isBasePlacement||!flipVariations?[getOppositePlacement(preferredPlacement)]:getExpandedFallbackPlacements(preferredPlacement));var placements=[preferredPlacement].concat(fallbackPlacements).reduce(function(acc,placement){return acc.concat(getBasePlacement(placement)===auto?computeAutoPlacement(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,padding:padding,flipVariations:flipVariations,allowedAutoPlacements:allowedAutoPlacements}):placement);},[]);var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var checksMap=new Map();var makeFallbackChecks=true;var firstFittingPlacement=placements[0];for(var i=0;i<placements.length;i++){var placement=placements[i];var _basePlacement=getBasePlacement(placement);var isStartVariation=getVariation(placement)===start;var isVertical=[top,bottom].indexOf(_basePlacement)>=0;var len=isVertical?'width':'height';var overflow=detectOverflow(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,altBoundary:altBoundary,padding:padding});var mainVariationSide=isVertical?isStartVariation?right:left:isStartVariation?bottom:top;if(referenceRect[len]>popperRect[len]){mainVariationSide=getOppositePlacement(mainVariationSide);}
var altVariationSide=getOppositePlacement(mainVariationSide);var checks=[];if(checkMainAxis){checks.push(overflow[_basePlacement]<=0);}
if(checkAltAxis){checks.push(overflow[mainVariationSide]<=0,overflow[altVariationSide]<=0);}
if(checks.every(function(check){return check;})){firstFittingPlacement=placement;makeFallbackChecks=false;break;}
checksMap.set(placement,checks);}
if(makeFallbackChecks){var numberOfChecks=flipVariations?3:1;var _loop=function _loop(_i){var fittingPlacement=placements.find(function(placement){var checks=checksMap.get(placement);if(checks){return checks.slice(0,_i).every(function(check){return check;});}});if(fittingPlacement){firstFittingPlacement=fittingPlacement;return"break";}};for(var _i=numberOfChecks;_i>0;_i--){var _ret=_loop(_i);if(_ret==="break")break;}}
if(state.placement!==firstFittingPlacement){state.modifiersData[name]._skip=true;state.placement=firstFittingPlacement;state.reset=true;}}
var flip$1={name:'flip',enabled:true,phase:'main',fn:flip,requiresIfExists:['offset'],data:{_skip:false}};function getAltAxis(axis){return axis==='x'?'y':'x';}
function within(min$1,value,max$1){return max(min$1,min(value,max$1));}
function withinMaxClamp(min,value,max){var v=within(min,value,max);return v>max?max:v;}
function preventOverflow(_ref){var state=_ref.state,options=_ref.options,name=_ref.name;var _options$mainAxis=options.mainAxis,checkMainAxis=_options$mainAxis===void 0?true:_options$mainAxis,_options$altAxis=options.altAxis,checkAltAxis=_options$altAxis===void 0?false:_options$altAxis,boundary=options.boundary,rootBoundary=options.rootBoundary,altBoundary=options.altBoundary,padding=options.padding,_options$tether=options.tether,tether=_options$tether===void 0?true:_options$tether,_options$tetherOffset=options.tetherOffset,tetherOffset=_options$tetherOffset===void 0?0:_options$tetherOffset;var overflow=detectOverflow(state,{boundary:boundary,rootBoundary:rootBoundary,padding:padding,altBoundary:altBoundary});var basePlacement=getBasePlacement(state.placement);var variation=getVariation(state.placement);var isBasePlacement=!variation;var mainAxis=getMainAxisFromPlacement(basePlacement);var altAxis=getAltAxis(mainAxis);var popperOffsets=state.modifiersData.popperOffsets;var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var tetherOffsetValue=typeof tetherOffset==='function'?tetherOffset(Object.assign({},state.rects,{placement:state.placement})):tetherOffset;var normalizedTetherOffsetValue=typeof tetherOffsetValue==='number'?{mainAxis:tetherOffsetValue,altAxis:tetherOffsetValue}:Object.assign({mainAxis:0,altAxis:0},tetherOffsetValue);var offsetModifierState=state.modifiersData.offset?state.modifiersData.offset[state.placement]:null;var data={x:0,y:0};if(!popperOffsets){return;}
if(checkMainAxis){var _offsetModifierState$;var mainSide=mainAxis==='y'?top:left;var altSide=mainAxis==='y'?bottom:right;var len=mainAxis==='y'?'height':'width';var offset=popperOffsets[mainAxis];var min$1=offset+overflow[mainSide];var max$1=offset-overflow[altSide];var additive=tether?-popperRect[len]/2:0;var minLen=variation===start?referenceRect[len]:popperRect[len];var maxLen=variation===start?-popperRect[len]:-referenceRect[len];var arrowElement=state.elements.arrow;var arrowRect=tether&&arrowElement?getLayoutRect(arrowElement):{width:0,height:0};var arrowPaddingObject=state.modifiersData['arrow#persistent']?state.modifiersData['arrow#persistent'].padding:getFreshSideObject();var arrowPaddingMin=arrowPaddingObject[mainSide];var arrowPaddingMax=arrowPaddingObject[altSide];var arrowLen=within(0,referenceRect[len],arrowRect[len]);var minOffset=isBasePlacement?referenceRect[len]/2-additive-arrowLen-arrowPaddingMin-normalizedTetherOffsetValue.mainAxis:minLen-arrowLen-arrowPaddingMin-normalizedTetherOffsetValue.mainAxis;var maxOffset=isBasePlacement?-referenceRect[len]/2+additive+arrowLen+arrowPaddingMax+normalizedTetherOffsetValue.mainAxis:maxLen+arrowLen+arrowPaddingMax+normalizedTetherOffsetValue.mainAxis;var arrowOffsetParent=state.elements.arrow&&getOffsetParent(state.elements.arrow);var clientOffset=arrowOffsetParent?mainAxis==='y'?arrowOffsetParent.clientTop||0:arrowOffsetParent.clientLeft||0:0;var offsetModifierValue=(_offsetModifierState$=offsetModifierState==null?void 0:offsetModifierState[mainAxis])!=null?_offsetModifierState$:0;var tetherMin=offset+minOffset-offsetModifierValue-clientOffset;var tetherMax=offset+maxOffset-offsetModifierValue;var preventedOffset=within(tether?min(min$1,tetherMin):min$1,offset,tether?max(max$1,tetherMax):max$1);popperOffsets[mainAxis]=preventedOffset;data[mainAxis]=preventedOffset-offset;}
if(checkAltAxis){var _offsetModifierState$2;var _mainSide=mainAxis==='x'?top:left;var _altSide=mainAxis==='x'?bottom:right;var _offset=popperOffsets[altAxis];var _len=altAxis==='y'?'height':'width';var _min=_offset+overflow[_mainSide];var _max=_offset-overflow[_altSide];var isOriginSide=[top,left].indexOf(basePlacement)!==-1;var _offsetModifierValue=(_offsetModifierState$2=offsetModifierState==null?void 0:offsetModifierState[altAxis])!=null?_offsetModifierState$2:0;var _tetherMin=isOriginSide?_min:_offset-referenceRect[_len]-popperRect[_len]-_offsetModifierValue+normalizedTetherOffsetValue.altAxis;var _tetherMax=isOriginSide?_offset+referenceRect[_len]+popperRect[_len]-_offsetModifierValue-normalizedTetherOffsetValue.altAxis:_max;var _preventedOffset=tether&&isOriginSide?withinMaxClamp(_tetherMin,_offset,_tetherMax):within(tether?_tetherMin:_min,_offset,tether?_tetherMax:_max);popperOffsets[altAxis]=_preventedOffset;data[altAxis]=_preventedOffset-_offset;}
state.modifiersData[name]=data;}
var preventOverflow$1={name:'preventOverflow',enabled:true,phase:'main',fn:preventOverflow,requiresIfExists:['offset']};var toPaddingObject=function toPaddingObject(padding,state){padding=typeof padding==='function'?padding(Object.assign({},state.rects,{placement:state.placement})):padding;return mergePaddingObject(typeof padding!=='number'?padding:expandToHashMap(padding,basePlacements));};function arrow(_ref){var _state$modifiersData$;var state=_ref.state,name=_ref.name,options=_ref.options;var arrowElement=state.elements.arrow;var popperOffsets=state.modifiersData.popperOffsets;var basePlacement=getBasePlacement(state.placement);var axis=getMainAxisFromPlacement(basePlacement);var isVertical=[left,right].indexOf(basePlacement)>=0;var len=isVertical?'height':'width';if(!arrowElement||!popperOffsets){return;}
var paddingObject=toPaddingObject(options.padding,state);var arrowRect=getLayoutRect(arrowElement);var minProp=axis==='y'?top:left;var maxProp=axis==='y'?bottom:right;var endDiff=state.rects.reference[len]+state.rects.reference[axis]-popperOffsets[axis]-state.rects.popper[len];var startDiff=popperOffsets[axis]-state.rects.reference[axis];var arrowOffsetParent=getOffsetParent(arrowElement);var clientSize=arrowOffsetParent?axis==='y'?arrowOffsetParent.clientHeight||0:arrowOffsetParent.clientWidth||0:0;var centerToReference=endDiff/2-startDiff/2;var min=paddingObject[minProp];var max=clientSize-arrowRect[len]-paddingObject[maxProp];var center=clientSize/2-arrowRect[len]/2+centerToReference;var offset=within(min,center,max);var axisProp=axis;state.modifiersData[name]=(_state$modifiersData$={},_state$modifiersData$[axisProp]=offset,_state$modifiersData$.centerOffset=offset-center,_state$modifiersData$);}
function effect(_ref2){var state=_ref2.state,options=_ref2.options;var _options$element=options.element,arrowElement=_options$element===void 0?'[data-popper-arrow]':_options$element;if(arrowElement==null){return;}
if(typeof arrowElement==='string'){arrowElement=state.elements.popper.querySelector(arrowElement);if(!arrowElement){return;}}
{if(!isHTMLElement(arrowElement)){console.error(['Popper: "arrow" element must be an HTMLElement (not an SVGElement).','To use an SVG arrow, wrap it in an HTMLElement that will be used as','the arrow.'].join(' '));}}
if(!contains(state.elements.popper,arrowElement)){{console.error(['Popper: "arrow" modifier\'s `element` must be a child of the popper','element.'].join(' '));}
return;}
state.elements.arrow=arrowElement;}
var arrow$1={name:'arrow',enabled:true,phase:'main',fn:arrow,effect:effect,requires:['popperOffsets'],requiresIfExists:['preventOverflow']};function getSideOffsets(overflow,rect,preventedOffsets){if(preventedOffsets===void 0){preventedOffsets={x:0,y:0};}
return{top:overflow.top-rect.height-preventedOffsets.y,right:overflow.right-rect.width+preventedOffsets.x,bottom:overflow.bottom-rect.height+preventedOffsets.y,left:overflow.left-rect.width-preventedOffsets.x};}
function isAnySideFullyClipped(overflow){return[top,right,bottom,left].some(function(side){return overflow[side]>=0;});}
function hide(_ref){var state=_ref.state,name=_ref.name;var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var preventedOffsets=state.modifiersData.preventOverflow;var referenceOverflow=detectOverflow(state,{elementContext:'reference'});var popperAltOverflow=detectOverflow(state,{altBoundary:true});var referenceClippingOffsets=getSideOffsets(referenceOverflow,referenceRect);var popperEscapeOffsets=getSideOffsets(popperAltOverflow,popperRect,preventedOffsets);var isReferenceHidden=isAnySideFullyClipped(referenceClippingOffsets);var hasPopperEscaped=isAnySideFullyClipped(popperEscapeOffsets);state.modifiersData[name]={referenceClippingOffsets:referenceClippingOffsets,popperEscapeOffsets:popperEscapeOffsets,isReferenceHidden:isReferenceHidden,hasPopperEscaped:hasPopperEscaped};state.attributes.popper=Object.assign({},state.attributes.popper,{'data-popper-reference-hidden':isReferenceHidden,'data-popper-escaped':hasPopperEscaped});}
var hide$1={name:'hide',enabled:true,phase:'main',requiresIfExists:['preventOverflow'],fn:hide};var defaultModifiers$1=[eventListeners,popperOffsets$1,computeStyles$1,applyStyles$1];var createPopper$1=popperGenerator({defaultModifiers:defaultModifiers$1});var defaultModifiers=[eventListeners,popperOffsets$1,computeStyles$1,applyStyles$1,offset$1,flip$1,preventOverflow$1,arrow$1,hide$1];var createPopper=popperGenerator({defaultModifiers:defaultModifiers});exports.applyStyles=applyStyles$1;exports.arrow=arrow$1;exports.computeStyles=computeStyles$1;exports.createPopper=createPopper;exports.createPopperLite=createPopper$1;exports.defaultModifiers=defaultModifiers;exports.detectOverflow=detectOverflow;exports.eventListeners=eventListeners;exports.flip=flip$1;exports.hide=hide$1;exports.offset=offset$1;exports.popperGenerator=popperGenerator;exports.popperOffsets=popperOffsets$1;exports.preventOverflow=preventOverflow$1;Object.defineProperty(exports,'__esModule',{value:true});})));;

/* /web/static/lib/bootstrap/js/dist/dom/data.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory():typeof define==='function'&&define.amd?define(factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Data=factory());})(this,(function(){'use strict';const elementMap=new Map();const data={set(element,key,instance){if(!elementMap.has(element)){elementMap.set(element,new Map());}
const instanceMap=elementMap.get(element);if(!instanceMap.has(key)&&instanceMap.size!==0){console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);return;}
instanceMap.set(key,instance);},get(element,key){if(elementMap.has(element)){return elementMap.get(element).get(key)||null;}
return null;},remove(element,key){if(!elementMap.has(element)){return;}
const instanceMap=elementMap.get(element);instanceMap.delete(key);if(instanceMap.size===0){elementMap.delete(element);}}};return data;}));;

/* /web/static/lib/bootstrap/js/dist/dom/event-handler.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory():typeof define==='function'&&define.amd?define(factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.EventHandler=factory());})(this,(function(){'use strict';const getjQuery=()=>{const{jQuery}=window;if(jQuery&&!document.body.hasAttribute('data-bs-no-jquery')){return jQuery;}
return null;};const namespaceRegex=/[^.]*(?=\..*)\.|.*/;const stripNameRegex=/\..*/;const stripUidRegex=/::\d+$/;const eventRegistry={};let uidEvent=1;const customEvents={mouseenter:'mouseover',mouseleave:'mouseout'};const customEventsRegex=/^(mouseenter|mouseleave)/i;const nativeEvents=new Set(['click','dblclick','mouseup','mousedown','contextmenu','mousewheel','DOMMouseScroll','mouseover','mouseout','mousemove','selectstart','selectend','keydown','keypress','keyup','orientationchange','touchstart','touchmove','touchend','touchcancel','pointerdown','pointermove','pointerup','pointerleave','pointercancel','gesturestart','gesturechange','gestureend','focus','blur','change','reset','select','submit','focusin','focusout','load','unload','beforeunload','resize','move','DOMContentLoaded','readystatechange','error','abort','scroll']);function getUidEvent(element,uid){return uid&&`${uid}::${uidEvent++}`||element.uidEvent||uidEvent++;}
function getEvent(element){const uid=getUidEvent(element);element.uidEvent=uid;eventRegistry[uid]=eventRegistry[uid]||{};return eventRegistry[uid];}
function bootstrapHandler(element,fn){return function handler(event){event.delegateTarget=element;if(handler.oneOff){EventHandler.off(element,event.type,fn);}
return fn.apply(element,[event]);};}
function bootstrapDelegationHandler(element,selector,fn){return function handler(event){const domElements=element.querySelectorAll(selector);for(let{target}=event;target&&target!==this;target=target.parentNode){for(let i=domElements.length;i--;){if(domElements[i]===target){event.delegateTarget=target;if(handler.oneOff){EventHandler.off(element,event.type,selector,fn);}
return fn.apply(target,[event]);}}}
return null;};}
function findHandler(events,handler,delegationSelector=null){const uidEventList=Object.keys(events);for(let i=0,len=uidEventList.length;i<len;i++){const event=events[uidEventList[i]];if(event.originalHandler===handler&&event.delegationSelector===delegationSelector){return event;}}
return null;}
function normalizeParams(originalTypeEvent,handler,delegationFn){const delegation=typeof handler==='string';const originalHandler=delegation?delegationFn:handler;let typeEvent=getTypeEvent(originalTypeEvent);const isNative=nativeEvents.has(typeEvent);if(!isNative){typeEvent=originalTypeEvent;}
return[delegation,originalHandler,typeEvent];}
function addHandler(element,originalTypeEvent,handler,delegationFn,oneOff){if(typeof originalTypeEvent!=='string'||!element){return;}
if(!handler){handler=delegationFn;delegationFn=null;}
if(customEventsRegex.test(originalTypeEvent)){const wrapFn=fn=>{return function(event){if(!event.relatedTarget||event.relatedTarget!==event.delegateTarget&&!event.delegateTarget.contains(event.relatedTarget)){return fn.call(this,event);}};};if(delegationFn){delegationFn=wrapFn(delegationFn);}else{handler=wrapFn(handler);}}
const[delegation,originalHandler,typeEvent]=normalizeParams(originalTypeEvent,handler,delegationFn);const events=getEvent(element);const handlers=events[typeEvent]||(events[typeEvent]={});const previousFn=findHandler(handlers,originalHandler,delegation?handler:null);if(previousFn){previousFn.oneOff=previousFn.oneOff&&oneOff;return;}
const uid=getUidEvent(originalHandler,originalTypeEvent.replace(namespaceRegex,''));const fn=delegation?bootstrapDelegationHandler(element,handler,delegationFn):bootstrapHandler(element,handler);fn.delegationSelector=delegation?handler:null;fn.originalHandler=originalHandler;fn.oneOff=oneOff;fn.uidEvent=uid;handlers[uid]=fn;element.addEventListener(typeEvent,fn,delegation);}
function removeHandler(element,events,typeEvent,handler,delegationSelector){const fn=findHandler(events[typeEvent],handler,delegationSelector);if(!fn){return;}
element.removeEventListener(typeEvent,fn,Boolean(delegationSelector));delete events[typeEvent][fn.uidEvent];}
function removeNamespacedHandlers(element,events,typeEvent,namespace){const storeElementEvent=events[typeEvent]||{};Object.keys(storeElementEvent).forEach(handlerKey=>{if(handlerKey.includes(namespace)){const event=storeElementEvent[handlerKey];removeHandler(element,events,typeEvent,event.originalHandler,event.delegationSelector);}});}
function getTypeEvent(event){event=event.replace(stripNameRegex,'');return customEvents[event]||event;}
const EventHandler={on(element,event,handler,delegationFn){addHandler(element,event,handler,delegationFn,false);},one(element,event,handler,delegationFn){addHandler(element,event,handler,delegationFn,true);},off(element,originalTypeEvent,handler,delegationFn){if(typeof originalTypeEvent!=='string'||!element){return;}
const[delegation,originalHandler,typeEvent]=normalizeParams(originalTypeEvent,handler,delegationFn);const inNamespace=typeEvent!==originalTypeEvent;const events=getEvent(element);const isNamespace=originalTypeEvent.startsWith('.');if(typeof originalHandler!=='undefined'){if(!events||!events[typeEvent]){return;}
removeHandler(element,events,typeEvent,originalHandler,delegation?handler:null);return;}
if(isNamespace){Object.keys(events).forEach(elementEvent=>{removeNamespacedHandlers(element,events,elementEvent,originalTypeEvent.slice(1));});}
const storeElementEvent=events[typeEvent]||{};Object.keys(storeElementEvent).forEach(keyHandlers=>{const handlerKey=keyHandlers.replace(stripUidRegex,'');if(!inNamespace||originalTypeEvent.includes(handlerKey)){const event=storeElementEvent[keyHandlers];removeHandler(element,events,typeEvent,event.originalHandler,event.delegationSelector);}});},trigger(element,event,args){if(typeof event!=='string'||!element){return null;}
const $=getjQuery();const typeEvent=getTypeEvent(event);const inNamespace=event!==typeEvent;const isNative=nativeEvents.has(typeEvent);let jQueryEvent;let bubbles=true;let nativeDispatch=true;let defaultPrevented=false;let evt=null;if(inNamespace&&$){jQueryEvent=$.Event(event,args);$(element).trigger(jQueryEvent);bubbles=!jQueryEvent.isPropagationStopped();nativeDispatch=!jQueryEvent.isImmediatePropagationStopped();defaultPrevented=jQueryEvent.isDefaultPrevented();}
if(isNative){evt=document.createEvent('HTMLEvents');evt.initEvent(typeEvent,bubbles,true);}else{evt=new CustomEvent(event,{bubbles,cancelable:true});}
if(typeof args!=='undefined'){Object.keys(args).forEach(key=>{Object.defineProperty(evt,key,{get(){return args[key];}});});}
if(defaultPrevented){evt.preventDefault();}
if(nativeDispatch){element.dispatchEvent(evt);}
if(evt.defaultPrevented&&typeof jQueryEvent!=='undefined'){jQueryEvent.preventDefault();}
return evt;}};return EventHandler;}));;

/* /web/static/lib/bootstrap/js/dist/dom/manipulator.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory():typeof define==='function'&&define.amd?define(factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Manipulator=factory());})(this,(function(){'use strict';function normalizeData(val){if(val==='true'){return true;}
if(val==='false'){return false;}
if(val===Number(val).toString()){return Number(val);}
if(val===''||val==='null'){return null;}
return val;}
function normalizeDataKey(key){return key.replace(/[A-Z]/g,chr=>`-${chr.toLowerCase()}`);}
const Manipulator={setDataAttribute(element,key,value){element.setAttribute(`data-bs-${normalizeDataKey(key)}`,value);},removeDataAttribute(element,key){element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);},getDataAttributes(element){if(!element){return{};}
const attributes={};Object.keys(element.dataset).filter(key=>key.startsWith('bs')).forEach(key=>{let pureKey=key.replace(/^bs/,'');pureKey=pureKey.charAt(0).toLowerCase()+pureKey.slice(1,pureKey.length);attributes[pureKey]=normalizeData(element.dataset[key]);});return attributes;},getDataAttribute(element,key){return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));},offset(element){const rect=element.getBoundingClientRect();return{top:rect.top+window.pageYOffset,left:rect.left+window.pageXOffset};},position(element){return{top:element.offsetTop,left:element.offsetLeft};}};return Manipulator;}));;

/* /web/static/lib/bootstrap/js/dist/dom/selector-engine.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory():typeof define==='function'&&define.amd?define(factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.SelectorEngine=factory());})(this,(function(){'use strict';const isElement=obj=>{if(!obj||typeof obj!=='object'){return false;}
if(typeof obj.jquery!=='undefined'){obj=obj[0];}
return typeof obj.nodeType!=='undefined';};const isVisible=element=>{if(!isElement(element)||element.getClientRects().length===0){return false;}
return getComputedStyle(element).getPropertyValue('visibility')==='visible';};const isDisabled=element=>{if(!element||element.nodeType!==Node.ELEMENT_NODE){return true;}
if(element.classList.contains('disabled')){return true;}
if(typeof element.disabled!=='undefined'){return element.disabled;}
return element.hasAttribute('disabled')&&element.getAttribute('disabled')!=='false';};const NODE_TEXT=3;const SelectorEngine={find(selector,element=document.documentElement){return[].concat(...Element.prototype.querySelectorAll.call(element,selector));},findOne(selector,element=document.documentElement){return Element.prototype.querySelector.call(element,selector);},children(element,selector){return[].concat(...element.children).filter(child=>child.matches(selector));},parents(element,selector){const parents=[];let ancestor=element.parentNode;while(ancestor&&ancestor.nodeType===Node.ELEMENT_NODE&&ancestor.nodeType!==NODE_TEXT){if(ancestor.matches(selector)){parents.push(ancestor);}
ancestor=ancestor.parentNode;}
return parents;},prev(element,selector){let previous=element.previousElementSibling;while(previous){if(previous.matches(selector)){return[previous];}
previous=previous.previousElementSibling;}
return[];},next(element,selector){let next=element.nextElementSibling;while(next){if(next.matches(selector)){return[next];}
next=next.nextElementSibling;}
return[];},focusableChildren(element){const focusables=['a','button','input','textarea','select','details','[tabindex]','[contenteditable="true"]'].map(selector=>`${selector}:not([tabindex^="-"])`).join(', ');return this.find(focusables,element).filter(el=>!isDisabled(el)&&isVisible(el));}};return SelectorEngine;}));;

/* /web/static/lib/bootstrap/js/dist/base-component.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./dom/data.js'),require('./dom/event-handler.js')):typeof define==='function'&&define.amd?define(['./dom/data','./dom/event-handler'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Base=factory(global.Data,global.EventHandler));})(this,(function(Data,EventHandler){'use strict';const _interopDefaultLegacy=e=>e&&typeof e==='object'&&'default'in e?e:{default:e};const Data__default=_interopDefaultLegacy(Data);const EventHandler__default=_interopDefaultLegacy(EventHandler);const MILLISECONDS_MULTIPLIER=1000;const TRANSITION_END='transitionend';const getTransitionDurationFromElement=element=>{if(!element){return 0;}
let{transitionDuration,transitionDelay}=window.getComputedStyle(element);const floatTransitionDuration=Number.parseFloat(transitionDuration);const floatTransitionDelay=Number.parseFloat(transitionDelay);if(!floatTransitionDuration&&!floatTransitionDelay){return 0;}
transitionDuration=transitionDuration.split(',')[0];transitionDelay=transitionDelay.split(',')[0];return(Number.parseFloat(transitionDuration)+Number.parseFloat(transitionDelay))*MILLISECONDS_MULTIPLIER;};const triggerTransitionEnd=element=>{element.dispatchEvent(new Event(TRANSITION_END));};const isElement=obj=>{if(!obj||typeof obj!=='object'){return false;}
if(typeof obj.jquery!=='undefined'){obj=obj[0];}
return typeof obj.nodeType!=='undefined';};const getElement=obj=>{if(isElement(obj)){return obj.jquery?obj[0]:obj;}
if(typeof obj==='string'&&obj.length>0){return document.querySelector(obj);}
return null;};const execute=callback=>{if(typeof callback==='function'){callback();}};const executeAfterTransition=(callback,transitionElement,waitForTransition=true)=>{if(!waitForTransition){execute(callback);return;}
const durationPadding=5;const emulatedDuration=getTransitionDurationFromElement(transitionElement)+durationPadding;let called=false;const handler=({target})=>{if(target!==transitionElement){return;}
called=true;transitionElement.removeEventListener(TRANSITION_END,handler);execute(callback);};transitionElement.addEventListener(TRANSITION_END,handler);setTimeout(()=>{if(!called){triggerTransitionEnd(transitionElement);}},emulatedDuration);};const VERSION='5.1.3';class BaseComponent{constructor(element){element=getElement(element);if(!element){return;}
this._element=element;Data__default.default.set(this._element,this.constructor.DATA_KEY,this);}
dispose(){Data__default.default.remove(this._element,this.constructor.DATA_KEY);EventHandler__default.default.off(this._element,this.constructor.EVENT_KEY);Object.getOwnPropertyNames(this).forEach(propertyName=>{this[propertyName]=null;});}
_queueCallback(callback,element,isAnimated=true){executeAfterTransition(callback,element,isAnimated);}
static getInstance(element){return Data__default.default.get(getElement(element),this.DATA_KEY);}
static getOrCreateInstance(element,config={}){return this.getInstance(element)||new this(element,typeof config==='object'?config:null);}
static get VERSION(){return VERSION;}
static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!');}
static get DATA_KEY(){return`bs.${this.NAME}`;}
static get EVENT_KEY(){return`.${this.DATA_KEY}`;}}
return BaseComponent;}));;

/* /web/static/lib/bootstrap/js/dist/alert.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./dom/event-handler.js'),require('./base-component.js')):typeof define==='function'&&define.amd?define(['./dom/event-handler','./base-component'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Alert=factory(global.EventHandler,global.Base));})(this,(function(EventHandler,BaseComponent){'use strict';const _interopDefaultLegacy=e=>e&&typeof e==='object'&&'default'in e?e:{default:e};const EventHandler__default=_interopDefaultLegacy(EventHandler);const BaseComponent__default=_interopDefaultLegacy(BaseComponent);const getSelector=element=>{let selector=element.getAttribute('data-bs-target');if(!selector||selector==='#'){let hrefAttr=element.getAttribute('href');if(!hrefAttr||!hrefAttr.includes('#')&&!hrefAttr.startsWith('.')){return null;}
if(hrefAttr.includes('#')&&!hrefAttr.startsWith('#')){hrefAttr=`#${hrefAttr.split('#')[1]}`;}
selector=hrefAttr&&hrefAttr!=='#'?hrefAttr.trim():null;}
return selector;};const getElementFromSelector=element=>{const selector=getSelector(element);return selector?document.querySelector(selector):null;};const isDisabled=element=>{if(!element||element.nodeType!==Node.ELEMENT_NODE){return true;}
if(element.classList.contains('disabled')){return true;}
if(typeof element.disabled!=='undefined'){return element.disabled;}
return element.hasAttribute('disabled')&&element.getAttribute('disabled')!=='false';};const getjQuery=()=>{const{jQuery}=window;if(jQuery&&!document.body.hasAttribute('data-bs-no-jquery')){return jQuery;}
return null;};const DOMContentLoadedCallbacks=[];const onDOMContentLoaded=callback=>{if(document.readyState==='loading'){if(!DOMContentLoadedCallbacks.length){document.addEventListener('DOMContentLoaded',()=>{DOMContentLoadedCallbacks.forEach(callback=>callback());});}
DOMContentLoadedCallbacks.push(callback);}else{callback();}};const defineJQueryPlugin=plugin=>{onDOMContentLoaded(()=>{const $=getjQuery();if($){const name=plugin.NAME;const JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface;$.fn[name].Constructor=plugin;$.fn[name].noConflict=()=>{$.fn[name]=JQUERY_NO_CONFLICT;return plugin.jQueryInterface;};}});};const enableDismissTrigger=(component,method='hide')=>{const clickEvent=`click.dismiss${component.EVENT_KEY}`;const name=component.NAME;EventHandler__default.default.on(document,clickEvent,`[data-bs-dismiss="${name}"]`,function(event){if(['A','AREA'].includes(this.tagName)){event.preventDefault();}
if(isDisabled(this)){return;}
const target=getElementFromSelector(this)||this.closest(`.${name}`);const instance=component.getOrCreateInstance(target);instance[method]();});};const NAME='alert';const DATA_KEY='bs.alert';const EVENT_KEY=`.${DATA_KEY}`;const EVENT_CLOSE=`close${EVENT_KEY}`;const EVENT_CLOSED=`closed${EVENT_KEY}`;const CLASS_NAME_FADE='fade';const CLASS_NAME_SHOW='show';class Alert extends BaseComponent__default.default{static get NAME(){return NAME;}
close(){const closeEvent=EventHandler__default.default.trigger(this._element,EVENT_CLOSE);if(closeEvent.defaultPrevented){return;}
this._element.classList.remove(CLASS_NAME_SHOW);const isAnimated=this._element.classList.contains(CLASS_NAME_FADE);this._queueCallback(()=>this._destroyElement(),this._element,isAnimated);}
_destroyElement(){this._element.remove();EventHandler__default.default.trigger(this._element,EVENT_CLOSED);this.dispose();}
static jQueryInterface(config){return this.each(function(){const data=Alert.getOrCreateInstance(this);if(typeof config!=='string'){return;}
if(data[config]===undefined||config.startsWith('_')||config==='constructor'){throw new TypeError(`No method named "${config}"`);}
data[config](this);});}}
enableDismissTrigger(Alert,'close');defineJQueryPlugin(Alert);return Alert;}));;

/* /web/static/lib/bootstrap/js/dist/button.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./dom/event-handler.js'),require('./base-component.js')):typeof define==='function'&&define.amd?define(['./dom/event-handler','./base-component'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Button=factory(global.EventHandler,global.Base));})(this,(function(EventHandler,BaseComponent){'use strict';const _interopDefaultLegacy=e=>e&&typeof e==='object'&&'default'in e?e:{default:e};const EventHandler__default=_interopDefaultLegacy(EventHandler);const BaseComponent__default=_interopDefaultLegacy(BaseComponent);const getjQuery=()=>{const{jQuery}=window;if(jQuery&&!document.body.hasAttribute('data-bs-no-jquery')){return jQuery;}
return null;};const DOMContentLoadedCallbacks=[];const onDOMContentLoaded=callback=>{if(document.readyState==='loading'){if(!DOMContentLoadedCallbacks.length){document.addEventListener('DOMContentLoaded',()=>{DOMContentLoadedCallbacks.forEach(callback=>callback());});}
DOMContentLoadedCallbacks.push(callback);}else{callback();}};const defineJQueryPlugin=plugin=>{onDOMContentLoaded(()=>{const $=getjQuery();if($){const name=plugin.NAME;const JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface;$.fn[name].Constructor=plugin;$.fn[name].noConflict=()=>{$.fn[name]=JQUERY_NO_CONFLICT;return plugin.jQueryInterface;};}});};const NAME='button';const DATA_KEY='bs.button';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const CLASS_NAME_ACTIVE='active';const SELECTOR_DATA_TOGGLE='[data-bs-toggle="button"]';const EVENT_CLICK_DATA_API=`click${EVENT_KEY}${DATA_API_KEY}`;class Button extends BaseComponent__default.default{static get NAME(){return NAME;}
toggle(){this._element.setAttribute('aria-pressed',this._element.classList.toggle(CLASS_NAME_ACTIVE));}
static jQueryInterface(config){return this.each(function(){const data=Button.getOrCreateInstance(this);if(config==='toggle'){data[config]();}});}}
EventHandler__default.default.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_TOGGLE,event=>{event.preventDefault();const button=event.target.closest(SELECTOR_DATA_TOGGLE);const data=Button.getOrCreateInstance(button);data.toggle();});defineJQueryPlugin(Button);return Button;}));;

/* /web/static/lib/bootstrap/js/dist/carousel.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./dom/event-handler.js'),require('./dom/manipulator.js'),require('./dom/selector-engine.js'),require('./base-component.js')):typeof define==='function'&&define.amd?define(['./dom/event-handler','./dom/manipulator','./dom/selector-engine','./base-component'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Carousel=factory(global.EventHandler,global.Manipulator,global.SelectorEngine,global.Base));})(this,(function(EventHandler,Manipulator,SelectorEngine,BaseComponent){'use strict';const _interopDefaultLegacy=e=>e&&typeof e==='object'&&'default'in e?e:{default:e};const EventHandler__default=_interopDefaultLegacy(EventHandler);const Manipulator__default=_interopDefaultLegacy(Manipulator);const SelectorEngine__default=_interopDefaultLegacy(SelectorEngine);const BaseComponent__default=_interopDefaultLegacy(BaseComponent);const TRANSITION_END='transitionend';const toType=obj=>{if(obj===null||obj===undefined){return`${obj}`;}
return{}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();};const getSelector=element=>{let selector=element.getAttribute('data-bs-target');if(!selector||selector==='#'){let hrefAttr=element.getAttribute('href');if(!hrefAttr||!hrefAttr.includes('#')&&!hrefAttr.startsWith('.')){return null;}
if(hrefAttr.includes('#')&&!hrefAttr.startsWith('#')){hrefAttr=`#${hrefAttr.split('#')[1]}`;}
selector=hrefAttr&&hrefAttr!=='#'?hrefAttr.trim():null;}
return selector;};const getElementFromSelector=element=>{const selector=getSelector(element);return selector?document.querySelector(selector):null;};const triggerTransitionEnd=element=>{element.dispatchEvent(new Event(TRANSITION_END));};const isElement=obj=>{if(!obj||typeof obj!=='object'){return false;}
if(typeof obj.jquery!=='undefined'){obj=obj[0];}
return typeof obj.nodeType!=='undefined';};const typeCheckConfig=(componentName,config,configTypes)=>{Object.keys(configTypes).forEach(property=>{const expectedTypes=configTypes[property];const value=config[property];const valueType=value&&isElement(value)?'element':toType(value);if(!new RegExp(expectedTypes).test(valueType)){throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);}});};const isVisible=element=>{if(!isElement(element)||element.getClientRects().length===0){return false;}
return getComputedStyle(element).getPropertyValue('visibility')==='visible';};const reflow=element=>{element.offsetHeight;};const getjQuery=()=>{const{jQuery}=window;if(jQuery&&!document.body.hasAttribute('data-bs-no-jquery')){return jQuery;}
return null;};const DOMContentLoadedCallbacks=[];const onDOMContentLoaded=callback=>{if(document.readyState==='loading'){if(!DOMContentLoadedCallbacks.length){document.addEventListener('DOMContentLoaded',()=>{DOMContentLoadedCallbacks.forEach(callback=>callback());});}
DOMContentLoadedCallbacks.push(callback);}else{callback();}};const isRTL=()=>document.documentElement.dir==='rtl';const defineJQueryPlugin=plugin=>{onDOMContentLoaded(()=>{const $=getjQuery();if($){const name=plugin.NAME;const JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface;$.fn[name].Constructor=plugin;$.fn[name].noConflict=()=>{$.fn[name]=JQUERY_NO_CONFLICT;return plugin.jQueryInterface;};}});};const getNextActiveElement=(list,activeElement,shouldGetNext,isCycleAllowed)=>{let index=list.indexOf(activeElement);if(index===-1){return list[!shouldGetNext&&isCycleAllowed?list.length-1:0];}
const listLength=list.length;index+=shouldGetNext?1:-1;if(isCycleAllowed){index=(index+listLength)%listLength;}
return list[Math.max(0,Math.min(index,listLength-1))];};const NAME='carousel';const DATA_KEY='bs.carousel';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const ARROW_LEFT_KEY='ArrowLeft';const ARROW_RIGHT_KEY='ArrowRight';const TOUCHEVENT_COMPAT_WAIT=500;const SWIPE_THRESHOLD=40;const Default={interval:5000,keyboard:true,slide:false,pause:'hover',wrap:true,touch:true};const DefaultType={interval:'(number|boolean)',keyboard:'boolean',slide:'(boolean|string)',pause:'(string|boolean)',wrap:'boolean',touch:'boolean'};const ORDER_NEXT='next';const ORDER_PREV='prev';const DIRECTION_LEFT='left';const DIRECTION_RIGHT='right';const KEY_TO_DIRECTION={[ARROW_LEFT_KEY]:DIRECTION_RIGHT,[ARROW_RIGHT_KEY]:DIRECTION_LEFT};const EVENT_SLIDE=`slide${EVENT_KEY}`;const EVENT_SLID=`slid${EVENT_KEY}`;const EVENT_KEYDOWN=`keydown${EVENT_KEY}`;const EVENT_MOUSEENTER=`mouseenter${EVENT_KEY}`;const EVENT_MOUSELEAVE=`mouseleave${EVENT_KEY}`;const EVENT_TOUCHSTART=`touchstart${EVENT_KEY}`;const EVENT_TOUCHMOVE=`touchmove${EVENT_KEY}`;const EVENT_TOUCHEND=`touchend${EVENT_KEY}`;const EVENT_POINTERDOWN=`pointerdown${EVENT_KEY}`;const EVENT_POINTERUP=`pointerup${EVENT_KEY}`;const EVENT_DRAG_START=`dragstart${EVENT_KEY}`;const EVENT_LOAD_DATA_API=`load${EVENT_KEY}${DATA_API_KEY}`;const EVENT_CLICK_DATA_API=`click${EVENT_KEY}${DATA_API_KEY}`;const CLASS_NAME_CAROUSEL='carousel';const CLASS_NAME_ACTIVE='active';const CLASS_NAME_SLIDE='slide';const CLASS_NAME_END='carousel-item-end';const CLASS_NAME_START='carousel-item-start';const CLASS_NAME_NEXT='carousel-item-next';const CLASS_NAME_PREV='carousel-item-prev';const CLASS_NAME_POINTER_EVENT='pointer-event';const SELECTOR_ACTIVE='.active';const SELECTOR_ACTIVE_ITEM='.active.carousel-item';const SELECTOR_ITEM='.carousel-item';const SELECTOR_ITEM_IMG='.carousel-item img';const SELECTOR_NEXT_PREV='.carousel-item-next, .carousel-item-prev';const SELECTOR_INDICATORS='.carousel-indicators';const SELECTOR_INDICATOR='[data-bs-target]';const SELECTOR_DATA_SLIDE='[data-bs-slide], [data-bs-slide-to]';const SELECTOR_DATA_RIDE='[data-bs-ride="carousel"]';const POINTER_TYPE_TOUCH='touch';const POINTER_TYPE_PEN='pen';class Carousel extends BaseComponent__default.default{constructor(element,config){super(element);this._items=null;this._interval=null;this._activeElement=null;this._isPaused=false;this._isSliding=false;this.touchTimeout=null;this.touchStartX=0;this.touchDeltaX=0;this._config=this._getConfig(config);this._indicatorsElement=SelectorEngine__default.default.findOne(SELECTOR_INDICATORS,this._element);this._touchSupported='ontouchstart'in document.documentElement||navigator.maxTouchPoints>0;this._pointerEvent=Boolean(window.PointerEvent);this._addEventListeners();}
static get Default(){return Default;}
static get NAME(){return NAME;}
next(){this._slide(ORDER_NEXT);}
nextWhenVisible(){if(!document.hidden&&isVisible(this._element)){this.next();}}
prev(){this._slide(ORDER_PREV);}
pause(event){if(!event){this._isPaused=true;}
if(SelectorEngine__default.default.findOne(SELECTOR_NEXT_PREV,this._element)){triggerTransitionEnd(this._element);this.cycle(true);}
clearInterval(this._interval);this._interval=null;}
cycle(event){if(!event){this._isPaused=false;}
if(this._interval){clearInterval(this._interval);this._interval=null;}
if(this._config&&this._config.interval&&!this._isPaused){this._updateInterval();this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval);}}
to(index){this._activeElement=SelectorEngine__default.default.findOne(SELECTOR_ACTIVE_ITEM,this._element);const activeIndex=this._getItemIndex(this._activeElement);if(index>this._items.length-1||index<0){return;}
if(this._isSliding){EventHandler__default.default.one(this._element,EVENT_SLID,()=>this.to(index));return;}
if(activeIndex===index){this.pause();this.cycle();return;}
const order=index>activeIndex?ORDER_NEXT:ORDER_PREV;this._slide(order,this._items[index]);}
_getConfig(config){config={...Default,...Manipulator__default.default.getDataAttributes(this._element),...(typeof config==='object'?config:{})};typeCheckConfig(NAME,config,DefaultType);return config;}
_handleSwipe(){const absDeltax=Math.abs(this.touchDeltaX);if(absDeltax<=SWIPE_THRESHOLD){return;}
const direction=absDeltax/this.touchDeltaX;this.touchDeltaX=0;if(!direction){return;}
this._slide(direction>0?DIRECTION_RIGHT:DIRECTION_LEFT);}
_addEventListeners(){if(this._config.keyboard){EventHandler__default.default.on(this._element,EVENT_KEYDOWN,event=>this._keydown(event));}
if(this._config.pause==='hover'){EventHandler__default.default.on(this._element,EVENT_MOUSEENTER,event=>this.pause(event));EventHandler__default.default.on(this._element,EVENT_MOUSELEAVE,event=>this.cycle(event));}
if(this._config.touch&&this._touchSupported){this._addTouchEventListeners();}}
_addTouchEventListeners(){const hasPointerPenTouch=event=>{return this._pointerEvent&&(event.pointerType===POINTER_TYPE_PEN||event.pointerType===POINTER_TYPE_TOUCH);};const start=event=>{if(hasPointerPenTouch(event)){this.touchStartX=event.clientX;}else if(!this._pointerEvent){this.touchStartX=event.touches[0].clientX;}};const move=event=>{this.touchDeltaX=event.touches&&event.touches.length>1?0:event.touches[0].clientX-this.touchStartX;};const end=event=>{if(hasPointerPenTouch(event)){this.touchDeltaX=event.clientX-this.touchStartX;}
this._handleSwipe();if(this._config.pause==='hover'){this.pause();if(this.touchTimeout){clearTimeout(this.touchTimeout);}
this.touchTimeout=setTimeout(event=>this.cycle(event),TOUCHEVENT_COMPAT_WAIT+this._config.interval);}};SelectorEngine__default.default.find(SELECTOR_ITEM_IMG,this._element).forEach(itemImg=>{EventHandler__default.default.on(itemImg,EVENT_DRAG_START,event=>event.preventDefault());});if(this._pointerEvent){EventHandler__default.default.on(this._element,EVENT_POINTERDOWN,event=>start(event));EventHandler__default.default.on(this._element,EVENT_POINTERUP,event=>end(event));this._element.classList.add(CLASS_NAME_POINTER_EVENT);}else{EventHandler__default.default.on(this._element,EVENT_TOUCHSTART,event=>start(event));EventHandler__default.default.on(this._element,EVENT_TOUCHMOVE,event=>move(event));EventHandler__default.default.on(this._element,EVENT_TOUCHEND,event=>end(event));}}
_keydown(event){if(/input|textarea/i.test(event.target.tagName)){return;}
const direction=KEY_TO_DIRECTION[event.key];if(direction){event.preventDefault();this._slide(direction);}}
_getItemIndex(element){this._items=element&&element.parentNode?SelectorEngine__default.default.find(SELECTOR_ITEM,element.parentNode):[];return this._items.indexOf(element);}
_getItemByOrder(order,activeElement){const isNext=order===ORDER_NEXT;return getNextActiveElement(this._items,activeElement,isNext,this._config.wrap);}
_triggerSlideEvent(relatedTarget,eventDirectionName){const targetIndex=this._getItemIndex(relatedTarget);const fromIndex=this._getItemIndex(SelectorEngine__default.default.findOne(SELECTOR_ACTIVE_ITEM,this._element));return EventHandler__default.default.trigger(this._element,EVENT_SLIDE,{relatedTarget,direction:eventDirectionName,from:fromIndex,to:targetIndex});}
_setActiveIndicatorElement(element){if(this._indicatorsElement){const activeIndicator=SelectorEngine__default.default.findOne(SELECTOR_ACTIVE,this._indicatorsElement);activeIndicator.classList.remove(CLASS_NAME_ACTIVE);activeIndicator.removeAttribute('aria-current');const indicators=SelectorEngine__default.default.find(SELECTOR_INDICATOR,this._indicatorsElement);for(let i=0;i<indicators.length;i++){if(Number.parseInt(indicators[i].getAttribute('data-bs-slide-to'),10)===this._getItemIndex(element)){indicators[i].classList.add(CLASS_NAME_ACTIVE);indicators[i].setAttribute('aria-current','true');break;}}}}
_updateInterval(){const element=this._activeElement||SelectorEngine__default.default.findOne(SELECTOR_ACTIVE_ITEM,this._element);if(!element){return;}
const elementInterval=Number.parseInt(element.getAttribute('data-bs-interval'),10);if(elementInterval){this._config.defaultInterval=this._config.defaultInterval||this._config.interval;this._config.interval=elementInterval;}else{this._config.interval=this._config.defaultInterval||this._config.interval;}}
_slide(directionOrOrder,element){const order=this._directionToOrder(directionOrOrder);const activeElement=SelectorEngine__default.default.findOne(SELECTOR_ACTIVE_ITEM,this._element);const activeElementIndex=this._getItemIndex(activeElement);const nextElement=element||this._getItemByOrder(order,activeElement);const nextElementIndex=this._getItemIndex(nextElement);const isCycling=Boolean(this._interval);const isNext=order===ORDER_NEXT;const directionalClassName=isNext?CLASS_NAME_START:CLASS_NAME_END;const orderClassName=isNext?CLASS_NAME_NEXT:CLASS_NAME_PREV;const eventDirectionName=this._orderToDirection(order);if(nextElement&&nextElement.classList.contains(CLASS_NAME_ACTIVE)){this._isSliding=false;return;}
if(this._isSliding){return;}
const slideEvent=this._triggerSlideEvent(nextElement,eventDirectionName);if(slideEvent.defaultPrevented){return;}
if(!activeElement||!nextElement){return;}
this._isSliding=true;if(isCycling){this.pause();}
this._setActiveIndicatorElement(nextElement);this._activeElement=nextElement;const triggerSlidEvent=()=>{EventHandler__default.default.trigger(this._element,EVENT_SLID,{relatedTarget:nextElement,direction:eventDirectionName,from:activeElementIndex,to:nextElementIndex});};if(this._element.classList.contains(CLASS_NAME_SLIDE)){nextElement.classList.add(orderClassName);reflow(nextElement);activeElement.classList.add(directionalClassName);nextElement.classList.add(directionalClassName);const completeCallBack=()=>{nextElement.classList.remove(directionalClassName,orderClassName);nextElement.classList.add(CLASS_NAME_ACTIVE);activeElement.classList.remove(CLASS_NAME_ACTIVE,orderClassName,directionalClassName);this._isSliding=false;setTimeout(triggerSlidEvent,0);};this._queueCallback(completeCallBack,activeElement,true);}else{activeElement.classList.remove(CLASS_NAME_ACTIVE);nextElement.classList.add(CLASS_NAME_ACTIVE);this._isSliding=false;triggerSlidEvent();}
if(isCycling){this.cycle();}}
_directionToOrder(direction){if(![DIRECTION_RIGHT,DIRECTION_LEFT].includes(direction)){return direction;}
if(isRTL()){return direction===DIRECTION_LEFT?ORDER_PREV:ORDER_NEXT;}
return direction===DIRECTION_LEFT?ORDER_NEXT:ORDER_PREV;}
_orderToDirection(order){if(![ORDER_NEXT,ORDER_PREV].includes(order)){return order;}
if(isRTL()){return order===ORDER_PREV?DIRECTION_LEFT:DIRECTION_RIGHT;}
return order===ORDER_PREV?DIRECTION_RIGHT:DIRECTION_LEFT;}
static carouselInterface(element,config){const data=Carousel.getOrCreateInstance(element,config);let{_config}=data;if(typeof config==='object'){_config={..._config,...config};}
const action=typeof config==='string'?config:_config.slide;if(typeof config==='number'){data.to(config);}else if(typeof action==='string'){if(typeof data[action]==='undefined'){throw new TypeError(`No method named "${action}"`);}
data[action]();}else if(_config.interval&&_config.ride){data.pause();data.cycle();}}
static jQueryInterface(config){return this.each(function(){Carousel.carouselInterface(this,config);});}
static dataApiClickHandler(event){const target=getElementFromSelector(this);if(!target||!target.classList.contains(CLASS_NAME_CAROUSEL)){return;}
const config={...Manipulator__default.default.getDataAttributes(target),...Manipulator__default.default.getDataAttributes(this)};const slideIndex=this.getAttribute('data-bs-slide-to');if(slideIndex){config.interval=false;}
Carousel.carouselInterface(target,config);if(slideIndex){Carousel.getInstance(target).to(slideIndex);}
event.preventDefault();}}
EventHandler__default.default.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_SLIDE,Carousel.dataApiClickHandler);EventHandler__default.default.on(window,EVENT_LOAD_DATA_API,()=>{const carousels=SelectorEngine__default.default.find(SELECTOR_DATA_RIDE);for(let i=0,len=carousels.length;i<len;i++){Carousel.carouselInterface(carousels[i],Carousel.getInstance(carousels[i]));}});defineJQueryPlugin(Carousel);return Carousel;}));;

/* /web/static/lib/bootstrap/js/dist/collapse.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./dom/data.js'),require('./dom/event-handler.js'),require('./dom/manipulator.js'),require('./dom/selector-engine.js'),require('./base-component.js')):typeof define==='function'&&define.amd?define(['./dom/data','./dom/event-handler','./dom/manipulator','./dom/selector-engine','./base-component'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Collapse=factory(global.Data,global.EventHandler,global.Manipulator,global.SelectorEngine,global.Base));})(this,(function(Data,EventHandler,Manipulator,SelectorEngine,BaseComponent){'use strict';const _interopDefaultLegacy=e=>e&&typeof e==='object'&&'default'in e?e:{default:e};const Data__default=_interopDefaultLegacy(Data);const EventHandler__default=_interopDefaultLegacy(EventHandler);const Manipulator__default=_interopDefaultLegacy(Manipulator);const SelectorEngine__default=_interopDefaultLegacy(SelectorEngine);const BaseComponent__default=_interopDefaultLegacy(BaseComponent);const toType=obj=>{if(obj===null||obj===undefined){return`${obj}`;}
return{}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();};const getSelector=element=>{let selector=element.getAttribute('data-bs-target');if(!selector||selector==='#'){let hrefAttr=element.getAttribute('href');if(!hrefAttr||!hrefAttr.includes('#')&&!hrefAttr.startsWith('.')){return null;}
if(hrefAttr.includes('#')&&!hrefAttr.startsWith('#')){hrefAttr=`#${hrefAttr.split('#')[1]}`;}
selector=hrefAttr&&hrefAttr!=='#'?hrefAttr.trim():null;}
return selector;};const getSelectorFromElement=element=>{const selector=getSelector(element);if(selector){return document.querySelector(selector)?selector:null;}
return null;};const getElementFromSelector=element=>{const selector=getSelector(element);return selector?document.querySelector(selector):null;};const isElement=obj=>{if(!obj||typeof obj!=='object'){return false;}
if(typeof obj.jquery!=='undefined'){obj=obj[0];}
return typeof obj.nodeType!=='undefined';};const getElement=obj=>{if(isElement(obj)){return obj.jquery?obj[0]:obj;}
if(typeof obj==='string'&&obj.length>0){return document.querySelector(obj);}
return null;};const typeCheckConfig=(componentName,config,configTypes)=>{Object.keys(configTypes).forEach(property=>{const expectedTypes=configTypes[property];const value=config[property];const valueType=value&&isElement(value)?'element':toType(value);if(!new RegExp(expectedTypes).test(valueType)){throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);}});};const reflow=element=>{element.offsetHeight;};const getjQuery=()=>{const{jQuery}=window;if(jQuery&&!document.body.hasAttribute('data-bs-no-jquery')){return jQuery;}
return null;};const DOMContentLoadedCallbacks=[];const onDOMContentLoaded=callback=>{if(document.readyState==='loading'){if(!DOMContentLoadedCallbacks.length){document.addEventListener('DOMContentLoaded',()=>{DOMContentLoadedCallbacks.forEach(callback=>callback());});}
DOMContentLoadedCallbacks.push(callback);}else{callback();}};const defineJQueryPlugin=plugin=>{onDOMContentLoaded(()=>{const $=getjQuery();if($){const name=plugin.NAME;const JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface;$.fn[name].Constructor=plugin;$.fn[name].noConflict=()=>{$.fn[name]=JQUERY_NO_CONFLICT;return plugin.jQueryInterface;};}});};const NAME='collapse';const DATA_KEY='bs.collapse';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const Default={toggle:true,parent:null};const DefaultType={toggle:'boolean',parent:'(null|element)'};const EVENT_SHOW=`show${EVENT_KEY}`;const EVENT_SHOWN=`shown${EVENT_KEY}`;const EVENT_HIDE=`hide${EVENT_KEY}`;const EVENT_HIDDEN=`hidden${EVENT_KEY}`;const EVENT_CLICK_DATA_API=`click${EVENT_KEY}${DATA_API_KEY}`;const CLASS_NAME_SHOW='show';const CLASS_NAME_COLLAPSE='collapse';const CLASS_NAME_COLLAPSING='collapsing';const CLASS_NAME_COLLAPSED='collapsed';const CLASS_NAME_DEEPER_CHILDREN=`:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;const CLASS_NAME_HORIZONTAL='collapse-horizontal';const WIDTH='width';const HEIGHT='height';const SELECTOR_ACTIVES='.collapse.show, .collapse.collapsing';const SELECTOR_DATA_TOGGLE='[data-bs-toggle="collapse"]';class Collapse extends BaseComponent__default.default{constructor(element,config){super(element);this._isTransitioning=false;this._config=this._getConfig(config);this._triggerArray=[];const toggleList=SelectorEngine__default.default.find(SELECTOR_DATA_TOGGLE);for(let i=0,len=toggleList.length;i<len;i++){const elem=toggleList[i];const selector=getSelectorFromElement(elem);const filterElement=SelectorEngine__default.default.find(selector).filter(foundElem=>foundElem===this._element);if(selector!==null&&filterElement.length){this._selector=selector;this._triggerArray.push(elem);}}
this._initializeChildren();if(!this._config.parent){this._addAriaAndCollapsedClass(this._triggerArray,this._isShown());}
if(this._config.toggle){this.toggle();}}
static get Default(){return Default;}
static get NAME(){return NAME;}
toggle(){if(this._isShown()){this.hide();}else{this.show();}}
show(){if(this._isTransitioning||this._isShown()){return;}
let actives=[];let activesData;if(this._config.parent){const children=SelectorEngine__default.default.find(CLASS_NAME_DEEPER_CHILDREN,this._config.parent);actives=SelectorEngine__default.default.find(SELECTOR_ACTIVES,this._config.parent).filter(elem=>!children.includes(elem));}
const container=SelectorEngine__default.default.findOne(this._selector);if(actives.length){const tempActiveData=actives.find(elem=>container!==elem);activesData=tempActiveData?Collapse.getInstance(tempActiveData):null;if(activesData&&activesData._isTransitioning){return;}}
const startEvent=EventHandler__default.default.trigger(this._element,EVENT_SHOW);if(startEvent.defaultPrevented){return;}
actives.forEach(elemActive=>{if(container!==elemActive){Collapse.getOrCreateInstance(elemActive,{toggle:false}).hide();}
if(!activesData){Data__default.default.set(elemActive,DATA_KEY,null);}});const dimension=this._getDimension();this._element.classList.remove(CLASS_NAME_COLLAPSE);this._element.classList.add(CLASS_NAME_COLLAPSING);this._element.style[dimension]=0;this._addAriaAndCollapsedClass(this._triggerArray,true);this._isTransitioning=true;const complete=()=>{this._isTransitioning=false;this._element.classList.remove(CLASS_NAME_COLLAPSING);this._element.classList.add(CLASS_NAME_COLLAPSE,CLASS_NAME_SHOW);this._element.style[dimension]='';EventHandler__default.default.trigger(this._element,EVENT_SHOWN);};const capitalizedDimension=dimension[0].toUpperCase()+dimension.slice(1);const scrollSize=`scroll${capitalizedDimension}`;this._queueCallback(complete,this._element,true);this._element.style[dimension]=`${this._element[scrollSize]}px`;}
hide(){if(this._isTransitioning||!this._isShown()){return;}
const startEvent=EventHandler__default.default.trigger(this._element,EVENT_HIDE);if(startEvent.defaultPrevented){return;}
const dimension=this._getDimension();this._element.style[dimension]=`${this._element.getBoundingClientRect()[dimension]}px`;reflow(this._element);this._element.classList.add(CLASS_NAME_COLLAPSING);this._element.classList.remove(CLASS_NAME_COLLAPSE,CLASS_NAME_SHOW);const triggerArrayLength=this._triggerArray.length;for(let i=0;i<triggerArrayLength;i++){const trigger=this._triggerArray[i];const elem=getElementFromSelector(trigger);if(elem&&!this._isShown(elem)){this._addAriaAndCollapsedClass([trigger],false);}}
this._isTransitioning=true;const complete=()=>{this._isTransitioning=false;this._element.classList.remove(CLASS_NAME_COLLAPSING);this._element.classList.add(CLASS_NAME_COLLAPSE);EventHandler__default.default.trigger(this._element,EVENT_HIDDEN);};this._element.style[dimension]='';this._queueCallback(complete,this._element,true);}
_isShown(element=this._element){return element.classList.contains(CLASS_NAME_SHOW);}
_getConfig(config){config={...Default,...Manipulator__default.default.getDataAttributes(this._element),...config};config.toggle=Boolean(config.toggle);config.parent=getElement(config.parent);typeCheckConfig(NAME,config,DefaultType);return config;}
_getDimension(){return this._element.classList.contains(CLASS_NAME_HORIZONTAL)?WIDTH:HEIGHT;}
_initializeChildren(){if(!this._config.parent){return;}
const children=SelectorEngine__default.default.find(CLASS_NAME_DEEPER_CHILDREN,this._config.parent);SelectorEngine__default.default.find(SELECTOR_DATA_TOGGLE,this._config.parent).filter(elem=>!children.includes(elem)).forEach(element=>{const selected=getElementFromSelector(element);if(selected){this._addAriaAndCollapsedClass([element],this._isShown(selected));}});}
_addAriaAndCollapsedClass(triggerArray,isOpen){if(!triggerArray.length){return;}
triggerArray.forEach(elem=>{if(isOpen){elem.classList.remove(CLASS_NAME_COLLAPSED);}else{elem.classList.add(CLASS_NAME_COLLAPSED);}
elem.setAttribute('aria-expanded',isOpen);});}
static jQueryInterface(config){return this.each(function(){const _config={};if(typeof config==='string'&&/show|hide/.test(config)){_config.toggle=false;}
const data=Collapse.getOrCreateInstance(this,_config);if(typeof config==='string'){if(typeof data[config]==='undefined'){throw new TypeError(`No method named "${config}"`);}
data[config]();}});}}
EventHandler__default.default.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_TOGGLE,function(event){if(event.target.tagName==='A'||event.delegateTarget&&event.delegateTarget.tagName==='A'){event.preventDefault();}
const selector=getSelectorFromElement(this);const selectorElements=SelectorEngine__default.default.find(selector);selectorElements.forEach(element=>{Collapse.getOrCreateInstance(element,{toggle:false}).toggle();});});defineJQueryPlugin(Collapse);return Collapse;}));;

/* /web/static/lib/bootstrap/js/dist/dropdown.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('@popperjs/core'),require('./dom/event-handler.js'),require('./dom/manipulator.js'),require('./dom/selector-engine.js'),require('./base-component.js')):typeof define==='function'&&define.amd?define(['@popperjs/core','./dom/event-handler','./dom/manipulator','./dom/selector-engine','./base-component'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Dropdown=factory(global.Popper,global.EventHandler,global.Manipulator,global.SelectorEngine,global.Base));})(this,(function(Popper,EventHandler,Manipulator,SelectorEngine,BaseComponent){'use strict';const _interopDefaultLegacy=e=>e&&typeof e==='object'&&'default'in e?e:{default:e};function _interopNamespace(e){if(e&&e.__esModule)return e;const n=Object.create(null);if(e){for(const k in e){if(k!=='default'){const d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:()=>e[k]});}}}
n.default=e;return Object.freeze(n);}
const Popper__namespace=_interopNamespace(Popper);const EventHandler__default=_interopDefaultLegacy(EventHandler);const Manipulator__default=_interopDefaultLegacy(Manipulator);const SelectorEngine__default=_interopDefaultLegacy(SelectorEngine);const BaseComponent__default=_interopDefaultLegacy(BaseComponent);const toType=obj=>{if(obj===null||obj===undefined){return`${obj}`;}
return{}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();};const getSelector=element=>{let selector=element.getAttribute('data-bs-target');if(!selector||selector==='#'){let hrefAttr=element.getAttribute('href');if(!hrefAttr||!hrefAttr.includes('#')&&!hrefAttr.startsWith('.')){return null;}
if(hrefAttr.includes('#')&&!hrefAttr.startsWith('#')){hrefAttr=`#${hrefAttr.split('#')[1]}`;}
selector=hrefAttr&&hrefAttr!=='#'?hrefAttr.trim():null;}
return selector;};const getElementFromSelector=element=>{const selector=getSelector(element);return selector?document.querySelector(selector):null;};const isElement=obj=>{if(!obj||typeof obj!=='object'){return false;}
if(typeof obj.jquery!=='undefined'){obj=obj[0];}
return typeof obj.nodeType!=='undefined';};const getElement=obj=>{if(isElement(obj)){return obj.jquery?obj[0]:obj;}
if(typeof obj==='string'&&obj.length>0){return document.querySelector(obj);}
return null;};const typeCheckConfig=(componentName,config,configTypes)=>{Object.keys(configTypes).forEach(property=>{const expectedTypes=configTypes[property];const value=config[property];const valueType=value&&isElement(value)?'element':toType(value);if(!new RegExp(expectedTypes).test(valueType)){throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);}});};const isVisible=element=>{if(!isElement(element)||element.getClientRects().length===0){return false;}
return getComputedStyle(element).getPropertyValue('visibility')==='visible';};const isDisabled=element=>{if(!element||element.nodeType!==Node.ELEMENT_NODE){return true;}
if(element.classList.contains('disabled')){return true;}
if(typeof element.disabled!=='undefined'){return element.disabled;}
return element.hasAttribute('disabled')&&element.getAttribute('disabled')!=='false';};const noop=()=>{};const getjQuery=()=>{const{jQuery}=window;if(jQuery&&!document.body.hasAttribute('data-bs-no-jquery')){return jQuery;}
return null;};const DOMContentLoadedCallbacks=[];const onDOMContentLoaded=callback=>{if(document.readyState==='loading'){if(!DOMContentLoadedCallbacks.length){document.addEventListener('DOMContentLoaded',()=>{DOMContentLoadedCallbacks.forEach(callback=>callback());});}
DOMContentLoadedCallbacks.push(callback);}else{callback();}};const isRTL=()=>document.documentElement.dir==='rtl';const defineJQueryPlugin=plugin=>{onDOMContentLoaded(()=>{const $=getjQuery();if($){const name=plugin.NAME;const JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface;$.fn[name].Constructor=plugin;$.fn[name].noConflict=()=>{$.fn[name]=JQUERY_NO_CONFLICT;return plugin.jQueryInterface;};}});};const getNextActiveElement=(list,activeElement,shouldGetNext,isCycleAllowed)=>{let index=list.indexOf(activeElement);if(index===-1){return list[!shouldGetNext&&isCycleAllowed?list.length-1:0];}
const listLength=list.length;index+=shouldGetNext?1:-1;if(isCycleAllowed){index=(index+listLength)%listLength;}
return list[Math.max(0,Math.min(index,listLength-1))];};const NAME='dropdown';const DATA_KEY='bs.dropdown';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const ESCAPE_KEY='Escape';const SPACE_KEY='Space';const TAB_KEY='Tab';const ARROW_UP_KEY='ArrowUp';const ARROW_DOWN_KEY='ArrowDown';const RIGHT_MOUSE_BUTTON=2;const REGEXP_KEYDOWN=new RegExp(`${ARROW_UP_KEY}|${ARROW_DOWN_KEY}|${ESCAPE_KEY}`);const EVENT_HIDE=`hide${EVENT_KEY}`;const EVENT_HIDDEN=`hidden${EVENT_KEY}`;const EVENT_SHOW=`show${EVENT_KEY}`;const EVENT_SHOWN=`shown${EVENT_KEY}`;const EVENT_CLICK_DATA_API=`click${EVENT_KEY}${DATA_API_KEY}`;const EVENT_KEYDOWN_DATA_API=`keydown${EVENT_KEY}${DATA_API_KEY}`;const EVENT_KEYUP_DATA_API=`keyup${EVENT_KEY}${DATA_API_KEY}`;const CLASS_NAME_SHOW='show';const CLASS_NAME_DROPUP='dropup';const CLASS_NAME_DROPEND='dropend';const CLASS_NAME_DROPSTART='dropstart';const CLASS_NAME_NAVBAR='navbar';const SELECTOR_DATA_TOGGLE='[data-bs-toggle="dropdown"]';const SELECTOR_MENU='.dropdown-menu:not(.o-dropdown--menu)';const SELECTOR_MENU_NOT_SUB='.dropdown-menu:not(.o-dropdown--menu):not(.o_wysiwyg_submenu)';const SELECTOR_NAVBAR_NAV='.navbar-nav';const SELECTOR_VISIBLE_ITEMS='.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';const PLACEMENT_TOP=isRTL()?'top-end':'top-start';const PLACEMENT_TOPEND=isRTL()?'top-start':'top-end';const PLACEMENT_BOTTOM=isRTL()?'bottom-end':'bottom-start';const PLACEMENT_BOTTOMEND=isRTL()?'bottom-start':'bottom-end';const PLACEMENT_RIGHT=isRTL()?'left-start':'right-start';const PLACEMENT_LEFT=isRTL()?'right-start':'left-start';const Default={offset:[0,2],boundary:'clippingParents',reference:'toggle',display:'dynamic',popperConfig:null,autoClose:true};const DefaultType={offset:'(array|string|function)',boundary:'(string|element)',reference:'(string|element|object)',display:'string',popperConfig:'(null|object|function)',autoClose:'(boolean|string)'};class Dropdown extends BaseComponent__default.default{constructor(element,config){super(element);this._popper=null;this._config=this._getConfig(config);this._menu=this._getMenuElement();this._inNavbar=this._detectNavbar();}
static get Default(){return Default;}
static get DefaultType(){return DefaultType;}
static get NAME(){return NAME;}
toggle(){return this._isShown()?this.hide():this.show();}
show(){if(isDisabled(this._element)||this._isShown(this._menu)){return;}
const relatedTarget={relatedTarget:this._element};const showEvent=EventHandler__default.default.trigger(this._element,EVENT_SHOW,relatedTarget);if(showEvent.defaultPrevented){return;}
const parent=Dropdown.getParentFromElement(this._element);if(this._inNavbar){Manipulator__default.default.setDataAttribute(this._menu,'popper','none');}else{this._createPopper(parent);}
if('ontouchstart'in document.documentElement&&!parent.closest(SELECTOR_NAVBAR_NAV)){[].concat(...document.body.children).forEach(elem=>EventHandler__default.default.on(elem,'mouseover',noop));}
this._element.focus();this._element.setAttribute('aria-expanded',true);this._menu.classList.add(CLASS_NAME_SHOW);this._element.classList.add(CLASS_NAME_SHOW);EventHandler__default.default.trigger(this._element,EVENT_SHOWN,relatedTarget);}
hide(){if(isDisabled(this._element)||!this._isShown(this._menu)){return;}
const relatedTarget={relatedTarget:this._element};this._completeHide(relatedTarget);}
dispose(){if(this._popper){this._popper.destroy();}
super.dispose();}
update(){this._inNavbar=this._detectNavbar();if(this._popper){this._popper.update();}}
_completeHide(relatedTarget){const hideEvent=EventHandler__default.default.trigger(this._element,EVENT_HIDE,relatedTarget);if(hideEvent.defaultPrevented){return;}
if('ontouchstart'in document.documentElement){[].concat(...document.body.children).forEach(elem=>EventHandler__default.default.off(elem,'mouseover',noop));}
if(this._popper){this._popper.destroy();}
this._menu.classList.remove(CLASS_NAME_SHOW);this._element.classList.remove(CLASS_NAME_SHOW);this._element.setAttribute('aria-expanded','false');Manipulator__default.default.removeDataAttribute(this._menu,'popper');EventHandler__default.default.trigger(this._element,EVENT_HIDDEN,relatedTarget);}
_getConfig(config){config={...this.constructor.Default,...Manipulator__default.default.getDataAttributes(this._element),...config};typeCheckConfig(NAME,config,this.constructor.DefaultType);if(typeof config.reference==='object'&&!isElement(config.reference)&&typeof config.reference.getBoundingClientRect!=='function'){throw new TypeError(`${NAME.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);}
return config;}
_createPopper(parent){if(typeof Popper__namespace==='undefined'){throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)');}
let referenceElement=this._element;if(this._config.reference==='parent'){referenceElement=parent;}else if(isElement(this._config.reference)){referenceElement=getElement(this._config.reference);}else if(typeof this._config.reference==='object'){referenceElement=this._config.reference;}
const popperConfig=this._getPopperConfig();const isDisplayStatic=popperConfig.modifiers.find(modifier=>modifier.name==='applyStyles'&&modifier.enabled===false);this._popper=Popper__namespace.createPopper(referenceElement,this._menu,popperConfig);if(isDisplayStatic){Manipulator__default.default.setDataAttribute(this._menu,'popper','static');}}
_isShown(element=this._element){return element.classList.contains(CLASS_NAME_SHOW);}
_getMenuElement(){return SelectorEngine__default.default.next(this._element,SELECTOR_MENU)[0];}
_getPlacement(){const parentDropdown=this._element.parentNode;if(parentDropdown.classList.contains(CLASS_NAME_DROPEND)){return PLACEMENT_RIGHT;}
if(parentDropdown.classList.contains(CLASS_NAME_DROPSTART)){return PLACEMENT_LEFT;}
const isEnd=getComputedStyle(this._menu).getPropertyValue('--bs-position').trim()==='end';if(parentDropdown.classList.contains(CLASS_NAME_DROPUP)){return isEnd?PLACEMENT_TOPEND:PLACEMENT_TOP;}
return isEnd?PLACEMENT_BOTTOMEND:PLACEMENT_BOTTOM;}
_detectNavbar(){return this._element.closest(`.${CLASS_NAME_NAVBAR}`)!==null;}
_getOffset(){const{offset}=this._config;if(typeof offset==='string'){return offset.split(',').map(val=>Number.parseInt(val,10));}
if(typeof offset==='function'){return popperData=>offset(popperData,this._element);}
return offset;}
_getPopperConfig(){const defaultBsPopperConfig={placement:this._getPlacement(),modifiers:[{name:'preventOverflow',options:{boundary:this._config.boundary}},{name:'offset',options:{offset:this._getOffset()}}]};if(this._config.display==='static'){defaultBsPopperConfig.modifiers=[{name:'applyStyles',enabled:false}];}
return{...defaultBsPopperConfig,...(typeof this._config.popperConfig==='function'?this._config.popperConfig(defaultBsPopperConfig):this._config.popperConfig)};}
_selectMenuItem({key,target}){const items=SelectorEngine__default.default.find(SELECTOR_VISIBLE_ITEMS,this._menu).filter(isVisible);if(!items.length){return;}
getNextActiveElement(items,target,key===ARROW_DOWN_KEY,!items.includes(target)).focus();}
static jQueryInterface(config){return this.each(function(){const data=Dropdown.getOrCreateInstance(this,config);if(typeof config!=='string'){return;}
if(typeof data[config]==='undefined'){throw new TypeError(`No method named "${config}"`);}
data[config]();});}
static clearMenus(event){if(event&&(event.button===RIGHT_MOUSE_BUTTON||event.type==='keyup'&&event.key!==TAB_KEY)){return;}
const toggles=SelectorEngine__default.default.find(SELECTOR_DATA_TOGGLE);for(let i=0,len=toggles.length;i<len;i++){const context=Dropdown.getInstance(toggles[i]);if(!context||context._config.autoClose===false){continue;}
if(!context._isShown()){continue;}
const relatedTarget={relatedTarget:context._element};if(event){const composedPath=event.composedPath();const isMenuTarget=composedPath.includes(context._menu);if(composedPath.includes(context._element)||context._config.autoClose==='inside'&&!isMenuTarget||context._config.autoClose==='outside'&&isMenuTarget){continue;}
if(context._menu.contains(event.target)&&(event.type==='keyup'&&event.key===TAB_KEY||/input|select|option|textarea|form/i.test(event.target.tagName))){continue;}
if(event.type==='click'){relatedTarget.clickEvent=event;}}
context._completeHide(relatedTarget);}}
static getParentFromElement(element){return getElementFromSelector(element)||element.parentNode;}
static dataApiKeydownHandler(event){if(/input|textarea/i.test(event.target.tagName)?event.key===SPACE_KEY||event.key!==ESCAPE_KEY&&(event.key!==ARROW_DOWN_KEY&&event.key!==ARROW_UP_KEY||event.target.closest(SELECTOR_MENU)):!REGEXP_KEYDOWN.test(event.key)){return;}
const isActive=this.classList.contains(CLASS_NAME_SHOW);if(!isActive&&event.key===ESCAPE_KEY){return;}
event.preventDefault();event.stopPropagation();if(isDisabled(this)){return;}
const getToggleButton=this.matches(SELECTOR_DATA_TOGGLE)?this:SelectorEngine__default.default.prev(this,SELECTOR_DATA_TOGGLE)[0];const instance=Dropdown.getOrCreateInstance(getToggleButton);if(event.key===ESCAPE_KEY){instance.hide();return;}
if(event.key===ARROW_UP_KEY||event.key===ARROW_DOWN_KEY){if(!isActive){instance.show();}
instance._selectMenuItem(event);return;}
if(!isActive||event.key===SPACE_KEY){Dropdown.clearMenus();}}}
EventHandler__default.default.on(document,EVENT_KEYDOWN_DATA_API,SELECTOR_DATA_TOGGLE,Dropdown.dataApiKeydownHandler);EventHandler__default.default.on(document,EVENT_KEYDOWN_DATA_API,SELECTOR_MENU_NOT_SUB,Dropdown.dataApiKeydownHandler);EventHandler__default.default.on(document,EVENT_CLICK_DATA_API,Dropdown.clearMenus);EventHandler__default.default.on(document,EVENT_KEYUP_DATA_API,Dropdown.clearMenus);EventHandler__default.default.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_TOGGLE,function(event){event.preventDefault();Dropdown.getOrCreateInstance(this).toggle();});defineJQueryPlugin(Dropdown);return Dropdown;}));;

/* /web/static/lib/bootstrap/js/dist/modal.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./dom/event-handler.js'),require('./dom/manipulator.js'),require('./dom/selector-engine.js'),require('./base-component.js')):typeof define==='function'&&define.amd?define(['./dom/event-handler','./dom/manipulator','./dom/selector-engine','./base-component'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Modal=factory(global.EventHandler,global.Manipulator,global.SelectorEngine,global.Base));})(this,(function(EventHandler,Manipulator,SelectorEngine,BaseComponent){'use strict';const _interopDefaultLegacy=e=>e&&typeof e==='object'&&'default'in e?e:{default:e};const EventHandler__default=_interopDefaultLegacy(EventHandler);const Manipulator__default=_interopDefaultLegacy(Manipulator);const SelectorEngine__default=_interopDefaultLegacy(SelectorEngine);const BaseComponent__default=_interopDefaultLegacy(BaseComponent);const MILLISECONDS_MULTIPLIER=1000;const TRANSITION_END='transitionend';const toType=obj=>{if(obj===null||obj===undefined){return`${obj}`;}
return{}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();};const getSelector=element=>{let selector=element.getAttribute('data-bs-target');if(!selector||selector==='#'){let hrefAttr=element.getAttribute('href');if(!hrefAttr||!hrefAttr.includes('#')&&!hrefAttr.startsWith('.')){return null;}
if(hrefAttr.includes('#')&&!hrefAttr.startsWith('#')){hrefAttr=`#${hrefAttr.split('#')[1]}`;}
selector=hrefAttr&&hrefAttr!=='#'?hrefAttr.trim():null;}
return selector;};const getElementFromSelector=element=>{const selector=getSelector(element);return selector?document.querySelector(selector):null;};const getTransitionDurationFromElement=element=>{if(!element){return 0;}
let{transitionDuration,transitionDelay}=window.getComputedStyle(element);const floatTransitionDuration=Number.parseFloat(transitionDuration);const floatTransitionDelay=Number.parseFloat(transitionDelay);if(!floatTransitionDuration&&!floatTransitionDelay){return 0;}
transitionDuration=transitionDuration.split(',')[0];transitionDelay=transitionDelay.split(',')[0];return(Number.parseFloat(transitionDuration)+Number.parseFloat(transitionDelay))*MILLISECONDS_MULTIPLIER;};const triggerTransitionEnd=element=>{element.dispatchEvent(new Event(TRANSITION_END));};const isElement=obj=>{if(!obj||typeof obj!=='object'){return false;}
if(typeof obj.jquery!=='undefined'){obj=obj[0];}
return typeof obj.nodeType!=='undefined';};const getElement=obj=>{if(isElement(obj)){return obj.jquery?obj[0]:obj;}
if(typeof obj==='string'&&obj.length>0){return document.querySelector(obj);}
return null;};const typeCheckConfig=(componentName,config,configTypes)=>{Object.keys(configTypes).forEach(property=>{const expectedTypes=configTypes[property];const value=config[property];const valueType=value&&isElement(value)?'element':toType(value);if(!new RegExp(expectedTypes).test(valueType)){throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);}});};const isVisible=element=>{if(!isElement(element)||element.getClientRects().length===0){return false;}
return getComputedStyle(element).getPropertyValue('visibility')==='visible';};const isDisabled=element=>{if(!element||element.nodeType!==Node.ELEMENT_NODE){return true;}
if(element.classList.contains('disabled')){return true;}
if(typeof element.disabled!=='undefined'){return element.disabled;}
return element.hasAttribute('disabled')&&element.getAttribute('disabled')!=='false';};const reflow=element=>{element.offsetHeight;};const getjQuery=()=>{const{jQuery}=window;if(jQuery&&!document.body.hasAttribute('data-bs-no-jquery')){return jQuery;}
return null;};const DOMContentLoadedCallbacks=[];const onDOMContentLoaded=callback=>{if(document.readyState==='loading'){if(!DOMContentLoadedCallbacks.length){document.addEventListener('DOMContentLoaded',()=>{DOMContentLoadedCallbacks.forEach(callback=>callback());});}
DOMContentLoadedCallbacks.push(callback);}else{callback();}};const isRTL=()=>document.documentElement.dir==='rtl';const defineJQueryPlugin=plugin=>{onDOMContentLoaded(()=>{const $=getjQuery();if($){const name=plugin.NAME;const JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface;$.fn[name].Constructor=plugin;$.fn[name].noConflict=()=>{$.fn[name]=JQUERY_NO_CONFLICT;return plugin.jQueryInterface;};}});};const execute=callback=>{if(typeof callback==='function'){callback();}};const executeAfterTransition=(callback,transitionElement,waitForTransition=true)=>{if(!waitForTransition){execute(callback);return;}
const durationPadding=5;const emulatedDuration=getTransitionDurationFromElement(transitionElement)+durationPadding;let called=false;const handler=({target})=>{if(target!==transitionElement){return;}
called=true;transitionElement.removeEventListener(TRANSITION_END,handler);execute(callback);};transitionElement.addEventListener(TRANSITION_END,handler);setTimeout(()=>{if(!called){triggerTransitionEnd(transitionElement);}},emulatedDuration);};const SELECTOR_FIXED_CONTENT='.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';const SELECTOR_STICKY_CONTENT='.sticky-top';class ScrollBarHelper{constructor(){this._element=document.body;}
getWidth(){const documentWidth=document.documentElement.clientWidth;return Math.abs(window.innerWidth-documentWidth);}
hide(){const width=this.getWidth();this._disableOverFlow();this._setElementAttributes(this._element,'paddingRight',calculatedValue=>calculatedValue+width);this._setElementAttributes(SELECTOR_FIXED_CONTENT,'paddingRight',calculatedValue=>calculatedValue+width);this._setElementAttributes(SELECTOR_STICKY_CONTENT,'marginRight',calculatedValue=>calculatedValue-width);}
_disableOverFlow(){this._saveInitialAttribute(this._element,'overflow');this._element.style.overflow='hidden';}
_setElementAttributes(selector,styleProp,callback){const scrollbarWidth=this.getWidth();const manipulationCallBack=element=>{if(element!==this._element&&window.innerWidth>element.clientWidth+scrollbarWidth){return;}
this._saveInitialAttribute(element,styleProp);const calculatedValue=window.getComputedStyle(element)[styleProp];element.style[styleProp]=`${callback(Number.parseFloat(calculatedValue))}px`;};this._applyManipulationCallback(selector,manipulationCallBack);}
reset(){this._resetElementAttributes(this._element,'overflow');this._resetElementAttributes(this._element,'paddingRight');this._resetElementAttributes(SELECTOR_FIXED_CONTENT,'paddingRight');this._resetElementAttributes(SELECTOR_STICKY_CONTENT,'marginRight');}
_saveInitialAttribute(element,styleProp){const actualValue=element.style[styleProp];if(actualValue){Manipulator__default.default.setDataAttribute(element,styleProp,actualValue);}}
_resetElementAttributes(selector,styleProp){const manipulationCallBack=element=>{const value=Manipulator__default.default.getDataAttribute(element,styleProp);if(typeof value==='undefined'){element.style.removeProperty(styleProp);}else{Manipulator__default.default.removeDataAttribute(element,styleProp);element.style[styleProp]=value;}};this._applyManipulationCallback(selector,manipulationCallBack);}
_applyManipulationCallback(selector,callBack){if(isElement(selector)){callBack(selector);}else{SelectorEngine__default.default.find(selector,this._element).forEach(callBack);}}
isOverflowing(){return this.getWidth()>0;}}
const Default$2={className:'modal-backdrop',isVisible:true,isAnimated:false,rootElement:'body',clickCallback:null};const DefaultType$2={className:'string',isVisible:'boolean',isAnimated:'boolean',rootElement:'(element|string)',clickCallback:'(function|null)'};const NAME$2='backdrop';const CLASS_NAME_FADE$1='fade';const CLASS_NAME_SHOW$1='show';const EVENT_MOUSEDOWN=`mousedown.bs.${NAME$2}`;class Backdrop{constructor(config){this._config=this._getConfig(config);this._isAppended=false;this._element=null;}
show(callback){if(!this._config.isVisible){execute(callback);return;}
this._append();if(this._config.isAnimated){reflow(this._getElement());}
this._getElement().classList.add(CLASS_NAME_SHOW$1);this._emulateAnimation(()=>{execute(callback);});}
hide(callback){if(!this._config.isVisible){execute(callback);return;}
this._getElement().classList.remove(CLASS_NAME_SHOW$1);this._emulateAnimation(()=>{this.dispose();execute(callback);});}
_getElement(){if(!this._element){const backdrop=document.createElement('div');backdrop.className=this._config.className;if(this._config.isAnimated){backdrop.classList.add(CLASS_NAME_FADE$1);}
this._element=backdrop;}
return this._element;}
_getConfig(config){config={...Default$2,...(typeof config==='object'?config:{})};config.rootElement=getElement(config.rootElement);typeCheckConfig(NAME$2,config,DefaultType$2);return config;}
_append(){if(this._isAppended){return;}
this._config.rootElement.append(this._getElement());EventHandler__default.default.on(this._getElement(),EVENT_MOUSEDOWN,()=>{execute(this._config.clickCallback);});this._isAppended=true;}
dispose(){if(!this._isAppended){return;}
EventHandler__default.default.off(this._element,EVENT_MOUSEDOWN);this._element.remove();this._isAppended=false;}
_emulateAnimation(callback){executeAfterTransition(callback,this._getElement(),this._config.isAnimated);}}
const Default$1={trapElement:null,autofocus:true};const DefaultType$1={trapElement:'element',autofocus:'boolean'};const NAME$1='focustrap';const DATA_KEY$1='bs.focustrap';const EVENT_KEY$1=`.${DATA_KEY$1}`;const EVENT_FOCUSIN=`focusin${EVENT_KEY$1}`;const EVENT_KEYDOWN_TAB=`keydown.tab${EVENT_KEY$1}`;const TAB_KEY='Tab';const TAB_NAV_FORWARD='forward';const TAB_NAV_BACKWARD='backward';class FocusTrap{constructor(config){this._config=this._getConfig(config);this._isActive=false;this._lastTabNavDirection=null;}
activate(){const{trapElement,autofocus}=this._config;if(this._isActive){return;}
if(autofocus){trapElement.focus();}
EventHandler__default.default.off(document,EVENT_KEY$1);EventHandler__default.default.on(document,EVENT_FOCUSIN,event=>this._handleFocusin(event));EventHandler__default.default.on(document,EVENT_KEYDOWN_TAB,event=>this._handleKeydown(event));this._isActive=true;}
deactivate(){if(!this._isActive){return;}
this._isActive=false;EventHandler__default.default.off(document,EVENT_KEY$1);}
_handleFocusin(event){const{target}=event;const{trapElement}=this._config;if(target===document||target===trapElement||trapElement.contains(target)){return;}
const elements=SelectorEngine__default.default.focusableChildren(trapElement);if(elements.length===0){trapElement.focus();}else if(this._lastTabNavDirection===TAB_NAV_BACKWARD){elements[elements.length-1].focus();}else{elements[0].focus();}}
_handleKeydown(event){if(event.key!==TAB_KEY){return;}
this._lastTabNavDirection=event.shiftKey?TAB_NAV_BACKWARD:TAB_NAV_FORWARD;}
_getConfig(config){config={...Default$1,...(typeof config==='object'?config:{})};typeCheckConfig(NAME$1,config,DefaultType$1);return config;}}
const enableDismissTrigger=(component,method='hide')=>{const clickEvent=`click.dismiss${component.EVENT_KEY}`;const name=component.NAME;EventHandler__default.default.on(document,clickEvent,`[data-bs-dismiss="${name}"]`,function(event){if(['A','AREA'].includes(this.tagName)){event.preventDefault();}
if(isDisabled(this)){return;}
const target=getElementFromSelector(this)||this.closest(`.${name}`);const instance=component.getOrCreateInstance(target);instance[method]();});};const NAME='modal';const DATA_KEY='bs.modal';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const ESCAPE_KEY='Escape';const Default={backdrop:true,keyboard:true,focus:true};const DefaultType={backdrop:'(boolean|string)',keyboard:'boolean',focus:'boolean'};const EVENT_HIDE=`hide${EVENT_KEY}`;const EVENT_HIDE_PREVENTED=`hidePrevented${EVENT_KEY}`;const EVENT_HIDDEN=`hidden${EVENT_KEY}`;const EVENT_SHOW=`show${EVENT_KEY}`;const EVENT_SHOWN=`shown${EVENT_KEY}`;const EVENT_RESIZE=`resize${EVENT_KEY}`;const EVENT_CLICK_DISMISS=`click.dismiss${EVENT_KEY}`;const EVENT_KEYDOWN_DISMISS=`keydown.dismiss${EVENT_KEY}`;const EVENT_MOUSEUP_DISMISS=`mouseup.dismiss${EVENT_KEY}`;const EVENT_MOUSEDOWN_DISMISS=`mousedown.dismiss${EVENT_KEY}`;const EVENT_CLICK_DATA_API=`click${EVENT_KEY}${DATA_API_KEY}`;const CLASS_NAME_OPEN='modal-open';const CLASS_NAME_FADE='fade';const CLASS_NAME_SHOW='show';const CLASS_NAME_STATIC='modal-static';const OPEN_SELECTOR='.modal.show';const SELECTOR_DIALOG='.modal-dialog';const SELECTOR_MODAL_BODY='.modal-body';const SELECTOR_DATA_TOGGLE='[data-bs-toggle="modal"]';class Modal extends BaseComponent__default.default{constructor(element,config){super(element);this._config=this._getConfig(config);this._dialog=SelectorEngine__default.default.findOne(SELECTOR_DIALOG,this._element);this._backdrop=this._initializeBackDrop();this._focustrap=this._initializeFocusTrap();this._isShown=false;this._ignoreBackdropClick=false;this._isTransitioning=false;this._scrollBar=new ScrollBarHelper();}
static get Default(){return Default;}
static get NAME(){return NAME;}
toggle(relatedTarget){return this._isShown?this.hide():this.show(relatedTarget);}
show(relatedTarget){if(this._isShown||this._isTransitioning){return;}
const showEvent=EventHandler__default.default.trigger(this._element,EVENT_SHOW,{relatedTarget});if(showEvent.defaultPrevented){return;}
this._isShown=true;if(this._isAnimated()){this._isTransitioning=true;}
this._scrollBar.hide();document.body.classList.add(CLASS_NAME_OPEN);this._adjustDialog();this._setEscapeEvent();this._setResizeEvent();EventHandler__default.default.on(this._dialog,EVENT_MOUSEDOWN_DISMISS,()=>{EventHandler__default.default.one(this._element,EVENT_MOUSEUP_DISMISS,event=>{if(event.target===this._element){this._ignoreBackdropClick=true;}});});this._showBackdrop(()=>this._showElement(relatedTarget));}
hide(){if(!this._isShown||this._isTransitioning){return;}
const hideEvent=EventHandler__default.default.trigger(this._element,EVENT_HIDE);if(hideEvent.defaultPrevented){return;}
this._isShown=false;const isAnimated=this._isAnimated();if(isAnimated){this._isTransitioning=true;}
this._setEscapeEvent();this._setResizeEvent();this._focustrap.deactivate();this._element.classList.remove(CLASS_NAME_SHOW);EventHandler__default.default.off(this._element,EVENT_CLICK_DISMISS);EventHandler__default.default.off(this._dialog,EVENT_MOUSEDOWN_DISMISS);this._queueCallback(()=>this._hideModal(),this._element,isAnimated);}
dispose(){[window,this._dialog].forEach(htmlElement=>EventHandler__default.default.off(htmlElement,EVENT_KEY));this._backdrop.dispose();this._focustrap.deactivate();super.dispose();}
handleUpdate(){this._adjustDialog();}
_initializeBackDrop(){return new Backdrop({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()});}
_initializeFocusTrap(){return new FocusTrap({trapElement:this._element});}
_getConfig(config){config={...Default,...Manipulator__default.default.getDataAttributes(this._element),...(typeof config==='object'?config:{})};typeCheckConfig(NAME,config,DefaultType);return config;}
_showElement(relatedTarget){const isAnimated=this._isAnimated();const modalBody=SelectorEngine__default.default.findOne(SELECTOR_MODAL_BODY,this._dialog);if(!this._element.parentNode||this._element.parentNode.nodeType!==Node.ELEMENT_NODE){document.body.append(this._element);}
this._element.style.display='block';this._element.removeAttribute('aria-hidden');this._element.setAttribute('aria-modal',true);this._element.setAttribute('role','dialog');this._element.scrollTop=0;if(modalBody){modalBody.scrollTop=0;}
if(isAnimated){reflow(this._element);}
this._element.classList.add(CLASS_NAME_SHOW);const transitionComplete=()=>{if(this._config.focus){this._focustrap.activate();}
this._isTransitioning=false;EventHandler__default.default.trigger(this._element,EVENT_SHOWN,{relatedTarget});};this._queueCallback(transitionComplete,this._dialog,isAnimated);}
_setEscapeEvent(){if(this._isShown){EventHandler__default.default.on(this._element,EVENT_KEYDOWN_DISMISS,event=>{if(this._config.keyboard&&event.key===ESCAPE_KEY){event.preventDefault();this.hide();}else if(!this._config.keyboard&&event.key===ESCAPE_KEY){this._triggerBackdropTransition();}});}else{EventHandler__default.default.off(this._element,EVENT_KEYDOWN_DISMISS);}}
_setResizeEvent(){if(this._isShown){EventHandler__default.default.on(window,EVENT_RESIZE,()=>this._adjustDialog());}else{EventHandler__default.default.off(window,EVENT_RESIZE);}}
_hideModal(){this._element.style.display='none';this._element.setAttribute('aria-hidden',true);this._element.removeAttribute('aria-modal');this._element.removeAttribute('role');this._isTransitioning=false;this._backdrop.hide(()=>{document.body.classList.remove(CLASS_NAME_OPEN);this._resetAdjustments();this._scrollBar.reset();EventHandler__default.default.trigger(this._element,EVENT_HIDDEN);});}
_showBackdrop(callback){EventHandler__default.default.on(this._element,EVENT_CLICK_DISMISS,event=>{if(this._ignoreBackdropClick){this._ignoreBackdropClick=false;return;}
if(event.target!==event.currentTarget){return;}
if(this._config.backdrop===true){this.hide();}else if(this._config.backdrop==='static'){this._triggerBackdropTransition();}});this._backdrop.show(callback);}
_isAnimated(){return this._element.classList.contains(CLASS_NAME_FADE);}
_triggerBackdropTransition(){const hideEvent=EventHandler__default.default.trigger(this._element,EVENT_HIDE_PREVENTED);if(hideEvent.defaultPrevented){return;}
const{classList,scrollHeight,style}=this._element;const isModalOverflowing=scrollHeight>document.documentElement.clientHeight;if(!isModalOverflowing&&style.overflowY==='hidden'||classList.contains(CLASS_NAME_STATIC)){return;}
if(!isModalOverflowing){style.overflowY='hidden';}
classList.add(CLASS_NAME_STATIC);this._queueCallback(()=>{classList.remove(CLASS_NAME_STATIC);if(!isModalOverflowing){this._queueCallback(()=>{style.overflowY='';},this._dialog);}},this._dialog);this._element.focus();}
_adjustDialog(){const isModalOverflowing=this._element.scrollHeight>document.documentElement.clientHeight;const scrollbarWidth=this._scrollBar.getWidth();const isBodyOverflowing=scrollbarWidth>0;if(!isBodyOverflowing&&isModalOverflowing&&!isRTL()||isBodyOverflowing&&!isModalOverflowing&&isRTL()){this._element.style.paddingLeft=`${scrollbarWidth}px`;}
if(isBodyOverflowing&&!isModalOverflowing&&!isRTL()||!isBodyOverflowing&&isModalOverflowing&&isRTL()){this._element.style.paddingRight=`${scrollbarWidth}px`;}}
_resetAdjustments(){this._element.style.paddingLeft='';this._element.style.paddingRight='';}
static jQueryInterface(config,relatedTarget){return this.each(function(){const data=Modal.getOrCreateInstance(this,config);if(typeof config!=='string'){return;}
if(typeof data[config]==='undefined'){throw new TypeError(`No method named "${config}"`);}
data[config](relatedTarget);});}}
EventHandler__default.default.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_TOGGLE,function(event){const target=getElementFromSelector(this);if(['A','AREA'].includes(this.tagName)){event.preventDefault();}
EventHandler__default.default.one(target,EVENT_SHOW,showEvent=>{if(showEvent.defaultPrevented){return;}
EventHandler__default.default.one(target,EVENT_HIDDEN,()=>{if(isVisible(this)){this.focus();}});});const allReadyOpen=SelectorEngine__default.default.findOne(OPEN_SELECTOR);if(allReadyOpen){Modal.getInstance(allReadyOpen).hide();}
const data=Modal.getOrCreateInstance(target);data.toggle(this);});enableDismissTrigger(Modal);defineJQueryPlugin(Modal);return Modal;}));;

/* /web/static/lib/bootstrap/js/dist/offcanvas.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./dom/selector-engine.js'),require('./dom/manipulator.js'),require('./dom/event-handler.js'),require('./base-component.js')):typeof define==='function'&&define.amd?define(['./dom/selector-engine','./dom/manipulator','./dom/event-handler','./base-component'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Offcanvas=factory(global.SelectorEngine,global.Manipulator,global.EventHandler,global.Base));})(this,(function(SelectorEngine,Manipulator,EventHandler,BaseComponent){'use strict';const _interopDefaultLegacy=e=>e&&typeof e==='object'&&'default'in e?e:{default:e};const SelectorEngine__default=_interopDefaultLegacy(SelectorEngine);const Manipulator__default=_interopDefaultLegacy(Manipulator);const EventHandler__default=_interopDefaultLegacy(EventHandler);const BaseComponent__default=_interopDefaultLegacy(BaseComponent);const MILLISECONDS_MULTIPLIER=1000;const TRANSITION_END='transitionend';const toType=obj=>{if(obj===null||obj===undefined){return`${obj}`;}
return{}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();};const getSelector=element=>{let selector=element.getAttribute('data-bs-target');if(!selector||selector==='#'){let hrefAttr=element.getAttribute('href');if(!hrefAttr||!hrefAttr.includes('#')&&!hrefAttr.startsWith('.')){return null;}
if(hrefAttr.includes('#')&&!hrefAttr.startsWith('#')){hrefAttr=`#${hrefAttr.split('#')[1]}`;}
selector=hrefAttr&&hrefAttr!=='#'?hrefAttr.trim():null;}
return selector;};const getElementFromSelector=element=>{const selector=getSelector(element);return selector?document.querySelector(selector):null;};const getTransitionDurationFromElement=element=>{if(!element){return 0;}
let{transitionDuration,transitionDelay}=window.getComputedStyle(element);const floatTransitionDuration=Number.parseFloat(transitionDuration);const floatTransitionDelay=Number.parseFloat(transitionDelay);if(!floatTransitionDuration&&!floatTransitionDelay){return 0;}
transitionDuration=transitionDuration.split(',')[0];transitionDelay=transitionDelay.split(',')[0];return(Number.parseFloat(transitionDuration)+Number.parseFloat(transitionDelay))*MILLISECONDS_MULTIPLIER;};const triggerTransitionEnd=element=>{element.dispatchEvent(new Event(TRANSITION_END));};const isElement=obj=>{if(!obj||typeof obj!=='object'){return false;}
if(typeof obj.jquery!=='undefined'){obj=obj[0];}
return typeof obj.nodeType!=='undefined';};const getElement=obj=>{if(isElement(obj)){return obj.jquery?obj[0]:obj;}
if(typeof obj==='string'&&obj.length>0){return document.querySelector(obj);}
return null;};const typeCheckConfig=(componentName,config,configTypes)=>{Object.keys(configTypes).forEach(property=>{const expectedTypes=configTypes[property];const value=config[property];const valueType=value&&isElement(value)?'element':toType(value);if(!new RegExp(expectedTypes).test(valueType)){throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);}});};const isVisible=element=>{if(!isElement(element)||element.getClientRects().length===0){return false;}
return getComputedStyle(element).getPropertyValue('visibility')==='visible';};const isDisabled=element=>{if(!element||element.nodeType!==Node.ELEMENT_NODE){return true;}
if(element.classList.contains('disabled')){return true;}
if(typeof element.disabled!=='undefined'){return element.disabled;}
return element.hasAttribute('disabled')&&element.getAttribute('disabled')!=='false';};const reflow=element=>{element.offsetHeight;};const getjQuery=()=>{const{jQuery}=window;if(jQuery&&!document.body.hasAttribute('data-bs-no-jquery')){return jQuery;}
return null;};const DOMContentLoadedCallbacks=[];const onDOMContentLoaded=callback=>{if(document.readyState==='loading'){if(!DOMContentLoadedCallbacks.length){document.addEventListener('DOMContentLoaded',()=>{DOMContentLoadedCallbacks.forEach(callback=>callback());});}
DOMContentLoadedCallbacks.push(callback);}else{callback();}};const defineJQueryPlugin=plugin=>{onDOMContentLoaded(()=>{const $=getjQuery();if($){const name=plugin.NAME;const JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface;$.fn[name].Constructor=plugin;$.fn[name].noConflict=()=>{$.fn[name]=JQUERY_NO_CONFLICT;return plugin.jQueryInterface;};}});};const execute=callback=>{if(typeof callback==='function'){callback();}};const executeAfterTransition=(callback,transitionElement,waitForTransition=true)=>{if(!waitForTransition){execute(callback);return;}
const durationPadding=5;const emulatedDuration=getTransitionDurationFromElement(transitionElement)+durationPadding;let called=false;const handler=({target})=>{if(target!==transitionElement){return;}
called=true;transitionElement.removeEventListener(TRANSITION_END,handler);execute(callback);};transitionElement.addEventListener(TRANSITION_END,handler);setTimeout(()=>{if(!called){triggerTransitionEnd(transitionElement);}},emulatedDuration);};const SELECTOR_FIXED_CONTENT='.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';const SELECTOR_STICKY_CONTENT='.sticky-top';class ScrollBarHelper{constructor(){this._element=document.body;}
getWidth(){const documentWidth=document.documentElement.clientWidth;return Math.abs(window.innerWidth-documentWidth);}
hide(){const width=this.getWidth();this._disableOverFlow();this._setElementAttributes(this._element,'paddingRight',calculatedValue=>calculatedValue+width);this._setElementAttributes(SELECTOR_FIXED_CONTENT,'paddingRight',calculatedValue=>calculatedValue+width);this._setElementAttributes(SELECTOR_STICKY_CONTENT,'marginRight',calculatedValue=>calculatedValue-width);}
_disableOverFlow(){this._saveInitialAttribute(this._element,'overflow');this._element.style.overflow='hidden';}
_setElementAttributes(selector,styleProp,callback){const scrollbarWidth=this.getWidth();const manipulationCallBack=element=>{if(element!==this._element&&window.innerWidth>element.clientWidth+scrollbarWidth){return;}
this._saveInitialAttribute(element,styleProp);const calculatedValue=window.getComputedStyle(element)[styleProp];element.style[styleProp]=`${callback(Number.parseFloat(calculatedValue))}px`;};this._applyManipulationCallback(selector,manipulationCallBack);}
reset(){this._resetElementAttributes(this._element,'overflow');this._resetElementAttributes(this._element,'paddingRight');this._resetElementAttributes(SELECTOR_FIXED_CONTENT,'paddingRight');this._resetElementAttributes(SELECTOR_STICKY_CONTENT,'marginRight');}
_saveInitialAttribute(element,styleProp){const actualValue=element.style[styleProp];if(actualValue){Manipulator__default.default.setDataAttribute(element,styleProp,actualValue);}}
_resetElementAttributes(selector,styleProp){const manipulationCallBack=element=>{const value=Manipulator__default.default.getDataAttribute(element,styleProp);if(typeof value==='undefined'){element.style.removeProperty(styleProp);}else{Manipulator__default.default.removeDataAttribute(element,styleProp);element.style[styleProp]=value;}};this._applyManipulationCallback(selector,manipulationCallBack);}
_applyManipulationCallback(selector,callBack){if(isElement(selector)){callBack(selector);}else{SelectorEngine__default.default.find(selector,this._element).forEach(callBack);}}
isOverflowing(){return this.getWidth()>0;}}
const Default$2={className:'modal-backdrop',isVisible:true,isAnimated:false,rootElement:'body',clickCallback:null};const DefaultType$2={className:'string',isVisible:'boolean',isAnimated:'boolean',rootElement:'(element|string)',clickCallback:'(function|null)'};const NAME$2='backdrop';const CLASS_NAME_FADE='fade';const CLASS_NAME_SHOW$1='show';const EVENT_MOUSEDOWN=`mousedown.bs.${NAME$2}`;class Backdrop{constructor(config){this._config=this._getConfig(config);this._isAppended=false;this._element=null;}
show(callback){if(!this._config.isVisible){execute(callback);return;}
this._append();if(this._config.isAnimated){reflow(this._getElement());}
this._getElement().classList.add(CLASS_NAME_SHOW$1);this._emulateAnimation(()=>{execute(callback);});}
hide(callback){if(!this._config.isVisible){execute(callback);return;}
this._getElement().classList.remove(CLASS_NAME_SHOW$1);this._emulateAnimation(()=>{this.dispose();execute(callback);});}
_getElement(){if(!this._element){const backdrop=document.createElement('div');backdrop.className=this._config.className;if(this._config.isAnimated){backdrop.classList.add(CLASS_NAME_FADE);}
this._element=backdrop;}
return this._element;}
_getConfig(config){config={...Default$2,...(typeof config==='object'?config:{})};config.rootElement=getElement(config.rootElement);typeCheckConfig(NAME$2,config,DefaultType$2);return config;}
_append(){if(this._isAppended){return;}
this._config.rootElement.append(this._getElement());EventHandler__default.default.on(this._getElement(),EVENT_MOUSEDOWN,()=>{execute(this._config.clickCallback);});this._isAppended=true;}
dispose(){if(!this._isAppended){return;}
EventHandler__default.default.off(this._element,EVENT_MOUSEDOWN);this._element.remove();this._isAppended=false;}
_emulateAnimation(callback){executeAfterTransition(callback,this._getElement(),this._config.isAnimated);}}
const Default$1={trapElement:null,autofocus:true};const DefaultType$1={trapElement:'element',autofocus:'boolean'};const NAME$1='focustrap';const DATA_KEY$1='bs.focustrap';const EVENT_KEY$1=`.${DATA_KEY$1}`;const EVENT_FOCUSIN=`focusin${EVENT_KEY$1}`;const EVENT_KEYDOWN_TAB=`keydown.tab${EVENT_KEY$1}`;const TAB_KEY='Tab';const TAB_NAV_FORWARD='forward';const TAB_NAV_BACKWARD='backward';class FocusTrap{constructor(config){this._config=this._getConfig(config);this._isActive=false;this._lastTabNavDirection=null;}
activate(){const{trapElement,autofocus}=this._config;if(this._isActive){return;}
if(autofocus){trapElement.focus();}
EventHandler__default.default.off(document,EVENT_KEY$1);EventHandler__default.default.on(document,EVENT_FOCUSIN,event=>this._handleFocusin(event));EventHandler__default.default.on(document,EVENT_KEYDOWN_TAB,event=>this._handleKeydown(event));this._isActive=true;}
deactivate(){if(!this._isActive){return;}
this._isActive=false;EventHandler__default.default.off(document,EVENT_KEY$1);}
_handleFocusin(event){const{target}=event;const{trapElement}=this._config;if(target===document||target===trapElement||trapElement.contains(target)){return;}
const elements=SelectorEngine__default.default.focusableChildren(trapElement);if(elements.length===0){trapElement.focus();}else if(this._lastTabNavDirection===TAB_NAV_BACKWARD){elements[elements.length-1].focus();}else{elements[0].focus();}}
_handleKeydown(event){if(event.key!==TAB_KEY){return;}
this._lastTabNavDirection=event.shiftKey?TAB_NAV_BACKWARD:TAB_NAV_FORWARD;}
_getConfig(config){config={...Default$1,...(typeof config==='object'?config:{})};typeCheckConfig(NAME$1,config,DefaultType$1);return config;}}
const enableDismissTrigger=(component,method='hide')=>{const clickEvent=`click.dismiss${component.EVENT_KEY}`;const name=component.NAME;EventHandler__default.default.on(document,clickEvent,`[data-bs-dismiss="${name}"]`,function(event){if(['A','AREA'].includes(this.tagName)){event.preventDefault();}
if(isDisabled(this)){return;}
const target=getElementFromSelector(this)||this.closest(`.${name}`);const instance=component.getOrCreateInstance(target);instance[method]();});};const NAME='offcanvas';const DATA_KEY='bs.offcanvas';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const EVENT_LOAD_DATA_API=`load${EVENT_KEY}${DATA_API_KEY}`;const ESCAPE_KEY='Escape';const Default={backdrop:true,keyboard:true,scroll:false};const DefaultType={backdrop:'boolean',keyboard:'boolean',scroll:'boolean'};const CLASS_NAME_SHOW='show';const CLASS_NAME_BACKDROP='offcanvas-backdrop';const OPEN_SELECTOR='.offcanvas.show';const EVENT_SHOW=`show${EVENT_KEY}`;const EVENT_SHOWN=`shown${EVENT_KEY}`;const EVENT_HIDE=`hide${EVENT_KEY}`;const EVENT_HIDDEN=`hidden${EVENT_KEY}`;const EVENT_CLICK_DATA_API=`click${EVENT_KEY}${DATA_API_KEY}`;const EVENT_KEYDOWN_DISMISS=`keydown.dismiss${EVENT_KEY}`;const SELECTOR_DATA_TOGGLE='[data-bs-toggle="offcanvas"]';class Offcanvas extends BaseComponent__default.default{constructor(element,config){super(element);this._config=this._getConfig(config);this._isShown=false;this._backdrop=this._initializeBackDrop();this._focustrap=this._initializeFocusTrap();this._addEventListeners();}
static get NAME(){return NAME;}
static get Default(){return Default;}
toggle(relatedTarget){return this._isShown?this.hide():this.show(relatedTarget);}
show(relatedTarget){if(this._isShown){return;}
const showEvent=EventHandler__default.default.trigger(this._element,EVENT_SHOW,{relatedTarget});if(showEvent.defaultPrevented){return;}
this._isShown=true;this._element.style.visibility='visible';this._backdrop.show();if(!this._config.scroll){new ScrollBarHelper().hide();}
this._element.removeAttribute('aria-hidden');this._element.setAttribute('aria-modal',true);this._element.setAttribute('role','dialog');this._element.classList.add(CLASS_NAME_SHOW);const completeCallBack=()=>{if(!this._config.scroll){this._focustrap.activate();}
EventHandler__default.default.trigger(this._element,EVENT_SHOWN,{relatedTarget});};this._queueCallback(completeCallBack,this._element,true);}
hide(){if(!this._isShown){return;}
const hideEvent=EventHandler__default.default.trigger(this._element,EVENT_HIDE);if(hideEvent.defaultPrevented){return;}
this._focustrap.deactivate();this._element.blur();this._isShown=false;this._element.classList.remove(CLASS_NAME_SHOW);this._backdrop.hide();const completeCallback=()=>{this._element.setAttribute('aria-hidden',true);this._element.removeAttribute('aria-modal');this._element.removeAttribute('role');this._element.style.visibility='hidden';if(!this._config.scroll){new ScrollBarHelper().reset();}
EventHandler__default.default.trigger(this._element,EVENT_HIDDEN);};this._queueCallback(completeCallback,this._element,true);}
dispose(){this._backdrop.dispose();this._focustrap.deactivate();super.dispose();}
_getConfig(config){config={...Default,...Manipulator__default.default.getDataAttributes(this._element),...(typeof config==='object'?config:{})};typeCheckConfig(NAME,config,DefaultType);return config;}
_initializeBackDrop(){return new Backdrop({className:CLASS_NAME_BACKDROP,isVisible:this._config.backdrop,isAnimated:true,rootElement:this._element.parentNode,clickCallback:()=>this.hide()});}
_initializeFocusTrap(){return new FocusTrap({trapElement:this._element});}
_addEventListeners(){EventHandler__default.default.on(this._element,EVENT_KEYDOWN_DISMISS,event=>{if(this._config.keyboard&&event.key===ESCAPE_KEY){this.hide();}});}
static jQueryInterface(config){return this.each(function(){const data=Offcanvas.getOrCreateInstance(this,config);if(typeof config!=='string'){return;}
if(data[config]===undefined||config.startsWith('_')||config==='constructor'){throw new TypeError(`No method named "${config}"`);}
data[config](this);});}}
EventHandler__default.default.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_TOGGLE,function(event){const target=getElementFromSelector(this);if(['A','AREA'].includes(this.tagName)){event.preventDefault();}
if(isDisabled(this)){return;}
EventHandler__default.default.one(target,EVENT_HIDDEN,()=>{if(isVisible(this)){this.focus();}});const allReadyOpen=SelectorEngine__default.default.findOne(OPEN_SELECTOR);if(allReadyOpen&&allReadyOpen!==target){Offcanvas.getInstance(allReadyOpen).hide();}
const data=Offcanvas.getOrCreateInstance(target);data.toggle(this);});EventHandler__default.default.on(window,EVENT_LOAD_DATA_API,()=>SelectorEngine__default.default.find(OPEN_SELECTOR).forEach(el=>Offcanvas.getOrCreateInstance(el).show()));enableDismissTrigger(Offcanvas);defineJQueryPlugin(Offcanvas);return Offcanvas;}));;

/* /web/static/lib/bootstrap/js/dist/tooltip.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('@popperjs/core'),require('./dom/data.js'),require('./dom/event-handler.js'),require('./dom/manipulator.js'),require('./dom/selector-engine.js'),require('./base-component.js')):typeof define==='function'&&define.amd?define(['@popperjs/core','./dom/data','./dom/event-handler','./dom/manipulator','./dom/selector-engine','./base-component'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Tooltip=factory(global.Popper,global.Data,global.EventHandler,global.Manipulator,global.SelectorEngine,global.Base));})(this,(function(Popper,Data,EventHandler,Manipulator,SelectorEngine,BaseComponent){'use strict';const _interopDefaultLegacy=e=>e&&typeof e==='object'&&'default'in e?e:{default:e};function _interopNamespace(e){if(e&&e.__esModule)return e;const n=Object.create(null);if(e){for(const k in e){if(k!=='default'){const d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:()=>e[k]});}}}
n.default=e;return Object.freeze(n);}
const Popper__namespace=_interopNamespace(Popper);const Data__default=_interopDefaultLegacy(Data);const EventHandler__default=_interopDefaultLegacy(EventHandler);const Manipulator__default=_interopDefaultLegacy(Manipulator);const SelectorEngine__default=_interopDefaultLegacy(SelectorEngine);const BaseComponent__default=_interopDefaultLegacy(BaseComponent);const MAX_UID=1000000;const toType=obj=>{if(obj===null||obj===undefined){return`${obj}`;}
return{}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();};const getUID=prefix=>{do{prefix+=Math.floor(Math.random()*MAX_UID);}while(document.getElementById(prefix));return prefix;};const isElement=obj=>{if(!obj||typeof obj!=='object'){return false;}
if(typeof obj.jquery!=='undefined'){obj=obj[0];}
return typeof obj.nodeType!=='undefined';};const getElement=obj=>{if(isElement(obj)){return obj.jquery?obj[0]:obj;}
if(typeof obj==='string'&&obj.length>0){return document.querySelector(obj);}
return null;};const typeCheckConfig=(componentName,config,configTypes)=>{Object.keys(configTypes).forEach(property=>{const expectedTypes=configTypes[property];const value=config[property];const valueType=value&&isElement(value)?'element':toType(value);if(!new RegExp(expectedTypes).test(valueType)){throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);}});};const findShadowRoot=element=>{if(!document.documentElement.attachShadow){return null;}
if(typeof element.getRootNode==='function'){const root=element.getRootNode();return root instanceof ShadowRoot?root:null;}
if(element instanceof ShadowRoot){return element;}
if(!element.parentNode){return null;}
return findShadowRoot(element.parentNode);};const noop=()=>{};const getjQuery=()=>{const{jQuery}=window;if(jQuery&&!document.body.hasAttribute('data-bs-no-jquery')){return jQuery;}
return null;};const DOMContentLoadedCallbacks=[];const onDOMContentLoaded=callback=>{if(document.readyState==='loading'){if(!DOMContentLoadedCallbacks.length){document.addEventListener('DOMContentLoaded',()=>{DOMContentLoadedCallbacks.forEach(callback=>callback());});}
DOMContentLoadedCallbacks.push(callback);}else{callback();}};const isRTL=()=>document.documentElement.dir==='rtl';const defineJQueryPlugin=plugin=>{onDOMContentLoaded(()=>{const $=getjQuery();if($){const name=plugin.NAME;const JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface;$.fn[name].Constructor=plugin;$.fn[name].noConflict=()=>{$.fn[name]=JQUERY_NO_CONFLICT;return plugin.jQueryInterface;};}});};const uriAttributes=new Set(['background','cite','href','itemtype','longdesc','poster','src','xlink:href']);const ARIA_ATTRIBUTE_PATTERN=/^aria-[\w-]*$/i;const SAFE_URL_PATTERN=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i;const DATA_URL_PATTERN=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;const allowedAttribute=(attribute,allowedAttributeList)=>{const attributeName=attribute.nodeName.toLowerCase();if(allowedAttributeList.includes(attributeName)){if(uriAttributes.has(attributeName)){return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue)||DATA_URL_PATTERN.test(attribute.nodeValue));}
return true;}
const regExp=allowedAttributeList.filter(attributeRegex=>attributeRegex instanceof RegExp);for(let i=0,len=regExp.length;i<len;i++){if(regExp[i].test(attributeName)){return true;}}
return false;};const DefaultAllowlist={'*':['class','dir','id','lang','role',ARIA_ATTRIBUTE_PATTERN],a:['target','href','title','rel'],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:['src','srcset','alt','title','width','height'],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]};function sanitizeHtml(unsafeHtml,allowList,sanitizeFn){if(!unsafeHtml.length){return unsafeHtml;}
if(sanitizeFn&&typeof sanitizeFn==='function'){return sanitizeFn(unsafeHtml);}
const domParser=new window.DOMParser();const createdDocument=domParser.parseFromString(unsafeHtml,'text/html');const elements=[].concat(...createdDocument.body.querySelectorAll('*'));for(let i=0,len=elements.length;i<len;i++){const element=elements[i];const elementName=element.nodeName.toLowerCase();if(!Object.keys(allowList).includes(elementName)){element.remove();continue;}
const attributeList=[].concat(...element.attributes);const allowedAttributes=[].concat(allowList['*']||[],allowList[elementName]||[]);attributeList.forEach(attribute=>{if(!allowedAttribute(attribute,allowedAttributes)){element.removeAttribute(attribute.nodeName);}});}
return createdDocument.body.innerHTML;}
const NAME='tooltip';const DATA_KEY='bs.tooltip';const EVENT_KEY=`.${DATA_KEY}`;const CLASS_PREFIX='bs-tooltip';const DISALLOWED_ATTRIBUTES=new Set(['sanitize','allowList','sanitizeFn']);const DefaultType={animation:'boolean',template:'string',title:'(string|element|function)',trigger:'string',delay:'(number|object)',html:'boolean',selector:'(string|boolean)',placement:'(string|function)',offset:'(array|string|function)',container:'(string|element|boolean)',fallbackPlacements:'array',boundary:'(string|element)',customClass:'(string|function)',sanitize:'boolean',sanitizeFn:'(null|function)',allowList:'object',popperConfig:'(null|object|function)'};const AttachmentMap={AUTO:'auto',TOP:'top',RIGHT:isRTL()?'left':'right',BOTTOM:'bottom',LEFT:isRTL()?'right':'left'};const Default={animation:true,template:'<div class="tooltip" role="tooltip">'+'<div class="tooltip-arrow"></div>'+'<div class="tooltip-inner"></div>'+'</div>',trigger:'hover focus',title:'',delay:0,html:false,selector:false,placement:'top',offset:[0,0],container:false,fallbackPlacements:['top','right','bottom','left'],boundary:'clippingParents',customClass:'',sanitize:true,sanitizeFn:null,allowList:DefaultAllowlist,popperConfig:null};const Event={HIDE:`hide${EVENT_KEY}`,HIDDEN:`hidden${EVENT_KEY}`,SHOW:`show${EVENT_KEY}`,SHOWN:`shown${EVENT_KEY}`,INSERTED:`inserted${EVENT_KEY}`,CLICK:`click${EVENT_KEY}`,FOCUSIN:`focusin${EVENT_KEY}`,FOCUSOUT:`focusout${EVENT_KEY}`,MOUSEENTER:`mouseenter${EVENT_KEY}`,MOUSELEAVE:`mouseleave${EVENT_KEY}`};const CLASS_NAME_FADE='fade';const CLASS_NAME_MODAL='modal';const CLASS_NAME_SHOW='show';const HOVER_STATE_SHOW='show';const HOVER_STATE_OUT='out';const SELECTOR_TOOLTIP_INNER='.tooltip-inner';const SELECTOR_MODAL=`.${CLASS_NAME_MODAL}`;const EVENT_MODAL_HIDE='hide.bs.modal';const TRIGGER_HOVER='hover';const TRIGGER_FOCUS='focus';const TRIGGER_CLICK='click';const TRIGGER_MANUAL='manual';class Tooltip extends BaseComponent__default.default{constructor(element,config){if(typeof Popper__namespace==='undefined'){throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)');}
super(element);this._isEnabled=true;this._timeout=0;this._hoverState='';this._activeTrigger={};this._popper=null;this._config=this._getConfig(config);this.tip=null;this._setListeners();}
static get Default(){return Default;}
static get NAME(){return NAME;}
static get Event(){return Event;}
static get DefaultType(){return DefaultType;}
enable(){this._isEnabled=true;}
disable(){this._isEnabled=false;}
toggleEnabled(){this._isEnabled=!this._isEnabled;}
toggle(event){if(!this._isEnabled){return;}
if(event){const context=this._initializeOnDelegatedTarget(event);context._activeTrigger.click=!context._activeTrigger.click;if(context._isWithActiveTrigger()){context._enter(null,context);}else{context._leave(null,context);}}else{if(this.getTipElement().classList.contains(CLASS_NAME_SHOW)){this._leave(null,this);return;}
this._enter(null,this);}}
dispose(){clearTimeout(this._timeout);EventHandler__default.default.off(this._element.closest(SELECTOR_MODAL),EVENT_MODAL_HIDE,this._hideModalHandler);if(this.tip){this.tip.remove();}
this._disposePopper();super.dispose();}
show(){if(this._element.style.display==='none'){throw new Error('Please use show on visible elements');}
if(!(this.isWithContent()&&this._isEnabled)){return;}
const showEvent=EventHandler__default.default.trigger(this._element,this.constructor.Event.SHOW);const shadowRoot=findShadowRoot(this._element);const isInTheDom=shadowRoot===null?this._element.ownerDocument.documentElement.contains(this._element):shadowRoot.contains(this._element);if(showEvent.defaultPrevented||!isInTheDom){return;}
if(this.constructor.NAME==='tooltip'&&this.tip&&this.getTitle()!==this.tip.querySelector(SELECTOR_TOOLTIP_INNER).innerHTML){this._disposePopper();this.tip.remove();this.tip=null;}
const tip=this.getTipElement();const tipId=getUID(this.constructor.NAME);tip.setAttribute('id',tipId);this._element.setAttribute('aria-describedby',tipId);if(this._config.animation){tip.classList.add(CLASS_NAME_FADE);}
const placement=typeof this._config.placement==='function'?this._config.placement.call(this,tip,this._element):this._config.placement;const attachment=this._getAttachment(placement);this._addAttachmentClass(attachment);const{container}=this._config;Data__default.default.set(tip,this.constructor.DATA_KEY,this);if(!this._element.ownerDocument.documentElement.contains(this.tip)){container.append(tip);EventHandler__default.default.trigger(this._element,this.constructor.Event.INSERTED);}
if(this._popper){this._popper.update();}else{this._popper=Popper__namespace.createPopper(this._element,tip,this._getPopperConfig(attachment));}
tip.classList.add(CLASS_NAME_SHOW);const customClass=this._resolvePossibleFunction(this._config.customClass);if(customClass){tip.classList.add(...customClass.split(' '));}
if('ontouchstart'in document.documentElement){[].concat(...document.body.children).forEach(element=>{EventHandler__default.default.on(element,'mouseover',noop);});}
const complete=()=>{const prevHoverState=this._hoverState;this._hoverState=null;EventHandler__default.default.trigger(this._element,this.constructor.Event.SHOWN);if(prevHoverState===HOVER_STATE_OUT){this._leave(null,this);}};const isAnimated=this.tip.classList.contains(CLASS_NAME_FADE);this._queueCallback(complete,this.tip,isAnimated);}
hide(){if(!this._popper){return;}
const tip=this.getTipElement();const complete=()=>{if(!this._element||!this._config){return;}
if(this._isWithActiveTrigger()){return;}
if(this._hoverState!==HOVER_STATE_SHOW){tip.remove();}
this._cleanTipClass();this._element.removeAttribute('aria-describedby');EventHandler__default.default.trigger(this._element,this.constructor.Event.HIDDEN);this._disposePopper();};const hideEvent=EventHandler__default.default.trigger(this._element,this.constructor.Event.HIDE);if(hideEvent.defaultPrevented){return;}
tip.classList.remove(CLASS_NAME_SHOW);if('ontouchstart'in document.documentElement){[].concat(...document.body.children).forEach(element=>EventHandler__default.default.off(element,'mouseover',noop));}
this._activeTrigger[TRIGGER_CLICK]=false;this._activeTrigger[TRIGGER_FOCUS]=false;this._activeTrigger[TRIGGER_HOVER]=false;const isAnimated=this.tip.classList.contains(CLASS_NAME_FADE);this._queueCallback(complete,this.tip,isAnimated);this._hoverState='';}
update(){if(this._popper!==null){this._popper.update();}}
isWithContent(){return Boolean(this.getTitle());}
getTipElement(){if(this.tip){return this.tip;}
const element=document.createElement('div');element.innerHTML=this._config.template;const tip=element.children[0];this.setContent(tip);tip.classList.remove(CLASS_NAME_FADE,CLASS_NAME_SHOW);this.tip=tip;return this.tip;}
setContent(tip){this._sanitizeAndSetContent(tip,this.getTitle(),SELECTOR_TOOLTIP_INNER);}
_sanitizeAndSetContent(template,content,selector){const templateElement=SelectorEngine__default.default.findOne(selector,template);if(!content&&templateElement){templateElement.remove();return;}
this.setElementContent(templateElement,content);}
setElementContent(element,content){if(element===null){return;}
if(isElement(content)){content=getElement(content);if(this._config.html){if(content.parentNode!==element){element.innerHTML='';element.append(content);}}else{element.textContent=content.textContent;}
return;}
if(this._config.html){if(this._config.sanitize){content=sanitizeHtml(content,this._config.allowList,this._config.sanitizeFn);}
element.innerHTML=content;}else{element.textContent=content;}}
getTitle(){const title=this._element.getAttribute('data-bs-original-title')||this._config.title;return this._resolvePossibleFunction(title);}
updateAttachment(attachment){if(attachment==='right'){return'end';}
if(attachment==='left'){return'start';}
return attachment;}
_initializeOnDelegatedTarget(event,context){return context||this.constructor.getOrCreateInstance(event.delegateTarget,this._getDelegateConfig());}
_getOffset(){const{offset}=this._config;if(typeof offset==='string'){return offset.split(',').map(val=>Number.parseInt(val,10));}
if(typeof offset==='function'){return popperData=>offset(popperData,this._element);}
return offset;}
_resolvePossibleFunction(content){return typeof content==='function'?content.call(this._element):content;}
_getPopperConfig(attachment){const defaultBsPopperConfig={placement:attachment,modifiers:[{name:'flip',options:{fallbackPlacements:this._config.fallbackPlacements}},{name:'offset',options:{offset:this._getOffset()}},{name:'preventOverflow',options:{boundary:this._config.boundary}},{name:'arrow',options:{element:`.${this.constructor.NAME}-arrow`}},{name:'onChange',enabled:true,phase:'afterWrite',fn:data=>this._handlePopperPlacementChange(data)}],onFirstUpdate:data=>{if(data.options.placement!==data.placement){this._handlePopperPlacementChange(data);}}};return{...defaultBsPopperConfig,...(typeof this._config.popperConfig==='function'?this._config.popperConfig(defaultBsPopperConfig):this._config.popperConfig)};}
_addAttachmentClass(attachment){this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(attachment)}`);}
_getAttachment(placement){return AttachmentMap[placement.toUpperCase()];}
_setListeners(){const triggers=this._config.trigger.split(' ');triggers.forEach(trigger=>{if(trigger==='click'){EventHandler__default.default.on(this._element,this.constructor.Event.CLICK,this._config.selector,event=>this.toggle(event));}else if(trigger!==TRIGGER_MANUAL){const eventIn=trigger===TRIGGER_HOVER?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN;const eventOut=trigger===TRIGGER_HOVER?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;EventHandler__default.default.on(this._element,eventIn,this._config.selector,event=>this._enter(event));EventHandler__default.default.on(this._element,eventOut,this._config.selector,event=>this._leave(event));}});this._hideModalHandler=()=>{if(this._element){this.hide();}};EventHandler__default.default.on(this._element.closest(SELECTOR_MODAL),EVENT_MODAL_HIDE,this._hideModalHandler);if(this._config.selector){this._config={...this._config,trigger:'manual',selector:''};}else{this._fixTitle();}}
_fixTitle(){const title=this._element.getAttribute('title');const originalTitleType=typeof this._element.getAttribute('data-bs-original-title');if(title||originalTitleType!=='string'){this._element.setAttribute('data-bs-original-title',title||'');if(title&&!this._element.getAttribute('aria-label')&&!this._element.textContent){this._element.setAttribute('aria-label',title);}
this._element.setAttribute('title','');}}
_enter(event,context){context=this._initializeOnDelegatedTarget(event,context);if(event){context._activeTrigger[event.type==='focusin'?TRIGGER_FOCUS:TRIGGER_HOVER]=true;}
if(context.getTipElement().classList.contains(CLASS_NAME_SHOW)||context._hoverState===HOVER_STATE_SHOW){context._hoverState=HOVER_STATE_SHOW;return;}
clearTimeout(context._timeout);context._hoverState=HOVER_STATE_SHOW;if(!context._config.delay||!context._config.delay.show){context.show();return;}
context._timeout=setTimeout(()=>{if(context._hoverState===HOVER_STATE_SHOW){context.show();}},context._config.delay.show);}
_leave(event,context){context=this._initializeOnDelegatedTarget(event,context);if(event){context._activeTrigger[event.type==='focusout'?TRIGGER_FOCUS:TRIGGER_HOVER]=context._element.contains(event.relatedTarget);}
if(context._isWithActiveTrigger()){return;}
clearTimeout(context._timeout);context._hoverState=HOVER_STATE_OUT;if(!context._config.delay||!context._config.delay.hide){context.hide();return;}
context._timeout=setTimeout(()=>{if(context._hoverState===HOVER_STATE_OUT){context.hide();}},context._config.delay.hide);}
_isWithActiveTrigger(){for(const trigger in this._activeTrigger){if(this._activeTrigger[trigger]){return true;}}
return false;}
_getConfig(config){const dataAttributes=Manipulator__default.default.getDataAttributes(this._element);Object.keys(dataAttributes).forEach(dataAttr=>{if(DISALLOWED_ATTRIBUTES.has(dataAttr)){delete dataAttributes[dataAttr];}});config={...this.constructor.Default,...dataAttributes,...(typeof config==='object'&&config?config:{})};config.container=config.container===false?document.body:getElement(config.container);if(typeof config.delay==='number'){config.delay={show:config.delay,hide:config.delay};}
if(typeof config.title==='number'){config.title=config.title.toString();}
if(typeof config.content==='number'){config.content=config.content.toString();}
typeCheckConfig(NAME,config,this.constructor.DefaultType);if(config.sanitize){config.template=sanitizeHtml(config.template,config.allowList,config.sanitizeFn);}
return config;}
_getDelegateConfig(){const config={};for(const key in this._config){if(this.constructor.Default[key]!==this._config[key]){config[key]=this._config[key];}}
return config;}
_cleanTipClass(){const tip=this.getTipElement();const basicClassPrefixRegex=new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`,'g');const tabClass=tip.getAttribute('class').match(basicClassPrefixRegex);if(tabClass!==null&&tabClass.length>0){tabClass.map(token=>token.trim()).forEach(tClass=>tip.classList.remove(tClass));}}
_getBasicClassPrefix(){return CLASS_PREFIX;}
_handlePopperPlacementChange(popperData){const{state}=popperData;if(!state){return;}
this.tip=state.elements.popper;this._cleanTipClass();this._addAttachmentClass(this._getAttachment(state.placement));}
_disposePopper(){if(this._popper){this._popper.destroy();this._popper=null;}}
static jQueryInterface(config){return this.each(function(){const data=Tooltip.getOrCreateInstance(this,config);if(typeof config==='string'){if(typeof data[config]==='undefined'){throw new TypeError(`No method named "${config}"`);}
data[config]();}});}}
defineJQueryPlugin(Tooltip);return Tooltip;}));;

/* /web/static/lib/bootstrap/js/dist/popover.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./tooltip.js')):typeof define==='function'&&define.amd?define(['./tooltip'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Popover=factory(global.Tooltip));})(this,(function(Tooltip){'use strict';const _interopDefaultLegacy=e=>e&&typeof e==='object'&&'default'in e?e:{default:e};const Tooltip__default=_interopDefaultLegacy(Tooltip);const getjQuery=()=>{const{jQuery}=window;if(jQuery&&!document.body.hasAttribute('data-bs-no-jquery')){return jQuery;}
return null;};const DOMContentLoadedCallbacks=[];const onDOMContentLoaded=callback=>{if(document.readyState==='loading'){if(!DOMContentLoadedCallbacks.length){document.addEventListener('DOMContentLoaded',()=>{DOMContentLoadedCallbacks.forEach(callback=>callback());});}
DOMContentLoadedCallbacks.push(callback);}else{callback();}};const defineJQueryPlugin=plugin=>{onDOMContentLoaded(()=>{const $=getjQuery();if($){const name=plugin.NAME;const JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface;$.fn[name].Constructor=plugin;$.fn[name].noConflict=()=>{$.fn[name]=JQUERY_NO_CONFLICT;return plugin.jQueryInterface;};}});};const NAME='popover';const DATA_KEY='bs.popover';const EVENT_KEY=`.${DATA_KEY}`;const CLASS_PREFIX='bs-popover';const Default={...Tooltip__default.default.Default,placement:'right',offset:[0,8],trigger:'click',content:'',template:'<div class="popover" role="tooltip">'+'<div class="popover-arrow"></div>'+'<h3 class="popover-header"></h3>'+'<div class="popover-body"></div>'+'</div>'};const DefaultType={...Tooltip__default.default.DefaultType,content:'(string|element|function)'};const Event={HIDE:`hide${EVENT_KEY}`,HIDDEN:`hidden${EVENT_KEY}`,SHOW:`show${EVENT_KEY}`,SHOWN:`shown${EVENT_KEY}`,INSERTED:`inserted${EVENT_KEY}`,CLICK:`click${EVENT_KEY}`,FOCUSIN:`focusin${EVENT_KEY}`,FOCUSOUT:`focusout${EVENT_KEY}`,MOUSEENTER:`mouseenter${EVENT_KEY}`,MOUSELEAVE:`mouseleave${EVENT_KEY}`};const SELECTOR_TITLE='.popover-header';const SELECTOR_CONTENT='.popover-body';class Popover extends Tooltip__default.default{static get Default(){return Default;}
static get NAME(){return NAME;}
static get Event(){return Event;}
static get DefaultType(){return DefaultType;}
isWithContent(){return this.getTitle()||this._getContent();}
setContent(tip){this._sanitizeAndSetContent(tip,this.getTitle(),SELECTOR_TITLE);this._sanitizeAndSetContent(tip,this._getContent(),SELECTOR_CONTENT);}
_getContent(){return this._resolvePossibleFunction(this._config.content);}
_getBasicClassPrefix(){return CLASS_PREFIX;}
static jQueryInterface(config){return this.each(function(){const data=Popover.getOrCreateInstance(this,config);if(typeof config==='string'){if(typeof data[config]==='undefined'){throw new TypeError(`No method named "${config}"`);}
data[config]();}});}}
defineJQueryPlugin(Popover);return Popover;}));;

/* /web/static/lib/bootstrap/js/dist/scrollspy.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./dom/event-handler.js'),require('./dom/manipulator.js'),require('./dom/selector-engine.js'),require('./base-component.js')):typeof define==='function'&&define.amd?define(['./dom/event-handler','./dom/manipulator','./dom/selector-engine','./base-component'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.ScrollSpy=factory(global.EventHandler,global.Manipulator,global.SelectorEngine,global.Base));})(this,(function(EventHandler,Manipulator,SelectorEngine,BaseComponent){'use strict';const _interopDefaultLegacy=e=>e&&typeof e==='object'&&'default'in e?e:{default:e};const EventHandler__default=_interopDefaultLegacy(EventHandler);const Manipulator__default=_interopDefaultLegacy(Manipulator);const SelectorEngine__default=_interopDefaultLegacy(SelectorEngine);const BaseComponent__default=_interopDefaultLegacy(BaseComponent);const toType=obj=>{if(obj===null||obj===undefined){return`${obj}`;}
return{}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();};const getSelector=element=>{let selector=element.getAttribute('data-bs-target');if(!selector||selector==='#'){let hrefAttr=element.getAttribute('href');if(!hrefAttr||!hrefAttr.includes('#')&&!hrefAttr.startsWith('.')){return null;}
if(hrefAttr.includes('#')&&!hrefAttr.startsWith('#')){hrefAttr=`#${hrefAttr.split('#')[1]}`;}
selector=hrefAttr&&hrefAttr!=='#'?hrefAttr.trim():null;}
return selector;};const getSelectorFromElement=element=>{const selector=getSelector(element);if(selector){return document.querySelector(selector)?selector:null;}
return null;};const isElement=obj=>{if(!obj||typeof obj!=='object'){return false;}
if(typeof obj.jquery!=='undefined'){obj=obj[0];}
return typeof obj.nodeType!=='undefined';};const getElement=obj=>{if(isElement(obj)){return obj.jquery?obj[0]:obj;}
if(typeof obj==='string'&&obj.length>0){return document.querySelector(obj);}
return null;};const typeCheckConfig=(componentName,config,configTypes)=>{Object.keys(configTypes).forEach(property=>{const expectedTypes=configTypes[property];const value=config[property];const valueType=value&&isElement(value)?'element':toType(value);if(!new RegExp(expectedTypes).test(valueType)){throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);}});};const getjQuery=()=>{const{jQuery}=window;if(jQuery&&!document.body.hasAttribute('data-bs-no-jquery')){return jQuery;}
return null;};const DOMContentLoadedCallbacks=[];const onDOMContentLoaded=callback=>{if(document.readyState==='loading'){if(!DOMContentLoadedCallbacks.length){document.addEventListener('DOMContentLoaded',()=>{DOMContentLoadedCallbacks.forEach(callback=>callback());});}
DOMContentLoadedCallbacks.push(callback);}else{callback();}};const defineJQueryPlugin=plugin=>{onDOMContentLoaded(()=>{const $=getjQuery();if($){const name=plugin.NAME;const JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface;$.fn[name].Constructor=plugin;$.fn[name].noConflict=()=>{$.fn[name]=JQUERY_NO_CONFLICT;return plugin.jQueryInterface;};}});};const NAME='scrollspy';const DATA_KEY='bs.scrollspy';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const Default={offset:10,method:'auto',target:''};const DefaultType={offset:'number',method:'string',target:'(string|element)'};const EVENT_ACTIVATE=`activate${EVENT_KEY}`;const EVENT_SCROLL=`scroll${EVENT_KEY}`;const EVENT_LOAD_DATA_API=`load${EVENT_KEY}${DATA_API_KEY}`;const CLASS_NAME_DROPDOWN_ITEM='dropdown-item';const CLASS_NAME_ACTIVE='active';const SELECTOR_DATA_SPY='[data-bs-spy="scroll"]';const SELECTOR_NAV_LIST_GROUP='.nav, .list-group';const SELECTOR_NAV_LINKS='.nav-link';const SELECTOR_NAV_ITEMS='.nav-item';const SELECTOR_LIST_ITEMS='.list-group-item';const SELECTOR_LINK_ITEMS=`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}, .${CLASS_NAME_DROPDOWN_ITEM}`;const SELECTOR_DROPDOWN='.dropdown';const SELECTOR_DROPDOWN_TOGGLE='.dropdown-toggle';const METHOD_OFFSET='offset';const METHOD_POSITION='position';class ScrollSpy extends BaseComponent__default.default{constructor(element,config){super(element);this._scrollElement=this._element.tagName==='BODY'?window:this._element;this._config=this._getConfig(config);this._offsets=[];this._targets=[];this._activeTarget=null;this._scrollHeight=0;EventHandler__default.default.on(this._scrollElement,EVENT_SCROLL,()=>this._process());this.refresh();this._process();}
static get Default(){return Default;}
static get NAME(){return NAME;}
refresh(){const autoMethod=this._scrollElement===this._scrollElement.window?METHOD_OFFSET:METHOD_POSITION;const offsetMethod=this._config.method==='auto'?autoMethod:this._config.method;const offsetBase=offsetMethod===METHOD_POSITION?this._getScrollTop():0;this._offsets=[];this._targets=[];this._scrollHeight=this._getScrollHeight();const targets=SelectorEngine__default.default.find(SELECTOR_LINK_ITEMS,this._config.target);targets.map(element=>{const targetSelector=getSelectorFromElement(element);const target=targetSelector?SelectorEngine__default.default.findOne(targetSelector):null;if(target){const targetBCR=target.getBoundingClientRect();if(targetBCR.width||targetBCR.height){return[Manipulator__default.default[offsetMethod](target).top+offsetBase,targetSelector];}}
return null;}).filter(item=>item).sort((a,b)=>a[0]-b[0]).forEach(item=>{this._offsets.push(item[0]);this._targets.push(item[1]);});}
dispose(){EventHandler__default.default.off(this._scrollElement,EVENT_KEY);super.dispose();}
_getConfig(config){config={...Default,...Manipulator__default.default.getDataAttributes(this._element),...(typeof config==='object'&&config?config:{})};config.target=getElement(config.target)||document.documentElement;typeCheckConfig(NAME,config,DefaultType);return config;}
_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop;}
_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight);}
_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height;}
_process(){const scrollTop=this._getScrollTop()+this._config.offset;const scrollHeight=this._getScrollHeight();const maxScroll=this._config.offset+scrollHeight-this._getOffsetHeight();if(this._scrollHeight!==scrollHeight){this.refresh();}
if(scrollTop>=maxScroll){const target=this._targets[this._targets.length-1];if(this._activeTarget!==target){this._activate(target);}
return;}
if(this._activeTarget&&scrollTop<this._offsets[0]&&this._offsets[0]>0){this._activeTarget=null;this._clear();return;}
for(let i=this._offsets.length;i--;){const isActiveTarget=this._activeTarget!==this._targets[i]&&scrollTop>=this._offsets[i]&&(typeof this._offsets[i+1]==='undefined'||scrollTop<this._offsets[i+1]);if(isActiveTarget){this._activate(this._targets[i]);}}}
_activate(target){this._activeTarget=target;this._clear();const queries=SELECTOR_LINK_ITEMS.split(',').map(selector=>`${selector}[data-bs-target="${target}"],${selector}[href="${target}"]`);const link=SelectorEngine__default.default.findOne(queries.join(','),this._config.target);link.classList.add(CLASS_NAME_ACTIVE);if(link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)){SelectorEngine__default.default.findOne(SELECTOR_DROPDOWN_TOGGLE,link.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE);}else{SelectorEngine__default.default.parents(link,SELECTOR_NAV_LIST_GROUP).forEach(listGroup=>{SelectorEngine__default.default.prev(listGroup,`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`).forEach(item=>item.classList.add(CLASS_NAME_ACTIVE));SelectorEngine__default.default.prev(listGroup,SELECTOR_NAV_ITEMS).forEach(navItem=>{SelectorEngine__default.default.children(navItem,SELECTOR_NAV_LINKS).forEach(item=>item.classList.add(CLASS_NAME_ACTIVE));});});}
EventHandler__default.default.trigger(this._scrollElement,EVENT_ACTIVATE,{relatedTarget:target});}
_clear(){SelectorEngine__default.default.find(SELECTOR_LINK_ITEMS,this._config.target).filter(node=>node.classList.contains(CLASS_NAME_ACTIVE)).forEach(node=>node.classList.remove(CLASS_NAME_ACTIVE));}
static jQueryInterface(config){return this.each(function(){const data=ScrollSpy.getOrCreateInstance(this,config);if(typeof config!=='string'){return;}
if(typeof data[config]==='undefined'){throw new TypeError(`No method named "${config}"`);}
data[config]();});}}
EventHandler__default.default.on(window,EVENT_LOAD_DATA_API,()=>{SelectorEngine__default.default.find(SELECTOR_DATA_SPY).forEach(spy=>new ScrollSpy(spy));});defineJQueryPlugin(ScrollSpy);return ScrollSpy;}));;

/* /web/static/lib/bootstrap/js/dist/tab.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./dom/event-handler.js'),require('./dom/selector-engine.js'),require('./base-component.js')):typeof define==='function'&&define.amd?define(['./dom/event-handler','./dom/selector-engine','./base-component'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Tab=factory(global.EventHandler,global.SelectorEngine,global.Base));})(this,(function(EventHandler,SelectorEngine,BaseComponent){'use strict';const _interopDefaultLegacy=e=>e&&typeof e==='object'&&'default'in e?e:{default:e};const EventHandler__default=_interopDefaultLegacy(EventHandler);const SelectorEngine__default=_interopDefaultLegacy(SelectorEngine);const BaseComponent__default=_interopDefaultLegacy(BaseComponent);const getSelector=element=>{let selector=element.getAttribute('data-bs-target');if(!selector||selector==='#'){let hrefAttr=element.getAttribute('href');if(!hrefAttr||!hrefAttr.includes('#')&&!hrefAttr.startsWith('.')){return null;}
if(hrefAttr.includes('#')&&!hrefAttr.startsWith('#')){hrefAttr=`#${hrefAttr.split('#')[1]}`;}
selector=hrefAttr&&hrefAttr!=='#'?hrefAttr.trim():null;}
return selector;};const getElementFromSelector=element=>{const selector=getSelector(element);return selector?document.querySelector(selector):null;};const isDisabled=element=>{if(!element||element.nodeType!==Node.ELEMENT_NODE){return true;}
if(element.classList.contains('disabled')){return true;}
if(typeof element.disabled!=='undefined'){return element.disabled;}
return element.hasAttribute('disabled')&&element.getAttribute('disabled')!=='false';};const reflow=element=>{element.offsetHeight;};const getjQuery=()=>{const{jQuery}=window;if(jQuery&&!document.body.hasAttribute('data-bs-no-jquery')){return jQuery;}
return null;};const DOMContentLoadedCallbacks=[];const onDOMContentLoaded=callback=>{if(document.readyState==='loading'){if(!DOMContentLoadedCallbacks.length){document.addEventListener('DOMContentLoaded',()=>{DOMContentLoadedCallbacks.forEach(callback=>callback());});}
DOMContentLoadedCallbacks.push(callback);}else{callback();}};const defineJQueryPlugin=plugin=>{onDOMContentLoaded(()=>{const $=getjQuery();if($){const name=plugin.NAME;const JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface;$.fn[name].Constructor=plugin;$.fn[name].noConflict=()=>{$.fn[name]=JQUERY_NO_CONFLICT;return plugin.jQueryInterface;};}});};const NAME='tab';const DATA_KEY='bs.tab';const EVENT_KEY=`.${DATA_KEY}`;const DATA_API_KEY='.data-api';const EVENT_HIDE=`hide${EVENT_KEY}`;const EVENT_HIDDEN=`hidden${EVENT_KEY}`;const EVENT_SHOW=`show${EVENT_KEY}`;const EVENT_SHOWN=`shown${EVENT_KEY}`;const EVENT_CLICK_DATA_API=`click${EVENT_KEY}${DATA_API_KEY}`;const CLASS_NAME_DROPDOWN_MENU='dropdown-menu';const CLASS_NAME_ACTIVE='active';const CLASS_NAME_FADE='fade';const CLASS_NAME_SHOW='show';const SELECTOR_DROPDOWN='.dropdown';const SELECTOR_NAV_LIST_GROUP='.nav, .list-group';const SELECTOR_ACTIVE='.active';const SELECTOR_ACTIVE_UL=':scope > li > .active';const SELECTOR_DATA_TOGGLE='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]';const SELECTOR_DROPDOWN_TOGGLE='.dropdown-toggle';const SELECTOR_DROPDOWN_ACTIVE_CHILD=':scope > .dropdown-menu .active';class Tab extends BaseComponent__default.default{static get NAME(){return NAME;}
show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains(CLASS_NAME_ACTIVE)){return;}
let previous;const target=getElementFromSelector(this._element);const listElement=this._element.closest(SELECTOR_NAV_LIST_GROUP);if(listElement){const itemSelector=listElement.nodeName==='UL'||listElement.nodeName==='OL'?SELECTOR_ACTIVE_UL:SELECTOR_ACTIVE;previous=SelectorEngine__default.default.find(itemSelector,listElement);previous=previous[previous.length-1];}
const hideEvent=previous?EventHandler__default.default.trigger(previous,EVENT_HIDE,{relatedTarget:this._element}):null;const showEvent=EventHandler__default.default.trigger(this._element,EVENT_SHOW,{relatedTarget:previous});if(showEvent.defaultPrevented||hideEvent!==null&&hideEvent.defaultPrevented){return;}
this._activate(this._element,listElement);const complete=()=>{EventHandler__default.default.trigger(previous,EVENT_HIDDEN,{relatedTarget:this._element});EventHandler__default.default.trigger(this._element,EVENT_SHOWN,{relatedTarget:previous});};if(target){this._activate(target,target.parentNode,complete);}else{complete();}}
_activate(element,container,callback){const activeElements=container&&(container.nodeName==='UL'||container.nodeName==='OL')?SelectorEngine__default.default.find(SELECTOR_ACTIVE_UL,container):SelectorEngine__default.default.children(container,SELECTOR_ACTIVE);const active=activeElements[0];const isTransitioning=callback&&active&&active.classList.contains(CLASS_NAME_FADE);const complete=()=>this._transitionComplete(element,active,callback);if(active&&isTransitioning){active.classList.remove(CLASS_NAME_SHOW);this._queueCallback(complete,element,true);}else{complete();}}
_transitionComplete(element,active,callback){if(active){active.classList.remove(CLASS_NAME_ACTIVE);const dropdownChild=SelectorEngine__default.default.findOne(SELECTOR_DROPDOWN_ACTIVE_CHILD,active.parentNode);if(dropdownChild){dropdownChild.classList.remove(CLASS_NAME_ACTIVE);}
if(active.getAttribute('role')==='tab'){active.setAttribute('aria-selected',false);}}
element.classList.add(CLASS_NAME_ACTIVE);if(element.getAttribute('role')==='tab'){element.setAttribute('aria-selected',true);}
reflow(element);if(element.classList.contains(CLASS_NAME_FADE)){element.classList.add(CLASS_NAME_SHOW);}
let parent=element.parentNode;if(parent&&parent.nodeName==='LI'){parent=parent.parentNode;}
if(parent&&parent.classList.contains(CLASS_NAME_DROPDOWN_MENU)){const dropdownElement=element.closest(SELECTOR_DROPDOWN);if(dropdownElement){SelectorEngine__default.default.find(SELECTOR_DROPDOWN_TOGGLE,dropdownElement).forEach(dropdown=>dropdown.classList.add(CLASS_NAME_ACTIVE));}
element.setAttribute('aria-expanded',true);}
if(callback){callback();}}
static jQueryInterface(config){return this.each(function(){const data=Tab.getOrCreateInstance(this);if(typeof config==='string'){if(typeof data[config]==='undefined'){throw new TypeError(`No method named "${config}"`);}
data[config]();}});}}
EventHandler__default.default.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_TOGGLE,function(event){if(['A','AREA'].includes(this.tagName)){event.preventDefault();}
if(isDisabled(this)){return;}
const data=Tab.getOrCreateInstance(this);data.show();});defineJQueryPlugin(Tab);return Tab;}));;

/* /web/static/lib/bootstrap/js/dist/toast.js */
(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(require('./dom/event-handler.js'),require('./dom/manipulator.js'),require('./base-component.js')):typeof define==='function'&&define.amd?define(['./dom/event-handler','./dom/manipulator','./base-component'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Toast=factory(global.EventHandler,global.Manipulator,global.Base));})(this,(function(EventHandler,Manipulator,BaseComponent){'use strict';const _interopDefaultLegacy=e=>e&&typeof e==='object'&&'default'in e?e:{default:e};const EventHandler__default=_interopDefaultLegacy(EventHandler);const Manipulator__default=_interopDefaultLegacy(Manipulator);const BaseComponent__default=_interopDefaultLegacy(BaseComponent);const toType=obj=>{if(obj===null||obj===undefined){return`${obj}`;}
return{}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();};const getSelector=element=>{let selector=element.getAttribute('data-bs-target');if(!selector||selector==='#'){let hrefAttr=element.getAttribute('href');if(!hrefAttr||!hrefAttr.includes('#')&&!hrefAttr.startsWith('.')){return null;}
if(hrefAttr.includes('#')&&!hrefAttr.startsWith('#')){hrefAttr=`#${hrefAttr.split('#')[1]}`;}
selector=hrefAttr&&hrefAttr!=='#'?hrefAttr.trim():null;}
return selector;};const getElementFromSelector=element=>{const selector=getSelector(element);return selector?document.querySelector(selector):null;};const isElement=obj=>{if(!obj||typeof obj!=='object'){return false;}
if(typeof obj.jquery!=='undefined'){obj=obj[0];}
return typeof obj.nodeType!=='undefined';};const typeCheckConfig=(componentName,config,configTypes)=>{Object.keys(configTypes).forEach(property=>{const expectedTypes=configTypes[property];const value=config[property];const valueType=value&&isElement(value)?'element':toType(value);if(!new RegExp(expectedTypes).test(valueType)){throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);}});};const isDisabled=element=>{if(!element||element.nodeType!==Node.ELEMENT_NODE){return true;}
if(element.classList.contains('disabled')){return true;}
if(typeof element.disabled!=='undefined'){return element.disabled;}
return element.hasAttribute('disabled')&&element.getAttribute('disabled')!=='false';};const reflow=element=>{element.offsetHeight;};const getjQuery=()=>{const{jQuery}=window;if(jQuery&&!document.body.hasAttribute('data-bs-no-jquery')){return jQuery;}
return null;};const DOMContentLoadedCallbacks=[];const onDOMContentLoaded=callback=>{if(document.readyState==='loading'){if(!DOMContentLoadedCallbacks.length){document.addEventListener('DOMContentLoaded',()=>{DOMContentLoadedCallbacks.forEach(callback=>callback());});}
DOMContentLoadedCallbacks.push(callback);}else{callback();}};const defineJQueryPlugin=plugin=>{onDOMContentLoaded(()=>{const $=getjQuery();if($){const name=plugin.NAME;const JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface;$.fn[name].Constructor=plugin;$.fn[name].noConflict=()=>{$.fn[name]=JQUERY_NO_CONFLICT;return plugin.jQueryInterface;};}});};const enableDismissTrigger=(component,method='hide')=>{const clickEvent=`click.dismiss${component.EVENT_KEY}`;const name=component.NAME;EventHandler__default.default.on(document,clickEvent,`[data-bs-dismiss="${name}"]`,function(event){if(['A','AREA'].includes(this.tagName)){event.preventDefault();}
if(isDisabled(this)){return;}
const target=getElementFromSelector(this)||this.closest(`.${name}`);const instance=component.getOrCreateInstance(target);instance[method]();});};const NAME='toast';const DATA_KEY='bs.toast';const EVENT_KEY=`.${DATA_KEY}`;const EVENT_MOUSEOVER=`mouseover${EVENT_KEY}`;const EVENT_MOUSEOUT=`mouseout${EVENT_KEY}`;const EVENT_FOCUSIN=`focusin${EVENT_KEY}`;const EVENT_FOCUSOUT=`focusout${EVENT_KEY}`;const EVENT_HIDE=`hide${EVENT_KEY}`;const EVENT_HIDDEN=`hidden${EVENT_KEY}`;const EVENT_SHOW=`show${EVENT_KEY}`;const EVENT_SHOWN=`shown${EVENT_KEY}`;const CLASS_NAME_FADE='fade';const CLASS_NAME_HIDE='hide';const CLASS_NAME_SHOW='show';const CLASS_NAME_SHOWING='showing';const DefaultType={animation:'boolean',autohide:'boolean',delay:'number'};const Default={animation:true,autohide:true,delay:5000};class Toast extends BaseComponent__default.default{constructor(element,config){super(element);this._config=this._getConfig(config);this._timeout=null;this._hasMouseInteraction=false;this._hasKeyboardInteraction=false;this._setListeners();}
static get DefaultType(){return DefaultType;}
static get Default(){return Default;}
static get NAME(){return NAME;}
show(){const showEvent=EventHandler__default.default.trigger(this._element,EVENT_SHOW);if(showEvent.defaultPrevented){return;}
this._clearTimeout();if(this._config.animation){this._element.classList.add(CLASS_NAME_FADE);}
const complete=()=>{this._element.classList.remove(CLASS_NAME_SHOWING);EventHandler__default.default.trigger(this._element,EVENT_SHOWN);this._maybeScheduleHide();};this._element.classList.remove(CLASS_NAME_HIDE);reflow(this._element);this._element.classList.add(CLASS_NAME_SHOW);this._element.classList.add(CLASS_NAME_SHOWING);this._queueCallback(complete,this._element,this._config.animation);}
hide(){if(!this._element.classList.contains(CLASS_NAME_SHOW)){return;}
const hideEvent=EventHandler__default.default.trigger(this._element,EVENT_HIDE);if(hideEvent.defaultPrevented){return;}
const complete=()=>{this._element.classList.add(CLASS_NAME_HIDE);this._element.classList.remove(CLASS_NAME_SHOWING);this._element.classList.remove(CLASS_NAME_SHOW);EventHandler__default.default.trigger(this._element,EVENT_HIDDEN);};this._element.classList.add(CLASS_NAME_SHOWING);this._queueCallback(complete,this._element,this._config.animation);}
dispose(){this._clearTimeout();if(this._element.classList.contains(CLASS_NAME_SHOW)){this._element.classList.remove(CLASS_NAME_SHOW);}
super.dispose();}
_getConfig(config){config={...Default,...Manipulator__default.default.getDataAttributes(this._element),...(typeof config==='object'&&config?config:{})};typeCheckConfig(NAME,config,this.constructor.DefaultType);return config;}
_maybeScheduleHide(){if(!this._config.autohide){return;}
if(this._hasMouseInteraction||this._hasKeyboardInteraction){return;}
this._timeout=setTimeout(()=>{this.hide();},this._config.delay);}
_onInteraction(event,isInteracting){switch(event.type){case'mouseover':case'mouseout':this._hasMouseInteraction=isInteracting;break;case'focusin':case'focusout':this._hasKeyboardInteraction=isInteracting;break;}
if(isInteracting){this._clearTimeout();return;}
const nextElement=event.relatedTarget;if(this._element===nextElement||this._element.contains(nextElement)){return;}
this._maybeScheduleHide();}
_setListeners(){EventHandler__default.default.on(this._element,EVENT_MOUSEOVER,event=>this._onInteraction(event,true));EventHandler__default.default.on(this._element,EVENT_MOUSEOUT,event=>this._onInteraction(event,false));EventHandler__default.default.on(this._element,EVENT_FOCUSIN,event=>this._onInteraction(event,true));EventHandler__default.default.on(this._element,EVENT_FOCUSOUT,event=>this._onInteraction(event,false));}
_clearTimeout(){clearTimeout(this._timeout);this._timeout=null;}
static jQueryInterface(config){return this.each(function(){const data=Toast.getOrCreateInstance(this,config);if(typeof config==='string'){if(typeof data[config]==='undefined'){throw new TypeError(`No method named "${config}"`);}
data[config](this);}});}}
enableDismissTrigger(Toast);defineJQueryPlugin(Toast);return Toast;}));;

/* /web/static/lib/select2/select2.js */
(function($){if(typeof $.fn.each2=="undefined"){$.extend($.fn,{each2:function(c){var j=$([0]),i=-1,l=this.length;while(++i<l&&(j.context=j[0]=this[i])&&c.call(j[0],i,j)!==false);return this;}});}})(jQuery);(function($,undefined){"use strict";if(window.Select2!==undefined){return;}
var AbstractSelect2,SingleSelect2,MultiSelect2,nextUid,sizer,lastMousePosition={x:0,y:0},$document,scrollBarDimensions,KEY={TAB:9,ENTER:13,ESC:27,SPACE:32,LEFT:37,UP:38,RIGHT:39,DOWN:40,SHIFT:16,CTRL:17,ALT:18,PAGE_UP:33,PAGE_DOWN:34,HOME:36,END:35,BACKSPACE:8,DELETE:46,isArrow:function(k){k=k.which?k.which:k;switch(k){case KEY.LEFT:case KEY.RIGHT:case KEY.UP:case KEY.DOWN:return true;}
return false;},isControl:function(e){var k=e.which;switch(k){case KEY.SHIFT:case KEY.CTRL:case KEY.ALT:return true;}
if(e.metaKey)return true;return false;},isFunctionKey:function(k){k=k.which?k.which:k;return k>=112&&k<=123;}},MEASURE_SCROLLBAR_TEMPLATE="<div class='select2-measure-scrollbar'></div>",DIACRITICS={"\u24B6":"A","\uFF21":"A","\u00C0":"A","\u00C1":"A","\u00C2":"A","\u1EA6":"A","\u1EA4":"A","\u1EAA":"A","\u1EA8":"A","\u00C3":"A","\u0100":"A","\u0102":"A","\u1EB0":"A","\u1EAE":"A","\u1EB4":"A","\u1EB2":"A","\u0226":"A","\u01E0":"A","\u00C4":"A","\u01DE":"A","\u1EA2":"A","\u00C5":"A","\u01FA":"A","\u01CD":"A","\u0200":"A","\u0202":"A","\u1EA0":"A","\u1EAC":"A","\u1EB6":"A","\u1E00":"A","\u0104":"A","\u023A":"A","\u2C6F":"A","\uA732":"AA","\u00C6":"AE","\u01FC":"AE","\u01E2":"AE","\uA734":"AO","\uA736":"AU","\uA738":"AV","\uA73A":"AV","\uA73C":"AY","\u24B7":"B","\uFF22":"B","\u1E02":"B","\u1E04":"B","\u1E06":"B","\u0243":"B","\u0182":"B","\u0181":"B","\u24B8":"C","\uFF23":"C","\u0106":"C","\u0108":"C","\u010A":"C","\u010C":"C","\u00C7":"C","\u1E08":"C","\u0187":"C","\u023B":"C","\uA73E":"C","\u24B9":"D","\uFF24":"D","\u1E0A":"D","\u010E":"D","\u1E0C":"D","\u1E10":"D","\u1E12":"D","\u1E0E":"D","\u0110":"D","\u018B":"D","\u018A":"D","\u0189":"D","\uA779":"D","\u01F1":"DZ","\u01C4":"DZ","\u01F2":"Dz","\u01C5":"Dz","\u24BA":"E","\uFF25":"E","\u00C8":"E","\u00C9":"E","\u00CA":"E","\u1EC0":"E","\u1EBE":"E","\u1EC4":"E","\u1EC2":"E","\u1EBC":"E","\u0112":"E","\u1E14":"E","\u1E16":"E","\u0114":"E","\u0116":"E","\u00CB":"E","\u1EBA":"E","\u011A":"E","\u0204":"E","\u0206":"E","\u1EB8":"E","\u1EC6":"E","\u0228":"E","\u1E1C":"E","\u0118":"E","\u1E18":"E","\u1E1A":"E","\u0190":"E","\u018E":"E","\u24BB":"F","\uFF26":"F","\u1E1E":"F","\u0191":"F","\uA77B":"F","\u24BC":"G","\uFF27":"G","\u01F4":"G","\u011C":"G","\u1E20":"G","\u011E":"G","\u0120":"G","\u01E6":"G","\u0122":"G","\u01E4":"G","\u0193":"G","\uA7A0":"G","\uA77D":"G","\uA77E":"G","\u24BD":"H","\uFF28":"H","\u0124":"H","\u1E22":"H","\u1E26":"H","\u021E":"H","\u1E24":"H","\u1E28":"H","\u1E2A":"H","\u0126":"H","\u2C67":"H","\u2C75":"H","\uA78D":"H","\u24BE":"I","\uFF29":"I","\u00CC":"I","\u00CD":"I","\u00CE":"I","\u0128":"I","\u012A":"I","\u012C":"I","\u0130":"I","\u00CF":"I","\u1E2E":"I","\u1EC8":"I","\u01CF":"I","\u0208":"I","\u020A":"I","\u1ECA":"I","\u012E":"I","\u1E2C":"I","\u0197":"I","\u24BF":"J","\uFF2A":"J","\u0134":"J","\u0248":"J","\u24C0":"K","\uFF2B":"K","\u1E30":"K","\u01E8":"K","\u1E32":"K","\u0136":"K","\u1E34":"K","\u0198":"K","\u2C69":"K","\uA740":"K","\uA742":"K","\uA744":"K","\uA7A2":"K","\u24C1":"L","\uFF2C":"L","\u013F":"L","\u0139":"L","\u013D":"L","\u1E36":"L","\u1E38":"L","\u013B":"L","\u1E3C":"L","\u1E3A":"L","\u0141":"L","\u023D":"L","\u2C62":"L","\u2C60":"L","\uA748":"L","\uA746":"L","\uA780":"L","\u01C7":"LJ","\u01C8":"Lj","\u24C2":"M","\uFF2D":"M","\u1E3E":"M","\u1E40":"M","\u1E42":"M","\u2C6E":"M","\u019C":"M","\u24C3":"N","\uFF2E":"N","\u01F8":"N","\u0143":"N","\u00D1":"N","\u1E44":"N","\u0147":"N","\u1E46":"N","\u0145":"N","\u1E4A":"N","\u1E48":"N","\u0220":"N","\u019D":"N","\uA790":"N","\uA7A4":"N","\u01CA":"NJ","\u01CB":"Nj","\u24C4":"O","\uFF2F":"O","\u00D2":"O","\u00D3":"O","\u00D4":"O","\u1ED2":"O","\u1ED0":"O","\u1ED6":"O","\u1ED4":"O","\u00D5":"O","\u1E4C":"O","\u022C":"O","\u1E4E":"O","\u014C":"O","\u1E50":"O","\u1E52":"O","\u014E":"O","\u022E":"O","\u0230":"O","\u00D6":"O","\u022A":"O","\u1ECE":"O","\u0150":"O","\u01D1":"O","\u020C":"O","\u020E":"O","\u01A0":"O","\u1EDC":"O","\u1EDA":"O","\u1EE0":"O","\u1EDE":"O","\u1EE2":"O","\u1ECC":"O","\u1ED8":"O","\u01EA":"O","\u01EC":"O","\u00D8":"O","\u01FE":"O","\u0186":"O","\u019F":"O","\uA74A":"O","\uA74C":"O","\u01A2":"OI","\uA74E":"OO","\u0222":"OU","\u24C5":"P","\uFF30":"P","\u1E54":"P","\u1E56":"P","\u01A4":"P","\u2C63":"P","\uA750":"P","\uA752":"P","\uA754":"P","\u24C6":"Q","\uFF31":"Q","\uA756":"Q","\uA758":"Q","\u024A":"Q","\u24C7":"R","\uFF32":"R","\u0154":"R","\u1E58":"R","\u0158":"R","\u0210":"R","\u0212":"R","\u1E5A":"R","\u1E5C":"R","\u0156":"R","\u1E5E":"R","\u024C":"R","\u2C64":"R","\uA75A":"R","\uA7A6":"R","\uA782":"R","\u24C8":"S","\uFF33":"S","\u1E9E":"S","\u015A":"S","\u1E64":"S","\u015C":"S","\u1E60":"S","\u0160":"S","\u1E66":"S","\u1E62":"S","\u1E68":"S","\u0218":"S","\u015E":"S","\u2C7E":"S","\uA7A8":"S","\uA784":"S","\u24C9":"T","\uFF34":"T","\u1E6A":"T","\u0164":"T","\u1E6C":"T","\u021A":"T","\u0162":"T","\u1E70":"T","\u1E6E":"T","\u0166":"T","\u01AC":"T","\u01AE":"T","\u023E":"T","\uA786":"T","\uA728":"TZ","\u24CA":"U","\uFF35":"U","\u00D9":"U","\u00DA":"U","\u00DB":"U","\u0168":"U","\u1E78":"U","\u016A":"U","\u1E7A":"U","\u016C":"U","\u00DC":"U","\u01DB":"U","\u01D7":"U","\u01D5":"U","\u01D9":"U","\u1EE6":"U","\u016E":"U","\u0170":"U","\u01D3":"U","\u0214":"U","\u0216":"U","\u01AF":"U","\u1EEA":"U","\u1EE8":"U","\u1EEE":"U","\u1EEC":"U","\u1EF0":"U","\u1EE4":"U","\u1E72":"U","\u0172":"U","\u1E76":"U","\u1E74":"U","\u0244":"U","\u24CB":"V","\uFF36":"V","\u1E7C":"V","\u1E7E":"V","\u01B2":"V","\uA75E":"V","\u0245":"V","\uA760":"VY","\u24CC":"W","\uFF37":"W","\u1E80":"W","\u1E82":"W","\u0174":"W","\u1E86":"W","\u1E84":"W","\u1E88":"W","\u2C72":"W","\u24CD":"X","\uFF38":"X","\u1E8A":"X","\u1E8C":"X","\u24CE":"Y","\uFF39":"Y","\u1EF2":"Y","\u00DD":"Y","\u0176":"Y","\u1EF8":"Y","\u0232":"Y","\u1E8E":"Y","\u0178":"Y","\u1EF6":"Y","\u1EF4":"Y","\u01B3":"Y","\u024E":"Y","\u1EFE":"Y","\u24CF":"Z","\uFF3A":"Z","\u0179":"Z","\u1E90":"Z","\u017B":"Z","\u017D":"Z","\u1E92":"Z","\u1E94":"Z","\u01B5":"Z","\u0224":"Z","\u2C7F":"Z","\u2C6B":"Z","\uA762":"Z","\u24D0":"a","\uFF41":"a","\u1E9A":"a","\u00E0":"a","\u00E1":"a","\u00E2":"a","\u1EA7":"a","\u1EA5":"a","\u1EAB":"a","\u1EA9":"a","\u00E3":"a","\u0101":"a","\u0103":"a","\u1EB1":"a","\u1EAF":"a","\u1EB5":"a","\u1EB3":"a","\u0227":"a","\u01E1":"a","\u00E4":"a","\u01DF":"a","\u1EA3":"a","\u00E5":"a","\u01FB":"a","\u01CE":"a","\u0201":"a","\u0203":"a","\u1EA1":"a","\u1EAD":"a","\u1EB7":"a","\u1E01":"a","\u0105":"a","\u2C65":"a","\u0250":"a","\uA733":"aa","\u00E6":"ae","\u01FD":"ae","\u01E3":"ae","\uA735":"ao","\uA737":"au","\uA739":"av","\uA73B":"av","\uA73D":"ay","\u24D1":"b","\uFF42":"b","\u1E03":"b","\u1E05":"b","\u1E07":"b","\u0180":"b","\u0183":"b","\u0253":"b","\u24D2":"c","\uFF43":"c","\u0107":"c","\u0109":"c","\u010B":"c","\u010D":"c","\u00E7":"c","\u1E09":"c","\u0188":"c","\u023C":"c","\uA73F":"c","\u2184":"c","\u24D3":"d","\uFF44":"d","\u1E0B":"d","\u010F":"d","\u1E0D":"d","\u1E11":"d","\u1E13":"d","\u1E0F":"d","\u0111":"d","\u018C":"d","\u0256":"d","\u0257":"d","\uA77A":"d","\u01F3":"dz","\u01C6":"dz","\u24D4":"e","\uFF45":"e","\u00E8":"e","\u00E9":"e","\u00EA":"e","\u1EC1":"e","\u1EBF":"e","\u1EC5":"e","\u1EC3":"e","\u1EBD":"e","\u0113":"e","\u1E15":"e","\u1E17":"e","\u0115":"e","\u0117":"e","\u00EB":"e","\u1EBB":"e","\u011B":"e","\u0205":"e","\u0207":"e","\u1EB9":"e","\u1EC7":"e","\u0229":"e","\u1E1D":"e","\u0119":"e","\u1E19":"e","\u1E1B":"e","\u0247":"e","\u025B":"e","\u01DD":"e","\u24D5":"f","\uFF46":"f","\u1E1F":"f","\u0192":"f","\uA77C":"f","\u24D6":"g","\uFF47":"g","\u01F5":"g","\u011D":"g","\u1E21":"g","\u011F":"g","\u0121":"g","\u01E7":"g","\u0123":"g","\u01E5":"g","\u0260":"g","\uA7A1":"g","\u1D79":"g","\uA77F":"g","\u24D7":"h","\uFF48":"h","\u0125":"h","\u1E23":"h","\u1E27":"h","\u021F":"h","\u1E25":"h","\u1E29":"h","\u1E2B":"h","\u1E96":"h","\u0127":"h","\u2C68":"h","\u2C76":"h","\u0265":"h","\u0195":"hv","\u24D8":"i","\uFF49":"i","\u00EC":"i","\u00ED":"i","\u00EE":"i","\u0129":"i","\u012B":"i","\u012D":"i","\u00EF":"i","\u1E2F":"i","\u1EC9":"i","\u01D0":"i","\u0209":"i","\u020B":"i","\u1ECB":"i","\u012F":"i","\u1E2D":"i","\u0268":"i","\u0131":"i","\u24D9":"j","\uFF4A":"j","\u0135":"j","\u01F0":"j","\u0249":"j","\u24DA":"k","\uFF4B":"k","\u1E31":"k","\u01E9":"k","\u1E33":"k","\u0137":"k","\u1E35":"k","\u0199":"k","\u2C6A":"k","\uA741":"k","\uA743":"k","\uA745":"k","\uA7A3":"k","\u24DB":"l","\uFF4C":"l","\u0140":"l","\u013A":"l","\u013E":"l","\u1E37":"l","\u1E39":"l","\u013C":"l","\u1E3D":"l","\u1E3B":"l","\u017F":"l","\u0142":"l","\u019A":"l","\u026B":"l","\u2C61":"l","\uA749":"l","\uA781":"l","\uA747":"l","\u01C9":"lj","\u24DC":"m","\uFF4D":"m","\u1E3F":"m","\u1E41":"m","\u1E43":"m","\u0271":"m","\u026F":"m","\u24DD":"n","\uFF4E":"n","\u01F9":"n","\u0144":"n","\u00F1":"n","\u1E45":"n","\u0148":"n","\u1E47":"n","\u0146":"n","\u1E4B":"n","\u1E49":"n","\u019E":"n","\u0272":"n","\u0149":"n","\uA791":"n","\uA7A5":"n","\u01CC":"nj","\u24DE":"o","\uFF4F":"o","\u00F2":"o","\u00F3":"o","\u00F4":"o","\u1ED3":"o","\u1ED1":"o","\u1ED7":"o","\u1ED5":"o","\u00F5":"o","\u1E4D":"o","\u022D":"o","\u1E4F":"o","\u014D":"o","\u1E51":"o","\u1E53":"o","\u014F":"o","\u022F":"o","\u0231":"o","\u00F6":"o","\u022B":"o","\u1ECF":"o","\u0151":"o","\u01D2":"o","\u020D":"o","\u020F":"o","\u01A1":"o","\u1EDD":"o","\u1EDB":"o","\u1EE1":"o","\u1EDF":"o","\u1EE3":"o","\u1ECD":"o","\u1ED9":"o","\u01EB":"o","\u01ED":"o","\u00F8":"o","\u01FF":"o","\u0254":"o","\uA74B":"o","\uA74D":"o","\u0275":"o","\u01A3":"oi","\u0223":"ou","\uA74F":"oo","\u24DF":"p","\uFF50":"p","\u1E55":"p","\u1E57":"p","\u01A5":"p","\u1D7D":"p","\uA751":"p","\uA753":"p","\uA755":"p","\u24E0":"q","\uFF51":"q","\u024B":"q","\uA757":"q","\uA759":"q","\u24E1":"r","\uFF52":"r","\u0155":"r","\u1E59":"r","\u0159":"r","\u0211":"r","\u0213":"r","\u1E5B":"r","\u1E5D":"r","\u0157":"r","\u1E5F":"r","\u024D":"r","\u027D":"r","\uA75B":"r","\uA7A7":"r","\uA783":"r","\u24E2":"s","\uFF53":"s","\u00DF":"s","\u015B":"s","\u1E65":"s","\u015D":"s","\u1E61":"s","\u0161":"s","\u1E67":"s","\u1E63":"s","\u1E69":"s","\u0219":"s","\u015F":"s","\u023F":"s","\uA7A9":"s","\uA785":"s","\u1E9B":"s","\u24E3":"t","\uFF54":"t","\u1E6B":"t","\u1E97":"t","\u0165":"t","\u1E6D":"t","\u021B":"t","\u0163":"t","\u1E71":"t","\u1E6F":"t","\u0167":"t","\u01AD":"t","\u0288":"t","\u2C66":"t","\uA787":"t","\uA729":"tz","\u24E4":"u","\uFF55":"u","\u00F9":"u","\u00FA":"u","\u00FB":"u","\u0169":"u","\u1E79":"u","\u016B":"u","\u1E7B":"u","\u016D":"u","\u00FC":"u","\u01DC":"u","\u01D8":"u","\u01D6":"u","\u01DA":"u","\u1EE7":"u","\u016F":"u","\u0171":"u","\u01D4":"u","\u0215":"u","\u0217":"u","\u01B0":"u","\u1EEB":"u","\u1EE9":"u","\u1EEF":"u","\u1EED":"u","\u1EF1":"u","\u1EE5":"u","\u1E73":"u","\u0173":"u","\u1E77":"u","\u1E75":"u","\u0289":"u","\u24E5":"v","\uFF56":"v","\u1E7D":"v","\u1E7F":"v","\u028B":"v","\uA75F":"v","\u028C":"v","\uA761":"vy","\u24E6":"w","\uFF57":"w","\u1E81":"w","\u1E83":"w","\u0175":"w","\u1E87":"w","\u1E85":"w","\u1E98":"w","\u1E89":"w","\u2C73":"w","\u24E7":"x","\uFF58":"x","\u1E8B":"x","\u1E8D":"x","\u24E8":"y","\uFF59":"y","\u1EF3":"y","\u00FD":"y","\u0177":"y","\u1EF9":"y","\u0233":"y","\u1E8F":"y","\u00FF":"y","\u1EF7":"y","\u1E99":"y","\u1EF5":"y","\u01B4":"y","\u024F":"y","\u1EFF":"y","\u24E9":"z","\uFF5A":"z","\u017A":"z","\u1E91":"z","\u017C":"z","\u017E":"z","\u1E93":"z","\u1E95":"z","\u01B6":"z","\u0225":"z","\u0240":"z","\u2C6C":"z","\uA763":"z","\u0386":"\u0391","\u0388":"\u0395","\u0389":"\u0397","\u038A":"\u0399","\u03AA":"\u0399","\u038C":"\u039F","\u038E":"\u03A5","\u03AB":"\u03A5","\u038F":"\u03A9","\u03AC":"\u03B1","\u03AD":"\u03B5","\u03AE":"\u03B7","\u03AF":"\u03B9","\u03CA":"\u03B9","\u0390":"\u03B9","\u03CC":"\u03BF","\u03CD":"\u03C5","\u03CB":"\u03C5","\u03B0":"\u03C5","\u03C9":"\u03C9","\u03C2":"\u03C3"};$document=$(document);nextUid=(function(){var counter=1;return function(){return counter++;};}());function reinsertElement(element){var placeholder=$(document.createTextNode(''));element.before(placeholder);placeholder.before(element);placeholder.remove();}
function stripDiacritics(str){function match(a){return DIACRITICS[a]||a;}
return str.replace(/[^\u0000-\u007E]/g,match);}
function indexOf(value,array){var i=0,l=array.length;for(;i<l;i=i+1){if(equal(value,array[i]))return i;}
return-1;}
function measureScrollbar(){var $template=$(MEASURE_SCROLLBAR_TEMPLATE);$template.appendTo(document.body);var dim={width:$template.width()-$template[0].clientWidth,height:$template.height()-$template[0].clientHeight};$template.remove();return dim;}
function equal(a,b){if(a===b)return true;if(a===undefined||b===undefined)return false;if(a===null||b===null)return false;if(a.constructor===String)return a+''===b+'';if(b.constructor===String)return b+''===a+'';return false;}
function splitVal(string,separator,transform){var val,i,l;if(string===null||string.length<1)return[];val=string.split(separator);for(i=0,l=val.length;i<l;i=i+1)val[i]=transform(val[i]);return val;}
function getSideBorderPadding(element){return element.outerWidth(false)-element.width();}
function installKeyUpChangeEvent(element){var key="keyup-change-value";element.on("keydown",function(){if($.data(element,key)===undefined){$.data(element,key,element.val());}});element.on("keyup",function(){var val=$.data(element,key);if(val!==undefined&&element.val()!==val){$.removeData(element,key);element.trigger("keyup-change");}});}
function installFilteredMouseMove(element){element.on("mousemove",function(e){var lastpos=lastMousePosition;if(lastpos===undefined||lastpos.x!==e.pageX||lastpos.y!==e.pageY){$(e.target).trigger("mousemove-filtered",e);}});}
function debounce(quietMillis,fn,ctx){ctx=ctx||undefined;var timeout;return function(){var args=arguments;window.clearTimeout(timeout);timeout=window.setTimeout(function(){fn.apply(ctx,args);},quietMillis);};}
function installDebouncedScroll(threshold,element){var notify=debounce(threshold,function(e){element.trigger("scroll-debounced",e);});element.on("scroll",function(e){if(indexOf(e.target,element.get())>=0)notify(e);});}
function focus($el){if($el[0]===document.activeElement)return;window.setTimeout(function(){var el=$el[0],pos=$el.val().length,range;$el.focus();var isVisible=(el.offsetWidth>0||el.offsetHeight>0);if(isVisible&&el===document.activeElement){if(el.setSelectionRange)
{el.setSelectionRange(pos,pos);}
else if(el.createTextRange){range=el.createTextRange();range.collapse(false);range.select();}}},0);}
function getCursorInfo(el){el=$(el)[0];var offset=0;var length=0;if('selectionStart'in el){offset=el.selectionStart;length=el.selectionEnd-offset;}else if('selection'in document){el.focus();var sel=document.selection.createRange();length=document.selection.createRange().text.length;sel.moveStart('character',-el.value.length);offset=sel.text.length-length;}
return{offset:offset,length:length};}
function killEvent(event){event.preventDefault();event.stopPropagation();}
function killEventImmediately(event){event.preventDefault();event.stopImmediatePropagation();}
function measureTextWidth(e){if(!sizer){var style=e[0].currentStyle||window.getComputedStyle(e[0],null);sizer=$(document.createElement("div")).css({position:"absolute",left:"-10000px",top:"-10000px",display:"none",fontSize:style.fontSize,fontFamily:style.fontFamily,fontStyle:style.fontStyle,fontWeight:style.fontWeight,letterSpacing:style.letterSpacing,textTransform:style.textTransform,whiteSpace:"nowrap"});sizer.attr("class","select2-sizer");$(document.body).append(sizer);}
sizer.text(e.val());return sizer.width();}
function syncCssClasses(dest,src,adapter){var classes,replacements=[],adapted;classes=$.trim(dest.attr("class"));if(classes){classes=''+classes;$(classes.split(/\s+/)).each2(function(){if(this.indexOf("select2-")===0){replacements.push(this);}});}
classes=$.trim(src.attr("class"));if(classes){classes=''+classes;$(classes.split(/\s+/)).each2(function(){if(this.indexOf("select2-")!==0){adapted=adapter(this);if(adapted){replacements.push(adapted);}}});}
dest.attr("class",replacements.join(" "));}
function markMatch(text,term,markup,escapeMarkup){var match=stripDiacritics(text.toUpperCase()).indexOf(stripDiacritics(term.toUpperCase())),tl=term.length;if(match<0){markup.push(escapeMarkup(text));return;}
markup.push(escapeMarkup(text.substring(0,match)));markup.push("<span class='select2-match'>");markup.push(escapeMarkup(text.substring(match,match+tl)));markup.push("</span>");markup.push(escapeMarkup(text.substring(match+tl,text.length)));}
function defaultEscapeMarkup(markup){var replace_map={'\\':'&#92;','&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;',"/":'&#47;'};return String(markup).replace(/[&<>"'\/\\]/g,function(match){return replace_map[match];});}
function ajax(options){var timeout,handler=null,quietMillis=options.quietMillis||100,ajaxUrl=options.url,self=this;return function(query){window.clearTimeout(timeout);timeout=window.setTimeout(function(){var data=options.data,url=ajaxUrl,transport=options.transport||$.fn.select2.ajaxDefaults.transport,deprecated={type:options.type||'GET',cache:options.cache||false,jsonpCallback:options.jsonpCallback||undefined,dataType:options.dataType||"json"},params=$.extend({},$.fn.select2.ajaxDefaults.params,deprecated);data=data?data.call(self,query.term,query.page,query.context):null;url=(typeof url==='function')?url.call(self,query.term,query.page,query.context):url;if(handler&&typeof handler.abort==="function"){handler.abort();}
if(options.params){if($.isFunction(options.params)){$.extend(params,options.params.call(self));}else{$.extend(params,options.params);}}
$.extend(params,{url:url,dataType:options.dataType,data:data,success:function(data){var results=options.results(data,query.page,query);query.callback(results);},error:function(jqXHR,textStatus,errorThrown){var results={hasError:true,jqXHR:jqXHR,textStatus:textStatus,errorThrown:errorThrown};query.callback(results);}});handler=transport.call(self,params);},quietMillis);};}
function local(options){var data=options,dataText,tmp,text=function(item){return""+item.text;};if($.isArray(data)){tmp=data;data={results:tmp};}
if($.isFunction(data)===false){tmp=data;data=function(){return tmp;};}
var dataItem=data();if(dataItem.text){text=dataItem.text;if(!$.isFunction(text)){dataText=dataItem.text;text=function(item){return item[dataText];};}}
return function(query){var t=query.term,filtered={results:[]},process;if(t===""){query.callback(data());return;}
process=function(datum,collection){var group,attr;datum=datum[0];if(datum.children){group={};for(attr in datum){if(datum.hasOwnProperty(attr))group[attr]=datum[attr];}
group.children=[];$(datum.children).each2(function(i,childDatum){process(childDatum,group.children);});if(group.children.length||query.matcher(t,text(group),datum)){collection.push(group);}}else{if(query.matcher(t,text(datum),datum)){collection.push(datum);}}};$(data().results).each2(function(i,datum){process(datum,filtered.results);});query.callback(filtered);};}
function tags(data){var isFunc=$.isFunction(data);return function(query){var t=query.term,filtered={results:[]};var result=isFunc?data(query):data;if($.isArray(result)){$(result).each(function(){var isObject=this.text!==undefined,text=isObject?this.text:this;if(t===""||query.matcher(t,text)){filtered.results.push(isObject?this:{id:this,text:this});}});query.callback(filtered);}};}
function checkFormatter(formatter,formatterName){if($.isFunction(formatter))return true;if(!formatter)return false;if(typeof(formatter)==='string')return true;throw new Error(formatterName+" must be a string, function, or falsy value");}
function evaluate(val,context){if($.isFunction(val)){var args=Array.prototype.slice.call(arguments,2);return val.apply(context,args);}
return val;}
function countResults(results){var count=0;$.each(results,function(i,item){if(item.children){count+=countResults(item.children);}else{count++;}});return count;}
function defaultTokenizer(input,selection,selectCallback,opts){var original=input,dupe=false,token,index,i,l,separator;if(!opts.createSearchChoice||!opts.tokenSeparators||opts.tokenSeparators.length<1)return undefined;while(true){index=-1;for(i=0,l=opts.tokenSeparators.length;i<l;i++){separator=opts.tokenSeparators[i];index=input.indexOf(separator);if(index>=0)break;}
if(index<0)break;token=input.substring(0,index);input=input.substring(index+separator.length);if(token.length>0){token=opts.createSearchChoice.call(this,token,selection);if(token!==undefined&&token!==null&&opts.id(token)!==undefined&&opts.id(token)!==null){dupe=false;for(i=0,l=selection.length;i<l;i++){if(equal(opts.id(token),opts.id(selection[i]))){dupe=true;break;}}
if(!dupe)selectCallback(token);}}}
if(original!==input)return input;}
function cleanupJQueryElements(){var self=this;$.each(arguments,function(i,element){self[element].remove();self[element]=null;});}
function clazz(SuperClass,methods){var constructor=function(){};constructor.prototype=new SuperClass;constructor.prototype.constructor=constructor;constructor.prototype.parent=SuperClass.prototype;constructor.prototype=$.extend(constructor.prototype,methods);return constructor;}
AbstractSelect2=clazz(Object,{bind:function(func){var self=this;return function(){func.apply(self,arguments);};},init:function(opts){var results,search,resultsSelector=".select2-results";this.opts=opts=this.prepareOpts(opts);this.id=opts.id;if(opts.element.data("select2")!==undefined&&opts.element.data("select2")!==null){opts.element.data("select2").destroy();}
this.container=this.createContainer();this.liveRegion=$('.select2-hidden-accessible');if(this.liveRegion.length==0){this.liveRegion=$("<span>",{role:"status","aria-live":"polite"}).addClass("select2-hidden-accessible").appendTo(document.body);}
this.containerId="s2id_"+(opts.element.attr("id")||"autogen"+nextUid());this.containerEventName=this.containerId.replace(/([.])/g,'_').replace(/([;&,\-\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g,'\\$1');this.container.attr("id",this.containerId);this.container.attr("title",opts.element.attr("title"));this.body=$(document.body);syncCssClasses(this.container,this.opts.element,this.opts.adaptContainerCssClass);this.container.attr("style",opts.element.attr("style"));this.container.css(evaluate(opts.containerCss,this.opts.element));this.container.addClass(evaluate(opts.containerCssClass,this.opts.element));this.elementTabIndex=this.opts.element.attr("tabindex");this.opts.element.data("select2",this).attr("tabindex","-1").before(this.container).on("click.select2",killEvent);this.container.data("select2",this);this.dropdown=this.container.find(".select2-drop");syncCssClasses(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass);this.dropdown.addClass(evaluate(opts.dropdownCssClass,this.opts.element));this.dropdown.data("select2",this);this.dropdown.on("click",killEvent);this.results=results=this.container.find(resultsSelector);this.search=search=this.container.find("input.select2-input");this.queryCount=0;this.resultsPage=0;this.context=null;this.initContainer();this.container.on("click",killEvent);installFilteredMouseMove(this.results);this.dropdown.on("mousemove-filtered",resultsSelector,this.bind(this.highlightUnderEvent));this.dropdown.on("touchstart touchmove touchend",resultsSelector,this.bind(function(event){this._touchEvent=true;this.highlightUnderEvent(event);}));this.dropdown.on("touchmove",resultsSelector,this.bind(this.touchMoved));this.dropdown.on("touchstart touchend",resultsSelector,this.bind(this.clearTouchMoved));this.dropdown.on('click',this.bind(function(event){if(this._touchEvent){this._touchEvent=false;this.selectHighlighted();}}));installDebouncedScroll(80,this.results);this.dropdown.on("scroll-debounced",resultsSelector,this.bind(this.loadMoreIfNeeded));$(this.container).on("change",".select2-input",function(e){e.stopPropagation();});$(this.dropdown).on("change",".select2-input",function(e){e.stopPropagation();});if($.fn.mousewheel){results.mousewheel(function(e,delta,deltaX,deltaY){var top=results.scrollTop();if(deltaY>0&&top-deltaY<=0){results.scrollTop(0);killEvent(e);}else if(deltaY<0&&results.get(0).scrollHeight-results.scrollTop()+deltaY<=results.height()){results.scrollTop(results.get(0).scrollHeight-results.height());killEvent(e);}});}
installKeyUpChangeEvent(search);search.on("keyup-change input paste",this.bind(this.updateResults));search.on("focus",function(){search.addClass("select2-focused");});search.on("blur",function(){search.removeClass("select2-focused");});this.dropdown.on("mouseup",resultsSelector,this.bind(function(e){if($(e.target).closest(".select2-result-selectable").length>0){this.highlightUnderEvent(e);this.selectHighlighted(e);}}));this.dropdown.on("click mouseup mousedown touchstart touchend focusin",function(e){e.stopPropagation();});this.lastSearchTerm=undefined;if($.isFunction(this.opts.initSelection)){this.initSelection();this.monitorSource();}
if(opts.maximumInputLength!==null){this.search.attr("maxlength",opts.maximumInputLength);}
var disabled=opts.element.prop("disabled");if(disabled===undefined)disabled=false;this.enable(!disabled);var readonly=opts.element.prop("readonly");if(readonly===undefined)readonly=false;this.readonly(readonly);scrollBarDimensions=scrollBarDimensions||measureScrollbar();this.autofocus=opts.element.prop("autofocus");opts.element.prop("autofocus",false);if(this.autofocus)this.focus();this.search.attr("placeholder",opts.searchInputPlaceholder);},destroy:function(){var element=this.opts.element,select2=element.data("select2"),self=this;this.close();if(element.length&&element[0].detachEvent&&self._sync){element.each(function(){if(self._sync){this.detachEvent("onpropertychange",self._sync);}});}
if(this.propertyObserver){this.propertyObserver.disconnect();this.propertyObserver=null;}
this._sync=null;if(select2!==undefined){select2.container.remove();select2.liveRegion.remove();select2.dropdown.remove();element.removeData("select2").off(".select2");if(!element.is("input[type='hidden']")){element.show().prop("autofocus",this.autofocus||false);if(this.elementTabIndex){element.attr({tabindex:this.elementTabIndex});}else{element.removeAttr("tabindex");}
element.show();}else{element.css("display","");}}
cleanupJQueryElements.call(this,"container","liveRegion","dropdown","results","search");},optionToData:function(element){if(element.is("option")){return{id:element.prop("value"),text:element.text(),element:element.get(),css:element.attr("class"),disabled:element.prop("disabled"),locked:equal(element.attr("locked"),"locked")||equal(element.data("locked"),true)};}else if(element.is("optgroup")){return{text:element.attr("label"),children:[],element:element.get(),css:element.attr("class")};}},prepareOpts:function(opts){var element,select,idKey,ajaxUrl,self=this;element=opts.element;if(element.get(0).tagName.toLowerCase()==="select"){this.select=select=opts.element;}
if(select){$.each(["id","multiple","ajax","query","createSearchChoice","initSelection","data","tags"],function(){if(this in opts){throw new Error("Option '"+this+"' is not allowed for Select2 when attached to a <select> element.");}});}
opts.debug=opts.debug||$.fn.select2.defaults.debug;if(opts.debug&&console&&console.warn){if(opts.id!=null){console.warn('Select2: The `id` option has been removed in Select2 4.0.0, '+'consider renaming your `id` property or mapping the property before your data makes it to Select2. '+'You can read more at https://select2.github.io/announcements-4.0.html#changed-id');}
if(opts.text!=null){console.warn('Select2: The `text` option has been removed in Select2 4.0.0, '+'consider renaming your `text` property or mapping the property before your data makes it to Select2. '+'You can read more at https://select2.github.io/announcements-4.0.html#changed-id');}
if(opts.sortResults!=null){console.warn('Select2: the `sortResults` option has been renamed to `sorter` in Select2 4.0.0. ');}
if(opts.selectOnBlur!=null){console.warn('Select2: The `selectOnBlur` option has been renamed to `selectOnClose` in Select2 4.0.0.');}
if(opts.ajax!=null&&opts.ajax.results!=null){console.warn('Select2: The `ajax.results` option has been renamed to `ajax.processResults` in Select2 4.0.0.');}
if(opts.formatNoResults!=null){console.warn('Select2: The `formatNoResults` option has been renamed to `language.noResults` in Select2 4.0.0.');}
if(opts.formatSearching!=null){console.warn('Select2: The `formatSearching` option has been renamed to `language.searching` in Select2 4.0.0.');}
if(opts.formatInputTooShort!=null){console.warn('Select2: The `formatInputTooShort` option has been renamed to `language.inputTooShort` in Select2 4.0.0.');}
if(opts.formatInputTooLong!=null){console.warn('Select2: The `formatInputTooLong` option has been renamed to `language.inputTooLong` in Select2 4.0.0.');}
if(opts.formatLoading!=null){console.warn('Select2: The `formatLoading` option has been renamed to `language.loadingMore` in Select2 4.0.0.');}
if(opts.formatSelectionTooBig!=null){console.warn('Select2: The `formatSelectionTooBig` option has been renamed to `language.maximumSelected` in Select2 4.0.0.');}
if(opts.element.data('select2Tags')){console.warn('Select2: The `data-select2-tags` attribute has been renamed to `data-tags` in Select2 4.0.0.');}}
if(opts.element.data('tags')!=null){var elemTags=opts.element.data('tags');if(!$.isArray(elemTags)){elemTags=[];}
opts.element.data('select2Tags',elemTags);}
if(opts.sorter!=null){opts.sortResults=opts.sorter;}
if(opts.selectOnClose!=null){opts.selectOnBlur=opts.selectOnClose;}
if(opts.ajax!=null){if($.isFunction(opts.ajax.processResults)){opts.ajax.results=opts.ajax.processResults;}}
if(opts.language!=null){var lang=opts.language;if($.isFunction(lang.noMatches)){opts.formatNoMatches=lang.noMatches;}
if($.isFunction(lang.searching)){opts.formatSearching=lang.searching;}
if($.isFunction(lang.inputTooShort)){opts.formatInputTooShort=lang.inputTooShort;}
if($.isFunction(lang.inputTooLong)){opts.formatInputTooLong=lang.inputTooLong;}
if($.isFunction(lang.loadingMore)){opts.formatLoading=lang.loadingMore;}
if($.isFunction(lang.maximumSelected)){opts.formatSelectionTooBig=lang.maximumSelected;}}
opts=$.extend({},{populateResults:function(container,results,query){var populate,id=this.opts.id,liveRegion=this.liveRegion;populate=function(results,container,depth){var i,l,result,selectable,disabled,compound,node,label,innerContainer,formatted;results=opts.sortResults(results,container,query);var nodes=[];for(i=0,l=results.length;i<l;i=i+1){result=results[i];disabled=(result.disabled===true);selectable=(!disabled)&&(id(result)!==undefined);compound=result.children&&result.children.length>0;node=$("<li></li>");node.addClass("select2-results-dept-"+depth);node.addClass("select2-result");node.addClass(selectable?"select2-result-selectable":"select2-result-unselectable");if(disabled){node.addClass("select2-disabled");}
if(compound){node.addClass("select2-result-with-children");}
node.addClass(self.opts.formatResultCssClass(result));node.attr("role","presentation");label=$(document.createElement("div"));label.addClass("select2-result-label");label.attr("id","select2-result-label-"+nextUid());label.attr("role","option");formatted=opts.formatResult(result,label,query,self.opts.escapeMarkup);if(formatted!==undefined){label.html(formatted);node.append(label);}
if(compound){innerContainer=$("<ul></ul>");innerContainer.addClass("select2-result-sub");populate(result.children,innerContainer,depth+1);node.append(innerContainer);}
node.data("select2-data",result);nodes.push(node[0]);}
container.append(nodes);liveRegion.text(opts.formatMatches(results.length));};populate(results,container,0);}},$.fn.select2.defaults,opts);if(typeof(opts.id)!=="function"){idKey=opts.id;opts.id=function(e){return e[idKey];};}
if($.isArray(opts.element.data("select2Tags"))){if("tags"in opts){throw"tags specified as both an attribute 'data-select2-tags' and in options of Select2 "+opts.element.attr("id");}
opts.tags=opts.element.data("select2Tags");}
if(select){opts.query=this.bind(function(query){var data={results:[],more:false},term=query.term,children,placeholderOption,process;process=function(element,collection){var group;if(element.is("option")){if(query.matcher(term,element.text(),element)){collection.push(self.optionToData(element));}}else if(element.is("optgroup")){group=self.optionToData(element);element.children().each2(function(i,elm){process(elm,group.children);});if(group.children.length>0){collection.push(group);}}};children=element.children();if(this.getPlaceholder()!==undefined&&children.length>0){placeholderOption=this.getPlaceholderOption();if(placeholderOption){children=children.not(placeholderOption);}}
children.each2(function(i,elm){process(elm,data.results);});query.callback(data);});opts.id=function(e){return e.id;};}else{if(!("query"in opts)){if("ajax"in opts){ajaxUrl=opts.element.data("ajax-url");if(ajaxUrl&&ajaxUrl.length>0){opts.ajax.url=ajaxUrl;}
opts.query=ajax.call(opts.element,opts.ajax);}else if("data"in opts){opts.query=local(opts.data);}else if("tags"in opts){opts.query=tags(opts.tags);if(opts.createSearchChoice===undefined){opts.createSearchChoice=function(term){return{id:$.trim(term),text:$.trim(term)};};}
if(opts.initSelection===undefined){opts.initSelection=function(element,callback){var data=[];$(splitVal(element.val(),opts.separator,opts.transformVal)).each(function(){var obj={id:this,text:this},tags=opts.tags;if($.isFunction(tags))tags=tags();$(tags).each(function(){if(equal(this.id,obj.id)){obj=this;return false;}});data.push(obj);});callback(data);};}}}}
if(typeof(opts.query)!=="function"){throw"query function not defined for Select2 "+opts.element.attr("id");}
if(opts.createSearchChoicePosition==='top'){opts.createSearchChoicePosition=function(list,item){list.unshift(item);};}
else if(opts.createSearchChoicePosition==='bottom'){opts.createSearchChoicePosition=function(list,item){list.push(item);};}
else if(typeof(opts.createSearchChoicePosition)!=="function"){throw"invalid createSearchChoicePosition option must be 'top', 'bottom' or a custom function";}
return opts;},monitorSource:function(){var el=this.opts.element,observer,self=this;el.on("change.select2",this.bind(function(e){if(this.opts.element.data("select2-change-triggered")!==true){this.initSelection();}}));this._sync=this.bind(function(){var disabled=el.prop("disabled");if(disabled===undefined)disabled=false;this.enable(!disabled);var readonly=el.prop("readonly");if(readonly===undefined)readonly=false;this.readonly(readonly);if(this.container){syncCssClasses(this.container,this.opts.element,this.opts.adaptContainerCssClass);this.container.addClass(evaluate(this.opts.containerCssClass,this.opts.element));}
if(this.dropdown){syncCssClasses(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass);this.dropdown.addClass(evaluate(this.opts.dropdownCssClass,this.opts.element));}});if(el.length&&el[0].attachEvent){el.each(function(){this.attachEvent("onpropertychange",self._sync);});}
observer=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;if(observer!==undefined){if(this.propertyObserver){delete this.propertyObserver;this.propertyObserver=null;}
this.propertyObserver=new observer(function(mutations){$.each(mutations,self._sync);});this.propertyObserver.observe(el.get(0),{attributes:true,subtree:false});}},triggerSelect:function(data){var evt=$.Event("select2-selecting",{val:this.id(data),object:data,choice:data});this.opts.element.trigger(evt);return!evt.isDefaultPrevented();},triggerChange:function(details){details=details||{};details=$.extend({},details,{type:"change",val:this.val()});this.opts.element.data("select2-change-triggered",true);this.opts.element.trigger(details);this.opts.element.data("select2-change-triggered",false);this.opts.element.click();if(this.opts.blurOnChange)
this.opts.element.blur();},isInterfaceEnabled:function()
{return this.enabledInterface===true;},enableInterface:function(){var enabled=this._enabled&&!this._readonly,disabled=!enabled;if(enabled===this.enabledInterface)return false;this.container.toggleClass("select2-container-disabled",disabled);this.close();this.enabledInterface=enabled;return true;},enable:function(enabled){if(enabled===undefined)enabled=true;if(this._enabled===enabled)return;this._enabled=enabled;this.opts.element.prop("disabled",!enabled);this.enableInterface();},disable:function(){this.enable(false);},readonly:function(enabled){if(enabled===undefined)enabled=false;if(this._readonly===enabled)return;this._readonly=enabled;this.opts.element.prop("readonly",enabled);this.enableInterface();},opened:function(){return(this.container)?this.container.hasClass("select2-dropdown-open"):false;},positionDropdown:function(){var $dropdown=this.dropdown,container=this.container,offset=container.offset(),height=container.outerHeight(false),width=container.outerWidth(false),dropHeight=$dropdown.outerHeight(false),$window=$(window),windowWidth=$window.width(),windowHeight=$window.height(),viewPortRight=$window.scrollLeft()+windowWidth,viewportBottom=$window.scrollTop()+windowHeight,dropTop=offset.top+height,dropLeft=offset.left,enoughRoomBelow=dropTop+dropHeight<=viewportBottom,enoughRoomAbove=(offset.top-dropHeight)>=$window.scrollTop(),dropWidth=$dropdown.outerWidth(false),enoughRoomOnRight=function(){return dropLeft+dropWidth<=viewPortRight;},enoughRoomOnLeft=function(){return offset.left+viewPortRight+container.outerWidth(false)>dropWidth;},aboveNow=$dropdown.hasClass("select2-drop-above"),bodyOffset,above,changeDirection,css,resultsListNode;if(aboveNow){above=true;if(!enoughRoomAbove&&enoughRoomBelow){changeDirection=true;above=false;}}else{above=false;if(!enoughRoomBelow&&enoughRoomAbove){changeDirection=true;above=true;}}
if(changeDirection){$dropdown.hide();offset=this.container.offset();height=this.container.outerHeight(false);width=this.container.outerWidth(false);dropHeight=$dropdown.outerHeight(false);viewPortRight=$window.scrollLeft()+windowWidth;viewportBottom=$window.scrollTop()+windowHeight;dropTop=offset.top+height;dropLeft=offset.left;dropWidth=$dropdown.outerWidth(false);$dropdown.show();this.focusSearch();}
if(this.opts.dropdownAutoWidth){resultsListNode=$('.select2-results',$dropdown)[0];$dropdown.addClass('select2-drop-auto-width');$dropdown.css('width','');dropWidth=$dropdown.outerWidth(false)+(resultsListNode.scrollHeight===resultsListNode.clientHeight?0:scrollBarDimensions.width);dropWidth>width?width=dropWidth:dropWidth=width;dropHeight=$dropdown.outerHeight(false);}
else{this.container.removeClass('select2-drop-auto-width');}
if(this.body.css('position')!=='static'){bodyOffset=this.body.offset();dropTop-=bodyOffset.top;dropLeft-=bodyOffset.left;}
if(!enoughRoomOnRight()&&enoughRoomOnLeft()){dropLeft=offset.left+this.container.outerWidth(false)-dropWidth;}
css={left:dropLeft,width:width};if(above){this.container.addClass("select2-drop-above");$dropdown.addClass("select2-drop-above");dropHeight=$dropdown.outerHeight(false);css.top=offset.top-dropHeight;css.bottom='auto';}
else{css.top=dropTop;css.bottom='auto';this.container.removeClass("select2-drop-above");$dropdown.removeClass("select2-drop-above");}
css=$.extend(css,evaluate(this.opts.dropdownCss,this.opts.element));$dropdown.css(css);},shouldOpen:function(){var event;if(this.opened())return false;if(this._enabled===false||this._readonly===true)return false;event=$.Event("select2-opening");this.opts.element.trigger(event);return!event.isDefaultPrevented();},clearDropdownAlignmentPreference:function(){this.container.removeClass("select2-drop-above");this.dropdown.removeClass("select2-drop-above");},open:function(){if(!this.shouldOpen())return false;this.opening();$document.on("mousemove.select2Event",function(e){lastMousePosition.x=e.pageX;lastMousePosition.y=e.pageY;});return true;},opening:function(){var cid=this.containerEventName,scroll="scroll."+cid,resize="resize."+cid,orient="orientationchange."+cid,mask;this.container.addClass("select2-dropdown-open").addClass("select2-container-active");this.clearDropdownAlignmentPreference();if(this.dropdown[0]!==this.body.children().last()[0]){this.dropdown.detach().appendTo(this.body);}
mask=$("#select2-drop-mask");if(mask.length===0){mask=$(document.createElement("div"));mask.attr("id","select2-drop-mask").attr("class","select2-drop-mask");mask.hide();mask.appendTo(this.body);mask.on("mousedown touchstart click",function(e){reinsertElement(mask);var dropdown=$("#select2-drop"),self;if(dropdown.length>0){self=dropdown.data("select2");if(self.opts.selectOnBlur){self.selectHighlighted({noFocus:true});}
self.close();e.preventDefault();e.stopPropagation();}});}
if(this.dropdown.prev()[0]!==mask[0]){this.dropdown.before(mask);}
$("#select2-drop").removeAttr("id");this.dropdown.attr("id","select2-drop");mask.show();this.positionDropdown();this.dropdown.show();this.positionDropdown();this.dropdown.addClass("select2-drop-active");var that=this;this.container.parents().add(window).each(function(){$(this).on(resize+" "+scroll+" "+orient,function(e){if(that.opened())that.positionDropdown();});});},close:function(){if(!this.opened())return;var cid=this.containerEventName,scroll="scroll."+cid,resize="resize."+cid,orient="orientationchange."+cid;this.container.parents().add(window).each(function(){$(this).off(scroll).off(resize).off(orient);});this.clearDropdownAlignmentPreference();$("#select2-drop-mask").hide();this.dropdown.removeAttr("id");this.dropdown.hide();this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active");this.results.empty();$document.off("mousemove.select2Event");this.clearSearch();this.search.removeClass("select2-active");this.search.removeAttr("aria-activedescendant");this.opts.element.trigger($.Event("select2-close"));},externalSearch:function(term){this.open();this.search.val(term);this.updateResults(false);},clearSearch:function(){},prefillNextSearchTerm:function(){if(this.search.val()!==""){return false;}
var nextSearchTerm=this.opts.nextSearchTerm(this.data(),this.lastSearchTerm);if(nextSearchTerm!==undefined){this.search.val(nextSearchTerm);this.search.select();return true;}
return false;},getMaximumSelectionSize:function(){return evaluate(this.opts.maximumSelectionSize,this.opts.element);},ensureHighlightVisible:function(){var results=this.results,children,index,child,hb,rb,y,more,topOffset;index=this.highlight();if(index<0)return;if(index==0){results.scrollTop(0);return;}
children=this.findHighlightableChoices().find('.select2-result-label');child=$(children[index]);topOffset=(child.offset()||{}).top||0;hb=topOffset+child.outerHeight(true);if(index===children.length-1){more=results.find("li.select2-more-results");if(more.length>0){hb=more.offset().top+more.outerHeight(true);}}
rb=results.offset().top+results.outerHeight(false);if(hb>rb){results.scrollTop(results.scrollTop()+(hb-rb));}
y=topOffset-results.offset().top;if(y<0&&child.css('display')!='none'){results.scrollTop(results.scrollTop()+y);}},findHighlightableChoices:function(){return this.results.find(".select2-result-selectable:not(.select2-disabled):not(.select2-selected)");},moveHighlight:function(delta){var choices=this.findHighlightableChoices(),index=this.highlight();while(index>-1&&index<choices.length){index+=delta;var choice=$(choices[index]);if(choice.hasClass("select2-result-selectable")&&!choice.hasClass("select2-disabled")&&!choice.hasClass("select2-selected")){this.highlight(index);break;}}},highlight:function(index){var choices=this.findHighlightableChoices(),choice,data;if(arguments.length===0){return indexOf(choices.filter(".select2-highlighted")[0],choices.get());}
if(index>=choices.length)index=choices.length-1;if(index<0)index=0;this.removeHighlight();choice=$(choices[index]);choice.addClass("select2-highlighted");this.search.attr("aria-activedescendant",choice.find(".select2-result-label").attr("id"));this.ensureHighlightVisible();this.liveRegion.text(choice.text());data=choice.data("select2-data");if(data){this.opts.element.trigger({type:"select2-highlight",val:this.id(data),choice:data});}},removeHighlight:function(){this.results.find(".select2-highlighted").removeClass("select2-highlighted");},touchMoved:function(){this._touchMoved=true;},clearTouchMoved:function(){this._touchMoved=false;},countSelectableResults:function(){return this.findHighlightableChoices().length;},highlightUnderEvent:function(event){var el=$(event.target).closest(".select2-result-selectable");if(el.length>0&&!el.is(".select2-highlighted")){var choices=this.findHighlightableChoices();this.highlight(choices.index(el));}else if(el.length==0){this.removeHighlight();}},loadMoreIfNeeded:function(){var results=this.results,more=results.find("li.select2-more-results"),below,page=this.resultsPage+1,self=this,term=this.search.val(),context=this.context;if(more.length===0)return;below=more.offset().top-results.offset().top-results.height();if(below<=this.opts.loadMorePadding){more.addClass("select2-active");this.opts.query({element:this.opts.element,term:term,page:page,context:context,matcher:this.opts.matcher,callback:this.bind(function(data){if(!self.opened())return;self.opts.populateResults.call(this,results,data.results,{term:term,page:page,context:context});self.postprocessResults(data,false,false);if(data.more===true){more.detach().appendTo(results).html(self.opts.escapeMarkup(evaluate(self.opts.formatLoadMore,self.opts.element,page+1)));window.setTimeout(function(){self.loadMoreIfNeeded();},10);}else{more.remove();}
self.positionDropdown();self.resultsPage=page;self.context=data.context;this.opts.element.trigger({type:"select2-loaded",items:data});})});}},tokenize:function(){},updateResults:function(initial){var search=this.search,results=this.results,opts=this.opts,data,self=this,input,term=search.val(),lastTerm=$.data(this.container,"select2-last-term"),queryNumber;if(initial!==true&&lastTerm&&equal(term,lastTerm))return;$.data(this.container,"select2-last-term",term);if(initial!==true&&(this.showSearchInput===false||!this.opened())){return;}
function postRender(){search.removeClass("select2-active");self.positionDropdown();if(results.find('.select2-no-results,.select2-selection-limit,.select2-searching').length){self.liveRegion.text(results.text());}
else{self.liveRegion.text(self.opts.formatMatches(results.find('.select2-result-selectable:not(".select2-selected")').length));}}
function render(html){results.html(html);postRender();}
queryNumber=++this.queryCount;var maxSelSize=this.getMaximumSelectionSize();if(maxSelSize>=1){data=this.data();if($.isArray(data)&&data.length>=maxSelSize&&checkFormatter(opts.formatSelectionTooBig,"formatSelectionTooBig")){render("<li class='select2-selection-limit'>"+evaluate(opts.formatSelectionTooBig,opts.element,maxSelSize)+"</li>");return;}}
if(search.val().length<opts.minimumInputLength){if(checkFormatter(opts.formatInputTooShort,"formatInputTooShort")){render("<li class='select2-no-results'>"+evaluate(opts.formatInputTooShort,opts.element,search.val(),opts.minimumInputLength)+"</li>");}else{render("");}
if(initial&&this.showSearch)this.showSearch(true);return;}
if(opts.maximumInputLength&&search.val().length>opts.maximumInputLength){if(checkFormatter(opts.formatInputTooLong,"formatInputTooLong")){render("<li class='select2-no-results'>"+evaluate(opts.formatInputTooLong,opts.element,search.val(),opts.maximumInputLength)+"</li>");}else{render("");}
return;}
if(opts.formatSearching&&this.findHighlightableChoices().length===0){render("<li class='select2-searching'>"+evaluate(opts.formatSearching,opts.element)+"</li>");}
search.addClass("select2-active");this.removeHighlight();input=this.tokenize();if(input!=undefined&&input!=null){search.val(input);}
this.resultsPage=1;opts.query({element:opts.element,term:search.val(),page:this.resultsPage,context:null,matcher:opts.matcher,callback:this.bind(function(data){var def;if(queryNumber!=this.queryCount){return;}
if(!this.opened()){this.search.removeClass("select2-active");return;}
if(data.hasError!==undefined&&checkFormatter(opts.formatAjaxError,"formatAjaxError")){render("<li class='select2-ajax-error'>"+evaluate(opts.formatAjaxError,opts.element,data.jqXHR,data.textStatus,data.errorThrown)+"</li>");return;}
this.context=(data.context===undefined)?null:data.context;if(this.opts.createSearchChoice&&search.val()!==""){def=this.opts.createSearchChoice.call(self,search.val(),data.results);if(def!==undefined&&def!==null&&self.id(def)!==undefined&&self.id(def)!==null){if($(data.results).filter(function(){return equal(self.id(this),self.id(def));}).length===0){this.opts.createSearchChoicePosition(data.results,def);}}}
if(data.results.length===0&&checkFormatter(opts.formatNoMatches,"formatNoMatches")){render("<li class='select2-no-results'>"+evaluate(opts.formatNoMatches,opts.element,search.val())+"</li>");if(this.showSearch){this.showSearch(search.val());}
return;}
results.empty();self.opts.populateResults.call(this,results,data.results,{term:search.val(),page:this.resultsPage,context:null});if(data.more===true&&checkFormatter(opts.formatLoadMore,"formatLoadMore")){results.append("<li class='select2-more-results'>"+opts.escapeMarkup(evaluate(opts.formatLoadMore,opts.element,this.resultsPage))+"</li>");window.setTimeout(function(){self.loadMoreIfNeeded();},10);}
this.postprocessResults(data,initial);postRender();this.opts.element.trigger({type:"select2-loaded",items:data});})});},cancel:function(){this.close();},blur:function(){if(this.opts.selectOnBlur)
this.selectHighlighted({noFocus:true});this.close();this.container.removeClass("select2-container-active");if(this.search[0]===document.activeElement){this.search.blur();}
this.clearSearch();this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");},focusSearch:function(){focus(this.search);},selectHighlighted:function(options){if(this._touchMoved){this.clearTouchMoved();return;}
var index=this.highlight(),highlighted=this.results.find(".select2-highlighted"),data=highlighted.closest('.select2-result').data("select2-data");if(data){this.highlight(index);this.onSelect(data,options);}else if(options&&options.noFocus){this.close();}},getPlaceholder:function(){var placeholderOption;return this.opts.element.attr("placeholder")||this.opts.element.attr("data-placeholder")||this.opts.element.data("placeholder")||this.opts.placeholder||((placeholderOption=this.getPlaceholderOption())!==undefined?placeholderOption.text():undefined);},getPlaceholderOption:function(){if(this.select){var firstOption=this.select.children('option').first();if(this.opts.placeholderOption!==undefined){return(this.opts.placeholderOption==="first"&&firstOption)||(typeof this.opts.placeholderOption==="function"&&this.opts.placeholderOption(this.select));}else if($.trim(firstOption.text())===""&&firstOption.val()===""){return firstOption;}}},initContainerWidth:function(){function resolveContainerWidth(){var style,attrs,matches,i,l,attr;if(this.opts.width==="off"){return null;}else if(this.opts.width==="element"){return this.opts.element.outerWidth(false)===0?'auto':this.opts.element.outerWidth(false)+'px';}else if(this.opts.width==="copy"||this.opts.width==="resolve"){style=this.opts.element.attr('style');if(typeof(style)==="string"){attrs=style.split(';');for(i=0,l=attrs.length;i<l;i=i+1){attr=attrs[i].replace(/\s/g,'');matches=attr.match(/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i);if(matches!==null&&matches.length>=1)
return matches[1];}}
if(this.opts.width==="resolve"){style=this.opts.element.css('width');if(style.indexOf("%")>0)return style;return(this.opts.element.outerWidth(false)===0?'auto':this.opts.element.outerWidth(false)+'px');}
return null;}else if($.isFunction(this.opts.width)){return this.opts.width();}else{return this.opts.width;}};var width=resolveContainerWidth.call(this);if(width!==null){this.container.css("width",width);}}});SingleSelect2=clazz(AbstractSelect2,{createContainer:function(){var container=$(document.createElement("div")).attr({"class":"select2-container"}).html(["<a href='javascript:void(0)' class='select2-choice' tabindex='-1'>","   <span class='select2-chosen'>&#160;</span><abbr class='select2-search-choice-close'></abbr>","   <span class='select2-arrow' role='presentation'><b role='presentation'></b></span>","</a>","<label for='' class='select2-offscreen'></label>","<input class='select2-focusser select2-offscreen' type='text' aria-haspopup='true' role='button' />","<div class='select2-drop select2-display-none'>","   <div class='select2-search'>","       <label for='' class='select2-offscreen'></label>","       <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input' role='combobox' aria-expanded='true'","       aria-autocomplete='list' />","   </div>","   <ul class='select2-results' role='listbox'>","   </ul>","</div>"].join(""));return container;},enableInterface:function(){if(this.parent.enableInterface.apply(this,arguments)){this.focusser.prop("disabled",!this.isInterfaceEnabled());}},opening:function(){var el,range,len;if(this.opts.minimumResultsForSearch>=0){this.showSearch(true);}
this.parent.opening.apply(this,arguments);if(this.showSearchInput!==false){this.search.val(this.focusser.val());}
if(this.opts.shouldFocusInput(this)){this.search.focus();el=this.search.get(0);if(el.createTextRange){range=el.createTextRange();range.collapse(false);range.select();}else if(el.setSelectionRange){len=this.search.val().length;el.setSelectionRange(len,len);}}
this.prefillNextSearchTerm();this.focusser.prop("disabled",true).val("");this.updateResults(true);this.opts.element.trigger($.Event("select2-open"));},close:function(){if(!this.opened())return;this.parent.close.apply(this,arguments);this.focusser.prop("disabled",false);if(this.opts.shouldFocusInput(this)){this.focusser.focus();}},focus:function(){if(this.opened()){this.close();}else{this.focusser.prop("disabled",false);if(this.opts.shouldFocusInput(this)){this.focusser.focus();}}},isFocused:function(){return this.container.hasClass("select2-container-active");},cancel:function(){this.parent.cancel.apply(this,arguments);this.focusser.prop("disabled",false);if(this.opts.shouldFocusInput(this)){this.focusser.focus();}},destroy:function(){$("label[for='"+this.focusser.attr('id')+"']").attr('for',this.opts.element.attr("id"));this.parent.destroy.apply(this,arguments);cleanupJQueryElements.call(this,"selection","focusser");},initContainer:function(){var selection,container=this.container,dropdown=this.dropdown,idSuffix=nextUid(),elementLabel;if(this.opts.minimumResultsForSearch<0){this.showSearch(false);}else{this.showSearch(true);}
this.selection=selection=container.find(".select2-choice");this.focusser=container.find(".select2-focusser");selection.find(".select2-chosen").attr("id","select2-chosen-"+idSuffix);this.focusser.attr("aria-labelledby","select2-chosen-"+idSuffix);this.results.attr("id","select2-results-"+idSuffix);this.search.attr("aria-owns","select2-results-"+idSuffix);this.focusser.attr("id","s2id_autogen"+idSuffix);elementLabel=$("label[for='"+this.opts.element.attr("id")+"']");this.opts.element.on('focus.select2',this.bind(function(){this.focus();}));this.focusser.prev().text(elementLabel.text()).attr('for',this.focusser.attr('id'));var originalTitle=this.opts.element.attr("title");this.opts.element.attr("title",(originalTitle||elementLabel.text()));this.focusser.attr("tabindex",this.elementTabIndex);this.search.attr("id",this.focusser.attr('id')+'_search');this.search.prev().text($("label[for='"+this.focusser.attr('id')+"']").text()).attr('for',this.search.attr('id'));this.search.on("keydown",this.bind(function(e){if(!this.isInterfaceEnabled())return;if(229==e.keyCode)return;if(e.which===KEY.PAGE_UP||e.which===KEY.PAGE_DOWN){killEvent(e);return;}
switch(e.which){case KEY.UP:case KEY.DOWN:this.moveHighlight((e.which===KEY.UP)?-1:1);killEvent(e);return;case KEY.ENTER:this.selectHighlighted();killEvent(e);return;case KEY.TAB:this.selectHighlighted({noFocus:true});return;case KEY.ESC:this.cancel(e);killEvent(e);return;}}));this.search.on("blur",this.bind(function(e){if(document.activeElement===this.body.get(0)){window.setTimeout(this.bind(function(){if(this.opened()&&this.results&&this.results.length>1){this.search.focus();}}),0);}}));this.focusser.on("keydown",this.bind(function(e){if(!this.isInterfaceEnabled())return;if(e.which===KEY.TAB||KEY.isControl(e)||KEY.isFunctionKey(e)||e.which===KEY.ESC){return;}
if(this.opts.openOnEnter===false&&e.which===KEY.ENTER){killEvent(e);return;}
if(e.which==KEY.DOWN||e.which==KEY.UP||(e.which==KEY.ENTER&&this.opts.openOnEnter)){if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey)return;this.open();killEvent(e);return;}
if(e.which==KEY.DELETE||e.which==KEY.BACKSPACE){if(this.opts.allowClear){this.clear();}
killEvent(e);return;}}));installKeyUpChangeEvent(this.focusser);this.focusser.on("keyup-change input",this.bind(function(e){if(this.opts.minimumResultsForSearch>=0){e.stopPropagation();if(this.opened())return;this.open();}}));selection.on("mousedown touchstart","abbr",this.bind(function(e){if(!this.isInterfaceEnabled()){return;}
this.clear();killEventImmediately(e);this.close();if(this.selection){this.selection.focus();}}));selection.on("mousedown touchstart",this.bind(function(e){reinsertElement(selection);if(!this.container.hasClass("select2-container-active")){this.opts.element.trigger($.Event("select2-focus"));}
if(this.opened()){this.close();}else if(this.isInterfaceEnabled()){this.open();}
killEvent(e);}));dropdown.on("mousedown touchstart",this.bind(function(){if(this.opts.shouldFocusInput(this)){this.search.focus();}}));selection.on("focus",this.bind(function(e){killEvent(e);}));this.focusser.on("focus",this.bind(function(){if(!this.container.hasClass("select2-container-active")){this.opts.element.trigger($.Event("select2-focus"));}
this.container.addClass("select2-container-active");})).on("blur",this.bind(function(){if(!this.opened()){this.container.removeClass("select2-container-active");this.opts.element.trigger($.Event("select2-blur"));}}));this.search.on("focus",this.bind(function(){if(!this.container.hasClass("select2-container-active")){this.opts.element.trigger($.Event("select2-focus"));}
this.container.addClass("select2-container-active");}));this.initContainerWidth();this.opts.element.hide();this.setPlaceholder();},clear:function(triggerChange){var data=this.selection.data("select2-data");if(data){var evt=$.Event("select2-clearing");this.opts.element.trigger(evt);if(evt.isDefaultPrevented()){return;}
var placeholderOption=this.getPlaceholderOption();this.opts.element.val(placeholderOption?placeholderOption.val():"");this.selection.find(".select2-chosen").empty();this.selection.removeData("select2-data");this.setPlaceholder();if(triggerChange!==false){this.opts.element.trigger({type:"select2-removed",val:this.id(data),choice:data});this.triggerChange({removed:data});}}},initSelection:function(){var selected;if(this.isPlaceholderOptionSelected()){this.updateSelection(null);this.close();this.setPlaceholder();}else{var self=this;this.opts.initSelection.call(null,this.opts.element,function(selected){if(selected!==undefined&&selected!==null){self.updateSelection(selected);self.close();self.setPlaceholder();self.lastSearchTerm=self.search.val();}});}},isPlaceholderOptionSelected:function(){var placeholderOption;if(this.getPlaceholder()===undefined)return false;return((placeholderOption=this.getPlaceholderOption())!==undefined&&placeholderOption.prop("selected"))||(this.opts.element.val()==="")||(this.opts.element.val()===undefined)||(this.opts.element.val()===null);},prepareOpts:function(){var opts=this.parent.prepareOpts.apply(this,arguments),self=this;if(opts.element.get(0).tagName.toLowerCase()==="select"){opts.initSelection=function(element,callback){var selected=element.find("option").filter(function(){return this.selected&&!this.disabled});callback(self.optionToData(selected));};}else if("data"in opts){opts.initSelection=opts.initSelection||function(element,callback){var id=element.val();var match=null;opts.query({matcher:function(term,text,el){var is_match=equal(id,opts.id(el));if(is_match){match=el;}
return is_match;},callback:!$.isFunction(callback)?$.noop:function(){callback(match);}});};}
return opts;},getPlaceholder:function(){if(this.select){if(this.getPlaceholderOption()===undefined){return undefined;}}
return this.parent.getPlaceholder.apply(this,arguments);},setPlaceholder:function(){var placeholder=this.getPlaceholder();if(this.isPlaceholderOptionSelected()&&placeholder!==undefined){if(this.select&&this.getPlaceholderOption()===undefined)return;this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(placeholder));this.selection.addClass("select2-default");this.container.removeClass("select2-allowclear");}},postprocessResults:function(data,initial,noHighlightUpdate){var selected=0,self=this,showSearchInput=true;this.findHighlightableChoices().each2(function(i,elm){if(equal(self.id(elm.data("select2-data")),self.opts.element.val())){selected=i;return false;}});if(noHighlightUpdate!==false){if(initial===true&&selected>=0){this.highlight(selected);}else{this.highlight(0);}}
if(initial===true){var min=this.opts.minimumResultsForSearch;if(min>=0){this.showSearch(countResults(data.results)>=min);}}},showSearch:function(showSearchInput){if(this.showSearchInput===showSearchInput)return;this.showSearchInput=showSearchInput;this.dropdown.find(".select2-search").toggleClass("select2-search-hidden",!showSearchInput);this.dropdown.find(".select2-search").toggleClass("select2-offscreen",!showSearchInput);$(this.dropdown,this.container).toggleClass("select2-with-searchbox",showSearchInput);},onSelect:function(data,options){if(!this.triggerSelect(data)){return;}
var old=this.opts.element.val(),oldData=this.data();this.opts.element.val(this.id(data));this.updateSelection(data);this.opts.element.trigger({type:"select2-selected",val:this.id(data),choice:data});this.lastSearchTerm=this.search.val();this.close();if((!options||!options.noFocus)&&this.opts.shouldFocusInput(this)){this.focusser.focus();}
if(!equal(old,this.id(data))){this.triggerChange({added:data,removed:oldData});}},updateSelection:function(data){var container=this.selection.find(".select2-chosen"),formatted,cssClass;this.selection.data("select2-data",data);container.empty();if(data!==null){formatted=this.opts.formatSelection(data,container,this.opts.escapeMarkup);}
if(formatted!==undefined){container.append(formatted);}
cssClass=this.opts.formatSelectionCssClass(data,container);if(cssClass!==undefined){container.addClass(cssClass);}
this.selection.removeClass("select2-default");if(this.opts.allowClear&&this.getPlaceholder()!==undefined){this.container.addClass("select2-allowclear");}},val:function(){var val,triggerChange=false,data=null,self=this,oldData=this.data();if(arguments.length===0){return this.opts.element.val();}
val=arguments[0];if(arguments.length>1){triggerChange=arguments[1];if(this.opts.debug&&console&&console.warn){console.warn('Select2: The second option to `select2("val")` is not supported in Select2 4.0.0. '+'The `change` event will always be triggered in 4.0.0.');}}
if(this.select){if(this.opts.debug&&console&&console.warn){console.warn('Select2: Setting the value on a <select> using `select2("val")` is no longer supported in 4.0.0. '+'You can use the `.val(newValue).trigger("change")` method provided by jQuery instead.');}
this.select.val(val).find("option").filter(function(){return this.selected}).each2(function(i,elm){data=self.optionToData(elm);return false;});this.updateSelection(data);this.setPlaceholder();if(triggerChange){this.triggerChange({added:data,removed:oldData});}}else{if(!val&&val!==0){this.clear(triggerChange);return;}
if(this.opts.initSelection===undefined){throw new Error("cannot call val() if initSelection() is not defined");}
this.opts.element.val(val);this.opts.initSelection(this.opts.element,function(data){self.opts.element.val(!data?"":self.id(data));self.updateSelection(data);self.setPlaceholder();if(triggerChange){self.triggerChange({added:data,removed:oldData});}});}},clearSearch:function(){this.search.val("");this.focusser.val("");},data:function(value){var data,triggerChange=false;if(arguments.length===0){data=this.selection.data("select2-data");if(data==undefined)data=null;return data;}else{if(this.opts.debug&&console&&console.warn){console.warn('Select2: The `select2("data")` method can no longer set selected values in 4.0.0, '+'consider using the `.val()` method instead.');}
if(arguments.length>1){triggerChange=arguments[1];}
if(!value){this.clear(triggerChange);}else{data=this.data();this.opts.element.val(!value?"":this.id(value));this.updateSelection(value);if(triggerChange){this.triggerChange({added:value,removed:data});}}}}});MultiSelect2=clazz(AbstractSelect2,{createContainer:function(){var container=$(document.createElement("div")).attr({"class":"select2-container select2-container-multi"}).html(["<ul class='select2-choices'>","  <li class='select2-search-field'>","    <label for='' class='select2-offscreen'></label>","    <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input'>","  </li>","</ul>","<div class='select2-drop select2-drop-multi select2-display-none'>","   <ul class='select2-results'>","   </ul>","</div>"].join(""));return container;},prepareOpts:function(){var opts=this.parent.prepareOpts.apply(this,arguments),self=this;if(opts.element.get(0).tagName.toLowerCase()==="select"){opts.initSelection=function(element,callback){var data=[];element.find("option").filter(function(){return this.selected&&!this.disabled}).each2(function(i,elm){data.push(self.optionToData(elm));});callback(data);};}else if("data"in opts){opts.initSelection=opts.initSelection||function(element,callback){var ids=splitVal(element.val(),opts.separator,opts.transformVal);var matches=[];opts.query({matcher:function(term,text,el){var is_match=$.grep(ids,function(id){return equal(id,opts.id(el));}).length;if(is_match){matches.push(el);}
return is_match;},callback:!$.isFunction(callback)?$.noop:function(){var ordered=[];for(var i=0;i<ids.length;i++){var id=ids[i];for(var j=0;j<matches.length;j++){var match=matches[j];if(equal(id,opts.id(match))){ordered.push(match);matches.splice(j,1);break;}}}
callback(ordered);}});};}
return opts;},selectChoice:function(choice){var selected=this.container.find(".select2-search-choice-focus");if(selected.length&&choice&&choice[0]==selected[0]){}else{if(selected.length){this.opts.element.trigger("choice-deselected",selected);}
selected.removeClass("select2-search-choice-focus");if(choice&&choice.length){this.close();choice.addClass("select2-search-choice-focus");this.opts.element.trigger("choice-selected",choice);}}},destroy:function(){$("label[for='"+this.search.attr('id')+"']").attr('for',this.opts.element.attr("id"));this.parent.destroy.apply(this,arguments);cleanupJQueryElements.call(this,"searchContainer","selection");},initContainer:function(){var selector=".select2-choices",selection;this.searchContainer=this.container.find(".select2-search-field");this.selection=selection=this.container.find(selector);var _this=this;this.selection.on("click",".select2-container:not(.select2-container-disabled) .select2-search-choice:not(.select2-locked)",function(e){_this.search[0].focus();_this.selectChoice($(this));});this.search.attr("id","s2id_autogen"+nextUid());this.search.prev().text($("label[for='"+this.opts.element.attr("id")+"']").text()).attr('for',this.search.attr('id'));this.opts.element.on('focus.select2',this.bind(function(){this.focus();}));this.search.on("input paste",this.bind(function(){if(this.search.attr('placeholder')&&this.search.val().length==0)return;if(!this.isInterfaceEnabled())return;if(!this.opened()){this.open();}}));this.search.attr("tabindex",this.elementTabIndex);this.keydowns=0;this.search.on("keydown",this.bind(function(e){if(!this.isInterfaceEnabled())return;++this.keydowns;var selected=selection.find(".select2-search-choice-focus");var prev=selected.prev(".select2-search-choice:not(.select2-locked)");var next=selected.next(".select2-search-choice:not(.select2-locked)");var pos=getCursorInfo(this.search);if(selected.length&&(e.which==KEY.LEFT||e.which==KEY.RIGHT||e.which==KEY.BACKSPACE||e.which==KEY.DELETE||e.which==KEY.ENTER)){var selectedChoice=selected;if(e.which==KEY.LEFT&&prev.length){selectedChoice=prev;}
else if(e.which==KEY.RIGHT){selectedChoice=next.length?next:null;}
else if(e.which===KEY.BACKSPACE){if(this.unselect(selected.first())){this.search.width(10);selectedChoice=prev.length?prev:next;}}else if(e.which==KEY.DELETE){if(this.unselect(selected.first())){this.search.width(10);selectedChoice=next.length?next:null;}}else if(e.which==KEY.ENTER){selectedChoice=null;}
this.selectChoice(selectedChoice);killEvent(e);if(!selectedChoice||!selectedChoice.length){this.open();}
return;}else if(((e.which===KEY.BACKSPACE&&this.keydowns==1)||e.which==KEY.LEFT)&&(pos.offset==0&&!pos.length)){this.selectChoice(selection.find(".select2-search-choice:not(.select2-locked)").last());killEvent(e);return;}else{this.selectChoice(null);}
if(this.opened()){switch(e.which){case KEY.UP:case KEY.DOWN:this.moveHighlight((e.which===KEY.UP)?-1:1);killEvent(e);return;case KEY.ENTER:this.selectHighlighted();killEvent(e);return;case KEY.TAB:this.selectHighlighted({noFocus:true});this.close();return;case KEY.ESC:this.cancel(e);killEvent(e);return;}}
if(e.which===KEY.TAB||KEY.isControl(e)||KEY.isFunctionKey(e)||e.which===KEY.BACKSPACE||e.which===KEY.ESC){return;}
if(e.which===KEY.ENTER){if(this.opts.openOnEnter===false){return;}else if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey){return;}}
this.open();if(e.which===KEY.PAGE_UP||e.which===KEY.PAGE_DOWN){killEvent(e);}
if(e.which===KEY.ENTER){killEvent(e);}}));this.search.on("keyup",this.bind(function(e){this.keydowns=0;this.resizeSearch();}));this.search.on("blur",this.bind(function(e){this.container.removeClass("select2-container-active");this.search.removeClass("select2-focused");this.selectChoice(null);if(!this.opened())this.clearSearch();e.stopImmediatePropagation();this.opts.element.trigger($.Event("select2-blur"));}));this.container.on("click",selector,this.bind(function(e){if(!this.isInterfaceEnabled())return;if($(e.target).closest(".select2-search-choice").length>0){return;}
this.selectChoice(null);this.clearPlaceholder();if(!this.container.hasClass("select2-container-active")){this.opts.element.trigger($.Event("select2-focus"));}
this.open();this.focusSearch();e.preventDefault();}));this.container.on("focus",selector,this.bind(function(){if(!this.isInterfaceEnabled())return;if(!this.container.hasClass("select2-container-active")){this.opts.element.trigger($.Event("select2-focus"));}
this.container.addClass("select2-container-active");this.dropdown.addClass("select2-drop-active");this.clearPlaceholder();}));this.initContainerWidth();this.opts.element.hide();this.clearSearch();},enableInterface:function(){if(this.parent.enableInterface.apply(this,arguments)){this.search.prop("disabled",!this.isInterfaceEnabled());}},initSelection:function(){var data;if(this.opts.element.val()===""&&this.opts.element.text()===""){this.updateSelection([]);this.close();this.clearSearch();}
if(this.select||this.opts.element.val()!==""){var self=this;this.opts.initSelection.call(null,this.opts.element,function(data){if(data!==undefined&&data!==null){self.updateSelection(data);self.close();self.clearSearch();}});}},clearSearch:function(){var placeholder=this.getPlaceholder(),maxWidth=this.getMaxSearchWidth();if(placeholder!==undefined&&this.getVal().length===0&&this.search.hasClass("select2-focused")===false){this.search.val(placeholder).addClass("select2-default");this.search.width(maxWidth>0?maxWidth:this.container.css("width"));}else{this.search.val("").width(10);}},clearPlaceholder:function(){if(this.search.hasClass("select2-default")){this.search.val("").removeClass("select2-default");}},opening:function(){this.clearPlaceholder();this.resizeSearch();this.parent.opening.apply(this,arguments);this.focusSearch();this.prefillNextSearchTerm();this.updateResults(true);if(this.opts.shouldFocusInput(this)){this.search.focus();}
this.opts.element.trigger($.Event("select2-open"));},close:function(){if(!this.opened())return;this.parent.close.apply(this,arguments);},focus:function(){this.close();this.search.focus();},isFocused:function(){return this.search.hasClass("select2-focused");},updateSelection:function(data){var ids={},filtered=[],self=this;$(data).each(function(){if(!(self.id(this)in ids)){ids[self.id(this)]=0;filtered.push(this);}});this.selection.find(".select2-search-choice").remove();this.addSelectedChoice(filtered);self.postprocessResults();},tokenize:function(){var input=this.search.val();input=this.opts.tokenizer.call(this,input,this.data(),this.bind(this.onSelect),this.opts);if(input!=null&&input!=undefined){this.search.val(input);if(input.length>0){this.open();}}},onSelect:function(data,options){if(!this.triggerSelect(data)||data.text===""){return;}
this.addSelectedChoice(data);this.opts.element.trigger({type:"selected",val:this.id(data),choice:data});this.lastSearchTerm=this.search.val();this.clearSearch();this.updateResults();if(this.select||!this.opts.closeOnSelect)this.postprocessResults(data,false,this.opts.closeOnSelect===true);if(this.opts.closeOnSelect){this.close();this.search.width(10);}else{if(this.countSelectableResults()>0){this.search.width(10);this.resizeSearch();if(this.getMaximumSelectionSize()>0&&this.val().length>=this.getMaximumSelectionSize()){this.updateResults(true);}else{if(this.prefillNextSearchTerm()){this.updateResults();}}
this.positionDropdown();}else{this.close();this.search.width(10);}}
this.triggerChange({added:data});if(!options||!options.noFocus)
this.focusSearch();},cancel:function(){this.close();this.focusSearch();},addSelectedChoice:function(data){var val=this.getVal(),self=this;$(data).each(function(){val.push(self.createChoice(this));});this.setVal(val);},createChoice:function(data){var enableChoice=!data.locked,enabledItem=$("<li class='select2-search-choice'>"+"    <div></div>"+"    <a href='#' class='select2-search-choice-close' tabindex='-1'></a>"+"</li>"),disabledItem=$("<li class='select2-search-choice select2-locked'>"+"<div></div>"+"</li>");var choice=enableChoice?enabledItem:disabledItem,id=this.id(data),formatted,cssClass;formatted=this.opts.formatSelection(data,choice.find("div"),this.opts.escapeMarkup);if(formatted!=undefined){choice.find("div").replaceWith($("<div></div>").html(formatted));}
cssClass=this.opts.formatSelectionCssClass(data,choice.find("div"));if(cssClass!=undefined){choice.addClass(cssClass);}
if(enableChoice){choice.find(".select2-search-choice-close").on("mousedown",killEvent).on("click dblclick",this.bind(function(e){if(!this.isInterfaceEnabled())return;this.unselect($(e.target));this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");killEvent(e);this.close();this.focusSearch();})).on("focus",this.bind(function(){if(!this.isInterfaceEnabled())return;this.container.addClass("select2-container-active");this.dropdown.addClass("select2-drop-active");}));}
choice.data("select2-data",data);choice.insertBefore(this.searchContainer);return id;},unselect:function(selected){var val=this.getVal(),data,index;selected=selected.closest(".select2-search-choice");if(selected.length===0){throw"Invalid argument: "+selected+". Must be .select2-search-choice";}
data=selected.data("select2-data");if(!data){return;}
var evt=$.Event("select2-removing");evt.val=this.id(data);evt.choice=data;this.opts.element.trigger(evt);if(evt.isDefaultPrevented()){return false;}
while((index=indexOf(this.id(data),val))>=0){val.splice(index,1);this.setVal(val);if(this.select)this.postprocessResults();}
selected.remove();this.opts.element.trigger({type:"select2-removed",val:this.id(data),choice:data});this.triggerChange({removed:data});return true;},postprocessResults:function(data,initial,noHighlightUpdate){var val=this.getVal(),choices=this.results.find(".select2-result"),compound=this.results.find(".select2-result-with-children"),self=this;choices.each2(function(i,choice){var id=self.id(choice.data("select2-data"));if(indexOf(id,val)>=0){choice.addClass("select2-selected");choice.find(".select2-result-selectable").addClass("select2-selected");}});compound.each2(function(i,choice){if(!choice.is('.select2-result-selectable')&&choice.find(".select2-result-selectable:not(.select2-selected)").length===0){choice.addClass("select2-selected");}});if(this.highlight()==-1&&noHighlightUpdate!==false&&this.opts.closeOnSelect===true){self.highlight(0);}
if(!this.opts.createSearchChoice&&!choices.filter('.select2-result:not(.select2-selected)').length>0){if(!data||data&&!data.more&&this.results.find(".select2-no-results").length===0){if(checkFormatter(self.opts.formatNoMatches,"formatNoMatches")){this.results.append("<li class='select2-no-results'>"+evaluate(self.opts.formatNoMatches,self.opts.element,self.search.val())+"</li>");}}}},getMaxSearchWidth:function(){return this.selection.width()-getSideBorderPadding(this.search);},resizeSearch:function(){var minimumWidth,left,maxWidth,containerLeft,searchWidth,sideBorderPadding=getSideBorderPadding(this.search);minimumWidth=measureTextWidth(this.search)+10;left=this.search.offset().left;maxWidth=this.selection.width();containerLeft=this.selection.offset().left;searchWidth=maxWidth-(left-containerLeft)-sideBorderPadding;if(searchWidth<minimumWidth){searchWidth=maxWidth-sideBorderPadding;}
if(searchWidth<40){searchWidth=maxWidth-sideBorderPadding;}
if(searchWidth<=0){searchWidth=minimumWidth;}
this.search.width(Math.floor(searchWidth));},getVal:function(){var val;if(this.select){val=this.select.val();return val===null?[]:val;}else{val=this.opts.element.val();return splitVal(val,this.opts.separator,this.opts.transformVal);}},setVal:function(val){if(this.select){this.select.val(val);}else{var unique=[],valMap={};$(val).each(function(){if(!(this in valMap)){unique.push(this);valMap[this]=0;}});this.opts.element.val(unique.length===0?"":unique.join(this.opts.separator));}},buildChangeDetails:function(old,current){var current=current.slice(0),old=old.slice(0);for(var i=0;i<current.length;i++){for(var j=0;j<old.length;j++){if(equal(this.opts.id(current[i]),this.opts.id(old[j]))){current.splice(i,1);i--;old.splice(j,1);break;}}}
return{added:current,removed:old};},val:function(val,triggerChange){var oldData,self=this;if(arguments.length===0){return this.getVal();}
oldData=this.data();if(!oldData.length)oldData=[];if(!val&&val!==0){this.opts.element.val("");this.updateSelection([]);this.clearSearch();if(triggerChange){this.triggerChange({added:this.data(),removed:oldData});}
return;}
this.setVal(val);if(this.select){this.opts.initSelection(this.select,this.bind(this.updateSelection));if(triggerChange){this.triggerChange(this.buildChangeDetails(oldData,this.data()));}}else{if(this.opts.initSelection===undefined){throw new Error("val() cannot be called if initSelection() is not defined");}
this.opts.initSelection(this.opts.element,function(data){var ids=$.map(data,self.id);self.setVal(ids);self.updateSelection(data);self.clearSearch();if(triggerChange){self.triggerChange(self.buildChangeDetails(oldData,self.data()));}});}
this.clearSearch();},onSortStart:function(){if(this.select){throw new Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.");}
this.search.width(0);this.searchContainer.hide();},onSortEnd:function(){var val=[],self=this;this.searchContainer.show();this.searchContainer.appendTo(this.searchContainer.parent());this.resizeSearch();this.selection.find(".select2-search-choice").each(function(){val.push(self.opts.id($(this).data("select2-data")));});this.setVal(val);this.triggerChange();},data:function(values,triggerChange){var self=this,ids,old;if(arguments.length===0){return this.selection.children(".select2-search-choice").map(function(){return $(this).data("select2-data");}).get();}else{old=this.data();if(!values){values=[];}
ids=$.map(values,function(e){return self.opts.id(e);});this.setVal(ids);this.updateSelection(values);this.clearSearch();if(triggerChange){this.triggerChange(this.buildChangeDetails(old,this.data()));}}}});$.fn.select2=function(){var args=Array.prototype.slice.call(arguments,0),opts,select2,method,value,multiple,allowedMethods=["val","destroy","opened","open","close","focus","isFocused","container","dropdown","onSortStart","onSortEnd","enable","disable","readonly","positionDropdown","data","search"],valueMethods=["opened","isFocused","container","dropdown"],propertyMethods=["val","data"],methodsMap={search:"externalSearch"};this.each(function(){if(args.length===0||typeof(args[0])==="object"){opts=args.length===0?{}:$.extend({},args[0]);opts.element=$(this);if(opts.element.get(0).tagName.toLowerCase()==="select"){multiple=opts.element.prop("multiple");}else{multiple=opts.multiple||false;if("tags"in opts){opts.multiple=multiple=true;}}
select2=multiple?new window.Select2["class"].multi():new window.Select2["class"].single();select2.init(opts);}else if(typeof(args[0])==="string"){if(indexOf(args[0],allowedMethods)<0){throw"Unknown method: "+args[0];}
value=undefined;select2=$(this).data("select2");if(select2===undefined)return;method=args[0];if(method==="container"){value=select2.container;}else if(method==="dropdown"){value=select2.dropdown;}else{if(methodsMap[method])method=methodsMap[method];value=select2[method].apply(select2,args.slice(1));}
if(indexOf(args[0],valueMethods)>=0||(indexOf(args[0],propertyMethods)>=0&&args.length==1)){return false;}}else{throw"Invalid arguments to select2 plugin: "+args;}});return(value===undefined)?this:value;};$.fn.select2.defaults={debug:false,width:"copy",loadMorePadding:0,closeOnSelect:true,openOnEnter:true,containerCss:{},dropdownCss:{},containerCssClass:"",dropdownCssClass:"",formatResult:function(result,container,query,escapeMarkup){var markup=[];markMatch(this.text(result),query.term,markup,escapeMarkup);return markup.join("");},transformVal:function(val){return $.trim(val);},formatSelection:function(data,container,escapeMarkup){return data?escapeMarkup(this.text(data)):undefined;},sortResults:function(results,container,query){return results;},formatResultCssClass:function(data){return data.css;},formatSelectionCssClass:function(data,container){return undefined;},minimumResultsForSearch:0,minimumInputLength:0,maximumInputLength:null,maximumSelectionSize:0,id:function(e){return e==undefined?null:e.id;},text:function(e){if(e&&this.data&&this.data.text){if($.isFunction(this.data.text)){return this.data.text(e);}else{return e[this.data.text];}}else{return e.text;}},matcher:function(term,text){return stripDiacritics(''+text).toUpperCase().indexOf(stripDiacritics(''+term).toUpperCase())>=0;},separator:",",tokenSeparators:[],tokenizer:defaultTokenizer,escapeMarkup:defaultEscapeMarkup,blurOnChange:false,selectOnBlur:false,adaptContainerCssClass:function(c){return c;},adaptDropdownCssClass:function(c){return null;},nextSearchTerm:function(selectedObject,currentSearchTerm){return undefined;},searchInputPlaceholder:'',createSearchChoicePosition:'top',shouldFocusInput:function(instance){var supportsTouchEvents=(('ontouchstart'in window)||(navigator.msMaxTouchPoints>0));if(!supportsTouchEvents){return true;}
if(instance.opts.minimumResultsForSearch<0){return false;}
return true;}};$.fn.select2.locales=[];$.fn.select2.locales['en']={formatMatches:function(matches){if(matches===1){return"One result is available, press enter to select it.";}return matches+" results are available, use up and down arrow keys to navigate.";},formatNoMatches:function(){return"No matches found";},formatAjaxError:function(jqXHR,textStatus,errorThrown){return"Loading failed";},formatInputTooShort:function(input,min){var n=min-input.length;return"Please enter "+n+" or more character"+(n==1?"":"s");},formatInputTooLong:function(input,max){var n=input.length-max;return"Please delete "+n+" character"+(n==1?"":"s");},formatSelectionTooBig:function(limit){return"You can only select "+limit+" item"+(limit==1?"":"s");},formatLoadMore:function(pageNumber){return"Loading more results…";},formatSearching:function(){return"Searching…";}};$.extend($.fn.select2.defaults,$.fn.select2.locales['en']);$.fn.select2.ajaxDefaults={transport:$.ajax,params:{type:"GET",cache:false,dataType:"json"}};window.Select2={query:{ajax:ajax,local:local,tags:tags},util:{debounce:debounce,markMatch:markMatch,escapeMarkup:defaultEscapeMarkup,stripDiacritics:stripDiacritics},"class":{"abstract":AbstractSelect2,"single":SingleSelect2,"multi":MultiSelect2}};}(jQuery));;

/* /web/static/src/legacy/js/libs/bootstrap.js */
odoo.define('@web/legacy/js/libs/bootstrap',[],function(require){'use strict';let __exports={};let bsSanitizeAllowList=Tooltip.Default.allowList;bsSanitizeAllowList['*'].push('title','style',/^data-[\w-]+/);bsSanitizeAllowList.header=[];bsSanitizeAllowList.main=[];bsSanitizeAllowList.footer=[];bsSanitizeAllowList.caption=[];bsSanitizeAllowList.col=['span'];bsSanitizeAllowList.colgroup=['span'];bsSanitizeAllowList.table=[];bsSanitizeAllowList.thead=[];bsSanitizeAllowList.tbody=[];bsSanitizeAllowList.tfooter=[];bsSanitizeAllowList.tr=[];bsSanitizeAllowList.th=['colspan','rowspan'];bsSanitizeAllowList.td=['colspan','rowspan'];bsSanitizeAllowList.address=[];bsSanitizeAllowList.article=[];bsSanitizeAllowList.aside=[];bsSanitizeAllowList.blockquote=[];bsSanitizeAllowList.section=[];bsSanitizeAllowList.button=['type'];bsSanitizeAllowList.del=[];__exports.makeExtendedSanitizeWhiteList=makeExtendedSanitizeWhiteList;function makeExtendedSanitizeWhiteList(extensions){let allowList=Object.assign({},Tooltip.Default.allowList);Object.keys(extensions).forEach(key=>{allowList[key]=(allowList[key]||[]).concat(extensions[key]);});return allowList;}
Tooltip.Default.placement='auto';Tooltip.Default.fallbackPlacement=['bottom','right','left','top'];Tooltip.Default.html=true;Tooltip.Default.trigger='hover';Tooltip.Default.container='body';Tooltip.Default.boundary='window';Tooltip.Default.delay={show:1000,hide:0};const bootstrapShowFunction=Tooltip.prototype.show;Tooltip.prototype.show=function(){$('.tooltip').remove();const errorsToIgnore=["Please use show on visible elements"];try{return bootstrapShowFunction.call(this);}catch(error){if(errorsToIgnore.includes(error.message)){return 0;}
throw error;}};const bootstrapSetElementContent=Tooltip.prototype.setElementContent;Tooltip.prototype.setElementContent=function(element,content){if(content&&content.jquery&&content.length){const $rootElement=$('<div/>');$rootElement.append(content);content=$rootElement[0];}
return bootstrapSetElementContent.call(this,element,content);};const bootstrapSpyRefreshFunction=ScrollSpy.prototype.refresh;ScrollSpy.prototype.refresh=function(){bootstrapSpyRefreshFunction.apply(this,arguments);if(this._scrollElement===window||this._config.method!=='offset'){return;}
const baseScrollTop=this._getScrollTop();for(let i=0;i<this._offsets.length;i++){this._offsets[i]+=baseScrollTop;}};const bootstrapSpyProcessFunction=ScrollSpy.prototype._process;ScrollSpy.prototype._process=function(){bootstrapSpyProcessFunction.apply(this,arguments);if(this._activeTarget===null&&this._config.alwaysKeepFirstActive){this._activate(this._targets[0]);}};const bootstrapSpyActivateFunction=ScrollSpy.prototype._activate;ScrollSpy.prototype._activate=function(target){const element=document.querySelector(`[href="${target}"]`);if(!element||$(element).is(':hidden')){return;}
bootstrapSpyActivateFunction.apply(this,arguments);};Dropdown.prototype._detectNavbar=function(){return this._element.closest(".navbar-collapse.show");};const bsAdjustDialogFunction=Modal.prototype._adjustDialog;Modal.prototype._adjustDialog=function(){const document=this._element.ownerDocument;document.body.classList.remove('modal-open');const $scrollable=$().getScrollingElement(document);if(document.body.contains($scrollable[0])){$scrollable.compensateScrollbar(true);}
document.body.classList.add('modal-open');return bsAdjustDialogFunction.apply(this,arguments);};const bsResetAdjustmentsFunction=Modal.prototype._resetAdjustments;Modal.prototype._resetAdjustments=function(){const document=this._element.ownerDocument;document.body.classList.remove('modal-open');const $scrollable=$().getScrollingElement(document);if(document.body.contains($scrollable[0])){$scrollable.compensateScrollbar(false);}
return bsResetAdjustmentsFunction.apply(this,arguments);};return __exports;});;

/* /web/static/src/legacy/js/libs/jquery.js */
odoo.define('@web/legacy/js/libs/jquery',[],function(require){'use strict';let __exports={};$.extend($.expr[':'],{containsLike:function(element,index,matches){return element.innerHTML.toUpperCase().indexOf(matches[3].toUpperCase())>=0;},containsTextLike:function(element,index,matches){return element.innerText.toUpperCase().indexOf(matches[3].toUpperCase())>=0;},containsExact:function(element,index,matches){return $.trim(element.innerHTML)===matches[3];},containsExactText:function(element,index,matches){return element.innerText.trim()===matches[3].trim();},containsRegex:function(element,index,matches){var regreg=/^\/((?:\\\/|[^\/])+)\/([mig]{0,3})$/,reg=regreg.exec(matches[3]);return reg?new RegExp(reg[1],reg[2]).test($.trim(element.innerHTML)):false;},propChecked:function(element,index,matches){return $(element).prop("checked")===true;},propSelected:function(element,index,matches){return $(element).prop("selected")===true;},propValue:function(element,index,matches){return $(element).prop("value")===matches[3];},propValueContains:function(element,index,matches){return $(element).prop("value")&&$(element).prop("value").indexOf(matches[3])!==-1;},hasData:function(element){return!!_.toArray(element.dataset).length;},data:function(element,index,matches){return $(element).data(matches[3]);},hasVisibility:function(element,index,matches){var $element=$(element);if($(element).css('visibility')==='hidden'){return false;}
var $parent=$element.parent();if(!$parent.length||$element.is('html')){return true;}
return $parent.is(':hasVisibility');},hasOpacity:function(element,index,matches){var $element=$(element);if(parseFloat($(element).css('opacity'))<=0.01){return false;}
var $parent=$element.parent();if(!$parent.length||$element.is('html')){return true;}
return $parent.is(':hasOpacity');},});$.fn.extend({getAttributes:function(){var o={};if(this.length){var attrs=this[0].attributes;for(var i=0,l=attrs.length;i<l;i++){var attr=attrs.item(i);o[attr.name]=attr.value;}}
return o;},odooBounce:function(extraClass){for(const el of this){el.classList.add('o_catch_attention',extraClass);setTimeout(()=>el.classList.remove('o_catch_attention',extraClass),400);}
return this;},prependEvent:function(events,selector,data,handler){this.on.apply(this,arguments);events=events.split(' ');return this.each(function(){var el=this;events.forEach((evNameNamespaced)=>{var evName=evNameNamespaced.split('.')[0];var handler=$._data(el,'events')[evName].pop();$._data(el,'events')[evName].unshift(handler);});});},closestScrollable(){const document=this.length?this[0].ownerDocument:window.document;let $el=this;while($el[0]!==document.scrollingElement){if(!$el.length||$el[0]instanceof Document){return $();}
if($el.isScrollable()){return $el;}
$el=$el.parent();}
return $el;},compensateScrollbar(add=true,isScrollElement=true,cssProperty='padding-right'){for(const el of this){const scrollableEl=isScrollElement?el:$(el).parent().closestScrollable()[0];const isRTL=scrollableEl.matches(".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');}},getScrollingElement(document=window.document){const $baseScrollingElement=$(document.scrollingElement);if($baseScrollingElement.isScrollable()&&$baseScrollingElement.hasScrollableContent()){return $baseScrollingElement;}
const bodyHeight=$(document.body).height();for(const el of document.body.children){if(bodyHeight-el.scrollHeight>1.5){continue;}
const $el=$(el);if($el.isScrollable()){return $el;}}
return $baseScrollingElement;},getScrollingTarget(contextItem=window.document){const isElement=obj=>obj&&obj.nodeType===Node.ELEMENT_NODE;const isJQuery=obj=>obj&&('jquery'in obj);const $scrollingElement=isElement(contextItem)?$(contextItem):isJQuery(contextItem)?contextItem:$().getScrollingElement(contextItem);const document=$scrollingElement[0].ownerDocument;return $scrollingElement.is(document.scrollingElement)?$(document.defaultView):$scrollingElement;},hasScrollableContent(){return this[0].scrollHeight>this[0].clientHeight;},isScrollable(){if(!this.length){return false;}
const overflow=this.css('overflow-y');const el=this[0];return overflow==='auto'||overflow==='scroll'||(overflow==='visible'&&el===el.ownerDocument.scrollingElement);},});const originalScrollTop=$.fn.scrollTop;$.fn.scrollTop=function(value){if(value!==undefined&&this.filter('html, body').length){const $withRealScrollable=this.not('html, body').add($().getScrollingElement(this[0].ownerDocument));originalScrollTop.apply($withRealScrollable,arguments);return this;}else if(value===undefined&&this.eq(0).is('html, body')){return originalScrollTop.apply($().getScrollingElement(this[0].ownerDocument),arguments);}
return originalScrollTop.apply(this,arguments);};const originalAnimate=$.fn.animate;$.fn.animate=function(properties,...rest){const props=Object.assign({},properties);if('scrollTop'in props&&this.filter('html, body').length){const $withRealScrollable=this.not('html, body').add($().getScrollingElement(this[0].ownerDocument));originalAnimate.call($withRealScrollable,{'scrollTop':props['scrollTop']},...rest);delete props['scrollTop'];}
if(!Object.keys(props).length){return this;}
return originalAnimate.call(this,props,...rest);};return __exports;});;

/* /web/static/src/legacy/js/core/class.js */
odoo.define('@web/legacy/js/core/class',[],function(require){'use strict';let __exports={};function OdooClass(){}
var initializing=false;var fnTest=/xyz/.test(function(){xyz();})?/\b_super\b/:/.*/;OdooClass.extend=function(){var _super=this.prototype;var args=[...arguments];args.unshift({});const prop={};args.forEach((arg)=>{Object.assign(prop,arg);});initializing=true;var This=this;var prototype=new This();initializing=false;Object.keys(prop).forEach((name)=>{prototype[name]=typeof prop[name]=="function"&&fnTest.test(prop[name])?(function(name,fn){return function(){var tmp=this._super;this._super=_super[name];var ret=fn.apply(this,arguments);this._super=tmp;return ret;};})(name,prop[name]):prop[name];});function Class(){if(this.constructor!==OdooClass){throw new Error("You can only instanciate objects with the 'new' operator");}
this._super=null;if(!initializing&&this.init){var ret=this.init.apply(this,arguments);if(ret){return ret;}}
return this;}
Class.include=function(properties){Object.keys(properties).forEach((name)=>{if(typeof properties[name]!=='function'||!fnTest.test(properties[name])){prototype[name]=properties[name];}else if(typeof prototype[name]==='function'&&prototype.hasOwnProperty(name)){prototype[name]=(function(name,fn,previous){return function(){var tmp=this._super;this._super=previous;var ret=fn.apply(this,arguments);this._super=tmp;return ret;};})(name,properties[name],prototype[name]);}else if(typeof _super[name]==='function'){prototype[name]=(function(name,fn){return function(){var tmp=this._super;this._super=_super[name];var ret=fn.apply(this,arguments);this._super=tmp;return ret;};})(name,properties[name]);}});};Class.prototype=prototype;Class.constructor=Class;Class.extend=this.extend;return Class;};__exports[Symbol.for("default")]=OdooClass;return __exports;});;

/* /web/static/src/legacy/js/core/dialog.js */
odoo.define('@web/legacy/js/core/dialog',['@web/legacy/js/core/dom','@web/legacy/js/core/widget','@web/core/l10n/translation','@web/core/utils/render','@web/core/utils/functions'],function(require){'use strict';let __exports={};const dom=require("@web/legacy/js/core/dom")[Symbol.for("default")];const Widget=require("@web/legacy/js/core/widget")[Symbol.for("default")];const{_t}=require("@web/core/l10n/translation");const{renderToElement}=require("@web/core/utils/render");const{uniqueId}=require("@web/core/utils/functions");var Dialog=Widget.extend({tagName:'main',custom_events:Object.assign({},Widget.prototype.custom_events,{focus_control_button:'_onFocusControlButton',close_dialog:'_onCloseDialog',}),events:Object.assign({},Widget.prototype.events,{'keydown .modal-footer button':'_onFooterButtonKeyDown',}),init:function(parent,options){var self=this;this._super(parent);this._opened=new Promise(function(resolve){self._openedResolver=resolve;});if(this.on_attach_callback){this._opened=this.opened(this.on_attach_callback);}
options=Object.assign({title:_t('Odoo'),subtitle:'',size:'large',fullscreen:false,dialogClass:'',$content:false,buttons:[{text:_t("Ok"),close:true}],technical:true,$parentNode:false||$(document.body.querySelector(".o_dialog_container")),backdrop:'static',renderHeader:true,renderFooter:true,onForceClose:false,},options||{});this.$content=options.$content;this.title=options.title;this.subtitle=options.subtitle;this.fullscreen=options.fullscreen;this.dialogClass=options.dialogClass;this.size=options.size;this.buttons=options.buttons;this.technical=options.technical;this.$parentNode=options.$parentNode;this.backdrop=options.backdrop;this.renderHeader=options.renderHeader;this.renderFooter=options.renderFooter;this.onForceClose=options.onForceClose;},willStart:function(){var self=this;return this._super.apply(this,arguments).then(function(){self.$modal=$(renderToElement('web.DialogWidget',{fullscreen:self.fullscreen,title:self.title,subtitle:self.subtitle,technical:self.technical,renderHeader:self.renderHeader,renderFooter:self.renderFooter,uniqueId:uniqueId("modal_"),}));switch(self.size){case'extra-large':self.$modal.find('.modal-dialog').addClass('modal-xl');break;case'large':self.$modal.find('.modal-dialog').addClass('modal-lg');break;case'small':self.$modal.find('.modal-dialog').addClass('modal-sm');break;}
if(self.renderFooter){self.$footer=self.$modal.find(".modal-footer");self.set_buttons(self.buttons);}
self.$modal.on('hidden.bs.modal',self.destroy.bind(self));});},renderElement:function(){this._super();if(this.$content){this.setElement(this.$content);}
this.$el.addClass('modal-body '+this.dialogClass);},set_buttons:function(buttons){this._setButtonsTo(this.$footer,buttons);},set_title:function(title,subtitle){this.title=title||"";if(subtitle!==undefined){this.subtitle=subtitle||"";}
var $title=this.$modal.find('.modal-title').first();var $subtitle=$title.find('.o_subtitle').detach();$title.html(this.title);$subtitle.html(this.subtitle).appendTo($title);return this;},opened:function(handler){return(handler)?this._opened.then(handler):this._opened;},open:function(options){$('.tooltip').remove();var self=this;this.appendTo($('<div/>')).then(function(){if(self.isDestroyed()){return;}
self.$modal.find(".modal-body").replaceWith(self.$el);self.$modal.attr('open',true);if(self.$parentNode){self.$modal.appendTo(self.$parentNode);}
const modalNode=self.$modal[0];const modal=new Modal(modalNode,{backdrop:self.backdrop,keyboard:false,});modal.show();self._openedResolver();if(options&&options.shouldFocusButtons){self._onFocusControlButton();}});return self;},close:function(){this.destroy();},destroy:function(options){if(!this.__closed){this.__closed=true;this.trigger('closed',options);}
if(this.isDestroyed()){return;}
if(this.onForceClose){this.onForceClose();}
var isFocusSet=this._focusOnClose();this._super();$('.tooltip').remove();if(this.$modal){if(this.on_detach_callback){this.on_detach_callback();}
this.$modal.modal('hide');this.$modal.remove();}
const modals=$('.modal[role="dialog"]').filter(':visible').filter(this._isBlocking);if(modals.length){if(!isFocusSet){modals.last().focus();}
$('body').addClass('modal-open');}},rebindButtonBehavior:function(){this.$footer.on('keydown',this._onFooterButtonKeyDown);},_focusOnClose:function(){return false;},_setButtonsTo($target,buttons){var self=this;$target.empty();buttons.forEach((buttonData)=>{var $button=dom.renderButton({attrs:{class:buttonData.classes||(buttons.length>1?'btn-secondary':'btn-primary'),disabled:buttonData.disabled,'data-hotkey':buttonData.hotkey,},icon:buttonData.icon,text:buttonData.text,});$button.on('click',function(e){var def;if(buttonData.click){def=buttonData.click.call(self,e);}
if(buttonData.close){self.onForceClose=false;Promise.resolve(def).then(self.close.bind(self));}});if(self.technical){$target.append($button);}else{$target.prepend($button);}});},_isBlocking(index,el){return true;},_onCloseDialog:function(ev){ev.stopPropagation();this.close();},_onFocusControlButton:function(e){if(this.$footer){if(e){e.stopPropagation();}
this.$footer.find('.btn-primary:visible:first()').focus();}},_onFooterButtonKeyDown:function(e){switch(e.key){case"Tab":if(!e.shiftKey&&e.target.classList.contains("btn-primary")){e.preventDefault();var $primaryButton=$(e.target);$primaryButton.tooltip({delay:{show:200,hide:0},title:function(){return renderToElement('FormButton.tooltip',{title:$primaryButton.text().toUpperCase()});},trigger:'manual',});$primaryButton.tooltip('show');}
break;}}});Dialog.alert=function(owner,message,options){var buttons=[{text:_t("Ok"),close:true,click:options&&options.confirm_callback,}];return new Dialog(owner,Object.assign({size:'medium',buttons:buttons,$content:$('<main/>',{role:'alert',text:message,}),title:_t("Alert"),onForceClose:options&&(options.onForceClose||options.confirm_callback),},options)).open({shouldFocusButtons:true});};Dialog.confirm=function(owner,message,options){let isBlocked=false;function makeCallback(key){const callback=options&&options[key];return function(){if(isBlocked){return Promise.reject();}
isBlocked=true;const callbackRes=callback&&callback.apply(this,arguments);Promise.resolve(callbackRes).catch((e)=>{isBlocked=false;return Promise.reject(e);});return callbackRes;};}
var buttons=[{text:_t("Ok"),classes:'btn-primary',close:true,click:makeCallback('confirm_callback'),},{text:_t("Cancel"),close:true,click:makeCallback('cancel_callback'),}];return new Dialog(owner,Object.assign({size:'medium',buttons:buttons,$content:$('<main/>',{role:'alert',text:message,}),title:_t("Confirmation"),onForceClose:options&&(options.onForceClose||options.cancel_callback),},options)).open({shouldFocusButtons:true});};__exports[Symbol.for("default")]=Dialog;return __exports;});;

/* /web/static/src/legacy/js/core/dom.js */
odoo.define('@web/legacy/js/core/dom',['@web/legacy/js/core/minimal_dom'],function(require){'use strict';let __exports={};const minimalDom=require('@web/legacy/js/core/minimal_dom');const dom=Object.assign({},minimalDom,{cssFind:function($from,selector,addBack){var $results;var multiParts=selector.indexOf(' ')>=0;if(multiParts){$results=$from.closest('body').find(selector).filter((i,$el)=>$from.has($el).length);}else{$results=$from.find(selector);}
if(addBack&&$from.is(selector)){$results=$results.add($from);}
return $results;},renderButton:function(options){var jQueryParams=Object.assign({type:'button',},options.attrs||{});var extraClasses=jQueryParams.class;if(extraClasses){extraClasses=extraClasses.replace(/\boe_highlight\b/g,'btn-primary').replace(/\boe_link\b/g,'btn-link');}
jQueryParams.class='btn';if(options.size){jQueryParams.class+=(' btn-'+options.size);}
jQueryParams.class+=(' '+(extraClasses||'btn-secondary'));var $button=$('<button/>',jQueryParams);if(options.icon){if(options.icon.substr(0,3)==='fa-'){$button.append($('<i/>',{class:'fa fa-fw o_button_icon '+options.icon,}));}else{$button.append($('<img/>',{src:options.icon,}));}}
if(options.text){$button.append($('<span/>',{text:options.text,}));}
return $button;},scrollFixedOffset(document=window.document){let size=0;for(const el of document.querySelectorAll('.o_top_fixed_element')){size+=$(el).outerHeight();}
return size;},scrollTo(el,options={}){if(!el){throw new Error("The scrollTo function was called without any given element");}
const $el=$(el);if(typeof(el)==='string'&&$el[0]){el=$el[0];}
const isTopOrBottomHidden=(el==='#top'||el==='#bottom');const $scrollable=isTopOrBottomHidden?$().getScrollingElement():(options.$scrollable||$el.parent().closestScrollable());const scrollDocument=$scrollable[0].ownerDocument;const isInOneDocument=isTopOrBottomHidden||scrollDocument===$el[0].ownerDocument;const $iframe=!isInOneDocument&&$scrollable.find('iframe').filter((i,node)=>$(node).contents().has($el));const $topLevelScrollable=$().getScrollingElement(scrollDocument);const isTopScroll=$scrollable.is($topLevelScrollable);function _computeScrollTop(){if(el==='#top'||el.id==='top'){return 0;}
if(el==='#bottom'||el.id==='bottom'){return $scrollable[0].scrollHeight-$scrollable[0].clientHeight;}
el.classList.add("o_check_scroll_position");let offsetTop=$el.offset().top;el.classList.remove("o_check_scroll_position");if(el.classList.contains('d-none')){el.classList.remove('d-none');offsetTop=$el.offset().top;el.classList.add('d-none');}
const isDocScrollingEl=$scrollable.is(el.ownerDocument.scrollingElement);let elPosition=offsetTop
-($scrollable.offset().top-(isDocScrollingEl?0:$scrollable[0].scrollTop));if(!isInOneDocument&&$iframe.length){elPosition+=$iframe.offset().top;}
let offset=options.forcedOffset;if(offset===undefined){offset=(isTopScroll?dom.scrollFixedOffset(scrollDocument):0)+(options.extraOffset||0);}
return Math.max(0,elPosition-offset);}
const originalScrollTop=_computeScrollTop();return new Promise(resolve=>{const clonedOptions=Object.assign({},options);clonedOptions.progress=function(a,b,remainingMs){if(options.progress){options.progress.apply(this,...arguments);}
const newScrollTop=_computeScrollTop();if(Math.abs(newScrollTop-originalScrollTop)<=1.0&&(isTopOrBottomHidden||!(el.classList.contains('o_transitioning')))){return;}
$scrollable.stop();dom.scrollTo(el,Object.assign({},options,{duration:remainingMs,easing:'linear',})).then(()=>resolve());};clonedOptions.complete=function(){if(options.complete){options.complete.apply(this,...arguments);}
resolve();};$scrollable.animate({scrollTop:originalScrollTop},clonedOptions);});},});__exports[Symbol.for("default")]=dom;return __exports;});;

/* /web/static/src/legacy/js/core/mixins.js */
odoo.define('@web/legacy/js/core/mixins',['@web/core/utils/numbers'],function(require){'use strict';let __exports={};const{floatIsZero}=require("@web/core/utils/numbers");var ParentedMixin={__parentedMixin:true,init:function(){this.__parentedDestroyed=false;this.__parentedChildren=[];this.__parentedParent=null;},setParent:function(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:function(){return this.__parentedParent;},getChildren:function(){return[...this.__parentedChildren];},isDestroyed:function(){return this.__parentedDestroyed;},alive:function(promise,shouldReject){var self=this;return new Promise(function(resolve,reject){promise.then(function(result){if(!self.isDestroyed()){resolve(result);}else if(shouldReject){reject();}}).catch(function(reason){if(!self.isDestroyed()){reject(reason);}else if(shouldReject){reject();}});});},destroy:function(){this.getChildren().forEach(function(child){child.destroy();});this.setParent(undefined);this.__parentedDestroyed=true;},findAncestor:function(predicate){var ancestor=this;while(ancestor&&!(predicate(ancestor))&&ancestor.getParent){ancestor=ancestor.getParent();}
return ancestor;},};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;}}
var EventDispatcherMixin=Object.assign({},ParentedMixin,{__eventDispatcherMixin:true,custom_events:{},init:function(){ParentedMixin.init.call(this);this.__edispatcherEvents=new Events();this.__edispatcherRegisteredEvents=[];this._delegateCustomEvents();},proxy:function(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:function(){if(Object.keys(this.custom_events||{}).length===0){return;}
for(var key in this.custom_events){if(!this.custom_events.hasOwnProperty(key)){continue;}
var method=this.proxy(this.custom_events[key]);this.on(key,this,method);}},on:function(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:function(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;},once:function(events,dest,func){var self=this;if(typeof func!=="function"){throw new Error("Event handler must be a function.");}
self.on(events,dest,function what(){func.apply(this,arguments);self.off(events,dest,what);});},trigger:function(){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:function(){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);},});var PropertiesMixin=Object.assign({},EventDispatcherMixin,{init:function(){EventDispatcherMixin.init.call(this);this.__getterSetterInternalMap={};},set:function(arg1,arg2,arg3){var map;var options;if(typeof arg1==="string"){map={};map[arg1]=arg2;options=arg3||{};}else{map=arg1;options=arg2||{};}
var self=this;var changed=false;for(const[key,val]of Object.entries(map)){var tmp=self.__getterSetterInternalMap[key];if(tmp===val)
return;if(key==='value'&&self.field&&self.field.type==='float'&&tmp&&val){var digits=self.field.digits;if(Array.isArray(digits)){if(floatIsZero(tmp-val,digits[1])){return;}}}
changed=true;self.__getterSetterInternalMap[key]=val;if(!options.silent)
self.trigger("change:"+key,self,{oldValue:tmp,newValue:val});}
if(changed)
self.trigger("change",self);},get:function(key){return this.__getterSetterInternalMap[key];}});__exports[Symbol.for("default")]={ParentedMixin:ParentedMixin,EventDispatcherMixin:EventDispatcherMixin,PropertiesMixin:PropertiesMixin,};return __exports;});;

/* /web/static/src/legacy/js/core/service_mixins.js */
odoo.define('@web/legacy/js/core/service_mixins',['@web/env','@odoo/owl'],function(require){'use strict';let __exports={};const{SERVICES_METADATA}=require("@web/env");const{Component}=require("@odoo/owl");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);}});});};}
var 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;},};__exports[Symbol.for("default")]=ServicesMixin;return __exports;});;

/* /web/static/src/legacy/js/core/widget.js */
odoo.define('@web/legacy/js/core/widget',['@web/legacy/js/core/class','@web/legacy/js/core/mixins','@web/legacy/js/core/service_mixins','@web/core/assets','@web/core/utils/render'],function(require){'use strict';let __exports={};const Class=require("@web/legacy/js/core/class")[Symbol.for("default")];const mixins=require("@web/legacy/js/core/mixins")[Symbol.for("default")];const ServicesMixin=require("@web/legacy/js/core/service_mixins")[Symbol.for("default")];const{loadBundle}=require("@web/core/assets");const{renderToElement}=require("@web/core/utils/render");var Widget=__exports.Widget=Class.extend(mixins.PropertiesMixin,ServicesMixin,{tagName:'div',id:null,className:null,attributes:{},events:{},template:null,cssLibs:null,jsLibs:null,assetLibs:null,init:function(parent){mixins.PropertiesMixin.init.call(this);this.setParent(parent);for(var name in this){if(typeof(this[name])==="function"){if((/^on_|^do_/).test(name)){this[name]=this[name].bind(this);}}}},willStart:function(){var proms=[];if(this.jsLibs||this.cssLibs||this.assetLibs){proms.push(loadBundle(this));}
return Promise.all(proms);},start:function(){return Promise.resolve();},destroy:function(){mixins.PropertiesMixin.destroy.call(this);if(this.$el){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();});},do_hide:function(){if(this.$el){this.$el.addClass('o_hidden');}},do_show:function(){if(this.$el){this.$el.removeClass('o_hidden');}},do_toggle:function(display){if(typeof display==="boolean"){display?this.do_show():this.do_hide();}else if(this.$el){this.$el.hasClass('o_hidden')?this.do_show():this.do_hide();}},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();return this;},$:function(selector){if(selector===undefined){return this.$el;}
return this.$el.find(selector);},_delegateEvents:function(){var events=this.events;if(Object.keys(events||{}).length===0){return;}
for(var key in events){if(!events.hasOwnProperty(key)){continue;}
var method=this.proxy(events[key]);var match=/^(\S+)(\s+(.*))?$/.exec(key);var event=match[1];var selector=match[3];event+='.widget_events';if(!selector){this.$el.on(event,method);}else{this.$el.on(event,selector,method);}}},_makeDescriptive:function(){var attrs=Object.assign({},this.attributes||{});if(this.id){attrs.id=this.id;}
if(this.className){attrs['class']=this.className;}
var $el=$(document.createElement(this.tagName));if(Object.keys(attrs||{}).length>0){$el.attr(attrs);}
return $el;},_replaceElement:function($el){var $oldel=this.$el;this.setElement($el);if($oldel&&!$oldel.is(this.$el)){if($oldel.length>1){$oldel.wrapAll('<div/>');$oldel.parent().replaceWith(this.$el);}else{$oldel.replaceWith(this.$el);}}
return this;},_undelegateEvents:function(){this.$el.off('.widget_events');},_widgetRenderAndInsert:function(insertion,target){var self=this;return this.willStart().then(function(){if(self.__parentedDestroyed){return;}
self.renderElement();insertion(target);return self.start();});},});__exports[Symbol.for("default")]=Widget;return __exports;});;

/* /web/static/src/env.js */
odoo.define('@web/env',['@web/core/registry','@web/core/assets','@odoo/owl','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{templates}=require("@web/core/assets");const{App,EventBus}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");__exports.makeEnv=makeEnv;function makeEnv(){return{bus:new EventBus(),services:{},debug:odoo.debug,get isSmall(){throw new Error("UI service not initialized!");},};}
const serviceRegistry=registry.category("services");const SERVICES_METADATA=__exports.SERVICES_METADATA={};let startServicesPromise=null;__exports.startServices=startServices;async function startServices(env){await Promise.resolve();const toStart=new Set();serviceRegistry.addEventListener("UPDATE",async(ev)=>{await Promise.resolve();const{operation,key:name,value:service}=ev.detail;if(operation==="delete"){return;}
if(toStart.size){const namedService=Object.assign(Object.create(service),{name});toStart.add(namedService);}else{await _startServices(env,toStart);}});await _startServices(env,toStart);}
async function _startServices(env,toStart){if(startServicesPromise){return startServicesPromise.then(()=>_startServices(env,toStart));}
const services=env.services;for(const[name,service]of serviceRegistry.getEntries()){if(!(name in services)){const namedService=Object.assign(Object.create(service),{name});toStart.add(namedService);}}
async function start(){let service=null;const proms=[];while((service=findNext())){const name=service.name;toStart.delete(service);const entries=(service.dependencies||[]).map((dep)=>[dep,services[dep]]);const dependencies=Object.fromEntries(entries);let value;try{value=service.start(env,dependencies);}catch(e){value=e;console.error(e);}
if("async"in service){SERVICES_METADATA[name]=service.async;}
if(value instanceof Promise){proms.push(new Promise((resolve)=>{value.then((val)=>{services[name]=val||null;}).catch((error)=>{services[name]=error;console.error("Can't load service '"+name+"' because:",error);}).finally(resolve);}));}else{services[service.name]=value||null;}}
await Promise.all(proms);if(proms.length){return start();}}
startServicesPromise=start();await startServicesPromise;startServicesPromise=null;if(toStart.size){const names=[...toStart].map((s)=>s.name);const missingDeps=new Set();[...toStart].forEach((s)=>s.dependencies.forEach((dep)=>{if(!(dep in services)&&!names.includes(dep)){missingDeps.add(dep);}}));const depNames=[...missingDeps].join(", ");throw new Error(`Some services could not be started: ${names}. Missing dependencies: ${depNames}`);}
function findNext(){for(const s of toStart){if(s.dependencies){if(s.dependencies.every((d)=>d in services)){return s;}}else{return s;}}
return null;}}
__exports.mountComponent=mountComponent;async function mountComponent(component,target,appConfig={}){let{env}=appConfig;const isRoot=!env;if(isRoot){env=await makeEnv();await startServices(env);}
const app=new App(component,{env,templates,dev:env.debug,warnIfNoStaticProps:true,name:component.constructor.name,translatableAttributes:["data-tooltip"],translateFn:_t,...appConfig,});const root=await app.mount(target);if(isRoot){odoo.__WOWL_DEBUG__={root};}
return app;}
return __exports;});;

/* /web/static/src/core/action_swiper/action_swiper.js */
odoo.define('@web/core/action_swiper/action_swiper',['@web/core/browser/browser','@web/core/l10n/localization','@web/core/utils/numbers','@odoo/owl','@web/core/utils/concurrency'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{localization}=require("@web/core/l10n/localization");const{clamp}=require("@web/core/utils/numbers");const{Component,onMounted,onWillUnmount,useRef,useState}=require("@odoo/owl");const{Deferred}=require("@web/core/utils/concurrency");const isScrollSwipable=(scrollables)=>{return{left:!scrollables.filter((e)=>e.scrollLeft!==0).length,right:!scrollables.filter((e)=>e.scrollLeft+Math.round(e.getBoundingClientRect().width)!==e.scrollWidth).length,};};const ActionSwiper=__exports.ActionSwiper=class ActionSwiper extends Component{setup(){this.actionTimeoutId=null;this.resetTimeoutId=null;this.defaultState={containerStyle:"",isSwiping:false,width:undefined,};this.root=useRef("root");this.targetContainer=useRef("targetContainer");this.state=useState({...this.defaultState});this.scrollables=undefined;this.startX=undefined;this.swipedDistance=0;this.isScrollValidated=false;onMounted(()=>{if(this.targetContainer.el){this.state.width=this.targetContainer.el.getBoundingClientRect().width;}
if(this.props.onLeftSwipe||this.props.onRightSwipe){const classes=new Set(this.root.el.classList);classes.delete("o_actionswiper");for(const className of classes){this.targetContainer.el.firstChild.classList.add(className);this.root.el.classList.remove(className);}}});onWillUnmount(()=>{browser.clearTimeout(this.actionTimeoutId);browser.clearTimeout(this.resetTimeoutId);});}
get localizedProps(){return{onLeftSwipe:localization.direction==="rtl"?this.props.onRightSwipe:this.props.onLeftSwipe,onRightSwipe:localization.direction==="rtl"?this.props.onLeftSwipe:this.props.onRightSwipe,};}
_onTouchEndSwipe(){if(this.state.isSwiping){this.state.isSwiping=false;if(this.localizedProps.onRightSwipe&&this.swipedDistance>this.state.width/this.props.swipeDistanceRatio){this.swipedDistance=this.state.width;this.handleSwipe(this.localizedProps.onRightSwipe.action);}else if(this.localizedProps.onLeftSwipe&&this.swipedDistance<-this.state.width/this.props.swipeDistanceRatio){this.swipedDistance=-this.state.width;this.handleSwipe(this.localizedProps.onLeftSwipe.action);}else{this.state.containerStyle="";}}}
_onTouchMoveSwipe(ev){if(this.state.isSwiping){if(this.props.swipeInvalid&&this.props.swipeInvalid()){this.state.isSwiping=false;return;}
const{onLeftSwipe,onRightSwipe}=this.localizedProps;this.swipedDistance=clamp(ev.touches[0].clientX-this.startX,onLeftSwipe?-this.state.width:0,onRightSwipe?this.state.width:0);if(Math.abs(this.swipedDistance)>40){ev.preventDefault();}
if(!this.isScrollValidated&&this.scrollables&&!isScrollSwipable(this.scrollables)[this.swipedDistance>0?"left":"right"]){return this._reset();}
this.isScrollValidated=true;if(this.props.animationOnMove){this.state.containerStyle=`transform: translateX(${this.swipedDistance}px)`;}}}
_onTouchStartSwipe(ev){this.scrollables=ev.composedPath().filter((e)=>e.nodeType===1&&this.targetContainer.el.contains(e)&&e.scrollWidth>e.getBoundingClientRect().width&&["auto","scroll"].includes(window.getComputedStyle(e)["overflow-x"]));if(!this.state.width){this.state.width=this.targetContainer&&this.targetContainer.el.getBoundingClientRect().width;}
this.state.isSwiping=true;this.isScrollValidated=false;this.startX=ev.touches[0].clientX;}
_reset(){Object.assign(this.state,{...this.defaultState});this.scrollables=undefined;this.startX=undefined;this.swipedDistance=0;this.isScrollValidated=false;}
handleSwipe(action){if(this.props.animationType==="bounce"){this.state.containerStyle=`transform: translateX(${this.swipedDistance}px)`;this.actionTimeoutId=browser.setTimeout(async()=>{await action(Promise.resolve());this._reset();},500);}else if(this.props.animationType==="forwards"){this.state.containerStyle=`transform: translateX(${this.swipedDistance}px)`;this.actionTimeoutId=browser.setTimeout(async()=>{const prom=new Deferred();await action(prom);this.state.isSwiping=true;this.state.containerStyle=`transform: translateX(${-this.swipedDistance}px)`;this.resetTimeoutId=browser.setTimeout(()=>{prom.resolve();this._reset();},100);},100);}else{return action(Promise.resolve());}}}
ActionSwiper.props={onLeftSwipe:{type:Object,args:{action:Function,icon:String,bgColor:String,},optional:true,},onRightSwipe:{type:Object,args:{action:Function,icon:String,bgColor:String,},optional:true,},slots:Object,animationOnMove:{type:Boolean,optional:true},animationType:{type:String,optional:true},swipeDistanceRatio:{type:Number,optional:true},swipeInvalid:{type:Function,optional:true},};ActionSwiper.defaultProps={onLeftSwipe:undefined,onRightSwipe:undefined,animationOnMove:true,animationType:"bounce",swipeDistanceRatio:2,};ActionSwiper.template="web.ActionSwiper";return __exports;});;

/* /web/static/src/core/assets.js */
odoo.define('@web/core/assets',['@web/core/utils/functions','@web/core/browser/browser','@web/core/registry','@web/session','@odoo/owl'],function(require){'use strict';let __exports={};const{memoize}=require("@web/core/utils/functions");const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{session}=require("@web/session");const{Component,xml,onWillStart,App}=require("@odoo/owl");const assets=__exports.assets={retries:{count:3,delay:5000,extraDelay:2500,},};class AssetsLoadingError extends Error{}
assets.loadJS=memoize(function loadJS(url){if(document.querySelector(`script[src="${url}"]`)){return Promise.resolve();}
const scriptEl=document.createElement("script");scriptEl.type="text/javascript";scriptEl.src=url;document.head.appendChild(scriptEl);return new Promise((resolve,reject)=>{scriptEl.addEventListener("load",()=>resolve(true));scriptEl.addEventListener("error",()=>{reject(new AssetsLoadingError(`The loading of ${url} failed`));});});});assets.loadCSS=memoize(function loadCSS(url,retryCount=0){if(document.querySelector(`link[href="${url}"]`)){return Promise.resolve();}
const linkEl=document.createElement("link");linkEl.type="text/css";linkEl.rel="stylesheet";linkEl.href=url;const promise=new Promise((resolve,reject)=>{linkEl.addEventListener("load",()=>resolve(true));linkEl.addEventListener("error",async()=>{if(retryCount<assets.retries.count){await new Promise((resolve)=>setTimeout(resolve,assets.retries.delay+assets.retries.extraDelay*retryCount));linkEl.remove();loadCSS(url,retryCount+1).then(resolve).catch(reject);}else{reject(new AssetsLoadingError(`The loading of ${url} failed`));}});});document.head.appendChild(linkEl);return promise;});assets.getBundle=memoize(async function getBundle(bundleName){const url=new URL(`/web/bundle/${bundleName}`,location.origin);for(const[key,value]of Object.entries(session.bundle_params||{})){url.searchParams.set(key,value);}
const response=await browser.fetch(url.href);const json=await response.json();const assets={cssLibs:[],cssContents:[],jsLibs:[],jsContents:[],};for(const key in json){const file=json[key];if(file.type==="link"){assets.cssLibs.push(file.src);}else if(file.type==="style"){assets.cssContents.push(file.content);}else{if(file.src){assets.jsLibs.push(file.src);}else{assets.jsContents.push(file.content);}}}
return assets;});assets.loadBundle=async function loadBundle(desc){if(typeof desc==="string"){desc=await assets.getBundle(desc);}
const promiseCSS=Promise.all((desc.cssLibs||[]).map(assets.loadCSS)).then(()=>{if(desc.cssContents&&desc.cssContents.length){const style=document.createElement("style");style.textContent=desc.cssContents.join("\n");document.head.appendChild(style);}});for(const urlData of desc.jsLibs||[]){if(typeof urlData==="string"){await assets.loadJS(urlData);}else{await Promise.all(urlData.map(loadJS));}}
if(desc.jsContents&&desc.jsContents.length){const script=document.createElement("script");script.type="text/javascript";script.textContent=desc.jsContents.join("\n");document.head.appendChild(script);}
await promiseCSS;for(const bundleName of desc.assetLibs||[]){if(typeof bundleName==="string"){await assets.loadBundle(bundleName);}else{await Promise.all(bundleName.map(async(bundleName)=>{return assets.loadBundle(bundleName);}));}}
odoo.loader.checkAndReportErrors();};const loadJS=__exports.loadJS=function(url){return assets.loadJS(url);};const loadCSS=__exports.loadCSS=function(url){return assets.loadCSS(url);};const getBundle=__exports.getBundle=function(bundleName){return assets.getBundle(bundleName);};const loadBundle=__exports.loadBundle=function(desc){return assets.loadBundle(desc);};const templates=__exports.templates=new DOMParser().parseFromString("<odoo/>","text/xml");registry.category("xml_templates").addEventListener("UPDATE",(ev)=>{const{operation,value}=ev.detail;if(operation==="add"){const doc=new DOMParser().parseFromString(value,"text/xml");if(doc.querySelector("parsererror")){let strError="";const nodes=doc.querySelectorAll("parsererror");for(const node of nodes){strError+=node.textContent.trim()+"\n";}
throw new Error(strError);}
for(const element of doc.querySelectorAll("templates > [t-name]")){templates.documentElement.appendChild(element);}
for(const app of App.apps){app.addTemplates(templates,app);}}});const LazyComponent=__exports.LazyComponent=class LazyComponent extends Component{setup(){onWillStart(async()=>{await loadBundle(this.props.bundle);this.Component=registry.category("lazy_components").get(this.props.Component);});}}
LazyComponent.template=xml`<t t-component="Component" t-props="props.props"/>`;LazyComponent.props={Component:String,bundle:String,props:{type:Object,optional:true},};return __exports;});;

/* /web/static/src/core/autocomplete/autocomplete.js */
odoo.define('@web/core/autocomplete/autocomplete',['@web/core/utils/concurrency','@web/core/utils/hooks','@web/core/utils/timing','@web/core/hotkeys/hotkey_service','@web/core/position_hook','@odoo/owl'],function(require){'use strict';let __exports={};const{Deferred}=require("@web/core/utils/concurrency");const{useAutofocus,useForwardRefToParent,useService}=require("@web/core/utils/hooks");const{useDebounced}=require("@web/core/utils/timing");const{getActiveHotkey}=require("@web/core/hotkeys/hotkey_service");const{usePosition}=require("@web/core/position_hook");const{Component,onWillUpdateProps,useExternalListener,useRef,useState}=require("@odoo/owl");const AutoComplete=__exports.AutoComplete=class AutoComplete extends Component{setup(){this.nextSourceId=0;this.nextOptionId=0;this.sources=[];this.inEdition=false;this.state=useState({navigationRev:0,optionsRev:0,open:false,activeSourceOption:null,value:this.props.value,});this.inputRef=useForwardRefToParent("input");if(this.props.autofocus){useAutofocus({refName:"input"});}
this.root=useRef("root");this.debouncedProcessInput=useDebounced(async()=>{const currentPromise=this.pendingPromise;this.pendingPromise=null;this.props.onInput({inputValue:this.inputRef.el.value,});try{await this.open(true);currentPromise.resolve();}catch{currentPromise.reject();}finally{if(currentPromise===this.loadingPromise){this.loadingPromise=null;}}},this.constructor.timeout);useExternalListener(window,"scroll",this.externalClose,true);useExternalListener(window,"pointerdown",this.externalClose,true);this.hotkey=useService("hotkey");this.hotkeysToRemove=[];onWillUpdateProps((nextProps)=>{if(this.props.value!==nextProps.value||this.forceValFromProp){this.forceValFromProp=false;if(!this.inEdition){this.state.value=nextProps.value;this.inputRef.el.value=nextProps.value;}
this.close();}});if(this.props.dropdown){usePosition("sourcesList",()=>this.targetDropdown,this.dropdownOptions);}else{this.open(false);}}
get targetDropdown(){return this.inputRef.el;}
get activeSourceOptionId(){if(!this.isOpened||!this.state.activeSourceOption){return undefined;}
const[sourceIndex,optionIndex]=this.state.activeSourceOption;const source=this.sources[sourceIndex];return`${this.props.id || "autocomplete"}_${sourceIndex}_${source.isLoading ? "loading" : optionIndex}`;}
get dropdownOptions(){return{position:"bottom-start",};}
get isOpened(){return this.state.open;}
get hasOptions(){for(const source of this.sources){if(source.isLoading||source.options.length){return true;}}
return false;}
open(useInput=false){this.state.open=true;return this.loadSources(useInput);}
close(){this.state.open=false;this.state.activeSourceOption=null;}
cancel(){if(this.inputRef.el.value.length){if(this.props.autoSelect){this.inputRef.el.value=this.props.value;this.props.onCancel();}}
this.close();}
async loadSources(useInput){this.sources=[];this.state.activeSourceOption=null;const proms=[];for(const pSource of this.props.sources){const source=this.makeSource(pSource);this.sources.push(source);const options=this.loadOptions(pSource.options,useInput?this.inputRef.el.value.trim():"");if(options instanceof Promise){source.isLoading=true;const prom=options.then((options)=>{source.options=options.map((option)=>this.makeOption(option));source.isLoading=false;this.state.optionsRev++;});proms.push(prom);}else{source.options=options.map((option)=>this.makeOption(option));}}
await Promise.all(proms);this.navigate(0);}
get displayOptions(){return!this.props.dropdown||(this.isOpened&&this.hasOptions);}
loadOptions(options,request){if(typeof options==="function"){return options(request);}else{return options;}}
makeOption(option){return Object.assign(Object.create(option),{id:++this.nextOptionId,});}
makeSource(source){return{id:++this.nextSourceId,options:[],isLoading:false,placeholder:source.placeholder,optionTemplate:source.optionTemplate,};}
isActiveSourceOption([sourceIndex,optionIndex]){return(this.state.activeSourceOption&&this.state.activeSourceOption[0]===sourceIndex&&this.state.activeSourceOption[1]===optionIndex);}
selectOption(indices,params={}){const option=this.sources[indices[0]].options[indices[1]];this.inEdition=false;if(option.unselectable){this.inputRef.el.value="";this.close();return;}
if(this.props.resetOnSelect){this.inputRef.el.value="";}
this.forceValFromProp=true;this.props.onSelect(option,{...params,input:this.inputRef.el,});this.close();}
navigate(direction){let step=Math.sign(direction);if(!step){this.state.activeSourceOption=null;step=1;}else{this.state.navigationRev++;}
if(this.state.activeSourceOption){let[sourceIndex,optionIndex]=this.state.activeSourceOption;let source=this.sources[sourceIndex];optionIndex+=step;if(0>optionIndex||optionIndex>=source.options.length){sourceIndex+=step;source=this.sources[sourceIndex];while(source&&source.isLoading){sourceIndex+=step;source=this.sources[sourceIndex];}
if(source){optionIndex=step<0?source.options.length-1:0;}}
this.state.activeSourceOption=source?[sourceIndex,optionIndex]:null;}else{let sourceIndex=step<0?this.sources.length-1:0;let source=this.sources[sourceIndex];while(source&&source.isLoading){sourceIndex+=step;source=this.sources[sourceIndex];}
if(source){const optionIndex=step<0?source.options.length-1:0;if(optionIndex<source.options.length){this.state.activeSourceOption=[sourceIndex,optionIndex];}}}}
onInputBlur(){if(this.ignoreBlur){this.ignoreBlur=false;return;}
this.props.onBlur({inputValue:this.inputRef.el.value,});this.inEdition=false;}
onInputClick(){if(!this.isOpened){this.open(this.inputRef.el.value.trim()!==this.props.value);}else{this.close();}}
onInputChange(ev){if(this.ignoreBlur){ev.stopImmediatePropagation();}
this.props.onChange({inputValue:this.inputRef.el.value,});}
async onInput(){this.inEdition=true;this.pendingPromise=this.pendingPromise||new Deferred();this.loadingPromise=this.pendingPromise;this.debouncedProcessInput();}
onInputFocus(ev){this.inputRef.el.setSelectionRange(0,this.inputRef.el.value.length);this.props.onFocus(ev);}
get autoCompleteRootClass(){let classList="";if(this.props.class){classList+=this.props.class;}
if(this.props.dropdown){classList+=" dropdown";}
return classList;}
get ulDropdownClass(){let classList="";if(this.props.dropdown){classList+=" dropdown-menu ui-autocomplete";}else{classList+=" list-group";}
return classList;}
async onInputKeydown(ev){const hotkey=getActiveHotkey(ev);const isSelectKey=hotkey==="enter"||hotkey==="tab";if(this.loadingPromise&&isSelectKey){if(hotkey==="enter"){ev.stopPropagation();ev.preventDefault();}
await this.loadingPromise;}
switch(hotkey){case"enter":if(!this.isOpened||!this.state.activeSourceOption){return;}
this.selectOption(this.state.activeSourceOption);break;case"escape":if(!this.isOpened){return;}
this.cancel();break;case"tab":if(!this.isOpened){return;}
if(this.props.autoSelect&&this.state.activeSourceOption&&(this.state.navigationRev>0||this.inputRef.el.value.length>0)){this.selectOption(this.state.activeSourceOption);}
this.close();return;case"arrowup":this.navigate(-1);if(!this.isOpened){this.open(true);}
break;case"arrowdown":this.navigate(+1);if(!this.isOpened){this.open(true);}
break;default:return;}
ev.stopPropagation();ev.preventDefault();}
onOptionMouseEnter(indices){this.state.activeSourceOption=indices;}
onOptionMouseLeave(){this.state.activeSourceOption=null;}
onOptionClick(indices){this.selectOption(indices);this.inputRef.el.focus();}
externalClose(ev){if(this.isOpened&&!this.root.el.contains(ev.target)){this.cancel();}}}
Object.assign(AutoComplete,{template:"web.AutoComplete",props:{value:{type:String,optional:true},id:{type:String,optional:true},onSelect:{type:Function},sources:{type:Array,element:{type:Object,shape:{placeholder:{type:String,optional:true},optionTemplate:{type:String,optional:true},options:[Array,Function],},},},placeholder:{type:String,optional:true},autoSelect:{type:Boolean,optional:true},resetOnSelect:{type:Boolean,optional:true},onCancel:{type:Function,optional:true},onInput:{type:Function,optional:true},onChange:{type:Function,optional:true},onBlur:{type:Function,optional:true},onFocus:{type:Function,optional:true},input:{type:Function,optional:true},dropdown:{type:Boolean,optional:true},autofocus:{type:Boolean,optional:true},class:{type:String,optional:true},},defaultProps:{value:"",placeholder:"",autoSelect:false,dropdown:true,onCancel:()=>{},onInput:()=>{},onChange:()=>{},onBlur:()=>{},onFocus:()=>{},},timeout:250,});return __exports;});;

/* /web/static/src/core/browser/browser.js */
odoo.define('@web/core/browser/browser',[],function(require){'use strict';let __exports={};let sessionStorage=window.sessionStorage;let localStorage=window.localStorage;try{localStorage.setItem("__localStorage__","true");localStorage.removeItem("__localStorage__");}catch{localStorage=makeRAMLocalStorage();sessionStorage=makeRAMLocalStorage();}
const browser=__exports.browser={addEventListener:window.addEventListener.bind(window),dispatchEvent:window.dispatchEvent.bind(window),AnalyserNode:window.AnalyserNode,Audio:window.Audio,AudioBufferSourceNode:window.AudioBufferSourceNode,AudioContext:window.AudioContext,AudioWorkletNode:window.AudioWorkletNode,BeforeInstallPromptEvent:window.BeforeInstallPromptEvent?.bind(window),GainNode:window.GainNode,MediaStreamAudioSourceNode:window.MediaStreamAudioSourceNode,removeEventListener:window.removeEventListener.bind(window),setTimeout:window.setTimeout.bind(window),clearTimeout:window.clearTimeout.bind(window),setInterval:window.setInterval.bind(window),clearInterval:window.clearInterval.bind(window),performance:window.performance,requestAnimationFrame:window.requestAnimationFrame.bind(window),cancelAnimationFrame:window.cancelAnimationFrame.bind(window),console:window.console,history:window.history,matchMedia:window.matchMedia.bind(window),navigator,Notification:window.Notification,open:window.open.bind(window),SharedWorker:window.SharedWorker,Worker:window.Worker,XMLHttpRequest:window.XMLHttpRequest,localStorage,sessionStorage,fetch:window.fetch.bind(window),innerHeight:window.innerHeight,innerWidth:window.innerWidth,ontouchstart:window.ontouchstart,BroadcastChannel:window.BroadcastChannel,};Object.defineProperty(browser,"location",{set(val){window.location=val;},get(){return window.location;},configurable:true,});Object.defineProperty(browser,"innerHeight",{get:()=>window.innerHeight,configurable:true,});Object.defineProperty(browser,"innerWidth",{get:()=>window.innerWidth,configurable:true,});__exports.makeRAMLocalStorage=makeRAMLocalStorage;function makeRAMLocalStorage(){let store={};return{setItem(key,value){const newValue=String(value);store[key]=newValue;window.dispatchEvent(new StorageEvent("storage",{key,newValue}));},getItem(key){return store[key];},clear(){store={};},removeItem(key){delete store[key];window.dispatchEvent(new StorageEvent("storage",{key,newValue:null}));},get length(){return Object.keys(store).length;},key(){return"";},};}
return __exports;});;

/* /web/static/src/core/browser/feature_detection.js */
odoo.define('@web/core/browser/feature_detection',['@web/core/browser/browser'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");__exports.isBrowserChrome=isBrowserChrome;function isBrowserChrome(){return/Chrome/i.test(browser.navigator.userAgent);}
__exports.isBrowserFirefox=isBrowserFirefox;function isBrowserFirefox(){return/Firefox/i.test(browser.navigator.userAgent);}
__exports.isBrowserSafari=isBrowserSafari;function isBrowserSafari(){return!isBrowserChrome()&&browser.navigator.userAgent.includes("Safari");}
__exports.isAndroid=isAndroid;function isAndroid(){return/Android/i.test(browser.navigator.userAgent);}
__exports.isIOS=isIOS;function isIOS(){return(/(iPad|iPhone|iPod)/i.test(browser.navigator.userAgent)||(browser.navigator.platform==="MacIntel"&&maxTouchPoints()>1));}
__exports.isOtherMobileOS=isOtherMobileOS;function isOtherMobileOS(){return/(webOS|BlackBerry|Windows Phone)/i.test(browser.navigator.userAgent);}
__exports.isMacOS=isMacOS;function isMacOS(){return/Mac/i.test(browser.navigator.userAgent);}
__exports.isMobileOS=isMobileOS;function isMobileOS(){return isAndroid()||isIOS()||isOtherMobileOS();}
__exports.isIosApp=isIosApp;function isIosApp(){return/OdooMobile \(iOS\)/i.test(browser.navigator.userAgent);}
__exports.isAndroidApp=isAndroidApp;function isAndroidApp(){return/OdooMobile.+Android/i.test(browser.navigator.userAgent);}
__exports.isDisplayStandalone=isDisplayStandalone;function isDisplayStandalone(){return browser.matchMedia("(display-mode: standalone)").matches;}
__exports.hasTouch=hasTouch;function hasTouch(){return browser.ontouchstart!==undefined||browser.matchMedia("(pointer:coarse)").matches;}
__exports.maxTouchPoints=maxTouchPoints;function maxTouchPoints(){return browser.navigator.maxTouchPoints||1;}
return __exports;});;

/* /web/static/src/core/browser/router_service.js */
odoo.define('@web/core/browser/router_service',['@web/core/registry','@web/core/utils/objects','@web/core/utils/urls','@web/core/browser/browser'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{shallowEqual}=require("@web/core/utils/objects");const{objectToUrlEncodedString}=require("@web/core/utils/urls");const{browser}=require("@web/core/browser/browser");function cast(value){return!value||isNaN(value)?value:Number(value);}
function parseString(str){const parts=str.split("&");const result={};for(const part of parts){const[key,value]=part.split("=");const decoded=decodeURIComponent(value||"");result[key]=cast(decoded);}
return result;}
function applyLocking(lockedKeys,hash,currentHash,options={}){const newHash={};for(const key in hash){if("lock"in options){options.lock?lockedKeys.add(key):lockedKeys.delete(key);}else if(lockedKeys.has(key)){continue;}
newHash[key]=hash[key];}
for(const key in currentHash){if(lockedKeys.has(key)&&!(key in newHash)){newHash[key]=currentHash[key];}}
return newHash;}
function computeNewRoute(hash,replace,currentRoute){if(!replace){hash=Object.assign({},currentRoute.hash,hash);}
hash=sanitizeHash(hash);if(!shallowEqual(currentRoute.hash,hash)){return Object.assign({},currentRoute,{hash});}
return false;}
function sanitizeHash(hash){return Object.fromEntries(Object.entries(hash).filter(([,v])=>v!==undefined).map(([k,v])=>[k,cast(v)]));}
__exports.parseHash=parseHash;function parseHash(hash){return hash&&hash!=="#"?parseString(hash.slice(1)):{};}
__exports.parseSearchQuery=parseSearchQuery;function parseSearchQuery(search){return search?parseString(search.slice(1)):{};}
__exports.routeToUrl=routeToUrl;function routeToUrl(route){const search=objectToUrlEncodedString(route.search);const hash=objectToUrlEncodedString(route.hash);return route.pathname+(search?"?"+search:"")+(hash?"#"+hash:"");}
function getRoute(urlObj){const{pathname,search,hash}=urlObj;const searchQuery=parseSearchQuery(search);const hashQuery=parseHash(hash);return{pathname,search:searchQuery,hash:hashQuery};}
function makeRouter(env){const bus=env.bus;const lockedKeys=new Set();let current=getRoute(browser.location);let pushTimeout;browser.addEventListener("hashchange",(ev)=>{browser.clearTimeout(pushTimeout);const loc=new URL(ev.newURL);current=getRoute(loc);bus.trigger("ROUTE_CHANGE");});function makeDebouncedPush(mode){let allPushArgs=[];function doPush(){const replace=allPushArgs.some(([,options])=>options&&options.replace);const newHash=allPushArgs.reduce((finalHash,[hash,options])=>{hash=applyLocking(lockedKeys,hash,current.hash,options);if(finalHash){hash=applyLocking(lockedKeys,hash,finalHash,options);}
return Object.assign(finalHash||{},hash);},null);const newRoute=computeNewRoute(newHash,replace,current);if(!newRoute){return;}
const url=browser.location.origin+routeToUrl(newRoute);if(mode==="push"){browser.history.pushState({},"",url);}else{browser.history.replaceState({},"",url);}
current=getRoute(browser.location);}
return function pushOrReplaceState(hash,options){allPushArgs.push([hash,options]);browser.clearTimeout(pushTimeout);pushTimeout=browser.setTimeout(()=>{doPush();pushTimeout=null;allPushArgs=[];});};}
return{get current(){return current;},pushState:makeDebouncedPush("push"),replaceState:makeDebouncedPush("replace"),cancelPushes:()=>browser.clearTimeout(pushTimeout),};}
const routerService=__exports.routerService={start(env){return makeRouter(env);},};__exports.objectToQuery=objectToQuery;function objectToQuery(obj){const query={};Object.entries(obj).forEach(([k,v])=>{query[k]=v?String(v):v;});return query;}
registry.category("services").add("router",routerService);return __exports;});;

/* /web/static/src/core/checkbox/checkbox.js */
odoo.define('@web/core/checkbox/checkbox',['@web/core/hotkeys/hotkey_hook','@odoo/owl'],function(require){'use strict';let __exports={};const{useHotkey}=require("@web/core/hotkeys/hotkey_hook");const{Component,useRef}=require("@odoo/owl");const CheckBox=__exports.CheckBox=class CheckBox extends Component{setup(){this.id=`checkbox-comp-${CheckBox.nextId++}`;this.rootRef=useRef("root");useHotkey("Enter",({area})=>{const oldValue=area.querySelector("input").checked;this.props.onChange(!oldValue);},{area:()=>this.rootRef.el,bypassEditableProtection:true});}
onClick(ev){if(ev.composedPath().find((el)=>["INPUT","LABEL"].includes(el.tagName))){ev.stopPropagation();return;}
const input=this.rootRef.el.querySelector("input");input.focus();if(!this.props.disabled){ev.stopPropagation();input.checked=!input.checked;this.props.onChange(input.checked);}}
onChange(ev){if(!this.props.disabled){this.props.onChange(ev.target.checked);}}}
CheckBox.template="web.CheckBox";CheckBox.nextId=1;CheckBox.defaultProps={onChange:()=>{},};CheckBox.props={id:{type:true,optional:true,},disabled:{type:Boolean,optional:true,},value:{type:Boolean,optional:true,},slots:{type:Object,optional:true,},onChange:{type:Function,optional:true,},className:{type:String,optional:true,},name:{type:String,optional:true,},};return __exports;});;

/* /web/static/src/core/code_editor/code_editor.js */
odoo.define('@web/core/code_editor/code_editor',['@odoo/owl','@web/core/assets','@web/core/utils/timing'],function(require){'use strict';let __exports={};const{Component,onWillDestroy,onWillStart,useEffect,useRef}=require("@odoo/owl");const{loadBundle}=require("@web/core/assets");const{useDebounced}=require("@web/core/utils/timing");function onResized(ref,callback){const _ref=typeof ref==="string"?useRef(ref):ref;const resizeObserver=new ResizeObserver(callback);useEffect((el)=>{if(el){resizeObserver.observe(el);return()=>resizeObserver.unobserve(el);}},()=>[_ref.el]);onWillDestroy(()=>{resizeObserver.disconnect();});}
const CodeEditor=__exports.CodeEditor=class CodeEditor extends Component{static template="web.CodeEditor";static components={};static props={mode:{type:String,optional:true,validate:(mode)=>CodeEditor.MODES.includes(mode),},value:{validate:(v)=>typeof v==="string",optional:true},readonly:{type:Boolean,optional:true},onChange:{type:Function,optional:true},onBlur:{type:Function,optional:true},class:{type:String,optional:true},theme:{type:String,optional:true,validate:(theme)=>CodeEditor.THEMES.includes(theme),},maxLines:{type:Number,optional:true},sessionId:{type:[Number,String],optional:true},};static defaultProps={readonly:false,value:"",onChange:()=>{},class:"",theme:"",sessionId:1,};static MODES=["js","xml","qweb","scss","python"];static THEMES=["","monokai"];setup(){this.editorRef=useRef("editorRef");onWillStart(async()=>await loadBundle("web.ace_lib"));const sessions={};let ignoredAceChange=false;useEffect((el)=>{if(!el){return;}
const aceEditor=window.ace.edit(el);this.aceEditor=aceEditor;this.aceEditor.setOptions({maxLines:this.props.maxLines,showPrintMargin:false,useWorker:false,});this.aceEditor.$blockScrolling=true;const session=aceEditor.getSession();if(!sessions[this.props.sessionId]){sessions[this.props.sessionId]=session;}
session.setValue(this.props.value);session.on("change",()=>{if(this.props.onChange&&!ignoredAceChange){this.props.onChange(this.aceEditor.getValue());}});this.aceEditor.on("blur",()=>{if(this.props.onBlur){this.props.onBlur();}});return()=>{aceEditor.destroy();};},()=>[this.editorRef.el]);useEffect((theme)=>this.aceEditor.setTheme(theme?`ace/theme/${theme}`:""),()=>[this.props.theme]);useEffect((readonly)=>{this.aceEditor.setOptions({readOnly:readonly,highlightActiveLine:!readonly,highlightGutterLine:!readonly,});this.aceEditor.renderer.setOptions({displayIndentGuides:!readonly,showGutter:!readonly,});this.aceEditor.renderer.$cursorLayer.element.style.display=readonly?"none":"block";},()=>[this.props.readonly]);useEffect((sessionId,mode,value)=>{let session=sessions[sessionId];if(session){if(session.getValue()!==value){ignoredAceChange=true;session.setValue(value);ignoredAceChange=false;}}else{session=new window.ace.EditSession(value);session.setUndoManager(new window.ace.UndoManager());session.setOptions({useWorker:false,tabSize:2,useSoftTabs:true,});session.on("change",()=>{if(this.props.onChange&&!ignoredAceChange){this.props.onChange(this.aceEditor.getValue());}});sessions[sessionId]=session;}
session.setMode(mode?`ace/mode/${mode}`:"");this.aceEditor.setSession(session);},()=>[this.props.sessionId,this.props.mode,this.props.value]);const debouncedResize=useDebounced(()=>{if(this.aceEditor){this.aceEditor.resize();}},250);onResized(this.editorRef,debouncedResize);}}
return __exports;});;

/* /web/static/src/core/colorlist/colorlist.js */
odoo.define('@web/core/colorlist/colorlist',['@web/core/l10n/translation','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{Component,useRef,useState,useExternalListener}=require("@odoo/owl");const ColorList=__exports.ColorList=class ColorList extends Component{setup(){this.colorlistRef=useRef("colorlist");this.state=useState({isExpanded:this.props.isExpanded});useExternalListener(window,"click",this.onOutsideClick);}
get colors(){return this.constructor.COLORS;}
onColorSelected(id){this.props.onColorSelected(id);if(!this.props.forceExpanded){this.state.isExpanded=false;}}
onOutsideClick(ev){if(this.colorlistRef.el.contains(ev.target)||this.props.forceExpanded){return;}
this.state.isExpanded=false;}
onToggle(ev){if(this.props.canToggle){ev.preventDefault();ev.stopPropagation();this.state.isExpanded=!this.state.isExpanded;this.colorlistRef.el.firstElementChild.focus();}}}
ColorList.COLORS=[_t("No color"),_t("Red"),_t("Orange"),_t("Yellow"),_t("Cyan"),_t("Purple"),_t("Almond"),_t("Teal"),_t("Blue"),_t("Raspberry"),_t("Green"),_t("Violet"),];ColorList.template="web.ColorList";ColorList.defaultProps={forceExpanded:false,isExpanded:false,};ColorList.props={canToggle:{type:Boolean,optional:true},colors:Array,forceExpanded:{type:Boolean,optional:true},isExpanded:{type:Boolean,optional:true},onColorSelected:Function,selectedColor:{type:Number,optional:true},};return __exports;});;

/* /web/static/src/core/colorpicker/colorpicker.js */
odoo.define('@web/core/colorpicker/colorpicker',['@web/core/utils/colors','@web/core/utils/functions','@web/core/utils/numbers','@web/core/utils/timing','@odoo/owl'],function(require){'use strict';let __exports={};const{convertCSSColorToRgba,convertRgbaToCSSColor,convertRgbToHsl,convertHslToRgb,}=require("@web/core/utils/colors");const{uniqueId}=require("@web/core/utils/functions");const{clamp}=require("@web/core/utils/numbers");const{throttleForAnimation,debounce}=require("@web/core/utils/timing");const{Component,useRef,onWillStart,onMounted,onWillUpdateProps,onWillDestroy,}=require("@odoo/owl");const Colorpicker=__exports.Colorpicker=class Colorpicker extends Component{static template="web.Colorpicker";static props={document:{type:true,optional:true},defaultColor:{type:String,optional:true},selectedColor:{type:String,optional:true},noTransparency:{type:Boolean,optional:true},colorPreview:{type:Boolean,optional:true},stopClickPropagation:{type:Boolean,optional:true},onColorSelect:{type:Function,optional:true},onColorPreview:{type:Function,optional:true},onInputEnter:{type:Function,optional:true},};static defaultProps={document:window.document,defaultColor:"#FF0000",noTransparency:false,colorPreview:false,stopClickPropagation:false,onColorSelect:()=>{},onColorPreview:()=>{},onInputEnter:()=>{},};elRef=useRef("el");setup(){onWillStart(()=>{this.init();});onMounted(async()=>{if(!this.elRef.el){await new Promise((resolve)=>{const observer=new MutationObserver(()=>{if(this.elRef.el){observer.disconnect();resolve();}});observer.observe(document.body,{childList:true,subtree:true});});}
this.el=this.elRef.el;this.$el=$(this.el);this.$el.on("click",this._onClick.bind(this));this.$el.on("keypress",this._onKeypress.bind(this));this.$el.on("mousedown",".o_color_pick_area",this._onMouseDownPicker.bind(this));this.$el.on("mousedown",".o_color_slider",this._onMouseDownSlider.bind(this));this.$el.on("mousedown",".o_opacity_slider",this._onMouseDownOpacitySlider.bind(this));const debouncedOnChangeInputs=debounce(this._onChangeInputs.bind(this),10,true);this.$el.on("change",".o_color_picker_inputs",debouncedOnChangeInputs);this.start();});onWillUpdateProps((newProps)=>{if(!this.el){return;}
if(newProps.selectedColor){this.setSelectedColor(newProps.selectedColor);}});onWillDestroy(()=>{this.destroy();});}
init(){this.pickerFlag=false;this.sliderFlag=false;this.opacitySliderFlag=false;this.colorComponents={};this.uniqueId=uniqueId("colorpicker");this.selectedHexValue="";}
start(){this.$colorpickerArea=this.$el.find(".o_color_pick_area");this.$colorpickerPointer=this.$el.find(".o_picker_pointer");this.$colorSlider=this.$el.find(".o_color_slider");this.$colorSliderPointer=this.$el.find(".o_slider_pointer");this.$opacitySlider=this.$el.find(".o_opacity_slider");this.$opacitySliderPointer=this.$el.find(".o_opacity_pointer");const rgba=convertCSSColorToRgba(this.props.defaultColor);if(rgba){this._updateRgba(rgba.red,rgba.green,rgba.blue,rgba.opacity);}
Object.entries(this.colorComponents).forEach(([component,value])=>{const input=this.el.querySelector(`.o_${component}_input`);if(input){input.value=value;}});const resizeObserver=new window.ResizeObserver(()=>{this._updateUI();});resizeObserver.observe(this.el);this.$documents=$([window.top,...Array.from(window.top.frames).filter((frame)=>{try{const document=frame.document;return!!document;}catch{return false;}}),].map((w)=>w.document));this.throttleOnMouseMove=throttleForAnimation((ev)=>{this._onMouseMovePicker(ev);this._onMouseMoveSlider(ev);this._onMouseMoveOpacitySlider(ev);});this.$documents.on(`mousemove.${this.uniqueId}`,this.throttleOnMouseMove);this.$documents.on(`mouseup.${this.uniqueId}`,()=>{if(this.pickerFlag||this.sliderFlag||this.opacitySliderFlag){this._colorSelected();}
this.pickerFlag=false;this.sliderFlag=false;this.opacitySliderFlag=false;});this.previewActive=true;}
destroy(){if(this.throttleOnMouseMove){this.$documents.off(`.${this.uniqueId}`);this.throttleOnMouseMove.cancel();}}
setSelectedColor(color){const rgba=convertCSSColorToRgba(color);if(rgba){const oldPreviewActive=this.previewActive;this.previewActive=false;this._updateRgba(rgba.red,rgba.green,rgba.blue,rgba.opacity);this.previewActive=oldPreviewActive;this._updateUI();}}
_updateUI(){for(const[color,value]of Object.entries(this.colorComponents)){this.$el.find(`.o_${color}_input`).val(value);}
this.$el.find(".o_color_preview").css("background-color",this.colorComponents.cssColor);this.$colorpickerArea.css("background-color",`hsl(${this.colorComponents.hue}, 100%, 50%)`);const top=((100-this.colorComponents.lightness)*this.$colorpickerArea.height())/100;const left=(this.colorComponents.saturation*this.$colorpickerArea.width())/100;this.$colorpickerPointer.css({top:top-5+"px",left:left-5+"px",});const height=this.$colorSlider.height();const y=(this.colorComponents.hue*height)/360;this.$colorSliderPointer.css("top",Math.round(y-2));if(!this.props.noTransparency){const heightOpacity=this.$opacitySlider.height();const z=heightOpacity*(1-this.colorComponents.opacity/100.0);this.$opacitySliderPointer.css("top",Math.round(z-2));this.$opacitySlider.css("background","linear-gradient("+this.colorComponents.hex+" 0%, transparent 100%)");}}
_updateHex(hex){const rgb=convertCSSColorToRgba(hex);if(!rgb){return;}
Object.assign(this.colorComponents,{hex:hex},rgb,convertRgbToHsl(rgb.red,rgb.green,rgb.blue));this._updateCssColor();}
_updateRgba(r,g,b,a){const opacity=a||this.colorComponents.opacity;if(opacity<0.1&&(r>0.1||g>0.1||b>0.1)){a=100;}
const hex=convertRgbaToCSSColor(r,g,b);if(!hex){return;}
Object.assign(this.colorComponents,{red:r,green:g,blue:b},a===undefined?{}:{opacity:a},{hex:hex},convertRgbToHsl(r,g,b));this._updateCssColor();}
_updateHsl(h,s,l){let a=this.colorComponents.opacity;if(a<0.1&&l>0.1){a=100;}
const rgb=convertHslToRgb(h,s,l);if(!rgb){return;}
const hex=convertRgbaToCSSColor(rgb.red,rgb.green,rgb.blue);Object.assign(this.colorComponents,{hue:h,saturation:s,lightness:l},rgb,{hex:hex},{opacity:a});this._updateCssColor();}
_updateOpacity(a){if(a<0||a>100){return;}
Object.assign(this.colorComponents,{opacity:a});this._updateCssColor();}
_colorSelected(){this.props.onColorSelect(this.colorComponents);}
_updateCssColor(){const r=this.colorComponents.red;const g=this.colorComponents.green;const b=this.colorComponents.blue;const a=this.colorComponents.opacity;Object.assign(this.colorComponents,{cssColor:convertRgbaToCSSColor(r,g,b,a)});if(this.previewActive){this.props.onColorPreview(this.colorComponents);}}
_onKeypress(ev){if(ev.key==="Enter"){if(ev.target.tagName==="INPUT"){this._onChangeInputs(ev);}
ev.preventDefault();this.props.onInputEnter(ev);}}
_onClick(ev){if(this.props.stopClickPropagation){ev.stopPropagation();}
ev.originalEvent.__isColorpickerClick=true;$(ev.target).find("> .o_opacity_pointer, > .o_slider_pointer, > .o_picker_pointer").addBack(".o_opacity_pointer, .o_slider_pointer, .o_picker_pointer").focus();if(ev.target.dataset.colorMethod==="hex"&&!this.selectedHexValue){ev.target.select();this.selectedHexValue=ev.target.value;return;}
this.selectedHexValue="";}
_onMouseDownPicker(ev){this.pickerFlag=true;ev.preventDefault();this._onMouseMovePicker(ev);}
_onMouseMovePicker(ev){if(!this.pickerFlag){return;}
const offset=this.$colorpickerArea.offset();const top=ev.pageY-offset.top;const left=ev.pageX-offset.left;let saturation=Math.round((100*left)/this.$colorpickerArea.width());let lightness=Math.round((100*(this.$colorpickerArea.height()-top))/this.$colorpickerArea.height());saturation=clamp(saturation,0,100);lightness=clamp(lightness,0,100);this._updateHsl(this.colorComponents.hue,saturation,lightness);this._updateUI();}
_onMouseDownSlider(ev){this.sliderFlag=true;ev.preventDefault();this._onMouseMoveSlider(ev);}
_onMouseMoveSlider(ev){if(!this.sliderFlag){return;}
const y=ev.pageY-this.$colorSlider.offset().top;let hue=Math.round((360*y)/this.$colorSlider.height());hue=clamp(hue,0,360);this._updateHsl(hue,this.colorComponents.saturation,this.colorComponents.lightness);this._updateUI();}
_onMouseDownOpacitySlider(ev){this.opacitySliderFlag=true;ev.preventDefault();this._onMouseMoveOpacitySlider(ev);}
_onMouseMoveOpacitySlider(ev){if(!this.opacitySliderFlag||this.props.noTransparency){return;}
const y=ev.pageY-this.$opacitySlider.offset().top;let opacity=Math.round(100*(1-y/this.$opacitySlider.height()));opacity=clamp(opacity,0,100);this._updateOpacity(opacity);this._updateUI();}
_onChangeInputs(ev){switch($(ev.target).data("colorMethod")){case"hex":return;case"rgb":this._updateRgba(parseInt(this.$el.find(".o_red_input").val()),parseInt(this.$el.find(".o_green_input").val()),parseInt(this.$el.find(".o_blue_input").val()));break;case"hsl":this._updateHsl(parseInt(this.$el.find(".o_hue_input").val()),parseInt(this.$el.find(".o_saturation_input").val()),parseInt(this.$el.find(".o_lightness_input").val()));break;case"opacity":this._updateOpacity(parseInt(this.$el.find(".o_opacity_input").val()));break;}
this._updateUI();this._colorSelected();}
_onHexColorInput(ev){const hexColorValue=ev.target.value.replaceAll("#","");if(hexColorValue.length===6){this._updateHex(`#${hexColorValue}`);this._updateUI();this._colorSelected();}}}
return __exports;});;

/* /web/static/src/core/colors/colors.js */
odoo.define('@web/core/colors/colors',[],function(require){'use strict';let __exports={};const COLORS_BRIGHT=["#1f77b4","#ff7f0e","#aec7e8","#ffbb78","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5","#875a7b","#c49c94","#e377c2","#dcd0d9","#7f7f7f","#c7c7c7","#bcbd22","#dbdb8d","#17becf","#a5d8d7",];const COLORS_DARK=["#00ffff","#ff6347","#00ced1","#ffd700","#29ef29","#c5fabb","#fe4b4c","#ffb6c1","#ba87e9","#eadbf6","#c568af","#ecc1b8","#fda9e3","#BB86FC","#808080","#f2e8e8","#fcfe2d","#f8f8bc","#17becf","#10efed",];__exports.getColors=getColors;function getColors(colorScheme){return colorScheme==="dark"?COLORS_DARK:COLORS_BRIGHT;}
__exports.getColor=getColor;function getColor(index,colorScheme){const colors=getColors(colorScheme);return colors[index%colors.length];}
const DEFAULT_BG=__exports.DEFAULT_BG="#d3d3d3";__exports.getBorderWhite=getBorderWhite;function getBorderWhite(colorScheme){return colorScheme==="dark"?"rgba(0, 0, 0, 0.6)":"rgba(255,255,255,0.6)";}
const RGB_REGEX=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;__exports.hexToRGBA=hexToRGBA;function hexToRGBA(hex,opacity){const rgb=RGB_REGEX.exec(hex).slice(1,4).map((n)=>parseInt(n,16)).join(",");return`rgba(${rgb},${opacity})`;}
return __exports;});;

/* /web/static/src/core/confirmation_dialog/confirmation_dialog.js */
odoo.define('@web/core/confirmation_dialog/confirmation_dialog',['@web/core/dialog/dialog','@web/core/l10n/translation','@web/core/utils/hooks','@odoo/owl'],function(require){'use strict';let __exports={};const{Dialog}=require("@web/core/dialog/dialog");const{_t}=require("@web/core/l10n/translation");const{useChildRef}=require("@web/core/utils/hooks");const{Component}=require("@odoo/owl");const deleteConfirmationMessage=__exports.deleteConfirmationMessage=_t(`Ready to make your record disappear into thin air? Are you sure?
It will be gone forever!

Think twice before you click that 'Delete' button!`);const ConfirmationDialog=__exports.ConfirmationDialog=class ConfirmationDialog extends Component{setup(){this.env.dialogData.dismiss=()=>this._dismiss();this.modalRef=useChildRef();this.isProcess=false;}
async _cancel(){return this.execButton(this.props.cancel);}
async _confirm(){return this.execButton(this.props.confirm);}
async _dismiss(){return this.execButton(this.props.dismiss||this.props.cancel);}
setButtonsDisabled(disabled){this.isProcess=disabled;if(!this.modalRef.el){return;}
for(const button of[...this.modalRef.el.querySelectorAll(".modal-footer button")]){button.disabled=disabled;}}
async execButton(callback){if(this.isProcess){return;}
this.setButtonsDisabled(true);if(callback){let shouldClose;try{shouldClose=await callback();}catch(e){this.props.close();throw e;}
if(shouldClose===false){this.setButtonsDisabled(false);return;}}
this.props.close();}}
ConfirmationDialog.template="web.ConfirmationDialog";ConfirmationDialog.components={Dialog};ConfirmationDialog.props={close:Function,title:{validate:(m)=>{return(typeof m==="string"||(typeof m==="object"&&typeof m.toString==="function"));},optional:true,},body:String,confirm:{type:Function,optional:true},confirmLabel:{type:String,optional:true},confirmClass:{type:String,optional:true},cancel:{type:Function,optional:true},cancelLabel:{type:String,optional:true},dismiss:{type:Function,optional:true},};ConfirmationDialog.defaultProps={confirmLabel:_t("Ok"),cancelLabel:_t("Cancel"),confirmClass:"btn-primary",title:_t("Confirmation"),};const AlertDialog=__exports.AlertDialog=class AlertDialog extends ConfirmationDialog{}
AlertDialog.template="web.AlertDialog";AlertDialog.props={...ConfirmationDialog.props,contentClass:{type:String,optional:true},};AlertDialog.defaultProps={...ConfirmationDialog.defaultProps,title:_t("Alert"),};return __exports;});;

/* /web/static/src/core/context.js */
odoo.define('@web/core/context',['@web/core/py_js/py','@web/core/py_js/py_interpreter'],function(require){'use strict';let __exports={};const{evaluateExpr,parseExpr}=require("@web/core/py_js/py");const{evaluate}=require("@web/core/py_js/py_interpreter");__exports.makeContext=makeContext;function makeContext(contexts,initialEvaluationContext){const evaluationContext=Object.assign({},initialEvaluationContext);const context={};for(let ctx of contexts){if(ctx!==""){ctx=typeof ctx==="string"?evaluateExpr(ctx,evaluationContext):ctx;Object.assign(context,ctx);Object.assign(evaluationContext,context);}}
return context;}
__exports.evalPartialContext=evalPartialContext;function evalPartialContext(_context,evaluationContext={}){const ast=parseExpr(_context);const context={};for(const key in ast.value){const value=ast.value[key];try{context[key]=evaluate(value,evaluationContext);}catch{}}
return context;}
return __exports;});;

/* /web/static/src/core/currency.js */
odoo.define('@web/core/currency',['@web/core/utils/numbers','@web/session','@web/core/utils/strings'],function(require){'use strict';let __exports={};const{formatFloat,humanNumber}=require("@web/core/utils/numbers");const{session}=require("@web/session");const{nbsp}=require("@web/core/utils/strings");const currencies=__exports.currencies=session.currencies||{};delete session.currencies;__exports.getCurrency=getCurrency;function getCurrency(id){return currencies[id];}
__exports.formatCurrency=formatCurrency;function formatCurrency(amount,currencyId,options={}){const currency=getCurrency(currencyId);const digits=options.digits||(currency&&currency.digits);let formattedAmount;if(options.humanReadable){formattedAmount=humanNumber(amount,{decimals:digits?digits[1]:2});}else{formattedAmount=formatFloat(amount,{digits});}
if(!currency||options.noSymbol){return formattedAmount;}
const formatted=[currency.symbol,formattedAmount];if(currency.position==="after"){formatted.reverse();}
return formatted.join(nbsp);}
return __exports;});;

/* /web/static/src/core/datetime/datetime_hook.js */
odoo.define('@web/core/datetime/datetime_hook',['@odoo/owl','@web/core/popover/popover_hook','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{onPatched,onWillRender,useEffect,useRef}=require("@odoo/owl");const{usePopover}=require("@web/core/popover/popover_hook");const{useService}=require("@web/core/utils/hooks");__exports.useDateTimePicker=useDateTimePicker;function useDateTimePicker(hookParams){const datetimePicker=useService("datetime_picker");if(typeof hookParams.target==="string"){const target=useRef(hookParams.target);Object.defineProperty(hookParams,"target",{get(){return target.el;},});}
const inputRefs=[useRef("start-date"),useRef("end-date")];const getInputs=()=>inputRefs.map((ref)=>ref?.el);const{computeBasePickerProps,state,open,focusIfNeeded,enable}=datetimePicker.create(hookParams,getInputs,usePopover);onWillRender(computeBasePickerProps);useEffect(enable,getInputs);onPatched(focusIfNeeded);return{state,open};}
return __exports;});;

/* /web/static/src/core/datetime/datetime_input.js */
odoo.define('@web/core/datetime/datetime_input',['@odoo/owl','@web/core/utils/objects','@web/core/datetime/datetime_hook','@web/core/datetime/datetime_picker'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{omit}=require("@web/core/utils/objects");const{useDateTimePicker}=require("@web/core/datetime/datetime_hook");const{DateTimePicker}=require("@web/core/datetime/datetime_picker");const dateTimeInputOwnProps={format:{type:String,optional:true},id:{type:String,optional:true},onChange:{type:Function,optional:true},onApply:{type:Function,optional:true},placeholder:{type:String,optional:true},};const DateTimeInput=__exports.DateTimeInput=class DateTimeInput extends Component{static props={...DateTimePicker.props,...dateTimeInputOwnProps,};static template="web.DateTimeInput";setup(){const getPickerProps=()=>omit(this.props,...Object.keys(dateTimeInputOwnProps));useDateTimePicker({format:this.props.format,get pickerProps(){return getPickerProps();},onApply:(...args)=>this.props.onApply?.(...args),onChange:(...args)=>this.props.onChange?.(...args),});}}
return __exports;});;

/* /web/static/src/core/datetime/datetime_picker.js */
odoo.define('@web/core/datetime/datetime_picker',['@odoo/owl','@web/core/l10n/translation','@web/core/l10n/dates','@web/core/l10n/localization','@web/core/utils/arrays'],function(require){'use strict';let __exports={};const{Component,onWillRender,onWillUpdateProps,useState}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{MAX_VALID_DATE,MIN_VALID_DATE,clampDate,is24HourFormat,isInRange,isMeridiemFormat,today,}=require("@web/core/l10n/dates");const{localization}=require("@web/core/l10n/localization");const{ensureArray}=require("@web/core/utils/arrays");const{DateTime,Info}=luxon;const earliest=(date1,date2)=>(date1<date2?date1:date2);const getStartOfDecade=(date)=>Math.floor(date.year/10)*10;const getStartOfCentury=(date)=>Math.floor(date.year/100)*100;const getStartOfWeek=(date)=>{const{weekStart}=localization;return date.set({weekday:date.weekday<weekStart?weekStart-7:weekStart});};const latest=(date1,date2)=>(date1>date2?date1:date2);const numberRange=(min,max)=>[...Array(max-min)].map((_,i)=>i+min);const parseLimitDate=(value,defaultValue)=>clampDate(value==="today"?today():value||defaultValue,MIN_VALID_DATE,MAX_VALID_DATE);const toDateItem=({isOutOfRange=false,isValid=true,label,range,extraClass})=>({id:range[0].toISODate(),includesToday:isInRange(today(),range),isOutOfRange,isValid,label:String(range[0][label]),range,extraClass,});const toWeekItem=(weekDayItems)=>({number:weekDayItems[3].range[0].weekNumber,days:weekDayItems,});const HOURS=numberRange(0,24).map((hour)=>[hour,String(hour)]);const MINUTES=numberRange(0,60).map((minute)=>[minute,String(minute||0).padStart(2,"0")]);const SECONDS=[...MINUTES];const MERIDIEMS=["AM","PM"];const PRECISION_LEVELS=new Map().set("days",{mainTitle:_t("Select month"),nextTitle:_t("Next month"),prevTitle:_t("Previous month"),step:{month:1},getTitle:(date,{additionalMonth})=>{const titles=[`${date.monthLong} ${date.year}`];if(additionalMonth){const next=date.plus({month:1});titles.push(`${next.monthLong} ${next.year}`);}
return titles;},getItems:(date,{additionalMonth,maxDate,minDate,showWeekNumbers,isDateValid,dayCellClass})=>{const startDates=[date];if(additionalMonth){startDates.push(date.plus({month:1}));}
return startDates.map((date,i)=>{const monthRange=[date.startOf("month"),date.endOf("month")];const weeks=[];let startOfNextWeek=getStartOfWeek(monthRange[0]);for(let w=0;w<6;w++){const weekDayItems=[];for(let d=0;d<7;d++){const day=startOfNextWeek.plus({day:d});const range=[day,day.endOf("day")];const dayItem=toDateItem({isOutOfRange:!isInRange(day,monthRange),isValid:isInRange(range,[minDate,maxDate])&&isDateValid?.(day),label:"day",range,extraClass:dayCellClass?.(day)||"",});weekDayItems.push(dayItem);if(d===6){startOfNextWeek=day.plus({day:1});}}
weeks.push(toWeekItem(weekDayItems));}
const daysOfWeek=weeks[0].days.map((d)=>[d.range[0].weekdayShort,d.range[0].weekdayLong,Info.weekdays("narrow",{locale:d.range[0].locale})[d.range[0].weekday-1],]);if(showWeekNumbers){daysOfWeek.unshift(["#",_t("Week numbers"),"#"]);}
return{id:`__month__${i}`,number:monthRange[0].month,daysOfWeek,weeks,};});},}).set("months",{mainTitle:_t("Select year"),nextTitle:_t("Next year"),prevTitle:_t("Previous year"),step:{year:1},getTitle:(date)=>String(date.year),getItems:(date,{maxDate,minDate})=>{const startOfYear=date.startOf("year");return numberRange(0,12).map((i)=>{const startOfMonth=startOfYear.plus({month:i});const range=[startOfMonth,startOfMonth.endOf("month")];return toDateItem({isValid:isInRange(range,[minDate,maxDate]),label:"monthShort",range,});});},}).set("years",{mainTitle:_t("Select decade"),nextTitle:_t("Next decade"),prevTitle:_t("Previous decade"),step:{year:10},getTitle:(date)=>`${getStartOfDecade(date) - 1} - ${getStartOfDecade(date) + 10}`,getItems:(date,{maxDate,minDate})=>{const startOfDecade=date.startOf("year").set({year:getStartOfDecade(date)});return numberRange(-GRID_MARGIN,GRID_COUNT+GRID_MARGIN).map((i)=>{const startOfYear=startOfDecade.plus({year:i});const range=[startOfYear,startOfYear.endOf("year")];return toDateItem({isOutOfRange:i<0||i>=GRID_COUNT,isValid:isInRange(range,[minDate,maxDate]),label:"year",range,});});},}).set("decades",{mainTitle:_t("Select century"),nextTitle:_t("Next century"),prevTitle:_t("Previous century"),step:{year:100},getTitle:(date)=>`${getStartOfCentury(date) - 10} - ${getStartOfCentury(date) + 100}`,getItems:(date,{maxDate,minDate})=>{const startOfCentury=date.startOf("year").set({year:getStartOfCentury(date)});return numberRange(-GRID_MARGIN,GRID_COUNT+GRID_MARGIN).map((i)=>{const startOfDecade=startOfCentury.plus({year:i*10});const range=[startOfDecade,startOfDecade.plus({year:10,millisecond:-1})];return toDateItem({label:"year",isOutOfRange:i<0||i>=GRID_COUNT,isValid:isInRange(range,[minDate,maxDate]),range,});});},});const GRID_COUNT=10;const GRID_MARGIN=1;const NULLABLE_DATETIME_PROPERTY=[DateTime,{value:false},{value:null}];const DateTimePicker=__exports.DateTimePicker=class DateTimePicker extends Component{static props={focusedDateIndex:{type:Number,optional:true},showWeekNumbers:{type:Boolean,optional:true},daysOfWeekFormat:{type:String,optional:true},maxDate:{type:[NULLABLE_DATETIME_PROPERTY,{value:"today"}],optional:true},maxPrecision:{type:[...PRECISION_LEVELS.keys()].map((value)=>({value})),optional:true,},minDate:{type:[NULLABLE_DATETIME_PROPERTY,{value:"today"}],optional:true},minPrecision:{type:[...PRECISION_LEVELS.keys()].map((value)=>({value})),optional:true,},onSelect:{type:Function,optional:true},range:{type:Boolean,optional:true},rounding:{type:Number,optional:true},slots:{type:Object,shape:{bottom_left:{type:Object,optional:true},buttons:{type:Object,optional:true},},optional:true,},type:{type:[{value:"date"},{value:"datetime"}],optional:true},value:{type:[NULLABLE_DATETIME_PROPERTY,{type:Array,element:NULLABLE_DATETIME_PROPERTY},],optional:true,},isDateValid:{type:Function,optional:true},dayCellClass:{type:Function,optional:true},};static defaultProps={focusedDateIndex:0,daysOfWeekFormat:"short",maxPrecision:"decades",minPrecision:"days",rounding:5,type:"datetime",};static template="web.DateTimePicker";get activePrecisionLevel(){return PRECISION_LEVELS.get(this.state.precision);}
get isLastPrecisionLevel(){return(this.allowedPrecisionLevels.indexOf(this.state.precision)===this.allowedPrecisionLevels.length-1);}
get titles(){return ensureArray(this.title);}
setup(){this.availableHours=HOURS;this.availableMinutes=MINUTES;this.allowedPrecisionLevels=[];this.items=[];this.title="";this.shouldAdjustFocusDate=false;this.state=useState({focusDate:null,hoveredDate:null,timeValues:[],precision:this.props.minPrecision,});this.onPropsUpdated(this.props);onWillUpdateProps((nextProps)=>this.onPropsUpdated(nextProps));onWillRender(()=>this.onWillRender());}
onPropsUpdated(props){this.values=ensureArray(props.value).map((value)=>value&&!value.isValid?null:value);this.availableHours=HOURS;this.availableMinutes=MINUTES.filter((minute)=>!(minute[0]%props.rounding));this.availableSeconds=props.rounding?[]:SECONDS;this.allowedPrecisionLevels=this.filterPrecisionLevels(props.minPrecision,props.maxPrecision);this.additionalMonth=props.range&&!this.env.isSmall;this.maxDate=parseLimitDate(props.maxDate,MAX_VALID_DATE);this.minDate=parseLimitDate(props.minDate,MIN_VALID_DATE);if(this.props.type==="date"){this.maxDate=this.maxDate.endOf("day");this.minDate=this.minDate.startOf("day");}
if(this.maxDate<this.minDate){throw new Error(`DateTimePicker error: given "maxDate" comes before "minDate".`);}
const timeValues=this.values.map((val)=>[(val||DateTime.local()).hour,val?.minute||0,val?.second||0,]);if(props.range){this.state.timeValues=timeValues;}else{this.state.timeValues=[];this.state.timeValues[props.focusedDateIndex]=timeValues[props.focusedDateIndex];}
this.shouldAdjustFocusDate=!props.range;this.adjustFocus(this.values,props.focusedDateIndex);this.handle12HourSystem();this.state.timeValues=this.state.timeValues.map((timeValue)=>timeValue.map(String));}
onWillRender(){const{hoveredDate}=this.state;const precision=this.activePrecisionLevel;const getterParams={additionalMonth:this.additionalMonth,maxDate:this.maxDate,minDate:this.minDate,showWeekNumbers:this.props.showWeekNumbers??!this.props.range,isDateValid:this.props.isDateValid,dayCellClass:this.props.dayCellClass,};const referenceDate=this.state.focusDate;this.title=precision.getTitle(referenceDate,getterParams);this.items=precision.getItems(referenceDate,getterParams);this.selectedRange=[...this.values];this.highlightedRange=[...this.values];if(hoveredDate){[this.selectedRange]=this.applyValueAtIndex(hoveredDate,this.props.focusedDateIndex);if(this.props.range&&this.selectedRange.every(Boolean)){this.highlightedRange=[earliest(this.selectedRange[0],this.values[0]),latest(this.selectedRange[1],this.values[1]),];}}}
adjustFocus(values,focusedDateIndex){if(!this.shouldAdjustFocusDate&&this.state.focusDate&&focusedDateIndex===this.props.focusedDateIndex){return;}
let dateToFocus=values[focusedDateIndex]||values[focusedDateIndex===1?0:1]||today();if(this.additionalMonth&&focusedDateIndex===1&&values[0]&&values[1]&&values[0].month!==values[1].month){dateToFocus=dateToFocus.minus({month:1});}
this.shouldAdjustFocusDate=false;this.state.focusDate=this.clamp(dateToFocus.startOf("month"));}
applyValueAtIndex(value,valueIndex){const result=[...this.values];if(this.props.range){if((result[0]&&value.endOf("day")<result[0].startOf("day"))||(result[1]&&!result[0])){valueIndex=0;}else if((result[1]&&result[1].endOf("day")<value.startOf("day"))||(result[0]&&!result[1])){valueIndex=1;}}
result[valueIndex]=value;return[result,valueIndex];}
clamp(value){return clampDate(value,this.minDate,this.maxDate);}
filterPrecisionLevels(minPrecision,maxPrecision){const levels=[...PRECISION_LEVELS.keys()];return levels.slice(levels.indexOf(minPrecision),levels.indexOf(maxPrecision)+1);}
getActiveRangeInfo({isOutOfRange,range}){const result={isSelected:!isOutOfRange&&isInRange(this.selectedRange,range),isSelectStart:false,isSelectEnd:false,isHighlighted:!isOutOfRange&&isInRange(this.highlightedRange,range),isHighlightStart:false,isHighlightEnd:false,isCurrent:false,};if(this.props.range){if(result.isSelected){const[selectStart,selectEnd]=this.selectedRange;result.isSelectStart=!selectStart||isInRange(selectStart,range);result.isSelectEnd=!selectEnd||isInRange(selectEnd,range);}
if(result.isHighlighted){const[currentStart,currentEnd]=this.highlightedRange;result.isHighlightStart=!currentStart||isInRange(currentStart,range);result.isHighlightEnd=!currentEnd||isInRange(currentEnd,range);}
result.isCurrent=!isOutOfRange&&(isInRange(this.values[0],range)||isInRange(this.values[1],range));}else{result.isSelectStart=result.isSelectEnd=result.isSelected;result.isHighlightStart=result.isHighlightEnd=result.isHighlighted;}
return result;}
getTimeValues(valueIndex){let[hour,minute,second]=this.state.timeValues[valueIndex].map(Number);if(this.is12HourFormat&&this.meridiems&&this.state.timeValues[valueIndex][3]==="PM"){hour+=12;}
return[hour,minute,second];}
handle12HourSystem(){if(isMeridiemFormat()){this.meridiems=MERIDIEMS.map((m)=>[m,m]);for(const timeValues of this.state.timeValues){if(timeValues){timeValues.push(MERIDIEMS[Math.floor(timeValues[0]/12)||0]);}}}
this.is12HourFormat=!is24HourFormat();if(this.is12HourFormat){this.availableHours=[[0,HOURS[12][1]],...HOURS.slice(1,12)];for(const timeValues of this.state.timeValues){if(timeValues){timeValues[0]%=12;}}}}
isSelectedDate({range}){return this.values.some((value)=>isInRange(value,range));}
next(ev){ev.preventDefault();const{step}=this.activePrecisionLevel;this.state.focusDate=this.clamp(this.state.focusDate.plus(step));}
previous(ev){ev.preventDefault();const{step}=this.activePrecisionLevel;this.state.focusDate=this.clamp(this.state.focusDate.minus(step));}
selectTime(valueIndex){const value=this.values[valueIndex]||today();this.validateAndSelect(value,valueIndex);}
validateAndSelect(value,valueIndex){if(!this.props.onSelect){return false;}
const[result,finalIndex]=this.applyValueAtIndex(value,valueIndex);if(this.props.type==="datetime"){const[hour,minute,second]=this.getTimeValues(finalIndex);result[finalIndex]=result[finalIndex].set({hour,minute,second});}
if(!isInRange(result[finalIndex],[this.minDate,this.maxDate])){return false;}
this.props.onSelect(result.length===2?result:result[0]);return true;}
zoomIn(date){const index=this.allowedPrecisionLevels.indexOf(this.state.precision)-1;if(index in this.allowedPrecisionLevels){this.state.focusDate=this.clamp(date);this.state.precision=this.allowedPrecisionLevels[index];return true;}
return false;}
zoomOut(){const index=this.allowedPrecisionLevels.indexOf(this.state.precision)+1;if(index in this.allowedPrecisionLevels){this.state.precision=this.allowedPrecisionLevels[index];return true;}
return false;}
zoomOrSelect(dateItem){if(!dateItem.isValid){return;}
if(this.zoomIn(dateItem.range[0])){return;}
const[value]=dateItem.range;const valueIndex=this.props.focusedDateIndex;const isValid=this.validateAndSelect(value,valueIndex);this.shouldAdjustFocusDate=isValid&&!this.props.range;}}
return __exports;});;

/* /web/static/src/core/datetime/datetime_picker_popover.js */
odoo.define('@web/core/datetime/datetime_picker_popover',['@odoo/owl','@web/core/hotkeys/hotkey_hook','@web/core/datetime/datetime_picker'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{useHotkey}=require("@web/core/hotkeys/hotkey_hook");const{DateTimePicker}=require("@web/core/datetime/datetime_picker");const DateTimePickerPopover=__exports.DateTimePickerPopover=class DateTimePickerPopover extends Component{static components={DateTimePicker};static props={close:Function,pickerProps:{type:Object,shape:DateTimePicker.props},};static template="web.DateTimePickerPopover";get isDateTimeRange(){return(this.props.pickerProps.type==="datetime"||Array.isArray(this.props.pickerProps.value));}
setup(){useHotkey("enter",()=>this.props.close());}}
return __exports;});;

/* /web/static/src/core/datetime/datetimepicker_service.js */
odoo.define('@web/core/datetime/datetimepicker_service',['@odoo/owl','@web/core/l10n/dates','@web/core/popover/popover_hook','@web/core/registry','@web/core/utils/arrays','@web/core/utils/objects','@web/core/datetime/datetime_picker','@web/core/datetime/datetime_picker_popover'],function(require){'use strict';let __exports={};const{markRaw,reactive}=require("@odoo/owl");const{areDatesEqual,formatDate,formatDateTime,parseDate,parseDateTime}=require("@web/core/l10n/dates");const{makePopover}=require("@web/core/popover/popover_hook");const{registry}=require("@web/core/registry");const{ensureArray,zip,zipWith}=require("@web/core/utils/arrays");const{deepCopy,shallowEqual}=require("@web/core/utils/objects");const{DateTimePicker}=require("@web/core/datetime/datetime_picker");const{DateTimePickerPopover}=require("@web/core/datetime/datetime_picker_popover");const arePropsEqual=(obj1,obj2)=>shallowEqual(obj1,obj2,(a,b)=>areDatesEqual(a,b)||shallowEqual(a,b));const FOCUS_CLASSNAME="text-primary";const formatters={date:formatDate,datetime:formatDateTime,};const listenedElements=new WeakSet();const parsers={date:parseDate,datetime:parseDateTime,};const datetimePickerService=__exports.datetimePickerService={dependencies:["popover"],start(env,{popover:popoverService}){return{create:(hookParams,getInputs=()=>[hookParams.target,null],createPopover=(...args)=>makePopover(popoverService,...args))=>{const popover=createPopover(DateTimePickerPopover,{onClose:()=>{if(!allowOnClose){return;}
updateValueFromInputs();apply();setFocusClass(null);if(restoreTargetMargin){restoreTargetMargin();restoreTargetMargin=null;}},});const apply=()=>{if(areDatesEqual(lastInitialProps?.value,deepCopy(pickerProps.value))){return;}
inputsChanged=ensureArray(pickerProps.value).map(()=>false);hookParams.onApply?.(pickerProps.value);};const computeBasePickerProps=()=>{const nextInitialProps=markValuesRaw(hookParams.pickerProps);const propsCopy=deepCopy(nextInitialProps);if(lastInitialProps&&arePropsEqual(lastInitialProps,propsCopy)){return;}
lastInitialProps=propsCopy;inputsChanged=ensureArray(lastInitialProps.value).map(()=>false);for(const[key,value]of Object.entries(nextInitialProps)){if(pickerProps[key]!==value&&!areDatesEqual(pickerProps[key],value)){pickerProps[key]=value;}}};const focusActiveInput=()=>{const inputEl=getInput(pickerProps.focusedDateIndex);if(!inputEl){shouldFocus=true;return;}
const{activeElement}=inputEl.ownerDocument;if(activeElement!==inputEl){inputEl.focus();}
setInputFocus(inputEl);};const getInput=(valueIndex)=>{const el=getInputs()[valueIndex];if(el&&document.body.contains(el)){return el;}
return null;};const getPopoverTarget=()=>{if(hookParams.target){return hookParams.target;}
if(pickerProps.range){let parentElement=getInput(0).parentElement;const inputEls=getInputs();while(parentElement&&!inputEls.every((inputEl)=>parentElement.contains(inputEl))){parentElement=parentElement.parentElement;}
return parentElement||getInput(0);}else{return getInput(0);}};const markValuesRaw=(obj)=>{const copy={};for(const[key,value]of Object.entries(obj)){if(value&&typeof value==="object"){copy[key]=markRaw(value);}else{copy[key]=value;}}
return copy;};const onInputChange=(ev)=>{updateValueFromInputs();inputsChanged[ev.target===getInput(1)?1:0]=true;if(!popover.isOpen||inputsChanged.every(Boolean)){saveAndClose();}};const onInputClick=({target})=>{openPicker(target===getInput(1)?1:0);};const onInputFocus=({target})=>{pickerProps.focusedDateIndex=target===getInput(1)?1:0;setInputFocus(target);};const onInputKeydown=(ev)=>{switch(ev.key){case"Enter":case"Escape":{return saveAndClose();}
case"Tab":{if(!getInput(0)||!getInput(1)||ev.target!==getInput(ev.shiftKey?1:0)){return saveAndClose();}}}};const openPicker=(inputIndex)=>{pickerProps.focusedDateIndex=inputIndex;if(!popover.isOpen){const popoverTarget=getPopoverTarget();if(env.isSmall){const{marginBottom}=popoverTarget.style;popoverTarget.style.marginBottom=`100vh`;popoverTarget.scrollIntoView(true);restoreTargetMargin=async()=>{popoverTarget.style.marginBottom=marginBottom;};}
popover.open(popoverTarget,{pickerProps});}
focusActiveInput();};const safeConvert=(operation,value)=>{const{type}=pickerProps;const convertFn=(operation==="format"?formatters:parsers)[type];try{return[convertFn(value,{format:hookParams.format}),null];}catch(error){if(error?.name==="ConversionError"){return[null,error];}else{throw error;}}};const saveAndClose=()=>{if(popover.isOpen){popover.close();}else{apply();}};const setFocusClass=(input)=>{for(const el of getInputs()){if(el){el.classList.toggle(FOCUS_CLASSNAME,popover.isOpen&&el===input);}}};const setInputFocus=(inputEl)=>{inputEl.selectionStart=0;inputEl.selectionEnd=inputEl.value.length;setFocusClass(inputEl);shouldFocus=false;};const updateInput=(el,value)=>{if(!el){return;}
const[formattedValue]=safeConvert("format",value);el.value=formattedValue||"";};const updateValue=(value)=>{const previousValue=pickerProps.value;pickerProps.value=value;if(areDatesEqual(previousValue,pickerProps.value)){return;}
if(pickerProps.range){const[prevStart,prevEnd]=ensureArray(previousValue);const[nextStart,nextEnd]=ensureArray(pickerProps.value);if((pickerProps.focusedDateIndex===0&&areDatesEqual(prevEnd,nextEnd))||(pickerProps.focusedDateIndex===1&&areDatesEqual(prevStart,nextStart))){pickerProps.focusedDateIndex=pickerProps.focusedDateIndex===1?0:1;}}
hookParams.onChange?.(pickerProps.value);};const updateValueFromInputs=()=>{const values=zipWith(getInputs(),ensureArray(pickerProps.value),(el,currentValue)=>{if(!el){return currentValue;}
const[parsedValue,error]=safeConvert("parse",el.value);if(error){updateInput(el,currentValue);return currentValue;}else{return parsedValue;}});updateValue(values.length===2?values:values[0]);};const rawPickerProps={...DateTimePicker.defaultProps,onSelect:(value)=>{value&&=markRaw(value);updateValue(value);if(!pickerProps.range&&pickerProps.type==="date"){saveAndClose();}},...markValuesRaw(hookParams.pickerProps),};const pickerProps=reactive(rawPickerProps,()=>{const currentIsRange=pickerProps.range;if(popover.isOpen&&lastIsRange!==currentIsRange){allowOnClose=false;popover.open(getPopoverTarget(),{pickerProps});allowOnClose=true;}
lastIsRange=currentIsRange;for(const[el,value]of zip(getInputs(),ensureArray(pickerProps.value),true)){if(el){updateInput(el,value);}}
shouldFocus=true;});let allowOnClose=true;let inputsChanged=[];let lastInitialProps=null;let lastIsRange=pickerProps.range;let restoreTargetMargin=null;let shouldFocus=false;return{state:pickerProps,open:openPicker,computeBasePickerProps,focusIfNeeded(){if(popover.isOpen&&shouldFocus){focusActiveInput();}},enable(){let editableInputs=0;for(const[el,value]of zip(getInputs(),ensureArray(pickerProps.value),true)){updateInput(el,value);if(el&&!el.disabled&&!el.readOnly&&!listenedElements.has(el)){listenedElements.add(el);el.addEventListener("change",onInputChange);el.addEventListener("click",onInputClick);el.addEventListener("focus",onInputFocus);el.addEventListener("keydown",onInputKeydown);editableInputs++;}}
const calendarIconGroupEl=getInput(0)?.parentElement.querySelector(".input-group-text .fa-calendar")?.parentElement;if(calendarIconGroupEl&&!listenedElements.has(calendarIconGroupEl)){listenedElements.add(calendarIconGroupEl);calendarIconGroupEl.classList.remove("pe-none");calendarIconGroupEl.classList.add("cursor-pointer");calendarIconGroupEl.addEventListener("click",()=>openPicker(0));}
if(!editableInputs&&popover.isOpen){saveAndClose();}
return()=>{};},get isOpen(){return popover.isOpen;},};},};},};registry.category("services").add("datetime_picker",datetimePickerService);return __exports;});;

/* /web/static/src/core/debug/debug_context.js */
odoo.define('@web/core/debug/debug_context',['@web/core/registry','@web/core/utils/functions','@odoo/owl'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{memoize}=require("@web/core/utils/functions");const{useEffect,useEnv,useSubEnv}=require("@odoo/owl");const debugRegistry=registry.category("debug");const getAccessRights=memoize(async function getAccessRights(orm){const rightsToCheck={"ir.ui.view":"write","ir.rule":"read","ir.model.access":"read",};const proms=Object.entries(rightsToCheck).map(([model,operation])=>{return orm.call(model,"check_access_rights",[],{operation,raise_exception:false,});});const[canEditView,canSeeRecordRules,canSeeModelAccess]=await Promise.all(proms);const accessRights={canEditView,canSeeRecordRules,canSeeModelAccess};return accessRights;});class DebugContext{constructor(env,defaultCategories){this.orm=env.services.orm;this.categories=new Map(defaultCategories.map((cat)=>[cat,[{}]]));}
activateCategory(category,context){const contexts=this.categories.get(category)||new Set();contexts.add(context);this.categories.set(category,contexts);return()=>{contexts.delete(context);if(contexts.size===0){this.categories.delete(category);}};}
async getItems(env){const accessRights=await getAccessRights(this.orm);return[...this.categories.entries()].flatMap(([category,contexts])=>{return debugRegistry.category(category).getAll().map((factory)=>factory(Object.assign({env,accessRights},...contexts)));}).filter(Boolean).sort((x,y)=>{const xSeq=x.sequence||1000;const ySeq=y.sequence||1000;return xSeq-ySeq;});}}
const debugContextSymbol=Symbol("debugContext");__exports.createDebugContext=createDebugContext;function createDebugContext(env,{categories=[]}={}){return{[debugContextSymbol]:new DebugContext(env,categories)};}
__exports.useOwnDebugContext=useOwnDebugContext;function useOwnDebugContext({categories=[]}={}){useSubEnv(createDebugContext(useEnv(),{categories}));}
__exports.useEnvDebugContext=useEnvDebugContext;function useEnvDebugContext(){const debugContext=useEnv()[debugContextSymbol];if(!debugContext){throw new Error("There is no debug context available in the current environment.");}
return debugContext;}
__exports.useDebugCategory=useDebugCategory;function useDebugCategory(category,context={}){const env=useEnv();if(env.debug){const debugContext=useEnvDebugContext();useEffect(()=>debugContext.activateCategory(category,context),()=>[]);}}
return __exports;});;

/* /web/static/src/core/debug/debug_menu_basic.js */
odoo.define('@web/core/debug/debug_menu_basic',['@web/core/debug/debug_context','@web/core/dropdown/dropdown','@web/core/dropdown/dropdown_item','@odoo/owl'],function(require){'use strict';let __exports={};const{useEnvDebugContext}=require("@web/core/debug/debug_context");const{Dropdown}=require("@web/core/dropdown/dropdown");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{Component}=require("@odoo/owl");const DebugMenuBasic=__exports.DebugMenuBasic=class DebugMenuBasic extends Component{setup(){const debugContext=useEnvDebugContext();this.getElements=async()=>{this.elements=await debugContext.getItems(this.env);};}}
DebugMenuBasic.components={Dropdown,DropdownItem,};DebugMenuBasic.template="web.DebugMenu";return __exports;});;

/* /web/static/src/core/debug/debug_menu_items.js */
odoo.define('@web/core/debug/debug_menu_items',['@web/core/l10n/translation','@web/core/browser/browser','@web/core/browser/router_service','@web/core/registry'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{browser}=require("@web/core/browser/browser");const{routeToUrl}=require("@web/core/browser/router_service");const{registry}=require("@web/core/registry");function activateAssetsDebugging({env}){return{type:"item",description:_t("Activate Assets Debugging"),callback:()=>{browser.location.search="?debug=assets";},sequence:410,};}
function activateTestsAssetsDebugging({env}){return{type:"item",description:_t("Activate Tests Assets Debugging"),callback:()=>{browser.location.search="?debug=assets,tests";},sequence:420,};}
__exports.regenerateAssets=regenerateAssets;function regenerateAssets({env}){return{type:"item",description:_t("Regenerate Assets Bundles"),callback:async()=>{await env.services.orm.call("ir.attachment","regenerate_assets_bundles",);browser.location.reload();},sequence:430,};}
function becomeSuperuser({env}){const becomeSuperuserURL=browser.location.origin+"/web/become";return{type:"item",description:_t("Become Superuser"),hide:!env.services.user.isAdmin,href:becomeSuperuserURL,callback:()=>{browser.open(becomeSuperuserURL,"_self");},sequence:440,};}
function leaveDebugMode({env}){return{type:"item",description:_t("Leave the Developer Tools"),callback:()=>{const route=env.services.router.current;route.search.debug="";browser.location.href=browser.location.origin+routeToUrl(route);},sequence:450,};}
registry.category("debug").category("default").add("activateAssetsDebugging",activateAssetsDebugging).add("regenerateAssets",regenerateAssets).add("becomeSuperuser",becomeSuperuser).add("leaveDebugMode",leaveDebugMode).add("activateTestsAssetsDebugging",activateTestsAssetsDebugging);return __exports;});;

/* /web/static/src/core/debug/debug_providers.js */
odoo.define('@web/core/debug/debug_providers',['@web/core/l10n/translation','@web/core/registry','@web/core/browser/browser','@web/core/browser/router_service'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{browser}=require("@web/core/browser/browser");const{routeToUrl}=require("@web/core/browser/router_service");const commandProviderRegistry=registry.category("command_provider");commandProviderRegistry.add("debug",{provide:(env,options)=>{const result=[];if(env.debug){if(!env.debug.includes("assets")){result.push({action(){browser.location.search="?debug=assets";},category:"debug",name:_t("Activate debug mode (with assets)"),});}
result.push({action(){const route=env.services.router.current;route.search.debug="";browser.location.href=browser.location.origin+routeToUrl(route);},category:"debug",name:_t("Deactivate debug mode"),});result.push({action(){const runTestsURL=browser.location.origin+"/web/tests?debug=assets";browser.open(runTestsURL);},category:"debug",name:_t("Run JS Tests"),});result.push({action(){const runTestsURL=browser.location.origin+"/web/tests/mobile?debug=assets";browser.open(runTestsURL);},category:"debug",name:_t("Run JS Mobile Tests"),});}else{const debugKey="debug";if(options.searchValue.toLowerCase()===debugKey){result.push({action(){browser.location.search="?debug=assets";},category:"debug",name:`${_t("Activate debug mode (with assets)")} (${debugKey})`,});}}
return result;},});return __exports;});;

/* /web/static/src/core/debug/debug_utils.js */
odoo.define('@web/core/debug/debug_utils',[],function(require){'use strict';let __exports={};__exports.editModelDebug=editModelDebug;function editModelDebug(env,title,model,id){return env.services.action.doAction({res_model:model,res_id:id,name:title,type:"ir.actions.act_window",views:[[false,"form"]],view_mode:"form",target:"current",});}
return __exports;});;

/* /web/static/src/core/debug/profiling/profiling_item.js */
odoo.define('@web/core/debug/profiling/profiling_item',['@web/core/dropdown/dropdown_item','@web/core/utils/hooks','@odoo/owl'],function(require){'use strict';let __exports={};const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{useBus,useService}=require("@web/core/utils/hooks");const{Component,EventBus}=require("@odoo/owl");const ProfilingItem=__exports.ProfilingItem=class ProfilingItem extends Component{setup(){this.profiling=useService("profiling");useBus(this.props.bus,"UPDATE",this.render);}
changeParam(param,ev){this.profiling.setParam(param,ev.target.value);}
toggleParam(param){const value=this.profiling.state.params.execution_context_qweb;this.profiling.setParam(param,!value);}
openProfiles(){if(this.env.services.action){this.env.services.action.doAction("base.action_menu_ir_profile");}else{window.location="/web/#action=base.action_menu_ir_profile";}}}
ProfilingItem.components={DropdownItem};ProfilingItem.template="web.DebugMenu.ProfilingItem";ProfilingItem.props={bus:{type:EventBus},};return __exports;});;

/* /web/static/src/core/debug/profiling/profiling_qweb.js */
odoo.define('@web/core/debug/profiling/profiling_qweb',['@web/core/registry','@web/core/utils/hooks','@web/core/assets','@web/core/utils/render','@web/core/utils/timing','@odoo/owl'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{useService}=require("@web/core/utils/hooks");const{loadBundle}=require("@web/core/assets");const{renderToString}=require("@web/core/utils/render");const{useDebounced}=require("@web/core/utils/timing");const{Component,useState,useRef,onWillStart,onMounted,onWillUnmount}=require("@odoo/owl");class MenuItem extends Component{static template="web.ProfilingQwebView.menuitem";}
function processValue(value){const data=JSON.parse(value);for(const line of data[0].results.data){line.xpath=line.xpath.replace(/([^\]])\//g,"$1[1]/").replace(/([^\]])$/g,"$1[1]");}
return data;}
const ProfilingQwebView=__exports.ProfilingQwebView=class ProfilingQwebView extends Component{static template="web.ProfilingQwebView";static components={MenuItem};setup(){super.setup();this.orm=useService("orm");this.ace=useRef("ace");this.selector=useRef("selector");this.value=processValue(this.props.record.data[this.props.name]);this.state=useState({viewID:this.profile.data.length?this.profile.data[0].view_id:0,view:null,});this.renderProfilingInformation=useDebounced(this.renderProfilingInformation,100);onWillStart(async()=>{await loadBundle({jsLibs:["/web/static/lib/ace/ace.js",["/web/static/lib/ace/mode-python.js","/web/static/lib/ace/mode-xml.js","/web/static/lib/ace/mode-qweb.js",],],});await this._fetchViewData();this.state.view=this.viewObjects.find((view)=>view.id===this.state.viewID);});onMounted(()=>{this._startAce(this.ace.el);this._renderView();});onWillUnmount(()=>{if(this.aceEditor){this.aceEditor.destroy();}
this._unmoutInfo();});}
get profile(){return this.value?this.value[0].results:{archs:{},data:[]};}
async _fetchViewData(){const viewIDs=Array.from(new Set(this.profile.data.map((line)=>line.view_id)));const viewObjects=await this.orm.call("ir.ui.view","search_read",[],{fields:["id","display_name","key"],domain:[["id","in",viewIDs]],});for(const view of viewObjects){view.delay=0;view.query=0;const lines=this.profile.data.filter((l)=>l.view_id===view.id);const root=lines.find((l)=>l.xpath==="");if(root){view.delay+=root.delay;view.query+=root.query;}else{view.delay=lines.map((l)=>l.delay).reduce((a,b)=>a+b);view.query=lines.map((l)=>l.query).reduce((a,b)=>a+b);}
view.delay=Math.ceil(view.delay*10)/10;}
this.viewObjects=viewObjects;}
_formatDelay(delay){return delay?(Math.ceil(delay*10)/10).toFixed(1):".";}
_startAce(node){this.aceEditor=window.ace.edit(node);this.aceEditor.setOptions({maxLines:Infinity,showPrintMargin:false,highlightActiveLine:false,highlightGutterLine:true,readOnly:true,});this.aceEditor.renderer.setOptions({displayIndentGuides:true,showGutter:true,});this.aceEditor.renderer.$cursorLayer.element.style.display="none";this.aceEditor.$blockScrolling=true;this.aceSession=this.aceEditor.getSession();this.aceSession.setOptions({useWorker:false,mode:"ace/mode/qweb",tabSize:2,useSoftTabs:true,});this.aceEditor.renderer.on("afterRender",this.renderProfilingInformation.bind(this));}
renderProfilingInformation(){this._unmoutInfo();const flat={};const arch=[{xpath:"",children:[]}];const rows=this.ace.el.querySelectorAll(".ace_gutter .ace_gutter-cell");const elems=this.ace.el.querySelectorAll(".ace_tag-open, .ace_end-tag-close, .ace_end-tag-open, .ace_qweb");elems.forEach((node)=>{const parent=arch[arch.length-1];let xpath=parent.xpath;if(node.classList.contains("ace_end-tag-close")){let previous=node;while((previous=previous.previousElementSibling)){if(previous&&previous.classList.contains("ace_tag-name")){break;}}
const tag=previous&&previous.textContent;if(parent.tag===tag){arch.pop();}}else if(node.classList.contains("ace_end-tag-open")){const tag=node.nextElementSibling&&node.nextElementSibling.textContent;if(parent.tag===tag){arch.pop();}}else if(node.classList.contains("ace_qweb")){const directive=node.textContent;parent.directive.push({el:node,directive:directive,});let delay=0;let query=0;for(const line of this.profile.data){if(line.view_id===this.state.viewID&&line.xpath===xpath&&line.directive.includes(directive)){delay+=line.delay;query+=line.query;}}
if((delay||query)&&!node.querySelector(".o_info")){this._renderHover(delay,query,node);}}else if(node.classList.contains("ace_tag-open")){const nodeTagName=node.nextElementSibling;const aceLine=nodeTagName.parentNode;const index=[].indexOf.call(aceLine.parentNode.children,aceLine);const row=rows[index];xpath+="/"+nodeTagName.textContent;let i=1;while(flat[xpath+"["+i+"]"]){i++;}
xpath+="["+i+"]";flat[xpath]={xpath:xpath,tag:nodeTagName.textContent,children:[],directive:[],};arch.push(flat[xpath]);parent.children.push(flat[xpath]);const closed=!!row.querySelector(".ace_closed");const delays=[];const querys=[];const groups={};let displayDetail=false;for(const line of this.profile.data){if(line.view_id===this.state.viewID&&(closed?line.xpath.startsWith(xpath):line.xpath===xpath)){delays.push(line.delay);querys.push(line.query);const directive=line.directive.split("=")[0];if(!groups[directive]){groups[directive]={delays:[],querys:[],};}else{displayDetail=true;}
groups[directive].delays.push(this._formatDelay(line.delay));groups[directive].querys.push(line.query);}}
if(delays.length&&!row.querySelector(".o_info")){this._renderInfo(delays,querys,displayDetail,groups,row);}}
node.setAttribute("data-xpath",xpath);});}
_renderView(){const view=this.viewObjects.find((view)=>view.id===this.state.viewID);if(view){const arch=this.profile.archs[view.id]||"";if(this.aceSession.getValue()!==arch){this.aceSession.setValue(arch);}}else{this.aceSession.setValue("");}
this.state.view=view;}
_unmoutInfo(){if(this.hover){if(this.ace.el.querySelector(".o_ace_hover")){this.ace.el.querySelector(".o_ace_hover").remove();}}
if(this.info){if(this.ace.el.querySelector(".o_ace_info")){this.ace.el.querySelector(".o_ace_info").remove();}}}
_renderHover(delay,query,node){const xml=renderToString("web.ProfilingQwebView.hover",{delay:this._formatDelay(delay),query:query,});const div=new DOMParser().parseFromString(xml,"text/html").querySelector("div");node.insertBefore(div,node.firstChild);}
_renderInfo(delays,querys,displayDetail,groups,node){const xml=renderToString("web.ProfilingQwebView.info",{delay:this._formatDelay(delays.reduce((a,b)=>a+b,0)),query:querys.reduce((a,b)=>a+b,0)||".",displayDetail:displayDetail,groups:groups,});const div=new DOMParser().parseFromString(xml,"text/html").querySelector("div");node.insertBefore(div,node.firstChild);}
_onSelectView(ev){this.state.viewID=+ev.currentTarget.dataset.id;this._renderView();}}
const profilingQwebView=__exports.profilingQwebView={component:ProfilingQwebView,};registry.category("fields").add("profiling_qweb_view",profilingQwebView);return __exports;});;

/* /web/static/src/core/debug/profiling/profiling_service.js */
odoo.define('@web/core/debug/profiling/profiling_service',['@web/core/registry','@web/core/debug/profiling/profiling_item','@web/session','@web/core/debug/profiling/profiling_systray_item','@odoo/owl'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{ProfilingItem}=require("@web/core/debug/profiling/profiling_item");const{session}=require("@web/session");const{profilingSystrayItem}=require("@web/core/debug/profiling/profiling_systray_item");const{EventBus,reactive}=require("@odoo/owl");const systrayRegistry=registry.category("systray");const profilingService={dependencies:["orm"],start(env,{orm}){if(!env.debug){return;}
function notify(){if(systrayRegistry.contains("web.profiling")&&state.isEnabled===false){systrayRegistry.remove("web.profiling",profilingSystrayItem);}
if(!systrayRegistry.contains("web.profiling")&&state.isEnabled===true){systrayRegistry.add("web.profiling",profilingSystrayItem,{sequence:99});}
bus.trigger("UPDATE");}
const state=reactive({session:session.profile_session||false,collectors:session.profile_collectors||["sql","traces_async"],params:session.profile_params||{},get isEnabled(){return Boolean(state.session);},},notify);const bus=new EventBus();notify();async function setProfiling(params){const kwargs=Object.assign({collectors:state.collectors,params:state.params,profile:state.isEnabled,},params);const resp=await orm.call("ir.profile","set_profiling",[],kwargs);if(resp.type){env.services.action.doAction(resp);}else{state.session=resp.session;state.collectors=resp.collectors;state.params=resp.params;}}
function profilingSeparator(){return{type:"separator",sequence:500,};}
function profilingItem(){return{type:"component",Component:ProfilingItem,props:{bus},sequence:510,};}
registry.category("debug").category("default").add("profilingSeparator",profilingSeparator).add("profilingItem",profilingItem);return{state,async toggleProfiling(){await setProfiling({profile:!state.isEnabled});},async toggleCollector(collector){const nextCollectors=state.collectors.slice();const index=nextCollectors.indexOf(collector);if(index>=0){nextCollectors.splice(index,1);}else{nextCollectors.push(collector);}
await setProfiling({collectors:nextCollectors});},async setParam(key,value){const nextParams=Object.assign({},state.params);nextParams[key]=value;await setProfiling({params:nextParams});},isCollectorEnabled(collector){return state.collectors.includes(collector);},};},};registry.category("services").add("profiling",profilingService);return __exports;});;

/* /web/static/src/core/debug/profiling/profiling_systray_item.js */
odoo.define('@web/core/debug/profiling/profiling_systray_item',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");class ProfilingSystrayItem extends Component{}
ProfilingSystrayItem.template="web.ProfilingSystrayItem";const profilingSystrayItem=__exports.profilingSystrayItem={Component:ProfilingSystrayItem,};return __exports;});;

/* /web/static/src/core/dialog/dialog.js */
odoo.define('@web/core/dialog/dialog',['@web/core/hotkeys/hotkey_hook','@web/core/ui/ui_service','@web/core/utils/hooks','@odoo/owl','@web/core/utils/timing','@web/core/utils/draggable_hook_builder_owl'],function(require){'use strict';let __exports={};const{useHotkey}=require("@web/core/hotkeys/hotkey_hook");const{useActiveElement}=require("@web/core/ui/ui_service");const{useForwardRefToParent}=require("@web/core/utils/hooks");const{Component,onWillDestroy,useChildSubEnv,useExternalListener,useState}=require("@odoo/owl");const{throttleForAnimation}=require("@web/core/utils/timing");const{makeDraggableHook}=require("@web/core/utils/draggable_hook_builder_owl");const useDialogDraggable=makeDraggableHook({name:"useDialogDraggable",onWillStartDrag({ctx,addCleanup,addStyle,getRect}){const{height,width}=getRect(ctx.current.element);ctx.current.container=document.createElement("div");addStyle(ctx.current.container,{position:"fixed",top:"0",bottom:`${70 - height}px`,left:`${70 - width}px`,right:`${70 - width}px`,});ctx.current.element.after(ctx.current.container);addCleanup(()=>ctx.current.container.remove());},onDrop({ctx,getRect}){const{top,left}=getRect(ctx.current.element);return{left:left-ctx.current.elementRect.left,top:top-ctx.current.elementRect.top,};},});const Dialog=__exports.Dialog=class Dialog extends Component{setup(){this.modalRef=useForwardRefToParent("modalRef");useActiveElement("modalRef");this.data=useState(this.env.dialogData);useHotkey("escape",()=>this.onEscape());useHotkey("control+enter",()=>{const btns=document.querySelectorAll(".o_dialog:not(.o_inactive_modal) .modal-footer button");const firstVisibleBtn=Array.from(btns).find((btn)=>{const styles=getComputedStyle(btn);return styles.display!=="none";});if(firstVisibleBtn){firstVisibleBtn.click();}},{bypassEditableProtection:true});this.id=`dialog_${this.data.id}`;useChildSubEnv({inDialog:true,dialogId:this.id});this.position=useState({left:0,top:0});useDialogDraggable({enable:()=>!this.env.isSmall,ref:this.modalRef,elements:".modal-content",handle:".modal-header",ignore:"button",edgeScrolling:{enabled:false},onDrop:({top,left})=>{this.position.left+=left;this.position.top+=top;},});const throttledResize=throttleForAnimation(this.onResize.bind(this));useExternalListener(window,"resize",throttledResize);onWillDestroy(()=>{if(this.env.isSmall){this.data.scrollToOrigin();}});}
get isFullscreen(){return this.props.fullscreen||this.env.isSmall;}
get contentStyle(){return`top: ${this.position.top}px; left: ${this.position.left}px;`;}
onResize(){this.position.left=0;this.position.top=0;}
onEscape(){return this.dismiss();}
async dismiss(){if(this.data.dismiss){await this.data.dismiss();}
return this.data.close();}}
Dialog.template="web.Dialog";Dialog.props={contentClass:{type:String,optional:true},bodyClass:{type:String,optional:true},fullscreen:{type:Boolean,optional:true},footer:{type:Boolean,optional:true},header:{type:Boolean,optional:true},size:{type:String,optional:true,validate:(s)=>["sm","md","lg","xl","fs","fullscreen"].includes(s),},technical:{type:Boolean,optional:true},title:{type:String,optional:true},modalRef:{type:Function,optional:true},slots:{type:Object,shape:{default:Object,header:{type:Object,optional:true},footer:{type:Object,optional:true},},},withBodyPadding:{type:Boolean,optional:true},};Dialog.defaultProps={contentClass:"",bodyClass:"",fullscreen:false,footer:true,header:true,size:"lg",technical:true,title:"Odoo",withBodyPadding:true,};return __exports;});;

/* /web/static/src/core/dialog/dialog_service.js */
odoo.define('@web/core/dialog/dialog_service',['@web/core/registry','@odoo/owl','@web/core/utils/components'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{Component,markRaw,reactive,xml}=require("@odoo/owl");const{WithEnv}=require("@web/core/utils/components");class DialogWrapper extends Component{static template=xml`
        <WithEnv env="{ dialogData: props.subEnv }">
            <t t-component="props.subComponent" t-props="props.subProps" />
        </WithEnv>
    `;static components={WithEnv};static props=["*"];}
const dialogService=__exports.dialogService={dependencies:["overlay"],start(env,{overlay}){const stack=[];let nextId=0;const deactivate=()=>{for(const subEnv of stack){subEnv.isActive=false;}};const add=(dialogClass,props,options={})=>{const id=nextId++;const close=()=>remove();const subEnv=reactive({id,close,isActive:true,});deactivate();stack.push(subEnv);document.body.classList.add("modal-open");const scrollOrigin={top:window.scrollY,left:window.scrollX};subEnv.scrollToOrigin=()=>{if(!stack.length){window.scrollTo(scrollOrigin);}};const remove=overlay.add(DialogWrapper,{subComponent:dialogClass,subProps:markRaw({...props,close}),subEnv,},{onRemove:()=>{stack.pop();deactivate();if(stack.length){stack.at(-1).isActive=true;}else{document.body.classList.remove("modal-open");}
options.onClose?.();},});return remove;};function closeAll(){for(const dialog of[...stack].reverse()){dialog.close();}}
return{add,closeAll};},};registry.category("services").add("dialog",dialogService);return __exports;});;

/* /web/static/src/core/domain.js */
odoo.define('@web/core/domain',['@web/core/utils/arrays','@web/core/py_js/py','@web/core/py_js/py_utils','@web/core/utils/strings'],function(require){'use strict';let __exports={};const{shallowEqual}=require("@web/core/utils/arrays");const{evaluate,formatAST,parseExpr}=require("@web/core/py_js/py");const{toPyValue}=require("@web/core/py_js/py_utils");const{escapeRegExp}=require("@web/core/utils/strings");const InvalidDomainError=__exports.InvalidDomainError=class InvalidDomainError extends Error{}
const Domain=__exports.Domain=class Domain{static combine(domains,operator){if(domains.length===0){return new Domain([]);}
const domain1=domains[0]instanceof Domain?domains[0]:new Domain(domains[0]);if(domains.length===1){return domain1;}
const domain2=Domain.combine(domains.slice(1),operator);const result=new Domain([]);const astValues1=domain1.ast.value;const astValues2=domain2.ast.value;const op=operator==="AND"?"&":"|";const combinedAST={type:4,value:astValues1.concat(astValues2)};result.ast=normalizeDomainAST(combinedAST,op);return result;}
static and(domains){return Domain.combine(domains,"AND");}
static or(domains){return Domain.combine(domains,"OR");}
static not(domain){const result=new Domain(domain);result.ast.value.unshift({type:1,value:"!"});return result;}
static removeDomainLeaves(domain,keysToRemove){function processLeaf(elements,idx,operatorCtx,newDomain){const leaf=elements[idx];if(leaf.type===10){if(keysToRemove.includes(leaf.value[0].value)){if(operatorCtx==="&"){newDomain.ast.value.push(...Domain.TRUE.ast.value);}else if(operatorCtx==="|"){newDomain.ast.value.push(...Domain.FALSE.ast.value);}}else{newDomain.ast.value.push(leaf);}
return 1;}else if(leaf.type===1){if(leaf.value==="|"&&elements[idx+1].type===10&&elements[idx+2].type===10&&keysToRemove.includes(elements[idx+1].value[0].value)&&keysToRemove.includes(elements[idx+2].value[0].value)){newDomain.ast.value.push(...Domain.TRUE.ast.value);return 3;}
newDomain.ast.value.push(leaf);if(leaf.value==="!"){return 1+processLeaf(elements,idx+1,"&",newDomain);}
const firstLeafSkip=processLeaf(elements,idx+1,leaf.value,newDomain);const secondLeafSkip=processLeaf(elements,idx+1+firstLeafSkip,leaf.value,newDomain);return 1+firstLeafSkip+secondLeafSkip;}
return 0;}
domain=new Domain(domain);if(domain.ast.value.length===0){return domain;}
const newDomain=new Domain([]);processLeaf(domain.ast.value,0,"&",newDomain);return newDomain;}
constructor(descr=[]){if(descr instanceof Domain){return new Domain(descr.toString());}else{let rawAST;try{rawAST=typeof descr==="string"?parseExpr(descr):toAST(descr);}catch(error){throw new InvalidDomainError(`Invalid domain representation: ${descr.toString()}`,{cause:error,});}
this.ast=normalizeDomainAST(rawAST);}}
contains(record){const expr=evaluate(this.ast,record);return matchDomain(record,expr);}
toString(){return formatAST(this.ast);}
toList(context){return evaluate(this.ast,context);}
toJson(){try{const evaluatedAsList=this.toList({});const evaluatedDomain=new Domain(evaluatedAsList);if(evaluatedDomain.toString()===this.toString()){return evaluatedAsList;}
return this.toString();}catch{return this.toString();}}}
__exports.evalDomain=evalDomain;function evalDomain(modifier,evalContext){if(modifier&&typeof modifier!=="boolean"){modifier=new Domain(modifier).contains(evalContext);}
return Boolean(modifier);}
const TRUE_LEAF=[1,"=",1];const FALSE_LEAF=[0,"=",1];const TRUE_DOMAIN=new Domain([TRUE_LEAF]);const FALSE_DOMAIN=new Domain([FALSE_LEAF]);Domain.TRUE=TRUE_DOMAIN;Domain.FALSE=FALSE_DOMAIN;function toAST(domain){const elems=domain.map((elem)=>{switch(elem){case"!":case"&":case"|":return{type:1,value:elem};default:return{type:10,value:elem.map(toPyValue),};}});return{type:4,value:elems};}
function normalizeDomainAST(domain,op="&"){if(domain.type!==4){if(domain.type===10){const value=domain.value;if(value.findIndex((e)=>e.type===10)===-1||!value.every((e)=>e.type===10||e.type===1)){throw new InvalidDomainError("Invalid domain AST");}}else{throw new InvalidDomainError("Invalid domain AST");}}
if(domain.value.length===0){return domain;}
let expected=1;for(const child of domain.value){switch(child.type){case 1:if(child.value==="&"||child.value==="|"){expected++;}else if(child.value!=="!"){throw new InvalidDomainError("Invalid domain AST");}
break;case 4:case 10:if(child.value.length===3){expected--;break;}
throw new InvalidDomainError("Invalid domain AST");default:throw new InvalidDomainError("Invalid domain AST");}}
const values=domain.value.slice();while(expected<0){expected++;values.unshift({type:1,value:op});}
if(expected>0){throw new InvalidDomainError(`invalid domain ${formatAST(domain)} (missing ${expected} segment(s))`);}
return{type:4,value:values};}
function matchCondition(record,condition){if(typeof condition==="boolean"){return condition;}
const[field,operator,value]=condition;if(typeof field==="string"){const names=field.split(".");if(names.length>=2){return matchCondition(record[names[0]],[names.slice(1).join("."),operator,value]);}}
let likeRegexp,ilikeRegexp;if(["like","not like","ilike","not ilike"].includes(operator)){likeRegexp=new RegExp(`(.*)${escapeRegExp(value).replaceAll("%", "(.*)")}(.*)`,"g");ilikeRegexp=new RegExp(`(.*)${escapeRegExp(value).replaceAll("%", "(.*)")}(.*)`,"gi");}
const fieldValue=typeof field==="number"?field:record[field];switch(operator){case"=?":if([false,null].includes(value)){return true;}
case"=":case"==":if(Array.isArray(fieldValue)&&Array.isArray(value)){return shallowEqual(fieldValue,value);}
return fieldValue===value;case"!=":case"<>":return!matchCondition(record,[field,"==",value]);case"<":return fieldValue<value;case"<=":return fieldValue<=value;case">":return fieldValue>value;case">=":return fieldValue>=value;case"in":{const val=Array.isArray(value)?value:[value];const fieldVal=Array.isArray(fieldValue)?fieldValue:[fieldValue];return fieldVal.some((fv)=>val.includes(fv));}
case"not in":{const val=Array.isArray(value)?value:[value];const fieldVal=Array.isArray(fieldValue)?fieldValue:[fieldValue];return!fieldVal.some((fv)=>val.includes(fv));}
case"like":if(fieldValue===false){return false;}
return Boolean(fieldValue.match(likeRegexp));case"not like":if(fieldValue===false){return false;}
return Boolean(!fieldValue.match(likeRegexp));case"=like":if(fieldValue===false){return false;}
return new RegExp(escapeRegExp(value).replace(/%/g,".*")).test(fieldValue);case"ilike":if(fieldValue===false){return false;}
return Boolean(fieldValue.match(ilikeRegexp));case"not ilike":if(fieldValue===false){return false;}
return Boolean(!fieldValue.match(ilikeRegexp));case"=ilike":if(fieldValue===false){return false;}
return new RegExp(escapeRegExp(value).replace(/%/g,".*"),"i").test(fieldValue);}
throw new InvalidDomainError("could not match domain");}
function makeOperators(record){const match=matchCondition.bind(null,record);return{"!":(x)=>!match(x),"&":(a,b)=>match(a)&&match(b),"|":(a,b)=>match(a)||match(b),};}
function matchDomain(record,domain){if(domain.length===0){return true;}
const operators=makeOperators(record);const reversedDomain=Array.from(domain).reverse();const condStack=[];for(const item of reversedDomain){const operator=typeof item==="string"&&operators[item];if(operator){const operands=condStack.splice(-operator.length);condStack.push(operator(...operands));}else{condStack.push(item);}}
return matchCondition(record,condStack.pop());}
return __exports;});;

/* /web/static/src/core/domain_selector/domain_selector.js */
odoo.define('@web/core/domain_selector/domain_selector',['@web/core/domain_selector/utils','@odoo/owl','@web/core/domain','@web/core/tree_editor/tree_editor','@web/core/tree_editor/condition_tree','@web/core/model_field_selector/utils','@web/core/checkbox/checkbox','@web/core/utils/objects','@web/core/domain_selector/domain_selector_operator_editor','@web/core/tree_editor/tree_editor_operator_editor','@web/core/l10n/translation','@web/core/model_field_selector/model_field_selector'],function(require){'use strict';let __exports={};const{extractPathsFromDomain,useGetDefaultCondition}=require("@web/core/domain_selector/utils");const{Component,onWillStart,onWillUpdateProps}=require("@odoo/owl");const{Domain}=require("@web/core/domain");const{TreeEditor}=require("@web/core/tree_editor/tree_editor");const{domainFromTree,treeFromDomain,formatValue,condition,}=require("@web/core/tree_editor/condition_tree");const{useLoadFieldInfo}=require("@web/core/model_field_selector/utils");const{CheckBox}=require("@web/core/checkbox/checkbox");const{deepEqual}=require("@web/core/utils/objects");const{getDomainDisplayedOperators}=require("@web/core/domain_selector/domain_selector_operator_editor");const{getOperatorEditorInfo}=require("@web/core/tree_editor/tree_editor_operator_editor");const{_t}=require("@web/core/l10n/translation");const{ModelFieldSelector}=require("@web/core/model_field_selector/model_field_selector");const ARCHIVED_CONDITION=condition("active","in",[true,false]);const ARCHIVED_DOMAIN=`[("active", "in", [True, False])]`;const DomainSelector=__exports.DomainSelector=class DomainSelector extends Component{static template="web.DomainSelector";static components={TreeEditor,CheckBox};static props={domain:String,resModel:String,className:{type:String,optional:true},defaultConnector:{type:[{value:"&"},{value:"|"}],optional:true},isDebugMode:{type:Boolean,optional:true},readonly:{type:Boolean,optional:true},update:{type:Function,optional:true},};static defaultProps={isDebugMode:false,readonly:true,update:()=>{},};setup(){this.loadFieldInfo=useLoadFieldInfo();this.getDefaultCondition=useGetDefaultCondition();this.tree=null;this.defaultCondition=null;this.fieldDefs={};this.showArchivedCheckbox=false;this.includeArchived=false;onWillStart(()=>this.onPropsUpdated(this.props));onWillUpdateProps((np)=>this.onPropsUpdated(np));}
async onPropsUpdated(p){let domain;let isSupported=true;try{domain=new Domain(p.domain);}catch{isSupported=false;}
if(!isSupported){this.tree=null;this.defaultCondition=null;this.fieldDefs={};this.showArchivedCheckbox=false;this.includeArchived=false;return;}
const paths=new Set([...extractPathsFromDomain(domain),"active"]);await this.loadFieldDefs(p.resModel,paths);const[defaultCondition]=await Promise.all([this.getDefaultCondition(p.resModel),this.loadFieldDefs(p.resModel,paths),]);this.tree=treeFromDomain(domain,{getFieldDef:this.getFieldDef.bind(this),distributeNot:!p.isDebugMode,});this.defaultCondition=defaultCondition;this.showArchivedCheckbox=Boolean(this.fieldDefs.active);this.includeArchived=false;if(this.showArchivedCheckbox){if(this.tree.value==="&"){this.tree.children=this.tree.children.filter((child)=>{if(deepEqual(child,ARCHIVED_CONDITION)){this.includeArchived=true;return false;}
return true;});if(this.tree.children.length===1){this.tree=this.tree.children[0];}}else if(deepEqual(this.tree,ARCHIVED_CONDITION)){this.includeArchived=true;this.tree=treeFromDomain(`[]`);}}}
getFieldDef(path){if(typeof path==="string"){return this.fieldDefs[path];}
return null;}
getDefaultOperator(fieldDef){return getDomainDisplayedOperators(fieldDef)[0];}
getOperatorEditorInfo(node){const fieldDef=this.getFieldDef(node.path);const operators=getDomainDisplayedOperators(fieldDef);return getOperatorEditorInfo(operators);}
getPathEditorInfo(){const{resModel,isDebugMode}=this.props;return{component:ModelFieldSelector,extractProps:({update,value:path})=>{return{path,update,resModel,isDebugMode,readonly:false,};},isSupported:(path)=>[0,1].includes(path)||typeof path==="string",defaultValue:()=>"id",stringify:(path)=>formatValue(path),message:_t("Invalid field chain"),};}
async loadFieldDefs(resModel,paths){const promises=[];const fieldDefs={};for(const path of paths){if(typeof path==="string"){promises.push(this.loadFieldInfo(resModel,path).then(({fieldDef})=>{fieldDefs[path]=fieldDef;}));}}
await Promise.all(promises);this.fieldDefs=fieldDefs;}
toggleIncludeArchived(){this.includeArchived=!this.includeArchived;this.update(this.tree);}
resetDomain(){this.props.update("[]");}
onDomainChange(domain){this.props.update(domain,true);}
update(tree){const archiveDomain=this.includeArchived?ARCHIVED_DOMAIN:`[]`;const domain=tree?Domain.and([domainFromTree(tree),archiveDomain]).toString():archiveDomain;this.props.update(domain);}}
return __exports;});;

/* /web/static/src/core/domain_selector/domain_selector_operator_editor.js */
odoo.define('@web/core/domain_selector/domain_selector_operator_editor',[],function(require){'use strict';let __exports={};__exports.getDomainDisplayedOperators=getDomainDisplayedOperators;function getDomainDisplayedOperators(fieldDef){if(!fieldDef){fieldDef={};}
const{type,is_property}=fieldDef;if(is_property){switch(type){case"many2many":case"tags":return["in","not in","set","not_set"];case"many2one":case"selection":return["=","!=","set","not_set"];}}
switch(type){case"boolean":return["is","is_not"];case"selection":return["=","!=","in","not in","set","not_set"];case"char":case"text":case"html":return["=","!=","ilike","not ilike","in","not in","set","not_set"];case"date":case"datetime":return["=","!=",">",">=","<","<=","between","set","not_set"];case"integer":case"float":case"monetary":return["=","!=",">",">=","<","<=","between","ilike","not ilike","set","not_set",];case"many2one":case"many2many":case"one2many":return["in","not in","=","!=","ilike","not ilike","set","not_set"];case"json":return["=","!=","ilike","not ilike","set","not_set"];case"properties":return["set","not_set"];case undefined:return["="];default:return["=","!=",">",">=","<","<=","ilike","not ilike","like","not like","=like","=ilike","child_of","parent_of","in","not in","set","not_set",];}}
return __exports;});;

/* /web/static/src/core/domain_selector/utils.js */
odoo.define('@web/core/domain_selector/utils',['@web/core/domain','@web/core/tree_editor/tree_editor_value_editors','@web/core/domain_selector/domain_selector_operator_editor','@web/core/utils/hooks','@web/core/l10n/translation','@web/core/tree_editor/condition_tree','@web/core/model_field_selector/utils','@web/core/tree_editor/utils'],function(require){'use strict';let __exports={};const{Domain}=require("@web/core/domain");const{getDefaultValue}=require("@web/core/tree_editor/tree_editor_value_editors");const{getDomainDisplayedOperators}=require("@web/core/domain_selector/domain_selector_operator_editor");const{useService}=require("@web/core/utils/hooks");const{_t}=require("@web/core/l10n/translation");const{toValue,domainFromTree,normalizeValue,formatValue:toString,createVirtualOperators,condition,}=require("@web/core/tree_editor/condition_tree");const{useLoadFieldInfo,useLoadPathDescription}=require("@web/core/model_field_selector/utils");const{extractIdsFromTree,getDefaultPath,getPathsInTree,leafToString,useLoadDisplayNames,}=require("@web/core/tree_editor/utils");__exports.extractPathsFromDomain=extractPathsFromDomain;function extractPathsFromDomain(domain){domain=new Domain(domain);const paths=new Set();for(const node of domain.ast.value){if([4,10].includes(node.type)){paths.add(toValue(node.value[0]));}}
return[...paths];}
function getDefaultCondition(fieldDefs){const defaultPath=getDefaultPath(fieldDefs);const fieldDef=fieldDefs[defaultPath];const operator=getDomainDisplayedOperators(fieldDef)[0];const value=getDefaultValue(fieldDef,operator);return condition(fieldDef.name,operator,value);}
function getDefaultDomain(fieldDefs){return domainFromTree(getDefaultCondition(fieldDefs));}
__exports.useGetDefaultCondition=useGetDefaultCondition;function useGetDefaultCondition(){const fieldService=useService("field");return async(resModel)=>{const fieldDefs=await fieldService.loadFields(resModel);return getDefaultCondition(fieldDefs);};}
__exports.useGetDefaultLeafDomain=useGetDefaultLeafDomain;function useGetDefaultLeafDomain(){const fieldService=useService("field");return async(resModel)=>{const fieldDefs=await fieldService.loadFields(resModel);return getDefaultDomain(fieldDefs);};}
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(const child of processedChildren){if(child.type==="connector"||typeof child.path!=="string"||!["=","in"].includes(child.operator)){children.push(child);}else{if(!childrenByPath[child.path]){childrenByPath[child.path]=[];}
childrenByPath[child.path].push(child);}}
for(const path in childrenByPath){if(childrenByPath[path].length===1){children.push(childrenByPath[path][0]);continue;}
const value=[];for(const child of childrenByPath[path]){if(child.operator==="="){value.push(child.value);}else{value.push(...child.value);}}
children.push(condition(path,"in",normalizeValue(value)));}
if(children.length===1){return{...children[0]};}
return{...tree,children};}
__exports.getDomainTreeDescription=getDomainTreeDescription;function getDomainTreeDescription(tree,getFieldDef,getDescription,displayNames,isSubExpression=true){if(tree.type==="connector"){const childDescriptions=tree.children.map((c)=>getDomainTreeDescription(c,getFieldDef,getDescription,displayNames));const separator=tree.value==="&"?_t("and"):_t("or");let description=childDescriptions.join(` ${separator} `);if(isSubExpression||tree.negate){description=`( ${description} )`;}
if(tree.negate){description=`! ${description}`;}
return description;}
const{path}=tree;const fieldDef=getFieldDef(path);const{operatorDescription,valueDescription}=leafToString(tree,fieldDef,displayNames[fieldDef?.relation||fieldDef?.comodel]);let description=`${getDescription(path)} ${operatorDescription} `;if(valueDescription){const{values,join,addParenthesis}=valueDescription;const jointedValues=values.join(` ${join} `);description+=addParenthesis?`( ${jointedValues} )`:jointedValues;}
return description;}
__exports.useGetDomainTreeDescription=useGetDomainTreeDescription;function useGetDomainTreeDescription(fieldService,nameService){fieldService||=useService("field");nameService||=useService("name");const loadFieldInfo=useLoadFieldInfo(fieldService);const loadPathDescription=useLoadPathDescription(fieldService);const loadDisplayNames=useLoadDisplayNames(nameService);return async(resModel,tree)=>{tree=simplifyTree(tree);const paths=getPathsInTree(tree);const promises=[];const pathFieldDefs={};const pathDescriptions={};for(const path of paths){promises.push(loadPathDescription(resModel,path).then(({displayNames})=>{pathDescriptions[toString(path)]=displayNames.join(" 🠒 ");}),loadFieldInfo(resModel,path).then(({fieldDef})=>{pathFieldDefs[toString(path)]=fieldDef;}));}
await Promise.all(promises);const getFieldDef=(path)=>pathFieldDefs[toString(path)];const getDescription=(path)=>pathDescriptions[toString(path)];const idsByModel=extractIdsFromTree(tree,getFieldDef);const treeWithVirtualOperators=createVirtualOperators(tree,{getFieldDef});const displayNames=await loadDisplayNames(idsByModel);return getDomainTreeDescription(treeWithVirtualOperators,getFieldDef,getDescription,displayNames,false);};}
return __exports;});;

/* /web/static/src/core/domain_selector_dialog/domain_selector_dialog.js */
odoo.define('@web/core/domain_selector_dialog/domain_selector_dialog',['@web/core/l10n/translation','@odoo/owl','@web/core/dialog/dialog','@web/core/domain','@web/core/domain_selector/domain_selector','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{Component,useRef,useState}=require("@odoo/owl");const{Dialog}=require("@web/core/dialog/dialog");const{Domain}=require("@web/core/domain");const{DomainSelector}=require("@web/core/domain_selector/domain_selector");const{useService}=require("@web/core/utils/hooks");const DomainSelectorDialog=__exports.DomainSelectorDialog=class DomainSelectorDialog extends Component{static template="web.DomainSelectorDialog";static components={Dialog,DomainSelector,};static props={close:Function,onConfirm:Function,resModel:String,className:{type:String,optional:true},defaultConnector:{type:[{value:"&"},{value:"|"}],optional:true},domain:String,isDebugMode:{type:Boolean,optional:true},readonly:{type:Boolean,optional:true},text:{type:String,optional:true},confirmButtonText:{type:String,optional:true},disableConfirmButton:{type:Function,optional:true},discardButtonText:{type:String,optional:true},title:{type:String,optional:true},context:{type:Object,optional:true},};static defaultProps={isDebugMode:false,readonly:false,context:{},};setup(){this.notification=useService("notification");this.rpc=useService("rpc");this.orm=useService("orm");this.user=useService("user");this.state=useState({domain:this.props.domain});this.confirmButtonRef=useRef("confirm");}
get confirmButtonText(){return this.props.confirmButtonText||_t("Confirm");}
get dialogTitle(){return this.props.title||_t("Domain");}
get disabled(){if(this.props.disableConfirmButton){return this.props.disableConfirmButton(this.state.domain);}
return false;}
get discardButtonText(){return this.props.discardButtonText||_t("Discard");}
get domainSelectorProps(){return{className:this.props.className,resModel:this.props.resModel,readonly:this.props.readonly,isDebugMode:this.props.isDebugMode,defaultConnector:this.props.defaultConnector,domain:this.state.domain,update:(domain)=>{this.state.domain=domain;},};}
async onConfirm(){this.confirmButtonRef.el.disabled=true;let domain;let isValid;try{const evalContext={...this.user.context,...this.props.context};domain=new Domain(this.state.domain).toList(evalContext);}catch{isValid=false;}
if(isValid===undefined){isValid=await this.rpc("/web/domain/validate",{model:this.props.resModel,domain,});}
if(!isValid){if(this.confirmButtonRef.el){this.confirmButtonRef.el.disabled=false;}
this.notification.add(_t("Domain is invalid. Please correct it"),{type:"danger",});return;}
this.props.onConfirm(this.state.domain);this.props.close();}
onDiscard(){this.props.close();}}
return __exports;});;

/* /web/static/src/core/dropdown/accordion_item.js */
odoo.define('@web/core/dropdown/accordion_item',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component,onPatched,useState}=require("@odoo/owl");const ACCORDION=__exports.ACCORDION=Symbol("Accordion");const AccordionItem=__exports.AccordionItem=class AccordionItem extends Component{static template="web.AccordionItem";static components={};static props={slots:{type:Object,shape:{default:{},},},description:String,selected:{type:Boolean,optional:true,},class:{type:String,optional:true,},};static defaultProps={class:"",selected:false,};setup(){this.state=useState({open:false,});this.parentComponent=this.env[ACCORDION];onPatched(()=>{this.parentComponent?.accordionStateChanged?.();});}}
return __exports;});;

/* /web/static/src/core/dropdown/checkbox_item.js */
odoo.define('@web/core/dropdown/checkbox_item',['@web/core/dropdown/dropdown_item'],function(require){'use strict';let __exports={};const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const CheckboxItem=__exports.CheckboxItem=class CheckboxItem extends DropdownItem{}
CheckboxItem.template="web.CheckboxItem";CheckboxItem.props={...DropdownItem.props,checked:{type:Boolean,optional:false,},};return __exports;});;

/* /web/static/src/core/dropdown/dropdown.js */
odoo.define('@web/core/dropdown/dropdown',['@web/core/utils/hooks','@web/core/position_hook','@web/core/dropdown/dropdown_navigation_hook','@web/core/l10n/localization','@odoo/owl'],function(require){'use strict';let __exports={};const{useBus,useService}=require("@web/core/utils/hooks");const{usePosition}=require("@web/core/position_hook");const{useDropdownNavigation}=require("@web/core/dropdown/dropdown_navigation_hook");const{localization}=require("@web/core/l10n/localization");const{Component,EventBus,onWillStart,status,useEffect,useExternalListener,useRef,useState,useChildSubEnv,}=require("@odoo/owl");const DIRECTION_CARET_CLASS={bottom:"dropdown",top:"dropup",left:"dropstart",right:"dropend",};const DROPDOWN=__exports.DROPDOWN=Symbol("Dropdown");const Dropdown=__exports.Dropdown=class Dropdown extends Component{setup(){this.state=useState({open:this.props.startOpen,groupIsOpen:this.props.startOpen,directionCaretClass:null,});this.rootRef=useRef("root");onWillStart(()=>{if(this.state.open&&this.props.beforeOpen){return this.props.beforeOpen();}});useExternalListener(window,"click",this.onWindowClicked,{capture:true});useBus(Dropdown.bus,"state-changed",({detail})=>this.onDropdownStateChanged(detail));this.ui=useService("ui");useEffect(()=>{Promise.resolve().then(()=>{this.myActiveEl=this.ui.activeElement;});},()=>[]);this.parentDropdown=this.env[DROPDOWN];useChildSubEnv({[DROPDOWN]:{close:this.close.bind(this),closeAllParents:()=>{this.close();if(this.parentDropdown){this.parentDropdown.closeAllParents();}},},});useDropdownNavigation();const position=this.props.position||(this.parentDropdown?"right-start":"bottom-start");let[direction]=position.split("-");if(["left","right"].includes(direction)&&localization.direction==="rtl"){direction=direction==="left"?"right":"left";}
this.defaultDirection=direction;const positioningOptions={position,onPositioned:(el,{direction})=>{this.state.directionCaretClass=DIRECTION_CARET_CLASS[direction];},};if(this.props.container){positioningOptions.container=()=>typeof this.props.container==="function"?this.props.container():this.props.container;}
this.state.directionCaretClass=DIRECTION_CARET_CLASS[direction];this.togglerRef=useRef("togglerRef");if(this.props.toggler==="parent"){useEffect(()=>{const onClick=(ev)=>{if(this.rootRef.el.contains(ev.target)){return;}
this.toggle();};if(this.rootRef.el.parentElement.tabIndex===-1){this.rootRef.el.parentElement.tabIndex=-1;}
this.rootRef.el.parentElement.addEventListener("click",onClick);return()=>{this.rootRef.el.parentElement.removeEventListener("click",onClick);};},()=>[]);useEffect((open)=>{this.rootRef.el.parentElement.ariaExpanded=open?"true":"false";},()=>[this.state.open]);this.position=usePosition("menuRef",()=>this.rootRef.el.parentElement,positioningOptions);}else{const togglerRef=useRef("togglerRef");this.position=usePosition("menuRef",()=>togglerRef.el,positioningOptions);}
useEffect((isOpen)=>{if(isOpen){this.props.onOpened();}else{this.position.unlock();}},()=>[this.state.open]);}
async changeStateAndNotify(stateSlice){if(stateSlice.open&&this.props.beforeOpen){await this.props.beforeOpen();if(status(this)==="destroyed"){return;}}
if(!stateSlice.open){this.state.directionCaretClass=DIRECTION_CARET_CLASS[this.defaultDirection];}
Object.assign(this.state,stateSlice);const stateChangedPayload={emitter:this,newState:{...this.state},};Dropdown.bus.trigger("state-changed",stateChangedPayload);this.props.onStateChanged({...this.state});}
close(){return this.changeStateAndNotify({open:false,groupIsOpen:false});}
open(){return this.changeStateAndNotify({open:true,groupIsOpen:this.props.autoOpen});}
toggle(){const toggled=!this.state.open;return this.changeStateAndNotify({open:toggled,groupIsOpen:toggled&&this.props.autoOpen,});}
get showCaret(){return this.props.showCaret===undefined?this.parentDropdown:this.props.showCaret;}
onDropdownStateChanged(args){if(!this.rootRef.el||this.rootRef.el.contains(args.emitter.rootRef.el)||args.emitter.myActiveEl!==this.myActiveEl){return;}
if(args.emitter.rootRef.el.parentElement===this.rootRef.el.parentElement){this.state.groupIsOpen=args.newState.groupIsOpen&&this.props.autoOpen;if(this.state.open&&args.newState.open){this.state.open=false;}}else{if(this.state.open&&args.newState.open){this.close();}}}
onTogglerClick(){this.toggle();}
onTogglerMouseEnter(){if(this.state.groupIsOpen&&!this.state.open){this.togglerRef.el.focus();this.open();}}
isInActiveElement(){return this.ui.activeElement===this.myActiveEl;}
onWindowClicked(ev){if(!this.state.open){return;}
if(!this.isInActiveElement()){return;}
if(ev.target.closest(".o_datetime_picker")){return;}
const rootEl=this.props.toggler==="parent"?this.rootRef.el.parentElement:this.rootRef.el;const gotClickedInside=rootEl.contains(ev.target);if(!gotClickedInside){this.close();}}}
Dropdown.bus=new EventBus();Dropdown.defaultProps={menuDisplay:"d-block",autoOpen:true,holdOnHover:false,onOpened:()=>{},onStateChanged:()=>{},onScroll:()=>{},};Dropdown.props={class:{type:String,optional:true,},disabled:{type:Boolean,optional:true,},toggler:{type:String,optional:true,validate:(prop)=>["parent"].includes(prop),},skipTogglerTabbing:{type:Boolean,optional:true,},startOpen:{type:Boolean,optional:true,},autoOpen:{type:Boolean,optional:true,},menuClass:{type:String,optional:true,},menuDisplay:{type:String,optional:true,},beforeOpen:{type:Function,optional:true,},onOpened:{type:Function,optional:true,},onScroll:{type:Function,optional:true,},onStateChanged:{type:Function,optional:true,},togglerClass:{type:String,optional:true,},hotkey:{type:String,optional:true,},tooltip:{type:String,optional:true,},title:{type:String,optional:true,},position:{type:String,optional:true,},slots:{type:Object,optional:true,},showCaret:{type:Boolean,optional:true,},holdOnHover:{type:Boolean,optional:true,},container:{type:[Element,Function],optional:true,},};Dropdown.template="web.Dropdown";return __exports;});;

/* /web/static/src/core/dropdown/dropdown_item.js */
odoo.define('@web/core/dropdown/dropdown_item',['@web/core/dropdown/dropdown','@odoo/owl'],function(require){'use strict';let __exports={};const{DROPDOWN}=require("@web/core/dropdown/dropdown");const{Component}=require("@odoo/owl");const ParentClosingMode={None:"none",ClosestParent:"closest",AllParents:"all",};const DropdownItem=__exports.DropdownItem=class DropdownItem extends Component{onClick(ev){const{href,onSelected,parentClosingMode}=this.props;if(href){ev.preventDefault();}
if(onSelected){onSelected();}
const dropdown=this.env[DROPDOWN];if(!dropdown){return;}
const{ClosestParent,AllParents}=ParentClosingMode;switch(parentClosingMode){case ClosestParent:dropdown.close();break;case AllParents:dropdown.closeAllParents();break;}}
get dataAttributes(){const{dataset}=this.props;if(this.props.dataset){const attributes=Object.entries(dataset).map(([key,value])=>{return[`data-${key.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`)}`,value];});return Object.fromEntries(attributes);}
return{};}}
DropdownItem.template="web.DropdownItem";DropdownItem.props={onSelected:{type:Function,optional:true,},class:{type:[String,Object],optional:true,},parentClosingMode:{type:ParentClosingMode,optional:true,},hotkey:{type:String,optional:true,},href:{type:String,optional:true,},slots:{type:Object,optional:true,},title:{type:String,optional:true,},dataset:{type:Object,optional:true,},};DropdownItem.defaultProps={parentClosingMode:ParentClosingMode.AllParents,};return __exports;});;

/* /web/static/src/core/dropdown/dropdown_navigation_hook.js */
odoo.define('@web/core/dropdown/dropdown_navigation_hook',['@web/core/utils/hooks','@web/core/browser/browser','@web/core/l10n/localization','@web/core/utils/scrolling','@odoo/owl','@web/core/dropdown/accordion_item'],function(require){'use strict';let __exports={};const{useService}=require("@web/core/utils/hooks");const{browser}=require("@web/core/browser/browser");const{localization}=require("@web/core/l10n/localization");const{scrollTo}=require("@web/core/utils/scrolling");const{useChildSubEnv,useComponent,useEffect,useRef}=require("@odoo/owl");const{ACCORDION}=require("@web/core/dropdown/accordion_item");const ACTIVE_MENU_ELEMENT_CLASS="focus";const MENU_ELEMENTS_SELECTORS=[":scope > .dropdown-item",":scope > .dropdown",":scope > .o_accordion > .dropdown-item",":scope > .o_accordion > .o_accordion_values > .dropdown-item",":scope > .o_dropdown_container > .dropdown-item",":scope > .o_dropdown_container > .dropdown",":scope > .o_dropdown_container > .o_accordion > .dropdown-item",":scope > .o_dropdown_container > .o_accordion > .o_accordion_values > .dropdown-item",];const NEXT_ACTIVE_INDEX_FNS={FIRST:()=>0,LAST:(list)=>list.length-1,NEXT:(list,prevActiveIndex)=>(prevActiveIndex+1)%list.length,PREV:(list,prevActiveIndex)=>(prevActiveIndex<=0?list.length:prevActiveIndex)-1,};__exports.useDropdownNavigation=useDropdownNavigation;function useDropdownNavigation(){const comp=useComponent();if(comp.parentDropdown&&comp.props.toggler==="parent"){throw new Error("A nested Dropdown must use its standard toggler");}
const originalOnTogglerClick=comp.onTogglerClick.bind(comp);comp.onTogglerClick=(ev)=>{if(comp.parentDropdown&&!ev.__fromDropdownNavigation){return;}
originalOnTogglerClick();};const originalOnTogglerMouseEnter=comp.onTogglerMouseEnter.bind(comp);comp.onTogglerMouseEnter=()=>{if(comp.parentDropdown){return;}
originalOnTogglerMouseEnter();};let mouseSelectionActive=true;const menuRef=useRef("menuRef");let menuElements=[];let cleanupMenuElements;const refreshMenuElements=()=>{if(!comp.state.open){return;}
const addedListeners=[];const queryResult=menuRef.el.querySelectorAll(MENU_ELEMENTS_SELECTORS.join());for(const el of queryResult){const isSubDropdown=el.classList.contains("dropdown");const isSubDropdownOpen=()=>el.classList.contains("show");const navTarget=isSubDropdown?el.querySelector(":scope > .dropdown-toggle"):el;let subDropdownTimeout;const closeSubDropdown=()=>{browser.clearTimeout(subDropdownTimeout);subDropdownTimeout=browser.setTimeout(()=>{if(isSubDropdownOpen()){const ev=new MouseEvent("click",{bubbles:false});ev.__fromDropdownNavigation=true;navTarget.dispatchEvent(ev);}},200);};const openSubDropdown=(immediate=false)=>{browser.clearTimeout(subDropdownTimeout);subDropdownTimeout=browser.setTimeout(()=>{if(!isSubDropdownOpen()){const ev=new MouseEvent("click",{bubbles:false});ev.__fromDropdownNavigation=true;navTarget.dispatchEvent(ev);}},immediate?0:200);};const makeOnlyActive=()=>{for(const menuElement of menuElements){if(menuElement.el===el){continue;}
menuElement.navTarget.classList.remove(ACTIVE_MENU_ELEMENT_CLASS);if(menuElement.isSubDropdown){menuElement.closeSubDropdown();}}
navTarget.classList.add(ACTIVE_MENU_ELEMENT_CLASS);navTarget.focus();};const menuElement={el,get isActive(){return navTarget.classList.contains(ACTIVE_MENU_ELEMENT_CLASS);},makeOnlyActive,navTarget,get isSubDropdownOpen(){return isSubDropdownOpen();},isSubDropdown,closeSubDropdown,openSubDropdown,};menuElements.push(menuElement);const elementListeners={mouseenter:()=>{if(!mouseSelectionActive){mouseSelectionActive=true;}else{makeOnlyActive();if(isSubDropdown){openSubDropdown();}}},};for(const[eventType,listener]of Object.entries(elementListeners)){navTarget.addEventListener(eventType,listener);}
addedListeners.push([navTarget,elementListeners]);}
cleanupMenuElements=()=>{menuElements=[];mouseSelectionActive=true;for(const[navTarget,listeners]of addedListeners){for(const[eventType,listener]of Object.entries(listeners)){navTarget.removeEventListener(eventType,listener);}}};return()=>cleanupMenuElements();};useEffect(refreshMenuElements);useChildSubEnv({[ACCORDION]:{accordionStateChanged:()=>{cleanupMenuElements?.();refreshMenuElements();},},});const getActiveMenuElement=()=>{return menuElements.find((menuElement)=>menuElement.isActive);};const setActiveMenuElement=(menuElement)=>{if(menuElements.length){if(typeof menuElement==="string"){const prevIndex=menuElements.indexOf(getActiveMenuElement());const nextIndex=NEXT_ACTIVE_INDEX_FNS[menuElement](menuElements,prevIndex);menuElement=menuElements[nextIndex];}
menuElement.makeOnlyActive();scrollTo(menuElement.el,{scrollable:menuElement.el.parentElement});}};useEffect((open)=>{if(open&&comp.parentDropdown){setActiveMenuElement("FIRST");}},()=>[comp.state.open]);const hotkeyService=useService("hotkey");const closeAndRefocus=()=>{const toFocus=comp.props.toggler==="parent"?comp.rootRef.el.parentElement:comp.rootRef.el.querySelector(":scope > .dropdown-toggle");comp.close().then(()=>{toFocus.focus();});};const closeSubDropdown=comp.parentDropdown?closeAndRefocus:()=>{};const openSubDropdown=()=>{const menuElement=getActiveMenuElement();if(menuElement&&menuElement.isSubDropdown){menuElement.openSubDropdown(true);}};const selectActiveMenuElement=()=>{const menuElement=getActiveMenuElement();if(menuElement){if(menuElement.isSubDropdown){menuElement.openSubDropdown(true);}else{menuElement.navTarget.click();}}};let hotkeyRemoves=[];const hotkeyCallbacks={home:()=>setActiveMenuElement("FIRST"),end:()=>setActiveMenuElement("LAST"),tab:()=>setActiveMenuElement("NEXT"),"shift+tab":()=>setActiveMenuElement("PREV"),arrowdown:()=>setActiveMenuElement("NEXT"),arrowup:()=>setActiveMenuElement("PREV"),arrowleft:localization.direction==="rtl"?openSubDropdown:closeSubDropdown,arrowright:localization.direction==="rtl"?closeSubDropdown:openSubDropdown,enter:selectActiveMenuElement,escape:closeAndRefocus,};useEffect((open)=>{if(!open){return;}
for(const[hotkey,callback]of Object.entries(hotkeyCallbacks)){const callbackWrapper=()=>{const hasOpenedSubDropdown=menuElements.some((m)=>m.isSubDropdownOpen);if(!hasOpenedSubDropdown){mouseSelectionActive=false;callback.call(comp);}};hotkeyRemoves.push(hotkeyService.add(hotkey,callbackWrapper,{allowRepeat:true}));}
return()=>{for(const removeHotkey of hotkeyRemoves){removeHotkey();}
hotkeyRemoves=[];};},()=>[comp.state.open]);}
return __exports;});;

/* /web/static/src/core/effects/effect_service.js */
odoo.define('@web/core/effects/effect_service',['@web/core/l10n/translation','@web/core/registry','@web/core/effects/rainbow_man'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{RainbowMan}=require("@web/core/effects/rainbow_man");const effectRegistry=registry.category("effects");function rainbowMan(env,params={}){let message=params.message;if(message instanceof jQuery){console.log("Providing a jQuery element to an effect is deprecated. Note that all event handlers will be lost.");message=message.html();}else if(message instanceof Element){console.log("Providing an HTML element to an effect is deprecated. Note that all event handlers will be lost.");message=message.outerHTML;}else if(!message){message=_t("Well Done!");}
if(env.services.user.showEffect){const props={imgUrl:params.img_url||"/web/static/img/smile.svg",fadeout:params.fadeout||"medium",message,Component:params.Component,props:params.props,};return{Component:RainbowMan,props};}
env.services.notification.add(message);}
effectRegistry.add("rainbow_man",rainbowMan);const effectService=__exports.effectService={dependencies:["overlay"],start(env,{overlay}){const add=(params={})=>{const type=params.type||"rainbow_man";const effect=effectRegistry.get(type);const{Component,props}=effect(env,params)||{};if(Component){const remove=overlay.add(Component,{...props,close:()=>remove(),});}};return{add};},};registry.category("services").add("effect",effectService);return __exports;});;

/* /web/static/src/core/effects/rainbow_man.js */
odoo.define('@web/core/effects/rainbow_man',['@web/core/browser/browser','@odoo/owl'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{Component,useEffect,useExternalListener,useState}=require("@odoo/owl");const RainbowMan=__exports.RainbowMan=class RainbowMan extends Component{setup(){useExternalListener(document.body,"click",this.closeRainbowMan);this.state=useState({isFading:false});this.delay=RainbowMan.rainbowFadeouts[this.props.fadeout];if(this.delay){useEffect(()=>{const timeout=browser.setTimeout(()=>{this.state.isFading=true;},this.delay);return()=>browser.clearTimeout(timeout);},()=>[]);}}
onAnimationEnd(ev){if(this.delay&&ev.animationName==="reward-fading-reverse"){ev.stopPropagation();this.closeRainbowMan();}}
closeRainbowMan(){this.props.close();}}
RainbowMan.template="web.RainbowMan";RainbowMan.props={fadeout:String,close:Function,message:String,imgUrl:String,Component:{type:Function,optional:true},props:{type:Object,optional:true},};RainbowMan.rainbowFadeouts={slow:4500,medium:3500,fast:2000,no:false};return __exports;});;

/* /web/static/src/core/emoji_picker/emoji_picker.js */
odoo.define('@web/core/emoji_picker/emoji_picker',['@web/core/utils/misc','@odoo/owl','@web/core/assets','@web/core/browser/browser','@web/core/l10n/translation','@web/core/popover/popover_hook','@web/core/utils/search','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{markEventHandled}=require("@web/core/utils/misc");const{Component,onMounted,onPatched,onWillDestroy,onWillPatch,onWillStart,onWillUnmount,useEffect,useRef,useState,}=require("@odoo/owl");const{loadBundle}=require("@web/core/assets");const{browser}=require("@web/core/browser/browser");const{_t}=require("@web/core/l10n/translation");const{usePopover}=require("@web/core/popover/popover_hook");const{fuzzyLookup}=require("@web/core/utils/search");const{useAutofocus,useService}=require("@web/core/utils/hooks");__exports.useEmojiPicker=useEmojiPicker;function useEmojiPicker(ref,props,options={}){const targets=[];const popover=usePopover(EmojiPicker,{...options,animation:false});props.storeScroll={scrollValue:0,set:(value)=>{props.storeScroll.scrollValue=value;},get:()=>{return props.storeScroll.scrollValue;},};function add(ref,onSelect,{show=false}={}){const toggler=()=>toggle(ref,onSelect);targets.push([ref,toggler]);if(!ref.el){return;}
ref.el.addEventListener("click",toggler);ref.el.addEventListener("mouseenter",loadEmoji);if(show){ref.el.click();}}
function toggle(ref,onSelect=props.onSelect){if(popover.isOpen){popover.close();}else{popover.open(ref.el,{...props,onSelect});}}
if(ref){add(ref);}
onMounted(()=>{for(const[ref,toggle]of targets){if(!ref.el){continue;}
ref.el.addEventListener("click",toggle);ref.el.addEventListener("mouseenter",loadEmoji);}});onWillPatch(()=>{for(const[ref,toggle]of targets){if(!ref.el){continue;}
ref.el.removeEventListener("click",toggle);ref.el.removeEventListener("mouseenter",loadEmoji);}});onPatched(()=>{for(const[ref,toggle]of targets){if(!ref.el){continue;}
ref.el.addEventListener("click",toggle);ref.el.addEventListener("mouseenter",loadEmoji);}});return{add,get isOpen(){return popover.isOpen;},};}
const loader=__exports.loader={loadEmoji:()=>loadBundle("web.assets_emoji"),};__exports.loadEmoji=loadEmoji;async function loadEmoji(){try{await loader.loadEmoji();return odoo.loader.modules.get("@web/core/emoji_picker/emoji_data");}catch{return{emojis:[],categories:[]};}}
const EMOJI_PER_ROW=__exports.EMOJI_PER_ROW=9;const EmojiPicker=__exports.EmojiPicker=class EmojiPicker extends Component{static props=["close?","onClose?","onSelect","state?","storeScroll?"];static template="web.EmojiPicker";categories=null;emojis=null;shouldScrollElem=null;lastSearchTerm;setup(){this.gridRef=useRef("emoji-grid");this.ui=useState(useService("ui"));this.state=useState({activeEmojiIndex:0,categoryId:null,recent:JSON.parse(browser.localStorage.getItem("web.emoji.frequent")||"{}"),searchTerm:"",});const onStorage=(ev)=>{if(ev.key==="web.emoji.frequent"){this.state.recent=ev.newValue?JSON.parse(ev.newValue):{};}else if(ev.key===null){this.state.recent={};}};browser.addEventListener("storage",onStorage);onWillDestroy(()=>{browser.removeEventListener("storage",onStorage);});useAutofocus();onWillStart(async()=>{const{categories,emojis}=await loadEmoji();this.categories=categories;this.emojis=emojis;this.emojiByCodepoints=Object.fromEntries(this.emojis.map((emoji)=>[emoji.codepoints,emoji]));this.state.categoryId=this.categories[0]?.sortId;this.recentCategory={name:"Frequently used",displayName:_t("Frequently used"),title:"🕓",sortId:0,};});onMounted(()=>{if(this.emojis.length===0){return;}
this.highlightActiveCategory();if(this.props.storeScroll){this.gridRef.el.scrollTop=this.props.storeScroll.get();}});onPatched(()=>{if(this.emojis.length===0){return;}
if(this.shouldScrollElem){this.shouldScrollElem=false;const getElement=()=>this.gridRef.el.querySelector(`.o-EmojiPicker-category[data-category="${this.state.categoryId}"`);const elem=getElement();if(elem){elem.scrollIntoView();}else{this.shouldScrollElem=getElement;}}});useEffect(()=>{if(this.searchTerm){this.gridRef.el.scrollTop=0;this.state.categoryId=null;}else{if(this.lastSearchTerm){this.gridRef.el.scrollTop=0;}
this.highlightActiveCategory();}
this.lastSearchTerm=this.searchTerm;},()=>[this.searchTerm]);onWillUnmount(()=>{if(!this.gridRef.el){return;}
if(this.props.storeScroll){this.props.storeScroll.set(this.gridRef.el.scrollTop);}});}
get searchTerm(){return this.props.state?this.props.state.searchTerm:this.state.searchTerm;}
set searchTerm(value){if(this.props.state){this.props.state.searchTerm=value;}else{this.state.searchTerm=value;}}
get itemsNumber(){return this.recentEmojis.length+this.getEmojis().length;}
get recentEmojis(){return Object.entries(this.state.recent).sort(([,usage_1],[,usage_2])=>usage_2-usage_1).slice(0,42).map(([codepoints])=>this.emojiByCodepoints[codepoints]);}
onClick(ev){markEventHandled(ev,"emoji.selectEmoji");}
onKeydown(ev){switch(ev.key){case"ArrowUp":{const newIndex=this.state.activeEmojiIndex-EMOJI_PER_ROW;if(newIndex>=0){this.state.activeEmojiIndex=newIndex;}
break;}
case"ArrowDown":{const newIndex=this.state.activeEmojiIndex+EMOJI_PER_ROW;if(newIndex<this.itemsNumber){this.state.activeEmojiIndex=newIndex;}
break;}
case"ArrowRight":{if(this.state.activeEmojiIndex+1===this.itemsNumber){break;}
this.state.activeEmojiIndex++;ev.preventDefault();break;}
case"ArrowLeft":{const newIndex=Math.max(this.state.activeEmojiIndex-1,0);if(newIndex!==this.state.activeEmojiIndex){this.state.activeEmojiIndex=newIndex;ev.preventDefault();}
break;}
case"Enter":ev.preventDefault();this.gridRef.el.querySelector(`.o-EmojiPicker-content .o-Emoji[data-index="${this.state.activeEmojiIndex}"]`)?.click();break;case"Escape":this.props.close?.();this.props.onClose?.();ev.stopPropagation();}}
getEmojis(){if(this.searchTerm.length>1){return fuzzyLookup(this.searchTerm,this.emojis,(emoji)=>[emoji.name,...emoji.keywords,...emoji.emoticons,...emoji.shortcodes].join(" "));}
return this.emojis;}
selectCategory(ev){const id=Number(ev.currentTarget.dataset.id);this.searchTerm="";this.state.categoryId=id;this.shouldScrollElem=true;}
selectEmoji(ev){const codepoints=ev.currentTarget.dataset.codepoints;const resetOnSelect=!ev.shiftKey&&!this.ui.isSmall;this.props.onSelect(codepoints,resetOnSelect);this.state.recent[codepoints]??=0;this.state.recent[codepoints]++;browser.localStorage.setItem("web.emoji.frequent",JSON.stringify(this.state.recent));if(resetOnSelect){this.gridRef.el.scrollTop=0;this.props.close?.();this.props.onClose?.();}}
highlightActiveCategory(){if(!this.gridRef||!this.gridRef.el){return;}
const coords=this.gridRef.el.getBoundingClientRect();const res=document.elementFromPoint(coords.x,coords.y+1);if(!res){return;}
this.state.categoryId=parseInt(res.dataset.category);}}
return __exports;});;

/* /web/static/src/core/errors/error_dialogs.js */
odoo.define('@web/core/errors/error_dialogs',['@web/core/browser/browser','@web/core/dialog/dialog','@web/core/l10n/translation','@web/core/registry','@web/core/utils/hooks','@web/core/utils/strings','@odoo/owl'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{Dialog}=require("@web/core/dialog/dialog");const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{useService}=require("@web/core/utils/hooks");const{capitalize}=require("@web/core/utils/strings");const{Component,useState,markup}=require("@odoo/owl");const standardErrorDialogProps=__exports.standardErrorDialogProps={traceback:{type:[String,{value:null}],optional:true},message:{type:String,optional:true},name:{type:String,optional:true},exceptionName:{type:[String,{value:null}],optional:true},data:{type:[Object,{value:null}],optional:true},subType:{type:[String,{value:null}],optional:true},code:{type:[Number,String,{value:null}],optional:true},type:{type:[String,{value:null}],optional:true},close:Function,};const odooExceptionTitleMap=__exports.odooExceptionTitleMap=new Map(Object.entries({"odoo.addons.base.models.ir_mail_server.MailDeliveryException":_t("MailDeliveryException"),"odoo.exceptions.AccessDenied":_t("Access Denied"),"odoo.exceptions.MissingError":_t("Missing Record"),"odoo.exceptions.UserError":_t("Invalid Operation"),"odoo.exceptions.ValidationError":_t("Validation Error"),"odoo.exceptions.AccessError":_t("Access Error"),"odoo.exceptions.Warning":_t("Warning"),}));const ErrorDialog=__exports.ErrorDialog=class ErrorDialog extends Component{setup(){this.state=useState({showTraceback:false,});}
onClickClipboard(){browser.navigator.clipboard.writeText(`${this.props.name}\n${this.props.message}\n${this.props.traceback}`);}}
ErrorDialog.template="web.ErrorDialog";ErrorDialog.components={Dialog};ErrorDialog.title=_t("Odoo Error");ErrorDialog.props={...standardErrorDialogProps};const ClientErrorDialog=__exports.ClientErrorDialog=class ClientErrorDialog extends ErrorDialog{}
ClientErrorDialog.title=_t("Odoo Client Error");const NetworkErrorDialog=__exports.NetworkErrorDialog=class NetworkErrorDialog extends ErrorDialog{}
NetworkErrorDialog.title=_t("Odoo Network Error");const RPCErrorDialog=__exports.RPCErrorDialog=class RPCErrorDialog extends ErrorDialog{setup(){super.setup();this.inferTitle();this.traceback=this.props.traceback;if(this.props.data&&this.props.data.debug){this.traceback=`${this.props.data.debug}\nThe above server error caused the following client error:\n${this.traceback}`;}}
inferTitle(){if(this.props.exceptionName&&odooExceptionTitleMap.has(this.props.exceptionName)){this.title=odooExceptionTitleMap.get(this.props.exceptionName).toString();return;}
if(!this.props.type){return;}
switch(this.props.type){case"server":this.title=_t("Odoo Server Error");break;case"script":this.title=_t("Odoo Client Error");break;case"network":this.title=_t("Odoo Network Error");break;}}
onClickClipboard(){browser.navigator.clipboard.writeText(`${this.props.name}\n${this.props.message}\n${this.traceback}`);}}
const WarningDialog=__exports.WarningDialog=class WarningDialog extends Component{setup(){this.title=this.inferTitle();const{data,message}=this.props;if(data&&data.arguments&&data.arguments.length>0){this.message=data.arguments[0];}else{this.message=message;}}
inferTitle(){if(this.props.exceptionName&&odooExceptionTitleMap.has(this.props.exceptionName)){return odooExceptionTitleMap.get(this.props.exceptionName).toString();}
return this.props.title||_t("Odoo Warning");}}
WarningDialog.template="web.WarningDialog";WarningDialog.components={Dialog};WarningDialog.props={...standardErrorDialogProps,title:{type:String,optional:true},};const RedirectWarningDialog=__exports.RedirectWarningDialog=class RedirectWarningDialog extends Component{setup(){this.actionService=useService("action");const{data,subType}=this.props;const[message,actionId,buttonText,additionalContext]=data.arguments;this.title=capitalize(subType)||_t("Odoo Warning");this.message=message;this.actionId=actionId;this.buttonText=buttonText;this.additionalContext=additionalContext;}
async onClick(){const options={};if(this.additionalContext){options.additionalContext=this.additionalContext;}
if(this.actionId.help){this.actionId.help=markup(this.actionId.help);}
await this.actionService.doAction(this.actionId,options);this.props.close();}}
RedirectWarningDialog.template="web.RedirectWarningDialog";RedirectWarningDialog.components={Dialog};RedirectWarningDialog.props={...standardErrorDialogProps};const Error504Dialog=__exports.Error504Dialog=class Error504Dialog extends Component{}
Error504Dialog.template="web.Error504Dialog";Error504Dialog.components={Dialog};Error504Dialog.title=_t("Request timeout");Error504Dialog.props={...standardErrorDialogProps};const SessionExpiredDialog=__exports.SessionExpiredDialog=class SessionExpiredDialog extends Component{onClick(){browser.location.reload();}}
SessionExpiredDialog.template="web.SessionExpiredDialog";SessionExpiredDialog.components={Dialog};SessionExpiredDialog.title=_t("Odoo Session Expired");SessionExpiredDialog.props={...standardErrorDialogProps};registry.category("error_dialogs").add("odoo.exceptions.AccessDenied",WarningDialog).add("odoo.exceptions.AccessError",WarningDialog).add("odoo.exceptions.MissingError",WarningDialog).add("odoo.exceptions.UserError",WarningDialog).add("odoo.exceptions.ValidationError",WarningDialog).add("odoo.exceptions.RedirectWarning",RedirectWarningDialog).add("odoo.http.SessionExpiredException",SessionExpiredDialog).add("werkzeug.exceptions.Forbidden",SessionExpiredDialog).add("504",Error504Dialog);return __exports;});;

/* /web/static/src/core/errors/error_handlers.js */
odoo.define('@web/core/errors/error_handlers',['@web/core/l10n/translation','@web/core/browser/browser','@web/core/network/rpc_service','@web/core/registry','@web/core/errors/error_dialogs','@web/core/errors/error_service'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{browser}=require("@web/core/browser/browser");const{ConnectionLostError,RPCError}=require("@web/core/network/rpc_service");const{registry}=require("@web/core/registry");const{ClientErrorDialog,ErrorDialog,NetworkErrorDialog,RPCErrorDialog,}=require("@web/core/errors/error_dialogs");const{UncaughtClientError,UncaughtCorsError,UncaughtPromiseError}=require("@web/core/errors/error_service");const errorHandlerRegistry=registry.category("error_handlers");const errorDialogRegistry=registry.category("error_dialogs");const errorNotificationRegistry=registry.category("error_notifications");__exports.rpcErrorHandler=rpcErrorHandler;function rpcErrorHandler(env,error,originalError){if(!(error instanceof UncaughtPromiseError)){return false;}
if(originalError instanceof RPCError){error.unhandledRejectionEvent.preventDefault();const exceptionName=originalError.exceptionName;let ErrorComponent=originalError.Component;if(!ErrorComponent&&exceptionName){if(errorNotificationRegistry.contains(exceptionName)){const notif=errorNotificationRegistry.get(exceptionName);env.services.notification.add(notif.message||originalError.data.message,notif);return true;}
if(errorDialogRegistry.contains(exceptionName)){ErrorComponent=errorDialogRegistry.get(exceptionName);}}
if(!ErrorComponent&&originalError.data.context){const exceptionClass=originalError.data.context.exception_class;if(errorDialogRegistry.contains(exceptionClass)){ErrorComponent=errorDialogRegistry.get(exceptionClass);}}
env.services.dialog.add(ErrorComponent||RPCErrorDialog,{traceback:error.traceback,message:originalError.message,name:originalError.name,exceptionName:originalError.exceptionName,data:originalError.data,subType:originalError.subType,code:originalError.code,type:originalError.type,});return true;}}
errorHandlerRegistry.add("rpcErrorHandler",rpcErrorHandler,{sequence:97});let connectionLostNotifRemove=null;__exports.lostConnectionHandler=lostConnectionHandler;function lostConnectionHandler(env,error,originalError){if(!(error instanceof UncaughtPromiseError)){return false;}
if(originalError instanceof ConnectionLostError){if(connectionLostNotifRemove){return true;}
connectionLostNotifRemove=env.services.notification.add(_t("Connection lost. Trying to reconnect..."),{sticky:true});let delay=2000;browser.setTimeout(function checkConnection(){env.services.rpc("/web/webclient/version_info",{}).then(function(){if(connectionLostNotifRemove){connectionLostNotifRemove();connectionLostNotifRemove=null;}
env.services.notification.add(_t("Connection restored. You are back online."),{type:"info",});}).catch(()=>{delay=delay*1.5+500*Math.random();browser.setTimeout(checkConnection,delay);});},delay);return true;}}
errorHandlerRegistry.add("lostConnectionHandler",lostConnectionHandler,{sequence:98});const defaultDialogs=new Map([[UncaughtClientError,ClientErrorDialog],[UncaughtPromiseError,ClientErrorDialog],[UncaughtCorsError,NetworkErrorDialog],]);__exports.defaultHandler=defaultHandler;function defaultHandler(env,error){const DialogComponent=defaultDialogs.get(error.constructor)||ErrorDialog;env.services.dialog.add(DialogComponent,{traceback:error.traceback,message:error.message,name:error.name,});return true;}
errorHandlerRegistry.add("defaultHandler",defaultHandler,{sequence:100});return __exports;});;

/* /web/static/src/core/errors/error_service.js */
odoo.define('@web/core/errors/error_service',['@web/core/browser/feature_detection','@web/core/browser/browser','@web/core/registry','@web/core/errors/error_utils'],function(require){'use strict';let __exports={};const{isBrowserFirefox,isBrowserChrome}=require("@web/core/browser/feature_detection");const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{completeUncaughtError,getErrorTechnicalName}=require("@web/core/errors/error_utils");const UncaughtError=__exports.UncaughtError=class UncaughtError extends Error{constructor(message){super(message);this.name=getErrorTechnicalName(this);this.traceback=null;}}
const UncaughtClientError=__exports.UncaughtClientError=class UncaughtClientError extends UncaughtError{constructor(message="Uncaught Javascript Error"){super(message);}}
const UncaughtPromiseError=__exports.UncaughtPromiseError=class UncaughtPromiseError extends UncaughtError{constructor(message="Uncaught Promise"){super(message);this.unhandledRejectionEvent=null;}}
const UncaughtCorsError=__exports.UncaughtCorsError=class UncaughtCorsError extends UncaughtError{constructor(message="Uncaught CORS Error"){super(message);}}
const errorService=__exports.errorService={start(env){function handleError(uncaughtError,retry=true){let originalError=uncaughtError;while(originalError instanceof Error&&"cause"in originalError){originalError=originalError.cause;}
for(const[name,handler]of registry.category("error_handlers").getEntries()){try{if(handler(env,uncaughtError,originalError)){break;}}catch(e){console.error(`A crash occured in error handler ${name} while handling ${uncaughtError}:`,e);return;}}
if(uncaughtError.event&&!uncaughtError.event.defaultPrevented&&uncaughtError.traceback){uncaughtError.event.preventDefault();console.error(uncaughtError.traceback);}}
browser.addEventListener("error",async(ev)=>{const{colno,error,filename,lineno,message}=ev;const errorsToIgnore=["ResizeObserver loop completed with undelivered notifications.","ResizeObserver loop limit exceeded",];if(!error&&errorsToIgnore.includes(message)){return;}
const isRedactedError=!filename&&!lineno&&!colno;const isThirdPartyScriptError=isRedactedError||(isBrowserFirefox()&&new URL(filename).origin!==window.location.origin);if(isThirdPartyScriptError&&!odoo.debug){return;}
let uncaughtError;if(isRedactedError){uncaughtError=new UncaughtCorsError();uncaughtError.traceback=`Unknown CORS error\n\n`+`An unknown CORS error occured.\n`+`The error probably originates from a JavaScript file served from a different origin.\n`+`(Opening your browser console might give you a hint on the error.)`;}else{uncaughtError=new UncaughtClientError();uncaughtError.event=ev;if(error instanceof Error){error.errorEvent=ev;const annotated=env.debug&&env.debug.includes("assets");await completeUncaughtError(uncaughtError,error,annotated);}}
uncaughtError.cause=error;handleError(uncaughtError);});browser.addEventListener("unhandledrejection",async(ev)=>{const error=ev.reason;let traceback;if(isBrowserChrome()&&ev instanceof CustomEvent&&error===undefined){if(!odoo.debug){return;}
traceback=`Uncaught unknown Error\n`+`An unknown error occured. This may be due to a Chrome extension meddling with Odoo.\n`+`(Opening your browser console might give you a hint on the error.)`;}
const uncaughtError=new UncaughtPromiseError();uncaughtError.unhandledRejectionEvent=ev;uncaughtError.event=ev;uncaughtError.traceback=traceback;if(error instanceof Error){error.errorEvent=ev;const annotated=env.debug&&env.debug.includes("assets");await completeUncaughtError(uncaughtError,error,annotated);}
uncaughtError.cause=error;handleError(uncaughtError);});},};registry.category("services").add("error",errorService,{sequence:1});return __exports;});;

/* /web/static/src/core/errors/error_utils.js */
odoo.define('@web/core/errors/error_utils',['@web/core/assets'],function(require){'use strict';let __exports={};const{loadJS}=require("@web/core/assets");function combineErrorNames(uncaughtError,originalError){const originalErrorName=getErrorTechnicalName(originalError);const uncaughtErrorName=getErrorTechnicalName(uncaughtError);if(originalErrorName===Error.name){return uncaughtErrorName;}else{return`${uncaughtErrorName} > ${originalErrorName}`;}}
__exports.fullTraceback=fullTraceback;function fullTraceback(error){let traceback=formatTraceback(error);let current=error.cause;while(current){traceback+=`\n\nCaused by: ${
            current instanceof Error ? formatTraceback(current) : current
        }`;current=current.cause;}
return traceback;}
__exports.fullAnnotatedTraceback=fullAnnotatedTraceback;async function fullAnnotatedTraceback(error){if(error.annotatedTraceback){return error.annotatedTraceback;}
if(error.errorEvent){error.errorEvent.preventDefault();}
let traceback;try{traceback=await annotateTraceback(error);let current=error.cause;while(current){traceback+=`\n\nCaused by: ${
                current instanceof Error ? await annotateTraceback(current) : current
            }`;current=current.cause;}}catch(e){console.warn("Failed to annotate traceback for error:",error,"failure reason:",e);traceback=fullTraceback(error);}
error.annotatedTraceback=traceback;if(error.errorEvent){throw error;}
return traceback;}
__exports.completeUncaughtError=completeUncaughtError;async function completeUncaughtError(uncaughtError,originalError,annotated=false){uncaughtError.name=combineErrorNames(uncaughtError,originalError);if(annotated){uncaughtError.traceback=await fullAnnotatedTraceback(originalError);}else{uncaughtError.traceback=fullTraceback(originalError);}
if(originalError.message){uncaughtError.message=`${uncaughtError.message} > ${originalError.message}`;}
uncaughtError.cause=originalError;}
__exports.getErrorTechnicalName=getErrorTechnicalName;function getErrorTechnicalName(error){return error.name!==Error.name?error.name:error.constructor.name;}
__exports.formatTraceback=formatTraceback;function formatTraceback(error){let traceback=error.stack;const errorName=getErrorTechnicalName(error);const descriptionLine=`${errorName}: ${error.message}`;if(error.stack.split("\n")[0].trim()!==descriptionLine){traceback=`${descriptionLine}\n${error.stack}`.replace(/\n/g,"\n    ");}
return traceback;}
__exports.annotateTraceback=annotateTraceback;async function annotateTraceback(error){const traceback=formatTraceback(error);try{await loadJS("/web/static/lib/stacktracejs/stacktrace.js");}catch{return traceback;}
if(error.stack){const regex=/ line (\d*) > (Function):(\d*)/gm;const subst=`:$1`;error.stack=error.stack.replace(regex,subst);}
let frames;try{frames=await StackTrace.fromError(error);}catch(e){console.warn("The following error could not be annotated:",error,e);return traceback;}
const lines=traceback.split("\n");if(lines[lines.length-1].trim()===""){lines.splice(-1);}
let lineIndex=0;let frameIndex=0;while(frameIndex<frames.length){const line=lines[lineIndex];if(!line.match(/:\d+:\d+\)?$/)){lineIndex++;continue;}
const frame=frames[frameIndex];const info=` (${frame.fileName}:${frame.lineNumber})`;lines[lineIndex]=line+info;lineIndex++;frameIndex++;}
return lines.join("\n");}
return __exports;});;

/* /web/static/src/core/errors/scss_error_dialog.js */
odoo.define('@web/core/errors/scss_error_dialog',['@web/core/browser/browser','@web/core/registry','@web/core/l10n/translation','@web/core/utils/urls'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{_t,translationIsReady}=require("@web/core/l10n/translation");const{getOrigin}=require("@web/core/utils/urls");const scssErrorNotificationService={dependencies:["notification"],start(env,{notification}){const origin=getOrigin();const assets=[...document.styleSheets].filter((sheet)=>{return(sheet.href?.includes("/web")&&sheet.href?.includes("/assets/")&&new URL(sheet.href,browser.location.origin).origin===origin);});translationIsReady.then(()=>{for(const asset of assets){let cssRules;try{cssRules=asset.cssRules;}catch{continue;}
const lastRule=cssRules?.[cssRules?.length-1];if(lastRule?.selectorText==="css_error_message"){const message=_t("The style compilation failed. This is an administrator or developer error that must be fixed for the entire database before continuing working. See browser console or server logs for details.");notification.add(message,{title:_t("Style error"),sticky:true,type:"danger",});console.log(lastRule.style.content.replaceAll("\\a","\n").replaceAll("\\*","*").replaceAll(`\\"`,`"`));}}});},};registry.category("services").add("scss_error_display",scssErrorNotificationService);return __exports;});;

/* /web/static/src/core/expression_editor/expression_editor.js */
odoo.define('@web/core/expression_editor/expression_editor',['@odoo/owl','@web/core/expression_editor/expression_editor_operator_editor','@web/core/tree_editor/condition_tree','@web/core/tree_editor/tree_editor','@web/core/tree_editor/tree_editor_operator_editor','@web/core/tree_editor/tree_editor_value_editors','@web/core/tree_editor/utils','@web/core/model_field_selector/model_field_selector','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{Component,onWillStart,onWillUpdateProps}=require("@odoo/owl");const{getExpressionDisplayedOperators}=require("@web/core/expression_editor/expression_editor_operator_editor");const{condition,expressionFromTree,treeFromExpression,}=require("@web/core/tree_editor/condition_tree");const{TreeEditor}=require("@web/core/tree_editor/tree_editor");const{getOperatorEditorInfo}=require("@web/core/tree_editor/tree_editor_operator_editor");const{getDefaultValue}=require("@web/core/tree_editor/tree_editor_value_editors");const{getDefaultPath}=require("@web/core/tree_editor/utils");const{ModelFieldSelector}=require("@web/core/model_field_selector/model_field_selector");const{_t}=require("@web/core/l10n/translation");function getDefaultCondition(fieldDefs){const defaultPath=getDefaultPath(fieldDefs);const fieldDef=fieldDefs[defaultPath];const operator=getExpressionDisplayedOperators(fieldDef)[0];const value=getDefaultValue(fieldDef,operator);return condition(fieldDef.name,operator,value);}
const ExpressionEditor=__exports.ExpressionEditor=class ExpressionEditor extends Component{static template="web.ExpressionEditor";static components={TreeEditor};static props={resModel:String,fields:Object,expression:String,update:Function,};setup(){onWillStart(()=>this.onPropsUpdated(this.props));onWillUpdateProps((nextProps)=>this.onPropsUpdated(nextProps));}
async onPropsUpdated(props){this.filteredFields=Object.fromEntries(Object.entries(props.fields).filter(([_,fieldDef])=>fieldDef.type!=="properties"));this.defaultCondition=getDefaultCondition(this.filteredFields);try{this.tree=treeFromExpression(props.expression,{getFieldDef:(name)=>this.getFieldDef(name,props),distributeNot:!this.isDebugMode,});}catch{this.tree=null;}}
getFieldDef(name,props=this.props){if(typeof name==="string"){return props.fields[name]||null;}
return null;}
getDefaultOperator(fieldDef){return getExpressionDisplayedOperators(fieldDef)[0];}
getOperatorEditorInfo(node){const fieldDef=this.getFieldDef(node.path);const operators=getExpressionDisplayedOperators(fieldDef);return getOperatorEditorInfo(operators);}
getPathEditorInfo(){return{component:ModelFieldSelector,extractProps:({value,update})=>({path:value,update,resModel:this.props.resModel,readonly:false,filter:(fieldDef)=>fieldDef.name in this.filteredFields,showDebugInput:false,followRelations:false,isDebugMode:this.isDebugMode,}),isSupported:(value)=>[0,1].includes(value)||value in this.filteredFields,stringify:(value)=>this.props.fields[value].string,defaultValue:()=>this.defaultCondition.path,message:_t("Field properties not supported"),};}
get isDebugMode(){return!!this.env.debug;}
onExpressionChange(expression){this.props.update(expression);}
resetExpression(){this.props.update("True");}
update(tree){const expression=expressionFromTree(tree,{getFieldDef:(name)=>this.getFieldDef(name),});this.props.update(expression);}}
return __exports;});;

/* /web/static/src/core/expression_editor/expression_editor_operator_editor.js */
odoo.define('@web/core/expression_editor/expression_editor_operator_editor',['@web/core/domain_selector/domain_selector_operator_editor'],function(require){'use strict';let __exports={};const{getDomainDisplayedOperators}=require("@web/core/domain_selector/domain_selector_operator_editor");const EXPRESSION_VALID_OPERATORS=["<","<=",">",">=","between","in","not in","=","!=","set","not_set","is","is_not",];__exports.getExpressionDisplayedOperators=getExpressionDisplayedOperators;function getExpressionDisplayedOperators(fieldDef){const operators=getDomainDisplayedOperators(fieldDef);return operators.filter((operator)=>EXPRESSION_VALID_OPERATORS.includes(operator));}
return __exports;});;

/* /web/static/src/core/expression_editor_dialog/expression_editor_dialog.js */
odoo.define('@web/core/expression_editor_dialog/expression_editor_dialog',['@odoo/owl','@web/core/dialog/dialog','@web/core/expression_editor/expression_editor','@web/core/py_js/py','@web/core/utils/hooks','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{Component,useRef,useState}=require("@odoo/owl");const{Dialog}=require("@web/core/dialog/dialog");const{ExpressionEditor}=require("@web/core/expression_editor/expression_editor");const{evaluateExpr}=require("@web/core/py_js/py");const{useService}=require("@web/core/utils/hooks");const{_t}=require("@web/core/l10n/translation");const ExpressionEditorDialog=__exports.ExpressionEditorDialog=class ExpressionEditorDialog extends Component{static components={Dialog,ExpressionEditor};static template="web.ExpressionEditorDialog";static props={close:Function,resModel:String,fields:Object,expression:String,onConfirm:Function,};setup(){this.notification=useService("notification");this.user=useService("user");this.state=useState({expression:this.props.expression,});this.confirmButtonRef=useRef("confirm");}
get expressionEditorProps(){return{resModel:this.props.resModel,fields:this.props.fields,expression:this.state.expression,update:(expression)=>{this.state.expression=expression;},};}
makeDefaultRecord(){const record={};for(const[name,{type}]of Object.entries(this.props.fields)){switch(type){case"integer":case"float":case"monetary":record[name]=name==="id"?false:0;break;case"one2many":case"many2many":record[name]=[];break;default:record[name]=false;}}
return record;}
async onConfirm(){this.confirmButtonRef.el.disabled=true;const record=this.makeDefaultRecord();const evalContext={...this.user.context,...record};try{evaluateExpr(this.state.expression,evalContext);}catch{if(this.confirmButtonRef.el){this.confirmButtonRef.el.disabled=false;}
this.notification.add(_t("Expression is invalid. Please correct it"),{type:"danger",});return;}
this.props.onConfirm(this.state.expression);this.props.close();}
onDiscard(){this.props.close();}}
return __exports;});;

/* /web/static/src/core/field_service.js */
odoo.define('@web/core/field_service',['@web/core/utils/cache','@web/core/domain','@web/core/registry'],function(require){'use strict';let __exports={};const{Cache}=require("@web/core/utils/cache");const{Domain}=require("@web/core/domain");const{registry}=require("@web/core/registry");const fieldService=__exports.fieldService={dependencies:["orm"],async:["loadFields","loadPath","loadPropertyDefinitions"],start(env,{orm}){const cache=new Cache((resModel,options)=>{return orm.call(resModel,"fields_get",[options.fieldNames,options.attributes]).catch((error)=>{cache.clear(resModel,options);return Promise.reject(error);});},(resModel,options)=>JSON.stringify([resModel,options.fieldNames,options.attributes]));env.bus.addEventListener("CLEAR-CACHES",()=>cache.invalidate());async function loadFields(resModel,options={}){if(typeof resModel!=="string"||!resModel){throw new Error(`Invalid model name: ${resModel}`);}
return cache.read(resModel,options);}
async function _loadPropertyDefinitions(fieldDefs,name,domain=[]){const{definition_record:definitionRecord,definition_record_field:definitionRecordField,}=fieldDefs[name];const definitionRecordModel=fieldDefs[definitionRecord].relation;domain=Domain.and([[[definitionRecordField,"!=",false]],domain]).toList();const result=await orm.webSearchRead(definitionRecordModel,domain,{specification:{display_name:{},[definitionRecordField]:{},},});const definitions={};for(const record of result.records){for(const definition of record[definitionRecordField]){definitions[definition.name]={is_property:true,searchable:true,record_id:record.id,record_name:record.display_name,...definition,};}}
return definitions;}
async function loadPropertyDefinitions(resModel,fieldName,domain){const fieldDefs=await loadFields(resModel);return _loadPropertyDefinitions(fieldDefs,fieldName,domain);}
async function _loadPath(resModel,fieldDefs,names){if(!fieldDefs){return{isInvalid:"path",names,modelsInfo:[]};}
const[name,...remainingNames]=names;const modelsInfo=[{resModel,fieldDefs}];if(resModel==="*"&&remainingNames.length){return{isInvalid:"path",names,modelsInfo};}
const fieldDef=fieldDefs[name];if((name!=="*"&&!fieldDef)||(name==="*"&&remainingNames.length)){return{isInvalid:"path",names,modelsInfo};}
if(!remainingNames.length){return{names,modelsInfo};}
let subResult;if(fieldDef.relation){subResult=await _loadPath(fieldDef.relation,await loadFields(fieldDef.relation),remainingNames);}else if(fieldDef.type==="properties"){subResult=await _loadPath("*",await _loadPropertyDefinitions(fieldDefs,name),remainingNames);}
if(subResult){const result={names,modelsInfo:[...modelsInfo,...subResult.modelsInfo],};if(subResult.isInvalid){result.isInvalid="path";}
return result;}
return{isInvalid:"path",names,modelsInfo};}
async function loadPath(resModel,path="*"){const fieldDefs=await loadFields(resModel);if(typeof path!=="string"||!path){throw new Error(`Invalid path: ${path}`);}
return _loadPath(resModel,fieldDefs,path.split("."));}
return{loadFields,loadPath,loadPropertyDefinitions};},};registry.category("services").add("field",fieldService);return __exports;});;

/* /web/static/src/core/file_input/file_input.js */
odoo.define('@web/core/file_input/file_input',['@web/core/utils/hooks','@odoo/owl','@web/core/utils/files'],function(require){'use strict';let __exports={};const{useService}=require("@web/core/utils/hooks");const{Component,onMounted,useRef,useState}=require("@odoo/owl");const{checkFileSize}=require("@web/core/utils/files");const FileInput=__exports.FileInput=class FileInput extends Component{setup(){this.http=useService("http");this.notification=useService("notification");this.fileInputRef=useRef("file-input");this.state=useState({isDisable:false,});onMounted(()=>{if(this.props.autoOpen){this.onTriggerClicked();}});}
get httpParams(){const{resId,resModel}=this.props;const params={csrf_token:odoo.csrf_token,ufile:[...this.fileInputRef.el.files],};if(resModel){params.model=resModel;}
if(resId!==undefined){params.id=resId;}
return params;}
async uploadFiles(params){if((params.ufile&&params.ufile.length)||params.file){const fileSize=(params.ufile&&params.ufile[0].size)||params.file.size;if(!checkFileSize(fileSize,this.notification)){return null;}}
const fileData=await this.http.post(this.props.route,params,"text");const parsedFileData=JSON.parse(fileData);if(parsedFileData.error){throw new Error(parsedFileData.error);}
return parsedFileData;}
async onFileInputChange(){this.state.isDisable=true;const parsedFileData=await this.uploadFiles(this.httpParams);if(parsedFileData){this.props.onUpload(parsedFileData,this.fileInputRef.el?this.fileInputRef.el.files:[]);this.fileInputRef.el.value=null;}
this.state.isDisable=false;}
async onTriggerClicked(){if(await this.props.beforeOpen()){this.fileInputRef.el.click();}}}
FileInput.defaultProps={acceptedFileExtensions:"*",hidden:false,multiUpload:false,onUpload:()=>{},route:"/web/binary/upload_attachment",beforeOpen:async()=>true,};FileInput.props={acceptedFileExtensions:{type:String,optional:true},autoOpen:{type:Boolean,optional:true},hidden:{type:Boolean,optional:true},multiUpload:{type:Boolean,optional:true},onUpload:{type:Function,optional:true},beforeOpen:{type:Function,optional:true},resId:{type:Number,optional:true},resModel:{type:String,optional:true},route:{type:String,optional:true},"*":true,};FileInput.template="web.FileInput";return __exports;});;

/* /web/static/src/core/file_upload/file_upload_progress_bar.js */
odoo.define('@web/core/file_upload/file_upload_progress_bar',['@web/core/l10n/translation','@web/core/utils/hooks','@web/core/confirmation_dialog/confirmation_dialog','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const{ConfirmationDialog}=require("@web/core/confirmation_dialog/confirmation_dialog");const{Component}=require("@odoo/owl");const FileUploadProgressBar=__exports.FileUploadProgressBar=class FileUploadProgressBar extends Component{setup(){this.dialogService=useService("dialog");}
onCancel(){if(!this.props.fileUpload.xhr){return;}
this.dialogService.add(ConfirmationDialog,{body:_t("Do you really want to cancel the upload of %s?",this.props.fileUpload.title),confirm:()=>{this.props.fileUpload.xhr.abort();},});}}
FileUploadProgressBar.props={fileUpload:{type:Object},};FileUploadProgressBar.template="web.FileUploadProgressBar";return __exports;});;

/* /web/static/src/core/file_upload/file_upload_progress_container.js */
odoo.define('@web/core/file_upload/file_upload_progress_container',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const FileUploadProgressContainer=__exports.FileUploadProgressContainer=class FileUploadProgressContainer extends Component{}
FileUploadProgressContainer.template="web.FileUploadProgressContainer";FileUploadProgressContainer.props={Component:{optional:false},shouldDisplay:{type:Function,optional:true},fileUploads:{type:Object},};return __exports;});;

/* /web/static/src/core/file_upload/file_upload_progress_record.js */
odoo.define('@web/core/file_upload/file_upload_progress_record',['@web/core/l10n/translation','@web/core/file_upload/file_upload_progress_bar','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{FileUploadProgressBar}=require("@web/core/file_upload/file_upload_progress_bar");const{Component}=require("@odoo/owl");const FileUploadProgressRecord=__exports.FileUploadProgressRecord=class FileUploadProgressRecord extends Component{getProgressTexts(){const fileUpload=this.props.fileUpload;const percent=Math.round(fileUpload.progress*100);if(percent===100){return{left:_t("Processing..."),right:"",};}else{const mbLoaded=Math.round(fileUpload.loaded/1000000);const mbTotal=Math.round(fileUpload.total/1000000);return{left:_t("Uploading... (%s%)",percent),right:_t("(%s/%sMB)",mbLoaded,mbTotal),};}}}
FileUploadProgressRecord.components={FileUploadProgressBar,};const FileUploadProgressKanbanRecord=__exports.FileUploadProgressKanbanRecord=class FileUploadProgressKanbanRecord extends FileUploadProgressRecord{}
FileUploadProgressKanbanRecord.template="web.FileUploadProgressKanbanRecord";const FileUploadProgressDataRow=__exports.FileUploadProgressDataRow=class FileUploadProgressDataRow extends FileUploadProgressRecord{}
FileUploadProgressDataRow.template="web.FileUploadProgressDataRow";return __exports;});;

/* /web/static/src/core/file_upload/file_upload_service.js */
odoo.define('@web/core/file_upload/file_upload_service',['@web/core/l10n/translation','@web/core/registry','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{EventBus,reactive}=require("@odoo/owl");const fileUploadService=__exports.fileUploadService={dependencies:["notification"],createXhr(){return new window.XMLHttpRequest();},start(env,{notificationService}){const uploads=reactive({});let nextId=1;const bus=new EventBus();const upload=async(route,files,params={})=>{const xhr=this.createXhr();xhr.open("POST",route);const formData=new FormData();formData.append("csrf_token",odoo.csrf_token);for(const file of files){formData.append("ufile",file);}
if(params.buildFormData){params.buildFormData(formData);}
const upload=reactive({id:nextId++,xhr,data:formData,progress:0,loaded:0,total:0,state:"pending",title:files.length===1?files[0].name:_t("%s Files",files.length),type:files.length===1?files[0].type:undefined,});uploads[upload.id]=upload;xhr.upload.addEventListener("progress",async(ev)=>{upload.progress=ev.loaded/ev.total;upload.loaded=ev.loaded;upload.total=ev.total;upload.state="loading";});xhr.addEventListener("load",()=>{delete uploads[upload.id];upload.state="loaded";bus.trigger("FILE_UPLOAD_LOADED",{upload});});xhr.addEventListener("error",async()=>{delete uploads[upload.id];upload.state="error";if(params.displayErrorNotification!==undefined&&params.displayErrorNotification){notificationService.add(_t("An error occured while uploading."),{title:_t("Error"),sticky:true,});}
bus.trigger("FILE_UPLOAD_ERROR",{upload});});xhr.addEventListener("abort",async()=>{delete uploads[upload.id];upload.state="abort";bus.trigger("FILE_UPLOAD_ERROR",{upload});});xhr.send(formData);bus.trigger("FILE_UPLOAD_ADDED",{upload});return upload;};return{bus,upload,uploads};},};registry.category("services").add("file_upload",fileUploadService);return __exports;});;

/* /web/static/src/core/file_viewer/file_model.js */
odoo.define('@web/core/file_viewer/file_model',['@web/core/utils/urls'],function(require){'use strict';let __exports={};const{url}=require("@web/core/utils/urls");const FileModelMixin=__exports.FileModelMixin=T=>class extends T{accessToken;checksum;extension;filename;id;mimetype;name;type;tmpUrl;url;uploading;get defaultSource(){const route=url(this.urlRoute,this.urlQueryParams);const encodedRoute=encodeURIComponent(route);if(this.isPdf){return`/web/static/lib/pdfjs/web/viewer.html?file=${encodedRoute}#pagemode=none`;}
if(this.isUrlYoutube){const urlArr=this.url.split("/");let token=urlArr[urlArr.length-1];if(token.includes("watch")){token=token.split("v=")[1];const amp=token.indexOf("&");if(amp!==-1){token=token.substring(0,amp);}}
return`https://www.youtube.com/embed/${token}`;}
return route;}
get displayName(){return this.name||this.filename;}
get downloadUrl(){return url(this.urlRoute,{...this.urlQueryParams,download:true});}
get isImage(){const imageMimetypes=["image/bmp","image/gif","image/jpeg","image/png","image/svg+xml","image/tiff","image/x-icon","image/webp",];return imageMimetypes.includes(this.mimetype);}
get isPdf(){return this.mimetype&&this.mimetype.startsWith("application/pdf");}
get isText(){const textMimeType=["application/javascript","application/json","text/css","text/html","text/plain",];return textMimeType.includes(this.mimetype);}
get isUrl(){return this.type==="url"&&this.url;}
get isUrlYoutube(){return!!this.url&&this.url.includes("youtu");}
get isVideo(){const videoMimeTypes=["audio/mpeg","video/x-matroska","video/mp4","video/webm"];return videoMimeTypes.includes(this.mimetype);}
get isViewable(){return((this.isText||this.isImage||this.isVideo||this.isPdf||this.isUrlYoutube)&&!this.uploading);}
get urlQueryParams(){if(this.uploading&&this.tmpUrl){return{};}
const params={access_token:this.accessToken,filename:this.name,unique:this.checksum,};for(const prop in params){if(!params[prop]){delete params[prop];}}
return params;}
get urlRoute(){if(this.isUrl){return this.url;}
if(this.uploading&&this.tmpUrl){return this.tmpUrl;}
return this.isImage?`/web/image/${this.id}`:`/web/content/${this.id}`;}}
const FileModel=__exports.FileModel=class FileModel extends FileModelMixin(Object){}
return __exports;});;

/* /web/static/src/core/file_viewer/file_viewer.js */
odoo.define('@web/core/file_viewer/file_viewer',['@odoo/owl','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,useRef,useState}=require("@odoo/owl");const{useAutofocus,useService}=require("@web/core/utils/hooks");const FileViewer=__exports.FileViewer=class FileViewer extends Component{static template="web.FileViewer";static components={};static props=["files","startIndex","close?","modal?"];static defaultProps={modal:true,};setup(){useAutofocus();this.imageRef=useRef("image");this.zoomerRef=useRef("zoomer");this.isDragging=false;this.dragStartX=0;this.dragStartY=0;this.scrollZoomStep=0.1;this.zoomStep=0.5;this.minScale=0.5;this.translate={dx:0,dy:0,x:0,y:0,};this.state=useState({index:this.props.startIndex,file:this.props.files[this.props.startIndex],imageLoaded:false,scale:1,angle:0,});this.ui=useState(useService("ui"));}
onImageLoaded(){this.state.imageLoaded=true;}
close(){this.props.close&&this.props.close();}
next(){const last=this.props.files.length-1;this.activateFile(this.state.index===last?0:this.state.index+1);}
previous(){const last=this.props.files.length-1;this.activateFile(this.state.index===0?last:this.state.index-1);}
activateFile(index){this.state.index=index;this.state.file=this.props.files[index];}
onKeydown(ev){switch(ev.key){case"ArrowRight":this.next();break;case"ArrowLeft":this.previous();break;case"Escape":this.close();break;case"q":this.close();break;}
if(this.state.file.isImage){switch(ev.key){case"r":this.rotate();break;case"+":this.zoomIn();break;case"-":this.zoomOut();break;case"0":this.resetZoom();break;}}}
onWheelImage(ev){if(ev.deltaY>0){this.zoomOut({scroll:true});}else{this.zoomIn({scroll:true});}}
onMousedownImage(ev){if(this.isDragging){return;}
if(ev.button!==0){return;}
this.isDragging=true;this.dragStartX=ev.clientX;this.dragStartY=ev.clientY;}
onMouseupImage(){if(!this.isDragging){return;}
this.isDragging=false;this.translate.x+=this.translate.dx;this.translate.y+=this.translate.dy;this.translate.dx=0;this.translate.dy=0;this.updateZoomerStyle();}
onMousemoveView(ev){if(!this.isDragging){return;}
this.translate.dx=ev.clientX-this.dragStartX;this.translate.dy=ev.clientY-this.dragStartY;this.updateZoomerStyle();}
resetZoom(){this.state.scale=1;this.updateZoomerStyle();}
rotate(){this.state.angle+=90;}
zoomIn({scroll=false}={}){this.state.scale=this.state.scale+(scroll?this.scrollZoomStep:this.zoomStep);this.updateZoomerStyle();}
zoomOut({scroll=false}={}){if(this.state.scale===this.minScale){return;}
const unflooredAdaptedScale=this.state.scale-(scroll?this.scrollZoomStep:this.zoomStep);this.state.scale=Math.max(this.minScale,unflooredAdaptedScale);this.updateZoomerStyle();}
updateZoomerStyle(){const tx=this.imageRef.el.offsetWidth*this.state.scale>this.zoomerRef.el.offsetWidth?this.translate.x+this.translate.dx:0;const ty=this.imageRef.el.offsetHeight*this.state.scale>this.zoomerRef.el.offsetHeight?this.translate.y+this.translate.dy:0;if(tx===0){this.translate.x=0;}
if(ty===0){this.translate.y=0;}
this.zoomerRef.el.style="transform: "+`translate(${tx}px, ${ty}px)`;}
get imageStyle(){let style="transform: "+`scale3d(${this.state.scale}, ${this.state.scale}, 1) `+`rotate(${this.state.angle}deg);`;if(this.state.angle%180!==0){style+=`max-height: ${window.innerWidth}px; max-width: ${window.innerHeight}px;`;}else{style+="max-height: 100%; max-width: 100%;";}
return style;}
onClickPrint(){const printWindow=window.open("about:blank","_new");printWindow.document.open();printWindow.document.write(`
                <html>
                    <head>
                        <script>
                            function onloadImage() {
                                setTimeout('printImage()', 10);
                            }
                            function printImage() {
                                window.print();
                                window.close();
                            }
                        </script>
                    </head>
                    <body onload='onloadImage()'>
                        <img src="${this.state.file.defaultSource}" alt=""/>
                    </body>
                </html>`);printWindow.document.close();}}
return __exports;});;

/* /web/static/src/core/file_viewer/file_viewer_hook.js */
odoo.define('@web/core/file_viewer/file_viewer_hook',['@odoo/owl','@web/core/registry','@web/core/file_viewer/file_viewer'],function(require){'use strict';let __exports={};const{onWillDestroy}=require("@odoo/owl");const{registry}=require("@web/core/registry");const{FileViewer}=require("@web/core/file_viewer/file_viewer");let id=1;__exports.useFileViewer=useFileViewer;function useFileViewer(){const fileViewerId=`web.file_viewer${id++}`;function open(file,files=[file]){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);}
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())&&(!reg.area||(target instanceof Node&&reg.area()&&reg.area().contains(target))));let winner=candidates.shift();if(winner&&winner.area){for(const candidate of candidates.filter((c)=>Boolean(c.area))){if(candidate.area()&&winner.area().contains(candidate.area())){winner=candidate;}}}
if(winner){winner.callback({area:winner.area&&winner.area(),target,});return true;}
return false;}
function getDomRegistrations(hotkey,activeElement){const overlayModParts=hotkeyService.overlayModifier.split("+");if(!overlayModParts.every((el)=>hotkey.includes(el))){return[];}
const cleanHotkey=hotkey.split("+").filter((key)=>!overlayModParts.includes(key)).join("+");const elems=getVisibleElements(activeElement,`[data-hotkey='${cleanHotkey}' i]`);return elems.map((el)=>({hotkey,activeElement,bypassEditableProtection:true,callback:()=>{el.focus();el.click();},}));}
function addHotkeyOverlays(activeElement){for(const el of getVisibleElements(activeElement,"[data-hotkey]:not(:disabled)")){const hotkey=el.dataset.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");const overlayKbd=document.createElement("kbd");overlayKbd.className="small";overlayKbd.appendChild(document.createTextNode(hotkey.toUpperCase()));overlay.appendChild(overlayKbd);let overlayParent;if(el.tagName.toUpperCase()==="INPUT"){overlayParent=el.parentElement;}else{overlayParent=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,};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_prompt/install_prompt.js */
odoo.define('@web/core/install_prompt/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/install_prompt/install_prompt_service.js */
odoo.define('@web/core/install_prompt/install_prompt_service',['@odoo/owl','@web/core/browser/browser','@web/core/browser/feature_detection','@web/core/registry','@web/core/install_prompt/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{registry}=require("@web/core/registry");const{InstallPrompt}=require("@web/core/install_prompt/install_prompt");const serviceRegistry=registry.category("services");const installPromptService={dependencies:["dialog"],start(env,{dialog}){let nativePrompt;const state=reactive({canPromptToInstall:false,decline,show,});const canBeInstalled=browser.BeforeInstallPromptEvent!==undefined||(isBrowserSafari()&&!isDisplayStandalone()&&(isIOS()||(isMacOS()&&browser.navigator.userAgent.match(/Version\/(\d+)/)[1]>=17)));const installationState=browser.localStorage.getItem("pwa.installationState");const isDeclined=installationState==="dismissed";if(canBeInstalled&&!isDeclined){browser.addEventListener("beforeinstallprompt",(ev)=>{ev.preventDefault();nativePrompt=ev;if(installationState==="accepted"){browser.localStorage.removeItem("pwa.installationState");}
state.canPromptToInstall=true;});if(isBrowserSafari()){state.canPromptToInstall=installationState!=="accepted";}}
async function show(){if(!state.canPromptToInstall){return;}
if(nativePrompt){const res=await nativePrompt.prompt();browser.localStorage.setItem("pwa.installationState",res.outcome);state.canPromptToInstall=false;}else if(isBrowserSafari()){dialog.add(InstallPrompt,{onClose:()=>this.decline(),});}}
function decline(){browser.localStorage.setItem("pwa.installationState","dismissed");state.canPromptToInstall=false;}
return state;},};serviceRegistry.add("installPrompt",installPromptService);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{_t}=require("@web/core/l10n/translation");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",};const smartDateRegex=new RegExp(["^","([+-])","(\\d+)",`([${Object.keys(smartDateUnits).join("")}]?)`,"$"].join("\\s*"),"i");const dateCache=new WeakMap();const dateTimeCache=new WeakMap();const ConversionError=__exports.ConversionError=class ConversionError extends Error{name="ConversionError";}
__exports.areDatesEqual=areDatesEqual;function areDatesEqual(d1,d2){if(Array.isArray(d1)||Array.isArray(d2)){d1=ensureArray(d1);d2=ensureArray(d2);return d1.length===d2.length&&d1.every((d1Val,i)=>areDatesEqual(d1Val,d2[i]));}
if(d1 instanceof DateTime&&d2 instanceof DateTime&&d1!==d2){return d1.equals(d2);}else{return d1===d2;}}
__exports.clampDate=clampDate;function clampDate(desired,minDate,maxDate){if(maxDate<desired){return maxDate;}
if(minDate>desired){return minDate;}
return desired;}
__exports.is24HourFormat=is24HourFormat;function is24HourFormat(format){return/H/.test(format||localization.timeFormat);}
__exports.isInRange=isInRange;function isInRange(value,range){if(!value||!range){return false;}
if(Array.isArray(value)){const actualValues=value.filter(Boolean);if(actualValues.length<2){return isInRange(actualValues[0],range);}
return((value[0]<=range[0]&&range[0]<=value[1])||(range[0]<=value[0]&&value[0]<=range[1]));}else{return range[0]<=value&&value<=range[1];}}
__exports.isMeridiemFormat=isMeridiemFormat;function isMeridiemFormat(format){return/a/.test(format||localization.timeFormat);}
function isValidDate(date){return date&&date.isValid&&isInRange(date,[MIN_VALID_DATE,MAX_VALID_DATE]);}
function parseSmartDateInput(value){const match=value.match(smartDateRegex);if(match){let date=DateTime.local();const offset=parseInt(match[2],10);const unit=smartDateUnits[(match[3]||"d").toLowerCase()];if(match[1]==="+"){date=date.plus({[unit]:offset});}else{date=date.minus({[unit]:offset});}
return date;}
return false;}
const stripAlphaDupes=memoize(function stripAlphaDupes(str){return str.replace(/[a-z]/gi,(letter,index,str)=>letter===str[index-1]?"":letter);});const strftimeToLuxonFormat=__exports.strftimeToLuxonFormat=memoize(function strftimeToLuxonFormat(format){const output=[];let inToken=false;for(let index=0;index<format.length;++index){let character=format[index];if(character==="%"&&!inToken){inToken=true;continue;}
if(/[a-z]/gi.test(character)){if(inToken&&normalizeFormatTable[character]!==undefined){character=normalizeFormatTable[character];}else{character=`'${character}'`;}}
output.push(character);inToken=false;}
return output.join("");});__exports.today=today;function today(){return DateTime.local().startOf("day");}
__exports.formatDate=formatDate;function formatDate(value,options={}){if(!value){return"";}
const format=options.format||localization.dateFormat;return value.toFormat(format);}
__exports.formatDateTime=formatDateTime;function formatDateTime(value,options={}){if(!value){return"";}
const format=options.format||localization.dateTimeFormat;return value.setZone("default").toFormat(format);}
__exports.formatDuration=formatDuration;function formatDuration(seconds,showFullDuration){const displayStyle=showFullDuration?"long":"narrow";const numberOfValuesToDisplay=showFullDuration?2:1;const durationKeys=["years","months","days","hours","minutes"];if(seconds<60){seconds=60;}
seconds-=seconds%60;let duration=luxon.Duration.fromObject({seconds:seconds}).shiftTo(...durationKeys);duration=duration.shiftTo(...durationKeys.filter((key)=>duration.get(key)));const durationSplit=duration.toHuman({unitDisplay:displayStyle}).split(",");if(!showFullDuration&&duration.loc.locale.includes("en")&&duration.months>0){durationSplit[0]=durationSplit[0].replace("m","M");}
return durationSplit.slice(0,numberOfValuesToDisplay).join(",");}
__exports.serializeDate=serializeDate;function serializeDate(value){if(!dateCache.has(value)){dateCache.set(value,value.toFormat(SERVER_DATE_FORMAT,{numberingSystem:"latn"}));}
return dateCache.get(value);}
__exports.serializeDateTime=serializeDateTime;function serializeDateTime(value){if(!dateTimeCache.has(value)){dateTimeCache.set(value,value.setZone("utc").toFormat(SERVER_DATETIME_FORMAT,{numberingSystem:"latn"}));}
return dateTimeCache.get(value);}
__exports.parseDate=parseDate;function parseDate(value,options={}){const parsed=parseDateTime(value,{...options,format:options.format||localization.dateFormat});return parsed&&parsed.startOf("day");}
__exports.parseDateTime=parseDateTime;function parseDateTime(value,options={}){if(!value){return false;}
const fmt=options.format||localization.dateTimeFormat;const parseOpts={setZone:true,zone:"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("default");}
__exports.deserializeDate=deserializeDate;function deserializeDate(value,options={}){const defaultDict={numberingSystem:"latn",zone:"default"}
const joinedDict={...defaultDict,...options}
return DateTime.fromSQL(value,joinedDict).reconfigure({numberingSystem:Settings.defaultNumberingSystem,});}
__exports.deserializeDateTime=deserializeDateTime;function deserializeDateTime(value){return DateTime.fromSQL(value,{numberingSystem:"latn",zone:"utc"}).setZone("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 notReadyError=new Error("Localization parameters not ready yet. Maybe add 'localization' to your dependencies?");const localization=__exports.localization={dateFormat:notReadyError,dateTimeFormat:notReadyError,timeFormat:notReadyError,decimalPoint:notReadyError,direction:notReadyError,grouping:notReadyError,multiLang:notReadyError,thousandsSep:notReadyError,weekStart:notReadyError,code:notReadyError,};return __exports;});;

/* /web/static/src/core/l10n/localization_service.js */
odoo.define('@web/core/l10n/localization_service',['@web/session','@web/core/browser/browser','@web/core/registry','@web/core/l10n/dates','@web/core/l10n/localization','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{session}=require("@web/session");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{translatedTerms,translationLoaded,translationIsReady}=require("@web/core/l10n/translation");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={dependencies:["user"],start:async(env,{user})=>{const cacheHashes=session.cache_hashes||{};const translationsHash=cacheHashes.translations||new Date().getTime().toString();const lang=user.lang||document.documentElement.getAttribute("lang")?.replace(/-/g,"_");const translationURL=session.translationURL||"/web/webclient/translations";let url=`${translationURL}/${translationsHash}`;if(lang){url+=`?lang=${lang}`;}
const response=await browser.fetch(url);if(!response.ok){throw new Error("Error while fetching translations");}
const{lang_parameters:userLocalization,modules:modules,multi_lang:multiLang,}=await response.json();const terms={};for(const addon of Object.keys(modules)){for(const message of modules[addon].messages){terms[message.id]=message.string;}}
Object.assign(translatedTerms,terms);translatedTerms[translationLoaded]=true;translationIsReady.resolve(true);const language=lang||browser.navigator.language;const locale=language==="sr@latin"?"sr-Latn-RS":language.replace(/_/g,"-");Settings.defaultLocale=locale;for(const[re,numberingSystem]of NUMBERING_SYSTEMS){if(re.test(locale)){Settings.defaultNumberingSystem=numberingSystem;break;}}
const dateFormat=strftimeToLuxonFormat(userLocalization.date_format);const timeFormat=strftimeToLuxonFormat(userLocalization.time_format);const dateTimeFormat=`${dateFormat} ${timeFormat}`;const grouping=JSON.parse(userLocalization.grouping);Object.assign(localization,{dateFormat,timeFormat,dateTimeFormat,decimalPoint:userLocalization.decimal_point,direction:userLocalization.direction,grouping,multiLang,thousandsSep:userLocalization.thousands_sep,weekStart:userLocalization.week_start,code:language,});return localization;},};registry.category("services").add("localization",localizationService);return __exports;});;

/* /web/static/src/core/l10n/translation.js */
odoo.define('@web/core/l10n/translation',['@web/core/utils/concurrency','@web/core/utils/strings'],function(require){'use strict';let __exports={};const{Deferred}=require("@web/core/utils/concurrency");const{sprintf}=require("@web/core/utils/strings");const translationLoaded=__exports.translationLoaded=Symbol("translationLoaded");const translatedTerms=__exports.translatedTerms={[translationLoaded]:false,};const translationIsReady=__exports.translationIsReady=new Deferred();__exports._t=_t;function _t(term,...values){if(translatedTerms[translationLoaded]){const translation=translatedTerms[term]??term;if(values.length===0){return translation;}
return sprintf(translation,...values);}else{return new LazyTranslatedString(term,...values);}}
const _lt=__exports._lt=(term,...values)=>_t(term,...values);class LazyTranslatedString extends String{constructor(term,...values){super(term);this.values=values;}
valueOf(){const term=super.valueOf();if(translatedTerms[translationLoaded]){const translation=translatedTerms[term]??term;if(this.values.length===0){return translation;}
return sprintf(translation,...this.values);}else{throw new Error(`translation error`);}}
toString(){return this.valueOf();}}
_t("less than a minute ago");_t("about a minute ago");_t("%d minutes ago");_t("about an hour ago");_t("%d hours ago");_t("a day ago");_t("%d days ago");_t("about a month ago");_t("%d months ago");_t("about a year ago");_t("%d years ago");__exports.loadLanguages=loadLanguages;async function loadLanguages(orm){if(!loadLanguages.installedLanguages){loadLanguages.installedLanguages=await orm.call("res.lang","get_installed");}
return loadLanguages.installedLanguages;}
return __exports;});;

/* /web/static/src/core/l10n/utils.js */
odoo.define('@web/core/l10n/utils',[],function(require){'use strict';let __exports={};__exports.pyToJsLocale=pyToJsLocale;function pyToJsLocale(locale){if(!locale){return"";}
const match=locale.match(/^([a-z]+)(_[A-Z\d]+)?(@.+)?$/);if(!match){return locale;}
const[,language,territory,modifier]=match;const subtags=[language];if(modifier==="@latin"){subtags.push("Latn");}
if(territory){subtags.push(territory.slice(1));}
return subtags.join("-");}
return __exports;});;

/* /web/static/src/core/macro.js */
odoo.define('@web/core/macro',['@web/core/browser/browser','@web/core/utils/ui','@web/core/utils/concurrency'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{isVisible}=require("@web/core/utils/ui");const{Mutex}=require("@web/core/utils/concurrency");const ACTION_HELPERS=__exports.ACTION_HELPERS={click(el,_step){el.dispatchEvent(new MouseEvent("mouseover"));el.dispatchEvent(new MouseEvent("mouseenter"));el.dispatchEvent(new MouseEvent("mousedown"));el.dispatchEvent(new MouseEvent("mouseup"));el.click();el.dispatchEvent(new MouseEvent("mouseout"));el.dispatchEvent(new MouseEvent("mouseleave"));},text(el,step){this.click(el,step);el.value=step.value;el.dispatchEvent(new InputEvent("input",{bubbles:true}));el.dispatchEvent(new InputEvent("change",{bubbles:true}));},};const mutex=new Mutex();class TimeoutError extends Error{}
class Macro{constructor(descr){this.name=descr.name||"anonymous";this.timeoutDuration=descr.timeout||0;this.timeout=null;this.currentIndex=0;this.checkDelay=descr.checkDelay||0;this.isComplete=false;this.steps=descr.steps;this.onStep=descr.onStep||(()=>{});this.onError=descr.onError;this.onTimeout=descr.onTimeout;this.setTimer();}
async advance(){if(this.isComplete){return;}
const step=this.steps[this.currentIndex];const[proceedToAction,el]=this.checkTrigger(step);if(proceedToAction){this.safeCall(this.onStep,el,step);const actionResult=await this.performAction(el,step);if(!actionResult){this.currentIndex++;if(this.currentIndex===this.steps.length){this.isComplete=true;browser.clearTimeout(this.timeout);}else{this.setTimer();await this.advance();}}}}
checkTrigger({trigger}){let el;if(!trigger){return[true,el];}
if(typeof trigger==="function"){el=this.safeCall(trigger);}else if(typeof trigger==="string"){const triggerEl=document.querySelector(trigger);el=isVisible(triggerEl)&&triggerEl;}else{throw new Error(`Trigger can only be string or function.`);}
if(el){return[true,el];}else{return[false,el];}}
async performAction(el,step){const action=step.action;let actionResult;if(action in ACTION_HELPERS){actionResult=ACTION_HELPERS[action](el,step);}else if(typeof action==="function"){actionResult=await this.safeCall(action,el,step);}
return actionResult;}
safeCall(fn,...args){if(this.isComplete){return;}
try{return fn(...args);}catch(e){this.handleError(e);}}
setTimer(){if(this.timeoutDuration){browser.clearTimeout(this.timeout);this.timeout=browser.setTimeout(()=>{if(this.onTimeout){const index=this.currentIndex;const step=this.steps[index];this.safeCall(this.onTimeout,step,index);}else{const error=new TimeoutError("Step timeout");this.handleError(error);}},this.timeoutDuration);}}
handleError(error){this.isComplete=true;browser.clearTimeout(this.timeout);if(this.onError){const index=this.currentIndex;const step=this.steps[index];this.onError(error,step,index);}else{console.error(error);}}}
const MacroEngine=__exports.MacroEngine=class MacroEngine{constructor(params={}){this.isRunning=false;this.timeout=null;this.target=params.target||document.body;this.defaultCheckDelay=params.defaultCheckDelay??750;this.macros=new Set();this.observerOptions={attributes:true,childList:true,subtree:true,characterData:true,};this.observer=new MutationObserver(this.delayedCheck.bind(this));this.iframeObserver=new MutationObserver(()=>{const iframeEl=document.querySelector("iframe.o_iframe");if(iframeEl){iframeEl.addEventListener("load",()=>{if(iframeEl.contentDocument){this.observer.observe(iframeEl.contentDocument,this.observerOptions);}});if(!iframeEl.src){if(iframeEl.contentDocument){this.observer.observe(iframeEl.contentDocument,this.observerOptions);}}}});}
async activate(descr,exclusive=false){if(this.exclusive){return;}
this.exclusive=exclusive;await Promise.resolve();const macro=new Macro(descr);if(exclusive){this.macros=new Set([macro]);}else{this.macros.add(macro);}
this.start();}
start(){if(!this.isRunning){this.isRunning=true;this.observer.observe(this.target,this.observerOptions);this.iframeObserver.observe(this.target,{childList:true,subtree:true});}
this.delayedCheck();}
stop(){if(this.isRunning){this.isRunning=false;browser.clearTimeout(this.timeout);this.timeout=null;this.observer.disconnect();this.iframeObserver.disconnect();}}
delayedCheck(){if(this.timeout){browser.clearTimeout(this.timeout);}
this.timeout=browser.setTimeout(()=>mutex.exec(this.advanceMacros.bind(this)),this.getCheckDelay()||this.defaultCheckDelay);}
getCheckDelay(){return[...this.macros].map((m)=>m.checkDelay).filter((delay)=>delay>0).reduce((m,v)=>Math.min(m,v),this.defaultCheckDelay);}
async advanceMacros(){await Promise.all([...this.macros].map((macro)=>macro.advance()));for(const macro of this.macros){if(macro.isComplete){this.macros.delete(macro);}}
if(this.macros.size===0){this.stop();}}}
return __exports;});;

/* /web/static/src/core/main_components_container.js */
odoo.define('@web/core/main_components_container',['@web/core/registry','@web/core/utils/components','@web/core/utils/hooks','@odoo/owl'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{ErrorHandler}=require("@web/core/utils/components");const{useBus}=require("@web/core/utils/hooks");const{Component,xml}=require("@odoo/owl");const MainComponentsContainer=__exports.MainComponentsContainer=class MainComponentsContainer extends Component{setup(){const mainComponents=registry.category("main_components");this.Components=mainComponents.getEntries();useBus(mainComponents,"UPDATE",()=>{this.Components=mainComponents.getEntries();this.render();});}
handleComponentError(error,C){this.Components.splice(this.Components.indexOf(C),1);this.render();Promise.resolve().then(()=>{throw error;});}}
MainComponentsContainer.template=xml`
<div class="o-main-components-container">
    <t t-foreach="Components" t-as="C" t-key="C[0]">
        <ErrorHandler onError="error => this.handleComponentError(error, C)">
            <t t-component="C[1].Component" t-props="C[1].props"/>
        </ErrorHandler>
    </t>
</div>
`;MainComponentsContainer.components={ErrorHandler};MainComponentsContainer.props={};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/utils/concurrency','@web/core/model_field_selector/model_field_selector_popover','@web/core/model_field_selector/utils','@web/core/popover/popover_hook'],function(require){'use strict';let __exports={};const{Component,onWillStart,onWillUpdateProps,useState}=require("@odoo/owl");const{KeepLast}=require("@web/core/utils/concurrency");const{ModelFieldSelectorPopover}=require("@web/core/model_field_selector/model_field_selector_popover");const{useLoadFieldInfo,useLoadPathDescription}=require("@web/core/model_field_selector/utils");const{usePopover}=require("@web/core/popover/popover_hook");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},showSearchInput:{type:Boolean,optional:true},isDebugMode:{type:Boolean,optional:true},update:{type:Function,optional:true},filter:{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.loadPathDescription=useLoadPathDescription();const loadFieldInfo=useLoadFieldInfo();this.popover=usePopover(this.constructor.components.Popover,{popoverClass:"o_popover_field_selector",onClose:async()=>{if(this.newPath!==null){const fieldInfo=await 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)=>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,update:(path,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,followRelations:this.props.followRelations,showDebugInput:this.props.showDebugInput,});}
async updateState(params,isConcurrent){const{resModel,path,allowEmpty}=params;let prom=this.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,fieodDef: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/utils/timing','@web/core/utils/search','@web/core/utils/concurrency','@web/core/utils/arrays','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,onWillStart,useEffect,useRef,useState}=require("@odoo/owl");const{debounce}=require("@web/core/utils/timing");const{fuzzyLookup}=require("@web/core/utils/search");const{KeepLast}=require("@web/core/utils/concurrency");const{sortBy}=require("@web/core/utils/arrays");const{useService}=require("@web/core/utils/hooks");class Page{constructor(resModel,fieldDefs,options={}){this.resModel=resModel;this.fieldDefs=fieldDefs;const{previousPage=null,selectedName=null,isDebugMode}=options;this.previousPage=previousPage;this.selectedName=selectedName;this.isDebugMode=isDebugMode;this.sortedFieldNames=sortBy(Object.keys(fieldDefs),(key)=>fieldDefs[key].string);this.fieldNames=this.sortedFieldNames;this.query="";this.focusedFieldName=null;this.resetFocusedFieldName();}
get path(){const previousPath=this.previousPage?.path||"";if(this.selectedName){if(previousPath){return`${previousPath}.${this.selectedName}`;}else{return this.selectedName;}}
return previousPath;}
get selectedField(){return this.fieldDefs[this.selectedName];}
get title(){const prefix=this.previousPage?.previousPage?"... > ":"";const title=this.previousPage?.selectedField.string||"";return`${prefix}${title}`;}
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},followRelations:{type:Boolean,optional:true},showDebugInput:{type:Boolean,optional:true},isDebugMode:{type:Boolean,optional:true},path:{optional:true},resModel:String,showSearchInput:{type:Boolean,optional:true},update:Function,};static defaultProps={filter:(fieldDef)=>fieldDef.searchable,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 showDebugInput(){return this.props.showDebugInput??this.props.isDebugMode;}
filter(fieldDefs,path){const filteredKeys=Object.keys(fieldDefs).filter((k)=>this.props.filter(fieldDefs[k],path));return Object.fromEntries(filteredKeys.map((k)=>[k,fieldDefs[k]]));}
async followRelation(fieldDef){const{modelsInfo}=await this.keepLast.add(this.fieldService.loadPath(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),{previousPage:this.state.page,isDebugMode:this.props.isDebugMode,}));}
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),{isDebugMode:this.props.isDebugMode,});}
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),{selectedName:path,isDebugMode:this.props.isDebugMode,});}
default:{let page=null;for(let index=0;index<names.length;index++){const name=names[index];const{resModel,fieldDefs}=modelsInfo[index];page=new Page(resModel,this.filter(fieldDefs,path),{previousPage:page,selectedName:name,isDebugMode:this.props.isDebugMode,});}
return page;}}}
openPage(page){this.state.page=page;this.state.page.searchFields();this.props.update(page.path);}
searchFields(query){this.state.page.searchFields(query);}
selectField(field){if(field.type==="properties"){return this.followRelation(field);}
this.keepLast.add(Promise.resolve());this.state.page.selectedName=field.name;this.props.update(this.state.page.path);this.props.close(true);}
onDebugInputKeydown(ev){switch(ev.key){case"Enter":{ev.preventDefault();ev.stopPropagation();this.loadNewPath(ev.currentTarget.value);break;}}}
async onInputKeydown(ev){const{page}=this.state;switch(ev.key){case"ArrowUp":{if(ev.target.selectionStart===0){page.focus("previous");}
break;}
case"ArrowDown":{if(ev.target.selectionStart===page.query.length){page.focus("next");}
break;}
case"ArrowLeft":{if(ev.target.selectionStart===0&&page.previousPage){this.goToPreviousPage();}
break;}
case"ArrowRight":{if(ev.target.selectionStart===page.query.length){const focusedFieldName=this.state.page.focusedFieldName;if(focusedFieldName){const fieldDef=this.state.page.fieldDefs[focusedFieldName];if(fieldDef.relation||fieldDef.type==="properties"){this.followRelation(fieldDef);}}}
break;}
case"Enter":{const focusedFieldName=this.state.page.focusedFieldName;if(focusedFieldName){const fieldDef=this.state.page.fieldDefs[focusedFieldName];this.selectField(fieldDef);}else{ev.preventDefault();ev.stopPropagation();}
break;}
case"Escape":{ev.preventDefault();ev.stopPropagation();this.props.close();break;}}}}
return __exports;});;

/* /web/static/src/core/model_field_selector/utils.js */
odoo.define('@web/core/model_field_selector/utils',['@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{useService}=require("@web/core/utils/hooks");function makeString(value){return String(value??"-");}
__exports.useLoadFieldInfo=useLoadFieldInfo;function useLoadFieldInfo(fieldService){fieldService||=useService("field");return async(resModel,path)=>{if(typeof path!=="string"||!path){return{resModel,fieldDef:null};}
const{isInvalid,names,modelsInfo}=await fieldService.loadPath(resModel,path);if(isInvalid){return{resModel,fieldDef:null};}
const name=names.at(-1);const modelInfo=modelsInfo.at(-1);return{resModel:modelInfo.resModel,fieldDef:modelInfo.fieldDefs[name]};};}
__exports.useLoadPathDescription=useLoadPathDescription;function useLoadPathDescription(fieldService){fieldService||=useService("field");return async(resModel,path,allowEmpty)=>{if([0,1].includes(path)){return{isInvalid:false,displayNames:[makeString(path)]};}
if(allowEmpty&&!path){return{isInvalid:false,displayNames:[]};}
if(typeof path!=="string"||!path){return{isInvalid:true,displayNames:[makeString()]};}
const{isInvalid,modelsInfo,names}=await fieldService.loadPath(resModel,path);const result={isInvalid:!!isInvalid,displayNames:[]};if(!isInvalid){const lastName=names.at(-1);const lastFieldDef=modelsInfo.at(-1).fieldDefs[lastName];if(["properties","properties_definition"].includes(lastFieldDef.type)){result.isInvalid=true;}}
for(let index=0;index<names.length;index++){const name=names[index];const fieldDef=modelsInfo[index]?.fieldDefs[name];result.displayNames.push(fieldDef?.string||makeString(name));}
return result;};}
return __exports;});;

/* /web/static/src/core/model_selector/model_selector.js */
odoo.define('@web/core/model_selector/model_selector',['@web/core/autocomplete/autocomplete','@web/core/utils/hooks','@web/core/utils/search','@web/core/l10n/translation','@odoo/owl'],function(require){'use strict';let __exports={};const{AutoComplete}=require("@web/core/autocomplete/autocomplete");const{useService}=require("@web/core/utils/hooks");const{fuzzyLookup}=require("@web/core/utils/search");const{_t}=require("@web/core/l10n/translation");const{Component,onWillStart}=require("@odoo/owl");const ModelSelector=__exports.ModelSelector=class ModelSelector extends Component{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)=>({label:record.display_name,technical:record.model,classList:{[`o_model_selector_${record.model}`]:1,},}));});}
get placeholder(){return _t("Type a model here...");}
get sources(){return[this.optionsSource];}
get optionsSource(){return{placeholder:_t("Loading..."),options:this.loadOptionsSource.bind(this),};}
onSelect(option){this.props.onModelSelected({label:option.label,technical:option.technical,});}
filterModels(name){if(!name){const visibleModels=this.models.slice(0,8);if(this.models.length-visibleModels.length>0){visibleModels.push({label:_t("Start typing..."),unselectable:true,classList:"o_m2o_start_typing",});}
return visibleModels;}
return fuzzyLookup(name,this.models,(model)=>model.technical+model.label);}
loadOptionsSource(request){const options=this.filterModels(request);if(!options.length){options.push({label:_t("No records"),classList:"o_m2o_no_result",unselectable:true,});}
return options;}
async _fetchAvailableModels(){const result=await this.orm.call("ir.model","get_available_models");return result||[];}}
ModelSelector.template="web.ModelSelector";ModelSelector.components={AutoComplete};ModelSelector.props={onModelSelected:Function,id:{type:String,optional:true},value:{type:String,optional:true},models:{type:Array,optional:true},};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}).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/network/download.js */
odoo.define('@web/core/network/download',['@web/core/l10n/translation','@web/core/network/rpc_service','@web/core/browser/browser'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{makeErrorFromResponse,ConnectionLostError}=require("@web/core/network/rpc_service");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]*("(?:[\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");}}
function parse(string){if(!string||typeof string!=="string"){throw new TypeError("argument string is required");}
let match=DISPOSITION_TYPE_REGEXP.exec(string);if(!match){throw new TypeError("invalid type format");}
let index=match[0].length;const type=match[1].toLowerCase();let key;const names=[];const params={};let value;index=PARAM_REGEXP.lastIndex=match[0].substr(-1)===";"?index-1:index;while((match=PARAM_REGEXP.exec(string))){if(match.index!==index){throw new TypeError("invalid parameter format");}
index+=match[0].length;key=match[1].toLowerCase();value=match[2];if(names.indexOf(key)!==-1){throw new TypeError("invalid duplicate parameter");}
names.push(key);if(key.indexOf("*")+1===key.length){key=key.slice(0,-1);value=decodefield(value);params[key]=value;continue;}
if(typeof params[key]==="string"){continue;}
if(value[0]==='"'){value=value.substr(1,value.length-2).replace(QESC_REGEXP,"$1");}
params[key]=value;}
if(index!==-1&&index!==string.length){throw new TypeError("invalid parameter format");}
return new ContentDisposition(type,params);}
function pdecode(str,hex){return String.fromCharCode(parseInt(hex,16));}
function ContentDisposition(type,parameters){this.type=type;this.parameters=parameters;}
function _download(data,filename,mimetype){let self=window,defaultMime="application/octet-stream",mimeType=mimetype||defaultMime,payload=data,url=!filename&&!mimetype&&payload,anchor=document.createElement("a"),toString=function(a){return String(a);},myBlob=self.Blob||self.MozBlob||self.WebKitBlob||toString,fileName=filename||"download",blob,reader;myBlob=myBlob.call?myBlob.bind(self):Blob;if(String(this)==="true"){payload=[payload,mimeType];mimeType=payload[0];payload=payload[1];}
if(url&&url.length<2048){fileName=url.split("/").pop().split("?")[0];anchor.href=url;if(anchor.href.indexOf(url)!==-1){return new Promise((resolve,reject)=>{let xhr=new browser.XMLHttpRequest();xhr.open("GET",url,true);configureBlobDownloadXHR(xhr,{onSuccess:resolve,onFailure:reject,url});xhr.send();});}}
if(/^data:[\w+\-]+\/[\w+\-]+[,;]/.test(payload)){if(payload.length>1024*1024*1.999&&myBlob!==toString){payload=dataUrlToBlob(payload);mimeType=payload.type||defaultMime;}else{return navigator.msSaveBlob?navigator.msSaveBlob(dataUrlToBlob(payload),fileName):saver(payload);}}
blob=payload instanceof myBlob?payload:new myBlob([payload],{type:mimeType});function dataUrlToBlob(strUrl){let parts=strUrl.split(/[:;,]/),type=parts[1],decoder=parts[2]==="base64"?atob:decodeURIComponent,binData=decoder(parts.pop()),mx=binData.length,i=0,uiArr=new Uint8Array(mx);for(i;i<mx;++i){uiArr[i]=binData.charCodeAt(i);}
return new myBlob([uiArr],{type});}
function saver(url,winMode){if("download"in anchor){anchor.href=url;anchor.setAttribute("download",fileName);anchor.className="download-js-link";anchor.innerText=_t("downloading...");anchor.style.display="none";document.body.appendChild(anchor);setTimeout(()=>{anchor.click();document.body.removeChild(anchor);if(winMode===true){setTimeout(()=>{self.URL.revokeObjectURL(anchor.href);},250);}},66);return true;}
if(/(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(navigator.userAgent)){url=url.replace(/^data:([\w\/\-+]+)/,defaultMime);if(!window.open(url)){if(confirm("Displaying New Document\n\nUse Save As... to download, then click back to return to this page.")){location.href=url;}}
return true;}
let f=document.createElement("iframe");document.body.appendChild(f);if(!winMode){url=`data:${url.replace(/^data:([\w\/\-+]+)/, defaultMime)}`;}
f.src=url;setTimeout(()=>{document.body.removeChild(f);},333);}
if(navigator.msSaveBlob){return navigator.msSaveBlob(blob,fileName);}
if(self.URL){saver(self.URL.createObjectURL(blob),true);}else{if(typeof blob==="string"||blob.constructor===toString){try{return saver(`data:${mimeType};base64,${self.btoa(blob)}`);}catch{return saver(`data:${mimeType},${encodeURIComponent(blob)}`);}}
reader=new FileReader();reader.onload=function(){saver(this.result);};reader.readAsDataURL(blob);}
return true;}
__exports.downloadFile=downloadFile;function downloadFile(data,filename,mimetype){return downloadFile._download(data,filename,mimetype)}
downloadFile._download=_download;__exports.download=download;function download(options){return download._download(options);}
download._download=(options)=>{return new Promise((resolve,reject)=>{const xhr=new browser.XMLHttpRequest();let data;if(Object.prototype.hasOwnProperty.call(options,"form")){xhr.open(options.form.method,options.form.action);data=new FormData(options.form);}else{xhr.open("POST",options.url);data=new FormData();Object.entries(options.data).forEach((entry)=>{const[key,value]=entry;data.append(key,value);});}
data.append("token","dummy-because-api-expects-one");if(odoo.csrf_token){data.append("csrf_token",odoo.csrf_token);}
configureBlobDownloadXHR(xhr,{onSuccess:resolve,onFailure:reject,url:options.url,});xhr.send(data);});};__exports.configureBlobDownloadXHR=configureBlobDownloadXHR;function configureBlobDownloadXHR(xhr,{onSuccess=()=>{},onFailure=()=>{},url}={}){xhr.responseType="blob";xhr.onload=()=>{const mimetype=xhr.response.type;const header=(xhr.getResponseHeader("Content-Disposition")||"").replace(/;$/,"");const filename=header?parse(header).parameters.filename:null;if(xhr.status===200&&(mimetype!=="text/html"||filename)){_download(xhr.response,filename,mimetype);onSuccess(filename);}else if(xhr.status===502){onFailure(new ConnectionLostError(url));}else{const decoder=new FileReader();decoder.onload=()=>{const contents=decoder.result;const doc=new DOMParser().parseFromString(contents,"text/html");const nodes=doc.body.children.length===0?[doc.body]:doc.body.children;let error;try{const node=nodes[1]||nodes[0];error=JSON.parse(node.textContent);}catch{error={message:"Arbitrary Uncaught Python Exception",data:{debug:`${xhr.status}`+`\n`+`${nodes.length > 0 ? nodes[0].textContent : ""}
                                ${nodes.length > 1 ? nodes[1].textContent : ""}`,},};}
error=makeErrorFromResponse(error);onFailure(error);};decoder.readAsText(xhr.response);}};xhr.onerror=()=>{onFailure(new ConnectionLostError(url));};}
return __exports;});;

/* /web/static/src/core/network/http_service.js */
odoo.define('@web/core/network/http_service',['@web/core/browser/browser','@web/core/registry'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");function checkResponseStatus(response){if(response.status===502){throw new Error("Failed to fetch");}}
__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_service.js */
odoo.define('@web/core/network/rpc_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");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){super(`Connection to "${url}" couldn't be established or was interrupted`,...args);this.url=url;}}
const ConnectionAbortedError=__exports.ConnectionAbortedError=class ConnectionAbortedError extends Error{}
__exports.makeErrorFromResponse=makeErrorFromResponse;function makeErrorFromResponse(reponse){const{code,data:errorData,message,type:subType}=reponse;const error=new RPCError();error.exceptionName=errorData.name;error.subType=subType;error.data=errorData;error.message=message;error.code=code;return error;}
let rpcId=0;__exports.jsonrpc=jsonrpc;function jsonrpc(url,params={},settings={}){const bus=settings.bus;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;bus?.trigger("RPC:REQUEST",{data,url,settings});request.addEventListener("load",()=>{if(request.status===502){const error=new ConnectionLostError(url);bus?.trigger("RPC:RESPONSE",{data,settings,error});reject(error);return;}
let params;try{params=JSON.parse(request.response);}catch{const error=new ConnectionLostError(url);bus?.trigger("RPC:RESPONSE",{data,settings,error});return reject(error);}
const{error:responseError,result:responseResult}=params;if(!params.error){bus?.trigger("RPC:RESPONSE",{data,settings,result:params.result});return resolve(responseResult);}
const error=makeErrorFromResponse(responseError);bus?.trigger("RPC:RESPONSE",{data,settings,error});reject(error);});request.addEventListener("error",()=>{const error=new ConnectionLostError(url);bus?.trigger("RPC:RESPONSE",{data,settings,error});reject(error);});request.open("POST",url);const headers=settings.headers||{};headers["Content-Type"]="application/json";for(let[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");bus?.trigger("RPC:RESPONSE",{data,settings,error});if(rejectError){rejectFn(error);}};return promise;}
const rpcService=__exports.rpcService={async:true,start(env){return function rpc(route,params={},settings={}){return jsonrpc(route,params,{bus:env.bus,...settings});};},};registry.category("services").add("rpc",rpcService);return __exports;});;

/* /web/static/src/core/notebook/notebook.js */
odoo.define('@web/core/notebook/notebook',['@web/core/utils/scrolling','@odoo/owl'],function(require){'use strict';let __exports={};const{scrollTo}=require("@web/core/utils/scrolling");const{Component,onWillDestroy,onWillUpdateProps,useEffect,useRef,useState,}=require("@odoo/owl");const Notebook=__exports.Notebook=class Notebook extends Component{setup(){this.activePane=useRef("activePane");this.anchorTarget=null;this.pages=this.computePages(this.props);this.state=useState({currentPage:null});this.state.currentPage=this.computeActivePage(this.props.defaultPage,true);const onAnchorClicked=this.onAnchorClicked.bind(this);this.env.bus.addEventListener("SCROLLER:ANCHOR_LINK_CLICKED",onAnchorClicked);useEffect(()=>{this.props.onPageUpdate(this.state.currentPage);if(this.anchorTarget){const matchingEl=this.activePane.el.querySelector(`#${this.anchorTarget}`);scrollTo(matchingEl,{isAnchor:true});this.anchorTarget=null;}},()=>[this.state.currentPage]);onWillUpdateProps((nextProps)=>{const activateDefault=this.props.defaultPage!==nextProps.defaultPage||!this.defaultVisible;this.pages=this.computePages(nextProps);this.state.currentPage=this.computeActivePage(nextProps.defaultPage,activateDefault);});onWillDestroy(()=>{this.env.bus.removeEventListener("SCROLLER:ANCHOR_LINK_CLICKED",onAnchorClicked);});}
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;}
onAnchorClicked(ev){if(!this.props.anchors){return;}
const id=ev.detail.detail.id.substring(1);if(this.props.anchors[id]){if(this.state.currentPage!==this.props.anchors[id].target){ev.preventDefault();ev.detail.detail.originalEv.preventDefault();this.anchorTarget=id;this.state.currentPage=this.props.anchors[id].target;}}}
activatePage(pageIndex){if(!this.disabledPages.includes(pageIndex)){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;}}
Notebook.template="web.Notebook";Notebook.defaultProps={className:"",orientation:"horizontal",onPageUpdate:()=>{},};Notebook.props={slots:{type:Object,optional:true},pages:{type:Object,optional:true},class:{optional:true},className:{type:String,optional:true},anchors:{type:Object,optional:true},defaultPage:{type:String,optional:true},orientation:{type:String,optional:true},icons:{type:Object,optional:true},onPageUpdate:{type:Function,optional:true},};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}=require("@odoo/owl");const Notification=__exports.Notification=class Notification extends Component{}
Notification.template="web.NotificationWowl";Notification.props={message:{validate:(m)=>{return(typeof m==="string"||(typeof m==="object"&&typeof m.toString==="function"));},},title:{type:[String,Boolean,{toString:Function}],optional:true},type:{type:String,optional:true,validate:(t)=>["warning","danger","success","info"].includes(t),},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,},close:{type:Function},refresh:{type:Function},freeze:{type:Function},};Notification.defaultProps={buttons:[],className:"",type:"warning",};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{setup(){this.notifications=useState(this.props.notifications);}}
NotificationContainer.props={notifications:Object,};NotificationContainer.template=xml`
    <div class="o_notification_manager">
        <t t-foreach="notifications" t-as="notification" t-key="notification">
            <Transition leaveDuration="0" name="'o_notification_fade'" t-slot-scope="transition">
                <Notification t-props="notification_value.props" className="(notification_value.props.className || '') + ' ' + transition.className"/>
            </Transition>
        </t>
    </div>`;NotificationContainer.components={Notification,Transition};return __exports;});;

/* /web/static/src/core/notifications/notification_service.js */
odoo.define('@web/core/notifications/notification_service',['@web/core/browser/browser','@web/core/registry','@web/core/notifications/notification_container','@odoo/owl'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{NotificationContainer}=require("@web/core/notifications/notification_container");const{reactive}=require("@odoo/owl");const AUTOCLOSE_DELAY=4000;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});const sticky=props.sticky;delete props.sticky;delete props.onClose;let closeTimeout;const refresh=sticky?()=>{}:()=>{closeTimeout=browser.setTimeout(closeFn,AUTOCLOSE_DELAY);};const freeze=sticky?()=>{}:()=>{browser.clearTimeout(closeTimeout);};props.refresh=refreshAll;props.freeze=freezeAll;const notification={id,props,onClose:options.onClose,refresh,freeze,};notifications[id]=notification;if(!sticky){closeTimeout=browser.setTimeout(closeFn,AUTOCLOSE_DELAY);}
return closeFn;}
function refreshAll(){for(const id in notifications){notifications[id].refresh();}}
function freezeAll(){for(const id in notifications){notifications[id].freeze();}}
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'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");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","action_archive","action_unarchive",];const ORM=__exports.ORM=class ORM{constructor(rpc,user){this.rpc=rpc;this.user=user;this._silent=false;}
get silent(){return Object.assign(Object.create(this),{_silent:true});}
call(model,method,args=[],kwargs={}){validateModel(model);const url=`/web/dataset/call_kw/${model}/${method}`;const fullContext=Object.assign({},this.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});}
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);}
readGroup(model,domain,fields,groupby,kwargs={}){validateArray("domain",domain);validatePrimitiveList("fields","string",fields);validatePrimitiveList("groupby","string",groupby);groupby=[...new Set(groupby)];return this.call(model,"read_group",[],{...kwargs,domain,fields,groupby});}
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,fields,groupby,kwargs={}){validateArray("domain",domain);validatePrimitiveList("fields","string",fields);validatePrimitiveList("groupby","string",groupby);return this.call(model,"web_read_group",[],{...kwargs,groupby,domain,fields,});}
webRead(model,ids,kwargs={}){validatePrimitiveList("ids","number",ids);return this.call(model,"web_read",[ids],kwargs);}
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);}}
const ormService=__exports.ormService={dependencies:["rpc","user"],async:["call","create","nameGet","read","readGroup","search","searchRead","unlink","webSearchRead","write",],start(env,{rpc,user}){return new ORM(rpc,user);},};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}=require("@odoo/owl");const{sortBy}=require("@web/core/utils/arrays");const{ErrorHandler}=require("@web/core/utils/components");const OverlayContainer=__exports.OverlayContainer=class OverlayContainer extends Component{static template="web.OverlayContainer";static components={ErrorHandler};static props={overlays:Object};get sortedOverlays(){return sortBy(Object.values(this.props.overlays),(overlay)=>overlay.sequence);}
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{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=(id,onRemove=()=>{})=>{if(id in overlays){onRemove();delete overlays[id];}};const add=(component,props,options={})=>{const id=++nextId;const removeCurrentOverlay=()=>remove(id,options.onRemove);overlays[id]={id,component,props,remove:removeCurrentOverlay,sequence:options.sequence??50,};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,useExternalListener,useState}=require("@odoo/owl");const Pager=__exports.Pager=class Pager extends Component{setup(){this.state=useState({isEditing:false,isDisabled:false,});this.inputRef=useAutofocus();useExternalListener(document,"mousedown",this.onClickAway,{capture:true});}
get minimum(){return this.props.offset+1;}
get maximum(){return Math.min(this.props.offset+this.props.limit,this.props.total);}
get value(){const parts=[this.minimum];if(this.props.limit>1){parts.push(this.maximum);}
return parts.join("-");}
get isSinglePage(){return!this.props.updateTotal&&this.minimum===1&&this.maximum===this.props.total;}
async navigate(direction){let minimum=this.props.offset+this.props.limit*direction;let total=this.props.total;if(this.props.updateTotal&&minimum<0){total=await this.props.updateTotal();}
if(minimum>=total){if(!this.props.updateTotal){minimum=0;}}else if(minimum<0&&this.props.limit===1){minimum=total-1;}else if(minimum<0&&this.props.limit>1){minimum=total-(total%this.props.limit||this.props.limit);}
this.update(minimum,this.props.limit,true);}
async parse(value){let[minimum,maximum]=value.trim().split(/\s*[-\s,;]\s*/);minimum=parseInt(minimum,10);maximum=maximum?parseInt(maximum,10):minimum;if(this.props.updateTotal){return{minimum:minimum-1,maximum};}
return{minimum:clamp(minimum,1,this.props.total)-1,maximum:clamp(maximum,1,this.props.total),};}
async setValue(value){const{minimum,maximum}=await this.parse(value);if(!isNaN(minimum)&&!isNaN(maximum)&&minimum<maximum){this.update(minimum,maximum-minimum);}}
async update(offset,limit,hasNavigated){this.state.isDisabled=true;await this.props.onUpdate({offset,limit},hasNavigated);this.state.isDisabled=false;this.state.isEditing=false;}
async updateTotal(){if(!this.state.isDisabled){this.state.isDisabled=true;await this.props.updateTotal();this.state.isDisabled=false;}}
onClickAway(ev){if(ev.target!==this.inputRef.el){this.state.isEditing=false;}}
onInputBlur(){this.state.isEditing=false;}
onInputChange(ev){this.setValue(ev.target.value);if(!this.state.isDisabled){ev.preventDefault();}}
onInputKeydown(ev){switch(ev.key){case"Enter":ev.preventDefault();ev.stopPropagation();this.setValue(ev.currentTarget.value);break;case"Escape":ev.preventDefault();ev.stopPropagation();this.state.isEditing=false;break;}}
onValueClick(){if(this.props.isEditable&&!this.state.isEditing&&!this.state.isDisabled){if(this.inputRef.el){this.inputRef.el.focus();}
this.state.isEditing=true;}}}
Pager.template="web.Pager";Pager.defaultProps={isEditable:true,withAccessKey:true,};Pager.props={offset:Number,limit:Number,total:Number,onUpdate:Function,isEditable:{type:Boolean,optional:true},withAccessKey:{type:Boolean,optional:true},updateTotal:{type:Function,optional:true},};return __exports;});;

/* /web/static/src/core/popover/popover.js */
odoo.define('@web/core/popover/popover',['@odoo/owl','@web/core/utils/hooks','@web/core/position_hook','@web/core/ui/ui_service'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{useForwardRefToParent}=require("@web/core/utils/hooks");const{usePosition}=require("@web/core/position_hook");const{useActiveElement}=require("@web/core/ui/ui_service");const Popover=__exports.Popover=class Popover extends Component{static animationTime=200;setup(){useActiveElement("ref");useForwardRefToParent("ref");this.shouldAnimate=this.props.animation;this.position=usePosition("ref",()=>this.props.target,{onPositioned:(el,solution)=>{(this.props.onPositioned||this.onPositioned.bind(this))(el,solution);if(this.props.fixedPosition){this.position.lock();}},position:this.props.position,});}
onPositioned(el,{direction,variant}){const position=`${direction[0]}${variant[0]}`;const directionMap={top:"top",bottom:"bottom",left:"start",right:"end",};el.classList=["o_popover popover mw-100",`bs-popover-${directionMap[direction]}`,`o-popover-${direction}`,`o-popover--${position}`,].join(" ");if(this.props.class){el.classList.add(...this.props.class.split(" "));}
if(this.props.arrow){const arrowEl=el.querySelector(":scope > .popover-arrow");arrowEl.className="popover-arrow";switch(position){case"tm":case"bm":case"tf":case"bf":arrowEl.classList.add("start-0","end-0","mx-auto");break;case"lm":case"rm":case"lf":case"rf":arrowEl.classList.add("top-0","bottom-0","my-auto");break;case"ts":case"bs":arrowEl.classList.add("end-auto");break;case"te":case"be":arrowEl.classList.add("start-auto");break;case"ls":case"rs":arrowEl.classList.add("bottom-auto");break;case"le":case"re":arrowEl.classList.add("top-auto");break;}}
if(this.shouldAnimate){this.shouldAnimate=false;const transform={top:["translateY(-5%)","translateY(0)"],right:["translateX(5%)","translateX(0)"],bottom:["translateY(5%)","translateY(0)"],left:["translateX(-5%)","translateX(0)"],}[direction];this.position.lock();const animation=el.animate({opacity:[0,1],transform},this.constructor.animationTime);animation.finished.then(this.position.unlock);}}}
Popover.template="web.PopoverWowl";Popover.defaultProps={position:"bottom",class:"",fixedPosition:false,arrow:true,animation:true,};Popover.props={ref:{type:Function,optional:true,},class:{optional:true,type:String,},position:{type:String,validate:(p)=>{const[d,v="middle"]=p.split("-");return(["top","bottom","left","right"].includes(d)&&["start","middle","end","fit"].includes(v));},optional:true,},onPositioned:{type:Function,optional:true,},fixedPosition:{type:Boolean,optional:true,},arrow:{type:Boolean,optional:true,},animation:{type:Boolean,optional:true,},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")));},},slots:{type:Object,optional:true,shape:{default:{optional:true},},},};return __exports;});;

/* /web/static/src/core/popover/popover_controller.js */
odoo.define('@web/core/popover/popover_controller',['@odoo/owl','@web/core/hotkeys/hotkey_hook','@web/core/utils/hooks','@web/core/popover/popover'],function(require){'use strict';let __exports={};const{Component,onWillDestroy,useExternalListener,useSubEnv,xml}=require("@odoo/owl");const{useHotkey}=require("@web/core/hotkeys/hotkey_hook");const{useChildRef}=require("@web/core/utils/hooks");const{Popover}=require("@web/core/popover/popover");const POPOVER_SYMBOL=__exports.POPOVER_SYMBOL=Symbol("popover");const PopoverController=__exports.PopoverController=class PopoverController extends Component{static template=xml`
        <Popover t-props="props.popoverProps" ref="popoverRef">
            <t t-component="props.component" t-props="props.componentProps" close="props.close"/>
        </Popover>
    `;static components={Popover};static props=["target","close","closeOnClickAway","component","componentProps","popoverProps","subPopovers?",];setup(){this.props.subPopovers?.add(this);this.subPopovers=new Set();useSubEnv({[POPOVER_SYMBOL]:this.subPopovers});if(this.props.target.isConnected){this.popoverRef=useChildRef();useExternalListener(window,"pointerdown",this.onClickAway,{capture:true});useHotkey("escape",()=>this.props.close());const targetObserver=new MutationObserver(this.onTargetMutate.bind(this));targetObserver.observe(this.props.target.parentElement,{childList:true});onWillDestroy(()=>{targetObserver.disconnect();this.props.subPopovers?.delete(this);});}else{this.props.close();}}
isInside(target){if(this.props.target.contains(target)||this.popoverRef.el.contains(target)){return true;}
return[...this.subPopovers].some((p)=>p.isInside(target));}
onClickAway(ev){const target=ev.composedPath()[0];if(this.props.closeOnClickAway(target)&&!this.isInside(target)){this.props.close();}}
onTargetMutate(){if(!this.props.target.isConnected){this.props.close();}}}
return __exports;});;

/* /web/static/src/core/popover/popover_hook.js */
odoo.define('@web/core/popover/popover_hook',['@web/core/utils/hooks','@odoo/owl','@web/core/popover/popover_controller'],function(require){'use strict';let __exports={};const{useService}=require("@web/core/utils/hooks");const{onWillUnmount,status,useComponent,useEnv}=require("@odoo/owl");const{POPOVER_SYMBOL}=require("@web/core/popover/popover_controller");__exports.makePopover=makePopover;function makePopover(popoverService,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=popoverService.add(target,component,props,newOptions);},close,get isOpen(){return Boolean(removeFn);},};}
__exports.usePopover=usePopover;function usePopover(component,options={}){const env=useEnv();const popoverService=useService("popover");const owner=useComponent();const newOptions=Object.create(options);newOptions[POPOVER_SYMBOL]=env[POPOVER_SYMBOL];newOptions.onClose=()=>{if(status(owner)!=="destroyed"){options.onClose?.();}};const popover=makePopover(popoverService,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/registry','@web/core/popover/popover_controller'],function(require){'use strict';let __exports={};const{markRaw}=require("@odoo/owl");const{registry}=require("@web/core/registry");const{POPOVER_SYMBOL,PopoverController}=require("@web/core/popover/popover_controller");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(PopoverController,{target,close:()=>remove(),closeOnClickAway,subPopovers:options[POPOVER_SYMBOL],component,componentProps:markRaw(props),popoverProps:{target,class:options.popoverClass,animation:options.animation,arrow:options.arrow,position:options.position,onPositioned:options.onPositioned,fixedPosition:options.fixedPosition,},},{onRemove:options.onClose});return remove;};return{add};},};registry.category("services").add("popover",popoverService);return __exports;});;

/* /web/static/src/core/position_hook.js */
odoo.define('@web/core/position_hook',['@web/core/utils/timing','@odoo/owl','@web/core/l10n/localization'],function(require){'use strict';let __exports={};const{useThrottleForAnimation}=require("@web/core/utils/timing");const{EventBus,onWillDestroy,useChildSubEnv,useComponent,useEffect,useRef,}=require("@odoo/owl");const{localization}=require("@web/core/l10n/localization");const DIRECTIONS={t:"top",r:"right",b:"bottom",l:"left"};const VARIANTS={s:"start",m:"middle",e:"end",f:"fit"};const DIRECTION_FLIP_ORDER={top:"tbrl",right:"rltb",bottom:"btrl",left:"lrbt"};const VARIANT_FLIP_ORDER={start:"sme",middle:"mse",end:"ems",fit:"f"};const FIT_FLIP_ORDER={top:"tb",right:"rl",bottom:"bt",left:"lr"};const DEFAULTS={margin:0,position:"bottom",};function getIFrame(popperEl,targetEl){return[...popperEl.ownerDocument.getElementsByTagName("iframe")].find((iframe)=>iframe.contentDocument?.contains(targetEl));}
function getBestPosition(popper,target,{container,margin,position},iframe){const[directionKey,variantKey="middle"]=position.split("-");const directions=variantKey==="fit"?FIT_FLIP_ORDER[directionKey]:DIRECTION_FLIP_ORDER[directionKey];const variants=VARIANT_FLIP_ORDER[variantKey];if(!container){container=popper.ownerDocument.documentElement;}else if(typeof container==="function"){container=container();}
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 popBox=popper.getBoundingClientRect();const targetBox=target.getBoundingClientRect();const contBox=container.getBoundingClientRect();const shouldAccountForIFrame=iframe&&popper.ownerDocument!==target.ownerDocument;const iframeBox=shouldAccountForIFrame?iframe.getBoundingClientRect():{top:0,left:0};const containerIsHTMLNode=container===container.ownerDocument.firstElementChild;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,};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=directions[0],v=variants[0],containerRestricted=false){const vertical=["t","b"].includes(d);const variantPrefix=vertical?"v":"h";const directionValue=directionsData[d];const variantValue=variantsData[variantPrefix+v];if(containerRestricted){const[directionSize,variantSize]=vertical?[popBox.height,popBox.width]:[popBox.width,popBox.height];let[directionMin,directionMax]=vertical?[contBox.top,contBox.bottom]:[contBox.left,contBox.right];let[variantMin,variantMax]=vertical?[contBox.left,contBox.right]:[contBox.top,contBox.bottom];if(containerIsHTMLNode){if(vertical){directionMin+=container.scrollTop;directionMax+=container.scrollTop;}else{variantMin+=container.scrollTop;variantMax+=container.scrollTop;}}
const directionOverflow=Math.ceil(directionValue)<Math.floor(directionMin)||Math.floor(directionValue+directionSize)>Math.ceil(directionMax);const variantOverflow=Math.ceil(variantValue)<Math.floor(variantMin)||Math.floor(variantValue+variantSize)>Math.ceil(variantMax);if(directionOverflow||variantOverflow){return null;}}
const positioning=vertical?{top:directionValue,left:variantValue,}:{top:variantValue,left:directionValue,};return{top:positioning.top-popBox.top,left:positioning.left-popBox.left,direction:DIRECTIONS[d],variant:VARIANTS[v],};}
for(const d of directions){for(const v of variants){const match=getPositioningData(d,v,true);if(match){return match;}}}
return getPositioningData();}
__exports.reposition=reposition;function reposition(popper,target,options,iframe){let[directionKey,variantKey="middle"]=options.position.split("-");if(localization.direction==="rtl"){if(["bottom","top"].includes(directionKey)){if(variantKey!=="middle"){variantKey=variantKey==="start"?"end":"start";}}else{directionKey=directionKey==="left"?"right":"left";}}
options.position=[directionKey,variantKey].join("-");popper.style.position="fixed";popper.style.top="0px";popper.style.left="0px";const position=getBestPosition(popper,target,options,iframe);const{top,left,direction,variant}=position;popper.style.top=`${top}px`;popper.style.left=`${left}px`;if(variant==="fit"){const styleProperty=["top","bottom"].includes(direction)?"width":"height";popper.style[styleProperty]=target.getBoundingClientRect()[styleProperty]+"px";}
options.onPositioned?.(popper,position);}
const 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||lock){return;}
const iframe=getIFrame(ref.el,targetEl);reposition(ref.el,targetEl,{...DEFAULTS,...options},iframe);};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 targetDocument=getTarget()?.ownerDocument;targetDocument?.addEventListener("scroll",scrollListener,{capture:true});targetDocument?.addEventListener("load",throttledUpdate,{capture:true});window.addEventListener("resize",throttledUpdate);return()=>{targetDocument?.removeEventListener("scroll",scrollListener,{capture:true});targetDocument?.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/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);});},time:{strftime(format){return PyDateTime.now().strftime(format);},},context_today(){return PyDate.today();},get current_date(){return this.today;},get today(){return PyDate.today().strftime("%Y-%m-%d");},get now(){return PyDateTime.now().strftime("%Y-%m-%d %H:%M:%S");},datetime:{time:PyTime,timedelta:PyTimeDelta,datetime:PyDateTime,date:PyDate,},relativedelta:PyRelativeDelta,true:true,false:false,};return __exports;});;

/* /web/static/src/core/py_js/py_date.js */
odoo.define('@web/core/py_js/py_date',['@web/core/py_js/py_parser'],function(require){'use strict';let __exports={};const{parseArgs}=require("@web/core/py_js/py_parser");const AssertionError=__exports.AssertionError=class AssertionError extends Error{}
const ValueError=__exports.ValueError=class ValueError extends Error{}
const NotSupportedError=__exports.NotSupportedError=class NotSupportedError extends Error{}
function fmt2(n){return String(n).padStart(2,"0");}
function fmt4(n){return String(n).padStart(4,"0");}
function divmod(a,b,fn){let mod=a%b;if((mod>0&&b<0)||(mod<0&&b>0)){mod+=b;}
return fn(Math.floor(a/b),mod);}
function assert(bool,message="AssertionError"){if(!bool){throw new AssertionError(message);}}
const DAYS_IN_MONTH=[null,31,28,31,30,31,30,31,31,30,31,30,31];const DAYS_BEFORE_MONTH=[null];for(let dbm=0,i=1;i<DAYS_IN_MONTH.length;++i){DAYS_BEFORE_MONTH.push(dbm);dbm+=DAYS_IN_MONTH[i];}
function daysInMonth(year,month){if(month===2&&isLeap(year)){return 29;}
return DAYS_IN_MONTH[month];}
function isLeap(year){return year%4===0&&(year%100!==0||year%400===0);}
function daysBeforeYear(year){const y=year-1;return y*365+Math.floor(y/4)-Math.floor(y/100)+Math.floor(y/400);}
function daysBeforeMonth(year,month){const postLeapFeb=month>2&&isLeap(year);return DAYS_BEFORE_MONTH[month]+(postLeapFeb?1:0);}
function ymd2ord(year,month,day){const dim=daysInMonth(year,month);if(!(1<=day&&day<=dim)){throw new ValueError(`day must be in 1..${dim}`);}
return daysBeforeYear(year)+daysBeforeMonth(year,month)+day;}
const DI400Y=daysBeforeYear(401);const DI100Y=daysBeforeYear(101);const DI4Y=daysBeforeYear(5);function ord2ymd(n){--n;let n400,n100,n4,n1,n0;divmod(n,DI400Y,function(_n400,n){n400=_n400;divmod(n,DI100Y,function(_n100,n){n100=_n100;divmod(n,DI4Y,function(_n4,n){n4=_n4;divmod(n,365,function(_n1,n){n1=_n1;n0=n;});});});});n=n0;const year=n400*400+1+n100*100+n4*4+n1;if(n1==4||n100==100){assert(n0===0);return{year:year-1,month:12,day:31,};}
const leapyear=n1===3&&(n4!==24||n100==3);assert(leapyear==isLeap(year));let month=(n+50)>>5;let preceding=DAYS_BEFORE_MONTH[month]+(month>2&&leapyear?1:0);if(preceding>n){--month;preceding-=DAYS_IN_MONTH[month]+(month===2&&leapyear?1:0);}
n-=preceding;return{year:year,month:month,day:n+1,};}
function tmxxx(year,month,day,hour,minute,second,microsecond){hour=hour||0;minute=minute||0;second=second||0;microsecond=microsecond||0;if(microsecond<0||microsecond>999999){divmod(microsecond,1000000,function(carry,ms){microsecond=ms;second+=carry;});}
if(second<0||second>59){divmod(second,60,function(carry,s){second=s;minute+=carry;});}
if(minute<0||minute>59){divmod(minute,60,function(carry,m){minute=m;hour+=carry;});}
if(hour<0||hour>23){divmod(hour,24,function(carry,h){hour=h;day+=carry;});}
if(month<1||month>12){divmod(month-1,12,function(carry,m){month=m+1;year+=carry;});}
const dim=daysInMonth(year,month);if(day<1||day>dim){if(day===0){--month;if(month>0){day=daysInMonth(year,month);}else{--year;month=12;day=31;}}else if(day==dim+1){++month;day=1;if(month>12){month=1;++year;}}else{const r=ord2ymd(ymd2ord(year,month,1)+(day-1));year=r.year;month=r.month;day=r.day;}}
return{year:year,month:month,day:day,hour:hour,minute:minute,second:second,microsecond:microsecond,};}
const PyDate=__exports.PyDate=class PyDate{static today(){return this.convertDate(new Date());}
static convertDate(date){const year=date.getFullYear();const month=date.getMonth()+1;const day=date.getDate();return new PyDate(year,month,day);}
constructor(year,month,day){this.year=year;this.month=month;this.day=day;}
static create(...args){const{year,month,day}=parseArgs(args,["year","month","day"]);return new PyDate(year,month,day);}
add(timedelta){const s=tmxxx(this.year,this.month,this.day+timedelta.days);return new PyDate(s.year,s.month,s.day);}
isEqual(other){if(!(other instanceof PyDate)){return false;}
return this.year===other.year&&this.month===other.month&&this.day===other.day;}
strftime(format){return format.replace(/%([A-Za-z])/g,(m,c)=>{switch(c){case"Y":return fmt4(this.year);case"m":return fmt2(this.month);case"d":return fmt2(this.day);}
throw new ValueError(`No known conversion for ${m}`);});}
substract(other){if(other instanceof PyTimeDelta){return this.add(other.negate());}
if(other instanceof PyDate){return PyTimeDelta.create(this.toordinal()-other.toordinal());}
throw NotSupportedError();}
toJSON(){return this.strftime("%Y-%m-%d");}
toordinal(){return ymd2ord(this.year,this.month,this.day);}}
const PyDateTime=__exports.PyDateTime=class PyDateTime{static now(){return this.convertDate(new Date());}
static convertDate(date){const year=date.getFullYear();const month=date.getMonth()+1;const day=date.getDate();const hour=date.getHours();const minute=date.getMinutes();const second=date.getSeconds();return new PyDateTime(year,month,day,hour,minute,second,0);}
static create(...args){const namedArgs=parseArgs(args,["year","month","day","hour","minute","second","microsecond",]);const year=namedArgs.year;const month=namedArgs.month;const day=namedArgs.day;const hour=namedArgs.hour||0;const minute=namedArgs.minute||0;const second=namedArgs.second||0;const ms=namedArgs.micro/1000||0;return new PyDateTime(year,month,day,hour,minute,second,ms);}
static combine(...args){const{date,time}=parseArgs(args,["date","time"]);return PyDateTime.create(date.year,date.month,date.day,time.hour,time.minute,time.second);}
constructor(year,month,day,hour,minute,second,microsecond){this.year=year;this.month=month;this.day=day;this.hour=hour;this.minute=minute;this.second=second;this.microsecond=microsecond;}
add(timedelta){const s=tmxxx(this.year,this.month,this.day+timedelta.days,this.hour,this.minute,this.second+timedelta.seconds,this.microsecond+timedelta.microseconds);return new PyDateTime(s.year,s.month,s.day,s.hour,s.minute,s.second,s.microsecond);}
isEqual(other){if(!(other instanceof PyDateTime)){return false;}
return(this.year===other.year&&this.month===other.month&&this.day===other.day&&this.hour===other.hour&&this.minute===other.minute&&this.second===other.second&&this.microsecond===other.microsecond);}
strftime(format){return format.replace(/%([A-Za-z])/g,(m,c)=>{switch(c){case"Y":return fmt4(this.year);case"m":return fmt2(this.month);case"d":return fmt2(this.day);case"H":return fmt2(this.hour);case"M":return fmt2(this.minute);case"S":return fmt2(this.second);}
throw new ValueError(`No known conversion for ${m}`);});}
substract(timedelta){return this.add(timedelta.negate());}
toJSON(){return this.strftime("%Y-%m-%d %H:%M:%S");}
to_utc(){const d=new Date(this.year,this.month-1,this.day,this.hour,this.minute,this.second);const timedelta=PyTimeDelta.create({minutes:d.getTimezoneOffset()});return this.add(timedelta);}}
const PyTime=__exports.PyTime=class PyTime extends PyDate{static create(...args){const namedArgs=parseArgs(args,["hour","minute","second"]);const hour=namedArgs.hour||0;const minute=namedArgs.minute||0;const second=namedArgs.second||0;return new PyTime(hour,minute,second);}
constructor(hour,minute,second){const now=new Date();const year=now.getFullYear();const month=now.getMonth();const day=now.getDate();super(year,month,day);this.hour=hour;this.minute=minute;this.second=second;}
strftime(format){return format.replace(/%([A-Za-z])/g,(m,c)=>{switch(c){case"Y":return fmt4(this.year);case"m":return fmt2(this.month+1);case"d":return fmt2(this.day);case"H":return fmt2(this.hour);case"M":return fmt2(this.minute);case"S":return fmt2(this.second);}
throw new ValueError(`No known conversion for ${m}`);});}
toJSON(){return this.strftime("%H:%M:%S");}}
const DAYS_IN_YEAR=[31,59,90,120,151,181,212,243,273,304,334,366];const TIME_PERIODS=["hour","minute","second"];const PERIODS=["year","month","day",...TIME_PERIODS];const RELATIVE_KEYS="years months weeks days hours minutes seconds microseconds leapdays".split(" ");const ABSOLUTE_KEYS="year month day hour minute second microsecond weekday nlyearday yearday".split(" ");const argsSpec=["dt1","dt2"];const PyRelativeDelta=__exports.PyRelativeDelta=class PyRelativeDelta{static create(...args){const params=parseArgs(args,argsSpec);if("dt1"in params){throw new Error("relativedelta(dt1, dt2) is not supported for now");}
for(const period of PERIODS){if(period in params){const val=params[period];assert(val>=0,`${period} ${val} is out of range`);}}
for(const key of RELATIVE_KEYS){params[key]=params[key]||0;}
for(const key of ABSOLUTE_KEYS){params[key]=key in params?params[key]:null;}
params.days+=7*params.weeks;let yearDay=0;if(params.nlyearday){yearDay=params.nlyearday;}else if(params.yearday){yearDay=params.yearday;if(yearDay>59){params.leapDays=-1;}}
if(yearDay){for(let monthIndex=0;monthIndex<DAYS_IN_YEAR.length;monthIndex++){if(yearDay<=DAYS_IN_YEAR[monthIndex]){params.month=monthIndex+1;if(monthIndex===0){params.day=yearDay;}else{params.day=yearDay-DAYS_IN_YEAR[monthIndex-1];}
break;}}}
return new PyRelativeDelta(params);}
static add(date,delta){if(!(date instanceof PyDate||date instanceof PyDateTime)){throw NotSupportedError();}
const s=tmxxx((delta.year||date.year)+delta.years,(delta.month||date.month)+delta.months,delta.day||date.day,delta.hour||date.hour||0,delta.minute||date.minute||0,delta.second||date.seconds||0,delta.microseconds||date.microseconds||0);const newDateTime=new PyDateTime(s.year,s.month,s.day,s.hour,s.minute,s.second,s.microsecond);let leapDays=0;if(delta.leapDays&&newDateTime.month>2&&isLeap(newDateTime.year)){leapDays=delta.leapDays;}
const temp=newDateTime.add(PyTimeDelta.create({days:delta.days+leapDays,hours:delta.hours,minutes:delta.minutes,seconds:delta.seconds,microseconds:delta.microseconds,}));const hasTime=Boolean(temp.hour||temp.minute||temp.second||temp.microsecond);const returnDate=!hasTime&&date instanceof PyDate?new PyDate(temp.year,temp.month,temp.day):temp;if(delta.weekday!==null){const wantedDow=delta.weekday+1;const _date=new Date(returnDate.year,returnDate.month-1,returnDate.day);const days=(7-_date.getDay()+wantedDow)%7;return returnDate.add(new PyTimeDelta(days,0,0));}
return returnDate;}
static substract(date,delta){return PyRelativeDelta.add(date,delta.negate());}
constructor(params={},sign=+1){this.years=sign*params.years;this.months=sign*params.months;this.days=sign*params.days;this.hours=sign*params.hours;this.minutes=sign*params.minutes;this.seconds=sign*params.seconds;this.microseconds=sign*params.microseconds;this.leapDays=params.leapDays;this.year=params.year;this.month=params.month;this.day=params.day;this.hour=params.hour;this.minute=params.minute;this.second=params.second;this.microsecond=params.microsecond;this.weekday=params.weekday;}
negate(){return new PyRelativeDelta(this,-1);}
isEqual(other){throw new NotSupportedError();}}
const TIME_DELTA_KEYS="weeks days hours minutes seconds milliseconds microseconds".split(" ");function modf(x){const mod=x%1;return[mod<0?mod+1:mod,Math.floor(x)];}
const PyTimeDelta=__exports.PyTimeDelta=class PyTimeDelta{static create(...args){const namedArgs=parseArgs(args,["days","seconds","microseconds"]);for(const key of TIME_DELTA_KEYS){namedArgs[key]=namedArgs[key]||0;}
let d=0;let s=0;let us=0;const days=namedArgs.days+namedArgs.weeks*7;let seconds=namedArgs.seconds+60*namedArgs.minutes+3600*namedArgs.hours;let microseconds=namedArgs.microseconds+1000*namedArgs.milliseconds;const[dFrac,dInt]=modf(days);d=dInt;let daysecondsfrac=0;if(dFrac){const[dsFrac,dsInt]=modf(dFrac*24*3600);s=dsInt;daysecondsfrac=dsFrac;}
const[sFrac,sInt]=modf(seconds);seconds=sInt;const secondsfrac=sFrac+daysecondsfrac;divmod(seconds,24*3600,(days,seconds)=>{d+=days;s+=seconds;});microseconds+=secondsfrac*1e6;divmod(microseconds,1000000,(seconds,microseconds)=>{divmod(seconds,24*3600,(days,seconds)=>{d+=days;s+=seconds;us+=Math.round(microseconds);});});return new PyTimeDelta(d,s,us);}
constructor(days,seconds,microseconds){this.days=days;this.seconds=seconds;this.microseconds=microseconds;}
add(other){return PyTimeDelta.create({days:this.days+other.days,seconds:this.seconds+other.seconds,microseconds:this.microseconds+other.microseconds,});}
divide(n){const us=(this.days*24*3600+this.seconds)*1e6+this.microseconds;return PyTimeDelta.create({microseconds:Math.floor(us/n)});}
isEqual(other){if(!(other instanceof PyTimeDelta)){return false;}
return(this.days===other.days&&this.seconds===other.seconds&&this.microseconds===other.microseconds);}
isTrue(){return this.days!==0||this.seconds!==0||this.microseconds!==0;}
multiply(n){return PyTimeDelta.create({days:n*this.days,seconds:n*this.seconds,microseconds:n*this.microseconds,});}
negate(){return PyTimeDelta.create({days:-this.days,seconds:-this.seconds,microseconds:-this.microseconds,});}
substract(other){return PyTimeDelta.create({days:this.days-other.days,seconds:this.seconds-other.seconds,microseconds:this.microseconds-other.microseconds,});}
total_seconds(){return this.days*86400+this.seconds+this.microseconds/1000000;}}
return __exports;});;

/* /web/static/src/core/py_js/py_interpreter.js */
odoo.define('@web/core/py_js/py_interpreter',['@web/core/py_js/py_builtin','@web/core/py_js/py_date','@web/core/py_js/py_utils','@web/core/py_js/py_parser'],function(require){'use strict';let __exports={};const{BUILTINS,EvaluationError,execOnIterable}=require("@web/core/py_js/py_builtin");const{NotSupportedError,PyDate,PyDateTime,PyRelativeDelta,PyTime,PyTimeDelta,}=require("@web/core/py_js/py_date");const{PY_DICT,toPyDict}=require("@web/core/py_js/py_utils");const{parseArgs}=require("@web/core/py_js/py_parser");const isTrue=BUILTINS.bool;function applyUnaryOp(ast,context){const value=evaluate(ast.right,context);switch(ast.op){case"-":if(value instanceof Object&&value.negate){return value.negate();}
return-value;case"+":return value;case"not":return!isTrue(value);}
throw new EvaluationError(`Unknown unary operator: ${ast.op}`);}
function pytypeIndex(val){switch(typeof val){case"object":return val===null?1:Array.isArray(val)?5:3;case"number":return 2;case"string":return 4;}
throw new EvaluationError(`Unknown type: ${typeof val}`);}
function isConstructor(obj){return!!obj.prototype&&!!obj.prototype.constructor.name;}
function isLess(left,right){if(typeof left==="number"&&typeof right==="number"){return left<right;}
if(typeof left==="boolean"){left=left?1:0;}
if(typeof right==="boolean"){right=right?1:0;}
const leftIndex=pytypeIndex(left);const rightIndex=pytypeIndex(right);if(leftIndex===rightIndex){return left<right;}
return leftIndex<rightIndex;}
function isEqual(left,right){if(typeof left!==typeof right){if(typeof left==="boolean"&&typeof right==="number"){return right===(left?1:0);}
if(typeof left==="number"&&typeof right==="boolean"){return left===(right?1:0);}
return false;}
if(left instanceof Object&&left.isEqual){return left.isEqual(right);}
return left===right;}
function isIn(left,right){if(Array.isArray(right)){return right.includes(left);}
if(typeof right==="string"&&typeof left==="string"){return right.includes(left);}
if(typeof right==="object"){return left in right;}
return false;}
function applyBinaryOp(ast,context){const left=evaluate(ast.left,context);const right=evaluate(ast.right,context);switch(ast.op){case"+":{const relativeDeltaOnLeft=left instanceof PyRelativeDelta;const relativeDeltaOnRight=right instanceof PyRelativeDelta;if(relativeDeltaOnLeft||relativeDeltaOnRight){const date=relativeDeltaOnLeft?right:left;const delta=relativeDeltaOnLeft?left:right;return PyRelativeDelta.add(date,delta);}
const timeDeltaOnLeft=left instanceof PyTimeDelta;const timeDeltaOnRight=right instanceof PyTimeDelta;if(timeDeltaOnLeft&&timeDeltaOnRight){return left.add(right);}
if(timeDeltaOnLeft){if(right instanceof PyDate||right instanceof PyDateTime){return right.add(left);}else{throw NotSupportedError();}}
if(timeDeltaOnRight){if(left instanceof PyDate||left instanceof PyDateTime){return left.add(right);}else{throw NotSupportedError();}}
if(left instanceof Array&&right instanceof Array){return[...left,...right];}
return left+right;}
case"-":{const isRightDelta=right instanceof PyRelativeDelta;if(isRightDelta){return PyRelativeDelta.substract(left,right);}
const timeDeltaOnRight=right instanceof PyTimeDelta;if(timeDeltaOnRight){if(left instanceof PyTimeDelta){return left.substract(right);}else if(left instanceof PyDate||left instanceof PyDateTime){return left.substract(right);}else{throw NotSupportedError();}}
if(left instanceof PyDate){return left.substract(right);}
return left-right;}
case"*":{const timeDeltaOnLeft=left instanceof PyTimeDelta;const timeDeltaOnRight=right instanceof PyTimeDelta;if(timeDeltaOnLeft||timeDeltaOnRight){const number=timeDeltaOnLeft?right:left;const delta=timeDeltaOnLeft?left:right;return delta.multiply(number);}
return left*right;}
case"/":return left/right;case"%":return left%right;case"//":if(left instanceof PyTimeDelta){return left.divide(right);}
return Math.floor(left/right);case"**":return left**right;case"==":return isEqual(left,right);case"<>":case"!=":return!isEqual(left,right);case"<":return isLess(left,right);case">":return isLess(right,left);case">=":return isEqual(left,right)||isLess(right,left);case"<=":return isEqual(left,right)||isLess(left,right);case"in":return isIn(left,right);case"not in":return!isIn(left,right);}
throw new EvaluationError(`Unknown binary operator: ${ast.op}`);}
const DICT={get(...args){const{key,defValue}=parseArgs(args,["key","defValue"]);if(key in this){return this[key];}else if(defValue){return defValue;}
return null;},};const STRING={lower(){return this.toLowerCase();},upper(){return this.toUpperCase();},};function applyFunc(key,func,set,...args){if(args.length===1){return new Set(set);}
if(args.length>2){throw new EvaluationError(`${key}: py_js supports at most 1 argument, got (${args.length - 1})`);}
return execOnIterable(args[0],func);}
const SET={intersection(...args){return applyFunc("intersection",(iterable)=>{const intersection=new Set();for(const i of iterable){if(this.has(i)){intersection.add(i);}}
return intersection;},this,...args);},difference(...args){return applyFunc("difference",(iterable)=>{iterable=new Set(iterable);const difference=new Set();for(const e of this){if(!iterable.has(e)){difference.add(e);}}
return difference;},this,...args);},union(...args){return applyFunc("union",(iterable)=>{return 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.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){return _parse(tokens,0);}
throw new ParserError("Missing token");}
__exports.parseArgs=parseArgs;function parseArgs(args,spec){const last=args[args.length-1];const unnamedArgs=typeof last==="object"?args.slice(0,-1):args;const kwargs=typeof last==="object"?last:{};for(const[index,val]of unnamedArgs.entries()){kwargs[spec[index]]=val;}
return kwargs;}
return __exports;});;

/* /web/static/src/core/py_js/py_tokenizer.js */
odoo.define('@web/core/py_js/py_tokenizer',[],function(require){'use strict';let __exports={};const TokenizerError=__exports.TokenizerError=class TokenizerError extends Error{}
const directMap={"\\":"\\",'"':'"',"'":"'",a:"\x07",b:"\x08",f:"\x0c",n:"\n",r:"\r",t:"\t",v:"\v",};function decodeStringLiteral(str,unicode){const out=[];let code;for(var i=0;i<str.length;++i){if(str[i]!=="\\"){out.push(str[i]);continue;}
var escape=str[i+1];if(escape in directMap){out.push(directMap[escape]);++i;continue;}
switch(escape){case"\n":++i;continue;case"N":if(!unicode){break;}
throw new TokenizerError("SyntaxError: \\N{} escape not implemented");case"u":if(!unicode){break;}
var uni=str.slice(i+2,i+6);if(!/[0-9a-f]{4}/i.test(uni)){throw new TokenizerError(["SyntaxError: (unicode error) 'unicodeescape' codec"," can't decode bytes in position ",i,"-",i+4,": truncated \\uXXXX escape",].join(""));}
code=parseInt(uni,16);out.push(String.fromCharCode(code));i+=5;continue;case"U":if(!unicode){break;}
throw new TokenizerError("SyntaxError: \\U escape not implemented");case"x":var hex=str.slice(i+2,i+4);if(!/[0-9a-f]{2}/i.test(hex)){if(!unicode){throw new TokenizerError("ValueError: invalid \\x escape");}
throw new TokenizerError(["SyntaxError: (unicode error) 'unicodeescape'"," codec can't decode bytes in position ",i,"-",i+2,": truncated \\xXX escape",].join(""));}
code=parseInt(hex,16);out.push(String.fromCharCode(code));i+=3;continue;default:if(!/[0-8]/.test(escape)){break;}
var r=/[0-8]{1,3}/g;r.lastIndex=i+1;var m=r.exec(str);var oct=m[0];code=parseInt(oct,8);out.push(String.fromCharCode(code));i+=oct.length;continue;}
out.push("\\");}
return out.join("");}
const constants=new Set(["None","False","True"]);const comparators=__exports.comparators=["in","not","not in","is","is not","<","<=",">",">=","<>","!=","==",];const binaryOperators=__exports.binaryOperators=["or","and","|","^","&","<<",">>","+","-","*","/","//","%","~","**",".",];const unaryOperators=__exports.unaryOperators=["-"];const symbols=new Set([...["(",")","[","]","{","}",":",","],...["if","else","lambda","="],...comparators,...binaryOperators,...unaryOperators,]);function group(...args){return"("+args.join("|")+")";}
const Name="[a-zA-Z_]\\w*";const Whitespace="[ \\f\\t]*";const DecNumber="\\d+(L|l)?";const IntNumber=DecNumber;const Exponent="[eE][+-]?\\d+";const PointFloat=group(`\\d+\\.\\d*(${Exponent})?`,`\\.\\d+(${Exponent})?`);const FloatNumber=group(PointFloat,`\\d+${Exponent}`);const Number=group(FloatNumber,IntNumber);const Operator=group("\\*\\*=?",">>=?","<<=?","<>","!=","//=?","[+\\-*/%&|^=<>]=?","~");const Bracket="[\\[\\]\\(\\)\\{\\}]";const Special="[:;.,`@]";const Funny=group(Operator,Bracket,Special);const ContStr=group("([uU])?'([^\n'\\\\]*(?:\\\\.[^\n'\\\\]*)*)'",'([uU])?"([^\n"\\\\]*(?:\\\\.[^\n"\\\\]*)*)"');const PseudoToken=Whitespace+group(Number,Funny,ContStr,Name);const NumberPattern=new RegExp("^"+Number+"$");const StringPattern=new RegExp("^"+ContStr+"$");const NamePattern=new RegExp("^"+Name+"$");const strip=new RegExp("^"+Whitespace);__exports.tokenize=tokenize;function tokenize(str){const tokens=[];const max=str.length;let start=0;let end=0;const pseudoprog=new RegExp(PseudoToken,"g");while(pseudoprog.lastIndex<max){const pseudomatch=pseudoprog.exec(str);if(!pseudomatch){if(/^\s+$/.test(str.slice(end))){break;}
throw new TokenizerError("Failed to tokenize <<"+
str+">> at index "+
(end||0)+"; parsed so far: "+
tokens);}
if(pseudomatch.index>end){if(str.slice(end,pseudomatch.index).trim()){throw new TokenizerError("Invalid expression");}}
start=pseudomatch.index;end=pseudoprog.lastIndex;let token=str.slice(start,end).replace(strip,"");if(NumberPattern.test(token)){tokens.push({type:0,value:parseFloat(token),});}else if(StringPattern.test(token)){var m=StringPattern.exec(token);tokens.push({type:1,value:decodeStringLiteral(m[3]!==undefined?m[3]:m[5],!!(m[2]||m[4])),});}else if(symbols.has(token)){if(token==="in"&&tokens.length>0&&tokens[tokens.length-1].value==="not"){token="not in";tokens.pop();}else if(token==="not"&&tokens.length>0&&tokens[tokens.length-1].value==="is"){token="is not";tokens.pop();}
tokens.push({type:2,value:token,});}else if(constants.has(token)){tokens.push({type:4,value:token,});}else if(NamePattern.test(token)){tokens.push({type:3,value:token,});}else{throw new TokenizerError("Invalid expression");}}
return tokens;}
return __exports;});;

/* /web/static/src/core/py_js/py_utils.js */
odoo.define('@web/core/py_js/py_utils',['@web/core/py_js/py_parser','@web/core/py_js/py_date'],function(require){'use strict';let __exports={};const{bp}=require("@web/core/py_js/py_parser");const{PyDate,PyDateTime}=require("@web/core/py_js/py_date");__exports.toPyValue=toPyValue;function toPyValue(value){switch(typeof value){case"string":return{type:1,value};case"number":return{type:0,value};case"boolean":return{type:2,value};case"object":if(Array.isArray(value)){return{type:4,value:value.map(toPyValue)};}else if(value===null){return{type:3};}else if(value instanceof Date){return{type:1,value:PyDateTime.convertDate(value)};}else if(value instanceof PyDate||value instanceof PyDateTime){return{type:1,value};}else{const content={};for(const key in value){content[key]=toPyValue(value[key]);}
return{type:11,value:content};}
default:throw new Error("Invalid type");}}
__exports.formatAST=formatAST;function formatAST(ast,lbp=0){switch(ast.type){case 3:return"None";case 1:return JSON.stringify(ast.value);case 0:return String(ast.value);case 2:return ast.value?"True":"False";case 4:return`[${ast.value.map(formatAST).join(", ")}]`;case 6:if(ast.op==="not"){return`not `+formatAST(ast.right,50);}
return ast.op+formatAST(ast.right,130);case 7:{const abp=bp(ast.op);const str=`${formatAST(ast.left, abp)} ${ast.op} ${formatAST(ast.right, abp)}`;return abp<lbp?`(${str})`:str;}
case 11:{const pairs=[];for(const k in ast.value){pairs.push(`"${k}": ${formatAST(ast.value[k])}`);}
return`{`+pairs.join(", ")+`}`;}
case 10:return`(${ast.value.map(formatAST).join(", ")})`;case 5:return ast.value;case 12:{return`${formatAST(ast.target)}[${formatAST(ast.key)}]`;}
case 13:{const{ifTrue,condition,ifFalse}=ast;return`${formatAST(ifTrue)} if ${formatAST(condition)} else ${formatAST(ifFalse)}`;}
case 14:{const abp=bp(ast.op);const str=`${formatAST(ast.left, abp)} ${ast.op} ${formatAST(ast.right, abp)}`;return abp<lbp?`(${str})`:str;}
case 15:return`${formatAST(ast.obj, 150)}.${ast.key}`;case 8:{const args=ast.args.map(formatAST);const kwargs=[];for(const kwarg in ast.kwargs){kwargs.push(`${kwarg} = ${formatAST(ast.kwargs[kwarg])}`);}
const argStr=args.concat(kwargs).join(", ");return`${formatAST(ast.fn)}(${argStr})`;}}
throw new Error("invalid expression: "+ast);}
const PY_DICT=__exports.PY_DICT=Object.create(null);__exports.toPyDict=toPyDict;function toPyDict(obj){return new Proxy(obj,{getPrototypeOf(){return PY_DICT;},});}
return __exports;});;

/* /web/static/src/core/record_selectors/multi_record_selector.js */
odoo.define('@web/core/record_selectors/multi_record_selector',['@odoo/owl','@web/core/tags_list/tags_list','@web/core/utils/hooks','@web/core/record_selectors/record_autocomplete','@web/core/l10n/translation','@web/core/record_selectors/tag_navigation_hook'],function(require){'use strict';let __exports={};const{Component,onWillStart,onWillUpdateProps}=require("@odoo/owl");const{TagsList}=require("@web/core/tags_list/tags_list");const{useService}=require("@web/core/utils/hooks");const{RecordAutocomplete}=require("@web/core/record_selectors/record_autocomplete");const{_t}=require("@web/core/l10n/translation");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");this.onTagKeydown=useTagNavigation("multiRecordSelector",this.deleteTag.bind(this));onWillStart(()=>this.computeDerivedParams());onWillUpdateProps((nextProps)=>this.computeDerivedParams(nextProps));}
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.getIds().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);},onKeydown:this.onTagKeydown,};});}
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{_t}=require("@web/core/l10n/translation");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},};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),},];}
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(([value,label])=>({value,label}));if(SEARCH_LIMIT<nameGets.length){options.push({label:_t("Search More..."),action:this.onSearchMore.bind(this,name),classList:"o_m2o_dropdown_option",});}
if(options.length===0){options.push({label:_t("(no result)"),unselectable:true});}
return options;}
async onSearchMore(name){const{fieldString,multiSelect,resModel}=this.props;let operator;const ids=[];if(name){const nameGets=await this.search(name,SEARCH_MORE_LIMIT);this.addNames(nameGets);operator="in";ids.push(...nameGets.map((nameGet)=>nameGet[0]));}else{operator="not in";ids.push(...this.getIds());}
const dynamicFilters=ids.length?[{description:_t("Quick search: %s",name),domain:[["id",operator,ids]],},]:undefined;const SelectCreateDialog=registry.category("dialogs").get("select_create");this.addDialog(SelectCreateDialog,{title:_t("Search: %s",fieldString),dynamicFilters,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();}
onSelect({value:resId,action},params){if(action){return action(params);}
this.props.update([resId]);}
search(name,limit){const domain=this.getDomain();return this.orm.call(this.props.resModel,"name_search",[],{name,args: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/utils/hooks','@web/core/record_selectors/record_autocomplete','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{Component,onWillStart,onWillUpdateProps}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{RecordAutocomplete}=require("@web/core/record_selectors/record_autocomplete");const{_t}=require("@web/core/l10n/translation");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));}
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',['@web/core/hotkeys/hotkey_service','@odoo/owl'],function(require){'use strict';let __exports={};const{getActiveHotkey}=require("@web/core/hotkeys/hotkey_service");const{useEffect,useRef}=require("@odoo/owl");__exports.useTagNavigation=useTagNavigation;function useTagNavigation(refName,deleteTag){const ref=useRef(refName);useEffect((autocomplete)=>{if(!autocomplete){return;}
autocomplete.addEventListener("keydown",onAutoCompleteKeydown);return()=>{autocomplete.removeEventListener("keydown",onAutoCompleteKeydown);};},()=>[ref.el?.querySelector(".o-autocomplete")]);function focusTag(index){const tags=ref.el.getElementsByClassName("o_tag");if(tags.length){if(index===undefined){tags[tags.length-1].focus();}else{tags[index].focus();}}}
function onAutoCompleteKeydown(ev){if(ev.isComposing){return;}
const hotkey=getActiveHotkey(ev);const input=ev.target.closest(".o-autocomplete--input");const autoCompleteMenuOpened=!!ref.el.querySelector(".o-autocomplete--dropdown-menu");switch(hotkey){case"arrowleft":{if(input.selectionStart||autoCompleteMenuOpened){return;}
focusTag();break;}
case"arrowright":{if(input.selectionStart!==input.value.length||autoCompleteMenuOpened){return;}
focusTag(0);break;}
case"backspace":{if(input.value){return;}
const tags=ref.el.getElementsByClassName("o_tag");if(tags.length){deleteTag(tags.length-1);}
break;}
default:return;}
ev.preventDefault();ev.stopPropagation();}
function onTagKeydown(ev){const hotkey=getActiveHotkey(ev);const tags=[...ref.el.getElementsByClassName("o_tag")];const closestTag=ev.target.closest(".o_tag");const tagIndex=tags.indexOf(closestTag);const input=ref.el.querySelector(".o-autocomplete--input");switch(hotkey){case"arrowleft":{if(tagIndex===0){input.focus();}else{focusTag(tagIndex-1);}
break;}
case"arrowright":{if(tagIndex===tags.length-1){input.focus();}else{focusTag(tagIndex+1);}
break;}
case"backspace":{input.focus();deleteTag(tagIndex);break;}
default:return;}
ev.preventDefault();ev.stopPropagation();}
return onTagKeydown;}
return __exports;});;

/* /web/static/src/core/registry.js */
odoo.define('@web/core/registry',['@odoo/owl'],function(require){'use strict';let __exports={};const{EventBus}=require("@odoo/owl");const KeyNotFoundError=__exports.KeyNotFoundError=class KeyNotFoundError extends Error{}
const DuplicatedKeyError=__exports.DuplicatedKeyError=class DuplicatedKeyError extends Error{}
const Registry=__exports.Registry=class Registry extends EventBus{constructor(){super();this.content={};this.subRegistries={};this.elements=null;this.entries=null;this.addEventListener("UPDATE",()=>{this.elements=null;this.entries=null;});}
add(key,value,{force,sequence}={}){if(!force&&key in this.content){throw new DuplicatedKeyError(`Cannot add '${key}' in this 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} in this 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();}
return this.subRegistries[subcategory];}}
const registry=__exports.registry=new Registry();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/scroller_service.js */
odoo.define('@web/core/scroller_service',['@web/core/browser/browser','@web/core/registry','@web/core/utils/scrolling'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{scrollTo}=require("@web/core/utils/scrolling");const scrollerService=__exports.scrollerService={start(env){browser.addEventListener("click",(ev)=>{const link=ev.target.closest("a");if(!link){return;}
const disableAnchor=link.attributes.getNamedItem("disable_anchor");if(disableAnchor&&disableAnchor.value==="true"){return;}
const href=link.attributes.getNamedItem("href");if(href){if(href.value[0]==="#"){if(href.value.length===1){ev.preventDefault();return;}
let matchingEl=null;try{matchingEl=document.querySelector(`.o_content #${href.value.substr(1)}`);}catch{}
const triggerEv=new CustomEvent("anchor-link-clicked",{detail:{element:matchingEl,id:href.value,originalEv:ev,},});env.bus.trigger("SCROLLER:ANCHOR_LINK_CLICKED",triggerEv);if(matchingEl&&!triggerEv.defaultPrevented){ev.preventDefault();scrollTo(matchingEl,{isAnchor:true});}}}});},};registry.category("services").add("scroller",scrollerService);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/l10n/translation','@web/core/utils/timing','@web/core/utils/scrolling','@web/core/utils/search','@web/core/tags_list/tags_list','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,useState,useRef,onWillUpdateProps,useEffect}=require("@odoo/owl");const{Dropdown}=require("@web/core/dropdown/dropdown");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{_t}=require("@web/core/l10n/translation");const{useDebounced}=require("@web/core/utils/timing");const{scrollTo}=require("@web/core/utils/scrolling");const{fuzzyLookup}=require("@web/core/utils/search");const{TagsList}=require("@web/core/tags_list/tags_list");const{useAutofocus}=require("@web/core/utils/hooks");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,class:"",togglerClass:"",multiSelect:false,onSelect:()=>{},required:false,searchable:true,autoSort:true,searchPlaceholder:_t("Search..."),choices:[],groups:[],};static props={choices:{optional:true,type:Array,element:{type:Object,shape:{value:true,label:{type:String},},},},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},},},},},},},class:{type:String,optional:true},togglerClass:{type:String,optional:true},required:{type:Boolean,optional:true},searchable:{type:Boolean,optional:true},autoSort:{type:Boolean,optional:true},searchPlaceholder:{type:String,optional:true},value:{optional:true},multiSelect:{type:Boolean,optional:true},onInput:{type:Function,optional:true},onSelect:{type:Function,optional:true},slots:{type:Object,optional:true},};static SCROLL_SETTINGS={defaultCount:500,increaseAmount:300,distanceBeforeReload:500,};setup(){this.state=useState({choices:[],displayedOptions:[],searchValue:"",});this.inputRef=useRef("inputRef");this.debouncedOnInput=useDebounced(()=>this.onInput(this.inputRef.el?this.inputRef.el.value.trim():""),250);this.isOpen=false;this.selectedChoice=this.getSelectedChoice(this.props);onWillUpdateProps((nextProps)=>{if(this.props.value!==nextProps.value){this.selectedChoice=this.getSelectedChoice(nextProps);}});useEffect(()=>{if(this.isOpen){const groups=[{choices:this.props.choices},...this.props.groups];this.filterOptions(this.state.searchValue,groups);}},()=>[this.props.choices,this.props.groups]);useAutofocus({refName:"inputRef"});}
get displayValue(){return this.selectedChoice?this.selectedChoice.label:"";}
get canDeselect(){return!this.props.required&&this.selectedChoice!==undefined;}
get multiSelectChoices(){const choices=[...this.props.choices,...this.props.groups.flatMap((g)=>g.choices),].filter((c)=>this.props.value.includes(c.value));return choices.map((c)=>{return{id:c.value,text:c.label,onDelete:()=>{const values=[...this.props.value];values.splice(values.indexOf(c.value),1);this.props.onSelect(values);},};});}
async onBeforeOpen(){if(this.state.searchValue.length){this.state.searchValue="";if(this.props.onInput){await this.executeOnInput("");}}
this.filterOptions();}
onStateChanged({open}){this.isOpen=open;if(open){const selectedElement=document.querySelector(".o_select_active");if(selectedElement){scrollTo(selectedElement);}}}
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 mb-1 o_select_active bg-primary fw-bolder fst-italic";}else{return"o_select_menu_item mb-1";}}
async executeOnInput(searchString){await this.props.onInput(searchString);}
onInput(searchString){this.filterOptions(searchString);this.state.searchValue=searchString;const inputEl=this.inputRef.el;if(inputEl&&inputEl.parentNode){inputEl.parentNode.scrollTo(0,0);}
if(this.props.onInput){this.executeOnInput(searchString);}}
onSearchKeydown(ev){if(ev.key==="ArrowDown"||ev.key==="Enter"){const target=ev.target.parentElement.querySelector(".o_select_menu_item");ev.target.classList.remove("focus");target?.classList.add("focus");target?.focus();ev.preventDefault();}
if(ev.key==="Enter"&&this.state.choices.length===1){ev.target.parentElement.querySelector(".o_select_menu_item").click();}}
getSelectedChoice(props){const choices=[...props.choices,...props.groups.flatMap((g)=>g.choices)];return choices.find((c)=>c.value===props.value);}
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);}}
filterOptions(searchString="",groups){const groupsList=groups||[{choices:this.props.choices},...this.props.groups];this.state.choices=[];for(const group of groupsList){let filteredOptions=[];if(searchString){filteredOptions=fuzzyLookup(searchString,group.choices,(choice)=>choice.label);}else{filteredOptions=group.choices;if(this.props.autoSort){filteredOptions.sort((optionA,optionB)=>optionA.label.localeCompare(optionB.label));}}
if(filteredOptions.length===0){continue;}
if(group.label){this.state.choices.push({...group,isGroup:true});}
this.state.choices.push(...filteredOptions);}
this.sliceDisplayedOptions();}
getGroupsIndex(choices){if(choices.length===0){return[];}
return choices.flatMap((choice,index)=>(index===0?0:choice.isGroup?index:[]));}
onScroll(event){const el=event.target;const hasReachMax=this.state.displayedOptions.length>=this.state.choices.length;const remainingDistance=el.scrollHeight-el.scrollTop;const distanceToReload=el.clientHeight+this.constructor.SCROLL_SETTINGS.distanceBeforeReload;if(!hasReachMax&&remainingDistance<distanceToReload){const displayCount=this.state.displayedOptions.length+
this.constructor.SCROLL_SETTINGS.increaseAmount;this.state.displayedOptions=this.state.choices.slice(0,displayCount);}}
sliceDisplayedOptions(){const selectedIndex=this.getSelectedOptionIndex();const defaultCount=this.constructor.SCROLL_SETTINGS.defaultCount;if(selectedIndex===-1){this.state.displayedOptions=this.state.choices.slice(0,defaultCount);}else{const endIndex=Math.max(selectedIndex+this.constructor.SCROLL_SETTINGS.increaseAmount,defaultCount);this.state.displayedOptions=this.state.choices.slice(0,endIndex);}}
getSelectedOptionIndex(){let selectedIndex=-1;for(let i=0;i<this.state.choices.length;i++){if(this.isOptionSelected(this.state.choices[i])){selectedIndex=i;}}
return selectedIndex;}}
return __exports;});;

/* /web/static/src/core/signature/name_and_signature.js */
odoo.define('@web/core/signature/name_and_signature',['@web/core/assets','@web/core/browser/feature_detection','@web/core/dropdown/dropdown','@web/core/dropdown/dropdown_item','@web/core/utils/hooks','@web/core/utils/objects','@web/core/utils/render','@web/core/utils/urls','@odoo/owl'],function(require){'use strict';let __exports={};const{loadJS}=require("@web/core/assets");const{isMobileOS}=require("@web/core/browser/feature_detection");const{Dropdown}=require("@web/core/dropdown/dropdown");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{useService,useAutofocus}=require("@web/core/utils/hooks");const{pick}=require("@web/core/utils/objects");const{renderToString}=require("@web/core/utils/render");const{getDataURLFromFile}=require("@web/core/utils/urls");const{Component,useState,onWillStart,useRef,useEffect}=require("@odoo/owl");let htmlId=0;const NameAndSignature=__exports.NameAndSignature=class NameAndSignature extends Component{setup(){this.rpc=useService("rpc");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 this.rpc(`/web/sign/get_fonts/${this.props.defaultFont}`);});onWillStart(async()=>{await loadJS("/web/static/lib/jSignature/jSignatureCustom.js");await loadJS("/web/static/src/libs/jSignatureCustom.js");});this.signatureRef=useRef("signature");useEffect((el)=>{if(el){this.$signatureField=$(".o_web_sign_signature");this.$signatureField.on("change",()=>{this.props.signature.isSignatureEmpty=this.isSignatureEmpty;this.props.onSignatureChange(this.state.signMode);});this.jSignature();this.resetSignature();this.props.signature.getSignatureImage=()=>this.jSignature("getData","image");this.props.signature.resetSignature=()=>this.resetSignature();if(this.state.signMode==="auto"){this.drawCurrentName();}}},()=>[this.signatureRef.el]);}
drawCurrentName(){const font=this.fonts[this.currentFont];const text=this.getCleanedName();const canvas=this.signatureRef.el.querySelector("canvas");const img=this.getSVGText(font,text,canvas.width,canvas.height);this.printImage(img);}
focusName(){if(!isMobileOS()&&this.signNameInputRef.el){this.signNameInputRef.el.focus();}}
getCleanedName(){const text=this.props.signature.name;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);}
jSignature(){return this.$signatureField.jSignature(...arguments);}
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.jSignature("reset");this.state.loadIsInvalid=true;return false;}
this.state.loadIsInvalid=false;const result=await getDataURLFromFile(file);this.printImage(result);}
onClickSignAutoSelectStyle(){this.state.showFontList=true;}
onClickSignDrawClear(){this.jSignature("reset");}
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();}
printImage(imgSrc){const image=new Image();image.onload=()=>{clearTimeout(this.drawTimeout);this.drawTimeout=setTimeout(()=>{let width=0;let height=0;const ratio=image.width/image.height;const signatureEl=this.signatureRef.el;if(!signatureEl){return;}
const canvas=signatureEl.querySelector("canvas");const context=canvas.getContext("2d");if(image.width/canvas.width>image.height/canvas.height){width=canvas.width;height=parseInt(width/ratio);}else{height=canvas.height;width=parseInt(height*ratio);}
this.jSignature("reset");const ignoredContext=pick(context,"shadowOffsetX","shadowOffsetY");Object.assign(context,{shadowOffsetX:0,shadowOffsetY:0});context.drawImage(image,0,0,image.width,image.height,(canvas.width-width)/2,(canvas.height-height)/2,width,height);Object.assign(context,ignoredContext);this.props.signature.isSignatureEmpty=this.isSignatureEmpty;this.props.onSignatureChange(this.state.signMode);return this.isSignatureEmpty;},0);};image.src=imgSrc;}
resetSignature(){const{width,height}=this.resizeSignature();this.$signatureField.empty().jSignature({"decor-color":"#D1D0CE","background-color":"rgba(255,255,255,0)","show-stroke":false,color:this.props.fontColor,lineWidth:2,width:width,height:height,});this.emptySignature=this.jSignature("getData");this.setMode(this.state.signMode,true);this.focusName();}
resizeSignature(){this.signatureRef.el.style.width="unset";const width=this.signatureRef.el.clientWidth;const height=parseInt(width/this.props.displaySignatureRatio);this.state.signature={width,height,};Object.assign(this.signatureRef.el.querySelector("canvas").style,{width,height});return{width,height};}
async setMode(mode,reset){if(reset!==true&&mode===this.signMode){return;}
this.state.signMode=mode;this.jSignature(this.state.signMode==="draw"?"enable":"disable");this.jSignature("reset");if(this.state.signMode==="auto"){this.drawCurrentName();}}
get isSignatureEmpty(){const signature=this.jSignature("getData");return signature&&this.emptySignature?this.emptySignature===signature:true;}
get loadIsInvalid(){return this.state.signMode==="load"&&this.state.loadIsInvalid;}
get signatureStyle(){const{signature}=this.state;return signature?`width: ${signature.width}px; height: ${signature.height}px`:"";}}
NameAndSignature.template="web.NameAndSignature";NameAndSignature.components={Dropdown,DropdownItem};NameAndSignature.props={signature:{type:Object},defaultFont:{type:String,optional:true},displaySignatureRatio:{type:Number,optional:true},fontColor:{type:String,optional:true},signatureType:{type:String,optional:true},noInputName:{type:Boolean,optional:true},mode:{type:String,optional:true},onSignatureChange:{type:Function,optional:true},};NameAndSignature.defaultProps={defaultFont:"",displaySignatureRatio:3.0,fontColor:"DarkBlue",signatureType:"signature",noInputName:false,onSignatureChange:()=>{},};return __exports;});;

/* /web/static/src/core/signature/signature_dialog.js */
odoo.define('@web/core/signature/signature_dialog',['@web/core/l10n/translation','@web/core/dialog/dialog','@web/core/signature/name_and_signature','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");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{setup(){this.title=_t("Adopt Your Signature");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,};}}
SignatureDialog.template="web.SignatureDialog";SignatureDialog.components={Dialog,NameAndSignature};SignatureDialog.defaultProps={defaultName:"",};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},itemsVisible:{type:Number,optional:true},tags:{type:Object},};get visibleTagsCount(){return this.props.itemsVisible-1;}
get visibleTags(){if(this.props.itemsVisible&&this.props.tags.length>this.props.itemsVisible){return this.props.tags.slice(0,this.visibleTagsCount);}
return this.props.tags;}
get otherTags(){if(!this.props.itemsVisible||this.props.tags.length<=this.props.itemsVisible){return[];}
return this.props.tags.slice(this.visibleTagsCount);}
get tooltipInfo(){return JSON.stringify({tags:this.otherTags.map((tag)=>({text:tag.text,id:tag.id,})),});}}
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{}
Tooltip.template="web.Tooltip";Tooltip.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=400;const CLOSE_DELAY=200;const tooltipService=__exports.tooltipService={dependencies:["popover"],start(env,{popover}){let openTooltipTimeout;let closeTooltip;let target=null;let touchPressed;let mouseEntered;const elementsWithTooltips=new Map();function cleanup(){browser.clearTimeout(openTooltipTimeout);if(closeTooltip){closeTooltip();}}
function shouldCleanup(){if(!target){return false;}
if(!document.body.contains(target)){return true;}
if(hasTouch()&&!mouseEntered){return!touchPressed;}
return false;}
function openTooltip(el,{tooltip="",template,info,position,delay=OPEN_DELAY}){target=el;cleanup();if(!tooltip&&!template){return;}
openTooltipTimeout=browser.setTimeout(()=>{if(target.isConnected){closeTooltip=popover.add(target,Tooltip,{tooltip,template,info},{position});target.title="";}},delay);}
function openElementsTooltip(el){if(el.nodeType===Node.TEXT_NODE){return;}
if(elementsWithTooltips.has(el)){openTooltip(el,elementsWithTooltips.get(el));}else if(el.matches("[data-tooltip], [data-tooltip-template]")){const dataset=el.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(el,params);}}
function onMouseenter(ev){mouseEntered=true;openElementsTooltip(ev.target);}
function onMouseleave(ev){if(target===ev.target){mouseEntered=false;cleanup();}}
function onTouchStart(ev){touchPressed=true;openElementsTooltip(ev.target);}
whenReady(()=>{browser.setInterval(()=>{if(shouldCleanup()){cleanup();}},CLOSE_DELAY);if(hasTouch()){document.body.addEventListener("touchstart",onTouchStart);document.body.addEventListener("touchend",(ev)=>{if(ev.target.matches("[data-tooltip], [data-tooltip-template]")){if(!ev.target.dataset.tooltipTouchTapToShow){touchPressed=false;}}});document.body.addEventListener("touchcancel",(ev)=>{if(ev.target.matches("[data-tooltip], [data-tooltip-template]")){if(!ev.target.dataset.tooltipTouchTapToShow){touchPressed=false;}}});}
document.body.addEventListener("mouseenter",onMouseenter,{capture:true});document.body.addEventListener("mouseleave",onMouseleave,{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,useState,useEffect,xml,onWillUpdateProps,useComponent}=require("@odoo/owl");const config=__exports.config={disabled:false,};__exports.useTransition=useTransition;function useTransition({name,initialVisibility=true,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){state.stage="enter";state.shouldMount=true;component.render();onNextPatch=()=>{state.stage="enter-active";};}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{setup(){const{visible,leaveDuration,name,onLeave}=this.props;this.transition=useTransition({initialVisibility:visible,leaveDuration,name,onLeave,});onWillUpdateProps(({visible=true})=>{this.transition.shouldMount=visible;});}}
Transition.template=xml`<t t-slot="default" t-if="transition.shouldMount" className="transition.className"/>`;Transition.props={name:String,visible:{type:Boolean,optional:true},leaveDuration:{type:Number,optional:true},onLeave:{type:Function,optional:true},slots:Object,};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 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={...TERM_OPERATORS_NEGATION,is:"is not","is not":"is","==":"!=","!=":"==",};const EXCHANGE={"<":">","<=":">=",">":"<",">=":"<=","=":"=","!=":"!=",};const COMPARATORS=["<","<=",">",">=","in","not in","==","is","!=","is not"];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.condition=condition;function condition(path,operator,value,negate=false){return{type:"condition",path,operator,value,negate};}
__exports.complexCondition=complexCondition;function complexCondition(value){parseExpr(value);return{type:"complex_condition",value};}
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;}
__exports.formatValue=formatValue;function formatValue(value){return formatAST(toAST(value));}
__exports.normalizeValue=normalizeValue;function normalizeValue(value){return toValue(toAST(value));}
__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);}}
function toAST(value){if(value instanceof Expression){return value.toAST();}
if(Array.isArray(value)){return{type:4,value:value.map(toAST)};}
return toPyValue(value);}
function addChild(parent,child){if(child.type==="connector"&&!child.negate&&child.value===parent.value){parent.children.push(...child.children);}else{parent.children.push(child);}}
function getNormalizedCondition(condition){let{operator,negate}=condition;if(negate&&typeof operator==="string"&&TERM_OPERATORS_NEGATION[operator]){operator=TERM_OPERATORS_NEGATION[operator];negate=false;}
return{...condition,operator,negate};}
function normalizeCondition(condition){Object.assign(condition,getNormalizedCondition(condition));}
function _construcTree(ASTs,distributeNot,negate=false){const[firstAST,...tailASTs]=ASTs;if(firstAST.type===1&&firstAST.value==="!"){return _construcTree(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);normalizeCondition(tree);}
let remaimingASTs=tailASTs;if(tree.type==="connector"){for(let i=0;i<2;i++){const{tree:child,remaimingASTs:otherASTs}=_construcTree(remaimingASTs,distributeNot,distributeNot&&negate);remaimingASTs=otherASTs;addChild(tree,child);}}
return{tree,remaimingASTs};}
function construcTree(initialASTs,options){if(!initialASTs.length){return connector("&");}
const{tree}=_construcTree(initialASTs,options.distributeNot);return tree;}
function getASTs(tree){const ASTs=[];if(tree.type==="condition"){if(tree.negate){ASTs.push(toAST("!"));}
ASTs.push({type:10,value:[tree.path,tree.operator,tree.value].map(toAST),});return ASTs;}
const length=tree.children.length;if(length&&tree.negate){ASTs.push(toAST("!"));}
for(let i=0;i<length-1;i++){ASTs.push(toAST(tree.value));}
for(const child of tree.children){ASTs.push(...getASTs(child));}
return ASTs;}
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};}
function bool(ast){if(isBool(ast)||isNot(ast)||ast.type===2){return ast;}
return{type:8,fn:{type:5,value:"bool"},args:[ast],kwargs:{}};}
function name(value){return{type:5,value};}
function or(left,right){return{type:14,op:"or",left,right};}
function and(left,right){return{type:14,op:"and",left,right};}
function isNot(ast){return ast.type===6&&ast.op==="not";}
function is(oneParamFunc,ast){return(ast.type===8&&ast.fn.type===5&&ast.fn.value===oneParamFunc&&ast.args.length===1);}
function isSet(ast){return ast.type===8&&ast.fn.type===5&&ast.fn.value==="set"&&ast.args.length<=1;}
function isBool(ast){return is("bool",ast);}
function isValidPath(ast,options){const getFieldDef=options.getFieldDef||(()=>null);if(ast.type===5){return getFieldDef(ast.value)!==null;}
return false;}
function isX2Many(ast,options){if(isValidPath(ast,options)){const fieldDef=options.getFieldDef(ast.value);return["many2many","one2many"].includes(fieldDef.type);}
return false;}
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 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 _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);}
function _expressionFromTree(tree,options,isRoot=false){if(tree.type==="connector"&&tree.value==="|"&&tree.children.length===2){const isSimpleAnd=(tree)=>tree.type==="connector"&&tree.value==="&"&&tree.children.length===2;if(tree.children.every((c)=>isSimpleAnd(c))){const[c1,c2]=tree.children;for(let i=0;i<2;i++){const c1Child=c1.children[i];const str1=_expressionFromTree({...c1Child},options);for(let j=0;j<2;j++){const c2Child=c2.children[j];const str2=_expressionFromTree(c2Child,options);if(str1===`not ${str2}`||`not ${str1}`===str2){const others=[c1.children[1-i],c2.children[1-j]];const str=_expressionFromTree(c1Child,options);const strs=others.map((c)=>_expressionFromTree(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)=>_expressionFromTree(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;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=toAST(path);if(typeof path=="string"&&isValidPath(name(path),options)){pathAST.type=5;}
if(value===false&&["=","!="].includes(operator)){return formatAST(operator==="="?not(pathAST):pathAST);}
let valueAST=toAST(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,});}
function createBetweenOperators(tree){if(["condition","complex_condition"].includes(tree.type)){return tree;}
const processedChildren=tree.children.map(createBetweenOperators);if(tree.value==="|"){return{...tree,children:processedChildren};}
const children=[];for(let i=0;i<processedChildren.length;i++){const child1=processedChildren[i];const child2=processedChildren[i+1];if(child1.type==="condition"&&child2&&child2.type==="condition"&&formatValue(child1.path)===formatValue(child2.path)&&child1.operator===">="&&child2.operator==="<="){children.push(condition(child1.path,"between",normalizeValue([child1.value,child2.value])));i+=1;}else{children.push(child1);}}
if(children.length===1){return{...children[0]};}
return{...tree,children};}
__exports.removeBetweenOperators=removeBetweenOperators;function removeBetweenOperators(tree){if(tree.type==="complex_condition"){return tree;}
if(tree.type==="condition"){if(tree.operator!=="between"){return tree;}
const{negate,path,value}=tree;return connector("&",[condition(path,">=",value[0]),condition(path,"<=",value[1])],negate);}
const processedChildren=tree.children.map(removeBetweenOperators);if(tree.value==="|"){return{...tree,children:processedChildren};}
const newTree={...tree,children:[]};for(let i=0;i<processedChildren.length;i++){addChild(newTree,processedChildren[i]);}
return newTree;}
__exports.createVirtualOperators=createVirtualOperators;function createVirtualOperators(tree,options={}){if(tree.type==="condition"){const{path,operator,value}=tree;if(["=","!="].includes(operator)){const fieldDef=options.getFieldDef?.(path)||null;if(fieldDef){if(fieldDef.type==="boolean"){return{...tree,operator:operator==="="?"is":"is_not"};}else if(!["many2one","date","datetime"].includes(fieldDef?.type)&&value===false){return{...tree,operator:operator==="="?"not_set":"set"};}}}
return tree;}
if(tree.type==="complex_condition"){return tree;}
const processedChildren=tree.children.map((c)=>createVirtualOperators(c,options));return{...tree,children:processedChildren};}
__exports.removeVirtualOperators=removeVirtualOperators;function removeVirtualOperators(tree){if(tree.type==="condition"){const{operator}=tree;if(["is","is_not"].includes(operator)){return{...tree,operator:operator==="is"?"=":"!="};}
if(["set","not_set"].includes(operator)){return{...tree,operator:operator==="set"?"!=":"="};}
return tree;}
if(tree.type==="complex_condition"){return tree;}
const processedChildren=tree.children.map((c)=>removeVirtualOperators(c));return{...tree,children:processedChildren};}
function createComplexConditions(tree){if(tree.type==="condition"){if(tree.path instanceof Expression&&tree.operator==="="&&tree.value===1){return complexCondition(String(tree.path));}
return cloneTree(tree);}
if(tree.type==="complex_condition"){return cloneTree(tree);}
return{...tree,children:tree.children.map((child)=>createComplexConditions(child)),};}
function removeComplexConditions(tree){if(tree.type==="condition"){return cloneTree(tree);}
if(tree.type==="complex_condition"){const ast=parseExpr(tree.value);return condition(new Expression(bool(ast)),"=",1);}
return{...tree,children:tree.children.map((child)=>removeComplexConditions(child)),};}
__exports.treeFromExpression=treeFromExpression;function treeFromExpression(expression,options={}){const ast=parseExpr(expression);const tree=_treeFromAST(ast,options);return createVirtualOperators(createBetweenOperators(tree),options);}
__exports.expressionFromTree=expressionFromTree;function expressionFromTree(tree,options={}){const simplifiedTree=createComplexConditions(removeBetweenOperators(removeVirtualOperators(tree)));return _expressionFromTree(simplifiedTree,options,true);}
__exports.domainFromTree=domainFromTree;function domainFromTree(tree){const simplifiedTree=removeBetweenOperators(removeVirtualOperators(removeComplexConditions(tree)));const domainAST={type:4,value:getASTs(simplifiedTree),};return formatAST(domainAST);}
__exports.treeFromDomain=treeFromDomain;function treeFromDomain(domain,options={}){domain=new Domain(domain);const domainAST=domain.ast;const tree=construcTree(domainAST.value,options);return createVirtualOperators(createBetweenOperators(tree),options);}
__exports.expressionFromDomain=expressionFromDomain;function expressionFromDomain(domain,options={}){const tree=treeFromDomain(domain,options);return expressionFromTree(tree,options);}
__exports.domainFromExpression=domainFromExpression;function domainFromExpression(expression,options={}){const tree=treeFromExpression(expression,options);return domainFromTree(tree);}
return __exports;});;

/* /web/static/src/core/tree_editor/tree_editor.js */
odoo.define('@web/core/tree_editor/tree_editor',['@web/core/tree_editor/utils','@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/model_field_selector/model_field_selector','@web/core/model_field_selector/utils','@web/core/utils/objects'],function(require){'use strict';let __exports={};const{leafToString,useLoadDisplayNames,extractIdsFromTree,getPathsInTree,getResModel,}=require("@web/core/tree_editor/utils");const{Component,onWillStart,onWillUpdateProps}=require("@odoo/owl");const{Dropdown}=require("@web/core/dropdown/dropdown");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{condition,cloneTree,formatValue,removeVirtualOperators,connector,}=require("@web/core/tree_editor/condition_tree");const{getDefaultValue,getValueEditorInfo,}=require("@web/core/tree_editor/tree_editor_value_editors");const{ModelFieldSelector}=require("@web/core/model_field_selector/model_field_selector");const{useLoadFieldInfo}=require("@web/core/model_field_selector/utils");const{deepEqual,shallowEqual}=require("@web/core/utils/objects");const TRUE_TREE=condition(1,"=",1);const DEFAULT_CONDITION=condition("id","=",1);function collectDifferences(tree,otherTree){if(tree.type!==otherTree.type){return[{type:"other"}];}
if(tree.negate!==otherTree.negate){return[{type:"other"}];}
if(tree.type==="condition"){if(formatValue(tree.path)!==formatValue(otherTree.path)){return[{type:"other"}];}
if(formatValue(tree.value)!==formatValue(otherTree.value)){return[{type:"other"}];}
if(formatValue(tree.operator)!==formatValue(otherTree.operator)){if(tree.operator==="!="&&otherTree.operator==="set"){return[{type:"replacement",tree,operator:"set"}];}else if(tree.operator==="="&&otherTree.operator==="not_set"){return[{type:"replacement",tree,operator:"not_set"}];}else{return[{type:"other"}];}}
return[];}
if(tree.value!==otherTree.value){return[{type:"other"}];}
if(tree.type==="complex_condition"){return[];}
if(tree.children.length!==otherTree.children.length){return[{type:"other"}];}
const diffs=[];for(let i=0;i<tree.children.length;i++){const child=tree.children[i];const otherChild=otherTree.children[i];const childDiffs=collectDifferences(child,otherChild);if(childDiffs.some((d)=>d.type!=="replacement")){return[{type:"other"}];}
diffs.push(...childDiffs);}
return diffs;}
function restoreVirtualOperators(tree,otherTree){const diffs=collectDifferences(tree,otherTree);if(diffs.some((d)=>d.type!=="replacement")){return;}
for(const{tree,operator}of diffs){tree.operator=operator;}}
const TreeEditor=__exports.TreeEditor=class TreeEditor extends Component{static template="web.TreeEditor";static components={Dropdown,DropdownItem,ModelFieldSelector,};static props={tree:Object,resModel:String,update: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},defaultCondition:{type:Object,optional:true},};static defaultProps={defaultConnector:"&",defaultCondition:DEFAULT_CONDITION,readonly:false,};setup(){this.loadFieldInfo=useLoadFieldInfo();this.loadDisplayNames=useLoadDisplayNames();onWillStart(()=>this.onPropsUpdated(this.props));onWillUpdateProps((nextProps)=>this.onPropsUpdated(nextProps));}
async onPropsUpdated(props){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){restoreVirtualOperators(this.tree,this.previousTree);this.previousTree=null;}
const paths=getPathsInTree(this.tree);await this.loadFieldDefs(props.resModel,paths);if(props.readonly){const idsByModel=extractIdsFromTree(this.tree,this.getFieldDef.bind(this));this.displayNames=await this.loadDisplayNames(idsByModel);}}
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;}
getFieldDef(path){if(typeof path==="string"){return this.fieldDefs[path];}
return null;}
async loadFieldDefs(resModel,paths){const promises=[];const fieldDefs={};for(const path of paths){if(typeof path==="string"){promises.push(this.loadFieldInfo(resModel,path).then(({fieldDef})=>{fieldDefs[path]=fieldDef;}));}}
await Promise.all(promises);this.fieldDefs=fieldDefs;}
notifyChanges(){this.previousTree=cloneTree(this.tree);this.props.update(this.tree);}
updateConnector(node,value){node.value=value;node.negate=false;this.notifyChanges();}
updateComplexCondition(node,value){node.value=value;this.notifyChanges();}
createNewLeaf(){return cloneTree(this.props.defaultCondition);}
createNewBranch(value){return connector(value,[this.createNewLeaf(),this.createNewLeaf()]);}
insertRootLeaf(parent){parent.children.push(this.createNewLeaf());this.notifyChanges();}
insertLeaf(parent,node){const newNode=node.type!=="connector"?cloneTree(node):this.createNewLeaf();const index=parent.children.indexOf(node);parent.children.splice(index+1,0,newNode);this.notifyChanges();}
insertBranch(parent,node){const nextConnector=parent.value==="&"?"|":"&";const newNode=this.createNewBranch(nextConnector);const index=parent.children.indexOf(node);parent.children.splice(index+1,0,newNode);this.notifyChanges();}
delete(parent,node){const index=parent.children.indexOf(node);parent.children.splice(index,1);this.notifyChanges();}
getDescription(node){const fieldDef=this.getFieldDef(node.path);return leafToString(node,fieldDef,this.displayNames[getResModel(fieldDef)]);}
getValueEditorInfo(node){const fieldDef=this.getFieldDef(node.path);return getValueEditorInfo(fieldDef,node.operator);}
async updatePath(node,path){const{fieldDef}=await this.loadFieldInfo(this.props.resModel,path);node.path=path;node.negate=false;node.operator=this.props.getDefaultOperator(fieldDef);node.value=getDefaultValue(fieldDef,node.operator);this.notifyChanges();}
updateLeafOperator(node,operator,negate){const previousNode=cloneTree(node);const fieldDef=this.getFieldDef(node.path);node.negate=negate;node.operator=operator;node.value=getDefaultValue(fieldDef,operator,node.value);if(deepEqual(removeVirtualOperators(node),removeVirtualOperators(previousNode))){this.render();}
this.notifyChanges();}
updateLeafValue(node,value){node.value=value;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/record_selectors/multi_record_selector','@web/core/l10n/translation','@web/core/py_js/py_utils','@web/core/tree_editor/condition_tree','@web/core/record_selectors/record_selector'],function(require){'use strict';let __exports={};const{MultiRecordSelector}=require("@web/core/record_selectors/multi_record_selector");const{_t}=require("@web/core/l10n/translation");const{formatAST,toPyValue}=require("@web/core/py_js/py_utils");const{Expression}=require("@web/core/tree_editor/condition_tree");const{RecordSelector}=require("@web/core/record_selectors/record_selector");const isId=__exports.isId=(val)=>Number.isInteger(val)&&val>=1;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),]);},};});}}
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'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{TagsList}=require("@web/core/tags_list/tags_list");const Input=__exports.Input=class Input extends Component{static props=["value","update","startEmpty?"];static template="web.TreeEditor.Input";}
const Select=__exports.Select=class Select extends Component{static props=["value","update","options","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 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/tree_editor/condition_tree','@web/core/utils/strings','@web/core/py_js/py','@web/core/tree_editor/tree_editor_components'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{formatValue,TERM_OPERATORS_NEGATION,toValue,}=require("@web/core/tree_editor/condition_tree");const{sprintf}=require("@web/core/utils/strings");const{parseExpr}=require("@web/core/py_js/py");const{Select}=require("@web/core/tree_editor/tree_editor_components");const OPERATOR_DESCRIPTIONS={"=":"=","!=":"!=","<=":"<=","<":"<",">":">",">=":">=","=?":"=?","=like":_t("=like"),"=ilike":_t("=ilike"),like:_t("like"),"not like":_t("not like"),ilike:_t("contains"),"not ilike":_t("does not contain"),in:_t("is in"),"not in":_t("is not in"),child_of:_t("child of"),parent_of:_t("parent of"),is:_t("is"),is_not:_t("is not"),set:_t("is set"),not_set:_t("is not set"),between:_t("is between"),};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];}
__exports.getOperatorLabel=getOperatorLabel;function getOperatorLabel(operator,negate=false){let label;if(typeof operator==="string"&&operator in OPERATOR_DESCRIPTIONS){if(negate&&operator in TERM_OPERATORS_NEGATION){return OPERATOR_DESCRIPTIONS[TERM_OPERATORS_NEGATION[operator]];}
label=OPERATOR_DESCRIPTIONS[operator];}else{label=formatValue(operator);}
if(negate){return sprintf(`not %s`,label);}
return label;}
function getOperatorInfo(operator,negate=false){const key=toKey(operator,negate);const label=getOperatorLabel(operator,negate);return[key,label];}
__exports.getOperatorEditorInfo=getOperatorEditorInfo;function getOperatorEditorInfo(operators){const defaultOperator=operators[0];const operatorsInfo=operators.map((operator)=>getOperatorInfo(operator));return{component:Select,extractProps:({update,value:[operator,negate]})=>{const[operatorKey,operatorLabel]=getOperatorInfo(operator,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,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/l10n/dates','@web/core/l10n/translation','@web/core/registry','@web/core/datetime/datetime_input','@web/core/tree_editor/tree_editor_autocomplete','@web/core/utils/arrays','@web/core/tree_editor/tree_editor_components','@web/core/tree_editor/condition_tree','@web/core/tree_editor/utils'],function(require){'use strict';let __exports={};const{deserializeDate,deserializeDateTime,serializeDate,serializeDateTime,}=require("@web/core/l10n/dates");const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{DateTimeInput}=require("@web/core/datetime/datetime_input");const{DomainSelectorAutocomplete,DomainSelectorSingleAutocomplete,}=require("@web/core/tree_editor/tree_editor_autocomplete");const{unique}=require("@web/core/utils/arrays");const{Input,Select,List,Range}=require("@web/core/tree_editor/tree_editor_components");const{formatValue}=require("@web/core/tree_editor/condition_tree");const{getResModel,disambiguate,isId}=require("@web/core/tree_editor/utils");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);}
const STRING_EDITOR={component:Input,extractProps:({value,update})=>({value,update}),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})=>({value,update,options,addBlankOption:params.addBlankOption,}),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 makeAutoCompleteEditor(fieldDef){return{component:DomainSelectorAutocomplete,extractProps:({value,update})=>{return{resModel:getResModel(fieldDef),fieldString:fieldDef.string,update:(value)=>update(unique(value)),resIds:unique(value),};},isSupported:(value)=>Array.isArray(value),defaultValue:()=>[],};}
function getPartialValueEditorInfo(fieldDef,operator,params={}){switch(operator){case"set":case"not_set":return{component:null,extractProps:null,isSupported:(value)=>value===false,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,"=");return{component:Range,extractProps:({value,update})=>({value,update,editorInfo,}),isSupported:(value)=>Array.isArray(value)&&value.length===2,defaultValue:()=>{const{defaultValue}=editorInfo;return[defaultValue(),defaultValue()];},};}
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,"=",{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:()=>[],};}}}}
const{type}=fieldDef;switch(type){case"integer":case"float":case"monetary":{const formatType=type==="integer"?"integer":"float";return{component:Input,extractProps:({value,update})=>({value:String(value),update:(value)=>update(parseValue(formatType,value)),startEmpty:params.startEmpty,}),isSupported:()=>true,defaultValue:()=>1,shouldResetValue:(value)=>parseValue(formatType,value)===value,};}
case"date":case"datetime":return{component:DateTimeInput,extractProps:({value,update})=>({value:params.startEmpty||value===false?false:genericDeserializeDate(type,value),type,onApply:(value)=>{if(!params.startEmpty||value){update(genericSerializeDate(type,value||DateTime.local()));}},}),isSupported:(value)=>value===false||(typeof value==="string"&&isParsable(type,value)),defaultValue:()=>genericSerializeDate(type,DateTime.local()),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"boolean":{if(["is","is_not"].includes(operator)){const options=[[true,_t("set")],[false,_t("not set")],];return makeSelectEditor(options,params);}
const options=[[true,_t("True")],[false,_t("False")],];return makeSelectEditor(options,params);}
case"many2one":{if(["=","!=","parent_of","child_of"].includes(operator)){return{component:DomainSelectorSingleAutocomplete,extractProps:({value,update})=>{return{resModel:getResModel(fieldDef),fieldString:fieldDef.string,update,resId:value,};},isSupported:()=>true,defaultValue:()=>false,shouldResetValue:(value)=>value!==false&&!isId(value),};}
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();}
return value;}
return __exports;});;

/* /web/static/src/core/tree_editor/utils.js */
odoo.define('@web/core/tree_editor/utils',['@web/core/utils/arrays','@web/core/tree_editor/tree_editor_operator_editor','@web/core/tree_editor/condition_tree','@web/core/utils/hooks','@web/core/l10n/translation','@web/core/l10n/dates'],function(require){'use strict';let __exports={};const{unique,zip}=require("@web/core/utils/arrays");const{getOperatorLabel}=require("@web/core/tree_editor/tree_editor_operator_editor");const{Expression}=require("@web/core/tree_editor/condition_tree");const{useService}=require("@web/core/utils/hooks");const{_t}=require("@web/core/l10n/translation");const{deserializeDate,deserializeDateTime,formatDate,formatDateTime}=require("@web/core/l10n/dates");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;}
__exports.isId=isId;function isId(value){return Number.isInteger(value)&&value>=1;}
__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.leafToString=leafToString;function leafToString(tree,fieldDef,displayNames){const{operator,negate,value}=tree;const operatorLabel=getOperatorLabel(operator,negate);const description={operatorDescription:`${operatorLabel}`,valueDescription:null,};if(["set","not_set"].includes(operator)){return description;}
if(["is","is_not"].includes(operator)){description.valueDescription={values:[value?_t("set"):_t("not set")],join:"",addParenthesis:false,};return description;}
const dis=disambiguate(value,displayNames);const values=(Array.isArray(value)?value:[value]).map((val)=>formatValue(val,dis,fieldDef,displayNames));let join;let addParenthesis=Array.isArray(value);switch(operator){case"between":join=_t("and");addParenthesis=false;break;case"in":case"not in":join=",";break;default:join=_t("or");}
description.valueDescription={values,join,addParenthesis};return description;}
__exports.useLoadDisplayNames=useLoadDisplayNames;function useLoadDisplayNames(nameService){nameService||=useService("name");return async(resIdsByModel)=>{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)));};}
__exports.getResModel=getResModel;function getResModel(fieldDef){if(fieldDef){return fieldDef.is_property?fieldDef.comodel:fieldDef.relation;}
return null;}
__exports.extractIdsFromTree=extractIdsFromTree;function extractIdsFromTree(tree,getFieldDef){const idsByModel=_extractIdsRecursive(tree,getFieldDef,{});for(const resModel in idsByModel){idsByModel[resModel]=unique(idsByModel[resModel]);}
return idsByModel;}
function _extractIdsRecursive(tree,getFieldDef,idsByModel){if(tree.type==="condition"){const fieldDef=getFieldDef(tree.path);if(["many2one","many2many","one2many"].includes(fieldDef?.type)){const value=tree.value;const values=Array.isArray(value)?value:[value];const ids=values.filter((val)=>Number.isInteger(val)&&val>=1);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;}
__exports.getPathsInTree=getPathsInTree;function getPathsInTree(tree){const paths=[];if(tree.type==="condition"){paths.push(tree.path);}
if(tree.type==="connector"&&tree.children){for(const child of tree.children){paths.push(...getPathsInTree(child));}}
return paths;}
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/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{_t}=require("@web/core/l10n/translation");const{browser}=require("@web/core/browser/browser");const{EventBus,Component,useState,xml}=require("@odoo/owl");const BlockUI=__exports.BlockUI=class BlockUI extends Component{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.state=useState({blockUI:false,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){this.state.blockUI=true;if(ev.detail?.message){this.state.line1=ev.detail.message;}else{this.replaceMessage(0);}}
unblock(){this.state.blockUI=false;clearTimeout(this.msgTimer);this.state.line1="";this.state.line2="";}}
BlockUI.props={bus:EventBus,};BlockUI.template=xml`
    <div t-att-class="state.blockUI ? 'o_blockUI fixed-top d-flex justify-content-center align-items-center flex-column vh-100' : ''">
      <t t-if="state.blockUI">
        <div class="o_spinner mb-4">
            <img src="/web/static/img/spin.svg" alt="Loading..."/>
        </div>
        <div class="o_message text-center px-4">
            <t t-esc="state.line1"/> <br/>
            <t t-esc="state.line2"/>
        </div>
      </t>
    </div>`;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}=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,VSM:1,SM:2,MD:3,LG:4,XL:5,XXL:6};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);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){return;}
const oldActiveElement=document.activeElement;uiService.activateElement(el);el.addEventListener("keydown",trapFocus);if(!el.contains(document.activeElement)){firstTabableEl.focus();}
return()=>{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:474},{minWidth:475,maxWidth:575},{minWidth:576,maxWidth:767},{minWidth:768,maxWidth:991},{minWidth:992,maxWidth:1199},{minWidth:1200,maxWidth:1533},{minWidth:1534},];__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,});}}
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_service.js */
odoo.define('@web/core/user_service',['@web/core/registry','@web/session','@web/core/utils/cache'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{session}=require("@web/session");const{Cache}=require("@web/core/utils/cache");const userService=__exports.userService={dependencies:["rpc"],async:["hasGroup"],start(env,{rpc}){const groupCache=new Cache((group)=>{if(!context.uid){return Promise.resolve(false);}
return rpc("/web/dataset/call_kw/res.users/has_group",{model:"res.users",method:"has_group",args:[group],kwargs:{context},});});groupCache.cache["base.group_user"]=session.is_internal_user;groupCache.cache["base.group_system"]=session.is_system;const accessRightCache=new Cache((model,operation)=>{const url=`/web/dataset/call_kw/${model}/check_access_rights`;return rpc(url,{model,method:"check_access_rights",args:[operation,false],kwargs:{context},});});const context={...session.user_context,uid:session.uid||session.user_id,};let settings=session.user_settings;delete session.user_settings;return{get context(){return Object.assign({},context);},removeFromContext(key){delete context[key];},updateContext(update){Object.assign(context,update);},hasGroup(group){return groupCache.read(group);},async checkAccessRight(model,operation){return accessRightCache.read(model,operation);},get settings(){return settings;},async setUserSettings(key,value){const changedSettings=await env.services.orm.call("res.users.settings","set_res_users_settings",[[this.settings.id]],{new_settings:{[key]:value,},});Object.assign(settings,changedSettings);},name:session.name,userName:session.username,isAdmin:session.is_admin,isSystem:session.is_system,partnerId:session.partner_id,home_action_id:session.home_action_id,showEffect:session.show_effect,get userId(){return context.uid;},get lang(){return context.lang;},get tz(){return context.tz;},get db(){const res={name:session.db,};if("dbuuid"in session){res.uuid=session.dbuuid;}
return res;},};},};registry.category("services").add("user",userService);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(){const args=Array.prototype.slice.call(arguments);if(args.length===0){return[undefined];}
const firstArray=args[0].map(function(elem){return[elem];});if(args.length===1){return firstArray;}
const productOfOtherArrays=_cartesian.apply(null,args.slice(1));return firstArray.reduce(function(acc,elem){return acc.concat(productOfOtherArrays.map(function(tuple){return elem.concat(tuple);}));},[]);}
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 value&&typeof value==="object"&&value[Symbol.iterator]?[...value]:[value];}
__exports.intersection=intersection;function intersection(array1,array2){return array1.filter((v)=>array2.includes(v));}
__exports.groupBy=groupBy;function groupBy(array,criterion){const extract=_getExtractorFrom(criterion);const groups={};for(const element of array){const group=String(extract(element));if(!(group in groups)){groups[group]=[];}
groups[group].push(element);}
return groups;}
__exports.sortBy=sortBy;function sortBy(array,criterion,order="asc"){const extract=_getExtractorFrom(criterion);return array.slice().sort((elA,elB)=>{const a=extract(elA);const b=extract(elB);let result;if(isNaN(a)&&isNaN(b)){result=a>b?1:a<b?-1:0;}else{result=a-b;}
return order==="asc"?result:-result;});}
__exports.symmetricalDifference=symmetricalDifference;function symmetricalDifference(arrayA,arrayB){return arrayA.filter((id)=>!arrayB.includes(id)).concat(arrayB.filter((id)=>!arrayA.includes(id)));}
__exports.cartesian=cartesian;function cartesian(){const args=Array.prototype.slice.call(arguments);if(args.length===0){return[undefined];}else if(args.length===1){return args[0];}else{return _cartesian.apply(null,args);}}
const shallowEqual=__exports.shallowEqual=_shallowEqual;__exports.sections=sections;function sections(array){const sections=[];for(let i=0;i<array.length+1;i++){sections.push(array.slice(0,i));}
return sections;}
__exports.unique=unique;function unique(array){return Array.from(new Set(array));}
__exports.zip=zip;function zip(array1,array2,fill=false){const result=[];const getLength=fill?Math.max:Math.min;for(let i=0;i<getLength(array1.length,array2.length);i++){result.push([array1[i],array2[i]]);}
return result;}
__exports.zipWith=zipWith;function zipWith(array1,array2,func){return zip(array1,array2).map(([e1,e2])=>func(e1,e2));}
return __exports;});;

/* /web/static/src/core/utils/autoresize.js */
odoo.define('@web/core/utils/autoresize',['@odoo/owl','@web/core/browser/browser'],function(require){'use strict';let __exports={};const{useEffect}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");__exports.useAutoresize=useAutoresize;function useAutoresize(ref,options={}){let resize=null;useEffect((el)=>{if(el){resize=(el instanceof HTMLInputElement?resizeInput:resizeTextArea).bind(null,el,options);el.addEventListener("input",resize);return()=>{el.removeEventListener("input",resize);resize=null;};}},()=>[ref.el]);useEffect(()=>{if(resize){resize(ref.el,options);}});}
function resizeInput(input){input.style.width="100%";const maxWidth=input.clientWidth;const isSafari16=/Version\/16.+Safari/i.test(browser.navigator.userAgent);input.style.width="10px";if(input.value===""&&input.placeholder!==""){input.style.width="auto";return;}
if(input.scrollWidth+5+(isSafari16?8:0)>maxWidth){input.style.width="100%";return;}
input.style.width=input.scrollWidth+5+(isSafari16?8:0)+"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,paddingRight:style.paddingRight,paddingBottom:0,paddingLeft:style.paddingLeft,});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{_t}=require("@web/core/l10n/translation");__exports.isBinarySize=isBinarySize;function isBinarySize(value){return/^\d+(\.\d*)? [^0-9]+$/.test(value);}
__exports.toBase64Length=toBase64Length;function toBase64Length(maxBytes){return Math.ceil(maxBytes*4/3);}
__exports.humanSize=humanSize;function humanSize(size){const units=_t("Bytes|Kb|Mb|Gb|Tb|Pb|Eb|Zb|Yb").split("|");let i=0;while(size>=1024){size/=1024;++i;}
return`${size.toFixed(2)} ${units[i].trim()}`;}
return __exports;});;

/* /web/static/src/core/utils/cache.js */
odoo.define('@web/core/utils/cache',[],function(require){'use strict';let __exports={};const Cache=__exports.Cache=class Cache{constructor(getValue,getKey){this.cache={};this.getKey=getKey;this.getValue=getValue;}
_getCacheAndKey(...path){let cache=this.cache;let key;if(this.getKey){key=this.getKey(...path);}else{for(let i=0;i<path.length-1;i++){cache=cache[path[i]]=cache[path[i]]||{};}
key=path[path.length-1];}
return{cache,key};}
clear(...path){const{cache,key}=this._getCacheAndKey(...path);delete cache[key];}
invalidate(){this.cache={};}
read(...path){const{cache,key}=this._getCacheAndKey(...path);if(!(key in cache)){cache[key]=this.getValue(...path);}
return cache[key];}}
return __exports;});;

/* /web/static/src/core/utils/colors.js */
odoo.define('@web/core/utils/colors',[],function(require){'use strict';let __exports={};__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;}
if(typeof(a)!=='number'||isNaN(a)||a<0||Math.abs(a-100)<Number.EPSILON){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);return(`#${rr}${gg}${bb}`).toUpperCase();}
return`rgba(${r}, ${g}, ${b}, ${parseFloat((a / 100.0).toFixed(3))})`;};__exports.convertCSSColorToRgba=convertCSSColorToRgba;function convertCSSColorToRgba(cssColor){const rgba=cssColor.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/);if(rgba){if(rgba[4]===undefined){rgba[4]=1;}
return{red:parseInt(rgba[1]),green:parseInt(rgba[2]),blue:parseInt(rgba[3]),opacity:Math.round(parseFloat(rgba[4])*100),};}
if(/^#([0-9A-F]{6}|[0-9A-F]{8})$/i.test(cssColor)){return{red:parseInt(cssColor.substr(1,2),16),green:parseInt(cssColor.substr(3,2),16),blue:parseInt(cssColor.substr(5,2),16),opacity:(cssColor.length===9?(parseInt(cssColor.substr(7,2),16)/255):1)*100,};}
if(/color\(.+\)/.test(cssColor)){const canvasEl=document.createElement("canvas");canvasEl.height=1;canvasEl.width=1;const ctx=canvasEl.getContext("2d");ctx.fillStyle=cssColor;ctx.fillRect(0,0,1,1);const data=ctx.getImageData(0,0,1,1).data;return{red:data[0],green:data[1],blue:data[2],opacity:data[3]/2.55,};}
return false;};__exports.normalizeCSSColor=normalizeCSSColor;function normalizeCSSColor(cssColor){const rgba=convertCSSColorToRgba(cssColor);if(!rgba){return cssColor;}
return convertRgbaToCSSColor(rgba.red,rgba.green,rgba.blue,rgba.opacity);};__exports.isCSSColor=isCSSColor;function isCSSColor(cssColor){return convertCSSColorToRgba(cssColor)!==false;};__exports.mixCssColors=mixCssColors;function mixCssColors(cssColor1,cssColor2,weight){const rgba1=convertCSSColorToRgba(cssColor1);const rgba2=convertCSSColorToRgba(cssColor2);const rgb1=[rgba1.red,rgba1.green,rgba1.blue];const rgb2=[rgba2.red,rgba2.green,rgba2.blue];const[r,g,b]=rgb1.map((_,idx)=>Math.round(rgb2[idx]+(rgb1[idx]-rgb2[idx])*weight));return convertRgbaToCSSColor(r,g,b);};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,useSubEnv}=require("@odoo/owl");const ErrorHandler=__exports.ErrorHandler=class ErrorHandler extends Component{setup(){onError((error)=>{this.props.onError(error);});}}
ErrorHandler.template=xml`<t t-slot="default" />`;ErrorHandler.props=["onError","slots"];const WithEnv=__exports.WithEnv=class WithEnv extends Component{setup(){useSubEnv(this.props.env);}}
WithEnv.template=xml`<t t-slot="default"/>`;WithEnv.props=["env","slots"];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/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{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={enable:[Boolean,Function],preventDrag:[Function],ref:[Object],elements:[String],handle:[String,Function],ignore:[String,Function],cursor:[String],edgeScrolling:[Object,Function],delay:[Number],tolerance:[Number],iframeWindow:[Object,Function],};const DEFAULT_DEFAULT_PARAMS={elements:`.${DRAGGABLE_CLASS}`,enable:true,preventDrag:()=>false,edgeScrolling:{speed:10,threshold:30,},delay:0,tolerance:10,touch_delay: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();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}.`);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;[ctx.current.scrollParentX,ctx.current.scrollParentY]=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`,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){if(!inErrorState){if(target){callBuildHandler("onDrop",{target});}
callBuildHandler("onDragEnd");}}
cleanup.cleanup();};const handleEdgeScrolling=(deltaTime)=>{updateRects();const eRect=ctx.current.elementRect;const xRect=ctx.current.scrollParentXRect;const yRect=ctx.current.scrollParentYRect;const{speed,threshold}=ctx.edgeScrolling;const correctedSpeed=(speed/16)*deltaTime;const diff={};if(xRect){const maxWidth=xRect.x+xRect.width;if(eRect.x-xRect.x<threshold){diff.x=[eRect.x-xRect.x,-1];}else if(maxWidth-eRect.x-eRect.width<threshold){diff.x=[maxWidth-eRect.x-eRect.width,1];}}
if(yRect){const maxHeight=yRect.y+yRect.height;if(eRect.y-yRect.y<threshold){diff.y=[eRect.y-yRect.y,-1];}else if(maxHeight-eRect.y-eRect.height<threshold){diff.y=[maxHeight-eRect.y-eRect.height,1];}}
const diffToScroll=([delta,sign])=>(1-clamp(delta,0,threshold)/threshold)*correctedSpeed*sign;if(diff.y){ctx.current.scrollParentY.scrollBy({top:diffToScroll(diff.y)});}
if(diff.x){ctx.current.scrollParentX.scrollBy({left:diffToScroll(diff.x)});}};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)=>{updatePointerPosition(ev);const initiationDelay=ev.pointerType==="touch"?ctx.touch_delay: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);let activeElement=document.activeElement;while(activeElement?.nodeName==="IFRAME"){activeElement=activeElement.contentDocument.activeElement;}
if(activeElement&&!activeElement.contains(ev.target)){activeElement.blur();}
const{currentTarget,pointerId,target}=ev;ctx.current.initialPosition={...ctx.pointer};if(target.hasPointerCapture(pointerId)){target.releasePointerCapture(pointerId);}
if(initiationDelay){if(hasTouch()){if(ev.pointerType==="touch"){dom.addClass(target.closest(ctx.elementSelector),"o_touch_bounce");}
if(isBrowserFirefox()){const links=[...currentTarget.querySelectorAll("[href")];if(currentTarget.hasAttribute("href")){links.unshift(currentTarget);}
for(const link of links){dom.removeAttribute(link,"href");}}
if(isIOS()){for(const image of currentTarget.getElementsByTagName("img")){dom.setAttribute(image,"draggable",false);}}}
ctx.current.timeout=browser.setTimeout(()=>{ctx.current.initialPosition={...ctx.pointer};willStartDrag(target);const{x:px,y:py}=ctx.pointer;const{x,y,width,height}=dom.getRect(ctx.current.element);if(px<x||x+width<px||py<y||y+height<py){dragEnd(null);}},initiationDelay);cleanup.add(()=>browser.clearTimeout(ctx.current.timeout));}else{willStartDrag(target);}};const onPointerMove=(ev)=>{updatePointerPosition(ev);if(!ctx.current.element||!ctx.enable()){return;}
safePrevent(ev);if(!state.dragging){if(!canStartDrag()){return;}
dragStart();}
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 actualParams={...defaultParams,...Object.fromEntries(deps)};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.touch_delay=actualParams.delay||actualParams.touch_delay;ctx.tolerance=actualParams.tolerance;callBuildHandler("onComputeParams",{params:actualParams});return effectCleanup.cleanup;},()=>computeParams(params));const useMouseEvents=isBrowserFirefox()&&!hasTouch()&&params.iframeWindow;setupHooks.setup((el)=>{if(el){const{add,cleanup}=makeCleanupManager();const{addListener}=makeDOMHelpers({add});const event=useMouseEvents?"mousedown":"pointerdown";addListener(el,event,onPointerDown,{noAddedStyle:true});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/files.js */
odoo.define('@web/core/utils/files',['@web/core/utils/numbers','@web/session','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{humanNumber}=require("@web/core/utils/numbers");const{session}=require("@web/session");const{_t}=require("@web/core/l10n/translation");const 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 (%sB) is over the maximum allowed file size (%sB).",humanNumber(fileSize),humanNumber(maxUploadSize)),{type:"danger",});return false;}
return true;}
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/env','@web/core/browser/feature_detection','@odoo/owl'],function(require){'use strict';let __exports={};const{SERVICES_METADATA}=require("@web/env");const{hasTouch,isMobileOS}=require("@web/core/browser/feature_detection");const{status,useComponent,useEffect,useRef,onWillUnmount}=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;}
useEffect((el)=>{if(el&&(!uiService.activeElement||uiService.activeElement.contains(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);},()=>[]);}
function _protectMethod(component,fn){return function(...args){if(status(component)==="destroyed"){return Promise.reject(new Error("Component is destroyed"));}
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,});};}
__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(serviceName in SERVICES_METADATA){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;}}
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.contenteditable?[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/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.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(!this._isAllowedNodeMove(ctx)){ctx.current.placeHolder.classList.add("d-none");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 position={previous:ctx.current.placeHolder.previousElementSibling,next:ctx.current.placeHolder.nextElementSibling,parent:ctx.nest?ctx.current.placeHolder.parentElement.closest(ctx.elementSelector):false,group:ctx.groupSelector?ctx.current.placeHolder.closest(ctx.groupSelector):false,};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 eRect=element.getBoundingClientRect();const pos=ctx.current.placeHolder.compareDocumentPosition(element);if(currentTop-eRect.y<10){if(pos===Node.DOCUMENT_POSITION_PRECEDING||pos===(Node.DOCUMENT_POSITION_PRECEDING|Node.DOCUMENT_POSITION_CONTAINS)){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{element.after(ctx.current.placeHolder);onMove(position);}}}else{const group=closestEl.closest(ctx.groupSelector);if(group&&group!==position.group){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,element:ctx.current.placeHolder});callHandler("onGroupLeave",{group:position.group,element: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{_t}=require("@web/core/l10n/translation");const{intersperse}=require("@web/core/utils/strings");__exports.clamp=clamp;function clamp(num,min,max){return Math.max(Math.min(num,max),min);}
__exports.range=range;function range(start,stop,step=1){const array=[];const nsteps=Math.floor((stop-start)/step);for(let i=0;i<nsteps;i++){array.push(start+step*i);}
return array;}
__exports.roundPrecision=roundPrecision;function roundPrecision(value,precision){if(!value){return 0;}else if(!precision||precision<0){precision=1;}
let normalizedValue=value/precision;const epsilonMagnitude=Math.log2(Math.abs(normalizedValue));const epsilon=Math.pow(2,epsilonMagnitude-52);normalizedValue+=normalizedValue>=0?epsilon:-epsilon;const sign=normalizedValue<0?-1.0:1.0;const roundedValue=sign*Math.round(Math.abs(normalizedValue));return roundedValue*precision;}
__exports.roundDecimals=roundDecimals;function roundDecimals(value,decimals){return roundPrecision(value,parseFloat("1e"+-decimals));}
__exports.floatIsZero=floatIsZero;function floatIsZero(value,decimals){return roundDecimals(value,decimals)===0;}
__exports.insertThousandsSep=insertThousandsSep;function insertThousandsSep(number,thousandsSep=",",grouping=[]){const negative=number[0]==="-";number=negative?number.slice(1):number;return(negative?"-":"")+intersperse(number,grouping,thousandsSep);}
__exports.humanNumber=humanNumber;function humanNumber(number,options={decimals:0,minDigits:1}){const decimals=options.decimals||0;const minDigits=options.minDigits||1;const d2=Math.pow(10,decimals);const numberMagnitude=+number.toExponential().split("e+")[1];number=Math.round(number*d2)/d2;if(numberMagnitude>=21){number=Math.round(number*Math.pow(10,decimals-numberMagnitude))/d2;return`${number}e+${numberMagnitude}`;}
const unitSymbols=_t("kMGTPE").toString();const sign=Math.sign(number);number=Math.abs(number);let symbol="";for(let i=unitSymbols.length;i>0;i--){const s=Math.pow(10,i*3);if(s<=number/Math.pow(10,minDigits-1)){number=Math.round((number*d2)/s)/d2;symbol=unitSymbols[i-1];break;}}
const{decimalPoint,grouping,thousandsSep}=l10n;const decimalsToKeep=number>=1000?0:decimals;number=sign*number;const[integerPart,decimalPart]=number.toFixed(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={}){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;let precision;if(options.digits&&options.digits[1]!==undefined){precision=options.digits[1];}else{precision=2;}
const formatted=value.toFixed(precision).split(".");formatted[0]=insertThousandsSep(formatted[0],thousandsSep,grouping);if(options.trailingZeros===false&&formatted[1]){formatted[1]=formatted[1].replace(/0+$/,"");}
return formatted[1]?formatted.join(decimalPoint):formatted[0];}
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||!obj2||typeof obj1!=="object"||typeof obj2!=="object"){return obj1===obj2;}
const obj1Keys=Object.keys(obj1);return(obj1Keys.length===Object.keys(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(obj){return JSON.parse(JSON.stringify(obj));}
__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]]));}
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/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/assets','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{App,blockDom,Component,markup}=require("@odoo/owl");const{templates}=require("@web/core/assets");const{_t}=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",templates,translatableAttributes:["data-tooltip"],translateFn:_t,});}
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.closestScrollableX=closestScrollableX;function closestScrollableX(el){if(!el){return null;}
if(el.scrollWidth>el.clientWidth&&el.clientWidth>0){const overflow=getComputedStyle(el).getPropertyValue("overflow-x");if(/\bauto\b|\bscroll\b/.test(overflow)){return el;}}
return closestScrollableX(el.parentElement);}
__exports.closestScrollableY=closestScrollableY;function closestScrollableY(el){if(!el){return null;}
if(el.scrollHeight>el.clientHeight&&el.clientHeight>0){const overflow=getComputedStyle(el).getPropertyValue("overflow-y");if(/\bauto\b|\bscroll\b/.test(overflow)){return el;}}
return closestScrollableY(el.parentElement);}
__exports.scrollTo=scrollTo;function scrollTo(element,options={behavior:"auto",scrollable:null,isAnchor:false}){const scrollable=closestScrollableY(options.scrollable||element.parentElement);if(scrollable){const scrollBottom=scrollable.getBoundingClientRect().bottom;const scrollTop=scrollable.getBoundingClientRect().top;const elementBottom=element.getBoundingClientRect().bottom;const elementTop=element.getBoundingClientRect().top;if(elementBottom>scrollBottom&&!options.isAnchor){scrollable.scrollTo({top:scrollable.scrollTop+
elementTop-
scrollBottom+
Math.ceil(element.getBoundingClientRect().height),behavior:options.behavior,});}else if(elementTop<scrollTop||options.isAnchor){scrollable.scrollTo({top:scrollable.scrollTop-scrollTop+elementTop,behavior:options.behavior,});if(options.isAnchor){const parentScrollable=closestScrollableY(scrollable.parentElement);if(parentScrollable){scrollTo(scrollable,{behavior:options.behavior,isAnchor:true,scrollable:parentScrollable,});}}}}}
return __exports;});;

/* /web/static/src/core/utils/search.js */
odoo.define('@web/core/utils/search',['@web/core/utils/strings'],function(require){'use strict';let __exports={};const{unaccent}=require("@web/core/utils/strings");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;const len=str.length;let patternIndex=0;pattern=unaccent(pattern,false);str=unaccent(str,false);for(let i=0;i<len;i++){if(str[i]===pattern[patternIndex]){patternIndex++;currentScore+=100+currentScore-i/200;}else{currentScore=0;}
totalScore=totalScore+currentScore;}
return patternIndex===pattern.length?totalScore:0;}
__exports.fuzzyLookup=fuzzyLookup;function fuzzyLookup(pattern,list,fn){const results=[];list.forEach((data)=>{const score=match(pattern,fn(data));if(score>0){results.push({score,elem:data});}});results.sort((a,b)=>b.score-a.score);return results.map((r)=>r.elem);}
__exports.fuzzyTest=fuzzyTest;function fuzzyTest(pattern,string){return _match(pattern,string)!==0;}
return __exports;});;

/* /web/static/src/core/utils/sortable.js */
odoo.define('@web/core/utils/sortable',['@web/core/utils/draggable_hook_builder','@web/core/utils/objects'],function(require){'use strict';let __exports={};const{DRAGGED_CLASS,makeDraggableHook:nativeMakeDraggableHook,}=require("@web/core/utils/draggable_hook_builder");const{pick}=require("@web/core/utils/objects");const hookParams={name:"useSortable",acceptedParams:{groups:[String,Function],connectGroups:[Boolean,Function],clone:[Boolean],placeholderClasses:[Object],applyChangeOnDrop:[Boolean],followingElementClasses:[Object],},defaultParams:{connectGroups:false,edgeScrolling:{speed:20,threshold:60},groupSelector:null,clone:true,placeholderClasses:[],applyChangeOnDrop:false,followingElementClasses:[],},onComputeParams({ctx,params}){ctx.groupSelector=params.groups||null;if(ctx.groupSelector){ctx.fullSelector=[ctx.groupSelector,ctx.fullSelector].join(" ");}
ctx.connectGroups=params.connectGroups;ctx.placeholderClone=params.clone;ctx.placeholderClasses=params.placeholderClasses;ctx.applyChangeOnDrop=params.applyChangeOnDrop;ctx.followingElementClasses=params.followingElementClasses;},onDragStart({ctx,addListener,addStyle,callHandler}){const onElementPointerEnter=(ev)=>{const element=ev.currentTarget;if(connectGroups||!groupSelector||current.group===element.closest(groupSelector)){const pos=current.placeHolder.compareDocumentPosition(element);if(pos===Node.DOCUMENT_POSITION_PRECEDING){element.before(current.placeHolder);}else if(pos===Node.DOCUMENT_POSITION_FOLLOWING){element.after(current.placeHolder);}}
callHandler("onElementEnter",{element});};const onElementPointerLeave=(ev)=>{const element=ev.currentTarget;callHandler("onElementLeave",{element});};const onElementComplexPointerEnter=(ev)=>{if(ctx.haveAlreadyChanged){return;}
const element=ev.currentTarget;const siblingArray=[...element.parentElement.children].filter((el)=>el===current.placeHolder||(el.matches(elementSelector)&&!el.classList.contains(DRAGGED_CLASS)));const elementIndex=siblingArray.indexOf(element);const placeholderIndex=siblingArray.indexOf(current.placeHolder);const isDirectSibling=Math.abs(elementIndex-placeholderIndex)===1;if(connectGroups||!groupSelector||current.group===element.closest(groupSelector)){const pos=current.placeHolder.compareDocumentPosition(element);if(isDirectSibling){if(pos===Node.DOCUMENT_POSITION_PRECEDING){element.before(current.placeHolder);ctx.haveAlreadyChanged=true;}else if(pos===Node.DOCUMENT_POSITION_FOLLOWING){element.after(current.placeHolder);ctx.haveAlreadyChanged=true;}}else{if(pos===Node.DOCUMENT_POSITION_FOLLOWING){element.before(current.placeHolder);ctx.haveAlreadyChanged=true;}else if(pos===Node.DOCUMENT_POSITION_PRECEDING){element.after(current.placeHolder);ctx.haveAlreadyChanged=true;}}}
callHandler("onElementEnter",{element});};const onElementComplexPointerLeave=(ev)=>{if(ctx.haveAlreadyChanged){return;}
const element=ev.currentTarget;const elementRect=element.getBoundingClientRect();const relatedElement=ev.relatedTarget;const relatedElementRect=element.getBoundingClientRect();const siblingArray=[...element.parentElement.children].filter((el)=>el===current.placeHolder||(el.matches(elementSelector)&&!el.classList.contains(DRAGGED_CLASS)));const pointerOnSiblings=siblingArray.indexOf(relatedElement)>-1;const elementIndex=siblingArray.indexOf(element);const isFirst=elementIndex===0;const isAbove=relatedElementRect.top<=elementRect.top;const isLast=elementIndex===siblingArray.length-1;const isBelow=relatedElementRect.bottom>=elementRect.bottom;const pos=current.placeHolder.compareDocumentPosition(element);if(!pointerOnSiblings){if(isFirst&&isAbove&&pos===Node.DOCUMENT_POSITION_PRECEDING){element.before(current.placeHolder);ctx.haveAlreadyChanged=true;}else if(isLast&&isBelow&&pos===Node.DOCUMENT_POSITION_FOLLOWING){element.after(current.placeHolder);ctx.haveAlreadyChanged=true;}}
callHandler("onElementLeave",{element});};const onGroupPointerEnter=(ev)=>{const group=ev.currentTarget;group.appendChild(current.placeHolder);callHandler("onGroupEnter",{group});};const onGroupPointerLeave=(ev)=>{const group=ev.currentTarget;callHandler("onGroupLeave",{group});};const{connectGroups,current,elementSelector,groupSelector,ref}=ctx;if(ctx.placeholderClone){const{width,height}=current.elementRect;addStyle(current.placeHolder,{visibility:"hidden",display:"block",width:`${width}px`,height:`${height}px`,});}
if(connectGroups&&groupSelector){for(const siblingGroup of ref.el.querySelectorAll(groupSelector)){addListener(siblingGroup,"pointerenter",onGroupPointerEnter);addListener(siblingGroup,"pointerleave",onGroupPointerLeave);}}
for(const siblingEl of ref.el.querySelectorAll(elementSelector)){if(siblingEl!==current.element&&siblingEl!==current.placeHolder){if(ctx.placeholderClone){addListener(siblingEl,"pointerenter",onElementPointerEnter);addListener(siblingEl,"pointerleave",onElementPointerLeave);}else{addListener(siblingEl,"pointerenter",onElementComplexPointerEnter);addListener(siblingEl,"pointerleave",onElementComplexPointerLeave);}}}
current.element.after(current.placeHolder);return pick(current,"element","group");},onDrag({ctx}){ctx.haveAlreadyChanged=false;},onDragEnd({ctx}){return pick(ctx.current,"element","group");},onDrop({ctx}){const{current,groupSelector}=ctx;const previous=current.placeHolder.previousElementSibling;const next=current.placeHolder.nextElementSibling;if(previous!==current.element&&next!==current.element){const element=current.element;if(ctx.applyChangeOnDrop){if(previous){previous.after(element);}else if(next){next.before(element);}}
return{element,group:current.group,previous,next,parent:groupSelector&&current.placeHolder.closest(groupSelector),};}},onWillStartDrag({ctx,addCleanup}){const{connectGroups,current,groupSelector}=ctx;if(groupSelector){current.group=current.element.closest(groupSelector);if(!connectGroups){current.container=current.group;}}
if(ctx.placeholderClone){current.placeHolder=current.element.cloneNode(false);}else{current.placeHolder=document.createElement("div");}
current.placeHolder.classList.add(...ctx.placeholderClasses);current.element.classList.add(...ctx.followingElementClasses);addCleanup(()=>current.element.classList.remove(...ctx.followingElementClasses));addCleanup(()=>current.placeHolder.remove());return pick(current,"element","group");},};const useSortable=__exports.useSortable=(sortableParams)=>{const{setupHooks}=sortableParams;delete sortableParams.setupHooks;return nativeMakeDraggableHook({...hookParams,setupHooks})(sortableParams);};return __exports;});;

/* /web/static/src/core/utils/sortable_owl.js */
odoo.define('@web/core/utils/sortable_owl',['@odoo/owl','@web/core/utils/timing','@web/core/utils/sortable'],function(require){'use strict';let __exports={};const{onWillUnmount,reactive,useEffect,useExternalListener}=require("@odoo/owl");const{useThrottleForAnimation}=require("@web/core/utils/timing");const{useSortable:nativeUseSortable}=require("@web/core/utils/sortable");__exports.useSortable=useSortable;function useSortable(params){return nativeUseSortable({...params,setupHooks:{addListener:useExternalListener,setup:useEffect,teardown:onWillUnmount,throttle:useThrottleForAnimation,wrapState:reactive,},});}
return __exports;});;

/* /web/static/src/core/utils/sortable_service.js */
odoo.define('@web/core/utils/sortable_service',['@web/core/registry','@web/core/utils/sortable','@web/core/utils/timing','@odoo/owl'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{useSortable}=require("@web/core/utils/sortable");const{throttleForAnimation}=require("@web/core/utils/timing");const{reactive}=require("@odoo/owl");const DEFAULT_SORTABLE_ID=Symbol.for("defaultSortable");const sortableService=__exports.sortableService={start(){const boundElements=new Map();return{create:(hookParams)=>{const element=hookParams.ref.el;const sortableId=hookParams.sortableId??DEFAULT_SORTABLE_ID;if(boundElements.has(element)){const boundElement=boundElements.get(element);if(sortableId in boundElement){return{enable(){return{cleanup:boundElement[sortableId],};},};}}
const setupFunctions=new Map();const cleanupFunctions=[];const cleanup=()=>{const boundElement=boundElements.get(element);if(sortableId in boundElement){delete boundElement[sortableId];if(boundElement.length===0){boundElements.delete(element);}}
cleanupFunctions.forEach((fn)=>fn());};const setupHooks={wrapState:reactive,throttle:throttleForAnimation,addListener:(el,type,listener)=>{el.addEventListener(type,listener);cleanupFunctions.push(()=>el.removeEventListener(type,listener));},setup:(setupFn,dependenciesFn)=>setupFunctions.set(setupFn,dependenciesFn),teardown:(fn)=>cleanupFunctions.push(fn),};useSortable({setupHooks,...hookParams});const boundElement=boundElements.get(element);if(boundElement){boundElement[sortableId]=cleanup;}else{boundElements.set(element,{[sortableId]:cleanup});}
return{enable(){setupFunctions.forEach((dependenciesFn,setupFn)=>setupFn(...dependenciesFn()));return{cleanup,};},};},};},};registry.category("services").add("sortable",sortableService);return __exports;});;

/* /web/static/src/core/utils/strings.js */
odoo.define('@web/core/utils/strings',[],function(require){'use strict';let __exports={};const nbsp=__exports.nbsp="\u00a0";const escapeMethod=__exports.escapeMethod=Symbol("html");__exports.escape=escape;function escape(str){if(typeof str==="object"&&str[escapeMethod]){return str[escapeMethod]();}else{if(str===undefined){return"";}
if(typeof str==="number"){return String(str);}
[["&","&amp;"],["<","&lt;"],[">","&gt;"],["'","&#x27;"],['"',"&quot;"],["`","&#x60;"],].forEach((pairs)=>{str=String(str).replaceAll(pairs[0],pairs[1]);});return str;}}
__exports.escapeRegExp=escapeRegExp;function escapeRegExp(str){return str.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");}
__exports.intersperse=intersperse;function intersperse(str,indices,separator=""){separator=separator||"";const result=[];let last=str.length;for(let i=0;i<indices.length;++i){let section=indices[i];if(section===-1||last<=0){break;}else if(section===0&&i===0){break;}else if(section===0){section=indices[--i];}
result.push(str.substring(last-section,last));last-=section;}
const s=str.substring(0,last);if(s){result.push(s);}
return result.reverse().join(separator);}
__exports.sprintf=sprintf;function sprintf(s,...values){if(values.length===1&&Object.prototype.toString.call(values[0])==="[object Object]"){const valuesDict=values[0];s=s.replace(/%\(([^)]+)\)s/g,(match,value)=>valuesDict[value]);}else if(values.length>0){s=s.replace(/%s/g,()=>values.shift());}
return s;}
__exports.capitalize=capitalize;function capitalize(s){return s?s[0].toUpperCase()+s.slice(1):"";}
const diacriticsMap={'\u0041':'A','\u24B6':'A','\uFF21':'A','\u00C0':'A','\u00C1':'A','\u00C2':'A','\u1EA6':'A','\u1EA4':'A','\u1EAA':'A','\u1EA8':'A','\u00C3':'A','\u0100':'A','\u0102':'A','\u1EB0':'A','\u1EAE':'A','\u1EB4':'A','\u1EB2':'A','\u0226':'A','\u01E0':'A','\u00C4':'A','\u01DE':'A','\u1EA2':'A','\u00C5':'A','\u01FA':'A','\u01CD':'A','\u0200':'A','\u0202':'A','\u1EA0':'A','\u1EAC':'A','\u1EB6':'A','\u1E00':'A','\u0104':'A','\u023A':'A','\u2C6F':'A','\uA732':'AA','\u00C6':'AE','\u01FC':'AE','\u01E2':'AE','\uA734':'AO','\uA736':'AU','\uA738':'AV','\uA73A':'AV','\uA73C':'AY','\u0042':'B','\u24B7':'B','\uFF22':'B','\u1E02':'B','\u1E04':'B','\u1E06':'B','\u0243':'B','\u0182':'B','\u0181':'B','\u0043':'C','\u24B8':'C','\uFF23':'C','\u0106':'C','\u0108':'C','\u010A':'C','\u010C':'C','\u00C7':'C','\u1E08':'C','\u0187':'C','\u023B':'C','\uA73E':'C','\u0044':'D','\u24B9':'D','\uFF24':'D','\u1E0A':'D','\u010E':'D','\u1E0C':'D','\u1E10':'D','\u1E12':'D','\u1E0E':'D','\u0110':'D','\u018B':'D','\u018A':'D','\u0189':'D','\uA779':'D','\u01F1':'DZ','\u01C4':'DZ','\u01F2':'Dz','\u01C5':'Dz','\u0045':'E','\u24BA':'E','\uFF25':'E','\u00C8':'E','\u00C9':'E','\u00CA':'E','\u1EC0':'E','\u1EBE':'E','\u1EC4':'E','\u1EC2':'E','\u1EBC':'E','\u0112':'E','\u1E14':'E','\u1E16':'E','\u0114':'E','\u0116':'E','\u00CB':'E','\u1EBA':'E','\u011A':'E','\u0204':'E','\u0206':'E','\u1EB8':'E','\u1EC6':'E','\u0228':'E','\u1E1C':'E','\u0118':'E','\u1E18':'E','\u1E1A':'E','\u0190':'E','\u018E':'E','\u0046':'F','\u24BB':'F','\uFF26':'F','\u1E1E':'F','\u0191':'F','\uA77B':'F','\u0047':'G','\u24BC':'G','\uFF27':'G','\u01F4':'G','\u011C':'G','\u1E20':'G','\u011E':'G','\u0120':'G','\u01E6':'G','\u0122':'G','\u01E4':'G','\u0193':'G','\uA7A0':'G','\uA77D':'G','\uA77E':'G','\u0048':'H','\u24BD':'H','\uFF28':'H','\u0124':'H','\u1E22':'H','\u1E26':'H','\u021E':'H','\u1E24':'H','\u1E28':'H','\u1E2A':'H','\u0126':'H','\u2C67':'H','\u2C75':'H','\uA78D':'H','\u0049':'I','\u24BE':'I','\uFF29':'I','\u00CC':'I','\u00CD':'I','\u00CE':'I','\u0128':'I','\u012A':'I','\u012C':'I','\u0130':'I','\u00CF':'I','\u1E2E':'I','\u1EC8':'I','\u01CF':'I','\u0208':'I','\u020A':'I','\u1ECA':'I','\u012E':'I','\u1E2C':'I','\u0197':'I','\u004A':'J','\u24BF':'J','\uFF2A':'J','\u0134':'J','\u0248':'J','\u004B':'K','\u24C0':'K','\uFF2B':'K','\u1E30':'K','\u01E8':'K','\u1E32':'K','\u0136':'K','\u1E34':'K','\u0198':'K','\u2C69':'K','\uA740':'K','\uA742':'K','\uA744':'K','\uA7A2':'K','\u004C':'L','\u24C1':'L','\uFF2C':'L','\u013F':'L','\u0139':'L','\u013D':'L','\u1E36':'L','\u1E38':'L','\u013B':'L','\u1E3C':'L','\u1E3A':'L','\u0141':'L','\u023D':'L','\u2C62':'L','\u2C60':'L','\uA748':'L','\uA746':'L','\uA780':'L','\u01C7':'LJ','\u01C8':'Lj','\u004D':'M','\u24C2':'M','\uFF2D':'M','\u1E3E':'M','\u1E40':'M','\u1E42':'M','\u2C6E':'M','\u019C':'M','\u004E':'N','\u24C3':'N','\uFF2E':'N','\u01F8':'N','\u0143':'N','\u00D1':'N','\u1E44':'N','\u0147':'N','\u1E46':'N','\u0145':'N','\u1E4A':'N','\u1E48':'N','\u0220':'N','\u019D':'N','\uA790':'N','\uA7A4':'N','\u01CA':'NJ','\u01CB':'Nj','\u004F':'O','\u24C4':'O','\uFF2F':'O','\u00D2':'O','\u00D3':'O','\u00D4':'O','\u1ED2':'O','\u1ED0':'O','\u1ED6':'O','\u1ED4':'O','\u00D5':'O','\u1E4C':'O','\u022C':'O','\u1E4E':'O','\u014C':'O','\u1E50':'O','\u1E52':'O','\u014E':'O','\u022E':'O','\u0230':'O','\u00D6':'O','\u022A':'O','\u1ECE':'O','\u0150':'O','\u01D1':'O','\u020C':'O','\u020E':'O','\u01A0':'O','\u1EDC':'O','\u1EDA':'O','\u1EE0':'O','\u1EDE':'O','\u1EE2':'O','\u1ECC':'O','\u1ED8':'O','\u01EA':'O','\u01EC':'O','\u00D8':'O','\u01FE':'O','\u0186':'O','\u019F':'O','\uA74A':'O','\uA74C':'O','\u01A2':'OI','\uA74E':'OO','\u0222':'OU','\u0050':'P','\u24C5':'P','\uFF30':'P','\u1E54':'P','\u1E56':'P','\u01A4':'P','\u2C63':'P','\uA750':'P','\uA752':'P','\uA754':'P','\u0051':'Q','\u24C6':'Q','\uFF31':'Q','\uA756':'Q','\uA758':'Q','\u024A':'Q','\u0052':'R','\u24C7':'R','\uFF32':'R','\u0154':'R','\u1E58':'R','\u0158':'R','\u0210':'R','\u0212':'R','\u1E5A':'R','\u1E5C':'R','\u0156':'R','\u1E5E':'R','\u024C':'R','\u2C64':'R','\uA75A':'R','\uA7A6':'R','\uA782':'R','\u0053':'S','\u24C8':'S','\uFF33':'S','\u1E9E':'S','\u015A':'S','\u1E64':'S','\u015C':'S','\u1E60':'S','\u0160':'S','\u1E66':'S','\u1E62':'S','\u1E68':'S','\u0218':'S','\u015E':'S','\u2C7E':'S','\uA7A8':'S','\uA784':'S','\u0054':'T','\u24C9':'T','\uFF34':'T','\u1E6A':'T','\u0164':'T','\u1E6C':'T','\u021A':'T','\u0162':'T','\u1E70':'T','\u1E6E':'T','\u0166':'T','\u01AC':'T','\u01AE':'T','\u023E':'T','\uA786':'T','\uA728':'TZ','\u0055':'U','\u24CA':'U','\uFF35':'U','\u00D9':'U','\u00DA':'U','\u00DB':'U','\u0168':'U','\u1E78':'U','\u016A':'U','\u1E7A':'U','\u016C':'U','\u00DC':'U','\u01DB':'U','\u01D7':'U','\u01D5':'U','\u01D9':'U','\u1EE6':'U','\u016E':'U','\u0170':'U','\u01D3':'U','\u0214':'U','\u0216':'U','\u01AF':'U','\u1EEA':'U','\u1EE8':'U','\u1EEE':'U','\u1EEC':'U','\u1EF0':'U','\u1EE4':'U','\u1E72':'U','\u0172':'U','\u1E76':'U','\u1E74':'U','\u0244':'U','\u0056':'V','\u24CB':'V','\uFF36':'V','\u1E7C':'V','\u1E7E':'V','\u01B2':'V','\uA75E':'V','\u0245':'V','\uA760':'VY','\u0057':'W','\u24CC':'W','\uFF37':'W','\u1E80':'W','\u1E82':'W','\u0174':'W','\u1E86':'W','\u1E84':'W','\u1E88':'W','\u2C72':'W','\u0058':'X','\u24CD':'X','\uFF38':'X','\u1E8A':'X','\u1E8C':'X','\u0059':'Y','\u24CE':'Y','\uFF39':'Y','\u1EF2':'Y','\u00DD':'Y','\u0176':'Y','\u1EF8':'Y','\u0232':'Y','\u1E8E':'Y','\u0178':'Y','\u1EF6':'Y','\u1EF4':'Y','\u01B3':'Y','\u024E':'Y','\u1EFE':'Y','\u005A':'Z','\u24CF':'Z','\uFF3A':'Z','\u0179':'Z','\u1E90':'Z','\u017B':'Z','\u017D':'Z','\u1E92':'Z','\u1E94':'Z','\u01B5':'Z','\u0224':'Z','\u2C7F':'Z','\u2C6B':'Z','\uA762':'Z','\u0061':'a','\u24D0':'a','\uFF41':'a','\u1E9A':'a','\u00E0':'a','\u00E1':'a','\u00E2':'a','\u1EA7':'a','\u1EA5':'a','\u1EAB':'a','\u1EA9':'a','\u00E3':'a','\u0101':'a','\u0103':'a','\u1EB1':'a','\u1EAF':'a','\u1EB5':'a','\u1EB3':'a','\u0227':'a','\u01E1':'a','\u00E4':'a','\u01DF':'a','\u1EA3':'a','\u00E5':'a','\u01FB':'a','\u01CE':'a','\u0201':'a','\u0203':'a','\u1EA1':'a','\u1EAD':'a','\u1EB7':'a','\u1E01':'a','\u0105':'a','\u2C65':'a','\u0250':'a','\uA733':'aa','\u00E6':'ae','\u01FD':'ae','\u01E3':'ae','\uA735':'ao','\uA737':'au','\uA739':'av','\uA73B':'av','\uA73D':'ay','\u0062':'b','\u24D1':'b','\uFF42':'b','\u1E03':'b','\u1E05':'b','\u1E07':'b','\u0180':'b','\u0183':'b','\u0253':'b','\u0063':'c','\u24D2':'c','\uFF43':'c','\u0107':'c','\u0109':'c','\u010B':'c','\u010D':'c','\u00E7':'c','\u1E09':'c','\u0188':'c','\u023C':'c','\uA73F':'c','\u2184':'c','\u0064':'d','\u24D3':'d','\uFF44':'d','\u1E0B':'d','\u010F':'d','\u1E0D':'d','\u1E11':'d','\u1E13':'d','\u1E0F':'d','\u0111':'d','\u018C':'d','\u0256':'d','\u0257':'d','\uA77A':'d','\u01F3':'dz','\u01C6':'dz','\u0065':'e','\u24D4':'e','\uFF45':'e','\u00E8':'e','\u00E9':'e','\u00EA':'e','\u1EC1':'e','\u1EBF':'e','\u1EC5':'e','\u1EC3':'e','\u1EBD':'e','\u0113':'e','\u1E15':'e','\u1E17':'e','\u0115':'e','\u0117':'e','\u00EB':'e','\u1EBB':'e','\u011B':'e','\u0205':'e','\u0207':'e','\u1EB9':'e','\u1EC7':'e','\u0229':'e','\u1E1D':'e','\u0119':'e','\u1E19':'e','\u1E1B':'e','\u0247':'e','\u025B':'e','\u01DD':'e','\u0066':'f','\u24D5':'f','\uFF46':'f','\u1E1F':'f','\u0192':'f','\uA77C':'f','\u0067':'g','\u24D6':'g','\uFF47':'g','\u01F5':'g','\u011D':'g','\u1E21':'g','\u011F':'g','\u0121':'g','\u01E7':'g','\u0123':'g','\u01E5':'g','\u0260':'g','\uA7A1':'g','\u1D79':'g','\uA77F':'g','\u0068':'h','\u24D7':'h','\uFF48':'h','\u0125':'h','\u1E23':'h','\u1E27':'h','\u021F':'h','\u1E25':'h','\u1E29':'h','\u1E2B':'h','\u1E96':'h','\u0127':'h','\u2C68':'h','\u2C76':'h','\u0265':'h','\u0195':'hv','\u0069':'i','\u24D8':'i','\uFF49':'i','\u00EC':'i','\u00ED':'i','\u00EE':'i','\u0129':'i','\u012B':'i','\u012D':'i','\u00EF':'i','\u1E2F':'i','\u1EC9':'i','\u01D0':'i','\u0209':'i','\u020B':'i','\u1ECB':'i','\u012F':'i','\u1E2D':'i','\u0268':'i','\u0131':'i','\u006A':'j','\u24D9':'j','\uFF4A':'j','\u0135':'j','\u01F0':'j','\u0249':'j','\u006B':'k','\u24DA':'k','\uFF4B':'k','\u1E31':'k','\u01E9':'k','\u1E33':'k','\u0137':'k','\u1E35':'k','\u0199':'k','\u2C6A':'k','\uA741':'k','\uA743':'k','\uA745':'k','\uA7A3':'k','\u006C':'l','\u24DB':'l','\uFF4C':'l','\u0140':'l','\u013A':'l','\u013E':'l','\u1E37':'l','\u1E39':'l','\u013C':'l','\u1E3D':'l','\u1E3B':'l','\u017F':'l','\u0142':'l','\u019A':'l','\u026B':'l','\u2C61':'l','\uA749':'l','\uA781':'l','\uA747':'l','\u01C9':'lj','\u006D':'m','\u24DC':'m','\uFF4D':'m','\u1E3F':'m','\u1E41':'m','\u1E43':'m','\u0271':'m','\u026F':'m','\u006E':'n','\u24DD':'n','\uFF4E':'n','\u01F9':'n','\u0144':'n','\u00F1':'n','\u1E45':'n','\u0148':'n','\u1E47':'n','\u0146':'n','\u1E4B':'n','\u1E49':'n','\u019E':'n','\u0272':'n','\u0149':'n','\uA791':'n','\uA7A5':'n','\u01CC':'nj','\u006F':'o','\u24DE':'o','\uFF4F':'o','\u00F2':'o','\u00F3':'o','\u00F4':'o','\u1ED3':'o','\u1ED1':'o','\u1ED7':'o','\u1ED5':'o','\u00F5':'o','\u1E4D':'o','\u022D':'o','\u1E4F':'o','\u014D':'o','\u1E51':'o','\u1E53':'o','\u014F':'o','\u022F':'o','\u0231':'o','\u00F6':'o','\u022B':'o','\u1ECF':'o','\u0151':'o','\u01D2':'o','\u020D':'o','\u020F':'o','\u01A1':'o','\u1EDD':'o','\u1EDB':'o','\u1EE1':'o','\u1EDF':'o','\u1EE3':'o','\u1ECD':'o','\u1ED9':'o','\u01EB':'o','\u01ED':'o','\u00F8':'o','\u01FF':'o','\u0254':'o','\uA74B':'o','\uA74D':'o','\u0275':'o','\u01A3':'oi','\u0223':'ou','\uA74F':'oo','\u0070':'p','\u24DF':'p','\uFF50':'p','\u1E55':'p','\u1E57':'p','\u01A5':'p','\u1D7D':'p','\uA751':'p','\uA753':'p','\uA755':'p','\u0071':'q','\u24E0':'q','\uFF51':'q','\u024B':'q','\uA757':'q','\uA759':'q','\u0072':'r','\u24E1':'r','\uFF52':'r','\u0155':'r','\u1E59':'r','\u0159':'r','\u0211':'r','\u0213':'r','\u1E5B':'r','\u1E5D':'r','\u0157':'r','\u1E5F':'r','\u024D':'r','\u027D':'r','\uA75B':'r','\uA7A7':'r','\uA783':'r','\u0073':'s','\u24E2':'s','\uFF53':'s','\u00DF':'s','\u015B':'s','\u1E65':'s','\u015D':'s','\u1E61':'s','\u0161':'s','\u1E67':'s','\u1E63':'s','\u1E69':'s','\u0219':'s','\u015F':'s','\u023F':'s','\uA7A9':'s','\uA785':'s','\u1E9B':'s','\u0074':'t','\u24E3':'t','\uFF54':'t','\u1E6B':'t','\u1E97':'t','\u0165':'t','\u1E6D':'t','\u021B':'t','\u0163':'t','\u1E71':'t','\u1E6F':'t','\u0167':'t','\u01AD':'t','\u0288':'t','\u2C66':'t','\uA787':'t','\uA729':'tz','\u0075':'u','\u24E4':'u','\uFF55':'u','\u00F9':'u','\u00FA':'u','\u00FB':'u','\u0169':'u','\u1E79':'u','\u016B':'u','\u1E7B':'u','\u016D':'u','\u00FC':'u','\u01DC':'u','\u01D8':'u','\u01D6':'u','\u01DA':'u','\u1EE7':'u','\u016F':'u','\u0171':'u','\u01D4':'u','\u0215':'u','\u0217':'u','\u01B0':'u','\u1EEB':'u','\u1EE9':'u','\u1EEF':'u','\u1EED':'u','\u1EF1':'u','\u1EE5':'u','\u1E73':'u','\u0173':'u','\u1E77':'u','\u1E75':'u','\u0289':'u','\u0076':'v','\u24E5':'v','\uFF56':'v','\u1E7D':'v','\u1E7F':'v','\u028B':'v','\uA75F':'v','\u028C':'v','\uA761':'vy','\u0077':'w','\u24E6':'w','\uFF57':'w','\u1E81':'w','\u1E83':'w','\u0175':'w','\u1E87':'w','\u1E85':'w','\u1E98':'w','\u1E89':'w','\u2C73':'w','\u0078':'x','\u24E7':'x','\uFF58':'x','\u1E8B':'x','\u1E8D':'x','\u0079':'y','\u24E8':'y','\uFF59':'y','\u1EF3':'y','\u00FD':'y','\u0177':'y','\u1EF9':'y','\u0233':'y','\u1E8F':'y','\u00FF':'y','\u1EF7':'y','\u1E99':'y','\u1EF5':'y','\u01B4':'y','\u024F':'y','\u1EFF':'y','\u007A':'z','\u24E9':'z','\uFF5A':'z','\u017A':'z','\u1E91':'z','\u017C':'z','\u017E':'z','\u1E93':'z','\u1E95':'z','\u01B6':'z','\u0225':'z','\u0240':'z','\u2C6C':'z','\uA763':'z',};__exports.unaccent=unaccent;function unaccent(str,caseSensitive){str=str.replace(/[^\u0000-\u007E]/g,function(accented){return diacriticsMap[accented]||accented;});return caseSensitive?str:str.toLowerCase();}
__exports.isEmail=isEmail;function isEmail(value){const re=/^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;return re.test(value);}
return __exports;});;

/* /web/static/src/core/utils/timing.js */
odoo.define('@web/core/utils/timing',['@web/core/browser/browser','@odoo/owl'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{onWillUnmount,useComponent}=require("@odoo/owl");__exports.batched=batched;function batched(callback,synchronize=()=>Promise.resolve()){let scheduled=false;return async(...args)=>{if(!scheduled){scheduled=true;await synchronize();scheduled=false;callback(...args);}};}
__exports.debounce=debounce;function debounce(func,delay,options){let handle;const funcName=func.name?func.name+" (debounce)":"debounce";const useAnimationFrame=delay==="animationFrame";const setFnName=useAnimationFrame?"requestAnimationFrame":"setTimeout";const clearFnName=useAnimationFrame?"cancelAnimationFrame":"clearTimeout";let lastArgs;let leading=false;let trailing=true;if(typeof options==="boolean"){leading=options;trailing=!options;}else if(options){leading=options.leading??leading;trailing=options.trailing??trailing;}
return Object.assign({[funcName](...args){return new Promise((resolve)=>{if(leading&&!handle){Promise.resolve(func.apply(this,args)).then(resolve);}else{lastArgs=args;}
browser[clearFnName](handle);handle=browser[setFnName](()=>{handle=null;if(trailing&&lastArgs){Promise.resolve(func.apply(this,lastArgs)).then(resolve);lastArgs=null;}},delay);});},}[funcName],{cancel(execNow=false){browser[clearFnName](handle);if(execNow&&lastArgs){func.apply(this,lastArgs);}},});}
__exports.setRecurringAnimationFrame=setRecurringAnimationFrame;function setRecurringAnimationFrame(callback){const handler=(timestamp)=>{callback(timestamp-lastTimestamp);lastTimestamp=timestamp;handle=browser.requestAnimationFrame(handler);};const stop=()=>{browser.cancelAnimationFrame(handle);};let lastTimestamp=browser.performance.now();let handle=browser.requestAnimationFrame(handler);return stop;}
__exports.throttleForAnimation=throttleForAnimation;function throttleForAnimation(func){let handle=null;const calls=new Set();const funcName=func.name?`${func.name} (throttleForAnimation)`:"throttleForAnimation";const pending=()=>{if(calls.size){handle=browser.requestAnimationFrame(pending);const{args,resolve}=[...calls].pop();calls.clear();Promise.resolve(func.apply(this,args)).then(resolve);}else{handle=null;}};return Object.assign({[funcName](...args){return new Promise((resolve)=>{const isNew=handle===null;if(isNew){handle=browser.requestAnimationFrame(pending);Promise.resolve(func.apply(this,args)).then(resolve);}else{calls.add({args,resolve});}});},}[funcName],{cancel(){browser.cancelAnimationFrame(handle);calls.clear();handle=null;},});}
__exports.useDebounced=useDebounced;function useDebounced(callback,delay,{execBeforeUnmount=false,immediate=false}={}){const component=useComponent();const debounced=debounce(callback.bind(component),delay,immediate);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/ui.js */
odoo.define('@web/core/utils/ui',[],function(require){'use strict';let __exports={};__exports.closest=closest;function closest(elements,targetPos){let closestEl=null;let closestDistance=Infinity;for(const el of elements){const rect=el.getBoundingClientRect();const distance=getQuadrance(rect,targetPos);if(!closestEl||distance<closestDistance){closestEl=el;closestDistance=distance;}}
return closestEl;}
__exports.isVisible=isVisible;function isVisible(el){if(el===document||el===window){return true;}
if(!el){return false;}
let _isVisible=false;if("offsetWidth"in el&&"offsetHeight"in el){_isVisible=el.offsetWidth>0&&el.offsetHeight>0;}else if("getBoundingClientRect"in el){const rect=el.getBoundingClientRect();_isVisible=rect.width>0&&rect.height>0;}
if(!_isVisible&&getComputedStyle(el).display==="contents"){for(const child of el.children){if(isVisible(child)){return true;}}}
return _isVisible;}
__exports._legacyIsVisible=_legacyIsVisible;function _legacyIsVisible(el){if(el===document||el===window){return true;}
if(!el){return false;}
let _isVisible=false;if("offsetWidth"in el&&"offsetHeight"in el){_isVisible=el.offsetWidth>0||el.offsetHeight>0;}else if("getBoundingClientRect"in el){const rect=el.getBoundingClientRect();_isVisible=rect.width>0||rect.height>0;}
if(!_isVisible&&getComputedStyle(el).display==="contents"){for(const child of el.children){if(isVisible(child)){return true;}}}
return _isVisible;}
__exports.getQuadrance=getQuadrance;function getQuadrance(rect,pos){let q=0;if(pos.x<rect.x){q+=(rect.x-pos.x)**2;}else if(rect.x+rect.width<pos.x){q+=(pos.x-(rect.x+rect.width))**2;}
if(pos.y<rect.y){q+=(rect.y-pos.y)**2;}else if(rect.y+rect.height<pos.y){q+=(pos.y-(rect.y+rect.height))**2;}
return q;}
__exports.getVisibleElements=getVisibleElements;function getVisibleElements(activeElement,selector){const visibleElements=[];const elements=activeElement.querySelectorAll(selector);for(const el of elements){if(isVisible(el)){visibleElements.push(el);}}
return visibleElements;}
__exports.touching=touching;function touching(elements,targetRect){const r1={x:0,y:0,width:0,height:0,...targetRect};return[...elements].filter((el)=>{const r2=el.getBoundingClientRect();return(r2.x+r2.width>=r1.x&&r2.x<=r1.x+r1.width&&r2.y+r2.height>=r1.y&&r2.y<=r1.y+r1.height);});}
const TABABLE_SELECTOR=["[tabindex]","a","area","button","frame","iframe","input","object","select","textarea","details > summary:nth-child(1)",].map((sel)=>`${sel}:not([tabindex="-1"]):not(:disabled)`).join(",");__exports.getTabableElements=getTabableElements;function getTabableElements(container=document.body){const elements=[...container.querySelectorAll(TABABLE_SELECTOR)].filter(isVisible);const byTabIndex={};for(const el of[...elements]){if(!byTabIndex[el.tabIndex]){byTabIndex[el.tabIndex]=[];}
byTabIndex[el.tabIndex].push(el);}
const withTabIndexZero=byTabIndex[0]||[];delete byTabIndex[0];return[...Object.values(byTabIndex).flat(),...withTabIndexZero];}
__exports.getNextTabableElement=getNextTabableElement;function getNextTabableElement(container=document.body){const tabableElements=getTabableElements(container);const index=tabableElements.indexOf(document.activeElement);return index===-1?tabableElements[0]:tabableElements[index+1]||null;}
__exports.getPreviousTabableElement=getPreviousTabableElement;function getPreviousTabableElement(container=document.body){const tabableElements=getTabableElements(container);const index=tabableElements.indexOf(document.activeElement);return index===-1?tabableElements[tabableElements.length-1]:tabableElements[index-1]||null;}
return __exports;});;

/* /web/static/src/core/utils/urls.js */
odoo.define('@web/core/utils/urls',['@web/session','@web/core/browser/browser'],function(require){'use strict';let __exports={};const{session}=require("@web/session");const{browser}=require("@web/core/browser/browser");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.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=_url.href;}
return __exports;});;

/* /web/static/src/core/utils/xml.js */
odoo.define('@web/core/utils/xml',[],function(require){'use strict';let __exports={};const serializer=new XMLSerializer();const parser=new DOMParser();const xmlDocument=parser.parseFromString("<templates/>","text/xml");function hasParsingError(parsedDocument){return parsedDocument.getElementsByTagName("parsererror").length>0;}
__exports.parseXML=parseXML;function parseXML(str){const xml=parser.parseFromString(str,"text/xml");if(hasParsingError(xml)){throw new Error(`An error occured while parsing ${str}: ${xml.getElementsByTagName("parsererror")}`);}
return xml.documentElement;}
__exports.serializeXML=serializeXML;function serializeXML(xml){return serializer.serializeToString(xml);}
__exports.visitXML=visitXML;function visitXML(xml,callback){const visit=(el)=>{if(el){let didVisitChildren=false;const visitChildren=()=>{for(const child of el.children){visit(child);}
didVisitChildren=true;};const shouldVisitChildren=callback(el,visitChildren);if(shouldVisitChildren!==false&&!didVisitChildren){visitChildren();}}};const xmlDoc=typeof xml==="string"?parseXML(xml):xml;visit(xmlDoc);}
__exports.append=append;function append(parent,node){const nodes=Array.isArray(node)?node:[node];parent.append(...nodes.filter(Boolean));return parent;}
__exports.combineAttributes=combineAttributes;function combineAttributes(el,attr,parts,glue=" "){const allValues=[];if(el.hasAttribute(attr)){allValues.push(el.getAttribute(attr));}
parts=Array.isArray(parts)?parts:[parts];parts=parts.filter((part)=>!!part);allValues.push(...parts);el.setAttribute(attr,allValues.join(glue));}
__exports.createElement=createElement;function createElement(tagName,...args){const el=xmlDocument.createElement(tagName);for(const arg of args){if(!arg){continue;}
if(Symbol.iterator in 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_hook.js */
odoo.define('@web/core/virtual_hook',['@odoo/owl','@web/core/utils/arrays','@web/core/utils/timing'],function(require){'use strict';let __exports={};const{onWillRender,onWillStart,toRaw,useEffect,useExternalListener,useState,}=require("@odoo/owl");const{shallowEqual}=require("@web/core/utils/arrays");const{useThrottleForAnimation}=require("@web/core/utils/timing");__exports.useVirtual=useVirtual;function useVirtual({getItems,scrollableRef,initialScroll,getItemHeight}){const computeVirtualItems=()=>{const{items,scroll}=current;const yStart=scroll.top-window.innerHeight;const yEnd=scroll.top+2*window.innerHeight;let[startIndex,endIndex]=[0,0];let currentTop=0;for(const item of items){const height=getItemHeight(item);if(currentTop+height<yStart){startIndex++;endIndex++;}else if(currentTop+height<=yEnd+height){endIndex++;}else{break;}
currentTop+=height;}
const prevItems=toRaw(virtualItems);const newItems=items.slice(startIndex,endIndex);if(!shallowEqual(prevItems,newItems)){virtualItems.length=0;virtualItems.push(...newItems);}};const current={items:getItems(),scroll:{top:0,...initialScroll},};const virtualItems=useState([]);onWillStart(computeVirtualItems);onWillRender(()=>{const previousItems=current.items;current.items=getItems();if(!shallowEqual(previousItems,current.items)){computeVirtualItems();}});const throttledCompute=useThrottleForAnimation(computeVirtualItems);const scrollListener=(ev)=>{current.scroll.top=ev.target.scrollTop;throttledCompute();};useExternalListener(window,"resize",throttledCompute);useEffect((el)=>{if(el){el.addEventListener("scroll",scrollListener);return()=>el.removeEventListener("scroll",scrollListener);}},()=>[scrollableRef.el]);return virtualItems;}
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{_t}=require("@web/core/l10n/translation");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{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());}}
HotkeyCommandItem.template="web.HotkeyCommandItem";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/strings','@odoo/owl'],function(require){'use strict';let __exports={};const{Dialog}=require("@web/core/dialog/dialog");const{useHotkey}=require("@web/core/hotkeys/hotkey_hook");const{_t}=require("@web/core/l10n/translation");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{escapeRegExp}=require("@web/core/utils/strings");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;};}
__exports.splitCommandName=splitCommandName;function splitCommandName(name,searchValue){if(name){const splitName=name.split(new RegExp(`(${escapeRegExp(searchValue)})`,"ig"));return searchValue.length&&splitName.length>1?splitName:[name];}
return[];}
const DefaultCommandItem=__exports.DefaultCommandItem=class DefaultCommandItem extends Component{}
DefaultCommandItem.template="web.DefaultCommandItem";DefaultCommandItem.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{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++,splitName:splitCommandName(command.name,options.searchValue),})));this.selectCommand(this.state.commands.length?0:-1);this.mouseSelectionActive=false;this.state.emptyMessage=(namespaceConfig.emptyMessage||DEFAULT_EMPTY_MESSAGE).toString();}
selectCommand(index){if(index===-1||index>=this.state.commands.length){this.state.selectedCommand=null;return;}
this.state.selectedCommand=markRaw(this.state.commands[index]);}
selectCommandAndScrollTo(type){this.mouseSelectionActive=false;const index=this.state.commands.indexOf(this.state.selectedCommand);if(index===-1){return;}
let nextIndex;if(type==="NEXT"){nextIndex=index<this.state.commands.length-1?index+1:0;}else if(type==="PREV"){nextIndex=index>0?index-1:this.state.commands.length-1;}
this.selectCommand(nextIndex);const command=this.listboxRef.el.querySelector(`#o_command_${nextIndex}`);scrollTo(command,{scrollable:this.listboxRef.el});}
onCommandClicked(event,index){event.preventDefault();this.selectCommand(index);const ctrlKey=isMacOS()?event.metaKey:event.ctrlKey;this.executeSelectedCommand(ctrlKey);}
async executeCommand(command){const config=await command.action();if(config){this.setCommandPaletteConfig(config);}else{this.props.close();}}
async executeSelectedCommand(ctrlKey){await this.searchValuePromise;const selectedCommand=this.state.selectedCommand;if(selectedCommand){if(!ctrlKey){this.executeCommand(selectedCommand);}else if(selectedCommand.href){window.open(selectedCommand.href,"_blank");}}}
onCommandMouseEnter(index){if(this.mouseSelectionActive){this.selectCommand(index);}else{this.mouseSelectionActive=true;}}
async search(searchValue){await this.setCommands(this.state.namespace,{searchValue,activeElement:this.activeElement,sessionId:this._sessionId,});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();}}
CommandPalette.lastSessionId=0;CommandPalette.props={bus:{type:EventBus,optional:true},close:Function,config:Object,closeMe:{type:Function,optional:true},};CommandPalette.template="web.CommandPalette";CommandPalette.components={Dialog};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{_t}=require("@web/core/l10n/translation");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/public_component_service.js */
odoo.define('@web/public/public_component_service',['@odoo/owl','@web/core/registry','@web/core/assets','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{App}=require("@odoo/owl");const{registry}=require("@web/core/registry");const{templates}=require("@web/core/assets");const{_t}=require("@web/core/l10n/translation");class ComponentManager{constructor(env){this.env=env;this.appConfig={templates,env:env,dev:env.debug,translateFn:_t,translatableAttributes:["data-tooltip"],};this.apps=new Map();}
async mountComponents(){for(const[key,component]of registry.category("public_components").getEntries()){for(const el of document.querySelectorAll(`owl-component[name="${CSS.escape(key)}"]`)){if(!this.apps.has(el)){const props=JSON.parse(el.getAttribute("props")||"{}");const app=new App(component,{...this.appConfig,props,});this.apps.set(el,{app,mountProm:app.mount(el)});}}}
await Promise.all([...this.apps.values()].map(({mountProm})=>mountProm));}
destroyComponents(){for(const{app}of this.apps.values()){app.destroy();}
this.apps.clear();}}
const publicComponentService=__exports.publicComponentService={start(env){return new ComponentManager(env);},};registry.category("services").add("public_component",publicComponentService);return __exports;});;

/* /web/static/src/public/datetime_picker_widget.js */
odoo.define('@web/public/datetime_picker_widget',['@web/core/l10n/dates','@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const{deserializeDate,deserializeDateTime,parseDate,parseDateTime,}=require("@web/core/l10n/dates");const PublicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const DateTimePickerWidget=__exports.DateTimePickerWidget=PublicWidget.Widget.extend({selector:"[data-widget='datetime-picker']",start(){this._super(...arguments);const{widgetType,minDate,maxDate}=this.el.dataset;const type=widgetType||"datetime";const{value}=this.el;const[parse,deserialize]=type==="date"?[parseDate,deserializeDate]:[parseDateTime,deserializeDateTime];this.disable=this.call("datetime_picker","create",{target:this.el,pickerProps:{type,minDate:minDate&&deserialize(minDate),maxDate:maxDate&&deserialize(maxDate),value:parse(value),},}).enable();},destroy(){this.disable();return this._super(...arguments);},});PublicWidget.registry.DateTimePickerWidget=DateTimePickerWidget;return __exports;});;

/* /web/static/src/libs/pdfjs.js */
odoo.define('@web/libs/pdfjs',['@web/core/browser/feature_detection'],function(require){'use strict';let __exports={};const{isMobileOS}=require("@web/core/browser/feature_detection");__exports.hidePDFJSButtons=hidePDFJSButtons;function hidePDFJSButtons(rootElement){const cssStyle=document.createElement("style");cssStyle.rel="stylesheet";cssStyle.textContent=`button#secondaryOpenFile.secondaryToolbarButton, button#openFile.toolbarButton,
a#secondaryViewBookmark.secondaryToolbarButton, a#viewBookmark.toolbarButton {
display: none !important;
}`;if(isMobileOS()){cssStyle.textContent=`${cssStyle.innerHTML}
button#secondaryDownload.secondaryToolbarButton, button#download.toolbarButton,
button#secondaryPrint.secondaryToolbarButton, button#print.toolbarButton{
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");}}
return __exports;});;

/* /web/static/src/legacy/js/public/public_root.js */
odoo.define('@web/legacy/js/public/public_root',['@web/legacy/js/core/dom','@web/core/browser/cookie','@web/legacy/js/public/public_widget','@web/core/registry','@web/legacy/js/public/lazyloader','@web/env','@web/core/assets','@web/core/main_components_container','@web/core/browser/browser','@web/core/l10n/translation','@odoo/owl','@web/core/network/rpc_service'],function(require){'use strict';let __exports={};const dom=require('@web/legacy/js/core/dom')[Symbol.for("default")];const{cookie}=require("@web/core/browser/cookie");const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const{registry}=require('@web/core/registry');const lazyloader=require("@web/legacy/js/public/lazyloader")[Symbol.for("default")];const{makeEnv,startServices}=require("@web/env");const{templates}=require('@web/core/assets');const{MainComponentsContainer}=require("@web/core/main_components_container");const{browser}=require('@web/core/browser/browser');const{_t}=require("@web/core/l10n/translation");const{App,Component,whenReady}=require("@odoo/owl");const{RPCError}=require('@web/core/network/rpc_service');const{Settings}=luxon;function getLang(){var html=document.documentElement;return(html.getAttribute('lang')||'en_US').replace('-','_');}
const lang=cookie.get('frontend_lang')||getLang();const PublicRoot=__exports.PublicRoot=publicWidget.RootWidget.extend({events:Object.assign({},publicWidget.RootWidget.prototype.events||{},{'submit .js_website_submit_form':'_onWebsiteFormSubmit','click .js_disable_on_click':'_onDisableOnClick',}),custom_events:Object.assign({},publicWidget.RootWidget.prototype.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=[];},start:function(){var defs=[this._super.apply(this,arguments),this._startWidgets()];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;},_getRegistry:function(){return registry.category("public_root_widgets");},_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);var defs=Object.values(this._getPublicWidgetsRegistry(options)).map((PublicWidget)=>{var selector=PublicWidget.prototype.selector||'';var $target=dom.cssFind($from,selector,true);var defs=Array.from($target).map((el)=>{var widget=new PublicWidget(self,options);self.publicWidgets.push(widget);return widget.attachTo($(el));});return Promise.all(defs);});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,});},_onWidgetsStartRequest:function(ev){this._startWidgets(ev.data.$target,ev.data.options).then(ev.data.onSuccess).catch((e)=>{if(ev.data.onFailure){ev.data.onFailure(e);}
if(!(e instanceof RPCError)){return Promise.reject(e);}});},_onWidgetsStopRequest:function(ev){this._stopWidgets(ev.data.$target);},_onWebsiteFormSubmit:function(ev){var $buttons=$(ev.currentTarget).find('button[type="submit"], a.a-submit').toArray();$buttons.forEach((btn)=>{var $btn=$(btn);$btn.prepend('<i class="fa fa-circle-o-notch fa-spin"></i> ');$btn.prop('disabled',true);});},_onDisableOnClick:function(ev){$(ev.currentTarget).addClass('disabled');},_onDateTimePickerError:function(ev){return false;},});__exports.createPublicRoot=createPublicRoot;async function createPublicRoot(RootWidget){await lazyloader.allScriptsLoaded;await whenReady();const env=makeEnv();await startServices(env);Component.env=env;await env.services.public_component.mountComponents();const publicRoot=new RootWidget(null,env);const app=new App(MainComponentsContainer,{templates,env,dev:env.debug,translateFn:_t,translatableAttributes:["data-tooltip"],});const language=lang||browser.navigator.language;const locale=language==="sr@latin"?"sr-Latn-RS":language.replace(/_/g,"-");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;});;

/* /website/static/src/js/content/website_root_instance.js */
odoo.define('@website/js/content/website_root_instance',['@web/legacy/js/public/public_root','@web/legacy/js/public/lazyloader','@website/js/content/website_root','@web/core/assets'],function(require){'use strict';let __exports={};const{createPublicRoot}=require("@web/legacy/js/public/public_root");const lazyloader=require("@web/legacy/js/public/lazyloader")[Symbol.for("default")];const{WebsiteRoot}=require("@website/js/content/website_root");const{loadBundle}=require("@web/core/assets");const prom=createPublicRoot(WebsiteRoot).then(async rootInstance=>{if(window.frameElement&&window.frameElement.dataset.loadWysiwyg==='true'){await loadBundle("website.assets_all_wysiwyg");window.dispatchEvent(new CustomEvent('PUBLIC-ROOT-READY',{detail:{rootInstance}}));}
return rootInstance;});lazyloader.registerPageReadinessDelay(prom);__exports[Symbol.for("default")]=prom;return __exports;});odoo.define(`root.widget`,['@website/js/content/website_root_instance'],function(require){return require('@website/js/content/website_root_instance')[Symbol.for("default")];});;

/* /web/static/src/legacy/js/public/public_widget.js */
odoo.define('@web/legacy/js/public/public_widget',['@web/legacy/js/core/dom','@web/legacy/js/core/class','@web/legacy/js/core/mixins','@web/legacy/js/core/service_mixins','@web/core/assets','@web/core/utils/render'],function(require){'use strict';let __exports={};const dom=require('@web/legacy/js/core/dom')[Symbol.for("default")];const Class=require("@web/legacy/js/core/class")[Symbol.for("default")];const mixins=require("@web/legacy/js/core/mixins")[Symbol.for("default")];const ServicesMixin=require("@web/legacy/js/core/service_mixins")[Symbol.for("default")];const{loadBundle}=require('@web/core/assets');const{renderToElement}=require("@web/core/utils/render");const PublicWidget=__exports.PublicWidget=Class.extend(mixins.PropertiesMixin,ServicesMixin,{tagName:'div',id:null,className:null,attributes:{},template:null,cssLibs:null,jsLibs:null,assetLibs:null,selector:false,events:{},init:function(parent,options){mixins.PropertiesMixin.init.call(this);this.setParent(parent);this.options=options||{};},willStart:function(){var proms=[];if(this.jsLibs||this.cssLibs||this.assetLibs){proms.push(loadBundle(this));}
return Promise.all(proms);},start:function(){return Promise.resolve();},destroy:function(){mixins.PropertiesMixin.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=dom.makeButtonHandler(method);}else{method=dom.makeAsyncHandler(method);}
_delegateEvent(method,event);});},_getContext:function(extra,extraContext){var context;this.trigger_up('context_get',{extra:extra||false,context:extraContext,callback:function(ctx){context=ctx;},});return context;},_makeDescriptive:function(){var attrs=Object.assign({},this.attributes||{});if(this.id){attrs.id=this.id;}
if(this.className){attrs['class']=this.className;}
var $el=$(document.createElement(this.tagName));if(Object.keys(attrs||{}).length>0){$el.attr(attrs);}
return $el;},_replaceElement:function($el){var $oldel=this.$el;this.setElement($el);if($oldel&&!$oldel.is(this.$el)){if($oldel.length>1){$oldel.wrapAll('<div/>');$oldel.parent().replaceWith(this.$el);}else{$oldel.replaceWith(this.$el);}}
return this;},_undelegateEvents:function(){this.$el.off('.widget_events');},_widgetRenderAndInsert:function(insertion,target){var self=this;return this.willStart().then(function(){if(self.__parentedDestroyed){return;}
self.renderElement();insertion(target);return self.start();});},});var RootWidget=PublicWidget.extend({init:function(){this._super.apply(this,arguments);this._widgets=[];},start:function(){var defs=[this._super.apply(this,arguments)];defs.push(this._attachComponents());this._getRegistry().addEventListener("UPDATE",({detail})=>{const{operation,value}=detail;if(operation==="add"){this._attachComponent(value);}});return Promise.all(defs);},_attachComponent:function(childInfo,$from){var self=this;var $elements=dom.cssFind($from||this.$el,childInfo.selector);var defs=Array.from($elements).map((element)=>{var w=new childInfo.Widget(self);self._widgets.push(w);return w.attachTo(element);});return Promise.all(defs);},_attachComponents:function($from){var self=this;var childInfos=this._getRegistry().getAll();var defs=childInfos.map((childInfo)=>{return self._attachComponent(childInfo,$from);});return Promise.all(defs);},_getRegistry:function(){},});var registry={};__exports[Symbol.for("default")]={RootWidget:RootWidget,Widget:PublicWidget,registry:registry,};return __exports;});;

/* /web/static/src/legacy/js/public/signin.js */
odoo.define('@web/legacy/js/public/signin',['@web/legacy/js/core/dom','@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const dom=require('@web/legacy/js/core/dom')[Symbol.for("default")];const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];publicWidget.registry.login=publicWidget.Widget.extend({selector:'.oe_login_form',events:{'submit':'_onSubmit',},_onSubmit(ev){if(!ev.isDefaultPrevented()){const btnEl=ev.currentTarget.querySelector('button[type="submit"]');const removeLoadingEffect=dom.addButtonLoadingEffect(btnEl);const oldPreventDefault=ev.preventDefault.bind(ev);ev.preventDefault=()=>{removeLoadingEffect();oldPreventDefault();};}},});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/im_status_service.js */
odoo.define('@bus/im_status_service',['@web/core/browser/browser','@web/core/registry','@web/session'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{session}=require("@web/session");const AWAY_DELAY=__exports.AWAY_DELAY=30*60*1000;const FIRST_UPDATE_DELAY=__exports.FIRST_UPDATE_DELAY=500;const UPDATE_BUS_PRESENCE_DELAY=__exports.UPDATE_BUS_PRESENCE_DELAY=60000;const imStatusService=__exports.imStatusService={dependencies:["bus_service","presence","user"],start(env,{bus_service,presence,user}){let lastSentInactivity;let becomeAwayTimeout;const updateBusPresence=()=>{lastSentInactivity=presence.getInactivityPeriod();startAwayTimeout();bus_service.send("update_presence",{inactivity_period:lastSentInactivity,im_status_ids_by_model:{},});};this.updateBusPresence=updateBusPresence;const startAwayTimeout=()=>{clearTimeout(becomeAwayTimeout);const awayTime=AWAY_DELAY-lastSentInactivity;if(awayTime>0){becomeAwayTimeout=browser.setTimeout(()=>updateBusPresence(),awayTime);}};bus_service.addEventListener("connect",()=>updateBusPresence(),{once:true});bus_service.subscribe("bus.bus/im_status_updated",async({partner_id,im_status})=>{if(session.is_public||!partner_id||partner_id!==user.partnerId){return;}
const isOnline=presence.getInactivityPeriod()<AWAY_DELAY;if(im_status==="offline"||(im_status==="away"&&isOnline)){this.updateBusPresence();}});presence.bus.addEventListener("presence",()=>{if(lastSentInactivity>=AWAY_DELAY){this.updateBusPresence();}
startAwayTimeout();});return{registerToImStatus(model,ids){},unregisterFromImStatus(model){},};},};registry.category("services").add("im_status",imStatusService);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:Date.now();timeout=null;result=func.apply(context,args);if(!timeout){context=args=null;}};const throttled=function(){const _now=Date.now();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_service.js */
odoo.define('@bus/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");let multiTabId=0;const multiTabService=__exports.multiTabService={start(){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;const PRIVATE_LOCAL_STORAGE_KEYS=["main","heartbeat"];let _isOnMainTab=false;let lastHeartbeat=0;let heartbeatTimeout;const sanitizedOrigin=location.origin.replace(/:\/{0,2}/g,"_");const localStoragePrefix=`${this.name}.${sanitizedOrigin}.`;const now=new Date().getTime();const tabId=`${this.name}${multiTabId++}:${now}`;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 startElection(){if(_isOnMainTab){return;}
const now=new Date().getTime();const lastPresenceByTab=getItemFromStorage("lastPresenceByTab",{});const heartbeatKillOld=now-HEARTBEAT_KILL_OLD_PERIOD;let newMain;for(const[tab,lastPresence]of Object.entries(lastPresenceByTab)){if(lastPresence<heartbeatKillOld){continue;}
newMain=tab;break;}
if(newMain===tabId){lastHeartbeat=now;setItemInStorage("heartbeat",lastHeartbeat);setItemInStorage("main",true);_isOnMainTab=true;bus.trigger("become_main_tab");delete lastPresenceByTab[newMain];setItemInStorage("lastPresenceByTab",lastPresenceByTab);}}
function heartbeat(){const now=new Date().getTime();let heartbeatValue=getItemFromStorage("heartbeat",0);const lastPresenceByTab=getItemFromStorage("lastPresenceByTab",{});if(heartbeatValue+HEARTBEAT_OUT_OF_DATE_PERIOD<now){startElection();heartbeatValue=getItemFromStorage("heartbeat",0);}
if(_isOnMainTab){const cleanedTabs={};for(const[tabId,lastPresence]of Object.entries(lastPresenceByTab)){if(lastPresence+HEARTBEAT_KILL_OLD_PERIOD>now){cleanedTabs[tabId]=lastPresence;}}
if(heartbeatValue!==lastHeartbeat){_isOnMainTab=false;lastHeartbeat=0;lastPresenceByTab[tabId]=now;setItemInStorage("lastPresenceByTab",lastPresenceByTab);bus.trigger("no_longer_main_tab");}else{lastHeartbeat=now;setItemInStorage("heartbeat",now);setItemInStorage("lastPresenceByTab",cleanedTabs);}}else{lastPresenceByTab[tabId]=now;setItemInStorage("lastPresenceByTab",lastPresenceByTab);}
const hbPeriod=_isOnMainTab?MAIN_TAB_HEARTBEAT_PERIOD:TAB_HEARTBEAT_PERIOD;heartbeatTimeout=browser.setTimeout(heartbeat,hbPeriod);}
function onStorage({key,newValue}){if(key===generateLocalStorageKey("main")&&!newValue){startElection();}
if(PRIVATE_LOCAL_STORAGE_KEYS.includes(key)){return;}
if(key&&key.includes(localStoragePrefix)){const baseKey=key.replace(localStoragePrefix,"");bus.trigger("shared_value_updated",{key:baseKey,newValue});}}
function unregister(){clearTimeout(heartbeatTimeout);const lastPresenceByTab=getItemFromStorage("lastPresenceByTab",{});delete lastPresenceByTab[tabId];setItemInStorage("lastPresenceByTab",lastPresenceByTab);if(_isOnMainTab){_isOnMainTab=false;bus.trigger("no_longer_main_tab");browser.localStorage.removeItem(generateLocalStorageKey("main"));}}
browser.addEventListener("pagehide",unregister);browser.addEventListener("storage",onStorage);const lastPresenceByTab=getItemFromStorage("lastPresenceByTab",{});lastPresenceByTab[tabId]=now;setItemInStorage("lastPresenceByTab",lastPresenceByTab);if(!getItemFromStorage("main")){startElection();}
heartbeat();return{bus,get currentTabId(){return tabId;},isOnMainTab(){return _isOnMainTab;},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));},unregister:unregister,};},};registry.category("services").add("multi_tab",multiTabService);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','@web/core/browser/feature_detection','@odoo/owl'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{_t}=require("@web/core/l10n/translation");const{Deferred}=require("@web/core/utils/concurrency");const{registry}=require("@web/core/registry");const{session}=require("@web/session");const{isIosApp}=require("@web/core/browser/feature_detection");const{EventBus}=require("@odoo/owl");const INTERNAL_EVENTS=new Set(["initialized","outdated"]);const busService=__exports.busService={dependencies:["bus.parameters","localization","multi_tab","notification"],async:true,start(env,{multi_tab:multiTab,notification,"bus.parameters":params}){const bus=new EventBus();const notificationBus=new EventBus();let worker;let isActive=false;let isInitialized=false;let isUsingSharedWorker=browser.SharedWorker&&!isIosApp();const startedAt=luxon.DateTime.now().set({milliseconds:0});const connectionInitializedDeferred=new Deferred();function send(action,data){if(!worker){return;}
const message={action,data};if(isUsingSharedWorker){worker.port.postMessage(message);}else{worker.postMessage(message);}}
function handleMessage(messageEv){const{type}=messageEv.data;let{data}=messageEv.data;switch(type){case"notification":{data.forEach((d)=>(d.message.id=d.id));multiTab.setSharedValue("last_notification_id",data[data.length-1].id);data=data.map((notification)=>notification.message);for(const{type,payload}of data){notificationBus.trigger(type,payload);}
break;}
case"initialized":{isInitialized=true;connectionInitializedDeferred.resolve();break;}
case"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);}}
function initializeWorkerConnection(){let uid=Array.isArray(session.user_id)?session.user_id[0]:session.user_id;if(!uid&&uid!==undefined){uid=false;}
send("initialize_connection",{websocketURL:`${params.serverURL.replace("http", "ws")}/websocket?version=${
                    session.websocket_worker_version
                }`,db:session.db,debug:odoo.debug,lastNotificationId:multiTab.getSharedValue("last_notification_id",0),uid,startTs:startedAt.valueOf(),});}
function startWorker(){let workerURL=`${params.serverURL}/bus/websocket_worker_bundle?v=${session.websocket_worker_version}`;if(params.serverURL!==window.origin){const source=`importScripts("${workerURL}");`;workerURL="data:application/javascript;base64,"+window.btoa(source);}
const workerClass=isUsingSharedWorker?browser.SharedWorker:browser.Worker;worker=new workerClass(workerURL,{name:isUsingSharedWorker?"odoo:websocket_shared_worker":"odoo:websocket_worker",});worker.addEventListener("error",(e)=>{if(!isInitialized&&workerClass===browser.SharedWorker){console.warn('Error while loading "bus_service" SharedWorker, fallback on Worker.');isUsingSharedWorker=false;startWorker();}else if(!isInitialized){isInitialized=true;connectionInitializedDeferred.resolve();console.warn("Bus service failed to initialized.");}});if(isUsingSharedWorker){worker.port.start();worker.port.addEventListener("message",handleMessage);}else{worker.addEventListener("message",handleMessage);}
initializeWorkerConnection();}
browser.addEventListener("pagehide",({persisted})=>{if(!persisted){send("leave");}});browser.addEventListener("online",()=>{if(isActive){send("start");}});browser.addEventListener("offline",()=>send("stop"));return{addEventListener:bus.addEventListener.bind(bus),addChannel:async(channel)=>{if(!worker){startWorker();await connectionInitializedDeferred;}
send("add_channel",channel);send("start");isActive=true;},deleteChannel:(channel)=>send("delete_channel",channel),forceUpdateChannels:()=>send("force_update_channels"),trigger:bus.trigger.bind(bus),removeEventListener:bus.removeEventListener.bind(bus),send:(eventName,data)=>send("send",{event_name:eventName,data}),start:async()=>{if(!worker){startWorker();await connectionInitializedDeferred;}
send("start");isActive=true;},stop:()=>{send("leave");isActive=false;},get isActive(){return isActive;},subscribe(notificationType,callback){notificationBus.addEventListener(notificationType,({detail})=>callback(detail));},startedAt,};},};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`)||new Date().getTime();function onPresence(){lastPresenceTime=new Date().getTime();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=new Date().getTime();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);browser.addEventListener("keydown",onPresence);return{bus,getLastPresence(){return lastPresenceTime;},isOdooFocused(){return isOdooFocused;},getInactivityPeriod(){return new Date().getTime()-this.getLastPresence();},};},};registry.category("services").add("presence",presenceService);return __exports;});;

/* /bus/static/src/workers/websocket_worker.js */
odoo.define('@bus/workers/websocket_worker',['@bus/workers/websocket_worker_utils'],function(require){'use strict';let __exports={};const{debounce,Deferred}=require("@bus/workers/websocket_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,});const WORKER_VERSION=__exports.WORKER_VERSION="17.0-1";const MAXIMUM_RECONNECT_DELAY=60000;const WebsocketWorker=__exports.WebsocketWorker=class WebsocketWorker{INITIAL_RECONNECT_DELAY=1000;RECONNECT_JITTER=1000;constructor(){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.isReconnecting=false;this.lastChannelSubscription=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);}
broadcast(type,data){for(const client of this.channelsByClient.keys()){client.postMessage({type,data});}}
registerClient(messagePort){messagePort.onmessage=(ev)=>{this._onClientMessage(messagePort,ev.data);};this.channelsByClient.set(messagePort,[]);}
sendToClient(client,type,data){client.postMessage({type,data});}
_onClientMessage(client,{action,data}){switch(action){case"send":{if(data["event_name"]==="update_presence"){this._debouncedSendToServer(data);}else{this._sendToServer(data);}
return;}
case"start":return this._start();case"stop":return this._stop();case"leave":return this._unregisterClient(client);case"add_channel":return this._addChannel(client,data);case"delete_channel":return this._deleteChannel(client,data);case"force_update_channels":return this._forceUpdateChannels();case"initialize_connection":return this._initializeConnection(client,data);}}
_addChannel(client,channel){const clientChannels=this.channelsByClient.get(client);if(!clientChannels.includes(channel)){clientChannels.push(channel);this.channelsByClient.set(client,clientChannels);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=Object.values(this.debugModeByClient).some((debugValue)=>debugValue!=="");this._debouncedUpdateChannels();}
_initializeConnection(client,{db,debug,lastNotificationId,uid,websocketURL,startTs}){if(this.newestStartTs&&this.newestStartTs>startTs){this.debugModeByClient[client]=debug;this.isDebug=Object.values(this.debugModeByClient).some((debugValue)=>debugValue!=="");this.sendToClient(client,"initialized");return;}
this.newestStartTs=startTs;this.websocketURL=websocketURL;this.lastNotificationId=lastNotificationId;this.debugModeByClient[client]=debug;this.isDebug=Object.values(this.debugModeByClient).some((debugValue)=>debugValue!=="");const isCurrentUserKnown=uid!==undefined;if(this.isWaitingForNewUID&&isCurrentUserKnown){this.isWaitingForNewUID=false;this.currentUID=uid;}
if((this.currentUID!==uid&&isCurrentUserKnown)||this.currentDB!==db){this.currentUID=uid;this.currentDB=db;if(this.websocket){this.websocket.close(WEBSOCKET_CLOSE_CODES.CLEAN);}
this.channelsByClient.forEach((_,key)=>this.channelsByClient.set(key,[]));}
this.sendToClient(client,"initialized");if(!this.active){this.sendToClient(client,"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}){if(this.isDebug){console.debug(`%c${new Date().toLocaleString()} - [onClose]`,"color: #c6e; font-weight: bold;",code,reason);}
this.lastChannelSubscription=null;this.firstSubscribeDeferred=new Deferred();if(this.isReconnecting){return;}
this.broadcast("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("outdated");}
return;}
this.broadcast("reconnecting",{closeCode:code});this.isReconnecting=true;if(code===WEBSOCKET_CLOSE_CODES.KEEP_ALIVE_TIMEOUT){this.connectRetryDelay=0;}
if(code===WEBSOCKET_CLOSE_CODES.SESSION_EXPIRED){this.isWaitingForNewUID=true;}
this._retryConnectionWithDelay();}
_onWebsocketError(){if(this.isDebug){console.debug(`%c${new Date().toLocaleString()} - [onError]`,"color: #c6e; font-weight: bold;");}
this._retryConnectionWithDelay();}
_onWebsocketMessage(messageEv){const notifications=JSON.parse(messageEv.data);if(this.isDebug){console.debug(`%c${new Date().toLocaleString()} - [onMessage]`,"color: #c6e; font-weight: bold;",notifications);}
this.lastNotificationId=notifications[notifications.length-1].id;this.broadcast("notification",notifications);}
_onWebsocketOpen(){if(this.isDebug){console.debug(`%c${new Date().toLocaleString()} - [onOpen]`,"color: #c6e; font-weight: bold;");}
this.broadcast(this.isReconnecting?"reconnect":"connect");this._debouncedUpdateChannels();this.connectRetryDelay=this.INITIAL_RECONNECT_DELAY;this.connectTimeout=null;this.isReconnecting=false;this.firstSubscribeDeferred.then(()=>{this.messageWaitQueue.forEach((msg)=>this.websocket.send(msg));this.messageWaitQueue=[];});}
_retryConnectionWithDelay(){this.connectRetryDelay=Math.min(this.connectRetryDelay*1.5,MAXIMUM_RECONNECT_DELAY)+
this.RECONNECT_JITTER*Math.random();this.connectTimeout=setTimeout(this._start.bind(this),this.connectRetryDelay);}
_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));}}}
_start(){if(!this.active||this._isWebsocketConnected()||this._isWebsocketConnecting()){return;}
if(this.websocket){this.websocket.removeEventListener("open",this._onWebsocketOpen);this.websocket.removeEventListener("message",this._onWebsocketMessage);this.websocket.removeEventListener("error",this._onWebsocketError);this.websocket.removeEventListener("close",this._onWebsocketClose);}
if(this._isWebsocketClosing()){this.lastChannelSubscription=null;this.broadcast("disconnect",{code:WEBSOCKET_CLOSE_CODES.ABNORMAL_CLOSURE});}
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(){clearTimeout(this.connectTimeout);this.connectRetryDelay=this.INITIAL_RECONNECT_DELAY;this.isReconnecting=false;this.lastChannelSubscription=null;if(this.websocket){this.websocket.close();}}
_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();}}}
return __exports;});;

/* /bus/static/src/workers/websocket_worker_utils.js */
odoo.define('@bus/workers/websocket_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});}}
return __exports;});;

/* /web_tour/static/src/tour_pointer/tour_pointer.js */
odoo.define('@web_tour/tour_pointer/tour_pointer',['@odoo/owl','@web/core/position_hook'],function(require){'use strict';let __exports={};const{Component,useEffect,useRef}=require("@odoo/owl");const{usePosition}=require("@web/core/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},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(){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,enumerable:true});const position=usePosition("pointer",()=>this.props.pointerState.anchor,positionOptions);const rootRef=useRef("pointer");let dimensions=null;let lastMeasuredContent=null;let lastOpenState=this.isOpen;let lastAnchor;let[anchorX,anchorY]=[0,0];useEffect(()=>{const{el:pointer}=rootRef;if(pointer){const hasContentChanged=lastMeasuredContent!==this.content;const hasOpenStateChanged=lastOpenState!==this.isOpen;lastOpenState=this.isOpen;if(hasContentChanged){lastMeasuredContent=this.content;pointer.style.removeProperty("width");pointer.style.removeProperty("height");dimensions=pointer.getBoundingClientRect();}
if(hasContentChanged||hasOpenStateChanged){const[width,height]=this.isOpen?[dimensions.width,dimensions.height]:[this.constructor.width,this.constructor.height];if(this.isOpen){pointer.style.removeProperty("transition");}else{pointer.style.setProperty("transition","none");}
pointer.style.setProperty("width",`${width}px`);pointer.style.setProperty("height",`${height}px`);}
if(!this.isOpen){const{anchor}=this.props.pointerState;if(anchor===lastAnchor){const{x,y,width}=anchor.getBoundingClientRect();const[lastAnchorX,lastAnchorY]=[anchorX,anchorY];[anchorX,anchorY]=[x,y];const delta=Math.sqrt(Math.pow(x-lastAnchorX,2)+Math.pow(y-lastAnchorY,2));if(delta<1){position.lock();return;}
const wouldOverflow=window.innerWidth-x-width/2<dimensions?.width;pointer.classList.toggle("o_expand_left",wouldOverflow);}
lastAnchor=anchor;pointer.style.bottom="";pointer.style.right="";position.unlock();}}else{lastMeasuredContent=null;lastOpenState=false;lastAnchor=null;dimensions=null;}});}
get content(){return this.props.pointerState.content||"";}
get isOpen(){return this.props.pointerState.isOpen;}
get position(){return this.props.pointerState.position||"top";}}
return __exports;});;

/* /web_tour/static/src/tour_service/tour_compilers.js */
odoo.define('@web_tour/tour_service/tour_compilers',['@web/core/browser/browser','@web/core/utils/timing','@web/core/utils/ui','@web_tour/tour_service/tour_state','@web_tour/tour_service/tour_utils'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{debounce}=require("@web/core/utils/timing");const{isVisible}=require("@web/core/utils/ui");const{tourState}=require("@web_tour/tour_service/tour_state");const{callWithUnloadCheck,getConsumeEventType,getFirstVisibleElement,getJQueryElementFromSelector,getScrollParent,RunningTourActionHelper,}=require("@web_tour/tour_service/tour_utils");function findTrigger(selector,inModal,shadowDOM){const $target=$(shadowDOM?document.querySelector(shadowDOM)?.shadowRoot:document);const $visibleModal=$target.find(".modal:visible").last();let $el;if(inModal!==false&&$visibleModal.length){$el=$visibleModal.find(selector);}else{$el=getJQueryElementFromSelector(selector,$target);}
return getFirstVisibleElement($el).get(0);}
function findExtraTrigger(selector,shadowDOM){const $target=$(shadowDOM?document.querySelector(shadowDOM)?.shadowRoot:document);const $el=getJQueryElementFromSelector(selector,$target);return getFirstVisibleElement($el).get(0);}
function findStepTriggers(step){const triggerEl=findTrigger(step.trigger,step.in_modal,step.shadow_dom);const altEl=findTrigger(step.alt_trigger,step.in_modal,step.shadow_dom);const skipEl=findTrigger(step.skip_trigger,step.in_modal,step.shadow_dom);const extraTriggerOkay=step.extra_trigger?findExtraTrigger(step.extra_trigger,step.shadow_dom):true;return{triggerEl,altEl,extraTriggerOkay,skipEl};}
function describeStep(step){return step.content?`${step.content} (trigger: ${step.trigger})`:step.trigger;}
function describeFailedStepSimple(step,tour){return`Tour ${tour.name} failed at step ${describeStep(step)}`;}
function describeFailedStepDetailed(step,tour){const offset=3;const stepIndex=tour.steps.findIndex((s)=>s===step);const start=stepIndex-offset>=0?stepIndex-offset:0;const end=stepIndex+offset+1<=tour.steps.length?stepIndex+offset+1:tour.steps.length;let result="";for(let i=start;i<end;i++){const highlight=i===stepIndex;const stepString=JSON.stringify(tour.steps[i],(_key,value)=>{if(typeof value==="function"){return"[function]";}else{return value;}},2);result+=`\n${highlight ? "----- FAILING STEP -----\n" : ""}${stepString},${
            highlight ? "\n-----------------------" : ""
        }`;}
return`${describeFailedStepSimple(step, tour)}\n\n${result.trim()}`;}
function getAnchorEl(el,consumeEvent){if(consumeEvent==="drag"){return el.closest(".ui-draggable, .o_draggable");}
if(consumeEvent==="input"&&!["textarea","input"].includes(el.tagName.toLowerCase())){return el.closest("[contenteditable='true']");}
if(consumeEvent==="sort"){return el.closest(".ui-sortable, .o_sortable");}
return el;}
function canContinue(el,step){const rootNode=el.getRootNode();const isInDoc=rootNode instanceof ShadowRoot?el.ownerDocument.contains(rootNode.host):el.ownerDocument.contains(el);const isElement=el instanceof el.ownerDocument.defaultView.Element||el instanceof Element;const isBlocked=document.body.classList.contains("o_ui_blocked")||document.querySelector(".o_blockUI");return(isInDoc&&isElement&&!isBlocked&&(!step.allowInvisible?isVisible(el):true)&&(!el.disabled||step.isCheck));}
function setupListeners({anchorEl,consumeEvent,onMouseEnter,onMouseLeave,onScroll,onConsume,}){anchorEl.addEventListener(consumeEvent,onConsume);anchorEl.addEventListener("mouseenter",onMouseEnter);anchorEl.addEventListener("mouseleave",onMouseLeave);const cleanups=[()=>{anchorEl.removeEventListener(consumeEvent,onConsume);anchorEl.removeEventListener("mouseenter",onMouseEnter);anchorEl.removeEventListener("mouseleave",onMouseLeave);},];const scrollEl=getScrollParent(anchorEl);if(scrollEl){const debouncedOnScroll=debounce(onScroll,50);scrollEl.addEventListener("scroll",debouncedOnScroll);cleanups.push(()=>scrollEl.removeEventListener("scroll",debouncedOnScroll));}
return()=>{while(cleanups.length){cleanups.pop()();}};}
__exports.compileStepManual=compileStepManual;function compileStepManual(stepIndex,step,options){const{tour,pointer,onStepConsummed}=options;let proceedWith=null;let removeListeners=()=>{};return[{action:()=>console.log(step.trigger),},{trigger:()=>{removeListeners();if(proceedWith){return proceedWith;}
const{triggerEl,altEl,extraTriggerOkay,skipEl}=findStepTriggers(step);if(skipEl){return skipEl;}
const stepEl=extraTriggerOkay&&(triggerEl||altEl);if(stepEl&&canContinue(stepEl,step)){const consumeEvent=step.consumeEvent||getConsumeEventType(stepEl,step.run);const anchorEl=getAnchorEl(stepEl,consumeEvent);const debouncedToggleOpen=debounce(pointer.showContent,50,true);const updatePointer=()=>{pointer.setState({onMouseEnter:()=>debouncedToggleOpen(true),onMouseLeave:()=>debouncedToggleOpen(false),});pointer.pointTo(anchorEl,step);};removeListeners=setupListeners({anchorEl,consumeEvent,onMouseEnter:()=>pointer.showContent(true),onMouseLeave:()=>pointer.showContent(false),onScroll:updatePointer,onConsume:()=>{proceedWith=stepEl;pointer.hide();},});updatePointer();}else{pointer.hide();}},action:()=>{tourState.set(tour.name,"currentIndex",stepIndex+1);pointer.hide();proceedWith=null;onStepConsummed(tour,step);},},];}
let tourTimeout;__exports.compileStepAuto=compileStepAuto;function compileStepAuto(stepIndex,step,options){const{tour,pointer,stepDelay,keepWatchBrowser,showPointerDuration,onStepConsummed}=options;let skipAction=false;return[{action:async()=>{await new Promise(resolve=>requestAnimationFrame(resolve))},},{action:async()=>{skipAction=false;console.log(`Tour ${tour.name} on step: '${describeStep(step)}'`);if(!keepWatchBrowser){browser.clearTimeout(tourTimeout);tourTimeout=browser.setTimeout(()=>{console.warn(describeFailedStepDetailed(step,tour));console.error(describeFailedStepSimple(step,tour));},(step.timeout||10000)+stepDelay);}
await new Promise((resolve)=>browser.setTimeout(resolve,stepDelay));},},{trigger:()=>{const{triggerEl,altEl,extraTriggerOkay,skipEl}=findStepTriggers(step);let stepEl=extraTriggerOkay&&(triggerEl||altEl);if(skipEl){skipAction=true;stepEl=skipEl;}
if(!stepEl){return false;}
return canContinue(stepEl,step)&&stepEl;},action:async(stepEl)=>{tourState.set(tour.name,"currentIndex",stepIndex+1);if(skipAction){return;}
const consumeEvent=step.consumeEvent||getConsumeEventType(stepEl,step.run);const $anchorEl=$(stepEl);if(showPointerDuration>0){pointer.pointTo($anchorEl.get(0),step);await new Promise((r)=>browser.setTimeout(r,showPointerDuration));pointer.hide();}
const actionHelper=new RunningTourActionHelper({consume_event:consumeEvent,$anchor:$anchorEl,});let result;if(typeof step.run==="function"){const willUnload=await callWithUnloadCheck(()=>step.run.call({$anchor:$anchorEl},actionHelper));result=willUnload&&"will unload";}else if(step.run!==undefined){const m=step.run.match(/^([a-zA-Z0-9_]+) *(?:\(? *(.+?) *\)?)?$/);actionHelper[m[1]](m[2]);}else if(!step.isCheck){if(stepIndex===tour.steps.length-1){console.warn('Tour %s: ignoring action (auto) of last step',tour.name);}else{actionHelper.auto();}}
return result;},},{action:()=>{onStepConsummed(tour,step);},},];}
__exports.compileTourToMacro=compileTourToMacro;function compileTourToMacro(tour,options){const{filteredSteps,stepCompiler,pointer,stepDelay,keepWatchBrowser,showPointerDuration,checkDelay,onStepConsummed,onTourEnd,}=options;const currentStepIndex=tourState.get(tour.name,"currentIndex");return{...tour,checkDelay,steps:filteredSteps.reduce((newSteps,step,i)=>{if(i<currentStepIndex){return newSteps;}else{return[...newSteps,...stepCompiler(i,step,{tour,pointer,stepDelay,keepWatchBrowser,showPointerDuration,onStepConsummed,}),];}},[]).concat([{action(){tourState.clear(tour.name);onTourEnd(tour);clearTimeout(tourTimeout);},},]),};}
return __exports;});;

/* /web_tour/static/src/tour_service/tour_pointer_state.js */
odoo.define('@web_tour/tour_service/tour_pointer_state',['@odoo/owl','@web/core/l10n/translation','@web_tour/tour_pointer/tour_pointer','@web_tour/tour_service/tour_utils'],function(require){'use strict';let __exports={};const{reactive}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{TourPointer}=require("@web_tour/tour_pointer/tour_pointer");const{getScrollParent}=require("@web_tour/tour_service/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 targetBounds=this.currentTarget.getBoundingClientRect();if(targetBounds.bottom<this.rootBounds.height/2){this._targetPosition="out-above";}else if(targetBounds.top>this.rootBounds.height/2){this._targetPosition="out-below";}}}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)=>{intersection.setTarget(anchor);if(anchor){let{position,content}=step;switch(intersection.targetPosition){case"unknown":{break;}
case"in":{if(document.body.contains(floatingAnchor)){floatingAnchor.remove();}
setState({anchor,content,onClick:null,position,isVisible:true});break;}
default:{const onClick=()=>{anchor.scrollIntoView({behavior:"smooth",block:"nearest"});hide();};const scrollParent=getScrollParent(anchor);if(!scrollParent){setState({anchor,content,onClick:null,position,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;}
floatingAnchor.style.left=`${x + width / 2}px`;if(intersection.targetPosition==="out-below"){position="top";content=_t("Scroll down to reach the next step.");floatingAnchor.style.top=`${y + height - TourPointer.height}px`;}else if(intersection.targetPosition==="out-above"){position="bottom";content=_t("Scroll up to reach the next step.");floatingAnchor.style.top=`${y + TourPointer.height}px`;}
if(!document.contains(floatingAnchor)){document.body.appendChild(floatingAnchor);}
setState({anchor:floatingAnchor,content,onClick,position,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,methods:{setState,showContent,pointTo,hide,destroy}};}
return __exports;});;

/* /web_tour/static/src/tour_service/tour_service.js */
odoo.define('@web_tour/tour_service/tour_service',['@odoo/owl','@web/core/browser/browser','@web/core/l10n/translation','@web/core/macro','@web/core/registry','@web/core/transition','@web/session','@web_tour/tour_pointer/tour_pointer','@web_tour/tour_service/tour_compilers','@web_tour/tour_service/tour_pointer_state','@web_tour/tour_service/tour_state','@web_tour/tour_service/tour_utils'],function(require){'use strict';let __exports={};const{EventBus,markup,whenReady,reactive}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{_t}=require("@web/core/l10n/translation");const{MacroEngine}=require("@web/core/macro");const{registry}=require("@web/core/registry");const{config:transitionConfig}=require("@web/core/transition");const{session}=require("@web/session");const{TourPointer}=require("@web_tour/tour_pointer/tour_pointer");const{compileStepAuto,compileStepManual,compileTourToMacro}=require("@web_tour/tour_service/tour_compilers");const{createPointerState}=require("@web_tour/tour_service/tour_pointer_state");const{tourState}=require("@web_tour/tour_service/tour_state");const{callWithUnloadCheck}=require("@web_tour/tour_service/tour_utils");const tourService=__exports.tourService={dependencies:["orm","effect","ui","overlay","localization"],start:async(_env,{orm,effect,ui,overlay})=>{await whenReady();const toursEnabled="tour_disable"in session&&!session.tour_disable;const consumedTours=new Set(session.web_tours);const tours={};const tourRegistry=registry.category("web_tour.tours");function register(name,tour){name=tour.saveAs||name;const wait_for=tour.wait_for||Promise.resolve();let steps;tours[name]={wait_for,name,get steps(){if(typeof tour.steps!=="function"){throw new Error(`tour.steps has to be a function that returns TourStep[]`);}
if(!steps){steps=tour.steps().map((step)=>{step.shadow_dom=step.shadow_dom??tour.shadow_dom;return step;});}
return steps;},shadow_dom:tour.shadow_dom,url:tour.url,rainbowMan:tour.rainbowMan===undefined?true:!!tour.rainbowMan,rainbowManMessage:tour.rainbowManMessage,fadeout:tour.fadeout||"medium",sequence:tour.sequence||1000,test:tour.test,checkDelay:tour.checkDelay,};wait_for.then(()=>{if(!tour.test&&toursEnabled&&!consumedTours.has(name)&&!tourState.getActiveTourNames().includes(name)){startTour(name,{mode:"manual",redirect:false});}});}
for(const[name,tour]of tourRegistry.getEntries()){register(name,tour);}
tourRegistry.addEventListener("UPDATE",({detail:{key,value}})=>{if(tourRegistry.contains(key)){register(key,value);if(tourState.getActiveTourNames().includes(key)&&(toursEnabled||tourState.get(key,"mode")==="auto")){resumeTour(key);}}else{delete tours[value];}});const bus=new EventBus();const macroEngine=new MacroEngine({target:document});const pointers=reactive({});const runningTours=new Set();const possiblePointTos=[];function createPointer(tourName,config){const{state:pointerState,methods}=createPointerState();let remove;return{start(){pointers[tourName]={methods,id:tourName,component:TourPointer,props:{pointerState,...config},};remove=overlay.add(pointers[tourName].component,pointers[tourName].props);},stop(){remove?.();delete pointers[tourName];methods.destroy();},...methods,async pointTo(anchor,step){possiblePointTos.push([tourName,()=>methods.pointTo(anchor,step)]);await Promise.resolve();if(!possiblePointTos.length){return;}
const toursByPriority=Object.fromEntries(getSortedTours().map((t,i)=>[t.name,i]));const sortedPointTos=possiblePointTos.slice(0).sort(([a],[b])=>toursByPriority[a]-toursByPriority[b]);possiblePointTos.splice(0);const active=sortedPointTos[0];const[activeId,enablePointer]=active||[];for(const{id,methods}of Object.values(pointers)){if(id===activeId){enablePointer();}else{methods.hide();}}},};}
function shouldOmit(step,mode){const isDefined=(key,obj)=>key in obj&&obj[key]!==undefined;const getEdition=()=>(session.server_version_info||[]).at(-1)==="e"?"enterprise":"community";const correctEdition=isDefined("edition",step)?step.edition===getEdition():true;const correctDevice=isDefined("mobile",step)?step.mobile===ui.isSmall:true;return(!correctEdition||!correctDevice||(mode==="manual"&&step.auto));}
function convertToMacro(tour,pointer,{mode,stepDelay,keepWatchBrowser,showPointerDuration}){const stepCompiler=mode==="auto"?compileStepAuto:compileStepManual;const checkDelay=mode==="auto"?tour.checkDelay:100;const filteredSteps=tour.steps.filter((step)=>!shouldOmit(step,mode));return compileTourToMacro(tour,{filteredSteps,stepCompiler,pointer,stepDelay,keepWatchBrowser,showPointerDuration,checkDelay,onStepConsummed(tour,step){bus.trigger("STEP-CONSUMMED",{tour,step});},onTourEnd({name,rainbowManMessage,fadeout}){if(mode==="auto"){transitionConfig.disabled=false;}
let message;if(typeof rainbowManMessage==="function"){message=rainbowManMessage({isTourConsumed:(name)=>consumedTours.has(name),});}else if(typeof rainbowManMessage==="string"){message=rainbowManMessage;}else{message=markup(_t("<strong><b>Good job!</b> You went through all steps of this tour.</strong>"));}
effect.add({type:"rainbow_man",message,fadeout});if(mode==="manual"){consumedTours.add(name);orm.call("web_tour.tour","consume",[[name]]);}
pointer.stop();browser.console.log("test successful");runningTours.delete(name);},});}
function observeShadows(shadowHostSelectors){const observer=new MutationObserver(()=>{const shadowRoots=[];for(const selector of shadowHostSelectors){const shadowHost=document.querySelector(selector);if(shadowHost){shadowRoots.push(shadowHost.shadowRoot);shadowHostSelectors.delete(selector);}}
for(const shadowRoot of shadowRoots){macroEngine.observer.observe(shadowRoot,macroEngine.observerOptions);}
if(shadowHostSelectors.size===0){observer.disconnect();}});observer.observe(macroEngine.target,{childList:true,subtree:true});}
function setupShadowObservers(tour){const shadowDOMs=new Set(tour.steps.filter((step)=>step.shadow_dom).map((step)=>step.shadow_dom));if(shadowDOMs.size>0){observeShadows(shadowDOMs);}}
function activateMacro(macro,mode){if(mode==="auto"){transitionConfig.disabled=true;}
macroEngine.activate(macro,mode==="auto");}
function startTour(tourName,options={}){if(runningTours.has(tourName)&&options.mode==="manual"){return;}
runningTours.add(tourName);const defaultOptions={stepDelay:0,keepWatchBrowser:false,mode:"auto",startUrl:"",showPointerDuration:0,redirect:true,};options=Object.assign(defaultOptions,options);const tour=tours[tourName];if(!tour){throw new Error(`Tour '${tourName}' is not found.`);}
tourState.set(tourName,"currentIndex",0);tourState.set(tourName,"stepDelay",options.stepDelay);tourState.set(tourName,"keepWatchBrowser",options.keepWatchBrowser);tourState.set(tourName,"showPointerDuration",options.showPointerDuration);tourState.set(tourName,"mode",options.mode);tourState.set(tourName,"sequence",tour.sequence);const pointer=createPointer(tourName,{bounce:!(options.mode==="auto"&&options.keepWatchBrowser),});const macro=convertToMacro(tour,pointer,options);const willUnload=callWithUnloadCheck(()=>{if(tour.url&&tour.url!==options.startUrl&&options.redirect){window.location.href=window.location.origin+tour.url;}});if(!willUnload){setupShadowObservers(tour);pointer.start();activateMacro(macro,options.mode);}}
function resumeTour(tourName){if(runningTours.has(tourName)){return;}
runningTours.add(tourName);const tour=tours[tourName];const stepDelay=tourState.get(tourName,"stepDelay");const keepWatchBrowser=tourState.get(tourName,"keepWatchBrowser");const showPointerDuration=tourState.get(tourName,"showPointerDuration");const mode=tourState.get(tourName,"mode");const pointer=createPointer(tourName,{bounce:!(mode==="auto"&&keepWatchBrowser),});const macro=convertToMacro(tour,pointer,{mode,stepDelay,keepWatchBrowser,showPointerDuration,});setupShadowObservers(tour);pointer.start();activateMacro(macro,mode);}
function getSortedTours(){return Object.values(tours).sort((t1,t2)=>{return t1.sequence-t2.sequence||(t1.name<t2.name?-1:1);});}
if(!window.frameElement){for(const tourName of tourState.getActiveTourNames()){if(tourName in tours){resumeTour(tourName);}}}
odoo.startTour=startTour;odoo.isTourReady=(tourName)=>tours[tourName].wait_for.then(()=>true);return{bus,startTour,getSortedTours,};},};registry.category("services").add("tour_service",tourService);return __exports;});;

/* /web_tour/static/src/tour_service/tour_state.js */
odoo.define('@web_tour/tour_service/tour_state',['@web/core/browser/browser'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const BOOLEAN={toLocalStorage:(val)=>(val?"1":"0"),fromLocalStorage:(val)=>(val==="1"?true:false),};const INTEGER={toLocalStorage:(val)=>val.toString(),fromLocalStorage:(val)=>parseInt(val,10),};const STRING={toLocalStorage:(x)=>x,fromLocalStorage:(x)=>x,};const ALLOWED_KEYS={keepWatchBrowser:BOOLEAN,showPointerDuration:INTEGER,currentIndex:INTEGER,stepDelay:INTEGER,mode:STRING,sequence:INTEGER,};function getPrefixedName(tourName,key){return`tour__${tourName}__${key}`;}
function destructurePrefixedName(prefixedName){const match=prefixedName.match(/tour__([.\w]+)__([\w]+)/);return match?[match[1],match[2]]:null;}
const tourState=__exports.tourState={get(tourName,key){if(!(key in ALLOWED_KEYS)){throw new Error(`Invalid key: '${key}' (tourName = '${tourName}')`);}
const prefixedName=getPrefixedName(tourName,key);const savedValue=browser.localStorage.getItem(prefixedName);return ALLOWED_KEYS[key].fromLocalStorage(savedValue);},set(tourName,key,value){if(!(key in ALLOWED_KEYS)){throw new Error(`Invalid key: '${key}' (tourName = '${tourName}')`);}
const prefixedName=getPrefixedName(tourName,key);browser.localStorage.setItem(prefixedName,ALLOWED_KEYS[key].toLocalStorage(value));},clear(tourName){for(const key in ALLOWED_KEYS){const prefixedName=getPrefixedName(tourName,key);browser.localStorage.removeItem(prefixedName);}},getActiveTourNames(){const tourNames=new Set();for(const key of Object.keys(browser.localStorage)){const[tourName]=destructurePrefixedName(key)||[false];if(tourName){tourNames.add(tourName);}}
return[...tourNames].sort((a,b)=>this.get(a,"sequence")-this.get(b,"sequence"));},};return __exports;});;

/* /web_tour/static/src/tour_service/tour_utils.js */
odoo.define('@web_tour/tour_service/tour_utils',['@odoo/owl','@web/core/l10n/translation','@web/core/ui/ui_service','@web/core/utils/ui'],function(require){'use strict';let __exports={};const{markup}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{utils}=require("@web/core/ui/ui_service");const{_legacyIsVisible}=require("@web/core/utils/ui");const TourError=__exports.TourError=class TourError extends Error{constructor(message,...args){super(message,...args);this.message=`(TourError) ${message}`;}}
__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;}}
__exports.getFirstVisibleElement=getFirstVisibleElement;function getFirstVisibleElement($elements){for(var i=0;i<$elements.length;i++){var $i=$elements.eq(i);if(_legacyIsVisible($i[0])){return $i;}}
return $();}
__exports.getJQueryElementFromSelector=getJQueryElementFromSelector;function getJQueryElementFromSelector(selector,$target){$target=$target||$(document);const iframeSplit=typeof selector==="string"&&selector.match(/(.*\biframe[^ ]*)(.*)/);if(iframeSplit&&iframeSplit[2]){var $iframe=$target.find(`${iframeSplit[1]}:not(.o_ignore_in_tour)`);if($iframe.is('[is-ready="false"]')){return $();}
var $el=$iframe.contents().find(iframeSplit[2]);$el.iframeContainer=$iframe[0];return $el;}else if(typeof selector==="string"){return $target.find(selector);}else{return $(selector);}}
__exports.getConsumeEventType=getConsumeEventType;function getConsumeEventType(element,runCommand){if(!element){return"click";}
const{classList,tagName,type}=element;const tag=tagName.toLowerCase();if(classList.contains("o_field_many2one")){return"autocompleteselect";}
if(tag==="textarea"||(tag==="input"&&(!type||["email","number","password","search","tel","text","url"].includes(type)))){if(utils.isSmall()&&element.closest(".o_field_widget")?.matches(".o_field_many2one, .o_field_many2many")){return"click";}
return"input";}
if(classList.contains("ui-draggable-handle")){return"mousedown";}
if(typeof runCommand==="string"&&/^drag_and_drop/.test(runCommand)){if(element.closest(".ui-sortable")){return"sort";}
if((/^drag_and_drop_native/.test(runCommand)&&classList.contains("o_draggable"))||element.closest(".o_draggable")){return"pointerdown";}}
return"click";}
__exports.getDifferentParents=getDifferentParents;function getDifferentParents(n1,n2){const parents=[n2];while(parents[0].parentNode){const parent=parents[0].parentNode;if(parent.contains(n1)){break;}
parents.unshift(parent);}
return parents;}
__exports.getScrollParent=getScrollParent;function getScrollParent(element){if(!element){return null;}
if(element.scrollHeight>element.clientHeight){return element;}else{return getScrollParent(element.parentNode);}}
const triggerPointerEvent=__exports.triggerPointerEvent=(el,type,canBubbleAndBeCanceled,additionalParams)=>{const eventInit={bubbles:canBubbleAndBeCanceled,cancelable:canBubbleAndBeCanceled,view:window,...additionalParams,};el.dispatchEvent(new PointerEvent(type,eventInit));if(type.startsWith("pointer")){el.dispatchEvent(new MouseEvent(type.replace("pointer","mouse"),eventInit));}};const RunningTourActionHelper=__exports.RunningTourActionHelper=class RunningTourActionHelper{constructor(tip_widget){this.tip_widget=tip_widget;}
click(element){this._click(this._get_action_values(element));}
dblclick(element){this._click(this._get_action_values(element),2);}
tripleclick(element){this._click(this._get_action_values(element),3);}
clicknoleave(element){this._click(this._get_action_values(element),1,false);}
text(text,element){this._text(this._get_action_values(element),text);}
remove_text(text,element){this._text(this._get_action_values(element),"\n");}
text_blur(text,element){this._text_blur(this._get_action_values(element),text);}
range(text,element){this._range(this._get_action_values(element),text);}
drag_and_drop(to,element){this._drag_and_drop_jquery(this._get_action_values(element),to);}
drag_and_drop_native(toSel,element){const to=getJQueryElementFromSelector(toSel)[0];this._drag_and_drop(this._get_action_values(element).$element[0],to);}
keydown(keyCodes,element){this._keydown(this._get_action_values(element),keyCodes.split(/[,\s]+/));}
auto(element){var values=this._get_action_values(element);if(values.consume_event==="input"){this._text(values);}else{this._click(values);}}
_get_action_values(element){var $e=getJQueryElementFromSelector(element);var $element=element?getFirstVisibleElement($e):this.tip_widget.$anchor;if($element.length===0){$element=$e.first();}
var consume_event=element?getConsumeEventType($element[0]):this.tip_widget.consume_event;return{$element:$element,consume_event:consume_event,};}
_click(values,nb,leave){const target=values.$element[0];triggerPointerEvent(target,"pointerover",true);triggerPointerEvent(target,"pointerenter",false);triggerPointerEvent(target,"pointermove",true);for(let i=1;i<=(nb||1);i++){triggerPointerEvent(target,"pointerdown",true);triggerPointerEvent(target,"pointerup",true);triggerPointerEvent(target,"click",true,{detail:i});if(i%2===0){triggerPointerEvent(target,"dblclick",true);}}
if(leave!==false){triggerPointerEvent(target,"pointerout",true);triggerPointerEvent(target,"pointerleave",false);}}
_text(values,text){this._click(values);text=text||"Test";if(values.consume_event==="input"){values.$element.trigger({type:"keydown",key:text[text.length-1]}).val(text).trigger({type:"keyup",key:text[text.length-1]});values.$element[0].dispatchEvent(new InputEvent("input",{bubbles:true,}));}else if(values.$element.is("select")){var $options=values.$element.find("option");$options.prop("selected",false).removeProp("selected");var $selectedOption=$options.filter(function(){return $(this).val()===text;});if($selectedOption.length===0){$selectedOption=$options.filter(function(){return $(this).text().trim()===text;});}
const regex=/option\s+([0-9]+)/;if($selectedOption.length===0&&regex.test(text)){const position=parseInt(regex.exec(text)[1]);$selectedOption=$options.eq(position-1);}
$selectedOption.prop("selected",true);this._click(values);values.$element.trigger("input");}else{values.$element.focusIn();values.$element.trigger($.Event("keydown",{key:"_"}));values.$element.text(text).trigger("input");values.$element.focusInEnd();values.$element.trigger($.Event("keyup",{key:"_"}));}
values.$element[0].dispatchEvent(new Event("change",{bubbles:true,cancelable:false}));}
_text_blur(values,text){this._text(values,text);values.$element.trigger("focusout");values.$element.trigger("blur");}
_range(values,text){values.$element[0].value=text;values.$element[0].dispatchEvent(new Event('change',{bubbles:true,cancelable:false}));}
_calculateCenter($el,selector){const center=$el.offset();if(selector&&selector.indexOf("iframe")!==-1){const iFrameOffset=$("iframe").offset();center.left+=iFrameOffset.left;center.top+=iFrameOffset.top;}
center.left+=$el.outerWidth()/2;center.top+=$el.outerHeight()/2;return center;}
_drag_and_drop_jquery(values,to){var $to;const elementCenter=this._calculateCenter(values.$element);if(to){$to=getJQueryElementFromSelector(to);}else{$to=$(document.body);}
values.$element.trigger($.Event("mouseenter"));values.$element.trigger($.Event("mousedown",{which:1,pageX:elementCenter.left+1,pageY:elementCenter.top,}));if(!$to.length){values.$element.trigger($.Event("mousemove",{which:1,pageX:elementCenter.left+1,pageY:elementCenter.top,}));$to=getJQueryElementFromSelector(to);}
let toCenter=this._calculateCenter($to,to);values.$element.trigger($.Event("mousemove",{which:1,pageX:toCenter.left,pageY:toCenter.top}));toCenter=this._calculateCenter($to,to);values.$element.trigger($.Event("mouseup",{which:1,pageX:toCenter.left,pageY:toCenter.top}));}
_drag_and_drop(source,target){const sourceRect=source.getBoundingClientRect();const sourcePosition={clientX:sourceRect.x+sourceRect.width/2,clientY:sourceRect.y+sourceRect.height/2,};const targetRect=target.getBoundingClientRect();const targetPosition={clientX:targetRect.x+targetRect.width/2,clientY:targetRect.y+targetRect.height/2,};triggerPointerEvent(source,"pointerdown",true,sourcePosition);triggerPointerEvent(source,"pointermove",true,targetPosition);for(const parent of getDifferentParents(source,target)){triggerPointerEvent(parent,"pointerenter",false,targetPosition);}
triggerPointerEvent(target,"pointerup",true,targetPosition);}
_keydown(values,keyCodes){while(keyCodes.length){const eventOptions={};const keyCode=keyCodes.shift();let insertedText=null;if(isNaN(keyCode)){eventOptions.key=keyCode;}else{const code=parseInt(keyCode,10);if(code===32||(code>47&&code<58)||(code>64&&code<91)||(code>95&&code<112)||(code>185&&code<193)||(code>218&&code<223)){insertedText=String.fromCharCode(code);}}
values.$element.trigger(Object.assign({type:"keydown"},eventOptions));if(insertedText){values.$element[0].ownerDocument.execCommand("insertText",0,insertedText);}
values.$element.trigger(Object.assign({type:"keyup"},eventOptions));}}}
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;},editionEnterpriseModifier(step){step.edition="enterprise";return step;},mobileModifier(step){step.mobile=true;return step;},showAppsMenuItem(){return{edition:"community",trigger:".o_navbar_apps_menu button",auto:true,position:"bottom",};},toggleHomeMenu(){return{edition:"enterprise",trigger:".o_main_navbar .o_menu_toggle",content:markup(_t("Click on the <i>Home icon</i> to navigate across apps.")),position:"bottom",};},autoExpandMoreButtons(extra_trigger){return{trigger:".o-form-buttonbox",extra_trigger:extra_trigger,auto:true,run:(actions)=>{const $more=$(".o-form-buttonbox .o_button_more");if($more.length){actions.click($more);}},};},goBackBreadcrumbsMobile(description,...extraTrigger){return extraTrigger.map((element)=>({mobile:true,trigger:".o_back_button",extra_trigger:element,content:description,position:"bottom",debugHelp:this._getHelpMessage("goBackBreadcrumbsMobile",description,...extraTrigger),}));},goToAppSteps(dataMenuXmlid,description){return[this.showAppsMenuItem(),{trigger:`.o_app[data-menu-xmlid="${dataMenuXmlid}"]`,content:description,position:"right",edition:"community",},{trigger:`.o_app[data-menu-xmlid="${dataMenuXmlid}"]`,content:description,position:"bottom",edition:"enterprise",},].map((step)=>this.addDebugHelp(this._getHelpMessage("goToApp",dataMenuXmlid,description),step));},openBurgerMenu(extraTrigger){return{mobile:true,trigger:".o_mobile_menu_toggle",extra_trigger:extraTrigger,content:_t("Open bugger menu."),position:"bottom",debugHelp:this._getHelpMessage("openBurgerMenu",extraTrigger),};},statusbarButtonsSteps(innerTextButton,description,extraTrigger){return[{mobile:true,auto:true,trigger:".o_statusbar_buttons",extra_trigger:extraTrigger,run:(actions)=>{const $action=$(".o_statusbar_buttons .btn.dropdown-toggle:contains(Action)");if($action.length){actions.click($action);}},},{trigger:`.o_statusbar_buttons button:enabled:contains('${innerTextButton}')`,content:description,position:"bottom",},].map((step)=>this.addDebugHelp(this._getHelpMessage("statusbarButtonsSteps",innerTextButton,description,extraTrigger),step));},simulateEnterKeyboardInSearchModal(){return{mobile:true,trigger:".o_searchview_input",extra_trigger:".modal:not(.o_inactive_modal) .dropdown-menu.o_searchview_autocomplete",position:"bottom",run:(action)=>{const keyEventEnter=new KeyboardEvent("keydown",{bubbles:true,cancelable:true,key:"Enter",code:"Enter",});action.tip_widget.$anchor[0].dispatchEvent(keyEventEnter);},debugHelp:this._getHelpMessage("simulateEnterKeyboardInSearchModal"),};},mobileKanbanSearchMany2X(modalTitle,valueSearched){return[{mobile:true,trigger:`.o_control_panel_navigation .btn .fa-search`,position:"bottom",},{mobile:true,trigger:".o_searchview_input",extra_trigger:`.modal:not(.o_inactive_modal) .modal-title:contains('${modalTitle}')`,position:"bottom",run:`text ${valueSearched}`,},this.simulateEnterKeyboardInSearchModal(),{mobile:true,trigger:`.o_kanban_record .o_kanban_record_title :contains('${valueSearched}')`,position:"bottom",},].map((step)=>this.addDebugHelp(this._getHelpMessage("mobileKanbanSearchMany2X",modalTitle,valueSearched),step));},saveForm(options={}){return[{content:options.content||"save form",trigger:".o_form_button_save",extra_trigger:options.extra_trigger,run:"click",auto:true,},{content:"wait for save completion",trigger:".o_form_readonly, .o_form_saved",run(){},auto:true,},];},discardForm(options={}){return[{content:options.content||"exit the form",trigger:".o_form_button_cancel",extra_trigger:options.extra_trigger,run:"click",auto:true,},{content:"wait for cancellation to complete",trigger:".o_view_controller.o_list_view, .o_form_view > div > div > .o_form_readonly, .o_form_view > div > div > .o_form_saved",run(){},auto:true,},];},};return __exports;});;

/* /web/static/src/legacy/utils.js */
odoo.define('@web/legacy/utils',['@odoo/owl','@web/core/assets','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{App,Component,useState,xml}=require("@odoo/owl");const{templates}=require("@web/core/assets");const{_t}=require("@web/core/l10n/translation");const rootTemplate=xml`<SubComp t-props="state"/>`;__exports.attachComponent=attachComponent;async function attachComponent(parent,element,componentClass,props={}){class Root extends Component{static template=rootTemplate;static components={SubComp:componentClass};state=useState(props);}
const env=Component.env;const app=new App(Root,{env,templates,dev:env.debug,translatableAttributes:["data-tooltip"],translateFn:_t,});if(parent.__parentedMixin){parent.__parentedChildren.push({get $el(){return $(app.root.el);},destroy(){app.destroy();},});}
const originalValidateTarget=App.validateTarget;App.validateTarget=()=>{};const mountPromise=app.mount(element);App.validateTarget=originalValidateTarget;const component=await mountPromise;const subComp=Object.values(component.__owl__.children)[0].component;return{component:subComp,destroy(){app.destroy();},update(props){Object.assign(component.state,props);},};}
return __exports;});;

/* /web_editor/static/src/components/history_dialog/history_dialog.js */
odoo.define('@web_editor/components/history_dialog/history_dialog',['@web/core/dialog/dialog','@web/core/l10n/dates','@web/core/utils/hooks','@web/core/utils/functions','@odoo/owl','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{Dialog}=require('@web/core/dialog/dialog');const{formatDateTime}=require('@web/core/l10n/dates');const{useService}=require('@web/core/utils/hooks');const{memoize}=require('@web/core/utils/functions');const{Component,onMounted,useState,markup}=require('@odoo/owl');const{_t}=require('@web/core/l10n/translation');const{DateTime}=luxon;class HistoryDialog extends Component{static template='web_editor.HistoryDialog';static components={Dialog};static props={recordId:Number,recordModel:String,close:Function,restoreRequested:Function,historyMetadata:Array,versionedFieldName:String};state=useState({revisionsData:[],revisionContent:null,revisionComparison:null,revisionId:null});setup(){this.size='xl';this.title=_t('History');this.orm=useService('orm');this.userService=useService('user');onMounted(()=>this.init());}
async init(){this.state.revisionsData=this.props.historyMetadata;await this.updateCurrentRevision(this.props.historyMetadata[0]['revision_id']);}
async updateCurrentRevision(revisionId){if(this.state.revisionId===revisionId){return;}
this.env.services.ui.block();this.state.revisionId=revisionId;this.state.revisionContent=await this.getRevisionContent(revisionId);this.state.revisionComparison=await this.getRevisionComparison(revisionId);this.env.services.ui.unblock();}
getRevisionComparison=memoize(async function getRevisionComparison(revisionId){const comparison=await this.orm.call(this.props.recordModel,'html_field_history_get_comparison_at_revision',[this.props.recordId,this.props.versionedFieldName,revisionId]);return markup(comparison);}.bind(this));getRevisionContent=memoize(async function getRevisionContent(revisionId){const content=await this.orm.call(this.props.recordModel,'html_field_history_get_content_at_revision',[this.props.recordId,this.props.versionedFieldName,revisionId]);return markup(content);}.bind(this));async _onRestoreRevisionClick(){this.env.services.ui.block();const restoredContent=await this.getRevisionContent(this.state.revisionId);this.props.restoreRequested(restoredContent);this.env.services.ui.unblock();this.props.close();}
getRevisionDate(revision){return formatDateTime(DateTime.fromISO(revision['create_date'],{zone:'utc'}).setZone(this.userService.tz));}}
__exports[Symbol.for("default")]=HistoryDialog;return __exports;});;

/* /web_editor/static/src/components/media_dialog/document_selector.js */
odoo.define('@web_editor/components/media_dialog/document_selector',['@web/core/l10n/translation','@web_editor/components/media_dialog/file_selector'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{Attachment,FileSelector,IMAGE_MIMETYPES}=require("@web_editor/components/media_dialog/file_selector");const DocumentAttachment=__exports.DocumentAttachment=class DocumentAttachment extends Attachment{}
DocumentAttachment.template='web_editor.DocumentAttachment';const DocumentSelector=__exports.DocumentSelector=class DocumentSelector extends FileSelector{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.getAttribute('href').replace(/[?].*/,'')){this.selectAttachment(attachment);}}}
return attachments;}
static async createElements(selectedMedia,{orm}){return Promise.all(selectedMedia.map(async attachment=>{const linkEl=document.createElement('a');let href=`/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],);}
href+=`&access_token=${encodeURIComponent(accessToken)}`;}
linkEl.href=href;linkEl.title=attachment.name;linkEl.dataset.mimetype=attachment.mimetype;return linkEl;}));}}
DocumentSelector.mediaSpecificClasses=['o_image'];DocumentSelector.mediaSpecificStyles=[];DocumentSelector.mediaExtraClasses=[];DocumentSelector.tagNames=['A'];DocumentSelector.attachmentsListTemplate='web_editor.DocumentsListTemplate';DocumentSelector.components={...FileSelector.components,DocumentAttachment,};return __exports;});;

/* /web_editor/static/src/components/media_dialog/file_selector.js */
odoo.define('@web_editor/components/media_dialog/file_selector',['@web/core/l10n/translation','@web/core/utils/hooks','@web/core/confirmation_dialog/confirmation_dialog','@web/core/dialog/dialog','@web/core/utils/concurrency','@web/core/utils/timing','@web_editor/components/media_dialog/search_media','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");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("@web_editor/components/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{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();}}
RemoveButton.template=xml`<i class="fa fa-trash o_existing_attachment_remove position-absolute top-0 end-0 p-2 bg-white-25 cursor-pointer opacity-0 opacity-100-hover z-index-1 transition-base" t-att-title="removeTitle" role="img" t-att-aria-label="removeTitle" t-on-click="this.remove"/>`;const AttachmentError=__exports.AttachmentError=class AttachmentError extends Component{setup(){this.title=_t("Alert");}}
AttachmentError.components={Dialog};AttachmentError.template=xml`
<Dialog title="title">
    <div class="form-text">
        <p>The image could not be deleted because it is used in the
            following pages or views:</p>
        <ul t-foreach="props.views"  t-as="view" t-key="view.id">
            <li>
                <a t-att-href="'/web#model=ir.ui.view&amp;id=' + window.encodeURIComponent(view.id)">
                    <t t-esc="view.name"/>
                </a>
            </li>
        </ul>
    </div>
    <t t-set-slot="footer">
        <button class="btn btn-primary" t-on-click="() => this.props.close()">
            Ok
        </button>
    </t>
</Dialog>`;const Attachment=__exports.Attachment=class Attachment extends Component{setup(){this.dialogs=useService('dialog');this.rpc=useService('rpc');}
remove(){this.dialogs.add(ConfirmationDialog,{body:_t("Are you sure you want to delete this file?"),confirm:async()=>{const prevented=await this.rpc('/web_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],});}},});}}
Attachment.components={RemoveButton,};const FileSelectorControlPanel=__exports.FileSelectorControlPanel=class FileSelectorControlPanel extends Component{setup(){this.state=useState({showUrlInput:false,urlInput:'',isValidUrl:false,isValidFileFormat:false});this.fileInput=useRef('file-input');}
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='';}}
onUrlInput(ev){const{isValidUrl,isValidFileFormat}=this.props.validateUrl(ev.target.value);this.state.isValidFileFormat=isValidFileFormat;this.state.isValidUrl=isValidUrl;}
onClickUpload(){this.fileInput.el.click();}
async onChangeFileInput(){const inputFiles=this.fileInput.el.files;if(!inputFiles.length){return;}
await this.props.uploadFiles(inputFiles);this.fileInput.el.value='';}}
FileSelectorControlPanel.template='web_editor.FileSelectorControlPanel';FileSelectorControlPanel.components={SearchMedia,};const FileSelector=__exports.FileSelector=class FileSelector extends Component{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 this.uploadService.uploadUrl(url,{resModel:this.props.resModel,resId:this.props.resId,},attachment=>this.onUploaded(attachment));}
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=>{return el.getBoundingClientRect().bottom>attachmentBottom;})
scrollToEl=firstNextRowAttachmentEl||scrollToEl;}
scrollToEl.scrollIntoView({block:"end",inline:"nearest",behavior:"smooth"});}}
FileSelector.template='web_editor.FileSelector';FileSelector.components={FileSelectorControlPanel,};return __exports;});;

/* /web_editor/static/src/components/media_dialog/icon_selector.js */
odoo.define('@web_editor/components/media_dialog/icon_selector',['@web/core/l10n/translation','@web_editor/js/wysiwyg/fonts','@web_editor/components/media_dialog/search_media','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const fonts=require('@web_editor/js/wysiwyg/fonts')[Symbol.for("default")];const{SearchMedia}=require("@web_editor/components/media_dialog/search_media");const{Component,useState}=require("@odoo/owl");const IconSelector=__exports.IconSelector=class IconSelector extends Component{setup(){this.state=useState({fonts:this.props.fonts,needle:'',});this.searchPlaceholder=_t("Search a pictogram");}
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)>=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;}}
IconSelector.mediaSpecificClasses=['fa'];IconSelector.mediaSpecificStyles=['color','background-color'];IconSelector.mediaExtraClasses=['rounded-circle','rounded','img-thumbnail','shadow',/^text-\S+$/,/^bg-\S+$/,/^fa-\S+$/,];IconSelector.tagNames=['SPAN','I'];IconSelector.template='web_editor.IconSelector';IconSelector.components={SearchMedia,};return __exports;});;

/* /web_editor/static/src/components/media_dialog/image_selector.js */
odoo.define('@web_editor/components/media_dialog/image_selector',['@web/core/l10n/translation','@web/core/utils/hooks','@web_editor/js/common/utils','@web_editor/components/media_dialog/file_selector','@web/core/utils/concurrency','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{useService}=require('@web/core/utils/hooks');const weUtils=require('@web_editor/js/common/utils')[Symbol.for("default")];const{Attachment,FileSelector,IMAGE_MIMETYPES,IMAGE_EXTENSIONS}=require("@web_editor/components/media_dialog/file_selector");const{KeepLast}=require("@web/core/utils/concurrency");const{useRef,useState,useEffect}=require("@odoo/owl");const AutoResizeImage=__exports.AutoResizeImage=class AutoResizeImage extends Attachment{setup(){super.setup();this.image=useRef('auto-resize-image');this.container=useRef('auto-resize-image-container');this.state=useState({loaded:false,});useEffect(()=>{this.image.el.addEventListener('load',()=>this.onImageLoaded());return this.image.el.removeEventListener('load',()=>this.onImageLoaded());},()=>[]);}
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;}}
AutoResizeImage.template='web_editor.AutoResizeImage';const ImageSelector=__exports.ImageSelector=class ImageSelector extends FileSelector{setup(){super.setup();this.rpc=useService('rpc');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(',');}
get canLoadMore(){if(this.state.searchService==='media-library'){return this.state.libraryResults&&this.state.libraryMedia.length<this.state.libraryResults;}
return super.canLoadMore;}
get hasContent(){if(this.state.searchService==='all'){return super.hasContent||!!this.state.libraryMedia.length;}else if(this.state.searchService==='media-library'){return!!this.state.libraryMedia.length;}
return super.hasContent;}
get isFetching(){return super.isFetching||this.state.isFetchingLibrary;}
get selectedMediaIds(){return this.props.selectedMedia[this.props.id].filter(media=>media.mediaType==='libraryMedia').map(({id})=>id);}
get allAttachments(){return[...super.allAttachments,...this.state.libraryMedia];}
get attachmentsDomain(){const domain=super.attachmentsDomain;domain.push(['mimetype','in',IMAGE_MIMETYPES]);if(!this.props.useMediaLibrary){domain.push('|',['url','=',false],'!',['url','=ilike','/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){await this.uploadService.uploadFiles(files,{resModel:this.props.resModel,resId:this.props.resId,isImage:true},(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."),{title:_t("Error"),sticky:true,});resolve();};imageEl.onload=()=>{super.uploadUrl(url).then(resolve);};imageEl.src=url;});});}
validateUrl(...args){const{isValidUrl,path}=super.validateUrl(...args);const isValidFileFormat=IMAGE_EXTENSIONS.some(format=>path.endsWith(format));return{isValidFileFormat,isValidUrl};}
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);const primaryColors={};for(let color=1;color<=5;color++){primaryColors[color]=weUtils.getCSSVariableValue('o-color-'+color);}
return attachments.map(attachment=>{if(attachment.image_src.startsWith('/')){const newURL=new URL(attachment.image_src,window.location.origin);if(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 this.rpc('/web_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){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,rpc}){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('/web_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('/web_editor/shape/')){const colorCustomizedURL=new URL(attachment.image_src,window.location.origin);colorCustomizedURL.searchParams.forEach((value,key)=>{const match=key.match(/^c([1-5])$/);if(match){colorCustomizedURL.searchParams.set(key,weUtils.getCSSVariableValue(`o-color-${match[1]}`));}});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||'';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')==='image/svg+xml'){let svg=await response.text();const dynamicColors={};const combinedColorsRegex=new RegExp(Object.values(weUtils.DEFAULT_PALETTE).join('|'),'gi');svg=svg.replace(combinedColorsRegex,match=>{const colorId=Object.keys(weUtils.DEFAULT_PALETTE).find(key=>weUtils.DEFAULT_PALETTE[key]===match.toUpperCase());const colorKey='c'+colorId
dynamicColors[colorKey]=weUtils.getCSSVariableValue('o-color-'+colorId);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.');}}}
ImageSelector.mediaSpecificClasses=['img','img-fluid','o_we_custom_image'];ImageSelector.mediaSpecificStyles=[];ImageSelector.mediaExtraClasses=['rounded-circle','rounded','img-thumbnail','shadow','w-25','w-50','w-75','w-100',];ImageSelector.tagNames=['IMG'];ImageSelector.attachmentsListTemplate='web_editor.ImagesListTemplate';ImageSelector.components={...FileSelector.components,AutoResizeImage,};return __exports;});;

/* /web_editor/static/src/components/media_dialog/media_dialog.js */
odoo.define('@web_editor/components/media_dialog/media_dialog',['@web/core/l10n/translation','@web/core/utils/hooks','@web/core/utils/concurrency','@web/core/dialog/dialog','@web/core/notebook/notebook','@web_editor/components/media_dialog/image_selector','@web_editor/components/media_dialog/document_selector','@web_editor/components/media_dialog/icon_selector','@web_editor/components/media_dialog/video_selector','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{useService,useChildRef}=require('@web/core/utils/hooks');const{Mutex}=require("@web/core/utils/concurrency");const{Dialog}=require('@web/core/dialog/dialog');const{Notebook}=require('@web/core/notebook/notebook');const{ImageSelector}=require("@web_editor/components/media_dialog/image_selector");const{DocumentSelector}=require("@web_editor/components/media_dialog/document_selector");const{IconSelector}=require("@web_editor/components/media_dialog/icon_selector");const{VideoSelector}=require("@web_editor/components/media_dialog/video_selector");const{Component,useState,useRef,useEffect}=require("@odoo/owl");const TABS=__exports.TABS={IMAGES:{id:'IMAGES',title:_t("Images"),Component:ImageSelector,},DOCUMENTS:{id:'DOCUMENTS',title:_t("Documents"),Component:DocumentSelector,},ICONS:{id:'ICONS',title:_t("Icons"),Component:IconSelector,},VIDEOS:{id:'VIDEOS',title:_t("Videos"),Component:VideoSelector,},};const MediaDialog=__exports.MediaDialog=class MediaDialog extends Component{setup(){this.size='xl';this.contentClass='o_select_media_dialog h-100';this.title=_t("Select a media");this.modalRef=useChildRef();this.rpc=useService('rpc');this.orm=useService('orm');this.notificationService=useService('notification');this.mutex=new Mutex();this.tabs=[];this.selectedMedia=useState({});this.addButtonRef=useRef('add-button');this.initialIconClasses=[];this.addTabs();this.errorMessages={};this.state=useState({activeTab:this.initialActiveTab,});useEffect((nbSelectedAttachments)=>{this.addButtonRef.el.toggleAttribute("disabled",!nbSelectedAttachments);},()=>[this.selectedMedia[this.state.activeTab].length]);}
get initialActiveTab(){if(this.props.activeTab){return this.props.activeTab;}
if(this.props.media){const correspondingTab=Object.keys(TABS).find(id=>TABS[id].Component.tagNames.includes(this.props.media.tagName));if(correspondingTab){return correspondingTab;}}
return this.tabs[0].id;}
addTab(tab,additionalProps={}){this.selectedMedia[tab.id]=[];this.tabs.push({...tab,props:{...tab.props,...additionalProps,id:tab.id,resModel:this.props.resModel,resId:this.props.resId,media:this.props.media,multiImages:this.props.multiImages,selectedMedia:this.selectedMedia,selectMedia:(...args)=>this.selectMedia(...args,tab.id,additionalProps.multiSelect),save:this.save.bind(this),onAttachmentChange:this.props.onAttachmentChange,errorMessages:(errorMessage)=>this.errorMessages[tab.id]=errorMessage,modalRef:this.modalRef,},});}
addTabs(){const onlyImages=this.props.onlyImages||this.props.multiImages||(this.props.media&&this.props.media.parentElement&&(this.props.media.parentElement.dataset.oeField==='image'||this.props.media.parentElement.dataset.oeType==='image'));const noDocuments=onlyImages||this.props.noDocuments;const noIcons=onlyImages||this.props.noIcons;const noVideos=onlyImages||this.props.noVideos;if(!this.props.noImages){this.addTab(TABS.IMAGES,{useMediaLibrary:this.props.useMediaLibrary,multiSelect:this.props.multiImages,});}
if(!noDocuments){this.addTab(TABS.DOCUMENTS);}
if(!noIcons){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 mediaFont=fonts.find(font=>classes.includes(font.base));if(mediaFont){const selectedIcon=mediaFont.icons.find(icon=>icon.names.some(name=>classes.includes(name)));if(selectedIcon){this.initialIconClasses.push(...selectedIcon.names);this.selectMedia(selectedIcon,TABS.ICONS.id);}}}}
if(!noVideos){this.addTab(TABS.VIDEOS,{vimeoPreviewIds:this.props.vimeoPreviewIds,isForBgVideo:this.props.isForBgVideo,});}}
async renderMedia(selectedMedia){const elements=await this.mutex.exec(async()=>await TABS[this.state.activeTab].Component.createElements(selectedMedia,{rpc:this.rpc,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);}
if(this.state.activeTab===TABS.IMAGES.id){if(this.props.media.dataset.shape){element.dataset.shape=this.props.media.dataset.shape;}
if(this.props.media.dataset.shapeColors){element.dataset.shapeColors=this.props.media.dataset.shapeColors;}
if(this.props.media.dataset.shapeFlip){element.dataset.shapeFlip=this.props.media.dataset.shapeFlip;}
if(this.props.media.dataset.shapeRotate){element.dataset.shapeRotate=this.props.media.dataset.shapeRotate;}
if(this.props.media.dataset.hoverEffect){element.dataset.hoverEffect=this.props.media.dataset.hoverEffect;}
if(this.props.media.dataset.hoverEffectColor){element.dataset.hoverEffectColor=this.props.media.dataset.hoverEffectColor;}
if(this.props.media.dataset.hoverEffectStrokeWidth){element.dataset.hoverEffectStrokeWidth=this.props.media.dataset.hoverEffectStrokeWidth;}
if(this.props.media.dataset.hoverEffectIntensity){element.dataset.hoverEffectIntensity=this.props.media.dataset.hoverEffectIntensity;}}}
for(const otherTab of Object.keys(TABS).filter(key=>key!==this.state.activeTab)){for(const property of TABS[otherTab].Component.mediaSpecificStyles){element.style.removeProperty(property);}
element.classList.remove(...TABS[otherTab].Component.mediaSpecificClasses);const extraClassesToRemove=[];for(const name of 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 TABS[this.state.activeTab].Component.mediaExtraClasses){if(typeof(name)==='string'){if(candidateName===name){return false;}}else{for(const className of element.classList){if(className.match(candidateName)){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(...TABS[this.state.activeTab].Component.mediaSpecificClasses);});return elements;}
selectMedia(media,tabId,multiSelect){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);if(saveSelectedMedia){const elements=await this.renderMedia(selectedMedia);if(this.props.multiImages){this.props.save(elements);}else{this.props.save(elements[0]);}}
this.props.close();}
onTabChange(tab){this.state.activeTab=tab;}}
MediaDialog.template='web_editor.MediaDialog';MediaDialog.defaultProps={useMediaLibrary:true,};MediaDialog.components={...Object.keys(TABS).map(key=>TABS[key].Component),Dialog,Notebook,};return __exports;});;

/* /web_editor/static/src/components/media_dialog/search_media.js */
odoo.define('@web_editor/components/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,xml,useEffect,useState}=require("@odoo/owl");const SearchMedia=__exports.SearchMedia=class SearchMedia extends Component{setup(){useAutofocus();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]);}}
SearchMedia.template=xml`
<div class="position-relative mw-lg-25 flex-grow-1 me-auto">
    <input type="text" class="o_we_search o_input form-control" t-att-placeholder="props.searchPlaceholder.trim()" t-model="state.input" t-ref="autofocus"/>
    <i class="oi oi-search input-group-text position-absolute end-0 top-50 me-n3 px-2 py-1 translate-middle bg-transparent border-0" title="Search" role="img" aria-label="Search"/>
</div>`;return __exports;});;

/* /web_editor/static/src/components/media_dialog/video_selector.js */
odoo.define('@web_editor/components/media_dialog/video_selector',['@web/core/l10n/translation','@web/core/utils/hooks','@web/core/utils/timing','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{useAutofocus,useService}=require('@web/core/utils/hooks');const{debounce}=require('@web/core/utils/timing');const{Component,useState,useRef,onMounted,onWillStart}=require("@odoo/owl");class VideoOption extends Component{}
VideoOption.template='web_editor.VideoOption';class VideoIframe extends Component{static template='web_editor.VideoIframe';static props={src:{type:String},};}
const VideoSelector=__exports.VideoSelector=class VideoSelector extends Component{setup(){this.rpc=useService('rpc');this.http=useService('http');this.PLATFORMS={youtube:'youtube',dailymotion:'dailymotion',vimeo:'vimeo',youku:'youku',};this.OPTIONS={autoplay:{label:_t("Autoplay"),description:_t("Videos are muted when autoplay is enabled"),platforms:[this.PLATFORMS.youtube,this.PLATFORMS.dailymotion,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.dailymotion,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,},hide_dm_logo:{label:_t("Hide Dailymotion logo"),platforms:[this.PLATFORMS.dailymotion],urlParameter:'ui-logo=0',},hide_dm_share:{label:_t("Hide sharing button"),platforms:[this.PLATFORMS.dailymotion],urlParameter:'sharing-enable=0',},};this.state=useState({options:[],src:'',urlInput:'',platform:null,vimeoPreviews:[],errorMessage:'',});this.urlInputRef=useRef('url-input');onWillStart(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;await this.updateVideo();this.state.options=this.state.options.map((option)=>{const{urlParameter}=this.OPTIONS[option.id];return{...option,value:src.indexOf(urlParameter)>=0};});}}});onMounted(async()=>{await Promise.all(this.props.vimeoPreviewIds.map(async(videoId)=>{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)}`});}));});useAutofocus();this.onChangeUrl=debounce((ev)=>this.updateVideo(ev.target.value),500);}
get shownOptions(){if(this.props.isForBgVideo){return[];}
return this.state.options.filter(option=>!this.OPTIONS[option.id].isHidden||!this.OPTIONS[option.id].isHidden());}
async onChangeOption(optionId){this.state.options=this.state.options.map(option=>{if(option.id===optionId){return{...option,value:!option.value};}
return option;});await this.updateVideo();}
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){Object.keys(this.OPTIONS).forEach(key=>{options[key]=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 this.rpc('/web_editor/video_url/data',{video_url:url,...options,});}
static createElements(selectedMedia){return selectedMedia.map(video=>{const div=document.createElement('div');div.dataset.oeExpression=video.src;div.innerHTML=`
                <div class="css_editable_mode_display"></div>
                <div class="media_iframe_video_size" contenteditable="false"></div>
                <iframe frameborder="0" contenteditable="false" allowfullscreen="allowfullscreen"></iframe>
            `;div.querySelector('iframe').src=video.src;return div;});}}
VideoSelector.mediaSpecificClasses=['media_iframe_video'];VideoSelector.mediaSpecificStyles=[];VideoSelector.mediaExtraClasses=[];VideoSelector.tagNames=['IFRAME','DIV'];VideoSelector.template='web_editor.VideoSelector';VideoSelector.components={VideoIframe,VideoOption,};VideoSelector.defaultProps={vimeoPreviewIds:[],isForBgVideo:false,};return __exports;});;

/* /web_editor/static/src/components/upload_progress_toast/upload_progress_toast.js */
odoo.define('@web_editor/components/upload_progress_toast/upload_progress_toast',['@web/core/utils/hooks','@odoo/owl'],function(require){'use strict';let __exports={};const{useService}=require('@web/core/utils/hooks');const{Component,useState}=require("@odoo/owl");const ProgressBar=__exports.ProgressBar=class ProgressBar extends Component{get progress(){return Math.round(this.props.progress);}}
ProgressBar.template='web_editor.ProgressBar';ProgressBar.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},};ProgressBar.defaultProps={progress:0,hasError:false,uploaded:false,size:"",errorMessage:"",};const UploadProgressToast=__exports.UploadProgressToast=class UploadProgressToast extends Component{setup(){this.uploadService=useService('upload');this.state=useState(this.uploadService.progressToast);}}
UploadProgressToast.template='web_editor.UploadProgressToast';UploadProgressToast.components={ProgressBar};UploadProgressToast.props={close:Function,};return __exports;});;

/* /web_editor/static/src/components/upload_progress_toast/upload_service.js */
odoo.define('@web_editor/components/upload_progress_toast/upload_service',['@web/core/registry','@web_editor/components/upload_progress_toast/upload_progress_toast','@web/core/l10n/translation','@web/core/utils/files','@web/core/utils/numbers','@web/core/utils/urls','@web/core/utils/strings','@odoo/owl'],function(require){'use strict';let __exports={};const{registry}=require('@web/core/registry');const{UploadProgressToast}=require("@web_editor/components/upload_progress_toast/upload_progress_toast");const{_t}=require("@web/core/l10n/translation");const{checkFileSize}=require("@web/core/utils/files");const{humanNumber}=require("@web/core/utils/numbers");const{getDataURLFromFile}=require("@web/core/utils/urls");const{sprintf}=require("@web/core/utils/strings");const{reactive}=require("@odoo/owl");const AUTOCLOSE_DELAY=__exports.AUTOCLOSE_DELAY=3000;const uploadService=__exports.uploadService={dependencies:['rpc','notification'],start(env,{rpc,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;}};return{get progressToast(){return progressToast;},get fileId(){return fileId;},addFile,deleteFile,incrementId(){fileId++;},uploadUrl:async(url,{resModel,resId},onUploaded)=>{const attachment=await rpc('/web_editor/attachment/add_url',{url,'res_model':resModel,'res_id':resId,});await onUploaded(attachment);},uploadFiles:async(files,{resModel,resId,isImage},onUploaded)=>{const sortedFiles=Array.from(files).sort((a,b)=>a.size-b.size);for(const file of sortedFiles){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){const file=progressToast.files[sortedFile.progressToastId];let dataURL;try{dataURL=await getDataURLFromFile(sortedFile);}catch{deleteFile(file.id);env.services.notification.add(sprintf(_t('Could not load the file "%s".'),sortedFile.name),{type:'danger'});continue}
try{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 attachment=await rpc('/web_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});if(attachment.error){file.hasError=true;file.errorMessage=attachment.error;}else{if(attachment.mimetype==='image/webp'){const image=document.createElement('img');image.src=`data:image/webp;base64,${dataURL.split(',')[1]}`;await new Promise(resolve=>image.addEventListener('load',resolve));const canvas=document.createElement('canvas');canvas.width=image.width;canvas.height=image.height;const ctx=canvas.getContext('2d');ctx.fillStyle='rgb(255, 255, 255)';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':file.name.replace(/\.webp$/,'.jpg'),'data':altDataURL.split(',')[1],'res_id':attachment.id,'res_model':'ir.attachment','is_image':true,'width':0,'quality':0,},{xhr});}
file.uploaded=true;await onUploaded(attachment);}
setTimeout(()=>deleteFile(file.id),AUTOCLOSE_DELAY);}catch(error){file.hasError=true;setTimeout(()=>deleteFile(file.id),AUTOCLOSE_DELAY);throw error;}}}};},};registry.category('services').add('upload',uploadService);return __exports;});;

/* /website/static/src/components/media_dialog/image_selector.js */
odoo.define('@website/components/media_dialog/image_selector',['@web/core/utils/patch','@web_editor/components/media_dialog/image_selector'],function(require){'use strict';let __exports={};const{patch}=require("@web/core/utils/patch");const{ImageSelector}=require('@web_editor/components/media_dialog/image_selector');patch(ImageSelector.prototype,{get attachmentsDomain(){const domain=super.attachmentsDomain;domain.push('|',['url','=',false],'!',['url','=like','/web/image/website.%']);domain.push(['key','=',false]);return domain;}});return __exports;});;

/* /web_unsplash/static/src/components/media_dialog/image_selector.js */
odoo.define('@web_unsplash/components/media_dialog/image_selector',['@web/core/l10n/translation','@web/core/utils/patch','@web/core/utils/concurrency','@web_editor/components/media_dialog/media_dialog','@web_editor/components/media_dialog/image_selector','@web/core/utils/hooks','@web_editor/components/upload_progress_toast/upload_service','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{patch}=require("@web/core/utils/patch");const{KeepLast}=require("@web/core/utils/concurrency");const{MediaDialog,TABS}=require('@web_editor/components/media_dialog/media_dialog');const{ImageSelector}=require('@web_editor/components/media_dialog/image_selector');const{useService}=require('@web/core/utils/hooks');const{uploadService,AUTOCLOSE_DELAY}=require('@web_editor/components/upload_progress_toast/upload_service');const{useState,Component}=require("@odoo/owl");class UnsplashCredentials extends Component{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);}}}
UnsplashCredentials.template='web_unsplash.UnsplashCredentials';const UnsplashError=__exports.UnsplashError=class UnsplashError extends Component{}
UnsplashError.template='web_unsplash.UnsplashError';UnsplashError.components={UnsplashCredentials,};patch(ImageSelector.prototype,{setup(){super.setup();this.unsplash=useService('unsplash');this.keepLastUnsplash=new KeepLast();this.state.unsplashRecords=[];this.state.isFetchingUnsplash=false;this.state.isMaxed=false;this.state.unsplashError=null;this.state.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.state.isMaxed&&!this.state.unsplashError;}else if(this.state.searchService==='unsplash'){return this.state.needle&&!this.state.isMaxed&&!this.state.unsplashError;}
return super.canLoadMore;},get hasContent(){if(this.state.searchService==='all'){return super.hasContent||!!this.state.unsplashRecords.length;}else if(this.state.searchService==='unsplash'){return!!this.state.unsplashRecords.length;}
return super.hasContent;},get errorTitle(){if(this.errorMessages[this.state.unsplashError]){return this.errorMessages[this.state.unsplashError].title;}
return _t("Something went wrong");},get errorSubtitle(){if(this.errorMessages[this.state.unsplashError]){return this.errorMessages[this.state.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.state.isFetchingUnsplash;},get combinedRecords(){function alternate(a,b){return[a.map((v,i)=>i<b.length?[v,b[i]]:v),b.slice(a.length),].flat(2);}
return alternate(this.state.unsplashRecords,this.state.libraryMedia);},get allAttachments(){return[...super.allAttachments,...this.state.unsplashRecords];},set canLoadMore(_){},set hasContent(_){},set isFetching(_){},set selectedMediaIds(_){},set attachmentsDomain(_){},set errorTitle(_){},set errorSubtitle(_){},set selectedRecordIds(_){},async fetchUnsplashRecords(offset){if(!this.state.needle){return{records:[],isMaxed:false};}
this.state.isFetchingUnsplash=true;try{const{isMaxed,images}=await this.unsplash.getImages(this.state.needle,offset,this.NUMBER_OF_RECORDS_TO_DISPLAY,this.props.orientation);this.state.isFetchingUnsplash=false;this.state.unsplashError=false;const existingIds=this.state.unsplashRecords.map(existing=>existing.id);const newImages=images.filter(record=>!existingIds.includes(record.id));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.state.isFetchingUnsplash=false;if(e==='no_access'){this.state.useUnsplash=false;}else{this.state.unsplashError=e;}
return{records:[],isMaxed:true};}},async loadMore(...args){await super.loadMore(...args);return this.keepLastUnsplash.add(this.fetchUnsplashRecords(this.state.unsplashRecords.length)).then(({records,isMaxed})=>{this.state.unsplashRecords.push(...records);this.state.isMaxed=isMaxed;});},async search(...args){await super.search(...args);await this.searchUnsplash();},async searchUnsplash(){if(!this.state.needle){this.state.unsplashError=false;this.state.unsplashRecords=[];this.state.isMaxed=false;}
return this.keepLastUnsplash.add(this.fetchUnsplashRecords(0)).then(({records,isMaxed})=>{this.state.unsplashRecords=records;this.state.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.state.unsplashError=null;await this.rpc('/web_unsplash/save_unsplash',{key,appId});await this.searchUnsplash();},});ImageSelector.components={...ImageSelector.components,UnsplashError,};patch(MediaDialog.prototype,{setup(){super.setup();this.uploadService=useService('upload');},async save(){const selectedImages=this.selectedMedia[TABS.IMAGES.id];if(selectedImages){const unsplashRecords=selectedImages.filter(media=>media.mediaType==='unsplashRecord');if(unsplashRecords.length){await this.uploadService.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);},});patch(uploadService,{start(env,{rpc}){const service=super.start(...arguments);return{...service,async uploadUnsplashRecords(records,{resModel,resId},onUploaded){service.incrementId();const file=service.addFile({id:service.fileId,name:records.length>1?_t("Uploading %s '%s' images.",records.length,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(()=>service.deleteFile(file.id),AUTOCLOSE_DELAY);}catch(error){file.hasError=true;setTimeout(()=>service.deleteFile(file.id),AUTOCLOSE_DELAY);throw error;}}};}});return __exports;});;

/* /web_unsplash/static/src/services/unsplash_service.js */
odoo.define('@web_unsplash/services/unsplash_service',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require('@web/core/registry');const unsplashService=__exports.unsplashService={dependencies:['rpc'],async start(env,{rpc}){const _cache={};return{async getImages(query,offset=0,pageSize=30,orientation){const from=offset;const to=offset+pageSize;let cachedData=orientation?_cache[query+orientation]:_cache[query];if(cachedData&&(cachedData.images.length>=to||(cachedData.totalImages!==0&&cachedData.totalImages<to))){return{images:cachedData.images.slice(from,to),isMaxed:to>cachedData.totalImages};}
cachedData=await this._fetchImages(query,orientation);return{images:cachedData.images.slice(from,to),isMaxed:to>cachedData.totalImages};},async _fetchImages(query,orientation){const key=orientation?query+orientation:query;if(!_cache[key]){_cache[key]={images:[],maxPages:0,totalImages:0,pageCached:0};}
const cachedData=_cache[key];const payload={query:query,page:cachedData.pageCached+1,per_page:30,};if(orientation){payload.orientation=orientation;}
const result=await rpc('/web_unsplash/fetch_images',payload);if(result.error){return Promise.reject(result.error);}
cachedData.pageCached++;cachedData.images.push(...result.results);cachedData.maxPages=result.total_pages;cachedData.totalImages=result.total;return cachedData;},};},};registry.category('services').add('unsplash',unsplashService);return __exports;});;

/* /web_editor/static/src/js/common/browser_extensions.js */
odoo.define('@web_editor/js/common/browser_extensions',[],function(require){'use strict';let __exports={};const originalGetRangeAt=Selection.prototype.getRangeAt;Selection.prototype.getRangeAt=function(){let range=originalGetRangeAt.apply(this,arguments);if(range.startContainer&&!Object.getPrototypeOf(range.startContainer)){range=document.createRange();range.setStart(this.anchorNode,0);range.setEnd(this.focusNode,0);}
return range;};return __exports;});;

/* /web_editor/static/src/js/common/column_layout_mixin.js */
odoo.define('@web_editor/js/common/column_layout_mixin',[],function(require){'use strict';let __exports={};const ColumnLayoutMixin=__exports.ColumnLayoutMixin={_getNbColumns(columnEls,isMobile){if(!columnEls){return 0;}
if(this._areColsCustomized(columnEls,isMobile)){return"custom";}
const resolutionModifier=isMobile?"":"lg-";const colRegex=new RegExp(`(?:^|\\s+)col-${resolutionModifier}(\\d{1,2})(?!\\S)`);const colSize=parseInt(columnEls[0].className.match(colRegex)?.[1]||12);const offsetSize=this._getFirstItem(columnEls,isMobile).classList.contains(`offset-${resolutionModifier}1`)?1:0;return Math.floor((12-offsetSize)/colSize);},_getItemMobileOrder(el){const order=el.style.order;return order?[`order-${order}`,order.toString()]:null;},_getFirstItem(columnEls,isMobile){return isMobile&&[...columnEls].find(el=>el.style.order==="0")||columnEls[0];},_addMobileOrders(columnEls){for(let i=0;i<columnEls.length;i++){columnEls[i].style.order=i;columnEls[i].classList.add("order-lg-0");}},_removeMobileOrders(columnEls){for(const el of columnEls){el.style.order="";el.classList.remove("order-lg-0");}},_areColsCustomized(columnEls,isMobile){const resolutionModifier=isMobile?"":"lg-";const colRegex=new RegExp(`(?:^|\\s+)col-${resolutionModifier}(\\d{1,2})(?!\\S)`);const colSize=parseInt(columnEls[0].className.match(colRegex)?.[1]||12);const allColsSizesEqual=[...columnEls].every((columnEl)=>parseInt(columnEl.className.match(colRegex)?.[1]||12)===colSize);if(!allColsSizesEqual){return true;}
const offsetRegex=new RegExp(`(?:^|\\s+)offset-${resolutionModifier}[1-9][0-1]?(?!\\S)`);const nbOffsets=[...columnEls].filter((columnEl)=>columnEl.className.match(offsetRegex)).length;if(nbOffsets===0){return false;}
if(nbOffsets===1&&colSize===2&&this._getFirstItem(columnEls,isMobile).className.match(`offset-${resolutionModifier}1`)){return false;}
return true;},_fillRemovedItemGap(parentEl,itemOrder){[...parentEl.children].forEach(el=>{const elOrder=parseInt(el.style.order);if(elOrder>itemOrder){el.style.order=elOrder-1;}});},};return __exports;});;

/* /web_editor/static/src/js/common/grid_layout_utils.js */
odoo.define('@web_editor/js/common/grid_layout_utils',['@web/core/utils/render','@web_editor/js/editor/odoo-editor/src/utils/utils'],function(require){'use strict';let __exports={};const{renderToElement}=require("@web/core/utils/render");const{descendants,preserveCursor}=require("@web_editor/js/editor/odoo-editor/src/utils/utils");const rowSize=__exports.rowSize=50;const additionalRowLimit=__exports.additionalRowLimit=10;const defaultGridPadding=10;__exports._getGridProperties=_getGridProperties;function _getGridProperties(rowEl){const style=window.getComputedStyle(rowEl);const rowGap=parseFloat(style.rowGap);const columnGap=parseFloat(style.columnGap);const columnSize=(rowEl.clientWidth-11*columnGap)/12;return{rowGap:rowGap,rowSize:rowSize,columnGap:columnGap,columnSize:columnSize};}
__exports._setElementToMaxZindex=_setElementToMaxZindex;function _setElementToMaxZindex(element,rowEl){const childrenEls=[...rowEl.children].filter(el=>el!==element&&!el.classList.contains("o_we_grid_preview"));element.style.zIndex=Math.max(...childrenEls.map(el=>el.style.zIndex))+1;}
__exports._addBackgroundGrid=_addBackgroundGrid;function _addBackgroundGrid(rowEl,gridHeight){const gridProp=_getGridProperties(rowEl);const rowCount=Math.max(rowEl.dataset.rowCount,gridHeight);const backgroundGrid=renderToElement('web_editor.background_grid',{rowCount:rowCount+1,rowGap:gridProp.rowGap,rowSize:gridProp.rowSize,columnGap:gridProp.columnGap,columnSize:gridProp.columnSize,});rowEl.prepend(backgroundGrid);return rowEl.firstElementChild;}
__exports._resizeGrid=_resizeGrid;function _resizeGrid(rowEl){const columnEls=[...rowEl.children].filter(c=>c.classList.contains('o_grid_item'));rowEl.dataset.rowCount=Math.max(...columnEls.map(el=>el.style.gridRowEnd))-1;}
__exports._gridCleanUp=_gridCleanUp;function _gridCleanUp(rowEl,columnEl){columnEl.style.removeProperty('position');columnEl.style.removeProperty('top');columnEl.style.removeProperty('left');columnEl.style.removeProperty('height');columnEl.style.removeProperty('width');rowEl.style.removeProperty('position');}
__exports._toggleGridMode=_toggleGridMode;function _toggleGridMode(containerEl){let rowEl=containerEl.querySelector(':scope > .row');const outOfRowEls=[...containerEl.children].filter(el=>!el.classList.contains('row'));const avoidRollback=(el)=>{for(const node of descendants(el)){node.ouid=undefined;}};const restoreCursor=!rowEl||outOfRowEls.length>0?preserveCursor(containerEl.ownerDocument):()=>{};if(rowEl&&outOfRowEls.length>0){const columnEl=document.createElement('div');columnEl.classList.add('col-lg-12');for(let i=outOfRowEls.length-1;i>=0;i--){columnEl.prepend(outOfRowEls[i]);}
avoidRollback(columnEl);rowEl.prepend(columnEl);}
if(!rowEl){rowEl=document.createElement('div');rowEl.classList.add('row');const columnEl=document.createElement('div');columnEl.classList.add('col-lg-12');const containerChildren=containerEl.children;for(let i=containerChildren.length-1;i>=0;i--){columnEl.prepend(containerChildren[i]);}
avoidRollback(columnEl);rowEl.appendChild(columnEl);containerEl.appendChild(rowEl);}
restoreCursor();const columnEls=rowEl.children;const columnSize=(rowEl.clientWidth)/12;rowEl.style.position='relative';const rowCount=_placeColumns(columnEls,rowSize,0,columnSize,0)-1;rowEl.style.removeProperty('position');rowEl.dataset.rowCount=rowCount;const classesToRemove=[...rowEl.classList].filter(c=>{return/^align-items/.test(c);});rowEl.classList.remove(...classesToRemove);rowEl.classList.add('o_grid_mode');}
function _placeColumns(columnEls,rowSize,rowGap,columnSize,columnGap){let maxRowEnd=0;const columnSpans=[];let zIndex=1;const imageColumns=[];for(const columnEl of columnEls){let isImageColumn=_checkIfImageColumn(columnEl);const imageEl=columnEl.querySelector('img');const hasBackgroundColor=columnEl.classList.contains("o_cc");const isImageWithoutPadding=isImageColumn&&!hasBackgroundColor;const style=window.getComputedStyle(columnEl);const borderLeft=parseFloat(style.borderLeft);const columnLeft=isImageWithoutPadding&&!borderLeft?imageEl.offsetLeft:columnEl.offsetLeft;const paddingLeft=parseFloat(style.paddingLeft);let width=isImageWithoutPadding?parseFloat(imageEl.scrollWidth):parseFloat(columnEl.scrollWidth)-(hasBackgroundColor?0:2*paddingLeft);const borderX=borderLeft+parseFloat(style.borderRight);width+=borderX+(hasBackgroundColor||isImageColumn?0:2*defaultGridPadding);let columnSpan=Math.round((width+columnGap)/(columnSize+columnGap));if(columnSpan<1){columnSpan=1;}
const columnStart=Math.round(columnLeft/(columnSize+columnGap))+1;const columnEnd=columnStart+columnSpan;const borderTop=parseFloat(style.borderTop);const columnTop=isImageWithoutPadding&&!borderTop?imageEl.offsetTop:columnEl.offsetTop;const paddingTop=parseFloat(style.paddingTop);const paddingBottom=parseFloat(style.paddingBottom);const rowOffsetTop=Math.floor((paddingTop+rowGap)/(rowSize+rowGap));let height=isImageWithoutPadding?parseFloat(imageEl.scrollHeight):parseFloat(columnEl.scrollHeight)-(hasBackgroundColor?0:paddingTop+paddingBottom);const borderY=borderTop+parseFloat(style.borderBottom);height+=borderY+(hasBackgroundColor||isImageColumn?0:2*defaultGridPadding);const rowSpan=Math.ceil((height+rowGap)/(rowSize+rowGap));const rowStart=Math.round(columnTop/(rowSize+rowGap))+1+(hasBackgroundColor||isImageWithoutPadding?0:rowOffsetTop);const rowEnd=rowStart+rowSpan;columnEl.style.gridArea=`${rowStart} / ${columnStart} / ${rowEnd} / ${columnEnd}`;columnEl.classList.add('o_grid_item');columnEl.classList.add('g-col-lg-'+columnSpan,'g-height-'+rowSpan);columnEl.style.zIndex=zIndex++;if(hasBackgroundColor){columnEl.style.setProperty("--grid-item-padding-y",`${paddingTop}px`);columnEl.style.setProperty("--grid-item-padding-x",`${paddingLeft}px`);}
_reloadLazyImages(columnEl);maxRowEnd=Math.max(rowEnd,maxRowEnd);columnSpans.push(columnSpan);imageColumns.push(isImageColumn);}
for(const[i,columnEl]of[...columnEls].entries()){const regex=/^(((pt|pb)\d{1,3}$)|col-lg-|offset-lg-)/;const toRemove=[...columnEl.classList].filter(c=>{return regex.test(c);});columnEl.classList.remove(...toRemove);columnEl.classList.add('col-lg-'+columnSpans[i]);if(imageColumns[i]){_convertImageColumn(columnEl);}}
return maxRowEnd;}
__exports._reloadLazyImages=_reloadLazyImages;function _reloadLazyImages(columnEl){const imageEls=columnEl.querySelectorAll('img');for(const imageEl of imageEls){const src=imageEl.getAttribute("src");imageEl.src='';imageEl.src=src;}}
__exports._convertColumnToGrid=_convertColumnToGrid;function _convertColumnToGrid(rowEl,columnEl,columnWidth,columnHeight){if(_checkIfImageColumn(columnEl)){_convertImageColumn(columnEl);}
const paddingX=parseFloat(rowEl.style.getPropertyValue("--grid-item-padding-x"))||defaultGridPadding;const paddingY=parseFloat(rowEl.style.getPropertyValue("--grid-item-padding-y"))||defaultGridPadding;columnWidth+=2*paddingX;columnHeight+=2*paddingY;const gridProp=_getGridProperties(rowEl);const columnColCount=Math.round((columnWidth+gridProp.columnGap)/(gridProp.columnSize+gridProp.columnGap));const columnRowCount=Math.ceil((columnHeight+gridProp.rowGap)/(gridProp.rowSize+gridProp.rowGap));const regex=/^(pt|pb|col-|offset-)/;const toRemove=[...columnEl.classList].filter(c=>regex.test(c));columnEl.classList.remove(...toRemove);columnEl.classList.add('g-col-lg-'+columnColCount,'g-height-'+columnRowCount,'col-lg-'+columnColCount);columnEl.classList.add('o_grid_item');return{columnColCount:columnColCount,columnRowCount:columnRowCount};}
__exports._convertToNormalColumn=_convertToNormalColumn;function _convertToNormalColumn(columnEl){const gridSizeClasses=columnEl.className.match(/(g-col-lg|g-height)-[0-9]+/g);columnEl.classList.remove("o_grid_item","o_grid_item_image","o_grid_item_image_contain",...gridSizeClasses);columnEl.style.removeProperty("z-index");columnEl.style.removeProperty("--grid-item-padding-x");columnEl.style.removeProperty("--grid-item-padding-y");columnEl.style.removeProperty("grid-area");}
__exports._checkIfImageColumn=_checkIfImageColumn;function _checkIfImageColumn(columnEl){let isImageColumn=false;const imageEls=columnEl.querySelectorAll(":scope > img, :scope > a > img");const columnChildrenEls=[...columnEl.children].filter(el=>el.nodeName!=='BR');if(imageEls.length===1&&columnChildrenEls.length===1){const textNodeEls=[...columnEl.childNodes].filter(el=>el.nodeType===Node.TEXT_NODE);const areTextNodesEmpty=[...textNodeEls].every(textNodeEl=>textNodeEl.nodeValue.trim()==='');isImageColumn=areTextNodesEmpty;}
return isImageColumn;}
function _convertImageColumn(columnEl){columnEl.querySelectorAll('br').forEach(el=>el.remove());const textNodeEls=[...columnEl.childNodes].filter(el=>el.nodeType===Node.TEXT_NODE);textNodeEls.forEach(el=>el.remove());const imageEl=columnEl.querySelector('img');columnEl.classList.add('o_grid_item_image');imageEl.style.removeProperty('width');}
return __exports;});;

/* /web_editor/static/src/js/common/utils.js */
odoo.define('@web_editor/js/common/utils',['@web/core/ui/ui_service','@web/core/utils/colors'],function(require){'use strict';let __exports={};const{SIZES,MEDIAS_BREAKPOINTS}=require("@web/core/ui/ui_service");const{normalizeCSSColor,isCSSColor,}=require('@web/core/utils/colors');let editableWindow=window;const _setEditableWindow=(ew)=>editableWindow=ew;let editableDocument=document;const _setEditableDocument=(ed)=>editableDocument=ed;const COLOR_PALETTE_COMPATIBILITY_COLOR_NAMES=['primary','secondary','alpha','beta','gamma','delta','epsilon','success','info','warning','danger'];const 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}-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}`);}
const CSS_SHORTHANDS={'border-width':['border-top-width','border-right-width','border-bottom-width','border-left-width'],'border-radius':['border-top-left-radius','border-top-right-radius','border-bottom-right-radius','border-bottom-left-radius'],'border-color':['border-top-color','border-right-color','border-bottom-color','border-left-color'],'border-style':['border-top-style','border-right-style','border-bottom-style','border-left-style'],'padding':['padding-top','padding-right','padding-bottom','padding-left'],};const CSS_UNITS_CONVERSION={'s-ms':()=>1000,'ms-s':()=>0.001,'rem-px':()=>_computePxByRem(),'px-rem':()=>_computePxByRem(true),'%-px':()=>-1,'px-%':()=>-1,};const DEFAULT_PALETTE={'1':'#3AADAA','2':'#7C6576','3':'#F6F6F6','4':'#FFFFFF','5':'#383E45',};const BACKGROUND_IMAGE_ATTRIBUTES=new Set(["originalId","originalSrc","mimetype","resizeWidth","glFilter","quality","bgSrc","filterOptions","mimetypeBeforeConversion",]);function _computePxByRem(toRem){if(editableDocument.PX_BY_REM===undefined){const htmlStyle=editableWindow.getComputedStyle(editableDocument.documentElement);editableDocument.PX_BY_REM=parseFloat(htmlStyle['font-size']);}
return toRem?(1/editableDocument.PX_BY_REM):editableDocument.PX_BY_REM;}
function _convertValueToUnit(value,unitTo,cssProp,$target){const m=_getNumericAndUnit(value);if(!m){return NaN;}
const numValue=parseFloat(m[0]);const valueUnit=m[1];return _convertNumericToUnit(numValue,valueUnit,unitTo,cssProp,$target);}
function _convertNumericToUnit(value,unitFrom,unitTo,cssProp,$target){if(Math.abs(value)<Number.EPSILON||unitFrom===unitTo){return value;}
const converter=CSS_UNITS_CONVERSION[`${unitFrom}-${unitTo}`];if(converter===undefined){throw new Error(`Cannot convert '${unitFrom}' units into '${unitTo}' units !`);}
return value*converter(cssProp,$target);}
function _getNumericAndUnit(value){const m=value.trim().match(/^(-?[0-9.]+(?:e[+|-]?[0-9]+)?)\s*([^\s]*)$/);if(!m){return null;}
return[m[1].trim(),m[2].trim()];}
function _areCssValuesEqual(value1,value2,cssProp,$target){if(value1===value2){return true;}
if(cssProp&&cssProp.endsWith('-size')){const pseudoPartProp=cssProp+'-part';const re=/-?[0-9.]+(?:e[+|-]?[0-9]+)?\s*[A-Za-z%-]+|auto/g;const parts1=value1.match(re);const parts2=value2.match(re);for(const index of[0,1]){const part1=parts1&&parts1.length>index?parts1[index]:'auto';const part2=parts2&&parts2.length>index?parts2[index]:'auto';if(!_areCssValuesEqual(part1,part2,pseudoPartProp,$target)){return false;}}
return true;}
if(value1.startsWith('var(--')){value1=_getCSSVariableValue(value1.substring(6,value1.length-1));}
if(value2.startsWith('var(--')){value2=_getCSSVariableValue(value2.substring(6,value2.length-1));}
if(value1===value2){return true;}
const color1=normalizeCSSColor(value1);const color2=normalizeCSSColor(value2);if(color1===color2){return true;}
const value1IsGradient=_isColorGradient(value1);const value2IsGradient=_isColorGradient(value2);if(value1IsGradient!==value2IsGradient){return false;}
if(value1IsGradient){const temp1El=document.createElement('div');temp1El.style.backgroundImage=value1;document.body.appendChild(temp1El);value1=getComputedStyle(temp1El).backgroundImage;document.body.removeChild(temp1El);const temp2El=document.createElement('div');temp2El.style.backgroundImage=value2;document.body.appendChild(temp2El);value2=getComputedStyle(temp2El).backgroundImage;document.body.removeChild(temp2El);return value1===value2;}
if(cssProp==='box-shadow'){const temp1El=document.createElement('div');temp1El.style.boxShadow=value1;document.body.appendChild(temp1El);value1=getComputedStyle(temp1El).boxShadow;document.body.removeChild(temp1El);const temp2El=document.createElement('div');temp2El.style.boxShadow=value2;document.body.appendChild(temp2El);value2=getComputedStyle(temp2El).boxShadow;document.body.removeChild(temp2El);return value1===value2;}
const data=_getNumericAndUnit(value1);if(!data){return false;}
const numValue1=data[0];const numValue2=_convertValueToUnit(value2,data[1],cssProp,$target);return(Math.abs(numValue1-numValue2)<Number.EPSILON);}
function _isColorCombinationName(name){const number=parseInt(name);return(!isNaN(number)&&number%100!==0);}
function _computeColorClasses(colorNames,prefix='bg-'){let hasCCClasses=false;const isBgPrefix=(prefix==='bg-');const classes=colorNames.map(c=>{if(isBgPrefix&&_isColorCombinationName(c)){hasCCClasses=true;return`o_cc${c}`;}
return(prefix+c);});if(hasCCClasses){classes.push('o_cc');}
return classes;}
function _getCSSVariableValue(key,htmlStyle){if(htmlStyle===undefined){htmlStyle=editableWindow.getComputedStyle(editableWindow.document.documentElement);}
let value=htmlStyle.getPropertyValue(`--${key}`).trim();value=normalizeCSSColor(value);return value.replace(/"/g,"'");}
function _normalizeColor(color){if(isCSSColor(color)){return color;}
return _getCSSVariableValue(color);}
function _getBgImageURL(el){const parts=_backgroundImageCssToParts($(el).css('background-image'));const string=parts.url||'';const match=string.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;}
function _backgroundImageCssToParts(css){const parts={};css=css||'';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;}
function _backgroundImagePartsToCss(parts){let css=parts.url||'';if(parts.gradient){css+=(css?', ':'')+parts.gradient;}
return css||'none';}
function _isColorGradient(value){return value&&value.includes('-gradient(');}
function _generateHTMLId(){return`o${Math.random().toString(36).substring(2, 15)}`;}
function _getColorClass(el,colorNames,prefix){const prefixedColorNames=_computeColorClasses(colorNames,prefix);return el.classList.value.split(' ').filter(cl=>prefixedColorNames.includes(cl)).join(' ');}
function _addBackgroundImageAttributes(...newAttributes){BACKGROUND_IMAGE_ATTRIBUTES.add(...newAttributes);}
function _isBackgroundImageAttribute(attribute){return BACKGROUND_IMAGE_ATTRIBUTES.has(attribute);}
function _shouldEditableMediaBeEditable(mediaEl){const parentEl=mediaEl.parentElement;const nonEditableAncestorRootEl=parentEl&&parentEl.closest('[contenteditable="false"]');return nonEditableAncestorRootEl&&nonEditableAncestorRootEl.parentElement&&nonEditableAncestorRootEl.parentElement.isContentEditable;}
function _isMobileView(targetEl){const mobileViewThreshold=MEDIAS_BREAKPOINTS[SIZES.LG].minWidth;const clientWidth=targetEl.ownerDocument.defaultView?.frameElement?.clientWidth||targetEl.ownerDocument.documentElement.clientWidth;return clientWidth&&clientWidth<mobileViewThreshold;}
function _getLinkLabel(linkEl){return linkEl.textContent.replaceAll("\u200B","").replaceAll("\uFEFF","");}
function _forwardToThumbnail(imgEl){const carouselEl=imgEl.closest(".carousel");if(carouselEl){const carouselInnerEl=imgEl.closest(".carousel-inner");const carouselItemEl=imgEl.closest(".carousel-item");if(carouselInnerEl&&carouselItemEl){const imageIndex=[...carouselInnerEl.children].indexOf(carouselItemEl);const miniatureEl=carouselEl.querySelector(`.carousel-indicators [data-bs-slide-to="${imageIndex}"]`);if(miniatureEl&&miniatureEl.style.backgroundImage){miniatureEl.style.backgroundImage=`url(${imgEl.getAttribute("src")})`;}}}}
__exports[Symbol.for("default")]={COLOR_PALETTE_COMPATIBILITY_COLOR_NAMES:COLOR_PALETTE_COMPATIBILITY_COLOR_NAMES,CSS_SHORTHANDS:CSS_SHORTHANDS,CSS_UNITS_CONVERSION:CSS_UNITS_CONVERSION,DEFAULT_PALETTE:DEFAULT_PALETTE,EDITOR_COLOR_CSS_VARIABLES:EDITOR_COLOR_CSS_VARIABLES,computePxByRem:_computePxByRem,convertValueToUnit:_convertValueToUnit,convertNumericToUnit:_convertNumericToUnit,getNumericAndUnit:_getNumericAndUnit,areCssValuesEqual:_areCssValuesEqual,isColorCombinationName:_isColorCombinationName,isColorGradient:_isColorGradient,computeColorClasses:_computeColorClasses,getCSSVariableValue:_getCSSVariableValue,normalizeColor:_normalizeColor,getBgImageURL:_getBgImageURL,backgroundImageCssToParts:_backgroundImageCssToParts,backgroundImagePartsToCss:_backgroundImagePartsToCss,generateHTMLId:_generateHTMLId,getColorClass:_getColorClass,setEditableWindow:_setEditableWindow,setEditableDocument:_setEditableDocument,addBackgroundImageAttributes:_addBackgroundImageAttributes,isBackgroundImageAttribute:_isBackgroundImageAttribute,shouldEditableMediaBeEditable:_shouldEditableMediaBeEditable,isMobileView:_isMobileView,getLinkLabel:_getLinkLabel,forwardToThumbnail:_forwardToThumbnail,};return __exports;});;

/* /web_editor/static/src/js/common/wysiwyg_utils.js */
odoo.define('@web_editor/js/common/wysiwyg_utils',[],function(require){'use strict';let __exports={};__exports.isImg=isImg;function isImg(node){return(node&&(node.nodeName==="IMG"||(node.className&&node.className.match(/(^|\s)(media_iframe_video|o_image|fa)(\s|$)/i))));}
__exports.ancestors=ancestors;function ancestors(node,stopElement){if(!node||!node.parentElement||node===stopElement)return[];return[node.parentElement,...ancestors(node.parentElement,stopElement)];}
return __exports;});;

/* /web_editor/static/src/js/editor/odoo-editor/src/utils/utils.js */
odoo.define('@web_editor/js/editor/odoo-editor/src/utils/utils',[],function(require){'use strict';let __exports={};const DIRECTIONS=__exports.DIRECTIONS={LEFT:false,RIGHT:true,};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,};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');const YOUTUBE_URL_GET_VIDEO_ID=__exports.YOUTUBE_URL_GET_VIDEO_ID=/^(?:(?:https?:)?\/\/)?(?:(?:www|m)\.)?(?:youtube\.com|youtu\.be)(?:\/(?:[\w-]+\?v=|embed\/|v\/)?)([^\s?&#]+)(?:\S+)?$/i;const EMAIL_REGEX=__exports.EMAIL_REGEX=/^(mailto:)?[\w-.]+@(?:[\w-]+\.)+[\w-]{2,4}$/i;const PHONE_REGEX=__exports.PHONE_REGEX=/^(tel:(?:\/\/)?)?\+?[\d\s.\-()\/]{3,25}$/;const PROTECTED_BLOCK_TAG=__exports.PROTECTED_BLOCK_TAG=['TR','TD','TABLE','TBODY','UL','OL','LI'];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","o_small-fs","small"];const TEXT_STYLE_CLASSES=__exports.TEXT_STYLE_CLASSES=["display-1","display-2","display-3","display-4","lead","o_small","small"];const ZWNBSP_CHAR='\ufeff';const ZERO_WIDTH_CHARS=__exports.ZERO_WIDTH_CHARS=['\u200b',ZWNBSP_CHAR];const ZERO_WIDTH_CHARS_REGEX=__exports.ZERO_WIDTH_CHARS_REGEX=new RegExp(`[${ZERO_WIDTH_CHARS.join('')}]`,'g');__exports.leftPos=leftPos;function leftPos(node){return[node.parentNode,childNodeIndex(node)];}
__exports.rightPos=rightPos;function rightPos(node){return[node.parentNode,childNodeIndex(node)+1];}
__exports.boundariesOut=boundariesOut;function boundariesOut(node){const index=childNodeIndex(node);return[node.parentNode,index,node.parentNode,index+1];}
__exports.startPos=startPos;function startPos(node){return[node,0];}
__exports.endPos=endPos;function endPos(node){return[node,nodeSize(node)];}
__exports.boundariesIn=boundariesIn;function boundariesIn(node){return[node,0,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;return isTextNode?node.length:node.childNodes.length;}
const closestPath=__exports.closestPath=function*(node){while(node){yield node;node=node.parentNode;}};const PATH_END_REASONS={NO_NODE:0,BLOCK_OUT:1,BLOCK_HIT:2,OUT_OF_SCOPE:3,};__exports.createDOMPathGenerator=createDOMPathGenerator;function createDOMPathGenerator(direction,{leafOnly=false,inScope=false,stopTraverseFunction,stopFunction}={},){const nextDeepest=direction===DIRECTIONS.LEFT?node=>lastLeaf(node.previousSibling,stopTraverseFunction):node=>firstLeaf(node.nextSibling,stopTraverseFunction);const firstNode=direction===DIRECTIONS.LEFT?(node,offset)=>lastLeaf(node.childNodes[offset-1],stopTraverseFunction):(node,offset)=>firstLeaf(node.childNodes[offset],stopTraverseFunction);return function*(node,offset,reasons=[]){let movedUp=false;let currentNode=firstNode(node,offset);if(!currentNode){movedUp=true;currentNode=node;}
while(currentNode){if(stopFunction&&stopFunction(currentNode)){reasons.push(movedUp?PATH_END_REASONS.BLOCK_OUT:PATH_END_REASONS.BLOCK_HIT);break;}
if(inScope&&currentNode===node){reasons.push(PATH_END_REASONS.OUT_OF_SCOPE);break;}
if(!(leafOnly&&movedUp)){yield currentNode;}
movedUp=false;let nextNode=nextDeepest(currentNode);if(!nextNode){movedUp=true;nextNode=currentNode.parentNode;}
currentNode=nextNode;}
reasons.push(PATH_END_REASONS.NO_NODE);};}
__exports.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.getFurthestUneditableParent=getFurthestUneditableParent;function getFurthestUneditableParent(node,parentLimit){if(node===parentLimit||(parentLimit&&!parentLimit.contains(node))){return undefined;}
let parent=node&&node.parentElement;let nonEditableElement;while(parent&&(!parentLimit||parent!==parentLimit)){if(!parent.isContentEditable){nonEditableElement=parent;}
if(parent.oid==="root"){break;}
parent=parent.parentElement;}
return nonEditableElement;}
__exports.closestElement=closestElement;function closestElement(node,predicate="*"){if(!node)return null;let element=node.nodeType===Node.ELEMENT_NODE?node:node.parentElement;if(typeof predicate==='function'){while(element&&!predicate(element)){element=element.parentElement;}}else{element=element?.closest(predicate);}
return element?.closest('.odoo-editor-editable')&&element;}
__exports.ancestors=ancestors;function ancestors(node,editable){if(!node||!node.parentElement||node===editable)return[];return[node.parentElement,...ancestors(node.parentElement,editable)];}
__exports.descendants=descendants;function descendants(node){const posterity=[];for(const child of(node.childNodes||[])){posterity.push(child,...descendants(child));}
return posterity;}
__exports.closestBlock=closestBlock;function closestBlock(node){return findNode(closestPath(node),node=>isBlock(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.previousLeaf=previousLeaf;function previousLeaf(node,editable,skipInvisible=false){let ancestor=node;while(ancestor&&!ancestor.previousSibling&&ancestor!==editable){ancestor=ancestor.parentElement;}
if(ancestor&&ancestor!==editable){if(skipInvisible&&!isVisible(ancestor.previousSibling)){return previousLeaf(ancestor.previousSibling,editable,skipInvisible);}else{const last=lastLeaf(ancestor.previousSibling);if(skipInvisible&&!isVisible(last)){return previousLeaf(last,editable,skipInvisible);}else{return last;}}}}
__exports.nextLeaf=nextLeaf;function nextLeaf(node,editable,skipInvisible=false){let ancestor=node;while(ancestor&&!ancestor.nextSibling&&ancestor!==editable){ancestor=ancestor.parentElement;}
if(ancestor&&ancestor!==editable){if(skipInvisible&&ancestor.nextSibling&&!isVisible(ancestor.nextSibling)){return nextLeaf(ancestor.nextSibling,editable,skipInvisible);}else{const first=firstLeaf(ancestor.nextSibling);if(skipInvisible&&!isVisible(first)){return nextLeaf(first,editable,skipInvisible);}else{return first;}}}}
__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.hasTableSelection=hasTableSelection;function hasTableSelection(editable){return!!editable.querySelector('.o_selected_table');}
__exports.hasValidSelection=hasValidSelection;function hasValidSelection(editable){return hasTableSelection(editable)||editable.ownerDocument.getSelection().rangeCount>0;}
__exports.getNormalizedCursorPosition=getNormalizedCursorPosition;function getNormalizedCursorPosition(node,offset,full=true){const editable=closestElement(node,'.odoo-editor-editable');let closest=closestElement(node);while(closest&&closest!==editable&&(isSelfClosingElement(node)||!closest.isContentEditable)){[node,offset]=offset||!nodeSize(node)?rightPos(node):leftPos(node);closest=closestElement(node);}
offset=Math.min(Math.max(offset,0),nodeSize(node));if(full){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)||!closestElement(leftInlineNode).isContentEditable;[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);}}}}}
const prevNode=node.nodeType===Node.ELEMENT_NODE&&node.childNodes[offset-1];if(prevNode&&prevNode.nodeName==='BR'&&isFakeLineBreak(prevNode)){offset--;}
return[node,offset];}
__exports.insertSelectionChars=insertSelectionChars;function insertSelectionChars(anchorNode,anchorOffset,focusNode,focusOffset,startChar='[',endChar=']'){if(anchorNode===focusNode&&anchorOffset<=focusOffset){focusOffset+=(focusNode.nodeType===Node.TEXT_NODE?startChar.length:1);}
insertCharsAt(startChar,anchorNode,anchorOffset);insertCharsAt(endChar,focusNode,focusOffset);}
__exports.logSelection=logSelection;function logSelection(root,options={}){const sel=options.selection||root.ownerDocument.getSelection();if(!root.contains(sel.anchorNode)||!root.contains(sel.focusNode)){console.warn('The selection is not contained in the root.');return;}
let anchorClone,focusClone;const cloneTree=node=>{const clone=node.cloneNode();if(options.includeOids){clone.oid=node.oid;}
anchorClone=anchorClone||(node===sel.anchorNode&&clone);focusClone=focusClone||(node===sel.focusNode&&clone);for(const child of node.childNodes||[]){clone.append(cloneTree(child));}
return clone;}
const rootClone=cloneTree(root);insertSelectionChars(anchorClone,sel.anchorOffset,focusClone,sel.focusOffset,'%c[%c','%c]%c');rootClone.removeAttribute('data-last-history-steps');if(options.doFormat){const formatHtml=(node,spaces=0)=>{node.before(document.createTextNode('\n'+' '.repeat(spaces)));for(const child of[...node.childNodes]){formatHtml(child,spaces+4);}
if(node.nodeType!==Node.TEXT_NODE){node.appendChild(document.createTextNode('\n'+' '.repeat(spaces)));}
if(options.includeOids){if(node.nodeType===Node.TEXT_NODE){node.textContent+=` (${node.oid})`;}else{node.setAttribute('oid',node.oid);}}}
formatHtml(rootClone);}
const selectionCharacterStyle='color: #75bfff; font-weight: 700;';const defaultStyle='color: inherit; font-weight: inherit;';console.log(makeZeroWidthCharactersVisible(rootClone.outerHTML),selectionCharacterStyle,defaultStyle,selectionCharacterStyle,defaultStyle,);}
__exports.ensureFocus=ensureFocus;function ensureFocus(element){const activeElement=element.ownerDocument.activeElement;if(activeElement!==element&&(!element.contains(activeElement)||!activeElement.isContentEditable)){element.focus();}}
__exports.setSelection=setSelection;function setSelection(anchorNode,anchorOffset,focusNode=anchorNode,focusOffset=anchorOffset,normalize=true,){if(!anchorNode||!anchorNode.parentElement||!anchorNode.parentElement.closest('body')||!focusNode||!focusNode.parentElement||!focusNode.parentElement.closest('body')){return null;}
const document=anchorNode.ownerDocument;const seemsCollapsed=anchorNode===focusNode&&anchorOffset===focusOffset;[anchorNode,anchorOffset]=getNormalizedCursorPosition(anchorNode,anchorOffset,normalize);[focusNode,focusOffset]=seemsCollapsed?[anchorNode,anchorOffset]:getNormalizedCursorPosition(focusNode,focusOffset,normalize);const direction=getCursorDirection(anchorNode,anchorOffset,focusNode,focusOffset);const sel=document.getSelection();if(!sel){return null;}
try{const range=new Range();if(direction===DIRECTIONS.RIGHT){range.setStart(anchorNode,anchorOffset);range.collapse(true);}else{range.setEnd(anchorNode,anchorOffset);range.collapse(false);}
sel.removeAllRanges();sel.addRange(range);sel.extend(focusNode,focusOffset);}catch(e){if(e.name!=='NS_ERROR_FAILURE'){throw e;}}
return[anchorNode,anchorOffset,focusNode,focusOffset];}
__exports.setCursorStart=setCursorStart;function setCursorStart(node,normalize=true){const pos=startPos(node);return setSelection(...pos,...pos,normalize);}
__exports.setCursorEnd=setCursorEnd;function setCursorEnd(node,normalize=true){const pos=endPos(node);return setSelection(...pos,...pos,normalize);}
__exports.getCursorDirection=getCursorDirection;function getCursorDirection(anchorNode,anchorOffset,focusNode,focusOffset){if(anchorNode===focusNode){if(anchorOffset===focusOffset)return false;return anchorOffset<focusOffset?DIRECTIONS.RIGHT:DIRECTIONS.LEFT;}
return anchorNode.compareDocumentPosition(focusNode)&Node.DOCUMENT_POSITION_FOLLOWING?DIRECTIONS.RIGHT:DIRECTIONS.LEFT;}
__exports.getTraversedNodes=getTraversedNodes;function getTraversedNodes(editable,range=getDeepRange(editable)){const selectedTableCells=editable.querySelectorAll('.o_selected_td');const document=editable.ownerDocument;if(!range)return[];const iterator=document.createNodeIterator(range.commonAncestorContainer);let node;do{node=iterator.nextNode();}while(node&&node!==range.startContainer&&!(selectedTableCells.length&&node===selectedTableCells[0]));if(node&&!(selectedTableCells.length&&node===selectedTableCells[0])&&!range.collapsed&&node.nodeType===Node.ELEMENT_NODE&&node.childNodes.length&&range.startOffset&&node.childNodes[range.startOffset-1].nodeName==="BR"){const targetBr=node.childNodes[range.startOffset-1];while(node!=targetBr){node=iterator.nextNode();}
node=iterator.nextNode();}
if(node&&!range.collapsed&&node===range.startContainer&&range.startOffset===nodeSize(node)&&node.nextSibling&&node.nextSibling.nodeName==="BR"){node=iterator.nextNode();}
const traversedNodes=new Set([node,...descendants(node)]);while(node&&node!==range.endContainer){node=iterator.nextNode();if(node){const selectedTable=closestElement(node,'.o_selected_table');if(selectedTable){for(const selectedTd of selectedTable.querySelectorAll('.o_selected_td')){traversedNodes.add(selectedTd);descendants(selectedTd).forEach(descendant=>traversedNodes.add(descendant));}}else if(!(node===range.endContainer&&range.endOffset===0&&!range.collapsed&&node.previousSibling&&node.previousSibling.nodeName==="BR")){traversedNodes.add(node);}}}
if(node){for(const descendant of descendants(node)){if(descendant.parentElement===node&&childNodeIndex(descendant)>=range.endOffset){break;}
traversedNodes.add(descendant);}}
return[...traversedNodes];}
__exports.getSelectedNodes=getSelectedNodes;function getSelectedNodes(editable){const selectedTableCells=editable.querySelectorAll('.o_selected_td');const document=editable.ownerDocument;const sel=document.getSelection();if(!sel.rangeCount&&!selectedTableCells.length){return[];}
const range=sel.getRangeAt(0);return[...new Set(getTraversedNodes(editable).flatMap(node=>{const td=closestElement(node,'.o_selected_td');if(td){return descendants(td);}else if(range.isPointInRange(node,0)&&range.isPointInRange(node,nodeSize(node))){return node;}else{return[];}},))];}
__exports.getDeepRange=getDeepRange;function getDeepRange(editable,{range,sel,splitText,select,correctTripleClick}={}){sel=sel||editable.parentElement&&editable.ownerDocument.getSelection();if(sel&&sel.isCollapsed&&sel.anchorNode&&sel.anchorNode.nodeName==="BR"){setSelection(sel.anchorNode.parentElement,childNodeIndex(sel.anchorNode));}
range=range?range.cloneRange():sel&&sel.rangeCount&&sel.getRangeAt(0).cloneRange();if(!range)return;let start=range.startContainer;let startOffset=range.startOffset;let end=range.endContainer;let endOffset=range.endOffset;const isBackwards=!range.collapsed&&start===sel.focusNode&&startOffset===sel.focusOffset;[start,startOffset]=getDeepestPosition(start,startOffset);[end,endOffset]=getDeepestPosition(end,endOffset);if(splitText){const isInSingleContainer=start===end;if(end.nodeType===Node.TEXT_NODE&&endOffset!==0&&endOffset!==end.textContent.length){const endParent=end.parentNode;const splitOffset=splitTextNode(end,endOffset);end=endParent.childNodes[splitOffset-1]||endParent.firstChild;if(isInSingleContainer){start=end;}
endOffset=end.textContent.length;}
if(start.nodeType===Node.TEXT_NODE&&startOffset!==0&&startOffset!==start.textContent.length){splitTextNode(start,startOffset);startOffset=0;if(isInSingleContainer){endOffset=start.textContent.length;}}}
const endLeaf=firstLeaf(end);const beforeEnd=endLeaf.previousSibling;if(correctTripleClick&&!endOffset&&(start!==end||startOffset!==endOffset)&&(!beforeEnd||(beforeEnd.nodeType===Node.TEXT_NODE&&!isVisibleTextNode(beforeEnd)&&!isZWS(beforeEnd)))&&!closestElement(endLeaf,'table')){const previous=previousLeaf(endLeaf,editable,true);if(previous&&closestElement(previous).isContentEditable){[end,endOffset]=[previous,nodeSize(previous)];}}
if(select){if(isBackwards){[start,end,startOffset,endOffset]=[end,start,endOffset,startOffset];range.setEnd(start,startOffset);range.collapse(false);}else{range.setStart(start,startOffset);range.collapse(true);}
sel.removeAllRanges();sel.addRange(range);try{sel.extend(end,endOffset);}catch{}
range=sel.getRangeAt(0);}else{range.setStart(start,startOffset);range.setEnd(end,endOffset);}
return range;}
__exports.getAdjacentCharacter=getAdjacentCharacter;function getAdjacentCharacter(editable,side){let{focusNode,focusOffset}=editable.ownerDocument.getSelection();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];}}
return closestBlock(focusNode)===originalBlock?adjacentCharacter:undefined;}
function isZwnbsp(node){return node.nodeType===Node.TEXT_NODE&&node.textContent==='\ufeff';}
function isTangible(node){return isVisible(node)||isZwnbsp(node)||hasTangibleContent(node);}
function hasTangibleContent(node){return[...(node?.childNodes||[])].some(n=>isTangible(n));}
__exports.getDeepestPosition=getDeepestPosition;function getDeepestPosition(node,offset){let direction=DIRECTIONS.RIGHT;let next=node;while(next){if(isTangible(next)||isZWS(next)){if(next!==node){[node,offset]=[next,direction?0:nodeSize(next)];}
direction=offset<node.childNodes.length;next=node.childNodes[direction?offset:offset-1];}else if(direction&&next.nextSibling&&closestBlock(node).contains(next.nextSibling)){next=next.nextSibling;}else{direction=DIRECTIONS.LEFT;next=closestBlock(node).contains(next.previousSibling)&&next.previousSibling;}
next=!isSelfClosingElement(next)&&next;}
return[node,offset];}
__exports.getCursors=getCursors;function getCursors(document){const sel=document.getSelection();if(getCursorDirection(sel.anchorNode,sel.anchorOffset,sel.focusNode,sel.focusOffset)===DIRECTIONS.LEFT)
return[[sel.focusNode,sel.focusOffset],[sel.anchorNode,sel.anchorOffset],];return[[sel.anchorNode,sel.anchorOffset],[sel.focusNode,sel.focusOffset],];}
__exports.preserveCursor=preserveCursor;function preserveCursor(document){const sel=document.getSelection();const cursorPos=[sel.anchorNode,sel.anchorOffset,sel.focusNode,sel.focusOffset];return replace=>{replace=replace||new Map();cursorPos[0]=replace.get(cursorPos[0])||cursorPos[0];cursorPos[2]=replace.get(cursorPos[2])||cursorPos[2];return setSelection(...cursorPos,false);};}
__exports.isSelectionInSelectors=isSelectionInSelectors;function isSelectionInSelectors(selector){let anchor=document.getSelection().anchorNode;if(anchor&&anchor.nodeType&&anchor.nodeType!==Node.ELEMENT_NODE){anchor=anchor.parentElement;}
if(anchor&&closestElement(anchor,selector)){return true;}
return false;}
__exports.getOffsetAndCharSize=getOffsetAndCharSize;function getOffsetAndCharSize(nodeValue,offset,direction){const splittedNodeValue=[...nodeValue];let charSize=1;let newOffset=offset;let currentSize=0;for(const item of splittedNodeValue){currentSize+=item.length;if(currentSize>=offset){newOffset=direction==DIRECTIONS.LEFT?currentSize:currentSize-item.length;charSize=item.length;break;}}
return[newOffset,charSize];}
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-line'].includes('underline'),addStyle:(node)=>node.style['text-decoration-line']+=' underline',removeStyle:(node)=>removeStyle(node,'text-decoration-line','underline'),},strikeThrough:{tagName:'s',isFormatted:isStrikeThrough,isTag:(node)=>node.tagName==='S',hasStyle:(node)=>node.style&&node.style['text-decoration-line'].includes('line-through'),addStyle:(node)=>node.style['text-decoration-line']+=' line-through',removeStyle:(node)=>removeStyle(node,'text-decoration-line','line-through'),},fontSize:{isFormatted:isFontSize,hasStyle:(node)=>node.style&&node.style['font-size'],addStyle:(node,props)=>{node.style['font-size']=props.size;node.classList.remove(...FONT_SIZE_CLASSES);},removeStyle:(node)=>removeStyle(node,'font-size'),},setFontSizeClassName:{isFormatted:hasClass,hasStyle:(node,props)=>FONT_SIZE_CLASSES.find(cls=>node.classList.contains(cls)),addStyle:(node,props)=>node.classList.add(props.className),removeStyle:(node)=>{node.classList.remove(...FONT_SIZE_CLASSES,...TEXT_STYLE_CLASSES);if(node.classList.length===0){node.removeAttribute("class");}},},switchDirection:{isFormatted:isDirectionSwitched,}}
const 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');}};const getOrCreateSpan=(node,ancestors)=>{const span=ancestors.find((element)=>element.tagName==='SPAN'&&element.isConnected);if(span){return span;}else{const span=document.createElement('span');node.after(span);span.append(node);return span;}}
const removeFormat=(node,formatSpec)=>{node=closestElement(node);if(formatSpec.hasStyle(node)){formatSpec.removeStyle(node);if(['SPAN','FONT'].includes(node.tagName)&&!node.getAttributeNames().length){return unwrapContents(node);}}
if(formatSpec.isTag&&formatSpec.isTag(node)){const attributesNames=node.getAttributeNames().filter((name)=>{return name!=='data-oe-zws-empty-inline';});if(attributesNames.length){const newNode=document.createElement('span');while(node.firstChild){newNode.appendChild(node.firstChild);}
for(let index=node.attributes.length-1;index>=0;--index){newNode.attributes.setNamedItem(node.attributes[index].cloneNode());}
node.parentNode.replaceChild(newNode,node);}else{unwrapContents(node);}}}
const formatSelection=__exports.formatSelection=(editor,formatName,{applyStyle,formatProps}={})=>{const selection=editor.document.getSelection();let direction
let wasCollapsed;if(editor.editable.querySelector('.o_selected_td')){direction=DIRECTIONS.RIGHT;}else{if(!selection.rangeCount)return;wasCollapsed=selection.getRangeAt(0).collapsed;direction=getCursorDirection(selection.anchorNode,selection.anchorOffset,selection.focusNode,selection.focusOffset);}
getDeepRange(editor.editable,{splitText:true,select:true,correctTripleClick:true});if(typeof applyStyle==='undefined'){applyStyle=!isSelectionFormat(editor.editable,formatName);}
let zws;if(wasCollapsed){if(selection.anchorNode.nodeType===Node.TEXT_NODE&&selection.anchorNode.textContent==='\u200b'){zws=selection.anchorNode;selection.getRangeAt(0).selectNode(zws);}else{zws=insertAndSelectZws(selection);}
getDeepRange(editor.editable,{splitText:true,select:true,correctTripleClick:true});}
const selectedNodesInTds=[...editor.editable.querySelectorAll('.o_selected_td')].map(node=>closestElement(node).querySelector('br'));const selectedNodes=getSelectedNodes(editor.editable).filter(n=>n.nodeType===Node.TEXT_NODE&&closestElement(n).isContentEditable&&(isVisibleTextNode(n)||isZWS(n)));const selectedTextNodes=selectedNodes.length?selectedNodes:selectedNodesInTds;const selectedFieldNodes=new Set(getSelectedNodes(editor.editable).map(n=>closestElement(n,"*[t-field],*[t-out],*[t-esc]")).filter(Boolean));const formatSpec=formatsSpecs[formatName];for(const selectedTextNode of selectedTextNodes){const inlineAncestors=[];let currentNode=selectedTextNode;let parentNode=selectedTextNode.parentElement;while(parentNode&&!isBlock(parentNode)&&!isUnbreakable(parentNode)&&!isUnbreakable(currentNode)&&(parentNode.classList.length===0||[...parentNode.classList].every(cls=>FONT_SIZE_CLASSES.includes(cls)))){const isUselessZws=parentNode.tagName==='SPAN'&&parentNode.hasAttribute('data-oe-zws-empty-inline')&&parentNode.getAttributeNames().length===1;if(isUselessZws){unwrapContents(parentNode);}else{const newLastAncestorInlineFormat=splitAroundUntil(currentNode,parentNode);removeFormat(newLastAncestorInlineFormat,formatSpec);if(newLastAncestorInlineFormat.isConnected){inlineAncestors.push(newLastAncestorInlineFormat);currentNode=newLastAncestorInlineFormat;}}
parentNode=currentNode.parentElement;}
const firstBlockOrClassHasFormat=formatSpec.isFormatted(parentNode,formatProps);if(firstBlockOrClassHasFormat&&!applyStyle){formatSpec.addNeutralStyle&&formatSpec.addNeutralStyle(getOrCreateSpan(selectedTextNode,inlineAncestors));}else if(!firstBlockOrClassHasFormat&&applyStyle){const tag=formatSpec.tagName&&document.createElement(formatSpec.tagName);if(tag){selectedTextNode.after(tag);tag.append(selectedTextNode);if(!formatSpec.isFormatted(tag,formatProps)){tag.after(selectedTextNode);tag.remove();formatSpec.addStyle(getOrCreateSpan(selectedTextNode,inlineAncestors),formatProps);}}else if(formatName!=='fontSize'||formatProps.size!==undefined){formatSpec.addStyle(getOrCreateSpan(selectedTextNode,inlineAncestors),formatProps);}}}
for(const selectedFieldNode of selectedFieldNodes){if(applyStyle){formatSpec.addStyle(selectedFieldNode,formatProps);}else{formatSpec.removeStyle(selectedFieldNode);}}
if(zws){const siblings=[...zws.parentElement.childNodes];if(!isBlock(zws.parentElement)&&selectedTextNodes.includes(siblings[0])&&selectedTextNodes.includes(siblings[siblings.length-1])){zws.parentElement.setAttribute('data-oe-zws-empty-inline','');}else{const span=document.createElement('span');span.setAttribute('data-oe-zws-empty-inline','');zws.before(span);span.append(zws);}}
if(selectedTextNodes[0]&&selectedTextNodes[0].textContent==='\u200B'){setSelection(selectedTextNodes[0],0);}else if(selectedTextNodes.length){const firstNode=selectedTextNodes[0];const lastNode=selectedTextNodes[selectedTextNodes.length-1];if(direction===DIRECTIONS.RIGHT){setSelection(firstNode,0,lastNode,lastNode.length,false);}else{setSelection(lastNode,lastNode.length,firstNode,0,false);}}}
const isLinkEligibleForZwnbsp=__exports.isLinkEligibleForZwnbsp=(editable,link)=>{return link.isContentEditable&&editable.contains(link)&&!([link,...link.querySelectorAll('*')].some(el=>el.nodeName==='IMG'||isBlock(el))||link.matches('nav a, a.nav-link'));}
const padLinkWithZws=__exports.padLinkWithZws=(editable,link)=>{if(!isLinkEligibleForZwnbsp(editable,link)){return;}
const selection=editable.ownerDocument.getSelection()||{};const{anchorOffset,focusOffset}=selection;let extraAnchorOffset=0;let extraFocusOffset=0;if(!link.textContent.startsWith('\uFEFF')){if(selection.anchorNode===link&&anchorOffset){extraAnchorOffset+=1;}
if(selection.focusNode===link&&focusOffset){extraFocusOffset+=1;}
link.prepend(document.createTextNode('\uFEFF'));}
if(!link.textContent.endsWith('\uFEFF')){if(selection.anchorNode===link&&anchorOffset+extraAnchorOffset===nodeSize(link)){extraAnchorOffset+=1;}
if(selection.focusNode===link&&focusOffset+extraFocusOffset===nodeSize(link)){extraFocusOffset+=1;}
link.append(document.createTextNode('\uFEFF'));}
const linkIndex=childNodeIndex(link);if(!(link.previousSibling&&link.previousSibling.textContent.endsWith('\uFEFF'))){if(selection.anchorNode===link.parentElement&&anchorOffset+extraAnchorOffset>linkIndex){extraAnchorOffset+=1;}
if(selection.focusNode===link.parentElement&&focusOffset+extraFocusOffset>linkIndex){extraFocusOffset+=1;}
link.before(document.createTextNode('\uFEFF'));}
if(!(link.nextSibling&&link.nextSibling.textContent.startsWith('\uFEFF'))){if(selection.anchorNode===link.parentElement&&anchorOffset+extraAnchorOffset>linkIndex+1){extraAnchorOffset+=1;}
if(selection.focusNode===link.parentElement&&focusOffset+extraFocusOffset>linkIndex+1){extraFocusOffset+=1;}
link.after(document.createTextNode('\uFEFF'));}
if(extraAnchorOffset||extraFocusOffset){setSelection(selection.anchorNode,anchorOffset+extraAnchorOffset,selection.focusNode,focusOffset+extraFocusOffset,);}}
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 computedStyles=new WeakMap();__exports.isBlock=isBlock;function isBlock(node){if(!node||node.nodeType!==Node.ELEMENT_NODE){return false;}
const tagName=node.nodeName.toUpperCase();if(tagName.startsWith('JW-')||(tagName==='T'&&node.getAttribute('t-esc')===null&&node.getAttribute('t-out')===null&&node.getAttribute('t-raw')===null)){return true;}
if(tagName==='BR'){return false;}
if(!node.isConnected){return blockTagNames.includes(tagName);}
let style=computedStyles.get(node);if(!style){style=node.ownerDocument.defaultView?.getComputedStyle(node);computedStyles.set(node,style);}
if(style?.display){return!style.display.includes('inline')&&style.display!=='contents';}
return blockTagNames.includes(tagName);}
__exports.isBold=isBold;function isBold(node){const fontWeight=+getComputedStyle(closestElement(node)).fontWeight;return fontWeight>500||fontWeight>+getComputedStyle(closestBlock(node)).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(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');return getComputedStyle(closestElement(node)).direction!==defaultDirection;}
__exports.isSelectionFormat=isSelectionFormat;function isSelectionFormat(editable,format){const selectedNodes=getTraversedNodes(editable).filter((n)=>n.nodeType===Node.TEXT_NODE&&n.nodeValue.replaceAll(ZWNBSP_CHAR,'').length);const isFormatted=formatsSpecs[format].isFormatted;return selectedNodes.length&&selectedNodes.every(n=>isFormatted(n,editable));}
__exports.isUnbreakable=isUnbreakable;function isUnbreakable(node){if(!node||node.nodeType===Node.TEXT_NODE){return false;}
if(node.nodeType!==Node.ELEMENT_NODE){return true;}
return(isUnremovable(node)||['TABLE','THEAD','TBODY','TFOOT','TR','TH','TD','SECTION','DIV'].includes(node.tagName)||node.hasAttribute('t')||(node.nodeType===Node.ELEMENT_NODE&&(node.nodeName==='T'||node.getAttribute('t-if')||node.getAttribute('t-esc')||node.getAttribute('t-elif')||node.getAttribute('t-else')||node.getAttribute('t-foreach')||node.getAttribute('t-value')||node.getAttribute('t-out')||node.getAttribute('t-raw'))||node.getAttribute('t-field'))||node.classList.contains('oe_unbreakable'));}
__exports.isUnremovable=isUnremovable;function isUnremovable(node){return((node.nodeType!==Node.COMMENT_NODE&&node.nodeType!==Node.ELEMENT_NODE&&node.nodeType!==Node.TEXT_NODE)||node.oid==='root'||(node.nodeType===Node.ELEMENT_NODE&&(node.classList.contains('o_editable')||node.getAttribute('t-set')||node.getAttribute('t-call')))||(node.classList&&node.classList.contains('oe_unremovable'))||(node.nodeName==='SPAN'&&node.parentElement&&node.parentElement.getAttribute('data-oe-type')==='monetary')||(node.ownerDocument&&node.ownerDocument.defaultWindow&&!ancestors(node).find(ancestor=>ancestor.oid==='root')));}
__exports.containsUnbreakable=containsUnbreakable;function containsUnbreakable(node){if(!node){return false;}
return isUnbreakable(node)||containsUnbreakable(node.firstChild);}
const iconTags=['I','SPAN'];const iconClasses=['fa','fab','fad','far','oi'];__exports.isFontAwesome=isFontAwesome;function isFontAwesome(node){return(node&&iconTags.includes(node.nodeName)&&iconClasses.some(cls=>node.classList.contains(cls)));}
const ICON_SELECTOR=__exports.ICON_SELECTOR=iconTags.map(tag=>{return iconClasses.map(cls=>{return`${tag}.${cls}`;}).join(', ');}).join(', ');__exports.isZWS=isZWS;function isZWS(node){return(node&&node.textContent==='\u200B');}
__exports.isEditorTab=isEditorTab;function isEditorTab(node){return(node&&(node.nodeName==='SPAN')&&node.classList.contains('oe-tabs'));}
__exports.isMediaElement=isMediaElement;function isMediaElement(node){return(isFontAwesome(node)||(node.classList&&(node.classList.contains('o_image')||node.classList.contains('media_iframe_video'))));}
__exports.isProtected=isProtected;function isProtected(node){const closestProtectedElement=closestElement(node,'[data-oe-protected]');if(closestProtectedElement){return["","true"].includes(closestProtectedElement.dataset.oeProtected);}
return false;}
const VOID_ELEMENT_NAMES=['AREA','BASE','BR','COL','EMBED','HR','IMG','INPUT','KEYGEN','LINK','META','PARAM','SOURCE','TRACK','WBR'];__exports.isArtificialVoidElement=isArtificialVoidElement;function isArtificialVoidElement(node){return isMediaElement(node)||node.nodeName==='HR';}
__exports.isNotAllowedContent=isNotAllowedContent;function isNotAllowedContent(node){return isArtificialVoidElement(node)||VOID_ELEMENT_NAMES.includes(node.nodeName);}
__exports.containsUnremovable=containsUnremovable;function containsUnremovable(node){if(!node){return false;}
return isUnremovable(node)||containsUnremovable(node.firstChild);}
__exports.getInSelection=getInSelection;function getInSelection(document,selector){const selection=document.getSelection();const range=selection&&!!selection.rangeCount&&selection.getRangeAt(0);if(range){const selectorInStartAncestors=closestElement(range.startContainer,selector);if(selectorInStartAncestors){return selectorInStartAncestors;}else{const commonElementAncestor=closestElement(range.commonAncestorContainer);return commonElementAncestor&&[...commonElementAncestor.querySelectorAll(selector)].find(node=>range.intersectsNode(node),);}}}
__exports.getRowIndex=getRowIndex;function getRowIndex(trOrTd){const tr=closestElement(trOrTd,'tr');const trParent=tr&&tr.parentElement;if(!trParent){return-1;}
const trSiblings=[...trParent.children].filter(child=>child.nodeName==='TR');return trSiblings.findIndex(child=>child===tr);}
__exports.getColumnIndex=getColumnIndex;function getColumnIndex(td){const tdParent=td.parentElement;if(!tdParent){return-1;}
const tdSiblings=[...tdParent.children].filter(child=>child.nodeName==='TD'||child.nodeName==='TH');return tdSiblings.findIndex(child=>child===td);}
const paragraphRelatedElements=__exports.paragraphRelatedElements=['P','H1','H2','H3','H4','H5','H6','PRE','BLOCKQUOTE',];__exports.allowsParagraphRelatedElements=allowsParagraphRelatedElements;function allowsParagraphRelatedElements(node){return isBlock(node)&&!paragraphRelatedElements.includes(node.nodeName);}
__exports.makeContentsInline=makeContentsInline;function makeContentsInline(node){let childIndex=0;for(const child of node.childNodes){if(isBlock(child)){if(childIndex&&paragraphRelatedElements.includes(child.nodeName)){child.before(document.createElement('br'));}
for(const grandChild of child.childNodes){child.before(grandChild);makeContentsInline(grandChild);}
child.remove();}
childIndex+=1;}}
__exports.getOuid=getOuid;function getOuid(node,optimize=false){while(node&&!isUnbreakable(node)){if(node.ouid&&optimize)return node.ouid;node=node.parentNode;}
return node&&node.oid;}
__exports.isHtmlContentSupported=isHtmlContentSupported;function isHtmlContentSupported(node){return!closestElement(node,'[data-oe-model]:not([data-oe-field="arch"]):not([data-oe-type="html"]),[data-oe-translation-id]',true);}
const selfClosingElementTags=['BR','IMG','INPUT'];__exports.isSelfClosingElement=isSelfClosingElement;function isSelfClosingElement(node){return node&&selfClosingElementTags.includes(node.nodeName);}
__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 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);}
__exports.isVisible=isVisible;function isVisible(node){return!!node&&((node.nodeType===Node.TEXT_NODE&&isVisibleTextNode(node))||(node.nodeType===Node.ELEMENT_NODE&&(node.getAttribute("t-esc")||node.getAttribute("t-out")))||isSelfClosingElement(node)||isFontAwesome(node)||hasVisibleContent(node));}
__exports.hasVisibleContent=hasVisibleContent;function hasVisibleContent(node){return[...(node?.childNodes||[])].some(n=>isVisible(n));}
const visibleCharRegex=/[^\s\u200b]|[\u00A0\u0009]$/;__exports.isVisibleTextNode=isVisibleTextNode;function isVisibleTextNode(testedNode){if(!testedNode||!testedNode.length||testedNode.nodeType!==Node.TEXT_NODE){return false;}
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);}
__exports.parentsGet=parentsGet;function parentsGet(node,root=undefined){const parents=[];while(node){parents.unshift(node);if(node===root){break;}
node=node.parentNode;}
return parents;}
__exports.commonParentGet=commonParentGet;function commonParentGet(node1,node2,root=undefined){if(!node1||!node2){return null;}
const n1p=parentsGet(node1,root);const n2p=parentsGet(node2,root);while(n1p.length>1&&n1p[1]===n2p[1]){n1p.shift();n2p.shift();}
return n1p[0]===n2p[0]?n1p[0]:null;}
__exports.getListMode=getListMode;function getListMode(pnode){if(!["UL","OL"].includes(pnode.tagName))return;if(pnode.tagName=='OL')return'OL';return pnode.classList.contains('o_checklist')?'CL':'UL';}
__exports.createList=createList;function createList(mode){const node=document.createElement(mode=='OL'?'OL':'UL');if(mode=='CL'){node.classList.add('o_checklist');}
return node;}
__exports.insertListAfter=insertListAfter;function insertListAfter(afterNode,mode,content=[]){const list=createList(mode);afterNode.after(list);list.append(...content.map(c=>{const li=document.createElement('LI');li.append(...[].concat(c));return li;}),);return list;}
__exports.toggleList=toggleList;function toggleList(node,mode,offset=0){let pnode=node.closest('ul, ol');if(!pnode)return;const listMode=getListMode(pnode)+mode;if(['OLCL','ULCL'].includes(listMode)){pnode.classList.add('o_checklist');for(let li=pnode.firstElementChild;li!==null;li=li.nextElementSibling){if(li.style.listStyle!=='none'){li.style.listStyle=null;if(!li.style.all)li.removeAttribute('style');}}
pnode=setTagName(pnode,'UL');}else if(['CLOL','CLUL'].includes(listMode)){toggleClass(pnode,'o_checklist');pnode=setTagName(pnode,mode);}else if(['OLUL','ULOL'].includes(listMode)){pnode=setTagName(pnode,mode);}else{let currNode=node;while(currNode){currNode=currNode.oShiftTab(offset);}
return;}
return pnode;}
__exports.convertList=convertList;function convertList(node,toMode){if(!["UL","OL","LI"].includes(node.nodeName))return;const listMode=getListMode(node);if(listMode&&toMode!==listMode){node=toggleList(node,toMode);}
for(const child of node.childNodes){convertList(child,toMode);}
return node;}
__exports.toggleClass=toggleClass;function toggleClass(node,className){node.classList.toggle(className);if(!node.className){node.removeAttribute('class');}}
__exports.makeZeroWidthCharactersVisible=makeZeroWidthCharactersVisible;function makeZeroWidthCharactersVisible(text){return text.replaceAll('\u200B','//ZWSP//').replaceAll('\uFEFF','//ZWNBSP//');}
__exports.isFakeLineBreak=isFakeLineBreak;function isFakeLineBreak(brEl){return!(getState(...rightPos(brEl),DIRECTIONS.RIGHT).cType&(CTYPES.CONTENT|CTGROUPS.BR));}
__exports.isEmptyBlock=isEmptyBlock;function isEmptyBlock(blockEl){if(!blockEl||blockEl.nodeType!==Node.ELEMENT_NODE){return false;}
if(isFontAwesome(blockEl)||visibleCharRegex.test(blockEl.textContent)){return false;}
if(blockEl.querySelectorAll('br').length>=2){return false;}
const nodes=blockEl.querySelectorAll('*');for(const node of nodes){if(node.nodeName!='BR'&&(isSelfClosingElement(node)||isFontAwesome(node))){return false;}}
return true;}
__exports.isShrunkBlock=isShrunkBlock;function isShrunkBlock(blockEl){return(isEmptyBlock(blockEl)&&!blockEl.querySelector('br')&&blockEl.nodeName!=="IMG");}
__exports.isColorGradient=isColorGradient;function isColorGradient(value){return value&&value.includes('-gradient(');}
__exports.getFontSizeDisplayValue=getFontSizeDisplayValue;function getFontSizeDisplayValue(sel,getCSSVariableValue,convertNumericToUnit){const tagNameRelatedToFontSize=["h1","h2","h3","h4","h5","h6"];const styleClassesRelatedToFontSize=["display-1","display-2","display-3","display-4"];const closestStartContainerEl=closestElement(sel.getRangeAt(0).startContainer);const closestFontSizedEl=closestStartContainerEl.closest(`
        [style*='font-size'],
        ${FONT_SIZE_CLASSES.map(className => `.${className}`)},
        ${styleClassesRelatedToFontSize.map(className => `.${className}`)},
        ${tagNameRelatedToFontSize}
    `);let remValue;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=styleClassesRelatedToFontSize.find(className=>closestFontSizedEl.classList.contains(className))||closestFontSizedEl.tagName.toLowerCase();}
remValue=parseFloat(getCSSVariableValue(`${fsName}-font-size`));}
if(remValue===undefined){remValue=parseFloat(getCSSVariableValue("font-size-base"));}
const pxValue=convertNumericToUnit(remValue,"rem","px");return pxValue||parseFloat(getComputedStyle(closestStartContainerEl).fontSize);}
__exports.splitTextNode=splitTextNode;function splitTextNode(textNode,offset,originalNodeSide=DIRECTIONS.RIGHT){let parentOffset=childNodeIndex(textNode);if(offset>0){parentOffset++;if(offset<textNode.length){const left=textNode.nodeValue.substring(0,offset);const right=textNode.nodeValue.substring(offset);if(originalNodeSide===DIRECTIONS.LEFT){const newTextNode=document.createTextNode(right);textNode.after(newTextNode);textNode.nodeValue=left;}else{const newTextNode=document.createTextNode(left);textNode.before(newTextNode);textNode.nodeValue=right;}}}
return parentOffset;}
__exports.splitElement=splitElement;function splitElement(element,offset){const before=element.cloneNode();const after=element.cloneNode();let index=0;for(const child of[...element.childNodes]){index<offset?before.appendChild(child):after.appendChild(child);index++;}
const blockEl=closestBlock(after);if(blockEl){fillEmpty(blockEl);}
element.before(before);element.after(after);element.remove();return[before,after];}
__exports.splitAroundUntil=splitAroundUntil;function splitAroundUntil(elements,limitAncestor){elements=Array.isArray(elements)?elements:[elements];const firstNode=elements[0];const lastNode=elements[elements.length-1];if([firstNode,lastNode].includes(limitAncestor)){return limitAncestor;}
let before=firstNode.previousSibling;let after=lastNode.nextSibling;let beforeSplit,afterSplit;if(!before&&!after&&elements[0]!==limitAncestor){return splitAroundUntil(elements[0].parentElement,limitAncestor);}
while(after&&after.parentElement!==limitAncestor){afterSplit=splitElement(after.parentElement,childNodeIndex(after))[0];after=afterSplit.nextSibling;}
if(after){afterSplit=splitElement(limitAncestor,childNodeIndex(after))[0];limitAncestor=afterSplit;}
while(before&&before.parentElement!==limitAncestor){beforeSplit=splitElement(before.parentElement,childNodeIndex(before)+1)[1];before=beforeSplit.previousSibling;}
if(before){beforeSplit=splitElement(limitAncestor,childNodeIndex(before)+1)[1];}
return beforeSplit||afterSplit||limitAncestor;}
__exports.insertText=insertText;function insertText(sel,content){if(!content){return;}
if(sel.anchorNode.nodeType===Node.TEXT_NODE){const pos=[sel.anchorNode.parentElement,splitTextNode(sel.anchorNode,sel.anchorOffset)];setSelection(...pos,...pos,false);}
const txt=document.createTextNode(content||'#');const restore=prepareUpdate(sel.anchorNode,sel.anchorOffset);sel.getRangeAt(0).insertNode(txt);restore();setSelection(...boundariesOut(txt),false);return txt;}
__exports.insertCharsAt=insertCharsAt;function insertCharsAt(chars,node,offset){if(node.nodeType===Node.TEXT_NODE){const startValue=node.nodeValue;if(offset<0||offset>startValue.length){throw new Error(`Invalid ${chars} insertion in text node`);}
node.nodeValue=startValue.slice(0,offset)+chars+startValue.slice(offset);}else{if(offset<0||offset>node.childNodes.length){throw new Error(`Invalid ${chars} insertion in non-text node`);}
const textNode=document.createTextNode(chars);if(offset<node.childNodes.length){node.insertBefore(textNode,node.childNodes[offset]);}else{node.appendChild(textNode);}}}
__exports.unwrapContents=unwrapContents;function unwrapContents(node){const contents=[...node.childNodes];for(const child of contents){node.parentNode.insertBefore(child,node);}
node.parentNode.removeChild(node);return contents;}
__exports.fillEmpty=fillEmpty;function fillEmpty(el){const fillers={};const blockEl=closestBlock(el);if(isShrunkBlock(blockEl)){const br=document.createElement('br');blockEl.appendChild(br);fillers.br=br;}
if(!isTangible(el)&&!el.hasAttribute("data-oe-zws-empty-inline")&&!el.hasChildNodes()){const zws=document.createTextNode('\u200B');el.appendChild(zws);el.setAttribute("data-oe-zws-empty-inline","");fillers.zws=zws;const previousSibling=el.previousSibling;if(previousSibling&&previousSibling.nodeName==="BR"){previousSibling.remove();}
setSelection(zws,0,zws,0);}
if(!isVisible(el)&&el.nodeName!=='A'&&closestElement(el,'a')&&getComputedStyle(el).display==='inline'){el.style.display='inline-block';}
return fillers;}
__exports.insertAndSelectZws=insertAndSelectZws;function insertAndSelectZws(selection){const offset=selection.anchorOffset;const zws=insertText(selection,'\u200B');splitTextNode(zws,offset);selection.getRangeAt(0).selectNode(zws);return zws;}
__exports.setTagName=setTagName;function setTagName(el,newTagName){if(el.tagName===newTagName){return el;}
const n=document.createElement(newTagName);if(el.nodeName!=='LI'){const attributes=el.attributes;for(const attr of attributes){n.setAttribute(attr.name,attr.value);}}
while(el.firstChild){n.append(el.firstChild);}
if(el.tagName==='LI'){el.append(n);}else{el.parentNode.replaceChild(n,el);}
return n;}
__exports.moveNodes=moveNodes;function moveNodes(destinationEl,destinationOffset,sourceEl,startIndex=0,endIndex=sourceEl.childNodes.length,){if(selfClosingElementTags.includes(destinationEl.nodeName)){throw new Error(`moveNodes: Invalid destination element ${destinationEl.nodeName}`);}
const nodes=[];for(let i=startIndex;i<endIndex;i++){nodes.push(sourceEl.childNodes[i]);}
if(nodes.length){const restoreDestination=prepareUpdate(destinationEl,destinationOffset);const restoreMoved=prepareUpdate(...leftPos(sourceEl.childNodes[startIndex]),...rightPos(sourceEl.childNodes[endIndex-1]),);const fragment=document.createDocumentFragment();nodes.forEach(node=>fragment.appendChild(node));const posRightNode=destinationEl.childNodes[destinationOffset];if(posRightNode){destinationEl.insertBefore(fragment,posRightNode);}else{destinationEl.appendChild(fragment);}
restoreDestination();restoreMoved();}
if(!nodeSize(sourceEl)){const restoreOrigin=prepareUpdate(...boundariesOut(sourceEl));sourceEl.remove();restoreOrigin();}
const firstNode=nodes.find(node=>!!node.parentNode);return firstNode?leftPos(firstNode):[destinationEl,destinationOffset];}
__exports.resetOuids=resetOuids;function resetOuids(node){node.ouid=undefined;for(const descendant of descendants(node)){descendant.ouid=undefined;}}
const prepareUpdateLockedEditables=new Set();__exports.prepareUpdate=prepareUpdate;function prepareUpdate(...args){const closestRoot=args.length&&ancestors(args[0]).find(ancestor=>ancestor.oid==='root');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&&makeZeroWidthCharactersVisible(editable.innerHTML).replaceAll(' ','_')||'';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);}};}
__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.replaceAll('\ufeff','');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|CTGROUPS.BLOCK},{spaceVisibility: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'+makeZeroWidthCharactersVisible(node.textContent).replaceAll(' ','_')+'\n'+'%c'+(direction===DIRECTIONS.LEFT?'left':'right')+'\n'+'%c'+ctypeToString(cType1)+'\n'+'%c'+ctypeToString(cType2)+'\n'+'%c'+'BEFORE: '+(oldEditableHTML||'(unavailable)')+'\n'+'%c'+'AFTER:  '+(editable?makeZeroWidthCharactersVisible(editable.innerHTML).replaceAll(' ','_'):'(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.enforceWhitespace=enforceWhitespace;function enforceWhitespace(el,offset,direction,rule){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.rgbToHex=rgbToHex;function rgbToHex(rgb='',node=null){if(rgb.startsWith('#')){return rgb;}else if(rgb.startsWith('rgba')){const values=rgb.match(/[\d\.]{1,5}/g)||[];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(/[\d\.]{1,5}/g)||[]).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.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.pxToFloat=pxToFloat;function pxToFloat(sizeString){return parseFloat(sizeString.replace('px',''));}
__exports.getRangePosition=getRangePosition;function getRangePosition(el,document,options={}){const selection=document.getSelection();if(!selection.rangeCount)return;const range=selection.getRangeAt(0);const isRtl=options.direction==='rtl';const marginRight=options.marginRight||20;const marginBottom=options.marginBottom||20;const marginTop=options.marginTop||10;const marginLeft=options.marginLeft||10;let offset;if(range.endOffset-1>0){const clonedRange=range.cloneRange();clonedRange.setStart(range.endContainer,range.endOffset-1);clonedRange.setEnd(range.endContainer,range.endOffset);const rect=clonedRange.getBoundingClientRect();offset={height:rect.height,left:rect.left+rect.width,top:rect.top};clonedRange.detach();}
if(!offset||offset.height===0){const clonedRange=range.cloneRange();const shadowCaret=document.createTextNode('|');clonedRange.insertNode(shadowCaret);clonedRange.selectNode(shadowCaret);const rect=clonedRange.getBoundingClientRect();offset={height:rect.height,left:rect.left,top:rect.top};shadowCaret.remove();clonedRange.detach();}
if(isRtl){offset.right=offset.left-el.offsetWidth;const leftMove=Math.max(0,offset.right+el.offsetWidth+marginLeft-window.innerWidth);if(leftMove&&offset.right-leftMove>marginRight){offset.right-=leftMove;}else if(offset.right-leftMove<marginRight){offset.right=marginRight;}}
const leftMove=Math.max(0,offset.left+el.offsetWidth+marginRight-window.innerWidth);if(leftMove&&offset.left-leftMove>marginLeft){offset.left-=leftMove;}else if(offset.left-leftMove<marginLeft){offset.left=marginLeft;}
if(options.getContextFromParentRect){const parentContextRect=options.getContextFromParentRect();offset.left+=parentContextRect.left;offset.top+=parentContextRect.top;if(isRtl){offset.right+=parentContextRect.left;}}
if(offset.top-marginTop+offset.height+el.offsetHeight>window.innerHeight&&offset.top-el.offsetHeight-marginBottom>0){offset.top-=el.offsetHeight;}else{offset.top+=offset.height;}
if(offset){offset.top+=window.scrollY;offset.left+=window.scrollX;if(isRtl){offset.right+=window.scrollX;}}
if(isRtl){offset.right=window.innerWidth-offset.right-el.offsetWidth;}
return offset;}
const isNotEditableNode=__exports.isNotEditableNode=node=>node.getAttribute&&node.getAttribute('contenteditable')&&node.getAttribute('contenteditable').toLowerCase()==='false';const isRoot=__exports.isRoot=node=>node.oid==="root";const leftLeafFirstPath=__exports.leftLeafFirstPath=createDOMPathGenerator(DIRECTIONS.LEFT);const leftLeafOnlyNotBlockPath=__exports.leftLeafOnlyNotBlockPath=createDOMPathGenerator(DIRECTIONS.LEFT,{leafOnly:true,stopTraverseFunction:isBlock,stopFunction:node=>isBlock(node)||isRoot(node),});const leftLeafOnlyInScopeNotBlockEditablePath=__exports.leftLeafOnlyInScopeNotBlockEditablePath=createDOMPathGenerator(DIRECTIONS.LEFT,{leafOnly:true,inScope:true,stopTraverseFunction:node=>isNotEditableNode(node)||isBlock(node),stopFunction:node=>isNotEditableNode(node)||isBlock(node)||isRoot(node),});const rightLeafOnlyNotBlockPath=__exports.rightLeafOnlyNotBlockPath=createDOMPathGenerator(DIRECTIONS.RIGHT,{leafOnly:true,stopTraverseFunction:isBlock,stopFunction:node=>isBlock(node)||isRoot(node),});const rightLeafOnlyPathNotBlockNotEditablePath=__exports.rightLeafOnlyPathNotBlockNotEditablePath=createDOMPathGenerator(DIRECTIONS.RIGHT,{leafOnly:true,stopFunction:node=>isRoot(node),});const rightLeafOnlyInScopeNotBlockEditablePath=__exports.rightLeafOnlyInScopeNotBlockEditablePath=createDOMPathGenerator(DIRECTIONS.RIGHT,{leafOnly:true,inScope:true,stopTraverseFunction:node=>isNotEditableNode(node)||isBlock(node),stopFunction:node=>isNotEditableNode(node)||isBlock(node)||isRoot(node),});const rightLeafOnlyNotBlockNotEditablePath=__exports.rightLeafOnlyNotBlockNotEditablePath=createDOMPathGenerator(DIRECTIONS.RIGHT,{leafOnly:true,stopTraverseFunction:node=>isNotEditableNode(node)||isBlock(node),stopFunction:node=>isBlock(node)&&!isNotEditableNode(node)||isRoot(node),});__exports.peek=peek;function peek(arr){return arr[arr.length-1];}
__exports.isMacOS=isMacOS;function isMacOS(){return window.navigator.userAgent.includes('Mac');}
__exports.cleanZWS=cleanZWS;function cleanZWS(node){[node,...descendants(node)].filter(node=>node.nodeType===Node.TEXT_NODE&&node.nodeValue.includes('\u200B')).forEach(node=>node.nodeValue=node.nodeValue.replace(/\u200B/g,''));}
return __exports;});;

/* /web_editor/static/src/js/wysiwyg/fonts.js */
odoo.define('@web_editor/js/wysiwyg/fonts',[],function(require){'use strict';let __exports={};const fonts=__exports.fonts={cacheCssSelectors:{},getCssSelectors:function(filter){if(this.cacheCssSelectors[filter]){return this.cacheCssSelectors[filter];}
this.cacheCssSelectors[filter]=[];var sheets=document.styleSheets;for(var i=0;i<sheets.length;i++){var rules;try{rules=sheets[i].rules||sheets[i].cssRules;}catch{continue;}
if(!rules){continue;}
for(var r=0;r<rules.length;r++){var selectorText=rules[r].selectorText;if(!selectorText){continue;}
var selectors=selectorText.split(/\s*,\s*/);var data=null;for(var s=0;s<selectors.length;s++){var match=selectors[s].trim().match(filter);if(!match){continue;}
if(!data){data={selector:match[0],css:rules[r].cssText.replace(/(^.*\{\s*)|(\s*\}\s*$)/g,''),names:[match[1]]};}else{data.selector+=(', '+match[0]);data.names.push(match[1]);}}
if(data){this.cacheCssSelectors[filter].push(data);}}}
return this.cacheCssSelectors[filter];},fontIcons:[{base:'fa',parser:/\.(fa-(?:\w|-)+)::?before/i}],computedFonts:false,computeFonts:function(){if(!this.computedFonts){var self=this;this.fontIcons.forEach((data)=>{data.cssData=self.getCssSelectors(data.parser);data.alias=data.cssData.map((x)=>x.names).flat();});this.computedFonts=true;}},};__exports[Symbol.for("default")]=fonts;return __exports;});;

/* /web_editor/static/src/js/frontend/loadWysiwygFromTextarea.js */
odoo.define('@web_editor/js/frontend/loadWysiwygFromTextarea',['@web/core/assets','@web/legacy/utils'],function(require){'use strict';let __exports={};const{loadBundle}=require("@web/core/assets");const{attachComponent}=require('@web/legacy/utils');__exports.loadWysiwygFromTextarea=loadWysiwygFromTextarea;async function loadWysiwygFromTextarea(parent,textarea,options){var loading=textarea.nextElementSibling;if(loading&&!loading.classList.contains('o_wysiwyg_loading')){loading=null;}
const $textarea=$(textarea);const currentOptions=Object.assign({},options);currentOptions.value=currentOptions.value||$textarea.val()||'';if(!currentOptions.value.trim()){currentOptions.value='<p><br></p>';}
await loadBundle("web_editor.assets_wysiwyg");const{Wysiwyg}=await odoo.loader.modules.get('@web_editor/js/wysiwyg/wysiwyg');let wysiwyg;class LegacyWysiwyg extends Wysiwyg{constructor(...args){super(...args);wysiwyg=this;}}
const $wysiwygWrapper=$textarea.closest('.o_wysiwyg_textarea_wrapper');const $form=$textarea.closest('form');$textarea.hide();$form.append($textarea);$wysiwygWrapper.html('');const wysiwygWrapper=$wysiwygWrapper[0];await attachComponent(parent,wysiwygWrapper,LegacyWysiwyg,{options:currentOptions,editingValue:currentOptions.value,});$form.find('.note-editable').data('wysiwyg',wysiwyg);$form.find('.note-editable').find('img.o_we_selected_image').removeClass('o_we_selected_image');let b64imagesPending=true;$form.on('click','button[type=submit]',(ev)=>{if(b64imagesPending){ev.preventDefault();wysiwyg.savePendingImages().finally(()=>{b64imagesPending=false;ev.currentTarget.click();});}else{$form.find('.note-editable').find('img.o_we_selected_image').removeClass('o_we_selected_image');$form.find('.note-editable').find('img.float-start').removeClass('float-start');$textarea.val(wysiwyg.getValue());}});return wysiwyg;};return __exports;});;

/* /auth_signup/static/src/js/signup.js */
odoo.define('@auth_signup/js/signup',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.SignUpForm=publicWidget.Widget.extend({selector:'.oe_signup_form',events:{'submit':'_onSubmit',},_onSubmit:function(){var $btn=this.$('.oe_login_buttons > button[type="submit"]');$btn.attr('disabled','disabled');$btn.prepend('<i class="fa fa-refresh fa-spin"/> ');},});return __exports;});;

/* /portal/static/src/js/portal.js */
odoo.define('@portal/js/portal',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.portalDetails=publicWidget.Widget.extend({selector:'.o_portal_details',events:{'change select[name="country_id"]':'_onCountryChange',},start:function(){var def=this._super.apply(this,arguments);this.$state=this.$('select[name="state_id"]');this.$stateOptions=this.$state.filter(':enabled').find('option:not(:first)');this._adaptAddressForm();return def;},_adaptAddressForm:function(){var $country=this.$('select[name="country_id"]');var countryID=($country.val()||0);this.$stateOptions.detach();var $displayedState=this.$stateOptions.filter('[data-country_id='+countryID+']');var nb=$displayedState.appendTo(this.$state).show().length;this.$state.parent().toggle(nb>=1);},_onCountryChange:function(){this._adaptAddressForm();},});const PortalHomeCounters=__exports.PortalHomeCounters=publicWidget.Widget.extend({selector:'.o_portal_my_home',init(){this._super(...arguments);this.rpc=this.bindService("rpc");},start:function(){var def=this._super.apply(this,arguments);this._updateCounters();return def;},_getCountersAlwaysDisplayed(){return[];},async _updateCounters(elem){const numberRpc=3;const needed=Object.values(this.el.querySelectorAll('[data-placeholder_count]')).map(documentsCounterEl=>documentsCounterEl.dataset['placeholder_count']);const counterByRpc=Math.ceil(needed.length/numberRpc);const countersAlwaysDisplayed=this._getCountersAlwaysDisplayed();const proms=[...Array(Math.min(numberRpc,needed.length)).keys()].map(async i=>{const documentsCountersData=await this.rpc("/my/counters",{counters:needed.slice(i*counterByRpc,(i+1)*counterByRpc)});Object.keys(documentsCountersData).forEach(counterName=>{const documentsCounterEl=this.el.querySelector(`[data-placeholder_count='${counterName}']`);documentsCounterEl.textContent=documentsCountersData[counterName];if(documentsCountersData[counterName]!==0||countersAlwaysDisplayed.includes(counterName)){documentsCounterEl.closest('.o_portal_index_card').classList.remove('d-none');}});return documentsCountersData;});return Promise.all(proms).then((results)=>{this.el.querySelector('.o_portal_doc_spinner').remove();});},});publicWidget.registry.PortalHomeCounters=PortalHomeCounters;publicWidget.registry.portalSearchPanel=publicWidget.Widget.extend({selector:'.o_portal_search_panel',events:{'click .dropdown-item':'_onDropdownItemClick','submit':'_onSubmit',},start:function(){var def=this._super.apply(this,arguments);this._adaptSearchLabel(this.$('.dropdown-item.active'));return def;},_adaptSearchLabel:function(elem){var $label=$(elem).clone();$label.find('span.nolabel').remove();this.$('input[name="search"]').attr('placeholder',$label.text().trim());},_search:function(){var search=new URL(window.location).searchParams;search.set("search_in",this.$('.dropdown-item.active').attr('href')?.replace('#','')||"");search.set("search",this.$('input[name="search"]').val());window.location.search=search.toString();},_onDropdownItemClick:function(ev){ev.preventDefault();var $item=$(ev.currentTarget);$item.closest('.dropdown-menu').find('.dropdown-item').removeClass('active');$item.addClass('active');this._adaptSearchLabel(ev.currentTarget);},_onSubmit:function(ev){ev.preventDefault();this._search();},});return __exports;});;

/* /portal/static/src/js/portal_chatter.js */
odoo.define('@portal/js/portal_chatter',['@web/core/utils/render','@web/legacy/js/core/dom','@web/legacy/js/public/public_widget','@portal/js/portal_composer','@web/core/utils/numbers','@odoo/owl'],function(require){'use strict';let __exports={};const{renderToElement}=require("@web/core/utils/render");const dom=require("@web/legacy/js/core/dom")[Symbol.for("default")];const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const portalComposer=require("@portal/js/portal_composer")[Symbol.for("default")];const{range}=require("@web/core/utils/numbers");const{Component,markup}=require("@odoo/owl");var PortalChatter=publicWidget.Widget.extend({template:'portal.Chatter',events:{'click .o_portal_chatter_pager_btn':'_onClickPager','click .o_portal_chatter_js_is_internal':'async _onClickUpdateIsInternal',},init:function(parent,options){this.options={};this._super.apply(this,arguments);this._setOptions(options);this.set('messages',[]);this.set('message_count',this.options['message_count']);this.set('pager',{});this.set('domain',this.options['domain']);this._currentPage=this.options['pager_start'];this.rpc=this.bindService("rpc");},willStart:function(){return Promise.all([this._super.apply(this,arguments),this._chatterInit()]);},start:function(){this.on("change:messages",this,this._renderMessages);this.on("change:message_count",this,function(){this._renderMessageCount();this.set('pager',this._pager(this._currentPage));});this.on("change:pager",this,this._renderPager);this.on("change:domain",this,this._onChangeDomain);this.set('message_count',this.options['message_count']);this.set('messages',this.preprocessMessages(this.result['messages']));Component.env.bus.addEventListener('reload_chatter_content',(ev)=>this._reloadChatterContent(ev.detail));return Promise.all([this._super.apply(this,arguments),this._reloadComposer()]);},messageFetch:function(domain){var self=this;return this.rpc('/mail/chatter_fetch',self._messageFetchPrepareParams()).then(function(result){self.set('messages',self.preprocessMessages(result['messages']));self.set('message_count',result['message_count']);return result;});},preprocessMessages(messages){messages.forEach((m)=>{m['body']=markup(m.body);});return messages;},_setOptions:function(options){const defaultOptions=Object.assign({'allow_composer':true,'display_composer':false,'csrf_token':odoo.csrf_token,'message_count':0,'pager_step':10,'pager_scope':5,'pager_start':1,'is_user_public':true,'is_user_employee':false,'is_user_publisher':false,'hash':false,'pid':false,'domain':[],'two_columns':false,},this.options||{});this.options=Object.entries(options).reduce((acc,[key,value])=>{acc[key.split(/\.?(?=[A-Z])/).join("_").toLowerCase()]=value;return acc;},defaultOptions);},_reloadChatterContent:function(data){this.messageFetch();this._reloadComposer();},_createComposerWidget:function(){return new portalComposer.PortalComposer(this,this.options);},_reloadComposer:async function(){if(this._composer){this._composer.destroy();}
if(this.options.display_composer){this._composer=this._createComposerWidget();await this._composer.appendTo(this.$('.o_portal_chatter_composer'));}},_chatterInit:function(){var self=this;return this.rpc('/mail/chatter_init',this._messageFetchPrepareParams()).then(function(result){self.result=result;self.options=Object.assign(self.options,self.result['options']||{});return result;});},_changeCurrentPage:function(page,domain){this._currentPage=page;var d=domain?domain:Object.assign({},this.get("domain"));this.set('domain',d);},_messageFetchPrepareParams:function(){var self=this;var data={'res_model':this.options['res_model'],'res_id':this.options['res_id'],'limit':this.options['pager_step'],'offset':(this._currentPage-1)*this.options['pager_step'],'allow_composer':this.options['allow_composer'],};if(self.options['token']){data['token']=self.options['token'];}
if(self.options['hash']&&self.options['pid']){Object.assign(data,{'hash':self.options['hash'],'pid':self.options['pid'],});}
if(this.get('domain')){data['domain']=this.get('domain');}
return data;},_pager:function(page){page=page||1;var total=this.get('message_count');var scope=this.options['pager_scope'];var step=this.options['pager_step'];var pageCount=Math.ceil(parseFloat(total)/step);page=Math.max(1,Math.min(parseInt(page),pageCount));scope-=1;var pmin=Math.max(page-parseInt(Math.floor(scope/2)),1);var pmax=Math.min(pmin+scope,pageCount);if(pmax-scope>0){pmin=pmax-scope;}else{pmin=1;}
var pages=[];range(pmin,pmax+1).forEach(index=>pages.push(index));return{"page_count":pageCount,"offset":(page-1)*step,"page":page,"page_start":pmin,"page_previous":Math.max(pmin,page-1),"page_next":Math.min(pmax,page+1),"page_end":pmax,"pages":pages};},_renderMessages:function(){this.$('.o_portal_chatter_messages').empty().append(renderToElement("portal.chatter_messages",{widget:this}));},_renderMessageCount:function(){this.$('.o_message_counter').replaceWith(renderToElement("portal.chatter_message_count",{widget:this}));},_renderPager:function(){this.$('.o_portal_chatter_pager').replaceWith(renderToElement("portal.pager",{widget:this}));},_onChangeDomain:function(){var self=this;return this.messageFetch().then(function(){var p=self._currentPage;self.set('pager',self._pager(p));});},_onClickPager:function(ev){ev.preventDefault();var page=$(ev.currentTarget).data('page');this._changeCurrentPage(page);},_onClickUpdateIsInternal:function(ev){ev.preventDefault();var $elem=$(ev.currentTarget);return this.rpc('/mail/update_is_internal',{message_id:$elem.data('message-id'),is_internal:!$elem.data('is-internal'),}).then(function(result){$elem.data('is-internal',result);if(result===true){$elem.addClass('o_portal_message_internal_on');$elem.removeClass('o_portal_message_internal_off');}else{$elem.addClass('o_portal_message_internal_off');$elem.removeClass('o_portal_message_internal_on');}});},});publicWidget.registry.portalChatter=publicWidget.Widget.extend({selector:'.o_portal_chatter',async start(){const proms=[this._super.apply(this,arguments)];const chatter=new PortalChatter(this,this.$el.data());proms.push(chatter.appendTo(this.$el));await Promise.all(proms);if(window.location.hash===`#${this.el.id}`){dom.scrollTo(this.el,{duration:0});}},});__exports[Symbol.for("default")]=PortalChatter
return __exports;});;

/* /portal/static/src/js/portal_composer.js */
odoo.define('@portal/js/portal_composer',['@web/core/l10n/translation','@web/core/utils/strings','@web/core/utils/render','@web/legacy/js/public/public_widget','@web/core/network/http_service','@odoo/owl','@web/core/network/rpc_service'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{escape}=require("@web/core/utils/strings");const{renderToElement}=require("@web/core/utils/render");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{post}=require("@web/core/network/http_service");const{Component}=require("@odoo/owl");const{RPCError}=require("@web/core/network/rpc_service");var PortalComposer=publicWidget.Widget.extend({template:'portal.Composer',events:{'change .o_portal_chatter_file_input':'_onFileInputChange','click .o_portal_chatter_attachment_btn':'_onAttachmentButtonClick','click .o_portal_chatter_attachment_delete':'async _onAttachmentDeleteClick','click .o_portal_chatter_composer_btn':'async _onSubmitButtonClick',},init:function(parent,options){this._super.apply(this,arguments);this.options=Object.assign({'allow_composer':true,'display_composer':false,'csrf_token':odoo.csrf_token,'token':false,'res_model':false,'res_id':false,},options||{});this.attachments=[];this.rpc=this.bindService("rpc");this.notification=this.bindService("notification");},start:function(){var self=this;this.$attachmentButton=this.$('.o_portal_chatter_attachment_btn');this.$fileInput=this.$('.o_portal_chatter_file_input');this.$sendButton=this.$('.o_portal_chatter_composer_btn');this.$attachments=this.$('.o_portal_chatter_composer_input .o_portal_chatter_attachments');this.$inputTextarea=this.$('.o_portal_chatter_composer_input textarea[name="message"]');return this._super.apply(this,arguments).then(function(){if(self.options.default_attachment_ids){self.attachments=self.options.default_attachment_ids||[];self.attachments.forEach((attachment)=>{attachment.state='done';});self._updateAttachments();}
return Promise.resolve();});},_onAttachmentButtonClick:function(){this.$fileInput.click();},_onAttachmentDeleteClick:function(ev){var self=this;var attachmentId=$(ev.currentTarget).closest('.o_portal_chatter_attachment').data('id');var accessToken=this.attachments.find(attachment=>attachment.id===attachmentId).access_token;ev.preventDefault();ev.stopPropagation();this.$sendButton.prop('disabled',true);return this.rpc('/portal/attachment/remove',{'attachment_id':attachmentId,'access_token':accessToken,}).then(function(){self.attachments=self.attachments.filter(attachment=>attachment.id!==attachmentId);self._updateAttachments();self.$sendButton.prop('disabled',false);});},_prepareAttachmentData:function(file){return{'name':file.name,'file':file,'res_id':this.options.res_id,'res_model':this.options.res_model,'access_token':this.options.token,};},_onFileInputChange:function(){var self=this;this.$sendButton.prop('disabled',true);return Promise.all([...this.$fileInput[0].files].map((file)=>{return new Promise(function(resolve,reject){var data=self._prepareAttachmentData(file);if(odoo.csrf_token){data.csrf_token=odoo.csrf_token;}
post('/portal/attachment/add',data).then(function(attachment){attachment.state='pending';self.attachments.push(attachment);self._updateAttachments();resolve();}).catch(function(error){if(error instanceof RPCError){self.notification.add(_t("Could not save file <strong>%s</strong>",escape(file.name)),{type:'warning',sticky:true});resolve();}});});})).then(function(){self.$fileInput[0].value=null;self.$sendButton.prop('disabled',false);});},_prepareMessageData:function(){return Object.assign(this.options||{},{'message':this.$('textarea[name="message"]').val(),attachment_ids:this.attachments.map((a)=>a.id),attachment_tokens:this.attachments.map((a)=>a.access_token),});},_onSubmitButtonClick:function(ev){ev.preventDefault();const error=this._onSubmitCheckContent();if(error){this.$inputTextarea.addClass('border-danger');this.$(".o_portal_chatter_composer_error").text(error).removeClass('d-none');return Promise.reject();}else{return this._chatterPostMessage(ev.currentTarget.getAttribute('data-action'));}},_onSubmitCheckContent:function(){if(!this.$inputTextarea.val().trim()&&!this.attachments.length){return _t('Some fields are required. Please make sure to write a message or attach a document');};},_updateAttachments:function(){this.$attachments.empty().append(renderToElement('portal.Chatter.Attachments',{attachments:this.attachments,showDelete:true,}));},_chatterPostMessage:async function(route){const result=await this.rpc(route,this._prepareMessageData());Component.env.bus.trigger('reload_chatter_content',result);return result;},});__exports[Symbol.for("default")]={PortalComposer:PortalComposer,};return __exports;});;

/* /portal/static/src/js/portal_security.js */
odoo.define('@portal/js/portal_security',['@web/core/confirmation_dialog/confirmation_dialog','@web/core/utils/render','@web/legacy/js/public/public_widget','@web/session','@portal/js/components/input_confirmation_dialog/input_confirmation_dialog','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{ConfirmationDialog}=require('@web/core/confirmation_dialog/confirmation_dialog');const{renderToMarkup}=require("@web/core/utils/render");const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const{session}=require("@web/session");const{InputConfirmationDialog}=require("@portal/js/components/input_confirmation_dialog/input_confirmation_dialog");const{_t}=require("@web/core/l10n/translation");publicWidget.registry.NewAPIKeyButton=publicWidget.Widget.extend({selector:'.o_portal_new_api_key',events:{click:'_onClick'},init(){this._super(...arguments);this.orm=this.bindService("orm");this.dialog=this.bindService("dialog");},async _onClick(e){e.preventDefault();await handleCheckIdentity(this.orm.call("res.users","api_key_wizard",[session.user_id]),this.orm,this.dialog);this.call("dialog","add",InputConfirmationDialog,{title:_t("New API Key"),body:renderToMarkup("portal.keydescription"),confirmLabel:_t("Confirm"),confirm:async({inputEl})=>{const description=inputEl.value;const wizard_id=await this.orm.create("res.users.apikeys.description",[{name:description}]);const res=await handleCheckIdentity(this.orm.call("res.users.apikeys.description","make_key",[wizard_id]),this.orm,this.dialog);this.call("dialog","add",ConfirmationDialog,{title:_t("API Key Ready"),body:renderToMarkup("portal.keyshow",{key:res.context.default_key}),confirmLabel:_t("Close"),},{onClose:()=>{window.location=window.location;},})}});}});publicWidget.registry.RemoveAPIKeyButton=publicWidget.Widget.extend({selector:'.o_portal_remove_api_key',events:{click:'_onClick'},init(){this._super(...arguments);this.orm=this.bindService("orm");this.dialog=this.bindService("dialog");},async _onClick(e){e.preventDefault();await handleCheckIdentity(this.orm.call("res.users.apikeys","remove",[parseInt(this.el.id)]),this.orm,this.dialog);window.location=window.location;}});publicWidget.registry.portalSecurity=publicWidget.Widget.extend({selector:'.o_portal_security_body',init:function(){$('.modal.show#portal_deactivate_account_modal').removeClass('d-block').modal('show');$('.modal#portal_deactivate_account_modal').on('hide.bs.modal',(event)=>{const $target=$(event.currentTarget);$target.find('.alert').remove();$target.find('.invalid-feedback').remove();$target.find('.is-invalid').removeClass('is-invalid');});return this._super(...arguments);},});publicWidget.registry.RevokeSessionsButton=publicWidget.Widget.extend({selector:'#portal_revoke_all_sessions_popup',events:{click:'_onClick',},init(){this._super(...arguments);this.orm=this.bindService("orm");},async _onClick(){const{res_id:checkId}=await this.orm.call("res.users","api_key_wizard",[session.user_id,]);this.call("dialog","add",InputConfirmationDialog,{title:_t("Log out from all devices?"),body:renderToMarkup("portal.revoke_all_devices_popup_template"),confirmLabel:_t("Log out from all devices"),confirm:async({inputEl})=>{if(!inputEl.reportValidity()){inputEl.classList.add("is-invalid");return false;}
await this.orm.write("res.users.identitycheck",[checkId],{password:inputEl.value});try{await this.orm.call("res.users.identitycheck","revoke_all_devices",[checkId]);}catch{inputEl.classList.add("is-invalid");inputEl.setCustomValidity(_t("Check failed"));inputEl.reportValidity();return false;}
window.location.href="/web/session/logout?redirect=/";return true;},cancel:()=>{},onInput:({inputEl})=>{inputEl.classList.remove("is-invalid");inputEl.setCustomValidity("");},});},});__exports.handleCheckIdentity=handleCheckIdentity;async function handleCheckIdentity(wrapped,ormService,dialogService){return wrapped.then((r)=>{if(!(r.type==="ir.actions.act_window"&&r.res_model==="res.users.identitycheck")){return r;}
const checkId=r.res_id;return new Promise((resolve)=>{dialogService.add(InputConfirmationDialog,{title:_t("Security Control"),body:renderToMarkup("portal.identitycheck"),confirmLabel:_t("Confirm Password"),confirm:async({inputEl})=>{if(!inputEl.reportValidity()){inputEl.classList.add("is-invalid");return false;}
let result;await ormService.write("res.users.identitycheck",[checkId],{password:inputEl.value});try{result=await ormService.call("res.users.identitycheck","run_check",[checkId]);}catch{inputEl.classList.add("is-invalid");inputEl.setCustomValidity(_t("Check failed"));inputEl.reportValidity();return false;}
resolve(result);return true;},cancel:()=>{},onInput:({inputEl})=>{inputEl.classList.remove("is-invalid");inputEl.setCustomValidity("");},});});});}
return __exports;});;

/* /portal/static/src/js/portal_sidebar.js */
odoo.define('@portal/js/portal_sidebar',['@web/core/l10n/translation','@web/legacy/js/public/public_widget','@web/core/l10n/dates'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{deserializeDateTime}=require("@web/core/l10n/dates");const{DateTime}=luxon;var PortalSidebar=publicWidget.Widget.extend({start:function(){this._setDelayLabel();return this._super.apply(this,arguments);},_setDelayLabel:function(){var $sidebarTimeago=this.$el.find('.o_portal_sidebar_timeago').toArray();$sidebarTimeago.forEach((el)=>{var dateTime=deserializeDateTime($(el).attr('datetime')),today=DateTime.now().startOf('day'),diff=dateTime.diff(today).as("days"),displayStr;if(diff===0){displayStr=_t('Due today');}else if(diff>0){displayStr=_t('Due in %s days',Math.abs(diff).toFixed());}else{displayStr=_t('%s days overdue',Math.abs(diff).toFixed());}
$(el).text(displayStr);});},_printIframeContent:function(href){if(!this.printContent){this.printContent=$('<iframe id="print_iframe_content" src="'+href+'" style="display:none"></iframe>');this.$el.append(this.printContent);this.printContent.on('load',function(){$(this).get(0).contentWindow.print();});}else{this.printContent.get(0).contentWindow.print();}},});__exports[Symbol.for("default")]=PortalSidebar;return __exports;});;

/* /portal/static/src/js/components/input_confirmation_dialog/input_confirmation_dialog.js */
odoo.define('@portal/js/components/input_confirmation_dialog/input_confirmation_dialog',['@odoo/owl','@web/core/confirmation_dialog/confirmation_dialog'],function(require){'use strict';let __exports={};const{useEffect}=require("@odoo/owl");const{ConfirmationDialog}=require("@web/core/confirmation_dialog/confirmation_dialog");const InputConfirmationDialog=__exports.InputConfirmationDialog=class InputConfirmationDialog extends ConfirmationDialog{static props={...ConfirmationDialog.props,onInput:{type:Function,optional:true},};static template="portal.InputConfirmationDialog";setup(){super.setup();const onInput=()=>{if(this.props.onInput){this.props.onInput({inputEl:this.inputEl});}};const onKeydown=(ev)=>{if(ev.key&&ev.key.toLowerCase()==="enter"){ev.preventDefault();this._confirm();}};useEffect((inputEl)=>{this.inputEl=inputEl;if(this.inputEl){this.inputEl.focus();this.inputEl.addEventListener("keydown",onKeydown);this.inputEl.addEventListener("input",onInput);return()=>{this.inputEl.removeEventListener("keydown",onKeydown);this.inputEl.removeEventListener("input",onInput);};}},()=>[this.modalRef.el?.querySelector("input")]);}
_confirm(){this.execButton(()=>this.props.confirm({inputEl:this.inputEl}));}}
return __exports;});;

/* /portal/static/src/signature_form/signature_form.js */
odoo.define('@portal/signature_form/signature_form',['@odoo/owl','@web/legacy/js/core/dom','@web/core/l10n/translation','@web/core/registry','@web/core/utils/urls','@web/core/signature/name_and_signature','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,onMounted,useRef,useState}=require("@odoo/owl");const dom=require("@web/legacy/js/core/dom")[Symbol.for("default")];const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{redirect}=require("@web/core/utils/urls");const{NameAndSignature}=require("@web/core/signature/name_and_signature");const{useService}=require("@web/core/utils/hooks");class SignatureForm extends Component{static template="portal.SignatureForm"
static components={NameAndSignature}
setup(){this.rootRef=useRef("root");this.rpc=useService("rpc");this.csrfToken=odoo.csrf_token;this.state=useState({error:false,success:false,});this.signature=useState({name:this.props.defaultName});this.nameAndSignatureProps={signature:this.signature,fontColor:this.props.fontColor||"black",};if(this.props.signatureRatio){this.nameAndSignatureProps.displaySignatureRatio=this.props.signatureRatio;}
if(this.props.signatureType){this.nameAndSignatureProps.signatureType=this.props.signatureType;}
if(this.props.mode){this.nameAndSignatureProps.mode=this.props.mode;}
onMounted(()=>{this.rootRef.el.closest('.modal').addEventListener('shown.bs.modal',()=>{this.signature.resetSignature();});});}
get sendLabel(){return this.props.sendLabel||_t("Accept & Sign");}
async onClickSubmit(){const button=document.querySelector('.o_portal_sign_submit')
const icon=button.removeChild(button.firstChild)
const restoreBtnLoading=dom.addButtonLoadingEffect(button);const name=this.signature.name;const signature=this.signature.getSignatureImage()[1];const data=await this.rpc(this.props.callUrl,{name,signature});if(data.force_refresh){restoreBtnLoading();button.prepend(icon)
if(data.redirect_url){redirect(data.redirect_url);}else{window.location.reload();}
return new Promise(()=>{});}
this.state.error=data.error||false;this.state.success=!data.error&&{message:data.message,redirectUrl:data.redirect_url,redirectMessage:data.redirect_message,};}}
registry.category("public_components").add("portal.signature_form",SignatureForm);return __exports;});;

/* /account/static/src/js/account_portal_sidebar.js */
odoo.define('@account/js/account_portal_sidebar',['@web/legacy/js/core/dom','@web/legacy/js/public/public_widget','@portal/js/portal_sidebar'],function(require){'use strict';let __exports={};const dom=require("@web/legacy/js/core/dom")[Symbol.for("default")];const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const PortalSidebar=require("@portal/js/portal_sidebar")[Symbol.for("default")];publicWidget.registry.AccountPortalSidebar=PortalSidebar.extend({selector:'.o_portal_invoice_sidebar',events:{'click .o_portal_invoice_print':'_onPrintInvoice',},start:function(){var def=this._super.apply(this,arguments);var $invoiceHtml=this.$el.find('iframe#invoice_html');var updateIframeSize=this._updateIframeSize.bind(this,$invoiceHtml);$(window).on('resize',updateIframeSize);var iframeDoc=$invoiceHtml[0].contentDocument||$invoiceHtml[0].contentWindow.document;if(iframeDoc.readyState==='complete'){updateIframeSize();}else{$invoiceHtml.on('load',updateIframeSize);}
return def;},_updateIframeSize:function($el){var $wrapwrap=$el.contents().find('div#wrapwrap');$el.height(0);$el.height($wrapwrap[0].scrollHeight);const isAnchor=/^#[\w-]+$/.test(window.location.hash)
if(!isAnchor){return;}
var $target=$(window.location.hash);if(!$target.length){return;}
dom.scrollTo($target[0],{duration:0});},_onPrintInvoice:function(ev){ev.preventDefault();var href=$(ev.currentTarget).attr('href');this._printIframeContent(href);},});return __exports;});;

/* /account/static/src/js/account_portal.js */
odoo.define('@account/js/account_portal',['@portal/js/portal'],function(require){'use strict';let __exports={};const{PortalHomeCounters}=require('@portal/js/portal');PortalHomeCounters.include({_getCountersAlwaysDisplayed(){return this._super(...arguments).concat(['invoice_count']);},});return __exports;});;

/* /payment/static/lib/jquery.payment/jquery.payment.js */
(function(){var $,cardFromNumber,cardFromType,cards,defaultFormat,formatBackCardNumber,formatBackExpiry,formatCardNumber,formatExpiry,formatForwardExpiry,formatForwardSlashAndSpace,hasTextSelected,luhnCheck,reFormatCVC,reFormatCardNumber,reFormatExpiry,reFormatNumeric,replaceFullWidthChars,restrictCVC,restrictCardNumber,restrictExpiry,restrictNumeric,safeVal,setCardType,__slice=[].slice,__indexOf=[].indexOf||function(item){for(var i=0,l=this.length;i<l;i++){if(i in this&&this[i]===item)return i;}return-1;};$=window.jQuery||window.Zepto||window.$;$.payment={};$.payment.fn={};$.fn.payment=function(){var args,method;method=arguments[0],args=2<=arguments.length?__slice.call(arguments,1):[];return $.payment.fn[method].apply(this,args);};defaultFormat=/(\d{1,4})/g;$.payment.cards=cards=[{type:'maestro',patterns:[5018,502,503,506,56,58,639,6220,67],format:defaultFormat,length:[12,13,14,15,16,17,18,19],cvcLength:[3],luhn:true},{type:'forbrugsforeningen',patterns:[600],format:defaultFormat,length:[16],cvcLength:[3],luhn:true},{type:'dankort',patterns:[5019],format:defaultFormat,length:[16],cvcLength:[3],luhn:true},{type:'visa',patterns:[4],format:defaultFormat,length:[13,16],cvcLength:[3],luhn:true},{type:'mastercard',patterns:[51,52,53,54,55,22,23,24,25,26,27],format:defaultFormat,length:[16],cvcLength:[3],luhn:true},{type:'amex',patterns:[34,37],format:/(\d{1,4})(\d{1,6})?(\d{1,5})?/,length:[15],cvcLength:[3,4],luhn:true},{type:'dinersclub',patterns:[30,36,38,39],format:/(\d{1,4})(\d{1,6})?(\d{1,4})?/,length:[14],cvcLength:[3],luhn:true},{type:'discover',patterns:[60,64,65,622],format:defaultFormat,length:[16],cvcLength:[3],luhn:true},{type:'unionpay',patterns:[62,88],format:defaultFormat,length:[16,17,18,19],cvcLength:[3],luhn:false},{type:'jcb',patterns:[35],format:defaultFormat,length:[16],cvcLength:[3],luhn:true}];cardFromNumber=function(num){var card,p,pattern,_i,_j,_len,_len1,_ref;num=(num+'').replace(/\D/g,'');for(_i=0,_len=cards.length;_i<_len;_i++){card=cards[_i];_ref=card.patterns;for(_j=0,_len1=_ref.length;_j<_len1;_j++){pattern=_ref[_j];p=pattern+'';if(num.substr(0,p.length)===p){return card;}}}};cardFromType=function(type){var card,_i,_len;for(_i=0,_len=cards.length;_i<_len;_i++){card=cards[_i];if(card.type===type){return card;}}};luhnCheck=function(num){var digit,digits,odd,sum,_i,_len;odd=true;sum=0;digits=(num+'').split('').reverse();for(_i=0,_len=digits.length;_i<_len;_i++){digit=digits[_i];digit=parseInt(digit,10);if((odd=!odd)){digit*=2;}
if(digit>9){digit-=9;}
sum+=digit;}
return sum%10===0;};hasTextSelected=function($target){var _ref;if(($target.prop('selectionStart')!=null)&&$target.prop('selectionStart')!==$target.prop('selectionEnd')){return true;}
if((typeof document!=="undefined"&&document!==null?(_ref=document.selection)!=null?_ref.createRange:void 0:void 0)!=null){if(document.selection.createRange().text){return true;}}
return false;};safeVal=function(value,$target){var currPair,cursor,digit,error,last,prevPair;try{cursor=$target.prop('selectionStart');}catch(_error){error=_error;cursor=null;}
last=$target.val();$target.val(value);if(cursor!==null&&$target.is(":focus")){if(cursor===last.length){cursor=value.length;}
if(last!==value){prevPair=last.slice(cursor-1,+cursor+1||9e9);currPair=value.slice(cursor-1,+cursor+1||9e9);digit=value[cursor];if(/\d/.test(digit)&&prevPair===(""+digit+" ")&&currPair===(" "+digit)){cursor=cursor+1;}}
$target.prop('selectionStart',cursor);return $target.prop('selectionEnd',cursor);}};replaceFullWidthChars=function(str){var chars,chr,fullWidth,halfWidth,idx,value,_i,_len;if(str==null){str='';}
fullWidth='\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19';halfWidth='0123456789';value='';chars=str.split('');for(_i=0,_len=chars.length;_i<_len;_i++){chr=chars[_i];idx=fullWidth.indexOf(chr);if(idx>-1){chr=halfWidth[idx];}
value+=chr;}
return value;};reFormatNumeric=function(e){var $target;$target=$(e.currentTarget);return setTimeout(function(){var value;value=$target.val();value=replaceFullWidthChars(value);value=value.replace(/\D/g,'');return safeVal(value,$target);});};reFormatCardNumber=function(e){var $target;$target=$(e.currentTarget);return setTimeout(function(){var value;value=$target.val();value=replaceFullWidthChars(value);value=$.payment.formatCardNumber(value);return safeVal(value,$target);});};formatCardNumber=function(e){var $target,card,digit,length,re,upperLength,value;digit=String.fromCharCode(e.which);if(!/^\d+$/.test(digit)){return;}
$target=$(e.currentTarget);value=$target.val();card=cardFromNumber(value+digit);length=(value.replace(/\D/g,'')+digit).length;upperLength=16;if(card){upperLength=card.length[card.length.length-1];}
if(length>=upperLength){return;}
if(($target.prop('selectionStart')!=null)&&$target.prop('selectionStart')!==value.length){return;}
if(card&&card.type==='amex'){re=/^(\d{4}|\d{4}\s\d{6})$/;}else{re=/(?:^|\s)(\d{4})$/;}
if(re.test(value)){e.preventDefault();return setTimeout(function(){return $target.val(value+' '+digit);});}else if(re.test(value+digit)){e.preventDefault();return setTimeout(function(){return $target.val(value+digit+' ');});}};formatBackCardNumber=function(e){var $target,value;$target=$(e.currentTarget);value=$target.val();if(e.which!==8){return;}
if(($target.prop('selectionStart')!=null)&&$target.prop('selectionStart')!==value.length){return;}
if(/\d\s$/.test(value)){e.preventDefault();return setTimeout(function(){return $target.val(value.replace(/\d\s$/,''));});}else if(/\s\d?$/.test(value)){e.preventDefault();return setTimeout(function(){return $target.val(value.replace(/\d$/,''));});}};reFormatExpiry=function(e){var $target;$target=$(e.currentTarget);return setTimeout(function(){var value;value=$target.val();value=replaceFullWidthChars(value);value=$.payment.formatExpiry(value);return safeVal(value,$target);});};formatExpiry=function(e){var $target,digit,val;digit=String.fromCharCode(e.which);if(!/^\d+$/.test(digit)){return;}
$target=$(e.currentTarget);val=$target.val()+digit;if(/^\d$/.test(val)&&(val!=='0'&&val!=='1')){e.preventDefault();return setTimeout(function(){return $target.val("0"+val+" / ");});}else if(/^\d\d$/.test(val)){e.preventDefault();return setTimeout(function(){var m1,m2;m1=parseInt(val[0],10);m2=parseInt(val[1],10);if(m2>2&&m1!==0){return $target.val("0"+m1+" / "+m2);}else{return $target.val(""+val+" / ");}});}};formatForwardExpiry=function(e){var $target,digit,val;digit=String.fromCharCode(e.which);if(!/^\d+$/.test(digit)){return;}
$target=$(e.currentTarget);val=$target.val();if(/^\d\d$/.test(val)){return $target.val(""+val+" / ");}};formatForwardSlashAndSpace=function(e){var $target,val,which;which=String.fromCharCode(e.which);if(!(which==='/'||which===' ')){return;}
$target=$(e.currentTarget);val=$target.val();if(/^\d$/.test(val)&&val!=='0'){return $target.val("0"+val+" / ");}};formatBackExpiry=function(e){var $target,value;$target=$(e.currentTarget);value=$target.val();if(e.which!==8){return;}
if(($target.prop('selectionStart')!=null)&&$target.prop('selectionStart')!==value.length){return;}
if(/\d\s\/\s$/.test(value)){e.preventDefault();return setTimeout(function(){return $target.val(value.replace(/\d\s\/\s$/,''));});}};reFormatCVC=function(e){var $target;$target=$(e.currentTarget);return setTimeout(function(){var value;value=$target.val();value=replaceFullWidthChars(value);value=value.replace(/\D/g,'').slice(0,4);return safeVal(value,$target);});};restrictNumeric=function(e){var input;if(e.metaKey||e.ctrlKey){return true;}
if(e.which===32){return false;}
if(e.which===0){return true;}
if(e.which<33){return true;}
input=String.fromCharCode(e.which);return!!/[\d\s]/.test(input);};restrictCardNumber=function(e){var $target,card,digit,value;$target=$(e.currentTarget);digit=String.fromCharCode(e.which);if(!/^\d+$/.test(digit)){return;}
if(hasTextSelected($target)){return;}
value=($target.val()+digit).replace(/\D/g,'');card=cardFromNumber(value);if(card){return value.length<=card.length[card.length.length-1];}else{return value.length<=16;}};restrictExpiry=function(e){var $target,digit,value;$target=$(e.currentTarget);digit=String.fromCharCode(e.which);if(!/^\d+$/.test(digit)){return;}
if(hasTextSelected($target)){return;}
value=$target.val()+digit;value=value.replace(/\D/g,'');if(value.length>6){return false;}};restrictCVC=function(e){var $target,digit,val;$target=$(e.currentTarget);digit=String.fromCharCode(e.which);if(!/^\d+$/.test(digit)){return;}
if(hasTextSelected($target)){return;}
val=$target.val()+digit;return val.length<=4;};setCardType=function(e){var $target,allTypes,card,cardType,val;$target=$(e.currentTarget);val=$target.val();cardType=$.payment.cardType(val)||'unknown';if(!$target.hasClass(cardType)){allTypes=(function(){var _i,_len,_results;_results=[];for(_i=0,_len=cards.length;_i<_len;_i++){card=cards[_i];_results.push(card.type);}
return _results;})();$target.removeClass('unknown');$target.removeClass(allTypes.join(' '));$target.addClass(cardType);$target.toggleClass('identified',cardType!=='unknown');return $target.trigger('payment.cardType',cardType);}};$.payment.fn.formatCardCVC=function(){this.on('keypress',restrictNumeric);this.on('keypress',restrictCVC);this.on('paste',reFormatCVC);this.on('change',reFormatCVC);this.on('input',reFormatCVC);return this;};$.payment.fn.formatCardExpiry=function(){this.on('keypress',restrictNumeric);this.on('keypress',restrictExpiry);this.on('keypress',formatExpiry);this.on('keypress',formatForwardSlashAndSpace);this.on('keypress',formatForwardExpiry);this.on('keydown',formatBackExpiry);this.on('change',reFormatExpiry);this.on('input',reFormatExpiry);return this;};$.payment.fn.formatCardNumber=function(){this.on('keypress',restrictNumeric);this.on('keypress',restrictCardNumber);this.on('keypress',formatCardNumber);this.on('keydown',formatBackCardNumber);this.on('keyup',setCardType);this.on('paste',reFormatCardNumber);this.on('change',reFormatCardNumber);this.on('input',reFormatCardNumber);this.on('input',setCardType);return this;};$.payment.fn.restrictNumeric=function(){this.on('keypress',restrictNumeric);this.on('paste',reFormatNumeric);this.on('change',reFormatNumeric);this.on('input',reFormatNumeric);return this;};$.payment.fn.cardExpiryVal=function(){return $.payment.cardExpiryVal($(this).val());};$.payment.cardExpiryVal=function(value){var month,prefix,year,_ref;_ref=value.split(/[\s\/]+/,2),month=_ref[0],year=_ref[1];if((year!=null?year.length:void 0)===2&&/^\d+$/.test(year)){prefix=(new Date).getFullYear();prefix=prefix.toString().slice(0,2);year=prefix+year;}
month=parseInt(month,10);year=parseInt(year,10);return{month:month,year:year};};$.payment.validateCardNumber=function(num){var card,_ref;num=(num+'').replace(/\s+|-/g,'');if(!/^\d+$/.test(num)){return false;}
card=cardFromNumber(num);if(!card){return false;}
return(_ref=num.length,__indexOf.call(card.length,_ref)>=0)&&(card.luhn===false||luhnCheck(num));};$.payment.validateCardExpiry=function(month,year){var currentTime,expiry,_ref;if(typeof month==='object'&&'month'in month){_ref=month,month=_ref.month,year=_ref.year;}
if(!(month&&year)){return false;}
month=$.trim(month);year=$.trim(year);if(!/^\d+$/.test(month)){return false;}
if(!/^\d+$/.test(year)){return false;}
if(!((1<=month&&month<=12))){return false;}
if(year.length===2){if(year<70){year="20"+year;}else{year="19"+year;}}
if(year.length!==4){return false;}
expiry=new Date(year,month);currentTime=new Date;expiry.setMonth(expiry.getMonth()-1);expiry.setMonth(expiry.getMonth()+1,1);return expiry>currentTime;};$.payment.validateCardCVC=function(cvc,type){var card,_ref;cvc=$.trim(cvc);if(!/^\d+$/.test(cvc)){return false;}
card=cardFromType(type);if(card!=null){return _ref=cvc.length,__indexOf.call(card.cvcLength,_ref)>=0;}else{return cvc.length>=3&&cvc.length<=4;}};$.payment.cardType=function(num){var _ref;if(!num){return null;}
return((_ref=cardFromNumber(num))!=null?_ref.type:void 0)||null;};$.payment.formatCardNumber=function(num){var card,groups,upperLength,_ref;num=num.replace(/\D/g,'');card=cardFromNumber(num);if(!card){return num;}
upperLength=card.length[card.length.length-1];num=num.slice(0,upperLength);if(card.format.global){return(_ref=num.match(card.format))!=null?_ref.join(' '):void 0;}else{groups=card.format.exec(num);if(groups==null){return;}
groups.shift();groups=$.grep(groups,function(n){return n;});return groups.join(' ');}};$.payment.formatExpiry=function(expiry){var mon,parts,sep,year;parts=expiry.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/);if(!parts){return'';}
mon=parts[1]||'';sep=parts[2]||'';year=parts[3]||'';if(year.length>0){sep=' / ';}else if(sep===' /'){mon=mon.substring(0,1);sep='';}else if(mon.length===2||sep.length>0){sep=' / ';}else if(mon.length===1&&(mon!=='0'&&mon!=='1')){mon="0"+mon;sep=' / ';}
return mon+sep+year;};}).call(this);;

/* /payment/static/src/js/express_checkout_form.js */
odoo.define('@payment/js/express_checkout_form',['@web/legacy/js/public/public_widget','@odoo/owl'],function(require){'use strict';let __exports={};const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const{Component}=require('@odoo/owl');publicWidget.registry.PaymentExpressCheckoutForm=publicWidget.Widget.extend({selector:'form[name="o_payment_express_checkout_form"]',start:async function(){await this._super(...arguments);this.paymentContext={};Object.assign(this.paymentContext,this.el.dataset);this.paymentContext.shippingInfoRequired=!!this.paymentContext['shippingInfoRequired'];const expressCheckoutForms=this._getExpressCheckoutForms();for(const expressCheckoutForm of expressCheckoutForms){await this._prepareExpressCheckoutForm(expressCheckoutForm.dataset);}
Component.env.bus.addEventListener('cart_amount_changed',(ev)=>this._updateAmount(...ev.detail));},_getExpressCheckoutForms(){return document.querySelectorAll('form[name="o_payment_express_checkout_form"] div[name="o_express_checkout_container"]');},async _prepareExpressCheckoutForm(providerData){},_prepareTransactionRouteParams(providerId){return{'provider_id':parseInt(providerId),'payment_method_id':parseInt(this.paymentContext['paymentMethodUnknownId']),'token_id':null,'flow':'direct','tokenization_requested':false,'landing_route':this.paymentContext['landingRoute'],'access_token':this.paymentContext['accessToken'],'csrf_token':odoo.csrf_token,};},_updateAmount(newAmount,newMinorAmount){this.paymentContext.amount=parseFloat(newAmount);this.paymentContext.minorAmount=parseInt(newMinorAmount);this._getExpressCheckoutForms().forEach(form=>{if(newAmount==0){form.classList.add('d-none')}
else{form.classList.remove('d-none')}})},});const paymentExpressCheckoutForm=__exports.paymentExpressCheckoutForm=publicWidget.registry.PaymentExpressCheckoutForm;return __exports;});;

/* /payment/static/src/js/payment_button.js */
odoo.define('@payment/js/payment_button',['@web/legacy/js/public/public_widget','@odoo/owl'],function(require){'use strict';let __exports={};const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const{Component}=require("@odoo/owl");publicWidget.registry.PaymentButton=publicWidget.Widget.extend({selector:'button[name="o_payment_submit_button"]',async start(){await this._super(...arguments);this.paymentButton=this.el;this.iconClass=this.paymentButton.dataset.iconClass;this._enable();Component.env.bus.addEventListener('enablePaymentButton',this._enable.bind(this));Component.env.bus.addEventListener('disablePaymentButton',this._disable.bind(this));Component.env.bus.addEventListener('hidePaymentButton',this._hide.bind(this));Component.env.bus.addEventListener('showPaymentButton',this._show.bind(this));},_enable(){if(this._canSubmit()){this.paymentButton.disabled=false;}},_canSubmit(){const paymentForm=document.querySelector('#o_payment_form');if(!paymentForm){return true;}
return document.querySelectorAll('input[name="o_payment_radio"]:checked').length===1;},_disable(){this.paymentButton.disabled=true;},_hide(){this.paymentButton.classList.add('d-none');},_show(){this.paymentButton.classList.remove('d-none');},});__exports[Symbol.for("default")]=publicWidget.registry.PaymentButton;return __exports;});;

/* /payment/static/src/js/payment_form.js */
odoo.define('@payment/js/payment_form',['@odoo/owl','@web/legacy/js/public/public_widget','@web/core/browser/browser','@web/core/confirmation_dialog/confirmation_dialog','@web/core/l10n/translation','@web/core/utils/render','@web/core/network/rpc_service'],function(require){'use strict';let __exports={};const{Component}=require('@odoo/owl');const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const{browser}=require('@web/core/browser/browser');const{ConfirmationDialog}=require('@web/core/confirmation_dialog/confirmation_dialog');const{_t}=require('@web/core/l10n/translation');const{renderToMarkup}=require('@web/core/utils/render');const{RPCError}=require('@web/core/network/rpc_service');publicWidget.registry.PaymentForm=publicWidget.Widget.extend({selector:'#o_payment_form',events:Object.assign({},publicWidget.Widget.prototype.events,{'click [name="o_payment_radio"]':'_selectPaymentOption','click [name="o_payment_delete_token"]':'_fetchTokenData','click [name="o_payment_expand_button"]':'_hideExpandButton','click [name="o_payment_submit_button"]':'_submitForm',}),init(){this._super(...arguments);this.rpc=this.bindService("rpc");this.orm=this.bindService("orm");},async start(){this.paymentContext={};Object.assign(this.paymentContext,this.el.dataset);await this._super(...arguments);const checkedRadio=document.querySelector('input[name="o_payment_radio"]:checked');if(checkedRadio){await this._expandInlineForm(checkedRadio);this._enableButton(false);}else{this._setPaymentFlow();}
this.$('[data-bs-toggle="tooltip"]').tooltip();},async _selectPaymentOption(ev){this._showInputs();this._disableButton();const checkedRadio=ev.target;await this._expandInlineForm(checkedRadio);this._enableButton(false);},_fetchTokenData(ev){ev.preventDefault();const linkedRadio=document.getElementById(ev.currentTarget.dataset['linkedRadio']);const tokenId=this._getPaymentOptionId(linkedRadio);this.orm.call('payment.token','get_linked_records_info',[tokenId],).then(linkedRecordsInfo=>{this._challengeTokenDeletion(tokenId,linkedRecordsInfo);}).catch(error=>{if(error instanceof RPCError){this._displayErrorDialog(_t("Cannot delete payment method"),error.data.message);}else{return Promise.reject(error);}});},_hideExpandButton(ev){ev.target.classList.add('d-none');},async _submitForm(ev){ev.stopPropagation();ev.preventDefault();const checkedRadio=this.el.querySelector('input[name="o_payment_radio"]:checked');this._disableButton(true);const flow=this.paymentContext.flow=this._getPaymentFlow(checkedRadio);const paymentOptionId=this.paymentContext.paymentOptionId=this._getPaymentOptionId(checkedRadio);if(flow==='token'&&this.paymentContext['assignTokenRoute']){await this._assignToken(paymentOptionId);}else{const providerCode=this.paymentContext.providerCode=this._getProviderCode(checkedRadio);const pmCode=this.paymentContext.paymentMethodCode=this._getPaymentMethodCode(checkedRadio);this.paymentContext.providerId=this._getProviderId(checkedRadio);if(this._getPaymentOptionType(checkedRadio)==='token'){this.paymentContext.tokenId=paymentOptionId;}else{this.paymentContext.paymentMethodId=paymentOptionId;}
const inlineForm=this._getInlineForm(checkedRadio);this.paymentContext.tokenizationRequested=inlineForm?.querySelector('[name="o_payment_tokenize_checkbox"]')?.checked??this.paymentContext['mode']==='validation';await this._initiatePaymentFlow(providerCode,paymentOptionId,pmCode,flow);}},_enableButton(unblockUI=true){Component.env.bus.trigger('enablePaymentButton');if(unblockUI){this.call('ui','unblock');}},_disableButton(blockUI=false){Component.env.bus.trigger('disablePaymentButton');if(blockUI){this.call('ui','block');}},_showInputs(){const tokenizeContainer=this.el.querySelector('[name="o_payment_tokenize_container"]');tokenizeContainer?.classList.remove('d-none');Component.env.bus.trigger('showPaymentButton');},_hideInputs(){const tokenizeContainer=this.el.querySelector('[name="o_payment_tokenize_container"]');tokenizeContainer?.classList.add('d-none');Component.env.bus.trigger('hidePaymentButton');},async _expandInlineForm(radio){this._collapseInlineForms();this._setPaymentFlow();const providerId=this._getProviderId(radio);const providerCode=this._getProviderCode(radio);const paymentOptionId=this._getPaymentOptionId(radio);const paymentMethodCode=this._getPaymentMethodCode(radio);const flow=this._getPaymentFlow(radio);await this._prepareInlineForm(providerId,providerCode,paymentOptionId,paymentMethodCode,flow);const inlineForm=this._getInlineForm(radio);if(inlineForm&&inlineForm.children.length>0){inlineForm.classList.remove('d-none');}},async _prepareInlineForm(providerId,providerCode,paymentOptionId,paymentMethodCode,flow){},_collapseInlineForms(){this.el.querySelectorAll('[name="o_payment_inline_form"]').forEach(inlineForm=>{inlineForm.classList.add('d-none');});},_displayErrorDialog(title,errorMessage=''){this.call('dialog','add',ConfirmationDialog,{title:title,body:errorMessage||""});},_challengeTokenDeletion(tokenId,linkedRecordsInfo){const body=renderToMarkup('payment.deleteTokenDialog',{linkedRecordsInfo});this.call('dialog','add',ConfirmationDialog,{title:_t("Warning!"),body,confirmLabel:_t("Confirm Deletion"),confirm:()=>this._archiveToken(tokenId),cancel:()=>{},});},_setPaymentFlow(flow='redirect'){if(['redirect','direct','token'].includes(flow)){this.paymentContext.flow=flow;}else{console.warn(`The value ${flow} is not a supported flow. Falling back to redirect.`);this.paymentContext.flow='redirect';}},async _assignToken(tokenId){this.rpc(this.paymentContext['assignTokenRoute'],{'token_id':tokenId,'access_token':this.paymentContext['accessToken'],}).then(()=>{window.location=this.paymentContext['landingRoute'];}).catch(error=>{if(error instanceof RPCError){this._displayErrorDialog(_t("Cannot save payment method"),error.data.message);this._enableButton();}else{return Promise.reject(error);}});},async _initiatePaymentFlow(providerCode,paymentOptionId,paymentMethodCode,flow){this.rpc(this.paymentContext['transactionRoute'],this._prepareTransactionRouteParams(),).then(processingValues=>{if(flow==='redirect'){this._processRedirectFlow(providerCode,paymentOptionId,paymentMethodCode,processingValues);}else if(flow==='direct'){this._processDirectFlow(providerCode,paymentOptionId,paymentMethodCode,processingValues);}else if(flow==='token'){this._processTokenFlow(providerCode,paymentOptionId,paymentMethodCode,processingValues);}}).catch(error=>{if(error instanceof RPCError){this._displayErrorDialog(_t("Payment processing failed"),error.data.message);this._enableButton();}else{return Promise.reject(error);}});},_prepareTransactionRouteParams(){let transactionRouteParams={'provider_id':this.paymentContext.providerId,'payment_method_id':this.paymentContext.paymentMethodId??null,'token_id':this.paymentContext.tokenId??null,'amount':this.paymentContext['amount']!==undefined?parseFloat(this.paymentContext['amount']):null,'flow':this.paymentContext['flow'],'tokenization_requested':this.paymentContext['tokenizationRequested'],'landing_route':this.paymentContext['landingRoute'],'is_validation':this.paymentContext['mode']==='validation','access_token':this.paymentContext['accessToken'],'csrf_token':odoo.csrf_token,};if(this.paymentContext['transactionRoute']==='/payment/transaction'){Object.assign(transactionRouteParams,{'currency_id':this.paymentContext['currencyId']?parseInt(this.paymentContext['currencyId']):null,'partner_id':parseInt(this.paymentContext['partnerId']),'reference_prefix':this.paymentContext['referencePrefix']?.toString(),});}
return transactionRouteParams;},_processRedirectFlow(providerCode,paymentOptionId,paymentMethodCode,processingValues){const div=document.createElement('div');div.innerHTML=processingValues['redirect_form_html'];const redirectForm=div.querySelector('form');redirectForm.setAttribute('id','o_payment_redirect_form');redirectForm.setAttribute('target','_top');document.body.appendChild(redirectForm);redirectForm.submit();},_processDirectFlow(providerCode,paymentOptionId,paymentMethodCode,processingValues){},_processTokenFlow(providerCode,paymentOptionId,paymentMethodCode,processingValues){window.location='/payment/status';},_archiveToken(tokenId){this.rpc('/payment/archive_token',{'token_id':tokenId,}).then(()=>{browser.location.reload();}).catch(error=>{if(error instanceof RPCError){this._displayErrorDialog(_t("Cannot delete payment method"),error.data.message);}else{return Promise.reject(error);}});},_getInlineForm(radio){const inlineFormContainer=radio.closest('[name="o_payment_option"]');return inlineFormContainer?.querySelector('[name="o_payment_inline_form"]');},_getPaymentFlow(radio){if(this._getPaymentOptionType(radio)==='token'||this.paymentContext.flow==='token'){return'token';}else if(this.paymentContext.flow==='redirect'){return'redirect';}else{return'direct';}},_getPaymentMethodCode(radio){return radio.dataset['paymentMethodCode'];},_getPaymentOptionId(radio){return Number(radio.dataset['paymentOptionId']);},_getPaymentOptionType(radio){return radio.dataset['paymentOptionType'];},_getProviderId(radio){return Number(radio.dataset['providerId']);},_getProviderCode(radio){return radio.dataset['providerCode'];},_getProviderState(radio){return radio.dataset['providerState'];},});__exports[Symbol.for("default")]=publicWidget.registry.PaymentForm;return __exports;});;

/* /payment/static/src/js/post_processing.js */
odoo.define('@payment/js/post_processing',['@web/legacy/js/public/public_widget','@web/core/utils/render','@odoo/owl','@web/core/currency','@web/core/l10n/translation','@web/core/network/rpc_service'],function(require){'use strict';let __exports={};const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const{renderToElement}=require('@web/core/utils/render');const{markup}=require("@odoo/owl");const{formatCurrency}=require("@web/core/currency");const{_t}=require('@web/core/l10n/translation');const{ConnectionLostError,RPCError}=require('@web/core/network/rpc_service');publicWidget.registry.PaymentPostProcessing=publicWidget.Widget.extend({selector:'div[name="o_payment_status"]',timeout:0,pollCount:0,init(){this._super(...arguments);this.rpc=this.bindService("rpc");},async start(){this.call('ui','block',{'message':_t("We are processing your payment. Please wait."),});this._poll();return this._super.apply(this,arguments);},_poll(){this._updateTimeout();setTimeout(()=>{const self=this;this.rpc('/payment/status/poll',{'csrf_token':odoo.csrf_token,}).then(postProcessingValues=>{let{state,display_message,landing_route}=postProcessingValues;if(display_message){postProcessingValues.display_message=markup(display_message);}
this._renderTemplate('payment.transactionDetails',{...postProcessingValues,formatCurrency});if(self._getFinalStates(postProcessingValues['provider_code']).includes(state)){window.location=landing_route;}else{self._poll();}}).catch(error=>{if(error instanceof RPCError){switch(error.data.message){case'retry':self._poll();break;case'tx_not_found':self._renderTemplate('payment.tx_not_found');break;default:self._renderTemplate('payment.exception',{error_message:error.data.message});break;}}else if(error instanceof ConnectionLostError){self._renderTemplate('payment.rpc_error');self._poll();}else{return Promise.reject(error);}});},this.timeout);},_getFinalStates(providerCode){return['authorized','done'];},_updateTimeout(){if(this.pollCount>=1&&this.pollCount<10){this.timeout=3000;}
if(this.pollCount>=10&&this.pollCount<20){this.timeout=10000;}
else if(this.pollCount>=20){this.timeout=30000;}
this.pollCount++;},_renderTemplate(xmlid,display_values={}){this.call('ui','unblock');const statusContainer=document.querySelector('div[name="o_payment_status_content"]');statusContainer.innerHTML=renderToElement(xmlid,display_values).innerHTML;},});__exports[Symbol.for("default")]=publicWidget.registry.PaymentPostProcessing;return __exports;});;

/* /sale/static/src/js/sale_portal_sidebar.js */
odoo.define('@sale/js/sale_portal_sidebar',['@web/legacy/js/public/public_widget','@portal/js/portal_sidebar','@web/core/utils/functions'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const PortalSidebar=require("@portal/js/portal_sidebar")[Symbol.for("default")];const{uniqueId}=require("@web/core/utils/functions");publicWidget.registry.SalePortalSidebar=PortalSidebar.extend({selector:'.o_portal_sale_sidebar',init:function(parent,options){this._super.apply(this,arguments);this.authorizedTextTag=['em','b','i','u'];this.spyWatched=$('body[data-target=".navspy"]');},start:function(){var def=this._super.apply(this,arguments);var $spyWatcheElement=this.$el.find('[data-id="portal_sidebar"]');this._setElementId($spyWatcheElement);this._generateMenu();const hash=new URLSearchParams(window.location.hash.substring(1));if(hash.get("allow_payment")==="yes"&&this.$("#o_sale_portal_paynow").length){this.el.querySelector('#o_sale_portal_paynow').click();hash.delete("allow_payment");window.location.hash=hash.toString();}
return def;},_setElementId:function(prefix,$el){var id=uniqueId(prefix);this.spyWatched.find($el).attr('id',id);return id;},_generateMenu:function(){var self=this,lastLI=false,lastUL=null,$bsSidenav=this.$el.find('.bs-sidenav');$("#quote_content [id^=quote_header_], #quote_content [id^=quote_]",this.spyWatched).attr("id","");this.spyWatched.find("#quote_content h2, #quote_content h3").toArray().forEach((el)=>{var id,text;switch(el.tagName.toLowerCase()){case"h2":id=self._setElementId('quote_header_',el);text=self._extractText($(el));if(!text){break;}
lastLI=$("<li class='nav-item'>").append($('<a class="nav-link p-0" href="#'+id+'"/>').text(text)).appendTo($bsSidenav);lastUL=false;break;case"h3":id=self._setElementId('quote_',el);text=self._extractText($(el));if(!text){break;}
if(lastLI){if(!lastUL){lastUL=$("<ul class='nav flex-column'>").appendTo(lastLI);}
$("<li class='nav-item'>").append($('<a class="nav-link p-0" href="#'+id+'"/>').text(text)).appendTo(lastUL);}
break;}
el.setAttribute('data-anchor',true);});this.trigger_up('widgets_start_request',{$target:$bsSidenav});},_extractText:function($node){var self=this;var rawText=[];$node.contents().toArray().forEach((el)=>{var current=$(el);if($.trim(current.text())){var tagName=current.prop("tagName");if(typeof tagName==="undefined"||(typeof tagName!=="undefined"&&self.authorizedTextTag.includes(tagName.toLowerCase()))){rawText.push($.trim(current.text()));}}});return rawText.join(' ');},});return __exports;});;

/* /sale/static/src/js/sale_portal_prepayment.js */
odoo.define('@sale/js/sale_portal_prepayment',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.PortalPrepayment=publicWidget.Widget.extend({selector:'.o_portal_sale_sidebar',events:Object.assign({},publicWidget.Widget.prototype.events,{'click button[name="o_sale_portal_amount_prepayment_button"]':'_onClickAmountPrepaymentButton','click button[name="o_sale_portal_amount_total_button"]':'_onClickAmountTotalButton',}),start:async function(){this.AmountTotalButton=document.querySelector('button[name="o_sale_portal_amount_total_button"]');this.AmountPrepaymentButton=document.querySelector('button[name="o_sale_portal_amount_prepayment_button"]');if(!this.AmountTotalButton){return;}
const params=new URLSearchParams(window.location.search);const isPartialPayment=params.has('downpayment')?params.get('downpayment')==='true':true;const showPaymentModal=params.get('showPaymentModal')==='true';if(isPartialPayment){this._onClickAmountPrepaymentButton(false);}else{this._onClickAmountTotalButton(false);}
if(showPaymentModal){const payNowButton=this.$('#o_sale_portal_paynow')[0];payNowButton&&payNowButton.click();}},_onClickAmountPrepaymentButton:function(doReload=true){this.AmountTotalButton?.classList.add('opacity-50');this.AmountPrepaymentButton?.classList.remove('opacity-50');if(doReload){this._reloadAmount(true);}else{this.$('div[id="o_sale_portal_use_amount_total"]').hide();this.$('div[id="o_sale_portal_use_amount_prepayment"]').show();}},_onClickAmountTotalButton:function(doReload=true){this.AmountTotalButton?.classList.remove('opacity-50');this.AmountPrepaymentButton?.classList.add('opacity-50');if(doReload){this._reloadAmount(false);}else{this.$('div[id="o_sale_portal_use_amount_total"]').show();this.$('div[id="o_sale_portal_use_amount_prepayment"]').hide();}},_reloadAmount:function(partialPayment){const searchParams=new URLSearchParams(window.location.search);if(partialPayment){searchParams.set('downpayment',true);}else{searchParams.set('downpayment',false);}
searchParams.set('showPaymentModal',true);window.location.search=searchParams.toString();},});__exports[Symbol.for("default")]=publicWidget.registry.PortalPrepayment;return __exports;});;

/* /sale/static/src/js/sale_portal.js */
odoo.define('@sale/js/sale_portal',['@portal/js/portal'],function(require){'use strict';let __exports={};const{PortalHomeCounters}=require('@portal/js/portal');PortalHomeCounters.include({_getCountersAlwaysDisplayed(){return this._super(...arguments).concat(['order_count']);},});return __exports;});;

/* /sale_management/static/src/js/sale_management.js */
odoo.define('@sale_management/js/sale_management',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.SaleUpdateLineButton=publicWidget.Widget.extend({selector:'.o_portal_sale_sidebar',events:{'click a.js_update_line_json':'_onClickOptionQuantityButton','click a.js_add_optional_products':'_onClickAddOptionalProduct','change .js_quantity':'_onChangeOptionQuantity',},init(){this._super(...arguments);this.rpc=this.bindService("rpc");},async start(){await this._super(...arguments);this.orderDetail=this.$el.find('table#sales_order_table').data();},_callUpdateLineRoute(order_id,params){return this.rpc("/my/orders/"+order_id+"/update_line_dict",params);},_refreshOrderUI(data){window.location.reload();},async _onChangeOptionQuantity(ev){ev.preventDefault();let self=this,$target=$(ev.currentTarget),quantity=parseInt($target.val());const result=await this._callUpdateLineRoute(self.orderDetail.orderId,{'line_id':$target.data('lineId'),'input_quantity':quantity>=0?quantity:false,'access_token':self.orderDetail.token});this._refreshOrderUI(result);},async _onClickOptionQuantityButton(ev){ev.preventDefault();let self=this,$target=$(ev.currentTarget);const result=await this._callUpdateLineRoute(self.orderDetail.orderId,{'line_id':$target.data('lineId'),'remove':$target.data('remove'),'unlink':$target.data('unlink'),'access_token':self.orderDetail.token});this._refreshOrderUI(result);},_onClickAddOptionalProduct(ev){ev.preventDefault();let self=this,$target=$(ev.currentTarget);$target.css('pointer-events','none');this.rpc("/my/orders/"+self.orderDetail.orderId+"/add_option/"+$target.data('optionId'),{access_token:self.orderDetail.token}).then((data)=>{this._refreshOrderUI(data);});},});return __exports;});;

/* /google_recaptcha/static/src/js/recaptcha.js */
odoo.define('@google_recaptcha/js/recaptcha',['@web/session','@web/core/assets','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{session}=require("@web/session");const{loadJS}=require("@web/core/assets");const{_t}=require("@web/core/l10n/translation");const ReCaptcha=__exports.ReCaptcha=class ReCaptcha{constructor(){this._publicKey=session.recaptcha_public_key;}
loadLibs(){if(this._publicKey){this._recaptchaReady=loadJS(`https://www.recaptcha.net/recaptcha/api.js?render=${encodeURIComponent(this._publicKey)}`).then(()=>new Promise(resolve=>window.grecaptcha.ready(()=>resolve())));return this._recaptchaReady.then(()=>!!document.querySelector('.grecaptcha-badge'));}
return false;}
async getToken(action){if(!this._publicKey){return{message:_t("No recaptcha site key set."),};}
await this._recaptchaReady;try{return{token:await window.grecaptcha.execute(this._publicKey,{action:action})};}catch{return{error:_t("The recaptcha site key is invalid."),};}}}
__exports[Symbol.for("default")]={ReCaptcha:ReCaptcha,};return __exports;});;

/* /website/static/src/libs/zoomodoo/zoomodoo.js */
odoo.define('@website/libs/zoomodoo/zoomodoo',[],function(require){'use strict';let __exports={};var dw,dh,rw,rh,lx,ly;var defaults={linkTag:'a',linkAttribute:'data-zoom-image',event:'click',timer:0,preventClicks:true,disabledOnMobile:true,beforeShow:$.noop,beforeHide:$.noop,onShow:$.noop,onHide:$.noop,onMove:$.noop,beforeAttach:$.noop};function ZoomOdoo(target,options){this.$target=$(target);this.opts=$.extend({},defaults,options,this.$target.data());if(this.isOpen===undefined){this._init();}}
ZoomOdoo.prototype._init=function(){if(window.outerWidth>467||!this.opts.disabledOnMobile){this.$link=this.$target.find(this.opts.linkTag).length&&this.$target.find(this.opts.linkTag)||this.$target;this.$image=this.$target.find('img').length&&this.$target.find('img')||this.$target;this.$flyout=$('<div class="zoomodoo-flyout" />');var $attach=this.$target;if(this.opts.attach!==undefined&&this.$target.closest(this.opts.attach).length){$attach=this.$target.closest(this.opts.attach);}
$attach.parent().on('mousemove.zoomodoo touchmove.zoomodoo',$.proxy(this._onMove,this));$attach.parent().on('mouseleave.zoomodoo touchend.zoomodoo',$.proxy(this._onLeave,this));this.$target.on(this.opts.event+'.zoomodoo touchstart.zoomodoo',$.proxy(this._onEnter,this));if(this.opts.preventClicks){this.$target.on('click.zoomodoo',function(e){e.preventDefault();});}else{var self=this;this.$target.on('click.zoomodoo',function(){self.hide();self.$target.unbind();});}}};ZoomOdoo.prototype.show=function(e,testMouseOver){var w1,h1,w2,h2;var self=this;if(this.opts.beforeShow.call(this)===false)return;if(!this.isReady){return this._loadImage(this.$link.attr(this.opts.linkAttribute),function(){if(self.isMouseOver||!testMouseOver){self.show(e);}});}
var $attach=this.$target;if(this.opts.attach!==undefined&&this.$target.closest(this.opts.attach).length){$attach=this.$target.closest(this.opts.attach);}
$attach.parent().find('.zoomodoo-flyout').remove();this.$flyout.removeAttr('style');$attach.parent().append(this.$flyout);if(this.opts.attachToTarget){this.opts.beforeAttach.call(this);this.$flyout.css('position','fixed');var flyoutOffset=this.$flyout.offset();if(flyoutOffset.left>0){var flyoutLeft=parseFloat(this.$flyout.css('left').replace('px',''));this.$flyout.css('left',flyoutLeft-flyoutOffset.left+'px');}
if(flyoutOffset.top>0){var flyoutTop=parseFloat(this.$flyout.css('top').replace('px',''));this.$flyout.css('top',flyoutTop-flyoutOffset.top+'px');}
if(this.$zoom.height()<this.$flyout.height()){this.$flyout.css('height',this.$zoom.height()+'px');}
if(this.$zoom.width()<this.$flyout.width()){this.$flyout.css('width',this.$zoom.width()+'px');}
var offset=this.$target.offset();var left=offset.left-this.$flyout.width();var top=offset.top;if(left<0){if(offset.left<($(document).width()/2)){left=offset.left+this.$target.width();}else{left=0;}}
if(left+this.$flyout.width()>$(document).width()){this.$flyout.css('width',$(document).width()-left+'px');}else if(left===0){this.$flyout.css('width',offset.left+'px');}
if((top+this.$flyout.height())>$(document).height()){top=$(document).height()-this.$flyout.height();}
this.$flyout.css('transform','translate3d('+left+'px, '+top+'px, 0px)');}else{var rightAvailableSpace=document.body.clientWidth-this.$flyout[0].getBoundingClientRect().left;this.$flyout.css('max-width',rightAvailableSpace);}
w1=this.$target[0].offsetWidth;h1=this.$target[0].offsetHeight;w2=this.$flyout.width();h2=this.$flyout.height();dw=this.$zoom.width()-w2;dh=this.$zoom.height()-h2;if(dw<0)dw=0;if(dh<0)dh=0;rw=dw/w1;rh=dh/h1;this.isOpen=true;this.opts.onShow.call(this);if(e){this._move(e);}};ZoomOdoo.prototype._onEnter=function(e){var self=this;var touches=e.originalEvent.touches;e.preventDefault();this.isMouseOver=true;setTimeout(function(){if(self.isMouseOver&&(!touches||touches.length===1)){self.show(e,true);}},this.opts.timer);};ZoomOdoo.prototype._onMove=function(e){if(!this.isOpen)return;e.preventDefault();this._move(e);};ZoomOdoo.prototype._onLeave=function(){this.isMouseOver=false;if(this.isOpen){this.hide();}};ZoomOdoo.prototype._onLoad=function(e){if(!e.currentTarget.width)return;this.isReady=true;this.$flyout.html(this.$zoom);if(e.data.call){e.data();}};ZoomOdoo.prototype._loadImage=function(href,callback){var zoom=new Image();this.$zoom=$(zoom).on('load',callback,$.proxy(this._onLoad,this));zoom.style.position='absolute';zoom.src=href;};ZoomOdoo.prototype._move=function(e){if(e.type.indexOf('touch')===0){var touchlist=e.touches||e.originalEvent.touches;lx=touchlist[0].pageX;ly=touchlist[0].pageY;}else{lx=e.pageX||lx;ly=e.pageY||ly;}
var offset=this.$target.offset();var pt=ly-offset.top;var pl=lx-offset.left;var xt=Math.ceil(pt*rh);var xl=Math.ceil(pl*rw);if(!this.opts.attachToTarget&&(xl<0||xt<0||xl>dw||xt>dh||lx>(offset.left+this.$target.outerWidth()))){this.hide();}else{var top=xt*-1;var left=xl*-1;this.$zoom.css({top:top,left:left});this.opts.onMove.call(this,top,left);}};ZoomOdoo.prototype.hide=function(){if(!this.isOpen)return;if(this.opts.beforeHide.call(this)===false)return;this.$flyout.detach();this.isOpen=false;this.opts.onHide.call(this);};$.fn.zoomOdoo=function(options){return this.each(function(){var api=$.data(this,'zoomOdoo');if(!api){$.data(this,'zoomOdoo',new ZoomOdoo(this,options));}else if(api.isOpen===undefined){api._init();}});};return __exports;});;

/* /website/static/src/libs/bootstrap/bootstrap.js */
const bsGetOffsetFunction=Dropdown.prototype._getOffset;Dropdown.prototype._getOffset=function(){const offset=bsGetOffsetFunction.apply(this,arguments);if(this._element.closest(".o_hoverable_dropdown .navbar")){return[offset[0],0];}
return offset;};;

/* /website/static/src/js/utils.js */
odoo.define('@website/js/utils',['@web/core/utils/arrays','@web/core/l10n/translation','@web/core/utils/render','@odoo/owl','@web/core/assets','@website/components/autocomplete_with_pages/url_autocomplete'],function(require){'use strict';let __exports={};const{intersection}=require("@web/core/utils/arrays");const{_t}=require("@web/core/l10n/translation");const{renderToElement}=require("@web/core/utils/render");const{App,Component}=require("@odoo/owl");const{templates}=require("@web/core/assets");const{UrlAutoComplete}=require("@website/components/autocomplete_with_pages/url_autocomplete");function loadAnchors(url,body){return new Promise(function(resolve,reject){if(url===window.location.pathname||url[0]==='#'){resolve(body?body:document.body.outerHTML);}else if(url.length&&!url.startsWith("http")){$.get(window.location.origin+url).then(resolve,reject);}else{resolve();}}).then(function(response){const anchors=$(response).find('[id][data-anchor=true], .modal[id][data-display="onClick"]').toArray().map((el)=>{return'#'+el.id;});if(!anchors.includes('#top')){anchors.unshift('#top');}
if(!anchors.includes('#bottom')){anchors.push('#bottom');}
return anchors;}).catch(error=>{console.debug(error);return[];});}
function autocompleteWithPages(input,options={}){const owlApp=new App(UrlAutoComplete,{env:Component.env,dev:Component.env.debug,templates,props:{options,loadAnchors,targetDropdown:input,},translatableAttributes:["data-tooltip"],translateFn:_t,});const container=document.createElement("div");container.classList.add("ui-widget","ui-autocomplete","ui-widget-content","border-0");document.body.appendChild(container);owlApp.mount(container)
return()=>{owlApp.destroy();container.remove();}}
function onceAllImagesLoaded($element,$excluded){var defs=Array.from($element.find("img").addBack("img")).map((img)=>{if(img.complete||$excluded&&($excluded.is(img)||$excluded.has(img).length)){return;}
var def=new Promise(function(resolve,reject){$(img).one('load',function(){resolve();});});return def;});return Promise.all(defs);}
function prompt(options,_qweb){if(typeof options==='string'){options={text:options};}
if(typeof _qweb==="undefined"){_qweb='website.prompt';}
options=Object.assign({window_title:'',field_name:'','default':'',init:function(){},btn_primary_title:_t('Create'),btn_secondary_title:_t('Cancel'),},options||{});var type=intersection(Object.keys(options),['input','textarea','select']);type=type.length?type[0]:'input';options.field_type=type;options.field_name=options.field_name||options[type];var def=new Promise(function(resolve,reject){var dialog=$(renderToElement(_qweb,options)).appendTo('body');options.$dialog=dialog;var field=dialog.find(options.field_type).first();field.val(options['default']);field.fillWith=function(data){if(field.is('select')){var select=field[0];data.forEach(function(item){select.options[select.options.length]=new window.Option(item[1],item[0]);});}else{field.val(data);}};var init=options.init(field,dialog);Promise.resolve(init).then(function(fill){if(fill){field.fillWith(fill);}
dialog.modal('show');field.focus();dialog.on('click','.btn-primary',function(){var backdrop=$('.modal-backdrop');resolve({val:field.val(),field:field,dialog:dialog});dialog.modal('hide').remove();backdrop.remove();});});dialog.on('hidden.bs.modal',function(){var backdrop=$('.modal-backdrop');reject();dialog.remove();backdrop.remove();});if(field.is('input[type="text"], select')){field.keypress(function(e){if(e.key==="Enter"){e.preventDefault();dialog.find('.btn-primary').trigger('click');}});}});return def;}
function websiteDomain(self){var websiteID;self.trigger_up('context_get',{callback:function(ctx){websiteID=ctx['website_id'];},});return['|',['website_id','=',false],['website_id','=',websiteID]];}
function isHTTPSorNakedDomainRedirection(url1,url2){try{url1=new URL(url1).host;url2=new URL(url2).host;}catch{return false;}
return url1===url2||url1.replace(/^www\./,'')===url2.replace(/^www\./,'');}
function sendRequest(route,params){function _addInput(form,name,value){let param=document.createElement('input');param.setAttribute('type','hidden');param.setAttribute('name',name);param.setAttribute('value',value);form.appendChild(param);}
let form=document.createElement('form');form.setAttribute('action',route);form.setAttribute('method',params.method||'POST');if(params.forceTopWindow){form.setAttribute('target','_top');}
if(odoo.csrf_token){_addInput(form,'csrf_token',odoo.csrf_token);}
for(const key in params){const value=params[key];if(Array.isArray(value)&&value.length){for(const val of value){_addInput(form,key,val);}}else{_addInput(form,key,value);}}
document.body.appendChild(form);form.submit();}
__exports.svgToPNG=svgToPNG;async function svgToPNG(src){return _exportToPNG(src,"svg+xml");}
__exports.webpToPNG=webpToPNG;async function webpToPNG(src){return _exportToPNG(src,"webp");}
async function _exportToPNG(src,format){function checkImg(imgEl){return(imgEl.naturalHeight!==0);}
function toPNGViaCanvas(imgEl){const canvas=document.createElement('canvas');canvas.width=imgEl.width;canvas.height=imgEl.height;canvas.getContext('2d').drawImage(imgEl,0,0);return canvas.toDataURL('image/png');}
if(src instanceof HTMLImageElement){const loadedImgEl=src;if(checkImg(loadedImgEl)){return toPNGViaCanvas(loadedImgEl);}
src=loadedImgEl.src;}
return new Promise(resolve=>{const imgEl=new Image();imgEl.onload=()=>{if(format!=="svg+xml"||checkImg(imgEl)){resolve(imgEl);return;}
imgEl.height=1000;imgEl.style.opacity=0;document.body.appendChild(imgEl);const request=new XMLHttpRequest();request.open('GET',imgEl.src,true);request.onload=()=>{const parser=new DOMParser();const result=parser.parseFromString(request.responseText,'text/xml');const svgEl=result.getElementsByTagName("svg")[0];svgEl.setAttribute('width',imgEl.width);svgEl.setAttribute('height',imgEl.height);imgEl.remove();const svg64=btoa(new XMLSerializer().serializeToString(svgEl));const finalImg=new Image();finalImg.onload=()=>{resolve(finalImg);};finalImg.src=`data:image/svg+xml;base64,${svg64}`;};request.send();};imgEl.src=src;}).then(loadedImgEl=>toPNGViaCanvas(loadedImgEl));}
__exports.generateGMapIframe=generateGMapIframe;function generateGMapIframe(){const iframeEl=document.createElement('iframe');iframeEl.classList.add('s_map_embedded','o_not_editable');iframeEl.setAttribute('width','100%');iframeEl.setAttribute('height','100%');iframeEl.setAttribute('frameborder','0');iframeEl.setAttribute('scrolling','no');iframeEl.setAttribute('marginheight','0');iframeEl.setAttribute('marginwidth','0');iframeEl.setAttribute('src','about:blank');return iframeEl;}
__exports.generateGMapLink=generateGMapLink;function generateGMapLink(dataset){return'https://maps.google.com/maps?q='+encodeURIComponent(dataset.mapAddress)
+'&t='+encodeURIComponent(dataset.mapType)
+'&z='+encodeURIComponent(dataset.mapZoom)
+'&ie=UTF8&iwloc=&output=embed';}
function isMobile(self){let isMobile;self.trigger_up("service_context_get",{callback:(ctx)=>{isMobile=ctx["isMobile"];},});return isMobile;}
function getParsedDataFor(formId,parentEl){const dataForEl=parentEl.querySelector(`[data-for='${formId}']`);if(!dataForEl){return;}
return JSON.parse(dataForEl.dataset.values.replace(/([,:\[]\s*)True/g,'$1true').replace(/([,:\[]\s*)(False|None)/g,'$1""').replace(/'(\s*[,:\]}])/g,'"$1').replace(/([{\[:,]\s*)'/g,'$1"'));}
__exports.cloneContentEls=cloneContentEls;function cloneContentEls(content,keepScripts=false){let copyFragment;if(typeof content==="string"){copyFragment=new Range().createContextualFragment(content);}else{copyFragment=new DocumentFragment();const els=[...content.children].map(el=>el.cloneNode(true));copyFragment.append(...els);}
if(!keepScripts){copyFragment.querySelectorAll("script").forEach(scriptEl=>scriptEl.remove());}
return copyFragment;}
__exports[Symbol.for("default")]={loadAnchors:loadAnchors,autocompleteWithPages:autocompleteWithPages,onceAllImagesLoaded:onceAllImagesLoaded,prompt:prompt,sendRequest:sendRequest,websiteDomain:websiteDomain,isHTTPSorNakedDomainRedirection:isHTTPSorNakedDomainRedirection,svgToPNG:svgToPNG,webpToPNG:webpToPNG,generateGMapIframe:generateGMapIframe,generateGMapLink:generateGMapLink,isMobile:isMobile,getParsedDataFor:getParsedDataFor,cloneContentEls:cloneContentEls,};return __exports;});;

/* /website/static/src/components/autocomplete_with_pages/autocomplete_with_pages.js */
odoo.define('@website/components/autocomplete_with_pages/autocomplete_with_pages',['@web/core/autocomplete/autocomplete','@odoo/owl'],function(require){'use strict';let __exports={};const{AutoComplete}=require("@web/core/autocomplete/autocomplete");const{useEffect}=require("@odoo/owl");const AutoCompleteWithPages=__exports.AutoCompleteWithPages=class AutoCompleteWithPages extends AutoComplete{static template="website.AutoCompleteWithPages";setup(){super.setup();useEffect((input,inputRef)=>{if(inputRef){inputRef.value=input.value;}
const targetBlur=this.onInputBlur.bind(this);const targetClick=this._syncInputClick.bind(this);const targetChange=this.onInputChange.bind(this);const targetInput=this._syncInputValue.bind(this);const targetKeydown=this.onInputKeydown.bind(this);const targetFocus=this.onInputFocus.bind(this);input.addEventListener("blur",targetBlur);input.addEventListener("click",targetClick);input.addEventListener("change",targetChange);input.addEventListener("input",targetInput);input.addEventListener("keydown",targetKeydown);input.addEventListener("focus",targetFocus);return()=>{input.removeEventListener("blur",targetBlur);input.removeEventListener("click",targetClick);input.removeEventListener("change",targetChange);input.removeEventListener("input",targetInput);input.removeEventListener("keydown",targetKeydown);input.removeEventListener("focus",targetFocus);};},()=>[this.targetDropdown,this.inputRef.el]);}
get dropdownOptions(){if(this.props.dropdownOptions){return{...super.dropdownOptions,...this.props.dropdownOptions,};}
return super.dropdownOptions;}
get ulDropdownClass(){let classList=super.ulDropdownClass;if(this.props.dropdownClass){classList+=` ${this.props.dropdownClass}`;}
return classList;}
get targetDropdown(){return this.props.targetDropdown;}
_syncInputClick(ev){ev.stopPropagation();this.onInputClick(ev);}
async _syncInputValue(){if(this.inputRef.el){this.inputRef.el.value=this.targetDropdown.value;this.onInput();}}
_isCategory(indices){const[sourceIndex,optionIndex]=indices;return!!this.sources[sourceIndex]?.options[optionIndex]?.separator;}
onOptionMouseEnter(indices){if(!this._isCategory(indices)){return super.onOptionMouseEnter(...arguments);}}
onOptionMouseLeave(indices){if(!this._isCategory(indices)){return super.onOptionMouseLeave(...arguments);}}
isActiveSourceOption(indices){if(!this._isCategory(indices)){return super.isActiveSourceOption(...arguments);}}
selectOption(indices){if(!this._isCategory(indices)){const[sourceIndex,optionIndex]=indices;const{value}=Object.getPrototypeOf(this.sources[sourceIndex].options[optionIndex]);this.targetDropdown.value=value;return super.selectOption(...arguments);}}
navigate(direction){super.navigate(direction);if(direction!==0&&this.state.activeSourceOption){let[sourceIndex,optionIndex]=this.state.activeSourceOption;const option=this.sources[sourceIndex]?.options[optionIndex];if(option){if(!!option.separator){this.navigate(direction);}
const suggestion=Object.getPrototypeOf(option);if(suggestion&&suggestion.value){this.inputRef.el.value=suggestion.value;}}}}
onInputFocus(ev){this.targetDropdown.setSelectionRange(0,this.targetDropdown.value.length);this.props.onFocus(ev);}
close(){this.props.onInput({inputValue:this.inputRef.el.value,});super.close();}}
AutoCompleteWithPages.props={...AutoComplete.props,targetDropdown:{type:HTMLElement},dropdownClass:{type:String,optional:true},dropdownOptions:{type:Object,optional:true},};return __exports;});;

/* /website/static/src/components/autocomplete_with_pages/url_autocomplete.js */
odoo.define('@website/components/autocomplete_with_pages/url_autocomplete',['@odoo/owl','@web/core/utils/hooks','@website/components/autocomplete_with_pages/autocomplete_with_pages'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{AutoCompleteWithPages}=require("@website/components/autocomplete_with_pages/autocomplete_with_pages");const UrlAutoComplete=__exports.UrlAutoComplete=class UrlAutoComplete extends Component{static template="website.UrlAutoComplete";static components={AutoCompleteWithPages};setup(){super.setup();this.rpc=useService("rpc");}
_mapItemToSuggestion(item){return{...item,classList:item.separator?"ui-autocomplete-category":"ui-autocomplete-item",};}
get dropdownClass(){const classList=[];for(const key in this.props.options?.classes){classList.push(key,this.props.options.classes[key]);}
return classList.join(" ")}
get dropdownOptions(){const options={};if(this.props.options?.position){options.position=this.props.options?.position;}
return options;}
get sources(){return[{optionTemplate:"website.AutoCompleteWithPagesItem",options:async(term)=>{if(term[0]==="#"){const anchors=await this.props.loadAnchors(term,this.props.options&&this.props.options.body);return anchors.map((anchor)=>this._mapItemToSuggestion({label:anchor,value:anchor}));}else if(term.startsWith("http")||term.length===0){return[];}
if(this.props.options.isDestroyed?.()){return[];}
const res=await this.rpc("/website/get_suggested_links",{needle:term,limit:15,});let choices=res.matching_pages;res.others.forEach((other)=>{if(other.values.length){choices=choices.concat([{separator:other.title,label:other.title}],other.values);}});return choices.map(this._mapItemToSuggestion);},},];}
onSelect(selectedSubjection,{input}){const{value}=Object.getPrototypeOf(selectedSubjection);input.value=value;this.props.targetDropdown.value=value;this.props.options.urlChosen?.();}
onInput({inputValue}){this.props.targetDropdown.value=inputValue;}}
UrlAutoComplete.props={options:{type:Object},loadAnchors:{type:Function},targetDropdown:{type:HTMLElement},};return __exports;});;

/* /website/static/src/js/tours/tour_utils.js */
odoo.define('@website/js/tours/tour_utils',['@web/core/l10n/translation','@web/core/registry','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{markup}=require("@odoo/owl");function addMedia(position="right"){return{trigger:`.modal-content footer .btn-primary`,content:markup(_t("<b>Add</b> the selected image.")),position:position,run:"click",};}
function assertCssVariable(variableName,variableValue,trigger='iframe body'){return{content:`Check CSS variable ${variableName}=${variableValue}`,trigger:trigger,auto:true,run:function(){const styleValue=getComputedStyle(this.$anchor[0]).getPropertyValue(variableName);if((styleValue&&styleValue.trim().replace(/["']/g,''))!==variableValue.trim().replace(/["']/g,'')){throw new Error(`Failed precondition: ${variableName}=${styleValue} (should be ${variableValue})`);}},};}
function assertPathName(pathName,trigger){return{content:`Check if we have been redirected to ${pathName}`,trigger:trigger,run:()=>{if(!window.location.pathname.startsWith(pathName)){console.error(`We should be on ${pathName}.`);}}};}
function changeBackground(snippet,position="bottom"){return{trigger:".o_we_customize_panel .o_we_bg_success",content:markup(_t("<b>Customize</b> any block through this menu. Try to change the background image of this block.")),position:position,run:"click",};}
function changeBackgroundColor(position="bottom"){return{trigger:".o_we_customize_panel .o_we_color_preview",content:markup(_t("<b>Customize</b> any block through this menu. Try to change the background color of this block.")),position:position,run:"click",};}
function selectColorPalette(position="left"){return{trigger:".o_we_customize_panel .o_we_so_color_palette we-selection-items",alt_trigger:".o_we_customize_panel .o_we_color_preview",content:markup(_t(`<b>Select</b> a Color Palette.`)),position:position,run:'click',location:position==='left'?'#oe_snippets':undefined,};}
function changeColumnSize(position="right"){return{trigger:`iframe .oe_overlay.o_draggable.o_we_overlay_sticky.oe_active .o_handle.e`,content:markup(_t("<b>Slide</b> this button to change the column size.")),position:position,};}
function changeIcon(snippet,index=0,position="bottom"){return{trigger:`#wrapwrap .${snippet.id} i:eq(${index})`,extra_trigger:"body.editor_enable",content:markup(_t("<b>Double click on an icon</b> to change it with one of your choice.")),position:position,run:"dblclick",};}
function changeImage(snippet,position="bottom"){return{trigger:snippet.id?`#wrapwrap .${snippet.id} img`:snippet,extra_trigger:"body.editor_enable",content:markup(_t("<b>Double click on an image</b> to change it with one of your choice.")),position:position,run:"dblclick",};}
function changeOption(optionName,weName='',optionTooltipLabel='',position="bottom",allowPalette=false){const noPalette=allowPalette?'':'.o_we_customize_panel:not(:has(.o_we_so_color_palette.o_we_widget_opened))';const option_block=`${noPalette} we-customizeblock-option[class='snippet-option-${optionName}']`;return{trigger:`${option_block} ${weName}, ${option_block} [title='${weName}']`,content:markup(_t("<b>Click</b> on this option to change the %s of the block.",optionTooltipLabel)),position:position,in_modal:false,run:"click",};}
function selectNested(trigger,optionName,alt_trigger=null,optionTooltipLabel='',position="top",allowPalette=false){const noPalette=allowPalette?'':'.o_we_customize_panel:not(:has(.o_we_so_color_palette.o_we_widget_opened))';const option_block=`${noPalette} we-customizeblock-option[class='snippet-option-${optionName}']`;return{trigger:trigger,content:markup(_t("<b>Select</b> a %s.",optionTooltipLabel)),alt_trigger:alt_trigger==null?undefined:`${option_block} ${alt_trigger}`,position:position,run:'click',location:position==='left'?'#oe_snippets':undefined,};}
function changePaddingSize(direction){let paddingDirection="n";let position="top";if(direction==="bottom"){paddingDirection="s";position="bottom";}
return{trigger:`iframe .oe_overlay.o_draggable.o_we_overlay_sticky.oe_active .o_handle.${paddingDirection}`,content:markup(_t("<b>Slide</b> this button to change the %s padding",direction)),consumeEvent:'mousedown',position:position,};}
function checkIfVisibleOnScreen(elementSelector){return{content:"Check if the element is visible on screen",trigger:`${elementSelector}`,run(){const boundingRect=this.$anchor[0].getBoundingClientRect();const centerX=boundingRect.left+boundingRect.width/2;const centerY=boundingRect.top+boundingRect.height/2;const iframeDocument=document.querySelector(".o_iframe").contentDocument;const el=iframeDocument.elementFromPoint(centerX,centerY);if(!this.$anchor[0].contains(el)){console.error("The element is not visible on screen");}},};}
function clickOnElement(elementName,selector){return{content:`Clicking on the ${elementName}`,trigger:selector,run:'click'};}
function clickOnEditAndWaitEditMode(position="bottom"){return[{content:markup(_t("<b>Click Edit</b> to start designing your homepage.")),trigger:".o_menu_systray .o_edit_website_container a",position:position,},{content:"Check that we are in edit mode",trigger:".o_website_preview.editor_enable.editor_has_snippets",auto:true,isCheck:true,}];}
function clickOnSnippet(snippet,position="bottom"){const trigger=snippet.id?`#wrapwrap .${snippet.id}`:snippet;return{trigger:`iframe ${trigger}`,extra_trigger:"body.editor_has_snippets",content:markup(_t("<b>Click on a snippet</b> to access its options menu.")),position:position,run:"click",};}
function clickOnSave(position="bottom",timeout){return[{trigger:"div:not(.o_loading_dummy) > #oe_snippets button[data-action=\"save\"]:not([disabled])",extra_trigger:"body:not(:has(.o_dialog)) #oe_snippets:not(:has(.o_we_already_dragging))",in_modal:false,content:markup(_t("Good job! It's time to <b>Save</b> your work.")),position:position,timeout:timeout,},{trigger:'iframe body:not(.editor_enable)',noPrepend:true,auto:true,run:()=>null,}];}
function clickOnText(snippet,element,position="bottom"){return{trigger:snippet.id?`iframe #wrapwrap .${snippet.id} ${element}`:snippet,extra_trigger:"iframe body.editor_enable",content:markup(_t("<b>Click on a text</b> to start editing it.")),position:position,run:"text",consumeEvent:"click",};}
function dragNDrop(snippet,position="bottom"){return{trigger:`#oe_snippets .oe_snippet[name="${snippet.name}"] .oe_snippet_thumbnail:not(.o_we_already_dragging)`,extra_trigger:".o_website_preview.editor_enable.editor_has_snippets",content:markup(_t("Drag the <b>%s</b> building block and drop it at the bottom of the page.",snippet.name)),position:position,run:"drag_and_drop_native iframe #wrapwrap > footer",};}
function goBackToBlocks(position="bottom"){return{trigger:'.o_we_add_snippet_btn',content:_t("Click here to go back to block tab."),position:position,run:"click",};}
function goToTheme(position="bottom"){return{trigger:'.o_we_customize_theme_btn',extra_trigger:'#oe_snippets.o_loaded',content:_t("Go to the Theme tab"),position:position,run:"click",};}
function selectHeader(position="bottom"){return{trigger:`iframe header#top`,content:markup(_t(`<b>Click</b> on this header to configure it.`)),position:position,run:"click",};}
function selectSnippetColumn(snippet,index=0,position="bottom"){return{trigger:`iframe #wrapwrap .${snippet.id} .row div[class*="col-lg-"]:eq(${index})`,content:markup(_t("<b>Click</b> on this column to access its options.")),position:position,run:"click",};}
function prepend_trigger(steps,prepend_text=''){for(const step of steps){if(!step.noPrepend&&prepend_text){step.trigger=prepend_text+step.trigger;}}
return steps;}
function getClientActionUrl(path,edition){let url=`/web#action=website.website_preview`;if(path){url+=`&path=${encodeURIComponent(path)}`;}
if(edition){url+='&enable_editor=1';}
return url;}
function clickOnExtraMenuItem(stepOptions,backend=false){return Object.assign({},{content:"Click on the extra menu dropdown toggle if it is there",trigger:`${backend ? "iframe" : ""} .top_menu`,run:function(){const extraMenuButton=this.$anchor[0].querySelector('.o_extra_menu_items a.nav-link');if(extraMenuButton&&!extraMenuButton.classList.contains("show")){extraMenuButton.click();}},},stepOptions);}
function registerWebsitePreviewTour(name,options,steps){if(typeof steps!=="function"){throw new Error(`tour.steps has to be a function that returns TourStep[]`);}
return registry.category("web_tour.tours").add(name,{...options,url:getClientActionUrl(options.url,!!options.edition),steps:()=>{const tourSteps=[...steps()];if(options.edition){tourSteps.unshift({content:"Wait for the edit mode to be started",trigger:".o_website_preview.editor_enable.editor_has_snippets",timeout:30000,auto:true,run:()=>{},});}else{tourSteps[0].timeout=20000;}
return tourSteps;},});}
function registerThemeHomepageTour(name,steps){if(typeof steps!=="function"){throw new Error(`tour.steps has to be a function that returns TourStep[]`);}
return registerWebsitePreviewTour(name,{url:'/',sequence:50,saveAs:"homepage",},()=>[...clickOnEditAndWaitEditMode(),...prepend_trigger(steps().concat(clickOnSave()),".o_website_preview[data-view-xmlid='website.homepage'] "),]);}
function registerBackendAndFrontendTour(name,options,steps){if(typeof steps!=="function"){throw new Error(`tour.steps has to be a function that returns TourStep[]`);}
if(window.location.pathname==='/web'){return registerWebsitePreviewTour(name,options,()=>{const newSteps=[];for(const step of steps()){const newStep=Object.assign({},step);newStep.trigger=`iframe ${step.trigger}`;if(step.extra_trigger){newStep.extra_trigger=`iframe ${step.extra_trigger}`;}
newSteps.push(newStep);}
return newSteps;});}
return registry.category("web_tour.tours").add(name,{url:options.url,steps:()=>{return steps();},});}
function selectElementInWeSelectWidget(widgetName,elementName,searchNeeded=false){const steps=[clickOnElement(`${widgetName} toggler`,`we-select[data-name=${widgetName}] we-toggler`)];if(searchNeeded){steps.push({content:`Inputing ${elementName} in m2o widget search`,trigger:`we-select[data-name=${widgetName}] div.o_we_m2o_search input`,run:`text ${elementName}`});}
steps.push(clickOnElement(`${elementName} in the ${widgetName} widget`,`we-select[data-name="${widgetName}"] we-button:contains("${elementName}"), `+`we-select[data-name="${widgetName}"] we-button[data-select-label="${elementName}"]`));steps.push({content:"Check we-select is set",trigger:`we-select[data-name=${widgetName}]:contains(${elementName})`,async run(){await new Promise((resolve)=>setTimeout(resolve,300));}});return steps;}
function switchWebsite(websiteId,websiteName){return[{content:`Click on the website switch to switch to website '${websiteName}'`,trigger:'.o_website_switcher_container button',},{content:`Switch to website '${websiteName}'`,extra_trigger:`iframe html:not([data-website-id="${websiteId}"])`,trigger:`.o_website_switcher_container .dropdown-item:contains("${websiteName}")`,},{content:"Wait for the iframe to be loaded",timeout:20000,trigger:`iframe html[data-website-id="${websiteId}"]`,isCheck:true,}];}
function toggleMobilePreview(toggleOn){const onOrOff=toggleOn?"on":"off";const mobileOnSelector=".o_is_mobile";const mobileOffSelector=":not(.o_is_mobile)";return[{content:`Toggle the mobile preview ${onOrOff}`,trigger:".o_we_website_top_actions [data-action='mobile']",extra_trigger:`iframe #wrapwrap${toggleOn ? mobileOffSelector : mobileOnSelector}`,},{content:`Check that the mobile preview is ${onOrOff}`,trigger:`iframe #wrapwrap${toggleOn ? mobileOnSelector : mobileOffSelector}`,isCheck:true,}];}
__exports[Symbol.for("default")]={addMedia,assertCssVariable,assertPathName,changeBackground,changeBackgroundColor,changeColumnSize,changeIcon,changeImage,changeOption,changePaddingSize,checkIfVisibleOnScreen,clickOnEditAndWaitEditMode,clickOnElement,clickOnExtraMenuItem,clickOnSave,clickOnSnippet,clickOnText,dragNDrop,getClientActionUrl,goBackToBlocks,goToTheme,registerBackendAndFrontendTour,registerThemeHomepageTour,registerWebsitePreviewTour,selectColorPalette,selectElementInWeSelectWidget,selectHeader,selectNested,selectSnippetColumn,switchWebsite,toggleMobilePreview,};return __exports;});;

/* /website/static/src/js/content/website_root.js */
odoo.define('@website/js/content/website_root',['@web/core/assets','@web/core/l10n/translation','@web/session','@web/legacy/js/public/public_root','@website/libs/zoomodoo/zoomodoo','@web/core/utils/objects','@odoo/owl'],function(require){'use strict';let __exports={};const{loadJS}=require("@web/core/assets");const{_t}=require("@web/core/l10n/translation");const{session}=require("@web/session");const publicRootData=require('@web/legacy/js/public/public_root')[Symbol.for("default")];require("@website/libs/zoomodoo/zoomodoo");const{pick}=require("@web/core/utils/objects");const{markup}=require("@odoo/owl");const WebsiteRoot=__exports.WebsiteRoot=publicRootData.PublicRoot.extend({events:Object.assign({},publicRootData.PublicRoot.prototype.events||{},{'click .js_change_lang':'_onLangChangeClick','click .js_publish_management .js_publish_btn':'_onPublishBtnClick','shown.bs.modal':'_onModalShown',}),custom_events:Object.assign({},publicRootData.PublicRoot.prototype.custom_events||{},{'gmap_api_request':'_onGMapAPIRequest','gmap_api_key_request':'_onGMapAPIKeyRequest','ready_to_clean_for_save':'_onWidgetsStopRequest','seo_object_request':'_onSeoObjectRequest','will_remove_snippet':'_onWidgetsStopRequest',}),init(){this.isFullscreen=false;this.rpc=this.bindService("rpc");this.notification=this.bindService("notification");return this._super(...arguments);},start:function(){this.$('.zoomable img[data-zoom]').zoomOdoo();return this._super.apply(this,arguments);},_getContext:function(context){var html=document.documentElement;return Object.assign({'website_id':html.getAttribute('data-website-id')|0,},this._super.apply(this,arguments));},_getExtraContext:function(context){var html=document.documentElement;return Object.assign({'editable':!!(html.dataset.editable||$('[data-oe-model]').length),'translatable':!!html.dataset.translatable,'edit_translations':!!html.dataset.edit_translations,},this._super.apply(this,arguments));},async _getGMapAPIKey(refetch){if(refetch||!this._gmapAPIKeyProm){this._gmapAPIKeyProm=new Promise(async resolve=>{const data=await this.rpc('/website/google_maps_api_key');resolve(JSON.parse(data).google_maps_api_key||'');});}
return this._gmapAPIKeyProm;},_getPublicWidgetsRegistry:function(options){var registry=this._super.apply(this,arguments);if(options.editableMode){const toPick=Object.keys(registry).filter((key)=>{const PublicWidget=registry[key];return!PublicWidget.prototype.disabledInEditableMode;});return pick(registry,...toPick);}
return registry;},async _loadGMapAPI(editableMode,refetch){if(refetch||!this._gmapAPILoading){this._gmapAPILoading=new Promise(async resolve=>{const key=await this._getGMapAPIKey(refetch);window.odoo_gmap_api_post_load=(async function odoo_gmap_api_post_load(){await this._startWidgets($("section.s_google_map"),{editableMode:editableMode});resolve(key);}).bind(this);if(!key){if(!editableMode&&session.is_admin){const message=_t("Cannot load google map.");const urlTitle=_t("Check your configuration.");this.notification.add(markup(`<div>
                                <span>${message}</span><br/>
                                <a href="/web#action=website.action_website_configuration">${urlTitle}</a>
                            </div>`),{type:'warning',sticky:true});}
resolve(false);this._gmapAPILoading=false;return;}
await loadJS(`https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places&callback=odoo_gmap_api_post_load&key=${encodeURIComponent(key)}`);});}
return this._gmapAPILoading;},_onWidgetsStartRequest:function(ev){ev.data.options=Object.assign({},ev.data.options||{});ev.data.options.editableMode=ev.data.editableMode;this._super.apply(this,arguments);},_onLangChangeClick:function(ev){ev.preventDefault();if(document.body.classList.contains('editor_enable')){return;}
var $target=$(ev.currentTarget);var redirect={lang:encodeURIComponent($target.data('url_code')),url:encodeURIComponent($target.attr('href').replace(/[&?]edit_translations[^&?]+/,'')),hash:encodeURIComponent(window.location.hash)};window.location.href=`/website/lang/${redirect.lang}?r=${redirect.url}${redirect.hash}`;},async _onGMapAPIRequest(ev){ev.stopPropagation();const apiKey=await this._loadGMapAPI(ev.data.editableMode,ev.data.refetch);ev.data.onSuccess(apiKey);},async _onGMapAPIKeyRequest(ev){ev.stopPropagation();const apiKey=await this._getGMapAPIKey(ev.data.refetch);ev.data.onSuccess(apiKey);},_onSeoObjectRequest:function(ev){var res=this._unslugHtmlDataObject('seo-object');ev.data.callback(res);},_unslugHtmlDataObject:function(dataAttr){var repr=$('html').data(dataAttr);var match=repr&&repr.match(/(.+)\((\d+),(.*)\)/);if(!match){return null;}
return{model:match[1],id:match[2]|0,};},_onPublishBtnClick:function(ev){ev.preventDefault();if(document.body.classList.contains('editor_enable')){return;}
var $data=$(ev.currentTarget).parents(".js_publish_management:first");this.rpc($data.data('controller')||'/website/publish',{id:+$data.data('id'),object:$data.data('object'),}).then(function(result){$data.toggleClass("css_published",result).toggleClass("css_unpublished",!result);$data.find('input').prop("checked",result);$data.parents("[data-publish]").attr("data-publish",+result?'on':'off');});},_onModalShown:function(ev){$(ev.target).addClass('modal_shown');},});__exports[Symbol.for("default")]={WebsiteRoot:WebsiteRoot,};return __exports;});;

/* /website/static/src/js/widgets/dialog.js */
odoo.define('@website/js/widgets/dialog',['@web/legacy/js/core/dialog'],function(require){'use strict';let __exports={};const Dialog=require('@web/legacy/js/core/dialog')[Symbol.for("default")];Dialog.include({_isBlocking(index,el){if(el.parentElement&&el.parentElement.id==='website_cookies_bar'&&!el.classList.contains('o_cookies_popup')){return false;}
return this._super(...arguments);},});return __exports;});;

/* /website/static/src/js/content/compatibility.js */
odoo.define('@website/js/content/compatibility',[],function(require){'use strict';let __exports={};var htmlStyle=document.documentElement.style;var isFlexSupported=(('flexWrap'in htmlStyle)||('WebkitFlexWrap'in htmlStyle)||('msFlexWrap'in htmlStyle));if(!isFlexSupported){document.documentElement.setAttribute('data-no-flex','');}
__exports[Symbol.for("default")]={isFlexSupported:isFlexSupported,};return __exports;});;

/* /website/static/src/js/content/menu.js */
odoo.define('@website/js/content/menu',['@web/legacy/js/public/public_widget','@website/js/content/snippets.animation','@web/core/ui/ui_service'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const animations=require("@website/js/content/snippets.animation")[Symbol.for("default")];const extraMenuUpdateCallbacks=__exports.extraMenuUpdateCallbacks=[];const{SIZES,utils:uiUtils}=require("@web/core/ui/ui_service");let headerHeight;const BaseAnimatedHeader=animations.Animation.extend({disabledInEditableMode:false,effects:[{startEvents:'scroll',update:'_updateHeaderOnScroll',},{startEvents:'resize',update:'_updateHeaderOnResize',}],init:function(){this._super(...arguments);this.fixedHeader=false;this.scrolledPoint=0;this.hasScrolled=false;this.closeOpenedMenus=false;this.scrollHeightTooShort=false;this.scrollableEl=$().getScrollingElement()[0];},start:function(){this.$main=this.$el.next('main');this.isOverlayHeader=!!this.$el.closest('.o_header_overlay, .o_header_overlay_theme').length;this.$dropdowns=this.$el.find('.dropdown, .dropdown-menu');this.hiddenOnScrollEl=this.el.querySelector(".o_header_hide_on_scroll");const disableScroll=function(){if(uiUtils.getSize()<SIZES.LG){$(document.body).addClass('overflow-hidden');}};const enableScroll=function(){$(document.body).removeClass('overflow-hidden');};this.$navbarOffcanvases=this.$el.find(".offcanvas");this.$navbarOffcanvases.on("show.bs.offcanvas.BaseAnimatedHeader",disableScroll).on("hide.bs.offcanvas.BaseAnimatedHeader",enableScroll);this.$navbarCollapses=this.$el.find('.navbar-collapse');this.$navbarCollapses.on("show.bs.collapse.BaseAnimatedHeader",disableScroll).on("hide.bs.collapse.BaseAnimatedHeader",enableScroll);this._transitionCount=0;this.$el.on('odoo-transitionstart.BaseAnimatedHeader',()=>{this.el.classList.add('o_transitioning');this._adaptToHeaderChangeLoop(1);});this.$el.on('transitionend.BaseAnimatedHeader',()=>this._adaptToHeaderChangeLoop(-1));return this._super(...arguments);},destroy:function(){this._toggleFixedHeader(false);this.$el.removeClass('o_header_affixed o_header_is_scrolled o_header_no_transition o_transitioning');this.$navbarOffcanvases.off(".BaseAnimatedHeader");this.$navbarCollapses.off('.BaseAnimatedHeader');this.$el.off('.BaseAnimatedHeader');this._super(...arguments);},_adaptFixedHeaderPosition(){$(this.el).compensateScrollbar(this.fixedHeader,false,'right');},_adaptToHeaderChange:function(){this.options.wysiwyg&&this.options.wysiwyg.odooEditor.observerUnactive();this._updateMainPaddingTop();this.el.classList.toggle('o_top_fixed_element',this._isShown());for(const callback of extraMenuUpdateCallbacks){callback();}
this.options.wysiwyg&&this.options.wysiwyg.odooEditor.observerActive();},_adaptToHeaderChangeLoop:function(addCount=0){this._adaptToHeaderChange();this._transitionCount+=addCount;this._transitionCount=Math.max(0,this._transitionCount);if(this._transitionCount>0){window.requestAnimationFrame(()=>this._adaptToHeaderChangeLoop());if(addCount!==0){clearTimeout(this._changeLoopTimer);this._changeLoopTimer=setTimeout(()=>{this._adaptToHeaderChangeLoop(-this._transitionCount);},500);}}else{clearTimeout(this._changeLoopTimer);this.el.classList.remove('o_transitioning');}},_adjustUrlAutoScroll(){if(!this.editableMode){this.scrollableEl.scrollBy(0,-this.el.offsetHeight);}},_computeTopGap(){return 0;},_isShown(){return true;},_toggleFixedHeader:function(useFixed=true){this.fixedHeader=useFixed;this._adaptToHeaderChange();this.el.classList.toggle('o_header_affixed',useFixed);this._adaptFixedHeaderPosition();},_updateMainPaddingTop:function(){headerHeight||=this.el.getBoundingClientRect().height;this.topGap=this._computeTopGap();if(this.isOverlayHeader){return;}
this.$main.css('padding-top',this.fixedHeader?headerHeight:'');},_scrollHeightTooShort(){const scrollEl=this.scrollableEl;const remainingScroll=(scrollEl.scrollHeight-scrollEl.clientHeight)-this.scrolledPoint;const clonedHeader=this.el.cloneNode(true);scrollEl.append(clonedHeader);clonedHeader.classList.add('o_header_is_scrolled','o_header_affixed','o_header_no_transition');const endHeaderHeight=clonedHeader.offsetHeight;clonedHeader.remove();const heightDiff=headerHeight-endHeaderHeight;return heightDiff>0?remainingScroll<=heightDiff:false;},_updateHeaderOnScroll:function(scroll){if(!this.hasScrolled){this.hasScrolled=true;if(scroll>0){this.$el.addClass('o_header_no_transition');this._adjustUrlAutoScroll();}}else{this.$el.removeClass('o_header_no_transition');this.closeOpenedMenus=true;}
const headerIsScrolled=(scroll>this.scrolledPoint);if(this.headerIsScrolled!==headerIsScrolled){this.scrollHeightTooShort=headerIsScrolled&&this._scrollHeightTooShort();if(!this.scrollHeightTooShort){this.el.classList.toggle('o_header_is_scrolled',headerIsScrolled);this.$el.trigger('odoo-transitionstart');this.headerIsScrolled=headerIsScrolled;}}
if(this.closeOpenedMenus){this.el.querySelectorAll(".dropdown-toggle.show").forEach(dropdownToggleEl=>{Dropdown.getOrCreateInstance(dropdownToggleEl).hide();});}},_updateHeaderOnResize:function(){this._adaptFixedHeaderPosition();if(document.body.classList.contains('overflow-hidden')&&uiUtils.getSize()>=SIZES.LG){this.el.querySelectorAll(".offcanvas.show").forEach(offcanvasEl=>{Offcanvas.getOrCreateInstance(offcanvasEl).hide();});this.el.querySelectorAll(".navbar-collapse.show").forEach(collapseEl=>{Collapse.getOrCreateInstance(collapseEl).hide();});}},});publicWidget.registry.StandardAffixedHeader=BaseAnimatedHeader.extend({selector:'header.o_header_standard:not(.o_header_sidebar)',init:function(){this._super(...arguments);this.fixedHeaderShow=false;this.scrolledPoint=300;},start:function(){headerHeight||=this.el.getBoundingClientRect().height;return this._super.apply(this,arguments);},destroy(){this.$el.css('transform','');this._super(...arguments);},_isShown(){return!this.fixedHeader||this.fixedHeaderShow;},_updateHeaderOnScroll:function(scroll){this._super(...arguments);const mainPosScrolled=(scroll>headerHeight+this.topGap);const reachPosScrolled=(scroll>this.scrolledPoint+this.topGap)&&!this.scrollHeightTooShort;const fixedUpdate=(this.fixedHeader!==mainPosScrolled);const showUpdate=(this.fixedHeaderShow!==reachPosScrolled);if(fixedUpdate||showUpdate){this.$el.css('transform',reachPosScrolled?`translate(0, -${this.topGap}px)`:mainPosScrolled?'translate(0, -100%)':'');void this.$el[0].offsetWidth;}
this.fixedHeaderShow=reachPosScrolled;this.hiddenOnScrollEl?.classList.toggle("hidden",mainPosScrolled);if(fixedUpdate){this._toggleFixedHeader(mainPosScrolled);}else if(showUpdate){this._adaptToHeaderChange();}},});publicWidget.registry.FixedHeader=BaseAnimatedHeader.extend({selector:'header.o_header_fixed:not(.o_header_sidebar)',start(){const _super=this._super(...arguments);this.dropdownToggleEls=[];if(this.hiddenOnScrollEl){this.dropdownToggleEls=this.hiddenOnScrollEl.querySelectorAll(".dropdown-toggle");for(const dropdownToggleEl of this.dropdownToggleEls){this.__onDropdownShow=this._onDropdownShow.bind(this);dropdownToggleEl.addEventListener("show.bs.dropdown",this.__onDropdownShow);}
this.searchbarEl=this.hiddenOnScrollEl.querySelector(":not(.modal-content) > .o_searchbar_form");if(this.searchbarEl){this.__onSearchbarInput=this._onSearchbarInput.bind(this);this.searchbarEl.addEventListener("input",this.__onSearchbarInput);}}
return _super;},destroy(){for(const dropdownToggleEl of this.dropdownToggleEls){dropdownToggleEl.removeEventListener("show.bs.dropdown",this.__onDropdownShow);}
if(this.searchbarEl){this.searchbarEl.removeEventListener("input",this.__onSearchbarInput);}
this._super(...arguments);},_updateHeaderOnScroll:function(scroll){this._super(...arguments);if(scroll>(this.scrolledPoint+this.topGap)){if(!this.$el.hasClass('o_header_affixed')){this.$el.css('transform',`translate(0, -${this.topGap}px)`);void this.$el[0].offsetWidth;this._toggleFixedHeader(true);}}else{this._toggleFixedHeader(false);void this.$el[0].offsetWidth;this.$el.css('transform','');}
if(this.hiddenOnScrollEl){let elHeight=0;if(this.fixedHeader&&this.searchbarEl?.matches(".show")){this.searchbarEl.querySelector("input").blur();elHeight=this.hiddenOnScrollEl.offsetHeight;}else{elHeight=this.hiddenOnScrollEl.scrollHeight;}
const scrollDelta=window.matchMedia(`(prefers-reduced-motion: reduce)`).matches?scroll:Math.floor(scroll/4);elHeight=Math.max(0,elHeight-scrollDelta);this.hiddenOnScrollEl.classList.toggle("hidden",elHeight===0);if(elHeight===0){this.hiddenOnScrollEl.removeAttribute("style");}else{this.hiddenOnScrollEl.style.overflow=this.fixedHeader?"hidden":"";this.hiddenOnScrollEl.style.height=this.fixedHeader?`${elHeight}px`:"";let elPadding=parseInt(getComputedStyle(this.hiddenOnScrollEl).paddingBlock);if(elHeight<elPadding*2){const heightDifference=elPadding*2-elHeight;elPadding=Math.max(0,elPadding-Math.floor(heightDifference/2));this.hiddenOnScrollEl.style.setProperty("padding-block",`${elPadding}px`,"important");}else{this.hiddenOnScrollEl.style.paddingBlock="";}
if(this.fixedHeader){headerHeight=this.el.getBoundingClientRect().height;this._updateMainPaddingTop();}}
if(!this.fixedHeader&&this.dropdownClickedEl){const dropdown=Dropdown.getOrCreateInstance(this.dropdownClickedEl);dropdown.show();this.dropdownClickedEl=null;}}},_onDropdownShow(ev){if(this.fixedHeader){ev.preventDefault();this.scrollableEl.scrollTo({top:0,behavior:"smooth"});this.dropdownClickedEl=ev.currentTarget;}},_onSearchbarInput(ev){if(this.fixedHeader){this.scrollableEl.scrollTo({top:0});}},});const BaseDisappearingHeader=publicWidget.registry.FixedHeader.extend({init:function(){this._super(...arguments);this.scrollingDownwards=true;this.hiddenHeader=false;this.position=0;this.atTop=true;this.checkPoint=0;this.scrollOffsetLimit=200;},destroy:function(){this._showHeader();this._super.apply(this,arguments);},_hideHeader:function(){this.$el.trigger('odoo-transitionstart');},_isShown(){return!this.fixedHeader||!this.hiddenHeader;},_showHeader:function(){this.$el.trigger('odoo-transitionstart');},_updateHeaderOnScroll:function(scroll){this._super(...arguments);const scrollingDownwards=(scroll>this.position);const atTop=(scroll<=0);if(scrollingDownwards!==this.scrollingDownwards){this.checkPoint=scroll;}
this.scrollingDownwards=scrollingDownwards;this.position=scroll;this.atTop=atTop;if(scrollingDownwards){if(!this.hiddenHeader&&scroll-this.checkPoint>(this.scrollOffsetLimit+this.topGap)){this.hiddenHeader=true;this._hideHeader();}}else{if(this.hiddenHeader&&scroll-this.checkPoint<-(this.scrollOffsetLimit+this.topGap)/2){this.hiddenHeader=false;this._showHeader();}}
if(atTop&&!this.atTop){this._showHeader();}},});publicWidget.registry.DisappearingHeader=BaseDisappearingHeader.extend({selector:'header.o_header_disappears:not(.o_header_sidebar)',_adjustUrlAutoScroll(){},_hideHeader:function(){this._super(...arguments);this.$el.css('transform','translate(0, -100%)');},_showHeader:function(){this._super(...arguments);this.$el.css('transform',this.atTop?'':`translate(0, -${this.topGap}px)`);},});publicWidget.registry.FadeOutHeader=BaseDisappearingHeader.extend({selector:'header.o_header_fade_out:not(.o_header_sidebar)',_adjustUrlAutoScroll(){},_hideHeader:function(){this._super(...arguments);this.$el.stop(false,true).fadeOut();},_showHeader:function(){this._super(...arguments);this.$el.css('transform',this.atTop?'':`translate(0, -${this.topGap}px)`);this.$el.stop(false,true).fadeIn();},});publicWidget.registry.hoverableDropdown=animations.Animation.extend({selector:'header.o_hoverable_dropdown',disabledInEditableMode:false,effects:[{startEvents:'resize',update:'_dropdownHover',}],events:{'mouseenter .dropdown':'_onMouseEnter','mouseleave .dropdown':'_onMouseLeave',},start:function(){this.$dropdownMenus=this.$el.find('.dropdown-menu');this.$dropdownToggles=this.$el.find('.dropdown-toggle');this._dropdownHover();return this._super.apply(this,arguments);},_dropdownHover:function(){this.$dropdownMenus.attr('data-bs-popper','none');if(uiUtils.getSize()>=SIZES.LG){this.$dropdownMenus.css('margin-top','0');this.$dropdownMenus.css('top','unset');}else{this.$dropdownMenus.css('margin-top','');this.$dropdownMenus.css('top','');}},_hideDropdowns(){for(const toggleEl of this.el.querySelectorAll('.dropdown-toggle.show')){Dropdown.getOrCreateInstance(toggleEl).hide();}},_updateDropdownVisibility(ev,doShow=true){if(uiUtils.getSize()<SIZES.LG){return;}
if(ev.currentTarget.closest('.o_extra_menu_items')){return;}
const dropdownToggleEl=ev.currentTarget.querySelector('.dropdown-toggle');if(!dropdownToggleEl){return;}
const dropdown=Dropdown.getOrCreateInstance(dropdownToggleEl);if(doShow){dropdown.show();}else{dropdown.hide();}},_onMouseEnter:function(ev){if(this.editableMode){if(this.el.querySelector('.dropdown-toggle.show')){return;}}
const focusedEl=this.el.ownerDocument.querySelector(":focus")||window.frameElement&&window.frameElement.ownerDocument.querySelector(":focus");this._updateDropdownVisibility(ev,true);if(focusedEl){focusedEl.focus({preventScroll:true});}else{const dropdownToggleEl=ev.currentTarget.querySelector(".dropdown-toggle");if(dropdownToggleEl){dropdownToggleEl.blur();}}},_onMouseLeave:function(ev){if(this.editableMode){return;}
this._updateDropdownVisibility(ev,false);},_onPageClick(ev){if(ev.target.closest('.dropdown-menu.show')){return;}
this._hideDropdowns();},});publicWidget.registry.MegaMenuDropdown=publicWidget.Widget.extend({selector:"header#top",disabledInEditableMode:false,events:{"mousedown .o_mega_menu_toggle":"_onMegaMenuClick","mouseenter .o_mega_menu_toggle":"_onMegaMenuHover","mousedown .o_extra_menu_items":"_onExtraMenuClick","keyup .o_mega_menu_toggle":"_onMegaMenuClick","keyup .o_extra_menu_items":"_onExtraMenuClick",},start(){const toggleEls=this.el.querySelectorAll(".o_mega_menu_toggle");this.desktopMegaMenuToggleEls=[];this.mobileMegaMenuToggleEls=[];for(const el of toggleEls){if(el.closest(".o_header_mobile")){this.mobileMegaMenuToggleEls.push(el);}else{this.desktopMegaMenuToggleEls.push(el);}}
this.mobileMegaMenuToggleEls.forEach((megaMenuToggleEl,i)=>{const desktopMenuEl=this.desktopMegaMenuToggleEls[i].parentElement.querySelector(".o_mega_menu");if(!desktopMenuEl){return;}
megaMenuToggleEl.parentElement.querySelector(".o_mega_menu")?.remove();});return this._super(...arguments);},_moveMegaMenu(megaMenuToggleEl){const hasMegaMenu=!!megaMenuToggleEl.parentElement.querySelector(".o_mega_menu");if(hasMegaMenu){return;}
this.options.wysiwyg?.odooEditor.observerUnactive("moveMegaMenu");const isMobileNavbar=!!megaMenuToggleEl.closest(".o_header_mobile");const currentNavbarToggleEls=isMobileNavbar?this.mobileMegaMenuToggleEls:this.desktopMegaMenuToggleEls;const otherNavbarToggleEls=isMobileNavbar?this.desktopMegaMenuToggleEls:this.mobileMegaMenuToggleEls;const megaMenuToggleIndex=currentNavbarToggleEls.indexOf(megaMenuToggleEl);const previousMegaMenuToggleEl=otherNavbarToggleEls[megaMenuToggleIndex];const megaMenuEl=previousMegaMenuToggleEl.parentElement.querySelector(".o_mega_menu");Dropdown.getOrCreateInstance(previousMegaMenuToggleEl).hide();megaMenuToggleEl.insertAdjacentElement("afterend",megaMenuEl);this.options.wysiwyg?.odooEditor.observerActive("moveMegaMenu");},_onMegaMenuClick(ev){const megaMenuToggleEl=ev.currentTarget;if(this.el.classList.contains("o_hoverable_dropdown")&&!megaMenuToggleEl.closest(".o_header_mobile")&&ev.type!=="keyup"){return;}
this._moveMegaMenu(megaMenuToggleEl);},_onMegaMenuHover(ev){const megaMenuToggleEl=ev.currentTarget;if(!this.el.classList.contains("o_hoverable_dropdown")||megaMenuToggleEl.closest(".o_header_mobile")){return;}
this._moveMegaMenu(megaMenuToggleEl);},_onExtraMenuClick(ev){const megaMenuToggleEls=ev.currentTarget.querySelectorAll(".o_mega_menu_toggle");megaMenuToggleEls.forEach(megaMenuToggleEl=>this._moveMegaMenu(megaMenuToggleEl));},});publicWidget.registry.HeaderGeneral=publicWidget.Widget.extend({selector:'header#top',disabledInEditableMode:false,events:{"show.bs.offcanvas #top_menu_collapse, #top_menu_collapse_mobile":"_onCollapseShow","hidden.bs.offcanvas #top_menu_collapse, #top_menu_collapse_mobile":"_onCollapseHidden","shown.bs.offcanvas #top_menu_collapse_mobile":"_onMobileMenuToggled","hidden.bs.offcanvas #top_menu_collapse_mobile":"_onMobileMenuToggled",},start(){this.searchModalEl=document.querySelector("#o_search_modal_block");if(this.searchModalEl){this.__onSearchModalShow=this._onSearchModalShow.bind(this);this.searchModalEl.addEventListener("show.bs.modal",this.__onSearchModalShow);this.__onSearchModalShown=this._onSearchModalShown.bind(this);this.searchModalEl.addEventListener("shown.bs.modal",this.__onSearchModalShown);}
return this._super(...arguments);},destroy(){if(this.searchModalEl){this.searchModalEl.removeEventListener("show.bs.modal",this.__onSearchModalShow);this.searchModalEl.removeEventListener("shown.bs.modal",this.__onSearchModalShown);}
this._super(...arguments);},_onCollapseShow(){this.options.wysiwyg?.odooEditor.observerUnactive("addCollapseClass");this.el.classList.add('o_top_menu_collapse_shown');this.options.wysiwyg?.odooEditor.observerActive("addCollapseClass");},_onCollapseHidden(){this.options.wysiwyg?.odooEditor.observerUnactive("removeCollapseClass");if(!this.el.querySelector("#top_menu_collapse_mobile.show")){this.el.classList.remove('o_top_menu_collapse_shown');}
this.options.wysiwyg?.odooEditor.observerActive("removeCollapseClass");},_onMobileMenuToggled(ev){document.querySelector("#wrapwrap").classList.toggle("overflow-hidden");},_onSearchModalShow(ev){if(this.editableMode){ev.preventDefault();}},_onSearchModalShown(ev){this.searchModalEl.querySelector(".search-query").focus();},});publicWidget.registry.navbarDropdown=animations.Animation.extend({selector:"header .navbar",disabledInEditableMode:false,events:{"shown.bs.collapse":"_onCollapseShown","hidden.bs.collapse":"_onCollapseHidden",},_updateDropdowns(){for(const toggleEl of this.el.querySelectorAll(".nav .dropdown-toggle")){Dropdown.getOrCreateInstance(toggleEl).update();}},_onCollapseShown(){this._updateDropdowns();},_onCollapseHidden(){this._updateDropdowns();},});__exports[Symbol.for("default")]={extraMenuUpdateCallbacks:extraMenuUpdateCallbacks,};return __exports;});;

/* /website/static/src/js/content/snippets.animation.js */
odoo.define('@website/js/content/snippets.animation',['@web/core/l10n/translation','@web/core/assets','@web/core/utils/functions','@web/core/utils/strings','@web/core/utils/timing','@web/legacy/js/core/class','@web/legacy/js/core/dom','@web/legacy/js/core/mixins','@web/legacy/js/public/public_widget','@website/js/utils','@web/core/utils/render','@web/core/browser/feature_detection','@web/core/ui/ui_service','@website/js/text_processing','@web/core/utils/ui'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{loadJS}=require("@web/core/assets");const{uniqueId}=require("@web/core/utils/functions");const{escape}=require("@web/core/utils/strings");const{debounce,throttleForAnimation}=require("@web/core/utils/timing");const Class=require("@web/legacy/js/core/class")[Symbol.for("default")];const dom=require("@web/legacy/js/core/dom")[Symbol.for("default")];const mixins=require("@web/legacy/js/core/mixins")[Symbol.for("default")];const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const wUtils=require("@website/js/utils")[Symbol.for("default")];const{renderToElement}=require("@web/core/utils/render");const{hasTouch}=require("@web/core/browser/feature_detection");const{SIZES,utils:uiUtils}=require("@web/core/ui/ui_service");const{applyTextHighlight,removeTextHighlight,switchTextHighlight,}=require("@website/js/text_processing");const{touching}=require("@web/core/utils/ui");window.requestAnimationFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame;window.cancelAnimationFrame=window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.msCancelAnimationFrame||window.oCancelAnimationFrame;if(!window.performance||!window.performance.now){window.performance={now:function(){return Date.now();}};}
publicWidget.Widget.include({disabledInEditableMode:true,edit_events:null,read_events:null,init:function(parent,options){this._super.apply(this,arguments);this.editableMode=this.options.editableMode||false;var extraEvents=this.editableMode?this.edit_events:this.read_events;if(extraEvents){this.events=Object.assign({},this.events||{},extraEvents);}},});var AnimationEffect=Class.extend(mixins.ParentedMixin,{init:function(parent,updateCallback,startEvents,$startTarget,options){mixins.ParentedMixin.init.call(this);this.setParent(parent);options=options||{};this._minFrameTime=1000/(options.maxFPS||100);this._updateCallback=updateCallback;this.startEvents=startEvents||'scroll';const modalEl=options.enableInModal?parent.target.closest('.modal'):null;const mainScrollingElement=modalEl?modalEl:$().getScrollingElement()[0];const mainScrollingTarget=$().getScrollingTarget(mainScrollingElement)[0];this.$startTarget=$($startTarget?$startTarget:this.startEvents==='scroll'?mainScrollingTarget:window);if(options.getStateCallback){this._getStateCallback=options.getStateCallback;}else if(this.startEvents==='scroll'&&this.$startTarget[0]===mainScrollingTarget){const $scrollable=this.$startTarget;this._getStateCallback=function(){return $scrollable.scrollTop();};}else if(this.startEvents==='resize'&&this.$startTarget[0]===window){this._getStateCallback=function(){return{width:window.innerWidth,height:window.innerHeight,};};}else{this._getStateCallback=function(){return undefined;};}
this.endEvents=options.endEvents||false;this.$endTarget=options.$endTarget?$(options.$endTarget):this.$startTarget;this._updateCallback=this._updateCallback.bind(parent);this._getStateCallback=this._getStateCallback.bind(parent);this._uid=uniqueId("_animationEffect");this.startEvents=_processEvents(this.startEvents,this._uid);if(this.endEvents){this.endEvents=_processEvents(this.endEvents,this._uid);}
function _processEvents(events,namespace){return events.split(" ").map((e)=>(e+="."+namespace)).join(" ");}},destroy:function(){mixins.ParentedMixin.destroy.call(this);this.stop();},start:function(){this._paused=false;this._rafID=window.requestAnimationFrame((function(t){this._update(t);this._paused=true;}).bind(this));if(this.endEvents){this.$startTarget.on(this.startEvents,(function(e){if(this._paused){setTimeout(()=>this.play.bind(this,e));}}).bind(this));this.$endTarget.on(this.endEvents,(function(){if(!this._paused){setTimeout(()=>this.pause.bind(this));}}).bind(this));}else{this.throttleOnStartEvents=throttleForAnimation(((e)=>{this.play(e);clearTimeout(pauseTimer);pauseTimer=setTimeout((()=>{this.pause();pauseTimer=null;}).bind(this),2000);}).bind(this));var pauseTimer=null;this.$startTarget.on(this.startEvents,this.throttleOnStartEvents);}},stop:function(){this.$startTarget.off(this.startEvents);if(this.endEvents){this.$endTarget.off(this.endEvents);}
this.pause();},play:function(e){this._newEvent=e;if(!this._paused){return;}
this._paused=false;this._rafID=window.requestAnimationFrame(this._update.bind(this));this._lastUpdateTimestamp=undefined;},pause:function(){if(this._paused){return;}
this._paused=true;window.cancelAnimationFrame(this._rafID);this._lastUpdateTimestamp=undefined;},_update:function(timestamp){if(this._paused){return;}
this._rafID=window.requestAnimationFrame(this._update.bind(this));var elapsedTime=0;if(this._lastUpdateTimestamp){elapsedTime=timestamp-this._lastUpdateTimestamp;if(elapsedTime<this._minFrameTime){return;}}
var animationState=this._getStateCallback(elapsedTime,this._newEvent);if(!this._newEvent&&animationState!==undefined&&JSON.stringify(animationState)===JSON.stringify(this._animationLastState)){return;}
this._animationLastState=animationState;this._updateCallback(this._animationLastState,elapsedTime,this._newEvent);this._lastUpdateTimestamp=timestamp;this._newEvent=undefined;},});var Animation=publicWidget.Widget.extend({maxFPS:100,effects:[],start:function(){this._prepareEffects();this._animationEffects.forEach((effect)=>{effect.start();});return this._super.apply(this,arguments);},_prepareEffects:function(){this._animationEffects=[];var self=this;this.effects.forEach((desc)=>{self._addEffect(self[desc.update],desc.startEvents,_findTarget(desc.startTarget),{getStateCallback:desc.getState&&self[desc.getState],endEvents:desc.endEvents||undefined,$endTarget:_findTarget(desc.endTarget),maxFPS:self.maxFPS,enableInModal:desc.enableInModal||undefined,});function _findTarget(selector){if(selector){if(selector==='selector'){return self.$el;}
return self.$(selector);}
return undefined;}});},_addEffect:function(updateCallback,startEvents,$startTarget,options){this._animationEffects.push(new AnimationEffect(this,updateCallback,startEvents,$startTarget,options));},});var registry=publicWidget.registry;registry.slider=publicWidget.Widget.extend({selector:'.carousel',disabledInEditableMode:false,edit_events:{'content_changed':'_onContentChanged',},start:function(){this.$('img').on('load.slider',()=>this._computeHeights());this._computeHeights();this.$el.carousel(this.editableMode?'pause':undefined);$(window).on('resize.slider',debounce(()=>this._computeHeights(),250));if(this.editableMode&&this.el.matches("section > .carousel")&&!this.options.wysiwyg.options.enableTranslation){this.controlEls=this.el.querySelectorAll(".carousel-control-prev, .carousel-control-next");const indicatorEls=this.el.querySelectorAll(".carousel-indicators > li");this.options.wysiwyg.odooEditor.observerUnactive("disable_controls");this.controlEls.forEach(controlEl=>controlEl.removeAttribute("data-bs-slide"));indicatorEls.forEach(indicatorEl=>indicatorEl.removeAttribute("data-bs-slide-to"));this.options.wysiwyg.odooEditor.observerActive("disable_controls");this.__onControlClick=this._onControlClick.bind(this);[...this.controlEls,...indicatorEls].forEach(controlEl=>{controlEl.addEventListener("mousedown",this.__onControlClick);});}
return this._super.apply(this,arguments);},destroy:function(){this._super.apply(this,arguments);this.$('img').off('.slider');this.$el.carousel('pause');this.$el.removeData('bs.carousel');this.options.wysiwyg&&this.options.wysiwyg.odooEditor.observerUnactive("destroy");this.$(".carousel-item").toArray().forEach((el)=>{$(el).css("min-height","");});this.options.wysiwyg&&this.options.wysiwyg.odooEditor.observerActive("destroy");$(window).off('.slider');this.$el.off('.slider');if(this.editableMode&&this.el.matches("section > .carousel")&&!this.options.wysiwyg.options.enableTranslation){const indicatorEls=this.el.querySelectorAll(".carousel-indicators > li");this.options.wysiwyg.odooEditor.observerUnactive("restore_controls");this.controlEls.forEach(controlEl=>{const direction=controlEl.classList.contains("carousel-control-prev")?"prev":"next";controlEl.setAttribute("data-bs-slide",direction);});indicatorEls.forEach((indicatorEl,i)=>indicatorEl.setAttribute("data-bs-slide-to",i));this.options.wysiwyg.odooEditor.observerActive("restore_controls");[...this.controlEls,...indicatorEls].forEach(controlEl=>{controlEl.removeEventListener("mousedown",this.__onControlClick);});}},_computeHeights:function(){var maxHeight=0;var $items=this.$('.carousel-item');this.options.wysiwyg&&this.options.wysiwyg.odooEditor.observerUnactive("_computeHeights");$items.css('min-height','');$items.toArray().forEach((el)=>{var $item=$(el);var isActive=$item.hasClass('active');$item.addClass('active');var height=$item.outerHeight();if(height>maxHeight){maxHeight=height;}
$item.toggleClass('active',isActive);});$items.css('min-height',maxHeight);this.options.wysiwyg&&this.options.wysiwyg.odooEditor.observerActive("_computeHeights");},_onContentChanged:function(ev){this._computeHeights();},_onControlClick(){this.el.querySelector(".carousel-item.active").click();},});registry.Parallax=Animation.extend({selector:'.parallax',disabledInEditableMode:false,effects:[{startEvents:'scroll',update:'_onWindowScroll',enableInModal:true,}],start:function(){this._rebuild();$(window).on('resize.animation_parallax',debounce(this._rebuild.bind(this),500));this.modalEl=this.$target[0].closest('.modal');if(this.modalEl){$(this.modalEl).on('shown.bs.modal.animation_parallax',()=>{this._rebuild();this.modalEl.dispatchEvent(new Event('scroll'));});}
return this._super.apply(this,arguments);},destroy:function(){this._super.apply(this,arguments);this._updateBgCss({transform:'',top:'',bottom:'',});$(window).off('.animation_parallax');if(this.modalEl){$(this.modalEl).off('.animation_parallax');}},_rebuild:function(){this.$bg=this.$('> .s_parallax_bg');this.speed=parseFloat(this.$el.attr('data-scroll-background-ratio')||0);var noParallaxSpeed=(this.speed===0||this.speed===1);if(noParallaxSpeed){this._updateBgCss({transform:'',top:'',bottom:'',});return;}
this.viewport=document.body.clientHeight-$('#wrapwrap').position().top;this.visibleArea=[this.$el.offset().top];this.visibleArea.push(this.visibleArea[0]+this.$el.innerHeight()+this.viewport);this.ratio=this.speed*(this.viewport/10);const absoluteRatio=Math.abs(this.ratio);this._updateBgCss({top:-absoluteRatio,bottom:-absoluteRatio,});},_updateBgCss(cssValues){if(!this.$bg){return;}
if(this.options.wysiwyg){this.options.wysiwyg.odooEditor.observerUnactive('_updateBgCss');}
this.$bg.css(cssValues);if(this.options.wysiwyg){this.options.wysiwyg.odooEditor.observerActive('_updateBgCss');}},_onWindowScroll:function(scrollOffset){if(this.speed===0||this.speed===1){return;}
var vpEndOffset=scrollOffset+this.viewport;if(vpEndOffset>=this.visibleArea[0]&&vpEndOffset<=this.visibleArea[1]){this._updateBgCss({'transform':'translateY('+_getNormalizedPosition.call(this,vpEndOffset)+'px)'});}
function _getNormalizedPosition(pos){var r=(pos-this.visibleArea[1])/(this.visibleArea[0]-this.visibleArea[1]);return Math.round(this.ratio*(2*r-1));}},});const MobileYoutubeAutoplayMixin={_setupAutoplay:function(src){let promise=Promise.resolve();this.isYoutubeVideo=src.indexOf('youtube')>=0;this.isMobileEnv=uiUtils.getSize()<=SIZES.LG&&hasTouch();if(this.isYoutubeVideo&&this.isMobileEnv&&!window.YT){const oldOnYoutubeIframeAPIReady=window.onYouTubeIframeAPIReady;promise=new Promise(resolve=>{window.onYouTubeIframeAPIReady=()=>{if(oldOnYoutubeIframeAPIReady){oldOnYoutubeIframeAPIReady();}
return resolve();};});loadJS('https://www.youtube.com/iframe_api');}
return promise;},_triggerAutoplay:function(iframeEl){if(this.isMobileEnv&&this.isYoutubeVideo){new window.YT.Player(iframeEl,{events:{onReady:ev=>ev.target.playVideo(),}});}},};registry.mediaVideo=publicWidget.Widget.extend(MobileYoutubeAutoplayMixin,{selector:'.media_iframe_video',start:function(){const proms=[this._super.apply(this,arguments)];let iframeEl=this.el.querySelector(':scope > iframe');if(!iframeEl){iframeEl=this._generateIframe();}
if(!iframeEl||!iframeEl.getAttribute('src')){return Promise.all(proms);}
proms.push(this._setupAutoplay(iframeEl.getAttribute('src')));return Promise.all(proms).then(()=>{this._triggerAutoplay(iframeEl);});},_generateIframe:function(){this.$el.empty();this.$el.append('<div class="css_editable_mode_display">&nbsp;</div>'+'<div class="media_iframe_video_size">&nbsp;</div>');var src=escape(this.$el.data('oe-expression')||this.$el.data('src'));var m=src.match(/^(?:https?:)?\/\/([^/?#]+)/);if(!m){return;}
var domain=m[1].replace(/^www\./,'');var supportedDomains=['youtu.be','youtube.com','youtube-nocookie.com','instagram.com','vine.co','player.vimeo.com','vimeo.com','dailymotion.com','player.youku.com','youku.com'];if(!supportedDomains.includes(domain)){return;}
const iframeEl=$('<iframe/>',{src:src,frameborder:'0',allowfullscreen:'allowfullscreen',"aria-label":_t("Media video"),})[0];this.$el.append(iframeEl);return iframeEl;},});registry.backgroundVideo=publicWidget.Widget.extend(MobileYoutubeAutoplayMixin,{selector:'.o_background_video',disabledInEditableMode:false,start:function(){var proms=[this._super(...arguments)];this.videoSrc=this.el.dataset.bgVideoSrc;this.iframeID=uniqueId("o_bg_video_iframe_");proms.push(this._setupAutoplay(this.videoSrc));if(this.isYoutubeVideo&&this.isMobileEnv&&!this.videoSrc.includes('enablejsapi=1')){this.videoSrc+='&enablejsapi=1';}
this.throttledUpdate=throttleForAnimation(()=>this._adjustIframe());var $dropdownMenu=this.$el.closest('.dropdown-menu');if($dropdownMenu.length){this.$dropdownParent=$dropdownMenu.parent();this.$dropdownParent.on("shown.bs.dropdown.backgroundVideo",this.throttledUpdate);}
$(window).on("resize."+this.iframeID,this.throttledUpdate);const $modal=this.$el.closest('.modal');if($modal.length){$modal.on('show.bs.modal',()=>{const videoContainerEl=this.el.querySelector('.o_bg_video_container');videoContainerEl.classList.add('d-none');});$modal.on('shown.bs.modal',()=>{this._adjustIframe();const videoContainerEl=this.el.querySelector('.o_bg_video_container');videoContainerEl.classList.remove('d-none');});}
return Promise.all(proms).then(()=>this._appendBgVideo());},destroy:function(){this._super.apply(this,arguments);if(this.$dropdownParent){this.$dropdownParent.off('.backgroundVideo');}
$(window).off('resize.'+this.iframeID);this.throttledUpdate.cancel();if(this.$bgVideoContainer){this.$bgVideoContainer.remove();}},_adjustIframe:function(){if(!this.$iframe){return;}
this.$iframe.removeClass('show');var wrapperWidth=this.$el.innerWidth();var wrapperHeight=this.$el.innerHeight();var relativeRatio=(wrapperWidth/wrapperHeight)/(16/9);var style={};if(relativeRatio>=1.0){style['width']='100%';style['height']=(relativeRatio*100)+'%';style['inset-inline-start']='0';style['inset-block-start']=(-(relativeRatio-1.0)/2*100)+'%';}else{style['width']=((1/relativeRatio)*100)+'%';style['height']='100%';style['inset-inline-start']=(-((1/relativeRatio)-1.0)/2*100)+'%';style['inset-block-start']='0';}
this.$iframe.css(style);void this.$iframe[0].offsetWidth;this.$iframe.addClass('show');},_appendBgVideo:function(){var $oldContainer=this.$bgVideoContainer||this.$('> .o_bg_video_container');this.$bgVideoContainer=$(renderToElement('website.background.video',{videoSrc:this.videoSrc,iframeID:this.iframeID,}));this.$iframe=this.$bgVideoContainer.find('.o_bg_video_iframe');this.$iframe.one('load',()=>{this.$bgVideoContainer.find('.o_bg_video_loading').remove();this._adjustIframe();});this.$bgVideoContainer.prependTo(this.$el);$oldContainer.remove();this._adjustIframe();this._triggerAutoplay(this.$iframe[0]);},});registry.socialShare=publicWidget.Widget.extend({selector:'.oe_social_share',events:{'mouseenter':'_onMouseEnter',},_bindSocialEvent:function(){this.$('.oe_social_facebook').click($.proxy(this._renderSocial,this,'facebook'));this.$('.oe_social_twitter').click($.proxy(this._renderSocial,this,'twitter'));this.$('.oe_social_linkedin').click($.proxy(this._renderSocial,this,'linkedin'));},_render:function(){this.$el.popover({content:renderToElement('website.social_hover',{medias:this.socialList}),placement:'bottom',container:this.$el,html:true,trigger:'manual',animation:false,}).popover("show");this.$el.off('mouseleave.socialShare').on('mouseleave.socialShare',function(){var self=this;setTimeout(function(){if(!$(".popover:hover").length){$(self).popover('dispose');}},200);});},_renderSocial:function(social){var url=this.$el.data('urlshare')||document.URL.split(/[?#]/)[0];url=encodeURIComponent(url);const titleParts=document.title.split(" | ");const title=titleParts[0];const hashtags=titleParts.length===1?` ${this.hashtags}`:` #${titleParts[1].replace(" ", "")} ${this.hashtags}`;var socialNetworks={'facebook':'https://www.facebook.com/sharer/sharer.php?u='+url,'twitter':'https://twitter.com/intent/tweet?original_referer='+url+'&text='+encodeURIComponent(title+hashtags+' - ')+url,'linkedin':'https://www.linkedin.com/sharing/share-offsite/?url='+url,};if(!Object.keys(socialNetworks).includes(social)){return;}
var wHeight=500;var wWidth=500;window.open(socialNetworks[social],'','menubar=no, toolbar=no, resizable=yes, scrollbar=yes, height='+wHeight+',width='+wWidth);},_onMouseEnter:function(){var social=this.$el.data('social');this.socialList=social?social.split(','):['facebook','twitter','linkedin'];this.hashtags=this.$el.data('hashtags')||'';this._render();this._bindSocialEvent();},});registry.anchorSlide=publicWidget.Widget.extend({selector:'a[href^="/"][href*="#"], a[href^="#"]',events:{'click':'_onAnimateClick',},async _scrollTo($el,scrollValue='true'){return dom.scrollTo($el[0],{duration:scrollValue==='true'?500:0,extraOffset:this._computeExtraOffset(),});},_computeExtraOffset(){return 0;},_onAnimateClick:function(ev){const ensureSlash=path=>path.endsWith("/")?path:path+"/";if(ensureSlash(this.el.pathname)!==ensureSlash(window.location.pathname)){return;}
if(this.el.pathname!==window.location.pathname){this.el.pathname=window.location.pathname;}
var hash=this.el.hash;if(!hash.length){return;}
hash='#'+$.escapeSelector(hash.substring(1));var $anchor=$(hash);const scrollValue=$anchor.attr('data-anchor');if(!$anchor.length||!scrollValue){return;}
const offcanvasEl=this.el.closest('.offcanvas.o_navbar_mobile');if(offcanvasEl&&offcanvasEl.classList.contains('show')){ev.preventDefault();Offcanvas.getInstance(offcanvasEl).hide();offcanvasEl.addEventListener('hidden.bs.offcanvas',()=>{this._manageScroll(hash,$anchor,scrollValue);},{once:true});}else{ev.preventDefault();this._manageScroll(hash,$anchor,scrollValue);}},_manageScroll(hash,$anchor,scrollValue="true"){if(hash==="#top"||hash==="#bottom"){dom.scrollTo(hash,{duration:500,extraOffset:this._computeExtraOffset(),});}else{this._scrollTo($anchor,scrollValue);}},});registry.FullScreenHeight=publicWidget.Widget.extend({selector:'.o_full_screen_height',disabledInEditableMode:false,start(){this.inModal=!!this.el.closest('.modal');if(this.$el.is(':not(:visible)')||this.$el.outerHeight()>this._computeIdealHeight()){this._adaptSize();$(window).on('resize.FullScreenHeight',debounce(()=>this._adaptSize(),250));}
return this._super(...arguments);},destroy(){this._super(...arguments);$(window).off('.FullScreenHeight');this.el.style.setProperty('min-height','');},_adaptSize(){const height=this._computeIdealHeight();this.el.style.setProperty('min-height',`${height}px`,'important');},_computeIdealHeight(){const windowHeight=$(window).outerHeight();if(this.inModal){return(windowHeight-$('#wrapwrap').position().top);}
const firstContentEl=$('#wrapwrap > main > :first-child')[0];const modalOpen=document.body.classList.contains("modal-open");document.body.classList.remove("modal-open");const mainTopPos=firstContentEl.getBoundingClientRect().top+$(firstContentEl.parentNode).closestScrollable()[0].scrollTop;document.body.classList.toggle("modal-open",modalOpen);return(windowHeight-mainTopPos);},});registry.ScrollButton=registry.anchorSlide.extend({selector:'.o_scroll_button',_onAnimateClick:function(ev){ev.preventDefault();const currentSectionEl=this.el.closest('section');let nextEl=currentSectionEl.nextElementSibling;while(nextEl){if($(nextEl).is(':visible')){this._scrollTo($(nextEl));return;}
nextEl=nextEl.nextElementSibling;}},});registry.FooterSlideout=publicWidget.Widget.extend({selector:'#wrapwrap:has(.o_footer_slideout)',disabledInEditableMode:false,async start(){const $main=this.$('> main');const slideoutEffect=$main.outerHeight()>=$(window).outerHeight();this.el.classList.toggle('o_footer_effect_enable',slideoutEffect);this.__pixelEl=document.createElement('div');this.__pixelEl.style.width=`1px`;this.__pixelEl.style.height=`1px`;this.__pixelEl.style.marginTop=`-1px`;if(/^((?!chrome|android).)*safari/i.test(navigator.userAgent)){this.__pixelEl.style.backgroundColor="transparent";this.__pixelEl.style.backgroundAttachment="fixed";this.__pixelEl.style.backgroundImage="url(/website/static/src/img/website_logo.svg)";}
this.el.appendChild(this.__pixelEl);return this._super(...arguments);},destroy(){this._super(...arguments);this.el.classList.remove('o_footer_effect_enable');this.__pixelEl.remove();},});registry.TopMenuCollapse=publicWidget.Widget.extend({selector:"header #top_menu_collapse",async start(){this.throttledResize=throttleForAnimation(()=>this._onResize());window.addEventListener("resize",this.throttledResize);return this._super(...arguments);},destroy(){this._super(...arguments);window.removeEventListener("resize",this.throttledResize);},_onResize(){if(this.el.classList.contains("show")){const togglerEl=this.el.closest("nav").querySelector(".navbar-toggler");if(getComputedStyle(togglerEl).display==="none"){this.$el.collapse("hide");}}},});registry.BottomFixedElement=publicWidget.Widget.extend({selector:'#wrapwrap',async start(){this.$scrollingElement=$().getScrollingElement();this.$scrollingTarget=$().getScrollingTarget(this.$scrollingElement);this.__hideBottomFixedElements=debounce(()=>this._hideBottomFixedElements(),100);this.$scrollingTarget.on('scroll.bottom_fixed_element',this.__hideBottomFixedElements);$(window).on('resize.bottom_fixed_element',this.__hideBottomFixedElements);return this._super(...arguments);},destroy(){this._super(...arguments);this.$scrollingElement.off('.bottom_fixed_element');this.$scrollingTarget.off('.bottom_fixed_element');$(window).off('.bottom_fixed_element');this._restoreBottomFixedElements($('.o_bottom_fixed_element'));},_hideBottomFixedElements(){const $bottomFixedElements=$('.o_bottom_fixed_element');if(!$bottomFixedElements.length){return;}
if(this.el.querySelector('.s_popup_no_backdrop.show')){for(const el of $bottomFixedElements){el.classList.add('o_bottom_fixed_element_hidden');}
return;}
this._restoreBottomFixedElements($bottomFixedElements);if((this.$scrollingElement[0].offsetHeight+this.$scrollingElement[0].scrollTop)>=(this.$scrollingElement[0].scrollHeight-2)){const buttonEls=[...this.$('a:visible, .btn:visible')];for(const el of $bottomFixedElements){const elRect=el.getBoundingClientRect();const hiddenButtonEl=touching(buttonEls,{top:elRect.top,right:elRect.right,bottom:elRect.bottom,left:elRect.left,width:elRect.width,height:elRect.height,x:elRect.x,y:elRect.y,});if(hiddenButtonEl){if(el.classList.contains('o_bottom_fixed_element_move_up')){el.style.marginBottom=window.innerHeight-hiddenButtonEl.getBoundingClientRect().top+5+'px';}else{el.classList.add('o_bottom_fixed_element_hidden');}}}}},_restoreBottomFixedElements($elements){$elements.removeClass('o_bottom_fixed_element_hidden');$elements.filter('.o_bottom_fixed_element_move_up').css('margin-bottom','');},});registry.WebsiteAnimate=publicWidget.Widget.extend({selector:'#wrapwrap',disabledInEditableMode:false,offsetRatio:0.3,offsetMin:10,start(){this.lastScroll=0;this.$scrollingElement=$().getScrollingElement();this.$scrollingTarget=$().getScrollingTarget(this.$scrollingElement);this.$animatedElements=this.$('.o_animate');const couldOverflowBecauseOfSafariBug=[...this.$animatedElements].some(el=>{return window.getComputedStyle(el).transform!=='none';});this.forceOverflowXYHidden=false;if(couldOverflowBecauseOfSafariBug){this._toggleOverflowXYHidden(true);this.forceOverflowXYHidden=true;}
this.$animatedElements.toArray().forEach((el)=>{if(el.closest('.dropdown')){el.classList.add('o_animate_in_dropdown');return;}
if(!el.classList.contains('o_animate_on_scroll')){this._resetAnimation($(el));}});this.$animatedElements.css("visibility","visible");this.__onScrollWebsiteAnimate=throttleForAnimation(this._onScrollWebsiteAnimate.bind(this));this.$scrollingTarget[0].addEventListener('scroll',this.__onScrollWebsiteAnimate,{capture:true});$(window).on('resize.o_animate, shown.bs.modal.o_animate, slid.bs.carousel.o_animate, shown.bs.tab.o_animate, shown.bs.collapse.o_animate',()=>{this.windowsHeight=$(window).height();this._scrollWebsiteAnimate(this.$scrollingElement[0]);}).trigger("resize");return this._super(...arguments);},destroy(){this._super(...arguments);this.$('.o_animate').removeClass('o_animating o_animated o_animate_preview o_animate_in_dropdown').css({'animation-name':'','animation-play-state':'','visibility':'',});$(window).off('.o_animate');this.__onScrollWebsiteAnimate.cancel();this.$scrollingTarget[0].removeEventListener('scroll',this.__onScrollWebsiteAnimate,{capture:true});this.$scrollingElement[0].classList.remove('o_wanim_overflow_xy_hidden');},_startAnimation($el){setTimeout(()=>{this._toggleOverflowXYHidden(true);$el.css({"animation-play-state":"running"}).addClass("o_animating").one('webkitAnimationEnd oanimationend msAnimationEnd animationend',()=>{$el.addClass("o_animated").removeClass("o_animating");this._toggleOverflowXYHidden(false);$(window).trigger("resize");});});},_resetAnimation($el){const animationName=$el.css("animation-name");$el.css({"animation-name":"dummy-none","animation-play-state":""}).removeClass("o_animated o_animating");this._toggleOverflowXYHidden(false);void $el[0].offsetWidth;$el.css({'animation-name':animationName,'animation-play-state':'paused'});},_toggleOverflowXYHidden(add){if(this.forceOverflowXYHidden){return;}
if(add){this.$scrollingElement[0].classList.add('o_wanim_overflow_xy_hidden');}else if(!this.$scrollingElement.find('.o_animating').length){this.$scrollingElement[0].classList.remove('o_wanim_overflow_xy_hidden');}},_getElementOffsetTop(el,topEl){var top=0;do{top+=el.offsetTop||0;el=el.offsetParent;if(topEl&&el===topEl){return top;}}while(el);return top;},_scrollWebsiteAnimate(el){this.$('.o_animate:not(.o_animate_in_dropdown)').toArray().forEach((el)=>{const $el=$(el);const elHeight=el.offsetHeight;const animateOnScroll=el.classList.contains('o_animate_on_scroll');let elOffset=animateOnScroll?0:Math.max((elHeight*this.offsetRatio),this.offsetMin);const state=$el.css("animation-play-state");const closestModal=$el.closest(".modal:visible")[0];let scrollTop=this.$scrollingElement[0].scrollTop;if(closestModal){scrollTop=closestModal.classList.contains("s_popup_no_backdrop")?closestModal.querySelector(".modal-content").scrollTop:closestModal.scrollTop;}
const elTop=this._getElementOffsetTop(el)-scrollTop;let visible;const footerEl=el.closest('.o_footer_slideout');const wrapEl=this.el;if(footerEl&&wrapEl.classList.contains('o_footer_effect_enable')){const actualScroll=wrapEl.scrollTop+this.windowsHeight;const totalScrollHeight=wrapEl.scrollHeight;const heightFromFooter=this._getElementOffsetTop(el,footerEl);visible=actualScroll>=totalScrollHeight-heightFromFooter-elHeight+elOffset;}else{visible=this.windowsHeight>(elTop+elOffset)&&0<(elTop+elHeight-elOffset);}
if(animateOnScroll){if(visible){const start=100/(parseFloat(el.dataset.scrollZoneStart)||1);const end=100/(parseFloat(el.dataset.scrollZoneEnd)||1);const out=el.classList.contains('o_animate_out');const ratio=(out?elTop+elHeight:elTop)/(this.windowsHeight-(this.windowsHeight/start));const duration=parseFloat(window.getComputedStyle(el).animationDuration);const delay=(ratio-1)*(duration*end);el.style.animationDelay=(out?-duration-delay:delay)+"s";el.classList.add('o_animating');this._toggleOverflowXYHidden(true);}else if(el.classList.contains('o_animating')){el.classList.remove('o_animating');this._toggleOverflowXYHidden(false);}}else{if(visible&&state==='paused'){$el.addClass('o_visible');this._startAnimation($el);}else if(!visible&&$el.hasClass('o_animate_both_scroll')&&state==='running'){$el.removeClass('o_visible');this._resetAnimation($el);}}});},_onScrollWebsiteAnimate(ev){this._scrollWebsiteAnimate(this.$scrollingElement[0]);},});registry.ImagesLazyLoading=publicWidget.Widget.extend({selector:'#wrapwrap',start(){const imgEls=this.el.querySelectorAll('img[loading="lazy"]');for(const imgEl of imgEls){this._updateImgMinHeight(imgEl);wUtils.onceAllImagesLoaded($(imgEl)).then(()=>{if(this.isDestroyed()){return;}
this._restoreImage(imgEl);});}
return this._super(...arguments);},destroy(){this._super(...arguments);const imgEls=this.el.querySelectorAll('img[data-lazy-loading-initial-min-height]');for(const imgEl of imgEls){this._restoreImage(imgEl);}},_restoreImage(imgEl){this._updateImgMinHeight(imgEl,true);},_updateImgMinHeight(imgEl,reset=false){if(this.options.wysiwyg){this.options.wysiwyg.odooEditor.observerUnactive('_updateImgMinHeight');}
if(reset){imgEl.style.minHeight=imgEl.dataset.lazyLoadingInitialMinHeight;delete imgEl.dataset.lazyLoadingInitialMinHeight;}else{imgEl.dataset.lazyLoadingInitialMinHeight=imgEl.style.minHeight;imgEl.style.minHeight='1px';}
if(this.options.wysiwyg){this.options.wysiwyg.odooEditor.observerActive('_updateImgMinHeight');}},});registry.ZoomedBackgroundShape=publicWidget.Widget.extend({selector:'.o_we_shape',disabledInEditableMode:false,start(){this._onBackgroundShapeResize();this.throttledShapeResize=throttleForAnimation(()=>this._onBackgroundShapeResize());window.addEventListener('resize',this.throttledShapeResize);return this._super(...arguments);},destroy(){this._updateShapePosition();this.throttledShapeResize.cancel();window.removeEventListener('resize',this.throttledShapeResize);this._super(...arguments);},_updateShapePosition(offset=''){this.el.style.left=offset;this.el.style.right=offset;},_onBackgroundShapeResize(){this._updateShapePosition();let decimalPart=this.el.getBoundingClientRect().width%1;decimalPart=Math.round((decimalPart+Number.EPSILON)*100)/100;if(decimalPart>0){let offset=(decimalPart<0.5?decimalPart:decimalPart-1)/2;this._updateShapePosition(offset+'px');}},});registry.ImageShapeHoverEffet=publicWidget.Widget.extend({selector:"img[data-hover-effect]",disabledInEditableMode:false,events:{"mouseenter":"_onMouseEnter","mouseleave":"_onMouseLeave",},init(){this._super(...arguments);this.lastMouseEvent=Promise.resolve();},start(){this._super(...arguments);this.originalImgSrc=this.el.getAttribute('src');},destroy(){this._super(...arguments);if(this.el.dataset.originalSrcBeforeHover&&!this.el.classList.contains("o_modified_image_to_save")){this.el.src=this.el.dataset.originalSrcBeforeHover;}else if(this.originalImgSrc&&(this.lastImgSrc===this.el.getAttribute("src"))){this.el.src=this.originalImgSrc;}
delete this.el.dataset.originalSrcBeforeHover;},_onMouseEnter(){if(!this.originalImgSrc||!this.$target[0].dataset.hoverEffect){return;}
this.lastMouseEvent=this.lastMouseEvent.then(()=>new Promise((resolve)=>{if(!this.svgInEl){fetch(this.el.src).then(response=>response.text()).then(text=>{const parser=new DOMParser();const result=parser.parseFromString(text,"text/xml");const svg=result.getElementsByTagName("svg")[0];this.svgInEl=svg;if(!this.svgInEl){resolve();return;}
const animateEls=this.svgInEl.querySelectorAll("#hoverEffects animateTransform, #hoverEffects animate");animateEls.forEach(animateTransformEl=>{animateTransformEl.removeAttribute("begin");});this._setImgSrc(this.svgInEl,resolve);}).catch(()=>{});}else{this._setImgSrc(this.svgInEl,resolve);}}));},_onMouseLeave(){this.lastMouseEvent=this.lastMouseEvent.then(()=>new Promise((resolve)=>{if(!this.originalImgSrc||!this.svgInEl||!this.$target[0].dataset.hoverEffect){resolve();return;}
if(!this.svgOutEl){this.svgOutEl=this.svgInEl.cloneNode(true);const animateTransformEls=this.svgOutEl.querySelectorAll("#hoverEffects animateTransform, #hoverEffects animate");animateTransformEls.forEach(animateTransformEl=>{let valuesValue=animateTransformEl.getAttribute("values");valuesValue=valuesValue.split(";").reverse().join(";");animateTransformEl.setAttribute("values",valuesValue);});}
this._setImgSrc(this.svgOutEl,resolve);}));},_setImgSrc(svg,resolve){const previousRandomClass=[...svg.classList].find(cl=>cl.startsWith("o_shape_anim_random_"));svg.classList.remove(previousRandomClass);svg.classList.add("o_shape_anim_random_"+Date.now());const svg64=btoa(new XMLSerializer().serializeToString(svg));const preloadedImg=new Image();preloadedImg.src=`data:image/svg+xml;base64,${svg64}`;preloadedImg.onload=()=>{if(this.isDestroyed()){resolve();return;}
this.options.wysiwyg&&this.options.wysiwyg.odooEditor.observerUnactive("setImgHoverEffectSrc");if(this.editableMode&&!this.el.dataset.originalSrcBeforeHover){this.el.dataset.originalSrcBeforeHover=this.originalImgSrc;}
this.el.src=preloadedImg.getAttribute('src');this.options.wysiwyg&&this.options.wysiwyg.odooEditor.observerActive("setImgHoverEffectSrc");this.lastImgSrc=preloadedImg.getAttribute('src');this.el.onload=()=>{resolve();};};},});registry.TextHighlight=publicWidget.Widget.extend({selector:'#wrapwrap',disabledInEditableMode:false,async start(){this.observerLock=new Map();this.resizeObserver=new window.ResizeObserver(entries=>{if(this.isDestroyed()){return;}
window.requestAnimationFrame(()=>{const textHighlightEls=new Set();entries.forEach(entry=>{const target=entry.target;if(this.observerLock.get(target)){return this.observerLock.set(target,false);}
const topTextEl=target.closest(".o_text_highlight");for(const el of topTextEl?[topTextEl]:target.querySelectorAll(":scope .o_text_highlight")){textHighlightEls.add(el);}});textHighlightEls.forEach(textHighlightEl=>{for(const textHighlightItemEl of this._getHighlightItems(textHighlightEl)){this.resizeObserver.unobserve(textHighlightItemEl);}
switchTextHighlight(textHighlightEl);});});});this.el.addEventListener("text_highlight_added",this._onTextHighlightAdded.bind(this));this.el.addEventListener("text_highlight_remove",this._onTextHighlightRemove.bind(this));for(const textEl of this.el.querySelectorAll(".o_text_highlight")){applyTextHighlight(textEl);}
return this._super(...arguments);},destroy(){for(const textHighlightEl of this.el.querySelectorAll(".o_text_highlight")){removeTextHighlight(textHighlightEl);}
this._super(...arguments);},_adaptOnFontsLoading(){this.observerLocked=new Map();this.resizeObserver=new window.ResizeObserver(entries=>{if(this.isDestroyed()){return;}
window.requestAnimationFrame(()=>{const topTextEls=new Set();entries.forEach(entry=>{const target=entry.target;if(this.observerLocked.get(target)){return this.observerLocked.set(target,false);}
const topTextEl=target.closest(".o_text_highlight");if(topTextEl){topTextEls.add(topTextEl);this.resizeObserver.unobserve(target);}});topTextEls.forEach(async topTextEl=>{[...topTextEl.querySelectorAll(".o_text_highlight_item")].forEach(unit=>{this.observerLocked.delete(unit);});switchTextHighlight(topTextEl);this._lockHighlightObserver(topTextEl);this._observeHighlightResize(topTextEl);});});});this._observeHighlightResize();this._lockHighlightObserver();},_closestToObserve(el){if(el===this.el||!el){return null;}
if(window.getComputedStyle(el).display!=="inline"){return el;}
return this._closestToObserve(el.parentElement);},_getHighlightItems(el=this.el){return el.querySelectorAll(":scope .o_text_highlight_item");},_getObservedEls(topTextEl){const closestToObserve=this._closestToObserve(topTextEl);return[...(closestToObserve?[closestToObserve]:[]),...this._getHighlightItems(topTextEl),];},_observeHighlightResize(topTextEl){for(const highlightItemEl of this._getObservedEls(topTextEl)){this.resizeObserver.observe(highlightItemEl);}},_lockHighlightObserver(topTextEl){for(const targetEl of this._getObservedEls(topTextEl)){this.observerLock.set(targetEl,true);}},_onTextHighlightAdded({target}){this._lockHighlightObserver(target);this._observeHighlightResize(target);},_onTextHighlightRemove({target}){for(const highlightItemEl of this._getHighlightItems(target)){this.observerLock.delete(highlightItemEl);}},});__exports[Symbol.for("default")]={Widget:publicWidget.Widget,Animation:Animation,registry:registry,Class:Animation,};return __exports;});;

/* /website/static/src/js/show_password.js */
odoo.define('@website/js/show_password',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.ShowPassword=publicWidget.Widget.extend({selector:'#showPass',events:{'mousedown':'_onShowText','touchstart':'_onShowText',},destroy:function(){this._super(...arguments);$('body').off(".ShowPassword");},_onShowPassword:function(){this.$el.closest('.input-group').find('#password').attr('type','password');},_onShowText:function(){$('body').one('mouseup.ShowPassword touchend.ShowPassword',this._onShowPassword.bind(this));this.$el.closest('.input-group').find('#password').attr('type','text');},});__exports[Symbol.for("default")]=publicWidget.registry.ShowPassword;return __exports;});;

/* /website/static/src/js/post_link.js */
odoo.define('@website/js/post_link',['@web/legacy/js/public/public_widget','@website/js/utils'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const wUtils=require("@website/js/utils")[Symbol.for("default")];publicWidget.registry.postLink=publicWidget.Widget.extend({selector:'.post_link',events:{'click':'_onClickPost',},start(){this.el.classList.add('o_post_link_js_loaded');return this._super(...arguments);},destroy(){this._super(...arguments);this.el.classList.remove('o_post_link_js_loaded');},_onClickPost:function(ev){ev.preventDefault();const url=this.el.dataset.post||this.el.href;let data={};for(let[key,value]of Object.entries(this.el.dataset)){if(key.startsWith('post_')){data[key.slice(5)]=value;}}
wUtils.sendRequest(url,data);},});return __exports;});;

/* /website/static/src/js/plausible.js */
odoo.define('@website/js/plausible',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];publicWidget.registry.o_plausible_push=publicWidget.Widget.extend({selector:'.js_plausible_push',start(){window.plausible=window.plausible||function(){(window.plausible.q=window.plausible.q||[]).push(arguments);};this._push();return this._super(...arguments);},_push(){const evName=this.$el.data('event-name').toString();const evParams=this.$el.data('event-params')||{};window.plausible(evName,{props:evParams});},});return __exports;});;

/* /website/static/src/js/website_controller_page_listing_layout.js */
odoo.define('@website/js/website_controller_page_listing_layout',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.WebsiteControllerPageListingLayout=publicWidget.Widget.extend({selector:".o_website_listing_layout",disabledInEditableMode:true,events:{"change .listing_layout_switcher input":"_onApplyLayoutChange",},init(parent,options){this._super(parent,options);this.rpc=this.bindService("rpc");},_onApplyLayoutChange(ev){const wysiwyg=this.options.wysiwyg;if(wysiwyg){wysiwyg.odooEditor.observerUnactive("_onApplyLayoutChange");}
const clickedValue=ev.target.value;const isList=clickedValue==="list";if(!this.editableMode){this.rpc("/website/save_session_layout_mode",{layout_mode:isList?"list":"grid",view_id:document.querySelector(".listing_layout_switcher").getAttribute("data-view-id"),});}
const activeClasses=ev.target.parentElement.dataset.activeClasses.split(" ");ev.target.parentElement.querySelectorAll(".btn").forEach((btn)=>{activeClasses.map((c)=>btn.classList.toggle(c));});const el=document.querySelector(isList?".o_website_grid":".o_website_list");this._toggle_view_mode(el,isList);if(wysiwyg){wysiwyg.odooEditor.observerActive("_onApplyLayoutChange");}},_toggle_view_mode(el,isList){if(el){el.classList.toggle("o_website_list",isList);el.classList.toggle("o_website_grid",!isList);const classList=isList?"":"col-lg-3 col-md-4 col-sm-6 px-2 col-xs-12";[...document.querySelectorAll(".o_website_list > div, .o_website_grid > div")].forEach((card)=>{card.classList=classList;});}}});return __exports;});;

/* /website/static/src/js/user_custom_javascript.js */
odoo.define('@website/js/user_custom_javascript',['@web/core/confirmation_dialog/confirmation_dialog','@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};return __exports;});;

/* /website/static/src/js/http_cookie.js */
odoo.define('@website/js/http_cookie',['@web/core/browser/cookie','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{cookie}=require("@web/core/browser/cookie");const{patch}=require("@web/core/utils/patch");patch(cookie,{isAllowedCookie(type){if(type==="optional"){if(!document.getElementById("cookies-consent-essential")){return true;}
const consents=JSON.parse(cookie.get("website_cookies_bar")||"{}");if(typeof consents!=="object"){cookie.delete("website_cookies_bar");return false;}
if("optional"in consents){return consents["optional"];}
return false;}
return true;},set(key,value,ttl,type="required"){super.set(key,value,this.isAllowedCookie(type)?ttl:0);},});return __exports;});;

/* /website/static/src/js/text_processing.js */
odoo.define('@website/js/text_processing',['@web/core/utils/ui','@web_editor/js/editor/odoo-editor/src/utils/utils'],function(require){'use strict';let __exports={};const{isVisible}=require("@web/core/utils/ui");const OdooEditorLib=require("@web_editor/js/editor/odoo-editor/src/utils/utils");const _textHighlightFactory={underline:targetEl=>{return drawPath(targetEl,{mode:"line"});},freehand_1:targetEl=>{const template=(w,h)=>[`M 0,${h * 1.1} C ${w / 8},${h * 1.05} ${w / 4},${h} ${w},${h}`];return drawPath(targetEl,{mode:"free",template});},freehand_2:targetEl=>{const template=(w,h)=>[`M181.27 13.873c-.451-1.976-.993-3.421-1.072-4.9-.125-2.214-.61-4.856.384-6.539.756-1.287 3.636-2.055 5.443-1.852 3.455.395 7.001 1.231`+` 10.14 2.676 1.728.802 3.174 3.06 3.817 4.98.237.712-1.953 2.824-3.399 3.4-2.766 1.095-5.748 1.75-8.706 2.179-2.394.339-4.879.068-6.584.068l-.023-.012ZM8.416 3.90`+`2c3.862.26 7.78.249 11.574.926 1.65.294 3.027 2.033 4.54 3.117-1.095 1.186-1.987 2.982-3.343 3.456a67.118 67.118 0 0 1-11.19 2.823c-3.253.53-6.494-.339-8.617-2.98`+`1C.364 9.978-.302 7.686.138 6.263c.361-1.152 2.54-2 4.077-2.44 1.287-.372 2.789.046 4.2.102v-.023Zm154.267 9.983c-4.291-.305-8.153-1.58-9.915-5.623-.745-1.694-.39`+`5-4.382.474-6.121 1.073-2.168 3.512-1.965 5.613-1.005 2.541 1.174 5.251 2.157 7.509 3.76 1.502 1.073 3.557 3.445 3.207 4.574-.519 1.694-2.857 2.913-4.562 4.133-.5`+`76.406-1.592.203-2.326.282ZM72.58 17.42c-2.733-1.807-5.307-3.004-7.137-4.913-.892-.925-.892-3.376-.361-4.776.407-1.05 2.304-2.112 3.546-2.135 3.602-.056 7.238.215`+` 10.818.723 3.828.542 5.15 4.1 2.213 6.539-2.439 2.021-5.77 2.958-9.079 4.562Zm30.795-.802c-2.507-1.536-5.228-2.823-7.397-4.743-.925-.813-1.377-3.297-.813-4.359.6`+`78-1.265 2.677-2.507 4.11-2.518 3.016-.023 6.155.418 9.001 1.389 1.412.485 3.173 2.552 3.185 3.907 0 1.57-1.423 3.557-2.801 4.619-1.152.892-3.139.711-4.743 1.005-`+`.181.226-.35.463-.531.689l-.011.01Zm-59.704-1.457c-2.066-1.163-4.788-2.224-6.82-4.054-.915-.824-1.04-3.478-.407-4.765.486-.983 2.722-1.559 4.156-1.502 2.676.101 5`+`.398.542 7.95 1.332 1.457.452 3.523 1.75 3.681 2.891.18 1.31-1.13 3.309-2.383 4.201-1.411 1.005-3.466 1.118-6.188 1.886l.011.011Zm88.489-1.863c-2.643-1.48-5.567-2`+`.62-7.803-4.574-1.005-.88-1.31-3.692-.667-5.002.509-1.04 2.982-1.615 4.529-1.513 2.032.135 4.054 1.027 6.007 1.772 2.485.95 5.026 2.236 4.382 5.455-.644 3.15-3.49`+` 2.947-5.963 3.004-.169.293-.327.575-.496.87l.011-.012Z`];return drawPath(targetEl,{mode:"fill",template,SVGWidth:200,SVGHeight:18,position:"bottom"});},freehand_3:targetEl=>{const template=(w,h)=>[`M189.705 18.285c-3.99.994-7.968 2.015-11.958 2.972-1.415.344-2.926 1.008-4.278.727-6.305-1.327-12.568-3.036-18.874-4.376-1.995-.42-4.2`+`46-.701-6.133-.038-5.867 2.067-11.54 2.386-17.374-.242-1.491-.676-3.56-.421-5.125.217-5.523 2.22-10.789 3.597-16.494.127-1.64-.995-4.675-.038-6.584 1.148-6.102 3.`+`789-12.01 4.414-18.198.434-.998-.638-2.681-.638-3.754-.115-6.852 3.355-13.404 2.858-20.043-1.008-1.5-.867-4.02-.6-5.608.307-7.528 4.35-14.842 5.702-22.07-.638-2.1`+`44-1.875-3.71-.37-5.394 1.046-4.622 3.89-9.565 6.327-15.367 4.286C6.338 20.989.505 13.067.022 5.949-.085 4.38.194 1.753.955 1.332 2.253.617 4.537.553 5.588 1.51 7`+`.55 3.27 9.18 5.77 10.52 8.296c2.82 5.269 4.15 5.766 8.504 2.156 1.555-1.288 2.992-2.768 4.396-4.286 4.022-4.311 7.143-4.465 11.26-.472 7.068 6.837 8.226 7.067 15`+`.979 1.314 3.721-2.755 7.206-2.653 10.627.128 4.987 4.056 9.791 4.49 14.853.191 2.702-2.296 5.78-2.296 8.45.115 4.29 3.89 8.45 3.33 12.719.166.847-.638 1.705-1.26`+`3 2.552-1.914 3.035-2.309 6.048-2.5 9.019.166 3.453 3.087 7.12 3.15 10.616.472 4.107-3.138 7.85-3.342 12.16-.306 3.668 2.59 7.83 1.964 11.594-.255 3.935-2.322 7.6`+`67-2.488 11.409.408.365.28.794.612 1.213.65 6.799.549 13.522 3.394 20.428.779 1.887-.715 3.914-1.034 5.899-1.148 3.313-.192 6.659-.358 9.941 0 1.993.23 4.354.905 `+`5.737 2.436 1.308 1.429 2.113 4.235 2.123 6.442.022 3.023-2.424 3.431-4.472 3.597-1.887.153-3.796.038-5.695.038-.053-.216-.106-.446-.16-.663l.032-.025Z`];return drawPath(targetEl,{mode:"fill",template,SVGWidth:200,SVGHeight:24,position:"bottom"});},double:targetEl=>{const template=(w,h)=>[`M 0,${h * 0.9} h ${w}`,`M 0,${h * 1.1} h ${w}`,];return drawPath(targetEl,{mode:"free",template});},wavy:targetEl=>{const template=(w,h)=>[`c ${w / 4},0 ${w / 4},-${h / 2} ${w / 2},-${h / 2}`+`c ${w / 4},0 ${w / 4},${h / 2} ${w / 2},${h / 2}`];return drawPath(targetEl,{mode:"pattern",template});},circle_1:targetEl=>{const template=(w,h)=>[`M ${w / 2.88},${h / 1.1} C ${w / 1.1},${h / 1.05} ${w * 1.05},${h / 1.1} ${w * 1.023},${h / 2.32}`+`C ${w}, ${h / 14.6} ${w / 1.411},0 ${w / 2},0 S -2,${h / 14.6} -2,${h / 2.2}`+`S ${w / 4.24},${h} ${w / 1.36},${h * 1.04}`];return drawPath(targetEl,{mode:"free",template});},circle_2:targetEl=>{const template=(w,h)=>[`M112.58 21.164h18.516c-.478-.176-1.722-.64-2.967-1.105.101-.401.214-.803.315-1.192 12.255 2.912 24.561 5.573 36.716 8.823 5.896 1.582 `+`11.628 3.967 17.171 6.527 10.433 4.832 14.418 14.22 16.479 24.739.377 1.92.566 3.878.83 5.823 2.212 15.94-5.858 23.986-21.595 33.813-.993.615-2.288.79-3.181 1.494`+`-14.229 11.308-31.412 14.32-48.608 17.107-29.01 4.694-57.431 2.209-84.91-8.372-8.145-3.138-16.164-6.853-23.706-11.22C6.176 90.986 1.16 80.053.193 67.25c-1.798-23.`+`809 9.025-42.485 30.356-53.304C44.678 6.793 59.8 3.367 75.45 2.375 90.583 1.42 105.793.379 120.927.78c16.089.427 32.041 3.05 46.911 9.84 2.074.941 3.67 2.912 4.91`+`5 5.083-9.73-1.443-19.433-2.987-29.175-4.305-4.89-.665-9.842-1.067-14.77-1.33-23.82-1.28-47.376.514-70.391 7.003a133.771 133.771 0 0 0-22.639 8.648c-17.9 8.786-27`+`.616 26.935-25.567 46.364.666 6.263 3.507 11.133 9.05 14.308 26.862 15.401 55.748 21.965 86.645 19.819 15.561-1.08 31.01-2.787 45.767-8.284 11.099-4.142 21.658-9.`+`25 30.595-17.195 9.779-8.698 11.715-18.55 5.669-30.249-1.131-2.196-3.256-4.079-5.33-5.56-7.981-5.736-17.773-7.48-26.459-11.534-13.249-6.175-27.541-6.916-41.343-10`+`.167-.817-.188-1.571-.64-2.35-.966.037-.364.088-.728.125-1.092Z`];return drawPath(targetEl,{mode:"fill",template,SVGWidth:200,SVGHeight:120});},circle_3:targetEl=>{const template=(w,h)=>[`M78.653 89.204c-14.815 0-29.403-1.096-43.354-4.698-5.227-1.346-10.407-3.069-14.997-5.199-22.996-10.649-27.04-28.502-9.135-43.035 12.18`+`-9.866 26.813-18.04 43.355-24.242C88.515-.718 124.19-3.725 161.228 4.889c13.224 3.07 24.449 8.268 31.902 16.662 8.862 9.992 9.453 20.422 0 30.068-5.817 5.889-13.2`+`24 11.37-21.359 15.786-27.176 14.752-58.579 21.518-93.072 21.8h-.046Zm3.5-4.228c4.408-.282 11.725-.47 18.86-1.253 30.357-3.351 57.579-11.432 79.211-26.842 5.362-3`+`.82 10.134-8.832 12.27-13.875 2.545-5.982 5.817-13.311-6.226-17.352-.454-.156-.727-.563-1.045-.845-10.771-9.146-25.086-14.157-41.719-15.348-39.674-2.85-76.62 3.19`+`5-109.66 18.762-8.18 3.883-15.497 9.177-21.359 14.752-9.725 9.27-8.044 19.889 3.727 28.032 4.862 3.383 10.997 6.233 17.269 8.237 14.406 4.605 30.04 5.544 48.58 5.`+`763l.092-.03ZM130.37 3.573c-24.813-1.88-48.263 1.378-70.44 9.146 22.814-5.481 46.172-9.02 70.44-9.146Z`];return drawPath(targetEl,{mode:"fill",template,SVGWidth:200,SVGHeight:90});},over_underline:targetEl=>{const template=(w,h)=>[`M 0,0 h ${w}`,`M 0,${h} h ${w}`,];return drawPath(targetEl,{mode:"free",template});},scribble_1:targetEl=>{const template=(w,h)=>[`M ${w / 2},${h * 0.9} c ${w / 16},0 ${w},1 ${w / 5},1 c 2,0 -${w / 10},-2 -${w / 2},-1`+`c -${w / 20},0 -${w / 5},2 -${w / 5},4 c -2,0 ${w / 10},-1 ${w / 2},${h / 16}`+`c ${w / 25},0 ${w / 10},0 ${w / 5},1 c 0,0 -${w / 10},1 -${w / 8},1`+`c -${w / 40},0 -${w / 16},0 -${w / 4},${h / 22}`];return drawPath(targetEl,{mode:"free",template});},scribble_2:targetEl=>{const template=(w,h)=>[`M200 3.985c-.228-.332-3.773.541-.01-.006-.811-.037-6.705-1.442-9.978-1.706-1.473.194-2.907.534-4.351.818-1.398.27-2.937.985-4.144.756-`+`9.56-1.782-19.3-1.089-28.955-1.31C118.932 1.767 85.301.942 51.671.45c-13.732-.201-27.492.333-41.233.665C6.561 1.212 3.026 2.363.84 4.838.09 5.684-.262 7.126.223 7`+`.993c.313.554 2.518.79 3.839.728 2.47-.118 4.922-.548 8.096-.936-.96 1.227-1.568 1.865-1.986 2.558-1.368 2.302.029 4 3.203 4.083 24.716.666 49.424 1.4 74.15 2.01 `+`21.087.52 42.145.34 63.146-1.414 4.495-.374 8.999-.644 14.425-1.026-3.117-1.629-4.723-3.521-8.39-3.535-17.999-.077-36.016-.07-54.005-.534-22.246-.576-44.464-1.58-`+`66.7-2.406-.276-.007-.551-.097-.817-.471 1.016 0 2.033-.021 3.04 0 21.961.506 43.913.998 65.864 1.539 25.249.624 50.47.367 75.642-1.144 5.892-.354 11.765-.93 17.6`+`19-1.54.788-.082 1.416-.99 2.651-1.92Z`];return drawPath(targetEl,{mode:"fill",template,SVGWidth:200,SVGHeight:17,position:"bottom"});},scribble_3:targetEl=>{const template=(w,h)=>[`M133.953 15.961c7.87.502 15.751.975 23.611 1.522 2.027.141 4.055.44 5.999.79 4.118.727 7.202 4.977 2.53 6.707.606.293 1.181.564 1.902.`+`908-8.477 2.069-17.267 2.65-26.203 2.818-19.023.361-38.056.603-57.068 1.088-13.807.355-27.572 1.06-41.369 1.545-3.23.113-6.532.096-9.73-.147-1.548-.118-3.492-.721`+`-4.234-1.42-.93-.88-1.484-2.199-.93-3.1.397-.655 2.812-1.263 4.41-1.33 6.397-.277 12.825-.333 19.243-.474 26.976-.592 53.942-1.156 80.919-1.804 3.742-.09 7.452-.5`+`92 11.173-.908 0-.174-.01-.35-.021-.524-2.717-.197-5.435-.53-8.163-.575-21.865-.383-43.741-1.009-65.607-.936-11.34.04-22.65 1.432-34 2.047-6.898.377-13.88.732-20.`+`779.569-7.044-.17-9.406-3.568-5.34-6.742 3.428-2.677 7.567-4.391 13.984-4.757 16.441-.93 32.798-2.26 49.219-3.27 14.162-.868 28.366-1.516 42.549-2.266.586-.034 1.`+`15-.147 1.641-.45-5.006 0-10.023-.012-15.029.01-1.077 0-2.154.186-3.24.192-18.793.18-37.596.355-56.389.507-10.672.085-21.343.13-32.014.153a65.89 65.89 0 0 1-6.167`+`-.277C1.787 5.555-.02 4.247 0 2.59 0 1.384.89.72 3.293.742c5.874.056 11.748.124 17.622.09C41.045.708 61.186.409 81.317.42c28.408.012 56.827.158 85.225.417 8.686.0`+`8 17.35.7 26.015 1.122 3.23.158 5.832.902 7.024 2.678 1.055 1.572.125 2.21-2.875 1.95a30.51 30.51 0 0 0-2.268-.107c-.397 0-.805.073-1.557.146.721.451 1.306.767 1.`+`777 1.128 2.926 2.238 1.641 4.013-3.272 4.369-13.483.958-26.966 1.91-40.459 2.767-3.334.214-6.752 0-10.118.085-2.31.062-4.609.299-6.909.462l.042.519.011.005Z`];return drawPath(targetEl,{mode:"fill",template,SVGWidth:200,SVGHeight:32,position:"bottom"});},scribble_4:targetEl=>{const template=(w,h)=>[`M96.414 17.157c1.34-2.173 2.462-4.075 3.649-5.944 2.117-3.335 5.528-4.302 9.372-2.694 3.962 1.651 4.89 3.575 3.908 8.073-.205.967-.388`+` 1.934-.022 3.118 1.513-3.075 3.013-6.15 4.557-9.203 1.306-2.586 4.297-3.433 7.859-2.195 2.765.968 4.395 2.706 3.564 5.922-.529 2.054-1.005 4.118-.918 6.487.463-.`+`859 1.015-1.685 1.371-2.586 1.447-3.673 3.002-7.324 4.2-11.083.896-2.792 2.192-3.955 5.323-3.564 4.772.598 7.049 3.412 5.84 7.986-.626 2.38-1.22 4.77-1.144 7.486.`+`745-1.358 1.544-2.683 2.213-4.074a138.72 138.72 0 0 0 2.926-6.487c2.376-5.66 3.12-4.704 8.724-3.618 3.552.685 5.063 4.031 4.34 7.997-.616 3.423-1.166 6.856-1.749 `+`10.29l.95.358c.993-2.151 2.062-4.27 2.958-6.454.594-1.456.886-3.042 1.403-4.53 2.43-6.911 2.43-6.813 9.566-5.542.928.163 2.656-.967 3.078-1.923.992-2.26 2.332-2.7`+`16 4.523-2.097 4.297 1.206 8.659 2.184 12.945 3.444 2.796.826 4.319 2.988 4.135 5.889-.173 2.684-.961 5.324-1.274 8.008-.734 6.4-1.361 12.799-2.019 19.21-.065.673`+`.043 1.38-.097 2.031-.551 2.477-.41 5.465-3.476 6.421-2.311.717-6.489-2.194-7.644-5.03-.206-.5-.357-1.01-.918-2.63-1.22 3.27-2.073 5.629-2.991 7.965-2.095 5.345-3`+`.66 5.954-8.874 3.705-.853-.37-2.354-.783-2.786-.359-3.163 3.075-5.971 1.217-8.853-.358-.378-.207-.81-.316-1.188-.457-5.851 7.65-12.502 4.596-15.061-3.944-1.543 3`+`.042-2.883 5.726-4.265 8.399-3.357 6.53-7.783 6.975-12.47 1.25-.485-.587-.992-1.152-1.511-1.75-5.647 6.715-12.848 2.293-15.19-6.063-1.253 2.25-2.257 3.88-3.099 5.`+`596-1.285 2.64-2.883 4.65-6.23 3.868-3.498-.826-6.532-4.085-6.65-7.225-.054-1.424 0-2.847-.475-4.433-1.393 2.879-2.71 5.802-4.19 8.637-3.228 6.204-6.067 6.824-11.`+`67 2.912-.962-.673-2.57-.988-3.704-.728-3.681.837-6.272-.619-8.626-3.248-.691-.783-2.084-1.771-2.807-1.543-4.243 1.347-6.91-.641-9.166-3.836-.378-.543-.8-1.053-1.`+`555-2.031-1.08 2.194-2.008 4.041-2.915 5.9-2.397 4.943-5.528 5.932-10.02 2.835-2.008-1.38-3.713-2.118-6.37-1.738-5.117.728-8.54-3.444-7.762-8.649.227-1.521.378-3.`+`064-.086-4.9-.853 1.369-1.793 2.684-2.548 4.107-2.775 5.259-5.301 5.856-10.074 2.206-.971-.75-1.803-1.674-2.86-2.673-.67.271-1.598 1.043-2.257.858-2.71-.771-5.625`+`-1.423-7.838-3.01-.842-.608-.378-3.683.108-5.465 2.008-7.41 4.232-14.755 6.413-22.11.572-1.945 1.166-3.901 1.943-5.77 1.89-4.52 5.02-5.454 9.145-2.89 1.144.706 2.`+`408 1.217 3.552 1.923 2.364 1.456 4.696 2.988 7.439 4.737C32.423 7.14 37.444 6.64 42.82 10.41c2.602-2.107 1.803-7.17 6.748-6.323 3.369.587 6.478 1.217 7.439 4.878`+` 2.289-2.281 4.221-5.693 6.877-6.42 2.624-.718 5.992 1.26 9.599 2.216-.044.054.636-.565.96-1.348 1.048-2.499 2.883-3.4 5.42-2.825 2.775.62 5.474 1.304 6.284 4.76.`+`216.89 1.285 2.042 2.159 2.248 7.58 1.793 7.6 1.739 8.108 9.55v.012Z`];return drawPath(targetEl,{mode:"fill",template,SVGWidth:200,SVGHeight:61});},jagged:targetEl=>{const template=(w,h)=>[`q ${4 * w / 3} -${2 * w / 3} ${2 * w / 3} 0`+`c -${w / 3} ${w / 3} -${w / 3} ${w / 3} ${w / 3} 0`];return drawPath(targetEl,{mode:"pattern",template});},cross:targetEl=>{const template=(w,h)=>[`M 0,0 L ${w},${h}`,`M 0,${h} L ${w},0`,];return drawPath(targetEl,{mode:"free",template});},diagonal:targetEl=>{const template=(w,h)=>[`M 0,${h} L${w},0`];return drawPath(targetEl,{mode:"free",template});},strikethrough:targetEl=>{return drawPath(targetEl,{mode:"line",position:"center"});},bold:targetEl=>{const template=(w,h)=>[`M136.604 41.568c5.373.513 10.746 1.047 16.12 1.479 14.437 1.13 29.327 4.047 42.858-4.294 4.92-3.04 2.346-13.56-2.687-13.395-.825.02-1.`+`635.062-2.46.082.858-3.677-.34-8.3-3.545-9.41 2.655.062 5.309.104 7.963.165 6.863.185 6.863-14.176 0-14.36A1958.994 1958.994 0 0 0 5.263 5.778C-.4 6.169-2.392 18.`+`455 3.84 19.893c9.727 2.24 19.454 4.335 29.214 6.307-1.085 1.09-1.764 2.671-2.023 4.356-.615.061-1.214.102-1.83.164-6.748.74-6.959 14.587 0 14.361l107.42-3.513h-.`+`016Z`];return drawPath(targetEl,{mode:"fill",template,SVGWidth:200,SVGHeight:46});},bold_1:targetEl=>{const template=(w,h)=>[`M190.276 34.01c5.618-.25 7.136-6.526 4.444-9.755.037-.25.055-.5.072-.749 7.046-.949 7.01-11.752-.523-11.553-.796.017-1.59.017-2.403.05`+`C196.78 9.573 195.931.8 189.264.983L13.784 5.678c-7.226.2-7.497 9.422-1.499 11.32-2.186 0-4.354 0-6.54-.017-7.696-.05-7.624 11.286 0 11.635 8.22.383 16.423.733 24`+`.643 1.016l-7.823.35c-7.624.349-7.678 11.985 0 11.635 55.915-2.53 111.813-5.077 167.729-7.607h-.018Z`];return drawPath(targetEl,{mode:"fill",template,SVGWidth:200,SVGHeight:42});},bold_2:targetEl=>{const template=(w,h)=>[`M193.221 20.193c.555 1.245.863 2.005 1.22 2.734 1.399 2.84 2.758 5.757 1.607 9.509-1.21 3.95-3.651 4.208-6.072 4.314-5.059.212-10.129.`+`152-15.178.592-15.873 1.367-31.737 3.585-47.619 4.238-19.921.82-39.862.638-59.802.486-13.938-.106-27.887-.88-41.825-1.428-4.018-.151-8.046-.47-12.064-.896-2.758-.`+`304-4.772-2.46-6.21-6.182-.645-1.656-1.756-2.993-2.798-4.177-2.768-3.13-5.06-6.38-3.899-12.502C.9 15.226.393 13.16.165 11.307c-.715-5.818.903-9.524 4.722-9.646 10`+`.218-.35 20.437-.38 30.655-.577C51.236.78 66.94-.04 82.635.264c14.652.273 29.296 1.655 43.948 2.643 19.822 1.336 39.643 2.02 59.455-.426.923-.121 1.835-.5 2.758-.`+`622 1.329-.183 2.688-.456 4.008-.274 3.829.501 7.073 5.666 7.192 11.21.09 4.466-1.418 6.213-6.775 7.428v-.03Z`];return drawPath(targetEl,{mode:"fill",template,SVGWidth:200,SVGHeight:43});},};const getDOMRectWidth=__exports.getDOMRectWidth=el=>el.getBoundingClientRect().width;function drawPath(textEl,options){const{width,height}=textEl.getBoundingClientRect();options={...options,width,height};const yStart=options.position==="center"?height/2:height;switch(options.mode){case"pattern":{let i=0,d=[];const nbrChars=textEl.textContent.length;const w=width/nbrChars,h=height*0.2;while(i<nbrChars){d.push(options.template(w,h));i++;}
return buildPath([`M 0,${yStart} ${d.join(" ")}`],options);}
case"line":{return buildPath([`M 0,${yStart} h ${width}`],options);}}
return buildPath(options.template(width,height),options);}
function buildPath(templates,options){return templates.map(d=>{const path=document.createElementNS("http://www.w3.org/2000/svg","path");path.setAttribute("stroke-width","var(--text-highlight-width)");path.setAttribute("stroke","var(--text-highlight-color)");path.setAttribute("stroke-linecap","round");if(options.mode==="fill"){let wScale=options.width/options.SVGWidth;let hScale=options.height/options.SVGHeight;const transforms=[];if(options.position==="bottom"){hScale*=0.3;transforms.push(`translate(0 ${options.height * 0.8})`);}
transforms.push(`scale(${wScale}, ${hScale})`);path.setAttribute("fill","var(--text-highlight-color)");path.setAttribute("transform",transforms.join(" "));}
path.setAttribute("d",d);return path;});}
__exports.drawTextHighlightSVG=drawTextHighlightSVG;function drawTextHighlightSVG(textEl,highlightID){const svg=document.createElementNS("http://www.w3.org/2000/svg","svg");svg.setAttribute("fill","none");svg.classList.add("o_text_highlight_svg","o_content_no_merge","position-absolute","overflow-visible","top-0","start-0","w-100","h-100","pe-none");_textHighlightFactory[highlightID](textEl).forEach(pathEl=>{pathEl.classList.add(`o_text_highlight_path_${highlightID}`);svg.appendChild(pathEl);});return svg;}
__exports.applyTextHighlight=applyTextHighlight;function applyTextHighlight(topTextEl,highlightID){const endHighlightUpdate=()=>topTextEl.dispatchEvent(new Event("text_highlight_added",{bubbles:true}));if(topTextEl.querySelector(".o_text_highlight_item")||!isVisible(topTextEl)){return endHighlightUpdate();}
const style=window.getComputedStyle(topTextEl);if(!style.getPropertyValue("--text-highlight-width")){topTextEl.style.setProperty("--text-highlight-width",`${Math.round(parseFloat(style.fontSize) * 0.1)}px`);}
const lines=[];let lineIndex=0;const nodeIsBR=node=>node.nodeName==="BR";const isRTL=el=>window.getComputedStyle(el).direction==="rtl";[...topTextEl.childNodes].forEach(child=>{if(nodeIsBR(child)){lines[++lineIndex]=[child];return lineIndex++;}
const textLines=splitNodeLines(child);let lastNodeInLine=false;if(child.textContent&&child.nextSibling?.textContent){const range=document.createRange();const lastCurrentText=selectAllTextNodes(child).at(-1);range.setStart(lastCurrentText,lastCurrentText.length-1);range.setEnd(lastCurrentText,lastCurrentText.length);const currentEnd=range.getBoundingClientRect()[isRTL(topTextEl)?"left":"right"];const firstnextText=selectAllTextNodes(child.nextSibling)[0];range.setStart(firstnextText,0);range.setEnd(firstnextText,1);const nextStart=range.getBoundingClientRect()[isRTL(topTextEl)?"right":"left"];lastNodeInLine=nextStart+1<currentEnd;}
textLines.map((node,i,{length})=>{if(!lines[lineIndex]){lines[lineIndex]=[];}
lines[lineIndex].push(node);if(i!==length-1||lastNodeInLine){lineIndex++;}});});topTextEl.replaceChildren(...lines.map(textLine=>{return nodeIsBR(textLine[0])?textLine[0]:createHighlightContainer(textLine);}));[...topTextEl.querySelectorAll(".o_text_highlight_item")].forEach(container=>{container.append(drawTextHighlightSVG(container,highlightID||getCurrentTextHighlight(topTextEl)));});endHighlightUpdate();}
__exports.removeTextHighlight=removeTextHighlight;function removeTextHighlight(topTextEl){topTextEl.dispatchEvent(new Event("text_highlight_remove",{bubbles:true}));[...topTextEl.querySelectorAll(".o_text_highlight_item")].forEach(unit=>{unit.after(...[...unit.childNodes].filter((node)=>node.tagName!=="svg"));unit.remove();});let child=topTextEl.firstElementChild;while(child){let next=child.nextElementSibling;if(next&&next===child.nextSibling&&child.cloneNode().isEqualNode(next.cloneNode())){child.replaceChildren(...child.childNodes,...next.childNodes);next.remove();}else{child=next;}}
topTextEl.normalize();}
__exports.switchTextHighlight=switchTextHighlight;function switchTextHighlight(textEl,highlightID){if(!isVisible(textEl)){return;}
highlightID=highlightID||getCurrentTextHighlight(textEl);const ownerDocument=textEl.ownerDocument;const sel=ownerDocument.getSelection();const restoreSelection=sel.rangeCount===1&&textEl.contains(sel.anchorNode);let rangeCollapsed,cursorEndPosition=0,rangeSize=0;if(restoreSelection){const range=sel.getRangeAt(0);rangeSize=range.toString().length;rangeCollapsed=range.collapsed;const globalRange=range.cloneRange();globalRange.selectNodeContents(textEl);globalRange.setEnd(range.endContainer,range.endOffset);cursorEndPosition=globalRange.toString().length;}
if(highlightID){removeTextHighlight(textEl);applyTextHighlight(textEl,highlightID);}
if(restoreSelection&&cursorEndPosition){if(rangeCollapsed){const selectionOffset=getOffsetNode(textEl,cursorEndPosition);OdooEditorLib.setSelection(...selectionOffset,...selectionOffset);}else{OdooEditorLib.setSelection(...getOffsetNode(textEl,cursorEndPosition-rangeSize),...getOffsetNode(textEl,cursorEndPosition));}}}
function createHighlightContainer(nodes){const highlightContainer=document.createElement("span");highlightContainer.className="o_text_highlight_item";highlightContainer.append(...nodes);return highlightContainer;}
__exports.getCurrentTextHighlight=getCurrentTextHighlight;function getCurrentTextHighlight(el){const topTextEl=el.closest(".o_text_highlight");const match=topTextEl?.className.match(/o_text_highlight_(?<value>[\w]+)/);let highlight="";if(match){highlight=match.groups.value;}
return highlight;}
function splitNodeLines(node){const isTextContainer=node.childNodes.length===1&&node.firstChild.nodeType===Node.TEXT_NODE;if(node.nodeType!==Node.TEXT_NODE&&!isTextContainer){return[node];}
const text=node.textContent;const textNode=isTextContainer?node.firstChild:node;const lines=[];const range=document.createRange();let i=-1;while(++i<text.length){range.setStart(textNode,0);range.setEnd(textNode,i+1);const clientRects=range.getClientRects().length||1;const lineIndex=clientRects-1;const currentText=lines[lineIndex];lines[lineIndex]=(currentText||"")+text.charAt(i);}
if(lines.length===1){return[node];}
return lines.map(line=>{if(isTextContainer){const wrapper=node.cloneNode();wrapper.appendChild(document.createTextNode(line));return wrapper;}
return document.createTextNode(line);});}
__exports.selectAllTextNodes=selectAllTextNodes;function selectAllTextNodes(topNode){const textNodes=[];const selectTextNodes=(node)=>{if(node.nodeType===Node.TEXT_NODE){textNodes.push(node);}else{[...node.childNodes].forEach(child=>selectTextNodes(child));}};selectTextNodes(topNode);return textNodes;}
__exports.getOffsetNode=getOffsetNode;function getOffsetNode(textEl,offset){let index=0,offsetNode;for(const node of selectAllTextNodes(textEl)){const stepLength=node.textContent.length;if(index+stepLength<offset-1){index+=stepLength;}else{offsetNode=node;break;}}
return[offsetNode,offset-index];}
return __exports;});;

/* /website/static/src/snippets/s_embed_code/000.js */
odoo.define('@website/snippets/s_embed_code/000',['@web/legacy/js/public/public_widget','@web/core/l10n/translation','@website/js/utils'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{_t}=require("@web/core/l10n/translation");const{cloneContentEls}=require("@website/js/utils");const EmbedCodeWidget=publicWidget.Widget.extend({selector:".s_embed_code",disabledInEditableMode:false,async start(){this.embedCodeEl=this.el.querySelector(".s_embed_code_embedded");if(!this.el.querySelector("template.s_embed_code_saved")){const templateEl=document.createElement("template");templateEl.classList.add("s_embed_code_saved");templateEl.content.append(cloneContentEls(this.embedCodeEl,true));this.el.prepend(templateEl);}
if(this.editableMode&&this.embedCodeEl.offsetHeight===0){const placeholderEl=document.createElement("div");placeholderEl.classList.add("s_embed_code_placeholder","alert","alert-info","pt16","pb16");placeholderEl.textContent=_t("Your Embed Code snippet doesn't have anything to display. Click on Edit to modify it.");this.el.querySelector(".s_embed_code_embedded").appendChild(placeholderEl);}
return this._super(...arguments);},destroy(){this._super(...arguments);if(!this.editableMode){const templateContent=this.el.querySelector("template.s_embed_code_saved").content;this.embedCodeEl.replaceChildren(cloneContentEls(templateContent));}},});publicWidget.registry.EmbedCode=EmbedCodeWidget;__exports[Symbol.for("default")]=EmbedCodeWidget;return __exports;});;

/* /purchase/static/src/js/purchase_datetimepicker.js */
odoo.define('@purchase/js/purchase_datetimepicker',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const PublicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const PurchaseDatePicker=__exports.PurchaseDatePicker=PublicWidget.Widget.extend({selector:".o-purchase-datetimepicker",init(){this._super(...arguments);this.rpc=this.bindService("rpc");},start(){this.call("datetime_picker","create",{target:this.el,onChange:(newDate)=>{const{accessToken,orderId,lineId}=this.el.dataset;this.rpc(`/my/purchase/${orderId}/update?access_token=${accessToken}`,{[lineId]:newDate.toISODate(),});},pickerProps:{type:"date",value:luxon.DateTime.fromISO(this.el.dataset.value),},}).enable();},});PublicWidget.registry.PurchaseDatePicker=PurchaseDatePicker;return __exports;});;

/* /purchase/static/src/js/purchase_portal_sidebar.js */
odoo.define('@purchase/js/purchase_portal_sidebar',['@web/legacy/js/public/public_widget','@portal/js/portal_sidebar','@web/core/utils/functions'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const PortalSidebar=require("@portal/js/portal_sidebar")[Symbol.for("default")];const{uniqueId}=require("@web/core/utils/functions");publicWidget.registry.PurchasePortalSidebar=PortalSidebar.extend({selector:".o_portal_purchase_sidebar",init:function(parent,options){this._super.apply(this,arguments);this.authorizedTextTag=["em","b","i","u"];this.spyWatched=$('body[data-target=".navspy"]');},start:function(){var def=this._super.apply(this,arguments);var $spyWatcheElement=this.$el.find('[data-id="portal_sidebar"]');this._setElementId($spyWatcheElement);this._generateMenu();return def;},_setElementId:function(prefix,$el){var id=uniqueId(prefix);this.spyWatched.find($el).attr("id",id);return id;},_generateMenu:function(){var self=this,lastLI=false,lastUL=null,$bsSidenav=this.$el.find(".bs-sidenav");$("#quote_content [id^=quote_header_], #quote_content [id^=quote_]",this.spyWatched).attr("id","");this.spyWatched.find("#quote_content h2, #quote_content h3").toArray().forEach((el)=>{var id,text;switch(el.tagName.toLowerCase()){case"h2":id=self._setElementId("quote_header_",el);text=self._extractText($(el));if(!text){break;}
lastLI=$("<li class='nav-item'>").append($('<a class="nav-link p-0" style="max-width: 200px;" href="#'+
id+'"/>').text(text)).appendTo($bsSidenav);lastUL=false;break;case"h3":id=self._setElementId("quote_",el);text=self._extractText($(el));if(!text){break;}
if(lastLI){if(!lastUL){lastUL=$("<ul class='nav flex-column'>").appendTo(lastLI);}
$("<li class='nav-item'>").append($('<a class="nav-link p-0" style="max-width: 200px;" href="#'+
id+'"/>').text(text)).appendTo(lastUL);}
break;}
el.setAttribute("data-anchor",true);});this.trigger_up("widgets_start_request",{$target:$bsSidenav});},_extractText:function($node){var self=this;var rawText=[];Array.from($node.contents()).forEach((el)=>{var current=$(el);if($.trim(current.text())){var tagName=current.prop("tagName");if(typeof tagName==="undefined"||(typeof tagName!=="undefined"&&self.authorizedTextTag.includes(tagName.toLowerCase()))){rawText.push($.trim(current.text()));}}});return rawText.join(" ");},});return __exports;});;

/* /project/static/src/js/portal_rating.js */
odoo.define('@project/js/portal_rating',['@web/legacy/js/public/public_widget','@web/core/l10n/dates'],function(require){'use strict';let __exports={};const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const{parseDate}=require('@web/core/l10n/dates');publicWidget.registry.ProjectRatingImage=publicWidget.Widget.extend({selector:'.o_portal_project_rating .o_rating_image',start:function(){this.$el.popover({placement:'bottom',trigger:'hover',html:true,content:function(){var $elem=$(this);var id=$elem.data('id');var ratingDate=$elem.data('rating-date');var baseDate=parseDate(ratingDate);var duration=baseDate.toRelative();var $rating=$('#rating_'+id);$rating.find('.rating_timeduration').text(duration);return $rating.html();},});return this._super.apply(this,arguments);},});return __exports;});;

/* /website_payment/static/src/js/payment_form.js */
odoo.define('@website_payment/js/payment_form',['@web/core/l10n/translation','@odoo/owl','@payment/js/payment_form'],function(require){'use strict';let __exports={};const{_t}=require('@web/core/l10n/translation');const{Component}=require('@odoo/owl');const PaymentForm=require('@payment/js/payment_form')[Symbol.for("default")];PaymentForm.include({events:Object.assign({},PaymentForm.prototype.events||{},{'change input[name="o_donation_amount"]':'_updateAmount','focus input[name="amount"]':'_updateAmount','focus input[name="o_donation_amount"]':'_updateAmount',}),async start(){Component.env.bus.addEventListener('update_shipping_cost',(ev)=>this._updateShippingCost(ev.detail));return await this._super.apply(this,arguments);},_updateAmount(ev){if(ev.target.value>=0){this.paymentContext.amount=ev.target.value;const otherAmountEl=this.el.querySelector("#other_amount");if(ev.target.name==="o_donation_amount"&&ev.target.type==="number"&&otherAmountEl){otherAmountEl.value=ev.target.value;}
if(ev.target.id==="other_amount"||(ev.target.name==="o_donation_amount"&&ev.target.type==="number")){this.el.querySelectorAll('input[name="o_donation_amount"][type="radio"]').forEach((radioEl)=>{radioEl.checked=false;});}else if(ev.target.name==="o_donation_amount"&&otherAmountEl){otherAmountEl.checked=false;}}},_updateShippingCost:function(amount){this.paymentContext.amount=amount;},async _initiatePaymentFlow(providerCode,paymentOptionId,paymentMethodCode,flow){if($('.o_donation_payment_form').length){const errorFields={};if(!this.$('input[name="email"]')[0].checkValidity()){errorFields['email']=_t("Email is invalid");}
const mandatoryFields={'name':_t('Name'),'email':_t('Email'),'country_id':_t('Country'),};for(const id in mandatoryFields){const $field=this.$('input[name="'+id+'"],select[name="'+id+'"]');$field.removeClass('is-invalid').popover('dispose');if(!$field.val().trim()){errorFields[id]=_t("Field '%s' is mandatory",mandatoryFields[id]);}}
if(Object.keys(errorFields).length){for(const id in errorFields){const $field=this.$('input[name="'+id+'"],select[name="'+id+'"]');$field.addClass('is-invalid');$field.popover({content:errorFields[id],trigger:'hover',container:'body',placement:'top'});}
this._displayErrorDialog(_t("Payment processing failed"),_t("Some information is missing to process your payment."));return;}}
await this._super(...arguments);},_prepareTransactionRouteParams(){const transactionRouteParams=this._super(...arguments);return $('.o_donation_payment_form').length?{...transactionRouteParams,'partner_id':parseInt(this.paymentContext['partnerId']),'currency_id':this.paymentContext['currencyId']?parseInt(this.paymentContext['currencyId']):null,'reference_prefix':this.paymentContext['referencePrefix']?.toString(),'partner_details':{'name':this.$('input[name="name"]').val(),'email':this.$('input[name="email"]').val(),'country_id':this.$('select[name="country_id"]').val(),},'donation_comment':this.$('#donation_comment').val(),'donation_recipient_email':this.$('input[name="donation_recipient_email"]').val(),}:transactionRouteParams;},});return __exports;});;

/* /website_payment/static/src/js/website_payment_donation.js */
odoo.define('@website_payment/js/website_payment_donation',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];publicWidget.registry.WebsitePaymentDonation=publicWidget.Widget.extend({selector:'.o_donation_payment_form',events:{'focus .o_amount_input':'_onFocusAmountInput','change #donation_comment_checkbox':'_onChangeDonationComment'},_onFocusAmountInput(ev){this.$el.find('#other_amount').prop("checked",true);},_onChangeDonationComment(ev){const $donationComment=this.$el.find('#donation_comment');const checked=$(ev.currentTarget).is(':checked');$donationComment.toggleClass('d-none',!checked);if(!checked){$donationComment.val('');}},});return __exports;});;

/* /website_mail/static/src/js/follow.js */
odoo.define('@website_mail/js/follow',['@web/legacy/js/public/public_widget','@google_recaptcha/js/recaptcha','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{ReCaptcha}=require("@google_recaptcha/js/recaptcha");const{_t}=require("@web/core/l10n/translation");publicWidget.registry.follow=publicWidget.Widget.extend({selector:'#wrapwrap:has(.js_follow)',disabledInEditableMode:false,init(){this._super(...arguments);this.rpc=this.bindService("rpc");this._recaptcha=new ReCaptcha();this.notification=this.bindService("notification");},async willStart(){return this._recaptcha.loadLibs();},start:function(){var self=this;this.isUser=false;var $jsFollowEls=this.$el.find('.js_follow');var always=function(data){self.isUser=data[0].is_user;const $jsFollowToEnable=$jsFollowEls.filter(function(){const model=this.dataset.object;return model in data[1]&&data[1][model].includes(parseInt(this.dataset.id));});self._toggleSubscription(true,data[0].email,$jsFollowToEnable);self._toggleSubscription(false,data[0].email,$jsFollowEls.not($jsFollowToEnable));$jsFollowEls.removeClass('d-none');};const records={};for(const el of $jsFollowEls){const model=el.dataset.object;if(!(model in records)){records[model]=[];}
records[model].push(parseInt(el.dataset.id));}
this.rpc('/website_mail/is_follower',{records:records,}).then(always,always);if(!this.editableMode){$('.js_follow > .d-none').removeClass('d-none');this.$el.find('.js_follow_btn, .js_unfollow_btn').on('click',function(event){event.preventDefault();self._onClick(event);});}
return this._super.apply(this,arguments);},_toggleSubscription:function(follow,email,$jsFollowEls){if(follow){this._updateSubscriptionDOM(follow,email,$jsFollowEls);}else{for(const el of $jsFollowEls){const follow=!email&&el.getAttribute('data-unsubscribe');this._updateSubscriptionDOM(follow,email,$(el));}}},_updateSubscriptionDOM:function(follow,email,$jsFollowEls){$jsFollowEls.find('input.js_follow_email').val(email||"").attr("disabled",email&&(follow||this.isUser)?"disabled":false);$jsFollowEls.attr("data-follow",follow?'on':'off');},async _onClick(ev){var self=this;var $jsFollow=$(ev.currentTarget).closest('.js_follow');var $email=$jsFollow.find(".js_follow_email");if($email.length&&!$email.val().match(/.+@.+/)){$jsFollow.addClass('o_has_error').find('.form-control, .form-select').addClass('is-invalid');return false;}
$jsFollow.removeClass('o_has_error').find('.form-control, .form-select').removeClass('is-invalid');var email=$email.length?$email.val():false;if(email||this.isUser){const tokenCaptcha=await this._recaptcha.getToken("website_mail_follow");const token=tokenCaptcha.token;if(tokenCaptcha.error){self.notification.add(tokenCaptcha.error,{type:"danger",title:_t("Error"),sticky:true});return false;}
this.rpc("/website_mail/follow",{"id":+$jsFollow.data("id"),"object":$jsFollow.data("object"),"message_is_follower":$jsFollow.attr("data-follow")||"off","email":email,"recaptcha_token_response":token}).then(function(follow){self._toggleSubscription(follow,email,$jsFollow);});}},});return __exports;});;

/* /portal_rating/static/src/js/portal_chatter.js */
odoo.define('@portal_rating/js/portal_chatter',['@web/core/l10n/translation','@portal/js/portal_chatter','@web/core/utils/numbers','@web/core/utils/render'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const PortalChatter=require("@portal/js/portal_chatter")[Symbol.for("default")];const{roundPrecision}=require("@web/core/utils/numbers");const{renderToElement}=require("@web/core/utils/render");PortalChatter.include({events:Object.assign({},PortalChatter.prototype.events,{'click .o_website_rating_table_row':'_onClickStarDomain','click .o_website_rating_selection_reset':'_onClickStarDomainReset','click .o_wrating_js_publisher_comment_btn':'_onClickPublisherComment','click .o_wrating_js_publisher_comment_edit':'_onClickPublisherComment','click .o_wrating_js_publisher_comment_delete':'_onClickPublisherCommentDelete','click .o_wrating_js_publisher_comment_submit':'_onClickPublisherCommentSubmit','click .o_wrating_js_publisher_comment_cancel':'_onClickPublisherCommentCancel',}),init:function(parent,options){this._super.apply(this,arguments);if(!Object.keys(this.options).includes("display_rating")){this.options=Object.assign({'display_rating':false,'rating_default_value':0.0,},this.options);}
this.set('rating_card_values',{});this.set('rating_value',false);this.on("change:rating_value",this,this._onChangeRatingDomain);},start:function(){this._super.apply(this,arguments);this.on("change:rating_card_values",this,this._renderRatingCard);},preprocessMessages:function(messages){var self=this;messages=this._super.apply(this,arguments);if(this.options['display_rating']){messages.forEach((m,i)=>{m.rating_value=self.roundToHalf(m['rating_value']);m.rating=self._preprocessCommentData(m.rating,i);});}
this.messages=messages;return messages;},roundToHalf:function(value){var converted=parseFloat(value);var decimal=(converted-parseInt(converted,10));decimal=Math.round(decimal*10);if(decimal===5){return(parseInt(converted,10)+0.5);}
if((decimal<3)||(decimal>7)){return Math.round(converted);}else{return(parseInt(converted,10)+0.5);}},_chatterInit:async function(){const result=await this._super(...arguments);this._updateRatingCardValues(result);return result;},messageFetch:async function(domain){const result=await this._super(...arguments);this._updateRatingCardValues(result);return result;},_updateRatingCardValues:function(result){if(!result['rating_stats']){return;}
const self=this;const ratingData={'avg':Math.round(result['rating_stats']['avg']*100)/100,'percent':[],};Object.keys(result["rating_stats"]["percent"]).sort().reverse().forEach((rating)=>{ratingData["percent"].push({num:self.roundToHalf(rating),percent:roundPrecision(result["rating_stats"]["percent"][rating],0.01),});});this.set('rating_card_values',ratingData);},_messageFetchPrepareParams:function(){var params=this._super.apply(this,arguments);if(this.options['display_rating']){params['rating_include']=true;const ratingValue=this.get('rating_value');if(ratingValue!==false){params['rating_value']=ratingValue;}}
return params;},_renderRatingCard:function(){this.$('.o_website_rating_card_container').replaceWith(renderToElement("portal_rating.rating_card",{widget:this}));},_newPublisherCommentData:function(messageIndex){return{mes_index:messageIndex,publisher_id:this.options.partner_id,publisher_avatar:`/web/image/res.partner/${this.options.partner_id}/avatar_128/50x50`,publisher_name:_t("Write your comment"),publisher_datetime:'',publisher_comment:'',};},_preprocessCommentData:function(rawRating,messageIndex){var ratingData={id:rawRating.id,mes_index:messageIndex,publisher_avatar:rawRating.publisher_avatar,publisher_comment:rawRating.publisher_comment,publisher_datetime:rawRating.publisher_datetime,publisher_id:rawRating.publisher_id,publisher_name:rawRating.publisher_name,};var commentData={...this._newPublisherCommentData(messageIndex),...ratingData};return commentData;},_getCommentContainer:function($source){return $source.parents(".o_wrating_publisher_container").first().find(".o_wrating_publisher_comment").first();},_getCommentButton:function($source){return $source.parents(".o_wrating_publisher_container").first().find(".o_wrating_js_publisher_comment_btn").first();},_getCommentTextarea:function($source){return $source.parents(".o_wrating_publisher_container").first().find(".o_portal_rating_comment_input").first();},_focusTextComment:function($source){this._getCommentTextarea($source).focus();},_onChangeDomain:function(){const spinnerDelayed=setTimeout(()=>{this.$('.o_portal_chatter_messages_loading').removeClass('d-none');this.$('.o_portal_chatter_messages').addClass('d-none');},500);return this._super.apply(this,arguments).finally(()=>{clearTimeout(spinnerDelayed);this.$('.o_portal_chatter_messages_loading').addClass('d-none');this.$('.o_portal_chatter_messages').removeClass('d-none');});},_onClickStarDomain:function(ev){var $tr=this.$(ev.currentTarget);var num=$tr.data('star');this.set('rating_value',num);},_onClickStarDomainReset:function(ev){ev.stopPropagation();ev.preventDefault();this.set('rating_value',false);},_onClickPublisherComment:function(ev){var $source=this.$(ev.currentTarget);if(this._getCommentTextarea($source).length===1){this._getCommentContainer($source).empty();return;}
var messageIndex=$source.data("mes_index");var data={is_publisher:this.options['is_user_publisher']};data.rating=this._newPublisherCommentData(messageIndex);var oldRating=this.messages[messageIndex].rating;data.rating.publisher_comment=oldRating.publisher_comment?oldRating.publisher_comment:'';this._getCommentContainer($source).empty().append(renderToElement("portal_rating.chatter_rating_publisher_form",data));this._focusTextComment($source);},_onClickPublisherCommentDelete:function(ev){var self=this;var $source=this.$(ev.currentTarget);var messageIndex=$source.data("mes_index");var ratingId=this.messages[messageIndex].rating.id;this.rpc('/website/rating/comment',{"rating_id":ratingId,"publisher_comment":''}).then(function(res){self.messages[messageIndex].rating=self._preprocessCommentData(res,messageIndex);self._getCommentButton($source).removeClass("d-none");self._getCommentContainer($source).empty();});},_onClickPublisherCommentSubmit:function(ev){var self=this;var $source=this.$(ev.currentTarget);var messageIndex=$source.data("mes_index");var comment=this._getCommentTextarea($source).val();var ratingId=this.messages[messageIndex].rating.id;this.rpc('/website/rating/comment',{"rating_id":ratingId,"publisher_comment":comment}).then(function(res){self.messages[messageIndex].rating=self._preprocessCommentData(res,messageIndex);if(self.messages[messageIndex].rating.publisher_comment!==''){self._getCommentButton($source).addClass('d-none');self._getCommentContainer($source).empty().append(renderToElement("portal_rating.chatter_rating_publisher_comment",{rating:self.messages[messageIndex].rating,is_publisher:self.options.is_user_publisher}));}else{self._getCommentButton($source).removeClass("d-none");self._getCommentContainer($source).empty();}});},_onClickPublisherCommentCancel:function(ev){var $source=this.$(ev.currentTarget);var messageIndex=$source.data("mes_index");var comment=this.messages[messageIndex].rating.publisher_comment;const $commentContainer=this._getCommentContainer($source);$commentContainer.empty();if(comment){var data={rating:this.messages[messageIndex].rating,is_publisher:this.options.is_user_publisher,};$commentContainer.append(renderToElement("portal_rating.chatter_rating_publisher_comment",data));}},_onChangeRatingDomain:function(){var domain=[];if(this.get('rating_value')){domain=[['rating_value','=',this.get('rating_value')]];}
this._changeCurrentPage(1,domain);},});return __exports;});;

/* /portal_rating/static/src/js/portal_composer.js */
odoo.define('@portal_rating/js/portal_composer',['@web/core/l10n/translation','@portal/js/portal_composer'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const portalComposer=require("@portal/js/portal_composer")[Symbol.for("default")];var PortalComposer=portalComposer.PortalComposer;PortalComposer.include({events:Object.assign({},PortalComposer.prototype.events,{'click .stars i':'_onClickStar','mouseleave .stars':'_onMouseleaveStarBlock','mousemove .stars i':'_onMoveStar','mouseleave .stars i':'_onMoveLeaveStar',}),init:function(parent,options){this._super.apply(this,arguments);if(options.default_rating_value){options.default_rating_value=parseFloat(options.default_rating_value);}
this.options=Object.assign({'rate_with_void_content':false,'default_message':false,'default_message_id':false,'default_rating_value':4.0,'force_submit_url':false,},this.options);this.labels={'0':"",'1':_t("I hate it"),'2':_t("I don't like it"),'3':_t("It's okay"),'4':_t("I like it"),'5':_t("I love it"),};this.user_click=false;this.set("star_value",this.options.default_rating_value);this.on("change:star_value",this,this._onChangeStarValue);},start:function(){var self=this;return this._super.apply(this,arguments).then(function(){self.$input=self.$('input[name="rating_value"]');self.$star_list=self.$('.stars').find('i');if(!self.options.default_message_id){self.$star_list.removeClass('text-black-25');}
self.set("star_value",self.options.default_rating_value);self.$input.val(self.options.default_rating_value);});},_prepareMessageData:function(){return Object.assign(this._super(...arguments)||{},{'message_id':this.options.default_message_id,'rating_value':this.$input.val()});},_onChangeStarValue:function(){var val=this.get("star_value");var index=Math.floor(val);var decimal=val-index;this.$star_list.removeClass('fa-star fa-star-half-o').addClass('fa-star-o');this.$('.stars').find("i:lt("+index+")").removeClass('fa-star-o fa-star-half-o').addClass('fa-star');if(decimal){this.$('.stars').find("i:eq("+index+")").removeClass('fa-star-o fa-star fa-star-half-o').addClass('fa-star-half-o');}
this.$('.rate_text .badge').text(this.labels[index]);},_onClickStar:function(ev){var index=this.$('.stars i').index(ev.currentTarget);this.set("star_value",index+1);this.user_click=true;this.$input.val(this.get("star_value"));},_onMouseleaveStarBlock:function(){this.$('.rate_text').hide();},_onMoveStar:function(ev){var index=this.$('.stars i').index(ev.currentTarget);this.$('.rate_text').show();this.set("star_value",index+1);},_onMoveLeaveStar:function(){if(!this.user_click){this.set("star_value",parseInt(this.$input.val()));}
this.user_click=false;},_onSubmitButtonClick:function(ev){return this._super(...arguments).then((result)=>{const $modal=this.$el.closest('#ratingpopupcomposer');$modal.on('hidden.bs.modal',()=>{this.trigger_up('reload_rating_popup_composer',result);});$modal.modal('hide');},()=>{});},_onSubmitCheckContent:function(ev){if(this.options.rate_with_void_content){if(this.$input.val()===0){return _t('The rating is required. Please make sure to select one before sending your review.')}
return false;}
return this._super.apply(this,arguments);},});return __exports;});;

/* /portal_rating/static/src/js/portal_rating_composer.js */
odoo.define('@portal_rating/js/portal_rating_composer',['@web/legacy/js/public/public_widget','@web/session','@portal/js/portal_composer','@web/core/l10n/translation','@web/core/utils/render'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{session}=require("@web/session");const portalComposer=require("@portal/js/portal_composer")[Symbol.for("default")];const{_t}=require("@web/core/l10n/translation");const{renderToElement}=require("@web/core/utils/render");const PortalComposer=portalComposer.PortalComposer;const RatingPopupComposer=publicWidget.Widget.extend({selector:'.o_rating_popup_composer',custom_events:{reload_rating_popup_composer:'_onReloadRatingPopupComposer',},willStart:function(parent){const def=this._super.apply(this,arguments);const options=this.$el.data();this.rating_avg=Math.round(options['rating_avg']*100)/100||0.0;this.rating_count=options['rating_count']||0.0;this.options=Object.assign({'token':false,'res_model':false,'res_id':false,'pid':0,'display_rating':true,'csrf_token':odoo.csrf_token,'user_id':session.user_id,},options,{});return def;},start:function(){return Promise.all([this._super.apply(this,arguments),this._reloadRatingPopupComposer(),]);},_reloadRatingPopupComposer:function(){if(this.options.hide_rating_avg){this.$('.o_rating_popup_composer_stars').empty();}else{const ratingAverage=renderToElement('portal_rating.rating_stars_static',{inline_mode:true,widget:this,val:this.rating_avg,});this.$('.o_rating_popup_composer_stars').empty().html(ratingAverage);}
const modal=renderToElement('portal_rating.PopupComposer',{inline_mode:true,widget:this,val:this.rating_avg,})||'';this.$('.o_rating_popup_composer_modal').html(modal);if(this._composer){this._composer.destroy();}
this._composer=new PortalComposer(this,this.options);return this._composer.appendTo(this.$('.o_rating_popup_composer_modal .o_portal_chatter_composer')).then(()=>{this.$('.o_rating_popup_composer_text').text(this.options.is_fullscreen?_t('Review'):this.options.default_message_id?_t('Edit Review'):_t('Add Review'));});},_onReloadRatingPopupComposer:function(event){const data=event.data;this.rating_avg=data.rating_avg;this.rating_count=data.rating_count;this.rating_value=data.rating_value;delete data.rating_avg;delete data.rating_count;delete data.rating_value;this.options=Object.assign(this.options,data);this._reloadRatingPopupComposer();}});publicWidget.registry.RatingPopupComposer=RatingPopupComposer;__exports[Symbol.for("default")]=RatingPopupComposer;return __exports;});;

/* /website_sale/static/src/js/tours/tour_utils.js */
odoo.define('@website_sale/js/tours/tour_utils',['@web/core/l10n/translation','@website/js/tours/tour_utils'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const wTourUtils=require("@website/js/tours/tour_utils")[Symbol.for("default")];function addToCart({productName,search=true,productHasVariants=false}){const steps=[];if(search){steps.push(...searchProduct(productName));}
steps.push(wTourUtils.clickOnElement(productName,`a:contains(${productName})`));steps.push(wTourUtils.clickOnElement('Add to cart','#add_to_cart'));if(productHasVariants){steps.push(wTourUtils.clickOnElement('Continue Shopping','button:contains("Continue Shopping")'));}
return steps;}
function assertCartAmounts({taxes=false,untaxed=false,total=false,delivery=false}){let steps=[];if(taxes){steps.push({content:'Check if the tax is correct',trigger:`tr#order_total_taxes .oe_currency_value:containsExact(${taxes})`,run:function(){},});}
if(untaxed){steps.push({content:'Check if the tax is correct',trigger:`tr#order_total_untaxed .oe_currency_value:containsExact(${untaxed})`,run:function(){},});}
if(total){steps.push({content:'Check if the tax is correct',trigger:`tr#order_total .oe_currency_value:containsExact(${total})`,run:function(){},});}
if(delivery){steps.push({content:'Check if the tax is correct',trigger:`tr#order_delivery .oe_currency_value:containsExact(${delivery})`,run:function(){},});}
return steps}
function assertCartContains({productName,backend,notContains=false}={}){let trigger=`a:contains(${productName})`;if(notContains){trigger=`:not(${trigger})`;}
return{content:`Checking if ${productName} is in the cart`,trigger:`${backend ? "iframe" : ""} ${trigger}`,run:()=>{}};}
function assertProductPrice(attribute,value,productName){return{content:`The ${attribute} of the ${productName} is ${value}`,trigger:`div:contains("${productName}") [data-oe-expression="template_price_vals['${attribute}']"] .oe_currency_value:contains("${value}")`,run:()=>{}};}
function fillAdressForm(adressParams={name:"John Doe",phone:"123456789",email:"johndoe@gmail.com",street:"1 rue de la paix",city:"Paris",zip:"75000"}){let steps=[];steps.push({content:"Address filling",trigger:'select[name="country_id"]',run:()=>{$('input[name="name"]').val(adressParams.name);$('input[name="phone"]').val(adressParams.phone);$('input[name="email"]').val(adressParams.email);$('input[name="street"]').val(adressParams.street);$('input[name="city"]').val(adressParams.city);$('input[name="zip"]').val(adressParams.zip);$('#country_id option:eq(1)').attr('selected',true);}});steps.push({content:"Continue checkout",trigger:'.oe_cart .btn:contains("Continue checkout")',});return steps;}
function goToCart({quantity=1,position="bottom",backend=false}={}){return{content:_t("Go to cart"),trigger:`${backend ? "iframe" : ""} a sup.my_cart_quantity:containsExact(${quantity})`,position:position,run:"click",};}
function goToCheckout(){return{content:'Checkout your order',trigger:'a[href^="/shop/checkout"]',run:'click',};}
function pay(){return{content:'Pay',trigger:'button[name="o_payment_submit_button"]:visible:not(:disabled)'};}
function payWithDemo(){return[{content:'eCommerce: select Test payment provider',trigger:'input[name="o_payment_radio"][data-payment-method-code="demo"]'},{content:'eCommerce: add card number',trigger:'input[name="customer_input"]',run:'text 4242424242424242'},pay(),{content:'eCommerce: check that the payment is successful',trigger:'.oe_website_sale_tx_status:contains("Your payment has been successfully processed.")',run:function(){}}]}
function payWithTransfer(redirect=false){const first_step={content:"Select `Wire Transfer` payment method",trigger:'input[name="o_payment_radio"][data-payment-method-code="wire_transfer"]',}
if(!redirect){return[first_step,pay(),{content:"Last step",trigger:'.oe_website_sale_tx_status:contains("Please use the following transfer details")',timeout:30000,isCheck:true,}]}else{return[first_step,pay(),{content:"Last step",trigger:'.oe_website_sale_tx_status:contains("Please use the following transfer details")',timeout:30000,run:()=>{window.location.href='/contactus';},},{content:"wait page loaded",trigger:'h1:contains("Contact us")',run:function(){},}]}}
function searchProduct(productName){return[wTourUtils.clickOnElement('Shop','a:contains("Shop")'),{content:"Search for the product",trigger:'form input[name="search"]',run:`text ${productName}`},wTourUtils.clickOnElement('Search','form:has(input[name="search"]) .oe_search_button'),];}
function selectPriceList(pricelist){return[{content:"Click on pricelist dropdown",trigger:"div.o_pricelist_dropdown a[data-bs-toggle=dropdown]",},{content:"Click on pricelist",trigger:`span:contains(${pricelist})`,},];}
__exports[Symbol.for("default")]={addToCart,assertCartAmounts,assertCartContains,assertProductPrice,fillAdressForm,goToCart,goToCheckout,pay,payWithDemo,payWithTransfer,selectPriceList,searchProduct,};return __exports;});;

/* /website_sale/static/src/js/payment_button.js */
odoo.define('@website_sale/js/payment_button',['@payment/js/payment_button'],function(require){'use strict';let __exports={};const paymentButton=require('@payment/js/payment_button')[Symbol.for("default")];paymentButton.include({_canSubmit(){return this._super(...arguments)&&this._isCarrierReady()&&this._isTCCheckboxReady();},_isCarrierReady(){const carriers=document.querySelectorAll('.o_delivery_carrier_select');if(carriers.length===0){return true;}
const checkedCarriers=document.querySelectorAll('input[name="delivery_type"]:checked');if(checkedCarriers.length===0){return false;}
const carriersContainer=checkedCarriers[0].closest('.o_delivery_carrier_select');if(carriersContainer.querySelector('.o_wsale_delivery_carrier_error')){return false;}
const isPickUpPointRequired=carriersContainer.querySelector('.o_show_pickup_locations');if(isPickUpPointRequired){const address=carriersContainer.querySelector('.o_order_location_address').innerText;return address!=='';}
return true;},_isTCCheckboxReady(){const checkbox=document.querySelector('#website_sale_tc_checkbox');if(!checkbox){return true;}
return checkbox.checked;},});return __exports;});;

/* /website_sale/static/src/js/payment_form.js */
odoo.define('@website_sale/js/payment_form',['@payment/js/payment_form'],function(require){'use strict';let __exports={};const PaymentForm=require('@payment/js/payment_form')[Symbol.for("default")];PaymentForm.include({async start(){const submitButton=document.querySelector('[name="o_payment_submit_button"]');submitButton.addEventListener('click',ev=>this._submitForm(ev));return await this._super(...arguments);}});return __exports;});;

/* /website_sale/static/src/js/sale_variant_mixin.js */
odoo.define('@website_sale/js/sale_variant_mixin',['@web/core/utils/concurrency','@web/core/utils/functions','@web/core/utils/timing','@web/core/utils/numbers','@web/core/l10n/translation','@web/core/l10n/localization','@web/core/network/rpc_service'],function(require){'use strict';let __exports={};const{KeepLast}=require("@web/core/utils/concurrency");const{memoize,uniqueId}=require("@web/core/utils/functions");const{throttleForAnimation}=require("@web/core/utils/timing");const{insertThousandsSep}=require("@web/core/utils/numbers");const{_t}=require("@web/core/l10n/translation");const{localization}=require("@web/core/l10n/localization");const{jsonrpc}=require("@web/core/network/rpc_service");var VariantMixin={events:{'change .css_attribute_color input':'_onChangeColorAttribute','click .o_variant_pills':'_onChangePillsAttribute','change .main_product:not(.in_cart) input.js_quantity':'onChangeAddQuantity','change [data-attribute_exclusions]':'onChangeVariant'},onChangeVariant:function(ev){var $parent=$(ev.target).closest('.js_product');if(!$parent.data('uniqueId')){$parent.data('uniqueId',uniqueId());}
this._throttledGetCombinationInfo(this,$parent.data('uniqueId'))(ev);},_getCombinationInfo:function(ev){if($(ev.target).hasClass('variant_custom_value')){return Promise.resolve();}
const $parent=$(ev.target).closest('.js_product');if(!$parent.length){return Promise.resolve();}
const combination=this.getSelectedVariantValues($parent);let parentCombination;if($parent.hasClass('main_product')){parentCombination=$parent.find('ul[data-attribute_exclusions]').data('attribute_exclusions').parent_combination;const $optProducts=$parent.parent().find(`[data-parent-unique-id='${$parent.data('uniqueId')}']`);for(const optionalProduct of $optProducts){const $currentOptionalProduct=$(optionalProduct);const childCombination=this.getSelectedVariantValues($currentOptionalProduct);const productTemplateId=parseInt($currentOptionalProduct.find('.product_template_id').val());jsonrpc('/website_sale/get_combination_info',{'product_template_id':productTemplateId,'product_id':this._getProductId($currentOptionalProduct),'combination':childCombination,'add_qty':parseInt($currentOptionalProduct.find('input[name="add_qty"]').val()),'parent_combination':combination,'context':this.context,...this._getOptionalCombinationInfoParam($currentOptionalProduct),}).then((combinationData)=>{if(this._shouldIgnoreRpcResult()){return;}
this._onChangeCombination(ev,$currentOptionalProduct,combinationData);this._checkExclusions($currentOptionalProduct,childCombination,combinationData.parent_exclusions);});}}else{parentCombination=this.getSelectedVariantValues($parent.parent().find('.js_product.in_cart.main_product'));}
return jsonrpc('/website_sale/get_combination_info',{'product_template_id':parseInt($parent.find('.product_template_id').val()),'product_id':this._getProductId($parent),'combination':combination,'add_qty':parseInt($parent.find('input[name="add_qty"]').val()),'parent_combination':parentCombination,'context':this.context,...this._getOptionalCombinationInfoParam($parent),}).then((combinationData)=>{if(this._shouldIgnoreRpcResult()){return;}
this._onChangeCombination(ev,$parent,combinationData);this._checkExclusions($parent,combination,combinationData.parent_exclusions);});},_getOptionalCombinationInfoParam($product){return{};},handleCustomValues:function($target){var $variantContainer;var $customInput=false;if($target.is('input[type=radio]')&&$target.is(':checked')){$variantContainer=$target.closest('ul').closest('li');$customInput=$target;}else if($target.is('select')){$variantContainer=$target.closest('li');$customInput=$target.find('option[value="'+$target.val()+'"]');}
if($variantContainer){if($customInput&&$customInput.data('is_custom')==='True'){var attributeValueId=$customInput.data('value_id');var attributeValueName=$customInput.data('value_name');if($variantContainer.find('.variant_custom_value').length===0||$variantContainer.find('.variant_custom_value').data('custom_product_template_attribute_value_id')!==parseInt(attributeValueId)){$variantContainer.find('.variant_custom_value').remove();const previousCustomValue=$customInput.attr("previous_custom_value");var $input=$('<input>',{type:'text','data-custom_product_template_attribute_value_id':attributeValueId,'data-attribute_value_name':attributeValueName,class:'variant_custom_value form-control mt-2'});$input.attr('placeholder',attributeValueName);$input.addClass('custom_value_radio');$variantContainer.append($input);if(previousCustomValue){$input.val(previousCustomValue);}}}else{$variantContainer.find('.variant_custom_value').remove();}}},onClickAddCartJSON:function(ev){ev.preventDefault();var $link=$(ev.currentTarget);var $input=$link.closest('.input-group').find("input");var min=parseFloat($input.data("min")||0);var max=parseFloat($input.data("max")||Infinity);var previousQty=parseFloat($input.val()||0,10);var quantity=($link.has(".fa-minus").length?-1:1)+previousQty;var newQty=quantity>min?(quantity<max?quantity:max):min;if(newQty!==previousQty){$input.val(newQty).trigger('change');}
return false;},onChangeAddQuantity:function(ev){var $parent;if($(ev.currentTarget).closest('.oe_advanced_configurator_modal').length>0){$parent=$(ev.currentTarget).closest('.oe_advanced_configurator_modal');}else if($(ev.currentTarget).closest('form').length>0){$parent=$(ev.currentTarget).closest('form');}else{$parent=$(ev.currentTarget).closest('.o_product_configurator');}
this.triggerVariantChange($parent);},triggerVariantChange:function($container){$container.find('ul[data-attribute_exclusions]').trigger('change');$container.find('input.js_variant_change:checked, select.js_variant_change').each(function(){VariantMixin.handleCustomValues($(this));});},getCustomVariantValues:function($container){var variantCustomValues=[];$container.find('.variant_custom_value').each(function(){var $variantCustomValueInput=$(this);if($variantCustomValueInput.length!==0){variantCustomValues.push({'custom_product_template_attribute_value_id':$variantCustomValueInput.data('custom_product_template_attribute_value_id'),'attribute_value_name':$variantCustomValueInput.data('attribute_value_name'),'custom_value':$variantCustomValueInput.val(),});}});return variantCustomValues;},getNoVariantAttributeValues:function($container){var noVariantAttributeValues=[];var variantsValuesSelectors=['input.no_variant.js_variant_change:checked','select.no_variant.js_variant_change'];$container.find(variantsValuesSelectors.join(',')).each(function(){var $variantValueInput=$(this);var singleNoCustom=$variantValueInput.data('is_single')&&!$variantValueInput.data('is_custom');if($variantValueInput.is('select')){$variantValueInput=$variantValueInput.find('option[value='+$variantValueInput.val()+']');}
if($variantValueInput.length!==0&&!singleNoCustom){noVariantAttributeValues.push({'custom_product_template_attribute_value_id':$variantValueInput.data('value_id'),'attribute_value_name':$variantValueInput.data('value_name'),'value':$variantValueInput.val(),'attribute_name':$variantValueInput.data('attribute_name'),'is_custom':$variantValueInput.data('is_custom')});}});return noVariantAttributeValues;},getSelectedVariantValues:function($container){var values=[];var unchangedValues=$container.find('div.oe_unchanged_value_ids').data('unchanged_value_ids')||[];var variantsValuesSelectors=['input.js_variant_change:checked','select.js_variant_change'];$container.find(variantsValuesSelectors.join(', ')).toArray().forEach((el)=>{values.push(+$(el).val());});return values.concat(unchangedValues);},selectOrCreateProduct:function($container,productId,productTemplateId,useAjax){productId=parseInt(productId);productTemplateId=parseInt(productTemplateId);var productReady=Promise.resolve();if(productId){productReady=Promise.resolve(productId);}else{var params={product_template_id:productTemplateId,product_template_attribute_value_ids:JSON.stringify(VariantMixin.getSelectedVariantValues($container)),};var route='/sale/create_product_variant';if(useAjax){productReady=jsonrpc(route,params);}else{productReady=this.rpc(route,params);}}
return productReady;},_checkExclusions:function($parent,combination,parentExclusions){var self=this;var combinationData=$parent.find('ul[data-attribute_exclusions]').data('attribute_exclusions');if(parentExclusions&&combinationData.parent_exclusions){combinationData.parent_exclusions=parentExclusions;}
$parent.find('option, input, label, .o_variant_pills').removeClass('css_not_available').attr('title',function(){return $(this).data('value_name')||'';}).data('excluded-by','');if(combinationData.exclusions){Object.values(combination).forEach((current_ptav)=>{if(combinationData.exclusions.hasOwnProperty(current_ptav)){Object.values(combinationData.exclusions[current_ptav]).forEach((excluded_ptav)=>{self._disableInput($parent,excluded_ptav,current_ptav,combinationData.mapped_attribute_names);});}});}
if(combinationData.archived_combinations){combinationData.archived_combinations.forEach((excludedCombination)=>{const ptavCommon=excludedCombination.filter((ptav)=>combination.includes(ptav));if(!!ptavCommon&&(combination.length===excludedCombination.length)&&(ptavCommon.length===combination.length)){combination.forEach((ptav)=>{combination.forEach((ptavOther)=>{if(ptav===ptavOther){return;}
self._disableInput($parent,ptav,ptavOther,combinationData.mapped_attribute_names,);})})}else if(!!ptavCommon&&(combination.length===excludedCombination.length)&&(ptavCommon.length===(combination.length-1))){const disabledPtav=excludedCombination.find((ptav)=>!combination.includes(ptav));excludedCombination.forEach((ptav)=>{if(ptav===disabledPtav){return;}
self._disableInput($parent,disabledPtav,ptav,combinationData.mapped_attribute_names,)});}});}
for(const[excluded_by,exclusions]of Object.entries(combinationData.parent_exclusions||{})){exclusions.forEach((ptav)=>{self._disableInput($parent,ptav,excluded_by,combinationData.mapped_attribute_names,combinationData.parent_product_name);});}},_getProductId:function($parent){return parseInt($parent.find('.product_id').val());},_disableInput:function($parent,attributeValueId,excludedBy,attributeNames,productName){var $input=$parent.find('option[value='+attributeValueId+'], input[value='+attributeValueId+']');$input.addClass('css_not_available');$input.closest('label').addClass('css_not_available');$input.closest('.o_variant_pills').addClass('css_not_available');if(excludedBy&&attributeNames){var $target=$input.is('option')?$input:$input.closest('label').add($input);var excludedByData=[];if($target.data('excluded-by')){excludedByData=JSON.parse($target.data('excluded-by'));}
var excludedByName=attributeNames[excludedBy];if(productName){excludedByName=productName+' ('+excludedByName+')';}
excludedByData.push(excludedByName);$target.attr('title',_t('Not available with %s',excludedByData.join(', ')));$target.data('excluded-by',JSON.stringify(excludedByData));}},_onChangeCombination:function(ev,$parent,combination){var self=this;var $price=$parent.find(".oe_price:first .oe_currency_value");var $default_price=$parent.find(".oe_default_price:first .oe_currency_value");var $optional_price=$parent.find(".oe_optional:first .oe_currency_value");$price.text(self._priceToStr(combination.price));$default_price.text(self._priceToStr(combination.list_price));var isCombinationPossible=true;if(typeof combination.is_combination_possible!=="undefined"){isCombinationPossible=combination.is_combination_possible;}
this._toggleDisable($parent,isCombinationPossible);if(combination.has_discounted_price&&!combination.compare_list_price){$default_price.closest('.oe_website_sale').addClass("discount");$optional_price.closest('.oe_optional').removeClass('d-none').css('text-decoration','line-through');$default_price.parent().removeClass('d-none');}else{$default_price.closest('.oe_website_sale').removeClass("discount");$optional_price.closest('.oe_optional').addClass('d-none');$default_price.parent().addClass('d-none');}
var rootComponentSelectors=['tr.js_product','.oe_website_sale','.o_product_configurator'];if(!combination.product_id||!this.last_product_id||combination.product_id!==this.last_product_id){this.last_product_id=combination.product_id;self._updateProductImage($parent.closest(rootComponentSelectors.join(', ')),combination.display_image,combination.product_id,combination.product_template_id,combination.carousel,isCombinationPossible);}
$parent.find('.product_id').first().val(combination.product_id||0).trigger('change');$parent.find('.product_display_name').first().text(combination.display_name);$parent.find('.js_raw_price').first().text(combination.price).trigger('change');$parent.find('.o_product_tags').first().html(combination.product_tags);this.handleCustomValues($(ev.target));},_priceToStr:function(price){var precision=2;if($('.decimal_precision').length){precision=parseInt($('.decimal_precision').last().data('precision'));}
var formatted=price.toFixed(precision).split(".");const{thousandsSep,decimalPoint,grouping}=localization;formatted[0]=insertThousandsSep(formatted[0],thousandsSep,grouping);return formatted.join(decimalPoint);},_throttledGetCombinationInfo:memoize(function(self,uniqueId){const keepLast=new KeepLast();var _getCombinationInfo=throttleForAnimation(self._getCombinationInfo.bind(self));return(ev,params)=>keepLast.add(_getCombinationInfo(ev,params));}),_toggleDisable:function($parent,isCombinationPossible){$parent.toggleClass('css_not_available',!isCombinationPossible);if($parent.hasClass('in_cart')){const primaryButton=$parent.parents('.modal-content').find('.modal-footer .btn-primary');primaryButton.prop('disabled',!isCombinationPossible);primaryButton.toggleClass('disabled',!isCombinationPossible);}},_updateProductImage:function($productContainer,displayImage,productId,productTemplateId){var model=productId?'product.product':'product.template';var modelId=productId||productTemplateId;var imageUrl='/web/image/{0}/{1}/'+(this._productImageField?this._productImageField:'image_1024');var imageSrc=imageUrl.replace("{0}",model).replace("{1}",modelId);var imagesSelectors=['span[data-oe-model^="product."][data-oe-type="image"] img:first','img.product_detail_img','span.variant_image img','img.variant_image',];var $img=$productContainer.find(imagesSelectors.join(', '));if(displayImage){$img.removeClass('invisible').attr('src',imageSrc);}else{$img.addClass('invisible');}},_onChangeColorAttribute:function(ev){var $parent=$(ev.target).closest('.js_product');$parent.find('.css_attribute_color').removeClass("active").filter(':has(input:checked)').addClass("active");},_onChangePillsAttribute:function(ev){const radio=ev.target.closest('.o_variant_pills').querySelector("input");radio.click();var $parent=$(ev.target).closest('.js_product');$parent.find('.o_variant_pills').removeClass("active").filter(':has(input:checked)').addClass("active");},_shouldIgnoreRpcResult(){return(typeof this.isDestroyed==="function"&&this.isDestroyed());},_getUri:function(uri){return uri;}};__exports[Symbol.for("default")]=VariantMixin;return __exports;});;

/* /website_sale/static/src/js/terms_and_conditions_checkbox.js */
odoo.define('@website_sale/js/terms_and_conditions_checkbox',['@odoo/owl','@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const{Component}=require('@odoo/owl');const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];publicWidget.registry.TermsAndConditionsCheckbox=publicWidget.Widget.extend({selector:'div[name="website_sale_terms_and_conditions_checkbox"]',events:{'change #website_sale_tc_checkbox':'_onClickTCCheckbox',},async start(){this.checkbox=this.el.querySelector('#website_sale_tc_checkbox');return this._super(...arguments);},_onClickTCCheckbox(){if(this.checkbox.checked){Component.env.bus.trigger('enablePaymentButton');}else{Component.env.bus.trigger('disablePaymentButton');}},});__exports[Symbol.for("default")]=publicWidget.registry.TermsAndConditionsCheckbox;return __exports;});;

/* /website_sale/static/src/js/variant_mixin.js */
odoo.define('@website_sale/js/variant_mixin',['@website_sale/js/sale_variant_mixin'],function(require){'use strict';let __exports={};const VariantMixin=require("@website_sale/js/sale_variant_mixin")[Symbol.for("default")];const originalOnChangeCombination=VariantMixin._onChangeCombination;VariantMixin._onChangeCombination=function(ev,$parent,combination){const $pricePerUom=$parent.find(".o_base_unit_price:first .oe_currency_value");if($pricePerUom){if(combination.is_combination_possible!==false&&combination.base_unit_price!=0){$pricePerUom.parents(".o_base_unit_price_wrapper").removeClass("d-none");$pricePerUom.text(this._priceToStr(combination.base_unit_price));$parent.find(".oe_custom_base_unit:first").text(combination.base_unit_name);}else{$pricePerUom.parents(".o_base_unit_price_wrapper").addClass("d-none");}}
if('product_tracking_info'in combination){const $product=$('#product_detail');$product.data('product-tracking-info',combination['product_tracking_info']);$product.trigger('view_item_event',combination['product_tracking_info']);}
const addToCart=$parent.find('#add_to_cart_wrap');const contactUsButton=$parent.find('#contact_us_wrapper');const productPrice=$parent.find('.product_price');const quantity=$parent.find('.css_quantity');const product_unavailable=$parent.find('#product_unavailable');if(combination.prevent_zero_price_sale){productPrice.removeClass('d-inline-block').addClass('d-none');quantity.removeClass('d-inline-flex').addClass('d-none');addToCart.removeClass('d-inline-flex').addClass('d-none');contactUsButton.removeClass('d-none').addClass('d-flex');product_unavailable.removeClass('d-none').addClass('d-flex')}else{productPrice.removeClass('d-none').addClass('d-inline-block');quantity.removeClass('d-none').addClass('d-inline-flex');addToCart.removeClass('d-none').addClass('d-inline-flex');contactUsButton.removeClass('d-flex').addClass('d-none');product_unavailable.removeClass('d-flex').addClass('d-none')}
originalOnChangeCombination.apply(this,[ev,$parent,combination]);};const originalToggleDisable=VariantMixin._toggleDisable;VariantMixin._toggleDisable=function($parent,isCombinationPossible){if($parent.hasClass('in_cart')){const secondaryButton=$parent.parents('.modal-content').find('.modal-footer .btn-secondary');secondaryButton.prop('disabled',!isCombinationPossible);secondaryButton.toggleClass('disabled',!isCombinationPossible);}
originalToggleDisable.apply(this,[$parent,isCombinationPossible]);};__exports[Symbol.for("default")]=VariantMixin;return __exports;});;

/* /website_sale_product_configurator/static/src/js/sale_product_configurator_modal.js */
odoo.define('@website_sale_product_configurator/js/sale_product_configurator_modal',['@web/legacy/js/core/dialog','@website_sale/js/sale_variant_mixin','@web/core/utils/functions','@web/core/network/rpc_service'],function(require){'use strict';let __exports={};const Dialog=require('@web/legacy/js/core/dialog')[Symbol.for("default")];const VariantMixin=require('@website_sale/js/sale_variant_mixin')[Symbol.for("default")];const{uniqueId}=require('@web/core/utils/functions');const{jsonrpc}=require('@web/core/network/rpc_service');const OptionalProductsModal=__exports.OptionalProductsModal=Dialog.extend(VariantMixin,{events:Object.assign({},Dialog.prototype.events,VariantMixin.events,{'click a.js_add, a.js_remove':'_onAddOrRemoveOption','click button.js_add_cart_json':'onClickAddCartJSON','change .in_cart input.js_quantity':'_onChangeQuantity','change .js_raw_price':'_computePriceTotal'}),init:function(parent,params){var self=this;var options=Object.assign({size:'large',buttons:[{text:params.okButtonText,click:this._onConfirmButtonClick,classes:'btn-primary o_sale_product_configurator_edit'},{text:params.cancelButtonText,click:this._onCancelButtonClick}],technical:!params.isWebsite,},params||{});this._super(parent,options);this.isWebsite=params.isWebsite;this.forceDialog=params.forceDialog;this.dialogClass='oe_advanced_configurator_modal'+(params.isWebsite?' oe_website_sale':'');this.context=params.context;this.rootProduct=params.rootProduct;this.container=parent;this.pricelistId=params.pricelistId;this.previousModalHeight=params.previousModalHeight;this.mode=params.mode;this.dialogClass='oe_advanced_configurator_modal';this._productImageField='image_128';this._opened.then(function(){if(self.previousModalHeight){self.$el.closest('.modal-content').css('min-height',self.previousModalHeight+'px');}});this.rpc=this.bindService("rpc");},willStart:function(){var self=this;var getModalContent=jsonrpc("/sale_product_configurator/show_advanced_configurator",{mode:self.mode,product_id:self.rootProduct.product_id,variant_values:self.rootProduct.variant_values,product_custom_attribute_values:self.rootProduct.product_custom_attribute_values,pricelist_id:self.pricelistId||false,add_qty:self.rootProduct.quantity,force_dialog:self.forceDialog,no_attribute:self.rootProduct.no_variant_attribute_values,custom_attribute:self.rootProduct.product_custom_attribute_values,context:Object.assign({'quantity':self.rootProduct.quantity},this.context),}).then(function(modalContent){if(modalContent){var $modalContent=$(modalContent);$modalContent=self._postProcessContent($modalContent);self.$content=$modalContent;}else{self.trigger('options_empty');self.preventOpening=true;}});var parentInit=self._super.apply(self,arguments);return Promise.all([getModalContent,parentInit]);},open:function(options){$('.tooltip').remove();var self=this;this.appendTo($('<div/>')).then(function(){if(!self.preventOpening){self.$modal.find(".modal-body").replaceWith(self.$el);self.$modal.attr('open',true);self.$modal.appendTo(self.container);const modal=new Modal(self.$modal[0],{focus:true,});modal.show();self._openedResolver();}});if(options&&options.shouldFocusButtons){self._onFocusControlButton();}
return self;},start:function(){var def=this._super.apply(this,arguments);var self=this;this.$el.find('input[name="add_qty"]').val(this.rootProduct.quantity);var $products=this.$el.find('tr.js_product').toArray();$products.forEach((el)=>{var $el=$(el);var uniqueId=self._getUniqueId(el);var productId=parseInt($el.find('input.product_id').val(),10);if(productId===self.rootProduct.product_id){self.rootProduct.unique_id=uniqueId;}else{el.dataset.parentUniqueId=self.rootProduct.unique_id;}});return def.then(function(){self._opened.then(function(){self.triggerVariantChange(self.$el);});});},getAndCreateSelectedProducts:async function(){var self=this;const products=[];let productCustomVariantValues;let noVariantAttributeValues;for(const product of self.$modal.find('.js_product.in_cart')){var $item=$(product);var quantity=parseFloat($item.find('input[name="add_qty"]').val().replace(',','.')||1);var parentUniqueId=product.dataset.parentUniqueId;var uniqueId=product.dataset.uniqueId;productCustomVariantValues=$item.find('.custom-attribute-info').data("attribute-value")||self.getCustomVariantValues($item);noVariantAttributeValues=$item.find('.no-attribute-info').data("attribute-value")||self.getNoVariantAttributeValues($item);const productID=await self.selectOrCreateProduct($item,parseInt($item.find('input.product_id').val(),10),parseInt($item.find('input.product_template_id').val(),10),true);products.push({'product_id':productID,'product_template_id':parseInt($item.find('input.product_template_id').val(),10),'quantity':quantity,'parent_unique_id':parentUniqueId,'unique_id':uniqueId,'product_custom_attribute_values':productCustomVariantValues,'no_variant_attribute_values':noVariantAttributeValues});}
return products;},_postProcessContent:function($modalContent){var productId=this.rootProduct.product_id;$modalContent.find('img:first').attr("src","/web/image/product.product/"+productId+"/image_128");if(this.rootProduct&&(this.rootProduct.product_custom_attribute_values||this.rootProduct.no_variant_attribute_values)){var $productDescription=$modalContent.find('.main_product').find('td.td-product_name div.text-muted.small > div:first');var $updatedDescription=$('<div/>');$updatedDescription.append($('<p>',{text:$productDescription.text()}));$.each(this.rootProduct.product_custom_attribute_values,function(){if(this.custom_value){const $customInput=$modalContent.find(".main_product [data-is_custom='True']").closest(`[data-value_id='${this.custom_product_template_attribute_value_id.res_id}']`);$customInput.attr('previous_custom_value',this.custom_value);VariantMixin.handleCustomValues($customInput);}});$.each(this.rootProduct.no_variant_attribute_values,function(){if(this.is_custom!=='True'){var $currentDescription=$updatedDescription.find(`div[name=ptal-${this.id}]`);if($currentDescription?.length>0){$currentDescription.text($currentDescription.text()+', '+this.attribute_value_name);}else{$updatedDescription.append($('<div>',{text:this.attribute_name+': '+this.attribute_value_name,name:`ptal-${this.id}`,}));}}});$productDescription.replaceWith($updatedDescription);}
return $modalContent;},_onConfirmButtonClick:function(){this.trigger('confirm');this.close();},_onCancelButtonClick:function(){this.trigger('back');this.close();},_onAddOrRemoveOption:function(ev){ev.preventDefault();var self=this;var $target=$(ev.currentTarget);var $modal=$target.parents('.oe_advanced_configurator_modal');var $parent=$target.parents('.js_product:first');$parent.find("a.js_add, span.js_remove").toggleClass('d-none');$parent.find(".js_remove");var productTemplateId=$parent.find(".product_template_id").val();if($target.hasClass('js_add')){self._onAddOption($modal,$parent,productTemplateId);}else{self._onRemoveOption($modal,$parent);}
self._computePriceTotal();},_onAddOption:function($modal,$parent,productTemplateId){var self=this;var $selectOptionsText=$modal.find('.o_select_options');var parentUniqueId=$parent[0].dataset.parentUniqueId;var $optionParent=$modal.find('tr.js_product[data-unique-id="'+parentUniqueId+'"]');$parent.find('.td-product_name').removeAttr("colspan");$parent.find('.td-qty').removeClass('d-none');var productCustomVariantValues=self.getCustomVariantValues($parent);var noVariantAttributeValues=self.getNoVariantAttributeValues($parent);if(productCustomVariantValues||noVariantAttributeValues){var $productDescription=$parent.find('td.td-product_name div.float-start');var $customAttributeValuesDescription=$('<div>',{class:'custom_attribute_values_description text-muted small'});if(productCustomVariantValues.length!==0||noVariantAttributeValues.length!==0){$customAttributeValuesDescription.append($('<br/>'));}
$.each(productCustomVariantValues,function(){$customAttributeValuesDescription.append($('<div>',{text:this.attribute_value_name+': '+this.custom_value}));});$.each(noVariantAttributeValues,function(){if(this.is_custom!=='True'){var $currentDescription=$customAttributeValuesDescription.find(`div[name=ptal-${this.id}]`);if($currentDescription?.length>0){$currentDescription.text($currentDescription.text()+', '+this.attribute_value_name);}else{$customAttributeValuesDescription.append($('<div>',{text:this.attribute_name+': '+this.attribute_value_name,name:`ptal-${this.id}`,}));}}});$productDescription.append($customAttributeValuesDescription);}
var $tmpOptionParent=$optionParent;while($tmpOptionParent.length){$optionParent=$tmpOptionParent;$tmpOptionParent=$modal.find('tr.js_product.in_cart[data-parent-unique-id="'+$optionParent[0].dataset.uniqueId+'"]').last();}
$optionParent.after($parent);$parent.addClass('in_cart');this.selectOrCreateProduct($parent,$parent.find('.product_id').val(),productTemplateId,true).then(function(productId){$parent.find('.product_id').val(productId);jsonrpc("/sale_product_configurator/optional_product_items",{'product_id':productId,'pricelist_id':self.pricelistId||false,}).then(function(addedItem){var $addedItem=$(addedItem);$modal.find('tr:last').after($addedItem);self.$el.find('input[name="add_qty"]').trigger('change');self.triggerVariantChange($addedItem);var parentUniqueId=$parent[0].dataset.uniqueId;var parentQty=$parent.find('input[name="add_qty"]').val();$addedItem.filter('.js_product').each(function(){var $el=$(this);var uniqueId=self._getUniqueId(this);this.dataset.uniqueId=uniqueId;this.dataset.parentUniqueId=parentUniqueId;$el.find('input[name="add_qty"]').val(parentQty);});if($selectOptionsText.nextAll('.js_product').length===0){$selectOptionsText.hide();}});});},_onRemoveOption:function($modal,$parent){var uniqueId=$parent[0].dataset.parentUniqueId;var qty=$modal.find('tr.js_product.in_cart[data-unique-id="'+uniqueId+'"]').find('input[name="add_qty"]').val();$parent.removeClass('in_cart');$parent.find('.td-product_name').attr("colspan",2);$parent.find('.td-qty').addClass('d-none');$parent.find('input[name="add_qty"]').val(qty);$parent.find('.custom_attribute_values_description').remove();$modal.find('.o_select_options').show();var productUniqueId=$parent[0].dataset.uniqueId;this._removeOptionOption($modal,productUniqueId);$modal.find('tr:last').after($parent);},_removeOptionOption:function($modal,optionUniqueId){var self=this;$modal.find('tr.js_product[data-parent-unique-id="'+optionUniqueId+'"]').each(function(){var uniqueId=this.dataset.uniqueId;$(this).remove();self._removeOptionOption($modal,uniqueId);});},_onChangeCombination:function(ev,$parent,combination){$parent.find('.td-product_name .product-name').first().text(combination.display_name);VariantMixin._onChangeCombination.apply(this,arguments);this._computePriceTotal();},_onChangeQuantity:function(ev){var $product=$(ev.target.closest('tr.js_product'));var qty=parseFloat($(ev.currentTarget).val());var uniqueId=$product[0].dataset.uniqueId;this.$el.find('tr.js_product:not(.in_cart)[data-parent-unique-id="'+uniqueId+'"] input[name="add_qty"]').each(function(){$(this).val(qty);});if(this._triggerPriceUpdateOnChangeQuantity()){this.onChangeAddQuantity(ev);}
if($product.hasClass('main_product')){this.rootProduct.quantity=qty;}
this.trigger('update_quantity',this.rootProduct.quantity);this._computePriceTotal();},_computePriceTotal:function(){if(this.$modal.find('.js_price_total').length){var price=0;this.$modal.find('.js_product.in_cart').each(function(){var quantity=parseFloat($(this).find('input[name="add_qty"]').first().val().replace(',','.')||1);price+=parseFloat($(this).find('.js_raw_price').html())*quantity;});this.$modal.find('.js_price_total .oe_currency_value').text(this._priceToStr(parseFloat(price)));}},_triggerPriceUpdateOnChangeQuantity:function(){return!this.isWebsite;},_getUniqueId:function(el){if(!el.dataset.uniqueId){el.dataset.uniqueId=parseInt(uniqueId(),10);}
return el.dataset.uniqueId;},});return __exports;});;

/* /website_sale_subscription/static/src/js/variant_mixin.js */
odoo.define('@website_sale_subscription/js/variant_mixin',['@website_sale/js/sale_variant_mixin','@web/legacy/js/public/public_widget','@website_sale/js/website_sale'],function(require){'use strict';let __exports={};const VariantMixin=require("@website_sale/js/sale_variant_mixin")[Symbol.for("default")];const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];require("@website_sale/js/website_sale");VariantMixin._onChangeCombinationSubscription=function(ev,$parent,combination){if(!this.isWebsite||!combination.is_subscription){return;}
const parent=$parent.get(0);const unit=parent.querySelector(".o_subscription_unit");if(!unit){return;}
unit.textContent=combination.temporal_unit_display;};publicWidget.registry.WebsiteSale.include({_onChangeCombination:function(){this._super.apply(this,arguments);VariantMixin._onChangeCombinationSubscription.apply(this,arguments);},});__exports[Symbol.for("default")]=VariantMixin;return __exports;});;

/* /website_sale/static/src/js/website_sale.js */
odoo.define('@website_sale/js/website_sale',['@web/legacy/js/public/public_widget','@website_sale/js/variant_mixin','@website_sale/js/website_sale_utils','@website/libs/zoomodoo/zoomodoo','@website/js/content/menu','@website_sale/js/components/website_sale_image_viewer','@web/core/network/rpc_service','@web/core/utils/timing','@web/core/ui/ui_service','@web/core/browser/feature_detection','@odoo/owl'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const VariantMixin=require("@website_sale/js/variant_mixin")[Symbol.for("default")];const wSaleUtils=require("@website_sale/js/website_sale_utils")[Symbol.for("default")];const cartHandlerMixin=wSaleUtils.cartHandlerMixin;require("@website/libs/zoomodoo/zoomodoo");const{extraMenuUpdateCallbacks}=require("@website/js/content/menu");const{ProductImageViewer}=require("@website_sale/js/components/website_sale_image_viewer");const{jsonrpc}=require("@web/core/network/rpc_service");const{debounce,throttleForAnimation}=require("@web/core/utils/timing");const{listenSizeChange,SIZES,utils:uiUtils}=require("@web/core/ui/ui_service");const{isBrowserFirefox,hasTouch}=require("@web/core/browser/feature_detection");const{Component}=require("@odoo/owl");const WebsiteSale=__exports.WebsiteSale=publicWidget.Widget.extend(VariantMixin,cartHandlerMixin,{selector:'.oe_website_sale',events:Object.assign({},VariantMixin.events||{},{'change form .js_product:first input[name="add_qty"]':'_onChangeAddQuantity','mouseup .js_publish':'_onMouseupPublish','touchend .js_publish':'_onMouseupPublish','change .oe_cart input.js_quantity[data-product-id]':'_onChangeCartQuantity','click .oe_cart a.js_add_suggested_products':'_onClickSuggestedProduct','click a.js_add_cart_json':'_onClickAddCartJSON','click .a-submit':'_onClickSubmit','change form.js_attributes input, form.js_attributes select':'_onChangeAttribute','mouseup form.js_add_cart_json label':'_onMouseupAddCartLabel','touchend form.js_add_cart_json label':'_onMouseupAddCartLabel','submit .o_wsale_products_searchbar_form':'_onSubmitSaleSearch','change select[name="country_id"]':'_onChangeCountry','change #shipping_use_same':'_onChangeShippingUseSame','click .toggle_summary':'_onToggleSummary','click #add_to_cart, .o_we_buy_now, #products_grid .o_wsale_product_btn .a-submit':'async _onClickAdd','click input.js_product_change':'onChangeVariant','change .js_main_product [data-attribute_exclusions]':'onChangeVariant','change oe_advanced_configurator_modal [data-attribute_exclusions]':'onChangeVariant','click .o_product_page_reviews_link':'_onClickReviewsLink','mousedown .o_wsale_filmstip_wrapper':'_onMouseDown','mouseleave .o_wsale_filmstip_wrapper':'_onMouseLeave','mouseup .o_wsale_filmstip_wrapper':'_onMouseUp','mousemove .o_wsale_filmstip_wrapper':'_onMouseMove','click .o_wsale_filmstip_wrapper':'_onClickHandler','submit':'_onClickConfirmOrder',"change select[name='state_id']":"_onChangeState",}),init:function(){this._super.apply(this,arguments);this._changeCartQuantity=debounce(this._changeCartQuantity.bind(this),500);this._changeCountry=debounce(this._changeCountry.bind(this),500);this.isWebsite=true;this.filmStripStartX=0;this.filmStripIsDown=false;this.filmStripScrollLeft=0;this.filmStripMoved=false;delete this.events['change .main_product:not(.in_cart) input.js_quantity'];delete this.events['change [data-attribute_exclusions]'];this.rpc=this.bindService("rpc");},start(){const def=this._super(...arguments);this._applyHashFromSearch();this.$("div.js_product").toArray().forEach((product)=>{$('input.js_product_change',product).first().trigger('change');});this.triggerVariantChange(this.$el);this.$('select[name="country_id"]').change();listenSizeChange(()=>{if(uiUtils.getSize()===SIZES.XL){$('.toggle_summary_div').addClass('d-none d-xl-block');}})
this._startZoom();window.addEventListener('hashchange',()=>{this._applyHash();this.triggerVariantChange(this.$el);});const filmstripContainer=this.el.querySelector('.o_wsale_filmstip_container');const filmstripContainerWidth=filmstripContainer?filmstripContainer.getBoundingClientRect().width:0;const filmstripWrapper=this.el.querySelector('.o_wsale_filmstip_wrapper');const filmstripWrapperWidth=filmstripWrapper?filmstripWrapper.getBoundingClientRect().width:0;const isFilmstripScrollable=filmstripWrapperWidth<filmstripContainerWidth
if(isBrowserFirefox()||hasTouch()||isFilmstripScrollable){filmstripContainer?.classList.add('o_wsale_filmstip_fancy_disabled');}
this.getRedirectOption();return def;},destroy(){this._super.apply(this,arguments);this._cleanupZoom();},getSelectedVariantValues:function($container){var combination=$container.find('input.js_product_change:checked').data('combination');if(combination){return combination;}
return VariantMixin.getSelectedVariantValues.apply(this,arguments);},_onMouseDown:function(ev){this.filmStripIsDown=true;this.filmStripStartX=ev.pageX-ev.currentTarget.offsetLeft;this.filmStripScrollLeft=ev.currentTarget.scrollLeft;this.formerTarget=ev.target;this.filmStripMoved=false;},_onMouseLeave:function(ev){if(!this.filmStripIsDown){return;}
ev.currentTarget.classList.remove('activeDrag');this.filmStripIsDown=false},_onMouseUp:function(ev){this.filmStripIsDown=false;ev.currentTarget.classList.remove('activeDrag');},_onMouseMove:function(ev){if(!this.filmStripIsDown){return;}
ev.preventDefault();ev.currentTarget.classList.add('activeDrag');this.filmStripMoved=true;const x=ev.pageX-ev.currentTarget.offsetLeft;const walk=(x-this.filmStripStartX)*2;ev.currentTarget.scrollLeft=this.filmStripScrollLeft-walk;},_onClickHandler:function(ev){if(this.filmStripMoved){ev.stopPropagation();ev.preventDefault();}},_applyHash:function(){const params=new URLSearchParams(window.location.hash.substring(1));if(params.get("attr")){var attributeIds=params.get("attr").split(',');var $inputs=this.$('input.js_variant_change, select.js_variant_change option');attributeIds.forEach((id)=>{var $toSelect=$inputs.filter('[data-value_id="'+id+'"]');if($toSelect.is('input[type="radio"]')){$toSelect.prop('checked',true);}else if($toSelect.is('option')){$toSelect.prop('selected',true);}});this._changeAttribute(['.css_attribute_color','.o_variant_pills']);}},_setUrlHash:function($parent){var $attributes=$parent.find('input.js_variant_change:checked, select.js_variant_change option:selected');if(!$attributes.length){return;}
var attributeIds=$attributes.toArray().map((elem)=>$(elem).data("value_id"));window.location.replace('#attr='+attributeIds.join(','));},_changeAttribute:function(valueSelectors){valueSelectors.forEach((selector)=>{$(selector).removeClass("active").filter(":has(input:checked)").addClass("active");});},_changeCartQuantity:function($input,value,$dom_optional,line_id,productIDs){$($dom_optional).toArray().forEach((elem)=>{$(elem).find('.js_quantity').text(value);productIDs.push($(elem).find('span[data-product-id]').data('product-id'));});$input.data('update_change',true);this.rpc("/shop/cart/update_json",{line_id:line_id,product_id:parseInt($input.data('product-id'),10),set_qty:value,display:true,}).then((data)=>{$input.data('update_change',false);var check_value=parseInt($input.val()||0,10);if(isNaN(check_value)){check_value=1;}
if(value!==check_value){$input.trigger('change');return;}
if(!data.cart_quantity){return window.location='/shop/cart';}
$input.val(data.quantity);$('.js_quantity[data-line-id='+line_id+']').val(data.quantity).text(data.quantity);wSaleUtils.updateCartNavBar(data);wSaleUtils.showWarning(data.notification_info.warning);Component.env.bus.trigger('cart_amount_changed',[data.amount,data.minor_amount]);});},_changeCountry:function(){if(!$("#country_id").val()){return;}
return this.rpc("/shop/country_infos/"+$("#country_id").val(),{mode:$("#country_id").attr('mode'),}).then(function(data){$("input[name='phone']").attr('placeholder',data.phone_code!==0?'+'+data.phone_code:'');var selectStates=$("select[name='state_id']");if(selectStates.data('init')===0||selectStates.find('option').length===1){if(data.states.length||data.state_required){selectStates.html('');data.states.forEach((x)=>{var opt=$('<option>').text(x[1]).attr('value',x[0]).attr('data-code',x[2]);selectStates.append(opt);});selectStates.parent('div').show();}else{selectStates.val('').parent('div').hide();}
selectStates.data('init',0);}else{selectStates.data('init',0);}
if(data.fields){if($.inArray('zip',data.fields)>$.inArray('city',data.fields)){$(".div_zip").before($(".div_city"));}else{$(".div_zip").after($(".div_city"));}
var all_fields=["street","zip","city","country_name"];all_fields.forEach((field)=>{$(".checkout_autoformat .div_"+field.split('_')[0]).toggle($.inArray(field,data.fields)>=0);});}
if($("label[for='zip']").length){$("label[for='zip']").toggleClass('label-optional',!data.zip_required);$("label[for='zip']").get(0).toggleAttribute('required',!!data.zip_required);}
if($("label[for='zip']").length){$("label[for='state_id']").toggleClass('label-optional',!data.state_required);$("label[for='state_id']").get(0).toggleAttribute('required',!!data.state_required);}});},_getProductId:function($parent){if($parent.find('input.js_product_change').length!==0){return parseInt($parent.find('input.js_product_change:checked').val());}
else{return VariantMixin._getProductId.apply(this,arguments);}},_getProductImageLayout:function(){return document.querySelector("#product_detail_main").dataset.image_layout;},_getProductImageWidth:function(){return document.querySelector("#product_detail_main").dataset.image_width;},_getProductImageContainerSelector:function(){return{'carousel':"#o-carousel-product",'grid':"#o-grid-product",}[this._getProductImageLayout()];},_getProductImageContainer:function(){return document.querySelector(this._getProductImageContainerSelector());},_isEditorEnabled(){return document.body.classList.contains("editor_enable");},_startZoom:function(){const salePage=document.querySelector(".o_wsale_product_page");if(!salePage||this._getProductImageWidth()==="none"){return;}
this._cleanupZoom();this.zoomCleanup=[];if(salePage.dataset.ecomZoomAuto&&!uiUtils.isSmall()){const images=salePage.querySelectorAll("img[data-zoom]");for(const image of images){const $image=$(image);const callback=()=>{$image.zoomOdoo({event:"mouseenter",attach:this._getProductImageContainerSelector(),preventClicks:salePage.dataset.ecomZoomClick,attachToTarget:this._getProductImageLayout()==="grid",});image.dataset.zoom=1;};image.addEventListener('load',callback);this.zoomCleanup.push(()=>{image.removeEventListener('load',callback);const zoomOdoo=$image.data("zoomOdoo");if(zoomOdoo){zoomOdoo.hide();$image.unbind();}});if(image.complete){callback();}}}
if(salePage.dataset.ecomZoomClick){const images=salePage.querySelectorAll(".product_detail_img");for(const image of images){const handler=()=>{if(salePage.dataset.ecomZoomAuto){const flyouts=document.querySelectorAll(".zoomodoo-flyout");for(const flyout of flyouts){flyout.remove();}}
this.call("dialog","add",ProductImageViewer,{selectedImageIdx:[...images].indexOf(image),images,});};image.addEventListener("click",handler);this.zoomCleanup.push(()=>{image.removeEventListener("click",handler);});}}},_cleanupZoom(){if(!this.zoomCleanup||!this.zoomCleanup.length){return;}
for(const cleanup of this.zoomCleanup){cleanup();}
this.zoomCleanup=undefined;},_updateProductImage:function($productContainer,displayImage,productId,productTemplateId,newImages,isCombinationPossible){let $images=$productContainer.find(this._getProductImageContainerSelector());if($images.length&&!this._isEditorEnabled()){const $newImages=$(newImages);$images.after($newImages);$images.remove();$images=$newImages;if($images.attr('id')==='o-carousel-product'){$images.carousel(0);}
this._startZoom();this.trigger_up('widgets_start_request',{$target:$images});}
$images.toggleClass('css_not_available',!isCombinationPossible);},_onClickAdd:function(ev){ev.preventDefault();var def=()=>{this.getCartHandlerOptions(ev);return this._handleAdd($(ev.currentTarget).closest('form'));};if($('.js_add_cart_variants').children().length){return this._getCombinationInfo(ev).then(()=>{return!$(ev.target).closest('.js_product').hasClass("css_not_available")?def():Promise.resolve();});}
return def();},_handleAdd:function($form){var self=this;this.$form=$form;var productSelector=['input[type="hidden"][name="product_id"]','input[type="radio"][name="product_id"]:checked'];var productReady=this.selectOrCreateProduct($form,parseInt($form.find(productSelector.join(', ')).first().val(),10),$form.find('.product_template_id').val(),false);return productReady.then(function(productId){$form.find(productSelector.join(', ')).val(productId);self._updateRootProduct($form,productId);return self._onProductReady();});},_onProductReady:function(){return this._submitForm();},_submitForm:function(){const params=this.rootProduct;const $product=$('#product_detail');const productTrackingInfo=$product.data('product-tracking-info');if(productTrackingInfo){productTrackingInfo.quantity=params.quantity;$product.trigger('add_to_cart_event',[productTrackingInfo]);}
params.add_qty=params.quantity;params.product_custom_attribute_values=JSON.stringify(params.product_custom_attribute_values);params.no_variant_attribute_values=JSON.stringify(params.no_variant_attribute_values);delete params.quantity;return this.addToCart(params);},_onClickAddCartJSON:function(ev){this.onClickAddCartJSON(ev);},_onChangeAddQuantity:function(ev){this.onChangeAddQuantity(ev);},_onMouseupPublish:function(ev){$(ev.currentTarget).parents('.thumbnail').toggleClass('disabled');},_onChangeCartQuantity:function(ev){var $input=$(ev.currentTarget);if($input.data('update_change')){return;}
var value=parseInt($input.val()||0,10);if(isNaN(value)){value=1;}
var $dom=$input.closest('tr');var $dom_optional=$dom.nextUntil(':not(.optional_product.info)');var line_id=parseInt($input.data('line-id'),10);var productIDs=[parseInt($input.data('product-id'),10)];this._changeCartQuantity($input,value,$dom_optional,line_id,productIDs);},_onClickSuggestedProduct:function(ev){$(ev.currentTarget).prev('input').val(1).trigger('change');},_onClickSubmit:function(ev,forceSubmit){if($(ev.currentTarget).is('#add_to_cart, #products_grid .a-submit')&&!forceSubmit){return;}
var $aSubmit=$(ev.currentTarget);if(!ev.isDefaultPrevented()&&!$aSubmit.is(".disabled")){ev.preventDefault();$aSubmit.closest('form').submit();}
if($aSubmit.hasClass('a-submit-disable')){$aSubmit.addClass("disabled");}
if($aSubmit.hasClass('a-submit-loading')){var loading='<span class="fa fa-cog fa-spin"/>';var fa_span=$aSubmit.find('span[class*="fa"]');if(fa_span.length){fa_span.replaceWith(loading);}else{$aSubmit.append(loading);}}},_onChangeAttribute:function(ev){if(!ev.isDefaultPrevented()){ev.preventDefault();const productGrid=this.el.querySelector(".o_wsale_products_grid_table_wrapper");if(productGrid){productGrid.classList.add("opacity-50");}
$(ev.currentTarget).closest("form").submit();}},_onMouseupAddCartLabel:function(ev){var $label=$(ev.currentTarget);var $price=$label.parents("form:first").find(".oe_price .oe_currency_value");if(!$price.data("price")){$price.data("price",parseFloat($price.text()));}
var value=$price.data("price")+parseFloat($label.find(".badge span").text()||0);var dec=value%1;$price.html(value+(dec<0.01?".00":(dec<1?"0":"")));},_onSubmitSaleSearch:function(ev){if(!this.$('.dropdown_sorty_by').length){return;}
var $this=$(ev.currentTarget);if(!ev.isDefaultPrevented()&&!$this.is(".disabled")){ev.preventDefault();var oldurl=$this.attr('action');oldurl+=(oldurl.indexOf("?")===-1)?"?":"";if($this.find('[name=noFuzzy]').val()==="true"){oldurl+='&noFuzzy=true';}
var search=$this.find('input.search-query');window.location=oldurl+'&'+search.attr('name')+'='+encodeURIComponent(search.val());}},_onChangeCountry:function(ev){if(!this.$('.checkout_autoformat').length){return;}
return this._changeCountry();},_onChangeState:function(ev){return Promise.resolve();},_onChangeShippingUseSame:function(ev){$('.ship_to_other').toggle(!$(ev.currentTarget).prop('checked'));},_toggleDisable:function($parent,isCombinationPossible){VariantMixin._toggleDisable.apply(this,arguments);$parent.find("#add_to_cart").toggleClass('disabled',!isCombinationPossible);$parent.find(".o_we_buy_now").toggleClass('disabled',!isCombinationPossible);},onChangeVariant:function(ev){var $component=$(ev.currentTarget).closest('.js_product');$component.find('input').each(function(){var $el=$(this);$el.attr('checked',$el.is(':checked'));});$component.find('select option').each(function(){var $el=$(this);$el.attr('selected',$el.is(':selected'));});this._setUrlHash($component);return VariantMixin.onChangeVariant.apply(this,arguments);},_onToggleSummary:function(){$('.toggle_summary_div').toggleClass('d-none');$('.toggle_summary_div').removeClass('d-xl-block');},_applyHashFromSearch(){const params=new URL(window.location).searchParams;if(params.get("attrib")){const dataValueIds=[];for(const attrib of[].concat(params.get("attrib"))){const attribSplit=attrib.split('-');const attribValueSelector=`.js_variant_change[name="ptal-${attribSplit[0]}"][value="${attribSplit[1]}"]`;const attribValue=this.el.querySelector(attribValueSelector);if(attribValue!==null){dataValueIds.push(attribValue.dataset.value_id);}}
if(dataValueIds.length){window.location.hash=`attr=${dataValueIds.join(',')}`;}}
this._applyHash();},_onClickReviewsLink:function(){$('#o_product_page_reviews_content').collapse('show');},_onClickConfirmOrder:function(){const submitFormButton=$('form[name="o_wsale_confirm_order"]').find('button[type="submit"]');submitFormButton.attr('disabled',true);setTimeout(()=>submitFormButton.attr('disabled',false),5000);},_updateRootProduct($form,productId){this.rootProduct={product_id:productId,quantity:parseFloat($form.find('input[name="add_qty"]').val()||1),product_custom_attribute_values:this.getCustomVariantValues($form.find('.js_product')),variant_values:this.getSelectedVariantValues($form.find('.js_product')),no_variant_attribute_values:this.getNoVariantAttributeValues($form.find('.js_product'))};},});publicWidget.registry.WebsiteSale=WebsiteSale
publicWidget.registry.WebsiteSaleLayout=publicWidget.Widget.extend({selector:'.oe_website_sale',disabledInEditableMode:false,events:{'change .o_wsale_apply_layout input':'_onApplyShopLayoutChange',},_onApplyShopLayoutChange:function(ev){const wysiwyg=this.options.wysiwyg;if(wysiwyg){wysiwyg.odooEditor.observerUnactive('_onApplyShopLayoutChange');}
var clickedValue=$(ev.target).val();var isList=clickedValue==='list';if(!this.editableMode){jsonrpc('/shop/save_shop_layout_mode',{'layout_mode':isList?'list':'grid',});}
const activeClasses=ev.target.parentElement.dataset.activeClasses.split(' ');ev.target.parentElement.querySelectorAll('.btn').forEach((btn)=>{activeClasses.map(c=>btn.classList.toggle(c));});var $grid=this.$('#products_grid');$grid.find('*').css('transition','none');$grid.toggleClass('o_wsale_layout_list',isList);void $grid[0].offsetWidth;$grid.find('*').css('transition','');if(wysiwyg){wysiwyg.odooEditor.observerActive('_onApplyShopLayoutChange');}},});publicWidget.registry.websiteSaleCart=publicWidget.Widget.extend({selector:'.oe_website_sale .oe_cart',events:{'click .js_change_billing':'_onClickChangeBilling','click .js_change_shipping':'_onClickChangeShipping','click .js_edit_address':'_onClickEditAddress','click .js_delete_product':'_onClickDeleteProduct',},_onClickChangeBilling:function(ev){this._onClickChangeAddress(ev,'all_billing','js_change_billing');},_onClickChangeShipping:function(ev){this._onClickChangeAddress(ev,'all_shipping','js_change_shipping');},_onClickChangeAddress:function(ev,rowAddrClass,cardClass){var $old=$(`.${rowAddrClass}`).find('.card.border.border-primary');$old.find('.btn-addr').toggle();$old.addClass(cardClass);$old.removeClass('bg-primary border border-primary');var $new=$(ev.currentTarget).parent('div.one_kanban').find('.card');$new.find('.btn-addr').toggle();$new.removeClass(cardClass);$new.addClass('bg-primary border border-primary');var $form=$(ev.currentTarget).parent('div.one_kanban').find('form.d-none');$.post($form.attr('action'),$form.serialize()+'&xhr=1');},_onClickEditAddress:function(ev){ev.stopPropagation();},_onClickDeleteProduct:function(ev){ev.preventDefault();$(ev.currentTarget).closest('.o_cart_product').find('.js_quantity').val(0).trigger('change');},});publicWidget.registry.websiteSaleCarouselProduct=publicWidget.Widget.extend({selector:'#o-carousel-product',disabledInEditableMode:false,events:{'wheel .o_carousel_product_indicators':'_onMouseWheel',},async start(){await this._super(...arguments);this._updateCarouselPosition();this.throttleOnResize=throttleForAnimation(this._onSlideCarouselProduct.bind(this));extraMenuUpdateCallbacks.push(this._updateCarouselPosition.bind(this));if(this.$el.find('.carousel-indicators').length>0){this.$el.on('slide.bs.carousel.carousel_product_slider',this._onSlideCarouselProduct.bind(this));$(window).on('resize.carousel_product_slider',this.throttleOnResize);this._updateJustifyContent();}},destroy(){this.$el.css('top','');this.$el.off('.carousel_product_slider');if(this.throttleOnResize){this.throttleOnResize.cancel();}
this._super(...arguments);},_updateCarouselPosition(){let size=5;for(const el of document.querySelectorAll('.o_top_fixed_element')){size+=$(el).outerHeight();}
this.$el.css('top',size);},_onSlideCarouselProduct:function(ev){const isReversed=this.$el.css('flex-direction')==="column-reverse";const isLeftIndicators=this.$el.hasClass('o_carousel_product_left_indicators');const $indicatorsDiv=isLeftIndicators?this.$el.find('.o_carousel_product_indicators'):this.$el.find('.carousel-indicators');let indicatorIndex=$(ev.relatedTarget).index();indicatorIndex=indicatorIndex>-1?indicatorIndex:this.$el.find('li.active').index();const $indicator=$indicatorsDiv.find('[data-bs-slide-to='+indicatorIndex+']');const indicatorsDivSize=isLeftIndicators&&!isReversed?$indicatorsDiv.outerHeight():$indicatorsDiv.outerWidth();const indicatorSize=isLeftIndicators&&!isReversed?$indicator.outerHeight():$indicator.outerWidth();const indicatorPosition=isLeftIndicators&&!isReversed?$indicator.position().top:$indicator.position().left;const scrollSize=isLeftIndicators&&!isReversed?$indicatorsDiv[0].scrollHeight:$indicatorsDiv[0].scrollWidth;let indicatorsPositionDiff=(indicatorPosition+(indicatorSize/2))-(indicatorsDivSize/2);indicatorsPositionDiff=Math.min(indicatorsPositionDiff,scrollSize-indicatorsDivSize);this._updateJustifyContent();const indicatorsPositionX=isLeftIndicators&&!isReversed?'0':'-'+indicatorsPositionDiff;const indicatorsPositionY=isLeftIndicators&&!isReversed?'-'+indicatorsPositionDiff:'0';const translate3D=indicatorsPositionDiff>0?"translate3d("+indicatorsPositionX+"px,"+indicatorsPositionY+"px,0)":'';$indicatorsDiv.css("transform",translate3D);},_updateJustifyContent:function(){const $indicatorsDiv=this.$el.find('.carousel-indicators');$indicatorsDiv.css('justify-content','start');if(uiUtils.getSize()<=SIZES.MD){if(($indicatorsDiv.children().last().position().left+this.$el.find('li').outerWidth())<$indicatorsDiv.outerWidth()){$indicatorsDiv.css('justify-content','center');}}},_onMouseWheel:function(ev){ev.preventDefault();if(ev.originalEvent.deltaY>0){this.$el.carousel('next');}else{this.$el.carousel('prev');}},});publicWidget.registry.websiteSaleProductPageReviews=publicWidget.Widget.extend({selector:'#o_product_page_reviews',disabledInEditableMode:false,async start(){await this._super(...arguments);this._updateChatterComposerPosition();extraMenuUpdateCallbacks.push(this._updateChatterComposerPosition.bind(this));},destroy(){this.$el.find('.o_portal_chatter_composer').css('top','');this._super(...arguments);},_updateChatterComposerPosition(){let size=20;for(const el of document.querySelectorAll('.o_top_fixed_element')){size+=$(el).outerHeight();}
this.$el.find('.o_portal_chatter_composer').css('top',size);},});__exports[Symbol.for("default")]={WebsiteSale:publicWidget.registry.WebsiteSale,WebsiteSaleLayout:publicWidget.registry.WebsiteSaleLayout,websiteSaleCart:publicWidget.registry.websiteSaleCart,WebsiteSaleCarouselProduct:publicWidget.registry.websiteSaleCarouselProduct,WebsiteSaleProductPageReviews:publicWidget.registry.websiteSaleProductPageReviews,};return __exports;});;

/* /website_sale/static/src/js/website_sale_offcanvas.js */
odoo.define('@website_sale/js/website_sale_offcanvas',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.websiteSaleOffcanvas=publicWidget.Widget.extend({selector:'#o_wsale_offcanvas',events:{'show.bs.offcanvas':'_toggleFilters','hidden.bs.offcanvas':'_toggleFilters',},_toggleFilters:function(ev){for(const btn of this.el.querySelectorAll('button[data-status]')){if(btn.classList.contains('collapsed')&&btn.dataset.status=="active"||!btn.classList.contains('collapsed')&&btn.dataset.status=="inactive"){btn.click();}}},});return __exports;});;

/* /website_sale/static/src/js/website_sale_price_range_option.js */
odoo.define('@website_sale/js/website_sale_price_range_option',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.multirangePriceSelector=publicWidget.Widget.extend({selector:'.o_wsale_products_page',events:{'newRangeValue #o_wsale_price_range_option input[type="range"]':'_onPriceRangeSelected',},_onPriceRangeSelected(ev){const range=ev.currentTarget;const searchParams=new URLSearchParams(window.location.search);searchParams.delete("min_price");searchParams.delete("max_price");if(parseFloat(range.min)!==range.valueLow){searchParams.set("min_price",range.valueLow);}
if(parseFloat(range.max)!==range.valueHigh){searchParams.set("max_price",range.valueHigh);}
let product_list_div=this.el.querySelector('.o_wsale_products_grid_table_wrapper');if(product_list_div){product_list_div.classList.add('opacity-50');}
window.location.search=searchParams.toString();},});return __exports;});;

/* /website_sale/static/src/js/website_sale_utils.js */
odoo.define('@website_sale/js/website_sale_utils',['@web/core/l10n/translation','@website/js/utils'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const wUtils=require("@website/js/utils")[Symbol.for("default")];const cartHandlerMixin=__exports.cartHandlerMixin={getRedirectOption(){const html=document.documentElement;this.stayOnPageOption=html.dataset.add2cartRedirect==='1';this.forceDialog=html.dataset.add2cartRedirect==='2';},getCartHandlerOptions(ev){this.isBuyNow=ev.currentTarget.classList.contains('o_we_buy_now');const targetSelector=ev.currentTarget.dataset.animationSelector||'img';this.$itemImgContainer=this.$(ev.currentTarget).closest(`:has(${targetSelector})`);},addToCart(params){if(this.isBuyNow){params.express=true;}else if(this.stayOnPageOption){return this._addToCartInPage(params);}
return wUtils.sendRequest('/shop/cart/update',params);},async _addToCartInPage(params){const data=await this.rpc("/shop/cart/update_json",{...params,display:false,force_create:true,});if(data.cart_quantity&&(data.cart_quantity!==parseInt($(".my_cart_quantity").text()))){updateCartNavBar(data);};showCartNotification(this.call.bind(this),data.notification_info);return data;},};function animateClone($cart,$elem,offsetTop,offsetLeft){if(!$cart.length){return Promise.resolve();}
$cart.removeClass('d-none').find('.o_animate_blink').addClass('o_red_highlight o_shadow_animation').delay(500).queue(function(){$(this).removeClass("o_shadow_animation").dequeue();}).delay(2000).queue(function(){$(this).removeClass("o_red_highlight").dequeue();});return new Promise(function(resolve,reject){if(!$elem)resolve();var $imgtodrag=$elem.find('img').eq(0);if($imgtodrag.length){var $imgclone=$imgtodrag.clone().offset({top:$imgtodrag.offset().top,left:$imgtodrag.offset().left}).removeClass().addClass('o_website_sale_animate').appendTo(document.body).css({width:$imgtodrag.width(),height:$imgtodrag.height(),}).animate({top:$cart.offset().top+offsetTop,left:$cart.offset().left+offsetLeft,width:75,height:75,},500);$imgclone.animate({width:0,height:0,},function(){resolve();$(this).detach();});}else{resolve();}});}
function updateCartNavBar(data){sessionStorage.setItem('website_sale_cart_quantity',data.cart_quantity);$(".my_cart_quantity").parents('li.o_wsale_my_cart').removeClass('d-none').end().toggleClass('d-none',data.cart_quantity===0).addClass('o_mycart_zoom_animation').delay(300).queue(function(){$(this).toggleClass('fa fa-warning',!data.cart_quantity).attr('title',data.warning).text(data.cart_quantity||'').removeClass('o_mycart_zoom_animation').dequeue();});$(".js_cart_lines").first().before(data['website_sale.cart_lines']).end().remove();$("#cart_total").replaceWith(data['website_sale.total']);if(data.cart_ready){document.querySelector("a[name='website_sale_main_button']")?.classList.remove('disabled');}else{document.querySelector("a[name='website_sale_main_button']")?.classList.add('disabled');}}
function showCartNotification(callService,props,options={}){if(props.lines){callService("cartNotificationService","add",_t("Item(s) added to your cart"),{lines:props.lines,currency_id:props.currency_id,...options,});}
if(props.warning){callService("cartNotificationService","add",_t("Warning"),{warning:props.warning,...options,});}}
function showWarning(message){if(!message){return;}
var $page=$('.oe_website_sale');var cart_alert=$page.children('#data_warning');if(!cart_alert.length){cart_alert=$('<div class="alert alert-danger alert-dismissible" role="alert" id="data_warning">'+'<button type="button" class="btn-close" data-bs-dismiss="alert"></button> '+'<span></span>'+'</div>').prependTo($page);}
cart_alert.children('span:last-child').text(message);}
__exports[Symbol.for("default")]={animateClone:animateClone,updateCartNavBar:updateCartNavBar,cartHandlerMixin:cartHandlerMixin,showCartNotification:showCartNotification,showWarning:showWarning,};return __exports;});;

/* /website_sale/static/src/js/website_sale_recently_viewed.js */
odoo.define('@website_sale/js/website_sale_recently_viewed',['@web/core/utils/timing','@web/legacy/js/public/public_widget','@web/core/browser/cookie'],function(require){'use strict';let __exports={};const{debounce}=require("@web/core/utils/timing");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{cookie}=require("@web/core/browser/cookie");;publicWidget.registry.productsRecentlyViewedUpdate=publicWidget.Widget.extend({selector:'#product_detail',events:{'change input.product_id[name="product_id"]':'_onProductChange',},debounceValue:8000,init:function(){this._super.apply(this,arguments);this._onProductChange=debounce(this._onProductChange,this.debounceValue);this.rpc=this.bindService("rpc");},_updateProductView:function($input){var productId=parseInt($input.val());var cookieName='seen_product_id_'+productId;if(!parseInt(this.el.dataset.viewTrack,10)){return;}
if(cookie.get(cookieName)){return;}
if($(this.el).find('.js_product.css_not_available').length){return;}
this.rpc('/shop/products/recently_viewed_update',{product_id:productId,}).then(function(res){cookie.set(cookieName,productId,30*60,'optional');});},_onProductChange:function(ev){this._updateProductView($(ev.currentTarget));},});return __exports;});;

/* /website_sale/static/src/js/website_sale_tracking.js */
odoo.define('@website_sale/js/website_sale_tracking',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.websiteSaleTracking=publicWidget.Widget.extend({selector:'.oe_website_sale',events:{'click form[action="/shop/cart/update"] a.a-submit':'_onAddProductIntoCart','click a[href^="/shop/checkout"]':'_onCheckoutStart','click a[href^="/web/login?redirect"][href*="/shop/checkout"]':'_onCustomerSignin','click form[action="/shop/confirm_order"] a.a-submit':'_onOrder','click form[target="_self"] button[type=submit]':'_onOrderPayment','view_item_event':'_onViewItem','add_to_cart_event':'_onAddToCart',},start:function(){var self=this;const $confirmation=this.$('div.oe_website_sale_tx_status');if($confirmation.length){const orderID=$confirmation.data('order-id');const json=$confirmation.data('order-tracking-info');this._vpv('/stats/ecom/order_confirmed/'+orderID);self._trackGA('event','purchase',json);}
return this._super.apply(this,arguments);},_trackGA:function(){const websiteGA=window.gtag||function(){};websiteGA.apply(this,arguments);},_vpv:function(page){this._trackGA('event','page_view',{'page_path':page,});},_onViewItem(event,productTrackingInfo){const trackingInfo={'currency':productTrackingInfo['currency'],'value':productTrackingInfo['price'],'items':[productTrackingInfo],};this._trackGA('event','view_item',trackingInfo);},_onAddToCart(event,...productsTrackingInfo){const trackingInfo={'currency':productsTrackingInfo[0]['currency'],'value':productsTrackingInfo.reduce((acc,val)=>acc+val['price']*val['quantity'],0),'items':productsTrackingInfo,};this._trackGA('event','add_to_cart',trackingInfo);},_onAddProductIntoCart:function(){var productID=this.$('input[name="product_id"]').attr('value');this._vpv('/stats/ecom/product_add_to_cart/'+productID);},_onCheckoutStart:function(){this._vpv('/stats/ecom/customer_checkout');},_onCustomerSignin:function(){this._vpv('/stats/ecom/customer_signin');},_onOrder:function(){if($('header#top [href="/web/login"]').length){this._vpv('/stats/ecom/customer_signup');}
this._vpv('/stats/ecom/order_checkout');},_onOrderPayment:function(){var method=$('#payment_method input[name=provider]:checked').nextAll('span:first').text();this._vpv('/stats/ecom/order_payment/'+method);},});__exports[Symbol.for("default")]=publicWidget.registry.websiteSaleTracking;return __exports;});;

/* /website/static/lib/multirange/multirange_custom.js */
odoo.define('@website/../lib/multirange/multirange_custom',[],function(require){'use strict';let __exports={};const HTMLInputElement=window.HTMLInputElement;const descriptor=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value");const Multirange=__exports.Multirange=class Multirange{constructor(input,options={}){const self=this;this.input=input;this.rangeWithInput=options.rangeWithInput===true||this.input.classList.contains('range-with-input');const value=options.value||this.input.getAttribute("value");const values=value===null?[]:value.split(",");this.input.min=this.min=options.min||this.input.min||0;this.input.max=this.max=options.max||this.input.max||100;this.input.step=this.step=options.step||this.input.step||1;this.currency=options.currency||this.input.dataset.currency||'';this.currencyPosition=options.currencyPosition||this.input.dataset.currencyPosition||'after';const inputClasses=["multirange","d-inline-block","p-0","align-top"];this.rangeDiv=document.createElement("div");this.rangeDiv.classList.add("multirange-wrapper","position-relative","mb-5");this.countersWrapper=document.createElement("small");this.countersWrapper.classList.add("d-flex","justify-content-between","mt-2");this.rangeDiv.appendChild(this.countersWrapper);this.input.parentNode.insertBefore(this.rangeDiv,this.input.nextSibling);this.rangeDiv.appendChild(this.input);this.ghost=this.input.cloneNode();this.rangeDiv.appendChild(this.ghost);this.input.classList.add("original","position-absolute","w-100","m-0",...inputClasses);this.ghost.classList.add("ghost","position-relative",...inputClasses);this.input.value=values[0]||this.min;this.ghost.value=values[1]||this.max;this.leftCounter=document.createElement("span");this.leftCounter.classList.add("multirange-min","position-absolute","opacity-75","opacity-100-hover","mt-1");this.rightCounter=document.createElement("span");this.rightCounter.classList.add("multirange-max","position-absolute","opacity-75","opacity-100-hover","mt-1","end-0");this.countersWrapper.append(this.leftCounter,this.rightCounter);if(this.rangeWithInput){this.leftInput=document.createElement("input");this.leftInput.type="number";this.leftInput.classList.add("invisible","form-control","form-control-sm","mb-2","mb-lg-1");this.leftInput.min=this.min;this.leftInput.max=this.max;this.leftInput.step=this.step;this.rightInput=this.leftInput.cloneNode();this.leftInput.classList.add("multirange-min","invisible");this.rightInput.classList.add("multirange-max","invisible");this.leftCounter.parentNode.appendChild(this.leftInput);this.rightCounter.parentNode.appendChild(this.rightInput);}
Object.defineProperty(this.input,"originalValue",descriptor.get?descriptor:{get:function(){return this.value;},set:function(v){this.value=v;}});Object.defineProperties(this.input,{valueLow:{get:function(){return Math.min(this.originalValue,self.ghost.value);},set:function(v){this.originalValue=v;},enumerable:true},valueHigh:{get:function(){return Math.max(this.originalValue,self.ghost.value);},set:function(v){self.ghost.value=v;},enumerable:true}});if(descriptor.get){Object.defineProperty(this.input,"value",{get:function(){return this.valueLow+","+this.valueHigh;},set:function(v){const values=v.split(",");this.valueLow=values[0];this.valueHigh=values[1];this.update();},enumerable:true});}
if(typeof this.input.oninput==="function"){this.ghost.oninput=this.input.oninput.bind(this.input);}
this.input.addEventListener("input",this.update.bind(this));this.ghost.addEventListener("input",this.update.bind(this));this.input.addEventListener("touchstart",this.saveOldValues.bind(this));this.ghost.addEventListener("touchstart",this.saveOldValues.bind(this));this.input.addEventListener("mousedown",this.saveOldValues.bind(this));this.ghost.addEventListener("mousedown",this.saveOldValues.bind(this));this.input.addEventListener("touchend",this.dispatchNewValueEvent.bind(this));this.ghost.addEventListener("touchend",this.dispatchNewValueEvent.bind(this));this.input.addEventListener("mouseup",this.dispatchNewValueEvent.bind(this));this.ghost.addEventListener("mouseup",this.dispatchNewValueEvent.bind(this));if(this.rangeWithInput){this.leftCounter.addEventListener("click",this.counterInputSwitch.bind(this));this.rightCounter.addEventListener("click",this.counterInputSwitch.bind(this));this.leftInput.addEventListener("blur",this.counterInputSwitch.bind(this));this.rightInput.addEventListener("blur",this.counterInputSwitch.bind(this));this.leftInput.addEventListener("keypress",this.elementBlurOnEnter.bind(this));this.rightInput.addEventListener("keypress",this.elementBlurOnEnter.bind(this));this.leftInput.addEventListener("focus",this.selectAllFocus.bind(this));this.rightInput.addEventListener("focus",this.selectAllFocus.bind(this));}
this.update();$(this.rangeDiv).addClass('visible');}
update(){const low=100*(this.input.valueLow-this.min)/(this.max-this.min);const high=100*(this.input.valueHigh-this.min)/(this.max-this.min);this.rangeDiv.style.setProperty("--low",low+'%');this.rangeDiv.style.setProperty("--high",high+'%');this.counterInputUpdate();}
counterInputUpdate(){if(this.rangeWithInput){this.leftCounter.innerText=this.formatNumber(this.input.valueLow);this.rightCounter.innerText=this.formatNumber(this.input.valueHigh);this.leftInput.value=this.input.valueLow;this.rightInput.value=this.input.valueHigh;}}
counterInputSwitch(ev){let counter=this.rightCounter;let input=this.rightInput;if(ev.currentTarget.classList.contains('multirange-min')){counter=this.leftCounter;input=this.leftInput;}
if(counter.classList.contains("invisible")){this.input.valueLow=this.leftInput.value;this.input.valueHigh=this.rightInput.value;this.dispatchNewValueEvent();this.update();counter.classList.remove("invisible");input.classList.add("invisible");}else{counter.classList.add("invisible");input.classList.remove("invisible");this.saveOldValues();window.setTimeout(function(){input.focus();},1);}}
elementBlurOnEnter(ev){if(ev.key==="Enter"){ev.currentTarget.blur();}}
selectAllFocus(ev){ev.currentTarget.select();}
dispatchNewValueEvent(){if(this._previousMaxPrice!==this.input.valueHigh||this._previousMinPrice!==this.input.valueLow){this.input.dispatchEvent(new CustomEvent("newRangeValue",{bubbles:true,}));}}
saveOldValues(){this._previousMinPrice=this.input.valueLow;this._previousMaxPrice=this.input.valueHigh;}
formatNumber(number){const language=document.querySelector("html").getAttribute("lang");const locale=language==="sr@latin"?"sr-Latn-RS":language.replace(/_/g,"-");let formatedNumber=number.toLocaleString(locale,{minimumFractionDigits:2,maximumFractionDigits:2,});if(this.currency.length){if(this.currencyPosition==='after'){formatedNumber=formatedNumber+' '+this.currency;}else{formatedNumber=this.currency+' '+formatedNumber;}}
return formatedNumber;}}
__exports.multirange=multirange;function multirange(input,options){if(input.classList.contains('multirange')){return;}
new Multirange(input,options);}
__exports[Symbol.for("default")]={Multirange:Multirange,init:multirange,};return __exports;});;

/* /website/static/lib/multirange/multirange_instance.js */
odoo.define('@website/../lib/multirange/multirange_instance',['@web/legacy/js/public/public_widget','@website/../lib/multirange/multirange_custom'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const multirange=require("@website/../lib/multirange/multirange_custom")[Symbol.for("default")];publicWidget.registry.WebsiteMultirangeInputs=publicWidget.Widget.extend({selector:'input[type=range][multiple]:not(.multirange)',start(){return this._super.apply(this,arguments).then(()=>{multirange.init(this.el);});},});return __exports;});;

/* /website_sale/static/src/js/website_sale_category_link.js */
odoo.define('@website_sale/js/website_sale_category_link',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")]
publicWidget.registry.ProductCategoriesLinks=publicWidget.Widget.extend({selector:'.o_wsale_products_page',events:{'click [data-link-href]':'_openLink',},_openLink:function(ev){const productsDiv=this.el.querySelector('.o_wsale_products_grid_table_wrapper');if(productsDiv){productsDiv.classList.add('opacity-50');}
window.location.href=ev.currentTarget.getAttribute('data-link-href');},});return __exports;});;

/* /website_sale/static/src/js/components/website_sale_image_viewer.js */
odoo.define('@website_sale/js/components/website_sale_image_viewer',['@web/core/dialog/dialog','@web/core/hotkeys/hotkey_hook','@odoo/owl'],function(require){'use strict';let __exports={};const{Dialog}=require("@web/core/dialog/dialog");const{useHotkey}=require("@web/core/hotkeys/hotkey_hook");const{onRendered,useRef,useEffect,useState}=require("@odoo/owl");const ZOOM_STEP=0.1;const ProductImageViewer=__exports.ProductImageViewer=class ProductImageViewer extends Dialog{setup(){super.setup();this.imageContainerRef=useRef("imageContainer");this.images=[...this.props.images].map(image=>{return{src:image.dataset.zoomImage||image.src,thumbnailSrc:image.src.replace('/image_1024/','/image_128/'),};});this.state=useState({selectedImageIdx:this.props.selectedImageIdx||0,imageScale:1,});this.isDragging=false;this.dragStartPos={x:0,y:0};this.imageTranslate={x:0,y:0};useHotkey("arrowleft",this.previousImage.bind(this));useHotkey("arrowright",this.nextImage.bind(this));useHotkey("r",()=>{this.imageTranslate={x:0,y:0};this.isDragging=false;this.state.imageScale=1;this.updateImage();});useEffect((document)=>{const onGlobalClick=this.onGlobalClick.bind(this);document.addEventListener("click",onGlobalClick);return()=>{document.removeEventListener("click",onGlobalClick)};},()=>[document],);onRendered(()=>{this.updateImage();})}
get selectedImage(){return this.images[this.state.selectedImageIdx];}
set selectedImage(image){this.state.imageScale=1;this.imageTranslate={x:0,y:0};this.state.selectedImageIdx=this.images.indexOf(image);}
get imageStyle(){return`transform:
            scale3d(${this.state.imageScale}, ${this.state.imageScale}, 1);
        `;}
get imageContainerStyle(){return`transform: translate(${this.imageTranslate.x}px, ${this.imageTranslate.y}px);`;}
previousImage(){this.selectedImage=this.images[(this.state.selectedImageIdx-1+this.images.length)%this.images.length];}
nextImage(){this.selectedImage=this.images[(this.state.selectedImageIdx+1)%this.images.length];}
updateImage(){if(!this.imageContainerRef||!this.imageContainerRef.el){return;}
this.imageContainerRef.el.style=this.imageContainerStyle;}
onGlobalClick(ev){if(ev.target.tagName==="IMG"){if(this.dragStartPos.clientX===ev.clientX&&this.dragStartPos.clientY===ev.clientY){this.zoomIn(ZOOM_STEP*3);}}
if(ev.target.classList.contains('o_wsale_image_viewer_void')&&!this.isDragging){ev.stopPropagation();ev.preventDefault();this.data.close();}else{this.isDragging=false;}}
zoomIn(step=undefined){this.state.imageScale+=step||ZOOM_STEP;}
zoomOut(step=undefined){this.state.imageScale=Math.max(0.5,this.state.imageScale-(step||ZOOM_STEP));}
onWheelImage(ev){if(ev.deltaY>0){this.zoomOut();}else{this.zoomIn();}}
onMousedownImage(ev){this.isDragging=true;this.dragStartPos={x:ev.clientX-this.imageTranslate.x,y:ev.clientY-this.imageTranslate.y,clientX:ev.clientX,clientY:ev.clientY,};}
onGlobalMousemove(ev){if(!this.isDragging){return;}
this.imageTranslate.x=ev.clientX-this.dragStartPos.x;this.imageTranslate.y=ev.clientY-this.dragStartPos.y;this.updateImage();}}
ProductImageViewer.props={...Dialog.props,images:{type:NodeList,required:true},selectedImageIdx:{type:Number,optional:true},close:Function,};delete ProductImageViewer.props.slots;ProductImageViewer.template="website_sale.ProductImageViewer";return __exports;});;

/* /website_sale/static/src/js/website_sale_reorder.js */
odoo.define('@website_sale/js/website_sale_reorder',['@web/core/l10n/translation','@web/core/utils/timing','@web/legacy/js/public/public_widget','@web/core/confirmation_dialog/confirmation_dialog','@web/core/currency','@web/core/utils/hooks','@web/core/dialog/dialog','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{debounce:debounceFn}=require("@web/core/utils/timing");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{ConfirmationDialog}=require("@web/core/confirmation_dialog/confirmation_dialog");const{formatCurrency}=require("@web/core/currency");publicWidget.registry.SaleOrderPortalReorderWidget=publicWidget.Widget.extend({selector:".o_portal_sidebar",events:{"click .o_wsale_reorder_button":"_onReorder",},_onReorder(ev){const orderId=parseInt(ev.currentTarget.dataset.saleOrderId);const urlSearchParams=new URLSearchParams(window.location.search);if(!orderId||!urlSearchParams.has("access_token")){return;}
this.call("dialog","add",ReorderDialog,{orderId:orderId,accessToken:urlSearchParams.get("access_token"),});},});const{useService}=require("@web/core/utils/hooks");const{Dialog}=require("@web/core/dialog/dialog");const{Component,onWillStart}=require("@odoo/owl");const ReorderConfirmationDialog=__exports.ReorderConfirmationDialog=class ReorderConfirmationDialog extends ConfirmationDialog{}
ReorderConfirmationDialog.template="website_sale.ReorderConfirmationDialog";const ReorderDialog=__exports.ReorderDialog=class ReorderDialog extends Component{setup(){this.rpc=useService("rpc");this.orm=useService("orm");this.dialogService=useService("dialog");this.formatCurrency=formatCurrency;onWillStart(this.onWillStartHandler.bind(this));}
async onWillStartHandler(){this.cartQty=parseInt(sessionStorage.getItem("website_sale_cart_quantity"));if(!this.cartQty){this.cartQty=await this.rpc("/shop/cart/quantity");}
this.content=await this.rpc("/my/orders/reorder_modal_content",{order_id:this.props.orderId,access_token:this.props.accessToken,});for(const product of this.content.products){product.debouncedLoadProductCombinationInfo=debounceFn(()=>{this.loadProductCombinationInfo(product).then(this.render.bind(this));},200);}}
get total(){return this.content.products.reduce((total,product)=>{if(product.add_to_cart_allowed){total+=product.combinationInfo.price*product.qty;}
return total;},0);}
get hasBuyableProducts(){return this.content.products.some((product)=>product.add_to_cart_allowed);}
async loadProductCombinationInfo(product){product.combinationInfo=await this.rpc("/website_sale/get_combination_info",{product_template_id:product.product_template_id,product_id:product.product_id,combination:product.combination,add_qty:product.qty,context:{website_sale_no_images:true,},});}
getWarningForProduct(product){if(!product.add_to_cart_allowed){return _t("This product is not available for purchase.");}
return false;}
changeProductQty(product,newQty){const productNewQty=Math.max(0,newQty);const qtyChanged=productNewQty!==product.qty;product.qty=productNewQty;this.render(true);if(!qtyChanged){return;}
product.debouncedLoadProductCombinationInfo();}
onChangeProductQtyInput(ev,product){const newQty=parseFloat(ev.target.value)||product.qty;this.changeProductQty(product,newQty);}
async confirmReorder(ev){if(this.confirmed){return;}
this.confirmed=true;const onConfirm=async()=>{await this.addProductsToCart();window.location="/shop/cart";};if(this.cartQty){this.dialogService.add(ReorderConfirmationDialog,{body:_t("Do you wish to clear your cart before adding products to it?"),confirm:async()=>{await this.rpc("/shop/cart/clear");await onConfirm();},cancel:onConfirm,});}else{await onConfirm();}}
async addProductsToCart(){for(const product of this.content.products){if(!product.add_to_cart_allowed){continue;}
await this.rpc("/shop/cart/update_json",{product_id:product.product_id,add_qty:product.qty,no_variant_attribute_values:JSON.stringify(product.no_variant_attribute_values),product_custom_attribute_values:JSON.stringify(product.product_custom_attribute_values),display:false,});}}}
ReorderDialog.props={close:Function,orderId:Number,accessToken:String,};ReorderDialog.components={Dialog,};ReorderDialog.template="website_sale.ReorderModal";return __exports;});;

/* /website_sale/static/src/js/website_sale_delivery.js */
odoo.define('@website_sale/js/website_sale_delivery',['@web/legacy/js/public/public_widget','@web/core/l10n/translation','@web/core/utils/render','@web/core/utils/concurrency','@odoo/owl'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{_t}=require("@web/core/l10n/translation");const{renderToElement}=require("@web/core/utils/render");const{KeepLast}=require("@web/core/utils/concurrency");const{Component}=require("@odoo/owl");publicWidget.registry.websiteSaleDelivery=publicWidget.Widget.extend({selector:'.oe_website_sale',events:{'change select[name="shipping_id"]':'_onSetAddress','click .o_delivery_carrier_select':'_onCarrierClick',"click .o_address_select":"_onClickLocation","click .o_remove_order_location":"_onClickRemoveLocation","click .o_show_pickup_locations":"_onClickShowLocations","click .o_payment_option_card":"_onClickPaymentMethod"},init(){this._super(...arguments);this.rpc=this.bindService("rpc");},start:async function(){this.carriers=Array.from(document.querySelectorAll('input[name="delivery_type"]'));this.keepLast=new KeepLast();if(this.carriers.length>0){const carrierChecked=this.carriers.filter(e=>e.checked)
if(carrierChecked.length===0){this._disablePayButton();}else{this.forceClickCarrier=true;await this._getCurrentLocation();carrierChecked[0].click();}}
await this.carriers.forEach(async(carrierInput)=>{this._showLoading((carrierInput));await this._getCarrierRateShipment(carrierInput);});if(this._super&&typeof(this._super.apply)==="function"){return this._super.apply(this,arguments);}},_getCurrentLocation:async function(){const data=await this.rpc("/shop/access_point/get");const carriers=document.querySelectorAll('.o_delivery_carrier_select')
for(let carrier of carriers){const deliveryType=carrier.querySelector('input[type="radio"]').getAttribute("delivery_type");const deliveryName=carrier.querySelector('label').innerText;const showLoc=carrier.querySelector(".o_show_pickup_locations");if(!showLoc){continue;}
const orderLoc=carrier.querySelector(".o_order_location");if(data[deliveryType+'_access_point']&&data.delivery_name==deliveryName){orderLoc.querySelector(".o_order_location_name").innerText=data.name
orderLoc.querySelector(".o_order_location_address").innerText=data[deliveryType+'_access_point']
orderLoc.parentElement.classList.remove("d-none");showLoc.classList.add("d-none");this.forceClickCarrier=false;break;}else{orderLoc.parentElement.classList.add("d-none");showLoc.classList.remove("d-none");}}},_specificDropperDisplay:function(docCarrier){if(!docCarrier?.closest("li").getElementsByTagName("input")[0].getAttribute("delivery_type")){return;}
while(docCarrier.firstChild){docCarrier.lastChild.remove();}
const currentCarrierChecked=docCarrier.closest("li").getElementsByTagName("input")[0].checked;const span=document.createElement("em");if(!currentCarrierChecked||this.carriers.length==1){span.textContent=_t("select to see available Pick-Up Locations");span.classList.add("text-muted");}
docCarrier.appendChild(span);},_showLoading:function(carrierInput){const priceTag=carrierInput.parentNode.querySelector('.o_wsale_delivery_badge_price')
while(priceTag.firstChild){priceTag.removeChild(priceTag.lastChild);}
const loadingCircle=priceTag.appendChild(document.createElement('span'));loadingCircle.classList.add("fa","fa-circle-o-notch","fa-spin");},_updateShippingCost:function(amount){Component.env.bus.trigger('update_shipping_cost',amount);},_getCarrierRateShipment:async function(carrierInput){const result=await this.rpc('/shop/carrier_rate_shipment',{'carrier_id':carrierInput.value,});this._handleCarrierUpdateResultBadge(result);},_handleCarrierUpdateResult:async function(carrierInput){const result=await this.rpc('/shop/update_carrier',{'carrier_id':carrierInput.value,'no_reset_access_point_address':this.forceClickCarrier,})
this.result=result;this._handleCarrierUpdateResultBadge(result);if(carrierInput.checked){var amountDelivery=document.querySelector('#order_delivery .monetary_field');var amountUntaxed=document.querySelector('#order_total_untaxed .monetary_field');var amountTax=document.querySelector('#order_total_taxes .monetary_field');var amountTotal=document.querySelectorAll('#order_total .monetary_field, #amount_total_summary.monetary_field');amountDelivery.innerHTML=result.new_amount_delivery;amountUntaxed.innerHTML=result.new_amount_untaxed;amountTax.innerHTML=result.new_amount_tax;amountTotal.forEach(total=>total.innerHTML=result.new_amount_total);if(result.new_amount_total_raw!==undefined){this._updateShippingCost(result.new_amount_total_raw);const hasPaymentMethod=document.querySelector("div[name='o_website_sale_free_cart']")===null;const shouldDisplayPaymentMethod=result.new_amount_total_raw!==0;if(hasPaymentMethod!==shouldDisplayPaymentMethod){location.reload(false);}}
this._updateShippingCost(result.new_amount_delivery);}
this._enableButton(result.status);let currentId=result.carrier_id
const showLocations=document.querySelectorAll(".o_show_pickup_locations");for(const showLoc of showLocations){const currentCarrierId=showLoc.closest("li").getElementsByTagName("input")[0].value;if(currentCarrierId==currentId){this._specificDropperDisplay(showLoc);break;}}},_handleCarrierUpdateResultBadge:function(result){var $carrierBadge=$('#delivery_carrier input[name="delivery_type"][value='+result.carrier_id+'] ~ .o_wsale_delivery_badge_price');if(result.status===true){if(result.is_free_delivery){$carrierBadge.text(_t('Free'));}else{$carrierBadge.html(result.new_amount_delivery);}
$carrierBadge.removeClass('o_wsale_delivery_carrier_error');}else{$carrierBadge.addClass('o_wsale_delivery_carrier_error');$carrierBadge.text(result.error_message);}},_disablePayButton:function(){Component.env.bus.trigger('disablePaymentButton');},_disablePayButtonNoPickupPoint:function(ev){const selectedCarrierEl=ev.currentTarget.closest('.o_delivery_carrier_select');const address=selectedCarrierEl.querySelector('.o_order_location_address').innerText
const orderLocationContainer=selectedCarrierEl.querySelector('.o_order_location').parentNode;const hasPickUpLocations=selectedCarrierEl.querySelector('.o_list_pickup_locations');document.querySelectorAll('.error_no_pick_up_point').forEach(el=>el.remove());if(hasPickUpLocations&&(address==""||orderLocationContainer.classList.contains("d-none"))){this._disablePayButton();const errorNode=document.createElement("i");errorNode.classList.add("small","error_no_pick_up_point","ms-2");errorNode.textContent=_t("Select a pick-up point");errorNode.style="color:red;";selectedCarrierEl.insertBefore(errorNode,selectedCarrierEl.querySelector("label").nextElementSibling);}},_checkCarrier:async function(ev,carrier_id){ev.stopPropagation();await this.keepLast.add(this.rpc('/shop/update_carrier',{carrier_id:carrier_id,}))
var closestDocElement=ev.currentTarget.closest('.o_delivery_carrier_select');var radio=closestDocElement.querySelector('input[type="radio"]');radio.checked=true;this._disablePayButtonNoPickupPoint(ev)},_onClickPaymentMethod:async function(ev){const carriers=Array.from(document.querySelectorAll('.o_delivery_carrier_select'))
if(carriers.length===0){return;}
this._disablePayButton();let carrierChecked=null;carriers.forEach((carrier)=>{if(carrier.querySelector('input').checked){carrierChecked=carrier;}})
if(!carrierChecked){return;}
const carrier_id=carrierChecked?.querySelector('input')?.value;const result=await this.rpc('/shop/update_carrier',{'carrier_id':carrier_id,'no_reset_access_point_address':true,})
this._enableButton(result.status);},_enableButton(status){if(status){Component.env.bus.trigger('enablePaymentButton');}
else{this._disablePayButton();}},_isPickupLocationSelected:function(ev){return!ev.currentTarget.closest('.o_delivery_carrier_select').querySelector(".o_order_location").parentElement.classList.contains("d-none");},_shouldDisplayPickupLocations:function(ev){const pickupPointsAreNeeded=ev.currentTarget.querySelector('.o_show_pickup_locations');const pickupPointsAreDisplayed=ev.currentTarget.querySelector('.o_list_pickup_locations')?.hasChildNodes();return pickupPointsAreNeeded&&!pickupPointsAreDisplayed&&!this._isPickupLocationSelected(ev);},_onClickRemoveLocation:async function(ev){ev.stopPropagation();await this.rpc("/shop/access_point/set",{access_point_encoded:null,})
const deliveryTypeInput=ev.currentTarget.closest(".o_delivery_carrier_select").querySelector('input[name="delivery_type"]');const deliveryTypeId=deliveryTypeInput.value;await Promise.all([this._getCurrentLocation(),this._checkCarrier(ev,deliveryTypeId)])
await this._onClickShowLocations(ev);},_onClickShowLocations:async function(ev){if(this._isPickupLocationSelected(ev)){return;}
const showPickupLocations=ev.currentTarget.closest('.o_delivery_carrier_select').querySelector('.o_show_pickup_locations');const modal=showPickupLocations?.nextElementSibling;if(!modal){return;}
while(modal.firstChild){modal.lastChild.remove();}
const deliveryTypeInput=ev.currentTarget.closest(".o_delivery_carrier_select").querySelector('input[name="delivery_type"]');const deliveryType=deliveryTypeInput.getAttribute("delivery_type");const deliveryTypeId=deliveryTypeInput.value;await this._checkCarrier(ev,deliveryTypeId)
$(renderToElement(deliveryType+"_pickup_location_loading")).appendTo($(modal));const data=await this.rpc("/shop/access_point/close_locations");if(modal.firstChild){modal.firstChild.remove();}
if(data.error||(data.close_locations.length===0)){const errorMessage=document.createElement("em");errorMessage.classList.add("text-error");errorMessage.innerText=data.error?data.error:"No available Pick-Up Locations";modal.appendChild(errorMessage);return;}
var listToRender=deliveryType+"_pickup_location_list";var dataToRender={partner_address:data.partner_address};dataToRender[deliveryType+"_pickup_locations"]=data.close_locations;$(renderToElement(listToRender,dataToRender)).appendTo($(modal));const showLocations=document.querySelectorAll(".o_show_pickup_locations");if(!ev.currentTarget.closest(".o_delivery_carrier_select")){return;}
for(const showLoc of showLocations){this._specificDropperDisplay(showLoc);}},_onCarrierClick:async function(ev){const radio=ev.currentTarget.closest('.o_delivery_carrier_select').querySelector('input[type="radio"]');if(radio.checked&&!this._shouldDisplayPickupLocations(ev)&&!this.forceClickCarrier){return;}
this.forceClickCarrier=false;const orderLocs=document.querySelectorAll('.o_order_location');orderLocs.forEach(loc=>{loc.querySelector('.o_order_location_name').textContent='';loc.querySelector('.o_order_location_address').textContent='';const divDNone=loc.parentElement;if(!divDNone.classList.contains('d-none')){divDNone.classList.add('d-none');}});this._disablePayButton();this._showLoading(radio);radio.checked=true;await this._onClickShowLocations(ev);await this._handleCarrierUpdateResult(radio);this._disablePayButtonNoPickupPoint(ev);},_onClickLocation:async function(ev){const carrierId=ev.currentTarget.closest(".o_delivery_carrier_select").childNodes[1].value;await this._checkCarrier(ev,carrierId)
const modal=ev.target.closest(".o_list_pickup_locations");const encodedLocation=ev.target.previousElementSibling.innerText;await this.rpc("/shop/access_point/set",{access_point_encoded:encodedLocation,})
while(modal.firstChild){modal.lastChild.remove();}
await this._getCurrentLocation();document.querySelectorAll('.error_no_pick_up_point').forEach(el=>el.remove());const result=await this.rpc('/shop/update_carrier',{'carrier_id':carrierId,'no_reset_access_point_address':true,})
this._enableButton(result.status);},_onSetAddress:function(ev){var value=$(ev.currentTarget).val();var $providerFree=$('select[name="country_id"]:not(.o_provider_restricted), select[name="state_id"]:not(.o_provider_restricted)');var $providerRestricted=$('select[name="country_id"].o_provider_restricted, select[name="state_id"].o_provider_restricted');if(value===0){$providerFree.hide().attr('disabled',true);$providerRestricted.show().attr('disabled',false).change();}else{$providerFree.show().attr('disabled',false).change();$providerRestricted.hide().attr('disabled',true);}},});return __exports;});;

/* /website_sale/static/src/js/notification/add_to_cart_notification/add_to_cart_notification.js */
odoo.define('@website_sale/js/notification/add_to_cart_notification/add_to_cart_notification',['@odoo/owl','@web/core/currency'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{formatCurrency}=require("@web/core/currency");const AddToCartNotification=__exports.AddToCartNotification=class AddToCartNotification extends Component{static template="website_sale.addToCartNotification";static props={lines:{type:Array,element:{type:Object,shape:{id:Number,image_url:String,quantity:Number,name:String,description:{type:String,optional:true},line_price_total:Number,},},},currency_id:Number,}
getFormattedPrice(line){return formatCurrency(line.line_price_total,this.props.currency_id);}
getProductSummary(line){return line.quantity+" x "+line.name;}}
return __exports;});;

/* /website_sale/static/src/js/notification/cart_notification/cart_notification.js */
odoo.define('@website_sale/js/notification/cart_notification/cart_notification',['@odoo/owl','@website_sale/js/notification/add_to_cart_notification/add_to_cart_notification','@website_sale/js/notification/warning_notification/warning_notification'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{AddToCartNotification}=require("@website_sale/js/notification/add_to_cart_notification/add_to_cart_notification");const{WarningNotification}=require("@website_sale/js/notification/warning_notification/warning_notification");const CartNotification=__exports.CartNotification=class CartNotification extends Component{static components={AddToCartNotification,WarningNotification};static template="website_sale.cartNotification";static props={message:[String,{toString:Function}],warning:{type:[String,{toString:Function}],optional:true},lines:{type:Array,optional:true,element:{type:Object,shape:{id:Number,image_url:String,quantity:Number,name:String,description:{type:String,optional:true},line_price_total:Number,},},},currency_id:Number,className:String,close:Function,refresh:Function,freeze:Function,}
get positionOffset(){return(document.querySelector('header.o_top_fixed_element')?.offsetHeight||0)+'px';}}
return __exports;});;

/* /website_sale/static/src/js/notification/warning_notification/warning_notification.js */
odoo.define('@website_sale/js/notification/warning_notification/warning_notification',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const WarningNotification=__exports.WarningNotification=class WarningNotification extends Component{static template="website_sale.warningNotification";static props={warning:[String,{toString:Function}],}}
return __exports;});;

/* /website_sale/static/src/js/notification/notification_service.js */
odoo.define('@website_sale/js/notification/notification_service',['@odoo/owl','@web/core/registry','@web/core/notifications/notification_service','@web/core/notifications/notification_container','@website_sale/js/notification/cart_notification/cart_notification'],function(require){'use strict';let __exports={};const{xml}=require("@odoo/owl");const{registry}=require("@web/core/registry");const{notificationService}=require("@web/core/notifications/notification_service");const{NotificationContainer}=require("@web/core/notifications/notification_container");const{CartNotification}=require("@website_sale/js/notification/cart_notification/cart_notification");const CartNotificationContainer=__exports.CartNotificationContainer=class CartNotificationContainer extends NotificationContainer{static components={...NotificationContainer.components,Notification:CartNotification,}
static template=xml`
    <div class="position-absolute w-100 h-100 top-0 pe-none">
        <div class="d-flex flex-column container align-items-end">
            <t t-foreach="notifications" t-as="notification" t-key="notification">
                <Transition leaveDuration="0" name="'o_notification_fade'" t-slot-scope="transition">
                    <Notification t-props="notification_value.props" className="(notification_value.props.className || '') + ' ' + transition.className"/>
                </Transition>
            </t>
        </div>
    </div>`;}
const cartNotificationService=__exports.cartNotificationService={...notificationService,notificationContainer:CartNotificationContainer,}
registry.category("services").add("cartNotificationService",cartNotificationService);return __exports;});;

/* /mass_mailing/static/src/js/tours/mass_mailing_tour.js */
odoo.define('@mass_mailing/js/tours/mass_mailing_tour',['@web/core/registry','@web_tour/tour_service/tour_utils','@web/core/l10n/translation','@odoo/owl'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{stepUtils}=require("@web_tour/tour_service/tour_utils");const{_t}=require("@web/core/l10n/translation");const{markup}=require("@odoo/owl");registry.category("web_tour.tours").add('mass_mailing_tour',{url:'/web',rainbowManMessage:_t('Congratulations, I love your first mailing. :)'),sequence:200,steps:()=>[stepUtils.showAppsMenuItem(),{trigger:'.o_app[data-menu-xmlid="mass_mailing.mass_mailing_menu_root"]',content:_t("Let's try the Email Marketing app."),width:225,position:'bottom',edition:'enterprise',},{trigger:'.o_app[data-menu-xmlid="mass_mailing.mass_mailing_menu_root"]',content:_t("Let's try the Email Marketing app."),edition:'community',},{trigger:'.o_list_button_add',extra_trigger:'.o_mass_mailing_mailing_tree',content:markup(_t("Start by creating your first <b>Mailing</b>.")),position:'bottom',},{trigger:'div[name="subject"]',content:markup(_t('Pick the <b>email subject</b>.')),position:'bottom',run:'click',},{trigger:'div[name="contact_list_ids"] > .o_input_dropdown > input[type="text"]',run:'click',auto:true,},{trigger:'li.ui-menu-item',run:'click',auto:true,},{trigger:'div[name="body_arch"] iframe #newsletter',content:markup(_t('Choose this <b>theme</b>.')),position:'left',edition:'enterprise',run:'click',},{trigger:'div[name="body_arch"] iframe #default',content:markup(_t('Choose this <b>theme</b>.')),position:'right',edition:'community',run:'click',},{trigger:'div[name="body_arch"] iframe div.theme_selection_done div.s_text_block',content:_t('Click on this paragraph to edit it.'),position:'top',edition:'enterprise',run:'click',},{trigger:'div[name="body_arch"] iframe div.o_mail_block_title_text',content:_t('Click on this paragraph to edit it.'),position:'top',edition:'community',run:'click',},{trigger:'button[name="action_set_favorite"]',content:_t('Click on this button to add this mailing to your templates.'),position:'bottom',run:'click',},{trigger:'button[name="action_test"]',content:_t("Test this mailing by sending a copy to yourself."),position:'bottom',},{trigger:'button[name="send_mail_test"]',content:_t("Check the email address and click send."),position:'bottom',},{trigger:'button[name="action_launch"]',content:_t("Ready for take-off!"),position:'bottom',},{trigger:'.btn-primary:contains("Send to all")',content:_t("Don't worry, the mailing contact we created is an internal user."),position:'bottom',run:"click",},{trigger:'.o_back_button',content:markup(_t("By using the <b>Breadcrumb</b>, you can navigate back to the overview.")),position:'bottom',run:'click',}]});return __exports;});;

/* /web_unsplash/static/src/js/unsplash_beacon.js */
odoo.define('@web_unsplash/js/unsplash_beacon',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.UnsplashBeacon=publicWidget.Widget.extend({selector:'#wrapwrap',init(){this._super(...arguments);this.rpc=this.bindService("rpc");},start:function(){var unsplashImages=Array.from(this.$('img[src*="/unsplash/"]')).map((img)=>{return img.src.split('/unsplash/')[1].split('/')[0];});if(unsplashImages.length){this.rpc('/web_unsplash/get_app_id').then(function(appID){if(!appID){return;}
$.get('https://views.unsplash.com/v',{'photo_id':unsplashImages.join(','),'app_id':appID,});});}
return this._super.apply(this,arguments);},});return __exports;});;

/* /knowledge/static/src/js/tools/knowledge_tools.js */
odoo.define('@knowledge/js/tools/knowledge_tools',[],function(require){'use strict';let __exports={};const HEADINGS=['H1','H2','H3','H4','H5','H6',];const fetchValidHeadings=(element)=>{const templateHeadings=Array.from(element.querySelectorAll(HEADINGS.map((heading)=>`.o_knowledge_behavior_type_template ${heading}`).join(',')));return Array.from(element.querySelectorAll(HEADINGS.join(','))).filter((heading)=>heading.innerText.trim().replaceAll('\u200B','').length>0).filter((heading)=>!templateHeadings.includes(heading));};Object.assign(__exports,{HEADINGS,fetchValidHeadings});return __exports;});;

/* /knowledge/static/src/js/knowledge_utils.js */
odoo.define('@knowledge/js/knowledge_utils',['@web/core/emoji_picker/emoji_picker','@odoo/owl'],function(require){'use strict';let __exports={};const{loadEmoji}=require("@web/core/emoji_picker/emoji_picker");const{useComponent,useEffect,useRef,}=require("@odoo/owl");const iconsBlocklist=["💩","💀","☠️","🤮","🖕","🤢","😒"];__exports.getRandomIcon=getRandomIcon;async function getRandomIcon(){const{emojis}=await loadEmoji();const randomEmojis=emojis.filter((emoji)=>!iconsBlocklist.includes(emoji.codepoints));return randomEmojis[Math.floor(Math.random()*randomEmojis.length)].codepoints;}
__exports.cloneBehaviorBlueprint=cloneBehaviorBlueprint;function cloneBehaviorBlueprint(anchor){const blueprint=anchor.cloneNode(true);const propNodes=getPropNameNodes(blueprint);const propNames=new Set();for(let i=propNodes.length-1;i>=0;i--){const propName=propNodes[i].dataset.propName;if(propNames.has(propName)){propNodes[i].remove();}else{propNames.add(propName);}}
return blueprint;}
__exports.copyOids=copyOids;function copyOids(source,destination){if(!destination){destination=cloneBehaviorBlueprint(source);}
const overrideOids=function(original,copy){if(!copy||!original){if(odoo.debug){console.warn(`Oids synchronization failed, mismatch between source and destination nodes. Some elements may not be shared properly in collaboration.`);}
return;}
copy.oid=original.oid;delete copy.ouid;if(copy.nodeType===Node.ELEMENT_NODE&&copy.firstChild&&original.firstChild){overrideOids(original.firstChild,copy.firstChild);}
if(copy.nextSibling&&original.nextSibling){overrideOids(original.nextSibling,copy.nextSibling);}}
overrideOids(source,destination);return destination;}
__exports.decodeDataBehaviorProps=decodeDataBehaviorProps;function decodeDataBehaviorProps(dataBehaviorPropsAttribute){return JSON.parse(decodeURIComponent(dataBehaviorPropsAttribute));}
__exports.encodeDataBehaviorProps=encodeDataBehaviorProps;function encodeDataBehaviorProps(dataBehaviorPropsObject){return encodeURIComponent(JSON.stringify(dataBehaviorPropsObject));}
__exports.getPropNameNode=getPropNameNode;function getPropNameNode(propName,anchor){const propNodes=anchor.querySelectorAll(`[data-prop-name="${propName}"]`);for(let i=propNodes.length-1;i>=0;i--){const closest=propNodes[i].closest('.o_knowledge_behavior_anchor');if(closest===anchor){return propNodes[i];}}}
__exports.getPropNameNodes=getPropNameNodes;function getPropNameNodes(anchor){const propNodes=[];const candidates=anchor.querySelectorAll("[data-prop-name]");const subAnchors=[...anchor.querySelectorAll(".o_knowledge_behavior_anchor")];for(const propNode of candidates){if(!subAnchors.some(subAnchor=>subAnchor.contains(propNode))){propNodes.push(propNode);}}
return propNodes;}
__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;case"youku":url=new URL(`https://player.youku.com/embed/${videoId}`);break;default:throw new Error();}
url.search=new URLSearchParams(params);return url;}
__exports.setIntersectionObserver=setIntersectionObserver;function setIntersectionObserver(element,callback){const options={root:null,rootMargin:'0px'};const observer=new window.IntersectionObserver(entries=>{const entry=entries[0];if(entry.isIntersecting){observer.unobserve(entry.target);callback();}},options);observer.observe(element);return observer;}
__exports.useRefWithSingleCollaborativeChild=useRefWithSingleCollaborativeChild;function useRefWithSingleCollaborativeChild(name,onChanged){const component=useComponent();const ref=useRef(name);if(component.props.readonly){return ref;}
let observedContent;const contentObserver=new MutationObserver(mutationList=>{const newEls=new Set();const newNodes=new Set();for(const mutation of mutationList){for(const node of mutation.addedNodes){if(node.nodeType===Node.ELEMENT_NODE){newEls.add(node);}else{newNodes.add(node);}}}
if(newNodes.size){component.editor.observerUnactive('knowledge_useRefWithSingleCollaborativeChild');for(const node of newNodes){node.remove();}
component.editor.observerActive('knowledge_useRefWithSingleCollaborativeChild');}
const currentEls=Array.from(observedContent.querySelectorAll(':scope > *'));if(currentEls.length>1){const previousEl=currentEls.find(el=>!newEls.has(el))||currentEls[0];component.editor.observerUnactive('knowledge_useRefWithSingleCollaborativeChild');observedContent.replaceChildren(previousEl);component.editor.observerActive('knowledge_useRefWithSingleCollaborativeChild');}else{onChanged(currentEls.at(0));}});useEffect(()=>{if(ref.el){observedContent=ref.el;contentObserver.observe(observedContent,{childList:true,});}
return()=>contentObserver.disconnect();},()=>[ref.el]);return ref;}
return __exports;});;

/* /sign/static/src/components/sign_request/PDF_iframe.js */
odoo.define('@sign/components/sign_request/PDF_iframe',['@web/core/l10n/translation','@web/core/utils/render','@web/core/confirmation_dialog/confirmation_dialog','@sign/components/sign_request/utils'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{renderToString}=require("@web/core/utils/render");const{AlertDialog}=require("@web/core/confirmation_dialog/confirmation_dialog");const{normalizePosition,pinchService,isVisible}=require("@sign/components/sign_request/utils");const PDFIframe=__exports.PDFIframe=class PDFIframe{constructor(root,env,owlServices,props){this.root=root;this.env=env;Object.assign(this,owlServices);this.props=props;this.cleanupFns=[];this.readonly=props.readonly;this.signItemTypesById=this.props.signItemTypes.reduce((obj,type)=>{obj[type.id]=type;return obj;},{});this.selectionOptionsById=this.props.signItemOptions.reduce((obj,option)=>{obj[option.id]=option;return obj;},{});this.waitForPagesToLoad();}
waitForPagesToLoad(){const errorElement=this.root.querySelector("#errorMessage");if(isVisible(errorElement)){return this.dialog.add(AlertDialog,{body:_t("Need a valid PDF to add signature fields!"),});}
this.pageCount=this.root.querySelectorAll(".page").length;if(this.pageCount>0){this.start();}else{setTimeout(()=>this.waitForPagesToLoad(),50);}}
start(){this.signItems=this.getSignItems();this.loadCustomCSS().then(()=>{this.pageCount=this.root.querySelectorAll(".page").length;this.clearNativePDFViewerButtons();this.startPinchService();this.preRender();this.renderSidebar();this.renderSignItems();this.postRender();});}
unmount(){this.cleanupFns.forEach((fn)=>typeof fn==="function"&&fn());}
async loadCustomCSS(){const assets=await this.rpc("/sign/render_assets_pdf_iframe",{args:[{debug:this.env.debug}],});this.root.querySelector("head").insertAdjacentHTML("beforeend",assets);}
clearNativePDFViewerButtons(){const selectors=["#pageRotateCw","#pageRotateCcw","#openFile","#presentationMode","#viewBookmark","#print","#download","#secondaryOpenFile","#secondaryPresentationMode","#secondaryViewBookmark","#secondaryPrint","#secondaryDownload",];const elements=this.root.querySelectorAll(selectors.join(", "));elements.forEach((element)=>{element.style.display="none";});this.root.querySelector("#lastPage").nextElementSibling.style.display="none";this.root.querySelector("#findInput").value="";this.root.querySelector("#findInput").setAttribute("autocomplete","off");const passwordInputs=this.root.querySelectorAll("[type=password]");Array.from(passwordInputs).forEach((input)=>input.setAttribute("autocomplete","new-password"));}
renderSidebar(){}
renderSignItems(){for(const page in this.signItems){const pageContainer=this.getPageContainer(page);for(const id in this.signItems[page]){const signItem=this.signItems[page][id];signItem.el=this.renderSignItem(signItem.data,pageContainer);}}
this.updateFontSize();}
enableCustom(signItem){}
startPinchService(){const pinchTarget=this.root.querySelector("#viewerContainer #viewer");const pinchServiceCleanup=pinchService(pinchTarget,{decreaseDistanceHandler:()=>this.root.querySelector("button#zoomIn").click(),increaseDistanceHandler:()=>this.root.querySelector("button#zoomOut").click(),});this.cleanupFns.push(pinchServiceCleanup);}
renderSignItem(signItemData,target){const signItemElement=renderToString("sign.signItem",this.getContext(signItemData));target.insertAdjacentHTML("beforeend",signItemElement);const signItem=target.lastChild;this.enableCustom({el:signItem,data:signItemData});return signItem;}
getContext(signItem){const normalizedPosX=Math.round(normalizePosition(signItem.posX,signItem.width)*1000)/1000;const normalizedPosY=Math.round(normalizePosition(signItem.posY,signItem.height)*1000)/1000;const responsible=parseInt(signItem.responsible??(signItem.responsible_id?.[0]||0));const type=this.signItemTypesById[signItem.type_id].item_type;if(type==="selection"){const options=signItem.option_ids.map((id)=>this.selectionOptionsById[id]);signItem.options=options;}
if(signItem.value===0){signItem.value="0";}
const readonly=this.readonly||(responsible>0&&responsible!==this.currentRole)||!!signItem.value;const isCurrentRole=this.currentRole===parseInt(responsible);return Object.assign(signItem,{readonly:signItem.readonly??readonly,editMode:signItem.editMode??false,required:Boolean(signItem.required),responsible,type,placeholder:signItem.placeholder||signItem.name||"",classes:`${signItem.required && isCurrentRole ? "o_sign_sign_item_required" : ""} ${
                readonly && isCurrentRole ? "o_readonly_mode" : ""
            } ${this.readonly ? "o_sign_sign_item_pdfview" : ""}`,style:`top: ${normalizedPosY * 100}%; left: ${normalizedPosX * 100}%;
                    width: ${signItem.width * 100}%; height: ${signItem.height * 100}%;
                    text-align: ${signItem.alignment}`,});}
refreshSignItems(){for(const page in this.signItems){const pageContainer=this.getPageContainer(page);for(const id in this.signItems[page]){const signItem=this.signItems[page][id].el;if(!signItem.parentElement||!signItem.parentElement.classList.contains("page")){pageContainer.append(signItem);}}}
this.updateFontSize();}
preRender(){const viewerContainer=this.root.querySelector("#viewerContainer");viewerContainer.style.visibility="visible";this.setInitialZoom();}
get normalSize(){return this.root.querySelector(".page").clientHeight*0.015;}
updateFontSize(){for(const page in this.signItems){for(const id in this.signItems[page]){const signItem=this.signItems[page][id];this.updateSignItemFontSize(signItem);}}}
updateSignItemFontSize({el,data}){const largerTypes=["signature","initial","textarea","selection"];const size=largerTypes.includes(data.type)?this.normalSize:parseFloat(el.clientHeight);el.style.fontSize=`${size * 0.8}px`;}
async rotatePDF(e){const button=e.target;button.setAttribute("disabled","");const result=await this.props.rotatePDF();if(result){this.root.querySelector("#pageRotateCw").click();button.removeAttribute("disabled");this.refreshSignItems();}}
setInitialZoom(){let button=this.root.querySelector("button#zoomIn");if(!this.env.isSmall){button=this.root.querySelector("button#zoomOut");button.click();}
button.click();}
postRender(){const refreshSignItemsIntervalId=setInterval(()=>this.refreshSignItems(),2000);this.cleanupFns.push(()=>clearInterval(refreshSignItemsIntervalId));}
createSignItemDataFromType(typeId){const type=this.signItemTypesById[typeId];return{required:true,editMode:true,readonly:true,updated:true,responsible:this.currentRole,option_ids:[],options:[],name:type.name,width:type.default_width,height:type.default_height,alignment:"center",type:type.item_type,placeholder:type.placeholder,classes:`o_color_responsible_${this.signRolesById[this.currentRole].color}`,style:`width: ${type.default_width * 100}%; height: ${type.default_height * 100}%;`,type_id:[type.id],};}
getSignItems(){const signItems={};for(let currentPage=1;currentPage<=this.pageCount;currentPage++){signItems[currentPage]={};}
for(const signItem of this.props.signItems){signItems[signItem.page][signItem.id]={data:signItem,el:null,};}
return signItems;}
getPageContainer(page){return this.root.querySelector(`.page[data-page-number="${page}"]`);}}
return __exports;});;

/* /sign/static/src/components/sign_request/document_signable.js */
odoo.define('@sign/components/sign_request/document_signable',['@odoo/owl','@web/core/main_components_container','@web/core/utils/hooks','@web/core/assets','@web/env','@sign/dialogs/dialogs','@sign/components/sign_request/signable_PDF_iframe','@sign/components/sign_request/utils','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{App,Component,xml,whenReady,useEffect,useComponent}=require("@odoo/owl");const{MainComponentsContainer}=require("@web/core/main_components_container");const{useService}=require("@web/core/utils/hooks");const{templates}=require("@web/core/assets");const{makeEnv,startServices}=require("@web/env");const{SignRefusalDialog}=require("@sign/dialogs/dialogs");const{SignablePDFIframe}=require("@sign/components/sign_request/signable_PDF_iframe");const{buildPDFViewerURL}=require("@sign/components/sign_request/utils");const{_t}=require("@web/core/l10n/translation");function datasetFromElements(elements){return Array.from(elements).map((el)=>{return Object.entries(el.dataset).reduce((dataset,[key,value])=>{try{dataset[key]=JSON.parse(value);}catch{dataset[key]=value;}
return dataset;},{});});}
const Document=__exports.Document=class Document extends Component{setup(){this.rpc=useService("rpc");this.orm=useService("orm");this.dialog=useService("dialog");this.user=useService("user");this.ui=useService("ui");this.signInfo=useService("signInfo");useEffect(()=>{this.getDataFromHTML();this.signInfo.set({documentId:this.requestID,signRequestToken:this.requestToken,signRequestState:this.requestState,signRequestItemToken:this.accessToken,todayFormattedDate:this.todayFormattedDate,});},()=>[]);}
getDataFromHTML(){this.attachmentLocation=this.props.parent.querySelector("#o_sign_input_attachment_location")?.value;this.templateName=this.props.parent.querySelector("#o_sign_input_template_name")?.value;this.templateID=parseInt(this.props.parent.querySelector("#o_sign_input_template_id")?.value);this.templateItemsInProgress=parseInt(this.props.parent.querySelector("#o_sign_input_template_in_progress_count")?.value);this.requestID=parseInt(this.props.parent.querySelector("#o_sign_input_sign_request_id")?.value);this.requestToken=this.props.parent.querySelector("#o_sign_input_sign_request_token")?.value;this.requestState=this.props.parent.querySelector("#o_sign_input_sign_request_state")?.value;this.accessToken=this.props.parent.querySelector("#o_sign_input_access_token")?.value;this.todayFormattedDate=this.props.parent.querySelector("#o_sign_input_today_formatted_date")?.value;this.templateEditable=Boolean(this.props.parent.querySelector("#o_sign_input_template_editable"));this.authMethod=this.props.parent.querySelector("#o_sign_input_auth_method")?.value;this.signerName=this.props.parent.querySelector("#o_sign_signer_name_input_info")?.value;this.signerPhone=this.props.parent.querySelector("#o_sign_signer_phone_input_info")?.value;this.redirectURL=this.props.parent.querySelector("#o_sign_input_optional_redirect_url")?.value;this.redirectURLText=this.props.parent.querySelector("#o_sign_input_optional_redirect_url_text")?.value;this.types=datasetFromElements(this.props.parent.querySelectorAll(".o_sign_field_type_input_info"));this.items=datasetFromElements(this.props.parent.querySelectorAll(".o_sign_item_input_info"));this.selectOptions=datasetFromElements(this.props.parent.querySelectorAll(".o_sign_select_options_input_info"));this.validateBanner=this.props.parent.querySelector(".o_sign_validate_banner");this.validateButton=this.props.parent.querySelector(".o_sign_validate_banner button");this.validateButtonText=this.validateButton?.textContent;this.currentRole=parseInt(this.props.parent.querySelector("#o_sign_input_current_role")?.value);this.currentName=this.props.parent.querySelector("#o_sign_input_current_role_name")?.value;this.isUnknownPublicUser=Boolean(this.props.parent.querySelector("#o_sign_is_public_user"));this.frameHash=this.props.parent.querySelector("#o_sign_input_sign_frame_hash")?.value;this.PDFIframe=this.props.parent.querySelector("iframe.o_sign_pdf_iframe");this.PDFIframe.setAttribute("src",buildPDFViewerURL(this.attachmentLocation,this.env.isSmall));this.PDFIframe.onload=()=>{setTimeout(()=>this.initializeIframe(),1);};}
initializeIframe(){this.iframe=new this.props.PDFIframeClass(this.PDFIframe.contentDocument,this.env,{rpc:this.rpc,orm:this.orm,dialog:this.dialog,user:this.user,ui:this.ui,signInfo:this.signInfo,},this.iframeProps);}
get iframeProps(){return{attachmentLocation:this.attachmentLocation,requestID:this.requestID,requestToken:this.requestToken,accessToken:this.accessToken,signItemTypes:this.types,signItems:this.items,hasSignRequests:false,signItemOptions:this.selectOptions,currentRole:this.currentRole,currentName:this.currentName,readonly:this.PDFIframe.getAttribute("readonly")==="readonly",frameHash:this.frameHash,signerName:this.signerName,signerPhone:this.signerPhone,validateBanner:this.validateBanner,validateButton:this.validateButton,validateButtonText:this.validateButtonText,isUnknownPublicUser:this.isUnknownPublicUser,authMethod:this.authMethod,redirectURL:this.redirectURL,redirectURLText:this.redirectURLText,templateEditable:this.templateEditable,};}}
Document.template=xml`<t t-slot='default'/>`;function usePublicRefuseButton(){const component=useComponent();useEffect(()=>{const refuseButton=document.querySelector(".o_sign_refuse_document_button");if(refuseButton){refuseButton.addEventListener("click",()=>{component.dialog.add(SignRefusalDialog);});}},()=>[]);}
const SignableDocument=__exports.SignableDocument=class SignableDocument extends Document{setup(){super.setup();this.coords={};usePublicRefuseButton();useEffect(()=>{if(this.requestID){const askLocation=this.props.parent.getElementById("o_sign_ask_location_input");if(askLocation&&navigator.geolocation){navigator.geolocation.getCurrentPosition(({coords:{latitude,longitude}})=>{Object.assign(this.coords,{latitude,longitude,});if(this.requestState!=="shared"){this.rpc(`/sign/save_location/${this.requestID}/${this.accessToken}`,this.coords);}},()=>{},{enableHighAccuracy:true});}}},()=>[this.requestID]);}
get iframeProps(){return{...super.iframeProps,coords:this.coords,};}}
SignableDocument.components={MainComponentsContainer,};SignableDocument.template=xml`<MainComponentsContainer/>`;__exports.initDocumentToSign=initDocumentToSign;async function initDocumentToSign(parent){const env=makeEnv();await startServices(env);await whenReady();const app=new App(SignableDocument,{name:"Signable Document",env,props:{parent,PDFIframeClass:SignablePDFIframe},templates,dev:env.debug,translatableAttributes:["data-tooltip"],translateFn:_t,});await app.mount(parent.body);}
return __exports;});;

/* /sign/static/src/components/sign_request/mobile_input_bottom_sheet.js */
odoo.define('@sign/components/sign_request/mobile_input_bottom_sheet',['@web/core/utils/render'],function(require){'use strict';let __exports={};const{renderToString}=require("@web/core/utils/render");const MobileInputBottomSheet=__exports.MobileInputBottomSheet=class MobileInputBottomSheet{constructor(options){this.type=options.type||"text";this.placeholder=options.placeholder||"";this.label=options.label||this.placeholder;this.value=options.value||"";this.buttonText=options.buttonText;this.element=options.element;this.onTextChange=options.onTextChange||function(){};this.onValidate=options.onValidate||function(){};document.body.insertAdjacentHTML("beforeend",renderToString("sign.MobileInputBottomSheet",this));this.el=document.body.lastChild;this.registerEvents();}
registerEvents(){const field=this.el.querySelector(".o_sign_item_bottom_sheet_field");const nextButton=this.el.querySelector(".o_sign_next_button");if(field){field.addEventListener("blur",()=>{this._onBlurField();});field.addEventListener("keyup",()=>{this._onKeyUpField();});}
if(nextButton){nextButton.addEventListener("click",()=>{this._onClickNext();});}}
updateInputText(text){this.value=text;this.el.querySelector(".o_sign_item_bottom_sheet_field").value=text;this._toggleButton();}
show(){const bottomSheet=document.querySelector(".o_sign_item_bottom_sheet.show");if(bottomSheet){bottomSheet.classList.remove("show");}
this._toggleButton();setTimeout(()=>this.el.classList.add("show"));this.el.querySelector(".o_sign_item_bottom_sheet_field").focus();}
hide(){this.el.classList.remove("show");this.el.addEventListener("transitionend",()=>(this.el.style.display="none"),{once:true,});}
_toggleButton(){const buttonNext=this.el.querySelector(".o_sign_next_button");this.value.length?buttonNext.removeAttribute("disabled"):buttonNext.setAttribute("disabled","disabled");}
_updateText(){this.value=this.el.querySelector(".o_sign_item_bottom_sheet_field").value;this.onTextChange(this.value);this._toggleButton();}
_onBlurField(){this._updateText();}
_onClickNext(){this.onValidate(this.value);}
_onKeyUpField(){this._updateText();}}
return __exports;});;

/* /sign/static/src/components/sign_request/sign_item_navigator.js */
odoo.define('@sign/components/sign_request/sign_item_navigator',['@web/core/l10n/translation','@sign/components/sign_request/utils'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{offset}=require("@sign/components/sign_request/utils");__exports.startSignItemNavigator=startSignItemNavigator;function startSignItemNavigator(parent,target,types,env){function setTip(text){navigator.innerText=text;}
const state={started:false,isScrolling:false,};const navigator=document.createElement("div");navigator.classList.add("o_sign_sign_item_navigator");navigator.addEventListener("click",goToNextSignItem);target.append(navigator);const navLine=document.createElement("div");navLine.classList.add("o_sign_sign_item_navline");navigator.before(navLine);setTip(_t("Click to start"));navigator.focus();function goToNextSignItem(){if(!state.started){state.started=true;parent.refreshSignItems();goToNextSignItem();return false;}
const selectedElement=target.querySelector(".ui-selected");if(selectedElement){selectedElement.classList.remove("ui-selected");}
const signItemsToComplete=parent.checkSignItemsCompletion().sort((a,b)=>{return(100*(a.data.page-b.data.page)+
10*(a.data.posY-b.data.posY)+
(a.data.posX-b.data.posX));});if(signItemsToComplete.length>0){scrollToSignItem(signItemsToComplete[0]);}}
function scrollToSignItem({el:item,data}){_scrollToSignItemPromise(item).then(()=>{const type=types[data.type_id];if(type.item_type==="text"&&item.querySelector("input")){item.value=item.querySelector("input").value;item.focus=()=>item.querySelector("input").focus();}
if(item.value===""&&!item.dataset.signature){setTip(type.tip);}
parent.refreshSignItems();item.focus();item.classList.add("ui-selected");if(["signature","initial"].includes(type.item_type)){if(item.dataset.hasFocus){const clickableElement=data.isSignItemEditable?item.querySelector(".o_sign_item_display"):item;clickableElement.click();}else{item.dataset.hasFocus=true;}}
state.isScrolling=false;});}
function _scrollToSignItemPromise(item){if(env.isSmall){return new Promise((resolve)=>{state.isScrolling=true;item.scrollIntoView({behavior:"smooth",block:"center",inline:"center",});resolve();});}
state.isScrolling=true;const viewer=target.querySelector("#viewer");const containerHeight=target.offsetHeight;const viewerHeight=viewer.offsetHeight;let scrollOffset=containerHeight/4;const scrollTop=offset(item).top-offset(viewer).top-scrollOffset;if(scrollTop+containerHeight>viewerHeight){scrollOffset+=scrollTop+containerHeight-viewerHeight;}
if(scrollTop<0){scrollOffset+=scrollTop;}
scrollOffset+=offset(target).top-
navigator.offsetHeight/2+
item.getBoundingClientRect().height/2;const duration=Math.max(Math.min(500,5*(Math.abs(target.scrollTop-scrollTop)+
Math.abs(navigator.getBoundingClientRect().top)-
scrollOffset)),100);return new Promise((resolve,reject)=>{target.scrollTo({top:scrollTop,behavior:"smooth"});const an=navigator.animate({top:`${scrollOffset}px`},{duration,fill:"forwards"});const an2=navLine.animate({top:`${scrollOffset}px`},{duration,fill:"forwards"});Promise.all([an.finished,an2.finished]).then(()=>resolve());});}
function toggle(force){navigator.style.display=force?"":"none";navLine.style.display=force?"":"none";}
return{setTip,goToNextSignItem,toggle,state,};}
return __exports;});;

/* /sign/static/src/components/sign_request/signable_PDF_iframe.js */
odoo.define('@sign/components/sign_request/signable_PDF_iframe',['@web/core/l10n/translation','@sign/components/sign_request/PDF_iframe','@sign/components/sign_request/sign_item_navigator','@web/core/confirmation_dialog/confirmation_dialog','@sign/components/sign_request/mobile_input_bottom_sheet','@sign/dialogs/dialogs'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{PDFIframe}=require("@sign/components/sign_request/PDF_iframe");const{startSignItemNavigator}=require("@sign/components/sign_request/sign_item_navigator");const{AlertDialog}=require("@web/core/confirmation_dialog/confirmation_dialog");const{MobileInputBottomSheet}=require("@sign/components/sign_request/mobile_input_bottom_sheet");const{SignNameAndSignatureDialog,ThankYouDialog,PublicSignerDialog,SMSSignerDialog,NextDirectSignDialog,}=require("@sign/dialogs/dialogs");const SignablePDFIframe=__exports.SignablePDFIframe=class SignablePDFIframe extends PDFIframe{constructor(root,env,owlServices,props){super(root,env,owlServices,props);this.currentRole=this.props.currentRole;this.currentRoleName=this.props.currentName;this.signerName=props.signerName;this.frameHash=(this.props.frameHash&&this.props.frameHash.substring(0,10)+"...")||"";}
enableCustom(signItem){if(this.readonly||signItem.data.responsible!==this.currentRole){return;}
const signItemElement=signItem.el;const signItemData=signItem.data;const signItemType=this.signItemTypesById[signItemData.type_id];const{name,item_type:type,auto_value:autoValue}=signItemType;if(name===_t("Date")){signItemElement.addEventListener("focus",(e)=>{this.fillTextSignItem(e.currentTarget,this.signInfo.get('todayFormattedDate'));});}else if(type==="signature"||type==="initial"){signItemElement.addEventListener("click",(e)=>{this.handleSignatureDialogClick(e.currentTarget,signItemType);});}
if(autoValue&&["text","textarea"].includes(type)){signItemElement.addEventListener("focus",(e)=>{this.fillTextSignItem(e.currentTarget,autoValue);});}
if(this.env.isSmall&&["text","textarea"].includes(type)){const inputBottomSheet=new MobileInputBottomSheet({type:type,element:signItemElement,value:signItemElement.value,label:`${signItemType.tip}: ${signItemType.placeholder}`,placeholder:signItemElement.placeholder,onTextChange:(value)=>{signItemElement.value=value;},onValidate:(value)=>{signItemElement.value=value;signItemElement.dispatchEvent(new Event("input",{bubbles:true}));inputBottomSheet.hide();this.navigator.goToNextSignItem();},buttonText:_t("next"),});signItemElement.addEventListener("focus",()=>{inputBottomSheet.updateInputText(signItemElement.value);inputBottomSheet.show();});}
if(type==="selection"){if(signItemElement.value){this.handleInput();}
const optionDiv=signItemElement.querySelector(".o_sign_select_options_display");optionDiv.addEventListener("click",(e)=>{if(e.target.classList.contains("o_sign_item_option")){const option=e.target;const selectedValue=option.dataset.id;signItemElement.value=selectedValue;option.classList.add("o_sign_selected_option");option.classList.remove("o_sign_not_selected_option");const notSelected=optionDiv.querySelectorAll(`.o_sign_item_option:not([data-id='${selectedValue}'])`);[...notSelected].forEach((el)=>{el.classList.remove("o_sign_selected_option");el.classList.add("o_sign_not_selected_option");});this.handleInput();}});}
signItemElement.addEventListener("input",this.handleInput.bind(this));}
handleInput(){this.checkSignItemsCompletion();this.navigator.setTip(_t("next"));}
handleSignatureDialogClick(signatureItem,signItemType){this.refreshSignItems();const signature=signatureItem.dataset.signature;const{auto_value:autoValue,frame_value:frameValue,item_type:type}=signItemType;if(autoValue&&!signature){Promise.all([this.adjustSignatureSize(autoValue,signatureItem),this.adjustSignatureSize(frameValue,signatureItem),]).then(([data,frameData])=>{this.fillItemWithSignature(signatureItem,data,{frame:frameData,hash:"0"});this.handleInput();});}else if(type==="initial"&&this.nextInitial&&!signature){this.adjustSignatureSize(this.nextInitial,signatureItem).then((data)=>{this.fillItemWithSignature(signatureItem,data);this.handleInput();});}else{this.openSignatureDialog(signatureItem,signItemType);}}
fillTextSignItem(signItemElement,value){if(signItemElement.value===""){signItemElement.value=value;this.handleInput();}}
adjustSignatureSize(data,signatureItem){if(!data){return Promise.resolve(false);}
return new Promise((resolve,reject)=>{const img=new Image();img.onload=()=>{const c=document.createElement("canvas");if(!signatureItem.parentElement||!signatureItem.parentElement.classList.contains("page")){this.refreshSignItems();}
const{width:boxWidth,height:boxHeight}=signatureItem.getBoundingClientRect();const imgHeight=img.height;const imgWidth=img.width;const ratioBoxWidthHeight=boxWidth/boxHeight;const ratioImageWidthHeight=imgWidth/imgHeight;const[canvasHeight,canvasWidth]=ratioBoxWidthHeight>ratioImageWidthHeight?[imgHeight,imgHeight*ratioBoxWidthHeight]:[imgWidth/ratioBoxWidthHeight,imgWidth];c.height=canvasHeight;c.width=canvasWidth;const ctx=c.getContext("2d");const oldShadowColor=ctx.shadowColor;ctx.shadowColor="transparent";ctx.drawImage(img,c.width/2-img.width/2,c.height/2-img.height/2,img.width,img.height);ctx.shadowColor=oldShadowColor;resolve(c.toDataURL());};img.src=data;});}
fillItemWithSignature(signatureItem,image,frameData=false){signatureItem.dataset.signature=image;signatureItem.replaceChildren();const signHelperSpan=document.createElement("span");signHelperSpan.classList.add("o_sign_helper");signatureItem.append(signHelperSpan);if(frameData&&frameData.frame){signatureItem.dataset.frameHash=frameData.hash;signatureItem.dataset.frame=frameData.frame;const frameImage=document.createElement("img");frameImage.src=frameData.frame;frameImage.classList.add("o_sign_frame");signatureItem.append(frameImage);}else{delete signatureItem.dataset.frame;}
const signatureImage=document.createElement("img");signatureImage.src=image;signatureItem.append(signatureImage);}
closeDialog(){this.closeFn&&this.closeFn();this.closeFn=false;}
openSignatureDialog(signatureItem,type){if(this.dialogOpen){return;}
const signature={name:this.signerName||"",};const frame={};const{height,width}=signatureItem.getBoundingClientRect();const signFrame=signatureItem.querySelector(".o_sign_frame");this.dialogOpen=true;this.closeFn=this.dialog.add(SignNameAndSignatureDialog,{frame,signature,signatureType:type.item_type,displaySignatureRatio:width/height,activeFrame:Boolean(signFrame)||!type.auto_value,mode:type.auto_value?"draw":"auto",defaultFrame:type.frame_value||"",hash:this.frameHash,onConfirm:async()=>{if(!signature.isSignatureEmpty&&signature.signatureChanged){const signatureName=signature.name;this.signerName=signatureName;await frame.updateFrame();const frameData=frame.getFrameImageSrc();const signatureSrc=`data:${signature.getSignatureImage().join(", ")}`;type.auto_value=signatureSrc;type.frame_value=frameData;if(this.user.userId){await this.updateUserSignature(type);}
this.fillItemWithSignature(signatureItem,signatureSrc,{frame:frameData,hash:this.frameHash,});}else if(signature.signatureChanged){delete signatureItem.dataset.signature;delete signatureItem.dataset.frame;signatureItem.replaceChildren();const signHelperSpan=document.createElement("span");signHelperSpan.classList.add("o_sign_helper");signatureItem.append(signHelperSpan);if(type.placeholder){const placeholderSpan=document.createElement("span");placeholderSpan.classList.add("o_placeholder");placeholderSpan.innerText=type.placeholder;signatureItem.append(placeholderSpan);}}
this.closeDialog();this.handleInput();},onConfirmAll:async()=>{const signatureName=signature.name;this.signerName=signatureName;await frame.updateFrame();const frameData=frame.getFrameImageSrc();const signatureSrc=`data:${signature.getSignatureImage().join(", ")}`;type.auto_value=signatureSrc;type.frame_value=frameData;if(this.user.userId){await this.updateUserSignature(type);}
for(const page in this.signItems){await Promise.all(Object.values(this.signItems[page]).reduce((promiseList,signItem)=>{if(signItem.data.responsible===this.currentRole&&signItem.data.type_id===type.id){promiseList.push(Promise.all([this.adjustSignatureSize(signatureSrc,signItem.el),this.adjustSignatureSize(frameData,signItem.el),]).then(([data,frameData])=>{this.fillItemWithSignature(signItem.el,data,{frame:frameData,hash:this.frameHash,});}));}
return promiseList;},[]));}
this.closeDialog();this.handleInput();},onCancel:()=>{this.closeDialog();},},{onClose:()=>{this.dialogOpen=false;},});}
checkSignItemsCompletion(){this.refreshSignItems();const itemsToSign=[];for(const page in this.signItems){Object.values(this.signItems[page]).forEach((signItem)=>{if(signItem.data.required&&signItem.data.responsible===this.currentRole&&!signItem.data.value){const el=signItem.data.isEditMode&&signItem.el.type==="text"?el.querySelector("input"):signItem.el;const uncheckedBox=el.value==="on"&&!el.checked;if(!((el.value&&el.value.trim())||el.dataset.signature)||uncheckedBox){itemsToSign.push(signItem);}}});}
itemsToSign.length?this.hideBanner():this.showBanner();this.navigator.toggle(itemsToSign.length>0);return itemsToSign;}
showBanner(){this.props.validateBanner.style.display="block";const an=this.props.validateBanner.animate({opacity:1},{duration:500,fill:"forwards"});an.finished.then(()=>{if(this.env.isSmall){this.props.validateBanner.scrollIntoView({behavior:"smooth",block:"center",inline:"center",});}});}
hideBanner(){this.props.validateBanner.style.display="none";this.props.validateBanner.style.opacity=0;}
updateUserSignature(type){return this.rpc("/sign/update_user_signature",{sign_request_id:this.props.requestID,role:this.currentRole,signature_type:type.item_type==="signature"?"sign_signature":"sign_initials",datas:type.auto_value,frame_datas:type.frame_value,});}
getContext(signItem){return super.getContext(signItem);}
preRender(){super.preRender();}
postRender(){super.postRender();if(this.readonly){return;}
this.navigator=startSignItemNavigator(this,this.root.querySelector("#viewerContainer"),this.signItemTypesById,this.env);this.checkSignItemsCompletion();this.root.querySelector("#viewerContainer").addEventListener("scroll",()=>{if(!this.navigator.state.isScrolling&&this.navigator.state.started){this.navigator.setTip(_t("next"));}});this.root.querySelector("#viewerContainer").addEventListener("keydown",(e)=>{if(e.key!=="Enter"||(e.target.tagName.toLowerCase()==='textarea')){return;}
this.navigator.goToNextSignItem();});this.props.validateBanner.querySelector(".o_validate_button").addEventListener("click",()=>{this.signDocument();});}
getMailFromSignItems(){let mail="";for(const page in this.signItems){Object.values(this.signItems[page]).forEach(({el})=>{const childInput=el.querySelector("input");const value=el.value||(childInput&&childInput.value);if(value&&value.indexOf("@")>=0){mail=value;}});}
return mail;}
signDocument(){this.props.validateBanner.setAttribute("disabled",true);this.signatureInfo={name:this.signerName||"",mail:this.getMailFromSignItems()};[this.signatureInfo.signatureValues,this.signatureInfo.frameValues,this.signatureInfo.newSignItems,]=this.getSignatureValuesFromConfiguration();if(!this.signatureInfo.signatureValues){this.checkSignItemsCompletion();this.dialog.add(AlertDialog,{title:_t("Warning"),body:_t("Some fields have still to be completed"),});this.props.validateButton.textContent=this.props.validateButtonText;this.props.validateBanner.removeAttribute("disabled");return;}
this.signatureInfo.hasNoSignature=Object.keys(this.signatureInfo.signatureValues).length==0&&Object.keys(this.signItems).length==0;this._signDocument();}
async _signDocument(){this.props.validateButton.textContent=this.props.validateButtonText;this.props.validateButton.setAttribute("disabled",true);if(this.signatureInfo.hasNoSignature){const signature={name:this.signerName||"",};this.closeFn=this.dialog.add(SignNameAndSignatureDialog,{signature,onConfirm:()=>{this.signatureInfo.name=signature.name;this.signatureInfo.signatureValues=signature.getSignatureImage()[1];this.signatureInfo.frameValues=[];this.signatureInfo.hasNoSignature=false;this.closeDialog();this._signDocument();},onCancel:()=>{this.closeDialog();},});}else if(this.props.isUnknownPublicUser){this.closeFn=this.dialog.add(PublicSignerDialog,{name:this.signatureInfo.name,mail:this.signatureInfo.mail,postValidation:async(requestID,requestToken,accessToken)=>{this.signInfo.set({documentId:requestID,signRequestToken:requestToken,signRequestItemToken:accessToken,});this.props.requestID=requestID;this.props.requestToken=requestToken;this.props.accessToken=accessToken;if(this.props.coords){await this.rpc(`/sign/save_location/${requestID}/${accessToken}`,this.props.coords);}
this.props.isUnknownPublicUser=false;this._signDocument();},},{onClose:()=>{this.props.validateButton.removeAttribute("disabled");},});}else if(this.props.authMethod){this.openAuthDialog();}else{this._sign();}}
_getRouteAndParams(){const route=this.signatureInfo.smsToken?`/sign/sign/${encodeURIComponent(this.props.requestID)}/${encodeURIComponent(
                  this.props.accessToken
              )}/${encodeURIComponent(this.signatureInfo.smsToken)}`:`/sign/sign/${encodeURIComponent(this.props.requestID)}/${encodeURIComponent(
                  this.props.accessToken
              )}`;const params={signature:this.signatureInfo.signatureValues,frame:this.signatureInfo.frameValues,new_sign_items:this.signatureInfo.newSignItems,};return[route,params];}
async _sign(){const[route,params]=this._getRouteAndParams();this.ui.block();const response=await this.rpc(route,params).finally(()=>this.ui.unblock());this.props.validateButton.textContent=this.props.validateButtonText;this.props.validateButton.removeAttribute("disabled");if(response.success){if(response.url){document.location.pathname=response.url;}else{this.disableItems();const nameList=this.signInfo.get("nameList");if(nameList&&nameList.length>0){this.dialog.add(NextDirectSignDialog);}else{this.openThankYouDialog();}}
this.hideBanner();}else{if(response.sms){this.dialog.add(AlertDialog,{title:_t("Error"),body:_t("Your signature was not submitted. Ensure the SMS validation code is correct."),});}else{this.dialog.add(AlertDialog,{title:_t("Error"),body:_t("Sorry, an error occurred, please try to fill the document again."),},{onClose:()=>{window.location.reload();},});}
this.props.validateButton.setAttribute("disabled",true);}}
getSignatureValuesFromConfiguration(){const signatureValues={};const frameValues={};const newSignItems={};for(const page in this.signItems){for(const item of Object.values(this.signItems[page])){const responsible=item.data.responsible||0;if(responsible>0&&responsible!==this.currentRole){continue;}
const value=this.getSignatureValueFromElement(item);const[frameValue,frameHash]=item.el.dataset.signature?[item.el.dataset.frame,item.el.dataset.frameHash]:[false,false];if(!value){if(item.data.required){return[{},{}];}
continue;}
signatureValues[item.data.id]=value;frameValues[item.data.id]={frameValue,frameHash};if(item.data.isSignItemEditable){newSignItems[item.data.id]={type_id:item.data.type_id,required:item.data.required,name:item.data.name||false,option_ids:item.data.option_ids,responsible_id:responsible,page:page,posX:item.data.posX,posY:item.data.posY,width:item.data.width,height:item.data.height,};}}}
return[signatureValues,frameValues,newSignItems];}
getSignatureValueFromElement(item){const types={text:()=>{const textValue=item.el.textContent&&item.el.textContent.trim()?item.el.textContent:false;const value=item.el.value&&item.el.value.trim()?item.el.value:item.el.querySelector("input")?.value||false;return value||textValue;},initial:()=>item.el.dataset.signature,signature:()=>item.el.dataset.signature,textarea:()=>this.textareaApplyLineBreak(item.el),selection:()=>(item.el.value&&item.el.value.trim()?item.el.value:false),checkbox:()=>{if(item.el.checked){return"on";}else{return item.data.required?false:"off";}},};const type=item.data.type;return type in types?types[type]():types["text"]();}
textareaApplyLineBreak(element){element.setAttribute("wrap","off");const strRawValue=element.value;element.value="";const nEmptyWidth=element.scrollWidth;let nLastWrappingIndex=-1;strRawValue.split("").forEach((curChar,i)=>{element.value+=curChar;if(curChar===" "||curChar==="-"||curChar==="+"){nLastWrappingIndex=i;}
if(element.scrollWidth>nEmptyWidth){let buffer="";if(nLastWrappingIndex>=0){for(let j=nLastWrappingIndex+1;j<i;j++){buffer+=strRawValue.charAt(j);}
nLastWrappingIndex=-1;}
buffer+=curChar;element.value=element.value.substr(0,element.value.length-buffer.length);element.value+="\n"+buffer;}});element.setAttribute("wrap","");return element.value;}
disableItems(){const items=this.root.querySelectorAll(".o_sign_sign_item");for(const item of Array.from(items)){item.classList.add("o_sign_sign_item_pdfview");}}
openThankYouDialog(){this.dialog.add(ThankYouDialog,{redirectURL:this.props.redirectURL,redirectURLText:this.props.redirectURLText,});}
async openAuthDialog(){const authDialog=await this.getAuthDialog();if(authDialog.component){this.closeFn=this.dialog.add(authDialog.component,authDialog.props,{onClose:()=>{this.props.validateButton.removeAttribute("disabled");},});}else{this._sign();}}
async getAuthDialog(){if(this.props.authMethod==="sms"&&!this.signatureInfo.smsToken){const credits=await this.rpc("/sign/has_sms_credits");if(credits){return{component:SMSSignerDialog,props:{signerPhone:this.props.signerPhone,postValidation:(code)=>{this.signatureInfo.smsToken=code;return this._signDocument();},},};}
return false;}
return false;}}
return __exports;});;

/* /sign/static/src/components/sign_request/utils.js */
odoo.define('@sign/components/sign_request/utils',['@web/core/utils/timing'],function(require){'use strict';let __exports={};const{setRecurringAnimationFrame,debounce}=require("@web/core/utils/timing");const MIN_ID=-(2**30);__exports.startHelperLines=startHelperLines;function startHelperLines(target){function showHelperLinesAt(signItem,coords){const calculate={left:(pos)=>({left:`${pos.left}px`}),right:(pos)=>({left:`${pos.left + pos.width}px`}),top:(pos)=>({top:`${pos.top}px`}),bottom:(pos)=>({top:`${pos.top + pos.height}px`}),};const rect=signItem.getBoundingClientRect();const positions={top:(coords&&coords.y)||rect.top,left:(coords&&coords.x)||rect.left,height:signItem.clientHeight,width:signItem.clientWidth,};for(const line in helperLines){const newPos=calculate[line](positions);Object.assign(helperLines[line].style,{visibility:"visible",...newPos,});}}
function hideHelperLines(){for(const line in helperLines){helperLines[line].style.visibility="hidden";}}
const top=target.createElement("div");const bottom=target.createElement("div");top.className="o_sign_drag_helper o_sign_drag_top_helper";bottom.className="o_sign_drag_helper o_sign_drag_top_helper";const left=target.createElement("div");const right=target.createElement("div");left.className="o_sign_drag_helper o_sign_drag_side_helper";right.className="o_sign_drag_helper o_sign_drag_side_helper";const body=target.querySelector("body");body.appendChild(top);body.appendChild(bottom);body.appendChild(left);body.appendChild(right);const helperLines={top,bottom,left,right,};return{show:showHelperLinesAt,hide:hideHelperLines,};}
__exports.isVisible=isVisible;function isVisible(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length);}
__exports.offset=offset;function offset(el){const box=el.getBoundingClientRect();const docElem=document.documentElement;return{top:box.top+window.scrollY-docElem.clientTop,left:box.left+window.scrollY-docElem.clientLeft,};}
__exports.normalizePosition=normalizePosition;function normalizePosition(position,itemDimension){if(position<0){return 0;}else if(position+itemDimension>1.0){return 1.0-itemDimension;}
return position;}
__exports.normalizeDimension=normalizeDimension;function normalizeDimension(dimension,position){if(position+dimension>1){return 1-position;}
return dimension;}
__exports.generateRandomId=generateRandomId;function generateRandomId(){return Math.floor(Math.random()*MIN_ID)-1;}
__exports.startSmoothScroll=startSmoothScroll;function startSmoothScroll(container,element,dragImageElement=null,helperLines){const boundary=0.2;const directions={up:-1,down:1,left:-1,right:1,};const mouse={};const containerOffset=offset(container);const dragAmount=10;const el=dragImageElement||element;function updateMousePosition(e){mouse.x=e.clientX-containerOffset.left;mouse.y=e.clientY-containerOffset.top;helperLines.show(el,{x:e.clientX,y:e.clientY});}
const debouncedOnMouseMove=debounce(updateMousePosition,"animationFrame",true);container.addEventListener("dragover",debouncedOnMouseMove);const cleanup=setRecurringAnimationFrame(()=>{const{x,y}=mouse;let scrollX,scrollY=0;if(x<=container.clientWidth*boundary){scrollX=directions.left*dragAmount;}else if(x>=container.clientWidth*(1-boundary)){scrollX=directions.right*dragAmount;}
if(y<=container.clientHeight*boundary){scrollY=directions.up*dragAmount;}else if(y>=container.clientHeight*(1-boundary)){scrollY=directions.down*dragAmount;}
container.scrollBy(scrollX,scrollY);});return()=>{cleanup();container.removeEventListener("dragover",debouncedOnMouseMove);helperLines.hide();};}
__exports.startResize=startResize;function startResize(signItem,onResize){const page=signItem.el.parentElement;const mouse={};const resizeHandleWidth=signItem.el.querySelector(".resize_width");const resizeHandleHeight=signItem.el.querySelector(".resize_height");const resizeHandleBoth=signItem.el.querySelector(".resize_both");const computeDimensions=(e)=>{const{direction,x,y}=mouse;const computedStyle=getComputedStyle(signItem.el);const signItemAbsoluteWidth=parseInt(computedStyle.width);const signItemAbsoluteHeight=parseInt(computedStyle.height);const dX=e.clientX-x;const dY=e.clientY-y;Object.assign(mouse,{x:e.clientX,y:e.clientY,});const factor={x:(dX+signItemAbsoluteWidth)/signItemAbsoluteWidth,y:(dY+signItemAbsoluteHeight)/signItemAbsoluteHeight,};if(dX<0&&Math.abs(dX)>=signItemAbsoluteWidth){factor.x=1;}
if(dY<0&&Math.abs(dY)>=signItemAbsoluteHeight){factor.y=1;}
const width=direction==="width"||direction==="both"?Math.round(normalizeDimension(factor.x*signItem.data.width,signItem.data.posX)*1000)/1000:signItem.data.width;const height=direction==="height"||direction==="both"?Math.round(normalizeDimension(factor.y*signItem.data.height,signItem.data.posY)*1000)/1000:signItem.data.height;return{height,width};};const handleMouseMove=(e)=>{if(signItem.el.classList.contains("o_resizing")){e.preventDefault();onResize(signItem,computeDimensions(e),false);}};const debouncedOnMouseMove=debounce(handleMouseMove,"animationFrame",true);const handleMouseDown=(e,direction)=>{e.preventDefault();signItem.el.classList.add("o_resizing");Object.assign(mouse,{x:e.clientX,y:e.clientY,direction});page.addEventListener("mousemove",debouncedOnMouseMove);};resizeHandleWidth.addEventListener("mousedown",(e)=>handleMouseDown(e,"width"));resizeHandleHeight.addEventListener("mousedown",(e)=>handleMouseDown(e,"height"));resizeHandleBoth.addEventListener("mousedown",(e)=>handleMouseDown(e,"both"));page.addEventListener("mouseup",(e)=>{if(signItem.el.classList.contains("o_resizing")){signItem.el.classList.remove("o_resizing");page.removeEventListener("mousemove",debouncedOnMouseMove);onResize(signItem,computeDimensions(e),true);}});}
__exports.pinchService=pinchService;function pinchService(target,handlers){let prevDiff=null;const{increaseDistanceHandler,decreaseDistanceHandler}=handlers;target.addEventListener("touchstart",reset);target.addEventListener("touchmove",touchMove);target.addEventListener("touchend",reset);function touchMove(e){const touches=e.touches;if(touches.length===2){const deltaX=touches[0].pageX-touches[1].pageX;const deltaY=touches[0].pageY-touches[1].pageY;const curDiff=Math.hypot(deltaX,deltaY);if(prevDiff===null){prevDiff=curDiff;}
const scale=prevDiff/curDiff;if(scale<1){decreaseDistanceHandler(e);}else if(scale>1){increaseDistanceHandler(e);}}}
function reset(){prevDiff=null;}
return()=>{target.removeEventListener("touchstart",reset);target.removeEventListener("touchmove",touchMove);target.removeEventListener("touchend",reset);};}
__exports.buildPDFViewerURL=buildPDFViewerURL;function buildPDFViewerURL(attachmentLocation,isSmall){const date=new Date().toISOString();const baseURL="/web/static/lib/pdfjs/web/viewer.html";attachmentLocation=encodeURIComponent(attachmentLocation).replace(/'/g,"%27").replace(/"/g,"%22");const zoom=isSmall?"page-fit":"page-width";return`${baseURL}?unique=${date}&file=${attachmentLocation}#page=1&zoom=${zoom}`;}
return __exports;});;

/* /sign/static/src/dialogs/dialogs.js */
odoo.define('@sign/dialogs/dialogs',['@sign/dialogs/initials_all_pages_dialog','@sign/dialogs/public_signer_dialog','@sign/dialogs/sign_name_and_signature_dialog','@sign/dialogs/sms_signer_dialog','@sign/dialogs/thank_you_dialog','@sign/dialogs/next_direct_sign_dialog','@sign/dialogs/encrypted_dialog','@sign/dialogs/sign_refusal_dialog'],function(require){'use strict';let __exports={};const{InitialsAllPagesDialog}=require("@sign/dialogs/initials_all_pages_dialog");const{PublicSignerDialog}=require("@sign/dialogs/public_signer_dialog");const{SignNameAndSignatureDialog}=require("@sign/dialogs/sign_name_and_signature_dialog");const{SMSSignerDialog}=require("@sign/dialogs/sms_signer_dialog");const{ThankYouDialog}=require("@sign/dialogs/thank_you_dialog");const{NextDirectSignDialog}=require("@sign/dialogs/next_direct_sign_dialog");const{EncryptedDialog}=require("@sign/dialogs/encrypted_dialog");const{SignRefusalDialog}=require("@sign/dialogs/sign_refusal_dialog");Object.assign(__exports,{InitialsAllPagesDialog,PublicSignerDialog,SignNameAndSignatureDialog,SMSSignerDialog,ThankYouDialog,NextDirectSignDialog,EncryptedDialog,SignRefusalDialog,});return __exports;});;

/* /sign/static/src/dialogs/encrypted_dialog.js */
odoo.define('@sign/dialogs/encrypted_dialog',['@web/core/l10n/translation','@web/core/utils/hooks','@web/core/confirmation_dialog/confirmation_dialog','@web/core/dialog/dialog','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const{AlertDialog}=require("@web/core/confirmation_dialog/confirmation_dialog");const{Dialog}=require("@web/core/dialog/dialog");const{Component,useRef}=require("@odoo/owl");const EncryptedDialog=__exports.EncryptedDialog=class EncryptedDialog extends Component{setup(){this.passwordInput=useRef("password");this.rpc=useService("rpc");this.dialog=useService("dialog");this.signInfo=useService("signInfo");}
get dialogProps(){return{title:_t("PDF is encrypted"),fullscreen:this.env.isSmall,size:"md",};}
async validatePassword(){const passwordInput=this.passwordInput.el;if(!passwordInput.value){passwordInput.classList.toggle("is-invalid",!passwordInput.value);return false;}
const route=`/sign/password/${this.signInfo.get("documentId")}`;const params={password:passwordInput.value,};const response=await this.rpc(route,params);if(!response){return this.dialog.add(AlertDialog,{body:_t("Password is incorrect."),});}else{this.props.close();}}}
EncryptedDialog.template="sign.EncryptedDialog";EncryptedDialog.components={Dialog,};EncryptedDialog.props={close:Function,};return __exports;});;

/* /sign/static/src/dialogs/initials_all_pages_dialog.js */
odoo.define('@sign/dialogs/initials_all_pages_dialog',['@web/core/l10n/translation','@odoo/owl','@web/core/dialog/dialog'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{Component,useRef}=require("@odoo/owl");const{Dialog}=require("@web/core/dialog/dialog");const InitialsAllPagesDialog=__exports.InitialsAllPagesDialog=class InitialsAllPagesDialog extends Component{setup(){this.selectRef=useRef("role_select");}
get currentRole(){return parseInt(this.selectRef.el?.value);}
onAddOnceClick(){this.props.addInitial(this.currentRole,false);this.props.close();}
onAddToAllPagesClick(){this.props.addInitial(this.currentRole,true);this.props.close();}
get dialogProps(){return{size:"md",title:_t("Add Initials"),};}}
InitialsAllPagesDialog.template="sign.InitialsAllPagesDialog";InitialsAllPagesDialog.components={Dialog,};InitialsAllPagesDialog.props={addInitial:Function,close:Function,roles:Object,responsible:Number,};return __exports;});;

/* /sign/static/src/dialogs/next_direct_sign_dialog.js */
odoo.define('@sign/dialogs/next_direct_sign_dialog',['@web/core/l10n/translation','@odoo/owl','@web/core/utils/hooks','@web/core/dialog/dialog'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{Component}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{Dialog}=require("@web/core/dialog/dialog");const NextDirectSignDialog=__exports.NextDirectSignDialog=class NextDirectSignDialog extends Component{setup(){this.action=useService("action");this.signInfo=useService("signInfo");this.title=_t("Thank You!");}
goToNextSigner(){const newCurrentToken=this.signInfo.get("tokenList").shift();this.signInfo.get("nameList").shift();this.action.doAction({type:"ir.actions.client",tag:"sign.SignableDocument",name:_t("Sign"),},{additionalContext:{id:this.signInfo.get("documentId"),create_uid:this.signInfo.get("createUid"),state:this.signInfo.get("signRequestState"),token:newCurrentToken,token_list:this.signInfo.get("tokenList"),name_list:this.signInfo.get("nameList"),},stackPosition:"replaceCurrentAction",});this.props.close();}
get nextSigner(){return this.signInfo.get("nameList")[0];}
get dialogProps(){return{size:"md",technical:this.env.isSmall,fullscreen:this.env.isSmall,};}}
NextDirectSignDialog.template="sign.NextDirectSignDialog";NextDirectSignDialog.components={Dialog,};NextDirectSignDialog.props={close:Function,};return __exports;});;

/* /sign/static/src/dialogs/public_signer_dialog.js */
odoo.define('@sign/dialogs/public_signer_dialog',['@web/core/l10n/translation','@odoo/owl','@web/core/utils/hooks','@web/core/dialog/dialog'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{Component,useRef}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{Dialog}=require("@web/core/dialog/dialog");const PublicSignerDialog=__exports.PublicSignerDialog=class PublicSignerDialog extends Component{setup(){this.nameInput=useRef("name");this.mailInput=useRef("mail");this.rpc=useService("rpc");this.signInfo=useService("signInfo");}
get dialogProps(){return{title:_t("Final Validation"),size:"md",technical:this.env.isSmall,fullscreen:this.env.isSmall,};}
async submit(){const name=this.nameInput.el.value;const mail=this.mailInput.el.value;if(!this.validateForm(name,mail)){return false;}
const response=await this.rpc(`/sign/send_public/${this.signInfo.get("documentId")}/${this.signInfo.get(
                "signRequestToken"
            )}`,{name,mail});await this.props.postValidation(response["requestID"],response["requestToken"],response["accessToken"]);this.props.close();}
validateForm(name,mail){const isEmailInvalid=!mail||mail.indexOf("@")<0;if(!name||isEmailInvalid){this.nameInput.el.classList.toggle("is-invalid",!name);this.mailInput.el.classList.toggle("is-invalid",isEmailInvalid);return false;}
return true;}}
PublicSignerDialog.template="sign.PublicSignerDialog";PublicSignerDialog.components={Dialog,};PublicSignerDialog.props={name:String,mail:String,postValidation:Function,close:Function,};return __exports;});;

/* /sign/static/src/dialogs/sign_name_and_signature_dialog.js */
odoo.define('@sign/dialogs/sign_name_and_signature_dialog',['@web/core/l10n/translation','@web/core/dialog/dialog','@web/core/utils/hooks','@web/core/assets','@odoo/owl','@web/core/l10n/localization','@web/core/signature/name_and_signature'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{Dialog}=require("@web/core/dialog/dialog");const{useService}=require("@web/core/utils/hooks");const{loadJS}=require("@web/core/assets");const{Component,onWillStart,useRef,useState}=require("@odoo/owl");const{localization}=require("@web/core/l10n/localization");const{NameAndSignature}=require("@web/core/signature/name_and_signature");const SignNameAndSignature=__exports.SignNameAndSignature=class SignNameAndSignature extends NameAndSignature{setup(){super.setup();this.user=useService("user");this.props.signature.signatureChanged=this.state.signMode!=="draw";if(this.props.frame){this.state.activeFrame=this.props.activeFrame||false;this.frame=this.props.defaultFrame;this.signFrame=useRef("signFrame");this.props.frame.updateFrame=()=>{if(this.state.activeFrame){this.props.signature.signatureChanged=true;const xOffset=localization.direction==="rtl"?0.75:0.06;this.signFrame.el.classList.toggle("active",true);return html2canvas(this.signFrame.el,{backgroundColor:null,width:this.$signatureField.width(),height:this.$signatureField.height(),x:-this.$signatureField.width()*xOffset,y:-this.$signatureField.height()*0.09,}).then((canvas)=>{this.frame=canvas.toDataURL("image/png");});}
return Promise.resolve(false);};this.props.frame.getFrameImageSrc=()=>{return this.state.activeFrame?this.frame:false;};}
onWillStart(()=>{if(this.props.frame){return Promise.all([this.user.hasGroup("base.group_user").then((isSystemUser)=>{this.showFrameCheck=isSystemUser;}),loadJS("/web_editor/static/lib/html2canvas.js"),]);}});}
onFrameChange(){this.state.activeFrame=!this.state.activeFrame;}
onSignatureAreaClick(){if(this.state.signMode==="draw"){this.props.signature.signatureChanged=true;}}
onClickSignLoad(){super.onClickSignLoad();this.props.signature.signatureChanged=true;}
onClickSignAuto(){super.onClickSignAuto();this.props.signature.signatureChanged=true;}
onClickSignDrawClear(){super.onClickSignDrawClear();this.props.signature.signatureChanged=true;}
get signFrameClass(){return this.state.activeFrame&&this.state.signMode!=="draw"?"active":"";}
onInputSignName(e){super.onInputSignName(e);this.props.onSignatureChange(this.state.signMode);}}
SignNameAndSignature.template="sign.NameAndSignature";SignNameAndSignature.props={...NameAndSignature.props,activeFrame:Boolean,defaultFrame:String,frame:{type:Object,optional:true},hash:String,onSignatureChange:{type:Function,optional:true},};const SignNameAndSignatureDialog=__exports.SignNameAndSignatureDialog=class SignNameAndSignatureDialog extends Component{setup(){this.footerState=useState({buttonsDisabled:!this.props.signature.name,});}
get nameAndSignatureProps(){return{signature:this.props.signature||"signature",signatureType:this.props.signatureType,displaySignatureRatio:this.props.displaySignatureRatio,activeFrame:this.props.activeFrame,defaultFrame:this.props.defaultFrame||"",mode:this.props.mode||"auto",frame:this.props.frame||false,hash:this.props.hash,onSignatureChange:this.onSignatureChange.bind(this),};}
get dialogProps(){return{title:_t("Adopt Your Signature"),size:"md",};}
onSignatureChange(signMode){const signature=this.props.signature;const buttonsDisabled=!signature.name||(signature.isSignatureEmpty&&(!signMode||signMode!=="auto"));if(this.footerState.buttonsDisabled!==buttonsDisabled){this.footerState.buttonsDisabled=buttonsDisabled;}}}
SignNameAndSignatureDialog.props={signature:Object,frame:{type:Object,optional:true},signatureType:{type:String,optional:true},displaySignatureRatio:Number,activeFrame:Boolean,defaultFrame:{type:String,optional:true},mode:{type:String,optional:true},hash:String,onConfirm:Function,onConfirmAll:Function,onCancel:Function,close:Function,};SignNameAndSignatureDialog.components={Dialog,SignNameAndSignature,};SignNameAndSignatureDialog.template="sign.SignNameAndSignatureDialog";return __exports;});;

/* /sign/static/src/dialogs/sign_refusal_dialog.js */
odoo.define('@sign/dialogs/sign_refusal_dialog',['@web/core/l10n/translation','@odoo/owl','@web/core/utils/hooks','@web/core/dialog/dialog','@web/core/confirmation_dialog/confirmation_dialog','@sign/dialogs/thank_you_dialog'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{Component,useRef}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{Dialog}=require("@web/core/dialog/dialog");const{AlertDialog}=require("@web/core/confirmation_dialog/confirmation_dialog");const{ThankYouDialog}=require("@sign/dialogs/thank_you_dialog");const SignRefusalDialog=__exports.SignRefusalDialog=class SignRefusalDialog extends Component{setup(){this.refuseReasonEl=useRef("refuse-reason");this.refuseButton=useRef("refuse-button");this.rpc=useService("rpc");this.dialog=useService("dialog");this.signInfo=useService("signInfo");}
get dialogProps(){return{size:"md",title:_t("Refuse Document"),};}
checkForChanges(){const value=this.refuseReasonEl.el.value.trim();this.refuseButton.el.disabled=value.length===0?"disabled":"";}
async refuse(){const reason=this.refuseReasonEl.el.value;const route=`/sign/refuse/${this.signInfo.get("documentId")}/${this.signInfo.get(
            "signRequestItemToken"
        )}`;const params={refusal_reason:reason,};const response=await this.rpc(route,params);if(!response){this.dialog.add(AlertDialog,{body:_t("Sorry, you cannot refuse this document"),},{onClose:()=>window.location.reload(),});}
this.dialog.add(ThankYouDialog,{subtitle:_t("The document has been refused"),message:_t("We'll send an email to warn other contacts in copy & signers with the reason you provided."),});this.props.close();}}
SignRefusalDialog.template="sign.SignRefusalDialog";SignRefusalDialog.components={Dialog,};SignRefusalDialog.props={close:Function,};return __exports;});;

/* /sign/static/src/dialogs/sms_signer_dialog.js */
odoo.define('@sign/dialogs/sms_signer_dialog',['@web/core/l10n/translation','@odoo/owl','@web/core/utils/hooks','@web/core/dialog/dialog','@web/core/confirmation_dialog/confirmation_dialog','@web/core/browser/browser'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{Component,useState,useRef,useEffect}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{Dialog}=require("@web/core/dialog/dialog");const{AlertDialog}=require("@web/core/confirmation_dialog/confirmation_dialog");const{browser}=require("@web/core/browser/browser");const SMSSignerDialog=__exports.SMSSignerDialog=class SMSSignerDialog extends Component{setup(){this.validationCodeInput=useRef("code");this.phoneInput=useRef("phone");this.rpc=useService("rpc");this.dialog=useService("dialog");this.signInfo=useService("signInfo");this.SMSInfo={phoneNumber:this.props.signerPhone||""};this.state=useState({sendingSMS:false,SMSCount:0,});useEffect(()=>{return()=>{browser.clearTimeout(this.timeout);};},()=>[]);}
sendSMS(phoneNumber){this.state.sendingSMS=true;const route=`/sign/send-sms/${this.signInfo.get("documentId")}/${this.signInfo.get(
            "signRequestItemToken"
        )}/${phoneNumber}`;this.rpc(route).then((success)=>{if(success){this.handleSendSMSSuccess();}else{this.handleSMSError();}}).catch((_)=>{this.handleSMSError();});}
handleSendSMSSuccess(){this.timeout=browser.setTimeout(()=>{this.state.sendingSMS=false;this.state.SMSCount++;},15000);}
handleSMSError(){this.state.sendingSMS=false;this.dialog.add(AlertDialog,{title:_t("Error"),body:_t("Unable to send the SMS, please contact the sender of the document."),});}
onSendSMSClick(e){const sendButton=e.target;sendButton.setAttribute("disabled",true);const phoneNumber=this.phoneInput.el.value;if(phoneNumber){this.SMSInfo.phoneNumber=phoneNumber;this.sendSMS(phoneNumber);}
sendButton.removeAttribute("disabled");}
async validateSMS(e){const validateButton=e.target;const validationCode=this.validationCodeInput.el?.value;if(!validationCode){this.validationCodeInput.el.classList.toggle("is-invalid");return false;}
validateButton.setAttribute("disabled",true);await this.props.postValidation(validationCode);validateButton.removeAttribute("disabled");this.props.close();}
get dialogProps(){return{size:"md",title:_t("Final Validation"),fullscreen:this.env.isSmall,};}}
SMSSignerDialog.template="sign.SMSSignerDialog";SMSSignerDialog.components={Dialog,};SMSSignerDialog.props={signerPhone:{type:String,optional:true,},postValidation:Function,close:Function,};return __exports;});;

/* /sign/static/src/dialogs/thank_you_dialog.js */
odoo.define('@sign/dialogs/thank_you_dialog',['@web/core/l10n/translation','@web/session','@web/core/dialog/dialog','@web/core/utils/hooks','@sign/dialogs/encrypted_dialog','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{session}=require("@web/session");const{Dialog}=require("@web/core/dialog/dialog");const{useService}=require("@web/core/utils/hooks");const{EncryptedDialog}=require("@sign/dialogs/encrypted_dialog");const{Component,onWillStart,useState}=require("@odoo/owl");const ThankYouDialog=__exports.ThankYouDialog=class ThankYouDialog extends Component{setup(){this.user=useService("user");this.rpc=useService("rpc");this.dialog=useService("dialog");this.signInfo=useService("signInfo");this.state=useState({nextDocuments:[],buttons:[],});this.redirectURL=this.processURL(this.props.redirectURL);this.message=this.props.message||_t("You will receive the final signed document by email.");onWillStart(this.willStart);}
get suggestSignUp(){return session.user_id===false;}
get dialogProps(){return{size:"md",};}
async checkIfEncryptedDialog(){const route=`/sign/encrypted/${this.signInfo.get("documentId")}`;return this.rpc(route);}
async willStart(){const isEncrypted=await this.checkIfEncryptedDialog();if(isEncrypted){this.dialog.add(EncryptedDialog);}
this.signRequestState=await this.rpc(`/sign/sign_request_state/${this.signInfo.get("documentId")}/${this.signInfo.get(
                "signRequestToken"
            )}`);if(!this.suggestSignUp&&!session.is_website_user){const result=await this.rpc("/sign/sign_request_items",{request_id:this.signInfo.get("documentId"),token:this.signInfo.get("signRequestToken"),});if(result&&result.length){this.state.nextDocuments=result.map((doc)=>{return{id:doc.id,name:doc.name,date:doc.date,user:doc.user,accessToken:doc.token,requestId:doc.requestId,ignored:false,};});}}
this.generateButtons();}
generateButtons(){if(this.redirectURL){this.state.buttons.push({name:this.props.redirectURLText,click:()=>{window.location.assign(this.redirectURL);},});}
if(this.signRequestState==="signed"){this.state.buttons.push({name:_t("Download Document"),click:this.downloadDocument,});}
if(this.suggestSignUp){this.message+=_t(" You can safely close this window.");this.state.buttons.push({name:_t("Sign Up for free"),classes:"btn btn-link ms-auto",ignored:true,click:()=>{window.open("https://www.odoo.com/trial?selected_app=sign&utm_source=db&utm_medium=sign","_blank");},});}else{this.state.buttons.push({name:_t("Close"),click:()=>{if(session.is_frontend){window.location.assign("/");}else{this.props.close();this.env.services.action.doAction("sign.sign_template_action",{clearBreadcrumbs:true,});}},});if(this.state.nextDocuments.length>0){this.state.buttons.push({name:_t("Sign Next Document"),classes:"o_thankyou_button_next",click:this.clickButtonNext,});}}
for(let i=0;i<this.state.buttons.length;i++){if(this.state.buttons[i].ignored){continue;}
const buttonClass=i===0?"btn btn-primary":"btn btn-secondary";this.state.buttons[i].classes=`${this.state.buttons[i].classes} ${buttonClass}`;}}
processURL(url){if(url&&!/^(f|ht)tps?:\/\//i.test(url)){url=`http://${url}`;}
return url;}
goToDocument(id,token){window.location.assign(this.makeURI("/sign/document",id,token,undefined,{portal:1}));}
clickNextSign(id,token){this.goToDocument(id,token);}
clickButtonNext(){const nextDocument=this.state.nextDocuments.find((document)=>!document.ignored);this.goToDocument(nextDocument.requestId,nextDocument.accessToken);}
async clickNextIgnore(doc){const result=await this.rpc(`/sign/ignore_sign_request_item/${doc.id}/${doc.accessToken}`);if(result){this.state.nextDocuments=this.state.nextDocuments.map((nextDoc)=>{if(nextDoc.id===doc.id){return{...nextDoc,ignored:true,};}
return nextDoc;});if(this.state.nextDocuments.every((doc)=>doc.ignored)){this.state.buttons=this.state.buttons.map((button)=>{if(button.name===_t("Sign Next Document")){return{...button,disabled:true,};}
return button;});}}}
async downloadDocument(){window.location.assign(this.makeURI("/sign/download",this.signInfo.get("documentId"),this.signInfo.get("signRequestToken"),"/completed"));}
makeURI(baseUrl,requestID,token,suffix="",params=""){params=params?"?"+new URLSearchParams(params).toString():"";return`${baseUrl}/${requestID}/${token}${suffix}${params}`;}}
ThankYouDialog.template="sign.ThankYouDialog";ThankYouDialog.components={Dialog,};ThankYouDialog.props={message:{type:String,optional:true,},subtitle:{type:String,optional:true,},redirectURL:{type:String,optional:true,},redirectURLText:{type:String,optional:true,},close:Function,};return __exports;});;

/* /sign/static/src/services/sign_info_service.js */
odoo.define('@sign/services/sign_info_service',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const signInfoService=__exports.signInfoService={dependencies:[],start(){let signInfo={};function set(data){Object.assign(signInfo,data);}
function reset(data){signInfo=data;}
function get(key){return signInfo[key];}
return{set,reset,get,};},};registry.category("services").add("signInfo",signInfoService);return __exports;});;

/* /sale_subscription/static/src/js/payment_form.js */
odoo.define('@sale_subscription/js/payment_form',['@web/core/confirmation_dialog/confirmation_dialog','@web/core/l10n/translation','@web/core/utils/render','@payment/js/payment_form'],function(require){'use strict';let __exports={};const{ConfirmationDialog}=require('@web/core/confirmation_dialog/confirmation_dialog');const{_t}=require('@web/core/l10n/translation');const{renderToMarkup}=require('@web/core/utils/render');const paymentForm=require('@payment/js/payment_form')[Symbol.for("default")];paymentForm.include({_challengeTokenDeletion(tokenId,linkedRecordsInfo){if(linkedRecordsInfo.every(linkedRecordInfo=>!linkedRecordInfo['active_subscription'])){this._super(...arguments);return;}
const body=renderToMarkup('sale_subscription.deleteTokenDialog',{linkedRecordsInfo});this.call('dialog','add',ConfirmationDialog,{title:_t("Warning!"),body,cancel:()=>{},});},});return __exports;});;

/* /sale_subscription/static/src/js/portal_subscription.js */
odoo.define('@sale_subscription/js/portal_subscription',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.SubscriptionChangePlan=publicWidget.Widget.extend({selector:'.o_portal_sale_sidebar',start:async function(){if(new URLSearchParams(window.location.search).get('change_plan')==='true'){const changePlanButton=document.getElementById('o_change_plan');changePlanButton&&changePlanButton.click();}}});publicWidget.registry.SubscriptionCloseSelect=publicWidget.Widget.extend({selector:'#subscription-close-select',events:{'change':'_onChange',},_onChange:function(){const reasonId=this.$el.val();$('.subscription-close-message').add('.subscription-close-link').hide().filter((i,e)=>$(e).attr('data-id')==reasonId).show();$('.subscription-close-init-retain').addClass('d-none');$('.subscription-close-init-noretain').addClass('d-none');if(reasonId){if(this.$el.children(':selected').attr('data-retention')){$('.subscription-close-init-retain').removeClass('d-none');}else{$('.subscription-close-init-noretain').removeClass('d-none');}}},});publicWidget.registry.SubscriptionCloseFinish=publicWidget.Widget.extend({selector:'.subscription-close-finish',events:{'click':'_onClick',},_onClick:function(){this.$el.attr('disabled',true);this.$el.prepend('<i class="fa fa-refresh fa-spin"></i> ');$('#wc-modal-close-init form').submit();},});return __exports;});;

/* /planning/static/src/js/planning_calendar_front.js */
odoo.define('@planning/js/planning_calendar_front',['@web/legacy/js/public/public_widget','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{_t}=require("@web/core/l10n/translation");const{DateTime}=luxon;publicWidget.registry.PlanningView=publicWidget.Widget.extend({selector:'#calendar_employee',jsLibs:['/web/static/lib/fullcalendar/core/main.js','/web/static/lib/fullcalendar/core/locales-all.js','/web/static/lib/fullcalendar/interaction/main.js','/web/static/lib/fullcalendar/daygrid/main.js','/web/static/lib/fullcalendar/timegrid/main.js','/web/static/lib/fullcalendar/list/main.js'],cssLibs:['/web/static/lib/fullcalendar/core/main.css','/web/static/lib/fullcalendar/daygrid/main.css','/web/static/lib/fullcalendar/timegrid/main.css','/web/static/lib/fullcalendar/list/main.css'],init:function(parent,options){this._super.apply(this,arguments);},start:function(){if($('.message_slug').attr('value')){$("#PlanningToast").toast('show');}
this._super.apply(this,arguments);if($('.no_data').attr('value')){return;}
this.calendarElement=this.$(".o_calendar_widget")[0];const employeeSlotsFcData=JSON.parse($('.employee_slots_fullcalendar_data').attr('value'));const openSlotsIds=$('.open_slots_ids').attr('value');const locale=$('.locale').attr('value');$('[data-bs-toggle="popover"]').popover();$('body').on('click',function(e){var parentElsClassList=$(e.target).parents().map(function(){return[...this.classList];})
if(!['assignee-cell','contact-assignee-popover'].some(el=>[...parentElsClassList].includes(el))){$('[data-bs-toggle="popover"]').popover('hide');}});$('[data-bs-toggle="popover"]').on('click',function(e){$('[data-bs-toggle="popover"]').not(this).popover('hide');});const defaultStartValue=$('.default_start').attr('value');const defaultView=$('.default_view').attr('value');const minTime=$('.mintime').attr('value');const maxTime=$('.maxtime').attr('value');let calendarHeaders={left:'dayGridMonth,timeGridWeek,listMonth',center:'title',right:'today,prev,next',};if(employeeSlotsFcData.length===0){calendarHeaders={left:false,center:'title',right:false,};}
const titleFormat={month:"long",year:"numeric"};if(defaultView&&defaultStartValue&&(employeeSlotsFcData||openSlotsIds)){this.calendar=new FullCalendar.Calendar($("#calendar_employee")[0],{plugins:["luxon","dayGrid","timeGrid","list","interraction"],locale:locale,defaultView:defaultView,navLinks:true,eventLimit:3,titleFormat:titleFormat,defaultDate:DateTime.fromFormat(defaultStartValue,"yyyy-MM-dd").toJSDate(),timeFormat:'LT',displayEventEnd:true,height:'auto',eventRender:this.eventRenderFunction,eventTextColor:'white',eventOverlap:true,eventTimeFormat:{hour:'numeric',minute:'2-digit',meridiem:'long',omitZeroMinute:true,},minTime:minTime,maxTime:maxTime,header:calendarHeaders,events:employeeSlotsFcData,eventClick:this.eventFunction.bind(this),buttonText:{today:_t("Today"),dayGridMonth:_t("Month"),timeGridWeek:_t("Week"),listMonth:_t("List"),},noEventsMessage:'',});this.calendar.setOption('locale',locale);this.calendar.render();}},eventRenderFunction:function(calRender){const eventContent=calRender.el.querySelectorAll('.fc-time, .fc-title');if(calRender.view.type!='listMonth'){calRender.el.classList.add('px-2','py-1');}
if(calRender.view.type==='dayGridMonth'){for(let i=0;i<eventContent.length;i++){eventContent[i].classList.add('d-block','text-truncate');}}
calRender.el.classList.add('cursor-pointer');calRender.el.childNodes[0].classList.add('fw-bold');if(calRender.event.extendedProps.request_to_switch&&!calRender.event.extendedProps.allow_self_unassign){calRender.el.style.borderColor='rgb(255, 172, 0)';calRender.el.style.borderWidth='5px';calRender.el.style.opacity='0.7';}},formatDateAsBackend:function(date){return DateTime.fromJSDate(date).toLocaleString({...DateTime.DATE_SHORT,...DateTime.TIME_24_SIMPLE,weekday:"short",});},eventFunction:function(calEvent){const planningToken=$('.planning_token').attr('value');const employeeToken=$('.employee_token').attr('value');let displayFooter=false;$(".modal-title").text(calEvent.event.title);$(".modal-header").css("background-color",calEvent.event.backgroundColor);if(calEvent.event.extendedProps.request_to_switch&&!calEvent.event.extendedProps.allow_self_unassign){document.getElementById("switch-warning").style.display="block";$(".warning-text").text("You requested to switch this shift. Other employees can now assign themselves to it.");}else{document.getElementById("switch-warning").style.display="none";}
$('.o_start_date').text(this.formatDateAsBackend(calEvent.event.start));let textValue=this.formatDateAsBackend(calEvent.event.end);if(calEvent.event.extendedProps.alloc_hours){textValue+=` (${calEvent.event.extendedProps.alloc_hours})`;}
if(parseFloat(calEvent.event.extendedProps.alloc_perc)<100){textValue+=` (${calEvent.event.extendedProps.alloc_perc}%)`;}
$('.o_end_date').text(textValue);if(calEvent.event.extendedProps.role){$("#role").prev().css("display","");$("#role").text(calEvent.event.extendedProps.role);$("#role").css("display","");}else{$("#role").prev().css("display","none");$("#role").css("display","none");}
if(calEvent.event.extendedProps.note){$("#note").prev().css("display","");$("#note").text(calEvent.event.extendedProps.note);$("#note").css("display","");}else{$("#note").prev().css("display","none");$("#note").css("display","none");}
$("#allow_self_unassign").text(calEvent.event.extendedProps.allow_self_unassign);if(calEvent.event.extendedProps.allow_self_unassign&&!calEvent.event.extendedProps.is_unassign_deadline_passed){document.getElementById("dismiss_shift").style.display="block";displayFooter=true;}else{document.getElementById("dismiss_shift").style.display="none";}
if(!calEvent.event.extendedProps.request_to_switch&&!calEvent.event.extendedProps.is_past&&!calEvent.event.extendedProps.allow_self_unassign){document.getElementById("switch_shift").style.display="block";displayFooter=true;}else{document.getElementById("switch_shift").style.display="none";}
if(calEvent.event.extendedProps.request_to_switch&&!calEvent.event.extendedProps.allow_self_unassign){document.getElementById("cancel_switch").style.display="block";displayFooter=true;}else{document.getElementById("cancel_switch").style.display="none";}
$("#modal_action_dismiss_shift").attr("action","/planning/"+planningToken+"/"+employeeToken+"/unassign/"+calEvent.event.extendedProps.slot_id);$("#modal_action_switch_shift").attr("action","/planning/"+planningToken+"/"+employeeToken+"/switch/"+calEvent.event.extendedProps.slot_id);$("#modal_action_cancel_switch").attr("action","/planning/"+planningToken+"/"+employeeToken+"/cancel_switch/"+calEvent.event.extendedProps.slot_id);$("#fc-slot-onclick-modal").modal("show");document.getElementsByClassName("modal-footer")[0].style.display=displayFooter?"block":"none";},});__exports[Symbol.for("default")]=publicWidget.registry.PlanningView;return __exports;});;

/* /industry_fsm/static/src/js/tours/industry_fsm_tour.js */
odoo.define('@industry_fsm/js/tours/industry_fsm_tour',['@web/core/l10n/translation','@web/core/registry','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{markup}=require("@odoo/owl");registry.category("web_tour.tours").add('industry_fsm_tour',{sequence:90,url:"/web",steps:()=>[{trigger:'.o_app[data-menu-xmlid="industry_fsm.fsm_menu_root"]',content:markup(_t('Ready to <b>manage your onsite interventions</b>? <i>Click Field Service to start.</i>')),position:'bottom',},{trigger:'.o-kanban-button-new',extra_trigger:'.o_fsm_kanban',content:markup(_t('Let\'s create your first <b>task</b>.')),position:'bottom',},{trigger:'h1 div[name="name"] > div > textarea',extra_trigger:'.o_form_editable',content:markup(_t('Give it a <b>title</b> <i>(e.g. Boiler maintenance, Air-conditioning installation, etc.).</i>')),position:'right',width:200,},{trigger:".o_field_widget[name=partner_id]",content:markup(_t('Select the <b>customer</b> for your task.')),position:"right",run(){document.querySelector('.o_field_widget[name="partner_id"] input').click();}},{trigger:".ui-autocomplete > li > a:not(:has(i.fa))",auto:true,},{trigger:'button[name="action_timer_start"]',extra_trigger:'.o_form_project_tasks',content:markup(_t('Launch the timer to <b>track the time spent</b> on your task.')),position:"bottom",id:'fsm_start',},{trigger:'button[name="action_timer_stop"]',content:markup(_t('Stop the <b>timer</b> when you are done.')),position:'bottom',},{trigger:'button[name="save_timesheet"]',content:markup(_t('Confirm the <b>time spent</b> on your task. <i>Tip: note that the duration has automatically been rounded to 15 minutes.</i>')),position:'bottom',id:"fsm_save_timesheet"},{trigger:"button[name='action_fsm_validate']",extra_trigger:'.o_form_project_tasks',content:markup(_t('Let\'s <b>mark your task as done!</b> <i>Tip: when doing so, your stock will automatically be updated, and your task will be closed.</i>')),position:'bottom',},{trigger:"div[name='state'] .btn-outline-success",auto:true,isCheck:true,id:'fsm_invoice_create',}]});return __exports;});;

/* /web/static/src/views/fields/file_handler.js */
odoo.define('@web/views/fields/file_handler',['@web/core/l10n/translation','@web/core/utils/hooks','@web/core/utils/urls','@web/core/utils/files','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const{getDataURLFromFile}=require("@web/core/utils/urls");const{checkFileSize}=require("@web/core/utils/files");const{Component,useRef,useState}=require("@odoo/owl");const FileUploader=__exports.FileUploader=class FileUploader extends Component{setup(){this.notification=useService("notification");this.fileInputRef=useRef("fileInput");this.state=useState({isUploading:false,});}
async onFileChange(ev){if(!ev.target.files.length){return;}
const{target}=ev;for(const file of ev.target.files){if(!checkFileSize(file.size,this.notification)){return null;}
this.state.isUploading=true;const data=await getDataURLFromFile(file);if(!file.size){console.warn(`Error while uploading file : ${file.name}`);this.notification.add(_t("There was a problem while uploading your file."),{type:"danger",});}
try{await this.props.onUploaded({name:file.name,size:file.size,type:file.type,data:data.split(",")[1],objectUrl:file.type==="application/pdf"?URL.createObjectURL(file):null,});}finally{this.state.isUploading=false;}}
target.value=null;if(this.props.multiUpload&&this.props.onUploadComplete){this.props.onUploadComplete({});}}
async onSelectFileButtonClick(ev){if(this.props.onClick){const ok=await this.props.onClick(ev);if(ok!==undefined&&!ok){return;}}
this.fileInputRef.el.click();}}
FileUploader.template="web.FileUploader";FileUploader.props={onClick:{type:Function,optional:true},onUploaded:Function,onUploadComplete:{type:Function,optional:true},multiUpload:{type:Boolean,optional:true},inputName:{type:String,optional:true},fileUploadClass:{type:String,optional:true},acceptedFileExtensions:{type:String,optional:true},slots:{type:Object,optional:true},showUploadingText:{type:Boolean,optional:true},};FileUploader.defaultProps={showUploadingText:true,};return __exports;});;

/* /web/static/src/views/fields/formatters.js */
odoo.define('@web/views/fields/formatters',['@web/core/l10n/dates','@web/core/l10n/localization','@web/core/l10n/translation','@web/core/registry','@web/core/utils/strings','@web/core/utils/binary','@web/core/utils/numbers','@odoo/owl','@web/core/currency'],function(require){'use strict';let __exports={};const{formatDate,formatDateTime}=require("@web/core/l10n/dates");const{localization:l10n}=require("@web/core/l10n/localization");const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{escape}=require("@web/core/utils/strings");const{isBinarySize}=require("@web/core/utils/binary");const{formatFloat:formatFloatNumber,humanNumber,insertThousandsSep,}=require("@web/core/utils/numbers");const{markup}=require("@odoo/owl");const{formatCurrency}=require("@web/core/currency");function humanSize(value){if(!value){return"";}
const suffix=value<1024?" "+_t("Bytes"):"b";return(humanNumber(value,{decimals:2,})+suffix);}
__exports.formatBinary=formatBinary;function formatBinary(value){if(!isBinarySize(value)){return humanSize(value.length/1.37);}
return value;}
__exports.formatBoolean=formatBoolean;function formatBoolean(value){return markup(`
        <div class="o-checkbox d-inline-block me-2">
            <input id="boolean_checkbox" type="checkbox" class="form-check-input" disabled ${
                value ? "checked" : ""
            }/>
            <label for="boolean_checkbox" class="form-check-label"/>
        </div>`);}
__exports.formatChar=formatChar;function formatChar(value,options){if(options&&options.isPassword){return"*".repeat(value?value.length:0);}
if(options&&options.escape){value=escape(value);}
return value;}
__exports.formatFloat=formatFloat;function formatFloat(value,options={}){if(value===false){return"";}
return formatFloatNumber(value,options);}
__exports.formatFloatFactor=formatFloatFactor;function formatFloatFactor(value,options={}){if(value===false){return"";}
const factor=options.factor||1;return formatFloatNumber(value*factor,options);}
__exports.formatFloatTime=formatFloatTime;function formatFloatTime(value,options={}){if(value===false){return"";}
const isNegative=value<0;value=Math.abs(value);let hour=Math.floor(value);const milliSecLeft=Math.round(value*3600000)-hour*3600000;let min=milliSecLeft/60000;if(options.displaySeconds){min=Math.floor(min);}else{min=Math.round(min);}
if(min===60){min=0;hour=hour+1;}
min=String(min).padStart(2,"0");if(!options.noLeadingZeroHour){hour=String(hour).padStart(2,"0");}
let sec="";if(options.displaySeconds){sec=":"+String(Math.floor((milliSecLeft%60000)/1000)).padStart(2,"0");}
return`${isNegative ? "-" : ""}${hour}:${min}${sec}`;}
__exports.formatInteger=formatInteger;function formatInteger(value,options={}){if(value===false||value===null){return"";}
if(options.isPassword){return"*".repeat(value.length);}
if(options.humanReadable){return humanNumber(value,options);}
const grouping=options.grouping||l10n.grouping;const thousandsSep="thousandsSep"in options?options.thousandsSep:l10n.thousandsSep;return insertThousandsSep(value.toFixed(0),thousandsSep,grouping);}
__exports.formatMany2one=formatMany2one;function formatMany2one(value,options){if(!value){value="";}else if(value[1]){value=value[1];}else{value=_t("Unnamed");}
if(options&&options.escape){value=encodeURIComponent(value);}
return value;}
__exports.formatX2many=formatX2many;function formatX2many(value){const count=value.currentIds.length;if(count===0){return _t("No records");}else if(count===1){return _t("1 record");}else{return _t("%s records",count);}}
__exports.formatMonetary=formatMonetary;function formatMonetary(value,options={}){if(value===false){return"";}
let currencyId=options.currencyId;if(!currencyId&&options.data){const currencyField=options.currencyField||(options.field&&options.field.currency_field)||"currency_id";const dataValue=options.data[currencyField];currencyId=Array.isArray(dataValue)?dataValue[0]:dataValue;}
return formatCurrency(value,currencyId,options)}
__exports.formatPercentage=formatPercentage;function formatPercentage(value,options={}){value=value||0;options=Object.assign({trailingZeros:false,thousandsSep:""},options);const formatted=formatFloatNumber(value*100,options);return`${formatted}${options.noSymbol ? "" : "%"}`;}
function formatProperties(value,field){if(!value||!value.length){return"";}
return value.map((property)=>property["string"]).join(", ");}
__exports.formatReference=formatReference;function formatReference(value,options){return formatMany2one(value?[value.resId,value.displayName]:false,options);}
__exports.formatSelection=formatSelection;function formatSelection(value,options={}){const selection=options.selection||(options.field&&options.field.selection)||[];const option=selection.find((option)=>option[0]===value);return option?option[1]:"";}
__exports.formatText=formatText;function formatText(value){return value?value.toString():"";}
__exports.formatHtml=formatHtml;function formatHtml(value){return value;}
__exports.formatJson=formatJson;function formatJson(value){return(value&&JSON.stringify(value))||"";}
registry.category("formatters").add("binary",formatBinary).add("boolean",formatBoolean).add("char",formatChar).add("date",formatDate).add("datetime",formatDateTime).add("float",formatFloat).add("float_factor",formatFloatFactor).add("float_time",formatFloatTime).add("html",formatHtml).add("integer",formatInteger).add("json",formatJson).add("many2one",formatMany2one).add("many2one_reference",formatInteger).add("one2many",formatX2many).add("many2many",formatX2many).add("monetary",formatMonetary).add("percentage",formatPercentage).add("properties",formatProperties).add("properties_definition",formatProperties).add("reference",formatReference).add("selection",formatSelection).add("text",formatText);return __exports;});;

/* /mail/static/src/core/common/attachment_list.js */
odoo.define('@mail/core/common/attachment_list',['@odoo/owl','@web/core/confirmation_dialog/confirmation_dialog','@web/core/file_viewer/file_viewer_hook','@web/core/l10n/translation','@web/core/utils/hooks','@web/core/utils/urls'],function(require){'use strict';let __exports={};const{Component,useState}=require("@odoo/owl");const{ConfirmationDialog}=require("@web/core/confirmation_dialog/confirmation_dialog");const{useFileViewer}=require("@web/core/file_viewer/file_viewer_hook");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const{url}=require("@web/core/utils/urls");const AttachmentList=__exports.AttachmentList=class AttachmentList extends Component{static props=["attachments","unlinkAttachment","imagesHeight","messageSearch?"];static template="mail.AttachmentList";setup(){this.ui=useState(useService("ui"));this.imagesWidth=1920;this.dialog=useService("dialog");this.fileViewer=useFileViewer();}
get nonImagesAttachments(){return this.props.attachments.filter((attachment)=>!attachment.isImage);}
get imagesAttachments(){return this.props.attachments.filter((attachment)=>attachment.isImage);}
getImageUrl(attachment){if(attachment.uploading&&attachment.tmpUrl){return attachment.tmpUrl;}
return url(attachment.urlRoute,{...attachment.urlQueryParams,width:this.imagesWidth,height:this.props.imagesHeight,});}
canDownload(attachment){return!attachment.uploading&&!this.env.inComposer;}
onClickDownload(attachment){const downloadLink=document.createElement("a");downloadLink.setAttribute("href",attachment.downloadUrl);downloadLink.setAttribute("download","");downloadLink.click();}
onClickUnlink(attachment){if(this.env.inComposer){return this.props.unlinkAttachment(attachment);}
this.dialog.add(ConfirmationDialog,{body:_t('Do you really want to delete "%s"?',attachment.filename),cancel:()=>{},confirm:()=>this.onConfirmUnlink(attachment),});}
onConfirmUnlink(attachment){this.props.unlinkAttachment(attachment);}
onImageLoaded(){this.env.onImageLoaded?.();}
get isInChatWindowAndIsAlignedRight(){return this.env.inChatWindow&&this.env.alignedRight;}
get isInChatWindowAndIsAlignedLeft(){return this.env.inChatWindow&&!this.env.alignedRight;}
get showDelete(){if(this.env.inComposer){return true;}
if(!this.attachment.isDeletable){return false;}
return(!this.env.message||this.env.message.hasTextContent||(this.env.message&&this.props.attachments.length>1));}}
return __exports;});;

/* /mail/static/src/core/common/attachment_model.js */
odoo.define('@mail/core/common/attachment_model',['@mail/core/common/record','@web/core/l10n/dates','@web/core/file_viewer/file_model'],function(require){'use strict';let __exports={};const{Record}=require("@mail/core/common/record");const{deserializeDateTime}=require("@web/core/l10n/dates");const{FileModelMixin}=require("@web/core/file_viewer/file_model");const Attachment=__exports.Attachment=class Attachment extends FileModelMixin(Record){static id="id";static records={};static get(data){return super.get(data);}
static insert(data){return super.insert(...arguments);}
static new(data){const attachment=super.new(data);Record.onChange(attachment,["extension","name"],()=>{if(!attachment.extension&&attachment.name){attachment.extension=attachment.name.split(".").pop();}});return attachment;}
originThread=Record.one("Thread",{inverse:"attachments"});res_name;message=Record.one("Message");create_date;get isDeletable(){return true;}
get monthYear(){if(!this.create_date){return undefined;}
const datetime=deserializeDateTime(this.create_date);return`${datetime.monthLong}, ${datetime.year}`;}}
Attachment.register();return __exports;});;

/* /mail/static/src/core/common/attachment_service.js */
odoo.define('@mail/core/common/attachment_service',['@mail/utils/common/misc','@web/core/registry'],function(require){'use strict';let __exports={};const{assignDefined}=require("@mail/utils/common/misc");const{registry}=require("@web/core/registry");const AttachmentService=__exports.AttachmentService=class AttachmentService{constructor(env,services){this.setup(env,services);}
setup(env,services){this.env=env;this.store=services["mail.store"];this.rpc=services["rpc"];}
remove(attachment){if(attachment.tmpUrl){URL.revokeObjectURL(attachment.tmpUrl);}
attachment.delete();}
async delete(attachment){if(attachment.id>0){await this.rpc("/mail/attachment/delete",assignDefined({attachment_id:attachment.id},{access_token:attachment.accessToken}));}
this.remove(attachment);}}
const attachmentService=__exports.attachmentService={dependencies:["mail.store","rpc"],start(env,services){return new AttachmentService(env,services);},};registry.category("services").add("mail.attachment",attachmentService);return __exports;});;

/* /mail/static/src/core/common/attachment_upload_service.js */
odoo.define('@mail/core/common/attachment_upload_service',['@web/core/l10n/translation','@web/core/registry','@web/core/utils/concurrency'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{Deferred}=require("@web/core/utils/concurrency");let nextId=-1;const AttachmentUploadService=__exports.AttachmentUploadService=class AttachmentUploadService{constructor(env,services){this.setup(env,services);}
setup(env,services){this.env=env;this.fileUploadService=services["file_upload"];this.store=services["mail.store"];this.notificationService=services["notification"];this.attachmentService=services["mail.attachment"];this.abortByAttachmentId=new Map();this.deferredByAttachmentId=new Map();this.uploadingAttachmentIds=new Set();this.hookersByTmpId=new Map();this.fileUploadService.bus.addEventListener("FILE_UPLOAD_ADDED",({detail:{upload}})=>{const tmpId=parseInt(upload.data.get("temporary_id"));if(!this.uploadingAttachmentIds.has(tmpId)){return;}
const hooker=this.hookersByTmpId.get(tmpId);const threadId=parseInt(upload.data.get("thread_id"));const threadModel=upload.data.get("thread_model");const tmpUrl=upload.data.get("tmp_url");const originThread=this.store.Thread.insert({model:threadModel,id:threadId,});this.abortByAttachmentId.set(tmpId,upload.xhr.abort.bind(upload.xhr));const attachment=this.store.Attachment.insert(this._makeAttachmentData(upload,tmpId,hooker.composer?undefined:originThread,tmpUrl));if(hooker.composer){hooker.composer.attachments.push(attachment);}});this.fileUploadService.bus.addEventListener("FILE_UPLOAD_LOADED",({detail:{upload}})=>{const tmpId=parseInt(upload.data.get("temporary_id"));if(!this.uploadingAttachmentIds.has(tmpId)){return;}
this.uploadingAttachmentIds.delete(tmpId);this.abortByAttachmentId.delete(tmpId);const hooker=this.hookersByTmpId.get(tmpId);if(upload.xhr.status===413){this.notificationService.add(_t("File too large"),{type:"danger"});this.hookersByTmpId.delete(tmpId);return;}
if(upload.xhr.status!==200){this.notificationService.add(_t("Server error"),{type:"danger"});this.hookersByTmpId.delete(tmpId);return;}
const response=JSON.parse(upload.xhr.response);if(response.error){this.notificationService.add(response.error,{type:"danger"});this.hookersByTmpId.delete(tmpId);return;}
const threadId=parseInt(upload.data.get("thread_id"));const threadModel=upload.data.get("thread_model");const originThread=this.store.Thread.get({model:threadModel,id:threadId});const attachment=this.store.Attachment.insert({...response,extension:upload.title.split(".").pop(),originThread:hooker.composer?undefined:originThread,});if(hooker.composer){const index=hooker.composer.attachments.findIndex(({id})=>id===tmpId);if(index>=0){hooker.composer.attachments[index]=attachment;}else{hooker.composer.attachments.push(attachment);}}
const def=this.deferredByAttachmentId.get(tmpId);this.unlink(this.store.Attachment.get(tmpId));if(def){def.resolve(attachment);this.deferredByAttachmentId.delete(tmpId);}
hooker.onFileUploaded?.();this.hookersByTmpId.delete(tmpId);});this.fileUploadService.bus.addEventListener("FILE_UPLOAD_ERROR",({detail:{upload}})=>{const tmpId=parseInt(upload.data.get("temporary_id"));if(!this.uploadingAttachmentIds.has(tmpId)){return;}
this.abortByAttachmentId.delete(tmpId);this.deferredByAttachmentId.delete(tmpId);this.uploadingAttachmentIds.delete(parseInt(tmpId));this.hookersByTmpId.delete(tmpId);});}
get uploadURL(){return"/mail/attachment/upload";}
async unlink(attachment){const abort=this.abortByAttachmentId.get(attachment.id);const def=this.deferredByAttachmentId.get(attachment.id);if(abort){abort();def.resolve();}
this.abortByAttachmentId.delete(attachment.id);this.deferredByAttachmentId.delete(attachment.id);await this.attachmentService.delete(attachment);}
async uploadFile(hooker,file,options){const tmpId=nextId--;this.hookersByTmpId.set(tmpId,hooker);this.uploadingAttachmentIds.add(tmpId);await this.fileUploadService.upload(this.uploadURL,[file],{buildFormData:(formData)=>{this._makeFormData(formData,file,hooker,tmpId,options);},}).catch((e)=>{if(e.name!=="AbortError"){throw e;}});const uploadDoneDeferred=new Deferred();this.deferredByAttachmentId.set(tmpId,uploadDoneDeferred);return uploadDoneDeferred;}
_makeFormData(formData,file,hooker,tmpId,options){formData.append("thread_id",hooker.thread.id);formData.append("tmp_url",URL.createObjectURL(file));formData.append("thread_model",hooker.thread.model);formData.append("is_pending",Boolean(hooker.composer));formData.append("temporary_id",tmpId);if(options?.activity){formData.append("activity_id",options.activity.id);}
return formData;}
_makeAttachmentData(upload,tmpId,originThread,tmpUrl){const attachmentData={filename:upload.title,id:tmpId,mimetype:upload.type,name:upload.title,originThread:originThread,extension:upload.title.split(".").pop(),uploading:true,tmpUrl,};return attachmentData;}}
const attachmentUploadService=__exports.attachmentUploadService={dependencies:["file_upload","mail.attachment","mail.store","notification"],start(env,services){return new AttachmentUploadService(env,services);},};registry.category("services").add("mail.attachment_upload",attachmentUploadService);return __exports;});;

/* /mail/static/src/core/common/attachment_uploader_hook.js */
odoo.define('@mail/core/common/attachment_uploader_hook',['@odoo/owl','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{useState}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");function dataUrlToBlob(data,type){const binData=window.atob(data);const uiArr=new Uint8Array(binData.length);uiArr.forEach((_,index)=>(uiArr[index]=binData.charCodeAt(index)));return new Blob([uiArr],{type});}
const AttachmentUploader=__exports.AttachmentUploader=class AttachmentUploader{constructor(thread,{composer,onFileUploaded}={}){this.attachmentUploadService=useService("mail.attachment_upload");Object.assign(this,{thread,composer,onFileUploaded});}
uploadData({data,name,type},options){const file=new File([dataUrlToBlob(data,type)],name,{type});return this.uploadFile(file,options);}
async uploadFile(file,options){return this.attachmentUploadService.uploadFile(this,file,options);}
async unlink(attachment){await this.attachmentUploadService.unlink(attachment);}}
__exports.useAttachmentUploader=useAttachmentUploader;function useAttachmentUploader(thread,{composer,onFileUploaded}={}){return useState(new AttachmentUploader(...arguments));}
return __exports;});;

/* /mail/static/src/core/common/attachment_view.js */
odoo.define('@mail/core/common/attachment_view',['@odoo/owl','@web/core/utils/hooks','@web/libs/pdfjs'],function(require){'use strict';let __exports={};const{Component,onWillUpdateProps,useEffect,useRef,useState}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{hidePDFJSButtons}=require("@web/libs/pdfjs");const AttachmentView=__exports.AttachmentView=class AttachmentView extends Component{static template="mail.AttachmentView";static components={};static props=["threadId","threadModel"];setup(){this.threadService=useService("mail.thread");this.store=useState(useService("mail.store"));this.iframeViewerPdfRef=useRef("iframeViewerPdf");this.state=useState({thread:undefined,});useEffect(()=>{if(this.iframeViewerPdfRef.el){hidePDFJSButtons(this.iframeViewerPdfRef.el);}});this.updateFromProps(this.props);onWillUpdateProps((props)=>this.updateFromProps(props));}
onClickNext(){const index=this.state.thread.attachmentsInWebClientView.findIndex((attachment)=>attachment.eq(this.state.thread.mainAttachment));this.threadService.setMainAttachmentFromIndex(this.state.thread,index===this.state.thread.attachmentsInWebClientView.length-1?0:index+1);}
onClickPrevious(){const index=this.state.thread.attachmentsInWebClientView.findIndex((attachment)=>attachment.eq(this.state.thread.mainAttachment));this.threadService.setMainAttachmentFromIndex(this.state.thread,index===0?this.state.thread.attachmentsInWebClientView.length-1:index-1);}
updateFromProps(props){this.state.thread=this.store.Thread.insert({id:props.threadId,model:props.threadModel,});}
get displayName(){return this.state.thread.mainAttachment.filename;}}
return __exports;});;

/* /mail/static/src/core/common/autoresize_input.js */
odoo.define('@mail/core/common/autoresize_input',['@odoo/owl','@web/core/utils/autoresize'],function(require){'use strict';let __exports={};const{Component,useRef,useState,onWillUpdateProps,onMounted}=require("@odoo/owl");const{useAutoresize}=require("@web/core/utils/autoresize");const AutoresizeInput=__exports.AutoresizeInput=class AutoresizeInput extends Component{static template="mail.AutoresizeInput";static props={autofocus:{type:Boolean,optional:true},className:{type:String,optional:true},enabled:{optional:true},onValidate:{type:Function,optional:true},placeholder:{type:String,optional:true},value:{type:String,optional:true},};static defaultProps={autofocus:false,className:"",enabled:true,onValidate:()=>{},placeholder:"",};setup(){this.state=useState({value:this.props.value,});this.inputRef=useRef("input");onWillUpdateProps((nextProps)=>{if(this.props.value!==nextProps.value){this.state.value=nextProps.value;}});useAutoresize(this.inputRef);onMounted(()=>{if(this.props.autofocus){this.inputRef.el.focus();this.inputRef.el.setSelectionRange(-1,-1);}});}
onKeydownInput(ev){switch(ev.key){case"Enter":this.inputRef.el.blur();break;case"Escape":this.state.value=this.props.value;this.inputRef.el.blur();break;}}}
return __exports;});;

/* /mail/static/src/core/common/canned_response_model.js */
odoo.define('@mail/core/common/canned_response_model',['@mail/core/common/record'],function(require){'use strict';let __exports={};const{Record}=require("@mail/core/common/record");const CannedResponse=__exports.CannedResponse=class CannedResponse extends Record{static id="id";static records={};static get(data){return super.get(data);}
static insert(data){return super.insert(...arguments);}
id;source;substitution;}
CannedResponse.register();return __exports;});;

/* /mail/static/src/core/common/channel_member_model.js */
odoo.define('@mail/core/common/channel_member_model',['@mail/core/common/record','@web/core/l10n/dates'],function(require){'use strict';let __exports={};const{Record}=require("@mail/core/common/record");const{deserializeDateTime}=require("@web/core/l10n/dates");const ChannelMember=__exports.ChannelMember=class ChannelMember extends Record{static id="id";static records={};static get(data){return super.get(data);}
static insert(data){return super.insert(...arguments);}
create_date;id;persona=Record.one("Persona",{inverse:"channelMembers"});rtcSession=Record.one("RtcSession");thread=Record.one("Thread",{inverse:"channelMembers"});threadAsSelf=Record.one("Thread",{compute(){if(this._store.self?.eq(this.persona)){return this.thread;}},});lastFetchedMessage=Record.one("Message");lastSeenMessage=Record.one("Message");getLangName(){return this.persona.lang_name;}
get memberSince(){return this.create_date?deserializeDateTime(this.create_date):undefined;}}
ChannelMember.register();return __exports;});;

/* /mail/static/src/core/common/channel_member_service.js */
odoo.define('@mail/core/common/channel_member_service',['@web/core/registry'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const ChannelMemberService=__exports.ChannelMemberService=class ChannelMemberService{constructor(env,services){this.env=env;this.store=services["mail.store"];}
getName(member){return member.persona.nameOrDisplayName;}}
const channelMemberService=__exports.channelMemberService={dependencies:["mail.store"],start(env,services){return new ChannelMemberService(env,services);},};registry.category("services").add("discuss.channel.member",channelMemberService);return __exports;});;

/* /mail/static/src/core/common/chat_window.js */
odoo.define('@mail/core/common/chat_window',['@mail/core/common/composer','@mail/core/common/im_status','@mail/core/common/thread','@mail/core/common/autoresize_input','@mail/core/common/thread_actions','@mail/core/common/thread_icon','@mail/utils/common/hooks','@web/core/utils/misc','@odoo/owl','@web/core/dropdown/dropdown','@web/core/dropdown/dropdown_item','@web/core/l10n/localization','@web/core/l10n/translation','@web/core/utils/hooks','@mail/discuss/typing/common/typing'],function(require){'use strict';let __exports={};const{Composer}=require("@mail/core/common/composer");const{ImStatus}=require("@mail/core/common/im_status");const{Thread}=require("@mail/core/common/thread");const{AutoresizeInput}=require("@mail/core/common/autoresize_input");const{useThreadActions}=require("@mail/core/common/thread_actions");const{ThreadIcon}=require("@mail/core/common/thread_icon");const{useMessageEdition,useMessageHighlight,useMessageToReplyTo,}=require("@mail/utils/common/hooks");const{isEventHandled}=require("@web/core/utils/misc");const{Component,useChildSubEnv,useRef,useState}=require("@odoo/owl");const{Dropdown}=require("@web/core/dropdown/dropdown");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{localization}=require("@web/core/l10n/localization");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const{Typing}=require("@mail/discuss/typing/common/typing");const ChatWindow=__exports.ChatWindow=class ChatWindow extends Component{static components={Dropdown,DropdownItem,Thread,Composer,ThreadIcon,ImStatus,AutoresizeInput,Typing,};static props=["chatWindow","right?"];static template="mail.ChatWindow";setup(){this.store=useState(useService("mail.store"));this.chatWindowService=useState(useService("mail.chat_window"));this.threadService=useState(useService("mail.thread"));this.messageEdition=useMessageEdition();this.messageHighlight=useMessageHighlight();this.messageToReplyTo=useMessageToReplyTo();this.typingService=useState(useService("discuss.typing"));this.state=useState({actionsMenuOpened:false,jumpThreadPresent:0,editingName:false,});this.ui=useState(useService("ui"));this.contentRef=useRef("content");this.threadActions=useThreadActions();useChildSubEnv({closeActionPanel:()=>this.threadActions.activeAction?.close(),inChatWindow:true,messageHighlight:this.messageHighlight,});}
get composerType(){if(this.thread&&this.thread.model!=="discuss.channel"){return"note";}
return undefined;}
get thread(){return this.props.chatWindow.thread;}
get style(){const maxHeight=!this.ui.isSmall?"max-height: 95vh;":"";const textDirection=localization.direction;const offsetFrom=textDirection==="rtl"?"left":"right";const visibleOffset=this.ui.isSmall?0:this.props.right;const oppositeFrom=offsetFrom==="right"?"left":"right";return`${offsetFrom}: ${visibleOffset}px; ${oppositeFrom}: auto; ${maxHeight}`;}
onKeydown(ev){if(ev.target.closest(".o-dropdown")){return;}
ev.stopPropagation();switch(ev.key){case"Escape":if(isEventHandled(ev,"NavigableList.close")||isEventHandled(ev,"Composer.discard")){return;}
if(this.state.editingName){this.state.editingName=false;return;}
this.close({escape:true});break;case"Tab":{const index=this.chatWindowService.visible.findIndex((cw)=>cw.eq(this.props.chatWindow));if(index===0){this.chatWindowService.visible[this.chatWindowService.visible.length-1].autofocus++;}else{this.chatWindowService.visible[index-1].autofocus++;}
break;}}}
onClickHeader(){if(!this.ui.isSmall&&!this.state.editingName){this.toggleFold();}}
toggleFold(){if(this.ui.isSmall||this.state.actionsMenuOpened){return;}
if(this.props.chatWindow.hidden){this.chatWindowService.makeVisible(this.props.chatWindow);}else{this.chatWindowService.toggleFold(this.props.chatWindow);}}
async close(options){await this.chatWindowService.close(this.props.chatWindow,options);}
get actionsMenuTitleText(){return _t("Open Actions Menu");}
async renameThread(name){await this.threadService.renameThread(this.thread,name);this.state.editingName=false;}
async onActionsMenuStateChanged(state){await new Promise(setTimeout);this.state.actionsMenuOpened=state.open;}}
return __exports;});;

/* /mail/static/src/core/common/chat_window_container.js */
odoo.define('@mail/core/common/chat_window_container',['@mail/core/common/chat_window','@mail/core/common/chat_window_service','@odoo/owl','@web/core/browser/browser','@web/core/dropdown/dropdown','@web/core/l10n/localization','@web/core/registry','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{ChatWindow}=require("@mail/core/common/chat_window");const{CHAT_WINDOW_END_GAP_WIDTH,CHAT_WINDOW_INBETWEEN_WIDTH,CHAT_WINDOW_WIDTH,}=require("@mail/core/common/chat_window_service");const{Component,useExternalListener,useState,onMounted,useRef,useEffect}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{Dropdown}=require("@web/core/dropdown/dropdown");const{localization}=require("@web/core/l10n/localization");const{registry}=require("@web/core/registry");const{useService}=require("@web/core/utils/hooks");const ChatWindowContainer=__exports.ChatWindowContainer=class ChatWindowContainer extends Component{static components={ChatWindow,Dropdown};static props=[];static template="mail.ChatWindowContainer";get CHAT_WINDOW_END_GAP_WIDTH(){return CHAT_WINDOW_END_GAP_WIDTH;}
get CHAT_WINDOW_INBETWEEN_WIDTH(){return CHAT_WINDOW_INBETWEEN_WIDTH;}
get CHAT_WINDOW_WIDTH(){return CHAT_WINDOW_WIDTH;}
setup(){this.messaging=useState(useService("mail.messaging"));this.store=useState(useService("mail.store"));this.chatWindowService=useState(useService("mail.chat_window"));this.ui=useState(useService("ui"));this.hiddenMenuRef=useRef("hiddenMenu");useEffect(()=>this.setHiddenMenuOffset(),()=>[this.chatWindowService.hidden,this.store.isMessagingReady]);onMounted(()=>this.setHiddenMenuOffset());this.onResize();useExternalListener(browser,"resize",this.onResize);}
setHiddenMenuOffset(){if(!this.hiddenMenuRef.el){return;}
const textDirection=localization.direction;const offsetFrom=textDirection==="rtl"?"left":"right";const visibleOffset=CHAT_WINDOW_END_GAP_WIDTH+
this.chatWindowService.maxVisible*(CHAT_WINDOW_WIDTH+CHAT_WINDOW_END_GAP_WIDTH);const oppositeFrom=offsetFrom==="right"?"left":"right";this.hiddenMenuRef.el.style=`${offsetFrom}: ${visibleOffset}px; ${oppositeFrom}: auto`;}
onResize(){while(this.chatWindowService.visible.length>this.chatWindowService.maxVisible){this.chatWindowService.hide(this.chatWindowService.visible[this.chatWindowService.visible.length-1]);}
while(this.chatWindowService.visible.length<this.chatWindowService.maxVisible&&this.chatWindowService.hidden.length>0){this.chatWindowService.show(this.chatWindowService.hidden[0]);}
this.setHiddenMenuOffset();}
get unread(){let unreadCounter=0;for(const chatWindow of this.chatWindowService.hidden){unreadCounter+=chatWindow.thread.message_unread_counter;}
return unreadCounter;}}
registry.category("main_components").add("mail.ChatWindowContainer",{Component:ChatWindowContainer});return __exports;});;

/* /mail/static/src/core/common/chat_window_model.js */
odoo.define('@mail/core/common/chat_window_model',['@mail/core/common/record','@mail/utils/common/misc','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{Record}=require("@mail/core/common/record");const{assignDefined}=require("@mail/utils/common/misc");const{_t}=require("@web/core/l10n/translation");const ChatWindow=__exports.ChatWindow=class ChatWindow extends Record{static id="thread";static records={};static get(data){return super.get(data);}
static insert(){return super.insert(...arguments);}
static _insert(data={}){const chatWindow=this.store.discuss.chatWindows.find((c)=>c.thread?.eq(data.thread));if(!chatWindow){const chatWindow=this.preinsert(data);assignDefined(chatWindow,data);let index;const visible=this.env.services["mail.chat_window"].visible;const maxVisible=this.env.services["mail.chat_window"].maxVisible;if(!data.replaceNewMessageChatWindow){if(maxVisible<=this.store.discuss.chatWindows.length){const swaped=visible[visible.length-1];index=visible.length-1;this.env.services["mail.chat_window"].hide(swaped);}else{index=this.store.discuss.chatWindows.length;}}else{const newMessageChatWindowIndex=this.store.discuss.chatWindows.findIndex((cw)=>!cw.thread);index=newMessageChatWindowIndex!==-1?newMessageChatWindowIndex:this.store.discuss.chatWindows.length;}
this.store.discuss.chatWindows.splice(index,data.replaceNewMessageChatWindow?1:0,chatWindow);return chatWindow;}
if(chatWindow.hidden){this.env.services["mail.chat_window"].makeVisible(chatWindow);}
assignDefined(chatWindow,data);return chatWindow;}
thread=Record.one("Thread");autofocus=0;folded=false;hidden=false;openMessagingMenuOnClose=false;get displayName(){return this.thread?.displayName??_t("New message");}
get isOpen(){return!this.folded&&!this.hidden;}}
ChatWindow.register();return __exports;});;

/* /mail/static/src/core/common/chat_window_service.js */
odoo.define('@mail/core/common/chat_window_service',['@mail/utils/common/misc','@web/core/browser/browser','@web/core/registry'],function(require){'use strict';let __exports={};const{assignDefined}=require("@mail/utils/common/misc");const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const CHAT_WINDOW_END_GAP_WIDTH=__exports.CHAT_WINDOW_END_GAP_WIDTH=10;const CHAT_WINDOW_INBETWEEN_WIDTH=__exports.CHAT_WINDOW_INBETWEEN_WIDTH=5;const CHAT_WINDOW_WIDTH=__exports.CHAT_WINDOW_WIDTH=360;const CHAT_WINDOW_HIDDEN_WIDTH=__exports.CHAT_WINDOW_HIDDEN_WIDTH=55;const ChatWindowService=__exports.ChatWindowService=class ChatWindowService{constructor(env,services){this.setup(env,services);}
setup(env,services){this.env=env;this.store=services["mail.store"];this.orm=services.orm;this.ui=services.ui;}
open(thread,replaceNewMessageChatWindow){const chatWindow=this.store.ChatWindow.insert({folded:false,thread,replaceNewMessageChatWindow,});chatWindow.autofocus++;if(thread){thread.state="open";}
return chatWindow;}
openNewMessage({openMessagingMenuOnClose}={}){if(this.store.discuss.chatWindows.some(({thread})=>!thread)){return;}
this.store.ChatWindow.insert(assignDefined({},{openMessagingMenuOnClose}));}
closeNewMessage(){const newMessageChatWindow=this.store.discuss.chatWindows.find(({thread})=>!thread);if(newMessageChatWindow){this.close(newMessageChatWindow);}}
get visible(){return this.store.discuss.chatWindows.filter((chatWindow)=>!chatWindow.hidden);}
get hidden(){return this.store.discuss.chatWindows.filter((chatWindow)=>chatWindow.hidden);}
get maxVisible(){const startGap=this.ui.isSmall?0:this.hidden.length>0?CHAT_WINDOW_END_GAP_WIDTH+CHAT_WINDOW_HIDDEN_WIDTH:CHAT_WINDOW_END_GAP_WIDTH;const endGap=this.ui.isSmall?0:CHAT_WINDOW_END_GAP_WIDTH;const available=browser.innerWidth-startGap-endGap;const maxAmountWithoutHidden=Math.max(1,Math.floor(available/(CHAT_WINDOW_WIDTH+CHAT_WINDOW_INBETWEEN_WIDTH)));return maxAmountWithoutHidden;}
focus(chatWindow){chatWindow.autofocus++;}
makeVisible(chatWindow){const swaped=this.visible[this.visible.length-1];this.hide(swaped);this.show(chatWindow,{notifyState:false});}
toggleFold(chatWindow){chatWindow.folded=!chatWindow.folded;const thread=chatWindow.thread;if(thread){thread.state=chatWindow.folded?"folded":"open";}}
show(chatWindow){chatWindow.hidden=false;chatWindow.folded=false;chatWindow.thread.state="open";}
hide(chatWindow){chatWindow.hidden=true;}
async close(chatWindow,options={}){const{escape=false}=options;if(!chatWindow.hidden&&this.maxVisible<this.store.discuss.chatWindows.length){const swaped=this.hidden[0];swaped.hidden=false;swaped.folded=false;}
const index=this.store.discuss.chatWindows.findIndex((c)=>c.eq(chatWindow));if(index>-1){this.store.discuss.chatWindows.splice(index,1);}
const thread=chatWindow.thread;if(thread){thread.state="closed";}
if(escape&&this.store.discuss.chatWindows.length>0){this.focus(this.store.discuss.chatWindows[index-1]);}
await this._onClose(chatWindow,options);chatWindow.delete();}
async _onClose(chatWindow,options){}}
const chatWindowService=__exports.chatWindowService={dependencies:["mail.store","orm","ui"],start(env,services){return new ChatWindowService(env,services);},};registry.category("services").add("mail.chat_window",chatWindowService);return __exports;});;

/* /mail/static/src/core/common/composer.js */
odoo.define('@mail/core/common/composer',['@mail/core/common/attachment_list','@mail/core/common/attachment_uploader_hook','@mail/core/common/dropzone_hook','@mail/core/common/picker','@mail/core/common/message_confirm_dialog','@mail/core/common/navigable_list','@mail/core/common/suggestion_hook','@mail/utils/common/format','@mail/utils/common/hooks','@mail/utils/common/misc','@web/core/utils/misc','@odoo/owl','@web/core/l10n/translation','@web/core/utils/hooks','@web/views/fields/file_handler','@web/core/utils/strings'],function(require){'use strict';let __exports={};const{AttachmentList}=require("@mail/core/common/attachment_list");const{useAttachmentUploader}=require("@mail/core/common/attachment_uploader_hook");const{useDropzone}=require("@mail/core/common/dropzone_hook");const{Picker,usePicker}=require("@mail/core/common/picker");const{MessageConfirmDialog}=require("@mail/core/common/message_confirm_dialog");const{NavigableList}=require("@mail/core/common/navigable_list");const{useSuggestion}=require("@mail/core/common/suggestion_hook");const{prettifyMessageContent}=require("@mail/utils/common/format");const{useSelection}=require("@mail/utils/common/hooks");const{isDragSourceExternalFile}=require("@mail/utils/common/misc");const{isEventHandled,markEventHandled}=require("@web/core/utils/misc");const{Component,markup,onMounted,useChildSubEnv,useEffect,useRef,useState,}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const{FileUploader}=require("@web/views/fields/file_handler");const{escape,sprintf}=require("@web/core/utils/strings");const EDIT_CLICK_TYPE={CANCEL:"cancel",SAVE:"save",};const Composer=__exports.Composer=class Composer extends Component{static components={AttachmentList,Picker,FileUploader,NavigableList,};static defaultProps={mode:"normal",className:"",sidebar:true,showFullComposer:true,allowUpload:true,};static props=["composer","autofocus?","messageToReplyTo?","onDiscardCallback?","onPostCallback?","mode?","placeholder?","dropzoneRef?","messageEdition?","messageComponent?","className?","sidebar?","type?","showFullComposer?","allowUpload?",];static template="mail.Composer";setup(){this.SEND_KEYBIND_TO_SEND=markup(_t("<samp>%(send_keybind)s</samp><i> to send</i>",{send_keybind:this.sendKeybind}));this.store=useState(useService("mail.store"));this.attachmentUploader=useAttachmentUploader(this.thread??this.props.composer.message.originThread,{composer:this.props.composer});this.messageService=useState(useService("mail.message"));this.threadService=useService("mail.thread");this.ui=useState(useService("ui"));this.rpc=useService("rpc");this.mainActionsRef=useRef("main-actions");this.ref=useRef("textarea");this.fakeTextarea=useRef("fakeTextarea");this.emojiButton=useRef("emoji-button");this.state=useState({active:true,});this.selection=useSelection({refName:"textarea",model:this.props.composer.selection,preserveOnClickAwayPredicate:async(ev)=>{await new Promise(setTimeout);return(!this.isEventTrusted(ev)||isEventHandled(ev,"sidebar.openThread")||isEventHandled(ev,"emoji.selectEmoji")||isEventHandled(ev,"Composer.onClickAddEmoji")||isEventHandled(ev,"composer.clickOnAddAttachment")||isEventHandled(ev,"composer.selectSuggestion"));},});this.suggestion=this.store.user?useSuggestion():undefined;this.markEventHandled=markEventHandled;this.onDropFile=this.onDropFile.bind(this);if(this.props.dropzoneRef){useDropzone(this.props.dropzoneRef,this.onDropFile,"o-mail-Composer-dropzone",()=>this.allowUpload);}
if(this.props.messageEdition){this.props.messageEdition.composerOfThread=this;}
useChildSubEnv({inComposer:true,});this.picker=usePicker(this.pickerSettings);useEffect((focus)=>{if(focus&&this.ref.el){this.selection.restore();this.ref.el.focus();}},()=>[this.props.autofocus+this.props.composer.autofocus,this.props.placeholder]);useEffect((rThread,cThread)=>{if(cThread&&cThread.eq(rThread)){this.props.composer.autofocus++;}},()=>[this.props.messageToReplyTo?.thread,this.props.composer.thread]);useEffect(()=>{this.ref.el.style.height=this.fakeTextarea.el.scrollHeight+"px";},()=>[this.props.composer.textInputContent,this.ref.el]);useEffect(()=>{if(!this.props.composer.forceCursorMove){return;}
this.selection.restore();this.props.composer.forceCursorMove=false;},()=>[this.props.composer.forceCursorMove]);onMounted(()=>{this.ref.el.scrollTo({top:0,behavior:"instant"});});}
get pickerSettings(){return{anchor:this.props.mode==="extended"?undefined:this.mainActionsRef,buttons:[this.emojiButton],close:()=>{if(!this.ui.isSmall){this.props.composer.autofocus++;}},pickers:{emoji:(emoji)=>this.addEmoji(emoji)},position:this.props.mode==="extended"?"bottom-start":"top-end",};}
get placeholder(){if(this.props.placeholder){return this.props.placeholder;}
if(this.thread){if(this.thread.type==="channel"){return _t("Message #%(thread name)s…",{"thread name":this.thread.displayName});}
return _t("Message %(thread name)s…",{"thread name":this.thread.displayName});}
return"";}
onClickCancelOrSaveEditText(ev){if(this.props.composer.message&&ev.target.dataset?.type===EDIT_CLICK_TYPE.CANCEL){this.props.onDiscardCallback(ev);}
if(this.props.composer.message&&ev.target.dataset?.type===EDIT_CLICK_TYPE.SAVE){this.editMessage(ev);}}
get CANCEL_OR_SAVE_EDIT_TEXT(){if(this.ui.isSmall){return markup(sprintf(escape(_t("%(open_button)s%(icon)s%(open_em)sDiscard editing%(close_em)s%(close_button)s")),{open_button:`<button class='btn px-1 py-0' data-type="${escape(
                            EDIT_CLICK_TYPE.CANCEL
                        )}">`,close_button:"</button>",icon:`<i class='fa fa-times-circle pe-1' data-type="${escape(
                            EDIT_CLICK_TYPE.CANCEL
                        )}"></i>`,open_em:`<em data-type="${escape(EDIT_CLICK_TYPE.CANCEL)}">`,close_em:"</em>",}));}else{const translation1=_t("%(open_samp)sEscape%(close_samp)s %(open_em)sto %(open_cancel)scancel%(close_cancel)s%(close_em)s, %(open_samp)sCTRL-Enter%(close_samp)s %(open_em)sto %(open_save)ssave%(close_save)s%(close_em)s");const translation2=_t("%(open_samp)sEscape%(close_samp)s %(open_em)sto %(open_cancel)scancel%(close_cancel)s%(close_em)s, %(open_samp)sEnter%(close_samp)s %(open_em)sto %(open_save)ssave%(close_save)s%(close_em)s");return markup(sprintf(escape(this.props.mode==="extended"?translation1:translation2),{open_samp:"<samp>",close_samp:"</samp>",open_em:"<em>",close_em:"</em>",open_cancel:`<a role="button" href="#" data-type="${escape(
                        EDIT_CLICK_TYPE.CANCEL
                    )}">`,close_cancel:"</a>",open_save:`<a role="button" href="#" data-type="${escape(
                        EDIT_CLICK_TYPE.SAVE
                    )}">`,close_save:"</a>",}));}}
get SEND_TEXT(){if(this.props.composer.message){return _t("Save editing");}
return this.props.type==="note"?_t("Log"):_t("Send");}
get sendKeybind(){return this.props.mode==="extended"?_t("CTRL-Enter"):_t("Enter");}
get thread(){return(this.props.messageToReplyTo?.message?.originThread??this.props.composer.thread??null);}
get allowUpload(){return this.props.allowUpload;}
get message(){return this.props.composer.message??null;}
get isSendButtonDisabled(){const attachments=this.props.composer.attachments;return(!this.state.active||(!this.props.composer.textInputContent&&attachments.length===0)||attachments.some(({uploading})=>Boolean(uploading)));}
get hasSuggestions(){return Boolean(this.suggestion?.state.items);}
get navigableListProps(){const props={anchorRef:this.ref.el,position:this.env.inChatter?"bottom-fit":"top-fit",placeholder:_t("Loading"),onSelect:(ev,option)=>{this.suggestion.insert(option);markEventHandled(ev,"composer.selectSuggestion");},options:[],};if(!this.hasSuggestions){return props;}
const suggestions=Array(...this.suggestion.state.items.mainSuggestions,...this.suggestion.state.items.extraSuggestions);switch(this.suggestion.state.items.type){case"Partner":return{...props,optionTemplate:"mail.Composer.suggestionPartner",options:suggestions.map((suggestion)=>{return{label:suggestion.name,partner:suggestion,classList:"o-mail-Composer-suggestion",};}),};case"Thread":return{...props,optionTemplate:"mail.Composer.suggestionThread",options:suggestions.map((suggestion)=>{return{label:suggestion.displayName,thread:suggestion,classList:"o-mail-Composer-suggestion",};}),};case"ChannelCommand":return{...props,optionTemplate:"mail.Composer.suggestionChannelCommand",options:suggestions.map((suggestion)=>{return{label:suggestion.name,help:suggestion.help,classList:"o-mail-Composer-suggestion",};}),};case"CannedResponse":return{...props,optionTemplate:"mail.Composer.suggestionCannedResponse",options:suggestions.map((suggestion)=>{return{cannedResponse:suggestion,source:suggestion.source,label:suggestion.substitution,classList:"o-mail-Composer-suggestion",};}),};default:return props;}}
onDropFile(ev){if(isDragSourceExternalFile(ev.dataTransfer)){for(const file of ev.dataTransfer.files){this.attachmentUploader.uploadFile(file);}}}
onPaste(ev){if(!this.allowUpload){return;}
if(!ev.clipboardData?.items){return;}
if(ev.clipboardData.files.length===0){return;}
ev.preventDefault();for(const file of ev.clipboardData.files){this.attachmentUploader.uploadFile(file);}}
onKeydown(ev){switch(ev.key){case"ArrowUp":if(this.props.messageEdition&&this.props.composer.textInputContent===""){const messageToEdit=this.props.composer.thread.lastEditableMessageOfSelf;if(messageToEdit){this.props.messageEdition.editingMessage=messageToEdit;}}
break;case"Enter":{if(isEventHandled(ev,"NavigableList.select")||!this.state.active){ev.preventDefault();return;}
const shouldPost=this.props.mode==="extended"?ev.ctrlKey:!ev.shiftKey;if(!shouldPost){return;}
ev.preventDefault();if(this.props.composer.message){this.editMessage();}else{this.sendMessage();}
break;}
case"Escape":if(isEventHandled(ev,"NavigableList.close")){return;}
if(this.props.onDiscardCallback){this.props.onDiscardCallback();markEventHandled(ev,"Composer.discard");}
break;}}
onClickAddAttachment(ev){markEventHandled(ev,"composer.clickOnAddAttachment");this.props.composer.autofocus++;}
async onClickFullComposer(ev){if(this.props.type!=="note"){const newPartners=this.thread.suggestedRecipients.filter((recipient)=>recipient.checked&&!recipient.persona);if(newPartners.length!==0){const recipientEmails=[];const recipientAdditionalValues={};newPartners.forEach((recipient)=>{recipientEmails.push(recipient.email);recipientAdditionalValues[recipient.email]=recipient.defaultCreateValues||{};});const partners=await this.rpc("/mail/partner/from_email",{emails:recipientEmails,additional_values:recipientAdditionalValues,});for(const index in partners){const partnerData=partners[index];const persona=this.store.Persona.insert({...partnerData,type:"partner"});const email=recipientEmails[index];const recipient=this.thread.suggestedRecipients.find((recipient)=>recipient.email===email);Object.assign(recipient,{persona});}}}
const attachmentIds=this.props.composer.attachments.map((attachment)=>attachment.id);const body=this.props.composer.textInputContent;const validMentions=this.store.user?this.messageService.getMentionsFromText(body,{mentionedChannels:this.props.composer.mentionedChannels,mentionedPartners:this.props.composer.mentionedPartners,}):undefined;const context={default_attachment_ids:attachmentIds,default_body:await prettifyMessageContent(body,validMentions),default_model:this.thread.model,default_partner_ids:this.props.type==="note"?[]:this.thread.suggestedRecipients.filter((recipient)=>recipient.checked).map((recipient)=>recipient.persona.id),default_res_ids:[this.thread.id],default_subtype_xmlid:this.props.type==="note"?"mail.mt_note":"mail.mt_comment",mail_post_autofollow:this.thread.hasWriteAccess,};const action={name:this.props.type==="note"?_t("Log note"):_t("Compose Email"),type:"ir.actions.act_window",res_model:"mail.compose.message",view_mode:"form",views:[[false,"form"]],target:"new",context:context,};const options={onClose:(...args)=>{const isDiscard=args.length===0||args[0]?.special;if(!isDiscard&&this.props.composer.thread.type==="mailbox"){this.notifySendFromMailbox();}
this.clear();this.props.messageToReplyTo?.cancel();if(this.thread){this.threadService.fetchNewMessages(this.thread);}},};await this.env.services.action.doAction(action,options);}
clear(){this.threadService.clearComposer(this.props.composer);}
notifySendFromMailbox(){this.env.services.notification.add(_t('Message posted on "%s"',this.thread.displayName),{type:"info",});}
onClickAddEmoji(ev){markEventHandled(ev,"Composer.onClickAddEmoji");}
isEventTrusted(ev){return ev.isTrusted;}
async processMessage(cb){const el=this.ref.el;const attachments=this.props.composer.attachments;if(this.props.composer.textInputContent.trim()||(attachments.length>0&&attachments.every(({uploading})=>!uploading))||(this.message&&this.message.attachments.length>0)){if(!this.state.active){return;}
this.state.active=false;await cb(this.props.composer.textInputContent);if(this.props.onPostCallback){this.props.onPostCallback();}
this.clear();this.state.active=true;el.focus();}else if(attachments.some(({uploading})=>Boolean(uploading))){this.env.services.notification.add(_t("Please wait while the file is uploading."),{type:"warning",});}}
async sendMessage(){if(this.props.composer.message){this.editMessage();return;}
await this.processMessage(async(value)=>{const postData={attachments:this.props.composer.attachments,isNote:this.props.type==="note",mentionedChannels:this.props.composer.mentionedChannels,mentionedPartners:this.props.composer.mentionedPartners,cannedResponseIds:this.props.composer.cannedResponses.map((c)=>c.id),parentId:this.props.messageToReplyTo?.message?.id,};await this._sendMessage(value,postData);});}
async _sendMessage(value,postData){const thread=this.props.composer.thread;await this.threadService.post(this.thread,value,postData);if(thread.type==="mailbox"){this.notifySendFromMailbox();}
this.suggestion?.clearRawMentions();this.suggestion?.clearCannedResponses();this.props.messageToReplyTo?.cancel();}
async editMessage(){if(this.props.composer.textInputContent||this.props.composer.message.attachments.length>0){await this.processMessage(async(value)=>this.messageService.edit(this.props.composer.message,value,this.props.composer.attachments,{mentionedChannels:this.props.composer.mentionedChannels,mentionedPartners:this.props.composer.mentionedPartners,}));}else{this.env.services.dialog.add(MessageConfirmDialog,{message:this.props.composer.message,messageComponent:this.props.messageComponent,onConfirm:()=>this.messageService.delete(this.message),prompt:_t("Are you sure you want to delete this message?"),});}
this.suggestion?.clearRawMentions();}
addEmoji(str){const textContent=this.props.composer.textInputContent;const firstPart=textContent.slice(0,this.props.composer.selection.start);const secondPart=textContent.slice(this.props.composer.selection.end,textContent.length);this.props.composer.textInputContent=firstPart+str+secondPart;this.selection.moveCursor((firstPart+str).length);if(!this.ui.isSmall){this.props.composer.autofocus++;}}
onFocusin(){this.props.composer.isFocused=true;if(this.props.composer.thread){this.threadService.markAsRead(this.props.composer.thread);}}}
return __exports;});;

/* /mail/static/src/core/common/composer_model.js */
odoo.define('@mail/core/common/composer_model',['@mail/core/common/record'],function(require){'use strict';let __exports={};const{OR,Record}=require("@mail/core/common/record");const Composer=__exports.Composer=class Composer extends Record{static id=OR("thread","message");static get(data){return super.get(data);}
static insert(data){return super.insert(...arguments);}
attachments=Record.many("Attachment");message=Record.one("Message");mentionedPartners=Record.many("Persona");mentionedChannels=Record.many("Thread");cannedResponses=Record.many("CannedResponse");textInputContent="";thread=Record.one("Thread");selection={start:0,end:0,direction:"none",};forceCursorMove;isFocused=false;autofocus=0;}
Composer.register();return __exports;});;

/* /mail/static/src/core/common/date_section.js */
odoo.define('@mail/core/common/date_section',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const DateSection=__exports.DateSection=class DateSection extends Component{static template="mail.DateSection";static props=["date","className?"];}
return __exports;});;

/* /mail/static/src/core/common/discuss.js */
odoo.define('@mail/core/common/discuss',['@mail/core/common/autoresize_input','@mail/core/common/composer','@mail/core/common/im_status','@mail/core/common/thread','@mail/core/common/thread_actions','@mail/core/common/thread_icon','@mail/utils/common/hooks','@odoo/owl','@web/core/hotkeys/hotkey_service','@web/core/l10n/translation','@web/core/utils/hooks','@web/views/fields/file_handler'],function(require){'use strict';let __exports={};const{AutoresizeInput}=require("@mail/core/common/autoresize_input");const{Composer}=require("@mail/core/common/composer");const{ImStatus}=require("@mail/core/common/im_status");const{Thread}=require("@mail/core/common/thread");const{useThreadActions}=require("@mail/core/common/thread_actions");const{ThreadIcon}=require("@mail/core/common/thread_icon");const{useMessageEdition,useMessageHighlight,useMessageToReplyTo,}=require("@mail/utils/common/hooks");const{Component,onWillStart,onMounted,onWillUnmount,useChildSubEnv,useRef,useState,useEffect,useExternalListener,}=require("@odoo/owl");const{getActiveHotkey}=require("@web/core/hotkeys/hotkey_service");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const{FileUploader}=require("@web/views/fields/file_handler");const Discuss=__exports.Discuss=class Discuss extends Component{static components={AutoresizeInput,Thread,ThreadIcon,Composer,FileUploader,ImStatus,};static props={};static template="mail.Discuss";setup(){this.messaging=useState(useService("mail.messaging"));this.store=useState(useService("mail.store"));this.threadService=useState(useService("mail.thread"));this.personaService=useService("mail.persona");this.messageHighlight=useMessageHighlight();this.messageEdition=useMessageEdition();this.messageToReplyTo=useMessageToReplyTo();this.contentRef=useRef("content");this.root=useRef("root");this.state=useState({jumpThreadPresent:0});this.orm=useService("orm");this.effect=useService("effect");this.ui=useState(useService("ui"));this.prevInboxCounter=this.store.discuss.inbox.counter;useChildSubEnv({inDiscussApp:true,messageHighlight:this.messageHighlight,});this.notification=useService("notification");this.threadActions=useThreadActions();useExternalListener(window,"keydown",(ev)=>{if(getActiveHotkey(ev)==="escape"&&!this.thread?.composer?.isFocused){if(this.thread?.composer){this.thread.composer.autofocus++;}}},{capture:true});useEffect(()=>{if(this.thread?.id==="inbox"&&this.prevInboxCounter!==this.store.discuss.inbox.counter&&this.store.discuss.inbox.counter===0){this.effect.add({message:_t("Congratulations, your inbox is empty!"),type:"rainbow_man",fadeout:"fast",});}
this.prevInboxCounter=this.store.discuss.inbox.counter;},()=>[this.store.discuss.inbox.counter]);onWillStart(()=>this.messaging.isReady);onMounted(()=>(this.store.discuss.isActive=true));onWillUnmount(()=>(this.store.discuss.isActive=false));}
get thread(){return this.store.discuss.thread;}
async onFileUploaded(file){await this.threadService.notifyThreadAvatarToServer(this.thread.id,file.data);this.notification.add(_t("The avatar has been updated!"),{type:"success"});}
async renameThread(name){await this.threadService.renameThread(this.thread,name);}
async updateThreadDescription(description){const newDescription=description.trim();if(!newDescription&&!this.thread.description){return;}
if(newDescription!==this.thread.description){await this.threadService.notifyThreadDescriptionToServer(this.thread,newDescription);}}
async renameGuest(name){const newName=name.trim();if(this.store.guest?.name!==newName){await this.personaService.updateGuestName(this.store.self,newName);}}}
return __exports;});;

/* /mail/static/src/core/common/discuss_app_category_model.js */
odoo.define('@mail/core/common/discuss_app_category_model',['@mail/utils/common/misc','@mail/core/common/record'],function(require){'use strict';let __exports={};const{compareDatetime}=require("@mail/utils/common/misc");const{Record}=require("@mail/core/common/record");const DiscussAppCategory=__exports.DiscussAppCategory=class DiscussAppCategory extends Record{static id="id";static get(data){return super.get(data);}
static insert(data){return super.insert(...arguments);}
sortThreads(t1,t2){if(this.id==="channels"){return String.prototype.localeCompare.call(t1.name,t2.name);}
if(this.id==="chats"){return(compareDatetime(t2.lastInterestDateTime,t1.lastInterestDateTime)||t2.id-t1.id);}}
extraClass;id;name;isOpen=false;canView=false;canAdd=false;serverStateKey;addTitle;addHotkey;threads=Record.many("Thread",{sort(t1,t2){return this.sortThreads(t1,t2);},});}
DiscussAppCategory.register();return __exports;});;

/* /mail/static/src/core/common/discuss_app_model.js */
odoo.define('@mail/core/common/discuss_app_model',['@web/core/l10n/translation','@mail/core/common/record'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{Record}=require("@mail/core/common/record");const DiscussApp=__exports.DiscussApp=class DiscussApp extends Record{static new(data){const res=super.new(data);Object.assign(res,{channels:{extraClass:"o-mail-DiscussSidebarCategory-channel",id:"channels",name:_t("Channels"),isOpen:false,canView:true,canAdd:true,serverStateKey:"is_discuss_sidebar_category_channel_open",addTitle:_t("Add or join a channel"),addHotkey:"c",},chats:{extraClass:"o-mail-DiscussSidebarCategory-chat",id:"chats",name:_t("Direct messages"),isOpen:false,canView:false,canAdd:true,serverStateKey:"is_discuss_sidebar_category_chat_open",addTitle:_t("Start a conversation"),addHotkey:"d",},});return res;}
static get(data){return super.get(data);}
static insert(data){return super.insert(...arguments);}
activeTab="main";chatWindows=Record.many("ChatWindow");isActive=false;hasRestoredThread=false;thread=Record.one("Thread");channels=Record.one("DiscussAppCategory");chats=Record.one("DiscussAppCategory");inbox=Record.one("Thread");starred=Record.one("Thread");history=Record.one("Thread");}
DiscussApp.register();return __exports;});;

/* /mail/static/src/core/common/dropzone.js */
odoo.define('@mail/core/common/dropzone',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component,useEffect,useRef,useState}=require("@odoo/owl");const Dropzone=__exports.Dropzone=class Dropzone extends Component{static props={extraClass:{type:String,optional:true},onDrop:{type:Function,optional:true},ref:Object,};static template="mail.Dropzone";setup(){this.root=useRef("root");this.state=useState({isDraggingInside:false,});useEffect(()=>{const{top,left,width,height}=this.props.ref.el.getBoundingClientRect();this.root.el.style=`top:${top}px;left:${left}px;width:${width}px;height:${height}px;`;});}}
return __exports;});;

/* /mail/static/src/core/common/dropzone_hook.js */
odoo.define('@mail/core/common/dropzone_hook',['@mail/core/common/dropzone','@odoo/owl','@web/core/registry'],function(require){'use strict';let __exports={};const{Dropzone}=require("@mail/core/common/dropzone");const{useEffect,useExternalListener}=require("@odoo/owl");const{registry}=require("@web/core/registry");const componentRegistry=registry.category("main_components");let id=1;__exports.useDropzone=useDropzone;function useDropzone(targetRef,onDrop,extraClass,isDropzoneEnabled=()=>true){const dropzoneId=`mail.dropzone_${id++}`;let dragCount=0;let hasTarget=false;useExternalListener(document,"dragenter",onDragEnter);useExternalListener(document,"dragleave",onDragLeave);useExternalListener(window,"dragover",(ev)=>ev.preventDefault());useExternalListener(window,"drop",(ev)=>{ev.preventDefault();dragCount=0;updateDropzone();});function updateDropzone(){const shouldDisplayDropzone=dragCount&&hasTarget&&isDropzoneEnabled();const hasDropzone=componentRegistry.contains(dropzoneId);if(shouldDisplayDropzone&&!hasDropzone){componentRegistry.add(dropzoneId,{Component:Dropzone,props:{extraClass,onDrop,ref:targetRef},});}
if(!shouldDisplayDropzone&&hasDropzone){componentRegistry.remove(dropzoneId);}}
function onDragEnter(ev){if(dragCount||(ev.dataTransfer&&ev.dataTransfer.types.includes("Files"))){dragCount++;updateDropzone();}}
function onDragLeave(){if(dragCount){dragCount--;updateDropzone();}}
useEffect((el)=>{hasTarget=!!el;updateDropzone();},()=>[targetRef.el]);}
return __exports;});;

/* /mail/static/src/core/common/failure_model.js */
odoo.define('@mail/core/common/failure_model',['@mail/core/common/record','@mail/utils/common/misc','@odoo/owl','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{Record}=require("@mail/core/common/record");const{assignIn}=require("@mail/utils/common/misc");const{markRaw}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const Failure=__exports.Failure=class Failure extends Record{static nextId=markRaw({value:1});static id="id";static records={};static new(data){const failure=super.new(data);Record.onChange(failure,"notifications",()=>{if(failure.notifications.length===0){failure.delete();}});return failure;}
static get(data){return super.get(data);}
static insert(data){return super.insert(...arguments);}
static _insert(){const failure=super._insert(...arguments);if(failure.notifications.length===0){failure.delete();}else{this.store.failures.add(failure);}
return failure;}
update(data){assignIn(this,data,["notifications"]);this.lastMessage=this.notifications[0]?.message;for(const notification of this.notifications){if(this.lastMessage?.id<notification.message?.id){this.lastMessage=notification.message;}}
this.resIds.add(data.resId);}
delete(){this._store.failures.delete(this);super.delete();}
notifications=Record.many("Notification");get modelName(){return this.notifications?.[0]?.message?.originThread?.modelName;}
get resModel(){return this.notifications?.[0]?.message?.originThread?.model;}
lastMessage=Record.one("Message");resIds=new Set();get type(){return this.notifications?.[0]?.notification_type;}
get status(){return this.notifications?.[0]?.notification_status;}
get iconSrc(){return"/mail/static/src/img/smiley/mailfailure.jpg";}
get body(){return _t("An error occurred when sending an email");}
get datetime(){return this.lastMessage?.datetime;}}
Failure.register();return __exports;});;

/* /mail/static/src/core/common/follower_model.js */
odoo.define('@mail/core/common/follower_model',['@mail/core/common/record'],function(require){'use strict';let __exports={};const{Record}=require("@mail/core/common/record");const Follower=__exports.Follower=class Follower extends Record{static id="id";static records={};static get(data){return super.get(data);}
static insert(data){return super.insert(...arguments);}
followedThread=Record.one("Thread");id;is_active;partner=Record.one("Persona");get isEditable(){const hasWriteAccess=this.followedThread?this.followedThread.hasWriteAccess:false;return this.partner.eq(this._store.user)?this.followedThread.hasReadAccess:hasWriteAccess;}}
Follower.register();return __exports;});;

/* /mail/static/src/core/common/im_status.js */
odoo.define('@mail/core/common/im_status',['@odoo/owl','@mail/discuss/typing/common/typing','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,useState}=require("@odoo/owl");const{Typing}=require("@mail/discuss/typing/common/typing");const{useService}=require("@web/core/utils/hooks");const ImStatus=__exports.ImStatus=class ImStatus extends Component{static props=["persona","className?","style?","thread?"];static template="mail.ImStatus";static defaultProps={className:"",style:""};static components={Typing};setup(){this.typingService=useState(useService("discuss.typing"));}}
return __exports;});;

/* /mail/static/src/core/common/im_status_service_patch.js */
odoo.define('@mail/core/common/im_status_service_patch',['@bus/im_status_service','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{AWAY_DELAY,imStatusService}=require("@bus/im_status_service");const{patch}=require("@web/core/utils/patch");const imStatusServicePatch=__exports.imStatusServicePatch={dependencies:[...imStatusService.dependencies,"mail.store"],start(env,services){const{bus_service,"mail.store":store,presence}=services;const API=super.start(env,services);bus_service.subscribe("bus.bus/im_status_updated",({im_status,partner_id,guest_id})=>{const persona=store.Persona.get({type:partner_id?"partner":"guest",id:partner_id??guest_id,});if(!persona){return;}
persona.im_status=im_status;if(persona.type!=="guest"||persona.notEq(store.self)){return;}
const isOnline=presence.getInactivityPeriod()<AWAY_DELAY;if((im_status==="away"&&isOnline)||im_status==="offline"){this.updateBusPresence();}});return API;},};const unpatchImStatusService=__exports.unpatchImStatusService=patch(imStatusService,imStatusServicePatch);return __exports;});;

/* /mail/static/src/core/common/link_preview.js */
odoo.define('@mail/core/common/link_preview',['@mail/core/common/link_preview_confirm_delete','@odoo/owl','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{LinkPreviewConfirmDelete}=require("@mail/core/common/link_preview_confirm_delete");const{Component}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const LinkPreview=__exports.LinkPreview=class LinkPreview extends Component{static template="mail.LinkPreview";static props=["linkPreview","deletable"];static components={};setup(){this.dialogService=useService("dialog");}
onClick(){this.dialogService.add(LinkPreviewConfirmDelete,{linkPreview:this.props.linkPreview,LinkPreview,});}
onImageLoaded(){this.env.onImageLoaded?.();}}
return __exports;});;

/* /mail/static/src/core/common/link_preview_confirm_delete.js */
odoo.define('@mail/core/common/link_preview_confirm_delete',['@odoo/owl','@web/core/dialog/dialog','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,useState}=require("@odoo/owl");const{Dialog}=require("@web/core/dialog/dialog");const{useService}=require("@web/core/utils/hooks");const LinkPreviewConfirmDelete=__exports.LinkPreviewConfirmDelete=class LinkPreviewConfirmDelete extends Component{static components={Dialog};static props=["linkPreview","close","LinkPreview"];static template="mail.LinkPreviewConfirmDelete";setup(){this.rpc=useService("rpc");this.store=useState(useService("mail.store"));}
get message(){return this.props.linkPreview.message;}
onClickOk(){this.rpc("/mail/link_preview/delete",{link_preview_ids:[this.props.linkPreview.id]},{silent:true});this.props.close();}
onClickDeleteAll(){this.rpc("/mail/link_preview/delete",{link_preview_ids:this.message.linkPreviews.map((lp)=>lp.id)},{silent:true});this.props.close();}
onClickCancel(){this.props.close();}}
return __exports;});;

/* /mail/static/src/core/common/link_preview_list.js */
odoo.define('@mail/core/common/link_preview_list',['@mail/core/common/link_preview','@odoo/owl'],function(require){'use strict';let __exports={};const{LinkPreview}=require("@mail/core/common/link_preview");const{Component}=require("@odoo/owl");const LinkPreviewList=__exports.LinkPreviewList=class LinkPreviewList extends Component{static template="mail.LinkPreviewList";static props=["linkPreviews","deletable?"];static defaultProps={deletable:false,};static components={LinkPreview};}
return __exports;});;

/* /mail/static/src/core/common/link_preview_model.js */
odoo.define('@mail/core/common/link_preview_model',['@mail/core/common/record'],function(require){'use strict';let __exports={};const{Record}=require("@mail/core/common/record");const LinkPreview=__exports.LinkPreview=class LinkPreview extends Record{static id="id";static get(data){return super.get(data);}
static insert(data){return super.insert(...arguments);}
id;message=Record.one("Message",{inverse:"linkPreviews"});image_mimetype;og_description;og_image;og_mimetype;og_title;og_type;og_site_name;source_url;get imageUrl(){return this.og_image?this.og_image:this.source_url;}
get isImage(){return Boolean(this.image_mimetype||this.og_mimetype==="image/gif");}
get isVideo(){return Boolean(!this.isImage&&this.og_type&&this.og_type.startsWith("video"));}
get isCard(){return!this.isImage&&!this.isVideo;}}
LinkPreview.register();return __exports;});;

/* /mail/static/src/core/common/mail_core_common_service.js */
odoo.define('@mail/core/common/mail_core_common_service',['@odoo/owl','@web/core/registry'],function(require){'use strict';let __exports={};const{reactive}=require("@odoo/owl");const{registry}=require("@web/core/registry");const MailCoreCommon=__exports.MailCoreCommon=class MailCoreCommon{constructor(env,services){this.env=env;this.busService=services.bus_service;this.attachmentService=services["mail.attachment"];this.messageService=services["mail.message"];this.messagingService=services["mail.messaging"];this.store=services["mail.store"];this.userSettingsService=services["mail.user_settings"];}
setup(){this.messagingService.isReady.then(()=>{this.busService.subscribe("ir.attachment/delete",(payload)=>{const{id:attachmentId,message:messageData}=payload;if(messageData){this.store.Message.insert(messageData);}
const attachment=this.store.Attachment.get(attachmentId);if(attachment){this.attachmentService.remove(attachment);}});this.busService.subscribe("mail.link.preview/delete",(payload)=>{const{id,message_id}=payload;const message=this.store.Message.get(message_id);if(message){message.linkPreviews.delete({id});}});this.busService.subscribe("mail.message/delete",(payload)=>{for(const messageId of payload.message_ids){const message=this.store.Message.get(messageId);if(!message){continue;}
this.env.bus.trigger("mail.message/delete",{message});message.delete();}});this.busService.subscribe("mail.message/notification_update",(payload)=>{this.store.Message.insert(payload.elements,{html:true});});this.busService.subscribe("mail.message/toggle_star",(payload)=>{const{message_ids:messageIds,starred}=payload;for(const messageId of messageIds){const message=this.store.Message.insert({id:messageId});message.isStarred=starred;const starredBox=this.store.discuss.starred;if(starred){starredBox.counter++;starredBox.messages.add(message);}else{starredBox.counter--;starredBox.messages.delete(message);}}});this.busService.subscribe("res.users.settings",(payload)=>{if(payload){this.userSettingsService.updateFromCommands(payload);}});this.busService.subscribe("mail.record/insert",(payload)=>{for(const Model in payload){this.store[Model].insert(payload[Model],{html:true});}});});}}
const mailCoreCommon=__exports.mailCoreCommon={dependencies:["bus_service","mail.attachment","mail.message","mail.messaging","mail.store","mail.user_settings",],start(env,services){const mailCoreCommon=reactive(new MailCoreCommon(env,services));mailCoreCommon.setup();return mailCoreCommon;},};registry.category("services").add("mail.core.common",mailCoreCommon);return __exports;});;

/* /mail/static/src/core/common/message.js */
odoo.define('@mail/core/common/message',['@mail/core/common/attachment_list','@mail/core/common/composer','@mail/core/common/im_status','@mail/core/common/link_preview_list','@mail/core/common/message_confirm_dialog','@mail/core/common/message_in_reply','@mail/core/common/message_notification_popover','@mail/core/common/message_reaction_menu','@mail/core/common/message_reactions','@mail/core/common/message_seen_indicator','@mail/core/common/relative_time','@mail/utils/common/format','@web/core/utils/misc','@odoo/owl','@web/core/action_swiper/action_swiper','@web/core/browser/feature_detection','@web/core/dropdown/dropdown','@web/core/dropdown/dropdown_item','@web/core/l10n/translation','@web/core/popover/popover_hook','@web/core/utils/hooks','@web/core/utils/urls','@mail/core/common/message_actions','@web/core/browser/cookie'],function(require){'use strict';let __exports={};const{AttachmentList}=require("@mail/core/common/attachment_list");const{Composer}=require("@mail/core/common/composer");const{ImStatus}=require("@mail/core/common/im_status");const{LinkPreviewList}=require("@mail/core/common/link_preview_list");const{MessageConfirmDialog}=require("@mail/core/common/message_confirm_dialog");const{MessageInReply}=require("@mail/core/common/message_in_reply");const{MessageNotificationPopover}=require("@mail/core/common/message_notification_popover");const{MessageReactionMenu}=require("@mail/core/common/message_reaction_menu");const{MessageReactions}=require("@mail/core/common/message_reactions");const{MessageSeenIndicator}=require("@mail/core/common/message_seen_indicator");const{RelativeTime}=require("@mail/core/common/relative_time");const{convertBrToLineBreak,htmlToTextContentInline}=require("@mail/utils/common/format");const{isEventHandled,markEventHandled}=require("@web/core/utils/misc");const{Component,markup,onMounted,useChildSubEnv,useEffect,useRef,useState,}=require("@odoo/owl");const{ActionSwiper}=require("@web/core/action_swiper/action_swiper");const{hasTouch}=require("@web/core/browser/feature_detection");const{Dropdown}=require("@web/core/dropdown/dropdown");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{_t}=require("@web/core/l10n/translation");const{usePopover}=require("@web/core/popover/popover_hook");const{useService}=require("@web/core/utils/hooks");const{url}=require("@web/core/utils/urls");const{useMessageActions}=require("@mail/core/common/message_actions");const{cookie}=require("@web/core/browser/cookie");const Message=__exports.Message=class Message extends Component{static SHADOW_LINK_COLOR="#66598f";static SHADOW_HIGHLIGHT_COLOR="#e99d00bf";static SHADOW_LINK_HOVER_COLOR="#564b79";static components={ActionSwiper,AttachmentList,Composer,Dropdown,DropdownItem,LinkPreviewList,MessageInReply,MessageReactions,MessageSeenIndicator,ImStatus,Popover:MessageNotificationPopover,RelativeTime,};static defaultProps={hasActions:true,isInChatWindow:false,showDates:true,};static props=["hasActions?","isInChatWindow?","highlighted?","onParentMessageClick?","message","messageEdition?","messageToReplyTo?","squashed?","thread?","messageSearch?","className?","showDates?","isFirstMessage?",];static template="mail.Message";setup(){this.popover=usePopover(this.constructor.components.Popover,{position:"top"});this.state=useState({isEditing:false,isHovered:false,isClicked:false,expandOptions:false,emailHeaderOpen:false,showTranslation:false,});this.shadowRoot;this.root=useRef("root");this.hasTouch=hasTouch;this.messageBody=useRef("body");this.messageActions=useMessageActions();this.store=useState(useService("mail.store"));this.shadowBody=useRef("shadowBody");this.rpc=useService("rpc");this.threadService=useState(useService("mail.thread"));this.messageService=useState(useService("mail.message"));this.attachmentService=useService("mail.attachment");this.user=useService("user");this.dialog=useService("dialog");this.ui=useState(useService("ui"));this.openReactionMenu=this.openReactionMenu.bind(this);useChildSubEnv({message:this.props.message,alignedRight:this.isAlignedRight,});useEffect((editingMessage)=>{if(this.props.message.eq(editingMessage)){this.enterEditMode();}},()=>[this.props.messageEdition?.editingMessage]);useEffect((highlighted)=>{if(highlighted){this.root.el.scrollIntoView({behavior:"smooth",block:"center"});}},()=>[this.props.highlighted]);onMounted(()=>{if(this.messageBody.el){this.prepareMessageBody(this.messageBody.el);}
if(this.shadowBody.el){this.shadowRoot=this.shadowBody.el.attachShadow({mode:"open"});const color=cookie.get("color_scheme")==="dark"?"white":"black";const shadowStyle=document.createElement("style");shadowStyle.innerHTML=`
                    * {
                        background-color: transparent !important;
                        color: ${color} !important;
                    }
                    a, a * {
                        color: ${this.constructor.SHADOW_LINK_COLOR} !important;
                    }
                    a:hover, a *:hover {
                        color: ${this.constructor.SHADOW_LINK_HOVER_COLOR} !important;
                    }
                    .o-mail-Message-searchHighlight {
                        background: ${this.constructor.SHADOW_HIGHLIGHT_COLOR} !important;
                    }
                `;if(cookie.get("color_scheme")==="dark"){this.shadowRoot.appendChild(shadowStyle);}}});useEffect(()=>{if(this.shadowBody.el){const body=document.createElement("span");body.innerHTML=this.state.showTranslation?this.message.translationValue:this.props.messageSearch?.highlight(this.message.body)??this.message.body;this.prepareMessageBody(body);this.shadowRoot.appendChild(body);return()=>{this.shadowRoot.removeChild(body);};}},()=>[this.state.showTranslation,this.message.translationValue,this.props.messageSearch?.searchTerm,this.message.body,]);}
get attClass(){return{[this.props.className]:true,"o-highlighted bg-view shadow-lg":this.props.highlighted,"o-selfAuthored":this.message.isSelfAuthored&&!this.env.messageCard,"o-selected":this.props.messageToReplyTo?.isSelected(this.props.thread,this.props.message),"o-squashed pb-1":this.props.squashed,"py-1":!this.props.squashed,"mt-2":!this.props.squashed&&this.props.thread&&!this.env.messageCard,"px-3":!this.props.isInChatWindow&&!this.env.messageCard,"px-2":this.props.isInChatWindow,"opacity-50":this.props.messageToReplyTo?.isNotSelected(this.props.thread,this.props.message),};}
get authorAvatarAttClass(){return{o_object_fit_contain:this.props.message.author?.is_company,o_object_fit_cover:!this.props.message.author?.is_company,};}
get authorAvatarUrl(){if(this.message.type&&this.message.type.includes("email")&&!["partner","guest"].includes(this.message.author?.type)){return url("/mail/static/src/img/email_icon.png");}
return this.threadService.avatarUrl(this.message.author,this.props.message.originThread);}
get expandText(){return _t("Expand");}
get message(){return this.props.message;}
get quickActionCount(){return this.env.inChatter?2:3;}
get showSubtypeDescription(){return(this.message.subtype_description&&this.message.subtype_description.toLowerCase()!==htmlToTextContentInline(this.message.body||"").toLowerCase());}
get messageTypeText(){if(this.props.message.type==="notification"){return _t("System notification");}
if(this.props.message.type==="auto_comment"){return _t("Automated message");}
if(!this.props.message.is_discussion&&this.props.message.type!=="user_notification"){return _t("Note");}
return _t("Message");}
get canAddReaction(){return Boolean(!this.message.is_transient&&this.message.res_id);}
get deletable(){return this.editable;}
get editable(){if(!this.props.hasActions){return false;}
return this.message.editable;}
get canReplyTo(){return this.props.messageToReplyTo;}
get canToggleStar(){return Boolean(!this.message.is_transient&&this.message.res_id&&this.store.user);}
get showUnfollow(){return Boolean(this.message.originThread?.selfFollower&&this.props.thread?.model==="mail.box");}
get isActive(){return(this.state.isHovered||this.state.isClicked||this.emojiPicker?.isOpen||this.state.expandOptions);}
get isAlignedRight(){return Boolean(this.env.inChatWindow&&this.props.message.isSelfAuthored);}
get isPersistentMessageFromAnotherThread(){return!this.isOriginThread&&!this.message.is_transient;}
get isOriginThread(){if(!this.props.thread){return false;}
return this.props.thread.eq(this.message.originThread);}
get isInInbox(){if(!this.props.thread){return false;}
return this.props.thread.id==="inbox";}
get translatable(){return this.store.hasMessageTranslationFeature&&this.env.inChatter;}
get translatedFromText(){return _t("(Translated from: %(language)s)",{language:this.message.translationSource});}
get translationFailureText(){return _t("(Translation Failure: %(error)s)",{error:this.message.translationErrors});}
onMouseenter(){this.state.isHovered=true;}
onMouseleave(){this.state.isHovered=false;this.state.isClicked=null;}
get shouldDisplayAuthorName(){if(!this.env.inChatWindow){return true;}
if(this.message.isSelfAuthored){return false;}
if(this.props.thread.type==="chat"){return false;}
return true;}
onClickDelete(){this.env.services.dialog.add(MessageConfirmDialog,{message:this.message,messageComponent:Message,prompt:_t("Are you sure you want to delete this message?"),onConfirm:()=>this.messageService.delete(this.message),});}
onClickReplyTo(ev){this.props.messageToReplyTo.toggle(this.props.thread,this.props.message);}
async onClickAttachmentUnlink(attachment){await this.attachmentService.delete(attachment);}
onClickMarkAsUnread(){const previousMessageId=this.message.originThread.getPreviousMessage(this.message)?.id??false;if(this.props.thread.seen_message_id===previousMessageId){return;}
return this.rpc("/discuss/channel/set_last_seen_message",{channel_id:this.message.originThread.id,last_message_id:previousMessageId,allow_older:true,});}
async onClick(ev){if(this.store.handleClickOnLink(ev,this.props.thread)){return;}
if(!isEventHandled(ev,"Message.ClickAuthor")&&!isEventHandled(ev,"Message.ClickFailure")){if(this.state.isClicked){this.state.isClicked=false;}else{this.state.isClicked=true;document.body.addEventListener("click",()=>{this.state.isClicked=false;},{capture:true,once:true});}}}
onClickEdit(){this.enterEditMode();}
prepareMessageBody(element){}
enterEditMode(){const body=document.createElement("span");body.innerHTML=this.props.message.body;const mentionedChannelElements=body.querySelectorAll(".o_channel_redirect");const mentionedChannels=Array.from(mentionedChannelElements).map((el)=>this.store.Thread.insert({id:el.dataset.oeId,model:el.dataset.oeModel,}));const messageContent=convertBrToLineBreak(this.props.message.body);this.props.message.composer={mentionedChannels,mentionedPartners:this.props.message.recipients,textInputContent:messageContent,selection:{start:messageContent.length,end:messageContent.length,direction:"none",},};this.state.isEditing=true;}
exitEditMode(){this.props.messageEdition?.exitEditMode();this.message.composer=undefined;this.state.isEditing=false;}
onClickNotification(ev){if(this.message.failureNotifications.length>0){this.onClickFailure(ev);}else{this.popover.open(ev.target,{message:this.message});}}
onClickFailure(ev){markEventHandled(ev,"Message.ClickFailure");this.env.services.action.doAction("mail.mail_resend_message_action",{additionalContext:{mail_message_to_resend:this.message.id,},});}
openReactionMenu(){this.dialog.add(MessageReactionMenu,{message:this.props.message,});}
async onClickToggleTranslation(){if(!this.message.translationValue){const{error,lang_name,body}=await this.rpc("/mail/message/translate",{message_id:this.message.id,});this.message.translationValue=body&&markup(body);this.message.translationSource=lang_name;this.message.translationErrors=error;}
this.state.showTranslation=!this.state.showTranslation&&Boolean(this.message.translationValue);}}
return __exports;});;

/* /mail/static/src/core/common/message_actions.js */
odoo.define('@mail/core/common/message_actions',['@odoo/owl','@web/core/l10n/translation','@web/core/network/download','@web/core/registry','@mail/core/common/message_reaction_button'],function(require){'use strict';let __exports={};const{useComponent,useState}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{download}=require("@web/core/network/download");const{registry}=require("@web/core/registry");const{MessageReactionButton}=require("@mail/core/common/message_reaction_button");const{DateTime}=luxon;const messageActionsRegistry=__exports.messageActionsRegistry=registry.category("mail.message/actions");messageActionsRegistry.add("reaction",{callComponent:MessageReactionButton,props:(component)=>({message:component.props.message}),condition:(component)=>component.canAddReaction,sequence:10,}).add("reply-to",{condition:(component)=>component.canReplyTo,icon:"fa-reply",title:_t("Reply"),onClick:(component)=>component.onClickReplyTo(),sequence:(component)=>(component.isInInbox?55:20),}).add("toggle-star",{condition:(component)=>component.canToggleStar,icon:(component)=>component.props.message.isStarred?"fa-star o-mail-Message-starred":"fa-star-o",title:_t("Mark as Todo"),onClick:(component)=>component.messageService.toggleStar(component.props.message),sequence:30,}).add("mark-as-read",{condition:(component)=>component.isInInbox,icon:"fa-check",title:_t("Mark as Read"),onClick:(component)=>component.messageService.setDone(component.props.message),sequence:40,}).add("reactions",{condition:(component)=>component.message.reactions.length,icon:"fa-smile-o",title:_t("View Reactions"),onClick:(component)=>component.openReactionMenu(),sequence:50,dropdown:true,}).add("unfollow",{condition:(component)=>component.showUnfollow,icon:"fa-user-times",title:_t("Unfollow"),onClick:(component)=>component.messageService.unfollow(component.props.message),sequence:60,}).add("mark-as-unread",{condition:(component)=>component.props.thread.model==="discuss.channel"&&component.store.user,icon:"fa-eye-slash",title:_t("Mark as Unread"),onClick:(component)=>component.onClickMarkAsUnread(),sequence:70,}).add("edit",{condition:(component)=>component.editable,icon:"fa-pencil",title:_t("Edit"),onClick:(component)=>component.onClickEdit(),sequence:80,}).add("delete",{condition:(component)=>component.deletable,icon:"fa-trash",title:_t("Delete"),onClick:(component)=>component.onClickDelete(),sequence:90,}).add("download_files",{condition:(component)=>component.message.attachments.length>1&&component.store.self?.user?.isInternalUser,icon:"fa-download",title:_t("Download Files"),onClick:(component)=>download({data:{file_ids:component.message.attachments.map((rec)=>rec.id),zip_name:`attachments_${DateTime.local().toFormat("HHmmddMMyyyy")}.zip`,},url:"mail/attachment/zip",}),sequence:55,}).add("toggle-translation",{condition:(component)=>component.translatable,icon:(component)=>`fa-language ${component.state.showTranslation ? "o-mail-Message-translated" : ""}`,title:(component)=>(component.state.showTranslation?_t("Revert"):_t("Translate")),onClick:(component)=>component.onClickToggleTranslation(),sequence:100,});function transformAction(component,id,action){return{component:action.component,id,get condition(){return action.condition(component);},get icon(){return typeof action.icon==="function"?action.icon(component):action.icon;},get title(){return typeof action.title==="function"?action.title(component):action.title;},callComponent:action.callComponent,get props(){return action.props(component);},onClick(){action.onClick?.(component);},get sequence(){return typeof action.sequence==="function"?action.sequence(component):action.sequence;},};}
__exports.useMessageActions=useMessageActions;function useMessageActions(){const component=useComponent();const transformedActions=messageActionsRegistry.getEntries().map(([id,action])=>transformAction(component,id,action));const state=useState({get actions(){return transformedActions.filter((action)=>action.condition).sort((a1,a2)=>a1.sequence-a2.sequence);},});return state;}
return __exports;});;

/* /mail/static/src/core/common/message_card_list.js */
odoo.define('@mail/core/common/message_card_list',['@mail/core/common/message','@mail/utils/common/hooks','@odoo/owl','@web/core/l10n/translation','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Message}=require("@mail/core/common/message");const{useVisible}=require("@mail/utils/common/hooks");const{Component,useState,useSubEnv}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const MessageCardList=__exports.MessageCardList=class MessageCardList extends Component{static components={Message};static props=["emptyText?","messages","messageSearch?","loadMore?","mode","onClickJump?","onClickUnpin?","onLoadMoreVisible?","showEmpty?","thread",];static template="mail.MessageCardList";setup(){this.ui=useState(useService("ui"));useSubEnv({messageCard:true});this.loadMore=useVisible("load-more",()=>{if(this.loadMore.isVisible){this.props.onLoadMoreVisible?.();}});}
async onClickJump(message){this.props.onClickJump?.();if(this.ui.isSmall||this.env.inChatWindow){this.env.pinMenu?.close();this.env.searchMenu?.close();}
await new Promise((resolve)=>setTimeout(()=>requestAnimationFrame(resolve)));await this.env.messageHighlight?.highlightMessage(message,this.props.thread);}
get emptyText(){return this.props.emptyText??_t("No messages found");}}
return __exports;});;

/* /mail/static/src/core/common/message_confirm_dialog.js */
odoo.define('@mail/core/common/message_confirm_dialog',['@odoo/owl','@web/core/dialog/dialog','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{Dialog}=require("@web/core/dialog/dialog");const{_t}=require("@web/core/l10n/translation");const MessageConfirmDialog=__exports.MessageConfirmDialog=class MessageConfirmDialog extends Component{static components={Dialog};static props=["close","confirmColor?","confirmText?","message","messageComponent","prompt","size?","title?","onConfirm",];static defaultProps={confirmColor:"btn-primary",confirmText:_t("Confirm"),size:"xl",title:_t("Confirmation"),};static template="mail.MessageConfirmDialog";onClickConfirm(){this.props.onConfirm();this.props.close();}}
return __exports;});;

/* /mail/static/src/core/common/message_in_reply.js */
odoo.define('@mail/core/common/message_in_reply',['@odoo/owl','@web/core/utils/hooks','@web/core/utils/urls'],function(require){'use strict';let __exports={};const{Component,useState}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{url}=require("@web/core/utils/urls");const MessageInReply=__exports.MessageInReply=class MessageInReply extends Component{static props=["message","alignedRight","onClick?"];static template="mail.MessageInReply";setup(){this.store=useState(useService("mail.store"));this.user=useService("user");this.threadService=useService("mail.thread");}
get authorAvatarUrl(){if(this.message.type&&this.message.type.includes("email")&&!["partner","guest"].includes(this.props.message.author?.type)){return url("/mail/static/src/img/email_icon.png");}
return this.threadService.avatarUrl(this.message.parentMessage.author,this.props.message.parentMessage.originThread);}}
return __exports;});;

/* /mail/static/src/core/common/message_model.js */
odoo.define('@mail/core/common/message_model',['@mail/core/common/record','@mail/utils/common/format','@mail/utils/common/misc','@odoo/owl','@web/core/l10n/dates','@web/core/l10n/translation','@web/core/utils/objects','@web/core/utils/urls'],function(require){'use strict';let __exports={};const{Record}=require("@mail/core/common/record");const{htmlToTextContentInline}=require("@mail/utils/common/format");const{assignDefined,assignIn}=require("@mail/utils/common/misc");const{toRaw}=require("@odoo/owl");const{deserializeDateTime}=require("@web/core/l10n/dates");const{_t}=require("@web/core/l10n/translation");const{omit}=require("@web/core/utils/objects");const{url}=require("@web/core/utils/urls");const{DateTime}=luxon;const Message=__exports.Message=class Message extends Record{static id="id";static records={};static new(data){const message=super.new(data);Record.onChange(message,"isEmpty",()=>{if(message.isEmpty&&message.isStarred){message.isStarred=false;const starred=this.store.discuss.starred;starred.counter--;starred.messages.delete(message);}});return message;}
static get(data){return super.get(data);}
static insert(data){return super.insert(...arguments);}
static _insert(data){if(data.res_id){this.store.Thread.insert({model:data.model,id:data.res_id,});}
return super._insert(...arguments);}
update(data){const{message_type:type=this.type,module_icon,record_name,res_model_name,...remainingData}=data;assignDefined(this,remainingData);assignDefined(this,{isStarred:this._store.user?this.starred_partner_ids.includes(this._store.user.id):false,type,});if(this.originThread){assignDefined(this.originThread,{modelName:res_model_name||undefined,module_icon:module_icon||undefined,name:this.originThread.model==="discuss.channel"?undefined:record_name||undefined,});}
assignIn(this,data,["author","notifications","reactions","recipients"]);if("user_follower_id"in data&&data.user_follower_id&&this._store.self){this.originThread.selfFollower={followedThread:this.originThread,id:data.user_follower_id,is_active:true,partner:this._store.self,};}
if(this.isNotification&&!this.notificationType){const parser=new DOMParser();const htmlBody=parser.parseFromString(this.body,"text/html");this.notificationType=htmlBody.querySelector(".o_mail_notification")?.dataset.oeType;}}
attachments=Record.many("Attachment",{inverse:"message"});author=Record.one("Persona");body=Record.attr("",{html:true});composer=Record.one("Composer",{inverse:"message",onDelete:(r)=>r.delete()});default_subject;id;is_discussion;is_note;isSeenBySelf=Record.attr(false,{compute(){return this.originThread?.selfMember?.lastSeenMessage?.id>=this.id;},});isStarred;is_transient;linkPreviews=Record.many("LinkPreview",{inverse:"message"});needaction_partner_ids=[];get originThread(){return this._store.Thread.get({model:this.model,id:this.res_id});}
originThread2=Record.one("Thread",{inverse:"allMessages",compute(){if(this.model&&this.res_id){return{model:this.model,id:this.res_id};}},});history_partner_ids=[];parentMessage=Record.one("Message");reactions=Record.many("MessageReactions",{inverse:"message"});notifications=Record.many("Notification",{inverse:"message"});recipients=Record.many("Persona");res_id;model;scheduledDatetime;starred_partner_ids=[];subject;subtype_description;trackingValues=[];translationValue;translationSource;translationErrors;type;temporary_id=null;notificationType;create_date;write_date;now=DateTime.now().set({milliseconds:0});get allowsEdition(){return this._store.user?.isAdmin||this.isSelfAuthored;}
get editable(){if(!this.allowsEdition){return false;}
return this.type==="comment";}
get dateDay(){let dateDay=this.datetime.toLocaleString(DateTime.DATE_FULL);if(dateDay===DateTime.now().toLocaleString(DateTime.DATE_FULL)){dateDay=_t("Today");}
return dateDay;}
datetime=Record.attr(undefined,{compute(){return toRaw(this.date?deserializeDateTime(this.date):this.now);},});get scheduledDate(){return toRaw(this.scheduledDatetime?deserializeDateTime(this.scheduledDatetime):undefined);}
get datetimeShort(){return this.datetime.toLocaleString(DateTime.DATETIME_SHORT_WITH_SECONDS);}
get isSelfMentioned(){return this._store.self?.in(this.recipients);}
get isHighlightedFromMention(){return this.isSelfMentioned&&this.model==="discuss.channel";}
get isSelfAuthored(){if(!this.author||!this._store.self){return false;}
return this.author.eq(this._store.self);}
get isNeedaction(){return this.needaction_partner_ids.includes(this._store.user?.id);}
get hasActions(){return!this.is_transient;}
get isHistory(){return this.history_partner_ids.includes(this._store.user?.id);}
get isNotification(){return this.type==="notification"&&this.model==="discuss.channel";}
get isSubjectSimilarToOriginThreadName(){if(!this.subject||!this.originThread||!this.originThread.name){return false;}
const regexPrefix=/^((re|fw|fwd)\s*:\s*)*/i;const cleanedThreadName=this.originThread.name.replace(regexPrefix,"");const cleanedSubject=this.subject.replace(regexPrefix,"");return cleanedSubject===cleanedThreadName;}
get isSubjectDefault(){const threadName=this.originThread?.name?.trim().toLowerCase();const defaultSubject=this.default_subject?this.default_subject.toLowerCase():"";const candidates=new Set([defaultSubject,threadName]);return candidates.has(this.subject?.toLowerCase());}
get resUrl(){return`${url("/web")}#model=${this.model}&id=${this.res_id}`;}
get editDate(){return this.write_date!==this.create_date?this.write_date:false;}
get hasTextContent(){return!this.isBodyEmpty;}
get isEmpty(){return(this.isBodyEmpty&&this.attachments.length===0&&this.trackingValues.length===0&&!this.subtype_description);}
get isBodyEmpty(){return(!this.body||["","<p></p>","<p><br></p>","<p><br/></p>"].includes(this.body.replace(/\s/g,"")));}
get linkPreviewSquash(){return(this._store.hasLinkPreviewFeature&&this.body&&this.body.startsWith("<a")&&this.body.endsWith("/a>")&&this.body.match(/<\/a>/im)?.length===1&&this.linkPreviews.length===1&&this.linkPreviews[0].isImage);}
get inlineBody(){if(!this.body){return"";}
return htmlToTextContentInline(this.body);}
get notificationIcon(){switch(this.notificationType){case"pin":return"fa fa-thumb-tack";}
return null;}
get failureNotifications(){return this.notifications.filter((notification)=>notification.isFailure);}
get editDatetimeHuge(){return deserializeDateTime(this.editDate).toLocaleString(omit(DateTime.DATETIME_HUGE,"timeZoneName"));}}
Message.register();return __exports;});;

/* /mail/static/src/core/common/message_notification_popover.js */
odoo.define('@mail/core/common/message_notification_popover',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const MessageNotificationPopover=__exports.MessageNotificationPopover=class MessageNotificationPopover extends Component{static template="mail.MessageNotificationPopover";static props=["message","close?"];}
return __exports;});;

/* /mail/static/src/core/common/message_reaction_button.js */
odoo.define('@mail/core/common/message_reaction_button',['@odoo/owl','@web/core/emoji_picker/emoji_picker','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,useRef,useState}=require("@odoo/owl");const{useEmojiPicker}=require("@web/core/emoji_picker/emoji_picker");const{useService}=require("@web/core/utils/hooks");const MessageReactionButton=__exports.MessageReactionButton=class MessageReactionButton extends Component{static template="mail.MessageReactionButton";static props=["message"];setup(){this.messageService=useState(useService("mail.message"));this.store=useState(useService("mail.store"));this.emojiPickerRef=useRef("emoji-picker");this.emojiPicker=useEmojiPicker(this.emojiPickerRef,{onSelect:(emoji)=>{const reaction=this.props.message.reactions.find(({content,personas})=>content===emoji&&personas.find((persona)=>persona.eq(this.store.self)));if(!reaction){this.messageService.react(this.props.message,emoji);}},});}}
return __exports;});;

/* /mail/static/src/core/common/message_reaction_menu.js */
odoo.define('@mail/core/common/message_reaction_menu',['@web/core/emoji_picker/emoji_picker','@mail/utils/common/hooks','@odoo/owl','@web/core/dialog/dialog','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{loadEmoji}=require("@web/core/emoji_picker/emoji_picker");const{onExternalClick}=require("@mail/utils/common/hooks");const{Component,onWillStart,useEffect,useExternalListener,useRef,useState,}=require("@odoo/owl");const{Dialog}=require("@web/core/dialog/dialog");const{useService}=require("@web/core/utils/hooks");const MessageReactionMenu=__exports.MessageReactionMenu=class MessageReactionMenu extends Component{static props=["close","message"];static components={Dialog};static template="mail.MessageReactionMenu";setup(){this.threadService=useService("mail.thread");this.root=useRef("root");this.store=useState(useService("mail.store"));this.ui=useState(useService("ui"));this.messageService=useService("mail.message");this.state=useState({reaction:this.props.message.reactions[0],});useExternalListener(document,"keydown",this.onKeydown);onExternalClick("root",()=>this.props.close());useEffect(()=>{const activeReaction=this.props.message.reactions.find(({content})=>content===this.state.reaction.content);if(this.props.message.reactions.length===0){this.props.close();}else if(!activeReaction){this.state.reaction=this.props.message.reactions[0];}},()=>[this.props.message.reactions.length]);onWillStart(async()=>{const{emojis}=await loadEmoji();this.emojis=emojis;});}
onKeydown(ev){switch(ev.key){case"Escape":this.props.close();break;case"q":this.props.close();break;default:return;}}
getEmojiShortcode(reaction){return this.emojis.find((emoji)=>emoji.codepoints===reaction.content).shortcodes[0];}}
return __exports;});;

/* /mail/static/src/core/common/message_reactions.js */
odoo.define('@mail/core/common/message_reactions',['@odoo/owl','@web/core/l10n/translation','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,useState}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const MessageReactions=__exports.MessageReactions=class MessageReactions extends Component{static props=["message","openReactionMenu"];static template="mail.MessageReactions";setup(){this.user=useService("user");this.store=useState(useService("mail.store"));this.ui=useService("ui");this.messageService=useState(useService("mail.message"));}
getReactionSummary(reaction){const[firstUserName,secondUserName,thirdUserName]=reaction.personas.map(({name,displayName})=>name||displayName);switch(reaction.count){case 1:return _t("%s has reacted with %s",firstUserName,reaction.content);case 2:return _t("%s and %s have reacted with %s",firstUserName,secondUserName,reaction.content);case 3:return _t("%s, %s, %s have reacted with %s",firstUserName,secondUserName,thirdUserName,reaction.content);case 4:return _t("%s, %s, %s and 1 other person have reacted with %s",firstUserName,secondUserName,thirdUserName,reaction.content);default:return _t("%s, %s, %s and %s other persons have reacted with %s",firstUserName,secondUserName,thirdUserName,reaction.personas.length-3,reaction.content);}}
hasSelfReacted(reaction){return this.store.self?.in(reaction.personas);}
onClickReaction(reaction){if(this.hasSelfReacted(reaction)){this.messageService.removeReaction(reaction);}else{this.messageService.react(this.props.message,reaction.content);}}
onContextMenu(ev){if(this.ui.isSmall){ev.preventDefault();this.props.openReactionMenu();}}}
return __exports;});;

/* /mail/static/src/core/common/message_reactions_model.js */
odoo.define('@mail/core/common/message_reactions_model',['@mail/core/common/record'],function(require){'use strict';let __exports={};const{AND,Record}=require("@mail/core/common/record");const MessageReactions=__exports.MessageReactions=class MessageReactions extends Record{static id=AND("message","content");static get(data){return super.get(data);}
static insert(data){return super.insert(...arguments);}
content;count;personas=Record.many("Persona");message=Record.one("Message");}
MessageReactions.register();return __exports;});;

/* /mail/static/src/core/common/message_search_hook.js */
odoo.define('@mail/core/common/message_search_hook',['@mail/utils/common/hooks','@odoo/owl','@web/core/utils/hooks','@web/core/utils/strings'],function(require){'use strict';let __exports={};const{useSequential}=require("@mail/utils/common/hooks");const{useState,onWillUnmount,markup}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{escapeRegExp}=require("@web/core/utils/strings");const HIGHLIGHT_CLASS=__exports.HIGHLIGHT_CLASS="o-mail-Message-searchHighlight";__exports.searchHighlight=searchHighlight;function searchHighlight(searchTerm,target){if(!searchTerm){return target;}
const htmlDoc=new DOMParser().parseFromString(target,"text/html");for(const term of searchTerm.split(" ")){const regexp=new RegExp(`(${escapeRegExp(term)})`,"gi");const split=term.toLowerCase().split("'");let lowercase=split.map((s)=>`'${s}'`).join(', "\'", ');let uppercase=lowercase.toUpperCase();if(split.length>1){lowercase=`concat(${lowercase})`;uppercase=`concat(${uppercase})`;}
const matchs=htmlDoc.evaluate(`//*[text()[contains(translate(., ${uppercase}, ${lowercase}), ${lowercase})]]`,htmlDoc,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);for(let i=0;i<matchs.snapshotLength;i++){const element=matchs.snapshotItem(i);const newNode=[];for(const node of element.childNodes){const match=node.textContent.match(regexp);if(node.nodeType===Node.TEXT_NODE&&match?.length>0){let curIndex=0;for(const match of node.textContent.matchAll(regexp)){const start=htmlDoc.createTextNode(node.textContent.slice(curIndex,match.index));newNode.push(start);const span=htmlDoc.createElement("span");span.setAttribute("class",HIGHLIGHT_CLASS);span.textContent=match[0];newNode.push(span);curIndex=match.index+match[0].length;}
const end=htmlDoc.createTextNode(node.textContent.slice(curIndex));newNode.push(end);}else{newNode.push(node);}}
element.replaceChildren(...newNode);}}
return markup(htmlDoc.body.innerHTML);}
__exports.useMessageSearch=useMessageSearch;function useMessageSearch(thread){const threadService=useService("mail.thread");const sequential=useSequential();const state=useState({thread,async search(before=false){if(this.searchTerm){this.searching=true;const data=await sequential(()=>threadService.search(this.searchTerm,this.thread,before));if(!data){return;}
const{count,loadMore,messages}=data;this.searched=true;this.searching=false;this.count=count;this.loadMore=loadMore;if(before){this.messages.push(...messages);}else{this.messages=messages;}}else{this.clear();}},count:0,clear(){this.messages=[];this.searched=false;this.searching=false;this.searchTerm=undefined;},loadMore:false,messages:[],searchTerm:undefined,searched:false,searching:false,highlight:(target)=>searchHighlight(state.searchTerm,target),});onWillUnmount(()=>{state.clear();});return state;}
return __exports;});;

/* /mail/static/src/core/common/message_seen_indicator.js */
odoo.define('@mail/core/common/message_seen_indicator',['@odoo/owl','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,useState}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const MessageSeenIndicator=__exports.MessageSeenIndicator=class MessageSeenIndicator extends Component{static template="mail.MessageSeenIndicator";static props=["message","thread","className?"];setup(){this.store=useState(useService("mail.store"));}
get hasEveryoneSeen(){const otherDidNotSee=this.props.thread.channelMembers.filter((member)=>{return(member.persona.notEq(this.props.message.author)&&(!member.lastSeenMessage||member.lastSeenMessage.id<this.props.message.id));});return otherDidNotSee.length===0;}
get hasEveryoneReceived(){return!this.props.thread.channelMembers.some((member)=>{return(member.persona.notEq(this.props.message.author)&&(!member.lastFetchedMessage||member.lastFetchedMessage.id<this.props.message.id));});}
get isMessagePreviousToLastSelfMessageSeenByEveryone(){if(!this.props.thread.lastSelfMessageSeenByEveryone){return false;}
return this.props.message.id<this.props.thread.lastSelfMessageSeenByEveryone.id;}
get hasSomeoneSeen(){const otherSeen=this.props.thread.channelMembers.filter((member)=>member.persona.notEq(this.props.message.author)&&member.lastSeenMessage?.id>=this.props.message.id);return otherSeen.length>0;}
get hasSomeoneFetched(){const otherFetched=this.props.thread.channelMembers.filter((member)=>member.persona.notEq(this.props.message.author)&&member.lastFetchedMessage?.id>=this.props.message.id);return otherFetched.length>0;}}
return __exports;});;

/* /mail/static/src/core/common/message_service.js */
odoo.define('@mail/core/common/message_service',['@mail/utils/common/format','@web/core/l10n/translation','@web/core/l10n/utils','@web/core/registry'],function(require){'use strict';let __exports={};const{convertBrToLineBreak,prettifyMessageContent}=require("@mail/utils/common/format");const{_t}=require("@web/core/l10n/translation");const{pyToJsLocale}=require("@web/core/l10n/utils");const{registry}=require("@web/core/registry");const{DateTime}=luxon;const MessageService=__exports.MessageService=class MessageService{constructor(env,services){this.env=env;this.store=services["mail.store"];this.rpc=services.rpc;this.orm=services.orm;this.userService=services.user;}
async edit(message,body,attachments=[],{mentionedChannels=[],mentionedPartners=[]}={}){if(convertBrToLineBreak(message.body)===body&&attachments.length===0){return;}
const validMentions=this.getMentionsFromText(body,{mentionedChannels,mentionedPartners,});const messageData=await this.rpc("/mail/message/update_content",{attachment_ids:attachments.concat(message.attachments).map((attachment)=>attachment.id),attachment_tokens:attachments.concat(message.attachments).map((attachment)=>attachment.accessToken),body:await prettifyMessageContent(body,validMentions),message_id:message.id,partner_ids:validMentions?.partners?.map((partner)=>partner.id),});this.store.Message.insert(messageData,{html:true});if(!message.isEmpty&&this.store.hasLinkPreviewFeature){this.rpc("/mail/link_preview",{message_id:message.id,clear:true},{silent:true});}}
async delete(message){await this.rpc("/mail/message/update_content",{attachment_ids:[],attachment_tokens:[],body:"",message_id:message.id,});if(message.isStarred){this.store.discuss.starred.counter--;this.store.discuss.starred.messages.delete(message);}
message.body="";message.attachments=[];}
getLastMessageId(){return Object.values(this.store.Message.records).reduce((lastMessageId,message)=>Math.max(lastMessageId,message.id),0);}
getNextTemporaryId(){return this.getLastMessageId()+0.01;}
getMentionsFromText(body,{mentionedChannels=[],mentionedPartners=[]}={}){if(!this.store.user){return{};}
const validMentions={};const partners=[];const threads=[];for(const partner of mentionedPartners){const index=body.indexOf(`@${partner.name}`);if(index===-1){continue;}
partners.push(partner);}
for(const thread of mentionedChannels){const index=body.indexOf(`#${thread.displayName}`);if(index===-1){continue;}
threads.push(thread);}
validMentions.partners=partners;validMentions.threads=threads;return validMentions;}
async toggleStar(message){await this.orm.silent.call("mail.message","toggle_message_starred",[[message.id]]);}
async setDone(message){await this.orm.silent.call("mail.message","set_message_done",[[message.id]]);}
async unfollow(message){if(message.isNeedaction){await this.setDone(message);}
const thread=message.originThread;await this.env.services["mail.thread"].removeFollower(thread.selfFollower);this.env.services.notification.add(_t('You are no longer following "%(thread_name)s".',{thread_name:thread.name}),{type:"success"});}
async unstarAll(){this.store.discuss.starred.counter=0;this.store.discuss.starred.messages=[];await this.orm.call("mail.message","unstar_all");}
async react(message,content){await this.rpc("/mail/message/reaction",{action:"add",content,message_id:message.id,},{silent:true});}
async removeReaction(reaction){await this.rpc("/mail/message/reaction",{action:"remove",content:reaction.content,message_id:reaction.message.id,},{silent:true});}
scheduledDateSimple(message){return message.scheduledDate.toLocaleString(DateTime.TIME_24_SIMPLE,{locale:pyToJsLocale(this.userService.lang),});}
dateSimple(message){return message.datetime.toLocaleString(DateTime.TIME_24_SIMPLE,{locale:pyToJsLocale(this.userService.lang),});}}
const messageService=__exports.messageService={dependencies:["mail.store","rpc","orm","user"],start(env,services){return new MessageService(env,services);},};registry.category("services").add("mail.message",messageService);return __exports;});;

/* /mail/static/src/core/common/messaging_service.js */
odoo.define('@mail/core/common/messaging_service',['@mail/utils/common/format','@web/core/l10n/translation','@web/core/registry','@web/core/utils/concurrency'],function(require){'use strict';let __exports={};const{cleanTerm}=require("@mail/utils/common/format");const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{Deferred}=require("@web/core/utils/concurrency");const Messaging=__exports.Messaging=class Messaging{constructor(...args){this.setup(...args);}
setup(env,services){this.env=env;this.store=services["mail.store"];this.rpc=services.rpc;this.orm=services.orm;this.userSettingsService=services["mail.user_settings"];this.router=services.router;this.isReady=new Deferred();this.imStatusService=services.im_status;const user=services.user;if(user.partnerId){this.store.Persona.insert({id:user.partnerId,type:"partner",isAdmin:user.isAdmin,});}
this.store.discuss.inbox={id:"inbox",model:"mail.box",name:_t("Inbox"),type:"mailbox",};this.store.discuss.starred={id:"starred",model:"mail.box",name:_t("Starred"),type:"mailbox",counter:0,};this.store.discuss.history={id:"history",model:"mail.box",name:_t("History"),type:"mailbox",counter:0,};this.updateImStatusRegistration();}
async initialize(){await this.rpc("/mail/init_messaging",{context:this.env.services.user.context},{silent:true}).then(this.initMessagingCallback.bind(this));}
initMessagingCallback(data){if(data.current_partner){this.store.user={...data.current_partner,type:"partner"};}
if(data.currentGuest){this.store.guest={...data.currentGuest,type:"guest",};}
this.store.odoobot={...data.odoobot,type:"partner"};const settings=data.current_user_settings;this.userSettingsService.updateFromCommands(settings);this.userSettingsService.id=settings.id;this.store.companyName=data.companyName;this.store.discuss.inbox.counter=data.needaction_inbox_counter;this.store.internalUserGroupId=data.internalUserGroupId;this.store.discuss.starred.counter=data.starred_counter;this.store.mt_comment_id=data.mt_comment_id;if(!this.store.discuss.isActive){const routerhash=this.router.current.hash;if(routerhash?.action==="mail.action_discuss"){this.store.discuss.isActive=true;}else if(data.action_discuss_id){this.store.discuss.isActive=data.action_discuss_id===routerhash?.action;}else{this.store.discuss.isActive=data.menu_id&&data.menu_id===routerhash?.menu_id;}}
this.store.CannedResponse.insert(data.shortcodes??[]);this.store.hasLinkPreviewFeature=data.hasLinkPreviewFeature;this.store.initBusId=data.initBusId;this.store.odoobotOnboarding=data.odoobotOnboarding;this.isReady.resolve(data);this.store.isMessagingReady=true;this.store.hasMessageTranslationFeature=data.hasMessageTranslationFeature;}
get registeredImStatusPartners(){return this.store.registeredImStatusPartners;}
updateImStatusRegistration(){}
async searchPartners(searchStr="",limit=10){const partners=[];const searchTerm=cleanTerm(searchStr);for(const localId in this.store.Persona.records){const persona=this.store.Persona.records[localId];if(persona.type!=="partner"){continue;}
const partner=persona;if(partner.name&&cleanTerm(partner.name).includes(searchTerm)&&((partner.active&&partner.user)||partner===this.store.odoobot)){partners.push(partner);if(partners.length>=limit){break;}}}
if(!partners.length){const partnersData=await this.orm.silent.call("res.partner","im_search",[searchTerm,limit,]);this.store.Persona.insert(partnersData);}
return partners;}
openDocument({id,model}){this.env.services.action.doAction({type:"ir.actions.act_window",res_model:model,views:[[false,"form"]],res_id:id,});}}
const messagingService=__exports.messagingService={dependencies:["mail.store","rpc","orm","user","router","im_status","mail.attachment","mail.user_settings","mail.thread","mail.message","mail.persona",],start(env,services){const messaging=new Messaging(env,services);messaging.initialize();return messaging;},};registry.category("services").add("mail.messaging",messagingService);return __exports;});;

/* /mail/static/src/core/common/navigable_list.js */
odoo.define('@mail/core/common/navigable_list',['@mail/core/common/im_status','@mail/utils/common/hooks','@web/core/utils/misc','@odoo/owl','@web/core/hotkeys/hotkey_service','@web/core/position_hook','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{ImStatus}=require("@mail/core/common/im_status");const{onExternalClick}=require("@mail/utils/common/hooks");const{markEventHandled,isEventHandled}=require("@web/core/utils/misc");const{Component,useEffect,useExternalListener,useRef,useState}=require("@odoo/owl");const{getActiveHotkey}=require("@web/core/hotkeys/hotkey_service");const{usePosition}=require("@web/core/position_hook");const{useService}=require("@web/core/utils/hooks");const NavigableList=__exports.NavigableList=class NavigableList extends Component{static components={ImStatus};static template="mail.NavigableList";static props={anchorRef:{optional:true},class:{type:String,optional:true},onSelect:{type:Function},options:{type:Array},optionTemplate:{type:String,optional:true},placeholder:{type:String,optional:true},position:{type:String,optional:true},isLoading:{type:Boolean,optional:true},};static defaultProps={position:"bottom",isLoading:false};setup(){this.rootRef=useRef("root");this.state=useState({activeIndex:null,open:false,});this.hotkey=useService("hotkey");this.hotkeysToRemove=[];useExternalListener(window,"keydown",this.onKeydown,true);onExternalClick("root",async(ev)=>{await new Promise(setTimeout);if(isEventHandled(ev,"composer.onClickTextarea")||isEventHandled(ev,"channelSelector.onClickInput")){return;}
this.close();});usePosition("root",()=>this.props.anchorRef,{position:this.props.position});useEffect(()=>{this.open();},()=>[this.props]);}
get show(){return Boolean(this.state.open&&(this.props.isLoading||this.props.options.length));}
open(){this.state.open=true;this.state.activeIndex=null;this.navigate("first");}
close(){this.state.open=false;this.state.activeIndex=null;}
selectOption(ev,index,params={}){const option=this.props.options[index];if(option.unselectable){this.close();return;}
this.props.onSelect(ev,option,{...params,});this.close();}
navigate(direction){const activeOptionId=this.state.activeIndex!==null?this.state.activeIndex:0;let targetId=undefined;switch(direction){case"first":targetId=0;break;case"last":targetId=this.props.options.length-1;break;case"previous":targetId=activeOptionId-1;if(targetId<0){this.navigate("last");return;}
break;case"next":targetId=activeOptionId+1;if(targetId>this.props.options.length-1){this.navigate("first");return;}
break;default:return;}
this.state.activeIndex=targetId;}
onKeydown(ev){if(!this.show){return;}
const hotkey=getActiveHotkey(ev);switch(hotkey){case"enter":if(!this.show||this.state.activeIndex===null){return;}
markEventHandled(ev,"NavigableList.select");this.selectOption(ev,this.state.activeIndex);break;case"escape":markEventHandled(ev,"NavigableList.close");this.close();break;case"tab":this.navigate("next");break;case"arrowup":this.navigate("previous");break;case"arrowdown":this.navigate("next");break;default:return;}
ev.preventDefault();}
onOptionMouseEnter(index){this.state.activeIndex=index;}}
return __exports;});;

/* /mail/static/src/core/common/notification_model.js */
odoo.define('@mail/core/common/notification_model',['@mail/core/common/record','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{Record}=require("@mail/core/common/record");const{_t}=require("@web/core/l10n/translation");const Notification=__exports.Notification=class Notification extends Record{static id="id";static records={};static get(data){return super.get(data);}
static insert(data){return super.insert(...arguments);}
id;message=Record.one("Message");notification_status;notification_type;failure=Record.one("Failure",{inverse:"notifications",compute(){const thread=this.message?.originThread;if(!this.message?.author?.eq(this._store.self)){return;}
const failure=Object.values(this._store.Failure.records).find((f)=>{return(f.resModel===thread?.model&&f.type===this.notification_type&&(f.resModel!=="discuss.channel"||f.resIds.has(thread?.id)));});return this.isFailure?{id:failure?failure.id:this._store.Failure.nextId.value++,resId:thread?.id,}:false;},eager:true,});failure_type;persona=Record.one("Persona");get isFailure(){return["exception","bounce"].includes(this.notification_status);}
get icon(){if(this.isFailure){return"fa fa-envelope";}
return"fa fa-envelope-o";}
get label(){return"";}
get statusIcon(){switch(this.notification_status){case"process":return"fa fa-hourglass-half";case"pending":return"fa fa-paper-plane-o";case"sent":return"fa fa-check";case"bounce":return"fa fa-exclamation";case"exception":return"fa fa-exclamation";case"ready":return"fa fa-send-o";case"canceled":return"fa fa-trash-o";}
return"";}
get statusTitle(){switch(this.notification_status){case"process":return _t("Processing");case"pending":return _t("Sent");case"sent":return _t("Delivered");case"bounce":return _t("Bounced");case"exception":return _t("Error");case"ready":return _t("Ready");case"canceled":return _t("Canceled");}
return"";}}
Notification.register();return __exports;});;

/* /mail/static/src/core/common/notification_permission_service.js */
odoo.define('@mail/core/common/notification_permission_service',['@odoo/owl','@web/core/browser/browser','@web/core/browser/feature_detection','@web/core/l10n/translation','@web/core/registry'],function(require){'use strict';let __exports={};const{reactive}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{isAndroidApp,isIosApp}=require("@web/core/browser/feature_detection");const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const notificationPermissionService=__exports.notificationPermissionService={dependencies:["notification"],_normalizePermission(permission){switch(permission){case"default":return"prompt";case undefined:return"denied";default:return permission;}},async start(env,services){const notification=services.notification;let permission;try{permission=await browser.navigator?.permissions?.query({name:"notifications",});}catch{}
const state=reactive({permission:isIosApp()||isAndroidApp()?"denied":this._normalizePermission(permission?.state??browser.Notification?.permission),requestPermission:async()=>{if(browser.Notification&&state.permission==="prompt"){state.permission=this._normalizePermission(await browser.Notification.requestPermission());if(state.permission==="denied"){notification.add(_t("Odoo will not send notifications on this device."),{type:"warning",title:_t("Notifications blocked"),});}else if(state.permission==="granted"){notification.add(_t("Odoo will send notifications on this device!"),{type:"success",title:_t("Notifications allowed"),});}}},});if(permission){permission.addEventListener("change",()=>(state.permission=permission.state));}
return state;},};registry.category("services").add("mail.notification.permission",notificationPermissionService);return __exports;});;

/* /mail/static/src/core/common/out_of_focus_service.js */
odoo.define('@mail/core/common/out_of_focus_service',['@mail/utils/common/format','@web/core/browser/browser','@web/core/l10n/translation','@web/core/registry','@web/core/utils/urls'],function(require){'use strict';let __exports={};const{htmlToTextContentInline}=require("@mail/utils/common/format");const{browser}=require("@web/core/browser/browser");const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{url}=require("@web/core/utils/urls");const PREVIEW_MSG_MAX_SIZE=350;const OutOfFocusService=__exports.OutOfFocusService=class OutOfFocusService{constructor(env,services){this.setup(env,services);}
setup(env,services){this.env=env;this.audio=undefined;this.multiTab=services.multi_tab;this.notificationService=services.notification;}
async notify(message,channel){const modelsHandleByPush=["mail.thread","discuss.channel"];if(modelsHandleByPush.includes(message.model)&&(await this.hasServiceWorkInstalledAndPushSubscriptionActive())){return;}
const author=message.author;let notificationTitle;if(!author){notificationTitle=_t("New message");}else{if(channel.channel_type==="channel"){notificationTitle=_t("%(author name)s from %(channel name)s",{"author name":author.name,"channel name":channel.displayName,});}else{notificationTitle=author.name;}}
const notificationContent=htmlToTextContentInline(message.body).substring(0,PREVIEW_MSG_MAX_SIZE);this.sendNotification({message:notificationContent,title:notificationTitle,type:"info",});}
async hasServiceWorkInstalledAndPushSubscriptionActive(){const registration=await browser.navigator.serviceWorker?.getRegistration();if(registration){const pushManager=await registration.pushManager;if(pushManager){const subscription=await pushManager.getSubscription();return!!subscription;}}
return false;}
sendNotification({message,title,type}){if(!this.canSendNativeNotification){this.sendOdooNotification(message,{title,type});return;}
if(!this.multiTab.isOnMainTab()){return;}
try{this.sendNativeNotification(title,message);}catch(error){if(error.message.includes("ServiceWorkerRegistration")){this.sendOdooNotification(message,{title,type});}else{throw error;}}}
async sendOdooNotification(message,options){this.notificationService.add(message,options);this._playSound();}
sendNativeNotification(title,message){const notification=new Notification(title,{body:message,icon:"/mail/static/src/img/odoobot_transparent.png",});notification.addEventListener("click",({target:notification})=>{window.focus();notification.close();});this._playSound();}
async _playSound(){if(this.canPlayAudio&&this.multiTab.isOnMainTab()){if(!this.audio){this.audio=new Audio();this.audio.src=this.audio.canPlayType("audio/ogg; codecs=vorbis")?url("/mail/static/src/audio/ting.ogg"):url("/mail/static/src/audio/ting.mp3");}
try{await this.audio.play();}catch{}}}
get canPlayAudio(){return typeof Audio!=="undefined";}
get canSendNativeNotification(){return Boolean(browser.Notification&&browser.Notification.permission==="granted");}}
const outOfFocusService=__exports.outOfFocusService={dependencies:["multi_tab","notification"],start(env,services){const service=new OutOfFocusService(env,services);return service;},};registry.category("services").add("mail.out_of_focus",outOfFocusService);return __exports;});;

/* /mail/static/src/core/common/partner_compare.js */
odoo.define('@mail/core/common/partner_compare',['@mail/utils/common/format','@web/core/registry'],function(require){'use strict';let __exports={};const{cleanTerm}=require("@mail/utils/common/format");const{registry}=require("@web/core/registry");const partnerCompareRegistry=__exports.partnerCompareRegistry=registry.category("mail.partner_compare");partnerCompareRegistry.add("mail.archived-last-except-odoobot",(p1,p2)=>{const p1active=p1.active||p1.eq(p1._store.odoobot);const p2active=p2.active||p2.eq(p2._store.odoobot);if(!p1active&&p2active){return 1;}
if(!p2active&&p1active){return-1;}},{sequence:5});partnerCompareRegistry.add("mail.internal-users",(p1,p2)=>{const isAInternalUser=p1.user?.isInternalUser;const isBInternalUser=p2.user?.isInternalUser;if(isAInternalUser&&!isBInternalUser){return-1;}
if(!isAInternalUser&&isBInternalUser){return 1;}},{sequence:35});partnerCompareRegistry.add("mail.followers",(p1,p2,{thread})=>{if(thread){const followerList=[...thread.followers];if(thread.selfFollower){followerList.push(thread.selfFollower);}
const isFollower1=followerList.some((follower)=>p1.eq(follower.partner));const isFollower2=followerList.some((follower)=>p2.eq(follower.partner));if(isFollower1&&!isFollower2){return-1;}
if(!isFollower1&&isFollower2){return 1;}}},{sequence:45});partnerCompareRegistry.add("mail.name",(p1,p2,{searchTerm})=>{const cleanedName1=cleanTerm(p1.name);const cleanedName2=cleanTerm(p2.name);if(cleanedName1.startsWith(searchTerm)&&!cleanedName2.startsWith(searchTerm)){return-1;}
if(!cleanedName1.startsWith(searchTerm)&&cleanedName2.startsWith(searchTerm)){return 1;}
if(cleanedName1<cleanedName2){return-1;}
if(cleanedName1>cleanedName2){return 1;}},{sequence:50});partnerCompareRegistry.add("mail.email",(p1,p2,{searchTerm})=>{const cleanedEmail1=cleanTerm(p1.email);const cleanedEmail2=cleanTerm(p2.email);if(cleanedEmail1.startsWith(searchTerm)&&!cleanedEmail1.startsWith(searchTerm)){return-1;}
if(!cleanedEmail2.startsWith(searchTerm)&&cleanedEmail2.startsWith(searchTerm)){return 1;}
if(cleanedEmail1<cleanedEmail2){return-1;}
if(cleanedEmail1>cleanedEmail2){return 1;}},{sequence:55});partnerCompareRegistry.add("mail.id",(p1,p2)=>{return p1.id-p2.id;},{sequence:75});return __exports;});;

/* /mail/static/src/core/common/persona_model.js */
odoo.define('@mail/core/common/persona_model',['@mail/core/common/record'],function(require){'use strict';let __exports={};const{AND,Record}=require("@mail/core/common/record");const Persona=__exports.Persona=class Persona extends Record{static id=AND("type","id");static records={};static get(data){return super.get(data);}
static insert(data){return super.insert(...arguments);}
channelMembers=Record.many("ChannelMember");id;is_company;landlineNumber;mobileNumber;storeAsTrackedImStatus=Record.one("Store",{compute(){if(this.type==="guest"||(this.type==="partner"&&this.im_status!=="im_partner"&&!this.is_public)){return this._store;}},onAdd(){if(!this._store.env.services.bus_service.isActive){return;}
const model=this.type==="partner"?"res.partner":"mail.guest";this._store.env.services.bus_service.addChannel(`odoo-presence-${model}_${this.id}`);},onDelete(){if(!this._store.env.services.bus_service.isActive){return;}
const model=this.type==="partner"?"res.partner":"mail.guest";this._store.env.services.bus_service.deleteChannel(`odoo-presence-${model}_${this.id}`);},eager:true,inverse:"imStatusTrackedPersonas",});type;name;displayName;country;email;user;im_status;isAdmin=false;write_date;get hasPhoneNumber(){return Boolean(this.mobileNumber||this.landlineNumber);}
get nameOrDisplayName(){return this.name||this.displayName;}
get emailWithoutDomain(){return this.email.substring(0,this.email.lastIndexOf("@"));}}
Persona.register();return __exports;});;

/* /mail/static/src/core/common/persona_service.js */
odoo.define('@mail/core/common/persona_service',['@web/core/registry','@mail/utils/common/hooks','@odoo/owl','@mail/utils/common/misc'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{useSequential}=require("@mail/utils/common/hooks");const{markRaw}=require("@odoo/owl");const{compareDatetime}=require("@mail/utils/common/misc");const DEFAULT_AVATAR=__exports.DEFAULT_AVATAR="/mail/static/src/img/smiley/avatar.jpg";const PersonaService=__exports.PersonaService=class PersonaService{constructor(...args){this.setup(...args);}
setup(env,services){this.env=env;this.rpc=services.rpc;this.orm=services.orm;this.store=services["mail.store"];this.sequential=useSequential();this._sQueue=markRaw({todo:new Set(),});}
async updateGuestName(guest,name){await this.rpc("/mail/guest/update_name",{guest_id:guest.id,name,});}
async fetchIsCompany(persona){if(persona.type!=="partner"){persona.is_company=false;return;}
this._sQueue.todo.add(persona.id);await new Promise(setTimeout);await this.sequential(async()=>{const ongoing=new Set();if(this._sQueue.todo.size===0){return;}
this._sQueue.todo.forEach((id)=>ongoing.add(id));this._sQueue.todo.clear();const partnerData=await this.orm.silent.read("res.partner",[...ongoing],["is_company"],{context:{active_test:false},});for(const{id,is_company}of partnerData){this.store.Persona.insert({id,is_company,type:"partner"});ongoing.delete(id);this._sQueue.todo.delete(id);}
for(const id of ongoing){this.store.Persona.insert({id,is_company:false,type:"partner"});this._sQueue.todo.delete(id);}});}
getRecentChatPartnerIds(){return Object.values(this.store.Thread.records).filter((thread)=>thread.type==="chat").sort((a,b)=>compareDatetime(b.lastInterestDateTime,a.lastInterestDateTime)||b.id-a.id).map((thread)=>thread.chatPartner?.id);}}
const personaService=__exports.personaService={dependencies:["orm","rpc","mail.store"],start(env,services){return new PersonaService(env,services);},};registry.category("services").add("mail.persona",personaService);return __exports;});;

/* /mail/static/src/core/common/picker.js */
odoo.define('@mail/core/common/picker',['@odoo/owl','@web/core/browser/browser','@web/core/utils/misc','@web/core/popover/popover_hook','@web/core/utils/hooks','@mail/core/common/picker_content','@mail/utils/common/hooks'],function(require){'use strict';let __exports={};const{Component,useExternalListener,useState}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{isEventHandled}=require("@web/core/utils/misc");const{usePopover}=require("@web/core/popover/popover_hook");const{useService}=require("@web/core/utils/hooks");const{PickerContent}=require("@mail/core/common/picker_content");const{useLazyExternalListener}=require("@mail/utils/common/hooks");__exports.usePicker=usePicker;function usePicker(setting){const storeScroll={scrollValue:0,set:(value)=>(storeScroll.scrollValue=value),get:()=>storeScroll.scrollValue,};const PICKERS={NONE:"none",EMOJI:"emoji",GIF:"gif",};return useState({PICKERS,anchor:setting.anchor,buttons:setting.buttons,close:setting.close,pickers:setting.pickers,position:setting.position,state:{picker:PICKERS.NONE,searchTerm:"",},storeScroll,});}
const Picker=__exports.Picker=class Picker extends Component{static components={PickerContent,};static props=["PICKERS","anchor?","buttons","close?","state","pickers","position?","storeScroll",];static template="mail.Picker";setup(){this.ui=useState(useService("ui"));this.popover=usePopover(PickerContent,{position:this.props.position,fixedPosition:true,onClose:()=>this.close(),closeOnClickAway:false,animation:false,arrow:false,});useExternalListener(browser,"click",async(ev)=>{if(this.props.state.picker===this.props.PICKERS.NONE){return;}
await new Promise(setTimeout);if(!this.isEventHandledByPicker(ev)){this.close();}},true);for(const button of this.props.buttons){useLazyExternalListener(()=>button.el,"click",async(ev)=>this.toggle(this.props.anchor?.el??button.el,ev));}}
get contentProps(){const pickers={};for(const[name,fn]of Object.entries(this.props.pickers)){pickers[name]=(str,resetOnSelect)=>{fn(str);if(resetOnSelect){this.close();}};}
return{PICKERS:this.props.PICKERS,close:()=>this.close(),pickers,state:this.props.state,storeScroll:this.props.storeScroll,};}
isEventHandledByPicker(ev){return(isEventHandled(ev,"Composer.onClickAddEmoji")||isEventHandled(ev,"PickerContent.onClick"));}
async toggle(el,ev){await new Promise(setTimeout);if(this.ui.isSmall){if(this.props.state.picker===this.props.PICKERS.NONE){this.props.state.picker=this.props.PICKERS.EMOJI;}else{this.props.state.picker=this.props.PICKERS.NONE;}
return;}
if(isEventHandled(ev,"Composer.onClickAddEmoji")){if(this.popover.isOpen){if(this.props.state.picker===this.props.PICKERS.EMOJI){this.props.state.picker=this.props.PICKERS.NONE;this.popover.close();return;}
this.props.state.picker=this.props.PICKERS.EMOJI;}else{this.props.state.picker=this.props.PICKERS.EMOJI;this.popover.open(el,this.contentProps);}}}
close(){this.props.close?.();this.popover.close();this.props.state.picker=this.props.PICKERS.NONE;this.props.state.searchTerm="";}}
return __exports;});;

/* /mail/static/src/core/common/picker_content.js */
odoo.define('@mail/core/common/picker_content',['@odoo/owl','@web/core/utils/misc','@web/core/emoji_picker/emoji_picker'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{markEventHandled}=require("@web/core/utils/misc");const{EmojiPicker}=require("@web/core/emoji_picker/emoji_picker");const PickerContent=__exports.PickerContent=class PickerContent extends Component{static components={EmojiPicker};static props=["PICKERS","close","pickers","state","storeScroll"];static template="mail.PickerContent";onClick(ev){markEventHandled(ev,"PickerContent.onClick");}}
return __exports;});;

/* /mail/static/src/core/common/record.js */
odoo.define('@mail/core/common/record',['@mail/utils/common/misc','@odoo/owl','@web/core/registry'],function(require){'use strict';let __exports={};const{onChange}=require("@mail/utils/common/misc");const{markRaw,markup,reactive,toRaw}=require("@odoo/owl");const{registry}=require("@web/core/registry");const modelRegistry=__exports.modelRegistry=registry.category("discuss.model");const Markup=markup("").constructor;const ATTR_SYM=Symbol("attr");const MANY_SYM=Symbol("many");const ONE_SYM=Symbol("one");const OR_SYM=Symbol("or");const AND_SYM=Symbol("and");const IS_RECORD_SYM=Symbol("isRecord");const IS_FIELD_SYM=Symbol("isField");__exports.AND=AND;function AND(...args){return[AND_SYM,...args];}
__exports.OR=OR;function OR(...args){return[OR_SYM,...args];}
function updateFields(record,vals){for(const[fieldName,value]of Object.entries(vals)){if(record instanceof BaseStore&&record.storeReady&&fieldName in record.Models){record[fieldName].insert(value);}else{const fieldDefinition=record.Model._fields.get(fieldName);if(!fieldDefinition||Record.isAttr(fieldDefinition)){updateAttr(record,fieldName,value);}else{updateRelation(record,fieldName,value);}}}}
function updateAttr(record,fieldName,value){const fieldDefinition=record.Model._fields.get(fieldName);const targetRecord=record._proxyUsed.has(fieldName)?record:record._proxy;let shouldChange=record[fieldName]!==value;let newValue=value;if(fieldDefinition?.html&&Record.trusted){shouldChange=record[fieldName]?.toString()!==value?.toString()||!(record[fieldName]instanceof Markup);newValue=typeof value==="string"?markup(value):value;}
if(shouldChange){record._updateFields.add(fieldName);targetRecord[fieldName]=newValue;record._updateFields.delete(fieldName);}}
function updateRelation(record,fieldName,value){const recordList=record._fields.get(fieldName).value;if(RecordList.isMany(recordList)){updateRelationMany(recordList,value);}else{updateRelationOne(recordList,value);}}
function updateRelationMany(recordList,value){if(Record.isCommand(value)){for(const[cmd,cmdData]of value){if(Array.isArray(cmdData)){for(const item of cmdData){if(cmd==="ADD"){recordList.add(item);}else if(cmd==="ADD.noinv"){recordList._addNoinv(item);}else if(cmd==="DELETE.noinv"){recordList._deleteNoinv(item);}else{recordList.delete(item);}}}else{if(cmd==="ADD"){recordList.add(cmdData);}else if(cmd==="ADD.noinv"){recordList._addNoinv(cmdData);}else if(cmd==="DELETE.noinv"){recordList._deleteNoinv(cmdData);}else{recordList.delete(cmdData);}}}}else if([null,false,undefined].includes(value)){recordList.clear();}else if(!Array.isArray(value)){recordList.assign([value]);}else{recordList.assign(value);}}
function updateRelationOne(recordList,value){if(Record.isCommand(value)){const[cmd,cmdData]=value.at(-1);if(cmd==="ADD"){recordList.add(cmdData);}else if(cmd==="ADD.noinv"){recordList._addNoinv(cmdData);}else if(cmd==="DELETE.noinv"){recordList._deleteNoinv(cmdData);}else{recordList.delete(cmdData);}}else if([null,false,undefined].includes(value)){recordList.clear();}else{recordList.add(value);}}
function sortRecordList(recordListFullProxy,func){const recordList=toRaw(recordListFullProxy)._raw;const recordsFullProxy=recordListFullProxy.data.map((localId)=>recordListFullProxy.store.recordByLocalId.get(localId));recordsFullProxy.sort(func);const data=recordsFullProxy.map((recordFullProxy)=>toRaw(recordFullProxy)._raw.localId);const hasChanged=recordList.data.some((localId,i)=>localId!==data[i]);if(hasChanged){recordListFullProxy.data=data;}}
__exports.makeStore=makeStore;function makeStore(env){Record.UPDATE=0;const recordByLocalId=reactive(new Map());const res={store:{env,get:(...args)=>BaseStore.prototype.get.call(this,...args),recordByLocalId,},};const Models={};for(const[name,_OgClass]of modelRegistry.getEntries()){const OgClass=_OgClass;if(res.store[name]){throw new Error(`There must be no duplicated Model Names (duplicate found: ${name})`);}
const Model=Object.create(OgClass);const Class={[OgClass.name]:class extends OgClass{[IS_RECORD_SYM]=true;constructor(){super();const record=this;record._proxyUsed=new Set();record._updateFields=new Set();record._raw=record;record.Model=Model;const recordProxyInternal=new Proxy(record,{get(record,name,recordFullProxy){recordFullProxy=record._downgradeProxy(recordFullProxy);const field=record._fields.get(name);if(field){if(field.compute&&!field.eager){field.computeInNeed=true;if(field.computeOnNeed){field.compute();}}
if(field.sort&&!field.eager){field.sortInNeed=true;if(field.sortOnNeed){field.sort();}}
if(Record.isRelation(field)){const recordList=field.value;const recordListFullProxy=recordFullProxy._fields.get(name).value._proxy;if(RecordList.isMany(recordList)){return recordListFullProxy;}
return recordListFullProxy[0];}}
return Reflect.get(record,name,recordFullProxy);},deleteProperty(record,name){return Record.MAKE_UPDATE(function recordDeleteProperty(){const field=record._fields.get(name);if(field&&Record.isRelation(field)){const recordList=field.value;recordList.clear();return true;}
return Reflect.deleteProperty(record,name);});},set(record,name,val){if(record._updateFields.has(name)){record[name]=val;return true;}
return Record.MAKE_UPDATE(function recordSet(){record._proxyUsed.add(name);updateFields(record,{[name]:val});record._proxyUsed.delete(name);return true;});},});record._proxyInternal=recordProxyInternal;const recordProxy=reactive(recordProxyInternal);record._proxy=recordProxy;if(record instanceof BaseStore){res.store=record;}
for(const[name,fieldDefinition]of Model._fields){const SYM=record[name]?.[0];const field={[SYM]:true,eager:fieldDefinition.eager,name};record._fields.set(name,field);if(Record.isRelation(SYM)){const recordList=new RecordList();Object.assign(recordList,{[SYM]:true,field,name,owner:record,_raw:recordList,});recordList.store=res.store;field.value=recordList;}else{record[name]=fieldDefinition.default;}
if(fieldDefinition.compute){if(!fieldDefinition.eager){onChange(recordProxy,name,()=>{if(field.computing){field.computeInNeed=false;}});field.computeInNeed=false;field.sortInNeed=false;}
const proxy2=reactive(recordProxy,function computeObserver(){field.requestCompute();});Object.assign(field,{compute:()=>{field.computing=true;field.computeOnNeed=false;updateFields(record,{[name]:fieldDefinition.compute.call(proxy2),});field.computing=false;},requestCompute:({force=false}={})=>{if(Record.UPDATE!==0&&!force){Record.ADD_QUEUE(field,"compute");}else{if(field.eager||field.computeInNeed){field.compute();}else{field.computeOnNeed=true;}}},});}
if(fieldDefinition.sort){if(!fieldDefinition.eager){onChange(recordProxy,name,()=>{if(field.sorting){field.sortInNeed=false;}});field.computeInNeed=false;field.sortInNeed=false;}
const proxy2=reactive(recordProxy,function sortObserver(){field.requestSort();});Object.assign(field,{sort:()=>{field.sortOnNeed=false;field.sorting=true;sortRecordList(proxy2._fields.get(name).value._proxy,fieldDefinition.sort.bind(proxy2));field.sorting=false;},requestSort:({force}={})=>{if(Record.UPDATE!==0&&!force){Record.ADD_QUEUE(field,"sort");}else{if(field.eager||field.sortInNeed){field.sort();}else{field.sortOnNeed=true;}}},});}
if(fieldDefinition.onUpdate){let observe;Object.assign(field,{onUpdate:()=>{fieldDefinition.onUpdate.call(record._proxyInternal);observe?.();},});Record._onChange(recordProxy,name,(obs)=>{observe=obs;if(Record.UPDATE!==0){Record.ADD_QUEUE(field,"onUpdate");}else{field.onUpdate();}});}}
return recordProxy;}},}[OgClass.name];Object.assign(Model,{Class,env,records:reactive({}),_fields:new Map(),});Models[name]=Model;res.store[name]=Model;const obj=new OgClass();for(const[name,val]of Object.entries(obj)){const SYM=val?.[0];if(!Record.isField(SYM)){continue;}
Model._fields.set(name,{[IS_FIELD_SYM]:true,[SYM]:true,...val[1]});}}
for(const Model of Object.values(Models)){for(const[name,fieldDefinition]of Model._fields){if(!Record.isRelation(fieldDefinition)){continue;}
const{targetModel,inverse}=fieldDefinition;if(targetModel&&!Models[targetModel]){throw new Error(`No target model ${targetModel} exists`);}
if(inverse){const rel2=Models[targetModel]._fields.get(inverse);if(rel2.targetModel&&rel2.targetModel!==Model.name){throw new Error(`Fields ${Models[targetModel].name}.${inverse} has wrong targetModel. Expected: "${Model.name}" Actual: "${rel2.targetModel}"`);}
if(rel2.inverse&&rel2.inverse!==name){throw new Error(`Fields ${Models[targetModel].name}.${inverse} has wrong inverse. Expected: "${name}" Actual: "${rel2.inverse}"`);}
Object.assign(rel2,{targetModel:Model.name,inverse:name});fieldDefinition.eager=true;rel2.eager=true;}}}
Object.assign(res.store.Store,{store:res.store,_rawStore:res.store});res.store=toRaw(res.store.Store.insert())._raw;for(const Model of Object.values(Models)){Model._rawStore=res.store;Model.store=res.store._proxy;res.store._proxy[Model.name]=Model;}
Object.assign(res.store,{Models,storeReady:true});return res.store._proxy;}
class RecordUses{data=new Map();add(list){const record=list.owner;if(!this.data.has(record.localId)){this.data.set(record.localId,new Map());}
const use=this.data.get(record.localId);if(!use.get(list.name)){use.set(list.name,0);}
use.set(list.name,use.get(list.name)+1);}
delete(list){const record=list.owner;if(!this.data.has(record.localId)){return;}
const use=this.data.get(record.localId);if(!use.get(list.name)){return;}
use.set(list.name,use.get(list.name)-1);if(use.get(list.name)===0){use.delete(list.name);}}}
class RecordList extends Array{static isOne(list){return Boolean(list?.[ONE_SYM]);}
static isMany(list){return Boolean(list?.[MANY_SYM]);}
owner;name;store;data=[];get fieldDefinition(){return this.owner.Model._fields.get(this.name);}
constructor(){super();const recordList=this;recordList._raw=recordList;const recordListProxyInternal=new Proxy(recordList,{get(recordList,name,recordListFullProxy){recordListFullProxy=recordList._downgradeProxy(recordListFullProxy);if(typeof name==="symbol"||Object.keys(recordList).includes(name)||Object.prototype.hasOwnProperty.call(recordList.constructor.prototype,name)){return Reflect.get(recordList,name,recordListFullProxy);}
if(recordList.field?.compute&&!recordList.field.eager){recordList.field.computeInNeed=true;if(recordList.field.computeOnNeed){recordList.field.compute();}}
if(name==="length"){return recordListFullProxy.data.length;}
if(recordList.field?.sort&&!recordList.field.eager){recordList.field.sortInNeed=true;if(recordList.field.sortOnNeed){recordList.field.sort();}}
if(typeof name!=="symbol"&&!window.isNaN(parseInt(name))){const index=parseInt(name);return recordListFullProxy.store.recordByLocalId.get(recordListFullProxy.data[index]);}
const array=[...recordList._proxyInternal[Symbol.iterator].call(recordListFullProxy),];return array[name]?.bind(array);},set(recordList,name,val,recordListProxy){return Record.MAKE_UPDATE(function recordListSet(){if(typeof name!=="symbol"&&!window.isNaN(parseInt(name))){const index=parseInt(name);recordList._insert(val,function recordListSet_Insert(newRecord){const oldRecord=toRaw(recordList.store.recordByLocalId).get(recordList.data[index]);if(oldRecord&&oldRecord.notEq(newRecord)){oldRecord.__uses__.delete(recordList);}
Record.ADD_QUEUE(recordList.field,"onDelete",oldRecord);const{inverse}=recordList.fieldDefinition;if(inverse){oldRecord._fields.get(inverse).value.delete(recordList);}
recordListProxy.data[index]=newRecord?.localId;if(newRecord){newRecord.__uses__.add(recordList);Record.ADD_QUEUE(recordList.field,"onAdd",newRecord);const{inverse}=recordList.fieldDefinition;if(inverse){newRecord._fields.get(inverse).value.add(recordList);}}});}else if(name==="length"){const newLength=parseInt(val);if(newLength!==recordList.data.length){if(newLength<recordList.data.length){recordList.splice.call(recordListProxy,newLength,recordList.length-newLength);}
recordListProxy.data.length=newLength;}}else{return Reflect.set(recordList,name,val,recordListProxy);}
return true;});},});recordList._proxyInternal=recordListProxyInternal;recordList._proxy=reactive(recordListProxyInternal);return recordList;}
_downgradeProxy(fullProxy){return this._proxy===fullProxy?this._proxyInternal:fullProxy;}
_insert(val,fn,{inv=true,mode="ADD"}={}){const recordList=this;const{inverse}=recordList.fieldDefinition;if(inverse&&inv){val[inverse]=[[mode==="ADD"?"ADD.noinv":"DELETE.noinv",recordList.owner]];}
let newRecordProxy;if(!Record.isRecord(val)){const{targetModel}=recordList.fieldDefinition;newRecordProxy=recordList.store[targetModel].preinsert(val);}else{newRecordProxy=val;}
const newRecord=toRaw(newRecordProxy)._raw;fn?.(newRecord);if(!Record.isRecord(val)){const{targetModel}=recordList.fieldDefinition;recordList.store[targetModel].insert(val);}
return newRecord;}
assign(data){const recordList=toRaw(this)._raw;return Record.MAKE_UPDATE(function recordListAssign(){const collection=Record.isRecord(data)?[data]:data;const vals=[...collection];const oldRecords=recordList._proxyInternal.slice.call(recordList._proxy).map((recordProxy)=>toRaw(recordProxy)._raw);const newRecords=vals.map((val)=>recordList._insert(val,function recordListAssignInsert(record){if(record.notIn(oldRecords)){record.__uses__.add(recordList);Record.ADD_QUEUE(recordList.field,"onAdd",record);}}));const inverse=recordList.fieldDefinition.inverse;for(const oldRecord of oldRecords){if(oldRecord.notIn(newRecords)){oldRecord.__uses__.delete(recordList);Record.ADD_QUEUE(recordList.field,"onDelete",oldRecord);if(inverse){oldRecord._fields.get(inverse).value.delete(recordList.owner);}}}
recordList._proxy.data=newRecords.map((newRecord)=>newRecord.localId);});}
push(...records){const recordList=toRaw(this)._raw;const recordListFullProxy=recordList._downgradeProxy(this);return Record.MAKE_UPDATE(function recordListPush(){for(const val of records){const record=recordList._insert(val,function recordListPushInsert(record){recordList._proxy.data.push(record.localId);record.__uses__.add(recordList);});Record.ADD_QUEUE(recordList.field,"onAdd",record);const{inverse}=recordList.fieldDefinition;if(inverse){record._fields.get(inverse).value.add(recordList.owner);}}
return recordListFullProxy.data.length;});}
pop(){const recordList=toRaw(this)._raw;const recordListFullProxy=recordList._downgradeProxy(this);return Record.MAKE_UPDATE(function recordListPop(){const oldRecordProxy=recordListFullProxy.at(-1);if(oldRecordProxy){recordList.splice.call(recordListFullProxy,recordListFullProxy.length-1,1);}
return oldRecordProxy;});}
shift(){const recordList=toRaw(this)._raw;const recordListFullProxy=recordList._downgradeProxy(this);return Record.MAKE_UPDATE(function recordListShift(){const recordProxy=recordListFullProxy.store.recordByLocalId.get(recordListFullProxy.data.shift());if(!recordProxy){return;}
const record=toRaw(recordProxy)._raw;record.__uses__.delete(recordList);Record.ADD_QUEUE(recordList.field,"onDelete",record);const{inverse}=recordList.fieldDefinition;if(inverse){record._fields.get(inverse).value.delete(recordList.owner);}
return recordProxy;});}
unshift(...records){const recordList=toRaw(this)._raw;const recordListFullProxy=recordList._downgradeProxy(this);return Record.MAKE_UPDATE(function recordListUnshift(){for(let i=records.length-1;i>=0;i--){const record=recordList._insert(records[i],(record)=>{recordList._proxy.data.unshift(record.localId);record.__uses__.add(recordList);});Record.ADD_QUEUE(recordList.field,"onAdd",record);const{inverse}=recordList.fieldDefinition;if(inverse){record._fields.get(inverse).value.add(recordList.owner);}}
return recordListFullProxy.data.length;});}
indexOf(recordProxy){const recordList=toRaw(this)._raw;const recordListFullProxy=recordList._downgradeProxy(this);return recordListFullProxy.data.indexOf(toRaw(recordProxy)?._raw.localId);}
splice(start,deleteCount,...newRecordsProxy){const recordList=toRaw(this)._raw;const recordListFullProxy=recordList._downgradeProxy(this);return Record.MAKE_UPDATE(function recordListSplice(){const oldRecordsProxy=recordList._proxyInternal.slice.call(recordListFullProxy,start,start+deleteCount);const list=recordListFullProxy.data.slice();list.splice(start,deleteCount,...newRecordsProxy.map((newRecordProxy)=>toRaw(newRecordProxy)._raw.localId));recordList._proxy.data=list;for(const oldRecordProxy of oldRecordsProxy){const oldRecord=toRaw(oldRecordProxy)._raw;oldRecord.__uses__.delete(recordList);Record.ADD_QUEUE(recordList.field,"onDelete",oldRecord);const{inverse}=recordList.fieldDefinition;if(inverse){oldRecord._fields.get(inverse).value.delete(recordList.owner);}}
for(const newRecordProxy of newRecordsProxy){const newRecord=toRaw(newRecordProxy)._raw;newRecord.__uses__.add(recordList);Record.ADD_QUEUE(recordList.field,"onAdd",newRecord);const{inverse}=recordList.fieldDefinition;if(inverse){newRecord._fields.get(inverse).value.add(recordList.owner);}}});}
sort(func){const recordList=toRaw(this)._raw;const recordListFullProxy=recordList._downgradeProxy(this);return Record.MAKE_UPDATE(function recordListSort(){sortRecordList(recordListFullProxy,func);return recordListFullProxy;});}
concat(...collections){const recordList=toRaw(this)._raw;const recordListFullProxy=recordList._downgradeProxy(this);return recordListFullProxy.data.map((localId)=>recordListFullProxy.store.recordByLocalId.get(localId)).concat(...collections.map((c)=>[...c]));}
add(...records){const recordList=toRaw(this)._raw;return Record.MAKE_UPDATE(function recordListAdd(){if(RecordList.isOne(recordList)){const last=records.at(-1);if(Record.isRecord(last)&&recordList.data.includes(toRaw(last)._raw.localId)){return;}
recordList._insert(last,function recordListAddInsertOne(record){if(record.localId!==recordList.data[0]){recordList.pop.call(recordList._proxy);recordList.push.call(recordList._proxy,record);}});return;}
for(const val of records){if(Record.isRecord(val)&&recordList.data.includes(val.localId)){continue;}
recordList._insert(val,function recordListAddInsertMany(record){if(recordList.data.indexOf(record.localId)===-1){recordList.push.call(recordList._proxy,record);}});}});}
_addNoinv(...records){const recordList=this;if(RecordList.isOne(recordList)){const last=records.at(-1);if(Record.isRecord(last)&&last.in(recordList)){return;}
const record=recordList._insert(last,function recordList_AddNoInvOneInsert(record){if(record.localId!==recordList.data[0]){const old=recordList._proxy.at(-1);recordList._proxy.data.pop();old?.__uses__.delete(recordList);recordList._proxy.data.push(record.localId);record.__uses__.add(recordList);}},{inv:false});Record.ADD_QUEUE(recordList.field,"onAdd",record);return;}
for(const val of records){if(Record.isRecord(val)&&val.in(recordList)){continue;}
const record=recordList._insert(val,function recordList_AddNoInvManyInsert(record){if(recordList.data.indexOf(record.localId)===-1){recordList.push.call(recordList._proxy,record);record.__uses__.add(recordList);}},{inv:false});Record.ADD_QUEUE(recordList.field,"onAdd",record);}}
delete(...records){const recordList=toRaw(this)._raw;return Record.MAKE_UPDATE(function recordListDelete(){for(const val of records){recordList._insert(val,function recordListDelete_Insert(record){const index=recordList.data.indexOf(record.localId);if(index!==-1){recordList.splice.call(recordList._proxy,index,1);}},{mode:"DELETE"});}});}
_deleteNoinv(...records){const recordList=this;for(const val of records){const record=recordList._insert(val,function recordList_DeleteNoInv_Insert(record){const index=recordList.data.indexOf(record.localId);if(index!==-1){recordList.splice.call(recordList._proxy,index,1);record.__uses__.delete(recordList);}},{inv:false});Record.ADD_QUEUE(recordList.field,"onDelete",record);}}
clear(){const recordList=toRaw(this)._raw;return Record.MAKE_UPDATE(function recordListClear(){while(recordList.data.length>0){recordList.pop.call(recordList._proxy);}});}*[Symbol.iterator](){const recordList=toRaw(this)._raw;const recordListFullProxy=recordList._downgradeProxy(this);for(const localId of recordListFullProxy.data){yield recordListFullProxy.store.recordByLocalId.get(localId);}}}
const Record=__exports.Record=class Record{static isAttr(definition){return Boolean(definition?.[ATTR_SYM]);}
static trusted=false;static id;static records;static store;static FC_QUEUE=new Set();static FS_QUEUE=[];static FA_QUEUE=[];static FD_QUEUE=[];static FU_QUEUE=[];static RO_QUEUE=[];static RD_QUEUE=[];static UPDATE=0;static MAKE_UPDATE(fn){Record.UPDATE++;const res=fn();Record.UPDATE--;if(Record.UPDATE===0){Record.UPDATE++;while(Record.FC_QUEUE.size>0||Record.FS_QUEUE.length>0||Record.FA_QUEUE.length>0||Record.FD_QUEUE.length>0||Record.FU_QUEUE.length>0||Record.RO_QUEUE.length>0||Record.RD_QUEUE.length>0){const FC_QUEUE=new Set([...Record.FC_QUEUE]);const FS_QUEUE=[...Record.FS_QUEUE];const FA_QUEUE=[...Record.FA_QUEUE];const FD_QUEUE=[...Record.FD_QUEUE];const FU_QUEUE=[...Record.FU_QUEUE];const RO_QUEUE=[...Record.RO_QUEUE];const RD_QUEUE=[...Record.RD_QUEUE];Record.FC_QUEUE.clear();Record.FS_QUEUE.length=0;Record.FA_QUEUE.length=0;Record.FD_QUEUE.length=0;Record.FU_QUEUE.length=0;Record.RO_QUEUE.length=0;Record.RD_QUEUE.length=0;while(FC_QUEUE.size>0){const[field]=FC_QUEUE.entries().next().value;FC_QUEUE.delete(field);field.requestCompute({force:true});}
while(FS_QUEUE.length>0){const field=FS_QUEUE.pop();field.requestSort({force:true});}
while(FA_QUEUE.length>0){const{field,records}=FA_QUEUE.pop();const{onAdd}=field.value.fieldDefinition;records.forEach((record)=>onAdd?.call(field.value.owner._proxy,record._proxy));}
while(FD_QUEUE.length>0){const{field,records}=FD_QUEUE.pop();const{onDelete}=field.value.fieldDefinition;records.forEach((record)=>onDelete?.call(field.value.owner._proxy,record._proxy));}
while(FU_QUEUE.length>0){const field=FU_QUEUE.pop();field.onUpdate();}
while(RO_QUEUE.length>0){const cb=RO_QUEUE.pop();cb();}
while(RD_QUEUE.length>0){const record=RD_QUEUE.pop();for(const name of record._fields.keys()){record[name]=undefined;}
for(const[localId,names]of record.__uses__.data.entries()){for(const[name2,count]of names.entries()){const usingRecordProxy=toRaw(record.Model._rawStore.recordByLocalId).get(localId);if(!usingRecordProxy){record.__uses__.data.delete(localId);continue;}
const usingRecordList=toRaw(usingRecordProxy)._raw._fields.get(name2).value;if(RecordList.isMany(usingRecordList)){for(let c=0;c<count;c++){usingRecordProxy[name2].delete(record);}}else{usingRecordProxy[name2]=undefined;}}}
delete record.Model.records[record.localId];record.Model._rawStore.recordByLocalId.delete(record.localId);}}
Record.UPDATE--;}
return res;}
static ADD_QUEUE(fieldOrRecord,type,record){if(Record.isRecord(fieldOrRecord)){const record=fieldOrRecord;if(type==="delete"){if(!Record.RD_QUEUE.includes(record)){Record.RD_QUEUE.push(record);}}}else{const field=fieldOrRecord;const rawField=toRaw(field);if(type==="compute"){if(!Record.FC_QUEUE.has(rawField)){Record.FC_QUEUE.add(rawField);}}
if(type==="sort"){if(!rawField.value?.fieldDefinition.sort){return;}
if(!Record.FS_QUEUE.some((f)=>toRaw(f)===rawField)){Record.FS_QUEUE.push(field);}}
if(type==="onAdd"){if(rawField.value?.fieldDefinition.sort){Record.ADD_QUEUE(fieldOrRecord,"sort");}
if(!rawField.value?.fieldDefinition.onAdd){return;}
const item=Record.FA_QUEUE.find((item)=>toRaw(item.field)===rawField);if(!item){Record.FA_QUEUE.push({field,records:[record]});}else{if(!item.records.some((recordProxy)=>recordProxy.eq(record))){item.records.push(record);}}}
if(type==="onDelete"){if(!rawField.value?.fieldDefinition.onDelete){return;}
const item=Record.FD_QUEUE.find((item)=>toRaw(item.field)===rawField);if(!item){Record.FD_QUEUE.push({field,records:[record]});}else{if(!item.records.some((recordProxy)=>recordProxy.eq(record))){item.records.push(record);}}}
if(type==="onUpdate"){if(!Record.FU_QUEUE.some((f)=>toRaw(f)===rawField)){Record.FU_QUEUE.push(field);}}}}
static onChange(record,name,cb){return Record._onChange(record,name,(observe)=>{const fn=()=>{observe();cb();};if(Record.UPDATE!==0){if(!Record.RO_QUEUE.some((f)=>toRaw(f)===fn)){Record.RO_QUEUE.push(fn);}}else{fn();}});}
static _onChange(record,key,callback){let proxy;function _observe(){const val=proxy[key];if(typeof val==="object"&&val!==null){void Object.keys(val);}
if(Array.isArray(val)){void val.length;void toRaw(val).forEach.call(val,(i)=>i);}}
if(Array.isArray(key)){for(const k of key){Record._onChange(record,k,callback);}
return;}
let ready=true;proxy=reactive(record,()=>{if(ready){callback(_observe);}});_observe();return()=>{ready=false;};}
static _fields;static isRecord(record){return Boolean(record?.[IS_RECORD_SYM]);}
static isRelation(val){if([MANY_SYM,ONE_SYM].includes(val)){return true;}
return RecordList.isOne(val)||RecordList.isMany(val);}
static isField(SYM){return[MANY_SYM,ONE_SYM,ATTR_SYM].includes(SYM);}
static get(data){const Model=toRaw(this);return this.records[Model.localId(data)];}
static register(){modelRegistry.add(this.name,this);}
static localId(data){const Model=toRaw(this);let idStr;if(typeof data==="object"&&data!==null){idStr=Model._localId(Model.id,data);}else{idStr=data;}
return`${Model.name},${idStr}`;}
static _localId(expr,data,{brackets=false}={}){const Model=toRaw(this);if(!Array.isArray(expr)){const fieldDefinition=Model._fields.get(expr);if(fieldDefinition){if(RecordList.isMany(fieldDefinition)){throw new Error("Using a Record.Many() as id is not (yet) supported");}
if(!Record.isRelation(fieldDefinition)){return data[expr];}
if(Record.isCommand(data[expr])){const[cmd,data2]=data[expr].at(-1);if(cmd==="DELETE"){return undefined;}else{return`(${data2?.localId})`;}}
return`(${data[expr]?.localId})`;}
return data[expr];}
const vals=[];for(let i=1;i<expr.length;i++){vals.push(Model._localId(expr[i],data,{brackets:true}));}
let res=vals.join(expr[0]===OR_SYM?" OR ":" AND ");if(brackets){res=`(${res})`;}
return res;}
static _retrieveIdFromData(data){const Model=toRaw(this);const res={};function _deepRetrieve(expr2){if(typeof expr2==="string"){if(Record.isCommand(data[expr2])){const[cmd,data2]=data[expr2].at(-1);return Object.assign(res,{[expr2]:cmd==="DELETE"?undefined:cmd==="DELETE.noinv"?[["DELETE.noinv",data2]]:cmd==="ADD.noinv"?[["ADD.noinv",data2]]:data2,});}
return Object.assign(res,{[expr2]:data[expr2]});}
if(expr2 instanceof Array){for(const expr of this.id){if(typeof expr==="symbol"){continue;}
_deepRetrieve(expr);}}}
if(Model.id===undefined){return res;}
if(typeof Model.id==="string"){if(typeof data!=="object"||data===null){return{[Model.id]:data};}
if(Record.isCommand(data[Model.id])){const[cmd,data2]=data[Model.id].at(-1);return Object.assign(res,{[Model.id]:cmd==="DELETE"?undefined:cmd==="DELETE.noinv"?[["DELETE.noinv",data2]]:cmd==="ADD.noinv"?[["ADD.noinv",data2]]:data2,});}
return{[Model.id]:data[Model.id]};}
for(const expr of Model.id){if(typeof expr==="symbol"){continue;}
_deepRetrieve(expr);}
return res;}
static Class;static new(data){const Model=toRaw(this);return Record.MAKE_UPDATE(function RecordNew(){const recordProxy=new Model.Class();const record=toRaw(recordProxy)._raw;const ids=Model._retrieveIdFromData(data);for(const name in ids){if(ids[name]&&!Record.isRecord(ids[name])&&!Record.isCommand(ids[name])&&Record.isRelation(Model._fields.get(name))){ids[name]=Model._rawStore[Model._fields.get(name).targetModel].preinsert(ids[name]);}}
Object.assign(record,{localId:Model.localId(ids)});Object.assign(recordProxy,{...ids});Model.records[record.localId]=recordProxy;if(record.Model.name==="Store"){Object.assign(record,{env:Model._rawStore.env,recordByLocalId:Model._rawStore.recordByLocalId,});}
Model._rawStore.recordByLocalId.set(record.localId,recordProxy);for(const field of record._fields.values()){field.requestCompute?.();field.requestSort?.();}
return recordProxy;});}
static one(targetModel,{compute,eager=false,inverse,onAdd,onDelete,onUpdate}={}){return[ONE_SYM,{targetModel,compute,eager,inverse,onAdd,onDelete,onUpdate}];}
static many(targetModel,{compute,eager=false,inverse,onAdd,onDelete,onUpdate,sort}={}){return[MANY_SYM,{targetModel,compute,eager,inverse,onAdd,onDelete,onUpdate,sort},];}
static attr(def,{compute,eager=false,html,onUpdate}={}){return[ATTR_SYM,{compute:compute,default:def,eager,html,onUpdate}];}
static insert(data,options={}){const ModelFullProxy=this;const Model=toRaw(ModelFullProxy);return Record.MAKE_UPDATE(function RecordInsert(){const isMulti=Array.isArray(data);if(!isMulti){data=[data];}
const oldTrusted=Record.trusted;Record.trusted=options.html??Record.trusted;const res=data.map(function RecordInsertMap(d){return Model._insert.call(ModelFullProxy,d,options);});Record.trusted=oldTrusted;if(!isMulti){return res[0];}
return res;});}
static _insert(data){const ModelFullProxy=this;const Model=toRaw(ModelFullProxy);const recordFullProxy=Model.preinsert.call(ModelFullProxy,data);const record=toRaw(recordFullProxy)._raw;record.update.call(record._proxy,data);return recordFullProxy;}
static preinsert(data){const ModelFullProxy=this;const Model=toRaw(ModelFullProxy);return Model.get.call(ModelFullProxy,data)??Model.new(data);}
static isCommand(data){return["ADD","DELETE","ADD.noinv","DELETE.noinv"].includes(data?.[0]?.[0]);}
_fields=new Map();__uses__=markRaw(new RecordUses());get _store(){return toRaw(this)._raw.Model._rawStore._proxy;}
Model;localId;constructor(){this.setup();}
setup(){}
update(data){const record=toRaw(this)._raw;return Record.MAKE_UPDATE(function recordUpdate(){if(typeof data==="object"&&data!==null){updateFields(record,data);}else{updateFields(record,{[record.Model.id]:data});}});}
delete(){const record=toRaw(this)._raw;return Record.MAKE_UPDATE(function recordDelete(){Record.ADD_QUEUE(record,"delete");});}
eq(record){return toRaw(this)._raw===toRaw(record)?._raw;}
notEq(record){return!this.eq(record);}
in(collection){if(!collection){return false;}
if(collection instanceof RecordList){return collection.includes(this);}
return collection.some((record)=>toRaw(record)._raw.eq(this));}
notIn(collection){return!this.in(collection);}
toData(){const recordProxy=this;const record=toRaw(recordProxy)._raw;const data={...recordProxy};for(const[name,{value}]of record._fields){if(RecordList.isMany(value)){data[name]=value.map((recordProxy)=>{const record=toRaw(recordProxy)._raw;return record.toIdData.call(record._proxyInternal);});}else if(RecordList.isOne(value)){const record=toRaw(value[0])?._raw;data[name]=record?.toIdData.call(record._proxyInternal);}else{data[name]=recordProxy[name];}}
delete data._fields;delete data._proxy;delete data._proxyInternal;delete data._proxyUsed;delete data._raw;delete data.Model;delete data._updateFields;delete data.__uses__;delete data.Model;return data;}
toIdData(){const data=this.Model._retrieveIdFromData(this);for(const[name,val]of Object.entries(data)){if(Record.isRecord(val)){data[name]=val.toIdData();}}
return data;}
_downgradeProxy(fullProxy){return this._proxy===fullProxy?this._proxyInternal:fullProxy;}}
Record.register();const BaseStore=__exports.BaseStore=class BaseStore extends Record{storeReady=false;get(localId){return this.recordByLocalId.get(localId);}}
return __exports;});;

/* /mail/static/src/core/common/relative_time.js */
odoo.define('@mail/core/common/relative_time',['@odoo/owl','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{Component,onWillDestroy,xml}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const MINUTE=60*1000;const HOUR=60*MINUTE;const RelativeTime=__exports.RelativeTime=class RelativeTime extends Component{static props=["datetime"];static template=xml`<t t-esc="relativeTime"/>`;setup(){this.timeout=null;this.computeRelativeTime();onWillDestroy(()=>clearTimeout(this.timeout));}
computeRelativeTime(){const datetime=this.props.datetime;if(!datetime){this.relativeTime="";return;}
const delta=Date.now()-datetime.ts;if(delta<45*1000){this.relativeTime=_t("now");}else{this.relativeTime=datetime.toRelative();}
const updateDelay=delta<HOUR?MINUTE:HOUR;if(updateDelay){this.timeout=setTimeout(()=>{this.computeRelativeTime();this.render();},updateDelay);}}}
return __exports;});;

/* /mail/static/src/core/common/scroll_position.js */
odoo.define('@mail/core/common/scroll_position',[],function(require){'use strict';let __exports={};const ScrollPosition=__exports.ScrollPosition=class ScrollPosition{top;left;clear(){this.top=this.left=undefined;}
get isSaved(){return this.top!==undefined||this.left!==undefined;}}
return __exports;});;

/* /mail/static/src/core/common/search_messages_panel.js */
odoo.define('@mail/core/common/search_messages_panel',['@odoo/owl','@web/core/utils/hooks','@mail/core/common/message_search_hook','@web/core/browser/browser','@mail/discuss/core/common/action_panel','@mail/core/common/message_card_list','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{Component,onWillUpdateProps,useExternalListener,useState}=require("@odoo/owl");const{useAutofocus}=require("@web/core/utils/hooks");const{useMessageSearch}=require("@mail/core/common/message_search_hook");const{browser}=require("@web/core/browser/browser");const{ActionPanel}=require("@mail/discuss/core/common/action_panel");const{MessageCardList}=require("@mail/core/common/message_card_list");const{_t}=require("@web/core/l10n/translation");const SearchMessagesPanel=__exports.SearchMessagesPanel=class SearchMessagesPanel extends Component{static components={MessageCardList,ActionPanel,};static props=["thread","className?","closeSearch?","onClickJump?"];static template="mail.SearchMessagesPanel";setup(){this.state=useState({searchTerm:"",searchedTerm:""});this.messageSearch=useMessageSearch(this.props.thread);useAutofocus();useExternalListener(browser,"keydown",(ev)=>{if(ev.key==="Escape"){this.props.closeSearch?.();}},{capture:true});onWillUpdateProps((nextProps)=>{if(this.props.thread.notEq(nextProps.thread)){this.env.searchMenu?.close();}});}
get title(){return _t("Search messages");}
get MESSAGES_FOUND(){if(this.messageSearch.messages.length===0){return false;}
return _t("%s messages found",this.messageSearch.count);}
search(){this.messageSearch.searchTerm=this.state.searchTerm;this.messageSearch.search();this.state.searchedTerm=this.state.searchTerm;}
clear(){this.state.searchTerm="";this.state.searchedTerm=this.state.searchTerm;this.messageSearch.clear();this.props.closeSearch?.();}
onKeydownSearch(ev){if(ev.key!=="Enter"){return;}
if(!this.state.searchTerm){this.clear();}else{this.search();}}
onLoadMoreVisible(){const before=this.messageSearch.messages?Math.min(...this.messageSearch.messages.map((message)=>message.id)):false;this.messageSearch.search(before);}}
return __exports;});;

/* /mail/static/src/core/common/sound_effects_service.js */
odoo.define('@mail/core/common/sound_effects_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");const SoundEffects=__exports.SoundEffects=class SoundEffects{constructor(env){this.soundEffects={"channel-join":{defaultVolume:0.3,path:"/mail/static/src/audio/channel_01_in"},"channel-leave":{path:"/mail/static/src/audio/channel_04_out"},deafen:{defaultVolume:0.15,path:"/mail/static/src/audio/deafen_new_01"},"incoming-call":{defaultVolume:0.15,path:"/mail/static/src/audio/call_02_in_"},"member-leave":{defaultVolume:0.5,path:"/mail/static/src/audio/channel_01_out"},mute:{defaultVolume:0.2,path:"/mail/static/src/audio/mute_1"},"new-message":{path:"/mail/static/src/audio/dm_02"},"push-to-talk-on":{defaultVolume:0.05,path:"/mail/static/src/audio/ptt_push_1"},"push-to-talk-off":{defaultVolume:0.05,path:"/mail/static/src/audio/ptt_release_1",},"screen-sharing":{defaultVolume:0.5,path:"/mail/static/src/audio/share_02"},undeafen:{defaultVolume:0.15,path:"/mail/static/src/audio/undeafen_new_01"},unmute:{defaultVolume:0.2,path:"/mail/static/src/audio/unmute_1"},};}
play(soundEffectName,{loop=false,volume}={}){if(typeof browser.Audio==="undefined"){return;}
const soundEffect=this.soundEffects[soundEffectName];if(!soundEffect){return;}
if(!soundEffect.audio){const audio=new browser.Audio();const ext=audio.canPlayType("audio/ogg; codecs=vorbis")?".ogg":".mp3";audio.src=soundEffect.path+ext;soundEffect.audio=audio;}
if(!soundEffect.audio.paused){soundEffect.audio.pause();}
soundEffect.audio.currentTime=0;soundEffect.audio.loop=loop;soundEffect.audio.volume=volume??soundEffect.defaultVolume??1;Promise.resolve(soundEffect.audio.play()).catch(()=>{});}
stop(soundEffectName){const soundEffect=this.soundEffects[soundEffectName];if(soundEffect){if(soundEffect.audio){soundEffect.audio.pause();soundEffect.audio.currentTime=0;}}else{for(const soundEffect of Object.values(this.soundEffects)){if(soundEffect.audio){soundEffect.audio.pause();soundEffect.audio.currentTime=0;}}}}}
const soundEffects=__exports.soundEffects={start(env){return new SoundEffects(env);},};registry.category("services").add("mail.sound_effects",soundEffects);return __exports;});;

/* /mail/static/src/core/common/store_service.js */
odoo.define('@mail/core/common/store_service',['@web/core/registry','@web/core/utils/timing','@mail/core/common/record'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");const{debounce}=require("@web/core/utils/timing");const{Record,makeStore,BaseStore}=require("@mail/core/common/record");const Store=__exports.Store=class Store extends BaseStore{static insert(){return super.insert(...arguments);}
Activity;Attachment;CannedResponse;ChannelMember;ChatWindow;Composer;DiscussApp;DiscussAppCategory;Failure;Follower;LinkPreview;Message;MessageReactions;Notification;Persona;RtcSession;Thread;get registeredImStatusPartners(){return this.imStatusTrackedPersonas.map((persona)=>persona.id);}
knownChannelIds=new Set();user=Record.one("Persona");guest=Record.one("Persona");initBusId=0;inPublicPage=false;companyName="";odoobot=Record.one("Persona");odoobotOnboarding;users={};internalUserGroupId=null;imStatusTrackedPersonas=Record.many("Persona",{inverse:"storeAsTrackedImStatus",});hasLinkPreviewFeature=true;menu={counter:0};menuThreads=Record.many("Thread",{compute(){let threads=Object.values(this.Thread.records).filter((thread)=>thread.displayToSelf||(thread.needactionMessages.length>0&&thread.type!=="mailbox"));const tab=this.discuss.activeTab;if(tab!=="main"){threads=threads.filter(({type})=>this.tabToThreadType(tab).includes(type));}else if(tab==="main"&&this.env.inDiscussApp){threads=threads.filter(({type})=>this.tabToThreadType("mailbox").includes(type));}
return threads;},sort(a,b){const aOdooBot=a.isCorrespondentOdooBot;const bOdooBot=b.isCorrespondentOdooBot;if(aOdooBot&&!bOdooBot){return 1;}
if(bOdooBot&&!aOdooBot){return-1;}
const aNeedaction=a.needactionMessages.length;const bNeedaction=b.needactionMessages.length;if(aNeedaction>0&&bNeedaction===0){return-1;}
if(bNeedaction>0&&aNeedaction===0){return 1;}
const aUnread=a.message_unread_counter;const bUnread=b.message_unread_counter;if(aUnread>0&&bUnread===0){return-1;}
if(bUnread>0&&aUnread===0){return 1;}
const aMessageDatetime=a.newestPersistentNotEmptyOfAllMessage?.datetime;const bMessageDateTime=b.newestPersistentNotEmptyOfAllMessage?.datetime;if(!aMessageDatetime&&bMessageDateTime){return 1;}
if(!bMessageDateTime&&aMessageDatetime){return-1;}
if(aMessageDatetime&&bMessageDateTime&&aMessageDatetime!==bMessageDateTime){return bMessageDateTime-aMessageDatetime;}
return b.localId>a.localId?1:-1;},});discuss=Record.one("DiscussApp");failures=Record.many("Failure",{sort:(f1,f2)=>f2.lastMessage?.id-f1.lastMessage?.id,});activityCounter=0;isMessagingReady=false;get self(){return this.guest??this.user;}
updateImStatusRegistration(){this.env.services.im_status?.registerToImStatus("res.partner",[...this.registeredImStatusPartners,]);}
tabToThreadType(tab){return tab==="chat"?["chat","group"]:[tab];}
handleClickOnLink(ev,thread){const model=ev.target.dataset.oeModel;const id=Number(ev.target.dataset.oeId);if(ev.target.closest(".o_channel_redirect")&&model&&id){ev.preventDefault();const thread=this.Thread.insert({model,id});this.env.services["mail.thread"].open(thread);return true;}else if(ev.target.closest(".o_mail_redirect")&&id){ev.preventDefault();this.env.services["mail.thread"].openChat({partnerId:id});return true;}else if(ev.target.tagName==="A"&&model&&id){ev.preventDefault();Promise.resolve(this.env.services.action.doAction({type:"ir.actions.act_window",res_model:model,views:[[false,"form"]],res_id:id,})).then(()=>this.onLinkFollowed(thread));return true;}
return false;}
onLinkFollowed(fromThread){}
setup(){super.setup();this.updateBusSubscription=debounce(()=>this.env.services.bus_service.forceUpdateChannels(),0);}}
Store.register();const storeService=__exports.storeService={dependencies:["bus_service","ui"],start(env,services){const store=makeStore(env);store.discuss={};store.discuss.activeTab="main";services.ui.bus.addEventListener("resize",()=>{store.discuss.activeTab="main";if(services.ui.isSmall&&store.discuss.thread&&store.discuss.thread.type!=="mailbox"){store.discuss.activeTab=store.discuss.thread.type;}});return store;},};registry.category("services").add("mail.store",storeService);return __exports;});;

/* /mail/static/src/core/common/suggestion_hook.js */
odoo.define('@mail/core/common/suggestion_hook',['@mail/utils/common/hooks','@odoo/owl','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{useSequential}=require("@mail/utils/common/hooks");const{status,useComponent,useEffect,useState}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");__exports.useSuggestion=useSuggestion;function useSuggestion(){const comp=useComponent();const sequential=useSequential();const suggestionService=useService("mail.suggestion");const self={clearRawMentions(){comp.props.composer.mentionedChannels.length=0;comp.props.composer.mentionedPartners.length=0;},clearCannedResponses(){comp.props.composer.cannedResponses=[];},clearSearch(){Object.assign(self.search,{delimiter:undefined,position:undefined,term:"",});self.state.items=undefined;},detect(){const selectionEnd=comp.props.composer.selection.end;const selectionStart=comp.props.composer.selection.start;const content=comp.props.composer.textInputContent;if(selectionStart!==selectionEnd){self.clearSearch();return;}
const candidatePositions=[];let numberOfSpaces=0;for(let index=selectionStart-1;index>=0;--index){if(/\s/.test(content[index])){numberOfSpaces++;if(numberOfSpaces===2){break;}}
candidatePositions.push(index);}
if(self.search.position!==undefined&&self.search.position<selectionStart){candidatePositions.push(self.search.position);}
const supportedDelimiters=suggestionService.getSupportedDelimiters(self.thread);for(const candidatePosition of candidatePositions){if(candidatePosition<0||candidatePosition>=content.length){continue;}
const candidateChar=content[candidatePosition];if(!supportedDelimiters.find(([delimiter,allowedPosition])=>delimiter===candidateChar&&(allowedPosition===undefined||allowedPosition===candidatePosition))){continue;}
const charBeforeCandidate=content[candidatePosition-1];if(charBeforeCandidate&&!/\s/.test(charBeforeCandidate)){continue;}
Object.assign(self.search,{delimiter:candidateChar,position:candidatePosition,term:content.substring(candidatePosition+1,selectionStart),});self.state.count++;return;}
self.clearSearch();},get thread(){return comp.props.composer.thread||comp.props.composer.message.originThread;},insert(option){const cursorPosition=comp.props.composer.selection.start;const content=comp.props.composer.textInputContent;let textLeft=content.substring(0,self.search.position+1);let textRight=content.substring(cursorPosition,content.length);if(self.search.delimiter===":"){textLeft=content.substring(0,self.search.position);textRight=content.substring(cursorPosition,content.length);}
const recordReplacement=option.label;if(option.partner){comp.props.composer.mentionedPartners.add({id:option.partner.id,type:"partner",});}
if(option.thread){comp.props.composer.mentionedChannels.add({model:"discuss.channel",id:option.thread.id,});}
if(option.cannedResponse){comp.props.composer.cannedResponses.push(option.cannedResponse);}
self.clearSearch();comp.props.composer.textInputContent=textLeft+recordReplacement+" "+textRight;comp.props.composer.selection.start=textLeft.length+recordReplacement.length+1;comp.props.composer.selection.end=textLeft.length+recordReplacement.length+1;comp.props.composer.forceCursorMove=true;},search:{delimiter:undefined,position:undefined,term:"",},state:useState({count:0,items:undefined,}),update(){if(!self.search.delimiter){return;}
const suggestions=suggestionService.searchSuggestions(self.search,{thread:self.thread,sort:true,});const{type,mainSuggestions,extraSuggestions=[]}=suggestions;if(!mainSuggestions.length&&!extraSuggestions.length){self.state.items=undefined;return;}
const limit=8;mainSuggestions.length=Math.min(mainSuggestions.length,limit);extraSuggestions.length=Math.min(extraSuggestions.length,limit-mainSuggestions.length);self.state.items={type,mainSuggestions,extraSuggestions};},};useEffect((delimiter,position,term)=>{self.update();if(self.search.position===undefined||!self.search.delimiter){return;}
sequential(async()=>{if(self.search.delimiter!==delimiter||self.search.position!==position||self.search.term!==term){return;}
await suggestionService.fetchSuggestions(self.search,{thread:self.thread,});if(status(comp)==="destroyed"){return;}
self.update();if(self.search.delimiter===delimiter&&self.search.position===position&&self.search.term===term&&!self.state.items?.mainSuggestions.length&&!self.state.items?.extraSuggestions.length){self.clearSearch();}});},()=>{return[self.search.delimiter,self.search.position,self.search.term];});useEffect(()=>{self.detect();},()=>[comp.props.composer.selection.start,comp.props.composer.selection.end,comp.props.composer.textInputContent,]);return self;}
return __exports;});;

/* /mail/static/src/core/common/suggestion_service.js */
odoo.define('@mail/core/common/suggestion_service',['@mail/core/common/partner_compare','@mail/utils/common/format','@odoo/owl','@web/core/registry'],function(require){'use strict';let __exports={};const{partnerCompareRegistry}=require("@mail/core/common/partner_compare");const{cleanTerm}=require("@mail/utils/common/format");const{toRaw}=require("@odoo/owl");const{registry}=require("@web/core/registry");const SuggestionService=__exports.SuggestionService=class SuggestionService{constructor(env,services){this.env=env;this.orm=services.orm;this.store=services["mail.store"];this.personaService=services["mail.persona"];}
getSupportedDelimiters(thread){return[["@"],["#"]];}
async fetchSuggestions({delimiter,term},{thread}={}){const cleanedSearchTerm=cleanTerm(term);switch(delimiter){case"@":{await this.fetchPartners(cleanedSearchTerm,thread);break;}
case"#":await this.fetchThreads(cleanedSearchTerm);break;}}
async fetchPartners(term,thread){const kwargs={search:term};if(thread?.model==="discuss.channel"){kwargs.channel_id=thread.id;}
const suggestedPartners=await this.orm.silent.call("res.partner",thread?.model==="discuss.channel"?"get_mention_suggestions_from_channel":"get_mention_suggestions",[],kwargs);this.store.Persona.insert(suggestedPartners);}
async fetchThreads(term){const suggestedThreads=await this.orm.silent.call("discuss.channel","get_mention_suggestions",[],{search:term});this.store.Thread.insert(suggestedThreads);}
searchSuggestions({delimiter,term},{thread,sort=false}={}){thread=toRaw(thread);const cleanedSearchTerm=cleanTerm(term);switch(delimiter){case"@":{return this.searchPartnerSuggestions(cleanedSearchTerm,thread,sort);}
case"#":return this.searchChannelSuggestions(cleanedSearchTerm,sort);}
return{type:undefined,mainSuggestions:[],extraSuggestions:[],};}
searchPartnerSuggestions(cleanedSearchTerm,thread,sort){let partners;const isNonPublicChannel=thread&&(thread.type==="group"||thread.type==="chat"||(thread.type==="channel"&&thread.authorizedGroupFullName));if(isNonPublicChannel){partners=thread.channelMembers.map((member)=>member.persona).filter((persona)=>persona.type==="partner");}else{partners=Object.values(this.store.Persona.records).filter((persona)=>persona.type==="partner");}
const mainSuggestionList=[];const extraSuggestionList=[];for(const partner of partners){if(!partner.name){continue;}
if(cleanTerm(partner.name).includes(cleanedSearchTerm)||(partner.email&&cleanTerm(partner.email).includes(cleanedSearchTerm))){if(partner.user){mainSuggestionList.push(partner);}else{extraSuggestionList.push(partner);}}}
return{type:"Partner",mainSuggestions:sort?this.sortPartnerSuggestions(mainSuggestionList,cleanedSearchTerm,thread):mainSuggestionList,extraSuggestions:sort?this.sortPartnerSuggestions(extraSuggestionList,cleanedSearchTerm,thread):extraSuggestionList,};}
sortPartnerSuggestions(partners,searchTerm="",thread=undefined){const cleanedSearchTerm=cleanTerm(searchTerm);const compareFunctions=partnerCompareRegistry.getAll();const context={recentChatPartnerIds:this.personaService.getRecentChatPartnerIds()};const memberPartnerIds=new Set(thread?.channelMembers.filter((member)=>member.persona.type==="partner").map((member)=>member.persona.id));return partners.sort((p1,p2)=>{p1=toRaw(p1);p2=toRaw(p2);for(const fn of compareFunctions){const result=fn(p1,p2,{env:this.env,memberPartnerIds,searchTerms:cleanedSearchTerm,thread,context,});if(result!==undefined){return result;}}});}
searchChannelSuggestions(cleanedSearchTerm,sort){const suggestionList=Object.values(this.store.Thread.records).filter((thread)=>thread.type==="channel"&&thread.displayName&&cleanTerm(thread.displayName).includes(cleanedSearchTerm));const sortFunc=(c1,c2)=>{const isPublicChannel1=c1.type==="channel"&&!c2.authorizedGroupFullName;const isPublicChannel2=c2.type==="channel"&&!c2.authorizedGroupFullName;if(isPublicChannel1&&!isPublicChannel2){return-1;}
if(!isPublicChannel1&&isPublicChannel2){return 1;}
if(c1.hasSelfAsMember&&!c2.hasSelfAsMember){return-1;}
if(!c1.hasSelfAsMember&&c2.hasSelfAsMember){return 1;}
const cleanedDisplayName1=cleanTerm(c1.displayName);const cleanedDisplayName2=cleanTerm(c2.displayName);if(cleanedDisplayName1.startsWith(cleanedSearchTerm)&&!cleanedDisplayName2.startsWith(cleanedSearchTerm)){return-1;}
if(!cleanedDisplayName1.startsWith(cleanedSearchTerm)&&cleanedDisplayName2.startsWith(cleanedSearchTerm)){return 1;}
if(cleanedDisplayName1<cleanedDisplayName2){return-1;}
if(cleanedDisplayName1>cleanedDisplayName2){return 1;}
return c1.id-c2.id;};return{type:"Thread",mainSuggestions:sort?suggestionList.sort(sortFunc):suggestionList,extraSuggestions:[],};}}
const suggestionService=__exports.suggestionService={dependencies:["orm","mail.store","mail.persona"],start(env,services){return new SuggestionService(env,services);},};registry.category("services").add("mail.suggestion",suggestionService);return __exports;});;

/* /mail/static/src/core/common/thread.js */
odoo.define('@mail/core/common/thread',['@mail/core/common/date_section','@mail/core/common/message','@mail/core/common/record','@mail/utils/common/hooks','@odoo/owl','@web/core/transition','@web/core/utils/hooks','@web/core/utils/strings'],function(require){'use strict';let __exports={};const{DateSection}=require("@mail/core/common/date_section");const{Message}=require("@mail/core/common/message");const{Record}=require("@mail/core/common/record");const{useVisible}=require("@mail/utils/common/hooks");const{Component,onMounted,onWillDestroy,onWillPatch,onWillUpdateProps,toRaw,useChildSubEnv,useEffect,useRef,useState,}=require("@odoo/owl");const{Transition}=require("@web/core/transition");const{useBus,useService}=require("@web/core/utils/hooks");const{escape}=require("@web/core/utils/strings");const PRESENT_THRESHOLD=__exports.PRESENT_THRESHOLD=2500;const Thread=__exports.Thread=class Thread extends Component{static components={Message,Transition,DateSection};static props=["showDates?","isInChatWindow?","jumpPresent?","thread","messageEdition?","messageToReplyTo?","order?","scrollRef?","showEmptyMessage?","showJumpPresent?","messageActions?",];static defaultProps={isInChatWindow:false,jumpPresent:0,order:"asc",showDates:true,showEmptyMessage:true,showJumpPresent:true,messageActions:true,};static template="mail.Thread";setup(){this.escape=escape;this.store=useState(useService("mail.store"));this.state=useState({isReplyingTo:false,mountedAndLoaded:false,showJumpPresent:false,});this.lastJumpPresent=this.props.jumpPresent;this.threadService=useState(useService("mail.thread"));this.messageHighlight=this.env.messageHighlight?useState(this.env.messageHighlight):null;this.present=useRef("load-newer");this.scrollableRef=this.props.scrollRef??useRef("messages");this.loadOlderState=useVisible("load-older",()=>{if(this.loadOlderState.isVisible){this.threadService.fetchMoreMessages(this.props.thread);}},{init:null,ready:false});this.loadNewerState=useVisible("load-newer",()=>{if(this.loadNewerState.isVisible){this.threadService.fetchMoreMessages(this.props.thread,"newer");}},{init:null,ready:false});this.presentThresholdState=useVisible("present-treshold",()=>this.updateShowJumpPresent(),{init:true});this.setupScroll();useEffect(()=>this.updateShowJumpPresent(),()=>[this.props.thread.loadNewer]);useEffect(()=>{if(this.props.jumpPresent!==this.lastJumpPresent){this.messageHighlight?.clearHighlight();if(this.props.thread.loadNewer){this.jumpToPresent();}else{if(this.props.order==="desc"){this.scrollableRef.el.scrollTop=0;}else{this.scrollableRef.el.scrollTop=this.scrollableRef.el.scrollHeight-
this.scrollableRef.el.clientHeight;}
this.props.thread.scrollTop="bottom";}
this.lastJumpPresent=this.props.jumpPresent;}},()=>[this.props.jumpPresent]);useEffect(()=>{if(!this.state.mountedAndLoaded){return;}
if(!this.env.inChatter){this.updateShowJumpPresent();}},()=>[this.state.mountedAndLoaded]);onMounted(()=>{if(!this.env.chatter||this.env.chatter?.fetchMessages){if(this.env.chatter){this.env.chatter.fetchMessages=false;}
this.threadService.fetchNewMessages(this.props.thread);}});useEffect((isLoaded)=>{this.state.mountedAndLoaded=isLoaded;},()=>[this.props.thread.isLoaded,this.state.mountedAndLoaded]);useBus(this.env.bus,"MAIL:RELOAD-THREAD",({detail})=>{const{model,id}=this.props.thread;if(detail.model===model&&detail.id===id){this.threadService.fetchNewMessages(this.props.thread);}});onWillUpdateProps((nextProps)=>{if(nextProps.thread.notEq(this.props.thread)){this.lastJumpPresent=nextProps.jumpPresent;}
if(!this.env.chatter||this.env.chatter?.fetchMessages){if(this.env.chatter){this.env.chatter.fetchMessages=false;}
this.threadService.fetchNewMessages(nextProps.thread);}});}
setupScroll(){const ref=this.scrollableRef;let lastSetValue;let loadedAndPatched=false;let snapshot;let newestPersistentMessage;let oldestPersistentMessage;let loadNewer;const reset=()=>{this.state.mountedAndLoaded=false;this.loadOlderState.ready=false;this.loadNewerState.ready=false;lastSetValue=undefined;snapshot=undefined;newestPersistentMessage=undefined;oldestPersistentMessage=undefined;loadedAndPatched=false;loadNewer=false;};let stopOnChange=Record.onChange(this.props.thread,"isLoaded",()=>{if(!this.props.thread.isLoaded||!this.state.mountedAndLoaded){reset();}});onWillUpdateProps((nextProps)=>{if(nextProps.thread.notEq(this.props.thread)){stopOnChange();stopOnChange=Record.onChange(nextProps.thread,"isLoaded",()=>{if(!nextProps.thread.isLoaded||!this.state.mountedAndLoaded){reset();}});}});onWillDestroy(()=>stopOnChange());const saveScroll=()=>{const isBottom=this.props.order==="asc"?ref.el.scrollHeight-ref.el.scrollTop-ref.el.clientHeight<30:ref.el.scrollTop<30;if(isBottom){this.props.thread.scrollTop="bottom";}else{this.props.thread.scrollTop=this.props.order==="asc"?ref.el.scrollTop:ref.el.scrollHeight-ref.el.scrollTop-ref.el.clientHeight;}};const setScroll=(value)=>{ref.el.scrollTop=value;lastSetValue=value;saveScroll();};const applyScroll=()=>{if(!this.props.thread.isLoaded||!this.state.mountedAndLoaded){reset();return;}
const thread=toRaw(this.props.thread);const olderMessages=thread.oldestPersistentMessage?.id<oldestPersistentMessage?.id;const newerMessages=thread.newestPersistentMessage?.id>newestPersistentMessage?.id;const messagesAtTop=(this.props.order==="asc"&&olderMessages)||(this.props.order==="desc"&&newerMessages);const messagesAtBottom=(this.props.order==="desc"&&olderMessages)||(this.props.order==="asc"&&newerMessages&&(loadNewer||thread.scrollTop!=="bottom"));if(snapshot&&messagesAtTop){setScroll(snapshot.scrollTop+ref.el.scrollHeight-snapshot.scrollHeight);}else if(snapshot&&messagesAtBottom){setScroll(snapshot.scrollTop);}else if(!this.env.messageHighlight?.highlightedMessageId&&thread.scrollTop!==undefined){let value;if(thread.scrollTop==="bottom"){value=this.props.order==="asc"?ref.el.scrollHeight-ref.el.clientHeight:0;}else{value=this.props.order==="asc"?thread.scrollTop:ref.el.scrollHeight-thread.scrollTop-ref.el.clientHeight;}
if(lastSetValue===undefined||Math.abs(lastSetValue-value)>1){setScroll(value);}}
snapshot=undefined;newestPersistentMessage=thread.newestPersistentMessage;oldestPersistentMessage=thread.oldestPersistentMessage;loadNewer=thread.loadNewer;if(!loadedAndPatched){loadedAndPatched=true;this.loadOlderState.ready=true;this.loadNewerState.ready=true;}};onWillPatch(()=>{if(!loadedAndPatched){return;}
snapshot={scrollHeight:ref.el.scrollHeight,scrollTop:ref.el.scrollTop,};});useEffect(applyScroll);useChildSubEnv({onImageLoaded:applyScroll});const observer=new ResizeObserver(applyScroll);useEffect((el,mountedAndLoaded)=>{if(el&&mountedAndLoaded){el.addEventListener("scroll",saveScroll);observer.observe(el);return()=>{observer.unobserve(el);el.removeEventListener("scroll",saveScroll);};}},()=>[ref.el,this.state.mountedAndLoaded]);}
get PRESENT_THRESHOLD(){return this.state.showJumpPresent?PRESENT_THRESHOLD-200:PRESENT_THRESHOLD;}
updateShowJumpPresent(){this.state.showJumpPresent=this.props.thread.loadNewer||!this.presentThresholdState.isVisible;}
onClickLoadOlder(){this.threadService.fetchMoreMessages(this.props.thread);}
async jumpToPresent(){this.messageHighlight?.clearHighlight();await this.threadService.loadAround(this.props.thread);this.props.thread.loadNewer=false;this.props.thread.scrollTop="bottom";this.state.showJumpPresent=false;}
async onClickNotification(ev){const{oeType,oeId}=ev.target.dataset;if(oeType==="highlight"){await this.env.messageHighlight?.highlightMessage(this.store.Message.insert({id:Number(oeId),res_id:this.props.thread.id,model:this.props.thread.model,}),this.props.thread);}}
isSquashed(msg,prevMsg){if(this.props.thread.model==="mail.box"){return false;}
if(!prevMsg||prevMsg.type==="notification"||prevMsg.isEmpty||this.env.inChatter){return false;}
if(!msg.author?.eq(prevMsg.author)){return false;}
if(msg.model!==prevMsg.model||msg.res_id!==prevMsg.res_id){return false;}
if(msg.parentMessage){return false;}
return msg.datetime.ts-prevMsg.datetime.ts<60*1000;}}
return __exports;});;

/* /mail/static/src/core/common/thread_actions.js */
odoo.define('@mail/core/common/thread_actions',['@odoo/owl','@web/core/l10n/translation','@web/core/registry','@mail/core/common/search_messages_panel'],function(require){'use strict';let __exports={};const{useSubEnv,useComponent,useState}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{SearchMessagesPanel}=require("@mail/core/common/search_messages_panel");const threadActionsRegistry=__exports.threadActionsRegistry=registry.category("mail.thread/actions");threadActionsRegistry.add("fold-chat-window",{condition(component){return!component.ui.isSmall&&component.props.chatWindow;},icon:"fa fa-fw fa-minus",name(component){return!component.props.chatWindow?.isOpen?_t("Open"):_t("Fold");},open(component){component.toggleFold();},displayActive(component){return!component.props.chatWindow?.isOpen;},sequence:99,}).add("rename-thread",{condition(component){return(component.thread&&component.props.chatWindow?.isOpen&&(component.thread.is_editable||component.thread.type==="chat"));},icon:"fa fa-fw fa-pencil",name:_t("Rename"),open(component){component.state.editingName=true;},sequence:17,}).add("close",{condition(component){return component.props.chatWindow;},icon:"fa fa-fw fa-close",name:_t("Close Chat Window"),open(component){component.close();},sequence:100,}).add("search-messages",{component:SearchMessagesPanel,condition(component){return(["discuss.channel","mail.box"].includes(component.thread?.model)&&(!component.props.chatWindow||component.props.chatWindow.isOpen));},panelOuterClass:"o-mail-SearchMessagesPanel",icon:"oi oi-fw oi-search",iconLarge:"oi oi-fw oi-search",name:_t("Search Messages"),nameActive:_t("Close Search"),sequence:(component)=>{const res=component.env.inDiscussApp?8:16;return res;},setup(action){useSubEnv({searchMenu:{open:()=>action.open(),close:()=>{if(action.isActive){action.close();}},},});},toggle:true,});function transformAction(component,id,action){return{close(){if(this.toggle){component.threadActions.activeAction=component.threadActions.actionStack.pop();}
action.close?.(component,this);},component:action.component,get componentCondition(){return this.isActive&&this.component&&this.condition&&!this.popover;},get componentProps(){return action.componentProps?.(this,component);},get condition(){return action.condition(component);},get disabledCondition(){return action.disabledCondition?.(component);},get icon(){return typeof action.icon==="function"?action.icon(component):action.icon;},get iconLarge(){return typeof action.iconLarge==="function"?action.iconLarge(component):action.iconLarge??action.icon;},id,get isActive(){return id===component.threadActions.activeAction?.id;},get name(){const res=this.isActive&&action.nameActive?action.nameActive:action.name;return typeof res==="function"?res(component):res;},onSelect({keepPrevious}={}){if(this.toggle&&this.isActive){this.close();}else{this.open({keepPrevious});}},open({keepPrevious}={}){if(this.toggle){if(component.threadActions.activeAction&&keepPrevious){component.threadActions.actionStack.push(component.threadActions.activeAction);}
component.threadActions.activeAction=this;}
action.open?.(component,this);},panelOuterClass:action.panelOuterClass,popover:null,get sequence(){return typeof action.sequence==="function"?action.sequence(component):action.sequence;},setup:action.setup,text:action.text,toggle:action.toggle,};}
__exports.useThreadActions=useThreadActions;function useThreadActions(){const component=useComponent();const transformedActions=threadActionsRegistry.getEntries().map(([id,action])=>transformAction(component,id,action));for(const action of transformedActions){if(action.setup){action.setup(action);}}
const state=useState({get actions(){return transformedActions.filter((action)=>action.condition).sort((a1,a2)=>a1.sequence-a2.sequence);},actionStack:[],activeAction:null,});return state;}
return __exports;});;

/* /mail/static/src/core/common/thread_icon.js */
odoo.define('@mail/core/common/thread_icon',['@web/core/utils/hooks','@odoo/owl'],function(require){'use strict';let __exports={};const{useService}=require("@web/core/utils/hooks");const{Component,useState}=require("@odoo/owl");const ThreadIcon=__exports.ThreadIcon=class ThreadIcon extends Component{static template="mail.ThreadIcon";static props=["thread","size?","className?"];static defaultProps={size:"medium",className:"",};setup(){this.store=useState(useService("mail.store"));}
get chatPartner(){return this.props.thread.chatPartner;}}
return __exports;});;

/* /mail/static/src/core/common/thread_model.js */
odoo.define('@mail/core/common/thread_model',['@mail/core/common/record','@mail/core/common/scroll_position','@mail/utils/common/misc','@web/core/l10n/dates','@web/core/l10n/translation','@web/core/l10n/utils','@web/core/utils/concurrency'],function(require){'use strict';let __exports={};const{AND,Record}=require("@mail/core/common/record");const{ScrollPosition}=require("@mail/core/common/scroll_position");const{assignDefined,assignIn}=require("@mail/utils/common/misc");const{deserializeDateTime}=require("@web/core/l10n/dates");const{_t}=require("@web/core/l10n/translation");const{pyToJsLocale}=require("@web/core/l10n/utils");const{Deferred}=require("@web/core/utils/concurrency");const Thread=__exports.Thread=class Thread extends Record{static id=AND("model","id");static records={};static get(data){return super.get(data);}
static new(data){const thread=super.new(data);thread.composer={};Record.onChange(thread,"isLoaded",()=>{if(thread.isLoaded){thread.isLoadedDeferred.resolve();}else{const def=thread.isLoadedDeferred;thread.isLoadedDeferred=new Deferred();thread.isLoadedDeferred.then(()=>def.resolve());}});return thread;}
static localIdToActiveId(localId){if(!localId){return undefined;}
return localId.split(",").slice(1).join("_").replace(" AND ","_");}
static insert(data){return super.insert(...arguments);}
static get onlineMemberStatuses(){return["away","bot","online"];}
update(data){const{id,name,attachments,description,...serverData}=data;assignDefined(this,{id,name,description});if(attachments){this.attachments=attachments;}
if(serverData){assignDefined(this,serverData,["uuid","authorizedGroupFullName","avatarCacheKey","description","hasWriteAccess","is_pinned","isLoaded","isLoadingAttachments","mainAttachment","message_unread_counter","message_needaction_counter","name","seen_message_id","state","type","status","group_based_subscription","last_interest_dt","custom_notifications","mute_until_dt","is_editable","defaultDisplayMode",]);assignIn(this,data,["custom_channel_name","memberCount","channelMembers","invitedMembers",]);if("channel_type"in data){this.type=data.channel_type;}
if("channelMembers"in data){if(this.type==="chat"){for(const member of this.channelMembers){if(member.persona.notEq(this._store.user)||(this.channelMembers.length===1&&member.persona?.eq(this._store.user))){this.chatPartner=member.persona;}}}}
if("seen_partners_info"in serverData){this._store.ChannelMember.insert(serverData.seen_partners_info.map(({id,fetched_message_id,partner_id,guest_id,seen_message_id})=>({id,persona:{id:partner_id??guest_id,type:partner_id?"partner":"guest",},lastFetchedMessage:fetched_message_id?{id:fetched_message_id}:undefined,lastSeenMessage:seen_message_id?{id:seen_message_id}:undefined,})));}}
if(this.type==="channel"){this._store.discuss.channels.threads.add(this);}else if(this.type==="chat"||this.type==="group"){this._store.discuss.chats.threads.add(this);}
if(!this.type&&!["mail.box","discuss.channel"].includes(this.model)){this.type="chatter";}}
id;uuid;model;allMessages=Record.many("Message",{inverse:"originThread2",});areAttachmentsLoaded=false;attachments=Record.many("Attachment",{sort:(a1,a2)=>(a1.id<a2.id?1:-1),});activeRtcSession=Record.one("RtcSession");channel;channelMembers=Record.many("ChannelMember",{onDelete:(r)=>r.delete()});rtcSessions=Record.many("RtcSession",{onDelete(r){this._store.env.services["discuss.rtc"].deleteSession(r.id);},});rtcInvitingSession=Record.one("RtcSession",{onAdd(r){this.rtcSessions.add(r);this._store.discuss.ringingThreads.add(this);},onDelete(r){this._store.discuss.ringingThreads.delete(this);},});toggleBusSubscription=Record.attr(false,{compute(){return(this.model==="discuss.channel"&&this.selfMember?.memberSince>=this._store.env.services.bus_service.startedAt);},onUpdate(){this._store.updateBusSubscription();},});invitedMembers=Record.many("ChannelMember");chatPartner=Record.one("Persona");composer=Record.one("Composer",{inverse:"thread",onDelete:(r)=>r.delete()});correspondent2=Record.one("Persona",{compute(){return this.computeCorrespondent();},});counter=0;custom_channel_name;description;displayToSelf=Record.attr(false,{compute(){return(this.is_pinned||(["channel","group"].includes(this.type)&&this.hasSelfAsMember));},onUpdate(){this.onPinStateUpdated();},});followers=Record.many("Follower");selfFollower=Record.one("Follower");followersCount;isAdmin=false;loadOlder=false;loadNewer=false;isCorrespondentOdooBot=Record.attr(undefined,{compute(){return this.correspondent2?.eq(this._store.odoobot);},});isLoadingAttachments=false;isLoadedDeferred=new Deferred();isLoaded=false;is_pinned=Record.attr(undefined,{onUpdate(){this.onPinStateUpdated();},});mainAttachment=Record.one("Attachment");memberCount=0;message_needaction_counter=0;message_unread_counter=0;message_unread_counter_bus_id=0;messages=Record.many("Message");modelName;module_icon;pendingNewMessages=Record.many("Message");needactionMessages=Record.many("Message");name;seen_message_id;selfMember=Record.one("ChannelMember",{inverse:"threadAsSelf",});state;status="new";scrollPosition=new ScrollPosition();scrollTop="bottom";showOnlyVideo=false;transientMessages=Record.many("Message");type;defaultDisplayMode;suggestedRecipients=[];hasLoadingFailed=false;canPostOnReadonly;last_interest_dt;is_editable;custom_notifications=false;mute_until_dt;isLocallyPinned=Record.attr(false,{onUpdate(){this.onPinStateUpdated();},});fetchMembersState="not_fetched";get accessRestrictedToGroupText(){if(!this.authorizedGroupFullName){return false;}
return _t('Access restricted to group "%(groupFullName)s"',{groupFullName:this.authorizedGroupFullName,});}
get areAllMembersLoaded(){return this.memberCount===this.channelMembers.length;}
get busChannel(){return`${this.model}_${this.id}`;}
get followersFullyLoaded(){return(this.followersCount===(this.selfFollower?this.followers.length+1:this.followers.length));}
get attachmentsInWebClientView(){const attachments=this.attachments.filter((attachment)=>(attachment.isPdf||attachment.isImage)&&!attachment.uploading);attachments.sort((a1,a2)=>{return a2.id-a1.id;});return attachments;}
get isUnread(){return this.message_unread_counter>0||this.needactionMessages.length>0;}
get typesAllowingCalls(){return["chat","channel","group"];}
get allowCalls(){return(this.typesAllowingCalls.includes(this.type)&&!this.correspondent?.eq(this._store.odoobot));}
get hasMemberList(){return["channel","group"].includes(this.type);}
get hasAttachmentPanel(){return this.model==="discuss.channel";}
get isChatChannel(){return["chat","group"].includes(this.type);}
get displayName(){if(this.type==="chat"&&this.chatPartner){return this.custom_channel_name||this.chatPartner.nameOrDisplayName;}
if(this.type==="group"&&!this.name){const listFormatter=new Intl.ListFormat(this._store.env.services["user"].lang&&pyToJsLocale(this._store.env.services["user"].lang),{type:"conjunction",style:"long"});return listFormatter.format(this.channelMembers.map((channelMember)=>channelMember.persona.name));}
return this.name;}
get correspondents(){return this.channelMembers.map((member)=>member.persona).filter((persona)=>!!persona).filter((p)=>p.notEq(this._store.self));}
get correspondent(){return this.correspondent2;}
computeCorrespondent(){if(this.type==="channel"){return undefined;}
const correspondents=this.correspondents;if(correspondents.length===1){return correspondents[0];}
if(correspondents.length===0&&this.channelMembers.length===1){return this._store.user;}
return undefined;}
get imgUrl(){return this.module_icon??"/mail/static/src/img/smiley/avatar.jpg";}
get allowDescription(){return["channel","group"].includes(this.type);}
get isTransient(){return!this.id;}
get lastEditableMessageOfSelf(){const editableMessagesBySelf=this.nonEmptyMessages.filter((message)=>message.isSelfAuthored&&message.editable);if(editableMessagesBySelf.length>0){return editableMessagesBySelf.at(-1);}
return null;}
get needactionCounter(){return this.isChatChannel?this.message_unread_counter:this.message_needaction_counter;}
get newestMessage(){return[...this.messages].reverse().find((msg)=>!msg.isEmpty);}
get newestPersistentMessage(){return[...this.messages].reverse().find((msg)=>Number.isInteger(msg.id));}
newestPersistentAllMessages=Record.many("Message",{compute(){const allPersistentMessages=this.allMessages.filter((message)=>Number.isInteger(message.id));allPersistentMessages.sort((m1,m2)=>m2.id-m1.id);return allPersistentMessages;},});newestPersistentOfAllMessage=Record.one("Message",{compute(){return this.newestPersistentAllMessages[0];},});newestPersistentNotEmptyOfAllMessage=Record.one("Message",{compute(){return this.newestPersistentAllMessages.find((message)=>!message.isEmpty);},});get oldestPersistentMessage(){return this.messages.find((msg)=>Number.isInteger(msg.id));}
onPinStateUpdated(){}
get hasSelfAsMember(){return Boolean(this.selfMember);}
get invitationLink(){if(!this.uuid||this.type==="chat"){return undefined;}
return`${window.location.origin}/chat/${this.id}/${this.uuid}`;}
get isEmpty(){return!this.messages.some((message)=>!message.isEmpty);}
get offlineMembers(){const orderedOnlineMembers=[];for(const member of this.channelMembers){if(!this._store.Thread.onlineMemberStatuses.includes(member.persona.im_status)){orderedOnlineMembers.push(member);}}
return orderedOnlineMembers.sort((m1,m2)=>(m1.persona.name<m2.persona.name?-1:1));}
get nonEmptyMessages(){return this.messages.filter((message)=>!message.isEmpty);}
get persistentMessages(){return this.messages.filter((message)=>!message.is_transient);}
get prefix(){return this.isChatChannel?"@":"#";}
get lastSelfMessageSeenByEveryone(){const otherMembers=this.channelMembers.filter((member)=>member.persona.notEq(this._store.self));if(otherMembers.length===0){return false;}
const otherLastSeenMessageIds=otherMembers.filter((member)=>member.lastSeenMessage).map((member)=>member.lastSeenMessage.id);if(otherLastSeenMessageIds.length===0){return false;}
const lastMessageSeenByAllId=Math.min(...otherLastSeenMessageIds);const orderedSelfSeenMessages=this.persistentMessages.filter((message)=>{return message.author?.eq(this._store.self)&&message.id<=lastMessageSeenByAllId;});if(!orderedSelfSeenMessages||orderedSelfSeenMessages.length===0){return false;}
return orderedSelfSeenMessages.slice().pop();}
get onlineMembers(){const orderedOnlineMembers=[];for(const member of this.channelMembers){if(this._store.Thread.onlineMemberStatuses.includes(member.persona.im_status)){orderedOnlineMembers.push(member);}}
return orderedOnlineMembers.sort((m1,m2)=>{const m1HasRtc=Boolean(m1.rtcSession);const m2HasRtc=Boolean(m2.rtcSession);if(m1HasRtc===m2HasRtc){const m1RaisingValue=m1.rtcSession?.raisingHand||Infinity;const m2RaisingValue=m2.rtcSession?.raisingHand||Infinity;if(m1HasRtc&&m1RaisingValue!==m2RaisingValue){return m1RaisingValue-m2RaisingValue;}else{return m1.persona.name?.localeCompare(m2.persona.name)??1;}}else{return m2HasRtc-m1HasRtc;}});}
get unknownMembersCount(){return this.memberCount-this.channelMembers.length;}
get videoCount(){return Object.values(this._store.RtcSession.records).filter((session)=>session.hasVideo).length;}
get lastInterestDateTime(){if(!this.last_interest_dt){return undefined;}
return deserializeDateTime(this.last_interest_dt);}
get muteUntilDateTime(){if(!this.mute_until_dt){return undefined;}
return deserializeDateTime(this.mute_until_dt);}
getMemberName(persona){return persona.name;}
getPreviousMessage(message){const previousMessages=this.nonEmptyMessages.filter(({id})=>id<message.id);if(previousMessages.length===0){return false;}
return this._store.Message.get(Math.max(...previousMessages.map((m)=>m.id)));}}
Thread.register();return __exports;});;

/* /mail/static/src/core/common/thread_service.js */
odoo.define('@mail/core/common/thread_service',['@web/core/emoji_picker/emoji_picker','@mail/core/common/persona_service','@mail/core/common/record','@mail/utils/common/format','@web/core/browser/browser','@web/core/l10n/translation','@web/core/registry','@web/core/utils/functions','@web/core/utils/urls','@mail/utils/common/misc'],function(require){'use strict';let __exports={};const{loadEmoji}=require("@web/core/emoji_picker/emoji_picker");const{DEFAULT_AVATAR}=require("@mail/core/common/persona_service");const{Record}=require("@mail/core/common/record");const{prettifyMessageContent}=require("@mail/utils/common/format");const{browser}=require("@web/core/browser/browser");const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{memoize}=require("@web/core/utils/functions");const{url}=require("@web/core/utils/urls");const{compareDatetime}=require("@mail/utils/common/misc");const FETCH_LIMIT=30;const ThreadService=__exports.ThreadService=class ThreadService{nextId=0;constructor(env,services){this.setup(env,services);}
setup(env,services){this.env=env;this.store=services["mail.store"];this.orm=services.orm;this.rpc=services.rpc;this.notificationService=services.notification;this.router=services.router;this.ui=services.ui;this.user=services.user;this.messageService=services["mail.message"];this.personaService=services["mail.persona"];this.outOfFocusService=services["mail.out_of_focus"];}
async fetchChannel(id){const channelData=await this.rpc("/discuss/channel/info",{channel_id:id});if(!channelData){return;}
return this.store.Thread.insert({...channelData,model:"discuss.channel",type:channelData.channel_type,});}
async fetchChannelMembers(thread){if(thread.fetchMembersState==="pending"){return;}
const previousState=thread.fetchMembersState;thread.fetchMembersState="pending";const known_member_ids=thread.channelMembers.map((channelMember)=>channelMember.id);let results;try{results=await this.rpc("/discuss/channel/members",{channel_id:thread.id,known_member_ids:known_member_ids,});}catch(e){thread.fetchMembersState=previousState;throw e;}
thread.fetchMembersState="fetched";let channelMembers=[];if(results["channelMembers"]&&results["channelMembers"][0]&&results["channelMembers"][0][1]){channelMembers=results["channelMembers"][0][1];}
thread.memberCount=results["memberCount"];Record.MAKE_UPDATE(()=>{for(const channelMember of channelMembers){if(channelMember.persona||channelMember.partner){thread.channelMembers.add({...channelMember,thread});}}});}
markAsRead(thread){const newestPersistentMessage=thread.newestPersistentOfAllMessage;if(!newestPersistentMessage&&!thread.isLoaded){thread.isLoadedDeferred.then(()=>new Promise(setTimeout)).then(()=>this.markAsRead(thread));}
thread.seen_message_id=newestPersistentMessage?.id??false;const alreadySeenBySelf=newestPersistentMessage?.isSeenBySelf;if(thread.selfMember){thread.selfMember.lastSeenMessage=newestPersistentMessage;}
if(newestPersistentMessage&&thread.selfMember&&!alreadySeenBySelf){this.rpc("/discuss/channel/set_last_seen_message",{channel_id:thread.id,last_message_id:newestPersistentMessage.id,}).catch((e)=>{if(e.code!==404){throw e;}});}
if(thread.needactionMessages.length>0){this.markAllMessagesAsRead(thread);}}
updateSeen(thread,lastSeenId=thread.newestPersistentOfAllMessage?.id){}
async markAllMessagesAsRead(thread){await this.orm.silent.call("mail.message","mark_all_as_read",[[["model","=",thread.model],["res_id","=",thread.id],],]);Object.assign(thread,{needactionMessages:[],message_unread_counter:0,message_needaction_counter:0,seen_message_id:thread.newestPersistentNotEmptyOfAllMessage?.id,});}
async markAsFetched(thread){await this.orm.silent.call("discuss.channel","channel_fetched",[[thread.id]]);}
getFetchRoute(thread){if(thread.model==="discuss.channel"){return"/discuss/channel/messages";}
switch(thread.type){case"chatter":return"/mail/thread/messages";case"mailbox":return`/mail/${thread.id}/messages`;default:throw new Error(`Unknown thread type: ${thread.type}`);}}
getFetchParams(thread){if(thread.model==="discuss.channel"){return{channel_id:thread.id};}
if(thread.type==="chatter"){return{thread_id:thread.id,thread_model:thread.model,};}
return{};}
async fetchMessages(thread,{after,before}={}){thread.status="loading";if(thread.type==="chatter"&&!thread.id){thread.isLoaded=true;return[];}
try{const{messages:rawMessages}=await this.rpc(this.getFetchRoute(thread),{...this.getFetchParams(thread),limit:FETCH_LIMIT,after,before,});const messages=this.store.Message.insert(rawMessages.reverse(),{html:true});thread.isLoaded=true;return messages;}catch(e){thread.hasLoadingFailed=true;throw e;}finally{thread.status="ready";}}
async fetchNewMessages(thread){if(thread.status==="loading"||(thread.isLoaded&&["discuss.channel","mail.box"].includes(thread.model))){return;}
const after=thread.isLoaded?thread.newestPersistentMessage?.id:undefined;try{const fetched=await this.fetchMessages(thread,{after});let startIndex;if(after===undefined){startIndex=0;}else{const afterIndex=thread.messages.findIndex((message)=>message.id===after);if(afterIndex===-1){return;}else{startIndex=afterIndex+1;}}
const alreadyKnownMessages=new Set(thread.messages.map((m)=>m.id));const filtered=fetched.filter((message)=>!alreadyKnownMessages.has(message.id)&&(thread.persistentMessages.length===0||message.id<thread.oldestPersistentMessage.id||message.id>thread.newestPersistentMessage.id));thread.messages.splice(startIndex,0,...filtered);if(thread.eq(this.store.discuss.inbox)){Record.MAKE_UPDATE(()=>{for(const message of fetched){const thread=message.originThread;if(thread&&message.notIn(thread.needactionMessages)){thread.needactionMessages.unshift(message);}}});}else{const startNeedactionIndex=after===undefined?0:thread.messages.findIndex((message)=>message.id===after);const filteredNeedaction=fetched.filter((message)=>message.isNeedaction&&(thread.needactionMessages.length===0||message.id<thread.needactionMessages[0].id||message.id>thread.needactionMessages.at(-1).id));thread.needactionMessages.splice(startNeedactionIndex,0,...filteredNeedaction);}
Object.assign(thread,{loadOlder:after===undefined&&fetched.length===FETCH_LIMIT?true:after===undefined&&fetched.length!==FETCH_LIMIT?false:thread.loadOlder,});}catch{}}
async loadAround(thread,messageId){if(!thread.messages.some(({id})=>id===messageId)){thread.isLoaded=false;thread.scrollTop=undefined;const{messages}=await this.rpc(this.getFetchRoute(thread),{...this.getFetchParams(thread),around:messageId,});thread.isLoaded=true;thread.messages=this.store.Message.insert(messages.reverse(),{html:true});thread.loadNewer=messageId?true:false;thread.loadOlder=true;if(messages.length<FETCH_LIMIT){const olderMessagesCount=messages.filter(({id})=>id<messageId).length;if(olderMessagesCount<FETCH_LIMIT/2){thread.loadOlder=false;}else{thread.loadNewer=false;}}
this._enrichMessagesWithTransient(thread);}}
fetchPreviews=memoize(async()=>{const ids=[];for(const thread of Object.values(this.store.Thread.records)){if(["channel","group","chat"].includes(thread.type)){ids.push(thread.id);}}
if(ids.length){const previews=await this.orm.call("discuss.channel","channel_fetch_preview",[ids]);Record.MAKE_UPDATE(()=>{for(const preview of previews){const thread=this.store.Thread.get({model:"discuss.channel",id:preview.id,});const message=this.store.Message.insert(preview.last_message,{html:true});if(message.isNeedaction){thread.needactionMessages.add(message);}}});}});async fetchMoreMessages(thread,epoch="older"){if(thread.status==="loading"||(epoch==="older"&&!thread.loadOlder)||(epoch==="newer"&&!thread.loadNewer)){return;}
const before=epoch==="older"?thread.oldestPersistentMessage?.id:undefined;const after=epoch==="newer"?thread.newestPersistentMessage?.id:undefined;try{const fetched=await this.fetchMessages(thread,{after,before});if((after!==undefined&&!thread.messages.some((message)=>message.id===after))||(before!==undefined&&!thread.messages.some((message)=>message.id===before))){return;}
const alreadyKnownMessages=new Set(thread.messages.map(({id})=>id));const messagesToAdd=fetched.filter((message)=>!alreadyKnownMessages.has(message.id));if(epoch==="older"){thread.messages.unshift(...messagesToAdd);}else{thread.messages.push(...messagesToAdd);}
if(fetched.length<FETCH_LIMIT){if(epoch==="older"){thread.loadOlder=false;}else if(epoch==="newer"){thread.loadNewer=false;const missingMessages=thread.pendingNewMessages.filter(({id})=>!alreadyKnownMessages.has(id));if(missingMessages.length>0){thread.messages.push(...missingMessages);thread.messages.sort((m1,m2)=>m1.id-m2.id);}}}
this._enrichMessagesWithTransient(thread);}catch{}
thread.pendingNewMessages=[];}
async unpin(thread){thread.isLocallyPinned=false;if(thread.eq(this.store.discuss.thread)){this.router.replaceState({active_id:undefined});}
if(thread.model==="discuss.channel"&&thread.is_pinned){return this.orm.silent.call("discuss.channel","channel_pin",[thread.id],{pinned:false,});}}
pin(thread){if(thread.model!=="discuss.channel"||!this.store.user){return;}
thread.is_pinned=true;return this.orm.silent.call("discuss.channel","channel_pin",[thread.id],{pinned:true,});}
sortChannels(){this.store.discuss.channels.threads.sort((t1,t2)=>String.prototype.localeCompare.call(t1.name,t2.name));this.store.discuss.chats.threads.sort((t1,t2)=>compareDatetime(t2.lastInterestDateTime,t1.lastInterestDateTime)||t2.id-t1.id);}
open(thread,replaceNewMessageChatWindow,options){this.setDiscussThread(thread);}
async openChat(person){const chat=await this.getChat(person);if(chat){this.open(chat);}}
async getPartner({userId,partnerId}){if(userId){let user=this.store.users[userId];if(!user){this.store.users[userId]={id:userId};user=this.store.users[userId];}
if(!user.partner_id){const[userData]=await this.orm.silent.read("res.users",[user.id],["partner_id"],{context:{active_test:false},});if(userData){user.partner_id=userData.partner_id[0];}}
if(!user.partner_id){this.notificationService.add(_t("You can only chat with existing users."),{type:"warning",});return;}
partnerId=user.partner_id;}
if(partnerId){const partner=this.store.Persona.insert({id:partnerId,type:"partner"});if(!partner.user){const[userId]=await this.orm.silent.search("res.users",[["partner_id","=",partnerId]],{context:{active_test:false}});if(!userId){this.notificationService.add(_t("You can only chat with partners that have a dedicated user."),{type:"info"});return;}
partner.user={id:userId};}
return partner;}}
searchChat(partner){if(!partner){return;}
return Object.values(this.store.Thread.records).find((thread)=>thread.type==="chat"&&thread.chatPartner?.eq(partner));}
async getChat({userId,partnerId}){const partner=await this.getPartner({userId,partnerId});let chat=this.searchChat(partner);if(!chat||!chat.is_pinned){chat=await this.joinChat(partnerId||partner?.id);}
if(!chat){this.notificationService.add(_t("An unexpected error occurred during the creation of the chat."),{type:"warning"});return;}
return chat;}
async joinChannel(id,name){await this.env.services["mail.messaging"].isReady;await this.orm.call("discuss.channel","add_members",[[id]],{partner_ids:[this.store.user.id],});const thread=this.store.Thread.insert({id,model:"discuss.channel",name,type:"channel",channel:{avatarCacheKey:"hello"},});this.open(thread);return thread;}
async joinChat(id){const data=await this.orm.call("discuss.channel","channel_get",[],{partners_to:[id],});const thread=this.store.Thread.insert({...data,model:"discuss.channel",type:"chat",});return thread;}
executeCommand(thread,command,body=""){return this.orm.call("discuss.channel",command.methodName,[[thread.id]],{body,});}
async renameThread(thread,name){if(!thread){return;}
const newName=name.trim();if(newName!==thread.displayName&&((newName&&thread.type==="channel")||thread.type==="chat"||thread.type==="group")){if(thread.type==="channel"||thread.type==="group"){thread.name=newName;await this.orm.call("discuss.channel","channel_rename",[[thread.id]],{name:newName,});}else if(thread.type==="chat"){thread.custom_channel_name=newName;await this.orm.call("discuss.channel","channel_set_custom_name",[[thread.id]],{name:newName,});}}}
async notifyThreadDescriptionToServer(thread,description){thread.description=description;return this.orm.call("discuss.channel","channel_change_description",[[thread.id]],{description,});}
async leaveChannel(channel){await this.orm.call("discuss.channel","action_unfollow",[channel.id]);channel.delete();this.setDiscussThread(this.store.discuss.channels.threads[0]?this.store.discuss.channels.threads[0]:this.store.discuss.inbox);}
setDiscussThread(thread,pushState){if(pushState===undefined){pushState=thread.localId!==this.store.discuss.thread?.localId;}
this.store.discuss.thread=thread;const activeId=typeof thread.id==="string"?`mail.box_${thread.id}`:`discuss.channel_${thread.id}`;this.store.discuss.activeTab=!this.ui.isSmall||thread.model==="mail.box"?"main":["chat","group"].includes(thread.type)?"chat":"channel";if(pushState){this.router.pushState({active_id:activeId});}}
async post(thread,body,{attachments=[],isNote=false,parentId,mentionedChannels=[],mentionedPartners=[],cannedResponseIds,}={}){let tmpMsg;const params=await this.getMessagePostParams({attachments,body,cannedResponseIds,isNote,mentionedChannels,mentionedPartners,thread,});const tmpId=this.messageService.getNextTemporaryId();params.context={...this.user.context,...params.context,temporary_id:tmpId};if(parentId){params.post_data.parent_id=parentId;}
if(thread.type==="chatter"){params.thread_id=thread.id;params.thread_model=thread.model;}else{const tmpData={id:tmpId,attachments:attachments,res_id:thread.id,model:"discuss.channel",};tmpData.author=this.store.self;if(parentId){tmpData.parentMessage=this.store.Message.get(parentId);}
const prettyContent=await prettifyMessageContent(body,this.messageService.getMentionsFromText(body,{mentionedChannels,mentionedPartners,}));const{emojis}=await loadEmoji();const recentEmojis=JSON.parse(browser.localStorage.getItem("web.emoji.frequent")||"{}");const emojisInContent=prettyContent.match(/\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu)??[];for(const codepoints of emojisInContent){if(emojis.some((emoji)=>emoji.codepoints===codepoints)){recentEmojis[codepoints]??=0;recentEmojis[codepoints]++;}}
browser.localStorage.setItem("web.emoji.frequent",JSON.stringify(recentEmojis));tmpMsg=this.store.Message.insert({...tmpData,body:prettyContent,res_id:thread.id,model:thread.model,temporary_id:tmpId,},{html:true});thread.messages.push(tmpMsg);thread.seen_message_id=tmpMsg.id;if(thread.selfMember){thread.selfMember.lastSeenMessage=tmpMsg;}}
const data=await this.rpc(this.getMessagePostRoute(thread),params);tmpMsg?.delete();if(!data){return;}
if(data.id in this.store.Message.records){data.temporary_id=null;}
const message=this.store.Message.insert(data,{html:true});thread.messages.add(message);if(thread.selfMember&&!message.isSeenBySelf){thread.seen_message_id=message.id;thread.selfMember.lastSeenMessage=message;}
if(!message.isEmpty&&this.store.hasLinkPreviewFeature){this.rpc("/mail/link_preview",{message_id:data.id},{silent:true});}
return message;}
async getMessagePostParams({attachments,body,cannedResponseIds,isNote,mentionedChannels,mentionedPartners,thread,}){const subtype=isNote?"mail.mt_note":"mail.mt_comment";const validMentions=this.store.user?this.messageService.getMentionsFromText(body,{mentionedChannels,mentionedPartners,}):undefined;const partner_ids=validMentions?.partners.map((partner)=>partner.id);const recipientEmails=[];const recipientAdditionalValues={};if(!isNote){const recipientIds=thread.suggestedRecipients.filter((recipient)=>recipient.persona&&recipient.checked).map((recipient)=>recipient.persona.id);thread.suggestedRecipients.filter((recipient)=>recipient.checked&&!recipient.persona).forEach((recipient)=>{recipientEmails.push(recipient.email);recipientAdditionalValues[recipient.email]=recipient.defaultCreateValues;});partner_ids?.push(...recipientIds);}
return{context:{mail_post_autofollow:!isNote&&thread.hasWriteAccess,},post_data:{body:await prettifyMessageContent(body,validMentions),attachment_ids:attachments.map(({id})=>id),attachment_tokens:attachments.map((attachment)=>attachment.accessToken),canned_response_ids:cannedResponseIds,message_type:"comment",partner_ids,subtype_xmlid:subtype,partner_emails:recipientEmails,partner_additional_values:recipientAdditionalValues,},thread_id:thread.id,thread_model:thread.model,};}
getMessagePostRoute(thread){return"/mail/message/post";}
canLeave(thread){return(["channel","group"].includes(thread.type)&&!thread.message_needaction_counter&&!thread.group_based_subscription);}
canUnpin(thread){return thread.type==="chat"&&this.getCounter(thread)===0;}
getCounter(thread){if(thread.type==="mailbox"){return thread.counter;}
if(thread.isChatChannel){return thread.message_unread_counter||thread.message_needaction_counter;}
return thread.message_needaction_counter;}
getDiscussSidebarCategoryCounter(categoryId){return this.store.discuss[categoryId].threads.reduce((acc,channel)=>{if(categoryId==="channels"){return channel.message_needaction_counter>0?acc+1:acc;}else{return channel.message_unread_counter>0?acc+1:acc;}},0);}
async setMainAttachmentFromIndex(thread,index){thread.mainAttachment=thread.attachmentsInWebClientView[index];await this.orm.call("ir.attachment","register_as_main_attachment",[thread.mainAttachment.id,]);}
clearComposer(composer){composer.attachments.length=0;composer.textInputContent="";Object.assign(composer.selection,{start:0,end:0,direction:"none",});}
avatarUrl(persona,thread){if(!persona){return DEFAULT_AVATAR;}
const urlParams={};if(persona.write_date){urlParams.unique=persona.write_date;}
if(persona.is_company===undefined&&this.store.self?.user?.isInternalUser){this.personaService.fetchIsCompany(persona);}
if(thread?.model==="discuss.channel"){if(persona.type==="partner"){return url(`/discuss/channel/${thread.id}/partner/${persona.id}/avatar_128`,urlParams);}
if(persona.type==="guest"){return url(`/discuss/channel/${thread.id}/guest/${persona.id}/avatar_128`,urlParams);}}
if(persona.type==="partner"&&persona?.id){const avatar=url("/web/image",{field:"avatar_128",id:persona.id,model:"res.partner",...urlParams,});return avatar;}
if(persona.user?.id){const avatar=url("/web/image",{field:"avatar_128",id:persona.user.id,model:"res.users",...urlParams,});return avatar;}
return DEFAULT_AVATAR;}
async notifyThreadAvatarToServer(threadId,data){await this.rpc("/discuss/channel/update_avatar",{channel_id:threadId,data,});}
notifyMessageToUser(thread,message){let notify=thread.type!=="channel";if(thread.type==="channel"&&message.recipients?.includes(this.store.user)){notify=true;}
if(thread.chatPartner?.eq(this.store.odoobot)||thread.muteUntilDateTime||thread.custom_notifications==="no_notif"||(thread.custom_notifications==="mentions"&&!message.recipients?.includes(this.store.user))){return;}
if(notify){this.store.ChatWindow.insert({thread});this.outOfFocusService.notify(message,thread);}}
_enrichMessagesWithTransient(thread){for(const message of thread.transientMessages){if(message.id<thread.oldestPersistentMessage&&!thread.loadOlder){thread.messages.unshift(message);}else if(message.id>thread.newestPersistentMessage&&!thread.loadNewer){thread.messages.push(message);}else{let afterIndex=thread.messages.findIndex((msg)=>msg.id>message.id);if(afterIndex===-1){afterIndex=thread.messages.length+1;}
thread.messages.splice(afterIndex-1,0,message);}}}
async search(searchTerm,thread,before=false){const{messages,count}=await this.rpc(this.getFetchRoute(thread),{...this.getFetchParams(thread),search_term:await prettifyMessageContent(searchTerm),before,});return{count,loadMore:messages.length===FETCH_LIMIT,messages:this.store.Message.insert(messages,{html:true}),};}}
const threadService=__exports.threadService={dependencies:["mail.store","orm","rpc","notification","router","mail.message","mail.persona","mail.out_of_focus","ui","user",],start(env,services){return new ThreadService(env,services);},};registry.category("services").add("mail.thread",threadService);return __exports;});;

/* /mail/static/src/core/common/user_settings_service.js */
odoo.define('@mail/core/common/user_settings_service',['@web/core/browser/browser','@web/core/registry','@web/core/utils/timing'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{debounce}=require("@web/core/utils/timing");const UserSettings=__exports.UserSettings=class UserSettings{id;constructor(env,services){this.orm=services.orm;this.store=services["mail.store"];this.saveVoiceThresholdDebounce=debounce(()=>{browser.localStorage.setItem("mail_user_setting_voice_threshold",this.voiceActivationThreshold.toString());},2000);this.hasCanvasFilterSupport=typeof document.createElement("canvas").getContext("2d").filter!=="undefined";this._loadLocalSettings();}
updateFromCommands(settings){this.usePushToTalk=settings.use_push_to_talk??this.usePushToTalk;this.pushToTalkKey=settings.push_to_talk_key??this.pushToTalkKey;this.voiceActiveDuration=settings.voice_active_duration??this.voiceActiveDuration;if(!settings.volume_settings_ids){return;}
const volumeRecordSet=settings.volume_settings_ids?.[0][1]??[];this.setVolumes(volumeRecordSet);}
partnerVolumes=new Map();guestVolumes=new Map();audioInputDeviceId="";backgroundBlurAmount=10;edgeBlurAmount=10;isRegisteringKey=false;logRtc=false;pushToTalkKey;usePushToTalk=false;voiceActiveDuration=200;useBlur=false;volumeSettingsTimeouts=new Map();voiceActivationThreshold=0.05;get audioConstraints(){const constraints={echoCancellation:true,noiseSuppression:true,};if(this.audioInputDeviceId){constraints.deviceId=this.audioInputDeviceId;}
return constraints;}
getVolume(rtcSession){return(rtcSession.volume||this.partnerVolumes.get(rtcSession.partnerId)||this.guestVolumes.get(rtcSession.guestId)||0.5);}
async setAudioInputDevice(audioInputDeviceId){this.audioInputDeviceId=audioInputDeviceId;browser.localStorage.setItem("mail_user_setting_audio_input_device_id",audioInputDeviceId);}
setDelayValue(value){this.voiceActiveDuration=parseInt(value,10);this._saveSettings();}
setVolumes(volumeRecordSet){for(const volumeRecord of volumeRecordSet){if(volumeRecord.partner_id){this.partnerVolumes.set(volumeRecord.partner_id.id,volumeRecord.volume);}else if(volumeRecord.guest_id){this.guestVolumes.set(volumeRecord.guest_id.id,volumeRecord.volume);}}}
async setPushToTalkKey(ev){const nonElligibleKeys=new Set(["Shift","Control","Alt","Meta"]);let pushToTalkKey=`${ev.shiftKey || ""}.${ev.ctrlKey || ev.metaKey || ""}.${
            ev.altKey || ""
        }`;if(!nonElligibleKeys.has(ev.key)){pushToTalkKey+=`.${ev.key === " " ? "Space" : ev.key}`;}
this.pushToTalkKey=pushToTalkKey;this._saveSettings();}
async saveVolumeSetting({partnerId,guestId,volume}){if(this.store.self?.type==="guest"){return;}
const key=`${partnerId}_${guestId}`;if(this.volumeSettingsTimeouts.get(key)){browser.clearTimeout(this.volumeSettingsTimeouts.get(key));}
this.volumeSettingsTimeouts.set(key,browser.setTimeout(this._onSaveVolumeSettingTimeout.bind(this,{key,partnerId,guestId,volume}),5000));}
setThresholdValue(voiceActivationThreshold){this.voiceActivationThreshold=voiceActivationThreshold;this.saveVoiceThresholdDebounce();}
buildKeySet({shiftKey,ctrlKey,altKey,key}){const keys=new Set();if(key){keys.add(key==="Meta"?"Alt":key);}
if(shiftKey){keys.add("Shift");}
if(ctrlKey){keys.add("Control");}
if(altKey){keys.add("Alt");}
return keys;}
isPushToTalkKey(ev){if(!this.usePushToTalk||!this.pushToTalkKey){return false;}
const[shiftKey,ctrlKey,altKey,key]=this.pushToTalkKey.split(".");const settingsKeySet=this.buildKeySet({shiftKey,ctrlKey,altKey,key});const eventKeySet=this.buildKeySet({shiftKey:ev.shiftKey,ctrlKey:ev.ctrlKey,altKey:ev.altKey,key:ev.key,});if(ev.type==="keydown"){return[...settingsKeySet].every((key)=>eventKeySet.has(key));}
return settingsKeySet.has(ev.key==="Meta"?"Alt":ev.key);}
pushToTalkKeyFormat(){if(!this.pushToTalkKey){return;}
const[shiftKey,ctrlKey,altKey,key]=this.pushToTalkKey.split(".");return{shiftKey:!!shiftKey,ctrlKey:!!ctrlKey,altKey:!!altKey,key:key||false,};}
togglePushToTalk(){this.usePushToTalk=!this.usePushToTalk;this._saveSettings();}
_loadLocalSettings(){const voiceActivationThresholdString=browser.localStorage.getItem("mail_user_setting_voice_threshold");this.voiceActivationThreshold=voiceActivationThresholdString?parseFloat(voiceActivationThresholdString):this.voiceActivationThreshold;this.audioInputDeviceId=browser.localStorage.getItem("mail_user_setting_audio_input_device_id");}
_onStorage(ev){if(ev.key==="mail_user_setting_voice_threshold"){this.voiceActivationThreshold=ev.newValue;}}
async _onSaveGlobalSettingsTimeout(){this.globalSettingsTimeout=undefined;await this.orm.call("res.users.settings","set_res_users_settings",[[this.id]],{new_settings:{push_to_talk_key:this.pushToTalkKey,use_push_to_talk:this.usePushToTalk,voice_active_duration:this.voiceActiveDuration,},});}
async _onSaveVolumeSettingTimeout({key,partnerId,guestId,volume}){this.volumeSettingsTimeouts.delete(key);await this.orm.call("res.users.settings","set_volume_setting",[[this.id],partnerId,volume],{guest_id:guestId,});}
async _saveSettings(){if(this.store.self?.type==="guest"){return;}
browser.clearTimeout(this.globalSettingsTimeout);this.globalSettingsTimeout=browser.setTimeout(()=>this._onSaveGlobalSettingsTimeout(),2000);}}
const userSettingsService=__exports.userSettingsService={dependencies:["orm","mail.store"],start(env,services){return new UserSettings(env,services);},};registry.category("services").add("mail.user_settings",userSettingsService);return __exports;});;

/* /mail/static/src/discuss/core/common/action_panel.js */
odoo.define('@mail/discuss/core/common/action_panel',['@odoo/owl'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const ActionPanel=__exports.ActionPanel=class ActionPanel extends Component{static template="mail.ActionPanel";static props={title:{type:String,optional:true},slots:{type:Object,optional:true},};}
return __exports;});;

/* /mail/static/src/discuss/core/common/attachment_model_patch.js */
odoo.define('@mail/discuss/core/common/attachment_model_patch',['@mail/core/common/attachment_model','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{Attachment}=require("@mail/core/common/attachment_model");const{patch}=require("@web/core/utils/patch");patch(Attachment.prototype,{get isDeletable(){if(this.message&&this.originThread?.model==="discuss.channel"){return this.message.editable;}
return super.isDeletable;},get urlRoute(){if(!this.accessToken&&this.originThread?.model==="discuss.channel"){return this.isImage?`/discuss/channel/${this.originThread.id}/image/${this.id}`:`/discuss/channel/${this.originThread.id}/attachment/${this.id}`;}
return super.urlRoute;},});return __exports;});;

/* /mail/static/src/discuss/core/common/attachment_panel.js */
odoo.define('@mail/discuss/core/common/attachment_panel',['@mail/core/common/date_section','@mail/discuss/core/common/action_panel','@mail/core/common/attachment_list','@odoo/owl','@web/core/utils/hooks','@mail/utils/common/hooks'],function(require){'use strict';let __exports={};const{DateSection}=require("@mail/core/common/date_section");const{ActionPanel}=require("@mail/discuss/core/common/action_panel");const{AttachmentList}=require("@mail/core/common/attachment_list");const{Component,onWillStart,onWillUpdateProps}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{useSequential,useVisible}=require("@mail/utils/common/hooks");const AttachmentPanel=__exports.AttachmentPanel=class AttachmentPanel extends Component{static components={ActionPanel,AttachmentList,DateSection};static props=["thread"];static template="mail.AttachmentPanel";setup(){this.sequential=useSequential();this.store=useService("mail.store");this.ormService=useService("orm");this.threadService=useService("mail.thread");this.attachmentUploadService=useService("mail.attachment_upload");onWillStart(()=>{this.threadService.fetchMoreAttachments(this.props.thread);});onWillUpdateProps((nextProps)=>{if(nextProps.thread.notEq(this.props.thread)){this.threadService.fetchMoreAttachments(nextProps.thread);}});const loadOlderState=useVisible("load-older",()=>{if(loadOlderState.isVisible){this.threadService.fetchMoreAttachments(this.props.thread);}});}
get attachmentsByDate(){const attachmentsByDate={};for(const attachment of this.props.thread.attachments){const attachments=attachmentsByDate[attachment.monthYear]??[];attachments.push(attachment);attachmentsByDate[attachment.monthYear]=attachments;}
return attachmentsByDate;}
get hasToggleAllowPublicUpload(){return(this.props.thread.model!=="mail.box"&&this.props.thread.type!=="chat"&&this.store.user?.user?.isInternalUser);}
toggleAllowPublicUpload(){this.sequential(()=>this.ormService.write("discuss.channel",[this.props.thread.id],{allow_public_upload:!this.props.thread.allow_public_upload,}));}}
return __exports;});;

/* /mail/static/src/discuss/core/common/attachment_upload_service_patch.js */
odoo.define('@mail/discuss/core/common/attachment_upload_service_patch',['@mail/core/common/attachment_upload_service','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{AttachmentUploadService}=require("@mail/core/common/attachment_upload_service");const{patch}=require("@web/core/utils/patch");patch(AttachmentUploadService.prototype,{setup(){super.setup(...arguments);this.env.services["bus_service"].subscribe("mail.record/insert",({Thread})=>{if(Thread&&"allow_public_upload"in Thread&&!Thread.allow_public_upload&&!this.store.user?.user?.isInternalUser){const attachments=[...this.store.Thread.insert(Thread).composer.attachments];for(const attachment of attachments){this.unlink(attachment);}}});},});return __exports;});;

/* /mail/static/src/discuss/core/common/channel_commands.js */
odoo.define('@mail/discuss/core/common/channel_commands',['@web/core/l10n/translation','@web/core/registry'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const commandRegistry=registry.category("discuss.channel_commands");commandRegistry.add("help",{help:_t("Show a helper message"),methodName:"execute_command_help",}).add("leave",{help:_t("Leave this channel"),methodName:"execute_command_leave",}).add("who",{channel_types:["channel","chat","group"],help:_t("List users in the current channel"),methodName:"execute_command_who",});return __exports;});;

/* /mail/static/src/discuss/core/common/channel_invitation.js */
odoo.define('@mail/discuss/core/common/channel_invitation',['@mail/core/common/im_status','@mail/discuss/core/common/action_panel','@odoo/owl','@web/core/l10n/translation','@web/core/utils/hooks','@mail/utils/common/hooks'],function(require){'use strict';let __exports={};const{ImStatus}=require("@mail/core/common/im_status");const{ActionPanel}=require("@mail/discuss/core/common/action_panel");const{Component,onMounted,onWillStart,useRef,useState}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const{useSequential}=require("@mail/utils/common/hooks");const ChannelInvitation=__exports.ChannelInvitation=class ChannelInvitation extends Component{static components={ImStatus,ActionPanel};static defaultProps={hasSizeConstraints:false};static props=["hasSizeConstraints?","thread","close","className?"];static template="discuss.ChannelInvitation";setup(){this.discussCoreCommonService=useState(useService("discuss.core.common"));this.orm=useService("orm");this.store=useState(useService("mail.store"));this.notification=useService("notification");this.threadService=useState(useService("mail.thread"));this.suggestionService=useService("mail.suggestion");this.ui=useService("ui");this.inputRef=useRef("input");this.sequential=useSequential();this.searchStr="";this.state=useState({selectablePartners:[],selectedPartners:[],searchResultCount:0,});onWillStart(()=>{if(this.store.user){this.fetchPartnersToInvite();}});onMounted(()=>{if(this.store.user){this.inputRef.el.focus();}});}
async fetchPartnersToInvite(){const results=await this.sequential(()=>this.orm.call("res.partner","search_for_channel_invite",[this.searchStr,this.props.thread.id,]));if(!results){return;}
const selectablePartners=this.store.Persona.insert(results.partners);this.state.selectablePartners=this.suggestionService.sortPartnerSuggestions(selectablePartners,this.searchStr,this.props.thread);this.state.searchResultCount=results["count"];}
onInput(){this.searchStr=this.inputRef.el.value;this.fetchPartnersToInvite();}
onClickSelectablePartner(partner){if(partner.in(this.state.selectedPartners)){const index=this.state.selectedPartners.indexOf(partner);if(index!==-1){this.state.selectedPartners.splice(index,1);}
return;}
this.state.selectedPartners.push(partner);}
onClickSelectedPartner(partner){const index=this.state.selectedPartners.indexOf(partner);this.state.selectedPartners.splice(index,1);}
onFocusInvitationLinkInput(ev){ev.target.select();}
async onClickCopy(ev){await navigator.clipboard.writeText(this.props.thread.invitationLink);this.notification.add(_t("Link copied!"),{type:"success"});}
async onClickInvite(){if(this.props.thread.type==="chat"){await this.discussCoreCommonService.startChat([this.props.thread.chatPartner?.id,...this.state.selectedPartners.map((partner)=>partner.id),]);}else{await this.orm.call("discuss.channel","add_members",[[this.props.thread.id]],{partner_ids:this.state.selectedPartners.map((partner)=>partner.id),});}
this.props.close();}
get invitationButtonText(){if(this.props.thread.type==="channel"){return _t("Invite to Channel");}else if(this.props.thread.type==="group"){return _t("Invite to Group Chat");}else if(this.props.thread.type==="chat"){if(this.props.thread.chatPartner?.eq(this.store.self)){if(this.state.selectedPartners.length===0){return _t("Invite");}
if(this.state.selectedPartners.length===1){const alreadyChat=Object.values(this.store.Thread.records).some((thread)=>thread.chatPartner?.eq(this.state.selectedPartners[0]));if(alreadyChat){return _t("Go to conversation");}
return _t("Start a Conversation");}}
return _t("Create Group Chat");}
return _t("Invite");}
get title(){return _t("Invite people");}}
return __exports;});;

/* /mail/static/src/discuss/core/common/channel_member_list.js */
odoo.define('@mail/discuss/core/common/channel_member_list',['@mail/core/common/im_status','@mail/discuss/core/common/action_panel','@odoo/owl','@web/core/l10n/translation','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{ImStatus}=require("@mail/core/common/im_status");const{ActionPanel}=require("@mail/discuss/core/common/action_panel");const{Component,onWillUpdateProps,onWillStart,useState,onWillRender}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const ChannelMemberList=__exports.ChannelMemberList=class ChannelMemberList extends Component{static components={ImStatus,ActionPanel};static props=["thread","openChannelInvitePanel","className?"];static template="discuss.ChannelMemberList";setup(){this.store=useState(useService("mail.store"));this.channelMemberService=useService("discuss.channel.member");this.threadService=useState(useService("mail.thread"));onWillStart(()=>{if(this.props.thread.fetchMembersState==="not_fetched"){this.threadService.fetchChannelMembers(this.props.thread);}});onWillUpdateProps((nextProps)=>{if(nextProps.thread.fetchMembersState==="not_fetched"){this.threadService.fetchChannelMembers(nextProps.thread);}});onWillRender(()=>{this.onlineMembers=this.props.thread.onlineMembers;this.offlineMembers=this.props.thread.offlineMembers;});}
canOpenChatWith(member){if(this.store.inPublicPage){return false;}
if(member.persona?.eq(this.store.self)){return false;}
if(member.persona.type==="guest"){return false;}
return true;}
openChatAvatar(member){if(!this.canOpenChatWith(member)){return;}
this.threadService.openChat({partnerId:member.persona.id});}
get title(){return _t("Member List");}}
return __exports;});;

/* /mail/static/src/discuss/core/common/composer_patch.js */
odoo.define('@mail/discuss/core/common/composer_patch',['@mail/core/common/composer','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{Composer}=require("@mail/core/common/composer");const{patch}=require("@web/core/utils/patch");patch(Composer.prototype,{get allowUpload(){const thread=this.thread??this.message.originThread;return(super.allowUpload&&(thread.model!=="discuss.channel"||thread?.allow_public_upload||this.store.user?.user?.isInternalUser));},});return __exports;});;

/* /mail/static/src/discuss/core/common/discuss_core_common_service.js */
odoo.define('@mail/discuss/core/common/discuss_core_common_service',['@mail/core/common/record','@odoo/owl','@web/core/l10n/translation','@web/core/registry'],function(require){'use strict';let __exports={};const{Record}=require("@mail/core/common/record");const{reactive}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const DiscussCoreCommon=__exports.DiscussCoreCommon=class DiscussCoreCommon{constructor(env,services){this.busService=services.bus_service;this.env=env;this.notificationService=services.notification;this.orm=services.orm;this.presence=services.presence;this.rpc=services.rpc;this.messageService=services["mail.message"];this.messagingService=services["mail.messaging"];this.store=services["mail.store"];this.threadService=services["mail.thread"];}
insertInitChannel(data){return this.createChannelThread(data);}
setup(){this.busService.addEventListener("connect",()=>this.store.imStatusTrackedPersonas.forEach((p)=>{const model=p.type==="partner"?"res.partner":"mail.guest";this.busService.addChannel(`odoo-presence-${model}_${p.id}`);}),{once:true});this.messagingService.isReady.then((data)=>{Record.MAKE_UPDATE(()=>{for(const channelData of data.channels){this.insertInitChannel(channelData);}});this.busService.subscribe("discuss.channel/joined",(payload)=>{const{channel,invited_by_user_id:invitedByUserId}=payload;const thread=this.store.Thread.insert({...channel,model:"discuss.channel",type:channel.channel_type,});if(invitedByUserId&&invitedByUserId!==this.store.user?.user?.id){this.notificationService.add(_t("You have been invited to #%s",thread.displayName),{type:"info"});}});this.busService.subscribe("discuss.channel/last_interest_dt_changed",(payload)=>{this.store.Thread.insert({model:"discuss.channel",...payload});});this.busService.subscribe("discuss.channel/leave",(payload)=>{const thread=this.store.Thread.insert({...payload,model:"discuss.channel",});this.notificationService.add(_t("You unsubscribed from %s.",thread.displayName),{type:"info",});thread.delete();});this.busService.subscribe("discuss.channel/delete",(payload)=>{const thread=this.store.Thread.insert({id:payload.id,model:"discuss.channel",});const filteredStarredMessages=[];let starredCounter=0;for(const msg of this.store.discuss.starred.messages){if(!msg.originThread?.eq(thread)){filteredStarredMessages.push(msg);}else{starredCounter++;}}
this.store.discuss.starred.messages=filteredStarredMessages;this.store.discuss.starred.counter-=starredCounter;this.store.discuss.inbox.messages=this.store.discuss.inbox.messages.filter((msg)=>!msg.originThread?.eq(thread));this.store.discuss.inbox.counter-=thread.message_needaction_counter;this.store.discuss.history.messages=this.store.discuss.history.messages.filter((msg)=>!msg.originThread?.eq(thread));this.threadService.closeChatWindow?.(thread);if(thread.eq(this.store.discuss.thread)){this.threadService.setDiscussThread(this.store.discuss.inbox);}
thread.messages.splice(0,thread.messages.length);thread.delete();});this.busService.addEventListener("notification",({detail:notifications})=>{const channelsLeft=new Set(notifications.filter(({type})=>type==="discuss.channel/leave").map(({payload})=>payload.id));for(const notif of notifications.filter(({payload,type})=>type==="discuss.channel/new_message"&&!channelsLeft.has(payload.id))){this._handleNotificationNewMessage(notif);}});this.busService.subscribe("discuss.channel/transient_message",(payload)=>{const channel=this.store.Thread.get({model:"discuss.channel",id:payload.res_id,});const{body,res_id,model}=payload;const lastMessageId=this.messageService.getLastMessageId();const message=this.store.Message.insert({author:this.store.odoobot,body,id:lastMessageId+0.01,is_note:true,is_transient:true,res_id,model,},{html:true});channel.messages.push(message);channel.transientMessages.push(message);});this.busService.subscribe("discuss.channel/unpin",(payload)=>{const thread=this.store.Thread.get({model:"discuss.channel",id:payload.id});if(thread){thread.is_pinned=false;this.notificationService.add(_t("You unpinned your conversation with %s",thread.displayName),{type:"info"});}});this.busService.subscribe("discuss.channel.member/fetched",(payload)=>{const{channel_id,id,last_message_id,partner_id}=payload;this.store.ChannelMember.insert({id,lastFetchedMessage:{id:last_message_id},persona:{type:"partner",id:partner_id},thread:{id:channel_id,model:"discuss.channel"},});});this.env.bus.addEventListener("mail.message/delete",({detail:{message}})=>{if(message.originThread){if(message.id>message.originThread.seen_message_id){message.originThread.message_unread_counter--;}}});});}
createChannelThread(serverData){const thread=this.store.Thread.insert({...serverData,model:"discuss.channel",type:serverData.channel_type,isAdmin:serverData.channel_type!=="group"&&serverData.create_uid===this.store.user?.user?.id,});return thread;}
async createGroupChat({default_display_mode,partners_to}){const data=await this.orm.call("discuss.channel","create_group",[],{default_display_mode,partners_to,});const channel=this.createChannelThread(data);this.threadService.open(channel);return channel;}
async startChat(partnerIds,inChatWindow){const partners_to=[...new Set([this.store.self.id,...partnerIds])];if(partners_to.length===1){const chat=await this.threadService.joinChat(partners_to[0]);this.threadService.open(chat,inChatWindow);}else if(partners_to.length===2){const correspondentId=partners_to.find((partnerId)=>partnerId!==this.store.self.id);const chat=await this.threadService.joinChat(correspondentId);this.threadService.open(chat,inChatWindow);}else{await this.createGroupChat({partners_to});}}
async _handleNotificationNewMessage(notif){const{id,message:messageData}=notif.payload;let channel=this.store.Thread.get({model:"discuss.channel",id});if(!channel||!channel.type){channel=await this.threadService.fetchChannel(id);if(!channel){return;}}
this.store.Message.get(messageData.temporary_id)?.delete();messageData.temporary_id=null;const message=this.store.Message.insert(messageData,{html:true});if(message.notIn(channel.messages)){if(!channel.loadNewer){channel.messages.push(message);}else if(channel.status==="loading"){channel.pendingNewMessages.push(message);}
if(message.isSelfAuthored){channel.seen_message_id=message.id;}else{if(notif.id>channel.message_unread_counter_bus_id){channel.message_unread_counter++;}}}
if(!channel.chatPartner?.eq(this.store.odoobot)&&channel.type!=="channel"&&this.store.user){this.threadService.markAsFetched(channel);}
if(!channel.loadNewer&&!message.isSelfAuthored&&channel.composer.isFocused&&!this.store.guest&&channel.newestPersistentMessage?.eq(channel.newestMessage)){this.threadService.markAsRead(channel);}
this.env.bus.trigger("discuss.channel/new_message",{channel,message});}}
const discussCoreCommon=__exports.discussCoreCommon={dependencies:["bus_service","mail.message","mail.messaging","mail.out_of_focus","mail.store","mail.thread","notification","orm","presence","rpc",],start(env,services){const discussCoreCommon=reactive(new DiscussCoreCommon(env,services));discussCoreCommon.setup(env,services);return discussCoreCommon;},};registry.category("services").add("discuss.core.common",discussCoreCommon);return __exports;});;

/* /mail/static/src/discuss/core/common/notification_settings.js */
odoo.define('@mail/discuss/core/common/notification_settings',['@odoo/owl','@web/core/dropdown/dropdown','@web/core/dropdown/dropdown_item','@web/core/l10n/translation','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{useState,Component}=require("@odoo/owl");const{Dropdown}=require("@web/core/dropdown/dropdown");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const NotificationSettings=__exports.NotificationSettings=class NotificationSettings extends Component{static components={Dropdown,DropdownItem};static props=["hasSizeConstraints?","thread","close","className?"];static template="discuss.NotificationSettings";setup(){this.threadService=useState(useService("mail.thread"));}
get muteUntilText(){if(this.props.thread.muteUntilDateTime&&this.props.thread.muteUntilDateTime.year<=new Date().getFullYear()+2){return _t("Until ")+this.props.thread.muteUntilDateTime.toFormat("MM/dd, HH:mm");}
return undefined;}
selectUnmute(){this.threadService.muteThread(this.props.thread);this.props.close();}
setMute(minutes){this.threadService.muteThread(this.props.thread,{minutes});this.props.close();}
setSetting(setting){this.threadService.updateCustomNotifications(this.props.thread,setting.id);}}
return __exports;});;

/* /mail/static/src/discuss/core/common/partner_compare.js */
odoo.define('@mail/discuss/core/common/partner_compare',['@mail/core/common/partner_compare'],function(require){'use strict';let __exports={};const{partnerCompareRegistry}=require("@mail/core/common/partner_compare");partnerCompareRegistry.add("discuss.recent-chats",(p1,p2,{env,context})=>{const recentChatPartnerIds=context.recentChatPartnerIds||env.services["mail.persona"].getRecentChatPartnerIds();const recentChatIndex_p1=recentChatPartnerIds.findIndex((partnerId)=>partnerId===p1.id);const recentChatIndex_p2=recentChatPartnerIds.findIndex((partnerId)=>partnerId===p2.id);if(recentChatIndex_p1!==-1&&recentChatIndex_p2===-1){return-1;}else if(recentChatIndex_p1===-1&&recentChatIndex_p2!==-1){return 1;}else if(recentChatIndex_p1<recentChatIndex_p2){return-1;}else if(recentChatIndex_p1>recentChatIndex_p2){return 1;}},{sequence:25});partnerCompareRegistry.add("discuss.members",(p1,p2,{thread,memberPartnerIds})=>{if(thread?.model==="discuss.channel"){const isMember1=memberPartnerIds.has(p1.id);const isMember2=memberPartnerIds.has(p2.id);if(isMember1&&!isMember2){return-1;}
if(!isMember1&&isMember2){return 1;}}},{sequence:40});return __exports;});;

/* /mail/static/src/discuss/core/common/store_service_patch.js */
odoo.define('@mail/discuss/core/common/store_service_patch',['@mail/core/common/store_service','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{Store}=require("@mail/core/common/store_service");const{patch}=require("@web/core/utils/patch");const storePatch={onLinkFollowed(fromThread){if(!this.env.isSmall&&fromThread?.model==="discuss.channel"){this.env.services["mail.thread"].open(fromThread,true,{autofocus:false});}},};patch(Store.prototype,storePatch);return __exports;});;

/* /mail/static/src/discuss/core/common/suggestion_service_patch.js */
odoo.define('@mail/discuss/core/common/suggestion_service_patch',['@mail/core/common/suggestion_service','@mail/utils/common/format','@web/core/registry','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{SuggestionService}=require("@mail/core/common/suggestion_service");const{cleanTerm}=require("@mail/utils/common/format");const{registry}=require("@web/core/registry");const{patch}=require("@web/core/utils/patch");const commandRegistry=registry.category("discuss.channel_commands");patch(SuggestionService.prototype,{getSupportedDelimiters(thread){const res=super.getSupportedDelimiters(thread);return thread?.model==="discuss.channel"?[...res,["/",0]]:res;},searchSuggestions({delimiter,term},{thread,sort=false}={}){if(delimiter==="/"){return this.searchChannelCommand(cleanTerm(term),thread,sort);}
return super.searchSuggestions(...arguments);},searchChannelCommand(cleanedSearchTerm,thread,sort){if(!thread.model==="discuss.channel"){return;}
const commands=commandRegistry.getEntries().filter(([name,command])=>{if(!cleanTerm(name).includes(cleanedSearchTerm)){return false;}
if(command.channel_types){return command.channel_types.includes(thread.type);}
return true;}).map(([name,command])=>{return{channel_types:command.channel_types,help:command.help,id:command.id,name,};});const sortFunc=(c1,c2)=>{if(c1.channel_types&&!c2.channel_types){return-1;}
if(!c1.channel_types&&c2.channel_types){return 1;}
const cleanedName1=cleanTerm(c1.name);const cleanedName2=cleanTerm(c2.name);if(cleanedName1.startsWith(cleanedSearchTerm)&&!cleanedName2.startsWith(cleanedSearchTerm)){return-1;}
if(!cleanedName1.startsWith(cleanedSearchTerm)&&cleanedName2.startsWith(cleanedSearchTerm)){return 1;}
if(cleanedName1<cleanedName2){return-1;}
if(cleanedName1>cleanedName2){return 1;}
return c1.id-c2.id;};return{type:"ChannelCommand",mainSuggestions:sort?commands.sort(sortFunc):commands,};},});return __exports;});;

/* /mail/static/src/discuss/core/common/thread_actions.js */
odoo.define('@mail/discuss/core/common/thread_actions',['@mail/core/common/thread_actions','@mail/discuss/core/common/attachment_panel','@mail/discuss/core/common/channel_invitation','@mail/discuss/core/common/channel_member_list','@mail/discuss/core/common/notification_settings','@odoo/owl','@web/core/l10n/translation','@web/core/popover/popover_hook'],function(require){'use strict';let __exports={};const{threadActionsRegistry}=require("@mail/core/common/thread_actions");const{AttachmentPanel}=require("@mail/discuss/core/common/attachment_panel");const{ChannelInvitation}=require("@mail/discuss/core/common/channel_invitation");const{ChannelMemberList}=require("@mail/discuss/core/common/channel_member_list");const{NotificationSettings}=require("@mail/discuss/core/common/notification_settings");const{useComponent}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{usePopover}=require("@web/core/popover/popover_hook");threadActionsRegistry.add("notification-settings",{condition(component){return(component.thread?.model==="discuss.channel"&&!component.props.chatWindow&&component.store.self.type!=="guest");},setup(action){const component=useComponent();if(!component.props.chatWindow){action.popover=usePopover(NotificationSettings,{onClose:()=>action.close(),position:"bottom-end",fixedPosition:true,popoverClass:action.panelOuterClass,});}},open(component,action){action.popover?.open(component.root.el.querySelector(`[name="${action.id}"]`),{hasSizeConstraints:true,thread:component.thread,});},close(component,action){action.popover?.close();},component:NotificationSettings,icon(component){return component.thread.muteUntilDateTime?"fa fa-fw text-danger fa-bell-slash":"fa fa-fw fa-bell";},iconLarge(component){return component.thread.muteUntilDateTime?"fa fa-fw fa-lg text-danger fa-bell-slash":"fa fa-fw fa-lg fa-bell";},name:_t("Notification Settings"),sequence:5,toggle:true,}).add("attachments",{condition:(component)=>component.thread?.hasAttachmentPanel&&(!component.props.chatWindow||component.props.chatWindow.isOpen),component:AttachmentPanel,icon:"fa fa-fw fa-paperclip",iconLarge:"fa fa-fw fa-lg fa-paperclip",name:_t("Show Attachments"),nameActive:_t("Hide Attachments"),sequence:25,toggle:true,}).add("add-users",{close(component,action){action.popover?.close();},component:ChannelInvitation,componentProps(action){return{close:()=>action.close()};},condition(component){return(component.thread?.model==="discuss.channel"&&(!component.props.chatWindow||component.props.chatWindow.isOpen));},panelOuterClass:"o-discuss-ChannelInvitation",icon:"fa fa-fw fa-user-plus",iconLarge:"fa fa-fw fa-lg fa-user-plus",name:_t("Add Users"),nameActive:_t("Stop Adding Users"),open(component,action){action.popover?.open(component.root.el.querySelector(`[name="${action.id}"]`),{hasSizeConstraints:true,thread:component.thread,});},sequence:30,setup(action){const component=useComponent();if(!component.props.chatWindow){action.popover=usePopover(ChannelInvitation,{onClose:()=>action.close(),popoverClass:action.panelOuterClass,});}},toggle:true,}).add("member-list",{component:ChannelMemberList,condition(component){return(component.thread?.hasMemberList&&(!component.props.chatWindow||component.props.chatWindow.isOpen));},componentProps(action,component){return{openChannelInvitePanel({keepPrevious}={}){component.threadActions.actions.find(({id})=>id==="add-users")?.open({keepPrevious});},};},panelOuterClass:"o-discuss-ChannelMemberList",icon:"fa fa-fw fa-users",iconLarge:"fa fa-fw fa-lg fa-users",name:_t("Show Member List"),nameActive:_t("Hide Member List"),sequence:40,toggle:true,});return __exports;});;

/* /mail/static/src/discuss/core/common/thread_model_patch.js */
odoo.define('@mail/discuss/core/common/thread_model_patch',['@mail/core/common/thread_model','@mail/utils/common/misc','@web/core/utils/patch','@web/core/utils/urls','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{Thread}=require("@mail/core/common/thread_model");const{assignDefined}=require("@mail/utils/common/misc");const{patch}=require("@web/core/utils/patch");const{url}=require("@web/core/utils/urls");const{_t}=require("@web/core/l10n/translation");patch(Thread.prototype,{get SETTINGS(){return[{id:false,name:_t("All Messages"),},{id:"mentions",name:_t("Mentions Only"),},{id:"no_notif",name:_t("Nothing"),},];},get MUTES(){return[{id:"15_mins",value:15,name:_t("For 15 minutes"),},{id:"1_hour",value:60,name:_t("For 1 hour"),},{id:"3_hours",value:180,name:_t("For 3 hours"),},{id:"8_hours",value:480,name:_t("For 8 hours"),},{id:"24_hours",value:1440,name:_t("For 24 hours"),},{id:"forever",value:-1,name:_t("Until I turn it back on"),},];},get imgUrl(){if(this.type==="channel"||this.type==="group"){return url(`/discuss/channel/${this.id}/avatar_128`,assignDefined({},{unique:this.avatarCacheKey}));}
if(this.type==="chat"){return url(`/web/image/res.partner/${this.chatPartner.id}/avatar_128`,assignDefined({},{unique:this.chatPartner.write_date}));}
return super.imgUrl;},update(data){super.update(data);assignDefined(this,data,["allow_public_upload"]);},});return __exports;});;

/* /mail/static/src/discuss/core/common/thread_service_patch.js */
odoo.define('@mail/discuss/core/common/thread_service_patch',['@mail/core/common/thread_service','@web/core/registry','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{ThreadService}=require("@mail/core/common/thread_service");const{registry}=require("@web/core/registry");const{patch}=require("@web/core/utils/patch");const commandRegistry=registry.category("discuss.channel_commands");patch(ThreadService.prototype,{async post(thread,body){if(thread.model==="discuss.channel"&&body.startsWith("/")){const[firstWord]=body.substring(1).split(/\s/);const command=commandRegistry.get(firstWord,false);if(command&&(!command.channel_types||command.channel_types.includes(thread.type))){await this.executeCommand(thread,command,body);return;}}
return super.post(...arguments);},async fetchMoreAttachments(thread,limit=30){if(thread.isLoadingAttachments||thread.areAttachmentsLoaded){return;}
thread.isLoadingAttachments=true;try{const rawAttachments=await this.rpc("/discuss/channel/attachments",{before:Math.min(...thread.attachments.map(({id})=>id)),channel_id:thread.id,limit,});const attachments=this.store.Attachment.insert(rawAttachments);if(attachments.length<limit){thread.areAttachmentsLoaded=true;}}finally{thread.isLoadingAttachments=false;}},async muteThread(thread,{minutes=false}={}){await this.rpc("/discuss/channel/mute",{channel_id:thread.id,minutes});},async updateCustomNotifications(thread,custom_notifications){thread.custom_notifications=custom_notifications;await this.rpc("/discuss/channel/update_custom_notifications",{channel_id:thread.id,custom_notifications,});},});return __exports;});;

/* /mail/static/src/discuss/call/common/blur_manager.js */
odoo.define('@mail/discuss/call/common/blur_manager',['@mail/utils/common/misc','@web/core/browser/browser'],function(require){'use strict';let __exports={};const{closeStream}=require("@mail/utils/common/misc");const{browser}=require("@web/core/browser/browser");function drawAndBlurImageOnCanvas(image,blurAmount,canvas){canvas.width=image.width;canvas.height=image.height;if(blurAmount===0){canvas.getContext("2d").drawImage(image,0,0,image.width,image.height);return;}
canvas.getContext("2d").clearRect(0,0,image.width,image.height);canvas.getContext("2d").save();canvas.getContext("2d").filter=`blur(${blurAmount}px)`;canvas.getContext("2d").drawImage(image,0,0,image.width,image.height);canvas.getContext("2d").restore();}
const BlurManager=__exports.BlurManager=class BlurManager{canvas=document.createElement("canvas");canvasBlur=document.createElement("canvas");canvasMask=document.createElement("canvas");canvasStream;isVideoDataLoaded=false;rejectStreamPromise;resolveStreamPromise;selfieSegmentation=new window.SelfieSegmentation({locateFile:(file)=>{return`https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation@0.1/${file}`;},});stream;video=document.createElement("video");constructor(stream,{backgroundBlur=10,edgeBlur=10,modelSelection=1,selfieMode=false}={}){this.edgeBlur=edgeBlur;this.backgroundBlur=backgroundBlur;this._onVideoPlay=this._onVideoPlay.bind(this);this.video.addEventListener("loadeddata",this._onVideoPlay);this.canvas.getContext("2d");this.canvasStream=this.canvas.captureStream();let rejectStreamPromise;let resolveStreamPromise;Object.assign(this,{stream:new Promise((resolve,reject)=>{rejectStreamPromise=reject;resolveStreamPromise=resolve;}),rejectStreamPromise,resolveStreamPromise,});this.video.srcObject=stream;this.video.load();this.selfieSegmentation.setOptions({selfieMode,modelSelection,});this.selfieSegmentation.onResults((r)=>this._onSelfieSegmentationResults(r));this.video.autoplay=true;Promise.resolve(this.video.play()).catch(()=>{});}
close(){this.video.removeEventListener("loadeddata",this._onVideoPlay);this.video.srcObject=null;this.isVideoDataLoaded=false;this.selfieSegmentation.reset();closeStream(this.canvasStream);this.canvasStream=null;if(this.rejectStreamPromise){this.rejectStreamPromise(new Error("The source stream was removed before the beginning of the blur process"));}}
_drawWithCompositing(image,compositeOperation){this.canvas.getContext("2d").globalCompositeOperation=compositeOperation;this.canvas.getContext("2d").drawImage(image,0,0);}
_onVideoPlay(){this.isVideoDataLoaded=true;this._requestFrame();}
async _onFrame(){if(!this.selfieSegmentation){return;}
if(!this.video){return;}
if(!this.isVideoDataLoaded){return;}
await this.selfieSegmentation.send({image:this.video});browser.setTimeout(()=>this._requestFrame(),Math.floor(1000/30));}
_onSelfieSegmentationResults(results){drawAndBlurImageOnCanvas(results.image,this.backgroundBlur,this.canvasBlur);this.canvas.width=this.canvasBlur.width;this.canvas.height=this.canvasBlur.height;drawAndBlurImageOnCanvas(results.segmentationMask,this.edgeBlur,this.canvasMask);this.canvas.getContext("2d").save();this.canvas.getContext("2d").drawImage(results.image,0,0,this.canvas.width,this.canvas.height);this._drawWithCompositing(this.canvasMask,"destination-in");this._drawWithCompositing(this.canvasBlur,"destination-over");this.canvas.getContext("2d").restore();}
_requestFrame(){browser.requestAnimationFrame(async()=>{await this._onFrame();this.resolveStreamPromise(this.canvasStream);});}}
return __exports;});;

/* /mail/static/src/discuss/call/common/call.js */
odoo.define('@mail/discuss/call/common/call',['@mail/discuss/call/common/call_action_list','@mail/discuss/call/common/call_participant_card','@web/core/utils/misc','@odoo/owl','@web/core/browser/browser','@web/core/l10n/translation','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{CallActionList}=require("@mail/discuss/call/common/call_action_list");const{CallParticipantCard}=require("@mail/discuss/call/common/call_participant_card");const{isEventHandled,markEventHandled}=require("@web/core/utils/misc");const{Component,onMounted,onPatched,onWillUnmount,useExternalListener,useRef,useState,}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const Call=__exports.Call=class Call extends Component{static components={CallActionList,CallParticipantCard};static props=["thread","compact?"];static template="discuss.Call";overlayTimeout;setup(){this.grid=useRef("grid");this.call=useRef("call");this.notification=useService("notification");this.rtc=useState(useService("discuss.rtc"));this.state=useState({isFullscreen:false,sidebar:false,tileWidth:0,tileHeight:0,columnCount:0,overlay:false,insetCard:undefined,});this.store=useState(useService("mail.store"));this.userSettings=useState(useService("mail.user_settings"));onMounted(()=>{this.resizeObserver=new ResizeObserver(()=>this.arrangeTiles());this.resizeObserver.observe(this.grid.el);this.arrangeTiles();});onPatched(()=>this.arrangeTiles());onWillUnmount(()=>{this.resizeObserver.disconnect();browser.clearTimeout(this.overlayTimeout);});useExternalListener(browser,"fullscreenchange",this.onFullScreenChange);}
get isActiveCall(){return Boolean(this.props.thread.eq(this.rtc.state?.channel));}
get minimized(){if(this.state.isFullscreen||this.props.compact||this.props.thread.activeRtcSession){return false;}
if(!this.isActiveCall||this.props.thread.videoCount===0){return true;}
return false;}
get visibleCards(){const raisingHandCards=[];const sessionCards=[];const invitationCards=[];const filterVideos=this.props.thread.showOnlyVideo&&this.props.thread.videoCount>0;for(const session of this.props.thread.rtcSessions){const target=session.raisingHand?raisingHandCards:sessionCards;const cameraStream=session.isCameraOn?session.videoStreams.get("camera"):undefined;if(!filterVideos||cameraStream){target.push({key:"session_main_"+session.id,session,type:"camera",videoStream:cameraStream,});}
const screenStream=session.isScreenSharingOn?session.videoStreams.get("screen"):undefined;if(screenStream){target.push({key:"session_secondary_"+session.id,session,type:"screen",videoStream:screenStream,});}}
if(!filterVideos){for(const member of this.props.thread.invitedMembers){invitationCards.push({key:"member_"+member.id,member,});}}
raisingHandCards.sort((c1,c2)=>{return c1.session.raisingHand-c2.session.raisingHand;});sessionCards.sort((c1,c2)=>{return(c1.session.channelMember?.persona?.name?.localeCompare(c2.session.channelMember?.persona?.name)??1);});invitationCards.sort((c1,c2)=>{return c1.member.persona?.name?.localeCompare(c2.member.persona?.name)??1;});return raisingHandCards.concat(sessionCards,invitationCards);}
get visibleMainCards(){const activeSession=this.props.thread.activeRtcSession;this.state.insetCard=undefined;if(!activeSession){return this.visibleCards;}
const type=activeSession.mainVideoStreamType;if(type==="screen"||activeSession.isScreenSharingOn){this.setInset(activeSession,type==="camera"?"screen":"camera");}
return[{key:"session_"+activeSession.id,session:activeSession,type,videoStream:activeSession.getStream(type),},];}
setInset(session,videoType){this.state.insetCard={key:"session_"+session.id,session,type:videoType,videoStream:session.getStream(videoType),};}
get hasCallNotifications(){return Boolean((!this.props.compact||this.state.isFullscreen)&&this.isActiveCall&&this.rtc.notifications.size);}
get hasSidebarButton(){return Boolean(this.props.thread.activeRtcSession&&this.state.overlay&&!this.props.compact);}
get isControllerFloating(){return(this.state.isFullscreen||(this.props.thread.activeRtcSession&&!this.props.compact));}
onMouseleaveMain(ev){if(ev.relatedTarget&&ev.relatedTarget.closest(".o-discuss-Call-overlay")){return;}
this.state.overlay=false;}
onMousemoveMain(ev){if(isEventHandled(ev,"CallMain.MousemoveOverlay")){return;}
this.showOverlay();}
onMousemoveOverlay(ev){markEventHandled(ev,"CallMain.MousemoveOverlay");this.state.overlay=true;browser.clearTimeout(this.overlayTimeout);}
showOverlay(){this.state.overlay=true;browser.clearTimeout(this.overlayTimeout);this.overlayTimeout=browser.setTimeout(()=>{this.state.overlay=false;},3000);}
arrangeTiles(){if(!this.grid.el){return;}
const{width,height}=this.grid.el.getBoundingClientRect();const aspectRatio=this.minimized?1:16/9;const tileCount=this.grid.el.children.length;let optimal={area:0,columnCount:0,tileHeight:0,tileWidth:0,};for(let columnCount=1;columnCount<=tileCount;columnCount++){const rowCount=Math.ceil(tileCount/columnCount);const potentialHeight=width/(columnCount*aspectRatio);const potentialWidth=height/rowCount;let tileHeight;let tileWidth;if(potentialHeight>potentialWidth){tileHeight=Math.floor(potentialWidth);tileWidth=Math.floor(tileHeight*aspectRatio);}else{tileWidth=Math.floor(width/columnCount);tileHeight=Math.floor(tileWidth/aspectRatio);}
const area=tileHeight*tileWidth;if(area<=optimal.area){continue;}
optimal={area,columnCount,tileHeight,tileWidth,};}
Object.assign(this.state,{tileWidth:optimal.tileWidth,tileHeight:optimal.tileHeight,columnCount:optimal.columnCount,});}
async enterFullScreen(){const el=this.call.el;try{if(el.requestFullscreen){await el.requestFullscreen();}else if(el.mozRequestFullScreen){await el.mozRequestFullScreen();}else if(el.webkitRequestFullscreen){await el.webkitRequestFullscreen();}
this.state.isFullscreen=true;}catch{this.state.isFullscreen=false;this.notification.add(_t("The Fullscreen mode was denied by the browser"),{type:"warning",});}}
async exitFullScreen(){const fullscreenElement=document.webkitFullscreenElement||document.fullscreenElement;if(fullscreenElement){if(document.exitFullscreen){await document.exitFullscreen();}else if(document.mozCancelFullScreen){await document.mozCancelFullScreen();}else if(document.webkitCancelFullScreen){await document.webkitCancelFullScreen();}}
this.state.isFullscreen=false;}
onFullScreenChange(){this.state.isFullscreen=Boolean(document.webkitFullscreenElement||document.fullscreenElement);}}
return __exports;});;

/* /mail/static/src/discuss/call/common/call_action_list.js */
odoo.define('@mail/discuss/call/common/call_action_list',['@odoo/owl','@web/core/browser/feature_detection','@web/core/dropdown/dropdown','@web/core/dropdown/dropdown_item','@web/core/l10n/translation','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,useState}=require("@odoo/owl");const{isMobileOS}=require("@web/core/browser/feature_detection");const{Dropdown}=require("@web/core/dropdown/dropdown");const{DropdownItem}=require("@web/core/dropdown/dropdown_item");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const CallActionList=__exports.CallActionList=class CallActionList extends Component{static components={Dropdown,DropdownItem};static props=["thread","fullscreen","compact?"];static template="discuss.CallActionList";setup(){this.rtc=useState(useService("discuss.rtc"));}
get MORE(){return _t("More");}
get moreActions(){const acts=[];acts.push({id:"raiseHand",name:!this.rtc.state?.selfSession.raisingHand?_t("Raise Hand"):_t("Lower Hand"),icon:"fa fa-fw fa-hand-paper-o",onSelect:(ev)=>this.onClickRaiseHand(ev),});if(!isMobileOS()){acts.push({id:"shareScreen",name:!this.rtc.state.sendScreen?_t("Share Screen"):_t("Stop Sharing Screen"),icon:"fa fa-fw fa-desktop",onSelect:()=>this.rtc.toggleVideo("screen"),});}
if(!this.props.fullscreen.isActive){acts.push({id:"fullScreen",name:_t("Enter Full Screen"),icon:"fa fa-fw fa-arrows-alt",onSelect:()=>this.props.fullscreen.enter(),});}else{acts.push({id:"exitFullScreen",name:_t("Exit Full Screen"),icon:"fa fa-fw fa-compress",onSelect:()=>this.props.fullscreen.exit(),});}
return acts;}
get isOfActiveCall(){return Boolean(this.props.thread.eq(this.rtc.state?.channel));}
get isSmall(){return Boolean(this.props.compact&&!this.props.fullscreen.isActive);}
get isMobileOS(){return isMobileOS();}
async onClickDeafen(ev){if(this.rtc.state.selfSession.isDeaf){this.rtc.undeafen();}else{this.rtc.deafen();}}
async onClickRaiseHand(ev){this.rtc.raiseHand(!this.rtc.state.selfSession.raisingHand);}
onClickMicrophone(ev){if(this.rtc.state.selfSession.isMute){if(this.rtc.state.selfSession.isSelfMuted){this.rtc.unmute();}
if(this.rtc.state.selfSession.isDeaf){this.rtc.undeafen();}}else{this.rtc.mute();}}
async onClickRejectCall(ev){if(this.rtc.state.hasPendingRequest){return;}
await this.rtc.leaveCall(this.props.thread);}
async onClickToggleAudioCall(ev){await this.rtc.toggleCall(this.props.thread);}}
return __exports;});;

/* /mail/static/src/discuss/call/common/call_context_menu.js */
odoo.define('@mail/discuss/call/common/call_context_menu',['@odoo/owl','@web/core/browser/browser','@web/core/l10n/translation','@web/core/utils/hooks','@mail/discuss/call/common/rtc_service'],function(require){'use strict';let __exports={};const{Component,onMounted,onWillUnmount,useState}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const{CONNECTION_TYPES}=require("@mail/discuss/call/common/rtc_service");const PROTOCOLS_TEXT={host:"HOST",srflx:"STUN",prflx:"STUN",relay:"TURN"};const CallContextMenu=__exports.CallContextMenu=class CallContextMenu extends Component{static props=["rtcSession","close?"];static template="discuss.CallContextMenu";updateStatsTimeout;rtcConnectionTypes=CONNECTION_TYPES;setup(){this.userSettings=useState(useService("mail.user_settings"));this.rtc=useState(useService("discuss.rtc"));this.state=useState({downloadStats:{},uploadStats:{},producerStats:{},});onMounted(()=>{if(!this.env.debug){return;}
this.updateStats();this.updateStatsTimeout=browser.setInterval(()=>this.updateStats(),3000);});onWillUnmount(()=>browser.clearInterval(this.updateStatsTimeout));}
get isSelf(){return this.rtc.state.selfSession?.eq(this.props.rtcSession);}
get inboundConnectionTypeText(){const candidateType=this.rtc.state.connectionType===CONNECTION_TYPES.SERVER?this.state.downloadStats.remoteCandidateType:this.props.rtcSession.remoteCandidateType;return this.formatProtocol(candidateType);}
get outboundConnectionTypeText(){const candidateType=this.rtc.state.connectionType===CONNECTION_TYPES.SERVER?this.state.uploadStats.localCandidateType:this.props.rtcSession.localCandidateType;return this.formatProtocol(candidateType);}
get volume(){return this.userSettings.getVolume(this.props.rtcSession);}
formatProtocol(candidateType){if(!candidateType){return _t("no connection");}
return _t("%(candidateType)s (%(protocol)s)",{candidateType,protocol:PROTOCOLS_TEXT[candidateType],});}
async updateStats(){if(this.rtc.state.selfSession?.eq(this.props.rtcSession)){if(this.rtc.sfuClient){const{uploadStats,downloadStats,...producerStats}=await this.rtc.sfuClient.getStats();const formattedUploadStats={};for(const value of uploadStats.values?.()||[]){switch(value.type){case"candidate-pair":if(value.state==="succeeded"&&value.localCandidateId){formattedUploadStats.localCandidateType=uploadStats.get(value.localCandidateId)?.candidateType||"";formattedUploadStats.availableOutgoingBitrate=value.availableOutgoingBitrate;}
break;case"transport":formattedUploadStats.dtlsState=value.dtlsState;formattedUploadStats.iceState=value.iceState;formattedUploadStats.packetsSent=value.packetsSent;break;}}
const formattedDownloadStats={};for(const value of downloadStats.values?.()||[]){switch(value.type){case"candidate-pair":if(value.state==="succeeded"&&value.localCandidateId){formattedDownloadStats.remoteCandidateType=downloadStats.get(value.remoteCandidateId)?.candidateType||"";}
break;case"transport":formattedDownloadStats.dtlsState=value.dtlsState;formattedDownloadStats.iceState=value.iceState;formattedDownloadStats.packetsReceived=value.packetsReceived;break;}}
const formattedProducerStats={};for(const[type,stat]of Object.entries(producerStats)){const currentTypeStats={};for(const value of stat.values()){switch(value.type){case"codec":currentTypeStats.codec=value.mimeType;currentTypeStats.clockRate=value.clockRate;break;}}
formattedProducerStats[type]=currentTypeStats;}
this.state.uploadStats=formattedUploadStats;this.state.downloadStats=formattedDownloadStats;this.state.producerStats=formattedProducerStats;}
return;}
await this.props.rtcSession.updateStats();}
onChangeVolume(ev){const volume=Number(ev.target.value);this.userSettings.saveVolumeSetting({guestId:this.props.rtcSession?.guestId,partnerId:this.props.rtcSession?.partnerId,volume,});this.props.rtcSession.volume=volume;}}
return __exports;});;

/* /mail/static/src/discuss/call/common/call_invitation.js */
odoo.define('@mail/discuss/call/common/call_invitation',['@odoo/owl','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const CallInvitation=__exports.CallInvitation=class CallInvitation extends Component{static props=["thread"];static template="discuss.CallInvitation";setup(){this.threadService=useService("mail.thread");this.rtc=useService("discuss.rtc");}
async onClickAccept(ev){this.threadService.open(this.props.thread);if(this.rtc.state.hasPendingRequest){return;}
await this.rtc.toggleCall(this.props.thread);}
onClickAvatar(ev){this.threadService.open(this.props.thread);}
onClickRefuse(ev){if(this.rtc.state.hasPendingRequest){return;}
this.rtc.leaveCall(this.props.thread);}}
return __exports;});;

/* /mail/static/src/discuss/call/common/call_invitations.js */
odoo.define('@mail/discuss/call/common/call_invitations',['@mail/discuss/call/common/call_invitation','@odoo/owl','@web/core/registry','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{CallInvitation}=require("@mail/discuss/call/common/call_invitation");const{Component,useState}=require("@odoo/owl");const{registry}=require("@web/core/registry");const{useService}=require("@web/core/utils/hooks");const CallInvitations=__exports.CallInvitations=class CallInvitations extends Component{static props=[];static components={CallInvitation};static template="discuss.CallInvitations";setup(){this.rtc=useState(useService("discuss.rtc"));this.store=useState(useService("mail.store"));}}
registry.category("main_components").add("discuss.CallInvitations",{Component:CallInvitations});return __exports;});;

/* /mail/static/src/discuss/call/common/call_menu.js */
odoo.define('@mail/discuss/call/common/call_menu',['@odoo/owl','@web/core/registry','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,useState}=require("@odoo/owl");const{registry}=require("@web/core/registry");const{useService}=require("@web/core/utils/hooks");const CallMenu=__exports.CallMenu=class CallMenu extends Component{static props=[];static template="discuss.CallMenu";setup(){this.threadService=useService("mail.thread");this.rtc=useState(useService("discuss.rtc"));}}
registry.category("systray").add("discuss.CallMenu",{Component:CallMenu},{sequence:100});return __exports;});;

/* /mail/static/src/discuss/call/common/call_participant_card.js */
odoo.define('@mail/discuss/call/common/call_participant_card',['@mail/discuss/call/common/call_context_menu','@mail/discuss/call/common/call_participant_video','@mail/utils/common/hooks','@web/core/utils/misc','@web/core/browser/browser','@odoo/owl','@web/core/popover/popover_hook','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{CallContextMenu}=require("@mail/discuss/call/common/call_context_menu");const{CallParticipantVideo}=require("@mail/discuss/call/common/call_participant_video");const{useHover}=require("@mail/utils/common/hooks");const{isEventHandled,markEventHandled}=require("@web/core/utils/misc");const{browser}=require("@web/core/browser/browser");const{Component,onMounted,onWillUnmount,useRef,useState,useExternalListener,}=require("@odoo/owl");const{usePopover}=require("@web/core/popover/popover_hook");const{useService}=require("@web/core/utils/hooks");const HIDDEN_CONNECTION_STATES=new Set(["connected","completed"]);const CallParticipantCard=__exports.CallParticipantCard=class CallParticipantCard extends Component{static props=["className","cardData","thread","minimized?","inset?"];static components={CallParticipantVideo};static template="discuss.CallParticipantCard";setup(){this.contextMenuAnchorRef=useRef("contextMenuAnchor");this.root=useRef("root");this.popover=usePopover(CallContextMenu);this.rpc=useService("rpc");this.rtc=useState(useService("discuss.rtc"));this.store=useState(useService("mail.store"));this.ui=useState(useService("ui"));this.rootHover=useHover("root");this.threadService=useService("mail.thread");this.state=useState({drag:false,dragPos:undefined});onMounted(()=>{if(!this.rtcSession){return;}
this.rtc.updateVideoDownload(this.rtcSession,{viewCountIncrement:1,});});onWillUnmount(()=>{if(!this.rtcSession){return;}
this.rtc.updateVideoDownload(this.rtcSession,{viewCountIncrement:-1,});});useExternalListener(browser,"fullscreenchange",this.onFullScreenChange);}
get isContextMenuAvailable(){if(!this.rtcSession){return false;}
if(this.env.debug){return true;}
return!this.rtcSession?.eq(this.rtc.state.selfSession);}
get rtcSession(){return this.props.cardData.session;}
get channelMember(){return this.rtcSession?this.rtcSession.channelMember:this.props.cardData.member;}
get isOfActiveCall(){return Boolean(this.rtcSession&&this.rtcSession.channel?.eq(this.rtc.state.channel));}
get showConnectionState(){return Boolean(this.isOfActiveCall&&this.rtcSession?.peerConnection&&!HIDDEN_CONNECTION_STATES.has(this.rtcSession.connectionState));}
get showServerState(){return Boolean(this.rtcSession.channelMember?.persona.eq(this.store.self)&&this.rtc.state.serverState&&this.rtc.state.serverState!=="connected");}
get name(){return this.channelMember?.persona.name;}
get hasMediaError(){return(this.isOfActiveCall&&Boolean(this.rtcSession?.videoError||this.rtcSession?.audioError));}
get hasVideo(){return Boolean(this.props.cardData.videoStream);}
get isTalking(){return Boolean(this.rtcSession&&this.rtcSession.isTalking&&!this.rtcSession.isMute);}
get hasRaisingHand(){const screenStream=this.rtcSession.videoStreams.get("screen");return Boolean(this.rtcSession.raisingHand&&(!screenStream||screenStream!==this.props.cardData.videoStream));}
async onClick(ev){if(isEventHandled(ev,"CallParticipantCard.clickVolumeAnchor")){return;}
if(this.state.drag){this.state.drag=false;return;}
if(this.rtcSession){const channel=this.rtcSession.channel;this.rtcSession.mainVideoStreamType=this.props.cardData.type;if(this.rtcSession.eq(channel.activeRtcSession)&&!this.props.inset){channel.activeRtcSession=undefined;this.rtcSession.mainVideoStreamType=undefined;}else{const activeRtcSession=channel.activeRtcSession;const currentMainVideoType=this.rtcSession.mainVideoStreamType;channel.activeRtcSession=this.rtcSession;if(this.props.inset&&activeRtcSession){this.props.inset(activeRtcSession,currentMainVideoType);}}
return;}
const channelData=await this.rpc("/mail/rtc/channel/cancel_call_invitation",{channel_id:this.props.thread.id,member_ids:[this.channelMember.id],});this.props.thread.invitedMembers=channelData.invitedMembers;}
async onClickReplay(){this.env.bus.trigger("RTC-SERVICE:PLAY_MEDIA");}
onContextMenu(ev){ev.preventDefault();markEventHandled(ev,"CallParticipantCard.clickVolumeAnchor");if(this.popover.isOpen){this.popover.close();return;}
if(!this.contextMenuAnchorRef?.el){return;}
this.popover.open(this.contextMenuAnchorRef.el,{rtcSession:this.rtcSession,});}
onMouseDown(){if(!this.props.inset){return;}
const onMousemove=(ev)=>this.drag(ev);const onMouseup=()=>{const insetEl=this.root.el;if(parseInt(insetEl.style.left)<insetEl.parentNode.offsetWidth/2){insetEl.style.left="1vh";insetEl.style.right="";}else{insetEl.style.left="";insetEl.style.right="1vh";}
if(parseInt(insetEl.style.top)<insetEl.parentNode.offsetHeight/2){insetEl.style.top="1vh";insetEl.style.bottom="";}else{insetEl.style.bottom="1vh";insetEl.style.top="";}
document.removeEventListener("mouseup",onMouseup);document.removeEventListener("mousemove",onMousemove);};document.addEventListener("mouseup",onMouseup);document.addEventListener("mousemove",onMousemove);}
drag(ev){this.state.drag=true;const insetEl=this.root.el;const parent=insetEl.parentNode;const clientX=ev.clientX??ev.touches[0].clientX;const clientY=ev.clientY??ev.touches[0].clientY;if(!this.state.dragPos){this.state.dragPos={posX:clientX,posY:clientY};}
const dX=this.state.dragPos.posX-clientX;const dY=this.state.dragPos.posY-clientY;this.state.dragPos.posX=Math.min(Math.max(clientX,parent.offsetLeft),parent.offsetLeft+parent.offsetWidth-insetEl.clientWidth);this.state.dragPos.posY=Math.min(Math.max(clientY,parent.offsetTop),parent.offsetTop+parent.offsetHeight-insetEl.clientHeight);insetEl.style.left=Math.min(Math.max(insetEl.offsetLeft-dX,0),parent.offsetWidth-insetEl.clientWidth)+"px";insetEl.style.top=Math.min(Math.max(insetEl.offsetTop-dY,0),parent.offsetHeight-insetEl.clientHeight)+"px";}
onFullScreenChange(){this.root.el.style="left:''; top:''";}}
return __exports;});;

/* /mail/static/src/discuss/call/common/call_participant_video.js */
odoo.define('@mail/discuss/call/common/call_participant_video',['@odoo/owl','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,onMounted,onPatched,useExternalListener,useRef,useState}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const CallParticipantVideo=__exports.CallParticipantVideo=class CallParticipantVideo extends Component{static props=["session","type","inset?"];static template="discuss.CallParticipantVideo";setup(){this.rtc=useState(useService("discuss.rtc"));this.root=useRef("root");onMounted(()=>this._update());onPatched(()=>this._update());useExternalListener(this.env.bus,"RTC-SERVICE:PLAY_MEDIA",async()=>{await this.play();});}
_update(){if(!this.root.el){return;}
if(!this.props.session||!this.props.session.getStream(this.props.type)){this.root.el.srcObject=undefined;}else{this.root.el.srcObject=this.props.session.getStream(this.props.type);}
this.root.el.load();}
async play(){try{await this.root.el?.play?.();this.props.session.videoError=undefined;}catch(error){this.props.session.videoError=error.name;}}
async onVideoLoadedMetaData(){await this.play();}}
return __exports;});;

/* /mail/static/src/discuss/call/common/call_settings.js */
odoo.define('@mail/discuss/call/common/call_settings',['@mail/discuss/core/common/action_panel','@odoo/owl','@web/core/l10n/translation','@web/core/browser/browser','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{ActionPanel}=require("@mail/discuss/core/common/action_panel");const{Component,onWillStart,useExternalListener,useState}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{browser}=require("@web/core/browser/browser");const{useService}=require("@web/core/utils/hooks");const CallSettings=__exports.CallSettings=class CallSettings extends Component{static components={ActionPanel};static template="discuss.CallSettings";static props=["thread","className?"];setup(){this.notification=useService("notification");this.userSettings=useState(useService("mail.user_settings"));this.rtc=useState(useService("discuss.rtc"));this.state=useState({userDevices:[],});useExternalListener(browser,"keydown",this._onKeyDown,{capture:true});useExternalListener(browser,"keyup",this._onKeyUp,{capture:true});onWillStart(async()=>{if(!browser.navigator.mediaDevices){this.notification.add(_t("Media devices unobtainable. SSL might not be set up properly."),{type:"warning"});console.warn("Media devices unobtainable. SSL might not be set up properly.");return;}
this.state.userDevices=await browser.navigator.mediaDevices.enumerateDevices();});}
get pushToTalkKeyText(){const{shiftKey,ctrlKey,altKey,key}=this.userSettings.pushToTalkKeyFormat();const f=(k,name)=>(k?name:"");const keys=[f(ctrlKey,"Ctrl"),f(altKey,"Alt"),f(shiftKey,"Shift"),key].filter(Boolean);return keys.join(" + ");}
_onKeyDown(ev){if(!this.userSettings.isRegisteringKey){return;}
ev.stopPropagation();ev.preventDefault();this.userSettings.setPushToTalkKey(ev);}
_onKeyUp(ev){if(!this.userSettings.isRegisteringKey){return;}
ev.stopPropagation();ev.preventDefault();this.userSettings.isRegisteringKey=false;}
onChangeLogRtcCheckbox(ev){this.userSettings.logRtc=ev.target.checked;}
onChangeSelectAudioInput(ev){this.userSettings.setAudioInputDevice(ev.target.value);}
onChangePushToTalk(){if(this.userSettings.usePushToTalk){this.userSettings.isRegisteringKey=false;}
this.userSettings.togglePushToTalk();}
onClickDownloadLogs(){const data=JSON.stringify(Object.fromEntries(this.rtc.state.logs));const blob=new Blob([data],{type:"application/json"});const downloadLink=document.createElement("a");const channelId=this.rtc.state.logs.get("channelId");const sessionId=this.rtc.state.logs.get("selfSessionId");const now=luxon.DateTime.now().toFormat("yyyy-ll-dd_HH-mm");downloadLink.download=`RtcLogs_Channel_${channelId}_Session_${sessionId}_${now}.json`;const url=URL.createObjectURL(blob);downloadLink.href=url;downloadLink.click();URL.revokeObjectURL(url);}
onClickRegisterKeyButton(){this.userSettings.isRegisteringKey=!this.userSettings.isRegisteringKey;}
onChangeDelay(ev){this.userSettings.setDelayValue(ev.target.value);}
onChangeThreshold(ev){this.userSettings.setThresholdValue(parseFloat(ev.target.value));}
onChangeBlur(ev){this.userSettings.useBlur=ev.target.checked;}
onChangeVideoFilterCheckbox(ev){const showOnlyVideo=ev.target.checked;this.props.thread.showOnlyVideo=showOnlyVideo;const activeRtcSession=this.props.thread.activeRtcSession;if(showOnlyVideo&&activeRtcSession&&!activeRtcSession.videoStream){this.props.thread.activeRtcSession=undefined;}}
onChangeBackgroundBlurAmount(ev){this.userSettings.backgroundBlurAmount=Number(ev.target.value);}
onChangeEdgeBlurAmount(ev){this.userSettings.edgeBlurAmount=Number(ev.target.value);}
get title(){return _t("Voice Settings");}}
return __exports;});;

/* /mail/static/src/discuss/call/common/chat_window_patch.js */
odoo.define('@mail/discuss/call/common/chat_window_patch',['@mail/core/common/chat_window','@mail/discuss/call/common/call'],function(require){'use strict';let __exports={};const{ChatWindow}=require("@mail/core/common/chat_window");const{Call}=require("@mail/discuss/call/common/call");Object.assign(ChatWindow.components,{Call});return __exports;});;

/* /mail/static/src/discuss/call/common/discuss_app_model_patch.js */
odoo.define('@mail/discuss/call/common/discuss_app_model_patch',['@mail/core/common/discuss_app_model','@mail/core/common/record','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{DiscussApp}=require("@mail/core/common/discuss_app_model");const{Record}=require("@mail/core/common/record");const{patch}=require("@web/core/utils/patch");patch(DiscussApp,{new(data){const app=super.new(data);Record.onChange(app,"ringingThreads",()=>{if(app.ringingThreads.length>0){this.env.services["mail.sound_effects"].play("incoming-call",{loop:true});}else{this.env.services["mail.sound_effects"].stop("incoming-call");}});return app;},});patch(DiscussApp.prototype,{setup(){super.setup();this.ringingThreads=Record.many("Thread");},});return __exports;});;

/* /mail/static/src/discuss/call/common/discuss_patch.js */
odoo.define('@mail/discuss/call/common/discuss_patch',['@mail/core/common/discuss','@mail/discuss/call/common/call','@odoo/owl','@web/core/utils/hooks','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{Discuss}=require("@mail/core/common/discuss");const{Call}=require("@mail/discuss/call/common/call");const{useState}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{patch}=require("@web/core/utils/patch");Object.assign(Discuss.components,{Call});patch(Discuss.prototype,{setup(){super.setup(...arguments);this.rtc=useState(useService("discuss.rtc"));},});return __exports;});;

/* /mail/static/src/discuss/call/common/media_monitoring.js */
odoo.define('@mail/discuss/call/common/media_monitoring',[],function(require){'use strict';let __exports={};const HUMAN_VOICE_FREQUENCY_RANGE=[80,1000];__exports.monitorAudio=monitorAudio;async function monitorAudio(track,processorOptions){const monitoredTrack=track.clone();monitoredTrack.enabled=true;const stream=new window.MediaStream([monitoredTrack]);const AudioContext=window.AudioContext||window.webkitAudioContext;if(!AudioContext){throw"missing audio context";}
const audioContext=new AudioContext();const source=audioContext.createMediaStreamSource(stream);let processor;try{processor=await _loadAudioWorkletProcessor(source,audioContext,processorOptions);}catch{processor=_loadScriptProcessor(source,audioContext,processorOptions);}
return async()=>{processor.disconnect();source.disconnect();monitoredTrack.stop();try{await audioContext.close();}catch(e){if(e.name==="InvalidStateError"){return;}
throw e;}};}
function _loadScriptProcessor(source,audioContext,{frequencyRange=HUMAN_VOICE_FREQUENCY_RANGE,minimumActiveCycles=30,onThreshold,onTic,volumeThreshold=0.3,}={}){const bitSize=1024;const analyser=audioContext.createAnalyser();source.connect(analyser);const scriptProcessorNode=audioContext.createScriptProcessor(bitSize,1,1);analyser.connect(scriptProcessorNode);analyser.fftsize=bitSize;scriptProcessorNode.connect(audioContext.destination);const processInterval=50;const intervalInFrames=(processInterval/1000)*analyser.context.sampleRate;let nextUpdateFrame=processInterval;let activityBuffer=0;let wasAboveThreshold=undefined;let isAboveThreshold=false;scriptProcessorNode.onaudioprocess=()=>{nextUpdateFrame-=bitSize;if(nextUpdateFrame>=0){return;}
nextUpdateFrame+=intervalInFrames;const normalizedVolume=getFrequencyAverage(analyser,frequencyRange[0],frequencyRange[1]);if(normalizedVolume>=volumeThreshold){activityBuffer=minimumActiveCycles;}else if(normalizedVolume<volumeThreshold&&activityBuffer>0){activityBuffer--;}
isAboveThreshold=activityBuffer>0;onTic?.(normalizedVolume);if(wasAboveThreshold!==isAboveThreshold){wasAboveThreshold=isAboveThreshold;onThreshold?.(isAboveThreshold);}};return{disconnect:()=>{analyser.disconnect();scriptProcessorNode.disconnect();scriptProcessorNode.onaudioprocess=null;},};}
async function _loadAudioWorkletProcessor(source,audioContext,{frequencyRange=HUMAN_VOICE_FREQUENCY_RANGE,minimumActiveCycles=10,onThreshold,onTic,volumeThreshold=0.3,}={}){await audioContext.resume();await audioContext.audioWorklet.addModule("/mail/rtc/audio_worklet_processor");const thresholdProcessor=new window.AudioWorkletNode(audioContext,"audio-processor",{processorOptions:{minimumActiveCycles,volumeThreshold,frequencyRange,postAllTics:!!onTic,},});source.connect(thresholdProcessor);thresholdProcessor.port.onmessage=(event)=>{const{isAboveThreshold,volume}=event.data;if(isAboveThreshold!==undefined){onThreshold?.(isAboveThreshold);}
if(volume!==undefined){onTic?.(volume);}};return{disconnect:()=>{thresholdProcessor.disconnect();},};}
function getFrequencyAverage(analyser,lowerFrequency,higherFrequency){const frequencies=new window.Uint8Array(analyser.frequencyBinCount);analyser.getByteFrequencyData(frequencies);const sampleRate=analyser.context.sampleRate;const startIndex=_getFrequencyIndex(lowerFrequency,sampleRate,analyser.frequencyBinCount);const endIndex=_getFrequencyIndex(higherFrequency,sampleRate,analyser.frequencyBinCount);const count=endIndex-startIndex;let sum=0;for(let index=startIndex;index<endIndex;index++){sum+=frequencies[index]/255;}
if(!count){return 0;}
return sum/count;}
function _getFrequencyIndex(targetFrequency,sampleRate,binCount){const index=Math.round((targetFrequency/(sampleRate/2))*binCount);return Math.min(Math.max(0,index),binCount);}
return __exports;});;

/* /mail/static/src/discuss/call/common/ptt_extension_service.js */
odoo.define('@mail/discuss/call/common/ptt_extension_service',['@mail/utils/common/misc','@web/core/browser/browser','@web/core/registry'],function(require){'use strict';let __exports={};const{parseVersion}=require("@mail/utils/common/misc");const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const pttExtensionHookService=__exports.pttExtensionHookService={start(env){const INITIAL_RELEASE_TIMEOUT=500;const COMMON_RELEASE_TIMEOUT=200;const EXT_ID="mdiacebcbkmjjlpclnbcgiepgifcnpmg";const versionPromise=window.chrome?.runtime?.sendMessage(EXT_ID,{type:"ask-version"})??Promise.resolve("1.0.0.0");let isEnabled=false;let voiceActivated=false;browser.addEventListener("message",({data,origin,source})=>{const rtc=env.services["discuss.rtc"];if(source!==window||origin!==location.origin||data.from!=="discuss-push-to-talk"||(!rtc&&data.type!=="answer-is-enabled")){return;}
switch(data.type){case"push-to-talk-pressed":{voiceActivated=false;const isFirstPress=!rtc.state.selfSession?.isTalking;rtc.onPushToTalk();if(rtc.state.selfSession?.isTalking){rtc.setPttReleaseTimeout(isFirstPress?INITIAL_RELEASE_TIMEOUT:COMMON_RELEASE_TIMEOUT);}}
break;case"toggle-voice":{if(voiceActivated){rtc.setPttReleaseTimeout(0);}else{rtc.onPushToTalk();}
voiceActivated=!voiceActivated;}
break;case"answer-is-enabled":isEnabled=true;break;}});async function sendMessage(type,value){if(!isEnabled&&type!=="ask-is-enabled"){return;}
const version=parseVersion(await versionPromise);if(version.isLowerThan("1.0.0.2")){window.postMessage({from:"discuss",type,value},location.origin);return;}
window.chrome?.runtime?.sendMessage(EXT_ID,{type,value});}
sendMessage("ask-is-enabled");return{notifyIsTalking(isTalking){sendMessage("is-talking",isTalking);},subscribe(){sendMessage("subscribe");},unsubscribe(){voiceActivated=false;sendMessage("unsubscribe");},get isEnabled(){return isEnabled;},};},};registry.category("services").add("discuss.ptt_extension",pttExtensionHookService);return __exports;});;

/* /mail/static/src/discuss/call/common/rtc_service.js */
odoo.define('@mail/discuss/call/common/rtc_service',['@mail/discuss/call/common/blur_manager','@mail/discuss/call/common/media_monitoring','@mail/utils/common/misc','@odoo/owl','@web/core/browser/browser','@web/core/l10n/translation','@web/core/registry','@web/core/utils/timing','@web/core/assets','@web/core/utils/functions'],function(require){'use strict';let __exports={};const{BlurManager}=require("@mail/discuss/call/common/blur_manager");const{monitorAudio}=require("@mail/discuss/call/common/media_monitoring");const{closeStream,onChange}=require("@mail/utils/common/misc");const{reactive}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{debounce}=require("@web/core/utils/timing");const{loadBundle}=require("@web/core/assets");const{memoize}=require("@web/core/utils/functions");const loadSfuAssets=memoize(async()=>await loadBundle("mail.assets_odoo_sfu"));const ORDERED_TRANSCEIVER_NAMES=["audio","screen","camera"];const CONNECTION_TYPES=__exports.CONNECTION_TYPES={P2P:"p2p",SERVER:"server"};const PEER_NOTIFICATION_WAIT_DELAY=50;const RECOVERY_TIMEOUT=15_000;const RECOVERY_DELAY=3_000;const SCREEN_CONFIG={width:{max:1920},height:{max:1080},aspectRatio:16/9,frameRate:{max:24,},};const CAMERA_CONFIG={width:{max:1280},height:{max:720},aspectRatio:16/9,frameRate:{max:30,},};const INVALID_ICE_CONNECTION_STATES=new Set(["disconnected","failed","closed"]);const IS_CLIENT_RTC_COMPATIBLE=Boolean(window.RTCPeerConnection&&window.MediaStream);const DEFAULT_ICE_SERVERS=[{urls:["stun:stun1.l.google.com:19302","stun:stun2.l.google.com:19302"]},];let tmpId=0;function serializeRTCDataChannel(data){const toLog=["binaryType","bufferedAmount","bufferedAmountLowThreshold","id","label","maxPacketLifeTime","maxRetransmits","negotiated","ordered","protocol","readyState",];return JSON.stringify(Object.fromEntries(toLog.map((p)=>[p,data[p]])));}
function getTransceiver(peerConnection,trackKind){const transceivers=peerConnection.getTransceivers();return transceivers[ORDERED_TRANSCEIVER_NAMES.indexOf(trackKind)];}
function hasTurn(iceServers){return iceServers.some((server)=>{let hasTurn=false;if(server.url){hasTurn=server.url.startsWith("turn:");}
if(server.urls){if(Array.isArray(server.urls)){hasTurn=server.urls.some((url)=>url.startsWith("turn:"))||hasTurn;}else{hasTurn=server.urls.startsWith("turn:")||hasTurn;}}
return hasTurn;});}
const Rtc=__exports.Rtc=class Rtc{notifications=reactive(new Map());timeouts=new Map();downloadTimeouts=new Map();sfuClient=undefined;constructor(env,services){this.env=env;this.store=services["mail.store"];this.notification=services.notification;this.rpc=services.rpc;this.soundEffectsService=services["mail.sound_effects"];this.userSettingsService=services["mail.user_settings"];this.pttExtService=services["discuss.ptt_extension"];this._handleSfuClientUpdates=this._handleSfuClientUpdates.bind(this);this._handleSfuClientStateChange=this._handleSfuClientStateChange.bind(this);this.linkVoiceActivationDebounce=debounce(this.linkVoiceActivation,500);this.state=reactive({connectionType:undefined,hasPendingRequest:false,selfSession:undefined,channel:undefined,iceServers:DEFAULT_ICE_SERVERS,logs:new Map(),sendCamera:false,sendScreen:false,serverInfo:undefined,serverState:undefined,updateAndBroadcastDebounce:undefined,isPendingNotify:false,notificationsToSend:new Map(),audioTrack:undefined,cameraTrack:undefined,screenTrack:undefined,disconnectAudioMonitor:undefined,recoverTimeouts:new Map(),outgoingSessions:new Set(),pttReleaseTimeout:undefined,sourceCameraStream:null,sourceScreenStream:null,});this.blurManager=undefined;onChange(this.userSettingsService,"useBlur",()=>{if(this.state.sendCamera){this.toggleVideo("camera",true);}});onChange(this.userSettingsService,["edgeBlurAmount","backgroundBlurAmount"],()=>{if(this.blurManager){this.blurManager.edgeBlur=this.userSettingsService.edgeBlurAmount;this.blurManager.backgroundBlur=this.userSettingsService.backgroundBlurAmount;}});onChange(this.userSettingsService,["voiceActivationThreshold","usePushToTalk"],()=>{this.linkVoiceActivationDebounce();});onChange(this.userSettingsService,"audioInputDeviceId",async()=>{if(this.state.selfSession){await this.resetAudioTrack({force:true});}});this.env.bus.addEventListener("RTC-SERVICE:PLAY_MEDIA",()=>{for(const session of this.state.channel.rtcSessions){session.playAudio();}});browser.addEventListener("keydown",(ev)=>{if(!this.userSettingsService.isPushToTalkKey(ev)){return;}
this.onPushToTalk();},{capture:true});browser.addEventListener("keyup",(ev)=>{if(!this.state.channel||!this.userSettingsService.usePushToTalk||!this.userSettingsService.isPushToTalkKey(ev)||!this.state.selfSession.isTalking){return;}
this.setPttReleaseTimeout();},{capture:true});browser.addEventListener("pagehide",()=>{if(this.state.channel){const data=JSON.stringify({params:{channel_id:this.state.channel.id},});const blob=new Blob([data],{type:"application/json"});browser.navigator.sendBeacon("/mail/rtc/channel/leave_call",blob);this.sfuClient?.disconnect();}});browser.setInterval(async()=>{if(!this.state.selfSession||!this.state.channel){return;}
await this.ping();if(!this.state.selfSession||!this.state.channel){return;}
this.call();},30_000);}
setPttReleaseTimeout(duration=200){this.state.pttReleaseTimeout=browser.setTimeout(()=>{this.setTalking(false);if(!this.state.selfSession?.isMute){this.soundEffectsService.play("push-to-talk-off",{volume:0.3});}},Math.max(this.userSettingsService.voiceActiveDuration||0,duration));}
onPushToTalk(){if(!this.state.channel||this.userSettingsService.isRegisteringKey||!this.userSettingsService.usePushToTalk){return;}
browser.clearTimeout(this.state.pttReleaseTimeout);if(!this.state.selfSession.isTalking&&!this.state.selfSession.isMute){this.soundEffectsService.play("push-to-talk-on",{volume:0.3});}
this.setTalking(true);}
async loadSfuClient(){this.state.connectionType=CONNECTION_TYPES.P2P;if(!this.state.serverInfo){return;}
try{await loadSfuAssets();const sfuModule=odoo.loader.modules.get("@mail/../lib/odoo_sfu/odoo_sfu");this.disconnectFromSfu();this.SFU_CLIENT_STATE=sfuModule.SFU_CLIENT_STATE;this.sfuClient=new sfuModule.SfuClient();this.sfuClient.addEventListener("update",this._handleSfuClientUpdates);this.sfuClient.addEventListener("stateChange",this._handleSfuClientStateChange);this.state.connectionType=CONNECTION_TYPES.SERVER;}catch(e){this.notification.add(_t("Failed to load the SFU server, falling back to peer-to-peer"),{type:"warning",});this.log(this.state.selfSession,"failed to load sfu server",{error:e});}}
addCallNotification({id,text,delay=3000}){if(this.notifications.has(id)){return;}
this.notifications.set(id,{id,text});this.timeouts.set(id,browser.setTimeout(()=>{this.notifications.delete(id);this.timeouts.delete(id);},delay));}
removeCallNotification(id){browser.clearTimeout(this.timeouts.get(id));this.notifications.delete(id);this.timeouts.delete(id);}
async leaveCall(channel=this.state.channel){this.state.hasPendingRequest=true;await this.rpcLeaveCall(channel);this.endCall(channel);this.state.hasPendingRequest=false;}
disconnectFromSfu(){if(!this.sfuClient){return;}
this.sfuClient.removeEventListener("update",this._handleSfuClientUpdates);this.sfuClient.removeEventListener("stateChange",this._handleSfuClientStateChange);this.sfuClient.disconnect();}
endCall(channel=this.state.channel){channel.rtcInvitingSession=undefined;channel.activeRtcSession=undefined;if(channel.eq(this.state.channel)){this.pttExtService.unsubscribe();this.disconnectFromSfu();this.clear();this.soundEffectsService.play("channel-leave");}}
async deafen(){await this.setDeaf(true);this.soundEffectsService.play("deafen");}
setRemoteRaiseHand(session,active){Object.assign(session,{raisingHand:active?new Date():undefined,});const notificationId="raise_hand_"+session.id;if(session.raisingHand){this.addCallNotification({id:notificationId,text:_t("%s raised their hand",session.name),});}else{this.removeCallNotification(notificationId);}}
async handleNotification(sessionId,content){const{event,channelId,payload}=JSON.parse(content);const session=this.store.RtcSession.get(sessionId);if(!session||!IS_CLIENT_RTC_COMPATIBLE||(!session.peerConnection&&(!channelId||!this.state.channel||channelId!==this.state.channel.id))){return;}
switch(event){case"offer":{this.log(session,`received notification: ${event}`,{step:"received offer",});const peerConnection=session.peerConnection||this.createConnection(session);if(!peerConnection||INVALID_ICE_CONNECTION_STATES.has(peerConnection.iceConnectionState)||peerConnection.signalingState==="have-remote-offer"){return;}
const description=new window.RTCSessionDescription(payload.sdp);try{await peerConnection.setRemoteDescription(description);}catch(e){this.log(session,"offer handling: failed at setting remoteDescription",{error:e,});return;}
if(peerConnection.getTransceivers().length===0){for(const trackKind of ORDERED_TRANSCEIVER_NAMES){const type=["screen","camera"].includes(trackKind)?"video":trackKind;peerConnection.addTransceiver(type);}}
for(const transceiverName of ORDERED_TRANSCEIVER_NAMES){await this.updateRemote(session,transceiverName);}
let answer;try{answer=await peerConnection.createAnswer();}catch(e){this.log(session,"offer handling: failed at creating answer",{error:e,});return;}
try{await peerConnection.setLocalDescription(answer);}catch(e){this.log(session,"offer handling: failed at setting localDescription",{error:e,});return;}
this.log(session,"sending notification: answer",{step:"sending answer",});await this.notify([session],"answer",{sdp:peerConnection.localDescription,});this.recover(session,RECOVERY_TIMEOUT,"standard answer timeout");break;}
case"answer":{this.log(session,`received notification: ${event}`,{step:"received answer",});const peerConnection=session.peerConnection;if(!peerConnection||INVALID_ICE_CONNECTION_STATES.has(peerConnection.iceConnectionState)||peerConnection.signalingState==="stable"||peerConnection.signalingState==="have-remote-offer"){return;}
const description=new window.RTCSessionDescription(payload.sdp);try{await peerConnection.setRemoteDescription(description);}catch(e){this.log(session,"answer handling: Failed at setting remoteDescription",{error:e,});}
break;}
case"ice-candidate":{const peerConnection=session.peerConnection;if(!peerConnection||INVALID_ICE_CONNECTION_STATES.has(peerConnection.iceConnectionState)){return;}
const rtcIceCandidate=new window.RTCIceCandidate(payload.candidate);try{await peerConnection.addIceCandidate(rtcIceCandidate);}catch(error){this.log(session,"ICE candidate handling: failed at adding the candidate to the connection",{error});this.recover(session,RECOVERY_TIMEOUT,"failed at adding ice candidate");}
break;}
case"disconnect":this.log(session,`received notification: ${event}`,{step:" peer cleanly disconnected ",});this.disconnect(session);break;case"raise_hand":this.setRemoteRaiseHand(session,payload.active);break;case"trackChange":{if(payload.type==="audio"){const{isSelfMuted,isTalking,isDeaf}=payload.state;if(!session.audioStream){return;}
Object.assign(session,{isSelfMuted,isTalking,isDeaf,});return;}
this.updateActiveSession(session,payload.type);session.videoStreams.delete(payload.type);session.updateStreamState(payload.type,false);break;}}}
async mute(){await this.setMute(true);this.soundEffectsService.play("mute");}
async toggleCall(channel,{video}={}){if(this.state.hasPendingRequest){return;}
const isActiveCall=channel.eq(this.state.channel);if(this.state.channel){await this.leaveCall(this.state.channel);}
if(!isActiveCall){await this.joinCall(channel,{video});}}
async toggleMicrophone(){if(this.state.selfSession.isMute){await this.unmute();}else{await this.mute();}}
async undeafen(){await this.setDeaf(false);this.soundEffectsService.play("undeafen");}
async unmute(){if(this.state.audioTrack){await this.setMute(false);}else{await this.resetAudioTrack({force:true});}
this.soundEffectsService.play("unmute");}
log(session,entry,{error,step,state,...data}={}){session.logStep=entry;if(!this.userSettingsService.logRtc){return;}
if(!this.state.logs.has(session.id)){this.state.logs.set(session.id,{step:"",state:"",logs:[]});}
if(step){this.state.logs.get(session.id).step=step;}
if(state){this.state.logs.get(session.id).state=state;}
const trace=window.Error().stack||"";this.state.logs.get(session.id).logs.push({event:`${luxon.DateTime.now().toFormat("HH:mm:ss")}: ${entry}`,error:error&&{name:error.name,message:error.message,stack:error.stack&&error.stack.split("\n"),},trace:trace.split("\n"),...data,});}
async connect(session){this.createConnection(session);for(const transceiverName of ORDERED_TRANSCEIVER_NAMES){await this.updateRemote(session,transceiverName);}
this.state.outgoingSessions.add(session.id);}
async _handleSfuClientUpdates({detail:{name,payload}}){if(!this.state.channel){return;}
switch(name){case"disconnect":{const{sessionId}=payload;const session=this.store.RtcSession.get(sessionId);if(!session){return;}
this.disconnect(session);}
return;case"info_change":if(!payload){return;}
for(const[id,info]of Object.entries(payload)){const session=this.store.RtcSession.get(Number(id));if(!session){return;}
this.setRemoteRaiseHand(session,info.isRaisingHand);delete info.isRaisingHand;Object.assign(session,info);}
return;case"track":{const{sessionId,type,track,active}=payload;const session=this.store.RtcSession.get(sessionId);if(!session){return;}
try{await this.handleRemoteTrack({session,track,type,active});}catch{}
setTimeout(()=>{this.updateVideoDownload(session);},2000);}
return;}}
async _handleSfuClientStateChange({detail:{state,cause}}){this.state.serverState=state;switch(state){case this.SFU_CLIENT_STATE.AUTHENTICATED:this.clearPeerToPeer();break;case this.SFU_CLIENT_STATE.CONNECTED:this.sfuClient.updateInfo(this.formatInfo(),{needRefresh:true,});this.sfuClient.updateUpload("audio",this.state.audioTrack);this.sfuClient.updateUpload("camera",this.state.cameraTrack);this.sfuClient.updateUpload("screen",this.state.screenTrack);return;case this.SFU_CLIENT_STATE.CLOSED:{let text;if(cause==="full"){text=_t("Channel full");}else{text=_t("Connection to SFU server closed by the server");}
this.notification.add(text,{type:"warning",});await this.leaveCall();}
return;}}
async call(){if(this.state.connectionType===CONNECTION_TYPES.SERVER){if(this.sfuClient.state===this.SFU_CLIENT_STATE.DISCONNECTED){await this.sfuClient.connect(this.state.serverInfo.url,this.state.serverInfo.jsonWebToken,{iceServers:this.state.iceServers,});}
return;}
if(this.state.channel.rtcSessions.length===0){return;}
for(const session of this.state.channel.rtcSessions){if(session.peerConnection||session.eq(this.state.selfSession)){continue;}
this.log(session,"init call",{step:"init call"});this.connect(session);}}
createConnection(session){const peerConnection=new window.RTCPeerConnection({iceServers:this.state.iceServers});this.log(session,"RTCPeerConnection created",{step:"peer connection created",});peerConnection.onicecandidate=async(event)=>{if(!event.candidate){return;}
await this.notify([session],"ice-candidate",{candidate:event.candidate,});};peerConnection.oniceconnectionstatechange=async(event)=>{this.log(session,`ICE connection state changed: ${peerConnection.iceConnectionState}`,{state:peerConnection.iceConnectionState,});if(!this.state.channel.rtcSessions.some((s)=>s.id===session.id)){return;}
session.connectionState=peerConnection.iceConnectionState;switch(peerConnection.iceConnectionState){case"closed":this.disconnect(session);break;case"failed":case"disconnected":await this.recover(session,RECOVERY_DELAY,`ice connection ${peerConnection.iceConnectionState}`);break;}};peerConnection.onicegatheringstatechange=(event)=>{this.log(session,`ICE gathering state changed: ${peerConnection.iceGatheringState}`);};peerConnection.onconnectionstatechange=async(event)=>{this.log(session,`connection state changed: ${peerConnection.connectionState}`);switch(peerConnection.connectionState){case"closed":this.disconnect(session);break;case"failed":case"disconnected":await this.recover(session,RECOVERY_DELAY,`connection ${peerConnection.connectionState}`);break;}};peerConnection.onicecandidateerror=async(error)=>{this.log(session,"ice candidate error");this.recover(session,RECOVERY_TIMEOUT,"ice candidate error");};peerConnection.onnegotiationneeded=async(event)=>{const offer=await peerConnection.createOffer();try{await peerConnection.setLocalDescription(offer);}catch(error){this.log(session,"couldn't setLocalDescription",{error});return;}
this.log(session,"sending notification: offer",{step:"sending offer",});await this.notify([session],"offer",{sdp:peerConnection.localDescription,});};peerConnection.ontrack=({transceiver,track})=>{this.log(session,`received ${track.kind} track`);this.handleRemoteTrack({session,track,type:this.getTransceiverType(session.peerConnection,transceiver),});};const dataChannel=peerConnection.createDataChannel("notifications",{negotiated:true,id:1,});dataChannel.onmessage=(event)=>{this.handleNotification(session.id,event.data);};dataChannel.onopen=async()=>{try{await this.notify([session],"trackChange",{type:"audio",state:{isTalking:this.state.selfSession.isTalking,isSelfMuted:this.state.selfSession.isSelfMuted,},});await this.notify([session],"raise_hand",{active:Boolean(this.state.selfSession.raisingHand),});}catch(e){if(!(e instanceof DOMException)||e.name!=="OperationError"){throw e;}
this.log(session,`failed to send on datachannel; dataChannelInfo: ${serializeRTCDataChannel(
                        dataChannel
                    )}`,{error:e});}};Object.assign(session,{peerConnection,dataChannel,connectionState:"connecting",});return peerConnection;}
async handleRemoteTrack({session,track,type,active=true}){session.updateStreamState(type,active);await this.updateStream(session,track,{mute:this.state.selfSession.isDeaf,videoType:type,});this.updateActiveSession(session,type,{addVideo:true});}
getTransceiverType(peerConnection,transceiver){const transceivers=peerConnection.getTransceivers();return ORDERED_TRANSCEIVER_NAMES[transceivers.indexOf(transceiver)];}
async joinCall(channel,{video=false}={}){if(!IS_CLIENT_RTC_COMPATIBLE){this.notification.add(_t("Your browser does not support webRTC."),{type:"warning"});return;}
this.pttExtService.subscribe();this.state.hasPendingRequest=true;const{rtcSessions,iceServers,sessionId,serverInfo}=await this.rpc("/mail/rtc/channel/join_call",{channel_id:channel.id,check_rtc_session_ids:channel.rtcSessions.map((session)=>session.id),},{silent:true});this.clear();this.state.logs.clear();this.state.channel=channel;this.state.serverInfo=serverInfo;this.state.channel.rtcSessions=rtcSessions;this.state.selfSession=this.store.RtcSession.get(sessionId);this.state.iceServers=iceServers||DEFAULT_ICE_SERVERS;this.state.logs.set("channelId",this.state.channel?.id);this.state.logs.set("selfSessionId",this.state.selfSession?.id);this.state.logs.set("hasTURN",hasTurn(this.state.iceServers));const channelProxy=reactive(this.state.channel,()=>{if(channel.notEq(this.state.channel)){throw new Error("channel has changed");}
if(this.state.channel){if(this.state.channel&&this.state.selfSession.notIn(channelProxy.rtcSessions)){this.endCall();return;}
for(const session of this.state.channel.rtcSessions){if(session.notIn(channelProxy.rtcSessions)){this.log(session,"session removed from the server");this.disconnect(session);}}}
void channelProxy.rtcSessions.map((s)=>s);});this.state.updateAndBroadcastDebounce=debounce(async()=>{if(!this.state.selfSession){return;}
await this.rpc("/mail/rtc/session/update_and_broadcast",{session_id:this.state.selfSession.id,values:{is_camera_on:this.state.selfSession.isCameraOn,is_deaf:this.state.selfSession.isDeaf,is_muted:this.state.selfSession.isSelfMuted,is_screen_sharing_on:this.state.selfSession.isScreenSharingOn,},},{silent:true});},3000,{leading:true,trailing:true});this.state.channel.rtcInvitingSession=undefined;await this.loadSfuClient();if(!this.state.channel?.id){return;}
await this.call();if(!this.state.channel?.id){return;}
this.soundEffectsService.play("channel-join");await this.resetAudioTrack({force:true});if(!this.state.channel?.id){return;}
if(video){await this.toggleVideo("camera");}
this.state.hasPendingRequest=false;}
async notify(sessions,event,payload){if(!sessions.length||!this.state.channel.id||!this.state.selfSession){return;}
if(event==="trackChange"){for(const session of sessions){if(!session?.dataChannel||session?.dataChannel.readyState!=="open"){continue;}
session.dataChannel.send(JSON.stringify({event,channelId:this.state.channel.id,payload,}));}}else{this.state.notificationsToSend.set(++tmpId,{channelId:this.state.channel.id,event,payload,sender:this.state.selfSession,sessions,});await this.sendNotifications();}}
async rpcLeaveCall(channel){await this.rpc("/mail/rtc/channel/leave_call",{channel_id:channel.id,},{silent:true});}
async ping(){const{rtcSessions}=await this.rpc("/discuss/channel/ping",{channel_id:this.state.channel.id,check_rtc_session_ids:this.state.channel.rtcSessions.map((session)=>session.id),rtc_session_id:this.state.selfSession.id,},{silent:true});if(this.state.channel&&rtcSessions){const activeSessionsData=rtcSessions[0][1];for(const sessionData of activeSessionsData){this.state.channel.rtcSessions.add(sessionData);}
const outdatedSessionsData=rtcSessions[1][1];for(const sessionData of outdatedSessionsData){this.deleteSession(sessionData);}}}
recover(session,delay=0,reason=""){if(this.state.recoverTimeouts.get(session.id)){return;}
this.state.recoverTimeouts.set(session.id,browser.setTimeout(async()=>{this.state.recoverTimeouts.delete(session.id);const peerConnection=session.peerConnection;if(!peerConnection||!this.state.channel.id||this.state.outgoingSessions.has(session.id)||peerConnection.iceConnectionState==="connected"){return;}
if(this.userSettingsService.logRtc){let stats;try{const iterableStats=await peerConnection.getStats();stats=iterableStats&&[...iterableStats.values()];}catch{}
this.log(session,`calling back to recover "${peerConnection.iceConnectionState}" connection`,{reason,stats});}
await this.notify([session],"disconnect");this.disconnect(session);this.connect(session);},delay));}
disconnect(session){const downloadTimeout=this.downloadTimeouts.get(session.id);if(downloadTimeout){clearTimeout(downloadTimeout);this.downloadTimeouts.delete(session.id);}
this.removeCallNotification("raise_hand_"+session.id);closeStream(session.audioStream);if(session.audioElement){session.audioElement.pause();try{session.audioElement.srcObject=undefined;}catch{}}
session.audioStream=undefined;session.connectionState=undefined;session.localCandidateType=undefined;session.remoteCandidateType=undefined;session.dataChannelState=undefined;session.packetsReceived=undefined;session.packetsSent=undefined;session.dtlsState=undefined;session.iceState=undefined;session.raisingHand=undefined;session.logStep=undefined;session.audioError=undefined;session.videoError=undefined;session.isTalking=false;session.mainVideoStreamType=undefined;this.removeVideoFromSession(session);session.dataChannel?.close();delete session.dataChannel;const peerConnection=session.peerConnection;if(peerConnection){const RTCRtpSenders=peerConnection.getSenders();for(const sender of RTCRtpSenders){try{peerConnection.removeTrack(sender);}catch{}}
for(const transceiver of peerConnection.getTransceivers()){try{transceiver.stop();}catch{}}
peerConnection.close();session.peerConnection=undefined;}
browser.clearTimeout(this.state.recoverTimeouts.get(session.id));this.state.recoverTimeouts.delete(session.id);this.state.outgoingSessions.delete(session.id);this.log(session,"peer removed",{step:"peer removed"});}
clearPeerToPeer(){for(const session of Object.values(this.store.RtcSession.records)){if(session===this.state.selfSession){continue;}
this.disconnect(session);}
for(const timeoutId of this.state.recoverTimeouts.values()){clearTimeout(timeoutId);}
this.state.recoverTimeouts.clear();this.state.notificationsToSend.clear();}
clear(){this.clearPeerToPeer();this.sfuClient=undefined;this.state.serverState=undefined;this.state.updateAndBroadcastDebounce?.cancel();this.state.disconnectAudioMonitor?.();this.state.audioTrack?.stop();this.state.cameraTrack?.stop();this.state.screenTrack?.stop();closeStream(this.state.sourceCameraStream);this.state.sourceCameraStream=null;if(this.blurManager){this.blurManager.close();this.blurManager=undefined;}
Object.assign(this.state,{updateAndBroadcastDebounce:undefined,connectionType:undefined,disconnectAudioMonitor:undefined,outgoingSessions:new Set(),cameraTrack:undefined,screenTrack:undefined,audioTrack:undefined,selfSession:undefined,sendCamera:false,sendScreen:false,serverInfo:undefined,channel:undefined,});}
async sendNotifications(){if(this.state.isPendingNotify){return;}
this.state.isPendingNotify=true;await new Promise((resolve)=>setTimeout(resolve,PEER_NOTIFICATION_WAIT_DELAY));const ids=[];const notifications=[];this.state.notificationsToSend.forEach((notification,id)=>{ids.push(id);notifications.push([notification.sender.id,notification.sessions.map((session)=>session.id),JSON.stringify({event:notification.event,channelId:notification.channelId,payload:notification.payload,}),]);});try{await this.rpc("/mail/rtc/session/notify_call_members",{peer_notifications:notifications,},{silent:true});for(const id of ids){this.state.notificationsToSend.delete(id);}}finally{this.state.isPendingNotify=false;if(this.state.notificationsToSend.size>0){this.sendNotifications();}}}
async setDeaf(isDeaf){this.updateAndBroadcast({isDeaf});for(const session of this.state.channel.rtcSessions){if(!session.audioElement){continue;}
session.audioElement.muted=isDeaf;}
await this.refreshAudioStatus();}
async setMute(isSelfMuted){this.updateAndBroadcast({isSelfMuted});await this.refreshAudioStatus();}
async raiseHand(raise){if(!this.state.selfSession||!this.state.channel){return;}
this.state.selfSession.raisingHand=raise?new Date():undefined;await this.notify(this.state.channel.rtcSessions,"raise_hand",{active:this.state.selfSession.raisingHand,});}
async setTalking(isTalking){if(!this.state.selfSession||isTalking===this.state.selfSession.isTalking){return;}
this.state.selfSession.isTalking=isTalking;if(!this.state.selfSession.isMute){this.pttExtService.notifyIsTalking(isTalking);await this.refreshAudioStatus();}}
async toggleVideo(type,force){if(!this.state.channel?.id){return;}
switch(type){case"camera":{const track=this.state.cameraTrack;const sendCamera=force??!this.state.sendCamera;this.state.sendCamera=false;await this.setVideo(track,type,sendCamera);break;}
case"screen":{const track=this.state.screenTrack;const sendScreen=force??!this.state.sendScreen;this.state.sendScreen=false;await this.setVideo(track,type,sendScreen);break;}}
if(this.state.selfSession){switch(type){case"camera":{this.removeVideoFromSession(this.state.selfSession,"camera");if(this.state.cameraTrack){this.updateStream(this.state.selfSession,this.state.cameraTrack);}
break;}
case"screen":{if(!this.state.screenTrack){this.removeVideoFromSession(this.state.selfSession,"screen");}else{this.updateStream(this.state.selfSession,this.state.screenTrack);}
break;}}}
const updatedTrack=type==="camera"?this.state.cameraTrack:this.state.screenTrack;if(this.sfuClient){await this.sfuClient.updateUpload(type,updatedTrack);}else{for(const session of this.state.channel.rtcSessions){if(session.eq(this.state.selfSession)){continue;}
await this.updateRemote(session,type);}}
if(!this.state.selfSession){return;}
switch(type){case"camera":{this.updateAndBroadcast({isCameraOn:!!this.state.sendCamera,});break;}
case"screen":{this.updateAndBroadcast({isScreenSharingOn:!!this.state.sendScreen,});break;}}}
updateAndBroadcast(data){const session=this.state.selfSession;Object.assign(session,data);this.state.updateAndBroadcastDebounce?.();}
async refreshAudioStatus(){if(!this.state.audioTrack){return;}
this.state.audioTrack.enabled=!this.state.selfSession.isMute&&this.state.selfSession.isTalking;if(this.sfuClient&&this.sfuClient.state===this.SFU_CLIENT_STATE.CONNECTED){this.sfuClient.updateInfo(this.formatInfo());}
await this.notify(this.state.channel.rtcSessions,"trackChange",{type:"audio",state:{isTalking:this.state.selfSession.isTalking&&!this.state.selfSession.isSelfMuted,isSelfMuted:this.state.selfSession.isSelfMuted,isDeaf:this.state.selfSession.isDeaf,},});}
async setVideo(track,type,activateVideo=false){if(this.blurManager){this.blurManager.close();this.blurManager=undefined;}
const stopVideo=()=>{if(track){track.stop();}
switch(type){case"camera":{this.state.cameraTrack=undefined;closeStream(this.state.sourceCameraStream);this.state.sourceCameraStream=null;break;}
case"screen":{this.state.screenTrack=undefined;closeStream(this.state.sourceScreenStream);this.state.sourceScreenStream=null;break;}}};if(!activateVideo){if(type==="screen"){this.soundEffectsService.play("screen-sharing");}
stopVideo();return;}
let sourceStream;try{if(type==="camera"){if(this.state.sourceCameraStream&&this.state.sendCamera){sourceStream=this.state.sourceCameraStream;}else{sourceStream=await browser.navigator.mediaDevices.getUserMedia({video:CAMERA_CONFIG,});}}
if(type==="screen"){if(this.state.sourceScreenStream&&this.state.sendScreen){sourceStream=this.state.sourceScreenStream;}else{sourceStream=await browser.navigator.mediaDevices.getDisplayMedia({video:SCREEN_CONFIG,});}
this.soundEffectsService.play("screen-sharing");}}catch{const str=type==="camera"?_t('%s" requires "camera" access',window.location.host):_t('%s" requires "screen recording" access',window.location.host);this.notification.add(str,{type:"warning"});stopVideo();return;}
let videoStream=sourceStream;if(this.userSettingsService.useBlur&&type==="camera"){try{this.blurManager=new BlurManager(sourceStream,{backgroundBlur:this.userSettingsService.backgroundBlurAmount,edgeBlur:this.userSettingsService.edgeBlurAmount,});videoStream=await this.blurManager.stream;}catch(_e){this.notification.add(_t("%(name)s: %(message)s)",{name:_e.name,message:_e.message}),{type:"warning"});this.userSettingsService.useBlur=false;}}
track=videoStream?videoStream.getVideoTracks()[0]:undefined;if(track){track.addEventListener("ended",async()=>{await this.toggleVideo(type,false);});}
switch(type){case"camera":{Object.assign(this.state,{sourceCameraStream:sourceStream,cameraTrack:track,sendCamera:Boolean(type==="camera"&&track),});break;}
case"screen":{Object.assign(this.state,{sourceScreenStream:sourceStream,screenTrack:track,sendScreen:Boolean(type==="screen"&&track),});break;}}}
async updateRemote(session,trackKind){if(!session.peerConnection){return;}
this.log(session,`updating ${trackKind} transceiver`);let track;switch(trackKind){case"audio":{track=this.state.audioTrack;break;}
case"camera":{track=this.state.cameraTrack;break;}
case"screen":{track=this.state.screenTrack;break;}}
let transceiverDirection=track?"sendrecv":"recvonly";if(trackKind!=="audio"){transceiverDirection=this.getTransceiverDirection(session,Boolean(track));}
const transceiver=getTransceiver(session.peerConnection,trackKind);try{await transceiver.sender.replaceTrack(track||null);transceiver.direction=transceiverDirection;}catch{this.log(session,`failed to update ${trackKind} transceiver`);}
if(!track&&trackKind!=="audio"){this.notify([session],"trackChange",{type:this.getTransceiverType(session.peerConnection,transceiver),});}}
async resetAudioTrack({force=false}){if(this.state.audioTrack){this.state.audioTrack.stop();this.state.audioTrack=undefined;}
if(!this.state.channel){return;}
if(force){let audioTrack;try{const audioStream=await browser.navigator.mediaDevices.getUserMedia({audio:this.userSettingsService.audioConstraints,});audioTrack=audioStream.getAudioTracks()[0];}catch{this.notification.add(_t('"%(hostname)s" requires microphone access',{hostname:window.location.host,}),{type:"warning"});if(this.state.selfSession){this.updateAndBroadcast({isSelfMuted:true});}
return;}
if(!this.state.selfSession){audioTrack.stop();return;}
audioTrack.addEventListener("ended",async()=>{await this.resetAudioTrack({force:false});this.updateAndBroadcast({isSelfMuted:true});await this.refreshAudioStatus();});this.updateAndBroadcast({isSelfMuted:false});audioTrack.enabled=!this.state.selfSession.isMute&&this.state.selfSession.isTalking;this.state.audioTrack=audioTrack;this.linkVoiceActivationDebounce();if(this.sfuClient){await this.sfuClient.updateUpload("audio",this.state.audioTrack);return;}
for(const session of this.state.channel.rtcSessions){if(session.eq(this.state.selfSession)){continue;}
await this.updateRemote(session,"audio");}}}
async linkVoiceActivation(){this.state.disconnectAudioMonitor?.();if(!this.state.selfSession){return;}
if(this.userSettingsService.usePushToTalk||!this.state.channel||!this.state.audioTrack){this.state.selfSession.isTalking=false;await this.refreshAudioStatus();return;}
try{this.state.disconnectAudioMonitor=await monitorAudio(this.state.audioTrack,{onThreshold:async(isAboveThreshold)=>{this.setTalking(isAboveThreshold);},volumeThreshold:this.userSettingsService.voiceActivationThreshold,});}catch{this.notification.add(_t("Your browser does not support voice activation"),{type:"warning",});this.state.selfSession.isTalking=true;}
await this.refreshAudioStatus();}
deleteSession(id){const session=this.store.RtcSession.get(id);if(session){if(this.state.selfSession&&session.eq(this.state.selfSession)){this.endCall();}
this.disconnect(session);session.delete();}}
formatInfo(){this.state.selfSession.isCameraOn=Boolean(this.state.cameraTrack);this.state.selfSession.isScreenSharingOn=Boolean(this.state.screenTrack);return this.state.selfSession.info;}
async updateStream(session,track,{mute,videoType}={}){const stream=new window.MediaStream();stream.addTrack(track);if(track.kind==="audio"){const audioElement=session.audioElement||new window.Audio();audioElement.srcObject=stream;audioElement.load();audioElement.muted=mute;audioElement.volume=this.userSettingsService.getVolume(session);audioElement.autoplay=true;session.audioElement=audioElement;session.audioStream=stream;session.isSelfMuted=false;session.isTalking=false;await session.playAudio();}
if(track.kind==="video"){videoType=videoType?videoType:track.id===this.state.cameraTrack?.id?"camera":"screen";session.videoStreams.set(videoType,stream);this.updateActiveSession(session,videoType,{addVideo:true});}}
removeVideoFromSession(session,videoType=false){if(videoType){this.updateActiveSession(session,videoType);closeStream(session.videoStreams.get(videoType));session.videoStreams.delete(videoType);}else{for(const stream of session.videoStreams.values()){closeStream(stream);}
session.videoStreams.clear();}}
updateActiveSession(session,videoType,{addVideo=false}={}){const activeRtcSession=this.state.channel.activeRtcSession;if(addVideo){if(videoType==="screen"){this.state.channel.activeRtcSession=session;session.mainVideoStreamType=videoType;return;}
if(activeRtcSession&&session.hasVideo&&!session.isMainVideoStreamActive){session.mainVideoStreamType=videoType;}
return;}
if(!activeRtcSession||activeRtcSession.notEq(session)){return;}
if(activeRtcSession.isMainVideoStreamActive){if(videoType===session.mainVideoStreamType){if(videoType==="screen"){this.state.channel.activeRtcSession=undefined;}else{session.mainVideoStreamType="screen";}}}}
updateVideoDownload(rtcSession,{viewCountIncrement=0}={}){rtcSession.videoComponentCount+=viewCountIncrement;const downloadTimeout=this.downloadTimeouts.get(rtcSession.id);if(downloadTimeout){this.downloadTimeouts.delete(rtcSession.id);browser.clearTimeout(downloadTimeout);}
if(this.state.connectionType===CONNECTION_TYPES.SERVER){if(rtcSession.videoComponentCount>0){this.sfuClient?.updateDownload(rtcSession.id,{camera:true,screen:true,});}else{this.downloadTimeouts.set(rtcSession.id,browser.setTimeout(()=>{this.downloadTimeouts.delete(rtcSession.id);this.sfuClient?.updateDownload(rtcSession.id,{camera:false,screen:false,});},1000));}}
if(!rtcSession.peerConnection){return;}
const transceivers=rtcSession.peerConnection.getTransceivers();const cameraTransceiver=transceivers[ORDERED_TRANSCEIVER_NAMES.indexOf("camera")];const screenTransceiver=transceivers[ORDERED_TRANSCEIVER_NAMES.indexOf("screen")];if(cameraTransceiver){cameraTransceiver.direction=this.getTransceiverDirection(rtcSession,Boolean(this.state.cameraTrack));}
if(screenTransceiver){screenTransceiver.direction=this.getTransceiverDirection(rtcSession,Boolean(this.state.screenTrack));}}
getTransceiverDirection(session,allowUpload=false){if(session.videoComponentCount>0){return allowUpload?"sendrecv":"recvonly";}else{return allowUpload?"sendonly":"inactive";}}
updateRtcSessions(channelId,sessionsData){const channel=this.store.Thread.get({model:"discuss.channel",id:channelId});if(!channel){return;}
const oldCount=channel.rtcSessions.length;const hadSelfSession=Boolean(this.state.selfSession?.in(channel.rtcSessions));channel.rtcSessions=sessionsData;if(!hadSelfSession||hadSelfSession!==Boolean(this.state.selfSession?.in(channel.rtcSessions))||!this.store.env.services["multi_tab"].isOnMainTab()){return;}
if(channel.rtcSessions.length>oldCount){this.soundEffectsService.play("channel-join");}else if(channel.rtcSessions.length<oldCount){this.soundEffectsService.play("member-leave");}}}
const rtcService=__exports.rtcService={dependencies:["bus_service","discuss.ptt_extension","mail.sound_effects","mail.store","mail.user_settings","notification","rpc",],start(env,services){const rtc=new Rtc(env,services);services["bus_service"].subscribe("discuss.channel.rtc.session/sfu_hot_swap",async({serverInfo})=>{if(!rtc.state.selfSession){return;}
if(rtc.state.serverInfo?.url===serverInfo?.url){return;}
rtc.state.serverInfo=serverInfo;await rtc.loadSfuClient();await rtc.call();});services["bus_service"].subscribe("discuss.channel.rtc.session/peer_notification",({sender,notifications})=>{for(const content of notifications){rtc.handleNotification(sender,content);}});services["bus_service"].subscribe("discuss.channel.rtc.session/ended",({sessionId})=>{if(rtc.state.selfSession?.id===sessionId){rtc.endCall();services.notification.add(_t("Disconnected from the RTC call by the server"),{type:"warning",});}});services["bus_service"].subscribe("discuss.channel/rtc_sessions_update",({id,rtcSessions})=>{rtc.updateRtcSessions(id,rtcSessions);});services["bus_service"].subscribe("discuss.channel/joined",({channel})=>{rtc.updateRtcSessions(channel.id,channel.rtcSessions);});services["bus_service"].subscribe("res.users.settings.volumes",(payload)=>{if(payload){services["mail.user_settings"].setVolumes(payload);}});services["bus_service"].subscribe("discuss.channel.rtc.session/update_and_broadcast",(payload)=>{const{data,channelId}=payload;if(channelId!==rtc.state.channel?.id){rtc.store.RtcSession.insert(data);}});return rtc;},};registry.category("services").add("discuss.rtc",rtcService);return __exports;});;

/* /mail/static/src/discuss/call/common/rtc_session_model.js */
odoo.define('@mail/discuss/call/common/rtc_session_model',['@mail/core/common/record'],function(require){'use strict';let __exports={};const{Record}=require("@mail/core/common/record");const RtcSession=__exports.RtcSession=class RtcSession extends Record{static id="id";static records={};static get(data){return super.get(data);}
static insert(data){return super.insert(...arguments);}
static _insert(){const session=super._insert(...arguments);session.channel?.rtcSessions.add(session);return session;}
channelMember=Record.one("ChannelMember",{inverse:"rtcSession"});isCameraOn;isScreenSharingOn;id;isDeaf;isSelfMuted;audioElement;audioStream;dataChannel;audioError;videoError;isTalking;localVolume;peerConnection;raisingHand;videoComponentCount=0;videoStreams=new Map();mainVideoStreamType;connectionState;localCandidateType;remoteCandidateType;dataChannelState;packetsReceived;packetsSent;dtlsState;iceState;iceGatheringState;logStep;get channel(){return this.channelMember?.thread;}
get isMute(){return this.isSelfMuted||this.isDeaf;}
get mainVideoStream(){return this.isMainVideoStreamActive&&this.videoStreams.get(this.mainVideoStreamType);}
get isMainVideoStreamActive(){if(!this.mainVideoStreamType){return false;}
return this.mainVideoStreamType==="camera"?this.isCameraOn:this.isScreenSharingOn;}
get hasVideo(){return this.isScreenSharingOn||this.isCameraOn;}
getStream(type){const isActive=type==="camera"?this.isCameraOn:this.isScreenSharingOn;return isActive&&this.videoStreams.get(type);}
get info(){return{isSelfMuted:this.isSelfMuted,isRaisingHand:Boolean(this.raisingHand),isDeaf:this.isDeaf,isTalking:this.isTalking,isCameraOn:this.isCameraOn,isScreenSharingOn:this.isScreenSharingOn,};}
get partnerId(){const persona=this.channelMember?.persona;return persona.type==="partner"?persona.id:undefined;}
get guestId(){const persona=this.channelMember?.persona;return persona.type==="guest"?persona.id:undefined;}
get name(){return this.channelMember?.persona.name;}
get volume(){return this.audioElement?.volume||this.localVolume;}
set volume(value){if(this.audioElement){this.audioElement.volume=value;}
this.localVolume=value;}
async playAudio(){if(!this.audioElement){return;}
try{await this.audioElement.play();this.audioError=undefined;}catch(error){this.audioError=error.name;}}
updateStreamState(type,state){if(type==="camera"){this.isCameraOn=state;}else if(type==="screen"){this.isScreenSharingOn=state;}}
async updateStats(){delete this.localCandidateType;delete this.remoteCandidateType;delete this.dataChannelState;delete this.packetsReceived;delete this.packetsSent;delete this.dtlsState;delete this.iceState;delete this.iceGatheringState;if(!this.peerConnection){return;}
let stats;try{stats=await this.peerConnection.getStats();}catch{return;}
this.iceGatheringState=this.peerConnection.iceGatheringState;for(const value of stats.values()||[]){switch(value.type){case"candidate-pair":if(value.state==="succeeded"&&value.localCandidateId){this.localCandidateType=stats.get(value.localCandidateId)?.candidateType||"";this.remoteCandidateType=stats.get(value.remoteCandidateId)?.candidateType||"";}
break;case"data-channel":this.dataChannelState=value.state;break;case"transport":this.dtlsState=value.dtlsState;this.iceState=value.iceState;this.packetsReceived=value.packetsReceived;this.packetsSent=value.packetsSent;break;}}}}
RtcSession.register();return __exports;});;

/* /mail/static/src/discuss/call/common/thread_actions.js */
odoo.define('@mail/discuss/call/common/thread_actions',['@mail/core/common/thread_actions','@mail/discuss/call/common/call_settings','@odoo/owl','@web/core/l10n/translation','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{threadActionsRegistry}=require("@mail/core/common/thread_actions");const{CallSettings}=require("@mail/discuss/call/common/call_settings");const{useComponent,useState}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");threadActionsRegistry.add("call",{condition(component){return(component.thread?.allowCalls&&!component.thread?.eq(component.rtc.state.channel)&&!component.props.chatWindow?.hidden);},icon:"fa fa-fw fa-phone",iconLarge:"fa fa-fw fa-lg fa-phone",name:_t("Start a Call"),open(component){component.rtc.toggleCall(component.thread);},sequence:10,setup(){const component=useComponent();component.rtc=useState(useService("discuss.rtc"));},}).add("settings",{component:CallSettings,condition(component){return(component.thread?.allowCalls&&(!component.props.chatWindow||component.props.chatWindow.isOpen));},panelOuterClass:"o-discuss-CallSettings",icon:"fa fa-fw fa-gear",iconLarge:"fa fa-fw fa-lg fa-gear",name:_t("Show Call Settings"),nameActive:_t("Hide Call Settings"),sequence(component){return component.props.chatWindow&&component.thread?.eq(component.rtc.state.channel)?6:60;},setup(){const component=useComponent();component.rtc=useState(useService("discuss.rtc"));},toggle:true,});return __exports;});;

/* /mail/static/src/discuss/call/common/thread_model_patch.js */
odoo.define('@mail/discuss/call/common/thread_model_patch',['@mail/core/common/thread_model','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{Thread}=require("@mail/core/common/thread_model");const{patch}=require("@web/core/utils/patch");patch(Thread.prototype,{update(data){super.update(data);if("rtc_inviting_session"in data){this.rtcInvitingSession=data.rtc_inviting_session;}
if("rtcInvitingSession"in data){this.rtcInvitingSession=data.rtcInvitingSession;}
if("rtcSessions"in data){this.rtcSessions=data.rtcSessions;}},});return __exports;});;

/* /mail/static/src/discuss/typing/common/composer_patch.js */
odoo.define('@mail/discuss/typing/common/composer_patch',['@mail/core/common/composer','@mail/discuss/typing/common/typing','@web/core/browser/browser','@web/core/registry','@web/core/utils/patch','@web/core/utils/timing'],function(require){'use strict';let __exports={};const{Composer}=require("@mail/core/common/composer");const{Typing}=require("@mail/discuss/typing/common/typing");const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const{patch}=require("@web/core/utils/patch");const{useDebounced}=require("@web/core/utils/timing");const commandRegistry=registry.category("discuss.channel_commands");const SHORT_TYPING=__exports.SHORT_TYPING=5000;const LONG_TYPING=__exports.LONG_TYPING=50000;patch(Composer,{components:{...Composer.components,Typing},});patch(Composer.prototype,{setup(){super.setup();this.typingNotified=false;this.stopTypingDebounced=useDebounced(this.stopTyping.bind(this),SHORT_TYPING);},notifyIsTyping(is_typing=true){if(["chat","channel","group"].includes(this.thread?.type)){this.rpc("/discuss/channel/notify_typing",{channel_id:this.thread.id,is_typing,},{silent:true});}},onInput(ev){if(this.thread?.model==="discuss.channel"&&ev.target.value.startsWith("/")){const[firstWord]=ev.target.value.substring(1).split(/\s/);const command=commandRegistry.get(firstWord,false);if(ev.target.value==="/"||this.hasSuggestions||(command&&(!command.channel_types||command.channel_types.includes(this.thread.type)))){this.stopTyping();return;}}
if(!this.typingNotified&&ev.target.value){this.typingNotified=true;this.notifyIsTyping();browser.setTimeout(()=>(this.typingNotified=false),LONG_TYPING);}
this.stopTypingDebounced();},async sendMessage(){await super.sendMessage();this.stopTyping();},stopTyping(){if(this.typingNotified){this.typingNotified=false;this.notifyIsTyping(false);}},});return __exports;});;

/* /mail/static/src/discuss/typing/common/thread_icon_patch.js */
odoo.define('@mail/discuss/typing/common/thread_icon_patch',['@mail/core/common/thread_icon','@mail/discuss/typing/common/typing','@odoo/owl','@web/core/utils/hooks','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{ThreadIcon}=require("@mail/core/common/thread_icon");const{Typing}=require("@mail/discuss/typing/common/typing");const{useState}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{patch}=require("@web/core/utils/patch");patch(ThreadIcon,{components:{...ThreadIcon.components,Typing},});patch(ThreadIcon.prototype,{setup(){super.setup();this.typingService=useState(useService("discuss.typing"));},});return __exports;});;

/* /mail/static/src/discuss/typing/common/typing.js */
odoo.define('@mail/discuss/typing/common/typing',['@odoo/owl','@web/core/l10n/translation','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{Component,useState}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const Typing=__exports.Typing=class Typing extends Component{static defaultProps={size:"small",displayText:true,};static props=["channel","size?","displayText?"];static template="discuss.Typing";setup(){this.typingService=useState(useService("discuss.typing"));}
get text(){const typingMemberNames=this.typingService.getTypingMembers(this.props.channel).map(({persona})=>this.props.channel.getMemberName(persona));if(typingMemberNames.length===1){return _t("%s is typing...",typingMemberNames[0]);}
if(typingMemberNames.length===2){return _t("%s and %s are typing...",typingMemberNames[0],typingMemberNames[1]);}
return _t("%s, %s and more are typing...",typingMemberNames[0],typingMemberNames[1]);}}
return __exports;});;

/* /mail/static/src/discuss/typing/common/typing_service.js */
odoo.define('@mail/discuss/typing/common/typing_service',['@odoo/owl','@web/core/browser/browser','@web/core/registry'],function(require){'use strict';let __exports={};const{reactive}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{registry}=require("@web/core/registry");const OTHER_LONG_TYPING=__exports.OTHER_LONG_TYPING=60000;const Typing=__exports.Typing=class Typing{busService;channelMemberService;memberIdsByChannelId=new Map();timerByMemberId=new Map();storeService;constructor(services){this.busService=services.bus_service;this.channelMemberService=services["discuss.channel.member"];this.storeService=services["mail.store"];}
setup(){this.busService.subscribe("discuss.channel.member/typing_status",(payload)=>{const member=this.storeService.ChannelMember.insert(payload);if(payload.isTyping){this.addTypingMember(member);}else{this.removeTypingMember(member);}});}
addTypingMember(member){if(!this.memberIdsByChannelId.has(member.thread.id)){this.memberIdsByChannelId.set(member.thread.id,new Set());}
const memberIds=this.memberIdsByChannelId.get(member.thread.id);memberIds.add(member.id);browser.clearTimeout(this.timerByMemberId.get(member.id));this.timerByMemberId.set(member.id,browser.setTimeout(()=>this.removeTypingMember(member),OTHER_LONG_TYPING));}
getTypingMembers(channel){return[...(this.memberIdsByChannelId.get(channel.id)??new Set())].map((id)=>this.storeService.ChannelMember.insert({id})).filter((member)=>!member.persona?.eq(this.storeService.self));}
hasTypingMembers(channel){return this.getTypingMembers(channel).length>0;}
removeTypingMember(member){const memberIds=this.memberIdsByChannelId.get(member.thread.id);if(memberIds){memberIds.delete(member.id);if(memberIds.size===0){this.memberIdsByChannelId.delete(member.thread.id);}}
browser.clearTimeout(this.timerByMemberId.get(member.id));this.timerByMemberId.delete(member.id);}}
const discussTypingService=__exports.discussTypingService={dependencies:["bus_service","discuss.channel.member","mail.store"],start(env,services){const typing=reactive(new Typing(services));typing.setup();return typing;},};registry.category("services").add("discuss.typing",discussTypingService);return __exports;});;

/* /mail/static/src/utils/common/dates.js */
odoo.define('@mail/utils/common/dates',[],function(require){'use strict';let __exports={};const{DateTime}=luxon;__exports.computeDelay=computeDelay;function computeDelay(dateStr){const today=DateTime.now().startOf("day");const date=DateTime.fromISO(dateStr);return date.diff(today,"days").days;}
__exports.getMsToTomorrow=getMsToTomorrow;function getMsToTomorrow(){const now=new Date();const night=new Date(now.getFullYear(),now.getMonth(),now.getDate()+1,0,0,0);return night.getTime()-now.getTime();}
return __exports;});;

/* /mail/static/src/utils/common/format.js */
odoo.define('@mail/utils/common/format',['@web/core/emoji_picker/emoji_picker','@web/core/utils/strings','@web/core/utils/urls'],function(require){'use strict';let __exports={};const{loadEmoji}=require("@web/core/emoji_picker/emoji_picker");const{escape,unaccent}=require("@web/core/utils/strings");const{url}=require("@web/core/utils/urls");const urlRegexp=/\b(?:https?:\/\/\d{1,3}(?:\.\d{1,3}){3}|(?:https?:\/\/|(?:www\.))[-a-z0-9@:%._+~#=\u00C0-\u024F\u1E00-\u1EFF]{2,256}\.[a-z]{2,13})\b(?:[-a-z0-9@:%_+~#?&[\]^|{}`\\'$//=\u00C0-\u024F\u1E00-\u1EFF]|,(?!$| )|\.(?!$| |\.)|;(?!$| ))*/gi;const _escapeEntities=(function(){const map={"&":"&amp;","<":"&lt;",">":"&gt;"};const escaper=function(match){return map[match];};const testRegexp=RegExp("(?:&|<|>)");const replaceRegexp=RegExp("(?:&|<|>)","g");return function(string){string=string==null?"":""+string;return testRegexp.test(string)?string.replace(replaceRegexp,escaper):string;};})();__exports.prettifyMessageContent=prettifyMessageContent;async function prettifyMessageContent(rawBody,validRecords=[]){const escapedAndCompactContent=escapeAndCompactTextContent(rawBody);let body=escapedAndCompactContent.replace(/&nbsp;/g," ").trim();body=generateMentionsLinks(body,validRecords);body=parseAndTransform(body,addLink);body=await _generateEmojisOnHtml(body);return body;}
__exports.parseAndTransform=parseAndTransform;function parseAndTransform(htmlString,transformFunction){const openToken="OPEN"+Date.now();const string=htmlString.replace(/&lt;/g,openToken);let children;try{const div=document.createElement("div");div.innerHTML=string;children=Array.from(div.childNodes);}catch{const div=document.createElement("div");div.innerHTML=`<pre>${string}</pre>`;children=Array.from(div.childNodes);}
return _parseAndTransform(children,transformFunction).replace(new RegExp(openToken,"g"),"&lt;");}
function _parseAndTransform(nodes,transformFunction){if(!nodes){return;}
return Object.values(nodes).map((node)=>{return transformFunction(node,function(){return _parseAndTransform(node.childNodes,transformFunction);});}).join("");}
function linkify(text){let curIndex=0;let result="";let match;while((match=urlRegexp.exec(text))!==null){result+=_escapeEntities(text.slice(curIndex,match.index));const url=decodeURI(match[0]);const href=encodeURI(!/^https?:\/\//i.test(url)?"http://"+url:url);result+=`<a target="_blank" rel="noreferrer noopener" href="${href}">${_escapeEntities(
            url
        )}</a>`;curIndex=match.index+match[0].length;}
return result+_escapeEntities(text.slice(curIndex));}
__exports.addLink=addLink;function addLink(node,transformChildren){if(node.nodeType===3){const linkified=linkify(node.data);if(linkified!==node.data){const div=document.createElement("div");div.innerHTML=linkified;for(const childNode of[...div.childNodes]){node.parentNode.insertBefore(childNode,node);}
node.parentNode.removeChild(node);return linkified;}
return node.textContent;}
if(node.tagName==="A"){return node.outerHTML;}
transformChildren();return node.outerHTML;}
__exports.escapeAndCompactTextContent=escapeAndCompactTextContent;function escapeAndCompactTextContent(content){let value=escape(content).trim();value=value.replace(/(\r|\n){2,}/g,"<br/><br/>");value=value.replace(/(\r|\n)/g,"<br/>");value=value.replace(/ /g,"&nbsp;").replace(/([^>])&nbsp;([^<])/g,"$1 $2");return value;}
function generateMentionsLinks(body,{partners=[],threads=[]}){const mentions=[];for(const partner of partners){const placeholder=`@-mention-partner-${partner.id}`;const text=`@${escape(partner.name)}`;mentions.push({class:"o_mail_redirect",id:partner.id,model:"res.partner",placeholder,text,});body=body.replace(text,placeholder);}
for(const thread of threads){const placeholder=`#-mention-channel-${thread.id}`;const text=`#${escape(thread.displayName)}`;mentions.push({class:"o_channel_redirect",id:thread.id,model:"discuss.channel",placeholder,text,});body=body.replace(text,placeholder);}
const baseHREF=url("/web");for(const mention of mentions){const href=`href='${baseHREF}#model=${mention.model}&id=${mention.id}'`;const attClass=`class='${mention.class}'`;const dataOeId=`data-oe-id='${mention.id}'`;const dataOeModel=`data-oe-model='${mention.model}'`;const target="target='_blank'";const link=`<a ${href} ${attClass} ${dataOeId} ${dataOeModel} ${target} contenteditable="false">${mention.text}</a>`;body=body.replace(mention.placeholder,link);}
return body;}
async function _generateEmojisOnHtml(htmlString){const{emojis}=await loadEmoji();for(const emoji of emojis){for(const source of[...emoji.shortcodes,...emoji.emoticons]){const escapedSource=escape(String(source)).replace(/([.*+?=^!:${}()|[\]/\\])/g,"\\$1");const regexp=new RegExp("(\\s|^)("+escapedSource+")(?=\\s|$)","g");htmlString=htmlString.replace(regexp,"$1"+emoji.codepoints);}}
return htmlString;}
__exports.htmlToTextContentInline=htmlToTextContentInline;function htmlToTextContentInline(htmlString){const fragment=document.createDocumentFragment();const div=document.createElement("div");fragment.appendChild(div);htmlString=htmlString.replace(/<br\s*\/?>/gi," ");try{div.innerHTML=htmlString;}catch{div.innerHTML=`<pre>${htmlString}</pre>`;}
return div.textContent.trim().replace(/[\n\r]/g,"").replace(/\s\s+/g," ");}
__exports.convertBrToLineBreak=convertBrToLineBreak;function convertBrToLineBreak(str){return new DOMParser().parseFromString(str.replaceAll("<br>","\n").replaceAll("</br>","\n"),"text/html").body.textContent;}
__exports.cleanTerm=cleanTerm;function cleanTerm(term){return unaccent((typeof term==="string"?term:"").toLowerCase());}
return __exports;});;

/* /mail/static/src/utils/common/hooks.js */
odoo.define('@mail/utils/common/hooks',['@odoo/owl','@web/core/browser/browser','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{onMounted,onPatched,onWillPatch,onWillUnmount,useComponent,useEffect,useRef,useState,}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{useService}=require("@web/core/utils/hooks");__exports.useLazyExternalListener=useLazyExternalListener;function useLazyExternalListener(target,eventName,handler,eventParams){const boundHandler=handler.bind(useComponent());let t;onMounted(()=>{t=target();if(!t){return;}
t.addEventListener(eventName,boundHandler,eventParams);});onPatched(()=>{const t2=target();if(t!==t2){if(t){t.removeEventListener(eventName,boundHandler,eventParams);}
if(t2){t2.addEventListener(eventName,boundHandler,eventParams);}
t=t2;}});onWillUnmount(()=>{if(!t){return;}
t.removeEventListener(eventName,boundHandler,eventParams);});}
__exports.onExternalClick=onExternalClick;function onExternalClick(refName,cb){let downTarget,upTarget;const ref=useRef(refName);function onClick(ev){if(ref.el&&!ref.el.contains(ev.target)){cb(ev,{downTarget,upTarget});upTarget=downTarget=null;}}
function onMousedown(ev){downTarget=ev.target;}
function onMouseup(ev){upTarget=ev.target;}
onMounted(()=>{document.body.addEventListener("mousedown",onMousedown,true);document.body.addEventListener("mouseup",onMouseup,true);document.body.addEventListener("click",onClick,true);});onWillUnmount(()=>{document.body.removeEventListener("mousedown",onMousedown,true);document.body.removeEventListener("mouseup",onMouseup,true);document.body.removeEventListener("click",onClick,true);});}
__exports.useHover=useHover;function useHover(refName,callback=()=>{}){const ref=useRef(refName);const state=useState({isHover:false});function onHover(hovered){state.isHover=hovered;callback(hovered);}
useLazyExternalListener(()=>ref.el,"mouseenter",(ev)=>{if(ref.el.contains(ev.relatedTarget)){return;}
onHover(true);},true);useLazyExternalListener(()=>ref.el,"mouseleave",(ev)=>{if(ref.el.contains(ev.relatedTarget)){return;}
onHover(false);},true);return state;}
__exports.useOnBottomScrolled=useOnBottomScrolled;function useOnBottomScrolled(refName,callback,threshold=1){const ref=useRef(refName);function onScroll(){if(Math.abs(ref.el.scrollTop+ref.el.clientHeight-ref.el.scrollHeight)<threshold){callback();}}
onMounted(()=>{ref.el.addEventListener("scroll",onScroll);});onWillUnmount(()=>{ref.el.removeEventListener("scroll",onScroll);});}
__exports.useAutoScroll=useAutoScroll;function useAutoScroll(refName,shouldScrollPredicate=()=>true){const ref=useRef(refName);let el=null;let isScrolled=true;let lastSetValue;const observer=new ResizeObserver(applyScroll);function onScroll(){isScrolled=Math.abs(el.scrollTop+el.clientHeight-el.scrollHeight)<1;}
async function applyScroll(){if(isScrolled&&shouldScrollPredicate()&&lastSetValue!==ref.el.scrollHeight){lastSetValue=ref.el.scrollHeight;ref.el.scrollTop=ref.el.scrollHeight;}}
onMounted(()=>{el=ref.el;applyScroll();observer.observe(el);el.addEventListener("scroll",onScroll);});onWillUnmount(()=>{observer.unobserve(el);el.removeEventListener("scroll",onScroll);});onPatched(applyScroll);}
__exports.useVisible=useVisible;function useVisible(refName,cb,{init=false,ready=true}={}){const ref=useRef(refName);const state=useState({isVisible:init,ready,});function setValue(value){state.isVisible=value;cb();}
const observer=new IntersectionObserver((entries)=>{setValue(entries.at(-1).isIntersecting);});useEffect((el,ready)=>{if(el&&ready){observer.observe(el);return()=>{setValue(false);observer.unobserve(el);};}},()=>[ref.el,state.ready]);return state;}
__exports.useScrollSnapshot=useScrollSnapshot;function useScrollSnapshot(ref,{onWillPatch:p_onWillPatch,onPatched:p_onPatched}){const snapshot={scrollHeight:null,scrollTop:null,clientHeight:null,};onMounted(()=>{const el=ref.el;Object.assign(snapshot,{scrollHeight:el.scrollHeight,scrollTop:el.scrollTop,clientHeight:el.clientHeight,});});onWillPatch(()=>{const el=ref.el;Object.assign(snapshot,{scrollHeight:el.scrollHeight,scrollTop:el.scrollTop,clientHeight:el.clientHeight,...p_onWillPatch(),});});onPatched(()=>{const el=ref.el;Object.assign(snapshot,{scrollHeight:el.scrollHeight,scrollTop:el.scrollTop,clientHeight:el.clientHeight,...p_onPatched(snapshot),});});}
__exports.useMessageHighlight=useMessageHighlight;function useMessageHighlight(duration=2000){let timeout;const threadService=useService("mail.thread");const state=useState({clearHighlight(){if(this.highlightedMessageId){browser.clearTimeout(timeout);timeout=null;this.highlightedMessageId=null;}},async highlightMessage(message,thread){if(thread.notEq(message.originThread)){return;}
await threadService.loadAround(thread,message.id);const lastHighlightedMessageId=state.highlightedMessageId;this.clearHighlight();if(lastHighlightedMessageId===message.id){await new Promise(setTimeout);}
thread.scrollTop=undefined;state.highlightedMessageId=message.id;timeout=browser.setTimeout(()=>this.clearHighlight(),duration);},highlightedMessageId:null,});return state;}
__exports.useSelection=useSelection;function useSelection({refName,model,preserveOnClickAwayPredicate=()=>false}){const ui=useState(useService("ui"));const ref=useRef(refName);function onSelectionChange(){if(document.activeElement&&document.activeElement===ref.el){Object.assign(model,{start:ref.el.selectionStart,end:ref.el.selectionEnd,direction:ref.el.selectionDirection,});}}
onExternalClick(refName,async(ev)=>{if(await preserveOnClickAwayPredicate(ev)){return;}
if(!ref.el){return;}
Object.assign(model,{start:ref.el.value.length,end:ref.el.value.length,direction:ref.el.selectionDirection,});});onMounted(()=>{document.addEventListener("selectionchange",onSelectionChange);document.addEventListener("input",onSelectionChange);});onWillUnmount(()=>{document.removeEventListener("selectionchange",onSelectionChange);document.removeEventListener("input",onSelectionChange);});return{restore(){ref.el?.setSelectionRange(model.start,model.end,model.direction);},moveCursor(position){model.start=model.end=position;if(!ui.isSmall){ref.el.selectionStart=ref.el.selectionEnd=position;}},};}
__exports.useScrollPosition=useScrollPosition;function useScrollPosition(refName,model,clearOn){const ref=useRef(refName);let observeScroll=false;const self={ref,model,restore(){if(!self.model){return;}
ref.el?.scrollTo({left:self.model.left,top:self.model.top,});},};function isScrolledToBottom(){if(!ref.el){return false;}
return Math.abs(ref.el.scrollTop+ref.el.clientHeight-ref.el.scrollHeight)<1;}
function onScrolled(){if(!self.model){return;}
if((clearOn==="bottom"&&isScrolledToBottom())||(clearOn==="top"&&ref.el.scrollTop===0)){return self.model.clear();}
Object.assign(self.model,{top:ref.el.scrollTop,left:ref.el.scrollLeft,});}
onMounted(()=>{if(ref.el){observeScroll=true;}
ref.el?.addEventListener("scroll",onScrolled);});onPatched(()=>{if(!observeScroll&&ref.el){observeScroll=true;ref.el.addEventListener("scroll",onScrolled);}});onWillUnmount(()=>{ref.el?.removeEventListener("scroll",onScrolled);});return self;}
__exports.useMessageEdition=useMessageEdition;function useMessageEdition(){const state=useState({composerOfThread:null,editingMessage:null,exitEditMode(){state.editingMessage=null;if(state.composerOfThread){state.composerOfThread.props.composer.autofocus++;}},});return state;}
__exports.useMessageToReplyTo=useMessageToReplyTo;function useMessageToReplyTo(){return useState({cancel(){Object.assign(this,{message:null,thread:null});},isNotSelected(thread,message){return thread.eq(this.thread)&&message.notEq(this.message);},isSelected(thread,message){return thread.eq(this.thread)&&message.eq(this.message);},message:null,thread:null,toggle(thread,message){if(message.eq(this.message)){this.cancel();}else{Object.assign(this,{message,thread});}},});}
__exports.useSequential=useSequential;function useSequential(){let inProgress=false;let nextFunction;let nextResolve;let nextReject;async function call(){const resolve=nextResolve;const reject=nextReject;const func=nextFunction;nextResolve=undefined;nextReject=undefined;nextFunction=undefined;inProgress=true;try{const data=await func();resolve(data);}catch(e){reject(e);}
inProgress=false;if(nextFunction&&nextResolve){call();}}
return(func)=>{nextResolve?.();const prom=new Promise((resolve,reject)=>{nextResolve=resolve;nextReject=reject;});nextFunction=func;if(!inProgress){call();}
return prom;};}
__exports.useDiscussSystray=useDiscussSystray;function useDiscussSystray(){const ui=useState(useService("ui"));return{class:"o-mail-DiscussSystray-class",get contentClass(){return`d-flex flex-column flex-grow-1 bg-view ${
                ui.isSmall ? "overflow-auto w-100 mh-100" : ""
            }`;},get menuClass(){return`p-0 o-mail-DiscussSystray ${
                ui.isSmall
                    ? "o-mail-systrayFullscreenDropdownMenu start-0 w-100 mh-100 d-flex flex-column mt-0 border-0 shadow-lg"
                    : ""
            }`;},};}
return __exports;});;

/* /mail/static/src/utils/common/misc.js */
odoo.define('@mail/utils/common/misc',['@odoo/owl'],function(require){'use strict';let __exports={};const{reactive}=require("@odoo/owl");__exports.assignDefined=assignDefined;function assignDefined(obj,data,keys=Object.keys(data)){for(const key of keys){if(data[key]!==undefined){obj[key]=data[key];}}
return obj;}
__exports.assignIn=assignIn;function assignIn(obj,data,keys=Object.keys(data)){for(const key of keys){if(key in data){obj[key]=data[key];}}
return obj;}
__exports.isDragSourceExternalFile=isDragSourceExternalFile;function isDragSourceExternalFile(dataTransfer){const dragDataType=dataTransfer.types;if(dragDataType.constructor===window.DOMStringList){return dragDataType.contains("Files");}
if(dragDataType.constructor===Array){return dragDataType.includes("Files");}
return false;}
__exports.onChange=onChange;function onChange(target,key,callback){let proxy;function _observe(){const val=proxy[key];if(typeof val==="object"&&val!==null){void Object.keys(val);}
if(Array.isArray(val)){void val.length;void val.forEach((i)=>i);}}
if(Array.isArray(key)){for(const k of key){onChange(target,k,callback);}
return;}
proxy=reactive(target,()=>{_observe();callback();});_observe();return proxy;}
__exports.closeStream=closeStream;function closeStream(stream){stream?.getTracks?.().forEach((track)=>track.stop());}
__exports.compareDatetime=compareDatetime;function compareDatetime(date1,date2){if(date1?.ts===date2?.ts){return 0;}
if(!date1){return-1;}
if(!date2){return 1;}
return date1.ts-date2.ts;}
function compareVersion(v1,v2){const parts1=v1.split(".");const parts2=v2.split(".");for(let i=0;i<Math.max(parts1.length,parts2.length);i++){const num1=parseInt(parts1[i])||0;const num2=parseInt(parts2[i])||0;if(num1<num2){return-1;}
if(num1>num2){return 1;}}
return 0;}
__exports.parseVersion=parseVersion;function parseVersion(v){return{isLowerThan(other){return compareVersion(v,other)<0;},};}
return __exports;});;

/* /im_livechat/static/src/core/common/thread_model_patch.js */
odoo.define('@im_livechat/core/common/thread_model_patch',['@mail/core/common/record','@mail/core/common/thread_model','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{Record}=require("@mail/core/common/record");const{Thread}=require("@mail/core/common/thread_model");const{patch}=require("@web/core/utils/patch");patch(Thread,{_insert(data){const thread=super._insert(...arguments);if(thread.type==="livechat"){if(data?.operator_pid){thread.operator={type:"partner",id:data.operator_pid[0],name:data.operator_pid[1],};}}
return thread;},});patch(Thread.prototype,{setup(){super.setup();this.operator=Record.one("Persona");},get typesAllowingCalls(){return super.typesAllowingCalls.concat(["livechat"]);},get isChatChannel(){return this.type==="livechat"||super.isChatChannel;},});return __exports;});;

/* /im_livechat/static/src/embed/common/autopopup_service.js */
odoo.define('@im_livechat/embed/common/autopopup_service',['@web/core/browser/browser','@web/core/browser/cookie','@web/core/registry'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{cookie}=require("@web/core/browser/cookie");const{registry}=require("@web/core/registry");const AutopopupService=__exports.AutopopupService=class AutopopupService{static COOKIE="im_livechat_auto_popup";constructor(env,{"im_livechat.chatbot":chatbotService,"im_livechat.livechat":livechatService,"mail.thread":threadService,"mail.store":storeService,ui,}){this.threadService=threadService;this.storeService=storeService;this.livechatService=livechatService;this.chatbotService=chatbotService;this.ui=ui;livechatService.initializedDeferred.then(()=>{if(livechatService.shouldRestoreSession){threadService.openChat();}else if(this.allowAutoPopup){browser.setTimeout(async()=>{if(await this.shouldOpenChatWindow()){cookie.set(AutopopupService.COOKIE,JSON.stringify(false));threadService.openChat();}},livechatService.rule.auto_popup_timer*1000);}});}
async shouldOpenChatWindow(){const thread=await this.livechatService.thread;return this.storeService.discuss.chatWindows.every((cw)=>!cw.thread?.eq(thread));}
get allowAutoPopup(){return Boolean(JSON.parse(cookie.get(AutopopupService.COOKIE)??"true")!==false&&!this.ui.isSmall&&this.livechatService.rule?.action==="auto_popup"&&(this.livechatService.available||this.chatbotService.available));}}
const autoPopupService=__exports.autoPopupService={dependencies:["im_livechat.livechat","im_livechat.chatbot","mail.thread","mail.store","ui",],start(env,services){return new AutopopupService(env,services);},};registry.category("services").add("im_livechat.autopopup",autoPopupService);return __exports;});;

/* /im_livechat/static/src/embed/common/boot_helpers.js */
odoo.define('@im_livechat/embed/common/boot_helpers',['@web/core/utils/urls'],function(require){'use strict';let __exports={};const{url}=require("@web/core/utils/urls");async function loadFont(name,url){await document.fonts.ready;if([...document.fonts].some(({family})=>family===name)){return;}
const link=document.createElement("link");link.rel="preload";link.as="font";link.href=url;link.crossOrigin="";const style=document.createElement("style");style.appendChild(document.createTextNode(`
            @font-face {
                font-family: ${name};
                src: url('${url}') format('woff2');
                font-weight: normal;
                font-style: normal;
                font-display: block;
            }
        `));const loadPromise=new Promise((res,rej)=>{link.addEventListener("load",res);link.addEventListener("error",rej);});document.head.appendChild(link);document.head.appendChild(style);return loadPromise;}
__exports.makeRoot=makeRoot;function makeRoot(target){const root=document.createElement("div");root.classList.add("o-livechat-root");root.style.zIndex="calc(9e999)";root.style.position="relative";target.appendChild(root);return root;}
__exports.makeShadow=makeShadow;async function makeShadow(root){const link=document.createElement("link");link.rel="stylesheet";link.href=url("/im_livechat/assets_embed.css");const stylesLoadedPromise=new Promise((res,rej)=>{link.addEventListener("load",res);link.addEventListener("error",rej);});const shadow=root.attachShadow({mode:"open"});shadow.appendChild(link);await Promise.all([stylesLoadedPromise,loadFont("FontAwesome",url("/im_livechat/font-awesome")),loadFont("odoo_ui_icons",url("/im_livechat/odoo_ui_icons")),]);return shadow;}
return __exports;});;

/* /im_livechat/static/src/embed/common/chat_window_patch.js */
odoo.define('@im_livechat/embed/common/chat_window_patch',['@im_livechat/embed/common/livechat_service','@im_livechat/embed/common/feedback_panel/feedback_panel','@mail/core/common/chat_window','@odoo/owl','@web/core/utils/hooks','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{SESSION_STATE}=require("@im_livechat/embed/common/livechat_service");const{FeedbackPanel}=require("@im_livechat/embed/common/feedback_panel/feedback_panel");const{ChatWindow}=require("@mail/core/common/chat_window");const{useState}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{patch}=require("@web/core/utils/patch");Object.assign(ChatWindow.components,{FeedbackPanel});patch(ChatWindow.prototype,{setup(){super.setup(...arguments);this.livechatService=useService("im_livechat.livechat");this.chatbotService=useState(useService("im_livechat.chatbot"));this.livechatState=useState({hasFeedbackPanel:false,});},async close(){if(this.thread?.type!=="livechat"){return super.close();}
if(this.livechatService.state===SESSION_STATE.PERSISTED){this.livechatState.hasFeedbackPanel=true;this.chatWindowService.show(this.props.chatWindow);}else{this.thread?.delete();await super.close();}
this.livechatService.leaveSession();this.chatbotService.stop();},});return __exports;});;

/* /im_livechat/static/src/embed/common/chatbot/chatbot_model.js */
odoo.define('@im_livechat/embed/common/chatbot/chatbot_model',['@mail/utils/common/misc'],function(require){'use strict';let __exports={};const{assignDefined}=require("@mail/utils/common/misc");const Chatbot=__exports.Chatbot=class Chatbot{name;partnerId;welcomeStepIndex=0;scriptId;welcomeSteps=[];constructor(data){assignDefined(this,data,["name","partnerId","scriptId","welcomeSteps","welcomeStepIndex",]);}
get welcomeCompleted(){return this.welcomeStepIndex>=this.welcomeSteps.length;}
get nextWelcomeStep(){return this.welcomeSteps[this.welcomeStepIndex++];}}
return __exports;});;

/* /im_livechat/static/src/embed/common/chatbot/chatbot_service.js */
odoo.define('@im_livechat/embed/common/chatbot/chatbot_service',['@im_livechat/embed/common/chatbot/chatbot_model','@im_livechat/embed/common/chatbot/chatbot_step_model','@im_livechat/embed/common/livechat_service','@odoo/owl','@web/core/browser/browser','@web/core/l10n/translation','@web/core/registry','@web/core/utils/timing'],function(require){'use strict';let __exports={};const{Chatbot}=require("@im_livechat/embed/common/chatbot/chatbot_model");const{ChatbotStep}=require("@im_livechat/embed/common/chatbot/chatbot_step_model");const{SESSION_STATE}=require("@im_livechat/embed/common/livechat_service");const{EventBus,markup,reactive}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{debounce}=require("@web/core/utils/timing");const MESSAGE_DELAY=1500;const STEP_DELAY=500;const MULTILINE_STEP_DEBOUNCE_DELAY=10000;const ChatBotService=__exports.ChatBotService=class ChatBotService{chatbot;currentStep;nextStepTimeout;hasPostedWelcomeSteps=false;isTyping=false;constructor(env,services){const self=reactive(this);self.setup(env,services);return self;}
setup(env,services){this.env=env;this.bus=new EventBus();this.livechatService=services["im_livechat.livechat"];this.messageService=services["mail.message"];this.store=services["mail.store"];this.rpc=services.rpc;this.debouncedProcessUserAnswer=debounce(this._processUserAnswer.bind(this),MULTILINE_STEP_DEBOUNCE_DELAY);if(this.livechatService.options.isTestChatbot){this.livechatService.rule.chatbot={...this.livechatService.options.testChatbotData,welcomeStepIndex:this.livechatService.options.testChatbotData.welcomeSteps.length,};this.currentStep=new ChatbotStep(this.livechatService.options.testChatbotData.welcomeSteps.at(-1));this.livechatService.updateSession(this.livechatService.options.testChatbotChannelData);}
this.livechatService.initializedDeferred.then(()=>{this.chatbot=this.livechatService.rule?.chatbot?new Chatbot(this.livechatService.rule.chatbot):undefined;});this.bus.addEventListener("MESSAGE_POST",({detail:message})=>{if(this.currentStep?.type==="free_input_multi"){this.debouncedProcessUserAnswer(message);}else{this._processUserAnswer(message);}});}
async start(){if(this.livechatService.options.isTestChatbot&&!this.hasPostedWelcomeSteps){await this.postWelcomeSteps();this.save();}
if(!this.currentStep?.expectAnswer){this._triggerNextStep();}else if(this.livechatService.thread?.isLastMessageFromCustomer){this._processUserAnswer(this.livechatService.thread.newestMessage);}}
stop(){this.clear();clearTimeout(this.nextStepTimeout);this.currentStep=null;this.isTyping=false;if(this.livechatService.rule?.chatbot){this.chatbot=new Chatbot(this.livechatService.rule.chatbot);}}
async restart(){if(!this.completed||!this.livechatService.thread){return;}
localStorage.removeItem(`im_livechat.chatbot.state.uuid_${this.livechatService.thread.uuid}`);const message=this.store.Message.insert(await this.rpc("/chatbot/restart",{channel_uuid:this.livechatService.thread.uuid,chatbot_script_id:this.chatbot.scriptId,}),{html:true});if(!this.livechatService.thread){return;}
if(message.notIn(this.livechatService.thread.messages)){this.livechatService.thread.messages.push(message);}
this.currentStep=null;this.start();}
async postWelcomeSteps(){const rawMessages=await this.rpc("/chatbot/post_welcome_steps",{channel_uuid:this.livechatService.thread.uuid,chatbot_script_id:this.chatbot.scriptId,});for(const rawMessage of rawMessages){this.livechatService.thread?.messages.add({...rawMessage,body:markup(rawMessage.body),});}
this.hasPostedWelcomeSteps=true;}
_triggerNextStep(){if(this.completed){return;}
this.isTyping=!this.isRestoringSavedState;this.nextStepTimeout=browser.setTimeout(async()=>{const{step,stepMessage}=await this._getNextStep();if(!this.active){return;}
this.isTyping=false;if(!step&&this.currentStep){this.currentStep.isLast=true;return;}
if(stepMessage){this.livechatService.thread?.messages.add({...stepMessage,body:markup(stepMessage.body),});}
this.currentStep=step;if(this.currentStep?.type==="question_email"&&this.livechatService.thread.isLastMessageFromCustomer){await this.validateEmail();}
this.save();if(this.currentStep.expectAnswer){return;}
browser.setTimeout(()=>this._triggerNextStep(),this.stepDelay);},this.messageDelay);}
async _getNextStep(){if(this.currentStep?.expectAnswer){return{step:this.currentStep};}
if(!this.chatbot.welcomeCompleted){const welcomeStep=this.chatbot.nextWelcomeStep;return{step:new ChatbotStep(welcomeStep),stepMessage:{chatbotStep:welcomeStep,id:this.messageService.getNextTemporaryId(),body:welcomeStep.message,res_id:this.livechatService.thread.id,model:this.livechatService.thread.model,author:this.livechatService.thread.operator,},};}
const nextStepData=await this.rpc("/chatbot/step/trigger",{channel_uuid:this.livechatService.thread.uuid,chatbot_script_id:this.chatbot.scriptId,});const{chatbot_posted_message,chatbot_step}=nextStepData??{};return{step:chatbot_step?new ChatbotStep(chatbot_step):null,stepMessage:chatbot_posted_message,};}
async _processUserAnswer(message){if(!this.active||message.originThread.localId!==this.livechatService.thread?.localId||!this.currentStep?.expectAnswer){return;}
const answer=this.currentStep.answers.find(({label})=>message.body.includes(label));const stepMessage=message.originThread.messages.findLast(({chatbotStep})=>chatbotStep?.id===this.currentStep.id);if(stepMessage){stepMessage.chatbotStep.hasAnswer=true;}
this.currentStep.hasAnswer=true;this.save();let isRedirecting=false;if(answer){if(answer.redirectLink&&URL.canParse(answer.redirectLink,window.location.href)){const url=new URL(window.location.href);const nextURL=new URL(answer.redirectLink,window.location.href);isRedirecting=url.pathname!==nextURL.pathname||url.origin!==nextURL.origin;browser.location.assign(answer.redirectLink);}
await this.rpc("/chatbot/answer/save",{channel_uuid:this.livechatService.thread.uuid,message_id:stepMessage.id,selected_answer_id:answer.id,});}
if(isRedirecting){return;}
this._triggerNextStep();}
async validateEmail(){const{success,posted_message:msg}=await this.rpc("/chatbot/step/validate_email",{channel_uuid:this.livechatService.thread.uuid,});this.currentStep.isEmailValid=success;if(msg){this.livechatService.thread.messages.add({...msg,body:markup(msg.body)});}}
isChatbotThread(thread){return thread?.operator.id===this.chatbot?.partnerId;}
async _restore(){const{_chatbotCurrentStep,_chatbot}=this.savedState;this.currentStep=_chatbotCurrentStep?new ChatbotStep(_chatbotCurrentStep):undefined;this.chatbot=_chatbot?new Chatbot(_chatbot):undefined;if(this.livechatService.state!==SESSION_STATE.PERSISTED){this.chatbot.welcomeStepIndex=0;this.currentStep=null;}}
async clear(){const chatbotStorageKey=this.livechatService.savedState?`im_livechat.chatbot.state.uuid_${this.livechatService.savedState.uuid}`:"";for(let i=0;i<browser.localStorage.length;i++){const key=browser.localStorage.key(i);if(key!==chatbotStorageKey&&key.includes("im_livechat.chatbot.state.uuid_")){browser.localStorage.removeItem(key);}}}
async save(){if(this.isRestoringSavedState){return;}
browser.localStorage.setItem(`im_livechat.chatbot.state.uuid_${this.livechatService.thread.uuid}`,JSON.stringify({_chatbot:this.chatbot,_chatbotCurrentStep:this.currentStep,}));}
get stepDelay(){return this.isRestoringSavedState||this.livechatService.thread?.isLastMessageFromCustomer?0:STEP_DELAY;}
get messageDelay(){return this.isRestoringSavedState|!this.currentStep?0:MESSAGE_DELAY;}
get active(){return this.available&&this.isChatbotThread(this.livechatService.thread);}
get available(){return Boolean(this.chatbot);}
get completed(){return(this.currentStep?.operatorFound||(this.currentStep?.isLast&&!this.currentStep?.expectAnswer));}
get canRestart(){return this.completed&&!this.currentStep?.operatorFound;}
get inputEnabled(){if(!this.active||this.currentStep?.operatorFound){return true;}
return(!this.isTyping&&this.currentStep?.expectAnswer&&this.currentStep?.answers.length===0);}
get inputDisabledText(){if(this.inputEnabled){return"";}
if(this.completed){return _t("Conversation ended...");}
switch(this.currentStep?.type){case"question_selection":return _t("Select an option above");default:return _t("Say something");}}
get savedState(){const raw=browser.localStorage.getItem(`im_livechat.chatbot.state.uuid_${this.livechatService.savedState?.uuid}`);return raw?JSON.parse(raw):null;}
get isRestoringSavedState(){return this.savedState?._chatbotCurrentStep.id>this.currentStep?.id;}}
const chatBotService=__exports.chatBotService={dependencies:["im_livechat.livechat","mail.message","mail.store","rpc"],start(env,services){return new ChatBotService(env,services);},};registry.category("services").add("im_livechat.chatbot",chatBotService);return __exports;});;

/* /im_livechat/static/src/embed/common/chatbot/chatbot_step_model.js */
odoo.define('@im_livechat/embed/common/chatbot/chatbot_step_model',['@mail/utils/common/misc'],function(require){'use strict';let __exports={};const{assignDefined}=require("@mail/utils/common/misc");const ChatbotStep=__exports.ChatbotStep=class ChatbotStep{id;answers=[];message;type;hasAnswer=false;isEmailValid=false;operatorFound=false;isLast=false;constructor(data){assignDefined(this,data,["answers","id","isLast","message","operatorFound","hasAnswer","type","isEmailValid",]);this.hasAnswer=data.hasAnswer??Boolean(data.selectedAnswerId);}
get expectAnswer(){if((this.type==="question_email"&&!this.isEmailValid)||(this.answers.length>0&&!this.hasAnswer)){return true;}
return(["free_input_multi","free_input_single","question_selection","question_email","question_phone",].includes(this.type)&&!this.hasAnswer);}}
return __exports;});;

/* /im_livechat/static/src/embed/common/composer_patch.js */
odoo.define('@im_livechat/embed/common/composer_patch',['@im_livechat/embed/common/livechat_data','@mail/core/common/composer','@web/core/l10n/translation','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{options}=require("@im_livechat/embed/common/livechat_data");const{Composer}=require("@mail/core/common/composer");const{_t}=require("@web/core/l10n/translation");const{patch}=require("@web/core/utils/patch");patch(Composer.prototype,{get placeholder(){if(this.thread?.type!=="livechat"){return super.placeholder;}
return options.input_placeholder||_t("Say something...");},});return __exports;});;

/* /im_livechat/static/src/embed/common/disabled_features.js */
odoo.define('@im_livechat/embed/common/disabled_features',['@mail/core/common/thread_actions','@mail/core/common/thread_model','@mail/core/common/thread_service','@web/core/utils/patch','@im_livechat/embed/common/livechat_service'],function(require){'use strict';let __exports={};const{threadActionsRegistry}=require("@mail/core/common/thread_actions");const{Thread}=require("@mail/core/common/thread_model");const{ThreadService}=require("@mail/core/common/thread_service");const{patch}=require("@web/core/utils/patch");const{SESSION_STATE}=require("@im_livechat/embed/common/livechat_service");patch(Thread.prototype,{get hasMemberList(){return false;},get hasAttachmentPanel(){return this.type!=="livechat"&&super.hasAttachmentPanel;},});patch(ThreadService.prototype,{async fetchNewMessages(thread){if(thread.type!=="livechat"||(this.livechatService.state===SESSION_STATE.PERSISTED&&!thread.isNewlyCreated)){return super.fetchNewMessages(...arguments);}},});const allowedThreadActions=new Set(["fold-chat-window","close","restart","settings"]);for(const[actionName]of threadActionsRegistry.getEntries()){if(!allowedThreadActions.has(actionName)){threadActionsRegistry.remove(actionName);}}
threadActionsRegistry.addEventListener("UPDATE",({detail:{operation,key}})=>{if(operation==="add"&&!allowedThreadActions.has(key)){threadActionsRegistry.remove(key);}});return __exports;});;

/* /im_livechat/static/src/embed/common/expirable_storage.js */
odoo.define('@im_livechat/embed/common/expirable_storage',['@web/core/browser/browser'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const BASE_STORAGE_KEY="EXPIRABLE_STORAGE";const CLEAR_INTERVAL=24*60*60*1000;function cleanupExpirableStorage(){const now=Date.now();for(const key of Object.keys(browser.localStorage)){if(key.startsWith(BASE_STORAGE_KEY)){const item=JSON.parse(browser.localStorage.getItem(key));if(item.expires&&item.expires<now){browser.localStorage.removeItem(key);}}}}
const expirableStorage=__exports.expirableStorage={getItem(key){cleanupExpirableStorage();const item=browser.localStorage.getItem(`${BASE_STORAGE_KEY}_${key}`);if(item){return JSON.parse(item).value;}
return null;},setItem(key,value,ttl){let expires;if(ttl){expires=Date.now()+ttl*1000;}
browser.localStorage.setItem(`${BASE_STORAGE_KEY}_${key}`,JSON.stringify({value,expires}));},removeItem(key){browser.localStorage.removeItem(`${BASE_STORAGE_KEY}_${key}`);},};cleanupExpirableStorage();setInterval(cleanupExpirableStorage,CLEAR_INTERVAL);return __exports;});;

/* /im_livechat/static/src/embed/common/feedback_panel/feedback_panel.js */
odoo.define('@im_livechat/embed/common/feedback_panel/feedback_panel',['@im_livechat/embed/common/livechat_service','@im_livechat/embed/common/feedback_panel/transcript_sender','@odoo/owl','@web/core/utils/hooks','@web/session','@web/core/utils/urls'],function(require){'use strict';let __exports={};const{RATING}=require("@im_livechat/embed/common/livechat_service");const{TranscriptSender}=require("@im_livechat/embed/common/feedback_panel/transcript_sender");const{Component,useState}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{session}=require("@web/session");const{url}=require("@web/core/utils/urls");const FeedbackPanel=__exports.FeedbackPanel=class FeedbackPanel extends Component{static template="im_livechat.FeedbackPanel";static props=["onClickClose?","thread"];static components={TranscriptSender};STEP=Object.freeze({RATING:"rating",THANKS:"thanks",});RATING=RATING;setup(){this.session=session;this.livechatService=useService("im_livechat.livechat");this.rpc=useService("rpc");this.state=useState({step:this.STEP.RATING,rating:null,feedback:"",});this.url=url;}
select(rating){this.state.rating=rating;}
async onClickSendFeedback(){this.rpc("/im_livechat/feedback",{reason:this.state.feedback,rate:this.state.rating,uuid:this.props.thread.uuid,});this.state.step=this.STEP.THANKS;}}
return __exports;});;

/* /im_livechat/static/src/embed/common/feedback_panel/transcript_sender.js */
odoo.define('@im_livechat/embed/common/feedback_panel/transcript_sender',['@im_livechat/embed/common/misc','@odoo/owl','@web/core/utils/hooks'],function(require){'use strict';let __exports={};const{isValidEmail}=require("@im_livechat/embed/common/misc");const{Component,useState}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const TranscriptSender=__exports.TranscriptSender=class TranscriptSender extends Component{static template="im_livechat.TranscriptSender";static props=["thread"];STATUS=Object.freeze({IDLE:"idle",SENDING:"sending",SENT:"sent",FAILED:"failed",});setup(){this.isValidEmail=isValidEmail;this.livechatService=useService("im_livechat.livechat");this.rpc=useService("rpc");this.state=useState({email:"",status:this.STATUS.IDLE,});}
async onClickSend(){this.state.status=this.STATUS.SENDING;try{await this.rpc("/im_livechat/email_livechat_transcript",{uuid:this.props.thread.uuid,email:this.state.email,});this.state.status=this.STATUS.SENT;}catch{this.state.status=this.STATUS.FAILED;}}}
return __exports;});;

/* /im_livechat/static/src/embed/common/history_service.js */
odoo.define('@im_livechat/embed/common/history_service',['@web/core/browser/browser','@web/core/browser/cookie','@web/core/registry'],function(require){'use strict';let __exports={};const{browser}=require("@web/core/browser/browser");const{cookie:cookieManager}=require("@web/core/browser/cookie");const{registry}=require("@web/core/registry");const HistoryService=__exports.HistoryService=class HistoryService{static HISTORY_COOKIE="im_livechat_history";static HISTORY_LIMIT=15;constructor(env,services){this.rpc=services.rpc;this.busService=services.bus_service;this.livechatService=services["im_livechat.livechat"];}
setup(){this.updateHistory();this.busService.subscribe("im_livechat.history_command",(payload)=>{if(payload.id!==this.livechatService.thread?.id){return;}
const cookie=cookieManager.get(HistoryService.HISTORY_COOKIE);const history=cookie?JSON.parse(cookie):[];this.rpc("/im_livechat/history",{pid:this.livechatService.thread.operator.id,channel_uuid:this.livechatService.thread.uuid,page_history:history,});});}
updateHistory(){const page=browser.location.href.replace(/^.*\/\/[^/]+/,"");const pageHistory=cookieManager.get(HistoryService.HISTORY_COOKIE);const urlHistory=pageHistory?JSON.parse(pageHistory):[];if(!urlHistory.includes(page)){urlHistory.push(page);if(urlHistory.length>HistoryService.HISTORY_LIMIT){urlHistory.shift();}
cookieManager.set(HistoryService.HISTORY_COOKIE,JSON.stringify(urlHistory),60*60*24,"optional");}}}
const historyService=__exports.historyService={dependencies:["im_livechat.livechat","bus_service","rpc"],start(env,services){const history=new HistoryService(env,services);history.setup();},};registry.category("services").add("im_livechat.history_service",historyService);return __exports;});;

/* /im_livechat/static/src/embed/common/livechat_button.js */
odoo.define('@im_livechat/embed/common/livechat_button',['@odoo/owl','@web/core/utils/draggable_hook_builder_owl','@web/core/utils/hooks','@web/core/utils/timing'],function(require){'use strict';let __exports={};const{Component,useExternalListener,useRef,useState}=require("@odoo/owl");const{makeDraggableHook}=require("@web/core/utils/draggable_hook_builder_owl");const{useService}=require("@web/core/utils/hooks");const{debounce}=require("@web/core/utils/timing");const LIVECHAT_BUTTON_SIZE=56;const useMovable=makeDraggableHook({name:"useMovable",onWillStartDrag({ctx,addCleanup,addStyle,getRect}){const{height}=getRect(ctx.current.element);ctx.current.container=document.createElement("div");addStyle(ctx.current.container,{position:"fixed",top:0,bottom:`${height}px`,left:0,right:0,});ctx.current.element.after(ctx.current.container);addCleanup(()=>ctx.current.container.remove());},onDrop({ctx,getRect}){const{top,left}=getRect(ctx.current.element);return{top,left};},});const LivechatButton=__exports.LivechatButton=class LivechatButton extends Component{static template="im_livechat.LivechatButton";static DEBOUNCE_DELAY=500;setup(){this.store=useState(useService("mail.store"));this.livechatService=useState(useService("im_livechat.livechat"));this.threadService=useService("mail.thread");this.onClick=debounce(this.onClick.bind(this),LivechatButton.DEBOUNCE_DELAY,{leading:true,});this.ref=useRef("button");this.size=LIVECHAT_BUTTON_SIZE;this.position=useState({left:`calc(97% - ${LIVECHAT_BUTTON_SIZE}px)`,top:`calc(97% - ${LIVECHAT_BUTTON_SIZE}px)`,});this.state=useState({animateNotification:!(this.livechatService.thread||this.livechatService.shouldRestoreSession),hasAlreadyMovedOnce:false,});useMovable({cursor:"grabbing",ref:this.ref,elements:".o-livechat-LivechatButton",onDrop:({top,left})=>{this.state.hasAlreadyMovedOnce=true;this.position.left=`${left}px`;this.position.top=`${top}px`;},});useExternalListener(document.body,"scroll",this._onScroll,{capture:true});}
_onScroll(ev){if(!this.ref.el||this.state.hasAlreadyMovedOnce){return;}
const container=ev.target;this.position.top=container.scrollHeight-container.scrollTop===container.clientHeight?`calc(93% - ${LIVECHAT_BUTTON_SIZE}px)`:`calc(97% - ${LIVECHAT_BUTTON_SIZE}px)`;}
onClick(){this.state.animateNotification=false;this.threadService.openChat();}
get isShown(){return(this.livechatService.initialized&&this.livechatService.available&&!this.livechatService.shouldRestoreSession&&this.store.discuss.chatWindows.length===0);}}
return __exports;});;

/* /im_livechat/static/src/embed/common/livechat_data.js */
odoo.define('@im_livechat/embed/common/livechat_data',['@web/session'],function(require){'use strict';let __exports={};const{session}=require("@web/session");const{isAvailable,serverUrl,options}=session.livechatData||{};Object.assign(__exports,{isAvailable,serverUrl,options});return __exports;});;

/* /im_livechat/static/src/embed/common/livechat_service.js */
odoo.define('@im_livechat/embed/common/livechat_service',['@im_livechat/embed/common/expirable_storage','@mail/core/common/record','@odoo/owl','@web/core/browser/browser','@web/core/browser/cookie','@web/core/l10n/translation','@web/core/registry','@web/core/utils/concurrency','@web/session'],function(require){'use strict';let __exports={};const{expirableStorage}=require("@im_livechat/embed/common/expirable_storage");const{Record}=require("@mail/core/common/record");const{reactive}=require("@odoo/owl");const{browser}=require("@web/core/browser/browser");const{cookie}=require("@web/core/browser/cookie");const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{Deferred}=require("@web/core/utils/concurrency");const{session}=require("@web/session");session.websocket_worker_version??=session.livechatData?.options?.websocket_worker_version;const RATING=__exports.RATING=Object.freeze({GOOD:5,OK:3,BAD:1,});const SESSION_STATE=__exports.SESSION_STATE=Object.freeze({NONE:"NONE",CREATED:"CREATED",PERSISTED:"PERSISTED",});const ODOO_VERSION_KEY=__exports.ODOO_VERSION_KEY=`${location.origin.replace(
    /:\/{0,2}/g,
    "_"
)}_im_livechat.odoo_version`;const LivechatService=__exports.LivechatService=class LivechatService{static TEMPORARY_ID="livechat_temporary_thread";SESSION_COOKIE="im_livechat_session";LIVECHAT_UUID_COOKIE="im_livechat_uuid";SESSION_STORAGE_KEY="im_livechat_session";OPERATOR_COOKIE="im_livechat_previous_operator_pid";GUEST_TOKEN_STORAGE_KEY="im_livechat_guest_token";state=SESSION_STATE.NONE;rule;initializedDeferred=new Deferred();initialized=false;persistThreadPromise=null;sessionInitialized=false;available=false;userName;constructor(env,services){this.setup(env,services);}
setup(env,services){this.env=env;this.busService=services.bus_service;this.chatWindowService=services["mail.chat_window"];this.rpc=services.rpc;this.notificationService=services.notification;this.store=services["mail.store"];this.available=session.livechatData?.isAvailable;this.userName=this.options.default_username??_t("Visitor");}
async initialize(){let init;if(!this.options.isTestChatbot){init=await this.rpc("/im_livechat/init",{channel_id:this.options.channel_id,});const prevOdooVersion=browser.localStorage.getItem(ODOO_VERSION_KEY);const currOdooVersion=init?.odoo_version;const visitorUid=this.visitorUid||false;const userId=session.user_id||false;if(prevOdooVersion!==currOdooVersion||(this.savedState&&visitorUid!==userId)){this.leaveSession({notifyServer:false});}
browser.localStorage.setItem(ODOO_VERSION_KEY,currOdooVersion);}
this.available=init?.available_for_me??this.available;this.rule=init?.rule??{};this.initialized=true;this.initializedDeferred.resolve();}
updateSession(values){if(Record.isRecord(values?.channel)){values.channel=values.channel.toData();}
const ONE_DAY_TTL=60*60*24;if(this.thread?.uuid){if(this.thread.uuid){cookie.set(this.LIVECHAT_UUID_COOKIE,this.thread.uuid,ONE_DAY_TTL);}}
const session=this.savedState||{};Object.assign(session,{visitor_uid:this.visitorUid,...values,});expirableStorage.removeItem(this.SESSION_STORAGE_KEY);cookie.delete(this.OPERATOR_COOKIE);expirableStorage.setItem(this.SESSION_STORAGE_KEY,JSON.stringify(session).replaceAll("→"," "),ONE_DAY_TTL);if(session?.operator_pid){cookie.set(this.OPERATOR_COOKIE,session.operator_pid[0],7*24*60*60);}}
async leaveSession({notifyServer=true}={}){const session=JSON.parse(expirableStorage.getItem(this.SESSION_STORAGE_KEY)??"{}");try{if(session?.uuid&&notifyServer){this.busService.deleteChannel(session.uuid);await this.rpc("/im_livechat/visitor_leave_session",{uuid:session.uuid});}}finally{expirableStorage.removeItem(this.SESSION_STORAGE_KEY);this.state=SESSION_STATE.NONE;this.sessionInitialized=false;}}
async persistThread(){if(this.state===SESSION_STATE.PERSISTED){return this.thread;}
this.persistThreadPromise=this.persistThreadPromise??this.getOrCreateThread({persist:true});try{await this.persistThreadPromise;}finally{this.persistThreadPromise=null;}
const chatWindow=this.store.discuss.chatWindows.find((c)=>c.thread.id===LivechatService.TEMPORARY_ID);if(chatWindow){chatWindow.thread?.delete();if(!this.thread){await this.chatWindowService.close(chatWindow);return;}
chatWindow.thread=this.thread;if(this.env.services["im_livechat.chatbot"].active){await this.env.services["im_livechat.chatbot"].postWelcomeSteps();}}
return this.thread;}
async getOrCreateThread({persist=false}={}){let threadData=this.savedState;let isNewlyCreated=false;if(!threadData||(!threadData.uuid&&persist)){const chatbotScriptId=this.savedState?this.savedState.chatbot_script_id:this.rule.chatbot?.scriptId;threadData=await this.rpc("/im_livechat/get_session",{channel_id:this.options.channel_id,anonymous_name:this.userName,chatbot_script_id:chatbotScriptId,previous_operator_id:cookie.get(this.OPERATOR_COOKIE),persisted:persist,},{shadow:true});isNewlyCreated=true;}
if(!threadData?.operator_pid){this.notificationService.add(_t("No available collaborator, please try again later."));this.leaveSession({notifyServer:false});return;}
if("guest_token"in threadData){localStorage.setItem(this.GUEST_TOKEN_STORAGE_KEY,threadData.guest_token);delete threadData.guest_token;}
this.updateSession(threadData);const thread=this.store.Thread.insert({...threadData,id:threadData.id??LivechatService.TEMPORARY_ID,isLoaded:!threadData.id||isNewlyCreated,model:"discuss.channel",type:"livechat",isNewlyCreated,});this.state=thread.uuid?SESSION_STATE.PERSISTED:SESSION_STATE.CREATED;if(this.state===SESSION_STATE.PERSISTED&&!this.sessionInitialized){this.sessionInitialized=true;await this.initializePersistedSession();}
return thread;}
async initializePersistedSession(){await this.busService.addChannel(`mail.guest_${this.guestToken}`);await this.env.services["mail.messaging"].initialize();}
get options(){return session.livechatData?.options??{};}
get displayWelcomeMessage(){return true;}
get sessionCookie(){try{return cookie.get(this.SESSION_COOKIE)?JSON.parse(decodeURI(cookie.get(this.SESSION_COOKIE))):false;}catch{cookie.delete(this.SESSION_COOKIE);return false;}}
get savedState(){return JSON.parse(expirableStorage.getItem(this.SESSION_STORAGE_KEY)??false);}
get shouldRestoreSession(){if(this.state!==SESSION_STATE.NONE){return false;}
return Boolean(this.savedState);}
get guestToken(){return localStorage.getItem(this.GUEST_TOKEN_STORAGE_KEY);}
get thread(){return Object.values(this.store.Thread.records).find(({id,type})=>type==="livechat"&&id===(this.savedState?.id??LivechatService.TEMPORARY_ID));}
get visitorUid(){const savedState=this.savedState;return savedState&&"visitor_uid"in savedState?savedState.visitor_uid:session.user_id;}}
const livechatService=__exports.livechatService={dependencies:["bus_service","mail.chat_window","mail.store","notification","notification","rpc",],start(env,services){const livechat=reactive(new LivechatService(env,services));if(livechat.available){livechat.initialize();}
return livechat;},};registry.category("services").add("im_livechat.livechat",livechatService);return __exports;});;

/* /im_livechat/static/src/embed/common/message_model_patch.js */
odoo.define('@im_livechat/embed/common/message_model_patch',['@im_livechat/embed/common/chatbot/chatbot_step_model','@mail/core/common/message_model','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{ChatbotStep}=require("@im_livechat/embed/common/chatbot/chatbot_step_model");const{Message}=require("@mail/core/common/message_model");const{patch}=require("@web/core/utils/patch");patch(Message,{_insert(data){const chatbotStep=this.store.Message.get(data)?.chatbotStep;const message=super._insert(...arguments);if(data.chatbotStep){message.chatbotStep=new ChatbotStep({...chatbotStep,...data.chatbotStep});}
return message;},});return __exports;});;

/* /im_livechat/static/src/embed/common/message_patch.js */
odoo.define('@im_livechat/embed/common/message_patch',['@mail/core/common/message','@web/core/utils/patch','@web/core/utils/urls','@im_livechat/embed/common/livechat_service'],function(require){'use strict';let __exports={};const{Message}=require("@mail/core/common/message");const{patch}=require("@web/core/utils/patch");const{url}=require("@web/core/utils/urls");const{SESSION_STATE}=require("@im_livechat/embed/common/livechat_service");Message.props.push("isTypingMessage?");patch(Message.prototype,{setup(){super.setup();this.url=url;},get quickActionCount(){return this.props.thread?.type==="livechat"?2:super.quickActionCount;},get canAddReaction(){return(super.canAddReaction&&(this.props.thread?.type!=="livechat"||this.env.services["im_livechat.livechat"].state===SESSION_STATE.PERSISTED));},get canReplyTo(){return(super.canReplyTo&&(this.props.thread?.type!=="livechat"||this.env.services["im_livechat.chatbot"].inputEnabled));},answerChatbot(answer){return this.threadService.post(this.props.message.originThread,answer.label);},});return __exports;});;

/* /im_livechat/static/src/embed/common/messaging_service_patch.js */
odoo.define('@im_livechat/embed/common/messaging_service_patch',['@im_livechat/embed/common/livechat_service','@mail/core/common/messaging_service','@web/core/utils/patch','@web/session'],function(require){'use strict';let __exports={};const{SESSION_STATE}=require("@im_livechat/embed/common/livechat_service");const{Messaging}=require("@mail/core/common/messaging_service");const{patch}=require("@web/core/utils/patch");const{session}=require("@web/session");patch(Messaging.prototype,{initialize(){if(this.env.services["im_livechat.livechat"].state===SESSION_STATE.PERSISTED){return super.initialize();}
if(session.livechatData?.options.current_partner_id){this.store.user={type:"partner",id:session.livechatData.options.current_partner_id,};}
this.store.isMessagingReady=true;this.isReady.resolve({channels:[],current_user_settings:{},});},});return __exports;});;

/* /im_livechat/static/src/embed/common/misc.js */
odoo.define('@im_livechat/embed/common/misc',[],function(require){'use strict';let __exports={};__exports.isValidEmail=isValidEmail;function isValidEmail(val){const re=/^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i;return re.test(val);}
return __exports;});;

/* /im_livechat/static/src/embed/common/thread_actions.js */
odoo.define('@im_livechat/embed/common/thread_actions',['@im_livechat/embed/common/livechat_service','@mail/core/common/thread_actions','@mail/discuss/call/common/thread_actions','@odoo/owl','@web/core/l10n/translation','@web/core/utils/hooks','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{SESSION_STATE}=require("@im_livechat/embed/common/livechat_service");const{threadActionsRegistry}=require("@mail/core/common/thread_actions");require("@mail/discuss/call/common/thread_actions");const{useComponent}=require("@odoo/owl");const{_t}=require("@web/core/l10n/translation");const{useService}=require("@web/core/utils/hooks");const{patch}=require("@web/core/utils/patch");threadActionsRegistry.add("restart",{condition(component){return component.chatbotService.canRestart;},icon:"fa fa-fw fa-refresh",name:_t("Restart Conversation"),open(component){component.chatbotService.restart();component.chatWindowService.show(component.props.chatWindow);},sequence:99,});const callSettingsAction=threadActionsRegistry.get("settings");patch(callSettingsAction,{condition(component){if(component.thread?.type!=="livechat"){return super.condition(...arguments);}
return(component.livechatService.state===SESSION_STATE.PERSISTED&&component.rtcService.state.channel?.eq(component.thread));},setup(){super.setup(...arguments);const component=useComponent();component.livechatService=useService("im_livechat.livechat");component.rtcService=useService("discuss.rtc");},});return __exports;});;

/* /im_livechat/static/src/embed/common/thread_model_patch.js */
odoo.define('@im_livechat/embed/common/thread_model_patch',['@im_livechat/embed/common/livechat_service','@mail/core/common/record','@mail/core/common/thread_model','@mail/utils/common/misc','@web/core/utils/patch','@web/core/utils/urls'],function(require){'use strict';let __exports={};const{LivechatService,SESSION_STATE}=require("@im_livechat/embed/common/livechat_service");const{Record}=require("@mail/core/common/record");const{Thread}=require("@mail/core/common/thread_model");const{onChange}=require("@mail/utils/common/misc");const{patch}=require("@web/core/utils/patch");const{url}=require("@web/core/utils/urls");patch(Thread,{_insert(data){const isUnknown=!this.get(data);const thread=super._insert(...arguments);const livechatService=this.env.services["im_livechat.livechat"];if(thread.type==="livechat"&&isUnknown){onChange(thread,["state","seen_message_id","message_unread_counter","allow_public_upload"],()=>{if(![SESSION_STATE.CLOSED,SESSION_STATE.NONE].includes(livechatService.state)){livechatService.updateSession({state:thread.state,seen_message_id:thread.seen_message_id,channel:thread,allow_public_upload:thread.allow_public_upload,});}});}
return thread;},});patch(Thread.prototype,{setup(){super.setup();this.chatbotTypingMessage=Record.one("Message",{compute(){if(this._store.env.services["im_livechat.chatbot"].isChatbotThread(this)){return{id:Number.isInteger(this.id)?-0.1-this.id:-0.1,res_id:this.id,model:this.model,author:this.operator,};}},});this.livechatWelcomeMessage=Record.one("Message",{compute(){if(this.displayWelcomeMessage){const livechatService=this._store.env.services["im_livechat.livechat"];return{id:Number.isInteger(this.id)?-0.2-this.id:-0.2,body:livechatService.options.default_message,res_id:this.id,model:this.model,author:this.operator,};}},});this.chatbotScriptId=null;this.isNewlyCreated=false;},get isLastMessageFromCustomer(){if(this.type!=="livechat"){return super.isLastMessageFromCustomer;}
return this.newestMessage?.isSelfAuthored;},get imgUrl(){if(this.type!=="livechat"){return super.imgUrl;}
return url(`/im_livechat/operator/${this.operator.id}/avatar`);},get isTransient(){return super.isTransient||this.id===LivechatService.TEMPORARY_ID;},get displayWelcomeMessage(){return!this._store.env.services["im_livechat.chatbot"].isChatbotThread(this);},});return __exports;});;

/* /im_livechat/static/src/embed/common/thread_patch.js */
odoo.define('@im_livechat/embed/common/thread_patch',['@mail/core/common/thread','@odoo/owl','@web/core/utils/hooks','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{Thread}=require("@mail/core/common/thread");const{useState}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{patch}=require("@web/core/utils/patch");patch(Thread.prototype,{setup(){super.setup();this.chatbotService=useState(useService("im_livechat.chatbot"));},});return __exports;});;

/* /im_livechat/static/src/embed/common/thread_service_patch.js */
odoo.define('@im_livechat/embed/common/thread_service_patch',['@mail/core/common/thread_service','@web/core/utils/patch','@web/core/utils/urls'],function(require){'use strict';let __exports={};const{ThreadService,threadService}=require("@mail/core/common/thread_service");const{patch}=require("@web/core/utils/patch");const{url}=require("@web/core/utils/urls");threadService.dependencies.push("im_livechat.livechat","im_livechat.chatbot");patch(ThreadService.prototype,{setup(env,services){super.setup(env,services);this.livechatService=services["im_livechat.livechat"];this.chatbotService=services["im_livechat.chatbot"];},async post(thread,body,params){thread=thread.type==="livechat"?await this.livechatService.persistThread():thread;if(!thread){return;}
const message=await super.post(thread,body,params);this.chatbotService.bus.trigger("MESSAGE_POST",message);return message;},async openChat(){const thread=await this.livechatService.getOrCreateThread();if(!thread){return;}
const chatWindow=this.store.ChatWindow.insert({thread,folded:thread.state==="folded",});chatWindow.autofocus++;if(this.chatbotService.savedState){this.chatbotService._restore();}
if(this.chatbotService.active){this.chatbotService.start();}},avatarUrl(persona,thread){if(thread.type==="livechat"&&persona.eq(thread.operator)){return url(`/im_livechat/operator/${persona.id}/avatar`);}
return super.avatarUrl(...arguments);},});return __exports;});;

/* /website_livechat/static/src/embed/common/livechat_service_patch.js */
odoo.define('@website_livechat/embed/common/livechat_service_patch',['@im_livechat/embed/common/livechat_service','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{LivechatService}=require("@im_livechat/embed/common/livechat_service");const{patch}=require("@web/core/utils/patch");patch(LivechatService.prototype,{setup(env,services){super.setup(env,services);if(this.options?.chat_request_session){this.updateSession(this.options.chat_request_session);}},get displayWelcomeMessage(){return!this.thread.requested_by_operator;},});return __exports;});;

/* /website_livechat/static/src/embed/common/thread_model_patch.js */
odoo.define('@website_livechat/embed/common/thread_model_patch',['@mail/core/common/thread_model','@mail/utils/common/misc','@web/core/utils/patch'],function(require){'use strict';let __exports={};const{Thread}=require("@mail/core/common/thread_model");const{assignDefined}=require("@mail/utils/common/misc");const{patch}=require("@web/core/utils/patch");patch(Thread.prototype,{update(data){super.update(data);assignDefined(this,data,["requested_by_operator"]);},get displayWelcomeMessage(){return super.displayWelcomeMessage&&!this.requested_by_operator;},});return __exports;});;

/* /im_livechat/static/src/embed/frontend/boot_service.js */
odoo.define('@im_livechat/embed/frontend/boot_service',['@im_livechat/embed/common/boot_helpers','@im_livechat/embed/frontend/livechat_root','@im_livechat/embed/common/livechat_data','@web/core/l10n/translation','@odoo/owl','@web/core/assets','@web/core/registry'],function(require){'use strict';let __exports={};const{makeRoot,makeShadow}=require("@im_livechat/embed/common/boot_helpers");const{LivechatRoot}=require("@im_livechat/embed/frontend/livechat_root");const{isAvailable}=require("@im_livechat/embed/common/livechat_data");const{_t}=require("@web/core/l10n/translation");const{App}=require("@odoo/owl");const{templates}=require("@web/core/assets");const{registry}=require("@web/core/registry");registry.category("main_components").remove("mail.ChatWindowContainer");const livechatBootService=__exports.livechatBootService={dependencies:["mail.messaging"],getTarget(){return document.body;},start(env){if(!isAvailable){return;}
const target=this.getTarget();const root=makeRoot(target);makeShadow(root).then((shadow)=>{new App(LivechatRoot,{env,templates,translatableAttributes:["data-tooltip"],translateFn:_t,dev:env.debug,}).mount(shadow);});},};registry.category("services").add("im_livechat.boot",livechatBootService);return __exports;});;

/* /im_livechat/static/src/embed/frontend/livechat_root.js */
odoo.define('@im_livechat/embed/frontend/livechat_root',['@im_livechat/embed/common/livechat_button','@mail/core/common/chat_window_container','@odoo/owl','@web/core/utils/hooks','@web/core/overlay/overlay_container'],function(require){'use strict';let __exports={};const{LivechatButton}=require("@im_livechat/embed/common/livechat_button");const{ChatWindowContainer}=require("@mail/core/common/chat_window_container");const{Component,xml,useSubEnv}=require("@odoo/owl");const{useService}=require("@web/core/utils/hooks");const{OverlayContainer}=require("@web/core/overlay/overlay_container");const LivechatRoot=__exports.LivechatRoot=class LivechatRoot extends Component{static template=xml`
        <ChatWindowContainer/>
        <LivechatButton/>
        <OverlayContainer overlays="overlayService.overlays"/>
    `;static components={ChatWindowContainer,LivechatButton,OverlayContainer};setup(){useSubEnv({inShadow:true});this.overlayService=useService("overlay");}}
return __exports;});;

/* /im_livechat/static/src/embed/frontend/overlay_container_patch.js */
odoo.define('@im_livechat/embed/frontend/overlay_container_patch',['@web/core/utils/patch','@web/core/overlay/overlay_container'],function(require){'use strict';let __exports={};const{patch}=require("@web/core/utils/patch");const{OverlayContainer}=require("@web/core/overlay/overlay_container");patch(OverlayContainer.prototype,{isVisible(overlay){const targetInShadow=overlay.props.target?.getRootNode()instanceof ShadowRoot;return targetInShadow?this.env.inShadow:!this.env.inShadow;},});return __exports;});;

/* /mail/static/src/js/utils.js */
odoo.define('@mail/js/utils',['@web/core/utils/strings'],function(require){'use strict';let __exports={};const{escape}=require("@web/core/utils/strings");function parseAndTransform(htmlString,transformFunction){var openToken="OPEN"+Date.now();var string=htmlString.replace(/&lt;/g,openToken);var children;try{children=$("<div>").html(string).contents();}catch{children=$("<div>").html("<pre>"+string+"</pre>").contents();}
return _parseAndTransform(children,transformFunction).replace(new RegExp(openToken,"g"),"&lt;");}
function _parseAndTransform(nodes,transformFunction){return Array.from($(nodes)).map((node)=>{return transformFunction(node,function(){return _parseAndTransform(node.childNodes,transformFunction);});}).join("");}
const _escapeEntities=(function(){const map={"&":"&amp;","<":"&lt;",">":"&gt;"};const escaper=function(match){return map[match];};const testRegexp=RegExp("(?:&|<|>)");const replaceRegexp=RegExp("(?:&|<|>)","g");return function(string){string=string==null?"":""+string;return testRegexp.test(string)?string.replace(replaceRegexp,escaper):string;};})();const urlRegexp=/\b(?:https?:\/\/\d{1,3}(?:\.\d{1,3}){3}|(?:https?:\/\/|(?:www\.))[-a-z0-9@:%._+~#=\u00C0-\u024F\u1E00-\u1EFF]{2,256}\.[a-z]{2,13})\b(?:[-a-z0-9@:%_+~#?&[\]^|{}`\\'$//=\u00C0-\u024F\u1E00-\u1EFF]|,(?!$| )|\.(?!$| |\.)|;(?!$| ))*/gi;function linkify(text,attrs){attrs=attrs||{};if(attrs.target===undefined){attrs.target="_blank";}
if(attrs.target==="_blank"){attrs.rel="noreferrer noopener";}
attrs=Object.keys(attrs||{}).map((key)=>{const value=attrs[key];return`${key}="${escape(value)}"`;}).join(" ");let curIndex=0;let result="";let match;while((match=urlRegexp.exec(text))!==null){result+=_escapeEntities(text.slice(curIndex,match.index));const url=match[0];const href=!/^https?:\/\//i.test(url)?"http://"+encodeURI(url):encodeURI(url);result+="<a "+attrs+' href="'+href+'">'+_escapeEntities(url)+"</a>";curIndex=match.index+match[0].length;}
return result+_escapeEntities(text.slice(curIndex));}
function addLink(node,transformChildren){if(node.nodeType===3){const linkified=linkify(node.data);if(linkified!==node.data){const div=document.createElement("div");div.innerHTML=linkified;for(const childNode of[...div.childNodes]){node.parentNode.insertBefore(childNode,node);}
node.parentNode.removeChild(node);return linkified;}
return node.textContent;}
if(node.tagName==="A"){return node.outerHTML;}
transformChildren();return node.outerHTML;}
function htmlToTextContentInline(htmlString){const fragment=document.createDocumentFragment();const div=document.createElement("div");fragment.appendChild(div);htmlString=htmlString.replace(/<br\s*\/?>/gi," ");try{div.innerHTML=htmlString;}catch{div.innerHTML=`<pre>${htmlString}</pre>`;}
return div.textContent.trim().replace(/[\n\r]/g,"").replace(/\s\s+/g," ");}
function stripHTML(node,transformChildren){if(node.nodeType===3){return node.data;}
if(node.tagName==="BR"){return"\n";}
return transformChildren();}
function inline(node,transform_children){if(node.nodeType===3){return node.data;}
if(node.nodeType===8){return"";}
if(node.tagName==="BR"){return" ";}
if(node.tagName.match(/^(A|P|DIV|PRE|BLOCKQUOTE)$/)){return transform_children();}
node.innerHTML=transform_children();return node.outerHTML;}
function parseEmail(text){if(text){var result=text.match(/"?(.*?)"? <(.*@.*)>/);if(result){name=(result[1]||"").trim().replace(/(^"|"$)/g,'')
return[name,(result[2]||"").trim()];}
result=text.match(/(.*@.*)/);if(result){return[String(result[1]||"").trim(),String(result[1]||"").trim()];}
return[text,false];}}
function escapeAndCompactTextContent(content){let value=escape(content).trim();value=value.replace(/(\r|\n){2,}/g,"<br/><br/>");value=value.replace(/(\r|\n)/g,"<br/>");value=value.replace(/ /g,"&nbsp;").replace(/([^>])&nbsp;([^<])/g,"$1 $2");return value;}
function getTextToHTML(text){return text.replace(/((?:https?|ftp):\/\/[\S]+)/g,'<a href="$1">$1</a> ').replace(/[\n\r]/g,"<br/>");}
Object.assign(__exports,{addLink,escapeAndCompactTextContent,getTextToHTML,htmlToTextContentInline,inline,linkify,parseAndTransform,parseEmail,stripHTML,});return __exports;});;

/* /appointment/static/src/js/utils.js */
odoo.define('@appointment/js/utils',['@mail/js/utils'],function(require){'use strict';let __exports={};const{parseEmail}=require("@mail/js/utils");function findInvalidEmailFromText(emailStr){const emailList=emailStr.split('\n');const invalidEmails=emailList.filter(email=>email!==''&&!parseEmail(email.trim())[1]);const emailInfo={'invalidEmails':invalidEmails,'emailList':emailList,}
return emailInfo}
Object.assign(__exports,{findInvalidEmailFromText});return __exports;});;

/* /appointment/static/src/js/appointment_select_appointment_type.js */
odoo.define('@appointment/js/appointment_select_appointment_type',['@web/core/utils/render','@web/legacy/js/public/public_widget','@web/core/utils/timing'],function(require){'use strict';let __exports={};const{renderToElement}=require("@web/core/utils/render");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{debounce}=require("@web/core/utils/timing");publicWidget.registry.appointmentTypeSelect=publicWidget.Widget.extend({selector:'.o_appointment_choice',events:{'change select[id="appointment_type_id"]':'_onAppointmentTypeChange',},init:function(){this._super.apply(this,arguments);this._onAppointmentTypeChange=debounce(this._onAppointmentTypeChange,250);this.rpc=this.bindService("rpc");},start:function(){return this._super(...arguments).then(()=>{this.$el.find('.o_appointment_svg i').replaceWith(renderToElement('Appointment.appointment_svg',{}));this.$el.find('.o_appointment_not_found div').removeClass('d-none');});},_onAppointmentTypeChange:function(ev){var self=this;const appointmentTypeID=$(ev.target).val();const filterAppointmentTypeIds=this.$("input[name='filter_appointment_type_ids']").val();const filterUserIds=this.$("input[name='filter_staff_user_ids']").val();const filterResourceIds=this.$("input[name='filter_resource_ids']").val();const inviteToken=this.$("input[name='invite_token']").val();self.$(".o_appointment_appointments_list_form").attr('action',`/appointment/${appointmentTypeID}${window.location.search}`);this.rpc(`/appointment/${appointmentTypeID}/get_message_intro`,{invite_token:inviteToken,filter_appointment_type_ids:filterAppointmentTypeIds,filter_staff_user_ids:filterUserIds,filter_resource_ids:filterResourceIds,}).then(function(message_intro){self.$('.o_appointment_intro').empty().append(message_intro);});},});return __exports;});;

/* /appointment/static/src/js/appointment_select_appointment_slot.js */
odoo.define('@appointment/js/appointment_select_appointment_slot',['@web/legacy/js/public/public_widget','@web/core/utils/render'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{renderToElement,renderToFragment}=require("@web/core/utils/render");const{DateTime}=luxon;publicWidget.registry.appointmentSlotSelect=publicWidget.Widget.extend({selector:'.o_appointment',events:{'change select[name="timezone"]':'_onRefresh','change select[id="selectAppointmentResource"]':'_onRefresh','change select[id="selectStaffUser"]':'_onRefresh','change select[id="resourceCapacity"]':'_onRefresh','click .o_js_calendar_navigate':'_onCalendarNavigate','click .o_slot_button':'_onClickDaySlot','click .o_slot_hours':'_onClickHoursSlot','click button[name="submitSlotInfoSelected"]':'_onClickConfirmSlot',},init(){this._super(...arguments);this.rpc=this.bindService("rpc");},start:function(){return this._super(...arguments).then(async()=>{this.initSlots();this._removeLoadingSpinner();this.$first.click();});},initSlots:async function(){this.$slotsList=this.$('#slotsList');this.$resourceSelection=this.$('#resourceSelection');this.$first=this.$('.o_slot_button').first();await this._updateSlotAvailability();},selectFirstAvailableMonth:function(){const $firstMonth=this.$first.closest('.o_appointment_month');const $currentMonth=this.$('.o_appointment_month:not(.d-none)');$currentMonth.addClass('d-none');$currentMonth.find('table').removeClass('d-none');$currentMonth.find('.o_appointment_no_slot_month_helper').remove();$firstMonth.removeClass('d-none');this.$slotsList.empty();this.$first.click();},_renderNoAvailabilityForMonth:function($month){const firstAvailabilityDate=this.$first.attr('id');const staffUserName=this.$("#slots_form select[name='staff_user_id'] :selected").text();$month.find('table').addClass('d-none');$month.append(renderToElement('Appointment.appointment_info_no_slot_month',{firstAvailabilityDate:DateTime.fromISO(firstAvailabilityDate).toFormat("cccc dd MMMM yyyy"),staffUserName:staffUserName,}));$month.find('#next_available_slot').on('click',()=>this.selectFirstAvailableMonth());},_updateSlotAvailability:function(){if(!this.$first.length){if(!this.$("select[name='resourceCapacity']").length){this.$('#slots_availabilities').empty();this.$('.o_appointment_timezone_selection').addClass('d-none');const staffUserName=this.$("#slots_form select[name='staff_user_id'] :selected").text();const hideSelectDropdown=!!this.$("input[name='hide_select_dropdown']").val();const active=this.$("input[name='active']").val();this.$('.o_appointment_no_slot_overall_helper').empty().append(renderToElement('Appointment.appointment_info_no_slot',{active:active,appointmentsCount:this.$slotsList.data('appointmentsCount'),staffUserName:hideSelectDropdown?staffUserName:false,}));}else{this.$(".o_appointment_no_capacity").empty().append(renderToElement('Appointment.appointment_info_no_capacity'));}}else{this.$('.o_appointment_timezone_selection').removeClass('d-none');this.$(".o_appointment_no_capacity").empty();}
if(this.$('.o_appointment_missing_configuration').hasClass('d-none')){this.$('.o_appointment_missing_configuration').removeClass('d-none');}},_onCalendarNavigate:function(ev){const parent=this.$('.o_appointment_month:not(.d-none)');let monthID=parseInt(parent.attr('id').split('-')[1]);monthID+=((this.$(ev.currentTarget).attr('id')==='nextCal')?1:-1);parent.find('table').removeClass('d-none');parent.find('.o_appointment_no_slot_month_helper').remove();parent.addClass('d-none');const $month=$(`div#month-${monthID}`).removeClass('d-none');this.$('.active').removeClass('active');this.$slotsList.empty();this.$resourceSelection.empty();if(!!this.$first.length){if(!$month.find('.o_day').length){this._renderNoAvailabilityForMonth($month);}}},_onClickDaySlot:function(ev){this.$('.o_slot_selected').removeClass('o_slot_selected active');this.$(ev.currentTarget).addClass('o_slot_selected active');if(this.$("select[name='resourceCapacity'] :selected").data('placeholderOption')){return;}
const slotDate=this.$(ev.currentTarget).data('slotDate');const slots=this.$(ev.currentTarget).data('availableSlots');const scheduleBasedOn=this.$("input[name='schedule_based_on']").val();const resourceAssignMethod=this.$("input[name='assign_method']").val();const resourceId=this.$("select[id='selectAppointmentResource']").val()||this.$("input[name='resource_selected_id']").val();const resourceCapacity=this.$("select[name='resourceCapacity']").val();let commonUrlParams=new URLSearchParams(window.location.search);commonUrlParams.delete('staff_user_id');commonUrlParams.delete('resource_selected_id');commonUrlParams.delete('duration');commonUrlParams.delete('date_time');if(resourceCapacity){commonUrlParams.set('asked_capacity',encodeURIComponent(resourceCapacity));}
if(resourceId){commonUrlParams.set('resource_selected_id',encodeURIComponent(resourceId));}
this.$slotsList.empty().append(renderToFragment('appointment.slots_list',{commonUrlParams:commonUrlParams,resourceAssignMethod:resourceAssignMethod,scheduleBasedOn:scheduleBasedOn,slotDate:DateTime.fromISO(slotDate).toFormat("cccc dd MMMM yyyy"),slots:slots,getAvailableResources:(slot)=>{return scheduleBasedOn==='resources'?JSON.stringify(slot['available_resources']):false;}}));this.$resourceSelection.addClass('d-none');},_onClickHoursSlot:function(ev){this.$('.o_slot_hours.o_slot_hours_selected').removeClass('o_slot_hours_selected active');this.$(ev.currentTarget).addClass('o_slot_hours_selected active');const assignMethod=this.$el.find("input[name='assign_method']").val();const scheduleBasedOn=this.$("input[name='schedule_based_on']").val();if(assignMethod!=="time_resource"||scheduleBasedOn==='users'){const appointmentTypeID=this.$("input[name='appointment_type_id']").val();const urlParameters=decodeURIComponent(this.$(".o_slot_hours_selected").data('urlParameters'));const url=new URL(`/appointment/${encodeURIComponent(appointmentTypeID)}/info?${urlParameters}`,location.origin);document.location=encodeURI(url.href);return;}
const availableResources=this.$(ev.currentTarget).data('available_resources');const previousResourceIdSelected=this.$("select[name='resource_id']").val();this.$('#resourceSelection').empty().append(renderToFragment('appointment.resources_list',{availableResources:availableResources,}));this.$("select[name='resource_id']").attr('disabled',availableResources.length===1);if(previousResourceIdSelected&&this.$(`select[name='resource_id'] > option[value='${previousResourceIdSelected}']`).length){this.$("select[name='resource_id']").val(previousResourceIdSelected);}
this.$('#resourceSelection').removeClass('d-none');},_onClickConfirmSlot:function(ev){const appointmentTypeID=this.$("input[name='appointment_type_id']").val();const resourceId=parseInt(this.$("select[name='resource_id']").val());const resourceCapacity=parseInt(this.$("select[name='resourceCapacity']").val())||1;const urlParameters=decodeURIComponent(this.$(".o_slot_hours_selected").data('urlParameters'));const url=new URL(`/appointment/${encodeURIComponent(appointmentTypeID)}/info?${urlParameters}`,location.origin);const assignMethod=this.$("input[name='assign_method']").val();let resourceIds=JSON.parse(url.searchParams.get('available_resource_ids'));const $resourceSelected=$(this.$('.o_resources_list').prop('selectedOptions')[0]);if(assignMethod==="time_resource"&&$resourceSelected.data('resourceCapacity')>=resourceCapacity){resourceIds=[resourceId];}
url.searchParams.set('resource_selected_id',encodeURIComponent(resourceId));url.searchParams.set('available_resource_ids',JSON.stringify(resourceIds));url.searchParams.set('asked_capacity',encodeURIComponent(resourceCapacity));document.location=encodeURI(url.href);},_onRefresh:async function(ev){if(this.$("#slots_availabilities").length){const daySlotSelected=this.$('.o_slot_selected').data('slotDate');const appointmentTypeID=this.$("input[name='appointment_type_id']").val();const filterAppointmentTypeIds=this.$("input[name='filter_appointment_type_ids']").val();const filterUserIds=this.$("input[name='filter_staff_user_ids']").val();const inviteToken=this.$("input[name='invite_token']").val();const previousMonthName=this.$('.o_appointment_month:not(.d-none) .o_appointment_month_name').text();const staffUserID=this.$("#slots_form select[name='staff_user_id']").val();const resourceID=this.$("select[id='selectAppointmentResource']").val()||this.$("input[name='resource_selected_id']").val();const filterResourceIds=this.$("input[name='filter_resource_ids']").val();const timezone=this.$("select[name='timezone']").val();const resourceCapacity=this.$("select[name='resourceCapacity']").length&&parseInt(this.$("select[name='resourceCapacity']").val())||1;this.$('.o_appointment_no_slot_overall_helper').empty();this.$slotsList.empty();this.$('#calendar, .o_appointment_timezone_selection').addClass('o_appointment_disable_calendar');this.$('#resourceSelection').empty();if(daySlotSelected&&!this.$("select[name='resourceCapacity'] :selected").data('placeholderOption')){this.$('.o_appointment_slot_list_loading').removeClass('d-none');}
const updatedAppointmentCalendarHtml=await this.rpc(`/appointment/${appointmentTypeID}/update_available_slots`,{asked_capacity:resourceCapacity,invite_token:inviteToken,filter_appointment_type_ids:filterAppointmentTypeIds,filter_staff_user_ids:filterUserIds,filter_resource_ids:filterResourceIds,month_before_update:previousMonthName,resource_selected_id:resourceID,staff_user_id:staffUserID,timezone:timezone,});if(updatedAppointmentCalendarHtml){this.$("#slots_availabilities").replaceWith(updatedAppointmentCalendarHtml);this.initSlots();const $displayedMonth=this.$('.o_appointment_month:not(.d-none)');if(!!this.$first.length&&!$displayedMonth.find('.o_day').length){this._renderNoAvailabilityForMonth($displayedMonth);}
this._removeLoadingSpinner();this.$(`div[data-slot-date="${daySlotSelected}"]`).click();}}},_removeLoadingSpinner:function(){this.$('.o_appointment_slots_loading').remove();this.$('.o_appointment_slot_list_loading').addClass('d-none');this.$('#slots_availabilities').removeClass('d-none');this.$('#calendar, .o_appointment_timezone_selection').removeClass('o_appointment_disable_calendar');},});return __exports;});;

/* /appointment/static/src/js/appointment_validation.js */
odoo.define('@appointment/js/appointment_validation',['@web/core/network/rpc_service','@web/legacy/js/public/public_widget','@appointment/js/utils','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const{jsonrpc}=require("@web/core/network/rpc_service");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{findInvalidEmailFromText}=require("@appointment/js/utils")
const{_t}=require("@web/core/l10n/translation");publicWidget.registry.appointmentValidation=publicWidget.Widget.extend({selector:'.o_appointment_validation_details',events:{'click .o_appointment_guest_addition_open':'_onGuestAdditionOpen','click .o_appointment_guest_discard':'_onGuestDiscard','click .o_appointment_guest_add':'_onGuestAdd',},_onGuestAdd:async function(){const guestEmails=this.el.querySelector('#o_appointment_input_guest_emails').value;const accessToken=this.el.querySelector('#access_token').value;const emailInfo=findInvalidEmailFromText(guestEmails)
if(emailInfo.emailList.length>10){this._showErrorMsg(_t('You cannot invite more than 10 people'));}else if(emailInfo.invalidEmails.length){this._showErrorMsg(_t('Invalid Email'));}else{this._hideErrorMsg();jsonrpc(`/calendar/${accessToken}/add_attendees_from_emails`,{access_token:accessToken,emails_str:guestEmails,}).then(()=>location.reload());}},_onGuestAdditionOpen:function(){const textArea=this.el.querySelector('#o_appointment_input_guest_emails');textArea.classList.remove('d-none');textArea.focus();this.el.querySelector('.o_appointment_guest_addition_open').classList.add('d-none');this.el.querySelector('.o_appointment_guest_add').classList.remove('d-none');this.el.querySelector('.o_appointment_guest_discard').classList.remove('d-none')},_onGuestDiscard:function(){this._hideErrorMsg();const textArea=this.el.querySelector('#o_appointment_input_guest_emails');textArea.value=""
textArea.classList.add('d-none')
this.el.querySelector('.o_appointment_guest_addition_open').classList.remove('d-none');this.el.querySelector('.o_appointment_guest_add').classList.add('d-none');this.el.querySelector('.o_appointment_guest_discard').classList.add('d-none');},_hideErrorMsg:function(){const errorMsgDiv=this.el.querySelector('.o_appointment_validation_error');errorMsgDiv.classList.add('d-none');},_showErrorMsg:function(errorMessage){const errorMsgDiv=this.el.querySelector('.o_appointment_validation_error');errorMsgDiv.classList.remove('d-none');errorMsgDiv.querySelector('.o_appointment_error_text').textContent=errorMessage;},});return __exports;});;

/* /appointment/static/src/js/appointment_form.js */
odoo.define('@appointment/js/appointment_form',['@web/legacy/js/core/dom','@web/legacy/js/public/public_widget','@appointment/js/utils','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const dom=require("@web/legacy/js/core/dom")[Symbol.for("default")];const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{findInvalidEmailFromText}=require("@appointment/js/utils")
const{_t}=require("@web/core/l10n/translation");publicWidget.registry.appointmentForm=publicWidget.Widget.extend({selector:'.o_appointment_attendee_form',events:{'click div.o_appointment_add_guests button.o_appointment_input_guest_add':'_onAddGuest','click div.o_appointment_add_guests button.o_appointment_input_guest_cancel':'_onHideGuest','click .o_appointment_form_confirm_btn':'_onConfirmAppointment',},_onAddGuest:function(){const textArea=this.el.querySelector('#o_appointment_input_guest_emails');textArea.classList.remove('d-none');textArea.focus();const addGuestDiv=this.el.querySelector('div.o_appointment_add_guests')
addGuestDiv.querySelector('button.o_appointment_input_guest_add').classList.add('d-none')
addGuestDiv.querySelector('button.o_appointment_input_guest_cancel').classList.remove('d-none')},_onConfirmAppointment:async function(event){this._validateCheckboxes();const textArea=this.el.querySelector('#o_appointment_input_guest_emails');const appointmentForm=document.querySelector('.appointment_submit_form');if(textArea&&textArea.value.trim()!==''){let emailInfo=findInvalidEmailFromText(textArea.value);if(emailInfo.invalidEmails.length||emailInfo.emailList.length>10){const errorMessage=emailInfo.invalidEmails.length>0?_t('Invalid Email'):_t("You cannot invite more than 10 people");this._showErrorMsg(errorMessage);return;}else{this._hideErrorMsg();}}
if(appointmentForm.reportValidity()){appointmentForm.submit();dom.addButtonLoadingEffect(event.target);}},_onHideGuest:function(){this._hideErrorMsg();const textArea=this.el.querySelector('#o_appointment_input_guest_emails');textArea.classList.add('d-none')
textArea.value="";const addGuestDiv=this.el.querySelector('div.o_appointment_add_guests')
addGuestDiv.querySelector('button.o_appointment_input_guest_add').classList.remove('d-none');addGuestDiv.querySelector('button.o_appointment_input_guest_cancel').classList.add('d-none');},_hideErrorMsg:function(){const errorMsgDiv=this.el.querySelector('.o_appointment_validation_error');errorMsgDiv.classList.add('d-none');},_showErrorMsg:function(errorMessage){const errorMsgDiv=this.el.querySelector('.o_appointment_validation_error');errorMsgDiv.classList.remove('d-none');errorMsgDiv.querySelector('.o_appointment_error_text').textContent=errorMessage;},_validateCheckboxes:function(){this.$el.find('.checkbox-group.required').each(function(){var checkboxes=$(this).find('.checkbox input');checkboxes.prop("required",![...checkboxes].some((checkbox)=>checkbox.checked));});},});return __exports;});;

/* /survey/static/src/js/tours/survey_tour.js */
odoo.define('@survey/js/tours/survey_tour',['@web/core/l10n/translation','@web/core/registry','@web_tour/tour_service/tour_utils','@odoo/owl'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{registry}=require("@web/core/registry");const{stepUtils}=require("@web_tour/tour_service/tour_utils");const{markup}=require("@odoo/owl");registry.category("web_tour.tours").add('survey_tour',{url:"/web",rainbowManMessage:_t("Congratulations! You are now ready to collect feedback like a pro :-)"),sequence:225,steps:()=>[...stepUtils.goToAppSteps('survey.menu_surveys',markup(_t("Ready to change the way you <b>gather data</b>?"))),{trigger:'.btn-outline-primary.o_survey_load_sample',content:markup(_t("Load a <b>sample Survey</b> to get started quickly.")),position:'left',},{trigger:'button[name=action_test_survey]',content:_t("Let's give it a spin!"),position:'bottom',},{trigger:'button[type=submit]',content:_t("Let's get started!"),position:'bottom',},{trigger:'button[type=submit]',extra_trigger:'.js_question-wrapper span:contains("How frequently")',content:_t("Whenever you pick an answer, Odoo saves it for you."),position:'bottom',},{trigger:'button[type=submit]',extra_trigger:'.js_question-wrapper span:contains("How many")',content:_t("Only a single question left!"),position:'bottom',},{trigger:'button[value=finish]',extra_trigger:'.js_question-wrapper span:contains("How likely")',content:_t("Now that you are done, submit your form."),position:'bottom',},{trigger:'.o_survey_review a',content:_t("Let's have a look at your answers!"),position:'bottom',},{trigger:'.alert-info a:contains("This is a Test Survey")',content:_t("Now, use this shortcut to go back to the survey."),position:'bottom',},{trigger:'button[name=action_survey_user_input_completed]',content:_t("Here, you can overview all the participations."),position:'bottom',},{trigger:'td[name=survey_id]',content:_t("Let's open the survey you just submitted."),position:'bottom',},{trigger:'.breadcrumb a:contains("Feedback Form")',content:_t("Use the breadcrumbs to quickly go back to the dashboard."),position:'bottom',}]});return __exports;});;

/* /website_hr_recruitment/static/src/js/website_hr_applicant_form.js */
odoo.define('@website_hr_recruitment/js/website_hr_applicant_form',['@web/legacy/js/public/public_widget','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{_t}=require("@web/core/l10n/translation");publicWidget.registry.hrRecruitment=publicWidget.Widget.extend({selector:'#hr_recruitment_form',events:{'click #apply-btn':'_onClickApplyButton','focusout #recruitment2':'_onFocusOutMail','focusout #recruitment4':'_onFocusOutLinkedin',},init:function(){this._super.apply(this,arguments);this.rpc=this.bindService("rpc");},willStart(){return Promise.all([this._super(),]);},_onClickApplyButton(ev){const $linkedin_profile=$('#recruitment4');const $resume=$('#recruitment6');const is_linkedin_empty=!$linkedin_profile.length||$linkedin_profile.val().trim()==='';const is_resume_empty=!$resume.length||!$resume[0].files.length;if(is_linkedin_empty&&is_resume_empty){$linkedin_profile.attr('required',true);$resume.attr('required',true);}else{$linkedin_profile.attr('required',false);$resume.attr('required',false);}},async _onFocusOutLinkedin(ev){const linkedin=$(ev.currentTarget).val();if(!linkedin){$(ev.currentTarget).removeClass('border-warning');$('#linkedin-message').removeClass('alert-warning').hide();return;}
const linkedin_regex=/^(https?:\/\/)?([\w\.]*)linkedin\.com\/in\/(.*?)(\/.*)?$/;if(!linkedin_regex.test(linkedin)){$('#linkedin-message').removeClass('alert-warning').hide();$(ev.currentTarget).addClass('border-warning');$('#linkedin-message').text(_t("The value entered doesn't seems like a linkedin profile.")).addClass('alert-warning').show();}else{$(ev.currentTarget).removeClass('border-warning');$('#linkedin-message').removeClass('alert-warning').hide();}},async _onFocusOutMail(ev){const email=$(ev.currentTarget).val();if(!email){$(ev.currentTarget).removeClass('border-warning');$('#email-message').removeClass('alert-warning').hide();return;}
const job_id=$('#recruitment7').val();const data=await this.rpc('/website_hr_recruitment/check_recent_application',{email:email,job_id:job_id,});if(data.applied_same_job){$('#email-message').removeClass('alert-warning').hide();$(ev.currentTarget).addClass('border-warning');$('#email-message').text(_t('You already applied to this job position recently.')).addClass('alert-warning').show();}else if(data.applied_other_job){$('#email-message').removeClass('alert-warning').hide();$(ev.currentTarget).addClass('border-warning');$('#email-message').text(_t("You already applied to another position recently. You can continue if it's not a mistake.")).addClass('alert-warning').show();}else{$(ev.currentTarget).removeClass('border-warning');$('#email-message').removeClass('alert-warning').hide();}},});return __exports;});;

/* /project_forecast/static/src/js/forecast_calendar_front.js */
odoo.define('@project_forecast/js/forecast_calendar_front',['@planning/js/planning_calendar_front'],function(require){'use strict';let __exports={};const PlanningView=require('@planning/js/planning_calendar_front')[Symbol.for("default")];PlanningView.include({eventFunction:function(calEvent){this._super.apply(this,arguments);const $project=$("#project");if(calEvent.event.extendedProps.project){$project.text(calEvent.event.extendedProps.project);$project.css("display","");$project.prev().css("display","");}else{$project.css("display","none");$project.prev().css("display","none");}
const $task=$("#task");if(calEvent.event.extendedProps.task){$task.text(calEvent.event.extendedProps.task);$task.prev().css("display","");$task.css("display","");}else{$task.css("display","none");$task.prev().css("display","none");}},});return __exports;});;

/* /website_helpdesk/static/src/js/website_helpdesk.autocomplete.js */
odoo.define('@website_helpdesk/js/website_helpdesk.autocomplete',['@web/core/utils/concurrency','@web/legacy/js/public/public_widget','@web/core/utils/render','@web/core/utils/timing'],function(require){'use strict';let __exports={};const{KeepLast}=require("@web/core/utils/concurrency");const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const{renderToElement}=require("@web/core/utils/render");const{debounce}=require("@web/core/utils/timing");publicWidget.registry.knowledgeBaseAutocomplete=publicWidget.Widget.extend({selector:'.o_helpdesk_knowledge_search',events:{'input .search-query':'_onInput','focusout':'_onFocusOut','keydown .search-query':'_onKeydown',},init:function(){this._super.apply(this,arguments);this.keepLast=new KeepLast();this._onInput=debounce(this._onInput,400);this._onFocusOut=debounce(this._onFocusOut,100);this.rpc=this.bindService("rpc");},start:function(){this.$input=this.$('.search-query');this.$url=this.$el.data('ac-url');this.enabled=this.$el.data('autocomplete');return this._super.apply(this,arguments);},async _fetch(){const search=this.$input.val();if(!search||search.length<3)
return;return this.rpc(this.$url,{'term':search});},_render:function(res){const $prevMenu=this.$menu;const search=this.$input.val();this.$el.toggleClass('dropdown show',!!res);if(!!res){this.$menu=$(renderToElement('website_helpdesk.knowledge_base_autocomplete',{results:res.results,showMore:res.showMore,term:search,}));this.$el.append(this.$menu);}
if($prevMenu){$prevMenu.remove();}},_onInput:function(){if(!this.enabled)
return;this.keepLast.add(this._fetch()).then(this._render.bind(this));},_onFocusOut:function(){if(!this.$el.has(document.activeElement).length){this._render();}},_onKeydown:function(ev){switch(ev.key){case"Escape":this._render();break;case"ArrowUp":case"ArrowDown":ev.preventDefault();if(this.$menu){let $element=ev.key==="ArrowUp"?this.$menu.children().last():this.$menu.children().first();$element.focus();}
break;}},});return __exports;});;

/* /website_helpdesk/static/src/js/website_helpdesk.menu.js */
odoo.define('@website_helpdesk/js/website_helpdesk.menu',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.HelpdeskMenu=publicWidget.Widget.extend({selector:'.team_menu',start:function(){var pathname=$(window.location).attr("pathname");var $links=this.$('li a');if(pathname!=="/helpdesk"){$links=$links.filter("[href$='"+pathname+"']");}
$links.first().closest("li").addClass("active");return this._super.apply(this,arguments);},});return __exports;});;

/* /account_online_synchronization/static/src/js/online_sync_portal.js */
odoo.define('@account_online_synchronization/js/online_sync_portal',['@web/legacy/js/public/public_widget','@web/core/assets'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{loadJS}=require("@web/core/assets");publicWidget.registry.OnlineSyncPortal=publicWidget.Widget.extend({selector:'.oe_online_sync',events:Object.assign({},{'click #renew_consent_button':'_onRenewConsent',}),OdooFinConnector:function(parent,action){const modeRegexp=/^[a-z0-9-_]+$/i;if(!modeRegexp.test(action.params.proxyMode)){return;}
const url='https://'+action.params.proxyMode+'.odoofin.com/proxy/v1/odoofin_link';loadJS(url).then(()=>{const params={data:action.params,proxyMode:action.params.proxyMode,onEvent:function(event,data){switch(event){case'success':const processUrl=window.location.pathname+'/complete'+window.location.search;$('.js_reconnect').toggleClass('d-none');$.post(processUrl,{csrf_token:odoo.csrf_token});default:return;}},};OdooFin.create(params);OdooFin.open();});return;},_onRenewConsent:async function(ev){ev.preventDefault();const action=JSON.parse($(ev.currentTarget).attr('iframe-params'));return this.OdooFinConnector(this,action);},});__exports[Symbol.for("default")]={OnlineSyncPortal:publicWidget.registry.OnlineSyncPortal,};return __exports;});;

/* /auth_totp_portal/static/src/js/totp_frontend.js */
odoo.define('@auth_totp_portal/js/totp_frontend',['@web/core/l10n/translation','@odoo/owl','@portal/js/components/input_confirmation_dialog/input_confirmation_dialog','@portal/js/portal_security','@web/legacy/js/public/public_widget','@web/session','@web/core/browser/browser'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{markup}=require("@odoo/owl");const{InputConfirmationDialog}=require("@portal/js/components/input_confirmation_dialog/input_confirmation_dialog");const{handleCheckIdentity}=require("@portal/js/portal_security");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{session}=require("@web/session");const{browser}=require("@web/core/browser/browser");function fromField(f,record){switch(f.getAttribute('name')){case'qrcode':const qrcode=document.createElement('img');qrcode.setAttribute('class','img img-fluid');qrcode.setAttribute('src','data:image/png;base64,'+record['qrcode']);return qrcode;case'url':const url=document.createElement('a');url.setAttribute('href',record['url']);url.textContent=f.getAttribute('text')||record['url'];return url;case'code':const code=document.createElement('input');code.setAttribute('name','code');code.setAttribute('class','form-control col-10 col-md-6');code.setAttribute('placeholder','6-digit code');code.required=true;code.maxLength=6;code.minLength=6;return code;case'secret':const secretSpan=document.createElement('span');secretSpan.setAttribute('name','secret');secretSpan.setAttribute('class','o_field_copy_url');secretSpan.textContent=record['secret'];const copySpanIcon=document.createElement('span');copySpanIcon.setAttribute('class','fa fa-clipboard');const copySpanText=document.createElement('span');copySpanText.textContent=_t(' Copy');const copyButton=document.createElement('button');copyButton.setAttribute('class','btn btn-sm btn-primary o_clipboard_button o_btn_char_copy py-0 px-2');copyButton.onclick=async function(event){event.preventDefault();$(copyButton).tooltip({title:_t("Copied!"),trigger:"manual",placement:"bottom"});await browser.navigator.clipboard.writeText($(secretSpan)[0].innerText);$(copyButton).tooltip('show');setTimeout(()=>$(copyButton).tooltip("hide"),800);};copyButton.appendChild(copySpanIcon);copyButton.appendChild(copySpanText);const secretDiv=document.createElement('div');secretDiv.setAttribute('class','o_field_copy d-flex justify-content-center align-items-center');secretDiv.appendChild(secretSpan);secretDiv.appendChild(copyButton);return secretDiv;default:return document.createTextNode(record[f.getAttribute('name')]||'');}}
function fixupViewBody(oldNode,record){let qrcode=null,code=null,node=null;switch(oldNode.nodeType){case 1:if(oldNode.tagName==='field'){node=fromField(oldNode,record);switch(oldNode.getAttribute('name')){case'qrcode':qrcode=node;break;case'code':code=node;break}
break;}
node=document.createElement(oldNode.tagName);for(let i=0;i<oldNode.attributes.length;++i){const attr=oldNode.attributes[i];node.setAttribute(attr.name,attr.value);}
for(let j=0;j<oldNode.childNodes.length;++j){const[ch,qr,co]=fixupViewBody(oldNode.childNodes[j],record);if(ch){node.appendChild(ch);}
if(qr){qrcode=qr;}
if(co){code=co;}}
break;case 3:case 4:node=document.createTextNode(oldNode.data);break;default:}
return[node,qrcode,code]}
publicWidget.registry.TOTPButton=publicWidget.Widget.extend({selector:'#auth_totp_portal_enable',events:{click:'_onClick',},init(){this._super(...arguments);this.orm=this.bindService("orm");this.dialog=this.bindService("dialog");},async _onClick(e){e.preventDefault();const w=await handleCheckIdentity(this.orm.call("res.users","action_totp_enable_wizard",[session.user_id]),this.orm,this.dialog);if(!w){window.location=window.location;return;}
const{res_model:model,res_id:wizard_id}=w;const record=await this.orm.read(model,[wizard_id],[]).then(ar=>ar[0]);const doc=new DOMParser().parseFromString(document.getElementById('totp_wizard_view').textContent,'application/xhtml+xml');const xmlBody=doc.querySelector('sheet *');const[body,,]=fixupViewBody(xmlBody,record);this.call("dialog","add",InputConfirmationDialog,{body:markup(body.outerHTML),onInput:({inputEl})=>{inputEl.setCustomValidity("");},confirmLabel:_t("Activate"),confirm:async({inputEl})=>{if(!inputEl.reportValidity()){inputEl.classList.add("is-invalid");return false;}
try{await this.orm.write(model,[record.id],{code:inputEl.value});await handleCheckIdentity(this.orm.call(model,"enable",[record.id]),this.orm,this.dialog);}catch(e){const errorMessage=(!e.message?e.toString():!e.message.data?e.message.message:e.message.data.message||_t("Operation failed for unknown reason."));inputEl.classList.add("is-invalid");inputEl.setCustomValidity(errorMessage);inputEl.reportValidity();return false;}
window.location=window.location;},cancel:()=>{},});},});publicWidget.registry.DisableTOTPButton=publicWidget.Widget.extend({selector:'#auth_totp_portal_disable',events:{click:'_onClick'},init(){this._super(...arguments);this.orm=this.bindService("orm");this.dialog=this.bindService("dialog");},async _onClick(e){e.preventDefault();await handleCheckIdentity(this.orm.call("res.users","action_totp_disable",[session.user_id]),this.orm,this.dialog)
window.location=window.location;}});publicWidget.registry.RevokeTrustedDeviceButton=publicWidget.Widget.extend({selector:'#totp_wizard_view + * .fa.fa-trash.text-danger',events:{click:'_onClick'},init(){this._super(...arguments);this.orm=this.bindService("orm");this.dialog=this.bindService("dialog");},async _onClick(e){e.preventDefault();await handleCheckIdentity(this.orm.call("auth_totp.device","remove",[parseInt(this.el.id)]),this.orm,this.dialog);window.location=window.location;}});publicWidget.registry.RevokeAllTrustedDevicesButton=publicWidget.Widget.extend({selector:'#auth_totp_portal_revoke_all_devices',events:{click:'_onClick'},init(){this._super(...arguments);this.orm=this.bindService("orm");this.dialog=this.bindService("dialog");},async _onClick(e){e.preventDefault();await handleCheckIdentity(this.orm.call("res.users","revoke_all_devices",[session.user_id]),this.orm,this.dialog);window.location=window.location;}});return __exports;});;

/* /industry_fsm_sale/static/src/js/tours/industry_fsm_sale_tour.js */
odoo.define('@industry_fsm_sale/js/tours/industry_fsm_sale_tour',['@web/core/registry','@industry_fsm/js/tours/industry_fsm_tour','@web/core/l10n/translation','@web/core/utils/patch','@odoo/owl'],function(require){'use strict';let __exports={};const{registry}=require("@web/core/registry");require('@industry_fsm/js/tours/industry_fsm_tour');const{_t}=require("@web/core/l10n/translation");const{patch}=require("@web/core/utils/patch");const{markup}=require("@odoo/owl");patch(registry.category("web_tour.tours").get("industry_fsm_tour"),{steps(){const originalSteps=super.steps();const fsmStartStepIndex=originalSteps.findIndex((step)=>step.id==="fsm_start");originalSteps.splice(fsmStartStepIndex+1,0,{trigger:'button[name="action_fsm_view_material"]',extra_trigger:'button[name="action_timer_stop"]',content:markup(_t('Let\'s <b>track the material</b> you use for your task.')),position:'bottom',},{trigger:".o-kanban-button-new",content:markup(_t('Let\'s create a new <b>product</b>.')),position:'right',},{trigger:'.o_field_text textarea',content:markup(_t('Choose a <b>name</b> for your product <i>(e.g. Bolts, Screws, Boiler, etc.).</i>')),position:'right',},{trigger:".breadcrumb-item.o_back_button",content:markup(_t("Use the breadcrumbs to navigate to your <b>list of products</b>.")),position:"bottom",},{trigger:'.o_kanban_record:first-child button:has(i.fa-shopping-cart)',alt_trigger:".o_fsm_product_kanban_view .o_kanban_record",extra_trigger:'.o_fsm_product_kanban_view',content:markup(_t('Click on a product to add it to your <b>list of materials</b>. <i>Tip: for large quantities, click on the number to edit it directly.</i>')),position:'right',},{trigger:".breadcrumb-item.o_back_button",extra_trigger:'.o_fsm_product_kanban_view',content:markup(_t("Use the breadcrumbs to return to your <b>task</b>.")),position:"bottom"});const fsmCreateInvoiceStepIndex=originalSteps.findIndex((step)=>step.id==="fsm_invoice_create");originalSteps.splice(fsmCreateInvoiceStepIndex+1,0,{trigger:".o_statusbar_buttons > button:contains('Create Invoice')",content:markup(_t("<b>Invoice your time and material</b> to your customer.")),position:"bottom"},{trigger:".modal-footer button[id='create_invoice_open'].btn-primary",extra_trigger:".modal-dialog.modal-lg",content:markup(_t("Confirm the creation of your <b>invoice</b>.")),position:"bottom"},{content:_t("Wait for the invoice to show up"),trigger:"span:contains('Customer Invoice')",run(){},auto:true,});return originalSteps;}});return __exports;});;

/* /mail_group/static/src/js/mail_group.js */
odoo.define('@mail_group/js/mail_group',['@web/legacy/js/public/public_widget','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{_t}=require("@web/core/l10n/translation");publicWidget.registry.MailGroup=publicWidget.Widget.extend({selector:'.o_mail_group',events:{'click .o_mg_subscribe_btn':'_onSubscribeBtnClick',},init(){this._super(...arguments);this.rpc=this.bindService("rpc");},start:function(){this.mailgroupId=this.$el.data('id');this.isMember=this.$el.data('isMember')||false;const searchParams=(new URL(document.location.href)).searchParams;this.token=searchParams.get('token');this.forceUnsubscribe=searchParams.has('unsubscribe');return this._super.apply(this,arguments);},_onSubscribeBtnClick:async function(ev){ev.preventDefault();const $email=this.$el.find(".o_mg_subscribe_email");const email=$email.val();if(!email.match(/.+@.+/)){this.$el.addClass('o_has_error').find('.form-control, .form-select').addClass('is-invalid');return false;}
this.$el.removeClass('o_has_error').find('.form-control, .form-select').removeClass('is-invalid');const action=(this.isMember||this.forceUnsubscribe)?'unsubscribe':'subscribe';const response=await this.rpc('/group/'+action,{'group_id':this.mailgroupId,'email':email,'token':this.token,});this.$el.find('.o_mg_alert').remove();if(response==='added'){this.isMember=true;this.$el.find('.o_mg_subscribe_btn').text(_t('Unsubscribe')).removeClass('btn-primary').addClass('btn-outline-primary');}else if(response==='removed'){this.isMember=false;this.$el.find('.o_mg_subscribe_btn').text(_t('Subscribe')).removeClass('btn-outline-primary').addClass('btn-primary');}else if(response==='email_sent'){this.$el.html($('<div class="o_mg_alert alert alert-success" role="alert"/>').text(_t('An email with instructions has been sent.')));}else if(response==='is_already_member'){this.isMember=true;this.$el.find('.o_mg_subscribe_btn').text(_t('Unsubscribe')).removeClass('btn-primary').addClass('btn-outline-primary');this.$el.find('.o_mg_subscribe_form').before($('<div class="o_mg_alert alert alert-warning" role="alert"/>').text(_t('This email is already subscribed.')));}else if(response==='is_not_member'){if(!this.forceUnsubscribe){this.isMember=false;this.$el.find('.o_mg_subscribe_btn').text(_t('Subscribe'));}
this.$el.find('.o_mg_subscribe_form').before($('<div class="o_mg_alert alert alert-warning" role="alert"/>').text(_t('This email is not subscribed.')));}},});__exports[Symbol.for("default")]=publicWidget.registry.MailGroup;return __exports;});;

/* /mail_group/static/src/js/mail_group_message.js */
odoo.define('@mail_group/js/mail_group_message',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.MailGroupMessage=publicWidget.Widget.extend({selector:'.o_mg_message',events:{'click .o_mg_link_hide':'_onHideLinkClick','click .o_mg_link_show':'_onShowLinkClick','click button.o_mg_read_more':'_onReadMoreClick',},init(){this._super(...arguments);this.rpc=this.bindService("rpc");},start:function(){const body=this.$el.find('.card-body').first();const quoted=body.find('*[data-o-mail-quote]');const readMore=$('<button class="btn btn-light btn-sm ms-1"/>').text('. . .');quoted.first().before(readMore);readMore.on('click',()=>{quoted.toggleClass('visible');});return this._super.apply(this,arguments);},_onHideLinkClick:function(ev){ev.preventDefault();ev.stopPropagation();const $link=$(ev.currentTarget);const $container=$link.closest('.o_mg_link_parent');$container.find('.o_mg_link_hide').first().addClass('d-none');$container.find('.o_mg_link_show').first().removeClass('d-none');$container.find('.o_mg_link_content').first().removeClass('d-none');},_onShowLinkClick:function(ev){ev.preventDefault();ev.stopPropagation();const $link=$(ev.currentTarget);const $container=$link.closest('.o_mg_link_parent');$container.find('.o_mg_link_hide').first().removeClass('d-none');$container.find('.o_mg_link_show').first().addClass('d-none');$container.find('.o_mg_link_content').first().addClass('d-none');},_onReadMoreClick:function(ev){const $link=$(ev.target);this.rpc($link.data('href'),{last_displayed_id:$link.data('last-displayed-id'),}).then(function(data){if(!data){return;}
const $threadContainer=$link.parents('.o_mg_replies').first().find('ul.list-unstyled').first();if($threadContainer){const $data=$(data);const $lastMsg=$threadContainer.children('li.media').last();const $newMessages=$data.find('ul.list-unstyled').first().children('li.media');$newMessages.insertAfter($lastMsg);$data.find('.o_mg_read_more').parent().appendTo($threadContainer);}
const $showMore=$link.parent();$showMore.remove();});},});return __exports;});;

/* /sale_planning/static/src/js/frontend/sale_planning_calendar_portal.js */
odoo.define('@sale_planning/js/frontend/sale_planning_calendar_portal',['@planning/js/planning_calendar_front'],function(require){'use strict';let __exports={};const PlanningView=require('@planning/js/planning_calendar_front')[Symbol.for("default")];PlanningView.include({eventFunction:function(calEvent){this._super.apply(this,arguments);const $saleLine=$("#sale_line");if(calEvent.event.extendedProps.sale_line){$saleLine.text(calEvent.event.extendedProps.sale_line);$saleLine.css("display","");$saleLine.prev().css("display","");}else{$saleLine.css("display","none");$saleLine.prev().css("display","none");}},});return __exports;});;

/* /social_push_notifications/static/lib/firebase-app-6.3.4.js */
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).firebase=t()}(this,function(){"use strict";var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])})(e,t)};var n=function(){return(n=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};function d(e,t){if(!(t instanceof Object))return t;switch(t.constructor){case Date:return new Date(t.getTime());case Object:void 0===e&&(e={});break;case Array:e=[];break;default:return t}for(var r in t)t.hasOwnProperty(r)&&(e[r]=d(e[r],t[r]));return e}var e,t,o,f=(o=Error,r(e=a,t=o),void(e.prototype=null===t?Object.create(t):(i.prototype=t.prototype,new i)),a);function i(){this.constructor=e}function a(e,t){var r=o.call(this,t)||this;return r.code=e,r.name="FirebaseError",Object.setPrototypeOf(r,a.prototype),Error.captureStackTrace&&Error.captureStackTrace(r,s.prototype.create),r}var s=(c.prototype.create=function(e){for(var t=[],r=1;r<arguments.length;r++)t[r-1]=arguments[r];for(var n=t[0]||{},o=this.service+"/"+e,i=this.errors[e],a=i?function(e,n){return e.replace(h,function(e,t){var r=n[t];return null!=r?r.toString():"<"+t+"?>"})}(i,n):"Error",s=this.serviceName+": "+a+" ("+o+").",c=new f(o,s),p=0,l=Object.keys(n);p<l.length;p++){var u=l[p];"_"!==u.slice(-1)&&(u in c&&console.warn('Overwriting FirebaseError base field "'+u+'" can cause unexpected behavior.'),c[u]=n[u])}return c},c);function c(e,t,r){this.service=e,this.serviceName=t,this.errors=r}var h=/\{\$([^}]+)}/g;function v(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function p(e,t){var r=new b(e,t);return r.subscribe.bind(r)}var l,u,b=(y.prototype.next=function(t){this.forEachObserver(function(e){e.next(t)})},y.prototype.error=function(t){this.forEachObserver(function(e){e.error(t)}),this.close(t)},y.prototype.complete=function(){this.forEachObserver(function(e){e.complete()}),this.close()},y.prototype.subscribe=function(e,t,r){var n,o=this;if(void 0===e&&void 0===t&&void 0===r)throw new Error("Missing Observer.");void 0===(n=function(e,t){if("object"!=typeof e||null===e)return!1;for(var r=0,n=t;r<n.length;r++){var o=n[r];if(o in e&&"function"==typeof e[o])return!0}return!1}(e,["next","error","complete"])?e:{next:e,error:t,complete:r}).next&&(n.next=g),void 0===n.error&&(n.error=g),void 0===n.complete&&(n.complete=g);var i=this.unsubscribeOne.bind(this,this.observers.length);return this.finalized&&this.task.then(function(){try{o.finalError?n.error(o.finalError):n.complete()}catch(e){}}),this.observers.push(n),i},y.prototype.unsubscribeOne=function(e){void 0!==this.observers&&void 0!==this.observers[e]&&(delete this.observers[e],this.observerCount-=1,0===this.observerCount&&void 0!==this.onNoObservers&&this.onNoObservers(this))},y.prototype.forEachObserver=function(e){if(!this.finalized)for(var t=0;t<this.observers.length;t++)this.sendOne(t,e)},y.prototype.sendOne=function(e,t){var r=this;this.task.then(function(){if(void 0!==r.observers&&void 0!==r.observers[e])try{t(r.observers[e])}catch(e){"undefined"!=typeof console&&console.error&&console.error(e)}})},y.prototype.close=function(e){var t=this;this.finalized||(this.finalized=!0,void 0!==e&&(this.finalError=e),this.task.then(function(){t.observers=void 0,t.onNoObservers=void 0}))},y);function y(e,t){var r=this;this.observers=[],this.unsubscribes=[],this.observerCount=0,this.task=Promise.resolve(),this.finalized=!1,this.onNoObservers=t,this.task.then(function(){e(r)}).catch(function(e){r.error(e)})}function g(){}(u=l=l||{})[u.DEBUG=0]="DEBUG",u[u.VERBOSE=1]="VERBOSE",u[u.INFO=2]="INFO",u[u.WARN=3]="WARN",u[u.ERROR=4]="ERROR",u[u.SILENT=5]="SILENT";function m(e,t){for(var r=[],n=2;n<arguments.length;n++)r[n-2]=arguments[n];if(!(t<e.logLevel)){var o=(new Date).toISOString();switch(t){case l.DEBUG:case l.VERBOSE:console.log.apply(console,["["+o+"]  "+e.name+":"].concat(r));break;case l.INFO:console.info.apply(console,["["+o+"]  "+e.name+":"].concat(r));break;case l.WARN:console.warn.apply(console,["["+o+"]  "+e.name+":"].concat(r));break;case l.ERROR:console.error.apply(console,["["+o+"]  "+e.name+":"].concat(r));break;default:throw new Error("Attempted to log a message with an invalid logType (value: "+t+")")}}}var _,E=l.INFO,N=(Object.defineProperty(O.prototype,"logLevel",{get:function(){return this._logLevel},set:function(e){if(!(e in l))throw new TypeError("Invalid value assigned to `logLevel`");this._logLevel=e},enumerable:!0,configurable:!0}),Object.defineProperty(O.prototype,"logHandler",{get:function(){return this._logHandler},set:function(e){if("function"!=typeof e)throw new TypeError("Value assigned to `logHandler` must be a function");this._logHandler=e},enumerable:!0,configurable:!0}),O.prototype.debug=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];this._logHandler.apply(this,[this,l.DEBUG].concat(e))},O.prototype.log=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];this._logHandler.apply(this,[this,l.VERBOSE].concat(e))},O.prototype.info=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];this._logHandler.apply(this,[this,l.INFO].concat(e))},O.prototype.warn=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];this._logHandler.apply(this,[this,l.WARN].concat(e))},O.prototype.error=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];this._logHandler.apply(this,[this,l.ERROR].concat(e))},O);function O(e){this.name=e,this._logLevel=E,this._logHandler=m}var w=((_={})["no-app"]="No Firebase App '{$appName}' has been created - call Firebase App.initializeApp()",_["bad-app-name"]="Illegal App name: '{$appName}",_["duplicate-app"]="Firebase App named '{$appName}' already exists",_["app-deleted"]="Firebase App named '{$appName}' already deleted",_["duplicate-service"]="Firebase service named '{$appName}' already registered",_["invalid-app-argument"]="firebase.{$appName}() takes either no argument or a Firebase App instance.",_),A=new s("app","Firebase",w),k="[DEFAULT]",R=[],I=(Object.defineProperty(T.prototype,"automaticDataCollectionEnabled",{get:function(){return this.checkDestroyed_(),this.automaticDataCollectionEnabled_},set:function(e){this.checkDestroyed_(),this.automaticDataCollectionEnabled_=e},enumerable:!0,configurable:!0}),Object.defineProperty(T.prototype,"name",{get:function(){return this.checkDestroyed_(),this.name_},enumerable:!0,configurable:!0}),Object.defineProperty(T.prototype,"options",{get:function(){return this.checkDestroyed_(),this.options_},enumerable:!0,configurable:!0}),T.prototype.delete=function(){var s=this;return new Promise(function(e){s.checkDestroyed_(),e()}).then(function(){s.firebase_.INTERNAL.removeApp(s.name_);for(var e=[],t=0,r=Object.keys(s.services_);t<r.length;t++)for(var n=r[t],o=0,i=Object.keys(s.services_[n]);o<i.length;o++){var a=i[o];e.push(s.services_[n][a])}return Promise.all(e.filter(function(e){return"INTERNAL"in e}).map(function(e){return e.INTERNAL.delete()}))}).then(function(){s.isDeleted_=!0,s.services_={}})},T.prototype._getService=function(e,t){if(void 0===t&&(t=k),this.checkDestroyed_(),this.services_[e]||(this.services_[e]={}),!this.services_[e][t]){var r=t!==k?t:void 0,n=this.firebase_.INTERNAL.factories[e](this,this.extendApp.bind(this),r);this.services_[e][t]=n}return this.services_[e][t]},T.prototype._removeServiceInstance=function(e,t){void 0===t&&(t=k),this.services_[e]&&this.services_[e][t]&&delete this.services_[e][t]},T.prototype.extendApp=function(e){var t=this;d(this,e),e.INTERNAL&&e.INTERNAL.addAuthTokenListener&&(R.forEach(function(e){t.INTERNAL.addAuthTokenListener(e)}),R=[])},T.prototype.checkDestroyed_=function(){if(this.isDeleted_)throw A.create("app-deleted",{appName:this.name_})},T);function T(e,t,r){this.firebase_=r,this.isDeleted_=!1,this.services_={},this.name_=t.name,this.automaticDataCollectionEnabled_=t.automaticDataCollectionEnabled||!1,this.options_=function(e){return d(void 0,e)}(e),this.INTERNAL={getUid:function(){return null},getToken:function(){return Promise.resolve(null)},addAuthTokenListener:function(e){R.push(e),setTimeout(function(){return e(null)},0)},removeAuthTokenListener:function(t){R=R.filter(function(e){return e!==t})}}}I.prototype.name&&I.prototype.options||I.prototype.delete||console.log("dc");var j="6.3.4";var F=new N("@firebase/app");if("object"==typeof self&&self.self===self&&void 0!==self.firebase){F.warn("\n    Warning: Firebase is already defined in the global scope. Please make sure\n    Firebase library is only loaded once.\n  ");var D=self.firebase.SDK_VERSION;D&&0<=D.indexOf("LITE")&&F.warn("\n    Warning: You are trying to load Firebase while using Firebase Performance standalone script.\n    You should load Firebase Performance with this instance of Firebase to avoid loading duplicate code.\n    ")}var L=function e(){var t=function(a){var i={},s={},c={},p={__esModule:!0,initializeApp:function(e,t){void 0===t&&(t={}),"object"==typeof t&&null!==t||(t={name:t});var r=t;void 0===r.name&&(r.name=k);var n=r.name;if("string"!=typeof n||!n)throw A.create("bad-app-name",{appName:String(n)});if(v(i,n))throw A.create("duplicate-app",{appName:n});var o=new a(e,r,p);return f(i[n]=o,"create"),o},app:l,apps:null,SDK_VERSION:j,INTERNAL:{registerService:function(r,e,t,n,o){if(void 0===o&&(o=!1),s[r])throw A.create("duplicate-service",{appName:r});function i(e){if(void 0===e&&(e=l()),"function"!=typeof e[r])throw A.create("invalid-app-argument",{appName:r});return e[r]()}return s[r]=e,n&&(c[r]=n,u().forEach(function(e){n("create",e)})),void 0!==t&&d(i,t),p[r]=i,a.prototype[r]=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return this._getService.bind(this,r).apply(this,o?e:[])},i},removeApp:function(e){f(i[e],"delete"),delete i[e]},factories:s,useAsService:h}};function l(e){if(!v(i,e=e||k))throw A.create("no-app",{appName:e});return i[e]}function u(){return Object.keys(i).map(function(e){return i[e]})}function f(e,t){for(var r=0,n=Object.keys(s);r<n.length;r++){var o=h(0,n[r]);if(null===o)return;c[o]&&c[o](t,e)}}function h(e,t){return"serverAuth"===t?null:t}return p.default=p,Object.defineProperty(p,"apps",{get:u}),l.App=a,p}(I);return t.INTERNAL=n({},t.INTERNAL,{createFirebaseNamespace:e,extendNamespace:function(e){d(t,e)},createSubscribe:p,ErrorFactory:s,deepExtend:d}),t}(),S=L.initializeApp;return L.initializeApp=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return function(){try{return"[object process]"===Object.prototype.toString.call(global.process)}catch(e){return!1}}()&&F.warn('\n      Warning: This is a browser-targeted Firebase bundle but it appears it is being\n      run in a Node environment.  If running in a Node environment, make sure you\n      are using the bundle specified by the "main" field in package.json.\n      \n      If you are using Webpack, you can specify "main" as the first item in\n      "resolve.mainFields":\n      https://webpack.js.org/configuration/resolve/#resolvemainfields\n      \n      If using Rollup, use the rollup-plugin-node-resolve plugin and specify "main"\n      as the first item in "mainFields", e.g. [\'main\', \'module\'].\n      https://github.com/rollup/rollup-plugin-node-resolve\n      '),S.apply(void 0,e)},L});;

/* /social_push_notifications/static/lib/firebase-messaging-6.3.4.js */
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(require("@firebase/app")):"function"==typeof define&&define.amd?define(["@firebase/app"],t):t((e=e||self).firebase)}(this,function(re){"use strict";try{(function(){re=re&&re.hasOwnProperty("default")?re.default:re;var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function e(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var i=function(){return(i=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};function b(i,s,a,c){return new(a=a||Promise)(function(e,t){function n(e){try{o(c.next(e))}catch(e){t(e)}}function r(e){try{o(c.throw(e))}catch(e){t(e)}}function o(t){t.done?e(t.value):new a(function(e){e(t.value)}).then(n,r)}o((c=c.apply(i,s||[])).next())})}function v(n,r){var o,i,s,e,a={label:0,sent:function(){if(1&s[0])throw s[1];return s[1]},trys:[],ops:[]};return e={next:t(0),throw:t(1),return:t(2)},"function"==typeof Symbol&&(e[Symbol.iterator]=function(){return this}),e;function t(t){return function(e){return function(t){if(o)throw new TypeError("Generator is already executing.");for(;a;)try{if(o=1,i&&(s=2&t[0]?i.return:t[0]?i.throw||((s=i.return)&&s.call(i),0):i.next)&&!(s=s.call(i,t[1])).done)return s;switch(i=0,s&&(t=[2&t[0],s.value]),t[0]){case 0:case 1:s=t;break;case 4:return a.label++,{value:t[1],done:!1};case 5:a.label++,i=t[1],t=[0];continue;case 7:t=a.ops.pop(),a.trys.pop();continue;default:if(!(s=0<(s=a.trys).length&&s[s.length-1])&&(6===t[0]||2===t[0])){a=0;continue}if(3===t[0]&&(!s||t[1]>s[0]&&t[1]<s[3])){a.label=t[1];break}if(6===t[0]&&a.label<s[1]){a.label=s[1],s=t;break}if(s&&a.label<s[2]){a.label=s[2],a.ops.push(t);break}s[2]&&a.ops.pop(),a.trys.pop();continue}t=r.call(n,a)}catch(e){t=[6,e],i=0}finally{o=s=0}if(5&t[0])throw t[1];return{value:t[0]?t[1]:void 0,done:!0}}([t,e])}}}function n(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,i=n.call(e),s=[];try{for(;(void 0===t||0<t--)&&!(r=i.next()).done;)s.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return s}var o,h=(e(s,o=Error),s);function s(e,t){var n=o.call(this,t)||this;return n.code=e,n.name="FirebaseError",Object.setPrototypeOf(n,s.prototype),Error.captureStackTrace&&Error.captureStackTrace(n,a.prototype.create),n}var a=(t.prototype.create=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];for(var r=t[0]||{},o=this.service+"/"+e,i=this.errors[e],s=i?function(e,r){return e.replace(l,function(e,t){var n=r[t];return null!=n?n.toString():"<"+t+"?>"})}(i,r):"Error",a=this.serviceName+": "+s+" ("+o+").",c=new h(o,a),u=0,d=Object.keys(r);u<d.length;u++){var f=d[u];"_"!==f.slice(-1)&&(f in c&&console.warn('Overwriting FirebaseError base field "'+f+'" can cause unexpected behavior.'),c[f]=r[f])}return c},t);function t(e,t,n){this.service=e,this.serviceName=t,this.errors=n}var l=/\{\$([^}]+)}/g;function c(e,t){var n=new d(e,t);return n.subscribe.bind(n)}var u,d=(f.prototype.next=function(t){this.forEachObserver(function(e){e.next(t)})},f.prototype.error=function(t){this.forEachObserver(function(e){e.error(t)}),this.close(t)},f.prototype.complete=function(){this.forEachObserver(function(e){e.complete()}),this.close()},f.prototype.subscribe=function(e,t,n){var r,o=this;if(void 0===e&&void 0===t&&void 0===n)throw new Error("Missing Observer.");void 0===(r=function(e,t){if("object"!=typeof e||null===e)return!1;for(var n=0,r=t;n<r.length;n++){var o=r[n];if(o in e&&"function"==typeof e[o])return!0}return!1}(e,["next","error","complete"])?e:{next:e,error:t,complete:n}).next&&(r.next=p),void 0===r.error&&(r.error=p),void 0===r.complete&&(r.complete=p);var i=this.unsubscribeOne.bind(this,this.observers.length);return this.finalized&&this.task.then(function(){try{o.finalError?r.error(o.finalError):r.complete()}catch(e){}}),this.observers.push(r),i},f.prototype.unsubscribeOne=function(e){void 0!==this.observers&&void 0!==this.observers[e]&&(delete this.observers[e],this.observerCount-=1,0===this.observerCount&&void 0!==this.onNoObservers&&this.onNoObservers(this))},f.prototype.forEachObserver=function(e){if(!this.finalized)for(var t=0;t<this.observers.length;t++)this.sendOne(t,e)},f.prototype.sendOne=function(e,t){var n=this;this.task.then(function(){if(void 0!==n.observers&&void 0!==n.observers[e])try{t(n.observers[e])}catch(e){"undefined"!=typeof console&&console.error&&console.error(e)}})},f.prototype.close=function(e){var t=this;this.finalized||(this.finalized=!0,void 0!==e&&(this.finalError=e),this.task.then(function(){t.observers=void 0,t.onNoObservers=void 0}))},f);function f(e,t){var n=this;this.observers=[],this.unsubscribes=[],this.observerCount=0,this.task=Promise.resolve(),this.finalized=!1,this.onNoObservers=t,this.task.then(function(){e(n)}).catch(function(e){n.error(e)})}function p(){}var g,y,w,m,k=((u={})["only-available-in-window"]="This method is available in a Window context.",u["only-available-in-sw"]="This method is available in a service worker context.",u["should-be-overriden"]="This method should be overriden by extended classes.",u["bad-sender-id"]="Please ensure that 'messagingSenderId' is set correctly in the options passed into firebase.initializeApp().",u["permission-default"]="The required permissions were not granted and dismissed instead.",u["permission-blocked"]="The required permissions were not granted and blocked instead.",u["unsupported-browser"]="This browser doesn't support the API's required to use the firebase SDK.",u["notifications-blocked"]="Notifications have been blocked.",u["failed-serviceworker-registration"]="We are unable to register the default service worker. {$browserErrorMessage}",u["sw-registration-expected"]="A service worker registration was the expected input.",u["get-subscription-failed"]="There was an error when trying to get any existing Push Subscriptions.",u["invalid-saved-token"]="Unable to access details of the saved token.",u["sw-reg-redundant"]="The service worker being used for push was made redundant.",u["token-subscribe-failed"]="A problem occurred while subscribing the user to FCM: {$errorInfo}",u["token-subscribe-no-token"]="FCM returned no token when subscribing the user to push.",u["token-subscribe-no-push-set"]="FCM returned an invalid response when getting an FCM token.",u["token-unsubscribe-failed"]="A problem occurred while unsubscribing the user from FCM: {$errorInfo}",u["token-update-failed"]="A problem occurred while updating the user from FCM: {$errorInfo}",u["token-update-no-token"]="FCM returned no token when updating the user to push.",u["use-sw-before-get-token"]="The useServiceWorker() method may only be called once and must be called before calling getToken() to ensure your service worker is used.",u["invalid-delete-token"]="You must pass a valid token into deleteToken(), i.e. the token from getToken().",u["delete-token-not-found"]="The deletion attempt for token could not be performed as the token was not found.",u["delete-scope-not-found"]="The deletion attempt for service worker scope could not be performed as the scope was not found.",u["bg-handler-function-expected"]="The input to setBackgroundMessageHandler() must be a function.",u["no-window-client-to-msg"]="An attempt was made to message a non-existant window client.",u["unable-to-resubscribe"]="There was an error while re-subscribing the FCM token for push messaging. Will have to resubscribe the user on next visit. {$errorInfo}",u["no-fcm-token-for-resubscribe"]="Could not find an FCM token and as a result, unable to resubscribe. Will have to resubscribe the user on next visit.",u["failed-to-delete-token"]="Unable to delete the currently saved token.",u["no-sw-in-reg"]="Even though the service worker registration was successful, there was a problem accessing the service worker itself.",u["incorrect-gcm-sender-id"]="Please change your web app manifest's 'gcm_sender_id' value to '103953800507' to use Firebase messaging.",u["bad-scope"]="The service worker scope must be a string with at least one character.",u["bad-vapid-key"]="The public VAPID key is not a Uint8Array with 65 bytes.",u["bad-subscription"]="The subscription must be a valid PushSubscription.",u["bad-token"]="The FCM Token used for storage / lookup was not a valid token string.",u["bad-push-set"]="The FCM push set used for storage / lookup was not not a valid push set string.",u["failed-delete-vapid-key"]="The VAPID key could not be deleted.",u["invalid-public-vapid-key"]="The public VAPID key must be a string.",u["use-public-key-before-get-token"]="The usePublicVapidKey() method may only be called once and must be called before calling getToken() to ensure your VAPID key is used.",u["public-vapid-key-decryption-failed"]="The public VAPID key did not equal 65 bytes when decrypted.",u),T=new a("messaging","Messaging",k),S=new Uint8Array([4,51,148,247,223,161,235,177,220,3,162,94,21,113,219,72,211,46,237,237,178,52,219,183,71,58,12,143,196,204,225,111,60,140,132,223,171,182,102,62,242,12,212,139,254,227,249,118,47,20,28,99,8,106,111,45,177,26,149,176,206,55,192,156,110]),_="https://fcm.googleapis.com";function P(e,t){if(null==e||null==t)return!1;if(e===t)return!0;if(e.byteLength!==t.byteLength)return!1;for(var n=new DataView(e),r=new DataView(t),o=0;o<e.byteLength;o++)if(n.getUint8(o)!==r.getUint8(o))return!1;return!0}function M(e){var t=new Uint8Array(e);return btoa(String.fromCharCode.apply(String,function(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(n(arguments[t]));return e}(t)))}function D(e){return M(e).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}(y=g=g||{}).TYPE_OF_MSG="firebase-messaging-msg-type",y.DATA="firebase-messaging-msg-data",(m=w=w||{}).PUSH_MSG_RECEIVED="push-msg-received",m.NOTIFICATION_CLICKED="notification-clicked";var I=(C.prototype.getToken=function(d,f,h){return b(this,void 0,void 0,function(){var t,n,r,o,i,s,a,c,u;return v(this,function(e){switch(e.label){case 0:t=D(f.getKey("p256dh")),n=D(f.getKey("auth")),r="authorized_entity="+d+"&endpoint="+f.endpoint+"&encryption_key="+t+"&encryption_auth="+n,P(h.buffer,S.buffer)||(o=D(h),r+="&application_pub_key="+o),(i=new Headers).append("Content-Type","application/x-www-form-urlencoded"),s={method:"POST",headers:i,body:r},e.label=1;case 1:return e.trys.push([1,4,,5]),[4,fetch(_+"/fcm/connect/subscribe",s)];case 2:return[4,e.sent().json()];case 3:return a=e.sent(),[3,5];case 4:throw c=e.sent(),T.create("token-subscribe-failed",{errorInfo:c});case 5:if(a.error)throw u=a.error.message,T.create("token-subscribe-failed",{errorInfo:u});if(!a.token)throw T.create("token-subscribe-no-token");if(!a.pushSet)throw T.create("token-subscribe-no-push-set");return[2,{token:a.token,pushSet:a.pushSet}]}})})},C.prototype.updateToken=function(d,f,h,l,p){return b(this,void 0,void 0,function(){var t,n,r,o,i,s,a,c,u;return v(this,function(e){switch(e.label){case 0:t=D(l.getKey("p256dh")),n=D(l.getKey("auth")),r="push_set="+h+"&token="+f+"&authorized_entity="+d+"&endpoint="+l.endpoint+"&encryption_key="+t+"&encryption_auth="+n,P(p.buffer,S.buffer)||(o=D(p),r+="&application_pub_key="+o),(i=new Headers).append("Content-Type","application/x-www-form-urlencoded"),s={method:"POST",headers:i,body:r},e.label=1;case 1:return e.trys.push([1,4,,5]),[4,fetch(_+"/fcm/connect/subscribe",s)];case 2:return[4,e.sent().json()];case 3:return a=e.sent(),[3,5];case 4:throw c=e.sent(),T.create("token-update-failed",{errorInfo:c});case 5:if(a.error)throw u=a.error.message,T.create("token-update-failed",{errorInfo:u});if(!a.token)throw T.create("token-update-no-token");return[2,a.token]}})})},C.prototype.deleteToken=function(a,c,u){return b(this,void 0,void 0,function(){var t,n,r,o,i,s;return v(this,function(e){switch(e.label){case 0:t="authorized_entity="+a+"&token="+c+"&pushSet="+u,(n=new Headers).append("Content-Type","application/x-www-form-urlencoded"),r={method:"POST",headers:n,body:t},e.label=1;case 1:return e.trys.push([1,4,,5]),[4,fetch(_+"/fcm/connect/unsubscribe",r)];case 2:return[4,e.sent().json()];case 3:if((o=e.sent()).error)throw i=o.error.message,T.create("token-unsubscribe-failed",{errorInfo:i});return[3,5];case 4:throw s=e.sent(),T.create("token-unsubscribe-failed",{errorInfo:s});case 5:return[2]}})})},C);function C(){}function O(e){for(var t=(e+"=".repeat((4-e.length%4)%4)).replace(/\-/g,"+").replace(/_/g,"/"),n=atob(t),r=new Uint8Array(n.length),o=0;o<n.length;++o)r[o]=n.charCodeAt(o);return r}var N="undefined",E="fcm_token_object_Store";function x(){var t=indexedDB.open(N);t.onerror=function(e){},t.onsuccess=function(e){!function(n){if(n.objectStoreNames.contains(E)){var e=n.transaction(E).objectStore(E),r=new I,o=e.openCursor();o.onerror=function(e){console.warn("Unable to cleanup old IDB.",e)},o.onsuccess=function(){var e=o.result;if(e){var t=e.value;r.deleteToken(t.fcmSenderId,t.fcmToken,t.fcmPushSet),e.continue()}else n.close(),indexedDB.deleteDatabase(N)}}}(t.result)}}var K=(A.prototype.get=function(t){return this.createTransaction(function(e){return e.get(t)})},A.prototype.getIndex=function(t,n){return this.createTransaction(function(e){return e.index(t).get(n)})},A.prototype.put=function(t){return this.createTransaction(function(e){return e.put(t)},"readwrite")},A.prototype.delete=function(t){return this.createTransaction(function(e){return e.delete(t)},"readwrite")},A.prototype.closeDatabase=function(){return b(this,void 0,void 0,function(){return v(this,function(e){switch(e.label){case 0:return this.dbPromise?[4,this.dbPromise]:[3,2];case 1:e.sent().close(),this.dbPromise=null,e.label=2;case 2:return[2]}})})},A.prototype.createTransaction=function(i,s){return void 0===s&&(s="readonly"),b(this,void 0,void 0,function(){var t,n,r,o;return v(this,function(e){switch(e.label){case 0:return[4,this.getDb()];case 1:return t=e.sent(),n=t.transaction(this.objectStoreName,s),r=n.objectStore(this.objectStoreName),[4,function(n){return new Promise(function(e,t){n.onsuccess=function(){e(n.result)},n.onerror=function(){t(n.error)}})}(i(r))];case 2:return o=e.sent(),[2,new Promise(function(e,t){n.oncomplete=function(){e(o)},n.onerror=function(){t(n.error)}})]}})})},A.prototype.getDb=function(){var r=this;return this.dbPromise||(this.dbPromise=new Promise(function(e,t){var n=indexedDB.open(r.dbName,r.dbVersion);n.onsuccess=function(){e(n.result)},n.onerror=function(){r.dbPromise=null,t(n.error)},n.onupgradeneeded=function(e){return r.onDbUpgrade(n,e)}})),this.dbPromise},A);function A(){this.dbPromise=null}var V,F=(e(W,V=K),W.prototype.onDbUpgrade=function(e,t){var n=e.result;switch(t.oldVersion){case 0:(r=n.createObjectStore(this.objectStoreName,{keyPath:"swScope"})).createIndex("fcmSenderId","fcmSenderId",{unique:!1}),r.createIndex("fcmToken","fcmToken",{unique:!0});case 1:x();case 2:var r,o=(r=e.transaction.objectStore(this.objectStoreName)).openCursor();o.onsuccess=function(){var e=o.result;if(e){var t=e.value,n=i({},t);t.createTime||(n.createTime=Date.now()),"string"==typeof t.vapidKey&&(n.vapidKey=O(t.vapidKey)),"string"==typeof t.auth&&(n.auth=O(t.auth).buffer),"string"==typeof t.auth&&(n.p256dh=O(t.p256dh).buffer),e.update(n),e.continue()}}}},W.prototype.getTokenDetailsFromToken=function(t){return b(this,void 0,void 0,function(){return v(this,function(e){if(!t)throw T.create("bad-token");return U({fcmToken:t}),[2,this.getIndex("fcmToken",t)]})})},W.prototype.getTokenDetailsFromSWScope=function(t){return b(this,void 0,void 0,function(){return v(this,function(e){if(!t)throw T.create("bad-scope");return U({swScope:t}),[2,this.get(t)]})})},W.prototype.saveTokenDetails=function(t){return b(this,void 0,void 0,function(){return v(this,function(e){if(!t.swScope)throw T.create("bad-scope");if(!t.vapidKey)throw T.create("bad-vapid-key");if(!t.endpoint||!t.auth||!t.p256dh)throw T.create("bad-subscription");if(!t.fcmSenderId)throw T.create("bad-sender-id");if(!t.fcmToken)throw T.create("bad-token");if(!t.fcmPushSet)throw T.create("bad-push-set");return U(t),[2,this.put(t)]})})},W.prototype.deleteToken=function(n){return b(this,void 0,void 0,function(){var t;return v(this,function(e){switch(e.label){case 0:return"string"!=typeof n||0===n.length?[2,Promise.reject(T.create("invalid-delete-token"))]:[4,this.getTokenDetailsFromToken(n)];case 1:if(!(t=e.sent()))throw T.create("delete-token-not-found");return[4,this.delete(t.swScope)];case 2:return e.sent(),[2,t]}})})},W);function W(){var e=null!==V&&V.apply(this,arguments)||this;return e.dbName="fcm_token_details_db",e.dbVersion=3,e.objectStoreName="fcm_token_object_Store",e}function U(e){if(e.fcmToken&&("string"!=typeof e.fcmToken||0===e.fcmToken.length))throw T.create("bad-token");if(e.swScope&&("string"!=typeof e.swScope||0===e.swScope.length))throw T.create("bad-scope");if(e.vapidKey&&(!(e.vapidKey instanceof Uint8Array)||65!==e.vapidKey.length))throw T.create("bad-vapid-key");if(e.endpoint&&("string"!=typeof e.endpoint||0===e.endpoint.length))throw T.create("bad-subscription");if(e.auth&&!(e.auth instanceof ArrayBuffer))throw T.create("bad-subscription");if(e.p256dh&&!(e.p256dh instanceof ArrayBuffer))throw T.create("bad-subscription");if(e.fcmSenderId&&("string"!=typeof e.fcmSenderId||0===e.fcmSenderId.length))throw T.create("bad-sender-id");if(e.fcmPushSet&&("string"!=typeof e.fcmPushSet||0===e.fcmPushSet.length))throw T.create("bad-push-set")}var j,R=(e(L,j=K),L.prototype.onDbUpgrade=function(e){e.result.createObjectStore(this.objectStoreName,{keyPath:"swScope"})},L.prototype.getVapidFromSWScope=function(n){return b(this,void 0,void 0,function(){var t;return v(this,function(e){switch(e.label){case 0:if("string"!=typeof n||0===n.length)throw T.create("bad-scope");return[4,this.get(n)];case 1:return[2,(t=e.sent())?t.vapidKey:void 0]}})})},L.prototype.saveVapidDetails=function(n,r){return b(this,void 0,void 0,function(){var t;return v(this,function(e){if("string"!=typeof n||0===n.length)throw T.create("bad-scope");if(null===r||65!==r.length)throw T.create("bad-vapid-key");return t={swScope:n,vapidKey:r},[2,this.put(t)]})})},L.prototype.deleteVapidDetails=function(n){return b(this,void 0,void 0,function(){var t;return v(this,function(e){switch(e.label){case 0:return[4,this.getVapidFromSWScope(n)];case 1:if(!(t=e.sent()))throw T.create("delete-scope-not-found");return[4,this.delete(n)];case 2:return e.sent(),[2,t]}})})},L);function L(){var e=null!==j&&j.apply(this,arguments)||this;return e.dbName="fcm_vapid_details_db",e.dbVersion=1,e.objectStoreName="fcm_vapid_object_Store",e}var H="messagingSenderId",B=(q.prototype.getToken=function(){return b(this,void 0,void 0,function(){var t,n,r,o,i;return v(this,function(e){switch(e.label){case 0:if("denied"===(t=this.getNotificationPermission_()))throw T.create("notifications-blocked");return"granted"!==t?[2,null]:[4,this.getSWRegistration_()];case 1:return n=e.sent(),[4,this.getPublicVapidKey_()];case 2:return r=e.sent(),[4,this.getPushSubscription(n,r)];case 3:return o=e.sent(),[4,this.tokenDetailsModel.getTokenDetailsFromSWScope(n.scope)];case 4:return(i=e.sent())?[2,this.manageExistingToken(n,o,r,i)]:[2,this.getNewToken(n,o,r)]}})})},q.prototype.manageExistingToken=function(t,n,r,o){return b(this,void 0,void 0,function(){return v(this,function(e){switch(e.label){case 0:return function(e,t,n){if(!n.vapidKey||!P(t.buffer,n.vapidKey.buffer))return!1;var r=e.endpoint===n.endpoint,o=P(e.getKey("auth"),n.auth),i=P(e.getKey("p256dh"),n.p256dh);return r&&o&&i}(n,r,o)?Date.now()<o.createTime+6048e5?[2,o.fcmToken]:[2,this.updateToken(t,n,r,o)]:[4,this.deleteTokenFromDB(o.fcmToken)];case 1:return e.sent(),[2,this.getNewToken(t,n,r)]}})})},q.prototype.updateToken=function(o,i,s,a){return b(this,void 0,void 0,function(){var t,n,r;return v(this,function(e){switch(e.label){case 0:return e.trys.push([0,4,,6]),[4,this.iidModel.updateToken(this.messagingSenderId,a.fcmToken,a.fcmPushSet,i,s)];case 1:return t=e.sent(),n={swScope:o.scope,vapidKey:s,fcmSenderId:this.messagingSenderId,fcmToken:t,fcmPushSet:a.fcmPushSet,createTime:Date.now(),endpoint:i.endpoint,auth:i.getKey("auth"),p256dh:i.getKey("p256dh")},[4,this.tokenDetailsModel.saveTokenDetails(n)];case 2:return e.sent(),[4,this.vapidDetailsModel.saveVapidDetails(o.scope,s)];case 3:return e.sent(),[2,t];case 4:return r=e.sent(),[4,this.deleteToken(a.fcmToken)];case 5:throw e.sent(),r;case 6:return[2]}})})},q.prototype.getNewToken=function(r,o,i){return b(this,void 0,void 0,function(){var t,n;return v(this,function(e){switch(e.label){case 0:return[4,this.iidModel.getToken(this.messagingSenderId,o,i)];case 1:return t=e.sent(),n={swScope:r.scope,vapidKey:i,fcmSenderId:this.messagingSenderId,fcmToken:t.token,fcmPushSet:t.pushSet,createTime:Date.now(),endpoint:o.endpoint,auth:o.getKey("auth"),p256dh:o.getKey("p256dh")},[4,this.tokenDetailsModel.saveTokenDetails(n)];case 2:return e.sent(),[4,this.vapidDetailsModel.saveVapidDetails(r.scope,i)];case 3:return e.sent(),[2,t.token]}})})},q.prototype.deleteToken=function(r){return b(this,void 0,void 0,function(){var t,n;return v(this,function(e){switch(e.label){case 0:return[4,this.deleteTokenFromDB(r)];case 1:return e.sent(),[4,this.getSWRegistration_()];case 2:return(t=e.sent())?[4,t.pushManager.getSubscription()]:[3,4];case 3:if(n=e.sent())return[2,n.unsubscribe()];e.label=4;case 4:return[2,!0]}})})},q.prototype.deleteTokenFromDB=function(n){return b(this,void 0,void 0,function(){var t;return v(this,function(e){switch(e.label){case 0:return[4,this.tokenDetailsModel.deleteToken(n)];case 1:return t=e.sent(),[4,this.iidModel.deleteToken(t.fcmSenderId,t.fcmToken,t.fcmPushSet)];case 2:return e.sent(),[2]}})})},q.prototype.getPushSubscription=function(t,n){return t.pushManager.getSubscription().then(function(e){return e||t.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:n})})},q.prototype.requestPermission=function(){throw T.create("only-available-in-window")},q.prototype.useServiceWorker=function(e){throw T.create("only-available-in-window")},q.prototype.usePublicVapidKey=function(e){throw T.create("only-available-in-window")},q.prototype.onMessage=function(e,t,n){throw T.create("only-available-in-window")},q.prototype.onTokenRefresh=function(e,t,n){throw T.create("only-available-in-window")},q.prototype.setBackgroundMessageHandler=function(e){throw T.create("only-available-in-sw")},q.prototype.delete=function(){return b(this,void 0,void 0,function(){return v(this,function(e){switch(e.label){case 0:return[4,Promise.all([this.tokenDetailsModel.closeDatabase(),this.vapidDetailsModel.closeDatabase()])];case 1:return e.sent(),[2]}})})},q.prototype.getNotificationPermission_=function(){return Notification.permission},q.prototype.getTokenDetailsModel=function(){return this.tokenDetailsModel},q.prototype.getVapidDetailsModel=function(){return this.vapidDetailsModel},q.prototype.getIidModel=function(){return this.iidModel},q);function q(e){var t=this;if(!e.options[H]||"string"!=typeof e.options[H])throw T.create("bad-sender-id");this.messagingSenderId=e.options[H],this.tokenDetailsModel=new F,this.vapidDetailsModel=new R,this.iidModel=new I,this.app=e,this.INTERNAL={delete:function(){return t.delete()}}}var G,z="FCM_MSG",$=(e(Y,G=B),Y.prototype.onPush=function(e){e.waitUntil(this.onPush_(e))},Y.prototype.onSubChange=function(e){e.waitUntil(this.onSubChange_(e))},Y.prototype.onNotificationClick=function(e){e.waitUntil(this.onNotificationClick_(e))},Y.prototype.onPush_=function(a){return b(this,void 0,void 0,function(){var t,n,r,o,i,s;return v(this,function(e){switch(e.label){case 0:if(!a.data)return[2];try{t=a.data.json()}catch(e){return[2]}return[4,this.hasVisibleClients_()];case 1:return e.sent()?[2,this.sendMessageToWindowClients_(t)]:(n=this.getNotificationData_(t))?(r=n.title||"",[4,this.getSWRegistration_()]):[3,3];case 2:return o=e.sent(),i=n.actions,s=Notification.maxActions,i&&s&&i.length>s&&console.warn("This browser only supports "+s+" actions.The remaining actions will not be displayed."),[2,o.showNotification(r,n)];case 3:return this.bgMessageHandler?[4,this.bgMessageHandler(t)]:[3,5];case 4:return e.sent(),[2];case 5:return[2]}})})},Y.prototype.onSubChange_=function(e){return b(this,void 0,void 0,function(){var t,n,r,o;return v(this,function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),[4,this.getSWRegistration_()];case 1:return t=e.sent(),[3,3];case 2:throw n=e.sent(),T.create("unable-to-resubscribe",{errorInfo:n});case 3:return e.trys.push([3,5,,8]),[4,t.pushManager.getSubscription()];case 4:return e.sent(),[3,8];case 5:return r=e.sent(),[4,this.getTokenDetailsModel().getTokenDetailsFromSWScope(t.scope)];case 6:if(!(o=e.sent()))throw r;return[4,this.deleteToken(o.fcmToken)];case 7:throw e.sent(),r;case 8:return[2]}})})},Y.prototype.onNotificationClick_=function(i){return b(this,void 0,void 0,function(){var t,n,r,o;return v(this,function(e){switch(e.label){case 0:return i.notification&&i.notification.data&&i.notification.data[z]?i.action?[2]:(i.stopImmediatePropagation(),i.notification.close(),(t=i.notification.data[z]).notification&&(n=t.fcmOptions&&t.fcmOptions.link||t.notification.click_action)?[4,this.getWindowClient_(n)]:[2]):[2];case 1:return(r=e.sent())?[3,3]:[4,self.clients.openWindow(n)];case 2:return r=e.sent(),[3,5];case 3:return[4,r.focus()];case 4:r=e.sent(),e.label=5;case 5:return r?(delete t.notification,delete t.fcmOptions,o=Q(w.NOTIFICATION_CLICKED,t),[2,this.attemptToMessageClient_(r,o)]):[2]}})})},Y.prototype.getNotificationData_=function(e){var t;if(e&&"object"==typeof e.notification){var n=i({},e.notification);return n.data=i({},e.notification.data,((t={})[z]=e,t)),n}},Y.prototype.setBackgroundMessageHandler=function(e){if(!e||"function"!=typeof e)throw T.create("bg-handler-function-expected");this.bgMessageHandler=e},Y.prototype.getWindowClient_=function(i){return b(this,void 0,void 0,function(){var t,n,r,o;return v(this,function(e){switch(e.label){case 0:return t=new URL(i,self.location.href).href,[4,J()];case 1:for(n=e.sent(),r=null,o=0;o<n.length;o++)if(new URL(n[o].url,self.location.href).href===t){r=n[o];break}return[2,r]}})})},Y.prototype.attemptToMessageClient_=function(t,n){return b(this,void 0,void 0,function(){return v(this,function(e){if(!t)throw T.create("no-window-client-to-msg");return t.postMessage(n),[2]})})},Y.prototype.hasVisibleClients_=function(){return b(this,void 0,void 0,function(){return v(this,function(e){switch(e.label){case 0:return[4,J()];case 1:return[2,e.sent().some(function(e){return"visible"===e.visibilityState&&!e.url.startsWith("chrome-extension://")})]}})})},Y.prototype.sendMessageToWindowClients_=function(o){return b(this,void 0,void 0,function(){var t,n,r=this;return v(this,function(e){switch(e.label){case 0:return[4,J()];case 1:return t=e.sent(),n=Q(w.PUSH_MSG_RECEIVED,o),[4,Promise.all(t.map(function(e){return r.attemptToMessageClient_(e,n)}))];case 2:return e.sent(),[2]}})})},Y.prototype.getSWRegistration_=function(){return b(this,void 0,void 0,function(){return v(this,function(e){return[2,self.registration]})})},Y.prototype.getPublicVapidKey_=function(){return b(this,void 0,void 0,function(){var t,n;return v(this,function(e){switch(e.label){case 0:return[4,this.getSWRegistration_()];case 1:if(!(t=e.sent()))throw T.create("sw-registration-expected");return[4,this.getVapidDetailsModel().getVapidFromSWScope(t.scope)];case 2:return null==(n=e.sent())?[2,S]:[2,n]}})})},Y);function Y(e){var t=G.call(this,e)||this;return t.bgMessageHandler=null,self.addEventListener("push",function(e){t.onPush(e)}),self.addEventListener("pushsubscriptionchange",function(e){t.onSubChange(e)}),self.addEventListener("notificationclick",function(e){t.onNotificationClick(e)}),t}function J(){return self.clients.matchAll({type:"window",includeUncontrolled:!0})}function Q(e,t){var n;return(n={})[g.TYPE_OF_MSG]=e,n[g.DATA]=t,n}var X,Z,ee=(e(te,X=B),te.prototype.getToken=function(){return b(this,void 0,void 0,function(){return v(this,function(e){switch(e.label){case 0:return this.manifestCheckPromise||(this.manifestCheckPromise=function(){return b(this,void 0,void 0,function(){var t,n;return v(this,function(e){switch(e.label){case 0:if(!(t=document.querySelector('link[rel="manifest"]')))return[2];e.label=1;case 1:return e.trys.push([1,4,,5]),[4,fetch(t.href)];case 2:return[4,e.sent().json()];case 3:return n=e.sent(),[3,5];case 4:return e.sent(),[2];case 5:if(!n||!n.gcm_sender_id)return[2];if("103953800507"!==n.gcm_sender_id)throw T.create("incorrect-gcm-sender-id");return[2]}})})}()),[4,this.manifestCheckPromise];case 1:return e.sent(),[2,X.prototype.getToken.call(this)]}})})},te.prototype.requestPermission=function(){return b(this,void 0,void 0,function(){var t;return v(this,function(e){switch(e.label){case 0:return"granted"===this.getNotificationPermission_()?[2]:[4,Notification.requestPermission()];case 1:if("granted"===(t=e.sent()))return[2];throw"denied"===t?T.create("permission-blocked"):T.create("permission-default")}})})},te.prototype.useServiceWorker=function(e){if(!(e instanceof ServiceWorkerRegistration))throw T.create("sw-registration-expected");if(null!=this.registrationToUse)throw T.create("use-sw-before-get-token");this.registrationToUse=e},te.prototype.usePublicVapidKey=function(e){if("string"!=typeof e)throw T.create("invalid-public-vapid-key");if(null!=this.publicVapidKeyToUse)throw T.create("use-public-key-before-get-token");var t=O(e);if(65!==t.length)throw T.create("public-vapid-key-decryption-failed");this.publicVapidKeyToUse=t},te.prototype.onMessage=function(e,t,n){return"function"==typeof e?this.onMessageInternal(e,t,n):this.onMessageInternal(e)},te.prototype.onTokenRefresh=function(e,t,n){return"function"==typeof e?this.onTokenRefreshInternal(e,t,n):this.onTokenRefreshInternal(e)},te.prototype.waitForRegistrationToActivate_=function(r){var o=r.installing||r.waiting||r.active;return new Promise(function(e,t){if(o)if("activated"!==o.state)if("redundant"!==o.state){var n=function(){if("activated"===o.state)e(r);else{if("redundant"!==o.state)return;t(T.create("sw-reg-redundant"))}o.removeEventListener("statechange",n)};o.addEventListener("statechange",n)}else t(T.create("sw-reg-redundant"));else e(r);else t(T.create("no-sw-in-reg"))})},te.prototype.getSWRegistration_=function(){var t=this;return this.registrationToUse?this.waitForRegistrationToActivate_(this.registrationToUse):(this.registrationToUse=null,navigator.serviceWorker.register("/firebase-messaging-sw.js",{scope:"/firebase-cloud-messaging-push-scope"}).catch(function(e){throw T.create("failed-serviceworker-registration",{browserErrorMessage:e.message})}).then(function(e){return t.waitForRegistrationToActivate_(e).then(function(){return(t.registrationToUse=e).update(),e})}))},te.prototype.getPublicVapidKey_=function(){return b(this,void 0,void 0,function(){return v(this,function(e){return this.publicVapidKeyToUse?[2,this.publicVapidKeyToUse]:[2,S]})})},te.prototype.setupSWMessageListener_=function(){var r=this;navigator.serviceWorker.addEventListener("message",function(e){if(e.data&&e.data[g.TYPE_OF_MSG]){var t=e.data;switch(t[g.TYPE_OF_MSG]){case w.PUSH_MSG_RECEIVED:case w.NOTIFICATION_CLICKED:var n=t[g.DATA];r.messageObserver&&r.messageObserver.next(n)}}},!1)},te);function te(e){var t=X.call(this,e)||this;return t.registrationToUse=null,t.publicVapidKeyToUse=null,t.manifestCheckPromise=null,t.messageObserver=null,t.tokenRefreshObserver=null,t.onMessageInternal=c(function(e){t.messageObserver=e}),t.onTokenRefreshInternal=c(function(e){t.tokenRefreshObserver=e}),t.setupSWMessageListener_(),t}function ne(){return self&&"ServiceWorkerGlobalScope"in self?"PushManager"in self&&"Notification"in self&&ServiceWorkerRegistration.prototype.hasOwnProperty("showNotification")&&PushSubscription.prototype.hasOwnProperty("getKey"):navigator.cookieEnabled&&"serviceWorker"in navigator&&"PushManager"in window&&"Notification"in window&&"fetch"in window&&ServiceWorkerRegistration.prototype.hasOwnProperty("showNotification")&&PushSubscription.prototype.hasOwnProperty("getKey")}Z={isSupported:ne},re.INTERNAL.registerService("messaging",function(e){if(!ne())throw T.create("unsupported-browser");return self&&"ServiceWorkerGlobalScope"in self?new $(e):new ee(e)},Z)}).apply(this,arguments)}catch(e){throw console.error(e),new Error("Cannot instantiate firebase-messaging - be sure to load firebase-app.js first.")}});;

/* /social_push_notifications/static/src/js/push_notification_request_popup.js */
odoo.define('@social_push_notifications/js/push_notification_request_popup',['@web/legacy/js/core/widget'],function(require){'use strict';let __exports={};const Widget=require("@web/legacy/js/core/widget")[Symbol.for("default")];var NotificationRequestPopup=Widget.extend({template:'social_push_notifications.NotificationRequestPopup',events:{'click .o_social_push_notifications_permission_allow':'_onClickAllow','click .o_social_push_notifications_permission_deny':'_onClickDeny'},init:function(parent,options){this._super.apply(this,arguments);this.notificationTitle=options.title;this.notificationBody=options.body;this.notificationDelay=options.delay;this.notificationIcon=options.icon;},start:function(){var self=this;return this._super.apply().then(function(){var $mainNavBar=$('#oe_main_menu_navbar');if($mainNavBar&&$mainNavBar.length!==0){self.$el.addClass('o_social_push_notifications_permission_with_menubar');}
self.timer=setTimeout(self._toggleDropdown.bind(self),self.notificationDelay*1000);const dropdown=self.$el.find('.dropdown');dropdown.on('hide.bs.dropdown',()=>{self.destroy();});});},destroy:function(){this._super(...arguments);if(this.timer){clearTimeout(this.timer);}},_onClickAllow:function(){this.trigger_up('allow');},_onClickDeny:function(){this.trigger_up('deny');},_toggleDropdown:function(){this.$('.dropdown-toggle').dropdown('toggle');}});__exports[Symbol.for("default")]=NotificationRequestPopup;return __exports;});;

/* /social_push_notifications/static/src/js/push_notification_widget.js */
odoo.define('@social_push_notifications/js/push_notification_widget',['@web/legacy/js/public/public_widget','@web/core/browser/browser','@social_push_notifications/js/push_notification_request_popup','@odoo/owl'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{browser}=require("@web/core/browser/browser");const NotificationRequestPopup=require("@social_push_notifications/js/push_notification_request_popup")[Symbol.for("default")];const{Component}=require("@odoo/owl");publicWidget.registry.NotificationWidget=publicWidget.Widget.extend({selector:'#wrapwrap',init(){this._super(...arguments);this.rpc=this.bindService("rpc");this.notification=this.bindService("notification");},start:function(){var self=this;var superPromise=this._super.apply(this,arguments);if(!this._isBrowserCompatible()){return superPromise;}
if(Notification.permission==="granted"){const{pushConfigurationPromise,wasUpdated}=this._getNotificationRequestConfiguration();pushConfigurationPromise.then((pushConfiguration)=>{if(Object.keys(pushConfiguration).length===1){return superPromise;}
const messaging=self._initializeFirebaseApp(pushConfiguration);if(wasUpdated){self._registerServiceWorker(pushConfiguration,messaging);}
self._setForegroundNotificationHandler(pushConfiguration,messaging);});}else if(Notification.permission!=="denied"){this._askPermission();}
Component.env.bus.addEventListener('open_notification_request',(ev)=>this._onNotificationRequest(...ev.detail));return superPromise;},_setForegroundNotificationHandler:function(config,messaging){const onMessage=(payload)=>{if(window.Notification&&Notification.permission==="granted"){const notificationData=payload.data;const options={title:notificationData.title,type:'success',};const targetUrl=notificationData.target_url;if(targetUrl){options.buttons=[{name:'Open',onClick:()=>window.open(targetUrl,'_blank'),}];}
this.notification.add(notificationData.body,options);}};messaging=messaging||this._initializeFirebaseApp(config);if(!messaging){return;}
messaging.onMessage(onMessage);},_isBrowserCompatible:function(){if(!('serviceWorker'in navigator)){return false;}
if(!('PushManager'in window)){return false;}
return true;},_initializeFirebaseApp:function(config){if(!config.firebase_push_certificate_key||!config.firebase_project_id||!config.firebase_web_api_key){return null;}
firebase.initializeApp({apiKey:config.firebase_web_api_key,projectId:config.firebase_project_id,messagingSenderId:config.firebase_sender_id});var messaging=firebase.messaging();return messaging;},_registerServiceWorker:function(config,messaging){const self=this;messaging=messaging||this._initializeFirebaseApp(config);if(!messaging){return;}
var baseWorkerUrl='/social_push_notifications/static/src/js/push_service_worker.js';navigator.serviceWorker.register(baseWorkerUrl+'?senderId='+encodeURIComponent(config.firebase_sender_id)).then(function(registration){messaging.useServiceWorker(registration);messaging.usePublicVapidKey(config.firebase_push_certificate_key);messaging.getToken().then(function(token){self._registerToken(token);});});},_isConfigurationUpToDate:function(pushConfiguration){if(pushConfiguration){if(new Date()<new Date(pushConfiguration.expirationDate)){return true;}}
return false;},_fetchPushConfiguration:function(){return this.rpc('/social_push_notifications/fetch_push_configuration').then(function(config){const expirationDate=new Date();expirationDate.setDate(expirationDate.getDate()+7);Object.assign(config,{'expirationDate':expirationDate});browser.localStorage.setItem('social_push_notifications.notification_request_config',JSON.stringify(config));return config;});},_registerToken:function(token){this;var pushConfiguration=this._getPushConfiguration();if(pushConfiguration&&pushConfiguration.token!==token){this.rpc('/social_push_notifications/unregister',{token:pushConfiguration.token});}
this.rpc('/social_push_notifications/register',{token:token}).then(function(){browser.localStorage.setItem('social_push_notifications.configuration',JSON.stringify({'token':token,}));});},_askPermission:async function(nextAskPermissionKeySuffix,forcedPopupConfig){var self=this;var nextAskPermission=browser.localStorage.getItem('social_push_notifications.next_ask_permission'+
(nextAskPermissionKeySuffix?'.'+nextAskPermissionKeySuffix:''));if(nextAskPermission&&new Date()<new Date(nextAskPermission)){return;}
const{pushConfigurationPromise}=this._getNotificationRequestConfiguration();const pushConfiguration=await pushConfigurationPromise;if(Object.keys(pushConfiguration).length===1){return;}
let popupConfig={title:pushConfiguration.notification_request_title,body:pushConfiguration.notification_request_body,delay:pushConfiguration.notification_request_delay,icon:pushConfiguration.notification_request_icon};if(!popupConfig||!popupConfig.title||!popupConfig.body){return;}
if(forcedPopupConfig){popupConfig=Object.assign({},popupConfig,forcedPopupConfig);}
self._showNotificationRequestPopup(popupConfig,pushConfiguration,nextAskPermissionKeySuffix);},_showNotificationRequestPopup:function(popupConfig,pushConfig,nextAskPermissionKeySuffix){var selector='.o_social_push_notifications_permission_request';if(!popupConfig.title||!popupConfig.body||this.$el.find(selector).length>0){return;}
var self=this;var notificationRequestPopup=new NotificationRequestPopup(this,{title:popupConfig.title,body:popupConfig.body,delay:popupConfig.delay,icon:popupConfig.icon});notificationRequestPopup.appendTo(this.$el);notificationRequestPopup.on('allow',null,function(){Notification.requestPermission().then(function(){if(Notification.permission==="granted"){const messaging=self._initializeFirebaseApp(pushConfig);self._registerServiceWorker(pushConfig,messaging);self._setForegroundNotificationHandler(pushConfig,messaging);}});});notificationRequestPopup.on('deny',null,function(){var nextAskPermissionDate=new Date();nextAskPermissionDate.setDate(nextAskPermissionDate.getDate()+7);browser.localStorage.setItem('social_push_notifications.next_ask_permission'+
(nextAskPermissionKeySuffix?'.'+nextAskPermissionKeySuffix:''),nextAskPermissionDate);});},_getPushConfiguration:function(){return this._getJSONLocalStorageItem('social_push_notifications.configuration');},_getNotificationRequestConfiguration:function(){const pushConfiguration=this._getJSONLocalStorageItem('social_push_notifications.notification_request_config');const wasUpdated=!this._isConfigurationUpToDate(pushConfiguration);const pushConfigurationPromise=wasUpdated?this._fetchPushConfiguration():Promise.resolve(pushConfiguration);return{pushConfigurationPromise,wasUpdated};},_getJSONLocalStorageItem:function(key){var value=browser.localStorage.getItem(key);if(value){return JSON.parse(value);}
return null;},_onNotificationRequest:async function(nextAskPermissionKeySuffix,forcedPopupConfig){if(Notification.permission!=='default'){return;}
this._askPermission(nextAskPermissionKeySuffix,forcedPopupConfig);},});__exports[Symbol.for("default")]=publicWidget.registry.NotificationWidget;return __exports;});;

/* /website_knowledge/static/src/js/knowledge_public.js */
odoo.define('@website_knowledge/js/knowledge_public',['@knowledge/js/knowledge_utils','@knowledge/js/tools/knowledge_tools','@web/legacy/js/public/public_widget','@web/core/utils/render','@web/core/utils/timing','@web/core/registry','@web/core/file_viewer/file_viewer','@web/core/file_viewer/file_model','@web/core/utils/functions'],function(require){'use strict';let __exports={};const{decodeDataBehaviorProps,getVideoUrl}=require("@knowledge/js/knowledge_utils");const{fetchValidHeadings}=require('@knowledge/js/tools/knowledge_tools');const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const{renderToElement}=require("@web/core/utils/render");const{debounce,throttleForAnimation}=require("@web/core/utils/timing");const{registry}=require("@web/core/registry");const{FileViewer}=require("@web/core/file_viewer/file_viewer");const{FileModel}=require("@web/core/file_viewer/file_model");const{uniqueId}=require("@web/core/utils/functions");publicWidget.registry.KnowledgeWidget=publicWidget.Widget.extend({selector:'.o_knowledge_public_view',events:{'keyup .knowledge_search_bar':'_searchArticles','click .o_article_caret':'_onFold','click .o_knowledge_toc_link':'_onTocLinkClick','click .o_knowledge_article_load_more':'_loadMoreArticles','click .o_knowledge_file_image a.o_image':'onFileImageClick','click .o_knowledge_behavior_type_file button[name="download"]':'onFileDownloadClick',},init(){this._super(...arguments);this.rpc=this.bindService("rpc");},start:function(){return this._super.apply(this,arguments).then(()=>{this.$id=this.$el.data('article-id');this.storageKey="knowledge.unfolded.ids";this.unfoldedArticlesIds=localStorage.getItem(this.storageKey)?.split(";").map(Number)||[];this._renderTree();this.renderViewLinks();this._setResizeListener();this._searchArticles=debounce(this._searchArticles,500);this.renderEmbeddedViews();this.renderVideoIframes();this.renderFileDownloadButtons();});},_loadMoreArticles:async function(ev){ev.preventDefault();let addedArticles;const rpcParams={active_article_id:this.$id||false,parent_id:ev.target.dataset['parentId']||false,limit:ev.target.dataset['limit'],offset:ev.target.dataset['offset']||0,};addedArticles=await this.rpc('/knowledge/public_sidebar/load_more',rpcParams);const listRoot=ev.target.closest('ul');ev.target.remove();const forcedDisplayedActiveArticle=listRoot.querySelector('.o_knowledge_article_force_show_active_article');if(forcedDisplayedActiveArticle){forcedDisplayedActiveArticle.remove();}
listRoot.insertAdjacentHTML('beforeend',addedArticles);},_searchArticles:async function(ev){ev.preventDefault();const searchTerm=this.$('.knowledge_search_bar').val();if(!searchTerm){await this._renderTree();return;}
const container=this.el.querySelector('.o_knowledge_tree');try{const htmlTree=await this.rpc('/knowledge/public_sidebar/',{search_term:searchTerm,active_article_id:this.$id,});container.innerHTML=htmlTree;}catch{container.innerHTML="";}},_setResizeListener:function(){const onPointerMove=throttleForAnimation(event=>{event.preventDefault();this.el.style.setProperty('--knowledge-article-sidebar-size',`${event.pageX}px`);},100);const onPointerUp=()=>{this.el.removeEventListener('pointermove',onPointerMove);document.body.style.cursor="auto";document.body.style.userSelect="auto";};const resizeSidebar=()=>{document.body.style.cursor="col-resize";document.body.style.userSelect="none";this.el.addEventListener('pointermove',onPointerMove);this.el.addEventListener('pointerup',onPointerUp,{once:true});};this.el.querySelector('.o_knowledge_article_form_resizer span').addEventListener('pointerdown',resizeSidebar);},renderEmbeddedViews:function(){for(const embeddedView of this.el.querySelectorAll('.o_knowledge_behavior_type_embedded_view')){const placeholder=renderToElement('website_knowledge.embedded_view_placeholder',{url:`/knowledge/article/${this.$id}`,});embeddedView.replaceChildren(placeholder);}},renderFileDownloadButtons:function(){for(const toolbar of this.el.querySelectorAll(".o_knowledge_behavior_type_file .o_knowledge_toolbar")){const toolbarContent=renderToElement('website_knowledge.file_behavior_toolbar_content',{});toolbar.replaceChildren(toolbarContent);}},_renderTree:async function(){const container=this.el.querySelector('.o_knowledge_tree');const params=new URLSearchParams(document.location.search);if(Boolean(params.get('auto_unfold'))){this.unfoldedArticlesIds.push(this.$id);}
try{const htmlTree=await this.rpc('/knowledge/public_sidebar',{active_article_id:this.$id,unfolded_articles_ids:this.unfoldedArticlesIds,});container.innerHTML=htmlTree;}catch{container.innerHTML="";}},renderVideoIframes:function(){for(const anchor of this.el.querySelectorAll(".o_knowledge_behavior_type_video")){const props=decodeDataBehaviorProps(anchor.dataset.behaviorProps);const url=getVideoUrl(props.platform,props.videoId,props.params);const iframe=document.createElement("iframe");iframe.src=url.toString();iframe.frameborder="0";iframe.allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share";anchor.replaceChildren();anchor.append(iframe);}},renderViewLinks(){for(const viewLink of this.el.getElementsByClassName("o_knowledge_view_link")){const link=document.createElement("A");link.classList.add("text-o-color-1");link.href=`/web/login?redirect=/knowledge/article/${this.$id}`;link.textContent=decodeDataBehaviorProps(viewLink.dataset.behaviorProps).name;viewLink.replaceWith(link);}},_fetchChildrenArticles:function(parentId){return this.rpc('/knowledge/public_sidebar/children',{parent_id:parentId});},_onFold:async function(event){event.stopPropagation();const $button=$(event.currentTarget);this._fold($button);},_fold:async function($button){const $icon=$button.find('i');const $li=$button.closest('li');const articleId=$li.data('articleId');const $ul=$li.find('> ul');if($icon.hasClass('fa-caret-down')){$ul.hide();if(this.unfoldedArticlesIds.indexOf(articleId)!==-1){this.unfoldedArticlesIds.splice(this.unfoldedArticlesIds.indexOf(articleId),1);}
$icon.removeClass('fa-caret-down');$icon.addClass('fa-caret-right');}else{if($ul.length){$ul.show();}else{let children;try{children=await this._fetchChildrenArticles($li.data('articleId'));}catch(error){$li.remove();throw error;}
const $newUl=$('<ul/>').append(children);$li.append($newUl);}
if(this.unfoldedArticlesIds.indexOf(articleId)===-1){this.unfoldedArticlesIds.push(articleId);}
$icon.removeClass('fa-caret-right');$icon.addClass('fa-caret-down');}
localStorage.setItem(this.storageKey,this.unfoldedArticlesIds.join(";"),);},onFileDownloadClick:function(event){event.preventDefault();event.stopPropagation();const behaviorAnchor=event.target.closest(".o_knowledge_behavior_type_file");const link=behaviorAnchor.querySelector(".o_knowledge_file_image a.o_image");if(!link?.href){return;}
window.open(link.href,"_blank");},onFileImageClick:function(event){event.preventDefault();event.stopPropagation();if(!event.target?.href){return;}
const viewerId=uniqueId('web.file_viewer');const behaviorAnchor=event.target.closest(".o_knowledge_behavior_type_file");const props=decodeDataBehaviorProps(behaviorAnchor.dataset.behaviorProps);const fileModel=Object.assign(new FileModel(),props.fileData);if(fileModel.isViewable){registry.category("main_components").add(viewerId,{Component:FileViewer,props:{files:[fileModel],startIndex:0,close:()=>{registry.category('main_components').remove(viewerId);},},});}},_onTocLinkClick:function(event){event.preventDefault();const headingIndex=parseInt(event.target.getAttribute('data-oe-nodeid'));const targetHeading=fetchValidHeadings(this.$el[0])[headingIndex];if(targetHeading){targetHeading.scrollIntoView({behavior:'smooth',});targetHeading.classList.add('o_knowledge_header_highlight');setTimeout(()=>{targetHeading.classList.remove('o_knowledge_header_highlight');},2000);}},});return __exports;});;

/* /website_links/static/src/js/website_links.js */
odoo.define('@website_links/js/website_links',['@web/core/l10n/translation','@web/legacy/js/public/public_widget','@web/core/browser/browser','@web/core/utils/concurrency'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{browser}=require("@web/core/browser/browser");const{KeepLast}=require("@web/core/utils/concurrency");var SelectBox=publicWidget.Widget.extend({events:{'change':'_onChange',},init:function(parent,obj,placeholder){this._super.apply(this,arguments);this.obj=obj;this.placeholder=placeholder;this.orm=this.bindService("orm");this.keepLast=new KeepLast();this.objects=[];},start:function(){var self=this;this.$el.select2({placeholder:self.placeholder,allowClear:true,formatNoMatches:false,createSearchChoice:function(term){if(self._objectExists(term)){return null;}
return{id:term,text:`Create '${term}'`};},createSearchChoicePosition:'bottom',multiple:false,ajax:{dataType:'json',data:term=>term,transport:(params,success,failure)=>{clearTimeout(this._loadDataTimeout);this._loadDataTimeout=setTimeout(()=>{const limit=100;const searchReadParams=[['id','name'],{limit:limit,order:'name, id desc',},];const proms=[];proms.push(this.orm.searchRead(this.obj,[['name','=ilike',`${params.data}%`]],...searchReadParams));proms.push(this.orm.searchRead(this.obj,[['name','=ilike',`%_${params.data}%`]],...searchReadParams));this.keepLast.add(Promise.all(proms)).then(([startingMatches,endingMatches])=>{if(startingMatches.length<limit){const startingMatchesId=startingMatches.map((value)=>value.id);const extraEndingMatches=endingMatches.filter((value)=>!startingMatchesId.includes(value.id));return startingMatches.concat(extraEndingMatches);}
return startingMatches;}).then(params.success).catch(params.error);},400);},results:data=>{this.objects=data.map(x=>({id:x.id,text:x.name,}));return{results:this.objects,};},},});},_objectExists:function(query){return this.objects.find(val=>val.text.toLowerCase()===query.toLowerCase())!==undefined;},_createObject:function(name){var args={name:name};if(this.obj==="utm.campaign"){args.is_auto_campaign=true;}
return this.orm.create(this.obj,[args]).then(record=>{this.$el.attr('value',record);});},_onChange:function(ev){if(!ev.added||typeof ev.added.id!=="string"){return;}
this._createObject(ev.added.id);},});var RecentLinkBox=publicWidget.Widget.extend({template:'website_links.RecentLink',events:{'click .btn_shorten_url_clipboard':'_toggleCopyButton','click .o_website_links_edit_code':'_editCode','click .o_website_links_ok_edit':'_onLinksOkClick','click .o_website_links_cancel_edit':'_onLinksCancelClick','submit #o_website_links_edit_code_form':'_onSubmitCode',},init:function(parent,obj){this._super.apply(this,arguments);this.link_obj=obj;this.animating_copy=false;this.rpc=this.bindService("rpc");},_toggleCopyButton:async function(){await browser.navigator.clipboard.writeText(this.link_obj.short_url);if(this.animating_copy){return;}
var self=this;this.animating_copy=true;var top=this.$('.o_website_links_short_url').position().top;this.$('.o_website_links_short_url').clone().css('position','absolute').css('left',15).css('top',top-2).css('z-index',2).removeClass('o_website_links_short_url').addClass('animated-link').insertAfter(this.$('.o_website_links_short_url')).animate({opacity:0,top:'-=20',},500,function(){self.$('.animated-link').remove();self.animating_copy=false;});},_notification:function(message){this.$('.notification').append('<strong>'+message+'</strong>');},_editCode:function(){var initCode=this.$('#o_website_links_code').html();this.$('#o_website_links_code').html('<form style="display:inline;" id="o_website_links_edit_code_form"><input type="hidden" id="init_code" value="'+initCode+'"/><input type="text" id="new_code" value="'+initCode+'"/></form>');this.$('.o_website_links_edit_code').hide();this.$('.copy-to-clipboard').hide();this.$('.o_website_links_edit_tools').show();},_cancelEdit:function(){this.$('.o_website_links_edit_code').show();this.$('.copy-to-clipboard').show();this.$('.o_website_links_edit_tools').hide();this.$('.o_website_links_code_error').hide();var oldCode=this.$('#o_website_links_edit_code_form #init_code').val();this.$('#o_website_links_code').html(oldCode);this.$('#code-error').remove();this.$('#o_website_links_code form').remove();},_submitCode:function(){var self=this;var initCode=this.$('#o_website_links_edit_code_form #init_code').val();var newCode=this.$('#o_website_links_edit_code_form #new_code').val();if(newCode===''){self.$('.o_website_links_code_error').html(_t("The code cannot be left empty"));self.$('.o_website_links_code_error').show();return;}
function showNewCode(newCode){self.$('.o_website_links_code_error').html('');self.$('.o_website_links_code_error').hide();self.$('#o_website_links_code form').remove();var host=self.$('#o_website_links_host').html();self.$('#o_website_links_code').html(newCode);self.$('.btn_shorten_url_clipboard').attr('data-clipboard-text',host+newCode);self.$('.o_website_links_edit_code').show();self.$('.copy-to-clipboard').show();self.$('.o_website_links_edit_tools').hide();}
if(initCode===newCode){showNewCode(newCode);}else{this.rpc('/website_links/add_code',{init_code:initCode,new_code:newCode,}).then(function(result){showNewCode(result[0].code);},function(){self.$('.o_website_links_code_error').show();self.$('.o_website_links_code_error').html(_t("This code is already taken"));});}},_onLinksOkClick:function(ev){ev.preventDefault();this._submitCode();},_onLinksCancelClick:function(ev){ev.preventDefault();this._cancelEdit();},_onSubmitCode:function(ev){ev.preventDefault();this._submitCode();},});var RecentLinks=publicWidget.Widget.extend({init(){this._super(...arguments);this.rpc=this.bindService("rpc");},getRecentLinks:function(filter){var self=this;return this.rpc('/website_links/recent_links',{filter:filter,limit:20,}).then(function(result){result.reverse().forEach((link)=>{self._addLink(link);});self._updateNotification();},function(){var message=_t("Unable to get recent links");self.$el.append('<div class="alert alert-danger">'+message+'</div>');});},_addLink:function(link){var nbLinks=this.getChildren().length;var recentLinkBox=new RecentLinkBox(this,link);recentLinkBox.prependTo(this.$el);$('.link-tooltip').tooltip();if(nbLinks===0){this._updateNotification();}},removeLinks:function(){this.getChildren().forEach((child)=>{child.destroy();});},_updateNotification:function(){if(this.getChildren().length===0){var message=_t("You don't have any recent links.");$('.o_website_links_recent_links_notification').html('<div class="alert alert-info">'+message+'</div>');}else{$('.o_website_links_recent_links_notification').empty();}},});publicWidget.registry.websiteLinks=publicWidget.Widget.extend({selector:'.o_website_links_create_tracked_url',events:{'click #filter-newest-links':'_onFilterNewestLinksClick','click #filter-most-clicked-links':'_onFilterMostClickedLinksClick','click #filter-recently-used-links':'_onFilterRecentlyUsedLinksClick','click #generated_tracked_link a':'_onGeneratedTrackedLinkClick','keyup #url':'_onUrlKeyUp','click #btn_shorten_url':'_onShortenUrlButtonClick','submit #o_website_links_link_tracker_form':'_onFormSubmit',},init(){this._super(...arguments);this.rpc=this.bindService("rpc");},start:async function(){var defs=[this._super.apply(this,arguments)];const campaignSelect=new SelectBox(this,"utm.campaign",_t("e.g. June Sale, Paris Roadshow, ..."));defs.push(campaignSelect.attachTo($('#campaign-select')));const mediumSelect=new SelectBox(this,"utm.medium",_t("e.g. InMails, Ads, Social, ..."));defs.push(mediumSelect.attachTo($('#channel-select')));const sourceSelect=new SelectBox(this,"utm.source",_t("e.g. LinkedIn, Facebook, Leads, ..."));defs.push(sourceSelect.attachTo($('#source-select')));this.recentLinks=new RecentLinks(this);defs.push(this.recentLinks.appendTo($('#o_website_links_recent_links')));this.recentLinks.getRecentLinks('newest');this.url_copy_animating=false;$('[data-bs-toggle="tooltip"]').tooltip();return Promise.all(defs);},_onFilterNewestLinksClick:function(){this.recentLinks.removeLinks();this.recentLinks.getRecentLinks('newest');},_onFilterMostClickedLinksClick:function(){this.recentLinks.removeLinks();this.recentLinks.getRecentLinks('most-clicked');},_onFilterRecentlyUsedLinksClick:function(){this.recentLinks.removeLinks();this.recentLinks.getRecentLinks('recently-used');},_onGeneratedTrackedLinkClick:function(){$('#generated_tracked_link a').text(_t("Copied")).removeClass('btn-primary').addClass('btn-success');setTimeout(function(){$('#generated_tracked_link a').text(_t("Copy")).removeClass('btn-success').addClass('btn-primary');},5000);},_onUrlKeyUp:function(ev){if(!$('#btn_shorten_url').hasClass('btn-copy')||ev.key==="Enter"){return;}
$('#btn_shorten_url').removeClass('btn-success btn-copy').addClass('btn-primary').html('Get tracked link');$('#generated_tracked_link').css('display','none');$('.o_website_links_utm_forms').show();},_onShortenUrlButtonClick:async function(ev){const textValue=ev.target.dataset.clipboardText;await browser.navigator.clipboard.writeText(textValue);if(!$('#btn_shorten_url').hasClass('btn-copy')||this.url_copy_animating){return;}
var self=this;this.url_copy_animating=true;$('#generated_tracked_link').clone().css('position','absolute').css('left','78px').css('bottom','8px').css('z-index',2).removeClass('#generated_tracked_link').addClass('url-animated-link').appendTo($('#generated_tracked_link')).animate({opacity:0,bottom:'+=20',},500,function(){$('.url-animated-link').remove();self.url_copy_animating=false;});},_onFormSubmit:function(ev){var self=this;ev.preventDefault();if($('#btn_shorten_url').hasClass('btn-copy')){return;}
ev.stopPropagation();var campaignID=$('#campaign-select').attr('value');var mediumID=$('#channel-select').attr('value');var sourceID=$('#source-select').attr('value');var params={};params.url=$('#url').val();if(campaignID!==''){params.campaign_id=parseInt(campaignID);}
if(mediumID!==''){params.medium_id=parseInt(mediumID);}
if(sourceID!==''){params.source_id=parseInt(sourceID);}
$('#btn_shorten_url').text(_t("Generating link..."));this.rpc('/website_links/new',params).then(function(result){if('error'in result){if(result.error==='empty_url'){$('.notification').html('<div class="alert alert-danger">The URL is empty.</div>');}else if(result.error==='url_not_found'){$('.notification').html('<div class="alert alert-danger">URL not found (404)</div>');}else{$('.notification').html('<div class="alert alert-danger">An error occur while trying to generate your link. Try again later.</div>');}}else{var link=result[0];$('#btn_shorten_url').removeClass('btn-primary').addClass('btn-success btn-copy').html('Copy');$('#btn_shorten_url').attr('data-clipboard-text',link.short_url);$('.notification').html('');$('#generated_tracked_link').html(link.short_url);$('#generated_tracked_link').css('display','inline');self.recentLinks._addLink(link);$('#campaign-select').select2('val','');$('#channel-select').select2('val','');$('#source-select').select2('val','');$('.o_website_links_utm_forms').hide();}});},});__exports[Symbol.for("default")]={SelectBox:SelectBox,RecentLinkBox:RecentLinkBox,RecentLinks:RecentLinks,};return __exports;});;

/* /website_links/static/src/js/website_links_code_editor.js */
odoo.define('@website_links/js/website_links_code_editor',['@web/core/l10n/translation','@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.websiteLinksCodeEditor=publicWidget.Widget.extend({selector:'#wrapwrap:has(.o_website_links_edit_code)',events:{'click .o_website_links_edit_code':'_onEditCodeClick','click .o_website_links_cancel_edit':'_onCancelEditClick','submit #edit-code-form':'_onEditCodeFormSubmit','click .o_website_links_ok_edit':'_onEditCodeFormSubmit',},init(){this._super(...arguments);this.rpc=this.bindService("rpc");},_showNewCode:function(newCode){$('.o_website_links_code_error').html('');$('.o_website_links_code_error').hide();$('#o_website_links_code form').remove();var host=$('#short-url-host').html();$('#o_website_links_code').html(newCode);$('.copy-to-clipboard').attr('data-clipboard-text',host+newCode);$('.o_website_links_edit_code').show();$('.copy-to-clipboard').show();$('.o_website_links_edit_tools').hide();},_submitCode:function(){var initCode=$('#edit-code-form #init_code').val();var newCode=$('#edit-code-form #new_code').val();var self=this;if(newCode===''){self.$('.o_website_links_code_error').html(_t("The code cannot be left empty"));self.$('.o_website_links_code_error').show();return;}
this._showNewCode(newCode);if(initCode===newCode){this._showNewCode(newCode);}else{return this.rpc('/website_links/add_code',{init_code:initCode,new_code:newCode,}).then(function(result){self._showNewCode(result[0].code);},function(){$('.o_website_links_code_error').show();$('.o_website_links_code_error').html(_t("This code is already taken"));});}
return Promise.resolve();},_onEditCodeClick:function(){var initCode=$('#o_website_links_code').html();$('#o_website_links_code').html('<form style="display:inline;" id="edit-code-form"><input type="hidden" id="init_code" value="'+initCode+'"/><input type="text" id="new_code" value="'+initCode+'"/></form>');$('.o_website_links_edit_code').hide();$('.copy-to-clipboard').hide();$('.o_website_links_edit_tools').show();},_onCancelEditClick:function(ev){ev.preventDefault();$('.o_website_links_edit_code').show();$('.copy-to-clipboard').show();$('.o_website_links_edit_tools').hide();$('.o_website_links_code_error').hide();var oldCode=$('#edit-code-form #init_code').val();$('#o_website_links_code').html(oldCode);$('#code-error').remove();$('#o_website_links_code form').remove();},_onEditCodeFormSubmit:function(ev){ev.preventDefault();this._submitCode();},});return __exports;});;

/* /website_links/static/src/js/website_links_charts.js */
odoo.define('@website_links/js/website_links_charts',['@web/core/assets','@web/core/l10n/translation','@web/legacy/js/public/public_widget','@web/core/browser/browser'],function(require){'use strict';let __exports={};const{loadBundle}=require("@web/core/assets");const{_t}=require("@web/core/l10n/translation");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{browser}=require("@web/core/browser/browser");const{DateTime}=luxon;var BarChart=publicWidget.Widget.extend({init:function(parent,beginDate,endDate,dates){this._super.apply(this,arguments);this.beginDate=beginDate.startOf("day");this.endDate=endDate.startOf("day");if(this.beginDate.toISO()===this.endDate.toISO()){this.endDate=this.endDate.plus({days:1});}
this.number_of_days=this.endDate.diff(this.beginDate).as("days");this.dates=dates;},start:function(){var clicksArray=[];for(var i=0;i<=this.number_of_days;i++){var dateKey=this.beginDate.toFormat("yyyy-MM-dd");clicksArray.push([dateKey,(dateKey in this.dates)?this.dates[dateKey]:0]);this.beginDate=this.beginDate.plus({days:1});}
var nbClicks=0;var data=[];var labels=[];clicksArray.forEach(function(pt){labels.push(pt[0]);nbClicks+=pt[1];data.push(pt[1]);});this.$('.title').html(nbClicks+_t(' clicks'));var config={type:'line',data:{labels:labels,datasets:[{data:data,fill:'start',label:_t('# of clicks'),backgroundColor:'#ebf2f7',borderColor:'#6aa1ca',}],},};var canvas=this.$('canvas')[0];var context=canvas.getContext('2d');new Chart(context,config);},willStart:async function(){await loadBundle("web.chartjs_lib");},});var PieChart=publicWidget.Widget.extend({init:function(parent,data){this._super.apply(this,arguments);this.data=data;},start:function(){var labels=[];var data=[];for(var i=0;i<this.data.length;i++){var countryName=this.data[i]['country_id']?this.data[i]['country_id'][1]:_t('Undefined');labels.push(countryName+' ('+this.data[i]['country_id_count']+')');data.push(this.data[i]['country_id_count']);}
this.$('.title').html(this.data.length+_t(' countries'));var config={type:'pie',data:{labels:labels,datasets:[{data:data,label:this.data.length>0?this.data[0].key:_t('No data'),}]},options:{aspectRatio:2,},};var canvas=this.$('canvas')[0];var context=canvas.getContext('2d');new Chart(context,config);},willStart:async function(){await loadBundle("web.chartjs_lib");},});publicWidget.registry.websiteLinksCharts=publicWidget.Widget.extend({selector:'.o_website_links_chart',events:{'click .copy-to-clipboard':'_onCopyToClipboardClick',},init(){this._super(...arguments);this.orm=this.bindService("orm");},start:async function(){var self=this;this.charts={};var linkID=parseInt($('#link_id').val());this.links_domain=['link_id','=',linkID];var defs=[];defs.push(this._totalClicks());defs.push(this._clicksByDay());defs.push(this._clicksByCountry());defs.push(this._lastWeekClicksByCountry());defs.push(this._lastMonthClicksByCountry());defs.push(this._super.apply(this,arguments));this.animating_copy=false;return Promise.all(defs).then(function(results){var _totalClicks=results[0];var _clicksByDay=results[1];var _clicksByCountry=results[2];var _lastWeekClicksByCountry=results[3];var _lastMonthClicksByCountry=results[4];if(!_totalClicks){$('#all_time_charts').prepend(_t("There is no data to show"));$('#last_month_charts').prepend(_t("There is no data to show"));$('#last_week_charts').prepend(_t("There is no data to show"));return;}
var formattedClicksByDay={};var beginDate;for(var i=0;i<_clicksByDay.length;i++){const date=DateTime.fromFormat(_clicksByDay[i]["__domain"].find((el)=>el.length&&el.includes(">="))[2].split(" ")[0],"yyyy-MM-dd");if(i===0){beginDate=date;}
formattedClicksByDay[date.setLocale("en").toFormat("yyyy-MM-dd")]=_clicksByDay[i]["create_date_count"];}
var now=DateTime.now();self.charts.all_time_bar=new BarChart(self,beginDate,now,formattedClicksByDay);self.charts.all_time_bar.attachTo($('#all_time_clicks_chart'));beginDate=DateTime.now().minus({days:30});self.charts.last_month_bar=new BarChart(self,beginDate,now,formattedClicksByDay);self.charts.last_month_bar.attachTo($('#last_month_clicks_chart'));beginDate=DateTime.now().minus({days:7});self.charts.last_week_bar=new BarChart(self,beginDate,now,formattedClicksByDay);self.charts.last_week_bar.attachTo($('#last_week_clicks_chart'));self.charts.all_time_pie=new PieChart(self,_clicksByCountry);self.charts.all_time_pie.attachTo($('#all_time_countries_charts'));self.charts.last_month_pie=new PieChart(self,_lastMonthClicksByCountry);self.charts.last_month_pie.attachTo($('#last_month_countries_charts'));self.charts.last_week_pie=new PieChart(self,_lastWeekClicksByCountry);self.charts.last_week_pie.attachTo($('#last_week_countries_charts'));var rowWidth=$('#all_time_countries_charts').parent().width();var $chartCanvas=$('#all_time_countries_charts,last_month_countries_charts,last_week_countries_charts').find('canvas');$chartCanvas.height(Math.max(_clicksByCountry.length*(rowWidth>750?1:2),20)+'em');});},_totalClicks:function(){return this.orm.searchCount("link.tracker.click",[this.links_domain]);},_clicksByDay:function(){return this.orm.readGroup("link.tracker.click",[this.links_domain],["create_date"],["create_date:day"]);},_clicksByCountry:function(){return this.orm.readGroup("link.tracker.click",[this.links_domain],["country_id"],["country_id"]);},_lastWeekClicksByCountry:function(){const aWeekAgoDate=new Date(Date.now()-7*24*60*60*1000);const aWeekAgoString=aWeekAgoDate.toISOString().split("T")[0];return this.orm.readGroup("link.tracker.click",[this.links_domain,["create_date",">",aWeekAgoString]],["country_id"],["country_id"]);},_lastMonthClicksByCountry:function(){const aMonthAgoDate=new Date(Date.now()-30*24*60*60*1000);const aMonthAgoString=aMonthAgoDate.toISOString().split("T")[0];return this.orm.readGroup("link.tracker.click",[this.links_domain,["create_date",">",aMonthAgoString]],["country_id"],["country_id"]);},_onCopyToClipboardClick:async function(ev){ev.preventDefault();const textValue=ev.target.dataset.clipboardText;await browser.navigator.clipboard.writeText(textValue);if(this.animating_copy){return;}
this.animating_copy=true;$('.o_website_links_short_url').clone().css('position','absolute').css('left','15px').css('bottom','10px').css('z-index',2).removeClass('.o_website_links_short_url').addClass('animated-link').appendTo($('.o_website_links_short_url')).animate({opacity:0,bottom:'+=20',},500,function(){$('.animated-link').remove();this.animating_copy=false;});},});__exports[Symbol.for("default")]={BarChart:BarChart,PieChart:PieChart,};return __exports;});;

/* /website_mail_group/static/src/snippets/s_group/000.js */
odoo.define('@website_mail_group/snippets/s_group/000',['@web/core/l10n/translation','@web/legacy/js/public/public_widget','@mail_group/js/mail_group'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const MailGroup=require("@mail_group/js/mail_group")[Symbol.for("default")];MailGroup.include({start:async function(){await this._super(...arguments);const email=(new URL(document.location.href)).searchParams.get('email');const response=await this.rpc('/group/is_member',{'group_id':this.mailgroupId,'email':email,'token':this.token,});if(!response){this.$el.empty();return;}
this.$el.removeClass('d-none');const userEmail=response.email;this.isMember=response.is_member;if(userEmail&&userEmail.length){const emailInput=this.$el.find('.o_mg_subscribe_email');emailInput.val(userEmail);emailInput.attr('readonly',1);}
if(this.isMember){this.$el.find('.o_mg_subscribe_btn').text(_t('Unsubscribe')).removeClass('btn-primary').addClass('btn-outline-primary');}
this.$el.data('isMember',this.isMember);},destroy:function(){this.el.classList.add('d-none');this._super(...arguments);},});publicWidget.registry.MailGroupEditMode=publicWidget.Widget.extend({selector:MailGroup.prototype.selector,disabledInEditableMode:false,start:function(){if(this.editableMode){this.el.classList.remove('d-none');}
return this._super(...arguments);},destroy:function(){if(this.editableMode){this.el.classList.add('d-none');}
this._super(...arguments);},});return __exports;});;

/* /website_mass_mailing/static/src/js/website_mass_mailing.js */
odoo.define('@website_mass_mailing/js/website_mass_mailing',['@web/core/l10n/translation','@web/legacy/js/public/public_widget','@google_recaptcha/js/recaptcha'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{ReCaptcha}=require("@google_recaptcha/js/recaptcha");publicWidget.registry.subscribe=publicWidget.Widget.extend({selector:".js_subscribe",disabledInEditableMode:false,read_events:{'click .js_subscribe_btn':'_onSubscribeClick',},init:function(){this._super(...arguments);this._recaptcha=new ReCaptcha();this.rpc=this.bindService("rpc");this.notification=this.bindService("notification");},willStart:function(){this._recaptcha.loadLibs();return this._super(...arguments);},start:function(){var def=this._super.apply(this,arguments);if(this.editableMode){return def;}
const always=this._updateView.bind(this);const inputName=this.el.querySelector('input').name;return Promise.all([def,this.rpc('/website_mass_mailing/is_subscriber',{'list_id':this._getListId(),'subscription_type':inputName,}).then(always,always)]);},destroy(){this._updateView({is_subscriber:false});this._super.apply(this,arguments);},_updateView(data){const isSubscriber=data.is_subscriber;const subscribeBtnEl=this.el.querySelector('.js_subscribe_btn');const thanksBtnEl=this.el.querySelector('.js_subscribed_btn');const valueInputEl=this.el.querySelector('input.js_subscribe_value, input.js_subscribe_email');subscribeBtnEl.disabled=isSubscriber;valueInputEl.value=data.value||'';valueInputEl.disabled=isSubscriber;this.el.classList.remove('d-none');subscribeBtnEl.classList.toggle('d-none',!!isSubscriber);thanksBtnEl.classList.toggle('d-none',!isSubscriber);},_getListId:function(){return this.$el.closest('[data-snippet=s_newsletter_block').data('list-id')||this.$el.data('list-id');},_onSubscribeClick:async function(){var self=this;const inputName=this.$('input').attr('name');const $input=this.$(".js_subscribe_value:visible, .js_subscribe_email:visible");if(inputName==='email'&&$input.length&&!$input.val().match(/.+@.+/)){this.$el.addClass('o_has_error').find('.form-control').addClass('is-invalid');return false;}
this.$el.removeClass('o_has_error').find('.form-control').removeClass('is-invalid');const tokenObj=await this._recaptcha.getToken('website_mass_mailing_subscribe');if(tokenObj.error){self.notification.add(tokenObj.error,{type:'danger',title:_t("Error"),sticky:true,});return false;}
this.rpc('/website_mass_mailing/subscribe',{'list_id':this._getListId(),'value':$input.length?$input.val():false,'subscription_type':inputName,recaptcha_token_response:tokenObj.token,}).then(function(result){let toastType=result.toast_type;if(toastType==='success'){self.$(".js_subscribe_btn").addClass('d-none');self.$(".js_subscribed_btn").removeClass('d-none');self.$('input.js_subscribe_value, input.js_subscribe_email').prop('disabled',!!result);const $popup=self.$el.closest('.o_newsletter_modal');if($popup.length){$popup.modal('hide');}}
self.notification.add(result.toast_content,{type:toastType,title:toastType==='success'?_t('Success'):_t('Error'),sticky:true,});});},});publicWidget.registry.fixNewsletterListClass=publicWidget.Widget.extend({selector:'.s_newsletter_subscribe_form:not(.s_subscription_list), .s_newsletter_block',start(){this.$target[0].classList.add('s_newsletter_list');return this._super(...arguments);},});return __exports;});;

/* /website_sale_loyalty/static/src/js/coupon_toaster_widget.js */
odoo.define('@website_sale_loyalty/js/coupon_toaster_widget',['@web/legacy/js/public/public_widget','@web/core/registry'],function(require){'use strict';let __exports={};const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const{registry}=require("@web/core/registry");const CouponToasterWidget=publicWidget.Widget.extend({init(){this._super(...arguments);this.notification=this.bindService("notification");},start(){let options={};const $content=this.$('.coupon-message-content');const $title=this.$('.coupon-message-title');let message=null;if($content.length){message=$content[0].innerHTML;if($title.length){Object.assign(options,{title:$title[0].innerHTML});}}else if($title.length){message=$title[0].innerHTML;}
if(this.$el.hasClass('coupon-info-message')){this.notification.add(message,Object.assign({type:'success'},options));}else if(this.$el.hasClass('coupon-error-message')){this.notification.add(message,Object.assign({type:'danger'},options));}else if(this.$el.hasClass('coupon-warning-message')){this.notification.add(message,Object.assign({type:'warning'},options));}
return this._super(...arguments);},});registry.category("public_root_widgets").add("CouponToasterWidget",{Widget:CouponToasterWidget,selector:'.coupon-message',});__exports[Symbol.for("default")]=CouponToasterWidget;return __exports;});;

/* /website_sale_loyalty/static/src/js/website_sale_gift_card.js */
odoo.define('@website_sale_loyalty/js/website_sale_gift_card',['@web/legacy/js/public/public_widget','@web/core/browser/browser'],function(require){'use strict';let __exports={};const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const{browser}=require('@web/core/browser/browser');publicWidget.registry.WebsiteSaleGiftCardCopy=publicWidget.Widget.extend({selector:'.o_purchased_gift_card',events:{"click .copy-to-clipboard":"_onClickCopyToClipboard",},async _onClickCopyToClipboard(ev){const textValue=ev.target.dataset.clipboardText;await browser.navigator.clipboard.writeText(textValue);},});return __exports;});;

/* /website_sale_loyalty/static/src/js/website_sale_loyalty_delivery.js */
odoo.define('@website_sale_loyalty/js/website_sale_loyalty_delivery',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.websiteSaleDelivery.include({async _handleCarrierUpdateResult(carrierInput){await this._super(...arguments);if(this.result.new_amount_delivery_discount){const cart_summary_discount_line=document.querySelector('[data-reward-type="shipping"]');if(cart_summary_discount_line){cart_summary_discount_line.innerHTML=this.result.new_amount_delivery_discount;}}
if(this.result.new_amount_order_discounted){const cart_summary_discount_line=document.querySelector('[data-reward-type="discount"]');if(cart_summary_discount_line){cart_summary_discount_line.innerHTML=this.result.new_amount_order_discounted;}}},});return __exports;});;

/* /website_sale_product_configurator/static/src/js/website_sale_options.js */
odoo.define('@website_sale_product_configurator/js/website_sale_options',['@web/legacy/js/public/public_widget','@website_sale/js/website_sale_utils','@website_sale_product_configurator/js/sale_product_configurator_modal','@website_sale/js/website_sale','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const wSaleUtils=require("@website_sale/js/website_sale_utils")[Symbol.for("default")];const{OptionalProductsModal}=require("@website_sale_product_configurator/js/sale_product_configurator_modal");require("@website_sale/js/website_sale");const{_t}=require("@web/core/l10n/translation");publicWidget.registry.WebsiteSale.include({_onProductReady:function(){if(this.isBuyNow){return this._submitForm();}
this.optionalProductsModal=new OptionalProductsModal(this.$form,{rootProduct:this.rootProduct,isWebsite:true,okButtonText:_t('Proceed to Checkout'),cancelButtonText:_t('Continue Shopping'),title:_t('Add to cart'),context:this._getContext(),forceDialog:this.forceDialog,}).open();this.optionalProductsModal.on('options_empty',null,this._submitForm.bind(this));this.optionalProductsModal.on('update_quantity',null,this._onOptionsUpdateQuantity.bind(this));this.optionalProductsModal.on('confirm',null,this._onModalSubmit.bind(this,true));this.optionalProductsModal.on('back',null,this._onModalSubmit.bind(this,false));return this.optionalProductsModal.opened();},_submitForm(){const ret=Promise.resolve(this._super(...arguments));if(this.optionalProductsModal&&this.stayOnPageOption){ret.then(()=>{this.optionalProductsModal._openedResolver()});}
return ret;},_onOptionsUpdateQuantity:function(quantity){var $qtyInput=this.$form.find('.js_main_product input[name="add_qty"]').first();if($qtyInput.length){$qtyInput.val(quantity).trigger('change');}else{this.optionalProductsModal.triggerVariantChange(this.optionalProductsModal.$el);}},_onModalSubmit:function(goToShop){const mainProduct=this.$('.js_product.in_cart.main_product').children('.product_id');const productTrackingInfo=mainProduct.data('product-tracking-info');if(productTrackingInfo){const currency=productTrackingInfo['currency'];const productsTrackingInfo=[];this.$('.js_product.in_cart').each((i,el)=>{productsTrackingInfo.push({'item_id':parseInt(el.getElementsByClassName('product_id')[0].value),'item_name':el.getElementsByClassName('product_display_name')[0].textContent,'quantity':parseFloat(el.getElementsByClassName('js_quantity')[0].value),'currency':currency,'price':parseFloat(el.getElementsByClassName('js_raw_price')[0].textContent),});});if(productsTrackingInfo.length){this.$el.trigger('add_to_cart_event',productsTrackingInfo);}}
const callService=this.call.bind(this)
this.optionalProductsModal.getAndCreateSelectedProducts().then((products)=>{const productAndOptions=JSON.stringify(products);this.rpc('/shop/cart/update_option',{product_and_options:productAndOptions,...this._getOptionalCombinationInfoParam(),}).then(function(values){if(goToShop){window.location.pathname="/shop/cart";}else{wSaleUtils.updateCartNavBar(values);wSaleUtils.showCartNotification(callService,values.notification_info);}}).then(()=>{this._getCombinationInfo($.Event('click',{target:$("#add_to_cart")}));});});},});__exports[Symbol.for("default")]=publicWidget.registry.WebsiteSaleOptions;return __exports;});;

/* /website_blog/static/src/js/contentshare.js */
odoo.define('@website_blog/js/contentshare',['@web/core/utils/strings','@web/legacy/js/core/dom'],function(require){'use strict';let __exports={};const{sprintf}=require("@web/core/utils/strings");const dom=require("@web/legacy/js/core/dom")[Symbol.for("default")];$.fn.share=function(options){var option=$.extend($.fn.share.defaults,options);var selected_text="";$.extend($.fn.share,{init:function(shareable){var self=this;$.fn.share.defaults.shareable=shareable;$.fn.share.defaults.shareable.on('mouseup',function(){if($(this).parents('body.editor_enable').length===0){self.popOver();}});$.fn.share.defaults.shareable.on('mousedown',function(){self.destroy();});},getContent:function(){var $popover_content=$('<div class="h4 m-0"/>');if($('.o_wblog_title, .o_wblog_post_content_field').hasClass('js_comment')){selected_text=this.getSelection('string');var $btn_c=$('<a class="o_share_comment btn btn-link px-2" href="#"/>').append($('<i class="fa fa-lg fa-comment"/>'));$popover_content.append($btn_c);}
if($('.o_wblog_title, .o_wblog_post_content_field').hasClass('js_tweet')){var tweet='"%s" - %s';var baseLength=tweet.replace(/%s/g,'').length;var selectedText=this.getSelection('string').substring(0,option.maxLength-baseLength-23);var text=window.btoa(encodeURIComponent(sprintf(tweet,selectedText,window.location.href)));$popover_content.append(sprintf("<a onclick=\"window.open('%s' + atob('%s'), '_%s','location=yes,height=570,width=520,scrollbars=yes,status=yes')\"><i class=\"ml4 mr4 fa fa-twitter fa-lg\"/></a>",option.shareLink,text,option.target));}
return $popover_content;},commentEdition:function(){$(".o_portal_chatter_composer_form textarea").val('"'+selected_text+'" ').focus();const commentsEl=$('#o_wblog_post_comments')[0];if(commentsEl){dom.scrollTo(commentsEl).then(()=>{window.location.hash='blog_post_comment_quote';});}},getSelection:function(share){if(window.getSelection){var selection=window.getSelection();if(!selection||selection.rangeCount===0){return"";}
if(share==='string'){return String(selection.getRangeAt(0)).replace(/\s{2,}/g,' ');}else{return selection.getRangeAt(0);}}else if(document.selection){if(share==='string'){return document.selection.createRange().text.replace(/\s{2,}/g,' ');}else{return document.selection.createRange();}}},popOver:function(){this.destroy();if(this.getSelection('string').length<option.minLength){return;}
var data=this.getContent();var range=this.getSelection();var newNode=document.createElement("span");range.insertNode(newNode);newNode.className=option.className;var $pop=$(newNode);$pop.popover({trigger:'manual',placement:option.placement,html:true,content:function(){return data;}}).popover('show');$('.o_share_comment').on('click',this.commentEdition);},destroy:function(){var $span=$('span.'+option.className);$span.popover('hide');$span.remove();}});$.fn.share.init(this);};$.fn.share.defaults={shareLink:"http://twitter.com/intent/tweet?text=",minLength:5,maxLength:140,target:"blank",className:"share",placement:"top",};return __exports;});;

/* /website_blog/static/src/js/website_blog.js */
odoo.define('@website_blog/js/website_blog',['@web/core/l10n/translation','@web/legacy/js/core/dom','@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const dom=require("@web/legacy/js/core/dom")[Symbol.for("default")];const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.websiteBlog=publicWidget.Widget.extend({selector:'.website_blog',events:{'click #o_wblog_next_container':'_onNextBlogClick','click #o_wblog_post_content_jump':'_onContentAnchorClick','click .o_twitter, .o_facebook, .o_linkedin, .o_google, .o_twitter_complete, .o_facebook_complete, .o_linkedin_complete, .o_google_complete':'_onShareArticle',},start:function(){$('.js_tweet, .js_comment').share({});return this._super.apply(this,arguments);},_onNextBlogClick:function(ev){ev.preventDefault();var self=this;var $el=$(ev.currentTarget);var nexInfo=$el.find('#o_wblog_next_post_info').data();$el.find('.o_record_cover_container').addClass(nexInfo.size+' '+nexInfo.text).end().find('.o_wblog_toggle').toggleClass('d-none');const placeholder=document.createElement('div');placeholder.style.minHeight='100vh';this.$('#o_wblog_next_container').append(placeholder);setTimeout(()=>{self._forumScrollAction($el,300,function(){window.location.href=nexInfo.url;});});},_onContentAnchorClick:function(ev){ev.preventDefault();ev.stopImmediatePropagation();var $el=$(ev.currentTarget.hash);this._forumScrollAction($el,500,function(){window.location.hash='blog_content';});},_onShareArticle:function(ev){ev.preventDefault();var url='';var $element=$(ev.currentTarget);var blogPostTitle=$('#o_wblog_post_name').html()||'';var articleURL=window.location.href;if($element.hasClass('o_twitter')){var tweetText=_t("Amazing blog article: %s! Check it live: %s",blogPostTitle,articleURL);url='https://twitter.com/intent/tweet?tw_p=tweetbutton&text='+encodeURIComponent(tweetText);}else if($element.hasClass('o_facebook')){url='https://www.facebook.com/sharer/sharer.php?u='+encodeURIComponent(articleURL);}else if($element.hasClass('o_linkedin')){url='https://www.linkedin.com/sharing/share-offsite/?url='+encodeURIComponent(articleURL);}
window.open(url,'','menubar=no, width=500, height=400');},_forumScrollAction:function($el,duration,callback){dom.scrollTo($el[0],{duration:duration}).then(()=>callback());},});return __exports;});;

/* /payment_custom/static/src/js/post_processing.js */
odoo.define('@payment_custom/js/post_processing',['@payment/js/post_processing'],function(require){'use strict';let __exports={};const paymentPostProcessing=require('@payment/js/post_processing')[Symbol.for("default")];paymentPostProcessing.include({_getFinalStates(providerCode){const finalStates=this._super(...arguments);if(providerCode==='custom'){finalStates.push('pending');}
return finalStates;}});return __exports;});;

/* /payment_stripe/static/src/js/express_checkout_form.js */
odoo.define('@payment_stripe/js/express_checkout_form',['@web/core/l10n/translation','@payment/js/express_checkout_form','@payment_stripe/js/stripe_options'],function(require){'use strict';let __exports={};const{_t}=require('@web/core/l10n/translation');const{paymentExpressCheckoutForm}=require('@payment/js/express_checkout_form');const{StripeOptions}=require('@payment_stripe/js/stripe_options');paymentExpressCheckoutForm.include({init(){this._super(...arguments);this.rpc=this.bindService("rpc");},_getOrderDetails(deliveryAmount,amountFreeShipping){const pending=this.paymentContext['shippingInfoRequired']&&deliveryAmount===undefined;const minorAmount=parseInt(this.paymentContext['minorAmount'])
const displayItems=[{label:_t("Your order"),amount:minorAmount,},];if(this.paymentContext['shippingInfoRequired']&&deliveryAmount!==undefined){displayItems.push({label:_t("Delivery"),amount:deliveryAmount,});}
if(amountFreeShipping){displayItems.push({label:_t("Free Shipping"),amount:amountFreeShipping,});}
return{total:{label:this.paymentContext['merchantName'],amount:minorAmount+(deliveryAmount??0)+(amountFreeShipping??0),pending:pending,},displayItems:displayItems,};},async _prepareExpressCheckoutForm(providerData){if(providerData.providerCode!=='stripe'||!this.paymentContext['amount']){this._super(...arguments);return;}
const stripeJS=Stripe(providerData.stripePublishableKey,new StripeOptions()._prepareStripeOptions(providerData),);const paymentRequest=stripeJS.paymentRequest({country:providerData.countryCode,currency:this.paymentContext['currencyName'],requestPayerName:true,requestPayerEmail:true,requestPayerPhone:true,requestShipping:this.paymentContext['shippingInfoRequired'],...this._getOrderDetails(),});if(this.stripePaymentRequests===undefined){this.stripePaymentRequests=[];}
this.stripePaymentRequests.push(paymentRequest);const paymentRequestButton=stripeJS.elements().create('paymentRequestButton',{paymentRequest:paymentRequest,style:{paymentRequestButton:{type:'buy'}},});const canMakePayment=await paymentRequest.canMakePayment();if(canMakePayment){paymentRequestButton.mount(`#o_stripe_express_checkout_container_${providerData.providerId}`);}else{document.querySelector(`#o_stripe_express_checkout_container_${providerData.providerId}`).style.display='none';}
paymentRequest.on('paymentmethod',async(ev)=>{const addresses={'billing_address':{name:ev.payerName,email:ev.payerEmail,phone:ev.payerPhone,street:ev.paymentMethod.billing_details.address.line1,street2:ev.paymentMethod.billing_details.address.line2,zip:ev.paymentMethod.billing_details.address.postal_code,city:ev.paymentMethod.billing_details.address.city,country:ev.paymentMethod.billing_details.address.country,state:ev.paymentMethod.billing_details.address.state,}};if(this.paymentContext['shippingInfoRequired']){addresses.shipping_address={name:ev.shippingAddress.recipient,email:ev.payerEmail,phone:ev.shippingAddress.phone||ev.payerPhone,street:ev.shippingAddress.addressLine[0],street2:ev.shippingAddress.addressLine[1],zip:ev.shippingAddress.postalCode,city:ev.shippingAddress.city,country:ev.shippingAddress.country,state:ev.shippingAddress.region,};addresses.shipping_option=ev.shippingOption;}
this.paymentContext.partnerId=parseInt(await this.rpc(this.paymentContext['expressCheckoutRoute'],addresses,));const{client_secret}=await this.rpc(this.paymentContext['transactionRoute'],this._prepareTransactionRouteParams(providerData.providerId),);const{paymentIntent,error:confirmError}=await stripeJS.confirmCardPayment(client_secret,{payment_method:ev.paymentMethod.id},{handleActions:false});if(confirmError){ev.complete('fail');}else{ev.complete('success');if(paymentIntent.status==='requires_action'){await stripeJS.confirmCardPayment(client_secret);}
window.location='/payment/status';}});if(this.paymentContext['shippingInfoRequired']){paymentRequest.on('shippingaddresschange',async(ev)=>{const availableCarriers=await this.rpc(this.paymentContext['shippingAddressUpdateRoute'],{partial_shipping_address:{zip:ev.shippingAddress.postalCode,city:ev.shippingAddress.city,country:ev.shippingAddress.country,state:ev.shippingAddress.region,},},);if(availableCarriers.length===0){ev.updateWith({status:'invalid_shipping_address'});}else{ev.updateWith({status:'success',shippingOptions:availableCarriers.map(carrier=>({id:String(carrier.id),label:carrier.name,detail:carrier.description?carrier.description:'',amount:carrier.minorAmount,})),...this._getOrderDetails(availableCarriers[0].minorAmount),});}});paymentRequest.on('shippingoptionchange',async(ev)=>{const result=await this.rpc('/shop/update_carrier',{carrier_id:parseInt(ev.shippingOption.id),});ev.updateWith({status:'success',...this._getOrderDetails(ev.shippingOption.amount,result.delivery_discount_minor_amount||0,),});});}},_updateAmount(newAmount,newMinorAmount){this._super(...arguments);this.stripePaymentRequests&&this.stripePaymentRequests.map(paymentRequest=>paymentRequest.update(this._getOrderDetails()));},});return __exports;});;

/* /payment_stripe/static/src/js/payment_form.js */
odoo.define('@payment_stripe/js/payment_form',['@web/core/l10n/translation','@payment_stripe/js/stripe_options','@payment/js/payment_form'],function(require){'use strict';let __exports={};const{_t}=require('@web/core/l10n/translation');const{StripeOptions}=require('@payment_stripe/js/stripe_options');const paymentForm=require('@payment/js/payment_form')[Symbol.for("default")];paymentForm.include({async _prepareInlineForm(providerId,providerCode,paymentOptionId,paymentMethodCode,flow){if(providerCode!=='stripe'){this._super(...arguments);return;}
this.stripeElements??={};if(flow==='token'){return;}else if(this.stripeElements[paymentOptionId]){this._setPaymentFlow('direct');return;}
this._setPaymentFlow('direct');const radio=document.querySelector('input[name="o_payment_radio"]:checked');const inlineForm=this._getInlineForm(radio);const stripeInlineForm=inlineForm.querySelector('[name="o_stripe_element_container"]');this.stripeInlineFormValues=JSON.parse(stripeInlineForm.dataset['stripeInlineFormValues']);this.stripeJS??=Stripe(this.stripeInlineFormValues['publishable_key'],new StripeOptions()._prepareStripeOptions(stripeInlineForm.dataset),);let elementsOptions={appearance:{theme:'stripe'},currency:this.stripeInlineFormValues['currency_name'],captureMethod:this.stripeInlineFormValues['capture_method'],paymentMethodTypes:[this.stripeInlineFormValues['payment_methods_mapping'][paymentMethodCode]??paymentMethodCode],};if(this.paymentContext['mode']==='payment'){elementsOptions.mode='payment';elementsOptions.amount=parseInt(this.stripeInlineFormValues['minor_amount']);if(this.stripeInlineFormValues['is_tokenization_required']){elementsOptions.setupFutureUsage='off_session';}}
else{elementsOptions.mode='setup';elementsOptions.setupFutureUsage='off_session';}
this.stripeElements[paymentOptionId]=this.stripeJS.elements(elementsOptions);const paymentElementOptions={defaultValues:{billingDetails:this.stripeInlineFormValues['billing_details'],},};const paymentElement=this.stripeElements[paymentOptionId].create('payment',paymentElementOptions);paymentElement.on('loaderror',response=>{this._displayErrorDialog(_t("Cannot display the payment form"),response.error.message);});paymentElement.mount(stripeInlineForm);const tokenizationCheckbox=inlineForm.querySelector('input[name="o_payment_tokenize_checkbox"]');if(tokenizationCheckbox){this.stripeElements[paymentOptionId].update({setupFutureUsage:tokenizationCheckbox.checked?'off_session':null,});tokenizationCheckbox.addEventListener('input',()=>{this.stripeElements[paymentOptionId].update({setupFutureUsage:tokenizationCheckbox.checked?'off_session':null,});});}},async _initiatePaymentFlow(providerCode,paymentOptionId,paymentMethodCode,flow){if(providerCode!=='stripe'||flow==='token'){await this._super(...arguments);return;}
const _super=this._super.bind(this);try{await this.stripeElements[paymentOptionId].submit();}catch(error){this._displayErrorDialog(_t("Incorrect payment details"),error.message);this._enableButton();return}
return await _super(...arguments);},async _processDirectFlow(providerCode,paymentOptionId,paymentMethodCode,processingValues){if(providerCode!=='stripe'){await this._super(...arguments);return;}
const{error}=await this._stripeConfirmIntent(processingValues,paymentOptionId);if(error){this._displayErrorDialog(_t("Payment processing failed"),error.message);this._enableButton();}},async _stripeConfirmIntent(processingValues,paymentOptionId){const confirmOptions={elements:this.stripeElements[paymentOptionId],clientSecret:processingValues['client_secret'],confirmParams:{return_url:processingValues['return_url'],},};if(this.paymentContext['mode']==='payment'){return await this.stripeJS.confirmPayment(confirmOptions);}
else{return await this.stripeJS.confirmSetup(confirmOptions);}},});return __exports;});;

/* /payment_stripe/static/src/js/stripe_options.js */
odoo.define('@payment_stripe/js/stripe_options',[],function(require){'use strict';let __exports={};const StripeOptions=__exports.StripeOptions=class StripeOptions{_prepareStripeOptions(processingValues){return{'apiVersion':'2019-05-16',};};}
return __exports;});;

/* /website/static/src/snippets/s_share/000.js */
odoo.define('@website/snippets/s_share/000',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const ShareWidget=publicWidget.Widget.extend({selector:'.s_share, .oe_share',events:{'click a':'_onShareLinkClick',},_onShareLinkClick(ev){const urlParams=["u","url","body"];const titleParams=["title","text","subject","description"];const mediaParams=["media"];const aEl=ev.currentTarget;const modifiedUrl=new URL(aEl.href);if(![...urlParams,...titleParams,...mediaParams].some(param=>modifiedUrl.searchParams.has(param))){return;}
ev.preventDefault();ev.stopPropagation();const currentUrl=window.location.href;const urlParamFound=urlParams.find(param=>modifiedUrl.searchParams.has(param));if(urlParamFound){modifiedUrl.searchParams.set(urlParamFound,currentUrl);}
const titleParamFound=titleParams.find(param=>modifiedUrl.searchParams.has(param));if(titleParamFound){const currentTitle=document.title;if(aEl.classList.contains('s_share_whatsapp')){modifiedUrl.searchParams.set(titleParamFound,`${currentTitle} ${currentUrl}`);}else{modifiedUrl.search=modifiedUrl.search.replace(encodeURIComponent("{title}"),encodeURIComponent(currentTitle));}}
const mediaParamFound=mediaParams.find(param=>modifiedUrl.searchParams.has(param));if(mediaParamFound){const ogImageEl=document.querySelector("meta[property='og:image']");if(ogImageEl){const media=ogImageEl.content;modifiedUrl.searchParams.set(mediaParamFound,media);}else{modifiedUrl.searchParams.delete(mediaParamFound);}}
window.open(modifiedUrl.toString(),aEl.target,"menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=550,width=600",);},});publicWidget.registry.share=ShareWidget;__exports[Symbol.for("default")]=ShareWidget;return __exports;});;

/* /website/static/src/snippets/s_facebook_page/000.js */
odoo.define('@website/snippets/s_facebook_page/000',['@web/core/l10n/translation','@web/core/utils/objects','@web/core/utils/numbers','@web/legacy/js/public/public_widget','@web/core/utils/timing'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const{pick}=require("@web/core/utils/objects");const{clamp}=require("@web/core/utils/numbers");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{debounce}=require("@web/core/utils/timing");const FacebookPageWidget=publicWidget.Widget.extend({selector:'.o_facebook_page',disabledInEditableMode:false,start:function(){var def=this._super.apply(this,arguments);this.previousWidth=0;const params=pick(this.$el[0].dataset,'href','id','height','tabs','small_header','hide_cover');if(!params.href){return def;}
if(params.id){params.href=`https://www.facebook.com/${params.id}`;}
delete params.id;this._renderIframe(params);this.resizeObserver=new ResizeObserver(debounce(this._renderIframe.bind(this,params),100));this.resizeObserver.observe(this.el.parentElement);return def;},destroy:function(){this._super.apply(this,arguments);if(this.iframeEl){this._deactivateEditorObserver();this.iframeEl.remove();this._activateEditorObserver();this.resizeObserver.disconnect();}},_renderIframe(params){this._deactivateEditorObserver();params.width=clamp(Math.floor(this.$el.width()),180,500);if(this.previousWidth!==params.width){this.previousWidth=params.width;const searchParams=new URLSearchParams(params);const src="https://www.facebook.com/plugins/page.php?"+searchParams;this.iframeEl=Object.assign(document.createElement("iframe"),{src:src,scrolling:"no",});this.iframeEl.setAttribute("frameborder","0");this.iframeEl.setAttribute("allowTransparency","true");this.iframeEl.setAttribute("style",`width: ${params.width}px; height: ${params.height}px; border: none; overflow: hidden;`);this.iframeEl.setAttribute("aria-label",_t("Facebook"));this.el.replaceChildren(this.iframeEl);}
this._activateEditorObserver();},_activateEditorObserver(){this.options.wysiwyg&&this.options.wysiwyg.odooEditor.observerActive();},_deactivateEditorObserver(){this.options.wysiwyg&&this.options.wysiwyg.odooEditor.observerUnactive();},});publicWidget.registry.facebookPage=FacebookPageWidget;__exports[Symbol.for("default")]=FacebookPageWidget;return __exports;});;

/* /website/static/src/snippets/s_image_gallery/000.js */
odoo.define('@website/snippets/s_image_gallery/000',['@web/core/utils/functions','@web/legacy/js/public/public_widget','@web/core/utils/render'],function(require){'use strict';let __exports={};const{uniqueId}=require("@web/core/utils/functions");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{renderToElement}=require("@web/core/utils/render");const GalleryWidget=publicWidget.Widget.extend({selector:'.s_image_gallery:not(.o_slideshow)',events:{'click img':'_onClickImg',},start(){this._super(...arguments);this.originalSources=[...this.el.querySelectorAll("img")].map(img=>img.getAttribute("src"));},_onClickImg:function(ev){const clickedEl=ev.currentTarget;if(this.$modal||clickedEl.matches("a > img")){return;}
var self=this;let imageEls=this.el.querySelectorAll("img");const currentImageEl=clickedEl.closest("img");const currentImageIndex=[...imageEls].indexOf(currentImageEl);imageEls=[...imageEls].map((el,i)=>{const cloneEl=el.cloneNode(true);cloneEl.src=this.originalSources[i];return cloneEl;});var size=0.8;var dimensions={min_width:Math.round(window.innerWidth*size*0.9),min_height:Math.round(window.innerHeight*size),max_width:Math.round(window.innerWidth*size*0.9),max_height:Math.round(window.innerHeight*size),width:Math.round(window.innerWidth*size*0.9),height:Math.round(window.innerHeight*size)};const milliseconds=this.el.dataset.interval||false;this.$modal=$(renderToElement('website.gallery.slideshow.lightbox',{images:imageEls,index:currentImageIndex,dim:dimensions,interval:milliseconds||0,id:uniqueId("slideshow_"),}));this.__onModalKeydown=this._onModalKeydown.bind(this);this.$modal.on('hidden.bs.modal',function(){$(this).hide();$(this).siblings().filter('.modal-backdrop').remove();this.removeEventListener("keydown",self.__onModalKeydown);$(this).remove();self.$modal=undefined;});this.$modal.one('shown.bs.modal',function(){self.trigger_up('widgets_start_request',{editableMode:false,$target:self.$modal.find('.modal-body.o_slideshow'),});this.addEventListener("keydown",self.__onModalKeydown);});this.$modal.appendTo(document.body);const modalBS=new Modal(this.$modal[0],{keyboard:true,backdrop:true});modalBS.show();},_onModalKeydown(ev){if(ev.key==="ArrowLeft"||ev.key==="ArrowRight"){const side=ev.key==="ArrowLeft"?"prev":"next";this.$modal[0].querySelector(`.carousel-control-${side}`).click();}
if(ev.key==="Escape"){ev.stopPropagation();}},});const GallerySliderWidget=publicWidget.Widget.extend({selector:'.o_slideshow',disabledInEditableMode:false,start:function(){var self=this;this.$carousel=this.$el.is('.carousel')?this.$el:this.$('.carousel');this.$indicator=this.$carousel.find('.carousel-indicators');this.$prev=this.$indicator.find('li.o_indicators_left').css('visibility','');this.$next=this.$indicator.find('li.o_indicators_right').css('visibility','');var $lis=this.$indicator.find('li[data-bs-slide-to]');let indicatorWidth=this.$indicator.width();if(indicatorWidth===0){const $indicatorParent=this.$indicator.parents().not(':visible').last();if(!$indicatorParent[0].style.display){$indicatorParent[0].style.display='block';indicatorWidth=this.$indicator.width();$indicatorParent[0].style.display='';}}
let nbPerPage=Math.floor(indicatorWidth/$lis.first().outerWidth(true))-3;var realNbPerPage=nbPerPage||1;var nbPages=Math.ceil($lis.length/realNbPerPage);var index;var page;update();function hide(){$lis.each(function(i){$(this).toggleClass('d-none',i<page*nbPerPage||i>=(page+1)*nbPerPage);});if(page<=0){self.$prev.detach();}else{self.$prev.removeClass('d-none');self.$prev.prependTo(self.$indicator);}
if(page>=nbPages-1){self.$next.detach();}else{self.$next.removeClass('d-none');self.$next.appendTo(self.$indicator);}}
function update(){const active=$lis.filter('.active');index=active.length?$lis.index(active):0;page=Math.floor(index/realNbPerPage);hide();}
this.$carousel.on('slide.bs.carousel.gallery_slider',function(){setTimeout(function(){var $item=self.$carousel.find('.carousel-inner .carousel-item-prev, .carousel-inner .carousel-item-next');var index=$item.index();$lis.removeClass('active').filter('[data-bs-slide-to="'+index+'"]').addClass('active');},0);});this.$indicator.on('click.gallery_slider','> li:not([data-bs-slide-to])',function(){page+=($(this).hasClass('o_indicators_left')?-1:1);page=Math.max(0,Math.min(nbPages-1,page));self.$carousel.carousel(page*realNbPerPage);if(!self.editableMode){hide();}});this.$carousel.on('slid.bs.carousel.gallery_slider',update);return this._super.apply(this,arguments);},destroy:function(){this._super.apply(this,arguments);if(!this.$indicator){return;}
this.$prev.prependTo(this.$indicator);this.$next.appendTo(this.$indicator);this.$carousel.off('.gallery_slider');this.$indicator.off('.gallery_slider');},});publicWidget.registry.gallery=GalleryWidget;publicWidget.registry.gallerySlider=GallerySliderWidget;__exports[Symbol.for("default")]={GalleryWidget:GalleryWidget,GallerySliderWidget:GallerySliderWidget,};return __exports;});;

/* /website/static/src/snippets/s_countdown/000.js */
odoo.define('@website/snippets/s_countdown/000',['@web/legacy/js/public/public_widget','@web_editor/js/common/utils','@web/core/utils/colors','@web/core/l10n/translation','@web/core/utils/render'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const weUtils=require("@web_editor/js/common/utils")[Symbol.for("default")];const{isCSSColor}=require('@web/core/utils/colors');const{_t}=require("@web/core/l10n/translation");const{renderToElement}=require("@web/core/utils/render");const CountdownWidget=publicWidget.Widget.extend({selector:'.s_countdown',disabledInEditableMode:false,start:function(){this.$el[0].querySelectorAll('svg').forEach(el=>{el.parentNode.remove();});this.$wrapper=this.$('.s_countdown_canvas_wrapper');this.$wrapper.addClass('d-flex justify-content-center');this.hereBeforeTimerEnds=false;this.endAction=this.el.dataset.endAction;this.endTime=parseInt(this.el.dataset.endTime);this.size=parseInt(this.el.dataset.size);this.display=this.el.dataset.display;if(!this.display&&this.el.dataset.bsDisplay){this.display=this.el.dataset.bsDisplay;delete this.el.dataset.bsDisplay;this.el.dataset.display=this.display;}
this.layout=this.el.dataset.layout;this.layoutBackground=this.el.dataset.layoutBackground;this.progressBarStyle=this.el.dataset.progressBarStyle;this.progressBarWeight=this.el.dataset.progressBarWeight;this.textColor=this._ensureCssColor(this.el.dataset.textColor);this.layoutBackgroundColor=this._ensureCssColor(this.el.dataset.layoutBackgroundColor);this.progressBarColor=this._ensureCssColor(this.el.dataset.progressBarColor);this.onlyOneUnit=this.display==='d';this.width=parseInt(this.size);if(this.layout==='boxes'){this.width/=1.75;}
this._initTimeDiff();this._render();this.setInterval=setInterval(this._render.bind(this),1000);return this._super(...arguments);},destroy:function(){this.$('.s_countdown_end_redirect_message').remove();this.$('.s_countdown_end_message').addClass('d-none');this.$('.s_countdown_text_wrapper').remove();this.$('.s_countdown_canvas_wrapper').removeClass('d-none');this.$('.s_countdown_canvas_flex').remove();clearInterval(this.setInterval);this._super(...arguments);},_ensureCssColor:function(color){if(isCSSColor(color)){return color;}
return weUtils.getCSSVariableValue(color)||this.defaultColor;},_getDelta:function(){const currentTimestamp=Date.now()/1000;return this.endTime-currentTimestamp;},_handleEndCountdownAction:function(){if(this.endAction==='redirect'){const redirectUrl=this.el.dataset.redirectUrl||'/';if(this.hereBeforeTimerEnds){setTimeout(()=>window.location=redirectUrl,500);}else{if(!this.$('.s_countdown_end_redirect_message').length){const $container=this.$('> .container, > .container-fluid, > .o_container_small');$container.append($(renderToElement('website.s_countdown.end_redirect_message',{redirectUrl:redirectUrl,})));}}}else if(this.endAction==='message'||this.endAction==='message_no_countdown'){this.$('.s_countdown_end_message').removeClass('d-none');}},_initTimeDiff:function(){const delta=this._getDelta();this.diff=[];if(this._isUnitVisible('d')&&!(this.onlyOneUnit&&delta<86400)){this.diff.push({canvas:$('<div class="s_countdown_canvas_flex"><canvas class="w-100"/></div>').appendTo(this.$wrapper)[0],total:15,label:_t("Days"),nbSeconds:86400,});}
if(this._isUnitVisible('h')||(this.onlyOneUnit&&delta<86400&&delta>3600)){this.diff.push({canvas:$('<div class="s_countdown_canvas_flex"><canvas class="w-100"/></div>').appendTo(this.$wrapper)[0],total:24,label:_t("Hours"),nbSeconds:3600,});}
if(this._isUnitVisible('m')||(this.onlyOneUnit&&delta<3600&&delta>60)){this.diff.push({canvas:$('<div class="s_countdown_canvas_flex"><canvas class="w-100"/></div>').appendTo(this.$wrapper)[0],total:60,label:_t("Minutes"),nbSeconds:60,});}
if(this._isUnitVisible('s')||(this.onlyOneUnit&&delta<60)){this.diff.push({canvas:$('<div class="s_countdown_canvas_flex"><canvas class="w-100"/></div>').appendTo(this.$wrapper)[0],total:60,label:_t("Seconds"),nbSeconds:1,});}},_isUnitVisible:function(unit){return this.display.includes(unit);},_render:function(){if(this.onlyOneUnit&&this._getDelta()<this.diff[0].nbSeconds){this.$('.s_countdown_canvas_flex').remove();this._initTimeDiff();}
this._updateTimeDiff();const hideCountdown=this.isFinished&&!this.editableMode&&this.$el.hasClass('hide-countdown');if(this.layout==='text'){this.$('.s_countdown_canvas_flex').addClass('d-none');if(!this.$textWrapper){this.$textWrapper=$('<span/>').attr({class:'s_countdown_text_wrapper d-none',});this.$textWrapper.text(_t("Countdown ends in"));this.$textWrapper.append($('<span/>').attr({class:'s_countdown_text ms-1',}));this.$textWrapper.appendTo(this.$wrapper);}
this.$textWrapper.toggleClass('d-none',hideCountdown);const countdownText=this.diff.map(e=>e.nb+' '+e.label).join(', ');this.$('.s_countdown_text').text(countdownText.toLowerCase());}else{for(const val of this.diff){const canvas=val.canvas.querySelector('canvas');const ctx=canvas.getContext("2d");ctx.canvas.width=this.width;ctx.canvas.height=this.size;this._clearCanvas(ctx);$(canvas).toggleClass('d-none',hideCountdown);if(hideCountdown){continue;}
if(this.layoutBackground!=='none'){this._drawBgShape(ctx,this.layoutBackground==='plain');}
this._drawText(canvas,val.nb,val.label,this.layoutBackground==='plain');if(this.progressBarStyle==='surrounded'){this._drawProgressBarBg(ctx,this.progressBarWeight==='thin');}
if(this.progressBarStyle!=='none'){this._drawProgressBar(ctx,val.nb,val.total,this.progressBarWeight==='thin');}
this.$('.s_countdown_canvas_flex').toggleClass('mx-1',this.layout==='boxes');}}
if(this.isFinished){clearInterval(this.setInterval);if(!this.editableMode){this._handleEndCountdownAction();}}},_updateTimeDiff:function(){let delta=this._getDelta();this.isFinished=delta<0;if(this.isFinished){for(const unitData of this.diff){unitData.nb=0;}
return;}
this.hereBeforeTimerEnds=true;for(const unitData of this.diff){unitData.nb=Math.floor(delta/unitData.nbSeconds);delta-=unitData.nb*unitData.nbSeconds;}},_clearCanvas:function(ctx){ctx.clearRect(0,0,this.size,this.size);},_drawText:function(canvas,textNb,textUnit,full=false){const ctx=canvas.getContext("2d");const nbSize=this.size/4;ctx.font=`${nbSize}px Arial`;ctx.fillStyle=this.textColor;ctx.textAlign='center';ctx.textBaseline='middle';ctx.fillText(textNb,canvas.width/2,canvas.height/2);const unitSize=this.size/12;ctx.font=`${unitSize}px Arial`;ctx.fillText(textUnit,canvas.width/2,canvas.height/2+nbSize/1.5,this.width);if(this.layout==='boxes'&&this.layoutBackground!=='none'&&this.progressBarStyle==='none'){let barWidth=this.size/(this.progressBarWeight==='thin'?31:10);if(full){barWidth=0;}
ctx.beginPath();ctx.moveTo(barWidth,this.size/2);ctx.lineTo(this.width-barWidth,this.size/2);ctx.stroke();}},_drawBgShape:function(ctx,full=false){ctx.fillStyle=this.layoutBackgroundColor;ctx.beginPath();if(this.layout==='circle'){let rayon=this.size/2;if(this.progressBarWeight==='thin'){rayon-=full?this.size/29:this.size/15;}else{rayon-=full?0:this.size/10;}
ctx.arc(this.size/2,this.size/2,rayon,0,Math.PI*2);ctx.fill();}else if(this.layout==='boxes'){let barWidth=this.size/(this.progressBarWeight==='thin'?31:10);if(full){barWidth=0;}
ctx.fillStyle=this.layoutBackgroundColor;ctx.rect(barWidth,barWidth,this.width-barWidth*2,this.size-barWidth*2);ctx.fill();const gradient=ctx.createLinearGradient(0,this.width,0,0);gradient.addColorStop(0,'#ffffff24');gradient.addColorStop(1,this.layoutBackgroundColor);ctx.fillStyle=gradient;ctx.rect(barWidth,barWidth,this.width-barWidth*2,this.size-barWidth*2);ctx.fill();$(ctx.canvas).css({'border-radius':'8px'});}},_drawProgressBar:function(ctx,nbUnit,totalUnit,thinLine){ctx.strokeStyle=this.progressBarColor;ctx.lineWidth=thinLine?this.size/35:this.size/10;if(this.layout==='circle'){ctx.beginPath();ctx.arc(this.size/2,this.size/2,this.size/2-this.size/20,Math.PI/-2,(Math.PI*2)*(nbUnit/totalUnit)+(Math.PI/-2));ctx.stroke();}else if(this.layout==='boxes'){ctx.lineWidth*=2;let pc=nbUnit/totalUnit*100;const linesCoordFuncs=[(linePc)=>[0+ctx.lineWidth/2,0,(this.width-ctx.lineWidth/2)*linePc/25+ctx.lineWidth/2,0],(linePc)=>[this.width,0+ctx.lineWidth/2,this.width,(this.size-ctx.lineWidth/2)*linePc/25+ctx.lineWidth/2],(linePc)=>[this.width-((this.width-ctx.lineWidth/2)*linePc/25)-ctx.lineWidth/2,this.size,this.width-ctx.lineWidth/2,this.size],(linePc)=>[0,this.size-((this.size-ctx.lineWidth/2)*linePc/25)-ctx.lineWidth/2,0,this.size-ctx.lineWidth/2],];while(pc>0&&linesCoordFuncs.length){const linePc=Math.min(pc,25);const lineCoord=(linesCoordFuncs.shift())(linePc);ctx.beginPath();ctx.moveTo(lineCoord[0],lineCoord[1]);ctx.lineTo(lineCoord[2],lineCoord[3]);ctx.stroke();pc-=linePc;}}},_drawProgressBarBg:function(ctx,thinLine){ctx.strokeStyle=this.progressBarColor;ctx.globalAlpha=0.2;ctx.lineWidth=thinLine?this.size/35:this.size/10;if(this.layout==='circle'){ctx.beginPath();ctx.arc(this.size/2,this.size/2,this.size/2-this.size/20,0,Math.PI*2);ctx.stroke();}else if(this.layout==='boxes'){ctx.lineWidth*=2;const points=[[0+ctx.lineWidth/2,0,this.width,0],[this.width,0+ctx.lineWidth/2,this.width,this.size],[0,this.size,this.width-ctx.lineWidth/2,this.size],[0,0,0,this.size-ctx.lineWidth/2],];while(points.length){const point=points.shift();ctx.beginPath();ctx.moveTo(point[0],point[1]);ctx.lineTo(point[2],point[3]);ctx.stroke();}}
ctx.globalAlpha=1;},});publicWidget.registry.countdown=CountdownWidget;__exports[Symbol.for("default")]=CountdownWidget;return __exports;});;

/* /website/static/src/snippets/s_popup/000.js */
odoo.define('@website/snippets/s_popup/000',['@web/legacy/js/public/public_widget','@web/core/browser/cookie','@web/core/l10n/translation','@web/core/utils/timing','@web/core/ui/ui_service','@website/js/content/inject_dom','@website/js/utils'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{cookie}=require("@web/core/browser/cookie");const{_t}=require("@web/core/l10n/translation");const{throttleForAnimation}=require("@web/core/utils/timing");const{utils:uiUtils,SIZES}=require("@web/core/ui/ui_service");const{setUtmsHtmlDataset}=require('@website/js/content/inject_dom');const wUtils=require("@website/js/utils")[Symbol.for("default")];const SharedPopupWidget=publicWidget.Widget.extend({selector:'.s_popup',disabledInEditableMode:false,events:{'show.bs.modal':'_onModalShow','hidden.bs.modal':'_onModalHidden',},destroy(){this._super(...arguments);if(!this.editableMode){this.el.classList.add('d-none');}},_onModalShow(){this.el.classList.remove('d-none');},_onModalHidden(){if(this.el.querySelector('.s_popup_no_backdrop')){$().getScrollingTarget()[0].dispatchEvent(new Event('scroll'));}
this.el.classList.add('d-none');},});publicWidget.registry.SharedPopup=SharedPopupWidget;const PopupWidget=publicWidget.Widget.extend({selector:".s_popup:not(#website_cookies_bar)",events:{'click .js_close_popup':'_onCloseClick','click .btn-primary':'_onBtnPrimaryClick','hide.bs.modal':'_onHideModal','show.bs.modal':'_onShowModal',},cookieValue:true,start:function(){this.modalShownOnClickEl=this.el.querySelector(".modal[data-display='onClick']");if(this.modalShownOnClickEl){this.__onHashChange=this._onHashChange.bind(this);window.addEventListener('hashchange',this.__onHashChange);this._showPopupOnClick();}else{this._popupAlreadyShown=!!cookie.get(this.$el.attr('id'));const isMobile=uiUtils.getSize()<SIZES.LG;const emptyPopup=[...this.$el[0].querySelectorAll(".oe_structure > *:not(.s_popup_close)")].every((el)=>{const visibilitySelectors=el.dataset.visibilitySelectors;const deviceInvisible=isMobile?el.classList.contains("o_snippet_mobile_invisible"):el.classList.contains("o_snippet_desktop_invisible");return(visibilitySelectors&&el.matches(visibilitySelectors))||deviceInvisible;});if(!this._popupAlreadyShown&&!emptyPopup){this._bindPopup();}}
return this._super(...arguments);},destroy:function(){this._super.apply(this,arguments);$(document).off('mouseleave.open_popup');this.$el.find('.modal').modal('hide');clearTimeout(this.timeout);if(this.modalShownOnClickEl){window.removeEventListener('hashchange',this.__onHashChange);}},_bindPopup:function(){const $main=this.$el.find('.modal');let display=$main.data('display');let delay=$main.data('showAfter');if(uiUtils.isSmall()){if(display==='mouseExit'){display='afterDelay';delay=5000;}}
if(display==='afterDelay'){this.timeout=setTimeout(()=>this._showPopup(),delay);}else if(display==="mouseExit"){$(document).on('mouseleave.open_popup',()=>this._showPopup());}},_canShowPopup(){return true;},_hidePopup:function(){this.$el.find('.modal').modal('hide');},_showPopup:function(){if(this._popupAlreadyShown||!this._canShowPopup()){return;}
this.$el.find('.modal').modal('show');},_showPopupOnClick(hash=window.location.hash){if(hash&&hash.substring(1)===this.modalShownOnClickEl.id){const urlWithoutHash=window.location.href.replace(hash,'');window.history.replaceState(null,null,urlWithoutHash);this._showPopup();}},_canBtnPrimaryClosePopup(primaryBtnEl){return!(primaryBtnEl.classList.contains("s_website_form_send")||primaryBtnEl.classList.contains("o_website_form_send"));},_onCloseClick:function(){this._hidePopup();},_onBtnPrimaryClick(ev){if(this._canBtnPrimaryClosePopup(ev.target)){this._hidePopup();}},_onHideModal:function(){const nbDays=this.$el.find('.modal').data('consentsDuration');cookie.set(this.el.id,this.cookieValue,nbDays*24*60*60,'required');this._popupAlreadyShown=true&&!this.modalShownOnClickEl;this.$el.find('.media_iframe_video iframe').each((i,iframe)=>{iframe.src='';});},_onShowModal(){this.el.querySelectorAll('.media_iframe_video').forEach(media=>{const iframe=media.querySelector('iframe');iframe.src=media.dataset.oeExpression||media.dataset.src;});},_onHashChange(ev){if(ev&&ev.newURL){this._showPopupOnClick(new URL(ev.newURL).hash);}else{this._showPopupOnClick();}},});publicWidget.registry.popup=PopupWidget;const noBackdropPopupWidget=publicWidget.Widget.extend({selector:'.s_popup_no_backdrop',disabledInEditableMode:false,events:{'shown.bs.modal':'_onModalNoBackdropShown','hide.bs.modal':'_onModalNoBackdropHide',},start(){this.throttledUpdateScrollbar=throttleForAnimation(()=>this._updateScrollbar());if(this.editableMode&&this.el.classList.contains('show')){this._updateScrollbar();this._addModalNoBackdropEvents();}
return this._super(...arguments);},destroy(){this._super(...arguments);this._removeModalNoBackdropEvents();window.dispatchEvent(new Event('resize'));},_updateScrollbar(){const modalContent=this.el.querySelector('.modal-content');const isOverflowing=$(modalContent).hasScrollableContent();const modalInstance=window.Modal.getInstance(this.el);if(isOverflowing){modalInstance._adjustDialog();}else{modalInstance._resetAdjustments();}},_addModalNoBackdropEvents(){window.addEventListener('resize',this.throttledUpdateScrollbar);this.resizeObserver=new window.ResizeObserver(()=>{this._updateScrollbar();});this.resizeObserver.observe(this.el.querySelector('.modal-content'));},_removeModalNoBackdropEvents(){this.throttledUpdateScrollbar.cancel();window.removeEventListener('resize',this.throttledUpdateScrollbar);if(this.resizeObserver){this.resizeObserver.disconnect();delete this.resizeObserver;}},_onModalNoBackdropShown(){this._updateScrollbar();this._addModalNoBackdropEvents();},_onModalNoBackdropHide(){this._removeModalNoBackdropEvents();},});publicWidget.registry.noBackdropPopup=noBackdropPopupWidget;publicWidget.registry.cookies_bar=PopupWidget.extend({selector:'#website_cookies_bar',events:Object.assign({},PopupWidget.prototype.events,{'click #cookies-consent-essential, #cookies-consent-all':'_onAcceptClick',}),destroy(){if(this.toggleEl){this.toggleEl.removeEventListener("click",this._onToggleCookiesBar);this.toggleEl.remove();}
this._super(...arguments);},_showPopup(){this._super(...arguments);const policyLinkEl=this.el.querySelector(".o_cookies_bar_text_policy");if(policyLinkEl&&window.location.pathname===new URL(policyLinkEl.href).pathname){this.toggleEl=wUtils.cloneContentEls(`
            <button class="o_cookies_bar_toggle btn btn-info btn-sm rounded-circle d-flex gap-2 align-items-center position-fixed pe-auto">
                <i class="fa fa-eye" alt="" aria-hidden="true"></i> <span class="o_cookies_bar_toggle_label"></span>
            </button>
            `).firstElementChild;this.el.insertAdjacentElement("beforebegin",this.toggleEl);this._toggleCookiesBar();this._onToggleCookiesBar=this._toggleCookiesBar.bind(this);this.toggleEl.addEventListener("click",this._onToggleCookiesBar);}},_toggleCookiesBar(){const popupEl=this.el.querySelector(".modal");$(popupEl).modal("toggle");this._popupAlreadyShown=false;cookie.delete(this.el.id);const hidden=!popupEl.classList.contains("show");this.toggleEl.querySelector(".fa").className=`fa ${hidden ? "fa-eye" : "fa-eye-slash"}`;this.toggleEl.querySelector(".o_cookies_bar_toggle_label").innerText=hidden?_t("Show the cookies bar"):_t("Hide the cookies bar");if(hidden||!popupEl.classList.contains("s_popup_bottom")){this.toggleEl.style.removeProperty("--cookies-bar-toggle-inset-block-end");}else{wUtils.onceAllImagesLoaded($(popupEl)).then(()=>{const popupHeight=popupEl.querySelector(".modal-content").offsetHeight;const toggleMargin=8;const bottom=document.body.offsetHeight>popupHeight+this.toggleEl.offsetHeight+toggleMargin?`calc(
                        ${getComputedStyle(popupEl.querySelector(".modal-dialog")).paddingBottom}
                        + ${popupHeight + toggleMargin}px
                    )`:"";this.toggleEl.style.setProperty("--cookies-bar-toggle-inset-block-end",bottom);});}},_onAcceptClick(ev){const isFullConsent=ev.target.id==="cookies-consent-all";this.cookieValue=`{"required": true, "optional": ${isFullConsent}}`;if(isFullConsent){document.dispatchEvent(new Event("optionalCookiesAccepted"));}
this._onHideModal();this.toggleEl&&this.toggleEl.remove();},_onHideModal(){this._super(...arguments);const params=new URLSearchParams(window.location.search);const trackingFields={utm_campaign:"odoo_utm_campaign",utm_source:"odoo_utm_source",utm_medium:"odoo_utm_medium",};for(const[key,value]of params){if(key in trackingFields){cookie.set(trackingFields[key],value,31*24*60*60,"optional");}}
setUtmsHtmlDataset();}});__exports[Symbol.for("default")]=PopupWidget;return __exports;});;

/* /website/static/src/snippets/s_table_of_content/000.js */
odoo.define('@website/snippets/s_table_of_content/000',['@web/legacy/js/public/public_widget','@website/js/content/menu'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{extraMenuUpdateCallbacks}=require("@website/js/content/menu");const TableOfContent=publicWidget.Widget.extend({selector:'section .s_table_of_content_navbar_sticky',disabledInEditableMode:false,async start(){this._stripNavbarStyles();await this._super(...arguments);this.$scrollingElement=this.$target.closest(".s_table_of_content").closestScrollable();this.$scrollingTarget=$().getScrollingTarget(this.$scrollingElement);this.previousPosition=-1;this._updateTableOfContentNavbarPosition();this._updateTableOfContentNavbarPositionBound=this._updateTableOfContentNavbarPosition.bind(this);extraMenuUpdateCallbacks.push(this._updateTableOfContentNavbarPositionBound);},destroy(){const indexCallback=extraMenuUpdateCallbacks.indexOf(this._updateTableOfContentNavbarPositionBound);if(indexCallback>=0){extraMenuUpdateCallbacks.splice(indexCallback,1);}
this.$el.css('top','');this.$el.find('.s_table_of_content_navbar').css({top:'',maxHeight:''});this._super(...arguments);},_stripNavbarStyles(){for(let el of this.el.querySelectorAll('.s_table_of_content_navbar .table_of_content_link')){const translationEl=el.querySelector('span[data-oe-translation-state]');if(translationEl){el=translationEl;}
const text=el.textContent;el.textContent=text;}},_updateTableOfContentNavbarPosition(){if(!this.el.querySelector('a.table_of_content_link')){return;}
let position=0;const $fixedElements=$('.o_top_fixed_element');$fixedElements.toArray().forEach((el)=>position+=$(el).outerHeight());const isHorizontalNavbar=this.$el.hasClass('s_table_of_content_horizontal_navbar');this.$el.css('top',isHorizontalNavbar?position:'');this.$el.find('.s_table_of_content_navbar').css('top',isHorizontalNavbar?'':position+20);position+=isHorizontalNavbar?this.$el.outerHeight():0;this.$el.find('.s_table_of_content_navbar').css('maxHeight',isHorizontalNavbar?'':`calc(100vh - ${position + 40}px)`);if(this.previousPosition!==position){const target=this.$scrollingTarget[0];new ScrollSpy(target instanceof Window?target.document.body:target,{target:this.$el.find('.s_table_of_content_navbar'),method:'offset',offset:position+100,alwaysKeepFirstActive:true});this.previousPosition=position;}},});publicWidget.registry.anchorSlide.include({_computeExtraOffset(){let extraOffset=this._super(...arguments);if(this.$el.hasClass('table_of_content_link')){const tableOfContentNavbarEl=this.$el.closest('.s_table_of_content_navbar_sticky.s_table_of_content_horizontal_navbar');if(tableOfContentNavbarEl.length>0){extraOffset+=$(tableOfContentNavbarEl).outerHeight();}}
return extraOffset;},});publicWidget.registry.snippetTableOfContent=TableOfContent;__exports[Symbol.for("default")]=TableOfContent;return __exports;});;

/* /website/static/src/snippets/s_chart/000.js */
odoo.define('@website/snippets/s_chart/000',['@web/core/assets','@web/legacy/js/public/public_widget','@web_editor/js/common/utils'],function(require){'use strict';let __exports={};const{loadBundle}=require("@web/core/assets");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const weUtils=require("@web_editor/js/common/utils")[Symbol.for("default")];const ChartWidget=publicWidget.Widget.extend({selector:'.s_chart',disabledInEditableMode:false,init:function(parent,options){this._super.apply(this,arguments);this.style=window.getComputedStyle(document.documentElement);},start:function(){const data=JSON.parse(this.el.dataset.data);data.datasets.forEach(el=>{if(Array.isArray(el.backgroundColor)){el.backgroundColor=el.backgroundColor.map(el=>this._convertToCssColor(el));el.borderColor=el.borderColor.map(el=>this._convertToCssColor(el));}else{el.backgroundColor=this._convertToCssColor(el.backgroundColor);el.borderColor=this._convertToCssColor(el.borderColor);}
el.borderWidth=this.el.dataset.borderWidth;});const radialAxis={beginAtZero:true,};const linearAxis={type:"linear",stacked:this.el.dataset.stacked==="true",beginAtZero:true,min:parseInt(this.el.dataset.ticksMin),max:parseInt(this.el.dataset.ticksMax),};const categoryAxis={type:"category",};const chartData={type:this.el.dataset.type,data:data,options:{plugins:{legend:{display:this.el.dataset.legendPosition!=='none',position:this.el.dataset.legendPosition,},tooltip:{enabled:this.el.dataset.tooltipDisplay==='true',position:"custom",},title:{display:!!this.el.dataset.title,text:this.el.dataset.title,},},scales:{x:categoryAxis,y:linearAxis,},aspectRatio:2,},};if(this.el.dataset.type==='radar'){chartData.options.scales={r:radialAxis,};}else if(this.el.dataset.type==="horizontalBar"){chartData.type="bar";chartData.options.scales={x:linearAxis,y:categoryAxis,};chartData.options.indexAxis="y";}else if(['pie','doughnut'].includes(this.el.dataset.type)){chartData.options.scales={};chartData.options.plugins.tooltip.callbacks={label:(tooltipItem)=>{const label=tooltipItem.label;const secondLabel=tooltipItem.dataset.label;let final=label;if(label){if(secondLabel){final=label+' - '+secondLabel;}}else if(secondLabel){final=secondLabel;}
return final+':'+tooltipItem.formattedValue;},};}
if(this.editableMode){chartData.options.animation={duration:0,};}
const canvas=this.el.querySelector('canvas');window.Chart.Tooltip.positioners.custom=(elements,eventPosition)=>eventPosition;this.chart=new window.Chart(canvas,chartData);return this._super.apply(this,arguments);},willStart:async function(){await loadBundle("web.chartjs_lib");},destroy:function(){if(this.chart){this.chart.destroy();this.el.querySelectorAll('.chartjs-size-monitor').forEach(el=>el.remove());}
this._super.apply(this,arguments);},_convertToCssColor:function(color){if(!color){return'transparent';}
return weUtils.getCSSVariableValue(color,this.style)||color;},});publicWidget.registry.chart=ChartWidget;__exports[Symbol.for("default")]=ChartWidget;return __exports;});;

/* /website/static/src/snippets/s_google_map/000.js */
odoo.define('@website/snippets/s_google_map/000',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];publicWidget.registry.GoogleMap=publicWidget.Widget.extend({selector:'.s_google_map',disabledInEditableMode:false,mapColors:{lightMonoMap:[{"featureType":"administrative.locality","elementType":"all","stylers":[{"hue":"#2c2e33"},{"saturation":7},{"lightness":19},{"visibility":"on"}]},{"featureType":"landscape","elementType":"all","stylers":[{"hue":"#ffffff"},{"saturation":-100},{"lightness":100},{"visibility":"simplified"}]},{"featureType":"poi","elementType":"all","stylers":[{"hue":"#ffffff"},{"saturation":-100},{"lightness":100},{"visibility":"off"}]},{"featureType":"road","elementType":"geometry","stylers":[{"hue":"#bbc0c4"},{"saturation":-93},{"lightness":31},{"visibility":"simplified"}]},{"featureType":"road","elementType":"labels","stylers":[{"hue":"#bbc0c4"},{"saturation":-93},{"lightness":31},{"visibility":"on"}]},{"featureType":"road.arterial","elementType":"labels","stylers":[{"hue":"#bbc0c4"},{"saturation":-93},{"lightness":-2},{"visibility":"simplified"}]},{"featureType":"road.local","elementType":"geometry","stylers":[{"hue":"#e9ebed"},{"saturation":-90},{"lightness":-8},{"visibility":"simplified"}]},{"featureType":"transit","elementType":"all","stylers":[{"hue":"#e9ebed"},{"saturation":10},{"lightness":69},{"visibility":"on"}]},{"featureType":"water","elementType":"all","stylers":[{"hue":"#e9ebed"},{"saturation":-78},{"lightness":67},{"visibility":"simplified"}]}],lillaMap:[{elementType:"labels",stylers:[{saturation:-20}]},{featureType:"poi",elementType:"labels",stylers:[{visibility:"off"}]},{featureType:'road.highway',elementType:'labels',stylers:[{visibility:"off"}]},{featureType:"road.local",elementType:"labels.icon",stylers:[{visibility:"off"}]},{featureType:"road.arterial",elementType:"labels.icon",stylers:[{visibility:"off"}]},{featureType:"road",elementType:"geometry.stroke",stylers:[{visibility:"off"}]},{featureType:"transit",elementType:"geometry.fill",stylers:[{hue:'#2d313f'},{visibility:"on"},{lightness:5},{saturation:-20}]},{featureType:"poi",elementType:"geometry.fill",stylers:[{hue:'#2d313f'},{visibility:"on"},{lightness:5},{saturation:-20}]},{featureType:"poi.government",elementType:"geometry.fill",stylers:[{hue:'#2d313f'},{visibility:"on"},{lightness:5},{saturation:-20}]},{featureType:"poi.sport_complex",elementType:"geometry.fill",stylers:[{hue:'#2d313f'},{visibility:"on"},{lightness:5},{saturation:-20}]},{featureType:"poi.attraction",elementType:"geometry.fill",stylers:[{hue:'#2d313f'},{visibility:"on"},{lightness:5},{saturation:-20}]},{featureType:"poi.business",elementType:"geometry.fill",stylers:[{hue:'#2d313f'},{visibility:"on"},{lightness:5},{saturation:-20}]},{featureType:"transit",elementType:"geometry.fill",stylers:[{hue:'#2d313f'},{visibility:"on"},{lightness:5},{saturation:-20}]},{featureType:"transit.station",elementType:"geometry.fill",stylers:[{hue:'#2d313f'},{visibility:"on"},{lightness:5},{saturation:-20}]},{featureType:"landscape",stylers:[{hue:'#2d313f'},{visibility:"on"},{lightness:5},{saturation:-20}]},{featureType:"road",elementType:"geometry.fill",stylers:[{hue:'#2d313f'},{visibility:"on"},{lightness:5},{saturation:-20}]},{featureType:"road.highway",elementType:"geometry.fill",stylers:[{hue:'#2d313f'},{visibility:"on"},{lightness:5},{saturation:-20}]},{featureType:"water",elementType:"geometry",stylers:[{hue:'#2d313f'},{visibility:"on"},{lightness:5},{saturation:-20}]}],blueMap:[{stylers:[{hue:"#00ffe6"},{saturation:-20}]},{featureType:"road",elementType:"geometry",stylers:[{lightness:100},{visibility:"simplified"}]},{featureType:"road",elementType:"labels",stylers:[{visibility:"off"}]}],retroMap:[{"featureType":"administrative","elementType":"all","stylers":[{"visibility":"on"},{"lightness":33}]},{"featureType":"landscape","elementType":"all","stylers":[{"color":"#f2e5d4"}]},{"featureType":"poi.park","elementType":"geometry","stylers":[{"color":"#c5dac6"}]},{"featureType":"poi.park","elementType":"labels","stylers":[{"visibility":"on"},{"lightness":20}]},{"featureType":"road","elementType":"all","stylers":[{"lightness":20}]},{"featureType":"road.highway","elementType":"geometry","stylers":[{"color":"#c5c6c6"}]},{"featureType":"road.arterial","elementType":"geometry","stylers":[{"color":"#e4d7c6"}]},{"featureType":"road.local","elementType":"geometry","stylers":[{"color":"#fbfaf7"}]},{"featureType":"water","elementType":"all","stylers":[{"visibility":"on"},{"color":"#acbcc9"}]}],flatMap:[{"stylers":[{"visibility":"off"}]},{"featureType":"road","stylers":[{"visibility":"on"},{"color":"#ffffff"}]},{"featureType":"road.arterial","stylers":[{"visibility":"on"},{"color":"#fee379"}]},{"featureType":"road.highway","stylers":[{"visibility":"on"},{"color":"#fee379"}]},{"featureType":"landscape","stylers":[{"visibility":"on"},{"color":"#f3f4f4"}]},{"featureType":"water","stylers":[{"visibility":"on"},{"color":"#7fc8ed"}]},{},{"featureType":"road","elementType":"labels","stylers":[{"visibility":"on"}]},{"featureType":"poi.park","elementType":"geometry.fill","stylers":[{"visibility":"on"},{"color":"#83cead"}]},{"elementType":"labels","stylers":[{"visibility":"on"}]},{"featureType":"landscape.man_made","elementType":"geometry","stylers":[{"weight":0.9},{"visibility":"off"}]}],cobaltMap:[{"featureType":"all","elementType":"all","stylers":[{"invert_lightness":true},{"saturation":10},{"lightness":30},{"gamma":0.5},{"hue":"#435158"}]}],cupertinoMap:[{"featureType":"water","elementType":"geometry","stylers":[{"color":"#a2daf2"}]},{"featureType":"landscape.man_made","elementType":"geometry","stylers":[{"color":"#f7f1df"}]},{"featureType":"landscape.natural","elementType":"geometry","stylers":[{"color":"#d0e3b4"}]},{"featureType":"landscape.natural.terrain","elementType":"geometry","stylers":[{"visibility":"off"}]},{"featureType":"poi.park","elementType":"geometry","stylers":[{"color":"#bde6ab"}]},{"featureType":"poi","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"poi.medical","elementType":"geometry","stylers":[{"color":"#fbd3da"}]},{"featureType":"poi.business","stylers":[{"visibility":"off"}]},{"featureType":"road","elementType":"geometry.stroke","stylers":[{"visibility":"off"}]},{"featureType":"road","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"road.highway","elementType":"geometry.fill","stylers":[{"color":"#ffe15f"}]},{"featureType":"road.highway","elementType":"geometry.stroke","stylers":[{"color":"#efd151"}]},{"featureType":"road.arterial","elementType":"geometry.fill","stylers":[{"color":"#ffffff"}]},{"featureType":"road.local","elementType":"geometry.fill","stylers":[{"color":"black"}]},{"featureType":"transit.station.airport","elementType":"geometry.fill","stylers":[{"color":"#cfb2db"}]}],carMap:[{"featureType":"administrative","stylers":[{"visibility":"off"}]},{"featureType":"poi","stylers":[{"visibility":"simplified"}]},{"featureType":"road","stylers":[{"visibility":"simplified"}]},{"featureType":"water","stylers":[{"visibility":"simplified"}]},{"featureType":"transit","stylers":[{"visibility":"simplified"}]},{"featureType":"landscape","stylers":[{"visibility":"simplified"}]},{"featureType":"road.highway","stylers":[{"visibility":"off"}]},{"featureType":"road.local","stylers":[{"visibility":"on"}]},{"featureType":"road.highway","elementType":"geometry","stylers":[{"visibility":"on"}]},{"featureType":"water","stylers":[{"color":"#84afa3"},{"lightness":52}]},{"stylers":[{"saturation":-77}]},{"featureType":"road"}],bwMap:[{stylers:[{hue:"#00ffe6"},{saturation:-100}]},{featureType:"road",elementType:"geometry",stylers:[{lightness:100},{visibility:"simplified"}]},{featureType:"road",elementType:"labels",stylers:[{visibility:"off"}]}],},async start(){await this._super(...arguments);if(typeof google!=='object'||typeof google.maps!=='object'){await new Promise(resolve=>{this.trigger_up('gmap_api_request',{editableMode:this.editableMode,onSuccess:()=>resolve(),});});return;}
const std=[];new google.maps.StyledMapType(std,{name:"Std Map"});const myOptions={zoom:12,center:new google.maps.LatLng(50.854975,4.3753899),mapTypeId:google.maps.MapTypeId.ROADMAP,panControl:false,zoomControl:false,mapTypeControl:false,streetViewControl:false,scrollwheel:false,mapTypeControlOptions:{mapTypeIds:[google.maps.MapTypeId.ROADMAP,'map_style']}};const mapC=this.$('.map_container');const map=new google.maps.Map(mapC.get(0),myOptions);const p=this.el.dataset.mapGps.substring(1).slice(0,-1).split(',');const gps=new google.maps.LatLng(p[0],p[1]);map.setCenter(gps);window.addEventListener('resize',()=>{map.setCenter(gps);});const markerOptions={map:map,animation:google.maps.Animation.DROP,position:new google.maps.LatLng(p[0],p[1])};if(this.el.dataset.pinStyle==='flat'){markerOptions.icon='/website/static/src/img/snippets_thumbs/s_google_map_marker.png';}
new google.maps.Marker(markerOptions);map.setMapTypeId(google.maps.MapTypeId[this.el.dataset.mapType]);map.setZoom(parseInt(this.el.dataset.mapZoom));const mapColorAttr=this.el.dataset.mapColor;if(mapColorAttr){const mapColor=this.mapColors[mapColorAttr];map.mapTypes.set('map_style',new google.maps.StyledMapType(mapColor,{name:"Styled Map"}));map.setMapTypeId('map_style');}},});return __exports;});;

/* /website/static/src/snippets/s_dynamic_snippet/000.js */
odoo.define('@website/snippets/s_dynamic_snippet/000',['@web/legacy/js/public/public_widget','@web/core/utils/functions','@web/core/utils/render','@web/core/ui/ui_service','@odoo/owl'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const{uniqueId}=require("@web/core/utils/functions");const{renderToString}=require("@web/core/utils/render");const{listenSizeChange,utils:uiUtils}=require("@web/core/ui/ui_service");const{markup}=require("@odoo/owl");const DEFAULT_NUMBER_OF_ELEMENTS=4;const DEFAULT_NUMBER_OF_ELEMENTS_SM=1;const DynamicSnippet=publicWidget.Widget.extend({selector:'.s_dynamic_snippet',read_events:{'click [data-url]':'_onCallToAction',},disabledInEditableMode:false,init:function(){this._super.apply(this,arguments);this.data=[];this.renderedContent='';this.isDesplayedAsMobile=uiUtils.isSmall();this.unique_id=uniqueId("s_dynamic_snippet_");this.template_key='website.s_dynamic_snippet.grid';this.rpc=this.bindService("rpc");},willStart:function(){return this._super.apply(this,arguments).then(()=>Promise.all([this._fetchData(),]));},start:function(){return this._super.apply(this,arguments).then(()=>{this._setupSizeChangedManagement(true);this.options.wysiwyg&&this.options.wysiwyg.odooEditor.observerUnactive();this._render();this.options.wysiwyg&&this.options.wysiwyg.odooEditor.observerActive();});},destroy:function(){this.options.wysiwyg&&this.options.wysiwyg.odooEditor.observerUnactive();this._toggleVisibility(false);this._setupSizeChangedManagement(false);this._clearContent();this.options.wysiwyg&&this.options.wysiwyg.odooEditor.observerActive();this._super.apply(this,arguments);},_clearContent:function(){const $templateArea=this.$el.find('.dynamic_snippet_template');this.trigger_up('widgets_stop_request',{$target:$templateArea,});$templateArea.html('');},_isConfigComplete:function(){return this.$el.get(0).dataset.filterId!==undefined&&this.$el.get(0).dataset.templateKey!==undefined;},_getSearchDomain:function(){return[];},_getRpcParameters:function(){return{};},async _fetchData(){if(this._isConfigComplete()){const nodeData=this.el.dataset;const filterFragments=await this.rpc('/website/snippet/filters',Object.assign({'filter_id':parseInt(nodeData.filterId),'template_key':nodeData.templateKey,'limit':parseInt(nodeData.numberOfRecords),'search_domain':this._getSearchDomain(),'with_sample':this.editableMode,},this._getRpcParameters()));this.data=filterFragments.map(markup);}else{this.data=[];}},_prepareContent:function(){this.renderedContent=renderToString(this.template_key,this._getQWebRenderOptions());},_getQWebRenderOptions:function(){const dataset=this.el.dataset;const numberOfRecords=parseInt(dataset.numberOfRecords);let numberOfElements;if(uiUtils.isSmall()){numberOfElements=parseInt(dataset.numberOfElementsSmallDevices)||DEFAULT_NUMBER_OF_ELEMENTS_SM;}else{numberOfElements=parseInt(dataset.numberOfElements)||DEFAULT_NUMBER_OF_ELEMENTS;}
const chunkSize=numberOfRecords<numberOfElements?numberOfRecords:numberOfElements;return{chunkSize:chunkSize,data:this.data,unique_id:this.unique_id,extraClasses:dataset.extraClasses||'',};},_render:function(){if(this.data.length>0||this.editableMode){this.$el.removeClass('o_dynamic_empty');this._prepareContent();}else{this.$el.addClass('o_dynamic_empty');this.renderedContent='';}
this._renderContent();this.trigger_up('widgets_start_request',{$target:this.$el.children(),options:{parent:this},editableMode:this.editableMode,});},_renderContent:function(){const $templateArea=this.$el.find('.dynamic_snippet_template');this.trigger_up('widgets_stop_request',{$target:$templateArea,});$templateArea.html(this.renderedContent);this.trigger_up('widgets_start_request',{$target:$templateArea,editableMode:this.editableMode,});},_setupSizeChangedManagement:function(enable){if(enable===true){this.removeSizeListener=listenSizeChange(this._onSizeChanged.bind(this));}else if(this.removeSizeListener){this.removeSizeListener();delete this.removeSizeListener;}},_toggleVisibility:function(visible){this.$el.toggleClass('o_dynamic_empty',!visible);},_onCallToAction:function(ev){window.location=$(ev.currentTarget).attr('data-url');},_onSizeChanged:function(){if(this.isDesplayedAsMobile!==uiUtils.isSmall()){this.isDesplayedAsMobile=uiUtils.isSmall();this._render();}},});publicWidget.registry.dynamic_snippet=DynamicSnippet;__exports[Symbol.for("default")]=DynamicSnippet;return __exports;});;

/* /website/static/src/snippets/s_dynamic_snippet_carousel/000.js */
odoo.define('@website/snippets/s_dynamic_snippet_carousel/000',['@web/legacy/js/public/public_widget','@website/snippets/s_dynamic_snippet/000','@web/core/ui/ui_service'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const DynamicSnippet=require("@website/snippets/s_dynamic_snippet/000")[Symbol.for("default")];const{utils:uiUtils}=require("@web/core/ui/ui_service");const DynamicSnippetCarousel=DynamicSnippet.extend({selector:'.s_dynamic_snippet_carousel',init:function(){this._super.apply(this,arguments);this.template_key='website.s_dynamic_snippet.carousel';},_getQWebRenderOptions:function(){return Object.assign(this._super.apply(this,arguments),{interval:parseInt(this.el.dataset.carouselInterval),rowPerSlide:parseInt(uiUtils.isSmall()?1:this.el.dataset.rowPerSlide||1),arrowPosition:this.el.dataset.arrowPosition||'',},);},});publicWidget.registry.dynamic_snippet_carousel=DynamicSnippetCarousel;__exports[Symbol.for("default")]=DynamicSnippetCarousel;return __exports;});;

/* /website/static/src/snippets/s_website_form/000.js */
odoo.define('@website/snippets/s_website_form/000',['@google_recaptcha/js/recaptcha','@web/session','@web/legacy/js/public/public_widget','@web/legacy/js/core/dom','@web/core/utils/concurrency','@web/core/utils/timing','@web/core/l10n/translation','@web/core/utils/render','@web/core/network/http_service','@web/core/l10n/localization','@web/core/l10n/dates','@website/js/utils'],function(require){'use strict';let __exports={};const{ReCaptcha}=require("@google_recaptcha/js/recaptcha");const{session}=require("@web/session");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const dom=require("@web/legacy/js/core/dom")[Symbol.for("default")];const{delay}=require("@web/core/utils/concurrency");const{debounce}=require("@web/core/utils/timing");const{_t}=require("@web/core/l10n/translation");const{renderToElement}=require("@web/core/utils/render");const{post}=require("@web/core/network/http_service");const{localization}=require("@web/core/l10n/localization");const{formatDate,formatDateTime,parseDate,parseDateTime,serializeDate,serializeDateTime,}=require("@web/core/l10n/dates");const{DateTime}=luxon;const wUtils=require('@website/js/utils')[Symbol.for("default")];publicWidget.registry.EditModeWebsiteForm=publicWidget.Widget.extend({selector:'.s_website_form form, form.s_website_form',disabledInEditableMode:false,start:function(){if(this.editableMode){this.el.querySelectorAll('.s_website_form_input.datetimepicker-input').forEach(el=>{const value=el.getAttribute('value');if(value){const format=el.closest(".s_website_form_field").dataset.type==="date"?formatDate:formatDateTime;el.value=format(DateTime.fromSeconds(parseInt(value)));}});}
return this._super(...arguments);},});publicWidget.registry.s_website_form=publicWidget.Widget.extend({selector:'.s_website_form form, form.s_website_form',events:{'click .s_website_form_send, .o_website_form_send':'send','submit':'send',"change input[type=file]":"_onFileChange","click input.o_add_files_button":"_onAddFilesButtonClick","click .o_file_delete":"_onFileDeleteClick",},init:function(){this._super(...arguments);this._recaptcha=new ReCaptcha();this.initialValues=new Map();this._visibilityFunctionByFieldName=new Map();this._visibilityFunctionByFieldEl=new Map();this.__started=new Promise(resolve=>this.__startResolve=resolve);this.orm=this.bindService("orm");},willStart:async function(){const res=this._super(...arguments);if(!this.el.classList.contains('s_website_form_no_recaptcha')){this._recaptchaLoaded=true;this._recaptcha.loadLibs();}
this.preFillValues={};if(session.user_id){this.preFillValues=(await this.orm.read("res.users",[session.user_id],this._getUserPreFillFields()))[0]||{};}
return res;},start:function(){this.resetForm();const visibilityFunctionsByFieldName=new Map();for(const fieldEl of this.el.querySelectorAll('[data-visibility-dependency]')){const inputName=fieldEl.querySelector('.s_website_form_input').name;if(!visibilityFunctionsByFieldName.has(inputName)){visibilityFunctionsByFieldName.set(inputName,[]);}
const func=this._buildVisibilityFunction(fieldEl);visibilityFunctionsByFieldName.get(inputName).push(func);this._visibilityFunctionByFieldEl.set(fieldEl,func);}
for(const[name,funcs]of visibilityFunctionsByFieldName.entries()){this._visibilityFunctionByFieldName.set(name,()=>funcs.some(func=>func()));}
this._onFieldInputDebounced=debounce(this._onFieldInput.bind(this),400);this.$el.on('input.s_website_form','.s_website_form_field',this._onFieldInputDebounced);this.$allDates=this.$el.find('.s_website_form_datetime, .o_website_form_datetime, .s_website_form_date, .o_website_form_date');for(const field of this.$allDates){const input=field.querySelector("input");const defaultValue=input.getAttribute("value");this.call("datetime_picker","create",{target:input,onChange:()=>input.dispatchEvent(new Event("input",{bubbles:true})),pickerProps:{type:field.matches('.s_website_form_date, .o_website_form_date')?'date':'datetime',value:defaultValue&&DateTime.fromSeconds(parseInt(defaultValue)),},}).enable();}
this.$allDates.addClass('s_website_form_datepicker_initialized');let dataForValues=wUtils.getParsedDataFor(this.el.id,document);this.editTranslations=!!this._getContext(true).edit_translations;if(!this.editTranslations&&(dataForValues||Object.keys(this.preFillValues).length)){dataForValues=dataForValues||{};const fieldNames=this.$target.serializeArray().map(el=>el.name);for(const name of fieldNames){const fieldEl=this.el.querySelector(`[name="${CSS.escape(name)}"]`);if(name==='email_to'&&fieldEl.value&&fieldEl.value!=='info@yourcompany.example.com'){continue;}
let newValue;if(dataForValues&&dataForValues[name]){newValue=dataForValues[name];}else if(this.preFillValues[fieldEl.dataset.fillWith]){newValue=this.preFillValues[fieldEl.dataset.fillWith];}
if(newValue){this.initialValues.set(fieldEl,fieldEl.getAttribute('value'));fieldEl.value=newValue;}}}
this._updateFieldsVisibility();if(session.geoip_phone_code){this.el.querySelectorAll('input[type="tel"]').forEach(telField=>{if(!telField.value){telField.value='+'+session.geoip_phone_code;}});}
this.inputEls=this.el.querySelectorAll('.s_website_form_field.s_website_form_field_hidden_if .s_website_form_input');this._disabledStates=new Map();for(const inputEl of this.inputEls){this._disabledStates[inputEl]=inputEl.disabled;}
this.el.querySelectorAll("input[type=file]").forEach(inputEl=>{const filesZoneEl=document.createElement("DIV");filesZoneEl.classList.add("o_files_zone","row","gx-1");inputEl.parentNode.insertBefore(filesZoneEl,inputEl);});return this._super(...arguments).then(()=>this.__startResolve());},destroy:function(){this._super.apply(this,arguments);this.$el.find('button').off('click');this.resetForm();this.el.querySelectorAll('input[type="text"], input[type="email"], input[type="number"]').forEach(el=>{let value=el.getAttribute('value');if(value){if(el.classList.contains('datetimepicker-input')){const format=el.closest(".s_website_form_field").dataset.type==="date"?formatDate:formatDateTime;value=format(DateTime.fromSeconds(parseInt(value)));}
el.value=value;}});this.el.querySelectorAll('textarea').forEach(el=>el.value=el.textContent);this.$el.find('.o_has_error').removeClass('o_has_error').find('.form-control, .form-select').removeClass('is-invalid');this.$el.find('#s_website_form_result, #o_website_form_result').empty();this.$el.removeClass('d-none');this.$el.parent().find('.s_website_form_end_message').addClass('d-none');this.$allDates.removeClass('s_website_form_datepicker_initialized');for(const inputEl of this.inputEls){inputEl.disabled=!!this._disabledStates.get(inputEl);}
this.el.querySelectorAll('.s_website_form_field_hidden_if:not(.d-none)').forEach(el=>el.classList.add('d-none'));for(const[fieldEl,initialValue]of this.initialValues.entries()){if(initialValue){fieldEl.setAttribute('value',initialValue);}else{fieldEl.removeAttribute('value');}}
this.$el.off('.s_website_form');},send:async function(e){e.preventDefault();const $button=this.$el.find('.s_website_form_send, .o_website_form_send');$button.addClass('disabled').attr('disabled','disabled');this.restoreBtnLoading=dom.addButtonLoadingEffect($button[0]);var self=this;self.$el.find('#s_website_form_result, #o_website_form_result').empty();if(!self.check_error_fields({})){if(this.fileInputError){const errorMessage=this.fileInputError.type==="number"?_t("Please fill in the form correctly. You uploaded too many files. (Maximum %s files)",this.fileInputError.limit):_t("Please fill in the form correctly. The file \"%s\" is too big. (Maximum %s MB)",this.fileInputError.fileName,this.fileInputError.limit);this.update_status("error",errorMessage);delete this.fileInputError;}else{this.update_status("error",_t("Please fill in the form correctly."));}
return false;}
this.form_fields=this.$el.serializeArray();$.each(this.$el.find('input[type=file]:not([disabled])'),(outer_index,input)=>{$.each($(input).prop('files'),function(index,file){self.form_fields.push({name:input.name+'['+outer_index+']['+index+']',value:file});});});var form_values={};this.form_fields.forEach((input)=>{if(input.name in form_values){if(Array.isArray(form_values[input.name])){form_values[input.name].push(input.value);}else{form_values[input.name]=[form_values[input.name],input.value];}}else{if(input.value!==''){form_values[input.name]=input.value;}}});this.$el.find('.s_website_form_field:not(.s_website_form_custom)').find('.s_website_form_date, .s_website_form_datetime').each(function(){const inputEl=this.querySelector('input');const{value}=inputEl;if(!value){return;}
form_values[inputEl.getAttribute("name")]=this.matches(".s_website_form_date")?serializeDate(parseDate(value)):serializeDateTime(parseDateTime(value));});if(this._recaptchaLoaded){const tokenObj=await this._recaptcha.getToken('website_form');if(tokenObj.token){form_values['recaptcha_token_response']=tokenObj.token;}else if(tokenObj.error){self.update_status('error',tokenObj.error);return false;}}
if(odoo.csrf_token){form_values.csrf_token=odoo.csrf_token;}
const formData=new FormData();for(const[key,value]of Object.entries(form_values)){formData.append(key,value);}
post(this.$el.attr('action')+(this.$el.data('force_action')||this.$el.data('model_name')),formData).then(async function(result_data){self.$el.find('.s_website_form_send, .o_website_form_send').removeAttr('disabled').removeClass('disabled');if(!result_data.id){self.update_status('error',result_data.error?result_data.error:false);if(result_data.error_fields){self.check_error_fields(result_data.error_fields);}}else{let successMode=self.el.dataset.successMode;let successPage=self.el.dataset.successPage;if(!successMode){successPage=self.$el.attr('data-success_page');successMode=successPage?'redirect':'nothing';}
switch(successMode){case'redirect':{let hashIndex=successPage.indexOf("#");if(hashIndex>0){let currentUrlPath=window.location.pathname;if(!currentUrlPath.endsWith("/")){currentUrlPath=currentUrlPath+"/";}
if(!successPage.includes("/#")){successPage=successPage.replace("#","/#");hashIndex++;}
if([successPage,"/"+session.lang_url_code+successPage].some(link=>link.startsWith(currentUrlPath+'#'))){successPage=successPage.substring(hashIndex);}}
if(successPage.charAt(0)==="#"){const successAnchorEl=document.getElementById(successPage.substring(1));if(successAnchorEl){if(successAnchorEl.classList.contains("modal")){window.location.href=successPage;}else{await dom.scrollTo(successAnchorEl,{duration:500,extraOffset:0,});}}
break;}
$(window.location).attr('href',successPage);return;}
case'message':{await delay(dom.DEBOUNCE);self.el.classList.add('d-none');self.el.parentElement.querySelector('.s_website_form_end_message').classList.remove('d-none');break;}
default:{await delay(dom.DEBOUNCE);self.update_status('success');break;}}
self.resetForm();self.restoreBtnLoading();}}).catch(error=>{this.update_status('error',error.status&&error.status===413?_t("Uploaded file is too large."):"",);});},resetForm(){this.el.reset();this.el.querySelectorAll("input[type=file]").forEach(inputEl=>{const fieldEl=inputEl.closest(".s_website_form_field");fieldEl.querySelectorAll(".o_files_zone").forEach(el=>el.remove());fieldEl.querySelectorAll(".o_add_files_button").forEach(el=>el.remove());inputEl.classList.remove("d-none");delete inputEl.fileList;});},check_error_fields:function(error_fields){var self=this;var form_valid=true;this.$el.find('.form-field, .s_website_form_field').each(function(k,field){var $field=$(field);var field_name=$field.find('.col-form-label').attr('for');var inputs=$field.find('.s_website_form_input, .o_website_form_input').not('#editable_select');var invalid_inputs=inputs.toArray().filter(function(input,k,inputs){if(input.required&&input.type==='checkbox'){var checkboxes=inputs.filter(input=>input.required&&input.type==='checkbox');return!checkboxes.some((checkbox)=>checkbox.checkValidity());}else if($(input).hasClass('s_website_form_date')||$(input).hasClass('o_website_form_date')){const date=parseDate(input.value);if(!date||!date.isValid){return true;}}else if($(input).hasClass('s_website_form_datetime')||$(input).hasClass('o_website_form_datetime')){const date=parseDateTime(input.value);if(!date||!date.isValid){return true;}}else if(input.type==="file"&&!self.isFileInputValid(input)){return true;}
return!input.checkValidity();});const $controls=$field.find('.form-control, .form-select, .form-check-input');$field.removeClass('o_has_error');$controls.removeClass('is-invalid');if(invalid_inputs.length||error_fields[field_name]){$field.addClass('o_has_error');$controls.addClass('is-invalid');if(typeof error_fields[field_name]==="string"){$field.popover({content:error_fields[field_name],trigger:'hover',container:'body',placement:'top'});const popover=Popover.getInstance($field);popover._config.content=error_fields[field_name];$field.popover('show');}
form_valid=false;}});return form_valid;},update_status:function(status,message){if(status!=='success'){this.$el.find('.s_website_form_send, .o_website_form_send').removeAttr('disabled').removeClass('disabled');this.restoreBtnLoading();}
var $result=this.$('#s_website_form_result, #o_website_form_result');if(status==='error'&&!message){message=_t("An error has occured, the form has not been sent.");}
this.__started.then(()=>$result.replaceWith(renderToElement(`website.s_website_form_status_${status}`,{message:message,})));},isFileInputValid(inputEl){const maxFilesNumber=inputEl.dataset.maxFilesNumber;if(maxFilesNumber&&inputEl.files.length>maxFilesNumber){this.fileInputError={type:"number",limit:maxFilesNumber};return false;}
const maxFileSize=inputEl.dataset.maxFileSize;const bytesInMegabyte=1_000_000;if(maxFileSize){for(const file of Object.values(inputEl.files)){if(file.size/bytesInMegabyte>maxFileSize){this.fileInputError={type:"size",limit:maxFileSize,fileName:file.name};return false;}}}
return true;},_getUserPreFillFields(){return['name','phone','email','commercial_company_name'];},_compareTo(comparator,value='',comparable,between){if(value===null){value='';}
switch(comparator){case'contains':return value.includes(comparable);case'!contains':return!value.includes(comparable);case'equal':case'selected':return value===comparable;case'!equal':case'!selected':return value!==comparable;case'set':return value;case'!set':return!value;case'greater':return parseFloat(value)>parseFloat(comparable);case'less':return parseFloat(value)<parseFloat(comparable);case'greater or equal':return parseFloat(value)>=parseFloat(comparable);case'less or equal':return parseFloat(value)<=parseFloat(comparable);case'fileSet':return value.name!=='';case'!fileSet':return value.name==='';}
const format=value.includes(':')?localization.dateTimeFormat:localization.dateFormat;const dateTime=DateTime.fromFormat(value,format);value=dateTime.isValid?dateTime.toUnixInteger():NaN;comparable=parseInt(comparable);between=parseInt(between)||'';switch(comparator){case'dateEqual':return value===comparable;case'date!equal':return value!==comparable;case'before':return value<comparable;case'after':return value>comparable;case'equal or before':return value<=comparable;case'between':return value>=comparable&&value<=between;case'!between':return!(value>=comparable&&value<=between);case'equal or after':return value>=comparable;}},_buildVisibilityFunction(fieldEl){const visibilityCondition=fieldEl.dataset.visibilityCondition;const dependencyName=fieldEl.dataset.visibilityDependency;const comparator=fieldEl.dataset.visibilityComparator;const between=fieldEl.dataset.visibilityBetween;return()=>{const dependencyVisibilityFunction=this._visibilityFunctionByFieldName.get(dependencyName);const dependencyIsVisible=!dependencyVisibilityFunction||dependencyVisibilityFunction();if(!dependencyIsVisible){return false;}
const formData=new FormData(this.el);const currentValueOfDependency=["contains","!contains"].includes(comparator)?formData.getAll(dependencyName).join():formData.get(dependencyName);return this._compareTo(comparator,currentValueOfDependency,visibilityCondition,between);};},_updateFieldsVisibility(){let anyFieldVisibilityUpdated=false;for(const[fieldEl,visibilityFunction]of this._visibilityFunctionByFieldEl.entries()){const wasVisible=!fieldEl.closest(".s_website_form_field").classList.contains("d-none");const isVisible=!!visibilityFunction();this._updateFieldVisibility(fieldEl,isVisible);anyFieldVisibilityUpdated|=wasVisible!==isVisible;}
if(anyFieldVisibilityUpdated){this._updateFieldsVisibility();}},_updateFieldVisibility(fieldEl,haveToBeVisible){const fieldContainerEl=fieldEl.closest('.s_website_form_field');fieldContainerEl.classList.toggle('d-none',!haveToBeVisible);for(const inputEl of fieldContainerEl.querySelectorAll('.s_website_form_input')){inputEl.disabled=!haveToBeVisible;}},_createFileBlock(fileDetails,filesZoneEl){const fileBlockEl=renderToElement("website.file_block",{fileName:fileDetails.name});fileBlockEl.fileDetails=fileDetails;filesZoneEl.append(fileBlockEl);},_createAddFilesButton(inputEl){const addFilesButtonEl=document.createElement("INPUT");addFilesButtonEl.classList.add("o_add_files_button","form-control");addFilesButtonEl.type="button";addFilesButtonEl.value=inputEl.hasAttribute("multiple")?_t("Add Files"):_t("Replace File");inputEl.parentNode.insertBefore(addFilesButtonEl,inputEl);inputEl.classList.add("d-none");},_onFieldInput(){this._updateFieldsVisibility();},_onFileChange(ev){const fileInputEl=ev.currentTarget;const fieldEl=fileInputEl.closest(".s_website_form_field");const uploadedFiles=fileInputEl.files;const addFilesButtonEl=fieldEl.querySelector(".o_add_files_button");let filesZoneEl=fieldEl.querySelector(".o_files_zone");if(!addFilesButtonEl){this._createAddFilesButton(fileInputEl);}
if(!fileInputEl.fileList){fileInputEl.fileList=new DataTransfer();}
if(!fileInputEl.hasAttribute("multiple")&&uploadedFiles.length>0){fileInputEl.fileList=new DataTransfer();const fileBlockEl=fieldEl.querySelector(".o_file_block");if(fileBlockEl){fileBlockEl.remove();}}
for(const newFile of uploadedFiles){if(![...fileInputEl.fileList.files].some(file=>newFile.name===file.name&&newFile.size===file.size&&newFile.type===file.type)){fileInputEl.fileList.items.add(newFile);const fileDetails={name:newFile.name,size:newFile.size,type:newFile.type};this._createFileBlock(fileDetails,filesZoneEl);}}
fileInputEl.files=fileInputEl.fileList.files;},_onFileDeleteClick(ev){const fileBlockEl=ev.target.closest(".o_file_block");const fieldEl=fileBlockEl.closest(".s_website_form_field");const fileInputEl=fieldEl.querySelector("input[type=file]");const fileDetails=fileBlockEl.fileDetails;const addFilesButtonEl=fieldEl.querySelector(".o_add_files_button");const newFileList=new DataTransfer();for(const file of Object.values(fileInputEl.fileList.files)){if(file.name!==fileDetails.name||file.size!==fileDetails.size||file.type!==fileDetails.type){newFileList.items.add(file);}}
Object.assign(fileInputEl,{fileList:newFileList,files:newFileList.files});fileBlockEl.remove();if(!newFileList.files.length){fileInputEl.classList.remove("d-none");addFilesButtonEl.remove();this._updateFieldsVisibility();}},_onAddFilesButtonClick(ev){const fileInputEl=ev.target.parentNode.querySelector("input[type=file]");fileInputEl.click();},});return __exports;});;

/* /website/static/src/snippets/s_searchbar/000.js */
odoo.define('@website/snippets/s_searchbar/000',['@web/core/utils/concurrency','@web/legacy/js/public/public_widget','@web/core/browser/feature_detection','@web/core/utils/render','@web/core/utils/timing','@odoo/owl'],function(require){'use strict';let __exports={};const{KeepLast}=require("@web/core/utils/concurrency");const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const{isBrowserSafari}=require("@web/core/browser/feature_detection");const{renderToElement,renderToString}=require("@web/core/utils/render");const{debounce}=require('@web/core/utils/timing');const{markup}=require("@odoo/owl");publicWidget.registry.searchBar=publicWidget.Widget.extend({selector:'.o_searchbar_form',events:{'input .search-query':'_onInput','focusout':'_onFocusOut',"mousedown .o_dropdown_menu .dropdown-item":"_onMousedown","mouseup .o_dropdown_menu .dropdown-item":"_onMouseup",'keydown .search-query, .dropdown-item':'_onKeydown','search .search-query':'_onSearch',},autocompleteMinWidth:300,init:function(){this._super.apply(this,arguments);this.keepLast=new KeepLast();this._onInput=debounce(this._onInput,400);this._onFocusOut=debounce(this._onFocusOut,100);this.rpc=this.bindService("rpc");},start:function(){this.$input=this.$('.search-query');this.searchType=this.$input.data('searchType');this.order=this.$('.o_search_order_by').val();this.limit=parseInt(this.$input.data('limit'));this.displayDescription=this.$input.data('displayDescription');this.displayExtraLink=this.$input.data('displayExtraLink');this.displayDetail=this.$input.data('displayDetail');this.displayImage=this.$input.data('displayImage');this.wasEmpty=!this.$input.val();this.allowFuzzy=!this.$input.data('noFuzzy');if(this.limit){this.$input.attr('autocomplete','off');}
this.options={'displayImage':this.displayImage,'displayDescription':this.displayDescription,'displayExtraLink':this.displayExtraLink,'displayDetail':this.displayDetail,'allowFuzzy':this.allowFuzzy,};const form=this.$('.o_search_order_by').parents('form');for(const field of form.find("input[type='hidden']")){this.options[field.name]=field.value;}
const action=form.attr('action')||window.location.pathname+window.location.search;const[urlPath,urlParams]=action.split('?');if(urlParams){for(const keyValue of urlParams.split('&')){const[key,value]=keyValue.split('=');if(value&&key!=='search'){this.options[decodeURIComponent(key.replace(/\+/g,'%20'))]=decodeURIComponent(value.replace(/\+/g,'%20'));}}}
const pathParts=urlPath.split('/');for(const index in pathParts){const value=decodeURIComponent(pathParts[index]);if(index>0&&/-[0-9]+$/.test(value)){this.options[decodeURIComponent(pathParts[index-1])]=value;}}
if(this.$input.data('noFuzzy')){$("<input type='hidden' name='noFuzzy' value='true'/>").appendTo(this.$input);}
return this._super.apply(this,arguments);},destroy(){this._super(...arguments);this._render(null);},_adaptToScrollingParent(){const bcr=this.el.getBoundingClientRect();this.$menu[0].style.setProperty('position','fixed','important');this.$menu[0].style.setProperty('top',`${bcr.bottom}px`,'important');this.$menu[0].style.setProperty('left',`${bcr.left}px`,'important');this.$menu[0].style.setProperty('max-width',`${bcr.width}px`,'important');this.$menu[0].style.setProperty('max-height',`${document.body.clientHeight - bcr.bottom - 16}px`,'important');},async _fetch(){const res=await this.rpc('/website/snippet/autocomplete',{'search_type':this.searchType,'term':this.$input.val(),'order':this.order,'limit':this.limit,'max_nb_chars':Math.round(Math.max(this.autocompleteMinWidth,parseInt(this.$el.width()))*0.22),'options':this.options,});const fieldNames=this._getFieldsNames();res.results.forEach(record=>{for(const fieldName of fieldNames){if(record[fieldName]){record[fieldName]=markup(record[fieldName]);}}});return res;},_render:function(res){if(this._scrollingParentEl){this._scrollingParentEl.removeEventListener('scroll',this._menuScrollAndResizeHandler);window.removeEventListener('resize',this._menuScrollAndResizeHandler);delete this._scrollingParentEl;delete this._menuScrollAndResizeHandler;}
let pageScrollHeight=null;const $prevMenu=this.$menu;if(res&&this.limit){const results=res['results'];let template='website.s_searchbar.autocomplete';const candidate=template+'.'+this.searchType;if(candidate in renderToString.app.rawTemplates){template=candidate;}
this.$menu=$(renderToElement(template,{results:results,parts:res['parts'],hasMoreResults:results.length<res['results_count'],search:this.$input.val(),fuzzySearch:res['fuzzy_search'],widget:this,}));this.$menu.css('min-width',this.autocompleteMinWidth);const megaMenuEl=this.el.closest('.o_mega_menu');if(megaMenuEl){const navbarEl=this.el.closest('.navbar');const navbarTogglerEl=navbarEl?navbarEl.querySelector('.navbar-toggler'):null;if(navbarTogglerEl&&navbarTogglerEl.clientWidth<1){this._scrollingParentEl=megaMenuEl;this._menuScrollAndResizeHandler=()=>this._adaptToScrollingParent();this._scrollingParentEl.addEventListener('scroll',this._menuScrollAndResizeHandler);window.addEventListener('resize',this._menuScrollAndResizeHandler);this._adaptToScrollingParent();}}
pageScrollHeight=document.querySelector("#wrapwrap").scrollHeight;this.$el.append(this.$menu);this.$el.find('button.extra_link').on('click',function(event){event.preventDefault();window.location.href=event.currentTarget.dataset['target'];});this.$el.find('.s_searchbar_fuzzy_submit').on('click',(event)=>{event.preventDefault();this.$input.val(res['fuzzy_search']);const form=this.$('.o_search_order_by').parents('form');form.submit();});}
this.$el.toggleClass('dropdown show',!!res);if($prevMenu){$prevMenu.remove();}
if(res&&this.limit){this.el.classList.remove("dropup");delete this.$menu[0].dataset.bsPopper;const wrapwrapEl=document.querySelector("#wrapwrap");if(wrapwrapEl.scrollHeight>pageScrollHeight){this.$menu[0].style.maxHeight="40vh";this.$menu[0].style.overflowY="auto";if(wrapwrapEl.scrollHeight>pageScrollHeight){this.el.classList.add("dropup");this.$menu[0].dataset.bsPopper="";}}}},_getFieldsNames(){return['description','detail','detail_extra','detail_strike','extra_link','name',];},_onInput:function(){if(!this.limit){return;}
if(this.searchType==='all'&&!this.$input.val().trim().length){this._render();}else{this.keepLast.add(this._fetch()).then(this._render.bind(this));}},_onFocusOut:function(){if(!this.linkHasFocus&&!this.$el.has(document.activeElement).length){this._render();}},_onMousedown(ev){if(isBrowserSafari){this.linkHasFocus=true;}},_onMouseup(ev){if(isBrowserSafari){this.linkHasFocus=false;}},_onKeydown:function(ev){switch(ev.key){case"Escape":this._render();break;case"ArrowUp":case"ArrowDown":ev.preventDefault();if(this.$menu){const focusableEls=[this.$input[0],...this.$menu[0].children];const focusedEl=document.activeElement;const currentIndex=focusableEls.indexOf(focusedEl)||0;const delta=ev.key==="ArrowUp"?focusableEls.length-1:1;const nextIndex=(currentIndex+delta)%focusableEls.length;const nextFocusedEl=focusableEls[nextIndex];nextFocusedEl.focus();}
break;case"Enter":this.limit=0;break;}},_onSearch:function(ev){if(this.$input[0].value){this.limit=0;}else{this._render();ev.preventDefault();if(!this.wasEmpty){this.limit=0;const form=this.$('.o_search_order_by').parents('form');form.submit();}}},});__exports[Symbol.for("default")]={searchBar:publicWidget.registry.searchBar,};return __exports;});;

/* /website_mass_mailing/static/src/snippets/s_popup/000.js */
odoo.define('@website_mass_mailing/snippets/s_popup/000',['@website/snippets/s_popup/000'],function(require){'use strict';let __exports={};const PopupWidget=require('@website/snippets/s_popup/000')[Symbol.for("default")];PopupWidget.include({_canShowPopup(){if(this.$el.is('.o_newsletter_popup')&&this.$el.find('input.js_subscribe_value, input.js_subscribe_email').prop('disabled')){return false;}
return this._super(...arguments);},_canBtnPrimaryClosePopup(primaryBtnEl){if(primaryBtnEl.classList.contains('js_subscribe_btn')){return false;}
return this._super(...arguments);},});__exports[Symbol.for("default")]=PopupWidget;return __exports;});;

/* /website_blog/static/src/snippets/s_blog_posts/000.js */
odoo.define('@website_blog/snippets/s_blog_posts/000',['@web/legacy/js/public/public_widget','@website/snippets/s_dynamic_snippet/000'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const DynamicSnippet=require("@website/snippets/s_dynamic_snippet/000")[Symbol.for("default")];const DynamicSnippetBlogPosts=DynamicSnippet.extend({selector:'.s_dynamic_snippet_blog_posts',disabledInEditableMode:false,_getSearchDomain:function(){const searchDomain=this._super.apply(this,arguments);const filterByBlogId=parseInt(this.$el.get(0).dataset.filterByBlogId);if(filterByBlogId>=0){searchDomain.push(['blog_id','=',filterByBlogId]);}
return searchDomain;},});publicWidget.registry.blog_posts=DynamicSnippetBlogPosts;__exports[Symbol.for("default")]=DynamicSnippetBlogPosts;return __exports;});;

/* /website_payment/static/src/snippets/s_donation/000.js */
odoo.define('@website_payment/snippets/s_donation/000',['@web/core/l10n/translation','@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const CUSTOM_BUTTON_EXTRA_WIDTH=10;let cachedCurrency;publicWidget.registry.DonationSnippet=publicWidget.Widget.extend({selector:'.s_donation',disabledInEditableMode:false,events:{'click .s_donation_btn':'_onClickPrefilledButton','click .s_donation_donate_btn':'_onClickDonateNowButton','input #s_donation_range_slider':'_onInputRangeSlider',},init(){this._super(...arguments);this.rpc=this.bindService("rpc");},async start(){await this._super(...arguments);this.$rangeSlider=this.$('#s_donation_range_slider');this.defaultAmount=this.el.dataset.defaultAmount;if(this.$rangeSlider.length){this.$rangeSlider.val(this.defaultAmount);this._setBubble(this.$rangeSlider);}
await this._displayCurrencies();const customButtonEl=this.el.querySelector("#s_donation_amount_input");if(customButtonEl){const canvasEl=document.createElement("canvas");const context=canvasEl.getContext("2d");context.font=window.getComputedStyle(customButtonEl).font;const width=context.measureText(customButtonEl.placeholder).width;customButtonEl.style.maxWidth=`${Math.ceil(width) + CUSTOM_BUTTON_EXTRA_WIDTH}px`;}},destroy(){const customButtonEl=this.el.querySelector("#s_donation_amount_input");if(customButtonEl){customButtonEl.style.maxWidth="";}
this.$el.find('.s_donation_currency').remove();this._deselectPrefilledButtons();this.$('.alert-danger').remove();this._super(...arguments);},_deselectPrefilledButtons(){this.$('.s_donation_btn').removeClass('active');},_setBubble($range){const $bubble=this.$('.s_range_bubble');const val=$range.val();const min=$range[0].min||0;const max=$range[0].max||100;const newVal=Number(((val-min)*100)/(max-min));const tipOffsetLow=8-(newVal*0.16);$bubble.contents().filter(function(){return this.nodeType===3;}).replaceWith(val);$bubble[0].style.left=`calc(${newVal}% + (${tipOffsetLow}px))`;},_displayCurrencies(){return this._getCachedCurrency().then((result)=>{if(this.currency===result){return;}
this.currency=result;this.$('.s_donation_currency').remove();const $prefilledButtons=this.$('.s_donation_btn, .s_range_bubble');$prefilledButtons.toArray().forEach((button)=>{const before=result.position==="before";const $currencySymbol=document.createElement('span');$currencySymbol.innerText=result.symbol;$currencySymbol.classList.add('s_donation_currency',before?"pe-1":"ps-1");if(before){$(button).prepend($currencySymbol);}else{$(button).append($currencySymbol);}});});},_getCachedCurrency(){return cachedCurrency?Promise.resolve(cachedCurrency):this.rpc("/website/get_current_currency").then((result)=>{cachedCurrency=result;return result;});},_onClickPrefilledButton(ev){const $button=$(ev.currentTarget);this._deselectPrefilledButtons();$button.addClass('active');if(this.$rangeSlider.length){this.$rangeSlider.val($button[0].dataset.donationValue);this._setBubble(this.$rangeSlider);}},_onClickDonateNowButton(ev){if(this.editableMode){return;};this.$('.alert-danger').remove();const $buttons=this.$('.s_donation_btn');const $selectedButton=$buttons.filter('.active');let amount=$selectedButton.length?$selectedButton[0].dataset.donationValue:0;if(this.el.dataset.displayOptions&&!amount){if(this.$rangeSlider.length){amount=this.$rangeSlider.val();}else if($buttons.length){amount=parseFloat(this.$('#s_donation_amount_input').val());let errorMessage='';const minAmount=this.el.dataset.minimumAmount;if(!amount){errorMessage=_t("Please select or enter an amount");}else if(amount<parseFloat(minAmount)){const before=this.currency.position==="before"?this.currency.symbol:"";const after=this.currency.position==="after"?this.currency.symbol:"";errorMessage=_t("The minimum donation amount is %s%s%s",before,minAmount,after);}
if(errorMessage){$(ev.currentTarget).before($('<p>',{class:'alert alert-danger',text:errorMessage,}));return;}}}
if(!amount){amount=this.defaultAmount;}
const $form=this.$('.s_donation_form');$('<input>').attr({type:'hidden',name:'amount',value:amount}).appendTo($form);$('<input>').attr({type:'hidden',name:'currency_id',value:this.currency.id}).appendTo($form);$('<input>').attr({type:'hidden',name:'csrf_token',value:odoo.csrf_token}).appendTo($form);$('<input>').attr({type:'hidden',name:'donation_options',value:JSON.stringify(this.el.dataset)}).appendTo($form);$form.submit();},_onInputRangeSlider(ev){this._deselectPrefilledButtons();this._setBubble($(ev.currentTarget));},});__exports[Symbol.for("default")]={DonationSnippet:publicWidget.registry.DonationSnippet,};return __exports;});;

/* /website/static/src/snippets/s_map/000.js */
odoo.define('@website/snippets/s_map/000',['@web/legacy/js/public/public_widget','@website/js/utils'],function(require){'use strict';let __exports={};const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const{generateGMapLink,generateGMapIframe}=require('@website/js/utils');publicWidget.registry.Map=publicWidget.Widget.extend({selector:'.s_map',start(){if(!this.el.querySelector('.s_map_embedded')){const dataset=this.el.dataset;if(dataset.mapAddress){const iframeEl=generateGMapIframe();iframeEl.setAttribute('src',generateGMapLink(dataset));this.el.querySelector('.s_map_color_filter').before(iframeEl);}}
return this._super(...arguments);},});__exports[Symbol.for("default")]=publicWidget.registry.Map;return __exports;});;

/* /website_appointment/static/src/snippets/s_searchbar/000.js */
odoo.define('@website_appointment/snippets/s_searchbar/000',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];publicWidget.registry.searchBar.include({_render:function(res){if(res&&this.searchType==='appointments'&&res.parts.website_url){res.results.forEach(result=>{result.website_url=`${result.website_url}${location.search}`;})}
this._super(...arguments);}});return __exports;});;

/* /website_sale/static/src/snippets/s_add_to_cart/000.js */
odoo.define('@website_sale/snippets/s_add_to_cart/000',['@web/legacy/js/public/public_widget','@website_sale/js/website_sale_utils','@website_sale/js/website_sale','@web/core/l10n/translation'],function(require){'use strict';let __exports={};const publicWidget=require('@web/legacy/js/public/public_widget')[Symbol.for("default")];const{cartHandlerMixin}=require('@website_sale/js/website_sale_utils');const{WebsiteSale}=require('@website_sale/js/website_sale');const{_t}=require("@web/core/l10n/translation");publicWidget.registry.AddToCartSnippet=WebsiteSale.extend(cartHandlerMixin,{selector:'.s_add_to_cart_btn',events:{'click':'_onClickAddToCartButton',},init(){this._super(...arguments);this.notification=this.bindService("notification");},_onClickAddToCartButton:async function(ev){const dataset=ev.currentTarget.dataset;const visitorChoice=dataset.visitorChoice==='true';const action=dataset.action;const productId=parseInt(dataset.productVariantId);if(!productId){return;}
if(visitorChoice){this._handleAdd($(ev.currentTarget.closest('div')));}else{const isAddToCartAllowed=await this.rpc(`/shop/product/is_add_to_cart_allowed`,{product_id:productId,});if(!isAddToCartAllowed){this.notification.add(_t('This product does not exist therefore it cannot be added to cart.'),{title:'User Error',type:'warning'});return;}
this.isBuyNow=action==='buy_now';this.stayOnPageOption=!this.isBuyNow;this.addToCart({product_id:productId,add_qty:1});}},});__exports[Symbol.for("default")]=publicWidget.registry.AddToCartSnippet;return __exports;});;

/* /website_sale/static/src/snippets/s_dynamic_snippet_products/000.js */
odoo.define('@website_sale/snippets/s_dynamic_snippet_products/000',['@web/legacy/js/public/public_widget','@website/snippets/s_dynamic_snippet_carousel/000','@website_sale/js/website_sale_utils'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const DynamicSnippetCarousel=require("@website/snippets/s_dynamic_snippet_carousel/000")[Symbol.for("default")];const wSaleUtils=require("@website_sale/js/website_sale_utils")[Symbol.for("default")];const DynamicSnippetProducts=DynamicSnippetCarousel.extend({selector:'.s_dynamic_snippet_products',_getCategorySearchDomain(){const searchDomain=[];let productCategoryId=this.$el.get(0).dataset.productCategoryId;if(productCategoryId&&productCategoryId!=='all'){if(productCategoryId==='current'){productCategoryId=undefined;const productCategoryField=$("#product_details").find(".product_category_id");if(productCategoryField&&productCategoryField.length){productCategoryId=parseInt(productCategoryField[0].value);}
if(!productCategoryId){this.trigger_up('main_object_request',{callback:function(value){if(value.model==="product.public.category"){productCategoryId=value.id;}},});}
if(!productCategoryId){const productTemplateId=$("#product_details").find(".product_template_id");if(productTemplateId&&productTemplateId.length){searchDomain.push(['public_categ_ids.product_tmpl_ids','=',parseInt(productTemplateId[0].value)]);}}}
if(productCategoryId){searchDomain.push(['public_categ_ids','child_of',parseInt(productCategoryId)]);}}
return searchDomain;},_getTagSearchDomain(){const searchDomain=[];let productTagIds=this.$el.get(0).dataset.productTagIds;productTagIds=productTagIds?JSON.parse(productTagIds):[];if(productTagIds.length){searchDomain.push(['all_product_tag_ids','in',productTagIds.map(productTag=>productTag.id)]);}
return searchDomain;},_getSearchDomain:function(){const searchDomain=this._super.apply(this,arguments);searchDomain.push(...this._getCategorySearchDomain());searchDomain.push(...this._getTagSearchDomain());const productNames=this.$el.get(0).dataset.productNames;if(productNames){const nameDomain=[];for(const productName of productNames.split(',')){if(!productName.length){continue;}
if(nameDomain.length){nameDomain.unshift('|');}
nameDomain.push(...['|','|',['name','ilike',productName],['default_code','=',productName],['barcode','=',productName],]);}
searchDomain.push(...nameDomain);}
return searchDomain;},_getRpcParameters:function(){const productTemplateId=$("#product_details").find(".product_template_id");return Object.assign(this._super.apply(this,arguments),{productTemplateId:productTemplateId&&productTemplateId.length?productTemplateId[0].value:undefined,});},});const DynamicSnippetProductsCard=publicWidget.Widget.extend({selector:'.o_carousel_product_card',read_events:{'click .js_add_cart':'_onClickAddToCart','click .js_remove':'_onRemoveFromRecentlyViewed',},init(root,options){const parent=options.parent||root;this._super(parent,options);this.rpc=this.bindService("rpc");},start(){this.add2cartRerender=this.el.dataset.add2cartRerender==='True';},async _onClickAddToCart(ev){const $card=$(ev.currentTarget).closest('.card');const data=await this.rpc("/shop/cart/update_json",{product_id:$card.find('input[data-product-id]').data('product-id'),add_qty:1,display:false,});wSaleUtils.updateCartNavBar(data);wSaleUtils.showCartNotification(this.call.bind(this),data.notification_info);if(this.add2cartRerender){this.trigger_up('widgets_start_request',{$target:this.$el.closest('.s_dynamic'),});}},async _onRemoveFromRecentlyViewed(ev){const $card=$(ev.currentTarget).closest('.card');await this.rpc("/shop/products/recently_viewed_delete",{product_id:$card.find('input[data-product-id]').data('product-id'),});this.trigger_up('widgets_start_request',{$target:this.$el.closest('.s_dynamic'),});},});publicWidget.registry.dynamic_snippet_products_cta=DynamicSnippetProductsCard;publicWidget.registry.dynamic_snippet_products=DynamicSnippetProducts;__exports[Symbol.for("default")]=DynamicSnippetProducts;return __exports;});;

/* /website/static/src/snippets/s_instagram_page/000.js */
odoo.define('@website/snippets/s_instagram_page/000',['@web/core/l10n/translation','@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const{_t}=require("@web/core/l10n/translation");const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const InstagramPage=publicWidget.Widget.extend({selector:".s_instagram_page",disabledInEditableMode:false,start(){const iframeEl=document.createElement("iframe");this.el.querySelector(".o_instagram_container").appendChild(iframeEl);iframeEl.setAttribute("scrolling","no");iframeEl.setAttribute("aria-label",_t("Instagram"));iframeEl.classList.add("w-100");iframeEl.height=this._estimateIframeHeight();this.__onMessage=this._onMessage.bind(this);window.addEventListener("message",this.__onMessage);iframeEl.src=`https://www.instagram.com/${this.el.dataset.instagramPage}/embed`;return this._super(...arguments);},destroy(){const iframeEl=this.el.querySelector(".o_instagram_container iframe");if(iframeEl){iframeEl.remove();window.removeEventListener("message",this.__onMessage);}
this._super.apply(this,arguments);},_estimateIframeHeight(){const iframeEl=this.el.querySelector(".o_instagram_container iframe");const iframeWidth=parseInt(getComputedStyle(iframeEl).width);return 0.659*iframeWidth+(iframeWidth<432?156:203);},_onMessage(ev){const iframeEl=this.el.querySelector(".o_instagram_container iframe");if(!iframeEl){window.removeEventListener("message",this.__onMessage);return;}
if(ev.origin!=="https://www.instagram.com"||iframeEl.contentWindow!==ev.source){return;}
const evDataJSON=JSON.parse(ev.data);if(evDataJSON.type!=="MEASURE"){return;}
const height=parseInt(evDataJSON.details.height);if(height){this.options.wysiwyg?.odooEditor.observerUnactive();iframeEl.height=height;this.options.wysiwyg?.odooEditor.observerActive();}},});publicWidget.registry.InstagramPage=InstagramPage;__exports[Symbol.for("default")]=InstagramPage;return __exports;});;

/* /website_appointment/static/src/snippets/s_online_appointment/000.js */
odoo.define('@website_appointment/snippets/s_online_appointment/000',['@web/legacy/js/public/public_widget'],function(require){'use strict';let __exports={};const publicWidget=require("@web/legacy/js/public/public_widget")[Symbol.for("default")];const OnlineAppointmentCtaWidget=publicWidget.Widget.extend({selector:'.s_online_appointment',disabledInEditableMode:true,events:{'click':'_onCtaClick'},_onCtaClick:function(ev){let url='/appointment';const selectedAppointments=ev.target.closest('.s_online_appointment').dataset.appointmentTypes;const appointmentsTypeIds=selectedAppointments?JSON.parse(selectedAppointments):[];const nbSelectedAppointments=appointmentsTypeIds.length;if(nbSelectedAppointments===1){url+=`/${encodeURIComponent(appointmentsTypeIds[0])}`;const selectedUsers=ev.target.closest('.s_online_appointment').dataset.staffUsers;if(JSON.parse(selectedUsers).length){url+=`?filter_staff_user_ids=${encodeURIComponent(selectedUsers)}`;}}else if(nbSelectedAppointments>1){url+=`?filter_appointment_type_ids=${encodeURIComponent(selectedAppointments)}`;}
window.location=url;},});publicWidget.registry.online_appointment=OnlineAppointmentCtaWidget;__exports[Symbol.for("default")]=OnlineAppointmentCtaWidget;return __exports;});;

/* /website_sale/static/src/snippets/s_popup/000.js */
odoo.define('@website_sale/snippets/s_popup/000',['@website/snippets/s_popup/000'],function(require){'use strict';let __exports={};const PopupWidget=require('@website/snippets/s_popup/000')[Symbol.for("default")];PopupWidget.include({_canBtnPrimaryClosePopup(primaryBtnEl){return(this._super(...arguments)&&!primaryBtnEl.classList.contains("js_add_cart"));},});__exports[Symbol.for("default")]=PopupWidget;return __exports;});

                    /*******************************************
                    *  Templates                               *
                    *******************************************/

                    odoo.define('web.assets_frontend.bundle.xml', ['@web/core/registry'], function(require){
                        'use strict';
                        const { registry } = require('@web/core/registry');
                        registry.category(`xml_templates`).add(`web.assets_frontend`, `<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="web.DialogWidget">
    <div role="dialog" t-attf-class="modal o_legacy_dialog #{ technical ? ' o_technical_modal' : '' } #{ fullscreen ? ' o_modal_full': '' }" tabindex="-1" data-bs-backdrop="static" t-att-id="uniqueId" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <header t-if="renderHeader" class="modal-header">
                    <h4 class="modal-title"><t t-out="title"/><span class="o_subtitle text-muted small" t-out="subtitle"/></h4>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" tabindex="-1"/>
                </header>
                <main class="modal-body"/>
                <footer t-if="renderFooter" class="modal-footer justify-content-around justify-content-md-start flex-wrap gap-1"/>
            </div>
        </div>
    </div>
</t>

<t t-name="web.ActionSwiper">
        <t t-if="props.onRightSwipe || props.onLeftSwipe">
            <div class="o_actionswiper" t-on-touchend="_onTouchEndSwipe" t-on-touchmove="_onTouchMoveSwipe" t-on-touchstart="_onTouchStartSwipe" t-ref="root">
                <div class="o_actionswiper_overflow_container position-relative overflow-hidden">
                    <div class="o_actionswiper_target_container" t-ref="targetContainer" t-att-style="state.containerStyle" t-att-class="{ o_actionswiper_swiping: state.isSwiping }">
                        <t t-slot="default"/>
                        <t t-if="localizedProps.onRightSwipe and (localizedProps.onRightSwipe.icon or localizedProps.onRightSwipe.bgColor)">
                            <div t-att-style="'max-width: ' + swipedDistance + 'px;'" class="o_actionswiper_right_swipe_area position-absolute overflow-hidden w-100 h-100 d-flex align-items-center justify-content-center rounded-end" t-att-class="localizedProps.onRightSwipe.bgColor">
                                <span><i class="fa fa-2x" t-att-class="localizedProps.onRightSwipe.icon"/></span>
                            </div>
                        </t>
                        <t t-if="localizedProps.onLeftSwipe and (localizedProps.onLeftSwipe.icon or localizedProps.onLeftSwipe.bgColor)">
                            <div t-att-style="'max-width: ' + -swipedDistance + 'px;'" class="o_actionswiper_left_swipe_area position-absolute overflow-hidden w-100 h-100 d-flex align-items-center justify-content-center rounded-start" t-att-class="localizedProps.onLeftSwipe.bgColor">
                                <span><i class="fa fa-2x" t-att-class="localizedProps.onLeftSwipe.icon"/></span>
                            </div>
                        </t>
                    </div>
                </div>
            </div>
        </t>
        <t t-else="">
            <t t-slot="default"/>
        </t>
    </t>
<t t-name="web.AutoComplete">
        <div class="o-autocomplete" t-ref="root" t-att-class="autoCompleteRootClass">
            <input type="text" t-att-id="props.id" class="o-autocomplete--input o_input" autocomplete="off" t-att-placeholder="props.placeholder" role="combobox" t-att-aria-activedescendant="activeSourceOptionId" t-att-aria-expanded="displayOptions ? 'true' : 'false'" aria-autocomplete="list" aria-haspopup="listbox" t-model="state.value" t-on-blur="onInputBlur" t-on-click.stop="onInputClick" t-on-change="onInputChange" t-on-input="onInput" t-on-keydown="onInputKeydown" t-on-focus="onInputFocus" t-ref="input"/>
            <t t-if="displayOptions">
                <ul role="menu" class="o-autocomplete--dropdown-menu ui-widget show" t-att-class="ulDropdownClass" t-ref="sourcesList">
                    <t t-foreach="sources" t-as="source" t-key="source.id">
                        <t t-if="source.isLoading">
                            <li class="ui-menu-item" t-att-class="{                                     'o-autocomplete--dropdown-item': props.dropdown,                                     'd-block': !props.dropdown                                 }">
                                <a t-attf-id="{{props.id or 'autocomplete'}}_{{source_index}}_loading" role="option" href="#" class="dropdown-item ui-menu-item-wrapper" aria-selected="true">
                                    <i class="fa fa-spin fa-circle-o-notch"/> <t t-esc="source.placeholder"/>
                                </a>
                            </li>
                        </t>
                        <t t-else="">
                            <t t-foreach="source.options" t-as="option" t-key="option.id">
                                <li class="o-autocomplete--dropdown-item ui-menu-item d-block" t-att-class="option.classList" t-on-mouseenter="() =&gt; this.onOptionMouseEnter([source_index, option_index])" t-on-mouseleave="() =&gt; this.onOptionMouseLeave([source_index, option_index])" t-on-click="() =&gt; this.onOptionClick([source_index, option_index])" t-on-pointerdown="() =&gt; this.ignoreBlur = true">
                                    <a t-attf-id="{{props.id or 'autocomplete'}}_{{source_index}}_{{option_index}}" role="option" href="#" class="dropdown-item ui-menu-item-wrapper text-truncate" t-att-class="{ 'ui-state-active': isActiveSourceOption([source_index, option_index]) }" t-att-aria-selected="isActiveSourceOption([source_index, option_index]) ? 'true' : 'false'">
                                        <t t-if="source.optionTemplate">
                                            <t t-call="{{ source.optionTemplate }}"/>
                                        </t>
                                        <t t-else="">
                                            <t t-esc="option.label"/>
                                        </t>
                                    </a>
                                </li>
                            </t>
                        </t>
                    </t>
                </ul>
            </t>
        </div>
    </t>

<t t-name="web.CheckBox">
    <div class="o-checkbox form-check" t-attf-class="{{ props.slots ? 'form-check' : '' }}" t-att-class="props.className" t-on-click="onClick" t-ref="root">
        <input t-att-id="props.id or id" type="checkbox" class="form-check-input" t-att-disabled="props.disabled" t-att-checked="props.value" t-att-name="props.name" t-on-change="onChange"/>
        <label t-att-for="props.id or id" class="form-check-label">
            <t t-slot="default"/>
        </label>
    </div>
</t>

<t t-name="web.CodeEditor">
        <div t-ref="editorRef" class="w-100" t-att-class="props.class"/>
    </t>

<t t-name="web.ColorList">
        <div class="o_colorlist d-flex flex-wrap align-items-center mw-100 gap-2" aria-atomic="true" t-ref="colorlist">
            <t t-if="!props.forceExpanded and !state.isExpanded">
                <button t-on-click="onToggle" role="menuitem" t-att-title="colors[props.selectedColor]" t-att-data-color="props.selectedColor" t-att-aria-label="colors[props.selectedColor]" t-attf-class="btn p-0 rounded-0 o_colorlist_toggler o_colorlist_item_color_{{ props.selectedColor }}"/>
            </t>
            <t t-else="" t-foreach="props.colors" t-as="colorId" t-key="colorId">
                <button t-on-click.prevent.stop="() =&gt; this.onColorSelected(colorId)" role="menuitem" t-att-title="colors[colorId]" t-att-data-color="colorId" t-att-aria-label="colors[colorId]" t-attf-class="btn p-0 rounded-0 o_colorlist_item_color_{{ colorId }} {{ colorId === props.selectedColor ? 'o_colorlist_selected' : '' }}"/>
            </t>
        </div>
    </t>

<t t-name="web.Colorpicker">
    <div class="o_colorpicker_widget" t-ref="el">
        <div class="d-flex justify-content-between align-items-stretch mb-2">
            <div class="o_color_pick_area position-relative w-75" t-att-style="props.noTransparency ? 'width: 89%;' : None">
                <div class="o_picker_pointer rounded-circle p-1 position-absolute" tabindex="-1"/>
            </div>
            <div class="o_color_slider position-relative">
                <div class="o_slider_pointer" tabindex="-1"/>
            </div>
            <div class="o_opacity_slider position-relative" t-if="!props.noTransparency">
                <div class="o_opacity_pointer" tabindex="-1"/>
            </div>
        </div>
        <div t-if="props.colorPreview" class="o_color_preview mb-1 w-100 p-2"/>
        <div class="o_color_picker_inputs d-flex justify-content-between mb-2">
            <t t-set="input_classes" t-value="'p-0 border-0 text-center font-monospace bg-transparent'"/>

            <div class="o_hex_div px-1 d-flex align-items-baseline">
                <input type="text" t-attf-class="o_hex_input {{input_classes}}" data-color-method="hex" size="1" t-on-input="_onHexColorInput"/>
                <label class="flex-grow-0 ms-1 mb-0">hex</label>
            </div>
            <div class="o_rgba_div px-1 d-flex align-items-baseline">
                <input type="text" t-attf-class="o_red_input {{input_classes}}" data-color-method="rgb" size="1"/>
                <input type="text" t-attf-class="o_green_input {{input_classes}}" data-color-method="rgb" size="1"/>
                <input type="text" t-attf-class="o_blue_input me-0 {{input_classes}}" data-color-method="rgb" size="1"/>
                <t t-if="!props.noTransparency">
                    <input type="text" t-attf-class="o_opacity_input {{input_classes}}" data-color-method="opacity" size="1"/>
                    <label class="flex-grow-0 ms-1 mb-0">
                        RGBA
                    </label>
                </t>
                <label t-else="" class="flex-grow-0 ms-1 mb-0">
                    RGB
                </label>
            </div>
        </div>
    </div>
</t>

<t t-name="web.ConfirmationDialog">
    <Dialog size="'md'" title="props.title" modalRef="modalRef">
      <p t-out="props.body" class="text-prewrap"/>
      <t t-set-slot="footer">
        <button class="btn" t-att-class="props.confirmClass" t-on-click="_confirm" t-esc="props.confirmLabel"/>
        <button t-if="props.cancel" class="btn btn-secondary" t-on-click="_cancel" t-esc="props.cancelLabel"/>
      </t>
    </Dialog>
  </t>

  <t t-name="web.AlertDialog">
    <Dialog size="'sm'" title="props.title" contentClass="props.contentClass">
      <p t-out="props.body" class="text-prewrap"/>
      <t t-set-slot="footer">
        <button class="btn" t-att-class="props.confirmClass" t-on-click="_confirm" t-esc="props.confirmLabel"/>
        <button t-if="props.cancel" class="btn btn-secondary" t-on-click="_cancel" t-esc="props.cancelLabel"/>
      </t>
    </Dialog>
  </t>

<t t-name="web.DateTimeInput">
        <input type="text" t-ref="start-date" t-att-id="props.id" class="o_datetime_input o_input cursor-pointer" autocomplete="off" t-att-placeholder="props.placeholder"/>
    </t>
<t t-name="web.DateTimePicker.Days">
        <div class="d-flex gap-3">
            <t t-foreach="items" t-as="month" t-key="month.id">
                <div class="o_date_picker d-grid flex-grow-1 bg-view rounded overflow-auto" t-on-pointerleave="() =&gt; (state.hoveredDate = null)">
                    <t t-foreach="month.daysOfWeek" t-as="dayOfWeek" t-key="dayOfWeek[0]">
                        <div class="o_day_of_week_cell o_text_sm o_cell_md fw-bolder bg-100 border-bottom border-2 d-flex align-items-center justify-content-center" t-att-title="dayOfWeek[1]">
                            <div class="text-nowrap overflow-hidden" t-esc="props.daysOfWeekFormat === 'narrow' ? dayOfWeek[2] : dayOfWeek[0]"/>
                        </div>
                    </t>
                    <t t-foreach="month.weeks" t-as="week" t-key="week.number">
                        <t t-if="props.showWeekNumbers ?? !props.range">
                            <div class="o_week_number_cell o_center o_cell_md o_text_sm bg-100 fw-bolder" t-att-class="{ 'border-bottom': !week_last }" t-esc="week.number"/>
                        </t>
                        <t t-foreach="week.days" t-as="itemInfo" t-key="itemInfo.id">
                            <t t-set="arInfo" t-value="getActiveRangeInfo(itemInfo)"/>
                            <button class="o_date_item_cell o_datetime_button o_center o_cell_md btn p-1 border-0 fw-normal" tabindex="-1" t-att-class="{                                     'o_selected': arInfo.isSelected,                                     o_select_start: arInfo.isSelectStart,                                     o_select_end: arInfo.isSelectEnd,                                     'o_highlighted': arInfo.isHighlighted,                                     o_highlight_start: arInfo.isHighlightStart,                                     o_highlight_end: arInfo.isHighlightEnd,                                     o_current: arInfo.isCurrent,                                     o_today: itemInfo.includesToday,                                     o_out_of_range: itemInfo.isOutOfRange or !itemInfo.isValid,                                     [itemInfo.extraClass]: true,                                 }" t-att-disabled="!itemInfo.isValid" t-on-pointerenter="() =&gt; (state.hoveredDate = itemInfo.range[0])" t-on-click="() =&gt; this.zoomOrSelect(itemInfo)">
                                <span t-esc="itemInfo.label" class="z-index-1"/>
                            </button>
                        </t>
                    </t>
                </div>
            </t>
        </div>
        <div t-attf-class="position-relative d-flex flex-column flex-md-row gap-4 gap-md-3 {{ props.type === 'datetime' ? 'justify-content-center' : 'justify-content-end' }}">
            <div t-attf-class="d-flex gap-3 w-100 {{ props.type === 'datetime' ? 'justify-content-center' : 'd-none' }}">
                <t t-if="props.type === 'datetime'">
                    <t t-foreach="state.timeValues" t-as="timeValue" t-key="timeValue_index">
                        <div t-if="timeValue" class="o_time_picker d-flex align-items-center justify-content-center w-lg-50 w-100 gap-1">
                            <t t-call="web.DateTimePicker.Select">
                                <t t-set="unitIndex" t-value="0"/>
                                <t t-set="unitList" t-value="availableHours"/>
                            </t>
                            <span>:</span>
                            <t t-call="web.DateTimePicker.Select">
                                <t t-set="unitIndex" t-value="1"/>
                                <t t-set="unitList" t-value="availableMinutes"/>
                            </t>
                            <t t-if="availableSeconds.length">
                                <span>:</span>
                                <t t-call="web.DateTimePicker.Select">
                                    <t t-set="unitIndex" t-value="2"/>
                                    <t t-set="unitList" t-value="availableSeconds"/>
                                </t>
                            </t>
                            <t t-if="meridiems">
                                <t t-call="web.DateTimePicker.Select">
                                    <t t-set="unitIndex" t-value="3"/>
                                    <t t-set="unitList" t-value="meridiems"/>
                                </t>
                            </t>
                        </div>
                    </t>
                </t>
            </div>

            <div t-attf-class="o_datetime_buttons {{ props.type === 'datetime' ? 'position-md-absolute h-100 start-0' : '' }}">
                <t t-slot="bottom_left"/>
            </div>
            <div t-attf-class="o_datetime_buttons {{ props.type === 'datetime' ? 'position-md-absolute h-100 end-0' : '' }}">
                <t t-slot="buttons"/>
            </div>
        </div>
    </t>

    <t t-name="web.DateTimePicker.Grid">
        <div class="o_date_item_picker d-grid">
            <t t-foreach="items" t-as="itemInfo" t-key="itemInfo.id">
                <t t-set="arInfo" t-value="getActiveRangeInfo(itemInfo)"/>
                <button class="o_date_item_cell o_datetime_button btn o_center o_cell_lg btn p-1 border-0" tabindex="-1" t-att-class="{                         'o_selected': arInfo.isSelected,                         o_select_start: arInfo.isSelectStart,                         o_select_end: arInfo.isSelectEnd,                         'o_highlighted': arInfo.isHighlighted,                         o_highlight_start: arInfo.isHighlightStart,                         o_highlight_end: arInfo.isHighlightEnd,                         o_today: itemInfo.includesToday,                         o_out_of_range: itemInfo.isOutOfRange or !itemInfo.isValid,                     }" t-att-disabled="!itemInfo.isValid" t-on-click="() =&gt; this.zoomOrSelect(itemInfo)">
                    <span t-esc="itemInfo.label" class="z-index-1"/>
                </button>
            </t>
        </div>
    </t>

    <t t-name="web.DateTimePicker.Select">

        <select class="o_time_picker_select form-control form-control-sm w-auto" tabindex="-1" t-model="timeValue[unitIndex]" t-on-change="() =&gt; this.selectTime(timeValue_index)">
            <t t-foreach="unitList" t-as="unit" t-key="unit[0]">
                <option class="text-center" t-att-value="unit[0]" t-esc="unit[1]" t-att-selected="timeValue[unitIndex] === unit[0].toString()"/>
            </t>
        </select>
    </t>

    <t t-name="web.DateTimePicker">
        <div class="o_datetime_picker d-flex flex-column gap-2 user-select-none" t-att-class="!isLastPrecisionLevel ? 'p-2 p-lg-3' : ''" t-attf-style="--DateTimePicker__Day-template-columns: {{ props.showWeekNumbers ?? !props.range ? 8 : 7 }}">
            <nav class="o_datetime_picker_header btn-group">
                <button class="o_previous btn btn-light flex-grow-0" tabindex="-1" t-att-class="isLastPrecisionLevel ? 'order-1 btn-sm px-1' : ''" t-on-click="previous">
                    <i class="oi oi-chevron-left" t-att-title="activePrecisionLevel.prevTitle"/>
                </button>
                <button class="o_zoom_out o_datetime_button btn btn-light d-flex align-items-center px-0 text-truncate" t-att-class="isLastPrecisionLevel ? 'pe-none text-start' : 'justify-content-around'" tabindex="-1" t-att-title="!isLastPrecisionLevel and activePrecisionLevel.mainTitle" t-on-click="zoomOut">
                    <t t-foreach="titles" t-as="title" t-key="title">
                        <strong t-attf-class="o_header_part fs-5 {{                                 props.range ? 'flex-basis-50' : 'flex-basis-100',                                 isLastPrecisionLevel ? 'fs-6' : 'fs-5'                             }}" t-esc="title"/>
                    </t>
                </button>
                <button class="o_next btn btn-light flex-grow-0" t-att-class="isLastPrecisionLevel ? 'order-2 btn-sm px-1' : ''" tabindex="-1" t-on-click="next">
                    <i class="oi oi-chevron-right" t-att-title="activePrecisionLevel.nextTitle"/>
                </button>
            </nav>
            <t t-if="state.precision === 'days'">
                <t t-call="web.DateTimePicker.Days"/>
            </t>
            <t t-else="">
                <t t-call="web.DateTimePicker.Grid"/>
            </t>
        </div>
    </t>
<t t-name="web.DateTimePickerPopover">
        <DateTimePicker t-props="props.pickerProps">
            <t t-set-slot="buttons">
                <t t-if="isDateTimeRange">
                    <button class="o_apply btn btn-primary btn-sm h-100 w-100 w-md-auto d-flex align-items-center justify-content-center gap-1" tabindex="-1" t-on-click="props.close">
                        <i class="fa fa-check"/>
                        <span>Apply</span>
                    </button>
                </t>
            </t>
            <t t-set-slot="bottom_left">
                <t t-if="isDateTimeRange">
                    <button class="btn btn-secondary btn-sm h-100 w-100 w-md-auto d-flex align-items-center justify-content-center" tabindex="-1" t-on-click="props.close">
                        <span>Close</span>
                    </button>
                </t>
            </t>
        </DateTimePicker>
    </t>
<t t-name="web.DebugMenu">
        <Dropdown class="'o_debug_manager'" beforeOpen="getElements" position="'bottom-end'" togglerClass="\`o-dropdown--narrow \${env.inDialog?'btn btn-link':''}\`" autoOpen="false">
            <t t-set-slot="toggler">
                <i class="fa fa-bug" role="img" aria-label="Open developer tools"/>
            </t>
            <t t-foreach="elements" t-as="element" t-key="element_index">
                <DropdownItem t-if="element.type == 'item'" onSelected="element.callback" href="element.href">
                    <t t-esc="element.description"/>
                </DropdownItem>
                <div t-if="element.type == 'separator'" role="separator" class="dropdown-divider"/>
                <t t-if="element.type == 'component'" t-component="element.Component" t-props="element.props"/>
            </t>
        </Dropdown>
    </t>

<t t-name="web.DebugMenu.SetDefaultDialog">
        <Dialog title="title">
            <table style="width: 100%">
                <tr>
                    <td>
                        <label for="formview_default_fields" class="oe_label oe_align_right">
                            Default:
                        </label>
                    </td>
                    <td class="oe_form_required">
                        <select id="formview_default_fields" class="o_input" t-model="state.fieldToSet">
                            <option value=""/>
                            <option t-foreach="defaultFields" t-as="field" t-att-value="field.name" t-key="field.name">
                                <t t-esc="field.string"/> = <t t-esc="field.displayed"/>
                            </option>
                        </select>
                    </td>
                </tr>
                <tr t-if="conditions.length">
                    <td>
                        <label for="formview_default_conditions" class="oe_label oe_align_right">
                            Condition:
                        </label>
                    </td>
                    <td>
                        <select id="formview_default_conditions" class="o_input" t-model="state.condition">
                            <option value=""/>
                            <option t-foreach="conditions" t-as="cond" t-att-value="cond.name + '=' + cond.value" t-key="cond.name">
                                <t t-esc="cond.string"/>=<t t-esc="cond.displayed"/>
                            </option>
                        </select>
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <input type="radio" id="formview_default_self" value="self" name="scope" t-model="state.scope"/>
                        <label for="formview_default_self" class="oe_label" style="display: inline;">
                            Only you
                        </label>
                        <br/>
                        <input type="radio" id="formview_default_all" value="all" name="scope" t-model="state.scope"/>
                        <label for="formview_default_all" class="oe_label" style="display: inline;">
                            All users
                        </label>
                    </td>
                </tr>
            </table>
            <t t-set-slot="footer">
                <button class="btn btn-secondary" t-on-click="props.close">Close</button>
                <button class="btn btn-secondary" t-on-click="saveDefault">Save default</button>
            </t>
        </Dialog>
    </t>

    <t t-name="web.DebugMenu.GetMetadataDialog">
        <Dialog title="title">
            <table class="table table-sm table-striped">
                <tr>
                    <th>ID:</th>
                    <td><t t-esc="state.id"/></td>
                </tr>
                <tr>
                    <th>XML ID:</th>
                    <td>
                        <t t-if="state.xmlids.length &gt; 1">
                            <t t-foreach="state.xmlids" t-as="imd" t-key="imd['xmlid']">
                                <div t-att-class="&quot;p-0 &quot; + (imd[&quot;xmlid&quot;] === state.xmlid ? &quot;fw-bolder &quot; : &quot;&quot;) + (imd[&quot;noupdate&quot;] === true ? &quot;fst-italic &quot; : &quot;&quot;)" t-esc="imd['xmlid']"/>
                            </t>
                        </t>
                        <t t-elif="state.xmlid" t-esc="state.xmlid"/>
                        <t t-else="">
                            / <a t-on-click="onClickCreateXmlid"> (create)</a>
                        </t>
                    </td>
                </tr>
                <tr>
                    <th>No Update:</th>
                    <td>
                        <t t-esc="state.noupdate"/>
                        <t t-if="state.xmlid">
                            <a t-on-click="toggleNoupdate"> (change)</a>
                        </t>
                    </td>
                </tr>
                <tr>
                    <th>Creation User:</th>
                    <td><t t-esc="state.creator"/></td>
                </tr>
                <tr>
                    <th>Creation Date:</th>
                    <td><t t-esc="state.createDate"/></td>
                </tr>
                <tr>
                    <th>Latest Modification by:</th>
                    <td><t t-esc="state.lastModifiedBy"/></td>
                </tr>
                <tr>
                    <th>Latest Modification Date:</th>
                    <td><t t-esc="state.writeDate"/></td>
                </tr>
            </table>
        </Dialog>
    </t>

    <t t-name="web.DebugMenu.GetViewDialog">
        <Dialog title="title">
            <pre t-esc="props.arch.outerHTML"/>
            <t t-set-slot="footer">
                <button class="btn btn-primary o-default-button" t-on-click="() =&gt; props.close()">Close</button>
            </t>
        </Dialog>
    </t>
<t t-name="web.DebugMenu.ProfilingItem">
        <DropdownItem class="o_debug_profiling_item_wrapper">
            <div class="o_debug_profiling_item d-flex justify-content-between">
                <div class="align-self-center">
                    <div t-if="profiling.state.isEnabled" class="alert alert-info py-2 me-3">Recording...</div>
                    <span class="o_profiling_switch">
                        <span class="form-check form-switch" t-on-click.stop.prevent="() =&gt; this.profiling.toggleProfiling()">
                            <input type="checkbox" class="form-check-input" id="enable_profiling" t-att-checked="profiling.state.isEnabled"/>
                            <label class="form-check-label">Enable profiling</label>
                        </span>
                    </span>
                    <t t-if="profiling.state.isEnabled">
                        <span class="o_profiling_switch form-check form-switch mt-2" t-on-click.stop.prevent="() =&gt; this.profiling.toggleCollector('sql')">
                            <input type="checkbox" class="form-check-input" id="profile_sql" t-att-checked="profiling.isCollectorEnabled('sql')"/>
                            <label class="form-check-label" for="profile_sql">Record sql</label>
                        </span>
                        <span class="o_profiling_switch form-check form-switch mt-2" t-on-click.stop.prevent="() =&gt; this.profiling.toggleCollector('traces_async')">
                            <input type="checkbox" class="form-check-input" id="profile_traces_async" t-att-checked="profiling.isCollectorEnabled('traces_async')"/>
                            <label class="form-check-label" for="profile_traces_async">Record traces</label>
                        </span>
                        <div t-if="profiling.isCollectorEnabled('traces_async')" class="input-group input-group-sm mt-2" t-on-click.stop.prevent="">
                            <div class="input-group-text">Interval</div>
                            <select class="profile_param form-select" t-on-change="(ev) =&gt; this.changeParam('traces_async_interval', ev)">
                                <t t-set="interval" t-value="profiling.state.params.traces_async_interval"/>
                                <option value="">Default</option>
                                <option value="0.001" t-att-selected="interval === '0.001'">0.001</option>
                                <option value="0.01" t-att-selected="interval === '0.01'">0.01</option>
                                <option value="0.1" t-att-selected="interval === '0.1'">0.1</option>
                                <option value="1" t-att-selected="interval === '1'">1</option>
                            </select>
                        </div>
                        <span t-if="profiling.isCollectorEnabled('sql') || profiling.isCollectorEnabled('traces_async')" class="o_profiling_switch form-check form-switch mt-2" t-on-click.stop.prevent="(ev) =&gt; this.toggleParam('execution_context_qweb', ev)">
                            <input type="checkbox" class="form-check-input" id="profile_execution_context_qweb" t-att-checked="!!profiling.state.params.execution_context_qweb"/>
                            <label class="form-check-label" for="profile_execution_context_qweb">Add qweb directive context</label>
                        </span>
                        <span class="o_profiling_switch form-check form-switch mt-2" t-on-click.stop.prevent="() =&gt; this.profiling.toggleCollector('qweb')">
                            <input type="checkbox" class="form-check-input" id="profile_qweb" t-att-checked="profiling.isCollectorEnabled('qweb')"/>
                            <label class="form-check-label" for="profile_qweb">Record qweb</label>
                        </span>
                    </t>
                </div>
                <a href="#" t-on-click.prevent="openProfiles" t-attf-class="btn btn-light align-self-baseline {{profiling.state.isEnabled ? 'py-2' : ''}}">
                    <i class="o_open_profiling oi oi-launch"/>
                </a>
            </div>
        </DropdownItem>
    </t>

<t t-name="web.ProfilingQwebView">
    <div class="oe_form_field o_ace_view_editor oe_ace_open o_profiling_qweb_view">
        <div class="o_select_view_profiling" t-ref="selector">
            <a role="button" class="dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false" href="#"><MenuItem view="state.view" t-if="state.view"/></a>
            <div class="dropdown-menu" role="menu">
                <t t-foreach="viewObjects" t-as="view" t-key="view_index">
                    <a role="menuitem" href="#" t-att-data-id="view.id" t-on-click.prevent="_onSelectView">
                        <MenuItem view="view"/>
                    </a>
                </t>
            </div>
        </div>
        <div class="ace-view-editor" t-ref="ace"/>
        <small class="text-muted">
            It is possible that the "t-call" time does not correspond to the overall time of the
            template. Because the global time (in the drop down) does not take into account the
            duration which is not in the rendering (look for the template, read, inheritance,
            compilation...). During rendering, the global time also takes part of the time to make
            the profile as well as some part not logged in the function generated by the qweb.
        </small>
    </div>
</t>
<t t-name="web.ProfilingQwebView.menuitem">
    <div class="o_delay"><t t-if="props.view.delay" t-esc="props.view.delay"/> ms</div>
    <div class="o_query"><t t-if="props.view.delay" t-esc="props.view.query"/> query</div>
    <t t-esc="props.view.display_name"/>
    <div class="o_key text-muted">(<t t-esc="props.view.id"/>, <t t-esc="props.view.key"/>)</div>
</t>
<t t-name="web.ProfilingQwebView.hover">
    <div class="o_info o_detail">
        <div class="o_delay"><t t-esc="delay"/> <span>ms</span></div>
        <div class="o_query"><t t-esc="query"/> <span>query</span></div>
    </div>
</t>
<t t-name="web.ProfilingQwebView.info">
    <div class="o_info">
        <div t-if="displayDetail" class="o_more">
            <span>*</span>
            <table class="o_detail">
                <thead>
                    <tr><th/><th>ms</th><th>query</th></tr>
                </thead>
                <tbody>
                    <tr t-foreach="groups" t-as="directive" t-key="directive_index">
                        <td><t t-esc="directive"/></td>
                        <td><t t-esc="groups[directive].delays.join(' ')"/></td>
                        <td><t t-esc="groups[directive].querys.join(' ')"/></td>
                    </tr>
                </tbody>
            </table>
        </div>
        <div class="o_delay"><t t-esc="delay"/></div>
        <div class="o_query"><t t-esc="query"/></div>
    </div>
</t>

<t t-name="web.ProfilingSystrayItem">
        <div class="d-flex align-items-center">
            <i class="fa fa-circle text-danger o_debug_recording"/>
        </div>
    </t>

<t t-name="web.Dialog">
        <div class="o_dialog" t-att-id="id" t-att-class="{ o_inactive_modal: !data.isActive }">
            <div role="dialog" class="modal d-block" tabindex="-1" t-att-class="{ o_technical_modal: props.technical, o_modal_full: isFullscreen, o_inactive_modal: !data.isActive }" t-ref="modalRef">
                <div class="modal-dialog modal-dialog-centered" t-attf-class="modal-{{props.size}}">
                    <div class="modal-content" t-att-class="props.contentClass" t-att-style="contentStyle">
                        <header t-if="props.header" class="modal-header">
                            <t t-slot="header" close="data.close" isFullscreen="isFullscreen">
                                <t t-call="web.Dialog.header">
                                    <t t-set="fullscreen" t-value="isFullscreen"/>
                                </t>
                            </t>
                        </header>

                        <footer t-if="props.footer" class="modal-footer justify-content-around justify-content-md-start flex-wrap gap-1 w-100" style="order:2">
                            <t t-slot="footer" close="() =&gt; this.data.close()">
                                <button class="btn btn-primary o-default-button" t-on-click="() =&gt; this.data.close()">
                                    <t>Ok</t>
                                </button>
                            </t>
                        </footer>
                        <main class="modal-body" t-attf-class="{{ props.bodyClass }} {{ !props.withBodyPadding ? 'p-0': '' }}">
                            <t t-slot="default" close="() =&gt; this.data.close()"/>
                        </main>
                    </div>
                </div>
            </div>
        </div>
    </t>

    <t t-name="web.Dialog.header">
        <t t-if="fullscreen">
            <button class="btn oi oi-arrow-left" data-bs-dismiss="modal" aria-label="Close" t-on-click="dismiss"/>
        </t>
        <h4 class="modal-title text-break" t-att-class="{ 'me-auto': fullscreen }">
            <t t-esc="props.title"/>
        </h4>
        <t t-if="!fullscreen">
            <button type="button" class="btn-close" aria-label="Close" tabindex="-1" t-on-click="dismiss"/>
        </t>
    </t>
<t t-name="web.DomainSelector">
        <div class="o_domain_selector w-100" aria-atomic="true" t-att-class="props.className">
            <t t-if="tree">
                <TreeEditor resModel="props.resModel" tree="tree" update.bind="update" readonly="props.readonly" isDebugMode="props.isDebugMode" defaultCondition="defaultCondition" defaultConnector="props.defaultConnector" getOperatorEditorInfo.bind="getOperatorEditorInfo" getDefaultOperator.bind="getDefaultOperator" getPathEditorInfo.bind="getPathEditorInfo">
                    <CheckBox t-if="showArchivedCheckbox" value="includeArchived" disabled="props.readonly" className="'form-switch'" onChange.bind="toggleIncludeArchived">
                        Include archived
                    </CheckBox>
                </TreeEditor>
            </t>
            <t t-else="">
                <div class="o_domain_selector_row d-flex align-items-center">
                    This domain is not supported.
                    <t t-if="!props.readonly">
                        <button class="btn btn-sm btn-primary ms-2" t-on-click="() =&gt; this.resetDomain()">Reset domain</button>
                    </t>
                </div>
            </t>
            <t t-if="props.isDebugMode and (!tree or !props.readonly)">
                <label class="o_domain_selector_debug_container d-block mt-3 border rounded p-3 bg-100 text-muted font-monospace">
                    <span class="small"># Code editor</span>
                    <textarea class="pt-2 border-0 bg-transparent text-body" type="text" t-att-readonly="props.readonly" spellcheck="false" t-att-value="props.domain" t-on-change="(ev) =&gt; this.onDomainChange(ev.target.value)"/>
                </label>
            </t>
        </div>
    </t>

<t t-name="web.DomainSelectorDialog">
        <Dialog title="dialogTitle">
            <div t-if="props.text" class="mb-3" t-out="props.text"/>
            <DomainSelector t-props="domainSelectorProps"/>
            <t t-set-slot="footer">
                <t t-if="props.readonly">
                    <button class="btn btn-secondary" t-on-click="() =&gt; props.close()">Close</button>
                </t>
                <t t-else="">
                    <button class="btn btn-primary" t-att-disabled="disabled" t-on-click="onConfirm" t-ref="confirm"><t t-esc="confirmButtonText"/></button>
                    <button class="btn btn-secondary" t-on-click="onDiscard"><t t-esc="discardButtonText"/></button>
                </t>
            </t>
        </Dialog>
    </t>

<t t-name="web.AccordionItem">
        <div class="o_accordion position-relative">
            <button class="o_menu_item o_accordion_toggle dropdown-item" tabindex="0" t-att-class="{'selected': props.selected, 'open': state.open}" t-attf-class="{{ props.class }}" t-att-aria-expanded="state.open ? 'true' : 'false'" t-esc="props.description" t-on-click="() =&gt; state.open = !state.open"/>
            <t t-if="state.open">
                <div class="o_accordion_values ms-4 border-start">
                    <t t-slot="default"/>
                </div>
            </t>
        </div>
    </t>

<t t-name="web.Dropdown">
    <div class="o-dropdown dropdown" t-att-class="props.class" t-attf-class="         {{ state.directionCaretClass || ''}}         {{ state.open ? 'show' : ''}}         {{ !showCaret ? 'o-dropdown--no-caret' : '' }}       " t-ref="root">
      <button t-if="props.toggler !== 'parent'" type="button" class="dropdown-toggle" t-attf-class="           {{props.togglerClass || ''}}           {{parentDropdown ? 'dropdown-item' : ''}}         " t-att-disabled="props.disabled" t-on-click.stop="onTogglerClick" t-on-mouseenter="onTogglerMouseEnter" t-att-title="props.title" t-att-data-hotkey="props.hotkey" t-att-data-tooltip="props.tooltip" t-att-tabindex="props.skipTogglerTabbing ? -1 : 0" t-att-aria-expanded="state.open ? 'true' : 'false'" t-ref="togglerRef">
        <t t-slot="toggler" open="state.open"/>
      </button>
      <div t-if="state.open" t-attf-class="           o-dropdown--menu dropdown-menu           {{ parentDropdown ? 'o-dropdown--menu-submenu' : '' }}           {{ props.menuDisplay }}         " t-att-class="props.menuClass" role="menu" t-ref="menuRef" t-on-pointerenter="() =&gt; props.holdOnHover and position.lock()" t-on-pointerleave="() =&gt; props.holdOnHover and position.unlock()" t-on-scroll="props.onScroll">
        <t t-slot="default"/>
      </div>
    </div>
  </t>

<t t-name="web.DropdownItem">
    <t t-tag="props.href ? 'a' : 'span'" t-att-href="props.href" class="dropdown-item" t-att-class="props.class" role="menuitem" t-on-click.stop="onClick" t-att-title="props.title" t-att-data-hotkey="props.hotkey" t-att="dataAttributes" tabindex="0">
      <t t-slot="default"/>
    </t>
  </t>


  <t t-name="web.CheckboxItem">
    <t t-tag="props.href ? 'a' : 'span'" t-att-href="props.href" class="dropdown-item" t-att-class="props.class" role="menuitemcheckbox" t-on-click.stop="onClick" t-att-title="props.title" t-att-data-hotkey="props.hotkey" t-att="dataAttributes" tabindex="0" t-att-aria-checked="props.checked ? 'true' : 'false'">
      <t t-slot="default"/>
    </t>
  </t>


  <t t-name="web.RainbowMan">
        <div class="o_reward position-absolute top-0 bottom-0 start-0 end-0 w-100 h-100" t-att-class="{ o_reward_fading: state.isFading }" t-on-animationend="onAnimationEnd">
            <svg class="o_reward_rainbow_man position-absolute top-0 bottom-0 start-0 end-0 m-auto overflow-visible" viewBox="0 0 400 400">
                <defs>
                    <radialGradient id="o_reward_gradient_bg" cx="200" cy="200" r="200" gradientUnits="userSpaceOnUse">
                        <stop offset="0.3" stop-color="#edeff4"/>
                        <stop offset="1" stop-color="#edeff4" stop-opacity="0"/>
                    </radialGradient>
                    <symbol id="o_reward_star">
                        <path d="M33 15.9C26.3558 13.6951 21.1575 8.4597 19 1.8 19 1.2477 18.5523.8 18 .8 17.4477.8 17 1.2477 17 1.8 14.6431 8.6938 9.0262 13.9736 2 15.9 1.3649 15.9.85 16.4149.85 17.05.85 17.6851 1.3649 18.2 2 18.2 8.6215 20.3845 13.8155 25.5785 16 32.2 16 32.7523 16.4477 33.2 17 33.2 17.5523 33.2 18 32.7523 18 32.2 20.3569 25.3062 25.9738 20.0264 33 18.1 33.6351 18.1 34.15 17.5851 34.15 16.95 34.15 16.3149 33.6351 15.8 33 15.8" fill="#FFFFFF"/>
                    </symbol>
                    <symbol id="o_reward_thumb">
                        <path d="M10 52C6 51 3 48 3 44 2 42 3 39 5 38 3 36 2 34 2 32 2 29 3 27 5 26 3 24 2 21 2 19 2 15 7 12 10 12L23 12C23 11 23 11 23 11L23 10C23 8 24 6 25 4 27 2 29 2 31 2 33 2 35 2 36 4 38 5 39 7 39 10L39 38C39 41 37 45 35 47 32 50 28 51 25 52L10 52 10 52Z" fill="#FBFBFC"/>
                        <polygon fill="#ECF1FF" points="25 11 25 51 5 52 5 12"/>
                        <path d="M31 0C28 0 26 1 24 3 22 5 21 7 21 10L10 10C8 10 6 11 4 12 2 14 1 16 1 19 1 21 1 24 2 26 1 27 1 29 1 32 1 34 1 36 2 38 1 40 0 42 1 45 1 50 5 53 10 54L25 54C29 54 33 52 36 49 39 46 41 42 41 38L41 10C41 4 36 0 31 0M31 4C34 4 37 6 37 10L37 38C37 41 35 44 33 46 31 48 28 49 25 50L10 50C7 49 5 47 5 44 4 41 6 38 9 37L9 37C6 37 5 35 5 32 5 28 6 26 9 26L9 26C6 26 5 22 5 19 5 16 8 14 11 14L23 14C24 14 25 12 25 11L25 10C25 7 28 4 31 4" fill="#A1ACBA"/>
                    </symbol>
                </defs>
                <rect width="400" height="400" fill="url(#o_reward_gradient_bg)"/>
                <g transform="translate(47 45) scale(0.9)" class="o_reward_rainbow">
                    <path d="M270,170a100,100,0,0,0-200,0" class="o_reward_rainbow_line" stroke="#FF9E80" stroke-linecap="round" stroke-width="21" fill="none" stroke-dasharray="600 600" stroke-dashoffset="-600"/>
                    <path d="M290,170a120,120,0,0,0-240,0" class="o_reward_rainbow_line" stroke="#FFE57F" stroke-linecap="round" stroke-width="21" fill="none" stroke-dasharray="600 600" stroke-dashoffset="-600"/>
                    <path d="M310,170a140,140,0,0,0-280,0" class="o_reward_rainbow_line" stroke="#80D8FF" stroke-linecap="round" stroke-width="21" fill="none" stroke-dasharray="600 600" stroke-dashoffset="-600"/>
                    <path d="M330,170a160,160,0,0,0-320,0" class="o_reward_rainbow_line" stroke="#C794BA" stroke-linecap="round" stroke-width="21" fill="none" stroke-dasharray="600 600" stroke-dashoffset="-600"/>
                </g>
                <g transform="translate(80 125)">
                    <use href="#o_reward_star" transform-origin="center" class="o_reward_box o_reward_star_01"/>
                </g>
                <g transform="translate(140 75)">
                    <use href="#o_reward_star" transform-origin="center" class="o_reward_box o_reward_star_02"/>
                </g>
                <g transform="translate(230 90)">
                    <use href="#o_reward_star" transform-origin="center" class="o_reward_box o_reward_star_03"/>
                </g>
                <g transform="translate(275 120)">
                    <use href="#o_reward_star" transform-origin="center" class="o_reward_box o_reward_star_04"/>
                </g>
                <g class="o_reward_face_group o_reward_box" transform-origin="center top">
                    <g class="o_reward_shadow_container o_reward_box">
                        <ellipse class="o_reward_shadow o_reward_box" cx="200" cy="105%" rx="100" ry="6" fill="#000" opacity="0.25" transform-origin="center"/>
                    </g>
                    <g class="o_reward_face_wrap o_reward_box" transform-origin="center">
                        <image class="o_reward_face" x="132" y="125" width="136" height="136" t-attf-href="{{props.imgUrl}}"/>
                    </g>
                    <g transform="translate(258 174)">
                        <use href="#o_reward_thumb" class="o_reward_box o_reward_thumbup" transform-origin="center"/>
                    </g>
                </g>
            </svg>
            <div class="o_reward_rainbow_man o_reward_msg_container position-absolute top-0 bottom-0 start-0 end-0 m-auto">
                <div class="o_reward_face_group h-100 w-75 mx-auto">
                    <svg viewBox="0 0 42 60" preserveAspectRatio="xMinYMax meet" width="37" height="65%" class="overflow-visible position-relative ms-5">
                        <g class="o_reward_box">
                            <use href="#o_reward_thumb" x="-60%" y="0" transform="rotate(-90) scale(1 -1)" transform-origin="center"/>
                        </g>
                    </svg>
                    <div class="o_reward_msg mx-4">
                        <div class="o_reward_msg_card">
                            <div class="o_reward_msg_content text-muted px-3 py-4 bg-view d-inline-block border border-light border-top-0">
                                <t t-if="!props.Component">
                                    <t t-out="props.message"/>
                                </t>
                                <t t-else="" t-component="props.Component" t-props="props.props"/>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </t>
<t t-name="web.EmojiPicker">
    <div class="o-EmojiPicker bg-view d-flex flex-column justify-content-center" t-att-class="{ 'align-items-center': emojis.length === 0 }" t-on-click="onClick" t-on-keydown="onKeydown">
        <t t-if="emojis.length === 0">
            <span class="o-EmojiPicker-empty">😵‍💫</span>
            <span class="fs-5 text-muted">Failed to load emojis...</span>
        </t>
        <t t-else="">
            <div class="o-EmojiPicker-search d-flex align-items-center mx-2 mt-2 rounded">
                <span class="d-flex mx-1 w-100 rounded o-active">
                    <t t-call="web.EmojiPicker.searchInput">
                        <t t-if="props.state" t-set="localState" t-value="props.state"/>
                        <t t-else="" t-set="localState" t-value="state"/>
                    </t>
                    <i class="oi oi-search p-2 fs-5 rounded-start-0 rounded-3 o-active" title="Search..." role="img" aria-label="Search..."/>
                </span>
            </div>
            <t t-set="itemIndex" t-value="0"/>
            <div class="o-EmojiPicker-content overflow-auto d-flex flex-grow-1 w-100 flex-wrap align-items-center user-select-none mt-1" t-att-class="getEmojis().length === 0 ? 'flex-column justify-content-center' : 'align-content-start'" t-ref="emoji-grid" t-on-scroll="highlightActiveCategory">
                <t t-if="searchTerm and getEmojis().length === 0" class="d-flex flex-column">
                    <span class="o-EmojiPicker-empty">😢</span>
                    <span class="fs-5 text-muted">No emoji match your search</span>
                </t>
                <t t-if="recentEmojis.length &gt; 0 and !searchTerm">
                    <t t-call="web.EmojiPicker.section">
                        <t t-set="category" t-value="recentCategory"/>
                    </t>
                    <t t-foreach="recentEmojis" t-as="emoji" t-key="'recent_' + emoji_index">
                        <t t-call="web.EmojiPicker.emoji">
                            <t t-set="emoji" t-value="emoji"/>
                        </t>
                        <t t-set="itemIndex" t-value="itemIndex + 1"/>
                    </t>
                </t>
                <t t-set="current" t-value=""/>
                <t t-foreach="getEmojis()" t-as="emoji" t-key="emoji_index">
                    <t t-if="!searchTerm and current !== emoji.category">
                        <t t-set="current" t-value="emoji.category"/>
                        <t t-set="category" t-value="categories.find(c =&gt; c.name === current)"/>
                        <t t-call="web.EmojiPicker.section">
                            <t t-set="category" t-value="category"/>
                        </t>
                    </t>
                    <t t-elif="searchTerm" t-set="categorySortId" t-value="null"/>
                    <t t-call="web.EmojiPicker.emoji">
                        <t t-set="emoji" t-value="emoji"/>
                    </t>
                    <t t-set="itemIndex" t-value="itemIndex + 1"/>
                </t>
            </div>
            <div class="o-EmojiPicker-navbar d-flex flex-shrink-0 w-100 align-items-center bg-100 overflow-auto border-top">
                <t t-if="recentEmojis.length &gt; 0" t-call="web.EmojiPicker.tab">
                    <t t-set="category" t-value="recentCategory"/>
                </t>
                <t t-foreach="categories" t-as="category" t-key="category.sortId">
                    <t t-call="web.EmojiPicker.tab">
                        <t t-set="category" t-value="category"/>
                    </t>
                </t>
            </div>
        </t>
    </div>
</t>

<t t-name="web.EmojiPicker.tab">
    <span class="o-Emoji text-center p-1 cursor-pointer" t-att-class="{'o-active': category.sortId === state.categoryId}" t-att-title="category.name" t-att-data-id="category.sortId" t-on-click="selectCategory">
        <t t-esc="category.title"/>
    </span>
</t>

<t t-name="web.EmojiPicker.section">
    <span class="w-100 fs-7 p-2 position-sticky top-0 bg-view" t-att-data-category="category.sortId"><span class="o-EmojiPicker-sectionIcon" t-esc="category.title"/><span class="ms-2" t-esc="category.displayName"/></span>
    <span class="o-EmojiPicker-category opacity-100 fs-7 py-2" t-att-data-category="category.sortId"/>
</t>

<t t-name="web.EmojiPicker.emoji">
    <span class="o-Emoji cursor-pointer d-flex justify-content-center rounded" t-att-class="{ 'o-active': state.activeEmojiIndex === itemIndex, 'fs-2': !ui.isSmall, 'fs-1': ui.isSmall }" t-att-title="emoji.name" t-att-data-codepoints="emoji.codepoints" t-att-data-index="itemIndex" t-att-data-category="recentCategory.sortId" t-on-click="selectEmoji">
        <span t-esc="emoji.codepoints"/>
    </span>
</t>

<t t-name="web.EmojiPicker.searchInput">
    <input class="form-control border-0 flex-grow-1 rounded-3 rounded-end-0 o-active" placeholder="Search for an emoji" t-model="localState.searchTerm" t-ref="autofocus" t-att-model="localState.searchTerm" t-on-input="() =&gt; this.state.activeEmojiIndex = 0"/>
</t>

<t t-name="web.WarningDialog">
      <Dialog title="title" size="'md'" contentClass="'o_error_dialog'">
        <div role="alert">
          <p t-esc="message" class="text-prewrap"/>
        </div>
        <t t-set-slot="footer">
          <button class="btn btn-primary o-default-button" t-on-click="props.close">Close</button>
        </t>
      </Dialog>
    </t>

    <t t-name="web.RedirectWarningDialog">
      <Dialog title="title" size="'md'" contentClass="'o_error_dialog'">
        <div role="alert">
          <p t-esc="message" class="text-prewrap"/>
        </div>
        <t t-set-slot="footer">
          <button class="btn btn-primary" t-on-click="onClick" t-esc="buttonText"/>
          <button class="btn btn-secondary" t-on-click="props.close">Close</button>
        </t>
      </Dialog>
    </t>

    <t t-name="web.Error504Dialog">
      <Dialog title="this.constructor.title" size="'md'" contentClass="'o_error_dialog'">
        <div role="alert">
            <p class="text-prewrap">
            The operation was interrupted. This usually means that the current operation is taking too much time.
            </p>
        </div>
        <t t-set-slot="footer">
          <button class="btn btn-primary o-default-button" t-on-click="props.close">Close</button>
        </t>
      </Dialog>
    </t>

    <t t-name="web.SessionExpiredDialog">
      <Dialog title="this.constructor.title" size="'md'" contentClass="'o_error_dialog'">
        <div role="alert">
          <p class="text-prewrap">
            Your Odoo session expired. The current page is about to be refreshed.
          </p>
        </div>
        <t t-set-slot="footer">
          <button class="btn btn-primary o-default-button" t-on-click="onClick">Close</button>
        </t>
      </Dialog>
    </t>

    <t t-name="web.ErrorDialog">
      <Dialog title="this.constructor.title" size="'md'" contentClass="'o_error_dialog'">
         <div role="alert">
          <p class="text-prewrap">
            <p><b>An error occurred</b></p>
            <p>Please use the copy button to report the error to your support service.</p>
          </p>

          <button class="btn btn-link" t-on-click="() =&gt; { state.showTraceback = !state.showTraceback }">See details</button>
          <div t-if="state.showTraceback and (props.name or props.message)" class="alert alert-info bg-100 clearfix" role="alert">
            <code t-if="props.name" t-esc="props.name"/>
            <p t-if="props.message" t-esc="props.message"/>
          </div>
          <div t-if="state.showTraceback" class="alert alert-danger o_error_detail" role="alert">
              <pre t-esc="traceback or props.traceback"/>
          </div>
        </div>
        <t t-set-slot="footer">
          <button class="btn btn-primary o-default-button" t-on-click="props.close">Close</button>
          <button class="btn btn-secondary" t-on-click="onClickClipboard">
            <i class="fa fa-clipboard mr8"/><t>Copy error to clipboard</t>
          </button>
        </t>
      </Dialog>
    </t>

<t t-name="web.ExpressionEditor">
        <div class="o_expression_editor w-100" aria-atomic="true">
            <t t-if="tree">
                <TreeEditor resModel="props.resModel" tree="tree" isDebugMode="isDebugMode" update.bind="update" defaultCondition="defaultCondition" getDefaultOperator.bind="getDefaultOperator" getOperatorEditorInfo.bind="getOperatorEditorInfo" getPathEditorInfo.bind="getPathEditorInfo"/>
            </t>
            <t t-else="">
                This expression is not supported.
                <button t-on-click="() =&gt; this.resetExpression()">Reset expression</button>
            </t>
            <t t-if="isDebugMode">
                <div class="o_expression_editor_debug_container d-block mt-3 border rounded p-3 bg-100 text-muted font-monospace">
                    <span class="small"># Code editor</span>
                    <textarea class="pt-2 border-0 bg-transparent text-body" type="text" spellcheck="false" t-att-value="props.expression" t-on-change="(ev) =&gt; this.onExpressionChange(ev.target.value)"/>
                </div>
            </t>
        </div>
    </t>

<t t-name="web.ExpressionEditorDialog">
        <Dialog title="'Edit Condition'">
            <ExpressionEditor t-props="expressionEditorProps"/>
            <t t-set-slot="footer">
                <button class="btn btn-primary" t-on-click="onConfirm" t-ref="confirm">Confirm</button>
                <button class="btn btn-secondary" t-on-click="onDiscard">Discard</button>
            </t>
        </Dialog>
    </t>

<t t-name="web.FileInput">
        <span class="o_file_input" t-att-class="{ 'd-none': props.hidden, 'show opacity-50 pe-none': state.isDisable}" aria-atomic="true">
            <span t-if="!props.hidden" class="o_file_input_trigger" t-on-click.prevent="onTriggerClicked">
                <t t-slot="default">
                    <button class="btn btn-primary">Choose File</button>
                </t>
            </span>
            <input type="file" name="ufile" class="o_input_file d-none" t-att-multiple="props.multiUpload" t-att-accept="props.acceptedFileExtensions" t-ref="file-input" t-att-disabled="state.isDisable" t-on-change="onFileInputChange"/>
        </span>
    </t>

<t t-name="web.FileUploadProgressBar">
        <div class="position-absolute top-0 start-0 h-100 w-100">
            <div class="o-file-upload-progress-bar-value h-100" t-ref="bar" t-att-style="'width: ' + (this.props.fileUpload.progress * 100) + '%;'"/>
            <span class="position-absolute top-0 end-0 cursor-pointer o-file-upload-progress-bar-abort fa fa-times-circle" title="Cancel Upload" aria-label="Cancel Upload" t-on-click.stop.prevent="onCancel"/>
        </div>
    </t>
<t t-name="web.FileUploadProgressContainer">
        <t t-foreach="Object.values(props.fileUploads)" t-as="fileUpload" t-key="fileUpload.id">
            <t t-if="!props.shouldDisplay || props.shouldDisplay(fileUpload)" t-component="props.Component" fileUpload="fileUpload" selector="props.selector"/>
        </t>
    </t>
<t t-name="web.FileUploadProgressKanbanRecord">
        <t t-set="progressTexts" t-value="getProgressTexts()"/>
        <div class="o_kanban_record d-flex flex-grow-1 flex-md-shrink-1 flex-shrink-0">
            <div class="o_kanban_progress_card o_kanban_attachment position-relative p-0 cursor-pointer">
                <div class="o_kanban_image">
                    <div class="o_kanban_image_wrapper">
                        <div class="o_image o_image_thumbnail" t-att-data-mimetype="props.fileUpload.type"/>
                    </div>
                </div>
                <div class="o_kanban_details">
                    <div class="o_kanban_details_wrapper">
                        <div t-att-title="props.fileUpload.title" t-att-aria-label="props.fileUpload.title" class="o_kanban_record_title">
                            <span t-esc="props.fileUpload.title"/>
                        </div>
                        <div class="o_kanban_record_body"/>
                        <div class="o_kanban_record_bottom">
                            <div class="oe_kanban_bottom_left">
                                <div class="o_file_upload_progress_text_left" t-esc="progressTexts.left"/>
                            </div>
                            <div class="oe_kanban_bottom_right">
                                <span class="o_file_upload_progress_text_right" t-esc="progressTexts.right"/>
                            </div>
                        </div>
                    </div>
                </div>
                <FileUploadProgressBar fileUpload="props.fileUpload"/>
            </div>
        </div>
    </t>

    <t t-name="web.FileUploadProgressDataRow">
        <t t-set="progressTexts" t-value="getProgressTexts()"/>
        <div class="o_data_row o_list_progress_card position-relative align-middle p-0">
            <span class="o_file_upload_upload_title" t-esc="props.fileUpload.title"/>
            <span class="o_file_upload_progress_text_left" t-esc="progressTexts.left"/>
            <span class="o_file_upload_progress_text_right" t-esc="progressTexts.right"/>
            <FileUploadProgressBar fileUpload="props.fileUpload"/>
        </div>
    </t>

<t t-name="web.FileViewer">
        <div class="d-flex justify-content-center" t-att-class="{ 'modal fixed-top bottom-0': props.modal }">
            <div class="o-FileViewer flex-column align-items-center d-flex w-100 h-100" tabindex="0" t-ref="autofocus" t-on-keydown.stop="(ev) =&gt; this.onKeydown(ev)">
                <div class="o-FileViewer-header position-absolute top-0 d-flex w-100 bg-black-75 text-400" t-on-click.stop="">
                    <div t-if="isViewable" class="d-flex align-items-center ms-4 me-2">
                        <i t-if="state.file.isImage" class="fa fa-picture-o" role="img" title="Image"/>
                        <i t-if="state.file.isPdf" class="fa fa-file-text" role="img" title="PDF file"/>
                        <i t-if="state.file.isText" class="fa fa-file-text" role="img" title="Text file"/>
                        <i t-if="state.file.isVideo" class="fa fa-video-camera" role="img" title="Video"/>
                    </div>
                    <div class="d-flex align-items-center mx-2 overflow-auto">
                        <span class="text-truncate" t-out="state.file.displayName"/>
                    </div>
                    <div class="flex-grow-1"/>
                    <div class="o-FileViewer-download o-FileViewer-headerButton d-flex align-items-center px-3 cursor-pointer" role="button" title="Download" t-on-click.stop="">
                        <a t-att-href="state.file.downloadUrl" class="text-reset" download="">
                            <i class="fa fa-download fa-fw" role="img"/>
                            <span>Download</span>
                        </a>
                    </div>

                    <div t-on-click.stop="close" class="o-FileViewer-headerButton d-flex align-items-center mb-0 px-3 h4 text-reset cursor-pointer" role="button" title="Close (Esc)" aria-label="Close">
                        <i class="fa fa-fw fa-times" role="img"/>
                    </div>
                </div>
                <div t-on-click.stop="close" t-on-mousemove="onMousemoveView" class="o-FileViewer-main position-absolute top-0 bottom-0 start-0 end-0 align-items-center justify-content-center d-flex" t-att-class="{ 'o_with_img overflow-hidden': state.file.isImage }">
                    <div t-if="state.file.isImage" class="o-FileViewer-zoomer position-absolute align-items-center justify-content-center d-flex w-100 h-100" t-ref="zoomer">
                        <div t-if="!state.imageLoaded" class="position-absolute">
                            <i class="fa fa-3x fa-circle-o-notch fa-fw fa-spin text-white" role="img" title="Loading"/>
                        </div>
                        <img t-on-click.stop="" t-on-load="onImageLoaded" t-on-wheel="onWheelImage" t-on-mousedown.stop="onMousedownImage" t-on-mouseup.stop="onMouseupImage" class="o-FileViewer-view o-FileViewer-viewImage mw-100 mh-100 transition-base" t-att-src="state.file.defaultSource" t-att-style="imageStyle" draggable="false" alt="Viewer" t-ref="image"/>
                    </div>
                    <iframe t-if="state.file.isPdf" class="o-FileViewer-view w-75 h-100 border-0" t-ref="iframeViewerPdf" t-att-class="{ 'w-100': ui.isSmall }" t-att-src="state.file.defaultSource"/>
                    <iframe t-if="state.file.isText" class="o-FileViewer-view o-isText o_text w-75 h-100 border-0" t-att-src="state.file.defaultSource"/>
                    <iframe t-if="state.file.isUrlYoutube" allow="autoplay; encrypted-media" class="o-FileViewer-view w-75 h-100 border-0" t-att-src="state.file.defaultSource" height="315" width="560"/>
                    <video t-if="state.file.isVideo" class="o-FileViewer-view w-75 h-75" t-att-class="{ 'w-100 h-100': ui.isSmall }" t-on-click.stop="" controls="controls">
                        <source t-att-data-type="state.file.mimetype" t-att-src="state.file.defaultSource"/>
                    </video>
                </div>
                <div t-if="state.file.isImage" class="position-absolute bottom-0 d-flex" role="toolbar">
                    <div class="o-FileViewer-toolbarButton p-3 rounded-0" t-on-click.stop="zoomIn" title="Zoom In (+)" role="button">
                        <i class="fa fa-fw fa-plus" role="img"/>
                    </div>
                    <div class="o-FileViewer-toolbarButton p-3 rounded-0" t-att-class="{ 'o_disabled opacity-50': state.scale === 1 }" t-on-click.stop="resetZoom" role="button" title="Reset Zoom (0)">
                        <i class="fa fa-fw fa-search" role="img"/>
                    </div>
                    <div class="o-FileViewer-toolbarButton p-3 rounded-0" t-att-class="{ 'o_disabled opacity-50': state.scale === minScale }" t-on-click.stop="zoomOut" title="Zoom Out (-)" role="button">
                        <i class="fa fa-fw fa-minus" role="img"/>
                    </div>
                    <div class="o-FileViewer-toolbarButton p-3 rounded-0" t-on-click.stop="rotate" title="Rotate (r)" role="button">
                        <i class="fa fa-fw fa-repeat" role="img"/>
                    </div>
                    <div class="o-FileViewer-toolbarButton p-3 rounded-0" t-on-click.stop="onClickPrint" title="Print" role="button">
                        <i class="fa fa-fw fa-print" role="img"/>
                    </div>
                    <div class="o-FileViewer-download o-FileViewer-toolbarButton p-3 rounded-0 cursor-pointer" title="Download" role="button" t-on-click.stop="">
                        <a t-att-href="state.file.downloadUrl" class="text-reset" download="">
                            <i class="fa fa-download fa-fw" role="img"/>
                        </a>
                    </div>
                </div>
                <t t-if="props.files.length &gt; 1">
                    <div class="o-FileViewer-navigation position-absolute top-0 bottom-0 start-0 align-items-center justify-content-center d-flex my-auto ms-3 rounded-circle" t-on-click.stop="previous" title="Previous (Left-Arrow)" aria-label="Previous" role="button">
                        <span class="oi oi-chevron-left" role="img"/>
                    </div>
                    <div class="o-FileViewer-navigation position-absolute top-0 bottom-0 end-0 align-items-center justify-content-center d-flex my-auto me-3 rounded-circle" t-on-click.stop="next" title="Next (Right-Arrow)" aria-label="Next" role="button">
                        <span class="oi oi-chevron-right" role="img"/>
                    </div>
                </t>
            </div>
        </div>
    </t>

<t t-name="web.InstallPrompt">
        <Dialog contentClass="'o_install_prompt position-fixed px-2 py-3 m-2'" size="'md'" footer="false">
            <t t-set-slot="header">
                <div class="d-flex w-100">
                    <h4>How to get the application</h4>
                    <div t-on-click="onClose" type="button" class="btn-close" aria-label="Close"/>
                </div>
            </t>
            <p>Install Odoo on your device to access it easily. Here are the steps to follow:</p>
            <t t-if="isMobileSafari">
                <ul class="list-group list-group-numbered">
                    <li>
                        Tap on the share icon
                    </li>
                    <li>
                        Select "Add to home screen"
                    </li>
                </ul>
            </t>
            <t t-else="">
                <ul class="list-group list-group-numbered">
                    <li>
                        Open "File" menu from your browser
                    </li>
                    <li>
                        Select "Add to dock"
                    </li>
                </ul>
            </t>
        </Dialog>
    </t>
<t t-name="web._ModelFieldSelector">
        <div class="o_model_field_selector d-flex" aria-atomic="true" t-att-class="props.readonly ? 'o_read_mode' : 'o_edit_mode o_input'" t-on-click="(ev) =&gt; this.openPopover(ev.currentTarget)">
            <div class="o_model_field_selector_value flex-grow-1 h-100" tabindex="0" t-att-data-tooltip="state.displayNames.join(' &gt; ')" data-tooltip-position="top">
                <t t-foreach="state.displayNames" t-as="displayName" t-key="displayName_index">
                    <t t-if="!displayName_first">
                        <i class="oi oi-chevron-right m-1" role="img" aria-label="Followed by" title="Followed by"/>
                    </t>
                    <span t-attf-class="o_model_field_selector_chain_part mb-1 #{props.readonly ? 'border-0 fw-bolder' : 'px-1'} text-nowrap">
                        <t t-esc="displayName"/>
                    </span>
                </t>
            </div>
            <div t-if="!props.readonly and state.isInvalid" class="o_model_field_selector_controls ms-2" tabindex="0">
                <i class="fa fa-exclamation-triangle text-warning o_model_field_selector_warning" role="alert" aria-label="Invalid field chain" title="Invalid field chain"/>
            </div>
            <div t-if="!props.readonly and props.allowEmpty and state.displayNames.length" class="o_model_field_selector_controls ms-2" tabindex="0">
                <i class="fa fa-times" t-on-click.stop="clear" aria-label="Clear" title="Clear"/>
            </div>
        </div>
    </t>

<t t-name="web.ModelFieldSelectorPopover">
        <div class="o_model_field_selector_popover" tabindex="0" t-ref="root" t-on-keydown="onInputKeydown">
            <div class="o_model_field_selector_popover_header text-center">
                <t t-if="state.page.previousPage">
                    <i class="oi oi-arrow-left o_model_field_selector_popover_option o_model_field_selector_popover_prev_page" title="Previous" role="img" aria-label="Previous" t-on-click="() =&gt; this.goToPreviousPage()"/>
                </t>
                <div class="o_model_field_selector_popover_title">
                    <t t-esc="state.page.title"/>
                </div>
                <i class="fa fa-times o_model_field_selector_popover_option o_model_field_selector_popover_close" title="Close" role="img" aria-label="Close" t-on-click="() =&gt; props.close()"/>
                <t t-if="props.showSearchInput">
                    <div class="o_model_field_selector_popover_search mt-2">
                        <input type="text" placeholder="Search..." class="o_input p-1 border rounded-1 bg-view" t-att-value="state.page.query" t-on-input="(ev) =&gt; this.debouncedSearchFields(ev.target.value)"/>
                    </div>
                </t>
            </div>
            <div class="o_model_field_selector_popover_body">
                <ul class="o_model_field_selector_popover_page">
                    <t t-foreach="state.page.fieldNames" t-as="fieldName" t-key="fieldName">
                        <t t-set="fieldDef" t-value="state.page.fieldDefs[fieldName]"/>
                        <li class="o_model_field_selector_popover_item d-flex border-bottom" t-att-class="{ 'active': fieldName === state.page.focusedFieldName }" t-att-data-name="fieldName">
                            <button class="o_model_field_selector_popover_item_name btn btn-light flex-fill rounded-0 text-start" t-on-click="() =&gt; this.selectField(fieldDef)">
                                <t t-esc="fieldDef.string"/>
                                <t t-if="fieldDef.record_name"> (<t t-esc="fieldDef.record_name"/>)</t>
                                <div t-if="props.isDebugMode" class="text-muted o_model_field_selector_popover_item_title"><t t-esc="fieldName"/> (<t t-esc="fieldDef.type"/>)</div>
                            </button>
                            <t t-if="(!fieldDef.is_property and fieldDef.relation and props.followRelations) or fieldDef.type === 'properties'">
                                <button class="o_model_field_selector_popover_item_relation btn btn-light border-0 border-start rounded-0" t-on-click.stop="() =&gt; this.followRelation(fieldDef)">
                                    <i class="oi oi-chevron-right o_model_field_selector_popover_relation_icon" role="img" aria-label="Relation to follow" title="Relation to follow"/>
                                </button>
                            </t>
                        </li>
                    </t>
                </ul>
            </div>
            <t t-if="showDebugInput">
                <div class="o_model_field_selector_popover_footer">
                    <input type="text" class="o_model_field_selector_debug o_input" t-att-value="state.page.path" t-on-change="(ev) =&gt; this.loadNewPath(ev.target.value)" t-on-keydown="onDebugInputKeydown" t-on-input="(ev) =&gt; this.props.update(ev.target.value, true)"/>
                </div>
            </t>
        </div>
    </t>

<t t-name="web.ModelSelector">
        <div class="o_model_selector" t-ref="autocomplete_container">
            <input t-if="env.isSmall" type="text" class="o_input" readonly="" t-att-id="props.id" t-att-value="props.value"/>
            <AutoComplete t-else="" id="props.id" value="props.value || ''" sources="sources" placeholder="placeholder" autoSelect="props.autoSelect" onSelect.bind="onSelect"/>
            <span class="o_dropdown_button"/>
        </div>
    </t>
<t t-name="web.Notebook">
        <div t-attf-class="o_notebook d-flex w-100 {{ props.orientation === 'horizontal' ? 'horizontal flex-column' : 'vertical flex-row' }} {{ props.className }}" t-if="state.currentPage">
            <div class="o_notebook_headers" t-att-class="{ 'm-0': props.orientation === 'vertical' }">
                <ul t-attf-class="nav nav-tabs {{ props.orientation === 'horizontal' ? 'flex-row flex-nowrap' : 'flex-column p-0' }}">
                    <li t-foreach="navItems" t-as="navItem" t-key="navItem[0]" class="nav-item flex-nowrap cursor-pointer" t-if="navItem[1].isVisible" t-attf-class="{{ navItem[1].isDisabled ? 'disabled' : '' }}">
                        <a class="nav-link" t-attf-class="{{ navItem[0] === state.currentPage ? 'active' : '' }} {{ props.orientation === 'vertical' ? 'p-3 rounded-0' : '' }} {{ navItem[1].className || '' }}" t-att-name="navItem[1].name" t-on-click.prevent="() =&gt; this.activatePage(navItem[0])" href="#" role="tab" tabindex="0">
                            <i t-if="props.icons and props.icons[navItem[0]]" t-attf-class="fa {{ props.icons[navItem[0]] }} me-2"/>
                            <t t-esc="navItem[1].title"/>
                        </a>
                    </li>
                </ul>
            </div>
            <div class="o_notebook_content tab-content">
                <div class="tab-pane active" t-ref="activePane">
                    <t t-if="page" t-component="page.Component" t-key="state.currentPage" t-props="page.props"/>
                    <t t-else="" t-slot="{{ state.currentPage }}"/>
                </div>
            </div>
        </div>
    </t>

<t t-name="web.NotificationWowl">
        <div t-on-mouseenter="this.props.freeze" t-on-mouseleave="this.props.refresh" t-attf-class="o_notification {{props.className}} border border-{{props.type}} mb-2 position-relative" role="alert" aria-live="assertive" aria-atomic="true">
            <strong t-if="props.title" t-attf-class="o_notification_title d-block text-{{props.type}} py-2 ps-3 pe-5" t-out="props.title"/>
            <button type="button" class="o_notification_close btn" aria-label="Close" t-on-click="props.close">
                <i class="oi oi-close"/>
            </button>
            <div t-attf-class="o_notification_body ps-3 pe-5 py-2">
                <div t-if="props.message" class="me-auto o_notification_content" t-out="props.message"/>
                <div t-if="props.buttons.length" class="o_notification_buttons d-flex gap-2 mt-2">
                    <button t-foreach="props.buttons" t-as="button" type="button" t-key="button_index" t-attf-class="btn {{button.primary ? 'btn-primary' : 'btn-secondary'}}" t-on-click="button.onClick">
                    <t t-if="button.icon">
                        <i t-if="button.icon.indexOf('fa-') === 0" role="img" t-att-aria-label="button.name" t-att-title="button.name" t-attf-class="fa fa-fw o_button_icon {{button.icon}}"/>
                        <img t-else="" t-att-src="button.icon" t-att-alt="button.name"/>
                    </t>
                    <span t-esc="button.name"/>
                </button>
                </div>
            </div>
        </div>
    </t>

<t t-name="web.OverlayContainer">
        <div class="o-overlay-container">
            <t t-foreach="sortedOverlays" t-as="overlay" t-key="overlay.id">
                <ErrorHandler onError="(error) =&gt; this.handleError(overlay, error)">
                    <t t-component="overlay.component" t-props="overlay.props" t-if="isVisible(overlay)"/>
                </ErrorHandler>
            </t>
        </div>
    </t>

<t t-name="web.Pager">
        <nav class="o_pager d-flex gap-2 h-100" aria-label="Pager">
            <span class="o_pager_counter align-self-center" t-on-click.stop="">
                <t t-if="state.isEditing">
                    <input type="text" class="o_pager_value o_input d-inline-block w-auto text-end mb-n1" size="7" t-ref="autofocus" t-att-value="value" t-on-blur="onInputBlur" t-on-change="onInputChange" t-on-keydown.stop="onInputKeydown"/>
                </t>
                <t t-else="">
                    <span class="o_pager_value d-inline-block border-bottom border-transparent mb-n1" t-esc="value" t-on-click="onValueClick"/>
                </t>
                <span> / </span>
                <t t-if="props.updateTotal">
                    <span class="o_pager_limit o_pager_limit_fetch" t-att-class="{ 'disabled': state.isDisabled }" t-on-click.stop="updateTotal"><t t-esc="props.total"/>+</span>
                </t>
                <t t-else="">
                    <span class="o_pager_limit" t-esc="props.total"/>
                </t>
            </span>
            <span class="btn-group d-print-none" aria-atomic="true">

                <button type="button" class="oi oi-chevron-left btn btn-secondary o_pager_previous px-2 rounded-start" aria-label="Previous" data-tooltip="Previous" tabindex="-1" t-att-data-hotkey="props.withAccessKey ? 'p' : false" t-att-disabled="state.isDisabled or isSinglePage" t-on-click.stop="() =&gt; this.navigate(-1)"/>
                <button type="button" class="oi oi-chevron-right btn btn-secondary o_pager_next px-2 rounded-end" aria-label="Next" data-tooltip="Next" tabindex="-1" t-att-data-hotkey="props.withAccessKey ? 'n' : false" t-att-disabled="state.isDisabled or isSinglePage" t-on-click.stop="() =&gt; this.navigate(1)"/>
            </span>
        </nav>
    </t>

<t t-name="web.PopoverWowl">
        <div role="tooltip" class="o_popover popover mw-100" t-att-class="props.class" t-ref="ref">
            <t t-slot="default"/>
            <div t-if="props.arrow" class="popover-arrow"/>
        </div>
    </t>

<t t-name="web.MultiRecordSelector">
        <div class="o_input d-flex flex-wrap gap-1 o_multi_record_selector" t-ref="multiRecordSelector">
            <TagsList tags="tags"/>
            <RecordAutocomplete resModel="props.resModel" value="''" domain="props.domain" context="props.context" className="'o_record_autocomplete_with_caret flex-grow-1'" fieldString="props.fieldString" placeholder="placeholder" multiSelect="true" getIds.bind="getIds" update.bind="update"/>
        </div>
    </t>

<t t-name="web.RecordAutocomplete">
        <AutoComplete placeholder="props.placeholder" value="props.value" autoSelect="true" resetOnSelect="props.multiSelect" class="props.className" sources="sources" onSelect.bind="onSelect" onChange.bind="onChange"/>
    </t>

<t t-name="web.RecordSelector">
        <div class="o_input d-flex flex-wrap gap-1 o_record_selector">
            <RecordAutocomplete resModel="props.resModel" value="displayName" domain="props.domain" context="props.context" className="'h-100 flex-grow-1'" fieldString="props.fieldString" placeholder="props.placeholder" multiSelect="false" getIds="() =&gt; []" update.bind="update"/>
            <span class="o_dropdown_button"/>
        </div>
    </t>

<t t-name="web_studio.ResizablePanel">
        <div class="o_resizable_panel d-flex flex-column" t-att-class="class" t-ref="containerRef">
            <t t-slot="default"/>
            <div class="o_resizable_panel_handle position-absolute top-0 bottom-0 end-0" t-att-class="props.handleSide === 'start' ? 'start-0' : 'end-0'" t-ref="handleRef"/>
        </div>
    </t>

<t t-name="web.SelectMenu">
        <Dropdown class="\`o_select_menu border w-auto rounded-2 overflow-hidden \${props.class || ''}\`" togglerClass="\`o_select_menu_toggler btn w-100 bg-light \${props.togglerClass || ''} \${canDeselect ? 'o_can_deselect' : ''}\`" menuClass="\`o_select_menu_menu\${props.searchable ? ' py-0' : ''}\${props.multiSelect ? ' o_select_menu_multi_select' : ''} border\`" position="'bottom-fit'" beforeOpen.bind="onBeforeOpen" onScroll.bind="onScroll" onStateChanged.bind="onStateChanged">
            <t t-set-slot="toggler">
                <t t-if="props.multiSelect">
                    <div class="text-wrap text-start">
                        <TagsList tags="multiSelectChoices"/>
                    </div>
                </t>
                <t t-else="">
                    <span class="o_select_menu_toggler_slot text-start text-truncate">
                        <t t-if="!props.slots or !props.slots.default" t-esc="displayValue"/>
                        <t t-else="" t-slot="default"/>
                    </span>
                    <span t-if="canDeselect" t-on-click.stop="() =&gt; this.props.onSelect(null)" class="o_select_menu_toggler_clear p-0 m-0">
                        <i class="fa fa-times"/>
                    </span>
                </t>
                <span class="o_select_menu_toggler_caret p-0 m-0">
                    <i class="fa fa-caret-down"/>
                </span>
            </t>
            <input t-if="props.searchable" type="text" class="dropdown-item o_select_menu_sticky px-3 py-3 position-sticky top-0 start-0 border-bottom" t-ref="inputRef" t-on-input="debouncedOnInput" t-on-keydown="onSearchKeydown" t-att-placeholder="props.searchPlaceholder" autocomplete="selectMenuAutocompleteOff" autocorrect="off" spellcheck="false"/>
            <t t-if="state.choices.length === 0">
                <span class="text-muted fst-italic ms-3">No result found</span>
            </t>
            <t t-foreach="state.displayedOptions" t-as="choice" t-key="choice_index">
                <t t-call="{{ this.constructor.choiceItemTemplate }}">
                    <t t-set="choice" t-value="choice"/>
                </t>
            </t>
            <t t-if="props.slots and props.slots.bottomArea" t-slot="bottomArea" data="state"/>
        </Dropdown>
    </t>

    <t t-name="web.SelectMenu.ChoiceItem">
        <div t-if="choice.isGroup" class="o_select_menu_group sticky-top bg-light px-3 mt-2 fst-italic fw-bolder user-select-none">
            <span t-esc="choice.label"/>
            <hr class="mt-2 mb-1"/>
        </div>
        <DropdownItem t-if="!choice.isGroup" onSelected="() =&gt; this.onItemSelected(choice.value)" class="getItemClass(choice) + ' d-flex align-items-center'">
            <t t-if="props.slots and props.slots.choice" t-slot="choice" data="choice"/>
            <t t-else="">
                <div class="o_select_menu_item_label text-wrap" t-esc="choice.label || choice.value"/>
            </t>
        </DropdownItem>
    </t>

<t t-name="web.sign_svg_text" name="SVG Signature Text">
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" t-att-width="width" t-att-height="height">
            <defs>
                <style type="text/css">
                    @font-face {
                        font-family: "font";
                        src: url(data:font/ttf;base64,<t t-esc="font"/>) format("woff");
                        font-weight: normal;
                        font-style: normal;
                    }
                </style>
            </defs>

            <text t-esc="text" x="50%" t-att-y="height * 3 / 5" t-att-font-size="height * 3 / 5" t-att-textLength="width * 4 / 5 * (type === 'signature' ? Math.min(1, text.length / 7) : 1)" t-att-lengthAdjust="'spacing' + (type === 'signature' ? 'AndGlyphs' : '')" t-attf-style="font-family:'font'; stroke: none; fill: {{color}};" text-anchor="middle"/>
        </svg>
    </t>


    <t t-name="web.NameAndSignature">
        <div class="o_web_sign_name_and_signature">
            <div t-if="!props.noInputName" class="o_web_sign_name_group">
                <label class="col-form-label" t-att-for="'o_web_sign_name_input_' + htmlId">Full Name</label>
                <input type="text" name="signer" t-att-id="'o_web_sign_name_input_' + htmlId" class="o_web_sign_name_input form-control" t-on-input="onInputSignName" t-att-value="props.signature.name" t-ref="signNameInput" placeholder="Type your name to sign" required=""/>
            </div>


            <div t-if="state.showSignatureArea" class="o_web_sign_signature_group bg-100 card mt-3" style="overflow: hidden;">
                <div class="card-header bg-transparent">
                    <div class="row g-0">
                        <div t-if="!props.noInputName or defaultName" class="col-auto">
                            <a role="button" href="#" t-on-click.prevent="onClickSignAuto" t-attf-class="o_web_sign_auto_button me-2 btn btn-light {{ state.signMode === 'auto' ? 'active': '' }}">
                                Auto
                            </a>
                        </div>
                        <div class="col-auto">
                            <a role="button" href="#" t-on-click.prevent="() =&gt; this.setMode('draw')" t-attf-class="o_web_sign_draw_button me-2 btn btn-light {{ state.signMode === 'draw' ? 'active': '' }}">
                                Draw
                            </a>
                        </div>
                        <div class="col-auto">
                            <a role="button" href="#" t-on-click.prevent="onClickSignLoad" t-attf-class="o_web_sign_load_button me-2 btn btn-light {{ state.signMode === 'load' ? 'active': '' }}">
                                Load
                            </a>
                        </div>

                        <div class="col-auto division ms-auto"/>

                        <Dropdown t-if="state.signMode === 'auto'" class="'o_web_sign_auto_select_style col-auto'" showCaret="true" togglerClass="'btn btn-link fa fa-font'">
                            <t t-foreach="fonts" t-as="font" t-key="font_index">
                                <DropdownItem onSelected="() =&gt; this.onSelectFont(font_index)">
                                    <img class="img-fluid" t-att-src="getSVGTextFont(font)"/>
                                </DropdownItem>
                            </t>
                        </Dropdown>

                        <div t-if="state.signMode === 'draw'" t-attf-class="o_web_sign_draw_clear col-auto">
                            <a role="button" href="#" t-on-click.prevent="onClickSignDrawClear" class="btn btn-link fa fa-trash"/>
                        </div>

                        <div t-if="state.signMode === 'load'" class="o_web_sign_load_file col-auto">
                            <button type="button" id="loadFileXml" t-on-click="uploadFile" class="btn btn-link fa fa-upload"/>
                            <input t-ref="signInputLoad" type="file" role="button" name="files[]" class="d-none" t-on-change="onChangeSignLoadInput"/>
                        </div>
                    </div>
                </div>

                <div class="o_web_sign_signature_container position-relative">
                    <div class="o_signature_stroke position-absolute"/>
                    <div t-if="state.showSignatureArea" t-ref="signature" t-att-style="signatureStyle" class="o_web_sign_signature p-0 bg-transparent position-relative"/>
                </div>

                <div t-if="loadIsInvalid" t-attf-class="o_web_sign_load_invalid card-footer d-none">
                    <div class="alert alert-danger mb-0" role="alert">
                        This file is invalid. Please select an image.
                    </div>
                </div>
            </div>
        </div>
    </t>
<t t-name="web.SignatureDialog">
      <Dialog title="title">
         <div>
            <NameAndSignature t-props="nameAndSignatureProps"/>
            <div class="mt16 small">By clicking Adopt &amp; Sign, I agree that the chosen signature/initials will be a valid electronic representation of my hand-written signature/initials for all purposes when it is used on documents, including legally binding contracts.</div>
        </div>
        <t t-set-slot="footer">
          <button class="btn btn-primary" t-att-disabled="signature.isSignatureEmpty" t-on-click="onClickConfirm">Adopt &amp; Sign</button>
          <button class="btn btn-secondary" t-on-click="props.close">Cancel</button>
        </t>
      </Dialog>
    </t>

<t t-name="web.TagsList">
        <t t-foreach="visibleTags" t-as="tag" t-key="tag.id or tag_index">
            <span class="o_tag position-relative d-inline-flex align-items-center user-select-none mw-100" t-att-class="{                     'o_avatar opacity-trigger-hover' : tag.img,                     'o_badge badge rounded-pill lh-1': !tag.img,                 }" t-attf-class="{{ !tag.img ? 'o_tag_color_' + (tag.colorIndex ? tag.colorIndex : '0') : '' }}" tabindex="-1" t-att-data-color="tag.colorIndex" t-att-title="tag.text" t-on-click="(ev) =&gt; tag.onClick and tag.onClick(ev)" t-on-keydown="tag.onKeydown">


                <span t-if="tag.img and props.displayText and tag.onDelete" class="o_avatar_backdrop position-absolute top-0 end-0 bottom-0 start-0 ms-n2 mt-n1 mb-n1 bg-view rounded border shadow opacity-0 opacity-100-hover"/>

                <img t-if="tag.img" t-att-src="tag.img" class="o_avatar o_m2m_avatar position-relative rounded" t-att-class="tag.imageClass"/>

                <i t-if="tag.icon" t-attf-class="p-1 fa {{ tag.icon }}" t-att-class="tag.className"/>

                <div t-if="props.displayText" class="o_tag_badge_text text-truncate" t-att-class="{'position-relative ms-1' : tag.img}" t-out="tag.text"/>

                <a t-if="tag.onDelete" t-on-click.stop.prevent="(ev) =&gt; tag.onDelete and tag.onDelete(ev)" class="o_delete d-flex align-items-center opacity-100-hover" t-att-class="{                             'btn btn-link position-relative py-0 px-1 text-danger opacity-0': tag.img,                             'ps-1 opacity-75': !tag.img                         }" title="Delete" aria-label="Delete" tabIndex="-1" href="#">
                        <i class="oi oi-close align-text-top"/>
                </a>
            </span>
        </t>
        <span t-if="props.tags and otherTags.length" class="o_m2m_avatar_empty rounded-circle text-center fw-bold" data-tooltip-template="web.TagsList.Tooltip" data-tooltip-position="right" t-att-data-tooltip-info="tooltipInfo">
            <span t-if="otherTags.length &gt; 9" t-esc="'9+'"/>
            <span t-else="" t-esc="'+' + otherTags.length"/>
        </span>
    </t>

    <t t-name="web.TagsList.Tooltip">
        <t t-foreach="tags" t-as="tag" t-key="tag.id">
            <div t-esc="tag.text"/>
        </t>
    </t>

<t t-name="web.Tooltip">
        <div class="o-tooltip tooltip-inner text-start">
            <t t-if="props.template" t-call="{{props.template}}" t-call-context="{ env, ...props.info }"/>
            <span t-else="" t-esc="props.tooltip"/>
        </div>
    </t>

<t t-name="web.TreeEditor">
        <div class="o_tree_editor w-100" aria-atomic="true" t-att-class="className">
            <div t-attf-class="o_tree_editor_node d-flex flex-column #{props.readonly ? 'gap-2' : 'gap-1'}">
                <t t-set="node" t-value="tree"/>
                <div class="o_tree_editor_row d-flex align-items-center">
                    <div class="o_tree_editor_connector d-flex flex-grow-1 align-items-center">
                        <t t-if="node.children.length">
                            <span>Match</span>
                            <t t-if="node.children.length &gt; 1">
                                <t t-call="web.TreeEditor.connector.dropdown"/>
                            </t>
                            <t t-else="">
                                <span class="px-1">
                                    <t t-call="web.TreeEditor.connector.title"/>
                                </span>
                            </t>
                            <span>of the following rules:</span>
                        </t>
                        <t t-else="">
                            <span>Match <strong>all records</strong></span>
                        </t>
                    </div>
                    <t t-slot="default"/>
                </div>
                <t t-if="node.children.length" t-call="web.TreeEditor.connector.children"/>
                <t t-if="!props.readonly">
                    <div class="o_tree_editor_row d-flex align-items-center">
                        <a href="#" role="button" t-on-click="() =&gt; this.insertRootLeaf(node)">New Rule</a>
                    </div>
                </t>
            </div>
        </div>
    </t>

    <t t-name="web.TreeEditor.controls">
        <div class="o_tree_editor_node_control_panel d-flex" role="toolbar" aria-label="Domain node">
            <button class="btn px-2 fs-4" role="button" title="Add New Rule" aria-label="Add New Rule" t-on-click="() =&gt; this.insertLeaf(parent, node)" t-on-mouseenter="(ev) =&gt; this.highlightNode(ev.target, true)" t-on-mouseleave="(ev) =&gt; this.highlightNode(ev.target, false)">
                <i class="fa fa-plus"/>
            </button>
            <button class="btn px-2 fs-4" role="button" title="Add branch" aria-label="Add branch" t-on-click="() =&gt; this.insertBranch(parent, node)" t-on-mouseenter="(ev) =&gt; this.highlightNode(ev.target, true)" t-on-mouseleave="(ev) =&gt; this.highlightNode(ev.target, false)">
                <i class="fa fa-sitemap"/>
            </button>
            <button class="btn btn-link px-2 text-danger fs-4" role="button" title="Delete node" aria-label="Delete node" t-on-click="() =&gt; this.delete(parent, node)" t-on-mouseenter="(ev) =&gt; this.highlightNode(ev.target, true)" t-on-mouseleave="(ev) =&gt; this.highlightNode(ev.target, false)">
                <i class="fa fa-trash"/>
            </button>
        </div>
    </t>

    <t t-name="web.TreeEditor.connector.title">
        <t t-set="title">
            <t t-if="node.value === '|'">
                <t t-if="node.negate">none</t>
                <t t-else="">any</t>
            </t>
            <t t-else="">
                <t t-if="node.negate">not all</t>
                <t t-else="">all</t>
            </t>
        </t>
        <t t-esc="title"/>
    </t>

    <t t-name="web.TreeEditor.connector.dropdown">
        <t t-if="props.readonly">
            <strong class="px-1">
                <t t-call="web.TreeEditor.connector.title"/>
            </strong>
        </t>
        <t t-else="">
            <div aria-atomic="true">
                <Dropdown togglerClass="'btn btn-link btn-primary py-0 px-1'" showCaret="true">
                    <t t-set-slot="toggler">
                        <t t-call="web.TreeEditor.connector.title"/>
                    </t>
                    <DropdownItem onSelected="() =&gt; this.updateConnector(node, '&amp;')">all</DropdownItem>
                    <DropdownItem onSelected="() =&gt; this.updateConnector(node, '|')">any</DropdownItem>
                </Dropdown>
            </div>
        </t>
    </t>

    <t t-name="web.TreeEditor.connector.children">
        <t t-foreach="node.children" t-as="child" t-key="child.type + '_' + child_index">
            <div class="o_tree_editor_node" t-att-class="{ 'ps-4': addPadding }">
                <t t-call="web.TreeEditor.{{ child.type }}">
                    <t t-set="parent" t-value="node"/>
                    <t t-set="node" t-value="child"/>
                </t>
            </div>
        </t>
    </t>

    <t t-name="web.TreeEditor.connector">
        <div class="o_tree_editor_row d-flex align-items-center">
            <div class="o_tree_editor_connector d-flex flex-grow-1">
                <t t-call="web.TreeEditor.connector.dropdown"/>
                <span>of:</span>
            </div>
            <t t-if="!props.readonly">
                <t t-call="web.TreeEditor.controls"/>
            </t>
        </div>
        <t t-call="web.TreeEditor.connector.children">
            <t t-set="addPadding" t-value="true"/>
        </t>
    </t>

    <t t-name="web.TreeEditor.condition">
        <div class="o_tree_editor_row d-flex align-items-center">
            <t t-if="props.readonly">
                <t t-call="web.TreeEditor.condition:readonly"/>
            </t>
            <t t-else="">
                <t t-call="web.TreeEditor.condition:editable"/>
                <t t-call="web.TreeEditor.controls"/>
            </t>
        </div>
    </t>

    <t t-name="web.TreeEditor.condition:readonly">
        <t t-set="description" t-value="getDescription(node)"/>
        <div class="o_tree_editor_condition d-flex gap-1 px-2 border bg-100">
            <ModelFieldSelector path="node.path" resModel="props.resModel" readonly="true"/>
            <span class="fst-italic" t-esc="description.operatorDescription"/>
            <t t-if="description.valueDescription">
                <t t-set="values" t-value="description.valueDescription.values"/>
                <t t-set="join" t-value="description.valueDescription.join"/>
                <t t-set="addParenthesis" t-value="description.valueDescription.addParenthesis"/>
                <t t-if="addParenthesis">( </t>
                <t t-foreach="values" t-as="val" t-key="val_index">
                    <span class="text-primary fw-bolder"><t t-esc="val"/></span>
                    <t t-if="!val_last"> <t t-esc="join"/> </t>
                </t>
                <t t-if="addParenthesis"> )</t>
            </t>
        </div>
    </t>

    <t t-name="web.TreeEditor.Editor">
        <t t-if="!info.isSupported(value)">
            <div t-attf-class="o_tree_editor_editor #{_classes}">
                <div class="o_input d-flex align-items-center">
                    <span class="flex-grow-1 text-truncate" t-esc="info.stringify(value)"/>
                    <i role="alert" class="fa fa-exclamation-triangle text-warning mx-2" t-att-title="(typeof info.message === 'function') ? info.message(value) : info.message"/>
                    <i class="fa fa-times" title="Clear" t-on-click="() =&gt; update(info.defaultValue())"/>
                </div>
            </div>
        </t>
        <t t-elif="info.component">
            <div t-attf-class="o_tree_editor_editor #{_classes}">
                <t t-component="info.component" t-props="info.extractProps({ update, value })"/>
            </div>
        </t>
    </t>

    <t t-name="web.TreeEditor.condition:editable">
        <div class="o_tree_editor_condition d-flex flex-grow-1 align-items-end gap-2">
            <t t-call="web.TreeEditor.Editor">
                <t t-set="_classes" t-value="'col col-md-4 pe-0'"/>
                <t t-set="info" t-value="props.getPathEditorInfo(node)"/>
                <t t-set="value" t-value="node.path"/>
                <t t-set="update" t-value="(path) =&gt; this.updatePath(node, path)"/>
            </t>
            <t t-call="web.TreeEditor.Editor">
                <t t-set="_classes" t-value="'col col-md-2 px-3'"/>
                <t t-set="info" t-value="props.getOperatorEditorInfo(node)"/>
                <t t-set="value" t-value="[node.operator, node.negate]"/>
                <t t-set="update" t-value="(operator, negate) =&gt; this.updateLeafOperator(node, operator, negate)"/>
            </t>
            <t t-call="web.TreeEditor.Editor">
                <t t-set="_classes" t-value="'col ps-0 overflow-hidden'"/>
                <t t-set="info" t-value="getValueEditorInfo(node)"/>
                <t t-set="value" t-value="node.value"/>
                <t t-set="update" t-value="(value) =&gt; this.updateLeafValue(node, value)"/>
            </t>
        </div>
    </t>

    <t t-name="web.TreeEditor.complex_condition">
        <div class="o_tree_editor_row d-flex align-items-center">
            <div class="o_tree_editor_complex_condition flex-grow-1">
                <input class="o_input w-100" t-att-value="node.value" t-att-readonly="props.readonly or !isDebugMode" t-on-change="(ev) =&gt; this.updateComplexCondition(node, ev.target.value)"/>
            </div>
            <t t-call="web.TreeEditor.controls"/>
        </div>
    </t>


<t t-name="web.TreeEditor.Input">
        <input type="text" class="o_input" t-att-value="props.startEmpty ? '' : props.value" t-on-change="(ev) =&gt; props.update(ev.target.value)"/>
    </t>

    <t t-name="web.TreeEditor.Select">
        <select class="o_input pe-3 text-truncate" t-on-change="(ev) =&gt; props.update(deserialize(ev.target.value))">
            <option t-if="props.addBlankOption" hidden="true"/>
            <t t-foreach="props.options" t-as="option" t-key="serialize(option[0])">
                <option t-att-value="serialize(option[0])" t-att-selected="!props.addBlankOption and option[0] === props.value" t-esc="option[1]"/>
            </t>
        </select>
    </t>

    <t t-name="web.TreeEditor.Range">
        <div class="d-flex align-items-center">
            <t t-call="web.TreeEditor.Editor">
                <t t-set="_classes" t-value="'overflow-hidden flex-grow-1'"/>
                <t t-set="info" t-value="props.editorInfo"/>
                <t t-set="value" t-value="props.value[0]"/>
                <t t-set="update" t-value="(val) =&gt; this.update(0, val)"/>
            </t>
            <i class="fa fa-long-arrow-right mx-2" aria-label="Arrow icon" title="Arrow"/>
            <t t-call="web.TreeEditor.Editor">
                <t t-set="_classes" t-value="'overflow-hidden flex-grow-1'"/>
                <t t-set="info" t-value="props.editorInfo"/>
                <t t-set="value" t-value="props.value[1]"/>
                <t t-set="update" t-value="(val) =&gt; this.update(1, val)"/>
            </t>
        </div>
    </t>

    <t t-name="web.TreeEditor.List">
        <div class="o_input d-flex flex-wrap gap-1">
            <TagsList tags="tags"/>
            <div class="flex-grow-1">
                <t t-call="web.TreeEditor.Editor">
                    <t t-set="info" t-value="props.editorInfo"/>
                    <t t-set="value" t-value="props.editorInfo.defaultValue()"/>
                    <t t-set="update" t-value="(val) =&gt; this.update(val)"/>
                </t>
            </div>
        </div>
    </t>

<t t-name="web.FileUploader">
        <t t-if="state.isUploading and props.showUploadingText">Uploading...</t>
        <span t-else="" t-on-click.prevent="onSelectFileButtonClick" style="display:contents">
            <t t-slot="toggler"/>
        </span>
        <t t-slot="default"/>
        <input type="file" t-att-name="props.inputName" t-ref="fileInput" t-attf-class="o_input_file d-none {{ props.fileUploadClass or '' }}" t-att-multiple="props.multiUpload ? 'multiple' : false" t-att-accept="props.acceptedFileExtensions or '*'" t-on-change="onFileChange"/>
    </t>

<t t-name="web_tour.TourPointer">
        <div t-if="props.pointerState.isVisible" t-ref="pointer" t-attf-class="                 o_tour_pointer                 o_{{ position }}                 {{ isOpen ? 'o_open' : (props.bounce ? 'o_bouncing' : '') }}                 {{ props.pointerState.onClick ? 'cursor-pointer' : '' }}             " t-attf-style="                 --TourPointer__width: {{ constructor.width }}px;                 --TourPointer__height: {{ constructor.height }}px;             " t-on-mouseenter="props.pointerState.onMouseEnter or (() =&gt; {})" t-on-mouseleave="props.pointerState.onMouseLeave or (() =&gt; {})" t-on-click="props.pointerState.onClick or (() =&gt; {})">
            <div class="o_tour_pointer_tip position-absolute"/>
            <div class="o_tour_pointer_content rounded overflow-hidden px-3 py-2 w-100 h-100 position-relative" t-att-class="{ invisible: content and !isOpen }">
                <t t-out="content"/>
            </div>
        </div>
    </t>
<t t-name="web_editor.HistoryDialog">
        <Dialog size="size" title="title">
            <div class="dialog-container html-history-dialog">
                <div class="revision-list d-flex flex-column align-content-stretch">
                    <t t-if="!state.revisionsData.length">
                        <div class="text-center w-100 pb-2 pt-0 px-0 fw-bolder">No history</div>
                    </t>

                    <t t-foreach="state.revisionsData" t-as="rev" t-key="rev.revision_id">
                        <a type="object" href="#" role="button" t-attf-class="btn btn-outline-primary #{state.revisionId === rev.revision_id ? 'active' : ''}" t-on-click="() =&gt; this.updateCurrentRevision(rev.revision_id )">
                            <strong><t t-esc="this.getRevisionDate(rev)"/></strong>
                            <br/>
                            <small><t t-esc="rev.create_user_name"/></small>
                        </a>
                    </t>
                </div>
                <div class="history-container o_notebook">
                    <ul class="nav nav-tabs" role="tablist">
                        <li class="nav-item" role="presentation">
                            <button class="nav-link active" id="history-content" data-bs-toggle="tab" data-bs-target="#history-content-tab" type="button" role="tab" aria-controls="content" aria-selected="true">Content</button>
                        </li>
                        <li class="nav-item" role="presentation">
                            <button class="nav-link" id="history-comparison" data-bs-toggle="tab" data-bs-target="#history-comparison-tab" type="button" role="tab" aria-controls="comparison" aria-selected="false">Comparison</button>
                        </li>
                    </ul>
                    <div class="tab-content">
                        <div class="tab-pane fade show active" id="history-content-tab" role="tabpanel" aria-labelledby="history-content">
                            <t t-out="state.revisionContent"/>
                        </div>
                        <div class="tab-pane fade" id="history-comparison-tab" role="tabpanel" aria-labelledby="history-comparison">
                            <t t-out="state.revisionComparison"/>
                        </div>
                    </div>
                </div>
            </div>
            <t t-set-slot="footer">
                <button class="btn btn-primary" t-on-click="_onRestoreRevisionClick">Restore history</button>
                <button class="btn btn-secondary" t-on-click="props.close">Cancel</button>
            </t>
        </Dialog>
    </t>
<t t-name="web_editor.DocumentAttachment">
    <div class="o_existing_attachment_cell o_we_attachment_highlight card col-2 position-relative mb-2 p-2 opacity-trigger-hover cursor-pointer" t-att-class="{ o_we_attachment_selected: props.selected }" t-on-click="props.selectAttachment">
        <RemoveButton remove="() =&gt; this.remove()"/>
        <div t-att-data-url="props.url" role="img" t-att-aria-label="props.name" t-att-title="props.name" t-att-data-mimetype="props.mimetype" class="o_image d-flex align-items-center justify-content-center"/>
        <small class="o_file_name d-block text-truncate" t-esc="props.name"/>
    </div>
</t>

<t t-name="web_editor.DocumentsListTemplate">
    <div class="o_we_existing_attachments o_we_documents" t-ref="existing-attachments">
        <div t-if="!hasContent" class="o_nocontent_help">
            <p class="o_empty_folder_image">No documents found.</p>
            <p class="o_empty_folder_subtitle">You can upload documents with the button located in the top left of the screen.</p>
        </div>
        <div t-else="" class="d-flex flex-wrap gap-2">
            <t t-foreach="state.attachments" t-as="attachment" t-key="attachment.id">
                <DocumentAttachment url="attachment.url" name="attachment.name" mimetype="attachment.mimetype" id="attachment.id" onRemoved="(attachmentId) =&gt; this.onRemoved(attachmentId)" selected="this.selectedAttachmentIds.includes(attachment.id)" selectAttachment="() =&gt; this.onClickDocument(attachment)"/>
            </t>
        </div>
    </div>
</t>
<t t-name="web_editor.FileSelectorControlPanel">
    <div class="o_we_file_selector_control_panel sticky-top d-flex flex-wrap gap-2 mb-1 p-3 align-items-end">
        <SearchMedia searchPlaceholder="props.searchPlaceholder" needle="props.needle" search="props.search"/>
        <div class="d-flex gap-3 justify-content-start align-items-center">
            <div t-if="props.showOptimizedOption" class="flex-shrink-0 form-check form-switch align-items-center" t-on-change="props.changeShowOptimized">
                <input class="o_we_show_optimized form-check-input" type="checkbox" t-att-checked="props.showOptimized" id="o_we_show_optimized_switch"/>
                <label class="form-check-label" for="o_we_show_optimized_switch">
                    Show optimized images
                </label>
            </div>
            <select t-if="showSearchServiceSelect" class="o_input o_we_search_select form-select" t-on-change="ev =&gt; props.changeSearchService(ev.target.value)">
                <option t-att-selected="props.searchService === 'all'" value="all">All</option>
                <option t-att-selected="props.searchService === 'database'" value="database">My Images</option>
                <option t-if="props.useMediaLibrary" t-att-selected="props.searchService === 'media-library'" value="media-library">Illustrations</option>
        <option t-if="props.useUnsplash" t-att-selected="props.searchService === 'unsplash'" value="unsplash">Photos (via Unsplash)</option>
            </select>
        </div>
        <div class="col justify-content-end flex-nowrap input-group has-validation">
            <input type="text" class="form-control o_input o_we_url_input o_we_transition_ease flex-grow-0" t-att-class="{ o_we_horizontal_collapse: !state.showUrlInput, 'w-auto': state.showUrlInput }" name="url" t-att-placeholder="props.urlPlaceholder" t-model="state.urlInput" t-on-input="onUrlInput" t-if="state.showUrlInput"/>
            <button type="button" class="btn o_upload_media_url_button text-nowrap" t-att-class="{ 'btn-primary': state.urlInput, 'btn-secondary': !state.urlInput}" t-on-click="onUrlUploadClick" t-att-disabled="!enableUrlUploadClick">
                    <t t-esc="props.addText"/>
            </button>
            <div class="d-flex align-items-center">
                <span t-if="state.urlInput and state.isValidUrl and state.isValidFileFormat" class="o_we_url_success text-success mx-2 fa fa-lg fa-check" title="The URL seems valid."/>
                <span t-if="state.urlInput and !state.isValidUrl" class="o_we_url_error text-danger mx-2 fa fa-lg fa-times" title="The URL does not seem to work."/>
                <span t-if="props.urlWarningTitle and state.urlInput and state.isValidUrl and !state.isValidFileFormat" class="o_we_url_warning text-warning mx-2 fa fa-lg fa-warning" t-att-title="props.urlWarningTitle"/>
            </div>
        </div>
        <input type="file" class="d-none o_file_input" t-on-change="onChangeFileInput" t-ref="file-input" t-att-accept="props.accept" t-att-multiple="props.multiSelect and 'multiple'"/>
        <div class="col-auto btn-group">
            <button type="button" class="btn btn-primary o_upload_media_button" t-on-click="onClickUpload">
                <t t-esc="props.uploadText"/>
            </button>
        </div>
    </div>
</t>

<t t-name="web_editor.FileSelector">
    <div>
        <FileSelectorControlPanel uploadText="uploadText" accept="fileMimetypes" urlPlaceholder="urlPlaceholder" addText="addText" searchPlaceholder="searchPlaceholder" urlWarningTitle="urlWarningTitle" uploadUrl="(url) =&gt; this.uploadUrl(url)" uploadFiles="(files) =&gt; this.uploadFiles(files)" showOptimizedOption="showOptimizedOption" showOptimized="state.showOptimized" changeShowOptimized="showOptimized =&gt; this.state.showOptimized = !this.state.showOptimized" changeSearchService="service =&gt; this.state.searchService = service" searchService="state.searchService" needle="state.needle" search="(needle) =&gt; this.handleSearch(needle)" useMediaLibrary="props.useMediaLibrary" validateUrl="validateUrl" multiSelect="props.multiSelect" useUnsplash="state.useUnsplash"/>
        <t t-call="{{ constructor.attachmentsListTemplate }}"/>
        <div t-if="state.unsplashError" class="d-flex mt-2 unsplash_error">
            <UnsplashError title="errorTitle" subtitle="errorSubtitle" showCredentials="['key_not_found', 401].includes(state.unsplashError)" submitCredentials="(key, appId)  =&gt; this.submitCredentials(key, appId)" hasCredentialsError="state.unsplashError === 401"/>
        </div>
        <div name="load_more_attachments" class="pt-3 pb-1 text-center mx-auto o_we_load_more" t-ref="load-more-button">
            <button t-if="canLoadMore" class="btn btn-primary o_load_more" type="button" t-on-click="handleLoadMore">
                Load more...
            </button>
            <div t-elif="hasContent" class="mt-2 o_load_done_msg">
                <span><i t-esc="allLoadedText"/></span>
            </div>
        </div>
        <div t-if="this.state.canScrollAttachments" class="position-sticky d-flex align-items-center mx-auto btn btn-primary rounded-circle oi oi-chevron-down o_scroll_attachments" t-on-click="handleScrollAttachments"/>
    </div>
</t>
<t t-name="web_editor.IconSelector">
    <div>
        <div class="o_we_file_selector_control_panel sticky-top d-flex gap-2 align-items-center mb-1 py-4 px-3">
            <SearchMedia searchPlaceholder="searchPlaceholder" search.bind="this.search" needle="state.needle"/>
        </div>
        <div class="font-icons-icons">
            <t t-foreach="state.fonts" t-as="font" t-key="font.base">
                <div t-if="!font.icons.length" class="o_nocontent_help">
                    <p class="o_empty_folder_image">No pictograms found.</p>
                    <p class="o_empty_folder_subtitle">Try searching with other keywords.</p>
                </div>
                <span t-foreach="font.icons" t-as="icon" t-key="icon.id" t-att-title="icon.names[0]" t-att-aria-label="icon.names[0]" role="img" class="font-icons-icon m-2 fs-2 p-3 cursor-pointer text-center" t-att-class="{ o_we_attachment_selected: this.selectedMediaIds.includes(icon.id) }" t-attf-class="{{ font.base }} {{ icon.names[0] }}" t-on-click="() =&gt; this.onClickIcon(font, icon)"/>
            </t>
        </div>
    </div>
</t>
<t t-name="web_editor.AutoResizeImage">
    <div t-ref="auto-resize-image-container" class="o_existing_attachment_cell o_we_image align-items-center justify-content-center me-1 mb-1 opacity-trigger-hover opacity-0 cursor-pointer" t-att-class="{ o_we_attachment_optimized: props.isOptimized, 'o_loaded position-relative opacity-100': state.loaded, o_we_attachment_selected: props.selected, 'position-fixed': !state.loaded }" t-on-click="props.onImageClick">
        <RemoveButton t-if="props.isRemovable" model="props.model" remove="() =&gt; this.remove()"/>
        <div class="o_we_media_dialog_img_wrapper">
            <img t-ref="auto-resize-image" class="o_we_attachment_highlight img img-fluid w-100" t-att-src="props.src" t-att-alt="props.altDescription" t-att-title="props.title" loading="lazy"/>
            <a t-if="props.author" class="o_we_media_author position-absolute start-0 bottom-0 end-0 text-truncate text-center text-primary fs-6 bg-white-50" t-att-href="props.authorLink" target="_blank" t-esc="props.author"/>
        </div>
        <span t-if="props.isOptimized" class="badge position-absolute bottom-0 end-0 m-1 text-bg-success">Optimized</span>
    </div>
</t>

<t t-name="web_editor.ExternalImage">
    <t t-if="record.mediaType == 'libraryMedia'">
        <AutoResizeImage author="record.author" src="record.thumbnail_url" authorLink="record.author_link" title="record.tooltip" altDescription="record.tooltip" minRowHeight="MIN_ROW_HEIGHT" selected="this.selectedMediaIds.includes(record.id)" onImageClick="() =&gt; this.onClickMedia(record)" onLoaded="(imgEl) =&gt; this.onImageLoaded(imgEl, record)"/>
    </t>
        <t t-elif="record.mediaType == 'unsplashRecord'">
            <AutoResizeImage src="record.url" author="record.user.name" authorLink="record.user.links.html" name="record.user.name" title="record.user.name" altDescription="record.alt_description" selected="this.selectedRecordIds.includes(record.id)" onImageClick="() =&gt; this.onClickRecord(record)" minRowHeight="MIN_ROW_HEIGHT" onLoaded="(imgEl) =&gt; this.onImageLoaded(imgEl, record)"/>
        </t>
</t>

<t t-name="web_editor.ImagesListTemplate">
    <div class="o_we_existing_attachments o_we_images d-flex flex-wrap my-0" t-ref="existing-attachments">
        <t t-if="!hasContent and !isFetching">
            <div t-if="state.needle" class="o_nocontent_help">
                <p class="o_empty_folder_image">No images found.</p>
                <p class="o_empty_folder_subtitle">Wow, it feels a bit empty in here. Upload from the button in the top right corner!</p>
            </div>
            <div t-else="" class="o_we_search_prompt">
                <h2>Discover a world of awesomeness in our copyright-free image haven. No legal drama, just nice images!</h2>
            </div>
        </t>
        <t t-else="">
            <t t-if="['all', 'database'].includes(state.searchService)">
                <t t-foreach="state.attachments" t-as="attachment" t-key="attachment.id">
                    <AutoResizeImage t-if="!attachment.original_id or state.showOptimized" id="attachment.id" isOptimized="!!attachment.original_id" isRemovable="true" onRemoved="(attachmentId) =&gt; this.onRemoved(attachmentId)" selected="this.selectedAttachmentIds.includes(attachment.id)" src="attachment.thumbnail_src or attachment.image_src" name="attachment.name" title="attachment.name" altDescription="attachment.altDescription" model="attachment.res_model" minRowHeight="MIN_ROW_HEIGHT" onImageClick="() =&gt; this.onClickAttachment(attachment)" onLoaded="(imgEl) =&gt; this.onImageLoaded(imgEl, attachment)"/>
                </t>
            </t>
            <t id="o_we_media_library_images" t-if="['all', 'unsplash', 'media-library'].includes(state.searchService)">
            <t t-foreach="combinedRecords" t-as="record" t-key="record.id">
                <t t-call="web_editor.ExternalImage"/>
            </t>
        </t>
    <t t-foreach="[...Array(20).keys()]" t-as="i" t-key="i">
                <div class="o_we_attachment_placeholder"/>
            </t>
        </t>
    </div>
</t>
<t t-name="web_editor.MediaDialog">
    <Dialog contentClass="contentClass" size="size" title="title" modalRef="modalRef">
        <Notebook pages="tabs" onPageUpdate.bind="onTabChange" defaultPage="state.activeTab"/>
        <t t-set-slot="footer">
            <button class="btn btn-primary" t-on-click="() =&gt; this.save()" t-ref="add-button">Add</button>
            <button class="btn btn-secondary" t-on-click="() =&gt; this.props.close()">Discard</button>
        </t>
    </Dialog>
</t>
<t t-name="web_editor.VideoOption">
    <div class="mb-1">
        <label class="d-flex align-items-start gap-2 cursor-pointer" t-on-change="props.onChangeOption">
            <div class="o_switch flex-shrink-0">
                <input type="checkbox" t-att-checked="props.value"/>
                <span/>
            </div>
            <span t-esc="props.label"/>
            <span t-if="props.description" class="text-muted" t-esc="props.description"/>
        </label>
    </div>
</t>

<t t-name="web_editor.VideoIframe">
    <iframe t-att-src="this.props.src" class="o_video_dialog_iframe mw-100 mh-100 overflow-hidden shadow" width="1280" height="720" allowfullscreen="allowfullscreen" frameborder="0"/>
</t>

<t t-name="web_editor.VideoSelector">
    <div class="row">
        <div class="col mt-4 o_video_dialog_form">
            <div class="mb-2">
                <label for="o_video_text">
                    <b>Video code </b>(URL or Embed)
                </label>
                <div class="text-start">
                    <small class="text-muted">Accepts <b><i>Youtube</i></b>, <b><i>Vimeo</i></b>, <b><i>Dailymotion</i></b> and <b><i>Youku</i></b> videos</small>
                </div>
                <textarea t-ref="autofocus" t-model="state.urlInput" class="form-control" id="o_video_text" placeholder="Copy-paste your URL or embed code here" t-on-input="onChangeUrl" t-att-class="{ 'is-valid': state.urlInput and !this.state.errorMessage, 'is-invalid': state.urlInput and this.state.errorMessage }"/>
            </div>
            <div t-if="shownOptions.length" class="o_video_dialog_options">
                <VideoOption t-foreach="shownOptions" t-as="option" t-key="option.id" value="option.value" onChangeOption="() =&gt; this.onChangeOption(option.id)" label="option.label" description="option.description"/>
            </div>
            <t t-if="state.vimeoPreviews.length">
                <span class="fw-bold">Suggestions</span>
                <div id="video-suggestion" class="mt-4 d-flex flex-wrap mh-75 overflow-auto">
                    <t t-foreach="state.vimeoPreviews" t-as="vimeoPreview" t-key="vimeoPreview.id">
                        <div class="o_sample_video w-25 mh-100 cursor-pointer" t-on-click="() =&gt; this.onClickSuggestion(vimeoPreview.src)">
                            <img class="mw-100 mh-100 p-1" t-att-src="vimeoPreview.thumbnailSrc"/>
                        </div>
                    </t>
                </div>
            </t>
        </div>
        <div class="col-md-6">
            <div class="o_video_preview position-relative border-0 p-3">
                <div t-if="this.state.src and !this.state.errorMessage" class="o_video_dialog_preview_text mb-2">Preview</div>
                <div class="media_iframe_video">
                    <div class="media_iframe_video_size"/>
                    <VideoIframe t-if="this.state.src and !this.state.errorMessage" src="this.state.src"/>
                    <div t-if="this.state.errorMessage" class="alert alert-warning o_video_dialog_iframe mw-100 mh-100 mb-2 mt-2" t-esc="this.state.errorMessage"/>
                </div>
            </div>
        </div>
    </div>
</t>
<t t-name="web_editor.ProgressBar">
    <small class="text-info d-flex align-items-center me-2">
        <span t-if="!props.hasError and !props.uploaded"><i class="fa fa-circle-o-notch fa-spin me-2"/></span>
        <span class="fst-italic fw-bold text-truncate flex-grow-1 me-2" t-esc="props.name"/>
        <span class="fw-bold text-nowrap" t-esc="props.size"/>
    </small>
    <small t-if="props.uploaded or props.hasError" class="d-flex align-items-center mt-1">
        <span t-if="props.uploaded" class="text-success"><i class="fa fa-check my-1 me-1"/> File has been uploaded</span>
        <span t-else="" class="text-danger"><i class="fa fa-times float-start my-1 me-1"/> <span class="o_we_error_text" t-esc="props.errorMessage ? props.errorMessage : 'File could not be saved'"/></span>
    </small>
    <div t-else="" class="progress">
        <div class="progress-bar bg-info progress-bar-striped progress-bar-animated" role="progressbar" t-attf-style="width: {{this.progress}}%;" aria-label="Progress bar"><span t-esc="this.progress + '%'"/></div>
    </div>
    <hr/>
</t>

<t t-name="web_editor.UploadProgressToast">
    <div class="o_notification_manager o_upload_progress_toast">
        <div t-if="state.isVisible" class="o_notification position-relative show fade mb-2 border border-info bg-white" role="alert" aria-live="assertive" aria-atomic="true">
            <button type="button" class="btn btn-close o_notification_close p-2" aria-label="Close" t-on-click="props.close"/>
            <div class="o_notification_body ps-2 pe-4 py-2">
                <div class="me-auto o_notification_content">
                    <div t-foreach="state.files" t-as="file" t-key="file" class="o_we_progressbar">
                        <ProgressBar progress="file_value.progress" errorMessage="file_value.errorMessage" hasError="file_value.hasError" name="file_value.name" uploaded="file_value.uploaded" size="file_value.size"/>
                    </div>
                </div>
            </div>
        </div>
    </div>
</t>
<t t-name="web_unsplash.UnsplashError">
    <div class="alert alert-info w-100">
        <h4><t t-esc="props.title"/></h4>
        <p><t t-esc="props.subtitle"/></p>
        <UnsplashCredentials t-if="props.showCredentials" submitCredentials="props.submitCredentials" hasCredentialsError="props.hasCredentialsError"/>
    </div>
</t>

<t t-name="web_unsplash.UnsplashCredentials">
    <div class="d-flex align-items-center flex-wrap">
        <a href="https://www.odoo.com/documentation/17.0/applications/websites/website/optimize/unsplash.html#generate-an-unsplash-access-key" class="me-1" target="_blank">Get an Access key</a>
        and paste it here:
        <input type="text" class="o_input o_required_modifier form-control w-auto mx-2" id="accessKeyInput" placeholder="Paste your access key here" t-model="state.key" t-on-input="() =&gt; this.state.hasKeyError = false" t-att-class="{ 'is-invalid': state.hasKeyError }"/>
        and paste
        <a href="https://www.odoo.com/documentation/17.0/applications/websites/website/optimize/unsplash.html#generate-an-unsplash-application-id" class="mx-1" target="_blank">Application ID</a>
        here:
        <input type="text" class="o_input o_required_modifier form-control w-auto ms-2" placeholder="Paste your application ID here" t-model="state.appId" t-on-input="() =&gt; this.state.hasAppIdError = false" t-att-class="{ 'is-invalid': state.hasAppIdError }"/>
        <button type="button" class="btn btn-primary w-auto ms-3 p-auto save_unsplash" t-on-click="() =&gt; this.submitCredentials()">Apply</button>
    </div>
</t>

<t t-name="portal.chatter_message_count">
        <t t-set="count" t-value="widget.get('message_count')"/>
        <div class="o_message_counter">
            <t t-if="count">
                <span class="fa fa-comments"/>
                <span class="o_message_count"> <t t-esc="count"/></span>
                <t t-if="count == 1"> comment</t>
                <t t-else=""> comments</t>
            </t>
            <t t-else="">
                There are no comments for now.
            </t>
        </div>
    </t>


    <t t-name="portal.Composer">
        <div class="o_portal_chatter_composer" t-if="widget.options['allow_composer']">
            <t t-set="discussion_url" t-value="window.encodeURI(window.location.href.split('#')[0] + '#discussion')"/>
            <t t-if="!widget.options['display_composer']">
                <h4>Leave a comment</h4>
                <p>You must be <a t-attf-href="/web/login?redirect=#{discussion_url}">logged in</a> to post a comment.</p>
            </t>
            <t t-if="widget.options['display_composer']">
                <div class="alert alert-danger mb8 d-none o_portal_chatter_composer_error" role="alert">
                    Oops! Something went wrong. Try to reload the page and log in.
                </div>
                <div class="d-flex">
                    <img alt="Avatar" class="o_avatar o_portal_chatter_avatar align-self-start me-3 rounded" t-attf-src="/web/image/res.partner/#{widget.options['partner_id']}/avatar_128" t-if="!widget.options['is_user_public'] or !widget.options['token']"/>
                    <div class="flex-grow-1">
                        <div class="o_portal_chatter_composer_input">
            <t t-call="portal_rating.rating_star_input">
                <t t-set="default_rating" t-value="widget.options['default_rating_value']"/>
            </t>
                            <div class="o_portal_chatter_composer_body d-flex flex-nowrap align-items-start flex-grow-1 mb-4">
                                <div class="d-flex flex-column flex-grow-1 rounded-3">
                                    <div class="position-relative flex-grow-1">
                                        <textarea rows="4" name="message" class="form-control rounded-3 shadow-none" placeholder="Write a message..." style="resize:none;"><t t-esc="widget.options['default_message'] ? widget.options['default_message'].trim() : ''"/></textarea>
                                    </div>
                                    <div class="d-flex flex-row align-self-end p-2">
                                        <div class="d-flex px-1">
                                            <button class="o_portal_chatter_attachment_btn btn fa fa-paperclip border-0" type="button" title="Add attachment"/>
                                        </div>
                                        <button t-attf-data-action="#{widget.options['force_submit_url'] || '/mail/chatter_post'}" class="o_portal_chatter_composer_btn btn btn-primary o-last rounded-3" type="submit">Send</button>
                                    </div>
                                </div>
                            </div>
                            <div class="o_portal_chatter_attachments mt-3"/>
                        </div>
                        <div class="d-none">
                            <input type="file" class="o_portal_chatter_file_input" multiple="multiple"/>
                        </div>
                    </div>
                </div>
            </t>
        </div>
    </t>

    <t t-name="portal.Chatter.Attachments">
        <div t-if="attachments.length" class="d-flex flex-grow-1 flex-wrap gap-1">
            <div t-foreach="attachments" t-as="attachment" t-key="attachment_index" class="bg-light p-2 rounded position-relative">
                <div class="o_portal_chatter_attachment text-center" t-att-data-id="attachment.id">
                    <button t-if="showDelete and attachment.state == 'pending'" class="o_portal_chatter_attachment_delete btn btn-sm btn-outline-danger" title="Delete">
                        <i class="fa fa-times"/>
                    </button>
                    <a t-attf-href="/web/content/#{attachment.id}?download=true&amp;access_token=#{attachment.access_token}" target="_blank" class="d-flex flex-row">
                        <div class="oe_attachment_embedded o_image" t-att-title="attachment.name" t-att-data-mimetype="attachment.mimetype"/>
                        <div class="o_portal_chatter_attachment_name align-self-center text-truncate" t-att-data-tooltip="attachment.name" data-tooltip-position="top">
                            <t t-esc="attachment.name"/>
                        </div>
                    </a>
                </div>
            </div>
        </div>
    </t>



    <t t-name="portal.chatter_messages">
        <div class="o_portal_chatter_messages">
            <t t-foreach="widget.get('messages') || []" t-as="message" t-key="message_index">
                <div class="d-flex o_portal_chatter_message mb-4" t-att-id="'message-' + message.id">
                    <img class="o_avatar o_portal_chatter_avatar rounded me-3" t-att-src="message.author_avatar_url" alt="avatar"/>
                    <div class="flex-grow-1">
                        <t t-call="portal.chatter_internal_toggle" t-if="widget.options['is_user_employee']"/>

                        <div class="o_portal_chatter_message_title">
                            <h5 class="mb-1"><t t-esc="message.author_id[1]"/></h5>
                            <p class="o_portal_chatter_puslished_date">Published on <t t-esc="message.published_date_str"/></p>
                        </div>
            <t t-if="message['rating_value']">
                <t t-call="portal_rating.rating_stars_static">
                    <t t-set="val" t-value="message.rating_value"/>
                </t>
            </t>
                        <t t-out="message.body"/>

                        <div class="o_portal_chatter_attachments">
                            <t t-call="portal.Chatter.Attachments">
                                <t t-set="attachments" t-value="message.attachment_ids"/>
                            </t>
                        </div>

            <t t-if="message.rating and message.rating.id" t-call="portal_rating.chatter_rating_publisher">
                <t t-set="is_publisher" t-value="widget.options['is_user_publisher']"/>
                <t t-set="rating" t-value="message.rating"/>
            </t>
                    </div>
                </div>
            </t>
        </div>
    </t>


    <t t-name="portal.chatter_internal_toggle">
        <div t-if="message.is_message_subtype_note" class="float-end">
            <span class="badge rounded-pill px-3 py-2 text-bg-light" title="Internal notes are only displayed to internal users.">Internal Note</span>
        </div>
        <div t-else="" t-attf-class="float-end o_portal_chatter_js_is_internal d-flex #{message.is_internal and 'o_portal_message_internal_on' or 'o_portal_message_internal_off'}" t-att-data-message-id="message.id" t-att-data-is-internal="message.is_internal">
            <div class="form-check form-switch o_portal_chatter_visibility_on" title="Currently restricted to internal employees, click to make it available to everyone viewing this document.">
                <input class="form-check-input" type="checkbox" role="switch"/>
                <label class="form-check-label small">Public</label>
            </div>
            <div class="form-check form-switch o_portal_chatter_visibility_off" title="Currently available to everyone viewing this document, click to restrict to internal employees.">
                <input class="form-check-input" type="checkbox" role="switch" checked="true"/>
                <label class="form-check-label small">Public</label>
            </div>
        </div>
    </t>

    <t t-name="portal.pager">
        <div class="o_portal_chatter_pager">
            <t t-if="Object.keys(widget.get('pager') || {}).length &gt; 0">
                <ul class="pagination" t-if="widget.get('pager')['pages'].length &gt; 1">
                    <li t-if="widget.get('pager')['page'] != widget.get('pager')['page_previous']" t-att-data-page="widget.get('pager')['page_previous']" class="page-item o_portal_chatter_pager_btn">
                        <a href="#" class="page-link"><i class="oi oi-chevron-left" role="img" aria-label="Previous" title="Previous"/></a>
                    </li>
                    <t t-foreach="widget.get('pager')['pages']" t-as="page" t-key="page_index">
                        <li t-att-data-page="page" t-attf-class="page-item #{page == widget.get('pager')['page'] ? 'o_portal_chatter_pager_btn active' : 'o_portal_chatter_pager_btn'}">
                            <a href="#" class="page-link"><t t-esc="page"/></a>
                        </li>
                    </t>
                    <li t-if="widget.get('pager')['page'] != widget.get('pager')['page_next']" t-att-data-page="widget.get('pager')['page_next']" class="page-item o_portal_chatter_pager_btn">
                        <a href="#" class="page-link"><i class="oi oi-chevron-right" role="img" aria-label="Next" title="Next"/></a>
                    </li>
                </ul>
            </t>
        </div>
    </t>

    <t t-name="portal.Chatter">
        <t t-set="two_columns" t-value="widget.options['two_columns']"/>
        <div t-attf-class="o_portal_chatter p-0 #{two_columns and 'row' or ''}">
            <div t-attf-class="#{two_columns and 'col-lg-5' or ''}">
                <div class="o_portal_chatter_header pb-2 text-muted">
                    <t t-if="widget.options['display_rating']">
                <t t-call="portal_rating.rating_card"/>
            </t>
            <t t-if="!widget.options['display_rating']">
                <t t-call="portal.chatter_message_count"/>
            </t>
        </div>
                <div class="o_portal_chatter_composer"/>
            </div>
            <div t-attf-class="#{two_columns and 'offset-lg-1 col-lg-6' or ''}">
            <div class="o_portal_chatter_messages_loading d-none">
                <div class="d-flex justify-content-center">
                    <div class="spinner-border text-primary" role="status">
                        <span class="visually-hidden">Loading...</span>
                    </div>
                </div>
            </div>
                <t t-call="portal.chatter_messages"/>
                <div class="o_portal_chatter_footer">
                    <t t-call="portal.pager"/>
                </div>
            </div>
        </div>
    </t>

<t t-name="portal.identitycheck">
        <form string="Security Control">
            <h3><strong>Please enter your password to confirm you own this account</strong></h3>
            <br/>
            <div>
                <input class="form-control col-10 col-md-6" autocomplete="current-password" name="password" type="password" required="required"/>
            </div>
            <a href="/web/reset_password/" class="btn btn-link" role="button">Forgot password?</a>
        </form>
    </t>
    <t t-name="portal.keydescription">
        <form string="Key Description">
            <h3><strong>Name your key</strong></h3>
            <p>Enter a description of and purpose for the key.</p>
            <input type="text" class="form-control col-10 col-md-6" placeholder="What's this key for?" name="description" required="required"/>
            <p>
                It is very important that this description be clear
                and complete, <strong>it will be the only way to
                identify the key once created</strong>.
            </p>
        </form>
    </t>
    <t t-name="portal.keyshow">
        <div>
            <h3><strong>Write down your key</strong></h3>
            <p>
                Here is your new API key, use it instead of a password for RPC access.
                Your login is still necessary for interactive usage.
            </p>
            <p><code><span t-out="key"/></code></p>
            <p class="alert alert-warning" role="alert">
                <strong>Important:</strong>
                The key cannot be retrieved later and provides <b>full access</b>
                to your user account, it is very important to store it securely.
            </p>
        </div>
    </t>

    <t t-name="portal.revoke_all_devices_popup_template">
        <section>
            <div>
                You are about to log out from all devices that currently have access to this user's account.
            </div><br/>
            <form action="/my/security" method="post" class="oe_reset_password_form">
                <div class="mb-3">
                    <label for="current">Type in your password to confirm :</label>
                    <input type="password" t-attf-class="form-control form-control-sm" id="current" name="password" autocomplete="current-password" required="required"/>
                </div>
                <input type="hidden" name="op" value="revoke"/>
            </form>
        </section>
    </t>
<t t-name="portal.InputConfirmationDialog">
    <Dialog size="'md'" title="props.title" modalRef="modalRef">
      <p t-out="props.body"/>
      <t t-set-slot="footer">
        <button class="btn" t-att-class="props.confirmClass" t-on-click="_confirm" t-esc="props.confirmLabel"/>
        <button t-if="props.cancel" class="btn btn-secondary" t-on-click="_cancel" t-esc="props.cancelLabel"/>
      </t>
    </Dialog>
  </t>

  <t t-name="portal.SignatureForm">
        <div t-ref="root">
            <div t-if="state.success" class="alert alert-success" role="status">
                <span t-if="state.success.message" t-esc="state.success.message"/>
                <span t-else="">Thank You!</span>
                <a t-if="state.success.redirect_url" t-att-href="state.success.redirect_url">
                    <t t-if="state.success.redirect_message" t-esc="state.success.redirect_message"/>
                    <t t-else="">Click here to see your document.</t>
                </a>
            </div>
            <t t-else="">
                <NameAndSignature t-props="nameAndSignatureProps"/>
                <form method="POST">
                    <input type="hidden" name="csrf_token" t-att-value="csrfToken"/>
                    <div class="o_web_sign_name_and_signature"/>
                    <div class="o_portal_sign_controls my-3">
                        <div t-if="state.error" class="o_portal_sign_error_msg alert alert-danger" role="status">
                            <t t-esc="state.error"/>
                        </div>
                        <div class="text-end my-3">
                            <button type="submit" class="o_portal_sign_submit btn btn-primary" t-on-click.prevent="onClickSubmit" t-att-disabled="signature.isSignatureEmpty ? 'disabled' : ''">
                                <i class="fa fa-check me-1"/>
                                <t t-esc="sendLabel"/>
                            </button>
                        </div>
                    </div>
                </form>
            </t>
        </div>
    </t>

<t t-name="payment.deleteTokenDialog">
        <div>
            <p>Are you sure you want to delete this payment method?</p>
            <t t-if="linkedRecordsInfo.length &gt; 0">
                <p>It is currently linked to the following documents:</p>
                <ul>
                    <li t-foreach="linkedRecordsInfo" t-as="documentInfo" t-key="documentInfoIndex">
                        <a t-att-title="documentInfo.description" t-att-href="documentInfo.url" t-esc="documentInfo.name"/>
                    </li>
                </ul>
            </t>
        </div>
    </t>

<t t-name="payment.transactionDetails">
        <div>  
            <t t-set="alert_style" t-value="'info'"/>
            <t t-set="alert_header" t-value="'Please wait...'"/>
            <t t-if="state == 'draft'">
                <t t-set="alert_message" t-value="display_message ? display_message                    : 'Your payment has not been processed yet.'"/>
            </t>
            <t t-elif="state == 'pending'">
                <t t-set="alert_style" t-value="'warning'"/>
                <t t-set="alert_message" t-value="display_message"/>
            </t>
            <t t-elif="state == 'authorized'">
                <t t-set="alert_style" t-value="'success'"/>
                <t t-set="alert_message" t-value="display_message"/>
            </t>
            <t t-elif="state == 'done'">
                <t t-set="alert_style" t-value="'success'"/>
                <t t-set="alert_header" t-value="operation !== 'validation' ? 'Your payment has been processed' :                             'Your payment method has been saved'"/>
            </t>
            <t t-elif="state == 'cancel'">
                <t t-set="alert_style" t-value="'danger'"/>
                <t t-set="alert_header" t-value="'This payment has been canceled'"/>
                <t t-set="alert_message" t-value="state_message ? 'Reason: ' + state_message : 'No payment has been processed.'"/>
            </t>
            <t t-elif="state == 'error'">
                <t t-set="alert_style" t-value="'danger'"/>
                <t t-set="alert_header" t-value="'Error'"/>
                <t t-set="alert_message" t-value="state_message"/>
            </t>

            <div name="o_payment_status_alert" t-attf-class="alert alert-{{alert_style}} d-flex gap-3">
                <div>
                    <i t-attf-class="fa fa-{{alert_style === 'danger' ? 'exclamation-triangle'                                      : 'cog fa-spin'}}"/>
                </div>
                <div>
                    <h5 class="alert-heading mb-0" t-out="alert_header"/>
                    <t t-if="alert_message" t-out="alert_message"/>
                </div>
                <a t-att-href="landing_route" class="alert-link ms-auto text-nowrap">
                    Skip <i class="oi oi-arrow-right ms-1 small"/>
                </a>
            </div>

            <div class="o_cc o_cc2 row row-cols-1 row-cols-md-2 mx-0 mb-3 py-2 rounded">
                <div class="col py-3">
                    <label for="o_payment_summary_amount" class="d-block small text-muted">
                        Amount
                    </label>
                    <span id="o_payment_summary_amount" t-out="formatCurrency(amount, currency_id)" class="fs-5 fw-bold"/>
                </div>
                <hr class="d-md-none m-0 text-300 opacity-100"/>
                <div class="o_payment_summary_separator col py-3 text-break">
                    <label for="o_payment_summary_reference" class="d-block small text-muted">
                        Reference
                    </label>
                    <span id="o_payment_summary_reference" t-out="reference" class="fs-5 fw-bold"/>
                </div>
            </div>
        </div>
    </t>

    <t t-name="payment.tx_not_found">
        <div class="text-center">  
            <p>We are not able to find your payment, but don't worry.</p>
            <p>You should receive an email confirming your payment in a few minutes.</p>
            <p>If the payment hasn't been confirmed you can contact us.</p>
        </div>
    </t>

    <t t-name="payment.rpc_error">
        <div class="text-center">  
            <p>Unable to contact the server. Please wait. <i class="fa fa-refresh fa-spin"/></p>
        </div>
    </t>

    <t t-name="payment.exception">
        <div class="text-center">  
            <h2>Internal server error</h2>
            <pre><t t-out="error_message"/></pre>
        </div>
    </t>

<t t-name="website.AutoCompleteWithPages">
        <div class="o-autocomplete" t-ref="root" t-att-class="autoCompleteRootClass">
            <input type="text" t-att-id="props.id" class="o-autocomplete--input o_input d-none" autocomplete="off" t-att-placeholder="props.placeholder" role="combobox" t-att-aria-activedescendant="activeSourceOptionId" t-att-aria-expanded="displayOptions ? 'true' : 'false'" aria-autocomplete="list" aria-haspopup="listbox" t-model="state.value" t-on-blur="onInputBlur" t-on-click.stop="onInputClick" t-on-change="onInputChange" t-on-input="onInput" t-on-keydown="onInputKeydown" t-on-focus="onInputFocus" t-ref="input"/>
            <t t-if="displayOptions">
                <ul role="menu" class="o-autocomplete--dropdown-menu ui-widget show" t-att-class="ulDropdownClass" t-ref="sourcesList">
                    <t t-foreach="sources" t-as="source" t-key="source.id">
                        <t t-if="source.isLoading">
                            <li class="ui-menu-item" t-att-class="{                                     'o-autocomplete--dropdown-item': props.dropdown,                                     'd-block': !props.dropdown                                 }">
                                <a t-attf-id="{{props.id or 'autocomplete'}}_{{source_index}}_loading" role="option" href="#" class="dropdown-item ui-menu-item-wrapper" aria-selected="true">
                                    <i class="fa fa-spin fa-circle-o-notch"/> <t t-esc="source.placeholder"/>
                                </a>
                            </li>
                        </t>
                        <t t-else="">
                            <t t-foreach="source.options" t-as="option" t-key="option.id">
                                <li class="o-autocomplete--dropdown-item ui-menu-item d-block" t-att-class="option.classList" t-on-mouseenter="() =&gt; this.onOptionMouseEnter([source_index, option_index])" t-on-mouseleave="() =&gt; this.onOptionMouseLeave([source_index, option_index])" t-on-click="() =&gt; this.onOptionClick([source_index, option_index])" t-on-pointerdown="() =&gt; this.ignoreBlur = true">
                                    <a t-attf-id="{{props.id or 'autocomplete'}}_{{source_index}}_{{option_index}}" role="option" href="#" class="dropdown-item ui-menu-item-wrapper text-truncate" t-att-class="{ 'ui-state-active': isActiveSourceOption([source_index, option_index]) }" t-att-aria-selected="isActiveSourceOption([source_index, option_index]) ? 'true' : 'false'">
                                        <t t-if="source.optionTemplate">
                                            <t t-call="{{ source.optionTemplate }}"/>
                                        </t>
                                        <t t-else="">
                                            <t t-esc="option.label"/>
                                        </t>
                                    </a>
                                </li>
                            </t>
                        </t>
                    </t>
                </ul>
            </t>
        </div>
    </t>

<t t-name="website.UrlAutoComplete">
        <AutoCompleteWithPages onInput.bind="onInput" onSelect.bind="onSelect" dropdownClass="dropdownClass" dropdownOptions="dropdownOptions" sources="sources" targetDropdown="props.targetDropdown"/>
    </t>

    <t t-name="website.AutoCompleteWithPagesItem">
        <div t-att-class="{             'fw-bold text-capitalize p-2': option.separator,         }">
            <t t-if="option.icon and option.icon.length">
                <img t-att-src="option.icon" width="24px" height="24px" class="me-2 rounded"/>
            </t>
            <t t-out="option.label"/>
        </div>
    </t>
<t t-name="website.prompt">
        <div role="dialog" class="modal o_technical_modal" tabindex="-1">
                <div class="modal-dialog">
                <div class="modal-content">
                    <header class="modal-header" t-if="window_title">
                        <h3 class="modal-title"><t t-esc="window_title"/></h3>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"/>
                    </header>
                    <main class="modal-body">
                        <form role="form" t-att-id="id">
                            <div class="row mb0">
                                <label for="page-name" class="col-md-3 col-form-label">
                                    <t t-esc="field_name"/>
                                </label>
                                <div class="col-md-9">
                                    <input t-if="field_type == 'input'" type="text" class="form-control" required="required"/>
                                    <textarea t-if="field_type == 'textarea'" class="form-control" required="required" rows="5"/>
                                    <select t-if="field_type == 'select'" class="form-select"/>
                                </div>
                            </div>
                        </form>
                    </main>
                    <footer class="modal-footer">
                        <button type="button" class="btn btn-primary btn-continue"><t t-esc="btn_primary_title"/></button>
                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal" aria-label="Cancel"><t t-esc="btn_secondary_title"/></button>
                    </footer>
                </div>
            </div>
        </div>
    </t>
<t t-name="website.background.video">
        <div class="o_bg_video_container">
            <div class="o_bg_video_loading d-flex justify-content-center align-items-center text-primary">
                <div class="spinner-border" style="width: 4em; height: 4em;" role="status">
                    <span class="visually-hidden">Loading...</span>
                </div>
            </div>
            <iframe t-att-id="iframeID" class="o_bg_video_iframe fade" frameBorder="0" t-att-src="videoSrc" aria-label="Background video"/>
        </div>
    </t>
<t t-name="website.social_hover">
        <div class="text-nowrap css_editable_mode_hidden">
            <t t-foreach="medias" t-as="media" t-key="media_index">
                <a href="#" t-attf-class="fa fa-3x fa-#{media}-square text-#{media} oe_social_#{media}" t-att-title="media" t-att-aria-label="media"/>
            </t>
        </div>
    </t>
<t t-name="website.gallery.slideshow">
        <div t-attf-id="#{id}" class="carousel slide" data-bs-ride="carousel" t-attf-data-bs-interval="#{interval}" style="margin: 0 12px;">
            <div class="carousel-inner" style="padding: 0;">
                 <t t-foreach="images" t-as="image" t-key="image_index">
                    <div t-attf-class="carousel-item #{image_index == index and 'active' or None}">
                        <img t-attf-class="#{attrClass || 'img img-fluid d-block'}" t-att-src="image.src" t-att-style="attrStyle" t-att-alt="image.alt" data-name="Image" data-o-main-image="true"/>
                    </div>
                 </t>
            </div>

            <ul class="carousel-indicators">
                <li class="o_indicators_left text-center d-none" aria-label="Previous" title="Previous">
                    <i class="oi oi-chevron-left"/>
                </li>
                <t t-foreach="images" t-as="image" t-key="image_index">
                    <li t-attf-data-bs-target="##{id}" t-att-data-bs-slide-to="image_index" t-att-class="image_index == index and 'active' or None" t-attf-style="background-image: url(#{image.src})"/>
                </t>
                <li class="o_indicators_right text-center d-none" aria-label="Next" title="Next">
                    <i class="oi oi-chevron-right"/>
                </li>
            </ul>

            <a class="carousel-control-prev o_we_no_overlay o_not_editable" t-attf-href="##{id}" data-bs-slide="prev" aria-label="Previous" title="Previous">
                <span class="oi oi-chevron-left fa-2x text-white"/>
                <span class="visually-hidden">Previous</span>
            </a>
            <a class="carousel-control-next o_we_no_overlay o_not_editable" t-attf-href="##{id}" data-bs-slide="next" aria-label="Next" title="Next">
                <span class="oi oi-chevron-right fa-2x text-white"/>
                <span class="visually-hidden">Next</span>
            </a>
        </div>
    </t>


    <t t-name="website.gallery.slideshow.lightbox">
        <div role="dialog" class="modal o_technical_modal fade s_gallery_lightbox p-0" aria-label="Image Gallery Dialog" tabindex="-1">
            <div class="modal-dialog m-0" role="Picture Gallery" t-attf-style="">
                <div class="modal-content bg-transparent modal-fullscreen">
                    <main class="modal-body o_slideshow bg-transparent">
                        <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close" style="position: absolute; right: 10px; top: 10px;"/>
                        <t t-call="website.gallery.slideshow"/>
                    </main>
                </div>
            </div>
        </div>
    </t>
<t t-name="website.s_countdown.end_redirect_message">
        <p class="text-center s_countdown_end_redirect_message">Time's up! You can now visit <a class="s_countdown_end_redirect_url" t-attf-href="#{redirectUrl}">this page</a>.</p>
    </t>
<t t-name="website.s_dynamic_snippet.grid">

        <t t-set="colClass" t-value="'d-flex flex-grow-0 flex-shrink-0 col-' + Math.trunc(12 / chunkSize).toString()"/>
        <t t-set="rowIndexGenerator" t-value="Array.from(Array(Math.ceil(data.length/chunkSize)).keys())"/>
        <t t-set="colIndexGenerator" t-value="Array.from(Array(chunkSize).keys())"/>
        <t t-foreach="rowIndexGenerator" t-as="rowIndex" t-key="rowIndex_index">
            <div t-attf-class="row my-4 #{extraClasses}">
                <t t-foreach="colIndexGenerator" t-as="colIndex" t-key="colIndex_index">
                    <t t-if="(rowIndex * chunkSize + colIndex) &lt; data.length">
                        <div t-attf-class="#{colClass}">
                            <t t-out="data[rowIndex * chunkSize + colIndex]"/>
                        </div>
                    </t>
                </t>
            </div>
        </t>
    </t>
<t t-name="website.s_dynamic_snippet.carousel.arrows">
        <a t-attf-href="##{unique_id}" class="carousel-control-prev" data-bs-slide="prev" role="button" aria-label="Previous" title="Previous">
            <span class="fa fa-chevron-circle-left fa-2x"/>
            <span class="visually-hidden">Previous</span>
        </a>
        <a t-attf-href="##{unique_id}" class="carousel-control-next" data-bs-slide="next" role="button" aria-label="Next" title="Next">
            <span class="fa fa-chevron-circle-right fa-2x"/>
            <span class="visually-hidden">Next</span>
        </a>
    </t>
    <t t-name="website.s_dynamic_snippet.carousel">
        <div t-att-id="unique_id" class="carousel slide" t-att-data-bs-interval="interval" data-bs-ride="carousel">

            <t t-set="rowSize" t-value="chunkSize"/>
            <t t-set="slideSize" t-value="rowSize * rowPerSlide"/>
            <t t-set="colClass" t-value="'d-flex flex-grow-0 flex-shrink-0 col-' + Math.trunc(12 / rowSize).toString()"/>
            <t t-set="slideIndexGenerator" t-value="Array.from(Array(Math.ceil(data.length/slideSize)).keys())"/>
            <t t-set="rowIndexGenerator" t-value="Array.from(Array(rowPerSlide).keys())"/>
            <t t-set="colIndexGenerator" t-value="Array.from(Array(rowSize).keys())"/>
            <div class="carousel-inner row w-100 mx-auto" role="listbox" aria-label="Carousel">
                <t t-foreach="slideIndexGenerator" t-as="slideIndex" t-key="slideIndex_index">
                    <t t-set="slideOffset" t-value="slideIndex * slideSize"/>
                    <div t-attf-class="carousel-item #{extraClasses} #{slideIndex_first ? 'active' : ''}" role="option">
                        <t t-foreach="rowIndexGenerator" t-as="rowIndex" t-key="rowIndex_index">
                            <t t-set="rowOffset" t-value="slideOffset + (rowIndex * rowSize)"/>
                            <t t-if="rowOffset &lt; data.length">
                                <div class="row">
                                    <t t-foreach="colIndexGenerator" t-as="colIndex" t-key="colIndex_index">
                                        <t t-set="itemIndex" t-value="rowOffset + colIndex"/>
                                        <t t-if="itemIndex &lt; data.length">
                                            <div t-attf-class="#{colClass}">
                                                <t t-out="data[itemIndex]"/>
                                            </div>
                                        </t>
                                    </t>
                                </div>
                            </t>
                        </t>
                    </div>
                </t>
            </div>

            <t t-if="slideIndexGenerator.length &gt; 1">
                <t t-if="arrowPosition === 'bottom'">
                    <div class="s_dynamic_snippet_arrow_bottom pt-2 d-flex justify-content-center">
                        <t t-call="website.s_dynamic_snippet.carousel.arrows">
                            <t t-set="unique_id" t-value="unique_id"/>
                        </t>
                    </div>
                </t>
                <t t-else="">
                    <t t-call="website.s_dynamic_snippet.carousel.arrows">
                        <t t-set="unique_id" t-value="unique_id"/>
                    </t>
                </t>
            </t>
        </div>
    </t>
<t t-name="website.s_website_form_status_success">
        <span id="s_website_form_result" class="text-success ml8">
            <i class="fa fa-check mr4" role="img" aria-label="Success" title="Success"/>The form has been sent successfully.
        </span>
    </t>


    <t t-name="website.s_website_form_status_error">
        <span id="s_website_form_result" class="text-danger ml8">
            <i class="fa fa-close mr4" role="img" aria-label="Error" title="Error"/>
            <t t-esc="message"/>
        </span>
    </t>


    <t t-name="website.file_block">
        <div class="o_file_block col-4">
            <div class="o_file_wrap mb-1 px-2 py-1">
                <div class="o_file_name d-inline-block w-75 pt-1" t-att-title="fileName" t-out="fileName"/>
                <i class="o_file_delete fa fa-times mt-1 float-end"/>
            </div>
        </div>
    </t>
<div t-name="website.s_searchbar.autocomplete" class="o_dropdown_menu show position-absolute w-100">
    <t t-if="fuzzySearch and results.length">
        <span class="dropdown-item-text">
            <span class="text-muted">No results found for '<t t-esc="search"/>'. Showing results for '<a href="#" class="s_searchbar_fuzzy_submit" t-esc="fuzzySearch"/>'.</span>
        </span>
    </t>
    <t t-elif="!results.length">
        <span class="dropdown-item-text">
            <span class="text-muted">No results found. Please try another search.</span>
        </span>
    </t>
    <a t-foreach="results" t-as="result" t-key="result_index" t-att-href="result['website_url']" class="dropdown-item p-2 text-wrap">
        <div class="d-flex align-items-center flex-wrap o_search_result_item">
            <t t-if="widget.displayImage">
                <img t-if="result['image_url']" t-att-src="result['image_url']" class="flex-shrink-0 o_image_64_contain"/>
                <i t-else="" t-attf-class="o_image_64_contain text-center pt16 fa #{result['_fa']}" style="font-size: 34px;"/>
            </t>
            <div class="o_search_result_item_detail px-3">
                <t t-set="description" t-value="parts['description'] and widget.displayDescription and result['description']"/>
                <t t-set="extra_link" t-value="parts['extra_link'] and widget.displayExtraLink and result['extra_link_url'] and result['extra_link']"/>
                <t t-set="extra_link_html" t-value="parts['extra_link'] and widget.displayExtraLink and !result['extra_link_url'] and result['extra_link']"/>
                <div t-attf-class="h6 fw-bold #{description ? '' : 'mb-0'}" t-out="result['name']"/>
                <p t-if="description" class="mb-0" t-out="description"/>
                <button t-if="extra_link" class="extra_link btn btn-link btn-sm" t-att-data-target="result['extra_link_url']" t-out="extra_link"/>
                <t t-if="extra_link_html" t-out="extra_link_html"/>
            </div>
            <div t-if="parts['detail'] and widget.displayDetail" class="flex-shrink-0 ms-auto">
                <t t-if="result['detail_strike']">
                    <span class="text-danger text-nowrap" style="text-decoration: line-through;">
                        <t t-out="result['detail_strike']"/>
                    </span>
                    <br/>
                </t>
                <b t-if="result['detail']" class="text-nowrap">
                    <t t-out="result['detail']"/>
                </b>
                <t t-if="result['detail_extra']">
                    <br/>
                    <span class="text-nowrap" t-out="result['detail_extra']"/>
                </t>
            </div>
        </div>
    </a>
    <t t-if="hasMoreResults">
        <button type="submit" class="dropdown-item text-center text-primary">All results</button>
    </t>
</div>

<t t-name="portal_rating.chatter_rating_publisher">
        <div class="o_wrating_publisher_container">
            <button t-if="is_publisher" t-attf-class="btn px-2 mb-2 btn-sm border o_wrating_js_publisher_comment_btn {{ rating.publisher_comment !== '' ? 'd-none' : '' }}" t-att-data-mes_index="rating.mes_index">
                <i class="fa fa-comment text-muted me-1"/>Comment
            </button>
            <div class="o_wrating_publisher_comment mt-2 mb-2">
                <t t-if="rating.publisher_comment" t-call="portal_rating.chatter_rating_publisher_comment"/>
            </div>
        </div>
    </t>

    <t t-name="portal_rating.chatter_rating_publisher_comment">
        <div class="d-flex o_portal_chatter_message gap-2">
            <img class="o_avatar o_portal_chatter_avatar" t-att-src="rating.publisher_avatar" alt="avatar"/>
            <div class="flex-grow-1">
                <div class="o_portal_chatter_message_title">
                    <div class="d-inline-block">
                        <h5 class="mb-1"><t t-esc="rating.publisher_name"/></h5>
                    </div>
                    <div t-if="is_publisher" class="dropdown d-inline-block">
                        <button class="btn py-0" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                            <i class="fa fa-ellipsis-v"/>
                        </button>
                        <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
                            <button class="dropdown-item o_wrating_js_publisher_comment_edit" t-att-data-mes_index="rating.mes_index">
                                <i class="fa fa-fw fa-pencil me-1"/>Edit
                            </button>
                            <button class="dropdown-item o_wrating_js_publisher_comment_delete" t-att-data-mes_index="rating.mes_index">
                                <i class="fa fa-fw fa-trash-o me-1"/>Delete
                            </button>
                        </div>
                    </div>
                    <p>Published on <t t-esc="rating.publisher_datetime"/></p>
                </div>
                <t t-out="rating.publisher_comment"/>
            </div>
        </div>
    </t>
    <t t-name="portal_rating.chatter_rating_publisher_form">
        <div t-if="is_publisher" class="d-flex o_portal_chatter_message shadow bg-white rounded px-3 py-3 my-1 gap-2">
            <img class="o_avatar o_portal_chatter_avatar" t-att-src="rating.publisher_avatar" alt="avatar"/>
            <div class="flex-grow-1">
                <div class="o_portal_chatter_message_title">
                    <h5 class="mb-1"><t t-esc="rating.publisher_name"/></h5>
                </div>
                <textarea rows="3" class="form-control o_portal_rating_comment_input"><t t-esc="rating.publisher_comment"/></textarea>
                <div>
                    <button class="btn btn-primary mt-2 o_wrating_js_publisher_comment_submit me-1" t-att-data-mes_index="rating.mes_index">
                        <t t-if="rating.publisher_comment === ''">
                            Post comment
                        </t><t t-else="">
                            Update comment
                        </t>
                    </button>
                    <button class="border btn btn-light mt-2 bg-white o_wrating_js_publisher_comment_cancel" t-att-data-mes_index="rating.mes_index">
                        Cancel
                    </button>
                </div>
            </div>
        </div>
    </t>
<t t-name="portal_rating.PopupComposer">
        <div t-if="widget.options['display_composer']" class="modal fade" id="ratingpopupcomposer" tabindex="-1" role="dialog" aria-labelledby="ratingpopupcomposerlabel" aria-hidden="true">
            <div class="modal-dialog" role="document">
                <div class="modal-content bg-white">
                    <div class="modal-header">
                        <h5 class="modal-title o_rating_popup_composer_label" id="ratingpopupcomposerlabel">
                            <t t-if="widget.options['default_message_id']">
                                Modify your review
                            </t>
                            <t t-else="">
                                Write a review
                            </t>
                        </h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"/>
                    </div>
                    <div class="modal-body">
                        <div class="o_portal_chatter_composer"/>
                    </div>
                </div>
            </div>
        </div>
    </t>
<t t-name="portal_rating.rating_stars_static">
        <t t-set="val_integer" t-value="Math.floor(val)"/>
        <t t-set="val_decimal" t-value="val - val_integer"/>
        <t t-set="empty_star" t-value="5 - (val_integer+Math.ceil(val_decimal))"/>
        <div class="o_website_rating_static" t-att-style="inline_mode ? 'display:inline' : ''" t-attf-aria-label="#{Math.round(val * 100) / 100} stars on 5" t-attf-title="#{Math.round(val * 100) / 100} stars on 5">
            <t t-foreach="Array(val_integer)" t-as="num" t-key="num_index">
                <i class="fa fa-star" role="img"/>
            </t>
            <t t-if="val_decimal">
                <i class="fa fa-star-half-o" role="img"/>
            </t>
            <t t-foreach="Array(empty_star)" t-as="num" t-key="num_index">
                <i class="fa fa-star text-black-25" role="img"/>
            </t>
        </div>
    </t>

    <t t-name="portal_rating.rating_card">
        <t t-set="two_columns" t-value="widget.options['two_columns']"/>
        <div class="row o_website_rating_card_container justify-content-center">
            <div t-attf-class="#{two_columns and 'col-lg-12' or 'col-lg-5'}" t-if="Object.keys(widget.get('rating_card_values') || {}).length &gt; 0">
                <p t-if="!two_columns" class="text-center"><strong>Average</strong></p>
                <div t-attf-class="o_website_rating_avg #{two_columns and 'mb-2' or 'text-center'}">
                    <h1><t t-esc="widget.get('rating_card_values')['avg']"/></h1>
                    <t t-call="portal_rating.rating_stars_static">
                        <t t-set="val" t-value="widget.get('rating_card_values')['avg'] || 0"/>
                    </t>
                    <t t-call="portal.chatter_message_count"/>
                </div>
            </div>
            <div t-attf-class="#{two_columns and 'col-lg-12' or 'col-lg-7'}" t-if="Object.keys(widget.get('rating_card_values') || {}).length &gt; 0">
                <hr t-if="two_columns"/>
                <p t-if="!two_columns"><strong>Details</strong></p>
                <t t-set="selected_rating" t-value="widget.get('rating_value')"/>
                <table t-attf-class="o_website_rating_table #{selected_rating and 'o_website_rating_table_has_selection' or ''}">
                    <t t-foreach="widget.get('rating_card_values')['percent']" t-as="percent" t-key="percent_index">
                        <t t-set="row_selected" t-value="percent['num'] == selected_rating"/>
                        <tr t-attf-class="o_website_rating_table_row #{row_selected ? 'o_website_rating_table_row_selected' : (selected_rating ? 'opacity-50' : '')}" t-att-data-star="percent['num']">
                            <td class="o_website_rating_table_star_num text-nowrap" t-att-data-star="percent['num']">
                                <t t-esc="percent['num']"/> stars
                            </td>
                            <td class="o_website_rating_table_progress">
                                <div class="progress">
                                    <div class="progress-bar o_rating_progressbar" role="progressbar" t-att-aria-valuenow="percent['percent']" aria-valuemin="0" aria-valuemax="100" t-att-style="'width:' + percent['percent'] + '%;'" aria-label="Progress bar">
                                    </div>
                                </div>
                            </td>
                            <td class="o_website_rating_table_percent">
                                <strong><t t-esc="Math.round(percent['percent'] * 100) / 100"/>%</strong>
                            </td>
                            <td class="o_website_rating_table_reset">
                                <button t-attf-class="btn btn-link o_website_rating_selection_reset #{row_selected and 'visible' or 'invisible'}" t-att-data-star="percent['num']">
                                    <i class="fa fa-times d-block" role="img" aria-label="Remove Selection"/>
                                </button>
                            </td>
                        </tr>
                    </t>
                </table>
            </div>
        </div>
    </t>

    <t t-name="portal_rating.rating_star_input">
        <div class="o_rating_star_card" t-if="widget.options['display_rating']">
            <t t-set="val_integer" t-value="Math.floor(default_rating)"/>
            <t t-set="val_decimal" t-value="default_rating - val_integer"/>
            <t t-set="empty_star" t-value="5 - (val_integer+Math.ceil(val_decimal))"/>

            <div class="stars enabled">
                <t t-foreach="Array(val_integer)" t-as="num" t-key="num_index">
                    <i class="fa fa-star" role="img" aria-label="Full star"/>
                </t>
                <t t-if="val_decimal">
                    <i class="fa fa-star-half-o" role="img" aria-label="Half a star"/>
                </t>
                <t t-foreach="Array(empty_star)" t-as="num" t-key="num_index">
                    <i class="fa fa-star-o text-black-25" role="img" aria-label="Empty star"/>
                </t>
            </div>
            <div class="rate_text">
                <span class="badge text-bg-info"/>
            </div>
            <input type="hidden" readonly="readonly" name="rating_value" t-att-value="default_rating || ''"/>
        </div>
    </t>
<t t-name="website_sale.FieldVideoPreview">
        <div class="ratio ratio-16x9 mt-2" t-if="props.record.data[props.name]">
            <t t-out="props.record.data[props.name]"/>
        </div>
    </t>

<we-button t-name="website_sale.ribbonSelectItem" t-att-data-set-ribbon="ribbon.id">
    <t t-out="ribbon.html"/>
    <span t-attf-class="fa fa-#{isTag ? 'tag' : 'bookmark'} ms-auto"/>
    <span t-attf-class="fa fa-arrow-#{isLeft ? 'left' : 'right'} ms-1"/>
    <span t-attf-class="o_wsale_color_preview #{colorClasses} ms-1" t-attf-style="background-color: #{ribbon.bg_color}"/>
    <span t-attf-class="o_wsale_color_preview #{colorClasses} ms-1" t-attf-style="background-color: #{textColor} !important;"/>
</we-button>

<t t-name="website_sale.ProductImageViewer">
        <div class="o_dialog" t-att-id="id" t-att-class="{ o_inactive_modal: !data.isActive }">
            <div role="dialog" class="modal" t-ref="modalRef">
                <div class="o_wsale_image_viewer flex-column align-items-center d-flex w-100 h-100" t-on-mousemove="onGlobalMousemove">

                    <div class="o_wsale_image_viewer_header d-flex w-100 text-white">
                        <div class="flex-grow-1"/>
                        <div class="d-flex align-items-center mb-0 px-3 h4 text-reset cursor-pointer">
                            <span class="fa fa-times" t-on-click="data.close"/>
                        </div>
                    </div>

                    <div class="o_wsale_image_viewer_image position-absolute top-0 bottom-0 start-0 end-0 align-items-center justify-content-center d-flex o_with_img overflow-hidden">
                        <div class="o_wsale_image_viewer_void position-absolute align-items-center justify-content-center d-flex w-100 h-100" t-ref="imageContainer" t-att-style="imageContainerStyle">
                            <img class="mw-100 mh-100 bg-black transition-base" t-att-src="selectedImage.src" draggable="false" alt="Viewer" t-att-style="imageStyle" t-on-wheel.stop="onWheelImage" t-on-mousedown="onMousedownImage"/>
                        </div>
                    </div>
                    <t t-if="images.length &gt; 1">

                        <div class="o_wsale_image_viewer_carousel position-absolute bottom-0 d-flex" role="toolbar">
                            <ol class="d-flex justify-content-start ps-0 pt-2 pt-lg-0 mx-auto my-0 text-start">
                                <t t-foreach="images" t-as="image" t-key="image.thumbnailSrc">
                                    <li t-attf-class="align-top position-relative px-1 pb-1 {{image === selectedImage ? 'active' : ''}}" t-on-click="() =&gt; this.selectedImage = image">
                                        <div>
                                            <img t-att-src="image.thumbnailSrc" t-attf-class="img o_wsale_image_viewer_thumbnail {{image === selectedImage ? 'active' : ''}}" t-att-alt="props.title" loading="lazy"/>
                                        </div>
                                    </li>
                                </t>
                            </ol>
                        </div>

                        <div class="o_wsale_image_viewer_control o_wsale_image_viewer_previous btn btn-dark position-absolute top-0 bottom-0 start-0 align-items-center justify-content-center d-flex my-auto ms-3 rounded-circle" t-on-click="previousImage" title="Previous (Left-Arrow)" role="button">
                            <span class="oi oi-chevron-left" role="img"/>
                        </div>
                        <div class="o_wsale_image_viewer_control o_wsale_image_viewer_next btn btn-dark position-absolute top-0 bottom-0 end-0 align-items-center justify-content-center d-flex my-auto me-3 rounded-circle" t-on-click="nextImage" title="Next (Right-Arrow)" role="button">
                            <span class="oi oi-chevron-right" role="img"/>
                        </div>
                    </t>
                </div>
            </div>
        </div>
    </t>
<t t-name="website_sale.ReorderModal">
        <t t-set="reorder">Re-Order</t>
        <Dialog title="reorder">
            <table id="o_wsale_reorder_table" class="table table-sm">
                <thead class="bg-100">
                    <tr id="o_wsale_reorder_header">

                        <th class="text-start td-img">Product</th>

                        <th/>

                        <th class="text-center td-qty">Quantity</th>

                        <th class="text-end td-price">Price</th>
                    </tr>
                </thead>
                <tbody id="o_wsale_reorder_body" class="sale_tbody">
                    <t t-foreach="content.products" t-as="product" t-key="product_index">
                        <tr class="js_product">
                            <td t-if="product.has_image" class="td-img">
                                <img class="product_detail_img" t-att-alt="product.name" t-attf-src="/web/image/product.product/{{product.product_id}}/image_128"/>
                            </td>
                            <td t-att-colspan="product.has_image ? '1' : '2'">
                                <h5><t t-esc="product.name"/></h5>
                                <span class="text-muted d-none d-md-inline-block" t-if="product.description_sale" t-out="product.description_sale"/>
                            </td>
                            <t t-if="product.add_to_cart_allowed">
                                <td class="text-center td-qty">
                                    <div class="css_quantity input-group input-group-sm justify-content-center">
                                        <a href="#" class="btn btn-link d-none d-md-inline-block" aria-label="Remove one" title="Remove one" t-on-click.stop.prevent="() =&gt; this.changeProductQty(product, product.qty - 1)">
                                            <i class="fa fa-minus"/>
                                        </a>
                                        <input type="text" class="js_quantity text-center form-control quantity" t-on-change="(ev) =&gt; this.onChangeProductQtyInput(ev, product)" t-att-value="product.qty"/>
                                        <a href="#" class="btn btn-link d-none d-md-inline-block" aria-label="Add one" title="Add one" t-on-click.stop.prevent="() =&gt; this.changeProductQty(product, product.qty + 1)">
                                            <i class="fa fa-plus"/>
                                        </a>
                                    </div>
                                    <div t-if="product.qty_warning and product.qty_warning !== ''" class="text-warning fw-bold">
                                        <i class="fa fa-exclamation-triangle"/>
                                        <span t-esc="product.qty_warning"/>
                                    </div>
                                </td>
                                <td class="text-end td-price">
                                    <span t-esc="formatCurrency(product.combinationInfo.price, content.currency)"/>
                                </td>
                            </t>
                            <t t-else="">
                                <td class="text-center" colspan="2">
                                    <div class="text-warning fw-bold">
                                        <i class="fa fa-exclamation-triangle"/>
                                        <span t-esc="getWarningForProduct(product)"/>
                                    </div>
                                </td>
                            </t>
                        </tr>
                    </t>
                </tbody>
            </table>
            <div id="o_wsale_reorder_total" class="row" name="total" style="page-break-inside: avoid;">
                <div class="col-sm-7 col-md-6 ms-auto">
                    <table class="table table-sm">
                        <tr class="border-black o_total">
                            <td>
                                <strong>Total</strong>
                            </td>
                            <td class="text-end">
                                <span t-out="formatCurrency(total, content.currency)"/>
                            </td>
                        </tr>
                    </table>
                </div>
            </div>
            <t t-set-slot="footer">
                <button class="btn btn-primary o_wsale_reorder_confirm" t-att-disabled="!hasBuyableProducts" t-on-click="confirmReorder">
                    Add To Cart
                </button>
                <button class="btn btn-secondary o_wsale_reorder_cancel" t-on-click.stop.prevent="props.close">
                    Discard
                </button>
            </t>
        </Dialog>
    </t>

    <t t-name="website_sale.ReorderConfirmationDialog">
    <Dialog size="'md'" title="props.title" modalRef="modalRef">
      <p t-out="props.body" class="text-prewrap"/>
      <t t-set-slot="footer">
        <button class="btn btn-primary" t-on-click="_confirm">
              Yes
            </button>
        <button class="btn btn-secondary" t-on-click="_cancel">
              No
            </button>
        </t>
    </Dialog>
  </t>

  <t t-name="website_sale.addToCartNotification">
        <div class="row g-2 mb-2" t-foreach="props.lines" t-as="line" t-key="line.id">
            <div class="col-3">
                <img class="img o_image_64_max rounded mb-2 img-fluid" t-att-src="line.image_url" t-att-alt="line.name"/>
            </div>
            <div class="col-6 d-flex flex-column align-items-start">
                <span t-out="getProductSummary(line)"/>
                <span class="text-muted small" t-if="line.description" t-out="line.description"/>
            </div>
            <div class="col-3 d-flex flex-column align-items-end gap-1" t-out="getFormattedPrice(line)"/>
        </div>
        <a role="button" class="w-100 btn btn-primary" href="/shop/cart">
            View cart
        </a>
    </t>

<t t-name="website_sale.cartNotification">
        <div t-attf-class="toast show o_cc1 position-relative start-0 mt-2 {{props.className}}" t-attf-style="top: {{positionOffset}};" role="alert" aria-live="assertive" aria-atomic="true">
            <div class="toast-header justify-content-between">
                <strong t-if="props.message" t-out="props.message"/>
                <button class="btn-close" type="button" t-on-click="props.close" aria-label="Close"/>
            </div>
            <div class="toast-body">
                <WarningNotification t-if="this.props.warning" warning="this.props.warning"/>
                <AddToCartNotification t-elif="this.props.lines.length" lines="this.props.lines" currency_id="this.props.currency_id"/>
            </div>
        </div>
    </t>

<t t-name="website_sale.warningNotification">
        <div class="alert alert-warning" role="alert">
            <i class="fa fa-warning"/>
            <t t-out="this.props.warning"/>
        </div>
    </t>

<div t-name="sign.MobileInputBottomSheet" class="o_sign_item_bottom_sheet">
        <label class="o_sign_label">
            <t t-esc="label"/>
            <input t-if="type === 'text'" type="text" class="o_sign_item_bottom_sheet_field" t-att-placeholder="placeholder" t-att-value="value"/>
            <textarea t-if="type === 'textarea'" class="o_sign_item_bottom_sheet_field" t-att-placeholder="placeholder" t-att-value="value" t-esc="value"/>
        </label>
        <button class="o_sign_next_button btn btn-primary btn-block">
            <t t-esc="buttonText"/>
        </button>
    </div>
<t t-name="sign.signItem">
        <t t-if="readonly">

            <t t-if="type == 'text'" t-call="sign.textSignItem"/>
            <t t-if="type == 'textarea'" t-call="sign.textareaSignItem"/>
            <t t-if="type == 'checkbox'" t-call="sign.checkboxSignItem"/>
            <t t-if="type == 'selection'" t-call="sign.selectionSignItem"/>
            <t t-if="type == 'signature' || type == 'initial'" t-call="sign.signatureSignItem"/>
        </t>
        <t t-if="!readonly">

            <button t-if="type == 'signature' || type == 'initial'" t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item text-center" style="color:#757575;" t-att-style="style" t-att-data-signature="value">
                <span class="o_sign_helper"/>
                <img t-if="frame_value" t-att-src="frame_value" alt="Frame"/>
                <img t-if="value" t-att-src="value" alt="Signature"/>
                <t t-if="!value">
                    <span class="o_placeholder ps-0">
                        <t t-esc="placeholder"/>
                    </span>
                </t>
            </button>
            <input t-if="type == 'text'" t-att-title="role" type="text" t-attf-class="{{classes}} o_sign_sign_item" t-att-style="style" t-att-placeholder="placeholder" t-att-value="value"/>
            <input t-if="type == 'checkbox' and value == 'on'" t-att-title="role" type="checkbox" t-attf-class="{{classes}} o_sign_sign_item" t-att-style="style" checked="1"/>
            <input t-elif="type == 'checkbox'" t-att-title="role" type="checkbox" t-attf-class="{{classes}} o_sign_sign_item" t-att-style="style"/>
            <textarea t-if="type == 'textarea'" t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item" t-att-style="style" t-att-placeholder="placeholder" t-att-value="value" t-esc="value"/>
            <div t-if="type == 'selection'" t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item" t-att-style="style" t-att-value="value">
                <div class="o_sign_select_options_display o_sign_select_options_display_edit">
                    <t t-foreach="options" t-key="option.value" t-as="option" t-index="index">
                        <t t-if="option_index !== 0">
                            <span class="o_sign_option_separator">/</span>
                        </t>
                        <span t-attf-class="o_sign_item_option {{ value ? (value == option.id ? 'o_sign_selected_option' : 'o_sign_not_selected_option') : ''}}" t-att-data-id="option.id" t-esc="option.value"/>
                    </t>
                </div>

            </div>
        </t>
    </t>

    <div t-name="sign.signItemConfiguration" t-attf-class="o_sign_config_area {{ isSignItemEditable &amp;&amp; type == 'text' ? 'o_sign_editable_config_area' : '' }}">
        <div class="o_sign_config_handle" aria-label="Signature configuration" title="Signature configuration">
            <span class="fa fa-arrows" role="img"/>
        </div>
        <span t-if="isSignItemEditable" class="fa fa-times" role="img" aria-label="Delete sign item" title="Delete sign"/>
        <div class="o_sign_item_display">

            <t t-if="type != 'checkbox' || isSignItemEditable">
                <span class="o_sign_responsible_display" t-att-title="responsibleName" t-esc="responsibleName"/>
            </t>
        </div>
        <div class="o_resize_handler resize_height"/>
        <div class="o_resize_handler resize_width"/>
        <div class="o_resize_handler resize_both"/>
    </div>

    <div t-name="sign.selectionSignItem" t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item" t-att-data-id="id" t-att-style="style + 'white-space: normal;text-align: center;'">
        <t t-if="!value">
            <span class="o_placeholder">
                <t t-esc="placeholder"/>
            </span>
        </t>
        <div class="o_sign_select_options_display">
            <t t-foreach="options" t-key="option.value" t-as="option" t-index="index">
                <t t-if="option_index !== 0">
                    <span class="o_sign_option_separator">/</span>
                </t>
                <span t-attf-class="o_sign_item_option {{ value ? (value == option.id ? 'o_sign_selected_option' : 'o_sign_not_selected_option') : ''}}" t-esc="option.value"/>
            </t>
        </div>
        <t t-if="editMode" t-call="sign.signItemConfiguration"/>
    </div>

    <div t-name="sign.signatureSignItem" t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item" t-att-data-id="id" t-att-style="style" t-att-data-signature="value">
        <span class="o_sign_helper"/>
        <img t-if="frame_value" t-att-src="frame_value" alt="Frame" class="o_sign_frame"/>
        <img t-if="value" t-att-src="value" alt="Signature"/>
        <t t-if="!value">
            <span class="o_placeholder ps-0">
                <t t-esc="placeholder"/>
            </span>
        </t>
        <t t-if="editMode" t-call="sign.signItemConfiguration"/>
    </div>

    <div t-name="sign.textareaSignItem" t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item o_sign_sign_textarea" t-att-style="style" t-att-data-id="id">
        <t t-if="!value">
            <p class="o_placeholder ps-0 o_sign_field_alignment">
                <t t-esc="placeholder"/>
            </p>
        </t>
        <t t-esc="value"/>
        <t t-if="editMode" t-call="sign.signItemConfiguration"/>
    </div>

    <div t-name="sign.checkboxSignItem" t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item" t-att-data-id="id" t-att-style="style + 'margin: 2px; padding:2px;'">
        <t t-if="value == 'on'">☑</t>
        <t t-if="value == 'off'">☐</t>
        <t t-if="!value">
            <span class="o_placeholder ps-0">
                <t t-if="placeholder == '☑'"><span class="o_custom_checkbox"/></t>
                <t t-else=""><span class="o_custom_checkbox unchecked"/></t>
            </span>
        </t>
        <t t-if="editMode" t-call="sign.signItemConfiguration"/>
    </div>

    <div t-name="sign.textSignItem" t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item" type="text" t-att-data-id="id" t-att-style="style">
        <t t-if="isSignItemEditable">
            <input t-att-placeholder="placeholder" t-att-value="value" class="o_sign_editable_input"/>
            <t t-call="sign.signItemConfiguration"/>
        </t>
        <t t-else="">
            <t t-if="!value">
                <p class="o_placeholder o_sign_field_alignment">
                    <t t-esc="placeholder"/>
                </p>
            </t>
            <t t-esc="value"/>
            <t t-if="editMode" t-call="sign.signItemConfiguration"/>
        </t>
    </div>
<t t-name="sign.EncryptedDialog">
        <Dialog t-props="dialogProps">
            <div class="mb-3">
                <span>Your file is encrypted, PDF's password is required to generate final document. The final document will be encrypted with the same password.</span>
                <div>
                    <input type="password" t-ref="password" class="form-control"/>
                </div>
            </div>
            <t t-set-slot="footer">
                <button class="btn btn-primary o_sign_validate_encrypted" t-on-click="validatePassword">Generate PDF</button>
            </t>
        </Dialog>
    </t>
<t t-name="sign.InitialsAllPagesDialog">
        <Dialog t-props="dialogProps">
            <div class="m-2">
                <label for="responsible_select_initials_input" class="col-md-2">Responsible</label>
                <select id="responsible_select_initials_input" class="form-select w-75" t-ref="role_select">
                    <t t-foreach="props.roles" t-as="role_id" t-key="role_id">
                        <t t-set="role" t-value="props.roles[role_id]"/>
                        <option t-att-value="role_id" t-att-selected="role_id == props.responsible">
                            <t t-esc="role.name"/>
                        </option>
                    </t>
                </select>
            </div>
            <t t-set-slot="footer">
                <button class="btn btn-primary" t-on-click="onAddOnceClick">Add Once</button>
                <button class="btn btn-secondary" t-on-click="onAddToAllPagesClick">Add to all pages</button>
            </t>
        </Dialog>
    </t>
<t t-name="sign.NextDirectSignDialog">
        <Dialog t-props="dialogProps">
            <t t-set-slot="header">
                <h4 class="modal-title text-break" t-att-class="{ 'me-auto': fullscreen }">
                    <t t-esc="title"/>
                </h4>
            </t>
            <div class="o_nextdirectsign_message">
                <p>Your signature has been saved. Next signatory is <t t-esc="nextSigner"/></p>
                <p>We will send you this document by email once everyone has signed.</p>
            </div>
            <t t-set-slot="footer">
                <button class="btn btn-primary" t-on-click="goToNextSigner">Next signatory (<t t-esc="nextSigner"/>)</button>
            </t>
        </Dialog>
    </t>
<t t-name="sign.PublicSignerDialog">
        <Dialog t-props="dialogProps">
            <div class="mb-3 row">
                    <label for="o_sign_public_signer_name_input" class="col-lg-3 col-form-label">Your name</label>
                    <div class="col-lg-9">
                        <input type="text" t-ref="name" id="o_sign_public_signer_name_input" placeholder="Your name" class="form-control" t-att-value="props.name"/>
                    </div>
                </div>
                <div class="mb-3 row">
                    <label for="o_sign_public_signer_mail_input" class="col-lg-3 col-form-label">Your email</label>
                    <div class="col-lg-9">
                        <input type="email" t-ref="mail" id="o_sign_public_signer_mail_input" placeholder="Your email" class="form-control" t-att-value="props.mail"/>
                    </div>
                </div>

                <t t-set-slot="footer">
                    <button class="btn btn-primary" t-on-click="submit">Validate &amp; Send</button>
                    <button class="btn btn-link" t-on-click="props.close">Cancel</button>
                </t>
        </Dialog>
    </t>
<t t-name="sign.SignNameAndSignatureDialog">
        <Dialog t-props="dialogProps">
            <SignNameAndSignature t-props="nameAndSignatureProps"/>
            <div class="mt16 small">
                By clicking Adopt &amp; Sign, I agree that the chosen signature/initials will be a valid electronic representation of my hand-written signature/initials for all purposes when it is used on documents, including legally binding contracts.
            </div>
            <t t-set-slot="footer">
                <button class="btn btn-primary" t-if="props.onConfirmAll" t-on-click="props.onConfirmAll" t-att-disabled="footerState.buttonsDisabled">Sign all</button>
                <button class="btn btn-secondary" t-on-click="props.onConfirm" t-att-disabled="footerState.buttonsDisabled">Sign</button>
                <button class="btn btn-secondary" t-on-click="props.close">Cancel</button>
            </t>
        </Dialog>
    </t>

    <t t-name="sign.NameAndSignature">
        <div class="o_web_sign_name_and_signature">
            <div t-if="!props.noInputName" class="o_web_sign_name_group">
                <label class="col-form-label" t-att-for="'o_web_sign_name_input_' + htmlId">Full Name</label>
                <input type="text" name="signer" t-att-id="'o_web_sign_name_input_' + htmlId" class="o_web_sign_name_input form-control" t-on-input="onInputSignName" t-att-value="props.signature.name" t-ref="signNameInput" placeholder="Type your name to sign" required=""/>
            </div>


            <div t-if="state.showSignatureArea" class="o_web_sign_signature_group bg-100 card mt-3" style="overflow: hidden;">
                <div class="card-header bg-transparent">
                    <div class="row g-0">
                        <div t-if="!props.noInputName or defaultName" class="col-auto">
                            <a role="button" href="#" t-on-click.prevent="onClickSignAuto" t-attf-class="o_web_sign_auto_button me-2 btn btn-light {{ state.signMode === 'auto' ? 'active': '' }}">
                                Auto
                            </a>
                        </div>
                        <div class="col-auto">
                            <a role="button" href="#" t-on-click.prevent="() =&gt; this.setMode('draw')" t-attf-class="o_web_sign_draw_button me-2 btn btn-light {{ state.signMode === 'draw' ? 'active': '' }}">
                                Draw
                            </a>
                        </div>
                        <div class="col-auto">
                            <a role="button" href="#" t-on-click.prevent="onClickSignLoad" t-attf-class="o_web_sign_load_button me-2 btn btn-light {{ state.signMode === 'load' ? 'active': '' }}">
                                Load
                            </a>
                        </div>

                        <div class="col-auto division ms-auto"/>
            <div t-attf-class="col-auto form-check btn border-0 {{ showFrameCheck ? '' : 'd-none'}}">
                <input type="checkbox" t-attf-class="o_web_frame_button form-check-input" id="switchFrame" t-att-checked="state.activeFrame" t-on-change="onFrameChange"/>
                <label class="form-check-label" for="switchFrame" data-tooltip="Include a visual security frame around your signature">Frame</label>
            </div>

                        <Dropdown t-if="state.signMode === 'auto'" class="'o_web_sign_auto_select_style col-auto'" showCaret="true" togglerClass="'btn btn-link fa fa-font'">
                            <t t-foreach="fonts" t-as="font" t-key="font_index">
                                <DropdownItem onSelected="() =&gt; this.onSelectFont(font_index)">
                                    <img class="img-fluid" t-att-src="getSVGTextFont(font)"/>
                                </DropdownItem>
                            </t>
                        </Dropdown>

                        <div t-if="state.signMode === 'draw'" t-attf-class="o_web_sign_draw_clear col-auto">
                            <a role="button" href="#" t-on-click.prevent="onClickSignDrawClear" class="btn btn-link fa fa-trash"/>
                        </div>

                        <div t-if="state.signMode === 'load'" class="o_web_sign_load_file col-auto">
                            <button type="button" id="loadFileXml" t-on-click="uploadFile" class="btn btn-link fa fa-upload"/>
                            <input t-ref="signInputLoad" type="file" role="button" name="files[]" class="d-none" t-on-change="onChangeSignLoadInput"/>
                        </div>
                    </div>
                </div>

                <div class="o_web_sign_signature_container position-relative">
            <div t-attf-class="o_sign_frame {{ signFrameClass }}" t-ref="signFrame">
                <p t-att-hash="props.hash" t-attf-sign_label="Signed with Odoo Sign"/>
            </div>
                    <div class="o_signature_stroke position-absolute"/>
                    <div t-if="state.showSignatureArea" t-ref="signature" t-att-style="signatureStyle" class="o_web_sign_signature p-0 bg-transparent position-relative" t-on-click="onSignatureAreaClick"/>
                </div>

                <div t-if="loadIsInvalid" t-attf-class="o_web_sign_load_invalid card-footer d-none">
                    <div class="alert alert-danger mb-0" role="alert">
                        This file is invalid. Please select an image.
                    </div>
                </div>
            </div>
        </div>
    </t>
<t t-name="sign.SignRefusalDialog">
        <Dialog t-props="dialogProps">
            <div>
                <h3>Reason</h3>
                <textarea class="o_sign_refuse_confirm_message" placeholder="Why do you refuse to sign this document?" t-ref="refuse-reason" t-on-change="checkForChanges" t-on-keyup="checkForChanges" t-on-paste="checkForChanges"/>
            </div>
            <t t-set-slot="footer">
                <button class="btn btn-primary refuse-button" t-on-click="refuse" t-ref="refuse-button" disabled="disabled">Refuse</button>
                <button class="btn btn-secondary" t-on-click="props.close">Cancel</button>
            </t>
        </Dialog>
    </t>
<t t-name="sign.SMSSignerDialog">
        <Dialog t-props="dialogProps">
            <div class="mb-3 row">
                <label class="col-sm-3 col-form-label" for="phone">Phone Number</label>
                <div class="col-sm">
                    <div class="input-group">
                        <input type="text" name="phone" t-ref="phone" placeholder="e.g. +1 415 555 0100" class="form-control" t-att-value="SMSInfo.phoneNumber"/>
                        <button class="btn btn-sm btn-primary o_sign_resend_sms" t-on-click="onSendSMSClick" t-ref="send-sms" t-att-disabled="state.sendingSMS">
                            <t t-if="state.sendingSMS">
                                <span>
                                    <i class="fa fa-check"/> SMS Sent
                                </span>
                            </t>
                            <t t-elif="state.SMSCount &gt; 0">
                                Re-send SMS
                            </t>
                            <t t-else="">
                                Send SMS
                            </t>
                        </button>
                    </div>
                    <span class="text-muted form-text">A SMS will be sent to the following phone number. Please update it if it's not relevant.</span>
                </div>
            </div>
            <div class="mb-3 row">
                <label class="col-sm-3 col-form-label" for="validation_code">Validation Code</label>
                <div class="col-sm">
                    <input type="text" name="validation_code" t-ref="code" id="o_sign_public_signer_sms_input" placeholder="e.g. 314159" class="form-control"/>
                    <span class="text-muted form-text">Enter the code received through SMS to complete your signature</span>
                </div>
            </div>

            <t t-set-slot="footer">
                <button class="btn btn-primary o_sign_validate_sms" t-on-click="validateSMS">Verify</button>
            </t>
        </Dialog>
    </t>
<t t-name="sign.ThankYouDialog">
        <Dialog t-props="dialogProps">
            <t t-set-slot="header" t-slot-scope="scope">
                <h4 class="modal-title text-break" t-att-class="{ 'me-auto': scope.isFullscreen }">
                    Thank you! Your signature has been submitted.
                </h4>
            </t>
            <h5 t-if="props.subtitle" id="thank-you-subtitle"><t t-esc="props.subtitle"/></h5>
            <div id="thank-you-message" class="o_thankyou_message" t-esc="message"/>
            <div t-if="suggestSignUp" class="o_thankyou_message alert alert-success py-4">
                Sign up for Odoo Sign to manage your own documents and signature requests.
            </div>
            <t t-if="state.nextDocuments.length &gt; 0">
                <div class="o_thankyou_message">There are other documents waiting for your signature:</div>
                <table class="table table-sm">
                    <tbody>
                        <t t-foreach="state.nextDocuments" t-as="doc" t-key="doc.id">
                            <tr t-attf-class="next-document {{ doc.ignored ? 'text-muted' : '' }}">
                                <td>
                                    <strong t-out="doc.name"/>
                                </td>
                                <td>
                                    <span>Sent by <span t-out="doc.user"/> on <span t-out="doc.date"/></span>
                                </td>
                                <td>
                                    <button class="btn btn-sm btn-secondary o_thankyou_next_sign me-1" t-att-disabled="doc.ignored" t-on-click="() =&gt; this.clickNextSign(doc.requestId, doc.accessToken)">Sign</button>
                                    <button class="btn btn-sm btn-secondary o_thankyou_next_ignore" t-att-disabled="doc.ignored" t-on-click="() =&gt; this.clickNextIgnore(doc)">Ignore</button>
                                </td>
                            </tr>
                        </t>
                    </tbody>
                </table>
            </t>
            <t t-set-slot="footer">
                <t t-foreach="state.buttons" t-as="button" t-key="button.name">
                    <button t-att-class="button.classes" t-on-click="button.click" t-att-disabled="button.disabled"><t t-out="button.name"/></button>
                </t>
            </t>
        </Dialog>
    </t>
<t t-name="sale_subscription.deleteTokenDialog">
        <div>
            <p>This payment method cannot be deleted, because it is currently linked to the
                following active subscriptions:
            </p>
            <ul>
                <li t-foreach="linkedRecordsInfo" t-as="documentInfo" t-key="documentInfoIndex">
                    <a t-att-title="documentInfo.description" t-att-href="documentInfo.url" t-esc="documentInfo.name"/>
                </li>
            </ul>
            <p>Please provide another payment method for these subscriptions first.</p>
        </div>
    </t>

<t t-name="mail.AttachmentList">
        <div class="o-mail-AttachmentList overflow-y-auto d-flex flex-column mt-1" t-att-class="{                 'o-inComposer': env.inComposer,                 'o-inChatWindow': env.inChatWindow,                 'me-2 pe-4': isInChatWindowAndIsAlignedLeft and !env.inComposer,                 'ms-2 ps-4': isInChatWindowAndIsAlignedRight and !env.inComposer,             }">
            <div class="d-flex flex-grow-1 flex-wrap mx-1" t-att-class="{                 'justify-content-end': isInChatWindowAndIsAlignedRight and !env.inComposer,             }" role="menu">
                <div t-foreach="imagesAttachments" t-as="attachment" t-key="attachment.id" t-att-aria-label="attachment.filename" class="o-mail-AttachmentImage d-flex position-relative flex-shrink-0 mw-100 mb-1 me-1" t-att-title="attachment.name" t-att-class="{ 'o-isUploading': attachment.uploading }" tabindex="0" aria-label="View image" role="menuitem" t-att-data-mimetype="attachment.mimetype" t-on-click="() =&gt; this.fileViewer.open(attachment, props.attachments)">
                    <img class="img img-fluid my-0 mx-auto o-viewable" t-att-class="{ 'opacity-25': attachment.uploading }" t-att-src="getImageUrl(attachment)" t-att-alt="attachment.name" t-attf-style="max-width: min(100%, {{ imagesWidth }}px); max-height: {{ props.imagesHeight }}px;" t-on-load="onImageLoaded"/>
                    <div t-if="attachment.uploading" class="position-absolute top-0 bottom-0 start-0 end-0 d-flex align-items-center justify-content-center" title="Uploading">
                        <i class="fa fa-spin fa-spinner"/>
                    </div>
                    <div class="position-absolute top-0 bottom-0 start-0 end-0 p-2 text-white opacity-0 opacity-100-hover d-flex align-items-end flax-wrap flex-column">
                        <div t-if="showDelete and !ui.isSmall" class="btn btn-sm btn-dark rounded opacity-75 opacity-100-hover" tabindex="0" aria-label="Remove" role="menuitem" t-on-click.stop="() =&gt; this.onClickUnlink(attachment)" title="Remove">
                            <i class="fa fa-trash"/>
                        </div>
                        <div t-if="canDownload(attachment) and !ui.isSmall" class="btn btn-sm btn-dark rounded opacity-75 opacity-100-hover mt-auto" t-on-click.stop="() =&gt; this.onClickDownload(attachment)" title="Download">
                            <i class="fa fa-download"/>
                        </div>
                    </div>
                </div>
            </div>
            <div class="d-flex flex-grow-1 flex-wrap mt-1 mx-1" t-att-class="{                 'justify-content-end': isInChatWindowAndIsAlignedRight and !env.inComposer,             }">

                <div t-foreach="nonImagesAttachments" t-as="attachment" t-key="attachment.id" class="o-mail-AttachmentCard d-flex rounded mb-1 me-1 mw-100 overflow-auto" t-att-class="{                         'ms-1': isInChatWindowAndIsAlignedRight,                         'me-1': !isInChatWindowAndIsAlignedRight,                         'o-viewable': attachment.isViewable,                         'o-isUploading': attachment.uploading,                     }" t-attf-class="bg-300" t-att-title="attachment.name ? attachment.name : undefined" role="menu" t-att-aria-label="attachment.name" t-on-click="() =&gt; this.fileViewer.open(attachment, props.attachments)">

                    <t t-ref="nonImageMain">
                        <div class="o-mail-AttachmentCard-image o_image flex-shrink-0 m-1" role="menuitem" aria-label="Preview" t-att-tabindex="-1" t-att-aria-disabled="false" t-att-data-mimetype="attachment.mimetype"/>
                        <div class="overflow-auto d-flex justify-content-center flex-column px-1">
                            <div t-if="attachment.name" class="text-truncate" t-out="props.messageSearch?.highlight(attachment.name) ?? attachment.name"/>
                            <small t-if="attachment.extension" class="text-uppercase" t-esc="attachment.extension"/>
                        </div>
                    </t>
                    <div class="o-mail-AttachmentCard-aside position-relative rounded-end overflow-hidden" t-att-class="{ 'o-hasMultipleActions d-flex flex-column': showDelete and !env.inComposer }">
                        <div t-if="attachment.uploading" class="d-flex justify-content-center align-items-center w-100 h-100" title="Uploading">
                            <i class="fa fa-spin fa-spinner"/>
                        </div>
                        <div t-if="!attachment.uploading and env.inComposer" class="d-flex justify-content-center align-items-center w-100 h-100 text-primary" title="Uploaded">
                            <i class="fa fa-check"/>
                        </div>
                        <button t-if="showDelete" class="o-mail-AttachmentCard-unlink btn top-0 justify-content-center align-items-center d-flex w-100 h-100 rounded-0 border-0" t-attf-class="{{ env.inComposer ? 'o-inComposer position-absolute btn-primary transition-base' : 'bg-300' }}" t-on-click.stop="() =&gt; this.onClickUnlink(attachment)" title="Remove">
                            <i class="fa fa-trash" role="img" aria-label="Remove"/>
                        </button>

                        <button t-if="canDownload(attachment)" class="btn d-flex justify-content-center align-items-center w-100 h-100 rounded-0" t-attf-class="bg-300" t-on-click.stop="() =&gt; this.onClickDownload(attachment)" title="Download">
                            <i class="fa fa-download" role="img" aria-label="Download"/>
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </t>

<t t-name="mail.AttachmentView">
        <div t-if="state.thread.attachmentsInWebClientView.length &gt; 0" class="o-mail-Attachment">
            <t t-if="state.thread.mainAttachment">
                <h3 t-if="!state.thread.mainAttachment.isPdf" class="mt0 mb8 ps-2 text-muted text-center"><t t-esc="displayName"/></h3>
                <div t-if="state.thread.mainAttachment.isImage" class="o-mail-Attachment-imgContainer">
                    <img id="attachment_img" class="img img-fluid d-block" t-att-src="state.thread.mainAttachment.defaultSource"/>
                </div>
                <iframe t-if="state.thread.mainAttachment.isPdf" class="mb48" t-att-src="state.thread.mainAttachment.defaultSource" t-ref="iframeViewerPdf"/>
                <t t-if="state.thread.attachmentsInWebClientView.length &gt; 1">
                    <a class="arrow o_move_previous text-center" href="#" t-on-click.prevent="onClickPrevious">
                        <span class="oi oi-chevron-left"/>
                    </a>
                    <a class="arrow o_move_next text-center" href="#" t-on-click.prevent="onClickNext">
                        <span class="oi oi-chevron-right"/>
                    </a>
                </t>
            </t>
        </div>
    </t>

<t t-name="mail.AutoresizeInput">
    <input class="o-mail-AutoresizeInput o_input px-1 border-1 text-truncate" t-attf-class="{{ props.className }}" t-attf-placeholder="{{ props.placeholder }}" t-att-disabled="!props.enabled" t-att-title="state.value" t-model="state.value" t-on-keydown="onKeydownInput" t-on-blur="() =&gt; this.props.onValidate(this.state.value)" t-ref="input" type="text"/>
</t>

<t t-name="mail.ChatWindow">
    <div class="o-mail-ChatWindow" t-att-style="style" t-att-class="{                 'w-100 h-100 o-mobile': ui.isSmall,                 'o-folded': props.chatWindow.folded or props.chatWindow.hidden,                 'position-fixed bottom-0 overflow-hidden d-flex flex-column': !props.chatWindow.hidden,                 'rounded-top-3': !props.chatWindow.hidden and !ui.isSmall,                 }" t-on-keydown="onKeydown" tabindex="1">
        <div class="o-mail-ChatWindow-header d-flex align-items-center flex-shrink-0 bg-100" t-on-click="onClickHeader" t-att-class="{ 'cursor-pointer': !ui.isSmall, 'border-bottom': !props.chatWindow.folded }" t-attf-style="color: {{ livechatService.options.title_color }}; background-color: {{ livechatService.options.header_background_color }} !important;">
            <t t-if="threadActions.actions.length &gt; 3">
                <Dropdown position="'bottom-start'" onStateChanged="state =&gt; this.onActionsMenuStateChanged(state)" togglerClass="\`o-mail-ChatWindow-command d-flex btn align-items-center text-truncate p-0 p-1 \${ !ui.isSmall ? 'ms-2' : '' } \${state.actionsMenuOpened ? 'o-active' : ''}\`" menuClass="'d-flex flex-column py-0'" class="'d-flex text-truncate'" disabled="state.editingName" title="actionsMenuTitleText">
                    <t t-set-slot="toggler">
                        <t t-call="mail.ChatWindow.headerContent"/>
                    </t>
                    <t t-set-slot="default">
                        <t t-if="ui.isSmall" t-set="actions" t-value="threadActions.actions.slice(1, -1)"/>
                        <t t-else="" t-set="actions" t-value="threadActions.actions.slice(1, -2)"/>
                        <DropdownItem t-foreach="actions" t-as="action" t-key="action.id" class="'o-mail-ChatWindow-command btn rounded-0 d-flex align-items-center px-2 py-2 m-0 opacity-75 opacity-100-hover'" title="action.name" onSelected="() =&gt; action.onSelect()"><i t-att-class="action.icon"/><span class="mx-2" t-out="action.name"/></DropdownItem>
                    </t>
                </Dropdown>
                <AutoresizeInput t-if="state.editingName" className="'text-truncate fw-bold flex-shrink-1 me-1 py-0'" enabled="true" autofocus="true" onValidate.bind="renameThread" value="props.chatWindow.displayName"/>
            </t>
            <t t-else="">
                <t t-call="mail.ChatWindow.headerContent"/>
            </t>
            <div class="flex-grow-1"/>
            <t t-if="!chatbotService.active"><div t-if="thread and thread.needactionCounter &gt; 0" class="o-mail-ChatWindow-counter mx-1 my-0 badge rounded-pill fw-bold o-discuss-badge" t-ref="needactionCounter">
                <t t-out="thread.needactionCounter"/>
            </div>
            </t>
        <t t-if="threadActions.actions.length &gt; 1" t-call="mail.ChatWindow.dropdownAction">
                <t t-set="action" t-value="threadActions.actions[0]"/>
            </t>
            <t t-if="!ui.isSmall and threadActions.actions.length &gt; 2">
                <t t-call="mail.ChatWindow.dropdownAction">
                    <t t-set="action" t-value="threadActions.actions.at(-2)"/>
                </t>
            </t>
            <t t-call="mail.ChatWindow.dropdownAction">
                <t t-set="action" t-value="threadActions.actions.at(-1)"/>
                <t t-set="itemClass" t-value="'me-1'"/>
            </t>
        </div>
        <div t-if="!props.chatWindow.folded and !props.chatWindow.hidden or ui.isSmall" class="bg-view d-flex flex-column h-100 overflow-auto position-relative" t-ref="content">
            <FeedbackPanel t-if="livechatState.hasFeedbackPanel" onClickClose="() =&gt; this.close()" thread="thread"/>
           <t t-else=""><t t-if="thread" name="thread content">
                <div t-if="threadActions.activeAction?.componentCondition" class="h-100" t-attf-class="{{ threadActions.activeAction.panelOuterClass }}">
                    <t t-component="threadActions.activeAction.component" t-props="{ ...threadActions.activeAction.componentProps, thread }"/>
                </div>
                <t t-else="">
            <Call t-if="thread.rtcSessions.length &gt; 0" thread="thread" compact="true"/>
                    <Thread isInChatWindow="true" thread="thread" t-key="thread.localId" jumpPresent="state.jumpThreadPresent" messageEdition="messageEdition" messageToReplyTo="messageToReplyTo"/>
                    <div t-if="thread and typingService.hasTypingMembers(thread)" class="d-flex bg-view position-relative">
                        <div class="o-mail-ChatWindow-typing d-flex px-2 position-absolute bottom-0 start-0 w-100 bg-view align-items-center">
                            <Typing channel="thread" size="'medium'"/>
                        </div>
                    </div>
                    <t t-if="chatbotService.inputEnabled"><Composer t-if="thread" composer="thread.composer" autofocus="props.chatWindow.autofocus" mode="'compact'" messageEdition="messageEdition" messageToReplyTo="messageToReplyTo" onPostCallback.bind="() =&gt; this.state.jumpThreadPresent++" dropzoneRef="contentRef" type="composerType"/>
                </t>
            <t t-else="">
                <span class="bg-200 py-1 text-center fst-italic" t-esc="chatbotService.inputDisabledText"/>
            </t>
        </t>
            </t>
        </t>
        </div>
    </div>
</t>

<t t-name="mail.ChatWindow.dropdownAction">
    <button class="o-mail-ChatWindow-command btn d-flex p-2 opacity-75 opacity-100-hover" t-att-class="itemClass" t-att-title="action.name" t-on-click.stop="() =&gt; action.onSelect()"><i t-att-class="action.icon"/></button>
</t>

<t t-name="mail.ChatWindow.headerContent">
    <div t-if="thread" class="o-mail-ChatWindow-threadAvatar my-0" t-attf-class="{{ threadActions.actions.length &gt; 4 ? 'ms-1' : 'ms-3' }} me-1">
        <img class="rounded" t-att-src="thread.imgUrl" alt="Thread Image"/>
    </div>
    <ThreadIcon t-if="thread and thread.type === 'chat' and thread.chatPartner" thread="thread"/>
    <div t-if="!state.editingName" class="text-truncate fw-bold border border-transparent me-1 my-0" t-att-title="props.chatWindow.displayName" t-esc="props.chatWindow.displayName" t-att-class="thread ? 'ms-1' : 'ms-3'"/>
</t>
<t t-name="mail.ChatWindowContainer">
    <div class="o-mail-ChatWindowContainer" t-if="store.isMessagingReady and (!store.discuss.isActive or ui.isSmall)" part="chatWindowContainer">
        <div t-if="chatWindowService.hidden.length &gt; 0 and !ui.isSmall" t-ref="hiddenMenu" class="o-mail-ChatWindow-hiddenMenuContainer position-fixed bottom-0">
            <t t-call="mail.ChatWindowHiddenMenu"/>
        </div>
        <t t-foreach="chatWindowService.visible" t-as="chatWindow" t-key="chatWindow.thread?.localId">
            <ChatWindow chatWindow="chatWindow" right="CHAT_WINDOW_END_GAP_WIDTH + chatWindow_index * (CHAT_WINDOW_WIDTH + CHAT_WINDOW_INBETWEEN_WIDTH * 2)"/>
        </t>
    </div>
</t>

<t t-name="mail.ChatWindowHiddenMenu">
    <Dropdown position="'top-end'" menuClass="'o-mail-ChatWindowHiddenMenu p-0'" togglerClass="'o-mail-ChatWindowHiddenToggler btn d-flex align-items-center rounded-top-3 bg-900'">
        <t t-set-slot="toggler">
            <div class="me-1 fa fa-comments-o"/>
            <div class="mx-1 text-truncate" t-esc="chatWindowService.hidden.length"/>
            <div t-if="unread &gt; 0" class="o-mail-ChatWindowHiddenMenu-unreadCounter position-absolute end-0 top-0 badge rounded-pill text-bg-primary" t-esc="unread"/>
        </t>
        <t t-set-slot="default">
            <ul class="m-0 p-0 overflow-auto" role="menu" t-ref="list">
                <li t-foreach="[...chatWindowService.hidden].reverse()" t-as="chatWindow" t-key="chatWindow.thread?.localId" class="o-mail-ChatWindowHiddenMenu-item dropdown-item p-0" t-att-class="{ 'border-bottom' : !chatWindow_last }" role="menuitem">
                    <ChatWindow chatWindow="chatWindow"/>
                </li>
            </ul>
        </t>
    </Dropdown>
</t>

<t t-name="mail.Composer">
    <t t-set="compact" t-value="props.mode === 'compact'"/>
    <t t-set="normal" t-value="props.mode === 'normal'"/>
    <t t-set="extended" t-value="props.mode === 'extended'"/>
    <div t-ref="composer">
        <div class="o-mail-Composer d-grid flex-shrink-0 pt-0" t-att-class="{                     'px-3 pb-2': extended and !props.composer.message,                     'o-extended': extended,                     'o-isUiSmall': ui.isSmall,                     'p-3': normal,                     'o-hasSelfAvatar px-3': !env.inChatWindow and thread,                 }" t-attf-class="{{ props.className }}">
            <div class="o-mail-Composer-sidebarMain flex-shrink-0" t-if="!compact and props.sidebar">
                <img class="o-mail-Composer-avatar o_avatar rounded" t-att-src="threadService.avatarUrl(store.self, props.composer.thread)" alt="Avatar of user"/>
            </div>
            <div class="o-mail-Composer-coreHeader text-truncate small p-2" t-if="props.composer.thread and props.messageToReplyTo?.thread?.eq(props.composer.thread)">
                <span class="cursor-pointer" t-on-click="() =&gt; env.messageHighlight?.highlightMessage(props.messageToReplyTo.message, props.composer.thread)">
                    Replying to <b t-esc="props.messageToReplyTo.message.author?.name ?? props.messageToReplyTo.message.email_from"/>
                </span>
                <span t-if="props.messageToReplyTo.message.originThread.notEq(props.composer.thread)">
                    on: <b><t t-esc="props.messageToReplyTo.message.originThread.displayName"/></b>
                </span>
                <i class="fa fa-lg fa-times-circle rounded-circle p-0 ms-1 cursor-pointer" title="Stop replying" t-on-click="() =&gt; props.messageToReplyTo.cancel()"/>
            </div>
            <div class="o-mail-Composer-coreMain d-flex flex-nowrap align-items-start flex-grow-1" t-att-class="{ 'flex-column' : extended }">
                <div class="d-flex bg-view flex-grow-1" t-att-class="{                         'border-top border-bottom': compact and !props.composer.message,                         'border': props.composer.message,                         'border rounded-3' : normal,                         'border rounded-3 align-self-stretch flex-column' : extended,                     }">
                    <div class="position-relative flex-grow-1">
                        <t t-set="inputClasses" t-value="'form-control px-3 border-0 rounded-3'"/>
                        <textarea class="o-mail-Composer-input bg-view shadow-none overflow-auto" t-att-class="inputClasses" t-ref="textarea" style="height:40px;" t-on-keydown="onKeydown" t-on-focusin="onFocusin" t-on-focusout="() =&gt; this.props.composer.isFocused = false" t-on-click="(ev) =&gt; markEventHandled(ev, 'composer.onClickTextarea')" t-on-paste="onPaste" t-model="props.composer.textInputContent" t-att-placeholder="placeholder" t-att-readOnly="!state.active" t-on-input="onInput"/>

                        <textarea class="o-mail-Composer-fake overflow-hidden position-absolute" t-att-class="inputClasses" t-model="props.composer.textInputContent" t-ref="fakeTextarea" disabled="1"/>
                    </div>
                    <div class="o-mail-Composer-actions d-flex bg-view" t-att-class="{                             'ms-1': compact and ui.isSmall,                             'mx-1 me-2': compact and !ui.isSmall,                             'ms-3': normal,                             'mx-3 border-top p-1': extended,                         }">
                        <div class="d-flex flex-grow-1 align-items-center" t-ref="main-actions">
                            <button class="btn border-0 rounded-pill" t-att-class="{'bg-300': this.picker.state.picker === this.picker.PICKERS.EMOJI}" aria-label="Emojis" t-on-click="onClickAddEmoji" t-ref="emoji-button"><i class="fa fa-smile-o"/></button>
                            <FileUploader t-if="allowUpload" multiUpload="true" onUploaded="(data) =&gt; { attachmentUploader.uploadData(data) }">
                                <t t-set-slot="toggler">
                                    <button t-att-disabled="!state.active" class="o-mail-Composer-attachFiles btn border-0 rounded-pill" title="Attach files" aria-label="Attach files" type="button" t-on-click="onClickAddAttachment"><i class="fa fa-paperclip"/></button>
                                </t>
                            </FileUploader>
                            <t t-if="extended and ui.isSmall and props.composer.message" t-call="mail.Composer.sendButton"/>
                        </div>
                        <button t-if="props.showFullComposer and thread and thread.type === 'chatter'" class="o-mail-Composer-fullComposer btn fa fa-expand m-1 border-0 rounded-pill" title="Full composer" aria-label="Full composer" type="button" t-on-click="onClickFullComposer"/>
                    </div>
                    <t t-if="!extended" t-call="mail.Composer.sendButton"/>
                </div>
                <div t-if="extended and !props.composer.message" class="d-flex align-items-center mt-2 gap-2">
                    <t t-call="mail.Composer.sendButton"/>
                    <span t-if="!isSendButtonDisabled and !props.composer.message" t-out="SEND_KEYBIND_TO_SEND"/>
                </div>
            </div>
            <div class="o-mail-Composer-footer overflow-auto">
                <AttachmentList t-if="allowUpload and props.composer.attachments.length &gt; 0" attachments="props.composer.attachments" unlinkAttachment.bind="(...args) =&gt; attachmentUploader.unlink(...args)" imagesHeight="50"/>
            <div t-if="thread and thread.type !== 'chatter' and !compact" class="o-discuss-Typing d-flex">
                <Typing channel="thread" size="'medium'"/>
            </div>
                <Picker t-props="picker"/>
            </div>
        </div>
        <span t-if="props.composer.message" class="text-muted" t-out="CANCEL_OR_SAVE_EDIT_TEXT" t-on-click="onClickCancelOrSaveEditText"/>
    </div>
    <NavigableList t-if="suggestion" class="'o-mail-Composer-suggestionList'" t-props="navigableListProps"/>
</t>

<t t-name="mail.Composer.sendButton">
    <button t-if="!compact or ui.isSmall" class="o-mail-Composer-send btn o-last" t-att-class="{'btn-primary': extended, 'rounded-0 rounded-end-3': !extended and !compact, 'btn-link align-self-stretch': !extended, 'border-start-0 ms-2 me-3': env.inDiscussApp}" t-on-click="sendMessage" t-att-disabled="isSendButtonDisabled" t-att-aria-label="SEND_TEXT">
        <t t-if="thread and thread.type === 'chatter'" t-out="SEND_TEXT"/>
        <t t-elif="ui.isSmall"><i class="fa fa-paper-plane-o"/></t>
        <t t-else="">Send</t>
    </button>
</t>

    <t t-name="mail.Composer.suggestionPartner">
        <t t-set="partner" t-value="option.partner"/>
        <ImStatus t-if="partner" persona="partner"/>
        <strong class="px-2 py-1 align-self-center flex-shrink-0 text-truncate">
            <t t-esc="partner.name"/>
        </strong>
        <em t-if="partner.email" class="text-600 text-truncate align-self-center">(<t t-esc="partner.email"/>)</em>
    </t>

    <t t-name="mail.Composer.suggestionThread">
        <strong class="px-2 py-1 align-self-center flex-shrink-0 text-truncate">
            #<t t-esc="option.label"/>
        </strong>
    </t>

    <t t-name="mail.Composer.suggestionChannelCommand">
        <strong class="px-2 py-1 align-self-center flex-shrink-0 text-truncate">
            <t t-esc="option.label"/>
        </strong>
        <em class="text-600 text-truncate align-self-center">
            <t t-esc="option.help"/>
        </em>
    </t>

    <t t-name="mail.Composer.suggestionCannedResponse">
        <strong class="px-2 py-1 align-self-center flex-shrink-0 text-truncate">
            <t t-esc="option.source"/>
        </strong>
        <em class="text-600 text-truncate align-self-center">
            <t t-esc="option.label"/>
        </em>
    </t>
<t t-name="mail.DateSection">
    <div class="o-mail-DateSection d-flex align-items-center fw-bolder w-100" t-attf-class="{{ props.className }}">
        <hr class="ms-3 flex-grow-1"/>
        <span class="px-3 text-muted"><t t-esc="props.date"/></span>
        <hr class="me-3 flex-grow-1"/>
    </div>
</t>
<t t-name="mail.Discuss">
    <div class="o-mail-Discuss d-flex h-100 flex-grow-1" t-att-class="{ 'border-top': !store.inPublicPage and !ui.isSmall, 'flex-column align-items-center bg-view': ui.isSmall }" t-ref="root">
        <div t-if="ui.isSmall and store.discuss.activeTab === 'main'" class="w-100 border-bottom" t-call="mail.Discuss.mobileTopbar" t-ref="mobileTopbar"/>
        <div t-if="thread and (store.inPublicPage or !(ui.isSmall and ['chat', 'channel'].includes(store.discuss.activeTab)))" class="o-mail-Discuss-content d-flex flex-column h-100 w-100 bg-view overflow-auto" t-ref="content">
            <div class="o-mail-Discuss-header px-3 bg-view border-bottom d-flex flex-shrink-0 align-items-center">
                <div t-if="thread and ['channel', 'group', 'chat'].includes(thread.type)" class="o-mail-Discuss-threadAvatar position-relative align-self-center align-items-center mt-2 mb-2 me-2">
                    <img class="rounded" t-att-src="thread.imgUrl" alt="Thread Image"/>
                    <FileUploader t-if="thread.is_editable" acceptedFileExtensions="'.bmp, .jpg, .jpeg, .png, .svg'" showUploadingText="false" multiUpload="false" onUploaded="(data) =&gt; this.onFileUploaded(data)">
                        <t t-set-slot="toggler">
                            <a href="#" class="position-absolute z-index-1 h-100 w-100 rounded start-0 bottom-0" title="Upload Avatar">
                                <i class="position-absolute top-50 start-50 fa fa-sm fa-pencil text-white"/>
                            </a>
                        </t>
                    </FileUploader>
                </div>
                <t t-else="">
                    <ThreadIcon className="'me-2 align-self-center'" thread="thread"/>
                </t>
                <ImStatus t-if="thread and thread.type === 'chat' and thread.chatPartner" className="'me-1'" persona="thread.chatPartner" thread="thread"/>
                <div class="d-flex flex-grow-1 align-self-center align-items-center h-100 py-2">
                    <AutoresizeInput className="'o-mail-Discuss-threadName lead fw-bold flex-shrink-1 text-dark py-0'" enabled="thread.is_editable or thread.type === 'chat'" onValidate.bind="renameThread" value="thread.displayName"/>
                    <t t-if="thread.allowDescription and (thread.is_editable or (!thread.is_editable and thread.description))">
                        <div class="flex-shrink-0 mx-2 py-2 border-start"/>
                        <t t-set="autogrowDescriptionPlaceholder">Add a description</t>
                        <AutoresizeInput className="'o-mail-Discuss-threadDescription flex-shrink-1 py-1'" enabled="thread.is_editable" onValidate.bind="updateThreadDescription" placeholder="thread.is_editable ? autogrowDescriptionPlaceholder : ''" value="thread.description or ''"/>
                    </t>
                </div>
                <div class="flex-shrink-0 d-flex align-items-center ms-1">
                    <t t-foreach="threadActions.actions" t-as="action" t-key="action.id">
                        <button class="btn px-2" t-attf-class="{{ action.isActive ? 'o-isActive' : '' }}" t-att-disabled="action.disabledCondition" t-att-title="action.name" t-att-name="action.id" t-on-click="() =&gt; action.onSelect()">
                            <i t-if="action.iconLarge" t-att-class="action.iconLarge"/> <span t-if="action.text" t-esc="action.text"/>
                        </button>
                    </t>
                    <div t-if="store.inPublicPage and !ui.isSmall" class="d-flex align-items-center">
                        <img class="o-mail-Discuss-selfAvatar mx-1 rounded-circle o_object_fit_cover flex-shrink-0" alt="Avatar" t-att-src="threadService.avatarUrl(store.self, thread)"/>
                        <div class="lead fw-bold flex-shrink-1 text-dark">
                            <t t-if="store.user" t-esc="store.user.name"/>
                            <t t-else="">
                                <AutoresizeInput className="'py-1'" onValidate.bind="renameGuest" value="store.guest.name"/>
                            </t>
                        </div>
                    </div>
                </div>
            </div>
            <div class="overflow-auto bg-view d-flex flex-grow-1" t-ref="core">
                <div class="d-flex flex-column flex-grow-1">
            <Call t-if="thread.rtcSessions.length &gt; 0" thread="thread"/>
                    <Thread thread="thread" t-key="thread.localId" jumpPresent="state.jumpThreadPresent" messageEdition="messageEdition" messageToReplyTo="messageToReplyTo"/>
                    <Composer t-if="thread.type !== 'mailbox' or thread.eq(messageToReplyTo.thread)" t-key="thread.localId" composer="thread.composer" autofocus="true" messageEdition="messageEdition" messageToReplyTo="messageToReplyTo" onDiscardCallback="() =&gt; messageToReplyTo.cancel()" onPostCallback.bind="() =&gt; this.state.jumpThreadPresent++" dropzoneRef="contentRef" type="messageToReplyTo?.message ? (messageToReplyTo.message.is_note ? 'note' : 'message') : undefined"/>
                </div>
                <div t-if="threadActions.activeAction?.componentCondition" t-attf-class="{{ threadActions.activeAction.panelOuterClass }}" class="h-100 border-start o-mail-Discuss-inspector">
                    <t t-component="threadActions.activeAction.component" thread="thread" t-props="threadActions.activeAction.componentProps"/>
                </div>
            </div>
        </div>
        <div t-if="!thread and (!ui.isSmall or store.discuss.activeTab === 'main') and store.discuss.hasRestoredThread" class="d-flex flex-grow-1 align-items-center justify-content-center w-100 bg-view">
            <h4 class="text-muted"><b><i>No conversation selected.</i></b></h4>
        </div>
    </div>
</t>

<t t-name="mail.Discuss.mobileTopbar">
    <div class="btn-group d-flex w-100 p-1">
        <t t-call="mail.MobileMailbox">
            <t t-set="mailbox" t-value="store.discuss.inbox"/>
        </t>
        <t t-call="mail.MobileMailbox">
            <t t-set="mailbox" t-value="store.discuss.starred"/>
        </t>
        <t t-call="mail.MobileMailbox">
            <t t-set="mailbox" t-value="store.discuss.history"/>
        </t>
    </div>
</t>

<t t-name="mail.MobileMailbox">
    <button class="btn btn-secondary flex-grow-1 p-2" t-att-class="{             'active o-active shadow-none': mailbox.eq(store.discuss.thread),         }" t-on-click="() =&gt; this.threadService.setDiscussThread(mailbox)" t-esc="mailbox.name"/>
</t>

<t t-name="mail.Dropzone">
    <div class="o-mail-Dropzone position-fixed align-items-center justify-content-center d-flex border-primary bg-100 text-primary opacity-75" t-att-class="{ 'o-dragging-inside': state.isDraggingInside }" t-attf-class="{{ props.extraClass }}" t-on-dragenter="() =&gt; state.isDraggingInside = true" t-on-dragleave="() =&gt; state.isDraggingInside = false" t-on-drop="props.onDrop" t-ref="root">
        <h4>Drag Files Here <i class="fa fa-download"/></h4>
    </div>
</t>

<t t-name="mail.ImStatus">
        <div class="o-mail-ImStatus d-flex justify-content-center flex-shrink-0 align-items-center rounded-circle bg-inherit" t-att-class="props.className" t-att-style="props.style">
            <span class="d-flex flex-column" name="icon">
                <t t-if="!props.thread or !typingService.hasTypingMembers(props.thread)">
                    <i t-if="props.persona.im_status === 'online'" class="fa fa-circle text-success" title="Online" role="img" aria-label="User is online"/>
                    <i t-elif="props.persona.im_status === 'away'" class="fa fa-circle o-away" title="Idle" role="img" aria-label="User is idle"/>
                    <i t-elif="props.persona.im_status === 'offline'" class="fa fa-circle-o text-700" title="Offline" role="img" aria-label="User is offline"/>
                    <i t-elif="props.persona.im_status === 'bot'" class="fa fa-heart text-success" title="Bot" role="img" aria-label="User is a bot"/>
                    <i t-else="" class="fa fa-fw fa-question-circle" title="No IM status available"/>
                </t>
                <Typing t-if="props.thread" channel="props.thread" size="'medium'" displayText="false"/>
            </span>
        </div>
    </t>

<t t-name="mail.LinkPreview">
        <t t-if="props.linkPreview.isCard">
            <t t-call="mail.LinkPreviewCard"/>
        </t>
        <t t-if="props.linkPreview.isVideo">
            <t t-call="mail.LinkPreviewVideo"/>
        </t>
        <t t-if="props.linkPreview.isImage">
            <t t-call="mail.LinkPreviewImage"/>
        </t>
    </t>

    <t t-name="mail.LinkPreviewCard">
        <div class="o-mail-LinkPreviewCard card position-relative w-100 mb-2 rounded bg-view shadow-sm overflow-hidden" t-att-class="{ 'me-2': env.inChatter }" t-attf-class="{{ className }}">
            <div class="row g-0 flex-row-reverse h-100">
                <div class="col min-w-0" t-att-class="{ 'd-flex align-items-center': !props.linkPreview.og_description }">
                    <div class="p-3">
                        <h6 class="card-title mb-0 me-2" t-attf-class="{{ props.linkPreview.og_description ? 'text-truncate' : 'overflow-hidden' }}">
                            <a t-att-href="props.linkPreview.source_url" target="_blank" t-out="props.linkPreview.og_title"/>
                        </h6>
                        <span t-if="props.linkPreview.og_site_name" t-out="props.linkPreview.og_site_name"/>
                        <p t-if="props.linkPreview.og_description" class="o-mail-LinkPreviewCard-description card-text mb-0 mt-2 text-muted small overflow-hidden" t-out="props.linkPreview.og_description"/>
                    </div>
                </div>
                <div class="o-mail-LinkPreviewCard-imageLinkWrap col-4 d-block">
                    <a t-att-href="props.linkPreview.source_url" target="_blank">
                        <img t-if="props.linkPreview.og_image" class="w-100 h-100 o_object_fit_cover" t-att-src="props.linkPreview.og_image" t-att-alt="props.linkPreview.og_title" t-on-load="onImageLoaded"/>
                        <span t-else="" class="d-flex align-items-center justify-content-center w-100 h-100 bg-100 text-300">
                            <i class="fa fa-camera fa-2x"/>
                        </span>
                    </a>
                </div>
            </div>
            <t t-if="props.deletable" t-call="mail.LinkPreview.aside">
                <t t-set="className" t-value="'fa fa-stack p-0 opacity-75 opacity-100-hover'"/>
            </t>
        </div>
    </t>

    <t t-name="mail.LinkPreviewImage">
        <div class="o-mail-LinkPreviewImage position-relative mb-2" t-att-class="{ 'me-2': env.inChatter }" t-attf-class="{{ className }}">
            <a t-if="props.linkPreview.imageUrl" t-att-href="props.linkPreview.imageUrl" target="_blank">
                <img class="h-auto w-auto rounded" t-att-src="props.linkPreview.imageUrl" t-on-load="onImageLoaded"/>
            </a>
            <t t-if="props.deletable" t-call="mail.LinkPreview.aside">
                <t t-set="className" t-value="'btn btn-sm btn-dark mt-2 me-2 rounded opacity-75 opacity-100-hover'"/>
            </t>
        </div>
    </t>

    <t t-name="mail.LinkPreviewVideo">
        <div class="o-mail-LinkPreviewVideo card position-relative w-100 mb-2 rounded bg-view shadow-sm overflow-hidden" t-att-class="{ 'me-2': env.inChatter }" t-attf-class="{{ className }}">
            <div class="row g-0 flex-row-reverse h-100">
                <div class="col min-w-0" t-att-class="{ 'd-flex align-items-center': !props.linkPreview.og_description }">
                    <div class="p-3 bg-view">
                        <h6 class="o-mail-LinkPreviewVideo-title card-title mb-0 me-2" t-attf-class="{{ props.linkPreview.og_description ? 'text-truncate' : 'o-mail-LinkPreviewVideo-hasDescription overflow-hidden' }}">
                            <a t-att-href="props.linkPreview.source_url" target="_blank" t-esc="props.linkPreview.og_title"/>
                        </h6>
                        <p t-if="props.linkPreview.og_description" class="o-mail-LinkPreviewVideo-description o-mail-LinkPreviewVideo-hasDescription card-text mb-0 mt-2 text-muted small overflow-hidden" t-out="props.linkPreview.og_description"/>
                    </div>
                </div>
                <div class="o-mail-LinkPreviewVideo-videoWrap col-4 d-block">
                    <a t-att-href="props.linkPreview.source_url" target="_blank">
                        <div t-if="props.linkPreview.og_image" class="o-mail-LinkPreviewVideo-overlay position-relative h-100 opacity-trigger-hover">
                            <img class="img-fluid h-100 rounded-bottom o_object_fit_cover" t-att-src="props.linkPreview.og_image" t-att-alt="props.linkPreview.og_title" t-on-load="onImageLoaded"/>
                            <div class="position-absolute top-50 start-50 translate-middle">
                                <div class="o-mail-LinkPreviewVideo-play btn btn-lg rounded opacity-75 opacity-100-hover transition-base">
                                    <i class="fa fa-play"/>
                                </div>
                            </div>
                        </div>
                        <span t-else="" class="d-flex align-items-center justify-content-center w-100 h-100 bg-100 text-300">
                            <i class="fa fa-camera fa-2x"/>
                        </span>
                    </a>
                </div>
            </div>
            <t t-if="props.deletable" t-call="mail.LinkPreview.aside">
                <t t-set="className" t-value="'fa fa-stack p-0 opacity-75 opacity-100-hover'"/>
            </t>
        </div>
    </t>

    <t t-name="mail.LinkPreview.aside">
        <div class="position-absolute top-0 end-0 small">
            <button t-attf-class="{{ className }}" class="o-mail-LinkPreview-aside btn" aria-label="Remove" t-on-click="onClick">
                <i class="fa fa-times"/>
            </button>
        </div>
    </t>
<t t-name="mail.LinkPreviewConfirmDelete">
        <Dialog size="'md'" title="'Confirmation'" modalRef="modalRef">
            <p class="mx-3 mb-3">Do you really want to delete this preview?</p>
            <t t-component="props.LinkPreview" linkPreview="props.linkPreview" deletable="false"/>
            <t t-set-slot="footer">
                <button class="btn btn-danger me-2" t-on-click="onClickOk">Delete</button>
                <button t-if="message.linkPreviews.length &gt; 1" class="btn btn-outline-danger me-2" t-on-click="onClickDeleteAll">Delete all previews</button>
                <button class="btn btn-secondary me-2" t-on-click="onClickCancel">Cancel</button>
            </t>
        </Dialog>
    </t>
<t t-name="mail.LinkPreviewList">
        <div class="o-mail-LinkPreviewList d-flex flex-column mt-2" t-att-class="{ 'me-2 pe-4': env.inChatWindow and !env.alignedRight, 'ms-2 ps-4': env.inChatWindow and env.alignedRight }">
            <div class="d-flex flex-grow-1 flex-wrap">
                <t t-foreach="props.linkPreviews" t-as="linkPreview" t-key="linkPreview.id">
                   <LinkPreview linkPreview="linkPreview" deletable="props.deletable"/>
                </t>
            </div>
        </div>
    </t>
<t t-name="mail.Message">
        <ActionSwiper onRightSwipe="hasTouch() and isInInbox ? { action: () =&gt; this.messageService.setDone(this.message), bgColor: 'bg-success', icon: 'fa-check-circle' } : undefined">
            <div class="o-mail-Message position-relative" t-att-class="attClass" role="group" t-att-aria-label="messageTypeText" t-on-click="onClick" t-on-mouseenter="onMouseenter" t-on-mouseleave="onMouseleave" t-ref="root">
                <MessageInReply t-if="message.parentMessage" alignedRight="isAlignedRight" message="message" onClick="props.onParentMessageClick"/>
                <div class="o-mail-Message-core position-relative d-flex flex-shrink-0">
                    <div class="o-mail-Message-sidebar d-flex flex-shrink-0" t-att-class="{ 'justify-content-end': isAlignedRight and !props.squashed, 'align-items-center justify-content-center': props.squashed }">
                        <div t-if="!props.squashed" class="o-mail-Message-avatarContainer position-relative bg-view">
                            <img class="o-mail-Message-avatar w-100 h-100 rounded" t-att-src="authorAvatarUrl" t-att-class="authorAvatarAttClass"/>
                        </div>
                        <t t-elif="!message.is_transient">
                            <small t-if="isActive and props.showDates" class="o-mail-Message-date text-muted opacity-75">
                                <t t-esc="messageService.dateSimple(message)"/>
                            </small>
                            <div t-else="">
                                <MessageSeenIndicator t-if="props.message.isSelfAuthored and props.thread" message="props.message" thread="props.thread"/>
                            </div>
                        </t>
                    </div>
                    <div t-if="props.isTypingMessage">
                <img height="30" t-att-src="url('/im_livechat/static/src/img/chatbot_is_typing.gif')"/>
            </div>
            <t t-else=""><div class="w-100 o-min-width-0" t-att-class="{ 'flex-grow-1': message.composer }" t-ref="messageContent">
                        <div t-if="!props.squashed" class="o-mail-Message-header d-flex flex-wrap align-items-baseline mb-1 lh-1">
                            <span t-if="(message.author or message.email_from) and shouldDisplayAuthorName" class="o-mail-Message-author">
                                <strong class="me-1"><t t-if="message.author" t-esc="message.author.name"/><t t-else="" t-esc="message.email_from"/></strong>
                            </span>
                            <t t-if="!isAlignedRight" t-call="mail.Message.notification"/>
                            <small t-if="!message.is_transient" class="o-mail-Message-date text-muted opacity-75" t-att-class="{ 'me-2': !isAlignedRight }" t-att-title="message.datetimeShort">
                                <t t-if="shouldDisplayAuthorName">- </t>
                                <RelativeTime datetime="message.datetime"/>
                            </small>
                            <MessageSeenIndicator t-if="props.message.isSelfAuthored and !props.squashed and props.thread" className="'ms-1'" message="props.message" thread="props.thread"/>
                            <small t-if="isPersistentMessageFromAnotherThread" t-on-click.prevent="openRecord" class="ms-1 text-500">
                                <t t-if="message.model !== 'discuss.channel'">
                                    on <a t-att-href="message.resUrl"><t t-esc="message.originThread?.displayName"/></a>
                                </t>
                                <t t-if="message.model === 'discuss.channel'">
                                    (from <a t-att-href="message.resUrl"><t t-esc="message.originThread?.prefix"/><t t-esc="message.originThread?.displayName"/></a>)
                                </t>
                            </small>
                            <div t-if="props.message.scheduledDate" t-att-class="{ 'ms-2': (props.isInChatWindow and isAlignedRight) or (isPersistentMessageFromAnotherThread) }" t-att-title="messageService.scheduledDateSimple(props.message)">
                                <span class="text-600 cursor-pointer">
                                    <i class="fa fa-calendar-o"/>
                                </span>
                            </div>
                            <t t-if="isAlignedRight" t-call="mail.Message.notification"/>
                        </div>
                        <div class="position-relative d-flex" t-att-class="{                                    'justify-content-end': isAlignedRight,                                    'ps-4': env.inChatWindow and isAlignedRight and !state.isEditing,                                    'ps-2': env.inChatWindow and isAlignedRight and state.isEditing,                                    'pe-4': env.inChatWindow and !isAlignedRight and !state.isEditing and !env.messageCard,                                    'pe-2': env.inChatWindow and !isAlignedRight and composerViewInEditing,                                    }">
                            <div class="o-mail-Message-content o-min-width-0" t-att-class="{ 'w-100': state.isEditing }">
                                <div class="o-mail-Message-textContent position-relative d-flex" t-att-class="{ 'w-100': state.isEditing }">
                                    <t t-if="message.type !== 'notification' and !message.is_transient and (message.hasTextContent or message.subtype_description or state.isEditing)">
                                        <LinkPreviewList t-if="!state.isEditing and message.linkPreviewSquash" linkPreviews="message.linkPreviews" deletable="false"/>
                                        <t t-else="">
                                            <div class="position-relative overflow-x-auto d-inline-block" t-att-class="{ 'w-100': state.isEditing }">
                                                <div class="o-mail-Message-bubble rounded-bottom-3 position-absolute top-0 start-0 w-100 h-100" t-att-class="{                                                     'border': state.isEditing and !message.is_note,                                                     'bg-info-light border border-info opacity-25': !message.isSelfAuthored and !message.is_note and !message.isHighlightedFromMention,                                                     'bg-success-light border border-success opacity-25': message.isSelfAuthored and !message.is_note and !message.isHighlightedFromMention,                                                     'bg-warning-light border border-warning opacity-50': message.isHighlightedFromMention,                                                     }" t-attf-class="{{ isAlignedRight ? 'rounded-start-3' : 'rounded-end-3' }}"/>
                                                <div class="position-relative text-break o-mail-Message-body" t-att-class="{                                                             'p-1': message.is_note,                                                             'mb-0 py-2 px-3': !message.is_note,                                                             'align-self-start rounded-end-3 rounded-bottom-3': !state.isEditing and !message.is_note,                                                             'o-mail-Message-editable flex-grow-1': state.isEditing,                                                             }" t-ref="body">
                                                    <Composer t-if="state.isEditing" autofocus="true" composer="message.composer" messageComponent="constructor" onDiscardCallback.bind="exitEditMode" onPostCallback.bind="exitEditMode" mode="env.inChatter ? 'extended' : 'compact'" sidebar="false"/>
                                                    <t t-else="">
                                                        <em t-if="message.subject and !message.isSubjectSimilarToOriginThreadName and !message.isSubjectDefault" class="mb-1 me-2">Subject: <t t-out="props.messageSearch?.highlight(message.subject) ?? message.subject"/></em>
                                                        <div class="overflow-x-auto" t-if="message.type and message.type.includes('email')" t-ref="shadowBody"/>
                                                        <t t-elif="state.showTranslation" t-out="message.translationValue"/>
                                                        <t t-elif="message.body" t-out="props.messageSearch?.highlight(message.body) ?? message.body"/>
                                                        <p class="fst-italic text-muted small" t-if="state.showTranslation">
                                                            <t t-if="message.translationSource" t-esc="translatedFromText"/>
                                                        </p>
                                                        <p class="fst-italic text-muted small" t-if="message.translationErrors">
                                                            <i class="text-danger fa fa-warning" role="img" aria-label="Translation Failure"/>
                                                            <t t-if="message.translationErrors" t-esc="translationFailureText"/>
                                                        </p>

                                                        <t t-if="showSubtypeDescription" t-out="props.messageSearch?.highlight(message.subtype_description) ?? message.subtype_description"/>
                                                    </t>
            <ul class="p-0 m-0" t-if="props.message.chatbotStep?.expectAnswer">
                <li t-foreach="props.message.chatbotStep?.answers" t-as="answer" t-key="answer.id" t-esc="answer.label" t-on-click="() =&gt; this.answerChatbot(answer)" class="btn btn-outline-primary d-block mt-2 py-2"/>
            </ul>
                                                </div>
                                            </div>
                                        </t>
                                    </t>
                                    <t t-if="message.hasTextContent and !env.inChatWindow" t-call="mail.Message.actions"/>
                                </div>
                                <AttachmentList t-if="message.attachments.length &gt; 0" attachments="message.attachments.map((a) =&gt; a)" unlinkAttachment.bind="onClickAttachmentUnlink" imagesHeight="message.attachments.length === 1 ? 300 : 75" messageSearch="props.messageSearch"/>
                                <LinkPreviewList t-if="message.linkPreviews.length &gt; 0 and store.hasLinkPreviewFeature and !message.linkPreviewSquash" linkPreviews="message.linkPreviews" deletable="deletable"/>
                            </div>
                            <t t-if="!message.hasTextContent or env.inChatWindow" t-call="mail.Message.actions"/>
                        </div>
                        <MessageReactions message="message" openReactionMenu="openReactionMenu" t-if="message.reactions.length"/>
                    </div>
                </t>
        </div>
            </div>
        </ActionSwiper>
    </t>

<t t-name="mail.Message.actions">
    <div t-if="props.hasActions and message.hasActions and !state.isEditing" class="o-mail-Message-actions" t-att-class="{             'start-0 ms-3': isAlignedRight,             'end-0 me-3': (env.inChatWindow or ui.isSmall) and !isAlignedRight,             'position-absolute top-0 mt-n3': env.inChatWindow or ui.isSmall,             'ms-2 mt-1': !env.inChatWindow and !ui.isSmall,             'invisible': !isActive,             'o-expanded': state.expandOptions         }">
        <div class="d-flex rounded-1 bg-view shadow-sm overflow-hidden" t-att-class="{                 'flex-row-reverse': env.inChatWindow and isAlignedRight,             }">
            <t t-foreach="messageActions.actions.slice(0, quickActionCount)" t-as="action" t-key="action.id">
                <t t-if="action.callComponent" t-component="action.callComponent" t-props="action.props"/>
                <button t-else="" class="btn px-1 py-0 rounded-0" t-att-title="action.title" t-att-name="action.id" t-on-click.stop="action.onClick">
                    <i class="fa fa-lg" t-att-class="action.icon"/>
                </button>
            </t>
            <Dropdown t-if="messageActions.actions.length gt quickActionCount" onStateChanged="state =&gt; this.state.expandOptions = state.open" position="props.message.eq(props.thread?.newestMessage)  ? 'top-start' : 'bottom-start'" togglerClass="\`btn p-0 rounded-0 \${ state.expandOptions ? 'bg-200' : '' }\`" menuClass="'d-flex flex-column py-0 o-mail-Message-moreMenu'" class="'d-flex rounded-0'" title="expandText">
                <t t-set-slot="toggler">
                    <i class="btn px-1 py-0 fa fa-lg fa-ellipsis-h rounded-0" t-att-class="{ 'order-1': props.isInChatWindow }" tabindex="1"/>
                </t>
                <t t-set-slot="default">
                    <t t-foreach="messageActions.actions.slice(quickActionCount)" t-as="action" t-key="action.id">
                        <DropdownItem class="'px-2 d-flex align-items-center rounded-0'" title="action.title" onSelected="action.onClick">
                            <i class="fa fa-lg fa-fw pe-2" t-att-class="action.icon"/>
                            <t t-esc="action.title"/>
                        </DropdownItem>
                    </t>
                </t>
            </Dropdown>
        </div>
    </div>
</t>

<t t-name="mail.Message.notification">
    <div t-if="message.originThread?.eq(props.thread) and message.notifications.length &gt; 0" class="mx-1">
        <span class="o-mail-Message-notification cursor-pointer" t-att-class="message.failureNotifications.length &gt; 0 ? 'text-danger' : text-600" role="button" tabindex="0" t-on-click="onClickNotification">
            <i t-att-class="message.notifications[0].icon" role="img" aria-label="Delivery failure"/> <span t-if="message.notifications[0].label" t-out="message.notifications[0].label"/>
        </span>
    </div>
</t>

<t t-name="mail.MessageCardList">
        <div class="o-mail-MessageCardList d-flex flex-column" t-att-class="{ 'justify-content-center flex-grow-1': props.messages.length === 0 }" t-ref="message-list">
            <div class="card mb-2" t-foreach="props.messages" t-as="message" t-key="message.id">
                <div class="card-body py-2">
                    <div class="d-flex justify-content-end position-absolute top-0 end-0 o-z-index-1 m-2">
                        <button class="o-mail-MessageCard-jump btn rounded bg-400 badge opacity-0 flex-shrink-0" t-att-class="{ 'opacity-100 py-1 px-2': ui.isSmall }" t-on-click="() =&gt; this.onClickJump(message)">Jump</button>
                        <button t-if="props.mode === 'pin'" class="btn ms-2 p-0 text-700 shadow-none" t-att-class="{ 'fs-5 align-self-end': ui.isSmall }" title="Unpin" t-on-click="() =&gt; this.props.onClickUnpin(message)">
                            <i class="d-block fa fa-times"/>
                        </button>
                    </div>
                    <Message hasActions="false" message="message" thread="props.thread" messageSearch="props.messageSearch"/>
                </div>
            </div>
            <span t-if="props.loadMore" t-ref="load-more"/>
            <p t-if="props.showEmpty !== undefined ? props.showEmpty : props.messages.length === 0" t-esc="emptyText" class="text-center fst-italic text-500 fs-6"/>
        </div>
    </t>

<t t-name="mail.MessageConfirmDialog">
    <Dialog size="props.size" title="props.title">
        <p class="mx-3 mb-3" t-esc="props.prompt"/>
        <blockquote class="mx-3 mb-3 fst-normal" style="pointer-events:none;">
            <t t-component="props.messageComponent" message="props.message" hasActions="false"/>
        </blockquote>
        <t t-set-slot="footer">
            <button class="btn me-2" t-att-class="props.confirmColor" t-on-click="onClickConfirm" t-out="props.confirmText"/>
            <button class="btn btn-secondary me-2" t-on-click="props.close">Cancel</button>
        </t>
    </Dialog>
</t>

<t t-name="mail.MessageInReply">
        <t t-set="message" t-value="props.message"/>
        <div class="o-mail-MessageInReply" t-att-class="{                 'me-5': store.discuss.isActive or (env.inChatWindow and !props.alignedRight),                 'd-flex justify-content-end ms-5': env.inChatWindow and props.alignedRight,             }">
            <small class="position-relative d-block text-small mb-1" t-attf-class="{{ env.inChatWindow and props.alignedRight ? 'justify-content-end pe-5': 'ps-5' }}">
                <span class="o-mail-MessageInReply-corner position-absolute bottom-0 top-50 pe-4 border-top text-300" t-attf-class="{{ env.inChatWindow and props.alignedRight ? 'o-isRightAlign border-end' : 'o-isLeftAlign border-start' }}" t-att-class="{ 'ms-n2': store.discuss.isActive }"/>
                <span t-if="!message.parentMessage.isEmpty" class="d-inline-flex align-items-center text-muted opacity-75" t-att-class="{ 'cursor-pointer opacity-100-hover': props.onClick }" t-on-click="() =&gt; this.props.onClick?.()">
                    <img class="o-mail-MessageInReply-avatar me-2 rounded" t-att-src="authorAvatarUrl" t-att-title="message.parentMessage.author?.name ?? message.parentMessage.email_from" alt="Avatar"/>
                    <span class="o-mail-MessageInReply-content overflow-hidden">
                        <b>@<t t-out="message.parentMessage.author?.name ?? message.parentMessage.email_from"/></b>:
                        <br t-if="env.inChatWindow and !props.alignedRight"/>
                        <span class="o-mail-MessageInReply-message ms-1 text-break">
                            <t t-if="!message.parentMessage.isBodyEmpty">
                                <t t-out="message.parentMessage.body"/>
                            </t>
                            <t t-elif="message.parentMessage.attachments.length &gt; 0">
                                <span class="me-2 fst-italic">Click to see the attachments</span>
                                <i class="fa fa-image"/>
                            </t>
                        </span>
                    </span>
                </span>
                <i t-else="" class="text-muted ms-2">Original message was deleted</i>
            </small>
        </div>
    </t>
<t t-name="mail.MessageNotificationPopover">
        <div class="o-mail-MessageNotificationPopover m-2">
            <div t-foreach="props.message.notifications" t-as="notification" t-key="notification.id">
                <i class="me-2" t-att-class="notification.statusIcon" t-att-title="notification.statusTitle" role="img"/>
                <span t-if="notification.persona" t-esc="notification.persona.nameOrDisplayName"/>
            </div>
        </div>
    </t>

<t t-name="mail.MessageReactionButton">
        <button class="btn px-1 py-0 rounded-0" tabindex="1" title="Add a Reaction" aria-label="Add a Reaction" t-ref="emoji-picker"><i class="oi fa-lg oi-smile-add"/></button>
    </t>

<t t-name="mail.MessageReactionMenu">
        <Dialog size="'md'" header="false" footer="false" contentClass="'o-mail-MessageReactionMenu h-50 d-flex'">
            <div class="d-flex h-100" t-on-keydown="onKeydown" t-ref="root">
                <div class="d-flex overflow-auto flex-column bg-100 p-2 h-100 border-end">
                    <t t-foreach="props.message.reactions" t-as="reaction" t-key="reaction.content">
                        <button class="btn p-1 rounded-2 mx-2 py-0 d-flex align-items-center" t-att-class="{ 'bg-200 border-primary': reaction.eq(state.reaction) }" t-att-title="getEmojiShortcode(reaction)" t-on-click="() =&gt; state.reaction = reaction">
                            <span class="mx-1 fs-2" t-esc="reaction.content"/>
                            <span class="mx-1 pe-2" t-att-class="{ 'text-primary': reaction.eq(state.reaction) }" t-esc="reaction.count"/>
                        </button>
                    </t>
                </div>
                <div class="d-flex overflow-auto flex-column flex-grow-1 bg-view p-2 h-100">
                    <div t-foreach="state.reaction.personas" t-as="persona" t-key="persona.id" class="o-mail-MessageReactionMenu-persona d-flex p-1 align-items-center" t-att-class="{ 'o-isDeviceSmall': ui.isSmall }">
                        <img class="rounded o_object_fit_cover o-mail-MessageReactionMenu-avatar" t-att-src="threadService.avatarUrl(persona, props.message.originThread)"/>
                        <span class="d-flex flex-grow-1 align-items-center">
                            <span class="mx-2 text-truncate fs-6" t-esc="persona.name"/>
                            <div class="flex-grow-1"/>
                            <button t-if="persona.eq(store.self)" class="btn btn-light fa fa-trash rounded-pill bg-inherit border-0" title="Remove" t-on-click.stop="() =&gt; this.messageService.removeReaction(state.reaction)"/>
                        </span>
                    </div>
                </div>
            </div>
        </Dialog>
    </t>

<t t-name="mail.MessageReactions">
    <div class="position-relative d-flex flex-wrap" t-att-class="{             'flex-row-reverse me-3': env.inChatWindow and env.alignedRight,             'ms-3': !(env.inChatWindow and env.alignedRight) and (props.message.is_discussion),         }" t-attf-class="{{ props.message.is_discussion ? 'mt-n2' : 'mt-1' }}">
        <button t-foreach="props.message.reactions" t-as="reaction" t-key="reaction.content" class="o-mail-MessageReaction btn d-flex p-0 border rounded-1 mb-1" t-on-click="() =&gt; this.onClickReaction(reaction)" t-on-contextmenu="onContextMenu" t-att-class="{                 'o-selfReacted border-primary text-primary fw-bolder': hasSelfReacted(reaction),                 'bg-view': !hasSelfReacted(reaction),                 'ms-1': env.inChatWindow and env.alignedRight,                 'me-1': !(env.inChatWindow and env.alignedRight),          }" t-att-title="getReactionSummary(reaction)">
            <span class="mx-1" t-esc="reaction.content"/>
            <span class="mx-1" t-esc="reaction.count"/>
        </button>
    </div>
</t>
<t t-name="mail.MessageSeenIndicator">
        <span class="o-mail-MessageSeenIndicator position-relative d-flex opacity-50" t-att-class="{ 'o-all-seen text-primary': hasEveryoneSeen }" t-attf-class="{{ props.className }}">
            <t t-if="!isMessagePreviousToLastSelfMessageSeenByEveryone">
                <i t-if="hasSomeoneFetched or hasSomeoneSeen" class="fa fa-check ps-1"/>
                <i t-if="hasSomeoneSeen" class="o-second fa fa-check position-absolute"/>
            </t>
        </span>
    </t>
<t t-name="mail.NavigableList">
        <div class="o-mail-NavigableList bg-view m-0 p-0" t-ref="root" t-att-class="props.class">
            <div t-if="show" class="o-open border" t-on-mousedown.prevent="">
                <div t-if="props.isLoading" class="o-mail-NavigableList-item">
                    <a href="#" class="d-flex align-items-center w-100 py-2 px-4 gap-1">
                        <i class="fa fa-spin fa-circle-o-notch"/>
                        <t t-esc="props.placeholder"/>
                    </a>
                </div>
                <t t-else="">
                    <div t-foreach="props.options" t-as="option" t-key="option_index" class="o-mail-NavigableList-item" t-att-class="option.classList" t-on-mouseenter="() =&gt; this.onOptionMouseEnter(option_index)" t-on-click="(ev) =&gt; this.selectOption(ev, option_index)">
                        <a href="#" class="d-flex align-items-center w-100 py-2 px-4" t-att-class="{ 'o-mail-NavigableList-active bg-300': state.activeIndex === option_index }">
                            <t t-if="props.optionTemplate" t-call="{{ props.optionTemplate }}"/>
                            <t t-else="" t-esc="option.label"/>
                        </a>
                    </div>
                </t>
            </div>
        </div>
    </t>

<t t-name="mail.Picker">
    <div t-if="ui.isSmall" class="o-mail-Picker d-flex flex-column w-100" t-att-class="{'d-none': props.state.picker === props.PICKERS.NONE}">
        <PickerContent t-props="contentProps"/>
    </div>
</t>

<t t-name="mail.PickerContent">
    <div class="o-mail-PickerContent d-flex flex-column flex-grow-1 o-min-height-0" t-on-click="onClick">
        <div class="o-mail-PickerContent-picker d-flex flex-grow-1 rounded overflow-auto">
            <div t-if="props.state.picker === props.PICKERS.EMOJI" class="o-mail-PickerContent-emojiPicker d-flex flex-grow-1 mw-100">
                <EmojiPicker close="props.close" onSelect="props.pickers.emoji" state="props.state" storeScroll="props.storeScroll"/>
            </div>
        </div>
    </div>
</t>

<t t-name="mail.SearchMessagesPanel">
        <ActionPanel title="env.inChatter ? undefined : title">
            <div class="d-flex pb-2">
                <div class="input-group">
                    <div class="o_searchview form-control d-flex align-items-center py-1" role="search" aria-autocomplete="list">
                        <div class="o_searchview_input_container d-flex flex-grow-1 flex-wrap gap-1">
                            <input type="text" class="o_searchview_input flex-grow-1 w-auto border-0" accesskey="Q" placeholder="Search" t-model="state.searchTerm" t-on-keydown="onKeydownSearch" t-ref="autofocus" role="searchbox"/>
                        </div>
                    </div>
                    <button class="btn" t-att-class="state.searchedTerm === state.searchTerm ? 'btn-outline-primary' : 'btn-primary'" t-on-click="() =&gt; this.search()" aria-label="Search button">
                        <i t-if="!messageSearch.searching" class="o_searchview_icon oi oi-search" role="img" aria-label="Search Messages" title="Search Messages"/>
                        <i t-else="" class="fa fa-spin fa-spinner" aria-label="Search in progress" title="Search in progress"/>
                    </button>
                </div>
                <button t-if="env.inChatter" class="btn btn-outline-secondary ms-3" t-on-click="() =&gt; this.clear()" aria-label="Close button">
                    <i class="o_searchview_icon oi oi-close cursor-pointer" role="img" aria-label="Close search" title="close"/>
                </button>
            </div>
            <p t-if="MESSAGES_FOUND" class="o-mail-SearchMessagesPanel-title py-1 mb-0 fw-bolder text-center text-uppercase text-700">
                <t t-out="MESSAGES_FOUND"/>
            </p>
            <MessageCardList messages="messageSearch.messages" thread="props.thread" mode="'search'" messageSearch="messageSearch" showEmpty="messageSearch.messages.length === 0 and messageSearch.searched" onClickJump="() =&gt; this.props.onClickJump?.()" loadMore="messageSearch.loadMore" onLoadMoreVisible="onLoadMoreVisible"/>
        </ActionPanel>
    </t>

<t t-name="mail.Thread">
    <t t-if="env.inChatter" t-call="mail.Thread.jumpPresent"/> 
    <div class="o-mail-Thread position-relative flex-grow-1 d-flex flex-column overflow-auto" t-att-class="{ 'pb-4':  props.showJumpPresent and !state.showJumpPresent }" t-ref="messages" tabindex="-1">
            <div t-if="props.thread?.livechatWelcomeMessage" class="bg-100 py-3">
                <Message message="props.thread.livechatWelcomeMessage" hasActions="false" thread="props.thread"/>
            </div>
        <t t-if="!props.thread.isEmpty or props.thread.loadOlder or props.thread.hasLoadingFailed" name="content">
            <div class="d-flex flex-column position-relative flex-grow-1" t-att-class="{'justify-content-end': !env.inChatter and props.thread.type !== 'mailbox'}">
                <span class="position-absolute w-100 invisible" t-att-class="props.order === 'asc' ? 'bottom-0' : 'top-0'" t-ref="present-treshold" t-att-style="\`height: Min(\${PRESENT_THRESHOLD}px, 100%)\`"/>
                <t t-set="currentDay" t-value="0"/>
                <t t-set="prevMsg" t-value="0"/>
                <t t-set="separatorDisplayed" t-value="false"/>
                <t t-if="props.order === 'asc'">
                    <t t-if="props.thread.loadOlder and !props.thread.isTransient and !props.thread.hasLoadingFailed" t-call="mail.Thread.loadOlder"/>
                    <t t-if="props.thread.hasLoadingFailed" t-call="mail.Thread.loadingError"/>
                </t>
                <t t-else="">
                    <span t-ref="load-newer"/>
                    <t t-if="!env.inChatter" t-call="mail.Thread.jumpPresent"/>
                </t>
                <t t-if="state.mountedAndLoaded" t-foreach="props.order === 'asc' ? props.thread.nonEmptyMessages : [...props.thread.nonEmptyMessages].reverse()" t-as="msg" t-key="msg.id">
                    <t t-if="msg.dateDay !== currentDay and props.showDates">
                        <DateSection date="msg.dateDay" className="'pt-4'"/>
                        <t t-set="currentDay" t-value="msg.dateDay"/>
                    </t>
                    <t t-if="props.thread.model === 'discuss.channel'">
                        <t t-set="showSeparator" t-value="(msg.id &gt; props.thread.seen_message_id and !separatorDisplayed)"/>
                        <t t-if="showSeparator">
                            <t t-set="separatorDisplayed" t-value="true"/>
                        </t>
                        <Transition visible="showSeparator" name="'o-fade'" t-slot-scope="transition">
                            <t t-if="!chatbotService.active"><div class="o-mail-Thread-newMessage d-flex align-items-center fw-bolder" t-att-class="{ 'opacity-0': transition.className.includes('o-fade-leave') }">
                                <hr class="ms-2 flex-grow-1 border border-danger opacity-50"/><span class="px-2 text-danger">New messages</span><hr class="me-2 flex-grow-1 border border-danger opacity-50"/>
                            </div>
                        </t>
        </Transition>
                    </t>
                    <t t-if="msg.isNotification">
                        <t t-call="mail.NotificationMessage"/>
                    </t>
                    <Message t-else="" isInChatWindow="props.isInChatWindow" message="msg" messageToReplyTo="props.messageToReplyTo" squashed="isSquashed(msg, prevMsg)" highlighted="messageHighlight?.highlightedMessageId === msg.id" onParentMessageClick="() =&gt; msg.parentMessage and env.messageHighlight?.highlightMessage(msg.parentMessage, props.thread)" thread="props.thread" messageEdition="props.messageEdition" isFirstMessage="msg_first" hasActions="props.messageActions" showDates="props.showDates"/>
                    <t t-set="prevMsg" t-value="msg"/>
                </t>
                <t t-if="props.order === 'asc'">
                    <span t-ref="load-newer"/>
                    <t t-call="mail.Thread.jumpPresent"/>
                </t>
                <t t-else="">
                    <t t-if="props.thread.loadOlder and !props.thread.isTransient and !props.thread.hasLoadingFailed" t-call="mail.Thread.loadOlder"/>
                    <t t-if="props.thread.hasLoadingFailed" t-call="mail.Thread.loadingError"/>
                </t>
            </div>
        </t>
            <Message t-if="chatbotService.isTyping" message="props.thread.chatbotTypingMessage" hasActions="false" isInChatWindow="env.inChatWindow" isTypingMessage="true" thread="props.thread"/>
        <t t-else="">
            <t t-if="props.thread.type !== 'livechat'"><div class="o-mail-Thread-empty d-flex flex-column align-items-center justify-content-center text-muted fst-italic h-100" t-att-class="{'p-4': props.showEmptyMessage}">
                <t t-if="props.thread.isLoaded">
                    <t t-if="props.thread.isEmpty and props.thread.type === 'mailbox'">
                    <t t-if="props.thread.id === 'inbox'">
                        <h4 class="mb-3 fw-bolder">
                            Congratulations, your inbox is empty
                        </h4>
                        New messages appear here.
                    </t>
                    <t t-if="props.thread.id === 'starred'">
                        <h4 class="mb-3 fw-bolder">
                            No starred messages
                        </h4>
                        You can mark any message as 'starred', and it shows up in this mailbox.
                    </t>
                    <t t-if="props.thread.id === 'history'">
                        <img src="/web/static/img/neutral_face.svg" alt="History"/>
                        <h4 class="mb-3 fw-bolder">
                            No history messages
                        </h4>
                        Messages marked as read will appear in the history.
                    </t>
                    </t>
                    <t t-elif="props.showEmptyMessage">
                        There are no messages in this conversation.
                    </t>
                </t>
            </div>
        </t>
        </t>
    </div>
</t>

<t t-name="mail.Thread.jumpPresent">
    <span t-if="props.showJumpPresent and state.showJumpPresent" class="o-mail-Thread-jumpPresent position-sticky btn btn-link alert alert-info d-flex cursor-pointer align-items-center py-2 m-0" t-att-class="{ 'px-4': !env.inChatWindow, 'px-2': env.inChatWindow, 'top-0': props.order !== 'asc', 'bottom-0': props.order === 'asc' }" role="button" t-on-click="() =&gt; this.jumpToPresent()">
        <span class="small">You're viewing older messages</span>
        <span class="flex-grow-1"/>
        <span class="fw-bolder small pe-2">Jump to Present</span>
        <i class="fa" t-att-class="{ 'fa-caret-up': props.order !== 'asc', 'fa-caret-down': props.order === 'asc' }"/>
    </span>
</t>

<t t-name="mail.Thread.loadOlder">
    <button class="btn btn-link" t-on-click="onClickLoadOlder" t-ref="load-older">Load More</button>
</t>

<t t-name="mail.Thread.loadingError">
    <div class="d-flex flex-grow-1 align-items-center justify-content-center flex-column">
        <div class="o-mail-Thread-error">
            An error occurred while fetching messages.
        </div>
        <button class="btn btn-link" t-on-click="onClickLoadOlder">
            Click here to retry
        </button>
    </div>
</t>

<t t-name="mail.NotificationMessage">
    <div class="o-mail-NotificationMessage text-break mx-auto text-500 small px-3 text-center" t-on-click="onClickNotification" t-att-class="{         'mt-2': prevMsg and !prevMsg.isNotification,     }" t-ref="root" t-attf-class="{{ props.thread.type === 'livechat' ? 'o-livechat-NoPinMenu' : '' }}">
        <i t-if="msg.notificationIcon" t-attf-class="{{ msg.notificationIcon }} me-1"/>
        <span class="o-mail-NotificationMessage-author d-inline" t-if="msg.author and !msg.body.includes(escape(msg.author.name))" t-esc="msg.author.name"/> <t t-out="msg.body"/>
    </div>
</t>

<t t-name="mail.ThreadIcon">
        <div class="o-mail-ThreadIcon d-flex justify-content-center flex-shrink-0" t-att-class="props.className">
            <t t-if="props.thread.type === 'channel'">
                <div t-if="props.thread.authorizedGroupFullName" class="fa fa-fw fa-hashtag" t-att-title="props.thread.accessRestrictedToGroupText"/>
                <div t-if="!props.thread.authorizedGroupFullName" class="fa fa-fw fa-globe" title="Public Channel"/>
            </t>
            <t t-elif="props.thread.type === 'chat' and chatPartner">
                <Typing t-if="typingService.hasTypingMembers(props.thread)" channel="props.thread" size="props.size" displayText="false"/>
            <t t-else=""><t name="chat">
                    <t name="chat_static">
                        <div t-if="chatPartner.im_status === 'online'" class="fa fa-fw fa-circle text-success" title="Online"/>
                        <div t-elif="chatPartner.im_status === 'offline'" class="fa fa-fw fa-circle-o" title="Offline"/>
                        <div t-elif="chatPartner.im_status === 'away'" class="fa fa-fw fa-circle o-yellow" title="Away"/>
                        <div t-elif="chatPartner.im_status === 'bot'" class="fa fa-fw fa-heart text-success" title="Bot"/>
                        <div t-else="" class="fa fa-fw fa-question-circle" title="No IM status available"/>
                    </t>
                </t>
            </t>
        </t>
            <div t-elif="props.thread.type === 'group'" class="o-mail-ThreadIcon fa fa-fw fa-users" title="Grouped Chat"/>
            <t t-elif="props.thread.type === 'mailbox'">
                <div t-if="props.thread.id === 'inbox'" class="fa fa-fw fa-inbox" title="Inbox"/>
                <div t-elif="props.thread.id === 'starred'" class="fa fa-fw fa-star-o" title="Favorites"/>
                <div t-elif="props.thread.id === 'history'" class="fa fa-fw fa-history" title="History"/>
            </t>
        </div>
    </t>

<t t-name="mail.ActionPanel">
        <div class="o-mail-ActionPanel overflow-auto d-flex flex-column flex-shrink-0 position-relative p-3 pt-0 h-100" t-att-class="{ 'bg-view': !env.inChatter }">
            <div class="o-mail-ActionPanel-header position-sticky top-0 py-3 d-flex align-items-baseline" t-att-class="{ 'bg-view': !env.inChatter }">
                <button t-if="env.closeActionPanel" class="o-mail-ActionPanel-backButton btn opacity-75 opacity-100-hover ps-0 py-0 fs-5" title="Close panel" t-on-click.stop="env.closeActionPanel">
                    <i class="oi oi-arrow-left"/>
                </button>
                <p t-if="props.title" class="fs-6 fw-bold text-uppercase m-0 text-700 flex-grow-1" t-esc="props.title"/>
            </div>
            <t t-slot="default"/>
        </div>
    </t>

<t t-name="mail.AttachmentPanel">
        <t t-set="title">Attachments</t>
        <ActionPanel title="title">
            <div t-if="hasToggleAllowPublicUpload" class="form-check form-switch">
                <label class="form-check-label">
                    <input t-on-change="toggleAllowPublicUpload" class="form-check-input" type="checkbox" role="switch" t-att-checked="props.thread.allow_public_upload"/>
                    <t t-if="props.thread.allow_public_upload">File upload is enabled for external users</t>
                    <t t-else="">File upload is disabled for external users</t>
                </label>
            </div>
            <div class="flex-grow-1" t-att-class="{                 'd-flex justify-content-center align-items-center': props.thread.attachments.length === 0,             }">
                <p t-if="props.thread.attachments.length === 0" class="text-center fst-italic text-500">
                    <t t-if="props.thread.type === 'channel'">This channel doesn't have any attachments.</t>
                    <t t-else="">This conversation doesn't have any attachments.</t>
                </p>
                <div t-else="" t-foreach="attachmentsByDate" t-as="dateDay" t-key="dateDay" class="d-flex flex-column">
                    <DateSection date="dateDay" className="'my-1'"/>
                    <AttachmentList imagesHeight="100" attachments="dateDay_value" unlinkAttachment="(attachment) =&gt; this.attachmentUploadService.unlink(attachment)"/>
                </div>
            </div>
            <span t-ref="load-older"/>
        </ActionPanel>
    </t>
<t t-name="discuss.ChannelInvitation">
        <ActionPanel title="title">
            <div t-att-class="{ 'o-discuss-ChannelInvitation-has-size-constraints': props.hasSizeConstraints }">
                <t t-if="store.user">
                    <input class="o-discuss-ChannelInvitation-search border form-control" t-ref="input" placeholder="Type the name of a person" t-on-input="onInput"/>
                    <div class="d-flex flex-column mx-0 py-2 overflow-auto">
                        <t t-foreach="state.selectablePartners" t-as="selectablePartner" t-key="selectablePartner.id">
                            <div class="o-discuss-ChannelInvitation-selectable o_object_fit_cover d-flex align-items-center px-3 py-1 btn" t-on-click="() =&gt; this.onClickSelectablePartner(selectablePartner)">
                                <div class="d-flex align-items-center p-2">
                                    <div class="o-discuss-ChannelInvitation-avatar position-relative d-flex flex-shrink-0">
                                        <img class="w-100 h-100 rounded o_object_fit_cover" t-att-src="threadService.avatarUrl(selectablePartner, props.thread)"/>
                                        <ImStatus persona="selectablePartner" className="'position-absolute top-100 start-100 translate-middle bg-view mt-n1 ms-n1'"/>
                                    </div>
                                </div>
                                <t name="selectablePartnerDetail">
                                    <span class="flex-grow-1 mx-2 text-truncate text-start fs-6" t-esc="selectablePartner.name"/>
                                </t>
                                <input class="form-check-input flex-shrink-0" type="checkbox" t-att-checked="selectablePartner.in(state.selectedPartners) ? 'checked' : undefined"/>
                            </div>
                        </t>
                        <div t-if="state.selectablePartners.length === 0">No user found that is not already a member of this channel.</div>
                        <div t-if="state.searchResultCount &gt; state.selectablePartners.length">
                            Showing
                            <t t-esc="state.selectablePartners.length"/>
                            results out of
                            <t t-esc="state.searchResultCount"/>
                            . Narrow your search to see more choices.
                        </div>
                    </div>
                    <div t-if="state.selectedPartners.length &gt; 0" class="mt-3">
                        <h4>Selected users:</h4>
                        <div class="o-discuss-ChannelInvitation-selectedList d-flex flex-wrap gap-1 overflow-auto">
                            <t t-foreach="state.selectedPartners" t-as="selectedPartner" t-key="selectedPartner.id">
                                <button class="btn btn-secondary" t-on-click="() =&gt; this.onClickSelectedPartner(selectedPartner)">
                                    <t t-esc="selectedPartner.name"/> <i class="fa fa-times"/>
                                </button>
                            </t>
                        </div>
                    </div>
                    <div class="mt-2">
                        <button class="btn btn-primary w-100" t-att-disabled="this.state.selectedPartners.length === 0" t-att-title="invitationButtonText" t-on-click="onClickInvite">
                            <t t-esc="invitationButtonText"/>
                        </button>
                    </div>
                </t>
                <div t-if="props.thread.invitationLink" class="mt-3">
                    <div class="input-group">
                        <input class="border form-control" type="text" t-att-value="props.thread.invitationLink" readonly="" t-on-focus="onFocusInvitationLinkInput"/>
                        <button class="btn btn-primary" t-on-click="onClickCopy">
                            <i class="fa fa-copy"/>
                        </button>
                    </div>
                    <div t-if="props.thread.accessRestrictedToGroupText" class="mt-2" t-esc="props.thread.accessRestrictedToGroupText"/>
                </div>
            </div>
        </ActionPanel>
    </t>

<t t-name="discuss.ChannelMemberList">
        <ActionPanel title="title">
            <button t-on-click="() =&gt; props.openChannelInvitePanel({ keepPrevious: env.inChatWindow })" class="btn btn-secondary m-3 mt-0">Invite a User</button>
            <t t-if="onlineMembers.length &gt; 0">
                <h6 class="mx-3 text-700">
                    Online -
                    <t t-esc="onlineMembers.length"/>
                </h6>
                <t t-foreach="onlineMembers" t-as="member" t-key="member.id" t-call="discuss.channel_member"/>
            </t>
            <t t-if="offlineMembers.length &gt; 0">
                <h6 class="mx-3 text-700">
                    Offline -
                    <t t-esc="offlineMembers.length"/>
                </h6>
                <t t-foreach="offlineMembers" t-as="member" t-key="member.id" t-call="discuss.channel_member"/>
            </t>
            <span t-if="props.thread.unknownMembersCount === 1" class="mx-2 mt-2">And 1 other member.</span>
            <span t-if="props.thread.unknownMembersCount &gt; 1" class="mx-2 mt-2">And <t t-esc="props.thread.unknownMembersCount"/> other members.</span>
            <div t-if="!props.thread.areAllMembersLoaded" class="mx-2 my-1">
                <button class="btn btn-secondary" title="Load more" t-on-click.stop="() =&gt; threadService.fetchChannelMembers(props.thread)">Load more</button>
            </div>
        </ActionPanel>
    </t>

    <t t-name="discuss.channel_member">
        <div class="o-discuss-ChannelMember d-flex align-items-center p-2 bg-inherit" t-att-class="{ 'cursor-pointer': canOpenChatWith(member) }" t-on-click.stop="() =&gt; this.openChatAvatar(member)">
            <div class="bg-inherit o-discuss-ChannelMember-avatar position-relative d-flex ms-4 flex-shrink-0">
                <img class="w-100 h-100 rounded o_object_fit_cover" t-att-src="threadService.avatarUrl(member.persona, props.thread)"/>
                <ImStatus persona="member.persona" className="'position-absolute top-100 start-100 translate-middle mt-n1 ms-n1'"/>
            </div>
            <span t-ref="displayName" class="ms-2 text-truncate" t-esc="channelMemberService.getName(member)"/>
            <span class="ms-auto">
                <span t-if="member.in(props.thread.invitedMembers)" class="p-1 fa fa-user-plus"/>
                <span t-if="member.rtcSession?.isSelfMuted and !member.rtcSession?.isDeaf" class="p-1 fa fa-microphone-slash"/>
                <span t-elif="member.rtcSession?.isDeaf" class="p-1 fa fa-deaf"/>
                <span t-if="member.rtcSession?.raisingHand" class="p-1 fa fa-hand-paper-o"/>
            </span>

        </div>
    </t>

<t t-name="discuss.NotificationSettings">
        <div class="o-discuss-NotificationSettings">
            <t t-if="props.thread.muteUntilDateTime">
                <button class="btn w-100 d-flex p-1 opacity-75 opacity-100-hover" t-on-click="selectUnmute">
                    <div class="d-flex flex-column flex-grow-1 px-2 py-1 w-100 rounded">
                        <span class="fs-6 fw-bold text-wrap text-start text-break">Unmute Channel</span>
                        <span class="fw-normal o-smaller" t-if="muteUntilText" t-out="muteUntilText"/>
                    </div>
                </button>
            </t>
            <t t-else="">
                <Dropdown position="'right-start'" onStateChanged="state =&gt; {}" togglerClass="\`d-flex btn w-100 align-items-center p-0\`" menuClass="'d-flex flex-column py-0 my-0'" class="'d-flex'">
                    <t t-set-slot="toggler">
                        <button class="btn w-100 d-flex p-1 opacity-75 opacity-100-hover" title="Mute Channel">
                            <div class="d-flex flex-grow-1 align-items-center px-2 py-1 rounded">
                                <span class="text-wrap text-start text-break">Mute Channel</span>
                                <div class="flex-grow-1"/>
                                <i class="ms-2 fa fa-arrow-right"/>
                            </div>
                        </button>
                    </t>
                    <t t-set-slot="default">
                        <t t-foreach="props.thread.MUTES" t-as="item" t-key="item.id">
                            <DropdownItem class="'o-mail-NotificationSettings-muteDuration btn rounded-0 d-flex align-items-center px-2 py-2 m-0 opacity-75 opacity-100-hover'" title="item.name" onSelected="()=&gt;this.setMute(item.value)"><button class="btn p-0 mx-2 text-wrap text-start text-break" t-out="item.name"/></DropdownItem>
                        </t>
                    </t>
                </Dropdown>
            </t>
            <hr class="solid mx-2 my-1"/>
            <t t-foreach="props.thread.SETTINGS" t-as="setting" t-key="setting.id">
                <button class="btn w-100 d-flex px-1 py-0 opacity-75 opacity-100-hover" t-on-click="() =&gt; this.setSetting(setting)">
                    <div class="d-flex flex-grow-1 align-items-center p-2 w-100 rounded">
                        <span class="fs-6 fw-normal text-wrap text-start text-break" t-esc="setting.name"/>
                        <div class="flex-grow-1"/>
                        <input class="form-check-input ms-2" type="radio" t-att-checked="props.thread.custom_notifications === setting.id"/>
                    </div>
                </button>
            </t>
        </div>
    </t>

<t t-name="discuss.Call">
        <div class="o-discuss-Call user-select-none d-flex" t-att-class="{'o-fullscreen fixed-top vw-100 vh-100': state.isFullscreen, 'o-minimized': minimized, 'position-relative': !state.isFullscreen }" t-ref="call">
            <div class="o-discuss-Call-main d-flex flex-grow-1 flex-column align-items-center justify-content-center position-relative overflow-auto" t-on-mouseleave="onMouseleaveMain">
                <div class="o-discuss-Call-mainCards d-flex align-items-center overflow-hidden h-100 w-100 flex-wrap justify-content-center" t-attf-style="--height:{{state.tileHeight}}px; --width:{{state.tileWidth}}px;" t-on-click="() =&gt; this.showOverlay()" t-on-mousemove="onMousemoveMain" t-ref="grid">
                    <CallParticipantCard t-foreach="visibleMainCards" t-as="cardData" t-key="cardData.key" cardData="cardData" className="'o-discuss-Call-mainCardStyle'" minimized="minimized" thread="props.thread"/>
                </div>


                <t t-if="hasSidebarButton">
                    <i t-if="state.sidebar" class="o-discuss-Call-sidebarToggler p-2 fs-5 cursor-pointer position-absolute oi oi-arrow-right" title="Hide sidebar" t-on-click="() =&gt; this.state.sidebar = false"/>
                    <i t-else="" class="o-discuss-Call-sidebarToggler p-2 fs-5 cursor-pointer position-absolute oi oi-arrow-left" title="Show sidebar" t-on-click="() =&gt; this.state.sidebar = true"/>
                </t>
                <div t-if="state.overlay or !isControllerFloating" class="o-discuss-Call-overlay d-flex justify-content-center w-100 pb-1" t-att-class="{ 'o-isFloating position-absolute bottom-0 pb-3': isControllerFloating }">
                    <div t-on-mousemove="onMousemoveOverlay">
                        <CallActionList thread="props.thread" compact="props.compact" fullscreen="{ isActive: state.isFullscreen, enter: () =&gt; this.enterFullScreen(), exit: () =&gt; this.exitFullScreen() }"/>
                    </div>
                </div>
                <div t-if="hasCallNotifications" class="position-absolute d-flex flex-column-reverse start-0 bottom-0" t-att-class="{ 'ps-5 pb-5': state.isFullscreen, 'ps-2 pb-2': !state.isFullscreen }">
                    <span class="text-bg-800 shadow-lg rounded-1 m-1" t-att-class="{ 'p-4 fs-4': state.isFullscreen, 'p-2': !state.isFullscreen }" t-foreach="rtc.notifications.values()" t-as="notification" t-key="notification.id" t-esc="notification.text"/>
                </div>
            </div>
            <div t-if="state.sidebar and props.thread.activeRtcSession" class="o-discuss-Call-sidebar d-flex align-items-center h-100 flex-column">
                <CallParticipantCard t-foreach="visibleCards" t-as="cardData" t-key="cardData.key" cardData="cardData" className="'o-discuss-Call-sidebarCard w-100'" thread="props.thread"/>
            </div>
            <CallParticipantCard t-if="props.thread.videoCount &gt; 0 and state.insetCard" cardData="state.insetCard" className="'o-discuss-Call-mainCardStyle'" thread="props.thread" inset.bind="setInset"/>
        </div>
    </t>

<t t-name="discuss.CallActionList">
        <div class="o-discuss-CallActionList d-flex justify-content-center" t-attf-class="{{ className }}" t-ref="root">
            <div class="d-flex align-items-center flex-wrap justify-content-between" t-att-class="{ 'w-100 ps-2 pe-2': isSmall }">
                <t t-if="isOfActiveCall and rtc.state.selfSession">
                    <t t-if="rtc.state?.selfSession.isMute" t-set="micText">Unmute</t>
                    <t t-else="" t-set="micText">Mute</t>
                    <button class="btn d-flex m-1 border-0 rounded-circle shadow-none opacity-100 opacity-75-hover" t-att-class="{ 'p-2': isSmall, 'p-3': !isSmall }" t-att-aria-label="micText" t-att-title="micText" t-on-click="onClickMicrophone">
                        <div class="fa-stack">
                            <i class="fa fa-stack-1x" t-att-class="{                                 'fa-lg': !isSmall,                                 'fa-microphone': !rtc.state.selfSession.isMute,                                 'fa-microphone-slash': rtc.state.selfSession.isMute,                                 'text-danger': rtc.state.selfSession.isMute,                             }"/>
                        </div>
                    </button>
                    <t t-if="rtc.state?.selfSession.isDeaf" t-set="headphoneText">Undeafen</t>
                    <t t-else="" t-set="headphoneText">Deafen</t>
                    <button class="btn d-flex m-1 border-0 rounded-circle shadow-none opacity-100 opacity-75-hover" t-att-class="{ 'p-2': isSmall, 'p-3': !isSmall }" t-att-aria-label="headphoneText" t-att-title="headphoneText" t-on-click="onClickDeafen">
                        <div class="fa-stack">
                            <i class="fa fa-stack-1x" t-att-class="{                                 'fa-lg': !isSmall,                                 'fa-headphones': !rtc.state.selfSession.isDeaf,                                 'fa-deaf': rtc.state.selfSession.isDeaf,                                 'text-danger': rtc.state.selfSession.isDeaf,                             }"/>
                        </div>
                    </button>
                    <t t-if="rtc.state.sendCamera" t-set="cameraText">Stop camera</t>
                    <t t-else="" t-set="cameraText">Turn camera on</t>
                    <button class="btn d-flex m-1 border-0 rounded-circle shadow-none opacity-100 opacity-75-hover" t-att-class="{                             'p-2': isSmall,                             'p-3': !isSmall,                         }" t-att-aria-label="cameraText" t-att-title="cameraText" t-on-click="() =&gt; this.rtc.toggleVideo('camera')">
                        <div class="fa-stack">
                            <i class="fa fa-video-camera fa-stack-1x" t-att-class="{ 'fa-lg': !isSmall, 'text-success': rtc.state.sendCamera }"/>
                        </div>
                    </button>
                    <Dropdown position="'top-end'" togglerClass="\`btn d-flex m-1 border-0 rounded-circle shadow-none opacity-100 opacity-75-hover \${ isSmall ? 'p-2' : 'p-3' }\`" menuClass="'d-flex flex-column py-0'" title="MORE">
                        <t t-set-slot="toggler">
                            <div class="fa-stack">
                                <i class="fa fa-ellipsis-v fa-stack-1x" t-att-class="{ 'fa-lg': !isSmall }"/>
                            </div>
                        </t>
                        <t t-set-slot="default">
                            <DropdownItem t-foreach="moreActions" t-as="action" t-key="action.id" class="'btn rounded-0 d-flex align-items-center px-2 py-2 m-0 opacity-75 opacity-100-hover'" title="action.name" onSelected="action.onSelect">
                                <i t-att-class="action.icon"/>
                                <span class="mx-2" t-out="action.name"/>
                            </DropdownItem>
                        </t>
                    </Dropdown>
                </t>
                <button t-if="props.thread.rtcInvitingSession and !isOfActiveCall" class="btn btn-danger d-flex m-1 border-0 rounded-circle shadow-none" t-att-class="{ 'p-2': isSmall, 'p-3': !isSmall }" aria-label="Reject" title="Reject" t-att-disabled="rtc.state.hasPendingRequest" t-on-click="onClickRejectCall">
                    <div class="fa-stack">
                        <i class="fa fa-times fa-stack-1x" t-att-class="{ 'fa-lg': !isSmall }"/>
                    </div>
                </button>
                <t t-if="props.thread.eq(rtc.state.channel)" t-set="callText">Disconnect</t>
                <t t-else="" t-set="callText">Join Call</t>
                <button class="btn d-flex m-1 border-0 rounded-circle shadow-none" t-att-aria-label="callText" t-att-class="{ 'btn-danger': isOfActiveCall, 'p-2': isSmall, 'p-3': !isSmall, 'btn-success': !isOfActiveCall }" t-att-disabled="rtc.state.hasPendingRequest" t-att-title="callText" t-on-click="onClickToggleAudioCall">
                    <div class="fa-stack">
                        <i class="fa fa-phone fa-stack-1x" t-att-class="{ 'fa-lg': !isSmall }"/>
                    </div>
                </button>
            </div>
        </div>
    </t>

<t t-name="discuss.CallContextMenu">
        <div class="d-flex flex-column p-3">
            <input t-if="!isSelf" type="range" min="0.0" max="1" step="0.01" t-att-value="volume" t-on-change="onChangeVolume" class="form-range"/>
            <t t-if="env.debug and !isSelf and rtc.state.connectionType === rtcConnectionTypes.P2P">
                <hr class="w-100 border-top"/>
                <div><span class="fw-bolder">Connection type: </span><t t-out="rtc.state.connectionType"/></div>
                <div><span class="fw-bolder">To peer: </span><t t-out="outboundConnectionTypeText"/></div>
                <div><span class="fw-bolder">From peer: </span><t t-out="inboundConnectionTypeText"/></div>
                <div><span class="fw-bolder">Connection: </span><t t-out="props.rtcSession.connectionState"/></div>
                <div><span class="fw-bolder">ICE: </span><t t-out="props.rtcSession.iceState"/></div>
                <div><span class="fw-bolder">DTLS: </span><t t-out="props.rtcSession.dtlsState"/></div>
                <div><span class="fw-bolder">Data channel: </span><t t-out="props.rtcSession.dataChannelState"/></div>
                <div t-if="props.rtcSession.audioError"><span class="fw-bolder">Audio player: </span><t t-out="props.rtcSession.audioError"/></div>
                <div t-if="props.rtcSession.videoError"><span class="fw-bolder">Video player: </span><t t-out="props.rtcSession.videoError"/></div>
                <hr class="w-100 border-top"/>
                <div><span class="fw-bolder">ICE gathering: </span><t t-out="props.rtcSession.iceGatheringState"/></div>
                <div><span class="fw-bolder">Packets sent: </span><t t-out="props.rtcSession.packetsSent"/></div>
                <div><span class="fw-bolder">Packets received: </span><t t-out="props.rtcSession.packetsReceived"/></div>
                <div><span class="fw-bolder">Log step: </span><t t-out="props.rtcSession.logStep"/></div>
            </t>
            <t t-elif="env.debug and isSelf and rtc.state.connectionType === rtcConnectionTypes.SERVER">
                <div><span class="fw-bolder">Connection type: </span><t t-out="rtc.state.connectionType"/></div>
                <div><span class="fw-bolder">RTC Session ID: </span><t t-out="props.rtcSession.id"/></div>
                <hr class="w-100 border-top"/>
                <div><span class="fw-bolder">Upload: </span><t t-out="outboundConnectionTypeText"/></div>
                <div><span class="fw-bolder">up ICE: </span><t t-out="state.uploadStats.iceState"/></div>
                <div><span class="fw-bolder">up DTLS: </span><t t-out="state.uploadStats.dtlsState"/></div>
                <div><span class="fw-bolder">Packets sent: </span><t t-out="state.uploadStats.packetsSent"/></div>
                <div><span class="fw-bolder">available bitrate: </span><t t-out="state.uploadStats.availableOutgoingBitrate"/></div>
                <hr class="w-100 border-top"/>
                <div><span class="fw-bolder">Download: </span><t t-out="inboundConnectionTypeText"/></div>
                <div><span class="fw-bolder">down ICE: </span><t t-out="state.downloadStats.iceState"/></div>
                <div><span class="fw-bolder">down DTLS: </span><t t-out="state.downloadStats.dtlsState"/></div>
                <div><span class="fw-bolder">Packets received: </span><t t-out="state.downloadStats.packetsReceived"/></div>
                <t t-if="state.producerStats.audio">
                    <hr class="w-100 border-top"/>
                    <div><span class="fw-bolder">microphone</span></div>
                    <div><span class="fw-bolder">codec: </span><t t-out="state.producerStats.audio.codec"/></div>
                    <div><span class="fw-bolder">clock rate: </span><t t-out="state.producerStats.audio.clockRate"/></div>
                </t>
                <t t-if="state.producerStats.camera and props.rtcSession.isCameraOn">
                    <hr class="w-100 border-top"/>
                    <div><span class="fw-bolder">camera</span></div>
                    <div><span class="fw-bolder">codec: </span><t t-out="state.producerStats.camera.codec"/></div>
                    <div><span class="fw-bolder">clock rate: </span><t t-out="state.producerStats.camera.clockRate"/></div>
                </t>
                <t t-if="state.producerStats.screen and props.rtcSession.isScreenSharingOn">
                    <hr class="w-100 border-top"/>
                    <div><span class="fw-bolder">screen</span></div>
                    <div><span class="fw-bolder">codec: </span><t t-out="state.producerStats.screen.codec"/></div>
                    <div><span class="fw-bolder">clock rate: </span><t t-out="state.producerStats.screen.clockRate"/></div>
                </t>
            </t>
        </div>
    </t>
<t t-name="discuss.CallInvitation">
        <div class="o-discuss-CallInvitation d-flex flex-column m-2 p-5 border border-dark rounded-1 text-bg-900" t-attf-class="{{ className }}" t-ref="root">
            <div t-if="props.thread.rtcInvitingSession" class="o-discuss-CallInvitation-correspondent d-flex flex-column justify-content-around align-items-center text-nowrap">
                <img class="mb-2 rounded-circle cursor-pointer" t-att-src="threadService.avatarUrl(props.thread.rtcInvitingSession?.channelMember?.persona, props.thread)" t-on-click="onClickAvatar" alt="Avatar"/>
                <span class="w-100 fw-bolder text-truncate text-center overflow-hidden" t-esc="props.thread.rtcInvitingSession.channelMember.persona.name"/>
                <span class="fst-italic opacity-75">Incoming Call...</span>
            </div>
            <div class="d-flex justify-content-around align-items-center w-100 mt-4">
                <button class="btn user-select-none p-2 rounded-circle border-0 btn-danger" aria-label="Refuse" title="Refuse" t-on-click="onClickRefuse">
                    <i class="fa fa-lg fa-times m-3"/>
                </button>
                <button class="btn user-select-none p-2 rounded-circle border-0 btn-success" aria-label="Accept" title="Accept" t-on-click="onClickAccept">
                    <i class="fa fa-lg fa-phone m-3"/>
                </button>
            </div>
        </div>
    </t>

<t t-name="discuss.CallInvitations">
        <div t-if="store.discuss.ringingThreads.length &gt; 0" class="o-discuss-CallInvitations position-absolute top-0 end-0 d-flex flex-column p-2">
            <t t-foreach="store.discuss.ringingThreads" t-as="thread" t-key="thread.localId">
                <CallInvitation thread="thread"/>
            </t>
        </div>
    </t>

<t t-name="discuss.CallMenu">
        <div class="dropdown" t-attf-class="{{ className }}" t-ref="root">
            <button t-if="rtc.state.channel" class="px-3 user-select-none dropdown-toggle o-no-caret o-dropdown--narrow" t-att-title="buttonTitle" role="button" t-on-click="() =&gt; this.threadService.open(this.rtc.state.channel)">
                <div class="o-discuss-CallMenu-buttonContent d-flex align-items-center">
                    <span class="position-relative me-2">
                        <i class="fa me-2" t-att-class="{                             'fa-microphone': !rtc.state.sendCamera and !rtc.state.sendScreen,                             'fa-video-camera': rtc.state.sendCamera,                             'fa-desktop': rtc.state.sendScreen,                         }"/>
                        <small class="position-absolute top-0 end-0 bottom-0 mt-n3 pt-1">
                            <i class="o-discuss-CallMenu-dot fa fa-circle text-warning small"/>
                        </small>
                    </span>
                    <em class="text-truncate" t-esc="rtc.state.channel.displayName"/>
                </div>
            </button>
        </div>
    </t>

<t t-name="discuss.CallParticipantCard">
        <div class="o-discuss-CallParticipantCard position-relative cursor-pointer d-flex flex-column align-items-center justify-content-center mh-100 mw-100 p-1 rounded-1" t-att-class="{                 'o-isTalking': !props.minimized and isTalking,                 'o-isInvitation opacity-50': !rtcSession,                 'o-inset': props.inset,                 'o-small': props.inset and (ui.isSmall or props.minimized)             }" t-att-title="name" t-att-aria-label="name" t-attf-class="{{ props.className }}" t-on-click="onClick" t-on-contextmenu="onContextMenu" t-on-mousedown="onMouseDown" t-on-touchmove="(ev) =&gt; this.drag(ev)" t-ref="root">

            <CallParticipantVideo t-if="hasVideo" session="rtcSession" type="props.cardData.type" inset="props.inset"/>
            <div t-else="" class="o-discuss-CallParticipantCard-avatar d-flex align-items-center justify-content-center h-100 w-100 rounded-1" t-att-class="{ 'o-minimized': props.minimized }" draggable="false">
                <img alt="Avatar" t-att-class="{                         'o-isTalking': isTalking,                         'o-isInvitation': !rtcSession,                         }" class="h-100 rounded-circle border-5 o_object_fit_cover" t-att-src="threadService.avatarUrl(channelMember?.persona, props.thread)" draggable="false"/>
            </div>
            <t t-if="rtcSession">

                <span class="o-discuss-CallParticipantCard-overlay o-discuss-CallParticipantCard-overlayBottom z-index-1 position-absolute bottom-0 start-0 d-flex overflow-hidden">
                    <span t-if="!props.minimized and !props.inset" class="p-1 rounded-1 text-truncate" t-esc="name"/>
                    <small t-if="rtcSession.isScreenSharingOn and props.minimized and !isOfActiveCall" class="user-select-none o-minimized rounded-pill text-bg-danger d-flex align-items-center fw-bolder" title="live" aria-label="live">
                        LIVE
                    </small>
                </span>
                <div class="o-discuss-CallParticipantCard-overlay position-absolute top-0 end-0 d-flex flex-row-reverse">
                    <span t-if="hasRaisingHand" class="d-flex flex-column justify-content-center me-1 rounded-circle bg-500" t-att-class="{'o-minimized p-1': props.minimized, 'p-2': !props.minimized }" title="raising hand" aria-label="raising hand">
                        <i class="fa fa-hand-paper-o"/>
                    </span>
                    <span t-if="rtcSession.isSelfMuted and !rtcSession.isDeaf" class="d-flex flex-column justify-content-center me-1 rounded-circle o-discuss-CallParticipantCard-iconBlackBg" t-att-class="{'o-minimized p-1': props.minimized, 'p-2': !props.minimized }" title="muted" aria-label="muted">
                        <i class="fa fa-microphone-slash"/>
                    </span>
                    <span t-if="rtcSession.isDeaf" class="d-flex flex-column justify-content-center me-1 rounded-circle o-discuss-CallParticipantCard-iconBlackBg" t-att-class="{'o-minimized p-1': props.minimized, 'p-2': !props.minimized }" title="deaf" aria-label="deaf">
                        <i class="fa fa-deaf"/>
                    </span>
                    <span t-if="hasMediaError" class="o-discuss-CallParticipantCard-overlay-replayButton d-flex flex-column justify-content-center me-1 p-2 rounded-circle" title="media player Error" t-on-click.stop="onClickReplay">
                        <i t-if="rootHover.isHover" class="fa fa-repeat text-danger"/>
                        <i t-else="" class="fa fa-exclamation-triangle text-danger"/>
                    </span>
                    <span t-if="showConnectionState" class="d-flex flex-column justify-content-center me-1 p-2 rounded-circle o-discuss-CallParticipantCard-iconBlackBg" t-att-title="rtcSession.connectionState">
                        <i class="fa fa-exclamation-triangle text-warning"/>
                    </span>
                    <span t-if="showServerState" class="d-flex flex-column justify-content-center me-1 p-2 rounded-circle o-discuss-CallParticipantCard-iconBlackBg" t-att-title="rtc.state.serverState">
                        <i class="fa fa-exclamation-triangle text-warning"/>
                    </span>
                    <span t-if="rtcSession.isScreenSharingOn and !props.minimized and !isOfActiveCall" class="user-select-none rounded-pill text-bg-danger d-flex align-items-center me-1 fw-bolder" title="live" aria-label="live">
                        LIVE
                    </span>
                </div>


                <i t-if="isContextMenuAvailable" class="position-absolute bottom-0 start-50" t-ref="contextMenuAnchor"/>
            </t>
        </div>
    </t>

<t t-name="discuss.CallParticipantVideo">
        <video class="w-100 h-100 rounded-1 cursor-pointer" t-att-class="{ 'o-inset': props.inset }" t-att-type="props.type" playsinline="true" autoplay="true" muted="true" t-on-loadedmetadata="onVideoLoadedMetaData" t-ref="root"/>
    </t>
<t t-name="discuss.CallSettings">
        <ActionPanel title="title">
            <div class="d-flex flex-column px-3 overflow-auto">
                <div class="mb-3 d-flex align-items-center flex-wrap">
                    <label class="d-flex align-items-center flex-wrap mw-100 cursor-pointer" title="Input device" aria-label="Input device">
                        <span class="me-2 text-truncate">Input device</span>
                        <div>
                            <select name="inputDevice" class="form-select" t-on-change="onChangeSelectAudioInput">
                                <option value="">Browser default</option>
                                <t t-foreach="state.userDevices" t-as="device" t-key="device_index" device="device">
                                    <option t-if="device.kind === 'audioinput'" t-att-selected="userSettings.audioInputDeviceId === device.deviceId" t-att-value="device.deviceId"><t t-esc="device.label || 'audio device ' + device_index"/></option>
                                </t>
                            </select>
                        </div>
                    </label>
                </div>
                <div class="mb-3 d-flex align-items-center flex-wrap">
                    <label class="d-flex align-items-center flex-wrap mw-100 cursor-pointer" title="Enable Push-to-talk" aria-label="Enable Push-to-talk">
                        <input type="checkbox" aria-label="toggle push-to-talk" title="toggle push-to-talk" t-on-change="onChangePushToTalk" t-att-checked="userSettings.usePushToTalk ? 'checked' : ''" class="form-check-input"/>
                        <span class="ms-2 text-truncate">Enable Push-to-talk</span>
                    </label>
                </div>
                <t t-if="userSettings.usePushToTalk">
                    <div class="mb-3 d-flex align-items-center flex-wrap">
                        <label class="d-flex align-items-center flex-wrap mw-100 cursor-pointer" title="Push-to-talk key" aria-label="Push-to-talk key">
                            <span class="me-2 text-truncate">Push-to-talk key</span>
                            <span class="d-flex">
                                <span t-if="userSettings.pushToTalkKey" class="ms-1 px-3 border border-2 rounded fs-3" t-attf-class="{{ userSettings.isRegisteringKey ? 'border-danger' : 'border-primary' }}" t-esc="pushToTalkKeyText"/>
                                <button class="btn btn-link px-2 py-0 text-black" t-on-click="onClickRegisterKeyButton">
                                    <i t-if="userSettings.isRegisteringKey" title="Cancel" aria-label="Cancel" class="fa fa-2x fa-times-circle"/>
                                    <i t-else="" title="Register new key" aria-label="Register new key" class="fa fa-2x fa-keyboard-o"/>
                                </button>
                            </span>
                        </label>
                    </div>
                    <div t-if="userSettings.isRegisteringKey">Press a key to register it as the push-to-talk shortcut.</div>
                    <div class="mb-3 d-flex align-items-center flex-wrap">
                        <label class="d-flex align-items-center flex-wrap mw-100 cursor-pointer" title="Delay after releasing push-to-talk" aria-label="Delay after releasing push-to-talk">
                            <span class="me-2 text-truncate">Delay after releasing push-to-talk</span>
                            <div class="d-flex w-100 align-items-center">
                                <input class="flex-grow-2 form-range" type="range" min="0" max="2000" step="1" t-att-value="userSettings.voiceActiveDuration" t-on-input="onChangeDelay"/>
                                <span class="p-1 w-50 text-end"><t t-out="userSettings.voiceActiveDuration"/>ms</span>
                            </div>
                        </label>
                    </div>
                </t>
                <div t-else="" class="mb-3 d-flex align-items-center flex-wrap">
                    <label class="d-flex align-items-center flex-wrap mw-100 cursor-pointer" title="Voice detection threshold" aria-label="Voice detection threshold">
                        <span class="me-2 text-truncate">Voice detection threshold</span>
                        <div class="d-flex w-100 align-items-center">
                            <input class="flex-grow-2 form-range" type="range" min="0.001" max="1" step="0.001" t-att-value="userSettings.voiceActivationThreshold" t-on-input="onChangeThreshold"/>
                            <span class="p-1 w-50 text-end"><t t-out="Math.floor(userSettings.voiceActivationThreshold * 100)"/>%</span>
                        </div>
                    </label>
                </div>
            </div>
            <div class="d-flex flex-column px-3 overflow-auto">
                <div class="py-2 fw-bolder text-700 text-truncate text-uppercase">Video Settings</div>
                <div class="mb-3 d-flex align-items-center flex-wrap">
                    <label class="d-flex align-items-center flex-wrap mw-100 cursor-pointer" title="Show video participants only" aria-label="Show video participants only">
                        <input type="checkbox" aria-label="toggle push-to-talk" title="Show video participants only" t-on-change="onChangeVideoFilterCheckbox" t-att-checked="props.thread.showOnlyVideo ? 'checked' : ''" class="form-check-input"/>
                        <span class="ms-2 text-truncate">Show video participants only</span>
                    </label>
                </div>
                <div t-if="userSettings.hasCanvasFilterSupport" class="mb-3 d-flex align-items-center flex-wrap">
                    <label class="d-flex align-items-center flex-wrap mw-100 cursor-pointer" title="Blur video background" aria-label="Blur video background">
                        <input type="checkbox" aria-label="Blur video background" title="Blur video background" t-on-change="onChangeBlur" t-att-checked="userSettings.useBlur ? 'checked' : ''" class="form-check-input"/>
                        <span class="ms-2 text-truncate">Blur video background</span>
                    </label>
                </div>
                <t t-if="userSettings.useBlur">
                    <div class="mb-3 d-flex align-items-center flex-wrap">
                        <label class="d-flex align-items-center flex-wrap mw-100 cursor-pointer" title="Background blur intensity" aria-label="Background blur intensity">
                            <span class="me-2 text-truncate">Background blur intensity</span>
                            <div class="d-flex w-100 align-items-center">
                                <input class="flex-grow-2 form-range" type="range" min="0" max="20" step="1" t-att-value="userSettings.backgroundBlurAmount" t-on-input="onChangeBackgroundBlurAmount"/>
                                <span class="p-1 w-50 text-end"><t t-out="Math.floor(userSettings.backgroundBlurAmount * 5)"/>%</span>
                            </div>
                        </label>
                    </div>
                    <div class="mb-3 d-flex align-items-center flex-wrap">
                        <label class="d-flex align-items-center flex-wrap mw-100 cursor-pointer" title="Edge blur intensity" aria-label="Edge blur intensity">
                            <span class="me-2 text-truncate">Edge blur intensity</span>
                            <div class="d-flex w-100 align-items-center">
                                <input class="flex-grow-2 form-range" type="range" min="0" max="20" step="1" t-att-value="userSettings.edgeBlurAmount" t-on-input="onChangeEdgeBlurAmount"/>
                                <span class="p-1 w-50 text-end"><t t-out="Math.floor(userSettings.edgeBlurAmount * 5)"/>%</span>
                            </div>
                        </label>
                    </div>
                </t>
            </div>
            <div t-if="env.debug" class="d-flex flex-column px-3 overflow-auto">
                <div class="py-2 fw-bolder text-700 text-truncate text-uppercase">Technical Settings</div>
                <div class="mb-3 d-flex align-items-center flex-wrap">
                    <label class="d-flex align-items-center flex-wrap mw-100 cursor-pointer" title="Log RTC events" aria-label="Log RTC events">
                        <input type="checkbox" aria-label="Log RTC events" title="Log RTC events" t-on-change="onChangeLogRtcCheckbox" t-att-checked="userSettings.logRtc ? 'checked' : ''" class="form-check-input"/>
                        <span class="ms-2 text-truncate">Log RTC events</span>
                    </label>
                </div>
                <div t-if="userSettings.logRtc" class="mb-3 d-flex align-items-center flex-wrap">
                    <button class="btn btn-primary" t-att-disabled="rtc.state.logs.size === 0" t-on-click="onClickDownloadLogs">Download logs</button>
                </div>
            </div>
        </ActionPanel>
    </t>

<t t-name="discuss.Typing">
        <t t-if="typingService.hasTypingMembers(props.channel)">
            <div class="o-discuss-Typing-icon d-flex align-items-center" t-attf-class="{{ className }}" t-att-title="text">
                <span class="o-discuss-Typing-dot d-flex flex-shrink-0 rounded-pill bg-500" t-att-class="{                              'o-sizeMedium': props.size === 'medium',                              'o-sizeSmall': props.size === 'small',                              }"/>
                <span class="flex-grow-1 flex-shrink-0"/>
                <span class="o-discuss-Typing-dot o-discuss-Typing-dot2 d-flex flex-shrink-0 rounded-pill bg-500" t-att-class="{                              'o-sizeMedium': props.size === 'medium',                              'o-sizeSmall': props.size === 'small',                              }"/>
                <span class="flex-grow-1 flex-shrink-0"/>
                <span class="o-discuss-Typing-dot o-discuss-Typing-dot3 d-flex flex-shrink-0 rounded-pill bg-500" t-att-class="{                              'o-sizeMedium': props.size === 'medium',                              'o-sizeSmall': props.size === 'small',                              }"/>
            </div>
            <t t-if="props.displayText">
                <span class="ms-1"/>
                <span class="text-truncate" t-out="text"/>
            </t>
        </t>
    </t>

<t t-name="im_livechat.FeedbackPanel">
<div class="d-flex flex-column bg-view flex-grow-1 p-3">
    <div class="p-2">
        <div class="mb-5">
            <t t-if="state.step === STEP.RATING">
                <p class="text-center fs-6 mb-4">Did we correctly answer your question?</p>
                <div class="d-flex justify-content-center">
                    <img role="button" class="mx-3 opacity-50 opacity-100-hover" t-att-class="{ 'opacity-100': state.rating === RATING.GOOD }" t-att-src="url(\`/rating/static/src/img/rating_\${RATING.GOOD}.png\`)" t-att-alt="RATING.GOOD" t-on-click="() =&gt; this.select(RATING.GOOD)"/>
                    <img role="button" class="mx-3 opacity-50 opacity-100-hover" t-att-class="{ 'opacity-100': state.rating === RATING.OK }" t-att-src="url(\`/rating/static/src/img/rating_\${RATING.OK}.png\`)" t-att-alt="RATING.OK" t-on-click="() =&gt; this.select(RATING.OK)"/>
                    <img role="button" class="mx-3 opacity-50 opacity-100-hover" t-att-class="{ 'opacity-100': state.rating === RATING.BAD }" t-att-src="url(\`/rating/static/src/img/rating_\${RATING.BAD}.png\`)" t-att-alt="RATING.BAD" t-on-click="() =&gt; this.select(RATING.BAD)"/>
                </div>
            </t>
            <t t-else="">
                <p class="text-center fs-5 fw-bold mb-4">Thank you for your feedback</p>
            </t>
        </div>
        <div t-if="state.rating and state.step === STEP.RATING" class="d-flex flex-column mb-5">
            <textarea t-model="state.feedback" class="form-control my-2" placeholder="Explain your note"/>
            <button class="btn btn-primary align-self-end" t-on-click="onClickSendFeedback">Send</button>
        </div>
        <div class="mb-5">
            <TranscriptSender thread="props.thread"/>
        </div>
        <button class="btn btn-link text-muted text-decoration-underline fw-normal w-100" t-on-click="props.onClickClose">Close conversation</button>
    </div>
</div>
</t>
<t t-name="im_livechat.TranscriptSender">
    <div class="form-text">
        <t t-if="state.status === STATUS.SENT">The conversation was sent.</t>
        <t t-elif="state.status === STATUS.FAILED">An error occurred. Please try again.</t>
        <t t-else="">Receive a copy of this conversation.</t>
    </div>
    <div class="input-group has-validation mb-3">
        <input t-model="state.email" t-att-disabled="[STATUS.SENDING, STATUS.SENT].includes(state.status)" type="text" class="form-control" placeholder="mail@example.com"/>
        <button class="btn btn-primary" type="button" data-action="sendTranscript" t-att-disabled="!state.email or !isValidEmail(state.email) or [STATUS.SENDING, STATUS.SENT].includes(state.status)" t-on-click="onClickSend">
            <i class="fa" t-att-class="{                 'fa-spinner fa-spin': state.status === STATUS.SENDING,                 'fa-check': state.status === STATUS.SENT,                 'fa-paper-plane': state.status === STATUS.IDLE,                 'fa-repeat': state.status === STATUS.FAILED,             }"/>
        </button>
    </div>
</t>
<t t-name="im_livechat.LivechatButton">
    <button part="openChatButton" t-if="isShown" class="btn o-livechat-LivechatButton d-print-none position-fixed p-3 d-flex justify-content-center align-items-center shadow rounded-circle " t-attf-style="color: {{livechatService.options.button_text_color}}; background-color: {{livechatService.options.button_background_color}}; width: {{size}}px; height: {{size}}px; min-width: 56px; top: {{ position.top }}; left: {{ position.left }};" t-ref="button" t-on-click="onClick" title="Drag to Move">
        <i class="fa fa-commenting" style="font-size: 24px;"/>
        <div t-if="livechatService.rule?.action === 'display_button_and_text'" class="o-livechat-LivechatButton-notification text-nowrap position-absolute bg-100 py-2 px-3 rounded" style="max-width: 75vw;" t-att-class="{'o-livechat-LivechatButton-animate': state.animateNotification}">
            <p class="m-0 text-dark text-truncate" t-esc="livechatService.options.button_text"/>
        </div>
    </button>
</t>

<t t-name="Appointment.appointment_info_no_slot">
        <div class="col-md-8 col-lg-6 mx-auto">
            <div class="px-2 pt-3 pb-5 text-center o_appointment_no_slot_overall_helper_txt">
                <t t-if="!active">
                    <p>
                        Sorry, it is no longer possible to schedule an appointment.
                    </p>
                </t>
                <t t-elif="staffUserName">
                    <p>
                        Sorry, <span t-out="staffUserName"/> has no availability for an appointment.
                    </p>
                </t>
                <t t-else="">
                    <p>
                        Sorry, we have no availability for an appointment.
                    </p>
                </t>
            <div t-if="appointmentsCount !== 1" class="text-center">
                <a href="/appointment">Go back to Appointment</a> or <a href="/contactus">contact us</a>.
            </div>
            <div t-else="" class="text-center">
                <a href="/contactus">Contact us</a>.
            </div>
            </div>
            <div class="o_appointment_no_slot_overall_helper_svg mx-auto">
                <t t-call="Appointment.appointment_svg"/>
            </div>
        </div>
    </t>

    <t t-name="Appointment.appointment_info_no_capacity">
        <div class="col-8 mx-auto">
            <div class="pt-2 o_appointment_no_slot_overall_helper_txt">
                <p>
                    Sorry, there is not any more availability for the asked capacity.
                </p>
            </div>
            <div class="o_appointment_no_slot_overall_helper_svg mx-auto">
                <t t-call="Appointment.appointment_svg"/>
            </div>
        </div>
    </t>

    <t t-name="Appointment.appointment_info_no_slot_month">
        <div class="o_appointment_no_slot_month_helper mt-4 p-3 text-center">
            <div class="o_appointment_no_slot_month_helper_svg w-25 mx-auto">
                <t t-call="Appointment.appointment_svg"/>
            </div>
            <t t-if="staffUserName">
                <p>
                    Sorry, <span t-out="staffUserName"/> has no more slots available for this month.
                </p>
                <p>
                    Their first availability is <br/>
                    <a href="#" id="next_available_slot" t-out="firstAvailabilityDate"/>
                </p>
            </t>
            <t t-else="">
                <p>
                    Sorry, we have no more slots available for this month.
                </p>
                <p>
                    Our first availability is <br/>
                    <a href="#" id="next_available_slot" t-out="firstAvailabilityDate"/>
                </p>
            </t>
        </div>
    </t>
<t t-name="appointment.resources_list">
        <label for="resource_id" class="mb-1">Make your choice</label>
        <select class="o_resources_list form-select cursor-pointer" name="resource_id">
            <option t-foreach="availableResources" t-as="availableResource" t-key="availableResource_index" t-att-value="availableResource['id']" t-att-data-resource-capacity="availableResource['capacity']">
                <t t-out="availableResource['name']"/>
            </option>
        </select>
        <button name="submitSlotInfoSelected" class="btn btn-primary w-100 mt-3">Confirm</button>
    </t>

<t t-name="appointment.slots_list">
        <span>Select a time</span>
        <div class="o_slots_list row px-0">
            <t t-foreach="slots" t-as="slot" t-key="slot_index">
                <div t-attf-class="col-6 mt-2 #{slot_index % 2 == 0 ? 'pe-1' : 'ps-1'}">
                    <button class="o_slot_hours d-flex btn btn-outline-primary align-items-center justify-content-center w-100 border" t-att-data-available_resources="getAvailableResources(slot)" t-attf-data-url-parameters="#{slot['url_parameters']}&amp;#{commonUrlParams}" t-out="slot['hours']"/>
                </div>
            </t>
        </div>
    </t>

<t t-name="Appointment.appointment_svg">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 313 241">
            <style type="text/css">
                .stgrey0{fill:#E3E3E3}
                .stgrey1{fill:#F2F2F2}
            </style>
            <path class="o_appointment_svg_fill_color_1" d="m137.81 0.0013474c48.392-0.21423 87.961 25.151 119.18 53.698 32.682 29.88 66.347 66.006 53.013 103.74-12.99 36.761-67.123 50.43-112.67 65.091-41.236 13.274-86.034 26.567-126.46 11.881-40.757-14.806-60.318-49.221-69.88-83.208-9.4111-33.448 50.381-45.66 75.77-73.718 27.562-30.46 12.921-77.267 61.044-77.48z" clip-rule="evenodd" fill-opacity=".15" fill-rule="evenodd"/>
            <path d="m57.116 27.372c0-8.4121 6.8204-15.232 15.234-15.232h169.34c8.414 0 15.234 6.8194 15.234 15.232v169.31c0 8.412-6.82 15.231-15.234 15.231h-169.34c-8.4134 0-15.234-6.819-15.234-15.231v-169.31z" fill="#fff"/>
            <path class="stgrey1" d="m241.69 15.452h-169.34c-6.5844 0-11.922 5.3369-11.922 11.92v169.31c0 6.583 5.3377 11.92 11.922 11.92h169.34c6.585 0 11.922-5.337 11.922-11.92v-169.31c0-6.5834-5.337-11.92-11.922-11.92zm-169.34-3.3112c-8.4134 0-15.234 6.8194-15.234 15.232v169.31c0 8.412 6.8204 15.231 15.234 15.231h169.34c8.414 0 15.234-6.819 15.234-15.231v-169.31c0-8.4121-6.82-15.232-15.234-15.232h-169.34z" clip-rule="evenodd" fill-rule="evenodd"/>
            <path class="stgrey0" d="m90.675 84.877c0-2.3773-1.9275-4.3045-4.3052-4.3045h-6.8441c-2.3777 0-4.3052 1.9272-4.3052 4.3045s1.9275 4.3046 4.3052 4.3046h6.8441c2.3777 0 4.3052-1.9273 4.3052-4.3046z"/>
            <path class="stgrey0" d="m115.4 84.877c0-2.3773-1.927-4.3045-4.305-4.3045h-6.844c-2.378 0-4.3052 1.9272-4.3052 4.3045s1.9272 4.3046 4.3052 4.3046h6.844c2.378 0 4.305-1.9273 4.305-4.3046z"/>
            <path class="stgrey0" d="m139.91 84.877c0-2.3773-1.928-4.3045-4.305-4.3045h-6.624c-2.377 0-4.305 1.9272-4.305 4.3045s1.928 4.3046 4.305 4.3046h6.624c2.377 0 4.305-1.9273 4.305-4.3046z"/>
            <path class="o_appointment_svg_fill_color_1" d="m164.42 84.877c0-2.3773-1.928-4.3045-4.306-4.3045h-6.623c-2.378 0-4.305 1.9272-4.305 4.3045s1.927 4.3046 4.305 4.3046h6.623c2.378 0 4.306-1.9273 4.306-4.3046z"/>
            <path class="o_appointment_svg_fill_color_1" d="m189.14 84.877c0-2.3773-1.928-4.3045-4.305-4.3045h-6.845c-2.377 0-4.305 1.9272-4.305 4.3045s1.928 4.3046 4.305 4.3046h6.845c2.377 0 4.305-1.9273 4.305-4.3046z"/>
            <path class="o_appointment_svg_fill_color_1" d="m213.87 84.877c0-2.3773-1.928-4.3045-4.305-4.3045h-6.845c-2.377 0-4.305 1.9272-4.305 4.3045s1.928 4.3046 4.305 4.3046h6.845c2.377 0 4.305-1.9273 4.305-4.3046z"/>
            <path class="o_appointment_svg_fill_color_1" d="m238.6 84.877c0-2.3773-1.927-4.3045-4.305-4.3045h-6.844c-2.378 0-4.305 1.9272-4.305 4.3045s1.927 4.3046 4.305 4.3046h6.844c2.378 0 4.305-1.9273 4.305-4.3046z"/>
            <path class="o_appointment_svg_fill_color_1" d="m90.675 107.83c0-2.377-1.9275-4.304-4.3052-4.304h-6.8441c-2.3777 0-4.3052 1.927-4.3052 4.304 0 2.378 1.9275 4.305 4.3052 4.305h6.8441c2.3777 0 4.3052-1.927 4.3052-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m115.4 107.83c0-2.377-1.927-4.304-4.305-4.304h-6.844c-2.378 0-4.3052 1.927-4.3052 4.304 0 2.378 1.9272 4.305 4.3052 4.305h6.844c2.378 0 4.305-1.927 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m139.91 107.83c0-2.377-1.928-4.304-4.305-4.304h-6.624c-2.377 0-4.305 1.927-4.305 4.304 0 2.378 1.928 4.305 4.305 4.305h6.624c2.377 0 4.305-1.927 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m164.42 107.83c0-2.377-1.928-4.304-4.306-4.304h-6.623c-2.378 0-4.305 1.927-4.305 4.304 0 2.378 1.927 4.305 4.305 4.305h6.623c2.378 0 4.306-1.927 4.306-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m189.14 107.83c0-2.377-1.928-4.304-4.305-4.304h-6.845c-2.377 0-4.305 1.927-4.305 4.304 0 2.378 1.928 4.305 4.305 4.305h6.845c2.377 0 4.305-1.927 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m213.87 107.83c0-2.377-1.928-4.304-4.305-4.304h-6.845c-2.377 0-4.305 1.927-4.305 4.304 0 2.378 1.928 4.305 4.305 4.305h6.845c2.377 0 4.305-1.927 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m238.6 107.83c0-2.377-1.927-4.304-4.305-4.304h-6.844c-2.378 0-4.305 1.927-4.305 4.304 0 2.378 1.927 4.305 4.305 4.305h6.844c2.378 0 4.305-1.927 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m90.675 130.79c0-2.377-1.9275-4.305-4.3052-4.305h-6.8441c-2.3777 0-4.3052 1.928-4.3052 4.305s1.9275 4.305 4.3052 4.305h6.8441c2.3777 0 4.3052-1.928 4.3052-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m115.4 130.79c0-2.377-1.927-4.305-4.305-4.305h-6.844c-2.378 0-4.3052 1.928-4.3052 4.305s1.9272 4.305 4.3052 4.305h6.844c2.378 0 4.305-1.928 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m139.91 130.79c0-2.377-1.928-4.305-4.305-4.305h-6.624c-2.377 0-4.305 1.928-4.305 4.305s1.928 4.305 4.305 4.305h6.624c2.377 0 4.305-1.928 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m164.42 130.79c0-2.377-1.928-4.305-4.306-4.305h-6.623c-2.378 0-4.305 1.928-4.305 4.305s1.927 4.305 4.305 4.305h6.623c2.378 0 4.306-1.928 4.306-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m189.14 130.79c0-2.377-1.928-4.305-4.305-4.305h-6.845c-2.377 0-4.305 1.928-4.305 4.305s1.928 4.305 4.305 4.305h6.845c2.377 0 4.305-1.928 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m213.87 130.79c0-2.377-1.928-4.305-4.305-4.305h-6.845c-2.377 0-4.305 1.928-4.305 4.305s1.928 4.305 4.305 4.305h6.845c2.377 0 4.305-1.928 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m238.6 130.79c0-2.377-1.927-4.305-4.305-4.305h-6.844c-2.378 0-4.305 1.928-4.305 4.305s1.927 4.305 4.305 4.305h6.844c2.378 0 4.305-1.928 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m90.675 153.75c0-2.377-1.9275-4.304-4.3052-4.304h-6.8441c-2.3777 0-4.3052 1.927-4.3052 4.304 0 2.378 1.9275 4.305 4.3052 4.305h6.8441c2.3777 0 4.3052-1.927 4.3052-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m115.4 153.75c0-2.377-1.927-4.304-4.305-4.304h-6.844c-2.378 0-4.3052 1.927-4.3052 4.304 0 2.378 1.9272 4.305 4.3052 4.305h6.844c2.378 0 4.305-1.927 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m139.91 153.75c0-2.377-1.928-4.304-4.305-4.304h-6.624c-2.377 0-4.305 1.927-4.305 4.304 0 2.378 1.928 4.305 4.305 4.305h6.624c2.377 0 4.305-1.927 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m164.42 153.75c0-2.377-1.928-4.304-4.306-4.304h-6.623c-2.378 0-4.305 1.927-4.305 4.304 0 2.378 1.927 4.305 4.305 4.305h6.623c2.378 0 4.306-1.927 4.306-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m189.14 153.75c0-2.377-1.928-4.304-4.305-4.304h-6.845c-2.377 0-4.305 1.927-4.305 4.304 0 2.378 1.928 4.305 4.305 4.305h6.845c2.377 0 4.305-1.927 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m213.87 153.75c0-2.377-1.928-4.304-4.305-4.304h-6.845c-2.377 0-4.305 1.927-4.305 4.304 0 2.378 1.928 4.305 4.305 4.305h6.845c2.377 0 4.305-1.927 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m238.6 153.75c0-2.377-1.927-4.304-4.305-4.304h-6.844c-2.378 0-4.305 1.927-4.305 4.304 0 2.378 1.927 4.305 4.305 4.305h6.844c2.378 0 4.305-1.927 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m90.675 176.71c0-2.377-1.9275-4.305-4.3052-4.305h-6.8441c-2.3777 0-4.3052 1.928-4.3052 4.305s1.9275 4.305 4.3052 4.305h6.8441c2.3777 0 4.3052-1.928 4.3052-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m115.4 176.71c0-2.377-1.927-4.305-4.305-4.305h-6.844c-2.378 0-4.3052 1.928-4.3052 4.305s1.9272 4.305 4.3052 4.305h6.844c2.378 0 4.305-1.928 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m139.91 176.71c0-2.377-1.928-4.305-4.305-4.305h-6.624c-2.377 0-4.305 1.928-4.305 4.305s1.928 4.305 4.305 4.305h6.624c2.377 0 4.305-1.928 4.305-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m164.42 176.71c0-2.377-1.928-4.305-4.306-4.305h-6.623c-2.378 0-4.305 1.928-4.305 4.305s1.927 4.305 4.305 4.305h6.623c2.378 0 4.306-1.928 4.306-4.305z"/>
            <path class="o_appointment_svg_fill_color_1" d="m189.14 176.71c0-2.377-1.928-4.305-4.305-4.305h-6.845c-2.377 0-4.305 1.928-4.305 4.305s1.928 4.305 4.305 4.305h6.845c2.377 0 4.305-1.928 4.305-4.305z"/>
            <path class="stgrey0" d="m213.87 176.71c0-2.377-1.928-4.305-4.305-4.305h-6.845c-2.377 0-4.305 1.928-4.305 4.305s1.928 4.305 4.305 4.305h6.845c2.377 0 4.305-1.928 4.305-4.305z"/>
            <path class="stgrey0" d="m238.6 176.71c0-2.377-1.927-4.305-4.305-4.305h-6.844c-2.378 0-4.305 1.928-4.305 4.305s1.927 4.305 4.305 4.305h6.844c2.378 0 4.305-1.928 4.305-4.305z"/>
            <path d="m57.116 27.372c0-8.4122 6.8204-15.232 15.234-15.232h169.34c8.414 0 15.234 6.8194 15.234 15.232v30.021h-199.81v-30.021z" fill="#fff"/>
            <path class="stgrey1" d="m241.69 15.452h-169.34c-6.5844 0-11.922 5.3369-11.922 11.92v26.71h193.18v-26.71c0-6.5834-5.337-11.92-11.922-11.92zm-169.34-3.3112c-8.4134 0-15.234 6.8194-15.234 15.232v30.021h199.81v-30.021c0-8.4121-6.82-15.232-15.234-15.232h-169.34z" clip-rule="evenodd" fill-rule="evenodd"/>
            <path class="stgrey1" d="m121.87 34.878c0-2.9259 2.373-5.2979 5.299-5.2979h62.702c2.926 0 5.298 2.372 5.298 5.2979 0 2.926-2.372 5.2979-5.298 5.2979h-62.702c-2.926 0-5.299-2.3719-5.299-5.2979z"/>
            <path class="stgrey0" d="m90.74 34.878c0-1.9507-1.5815-3.532-3.5324-3.532h-14.792c-1.9509 0-3.5325 1.5813-3.5325 3.532 0 1.9506 1.5816 3.5319 3.5325 3.5319h14.792c1.9509 0 3.5324-1.5813 3.5324-3.5319z"/>
            <path class="stgrey0" d="m245.07 34.878c0-1.9507-1.582-3.532-3.533-3.532h-14.792c-1.951 0-3.533 1.5813-3.533 3.532 0 1.9506 1.582 3.5319 3.533 3.5319h14.792c1.951 0 3.533-1.5813 3.533-3.5319z"/>
            <path d="m284.3 201.65c0 16.154-13.098 29.249-29.254 29.249s-29.253-13.095-29.253-29.249c0-16.153 13.097-29.248 29.253-29.248s29.254 13.095 29.254 29.248z" fill="#fff"/>
            <path class="stgrey1" d="m255.04 227.59c14.327 0 25.942-11.613 25.942-25.938s-11.615-25.937-25.942-25.937-25.941 11.612-25.941 25.937 11.614 25.938 25.941 25.938zm0 3.311c16.156 0 29.254-13.095 29.254-29.249 0-16.153-13.098-29.248-29.254-29.248s-29.253 13.095-29.253 29.248c0 16.154 13.097 29.249 29.253 29.249z" clip-rule="evenodd" fill-rule="evenodd"/>
            <path class="o_appointment_svg_fill_color_1" d="m243.98 212.52c-0.862-0.862-0.862-2.26 0-3.122l18.886-18.882c0.862-0.863 2.26-0.863 3.122 0 0.862 0.862 0.862 2.259 0 3.121l-18.886 18.883c-0.862 0.862-2.26 0.862-3.122 0z"/>
            <path class="o_appointment_svg_fill_color_1" d="m243.98 190.52c0.862-0.863 2.26-0.863 3.122 0l18.886 18.882c0.862 0.862 0.862 2.26 0 3.122s-2.26 0.862-3.122 0l-18.886-18.883c-0.862-0.862-0.862-2.259 0-3.121z"/>
        </svg>
    </t>
<div t-name="website_helpdesk.knowledge_base_autocomplete" class="dropdown-menu show w-100">
        <a t-foreach="results" t-as="result" t-key="result_index" class="dropdown-item p-2 text-wrap" t-attf-href="{{result.url}}">
            <i t-attf-class="fa fa-fw {{result.icon}}"/> <t t-esc="result.name"/>
        </a>
        <span t-if="!results.length" class="dropdown-item-text">
            <span class="text-muted">
                No results found. Please try another search.
            </span>
        </span>
        <a t-attf-href="?search={{term}}" class="dropdown-item p-2 text-primary text-center" t-if="showMore">
            All results
        </a>
    </div>
<t t-name="social_push_notifications.NotificationRequestPopup">
        <div class="o_social_push_notifications_permission_request position-fixed w-100">
            <div class="container-fluid">
                <div class="dropdown">
                    <a href="#" class="dropdown-toggle invisible" data-bs-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"/>
                    <div class="dropdown-menu px-3 pt-3 border shadow" t-name="">
                        <button class="btn px-1 py-0 close">×</button>
                        <div class="d-flex text-start">
                            <div class="me-2 pt-1">
                                <img width="48" height="auto" t-att-src="widget.notificationIcon" alt="Notification Request Icon"/>
                            </div>
                            <div class="o_social_push_notifications_permission_content">
                                <h6 class="o_social_push_notifications_permission_content_title pe-1" t-esc="widget.notificationTitle"/>
                                <p class="o_social_push_notifications_permission_content_body text-muted small mb-1" t-esc="widget.notificationBody"/>
                            </div>
                        </div>
                        <div class="text-end">
                            <button class="o_social_push_notifications_permission_deny btn btn-light">Deny</button>
                            <button class="o_social_push_notifications_permission_allow btn btn-primary">Allow</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </t>
<t t-name="website_appointment.new_appointment_type_dialog">
        <main class="modal-body">
            <form role="form">
                <div class="mb-3">
                    <label for="appointment_name" class="col-form-label">Appointment Type Name</label>
                    <input id="appointment_name" type="text" class="form-control" required="1" placeholder="e.g. &quot;Technical Demo&quot;"/>
                    <p id="name-required" class="text-danger mt-1 mb-0 d-none">Please fill this field</p>
                </div>
                <div class="mb-3">
                    <label for="user_ids" class="col-form-label">Users</label>
                    <input id="user_ids" type="text" class="form-control"/>
                </div>
            </form>
        </main>
    </t>
<t t-name="website_knowledge.embedded_view_placeholder">

        <div class="o_knowledge_embedded_view_placeholder d-flex flex-column flex-grow-1 position-relative bg-white border">
            <div class="d-flex border-bottom p-5 pb-0">
                <div class="mb-3 p-3 bg-light w-25 me-auto"/>
                <div class="mb-3 p-3 bg-light w-50"/>
            </div>
            <div class="bg-light flex-grow-1 p-3 w-100"/>
            <div class="o_knowledge_embedded_view_placeholder_cover d-flex flex-column align-items-center justify-content-center">
                <p class="o_view_nocontent_empty_folder m-0"/>
                <p class="fw-bold">This view is only available for internal users</p>
                <a t-attf-href="/web/login?redirect=#{url}" class="btn btn-primary">Log in</a>
            </div>
        </div>
    </t>
    <t t-name="website_knowledge.file_behavior_toolbar_content">
        <div class="btn-group d-flex flex-wrap">
            <button title="Download" name="download" class="btn btn-primary btn-link btn-sm border-0 text-break text-start text-o-color-2 text-capitalize fw-bold border-transparent bg-transparent">
                <i class="fa fa-download me-1"/>
                <span class="o_knowledge_toolbar_button_text">Download</span>
            </button>
        </div>
    </t>
<t t-name="website_links.RecentLink">
        <div class="row mb16">
            <div class="col-md-1 col-2 text-center">
                <h4><t t-esc="widget.link_obj.count"/></h4>
                <p class="text-muted" style="margin-top: -5px;">clicks</p>
            </div>
            <div class="col-md-7 col-7">
                <h4 class="truncate_text">
                    <img t-attf-src="http://www.google.com/s2/favicons?domain={{ widget.link_obj.url }}" loading="lazy" alt="Icon" onerror="this.src='/website_links/static/img/default_favicon.png'"/>
                    <a class="no-link-style" t-att-href="widget.link_obj.url"><t t-esc="widget.link_obj.title"/></a>
                </h4>
                <p class="text-muted mb0" style="margin-top: -5px;">
                    <span class="o_website_links_short_url text-muted" style="position:relative;">
                        <span id="o_website_links_host"><t t-esc="widget.link_obj.short_url_host"/></span><span id="o_website_links_code"><t t-esc="widget.link_obj.code"/></span>
                    </span>

                    <span class="o_website_links_edit_tools" style="display:none;">
                        <a role="button" class="o_website_links_ok_edit btn btn-sm btn-primary" href="#">ok</a> or
                        <a class="o_website_links_cancel_edit" href="#">cancel</a>
                    </span>

                    <a class="o_website_links_edit_code" aria-label="Edit code" title="Edit code"><span class="fa fa-pencil gray"/></a>

                    <br/>
                    <span class="badge text-bg-success"><t t-esc="widget.link_obj.campaign_id[1]"/></span>
                    <span class="badge text-bg-success"><t t-esc="widget.link_obj.medium_id[1]"/></span>
                    <span class="badge text-bg-success"><t t-esc="widget.link_obj.source_id[1]"/></span>
                </p>
                <p class="o_website_links_code_error" style="color:red;font-weight:bold;"/>
            </div>

            <div class="col-md-4 col-2">
                <button class="btn btn-info btn_shorten_url_clipboard mt8">Copy</button>
                <a role="button" t-attf-href="{{widget.link_obj.short_url}}+" class="btn btn-warning mt8">Stats</a>
            </div>
        </div>
    </t>
<t t-name="website_mass_mailing.edition.wrapper">
    <div class="modal fade show d-block o_newsletter_modal">
        <div role="dialog" class="modal-dialog modal-dialog-centered">
            <div class="modal-content">
                <header class="modal-header">
                    <button type="button" class="close" aria-label="Close" tabindex="-1">×</button>
                </header>
                <div id="wrapper" class="modal-body p-0 oe_structure oe_empty"/>
            </div>
        </div>
    </div>
</t>

</templates>`);
                    });