bienvenue sur
Move more !
Un nouvel espace pour votre pratique sportive, pensé pour vous, mais pas seulement…
Votre titre va ici
Your content goes here. Edit or remove this text inline or in the module Content settings. You can also style every aspect of this content in the module Design settings and even apply custom CSS to this text in the module Advanced settings.
Votre titre va ici
Your content goes here. Edit or remove this text inline or in the module Content settings. You can also style every aspect of this content in the module Design settings and even apply custom CSS to this text in the module Advanced settings.
(function(firebaseConfig, initialAuthToken, appId) {
window.__firebase_config = firebaseConfig;
window.__initial_auth_token = initialAuthToken;
window.__app_id = appId;
})("\n{\n \"apiKey\": \"AIzaSyCqyCcs2R2e7AegGjvFAwG98wlamtbHvZY\",\n \"authDomain\": \"bard-frontend.firebaseapp.com\",\n \"projectId\": \"bard-frontend\",\n \"storageBucket\": \"bard-frontend.firebasestorage.app\",\n \"messagingSenderId\": \"175205271074\",\n \"appId\": \"1:175205271074:web:2b7bd4d34d33bf38e6ec7b\"\n}\n","eyJhbGciOiJSUzI1NiIsImtpZCI6IjcxNmI5NDI0NGEwYzk3YjE5ZTA1YzM3NTU4ZTA2Y2ZhNTBlNDg2NTEiLCJ0eXAiOiJKV1QifQ.eyJzdWIiOiJmaXJlYmFzZS1hZG1pbnNkay1mYnN2Y0BiYXJkLWZyb250ZW5kLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYXVkIjoiaHR0cHM6Ly9pZGVudGl0eXRvb2xraXQuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLmlkZW50aXR5LmlkZW50aXR5dG9vbGtpdC52MS5JZGVudGl0eVRvb2xraXQiLCJ1aWQiOiIxMTg5NTU4MjczMDQ3MjkwODc1OSIsImlzcyI6ImZpcmViYXNlLWFkbWluc2RrLWZic3ZjQGJhcmQtZnJvbnRlbmQuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJjbGFpbXMiOnsiYXBwSWQiOiJjX2IyYzZkYjU4MDk1MjFiMmVfaW5kZXguaHRtbC0yNDAifSwiZXhwIjoxNzgxMDgwMzM1LCJpYXQiOjE3ODEwNzY3MzUsImFsZyI6IlJTMjU2In0.ImGjtzG4qjkC6IOmiXPzoQIJhgyV-inCBImxU2YKcriUxFluKYo_SFXW5bmU_5romXd9gHxVG4j6PIOJi8N_zEtWeSVswf5lUQ6zhZjt1UBwtumGhdTdHmhqYvsPenGu2q3USLOJEAODelqrSbXMSDe3NrkTGsu5s2xJyGuOBfhkuKrnGFhdfMCrUU9ExvULc-BL43eTjcS7e7n4pgIriMYx9JzPiuo8XPRHF-MLp9Obc8AFiado40E7AlVpFAGJ6G-4_8_T3NxjoGf1w5d9nOynHy1LBoNlXcS4NxuxX3sV4uOhbEPTksig46dp4ofEn9mIw9evfF8MCaJAvEdmRQ","c_b2c6db5809521b2e_index.html-240")(function(){'use strict';window.addEventListener("message",a=>{a.data&&a.data.type==="SUPPLEMENTAL_DATA_UPDATE"&&window.dispatchEvent(new CustomEvent("supplementaldataupdate",{detail:a.data.data}))});}).call(this);
(function(){'use strict';var h=typeof Object.defineProperties=="function"?Object.defineProperty:function(a,b,d){if(a==Array.prototype||a==Object.prototype)return a;a[b]=d.value;return a};function l(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var b=0;b{d[e]=c[e]})};var v=(()=>{var a=0;return()=>{a+=1;return`u${`0000${(Math.random()*1679616<<0).toString(36)}`.slice(-4)}${a}`}})();function w(a){var b=[];for(let d=0,c=a.length;d{var c=new Image;c.onload=()=>{c.decode().then(()=>{requestAnimationFrame(()=>b(c))})};c.onerror=d;c.crossOrigin="anonymous";c.decoding="async";c.src=a})}
function C(a){return t(function*(){return Promise.resolve().then(()=>(new XMLSerializer).serializeToString(a)).then(encodeURIComponent).then(b=>`data:image/svg+xml;charset=utf-8,${b}`)})}
function D(a,b,d){return t(function*(){var c=document.createElementNS("http://www.w3.org/2000/svg","svg"),e=document.createElementNS("http://www.w3.org/2000/svg","foreignObject");c.setAttribute("width",`${b}`);c.setAttribute("height",`${d}`);c.setAttribute("viewBox",`0 0 ${b} ${d}`);e.setAttribute("width","100%");e.setAttribute("height","100%");e.setAttribute("x","0");e.setAttribute("y","0");e.setAttribute("externalResourcesRequired","true");c.appendChild(e);e.appendChild(a);return C(c)})}
var E=(a,b)=>{if(a instanceof b)return!0;a=Object.getPrototypeOf(a);return a===null?!1:a.constructor.name===b.name||E(a,b)};function F(a,b){return y(b).map(d=>{var c=a.getPropertyValue(d),e=a.getPropertyPriority(d);return`${d}: ${c}${e?" !important":""};`}).join(" ")}
function G(a,b,d,c){a=window.getComputedStyle(a,d);var e=a.getPropertyValue("content");if(e!==""&&e!=="none"){var f=v();try{b.className=`${b.className} ${f}`}catch(k){return}e=document.createElement("style");var g=e.appendChild;d=`.${f}:${d}`;a.cssText?(c=a.getPropertyValue("content"),c=`${a.cssText} content: '${c.replace(/'|"/g,"")}';`):c=F(a,c);g.call(e,document.createTextNode(`${d}{${c}}`));b.appendChild(e)}};function H(a){return a.search(/^(data:)/)!==-1}function I(a,b,d){return t(function*(){var c=yield fetch(a,b);if(c.status===404)throw Error(`Resource "${c.url}" not found`);var e=yield c.blob();return new Promise((f,g)=>{var k=new FileReader;k.onerror=g;k.onloadend=()=>{try{f(d({o:c,result:k.result}))}catch(m){g(m)}};k.readAsDataURL(e)})})}const J={};function K(a,b,d){var c=a.replace(/\?.*/,"");d&&(c=a);/ttf|otf|eot|woff2?/i.test(c)&&(c=c.replace(/.*\//,""));return b?`[${b}]${c}`:c}
function L(a,b,d){return t(function*(){var c=K(a,b,d.C);if(J[c]!=null)return J[c];d.u&&(a+=(/\?/.test(a)?"&":"?")+(new Date).getTime());try{let f=yield I(a,d.i,({o:g,result:k})=>{b||(b=g.headers.get("Content-Type")||"");return k.split(/,/)[1]});var e=`data:${b};base64,${f}`}catch(f){e=d.B||""}return J[c]=e})};const M={P:"application/font-woff",R:"application/font-woff",N:"application/font-truetype",v:"application/vnd.ms-fontobject",H:"image/png",F:"image/jpeg",D:"image/jpeg",A:"image/gif",M:"image/tiff",L:"image/svg+xml",O:"image/webp"};function N(a){return(a=/\.([^./]*?)$/g.exec(a))?a[1]:""};function O(a){return t(function*(){var b=a.toDataURL();return b==="data:,"?a.cloneNode(!1):B(b)})}function aa(a,b){return t(function*(){if(a.currentSrc){var d=document.createElement("canvas");let c=d.getContext("2d");d.width=a.clientWidth;d.height=a.clientHeight;c==null||c.drawImage(a,0,0,d.width,d.height);d=d.toDataURL();return B(d)}d=a.poster;d=yield L(d,M[N(d).toLowerCase()]||"",b);return B(d)})}
function ba(a,b){return t(function*(){try{let d;if(a==null?0:(d=a.contentDocument)==null?0:d.body)return yield P(a.contentDocument.body,b,!0)}catch(d){}return a.cloneNode(!1)})}function ca(a,b){return t(function*(){return E(a,HTMLCanvasElement)?O(a):E(a,HTMLVideoElement)?aa(a,b):E(a,HTMLIFrameElement)?ba(a,b):a.cloneNode(a.tagName!=null&&a.tagName.toUpperCase()==="SVG")})}
function da(a,b,d){return t(function*(){if(b.tagName!=null&&b.tagName.toUpperCase()==="SVG")return b;var c=[];if(a.tagName!=null&&a.tagName.toUpperCase()==="SLOT"&&a.assignedNodes)c=w(a.assignedNodes());else{let e;if(E(a,HTMLIFrameElement)&&((e=a.contentDocument)==null?0:e.body))c=w(a.contentDocument.body.childNodes);else{let f;c=w(((f=a.shadowRoot)!=null?f:a).childNodes)}}if(c.length===0||E(a,HTMLVideoElement))return b;yield c.reduce((e,f)=>e.then(()=>P(f,d)).then(g=>{g&&b.appendChild(g)}),Promise.resolve());
return b})}function ea(a,b,d){var c=b.style;if(c){var e=window.getComputedStyle(a);e.cssText?(c.cssText=e.cssText,c.transformOrigin=e.transformOrigin):y(d).forEach(f=>{var g=e.getPropertyValue(f);f==="font-size"&&g.endsWith("px")&&(g=`${Math.floor(parseFloat(g.substring(0,g.length-2)))-.1}px`);E(a,HTMLIFrameElement)&&f==="display"&&g==="inline"&&(g="block");f==="d"&&b.getAttribute("d")&&(g=`path(${b.getAttribute("d")})`);c.setProperty(f,g,e.getPropertyPriority(f))})}}
function fa(a,b){E(a,HTMLSelectElement)&&(b=Array.from(b.children).find(d=>a.value===d.getAttribute("value")))&&b.setAttribute("selected","")}
function ha(a,b){return t(function*(){var d=a.querySelectorAll?a.querySelectorAll("use"):[];if(d.length===0)return a;var c={};for(var e=0;eca(c,b)).then(c=>da(a,c,b)).then(c=>{E(c,Element)&&(ea(a,c,b),G(a,c,":before",b),G(a,c,":after",b),E(a,HTMLTextAreaElement)&&(c.textContent=a.value),E(a,HTMLInputElement)&&c.setAttribute("value",a.value),fa(a,c));return c}).then(c=>ha(c,b)):null})};const Q=/url\((['"]?)([^'"]+?)\1\)/g,ia=/url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g,ja=/src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;function ka(a){var b=[];a.replace(Q,(d,c,e)=>{b.push(e);return d});return b.filter(d=>!H(d))}
function la(a,b,d,c){return t(function*(){try{let e=d?(new URL(b,d||void 0)).toString():b,f;f=yield L(e,M[N(b).toLowerCase()]||"",c);return a.replace(new RegExp(`(url\\(['"]?)(${b.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")})(['"]?\\))`,"g"),`$1${f}$3`)}catch(e){}return a})}function ma(a,{I:b}){return b?a.replace(ja,d=>{for(;;){let [c,,e]=ia.exec(d)||[];if(!e)return"";if(e===b)return`src: ${c};`}}):a}
function R(a,b,d){return t(function*(){if(a.search(Q)===-1)return a;var c=ma(a,d);return ka(c).reduce((e,f)=>e.then(g=>la(g,f,b,d)),Promise.resolve(c))})};function S(a,b,d){return t(function*(){var c,e=(c=b.style)==null?void 0:c.getPropertyValue(a);return e?(c=yield R(e,null,d),b.style.setProperty(a,c,b.style.getPropertyPriority(a)),!0):!1})}function na(a,b){return t(function*(){(yield S("background",a,b))||(yield S("background-image",a,b));(yield S("mask",a,b))||(yield S("-webkit-mask",a,b))||(yield S("mask-image",a,b))||(yield S("-webkit-mask-image",a,b))})}
function oa(a,b){return t(function*(){var d=E(a,HTMLImageElement);if(d&&!H(a.src)||E(a,SVGImageElement)&&!H(a.href.baseVal)){var c=d?a.src:a.href.baseVal,e=yield L(c,M[N(c).toLowerCase()]||"",b);yield new Promise((f,g)=>{a.onload=f;a.onerror=b.m?(...k)=>{try{f(b.m(...k))}catch(m){g(m)}}:g;a.decode&&(a.decode=f);a.loading==="lazy"&&(a.loading="eager");d?(a.srcset="",a.src=e):a.href.baseVal=e})}})}
function pa(a,b){return t(function*(){var d=w(a.childNodes).map(c=>T(c,b));yield Promise.all(d).then(()=>a)})}function T(a,b){return t(function*(){E(a,Element)&&(yield na(a,b),yield oa(a,b),yield pa(a,b))})};const U={};function V(a){return t(function*(){var b=U[a];if(b!=null)return b;b=yield(yield fetch(a)).text();b={url:a,cssText:b};return U[a]=b})}function W(a,b){return t(function*(){var d=a.cssText,c=/url\(["']?([^"')]+)["']?\)/g,e=(d.match(/url\([^)]+\)/g)||[]).map(f=>t(function*(){var g=f.replace(c,"$1");g.startsWith("https://")||(g=(new URL(g,a.url)).href);return I(g,b.i,({result:k})=>{d=d.replace(f,`url(${k})`);return[f,k]})}));return Promise.all(e).then(()=>d)})}
function X(a){if(a==null)return[];var b=[];a=a.replace(/(\/\*[\s\S]*?\*\/)/gi,"");for(var d=RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})","gi");;){var c=d.exec(a);if(c===null)break;b.push(c[0])}a=a.replace(d,"");d=/@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi;for(c=RegExp("((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})","gi");;){let e=d.exec(a);if(e===null)if(e=c.exec(a),e===null)break;else d.lastIndex=c.lastIndex;else c.lastIndex=
d.lastIndex;b.push(e[0])}return b}
function qa(a,b){return t(function*(){var d=[],c=[];a.forEach(e=>{if("cssRules"in e)try{w(e.cssRules||[]).forEach((f,g)=>{if(f.type===CSSRule.IMPORT_RULE){let k=g+1;f=V(f.href).then(m=>W(m,b)).then(m=>X(m).forEach(q=>{try{e.insertRule(q,q.startsWith("@import")?k+=1:e.cssRules.length)}catch(Da){}})).catch(()=>{});c.push(f)}})}catch(f){let g=a.find(k=>k.href==null)||document.styleSheets[0];e.href!=null&&c.push(V(e.href).then(k=>W(k,b)).then(k=>X(k).forEach(m=>{g.insertRule(m,g.cssRules.length)})).catch(()=>
{}))}});return Promise.all(c).then(()=>{a.forEach(e=>{if("cssRules"in e)try{w(e.cssRules||[]).forEach(f=>{d.push(f)})}catch(f){}});return d})})}function ra(a){return a.filter(b=>b.type===CSSRule.FONT_FACE_RULE).filter(b=>b.style.getPropertyValue("src").search(Q)!==-1)}function sa(a,b){return t(function*(){if(a.ownerDocument==null)throw Error("Provided element is not within a Document");var d=w(a.ownerDocument.styleSheets);d=yield qa(d,b);return ra(d)})}
function ta(a){function b(c){(c.style.fontFamily||getComputedStyle(c).fontFamily).split(",").forEach(e=>{d.add(e.trim().replace(/["']/g,""))});Array.from(c.children).forEach(e=>{e instanceof HTMLElement&&b(e)})}var d=new Set;b(a);return d}function ua(a,b){return t(function*(){var d=yield sa(a,b),c=ta(a);return(yield Promise.all(d.filter(e=>c.has(e.style.fontFamily.trim().replace(/["']/g,""))).map(e=>R(e.cssText,e.parentStyleSheet?e.parentStyleSheet.href:null,b)))).join("\n")})}
function va(a,b){return t(function*(){var d=b.j!=null?b.j:b.K?null:yield ua(a,b);if(d){let c=document.createElement("style");c.appendChild(document.createTextNode(d));a.firstChild?a.insertBefore(c,a.firstChild):a.appendChild(c)}})};function wa(a,b={}){return t(function*(){var {width:d,height:c}=A(a,b),e=yield P(a,b,!0);yield va(e,b);yield T(e,b);u(e,b);return yield D(e,d,c)})}
function xa(a,b={}){return t(function*(){var {width:d,height:c}=A(a,b),e=yield wa(a,b);e=yield B(e);var f=document.createElement("canvas"),g=f.getContext("2d"),k=b.G||window.devicePixelRatio||1,m=b.h||d,q=b.g||c;f.width=m*k;f.height=q*k;!b.J&&(f.width>16384||f.height>16384)&&(f.width>16384&&f.height>16384?f.width>f.height?(f.height*=16384/f.width,f.width=16384):(f.width*=16384/f.height,f.height=16384):f.width>16384?(f.height*=16384/f.width,f.width=16384):(f.width*=16384/f.height,f.height=16384));
f.style.width=`${m}`;f.style.height=`${q}`;b.backgroundColor&&(g.fillStyle=b.backgroundColor,g.fillRect(0,0,f.width,f.height));g.drawImage(e,0,0,f.width,f.height);return f})}function ya(a,b={}){return t(function*(){return(yield xa(a,b)).toDataURL()})};const za=["gemini.google.com","corp.google.com","proxy.googlers.com"];function Y(){return document.body.querySelectorAll('[class*="animate"]').length>0}function Z(a){return t(function*(){try{return yield ya(a,{h:a.offsetWidth,g:a.offsetHeight})}catch(d){var b=a.offsetHeight;let c=document.createElement("canvas");c.width=a.offsetWidth;c.height=b;return c.toDataURL("image/png")}})}
function Aa(){return t(function*(){var a=document.body.offsetWidth,b=document.body.offsetHeight,d=document.body.cloneNode(!0);d.querySelectorAll('[class*="animate"]').forEach(c=>{c.classList.remove(...Array.from(c.classList).filter(e=>e.startsWith("animate")))});d.style.width=`${a}px`;d.style.height=`${b}px`;return d})}
function Ba(a){return t(function*(){var b=document.body;if(Y()){var d=yield Aa();b=d;document.body.appendChild(d)}d=yield Z(b);Y()&&document.body.removeChild(b);window.parent.postMessage({type:"SEND_SCREENSHOT",image:d,topOffset:document.documentElement.scrollTop},a.origin)})}function Ca(a){return t(function*(){var b={type:"SEND_SCREENSHOT_FOR_DATA_VISUALIZATION",image:yield Z(document.body),topOffset:0};window.parent.postMessage(b,a.origin)})}
window.addEventListener("message",a=>t(function*(){if(za.some(d=>a.origin.includes(d))){var b=a.data;b&&(b.type==="MAKE_SCREENSHOT"&&(yield Ba(a)),b.type==="MAKE_SCREENSHOT_FOR_DATA_VISUALIZATION"&&(yield Ca(a)))}}));
})();(function() {
// Ensure this script is executed only once
if (window.firebaseAuthBridgeScriptLoaded) {
return;
}
window.firebaseAuthBridgeScriptLoaded = true;
let nextTokenPromiseId = 0;
// Stores { resolve, reject } for ongoing token requests
const pendingTokenPromises = {};
// Listen for messages from the Host Application
window.addEventListener('message', function(event) {
const messageData = event.data;
if (messageData && messageData.type === 'RESOLVE_NEW_FIREBASE_TOKEN') {
const { success, token, error, promiseId } = messageData ?? {};
if (pendingTokenPromises[promiseId]) {
if (success) {
pendingTokenPromises[promiseId].resolve(token);
} else {
pendingTokenPromises[promiseId].reject(new Error(error || 'Token refresh failed from host.'));
}
delete pendingTokenPromises[promiseId];
}
}
});
// Expose a function for the Generated App to request a new Firebase token
window.requestNewFirebaseToken = function() {
const currentPromiseId = nextTokenPromiseId++;
const promise = new Promise((resolve, reject) => {
pendingTokenPromises[currentPromiseId] = { resolve, reject };
});
if (window.parent && window.parent !== window) {
window.parent.postMessage({
type: 'REQUEST_NEW_FIREBASE_TOKEN',
promiseId: currentPromiseId
}, '*');
} else {
pendingTokenPromises[currentPromiseId].reject(new Error('No parent window to request token from.'));
delete pendingTokenPromises[currentPromiseId];
}
return promise;
};
})();
let realOriginalGetUserMedia = null;
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
realOriginalGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);
}
(function() {
if (navigator.mediaDevices && navigator.mediaDevices.__proto__) {
try {
Object.defineProperty(navigator.mediaDevices.__proto__, 'getUserMedia', {
get: function() {
return undefined; // Or throw an error
},
configurable: false
});
} catch (error) {
console.error("Error defining prototype getter:", error);
}
}
})();
(function() {
const pendingMediaResolvers = {};
let nextMediaPromiseId = 0;
function requestMediaPermissions(constraints) {
const mediaPromiseId = nextMediaPromiseId++;
const promise = new Promise((resolve, reject) => {
pendingMediaResolvers[mediaPromiseId] = (granted) => {
delete pendingMediaResolvers[mediaPromiseId];
resolve(granted);
};
});
window.parent.postMessage({
type: 'requestMediaPermission',
constraints: constraints,
promiseId: mediaPromiseId,
}, '*');
return promise;
}
let originalGetUserMedia = realOriginalGetUserMedia;
function interceptGetUserMedia() {
if (navigator.mediaDevices) {
Object.defineProperty(navigator.mediaDevices, 'getUserMedia', {
value: function(constraints) {
return requestMediaPermissions(constraints).then((granted) => {
if (granted) {
if (originalGetUserMedia) {
return originalGetUserMedia(constraints);
} else {
throw new Error("Original getUserMedia not available.");
}
} else {
throw new DOMException('Permission denied', 'NotAllowedError');
}
});
},
writable: false,
configurable: false
});
}
}
interceptGetUserMedia();
const observer = new MutationObserver(function(mutationsList, observer) {
for (const mutation of mutationsList) {
if (mutation.type === 'reconfigured' && mutation.name === 'getUserMedia' && mutation.object === navigator.mediaDevices) {
interceptGetUserMedia();
} else if (mutation.type === 'attributes' && mutation.attributeName === 'getUserMedia' && mutation.target === navigator.mediaDevices) {
interceptGetUserMedia();
} else if (mutation.type === 'childList' && mutation.addedNodes) {
mutation.addedNodes.forEach(node => {
if (node === navigator.mediaDevices) {
interceptGetUserMedia();
}
});
}
}
});
function interceptSpeechRecognition() {
if (!window.SpeechRecognition && !window.webkitSpeechRecognition) {
return;
}
const OriginalSpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
const SpeechRecognitionWrapper = function(...args) {
const recognizer = new OriginalSpeechRecognition(...args);
const originalStart = recognizer.start.bind(recognizer);
recognizer.start = function() {
requestMediaPermissions({ audio: true }).then(granted => {
if (granted) {
originalStart();
} else {
const errorEvent = new SpeechRecognitionErrorEvent('error');
errorEvent.error = 'not-allowed'; // This is the standard error for permission denial.
recognizer.dispatchEvent(errorEvent);
}
});
};
return recognizer;
};
SpeechRecognitionWrapper.prototype = OriginalSpeechRecognition.prototype;
SpeechRecognitionWrapper.prototype.constructor = SpeechRecognitionWrapper;
if (window.SpeechRecognition) {
window.SpeechRecognition = SpeechRecognitionWrapper;
}
if (window.webkitSpeechRecognition) {
window.webkitSpeechRecognition = SpeechRecognitionWrapper;
}
}
interceptSpeechRecognition();
window.addEventListener('message', function(event) {
if (event.data) {
if (event.data.type === 'resolveMediaPermission') {
const { promiseId, granted } = event.data;
if (pendingMediaResolvers[promiseId]) {
pendingMediaResolvers[promiseId](granted);
}
}
}
});
})();(function(){'use strict';var u=typeof Object.defineProperties=="function"?Object.defineProperty:function(b,d,e){if(b==Array.prototype||b==Object.prototype)return b;b[d]=e.value;return b};function v(b){b=["object"==typeof globalThis&&globalThis,b,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var d=0;d{if(a.data.type==="message"){a=new MessageEvent("message",{data:G.decode(a.data.data)});
let f;(f=c.onmessage)==null||f.call(c,a);c.dispatchEvent(a)}}}function n(){if(!t)throw Error("Control port not captured yet.");t.onmessage=a=>{switch(a.data.type){case "open":l=1;var f=new Event("open"),g;(g=c.onopen)==null||g.call(c,f);c.dispatchEvent(f);q.forEach(H=>{k(H)});q=[];break;case "close":g=a.data;l=3;g=new CloseEvent("close",{code:g.code,reason:g.reason,wasClean:g.wasClean});(f=c.onclose)==null||f.call(c,g);c.dispatchEvent(g);break;case "error":l=3;f=new Event("error");let x;(x=c.onerror)==
null||x.call(c,f);c.dispatchEvent(f)}}}function p(a){return z(function*(){var f=new MessageChannel;t=f.port1;var g=new MessageChannel;r=g.port1;n();m();window.parent.postMessage({type:"websocket_open",portOrdering:["control","data"],url:b,protocols:a||[],connectionId:I},e,[f.port2,g.port2])}())}var c=Reflect.construct(EventTarget,[],new.target);c.CONNECTING=0;c.OPEN=1;c.CLOSING=2;c.CLOSED=3;c.url=b;c.binaryType="arraybuffer";c.protocol="";c.h="";var l=0,t=null,r=null,q=[],F=new TextEncoder,G=new TextDecoder;
c.onopen=null;c.onmessage=null;c.onclose=null;c.onerror=null;Object.defineProperty(c,"readyState",{get:()=>l,enumerable:!0,configurable:!0});Object.defineProperty(c,"bufferedAmount",{get:()=>{var a=0;q.forEach(f=>{a+=typeof f==="string"?f.length:f.byteLength});return a},enumerable:!0,configurable:!0});var I=function(){var a;return((a=globalThis.crypto)==null?0:a.randomUUID)?globalThis.crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,f=>{var g=Math.random()*16|0;return(f===
"x"?g:g&3|8).toString(16)})}();c.send=a=>{if(l===1)a instanceof Blob?a.arrayBuffer().then(f=>{k(f)}):k(a);else if(l===0)if(typeof a==="string")q.push(a);else if(a instanceof ArrayBuffer||ArrayBuffer.isView(a))q.push(h(a));else throw Error("Sending Blob is not supported before the connection is open.");else console.debug("WebSocket send called in CLOSING or CLOSED state; ignored.")};c.close=(a=1E3,f="")=>{if(l!==2&&l!==3){l=2;a={type:"close",code:a,reason:f,wasClean:a===1E3};var g;(g=t)==null||g.postMessage(a)}};
Promise.resolve().then(()=>p(d));return c}A(B,EventTarget);var C=document.currentScript,D=C==null?void 0:C.getAttribute("ws-interception-config");if(!D)throw Error("WebSocket Interceptor: Missing ws-interception-config attribute in the script tag.");var E=JSON.parse(D);if(!E.parentOrigin||typeof E.parentOrigin!=="string")throw Error("WebSocket Interceptor: Invalid parentOrigin in ws-interception-config");
(function(b){var d=Object.getOwnPropertyDescriptor(window,"WebSocket");if(!d||d.writable||d.configurable)d=Object.assign(function(e,h){try{let k=(new URL(e)).hostname;if(b.proxiedDomains.some(m=>k===m||k.endsWith(`.${m}`)))return new B(e,h,b.parentOrigin)}catch(k){throw window.parent.postMessage({type:"websocket_blocked",url:e,reason:"blocked_invalid_url"},b.parentOrigin),new DOMException(`WebSocket connection to '${e}' is not allowed in Canvas.`,"SecurityError");}window.parent.postMessage({type:"websocket_blocked",
url:e,reason:"blocked_domain_not_allowlisted"},b.parentOrigin);throw new DOMException(`WebSocket connection to '${e}' is not allowed in Canvas.`,"SecurityError");},{CONNECTING:0,OPEN:1,CLOSING:2,CLOSED:3}),Object.defineProperty(window,"WebSocket",{value:d,writable:!1,configurable:!1})})({proxiedDomains:E.proxiedDomains||[],parentOrigin:E.parentOrigin});}).call(this);
((function(modelInformation) {
const originalFetch = window.fetch;
// TODO: b/421908508 - Move these out of the script and match all generative AI model calls.
let googleLlmBaseApiUrls = [
'https://generativelanguage.googleapis.com/v1beta/models/' + modelInformation.textModelName + ':streamGenerateContent',
'https://generativelanguage.googleapis.com/v1beta/models/' + modelInformation.textModelName + ':generateContent',
'https://generativelanguage.googleapis.com/v1beta/models/' + modelInformation.imageModelName + ':predict',
'https://generativelanguage.googleapis.com/v1beta/models/' + modelInformation.imageModelName + ':predictLongRunning',
'https://generativelanguage.googleapis.com/v1beta/models/' + modelInformation.imageEditModelName + ':generateContent',
'https://generativelanguage.googleapis.com/v1beta/models/' + modelInformation.imageTransformModelName + ':generateContent',
'https://generativelanguage.googleapis.com/v1beta/models/' + modelInformation.videoModelName + ':predict',
'https://generativelanguage.googleapis.com/v1beta/models/' + modelInformation.videoModelName + ':predictLongRunning',
'https://generativelanguage.googleapis.com/v1beta/models/' + modelInformation.ttsModelName + ':generateContent',
];
modelInformation.deprecatedTextModelNames.forEach((modelName) => {
googleLlmBaseApiUrls.push(
'https://generativelanguage.googleapis.com/v1beta/models/' + modelName + ':streamGenerateContent',
'https://generativelanguage.googleapis.com/v1beta/models/' + modelName + ':generateContent',
);
});
modelInformation.deprecatedImageModelNames.forEach((modelName) => {
googleLlmBaseApiUrls.push(
'https://generativelanguage.googleapis.com/v1beta/models/' + modelName + ':predict',
'https://generativelanguage.googleapis.com/v1beta/models/' + modelName + ':predictLongRunning',
'https://generativelanguage.googleapis.com/v1beta/models/' + modelName + ':generateContent',
'https://generativelanguage.googleapis.com/v1beta/models/' + modelName + ':streamGenerateContent',
);
});
modelInformation.deprecatedGenerateImageModelNames.forEach((modelName) => {
googleLlmBaseApiUrls.push(
'https://generativelanguage.googleapis.com/v1beta/models/' + modelName + ':generateContent',
'https://generativelanguage.googleapis.com/v1beta/models/' + modelName + ':streamGenerateContent',
);
});
const pendingFetchResolvers = {};
let nextPromiseId = 0;
function handleStringInput(input, optionsArgument) {
const actualUrl = input;
const fetchCallArgs = [actualUrl, optionsArgument];
const effectiveOptions = optionsArgument || {};
const bodyForApiKeyCheck = effectiveOptions.body;
const bodyForPostMessage = effectiveOptions.body;
return { actualUrl, fetchCallArgs, effectiveOptions, bodyForApiKeyCheck, bodyForPostMessage };
}
function handleRequestInput(input, optionsArgument) {
const actualUrl = input.url;
const fetchCallArgs = [input, optionsArgument];
const effectiveOptions = { method: input.method, headers: new Headers(input.headers) };
let bodyForApiKeyCheck;
let bodyForPostMessage;
if (optionsArgument) {
if (optionsArgument.method) effectiveOptions.method = optionsArgument.method;
if (optionsArgument.headers) effectiveOptions.headers = new Headers(optionsArgument.headers);
if ('body' in optionsArgument) {
bodyForApiKeyCheck = optionsArgument.body;
bodyForPostMessage = optionsArgument.body;
} else {
bodyForApiKeyCheck = undefined;
bodyForPostMessage = input.body;
}
} else {
bodyForApiKeyCheck = undefined;
bodyForPostMessage = input.body;
}
return { actualUrl, fetchCallArgs, effectiveOptions, bodyForApiKeyCheck, bodyForPostMessage };
}
window.fetch = function(input, optionsArgument) {
let actualUrl;
let fetchCallArgs;
let effectiveOptions = {};
let bodyForApiKeyCheck;
let bodyForPostMessage;
if (typeof input === 'string') {
({actualUrl, fetchCallArgs, effectiveOptions, bodyForApiKeyCheck, bodyForPostMessage} = handleStringInput(input, optionsArgument));
} else if (input instanceof Request) {
({actualUrl, fetchCallArgs, effectiveOptions, bodyForApiKeyCheck, bodyForPostMessage} = handleRequestInput(input, optionsArgument));
} else {
return originalFetch.apply(window, [input, optionsArgument]);
}
effectiveOptions.method = effectiveOptions.method || 'GET';
if (!effectiveOptions.headers) {
effectiveOptions.headers = new Headers();
}
if (typeof actualUrl === 'string' && googleLlmBaseApiUrls.some((url) => actualUrl.startsWith(url))) {
let apiKeyIsNull = true;
const regex = new RegExp("models/([^:]+)");
const modelNameMatch = actualUrl.match(regex);
const modelName = modelNameMatch ? modelNameMatch[1] : 'unspecified';
try {
const urlObject = new URL(actualUrl); // Use URL object for robust parsing
const apiKeyParam = urlObject.searchParams.get('key');
if (apiKeyParam) {
apiKeyIsNull = false;
}
} catch (e) {
// Continue checks even if URL parsing fails
}
if (apiKeyIsNull && effectiveOptions.headers) {
const h = new Headers(effectiveOptions.headers);
const apiKeyHeaderValue = h.get('X-API-Key') || h.get('x-api-key');
if (apiKeyHeaderValue) {
apiKeyIsNull = false;
return originalFetch.apply(window, fetchCallArgs);
}
}
if (apiKeyIsNull && effectiveOptions.method && ['POST', 'PUT', 'PATCH'].includes(effectiveOptions.method.toUpperCase()) && typeof bodyForApiKeyCheck === 'string') {
try {
const bodyData = JSON.parse(bodyForApiKeyCheck);
if (bodyData && bodyData.apiKey) {
apiKeyIsNull = false;
return originalFetch.apply(window, fetchCallArgs);
}
} catch (e) {
// Ignore JSON parsing errors
}
}
if(apiKeyIsNull) {
const promiseId = nextPromiseId++;
const promise = new Promise((resolve) => {
pendingFetchResolvers[promiseId] = (resolvedResponse) => {
delete pendingFetchResolvers[promiseId];
resolve(resolvedResponse);
};
});
let serializedBodyForPostMessage;
if (typeof bodyForPostMessage === 'string' || bodyForPostMessage == null) {
serializedBodyForPostMessage = bodyForPostMessage;
} else if (bodyForPostMessage instanceof ReadableStream) {
serializedBodyForPostMessage = null;
} else {
try {
serializedBodyForPostMessage = JSON.stringify(bodyForPostMessage);
} catch (e) {
serializedBodyForPostMessage = null;
}
}
const messageOptions = {
method: effectiveOptions.method,
headers: Object.fromEntries(new Headers(effectiveOptions.headers).entries()),
body: serializedBodyForPostMessage
};
window.parent.postMessage({
type: 'requestFetch',
url: actualUrl,
modelName: modelName,
options: messageOptions,
promiseId: promiseId,
}, '*');
return promise;
}
return originalFetch.apply(window, fetchCallArgs);
}
return originalFetch.apply(window, fetchCallArgs);
};
window.addEventListener('message', function(event) {
if (event.data && event.data.type === 'resolveFetch') {
const { promiseId, response } = event.data;
if (pendingFetchResolvers[promiseId]) {
try {
const reconstructedResponse = new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: new Headers(response.headers),
});
pendingFetchResolvers[promiseId](reconstructedResponse);
} catch (error) {
pendingFetchResolvers[promiseId](new Response(null, { status: 500, statusText: "Interceptor Response Reconstruction Error" }));
}
}
}
});
}))({"textModelName":"gemini-3-flash-preview","imageModelName":"imagen-4.0-generate-001","imageEditModelName":"gemini-3.1-flash-image-preview","imageTransformModelName":"gemini-3-pro-image-preview-11-2025","videoModelName":"veo-2.0-generate-001","ttsModelName":"gemini-2.5-flash-preview-tts","deprecatedTextModelNames":["gemini-2.0-flash","gemini-2.5-flash","gemini-2.5-flash-preview-04-17","gemini-2.5-flash-preview-05-20","gemini-2.5-flash-preview-09-2025"],"deprecatedImageModelNames":["imagen-3.0-generate-001","imagen-3.0-generate-002"],"deprecatedGenerateImageModelNames":["gemini-2.5-flash-image-preview","gemini-2.5-flash-image"]})(function(){'use strict';function a(){window.parent.postMessage({type:"interaction"},"*")}window.addEventListener("click",a,{capture:!0,passive:!0});window.addEventListener("touchstart",a,{capture:!0,passive:!0});window.addEventListener("keydown",a,{capture:!0,passive:!0});}).call(this);
(function() {
const originalConsoleLog = console.log;
const originalConsoleError = console.error;
/**
* Normalizes an error event or a promise rejection reason into a structured error object.
* @param {*} errorEventOrReason The error object or reason.
* @return {object} Structured error data { message, name, stack }.
*/
function getErrorObject(errorEventOrReason) {
if (errorEventOrReason instanceof Error) {
return {
message: errorEventOrReason.message,
name: errorEventOrReason.name,
stack: errorEventOrReason.stack,
};
}
// Fallback for non-Error objects.
try {
return {
message: JSON.stringify(errorEventOrReason),
name: 'UnknownErrorType',
stack: null,
};
} catch (e) {
return {
message: String(errorEventOrReason),
name: 'UnknownErrorTypeNonStringifiable',
stack: null,
};
}
}
/**
* Converts an array of arguments (from log/error) into a single string.
* Handles Error objects specially to include their message and stack.
* @param {Array<*>} args - Arguments passed to console methods.
* @return {string} A string representation of the arguments.
*/
function stringifyArgs(args) {
return args
.map((arg) => {
if (arg instanceof Error) {
const {message, stack} = arg;
return `Error: ${message}${stack ? ('\nStack: ' + stack) : ''}`;
}
if (typeof arg === 'object' && arg !== null) {
try {
return JSON.stringify(arg);
} catch (error) {
return '[Circular Object]';
}
} else {
return String(arg);
}
})
.join(' ');
}
console.log = function(...args) {
const logString = stringifyArgs(args);
window.parent.postMessage({ type: 'log', message: logString }, '*');
originalConsoleLog.apply(console, args);
};
console.error = function(...args) {
let errorData;
if (args.length > 0 && args[0] instanceof Error) {
const err = args[0];
// If the first arg is an Error, capture its details.
errorData = {
type: 'error',
source: 'CONSOLE_ERROR',
...getErrorObject(err),
rawArgsString: stringifyArgs(args.slice(1)),
timestamp: new Date().toISOString(),
};
} else {
// If not an Error object, treat all args as a general error message.
errorData = {
type: 'error',
source: 'CONSOLE_ERROR',
message: stringifyArgs(args),
name: 'ConsoleLoggedError',
stack: null,
timestamp: new Date().toISOString(),
};
}
window.parent.postMessage(errorData, '*');
originalConsoleError.apply(console, args);
};
// Listen for global unhandled synchronous errors.
window.addEventListener('error', function(event) {
const errorDetails = event.error ? getErrorObject(event.error) : {
message: event.message,
name: 'GlobalError',
stack: null,
filename: event.filename,
lineno: event.lineno,
colno: event.colno,
};
window.parent.postMessage({
type: 'error',
source: 'global',
...errorDetails,
message: errorDetails.message || event.message,
timestamp: new Date().toISOString(),
}, '*');
});
// Listen for unhandled promise rejections (asynchronous errors).
window.addEventListener('unhandledrejection', function(event) {
const errorDetails = getErrorObject(event.reason);
window.parent.postMessage({
type: 'error',
source: 'unhandledrejection',
...errorDetails,
message: errorDetails.message || 'Unhandled Promise Rejection',
timestamp: new Date().toISOString(),
}, '*');
});
})();
Move More Hub - Infographie Interactive Responsive
body {
font-family: 'Inter', sans-serif;
background-color: #0b1528; /* Bleu Royal Uni et Profond */
}
/* Effet de verre dépoli (Glassmorphism) */
.glass-card {
background: rgba(255, 255, 255, 0.03);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.12);
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.glass-card:hover {
background: rgba(255, 255, 255, 0.06);
border-color: var(--accent-color, rgba(255, 255, 255, 0.25));
transform: translateY(-4px);
box-shadow: 0 12px 40px 0 var(--accent-glow, rgba(59, 130, 246, 0.15));
}
*, ::before, ::after{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/* ! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com */*,::after,::before{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}::after,::before{--tw-content:''}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.pointer-events-none{pointer-events:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0px}.right-0{right:0px}.top-0{top:0px}.right-2{right:0.5rem}.top-2{top:0.5rem}.z-10{z-index:10}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.my-2{margin-top:0.5rem;margin-bottom:0.5rem}.mb-1{margin-bottom:0.25rem}.mb-6{margin-bottom:1.5rem}.mt-1{margin-top:0.25rem}.mt-8{margin-top:2rem}.mb-1\.5{margin-bottom:0.375rem}.mb-3{margin-bottom:0.75rem}.block{display:block}.flex{display:flex}.grid{display:grid}.h-10{height:2.5rem}.h-2\.5{height:0.625rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-full{height:100%}.h-14{height:3.5rem}.h-16{height:4rem}.h-8{height:2rem}.min-h-screen{min-height:100vh}.min-h-\[310px\]{min-height:310px}.w-10{width:2.5rem}.w-2\.5{width:0.625rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-full{width:100%}.w-14{width:3.5rem}.w-20{width:5rem}.w-8{width:2rem}.max-w-7xl{max-width:80rem}.flex-grow{flex-grow:1}.translate-x-full{--tw-translate-x:100%;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite}.cursor-pointer{cursor:pointer}.grid-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr))}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2{gap:0.5rem}.gap-3{gap:0.75rem}.gap-4{gap:1rem}.space-y-4 > :not([hidden]) ~ :not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6 > :not([hidden]) ~ :not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-3 > :not([hidden]) ~ :not([hidden]){--tw-space-y-reverse:0;margin-top:calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0.75rem * var(--tw-space-y-reverse))}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.rounded{border-radius:0.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:0.5rem}.rounded-xl{border-radius:0.75rem}.border{border-width:1px}.border-0{border-width:0px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-t{border-top-width:1px}.border-white\/10{border-color:rgb(255 255 255 / 0.1)}.border-white\/15{border-color:rgb(255 255 255 / 0.15)}.border-white\/5{border-color:rgb(255 255 255 / 0.05)}.bg-cyan-400{--tw-bg-opacity:1;background-color:rgb(34 211 238 / var(--tw-bg-opacity, 1))}.bg-slate-800{--tw-bg-opacity:1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.bg-slate-900{--tw-bg-opacity:1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.bg-slate-700{--tw-bg-opacity:1;background-color:rgb(51 65 85 / var(--tw-bg-opacity, 1))}.bg-slate-800\/50{background-color:rgb(30 41 59 / 0.5)}.bg-transparent{background-color:transparent}.bg-gradient-to-r{background-image:linear-gradient(to right, var(--tw-gradient-stops))}.from-cyan-500{--tw-gradient-from:#06b6d4 var(--tw-gradient-from-position);--tw-gradient-to:rgb(6 182 212 / 0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to)}.to-blue-600{--tw-gradient-to:#2563eb var(--tw-gradient-to-position)}.p-1{padding:0.25rem}.p-6{padding:1.5rem}.p-3{padding:0.75rem}.p-4{padding:1rem}.px-3{padding-left:0.75rem;padding-right:0.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-2{padding-top:0.5rem;padding-bottom:0.5rem}.py-3{padding-top:0.75rem;padding-bottom:0.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.px-1{padding-left:0.25rem;padding-right:0.25rem}.px-1\.5{padding-left:0.375rem;padding-right:0.375rem}.px-2{padding-left:0.5rem;padding-right:0.5rem}.px-2\.5{padding-left:0.625rem;padding-right:0.625rem}.py-0\.5{padding-top:0.125rem;padding-bottom:0.125rem}.py-1\.5{padding-top:0.375rem;padding-bottom:0.375rem}.pb-4{padding-bottom:1rem}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.pt-8{padding-top:2rem}.text-center{text-align:center}.font-mono{font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-sm{font-size:0.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:0.75rem;line-height:1rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-0.025em}.tracking-wider{letter-spacing:0.05em}.tracking-widest{letter-spacing:0.1em}.text-cyan-400{--tw-text-opacity:1;color:rgb(34 211 238 / var(--tw-text-opacity, 1))}.text-emerald-400{--tw-text-opacity:1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity:1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-slate-300{--tw-text-opacity:1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity:1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.opacity-0{opacity:0}.shadow-2xl{--tw-shadow:0 25px 50px -12px rgb(0 0 0 / 0.25);--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}.shadow-cyan-500\/20{--tw-shadow-color:rgb(6 182 212 / 0.2);--tw-shadow:var(--tw-shadow-colored)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms}.duration-300{transition-duration:300ms}.ease-in-out{transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1)}.hover\:bg-slate-700:hover{--tw-bg-opacity:1;background-color:rgb(51 65 85 / var(--tw-bg-opacity, 1))}.hover\:from-cyan-400:hover{--tw-gradient-from:#22d3ee var(--tw-gradient-from-position);--tw-gradient-to:rgb(34 211 238 / 0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to)}.hover\:to-blue-500:hover{--tw-gradient-to:#3b82f6 var(--tw-gradient-to-position)}.hover\:text-white:hover{--tw-text-opacity:1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.focus\:border-cyan-500:focus{--tw-border-opacity:1;border-color:rgb(6 182 212 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.active\:scale-95:active{--tw-scale-x:.95;--tw-scale-y:.95;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@media (min-width: 640px){.sm\:right-4{right:1rem}.sm\:top-4{top:1rem}.sm\:my-4{margin-top:1rem;margin-bottom:1rem}.sm\:mb-4{margin-bottom:1rem}.sm\:mb-6{margin-bottom:1.5rem}.sm\:h-20{height:5rem}.sm\:h-24{height:6rem}.sm\:min-h-\[380px\]{min-height:380px}.sm\:w-\[450px\]{width:450px}.sm\:w-20{width:5rem}.sm\:flex-row{flex-direction:row}.sm\:gap-6{gap:1.5rem}.sm\:rounded-2xl{border-radius:1rem}.sm\:rounded-xl{border-radius:0.75rem}.sm\:p-5{padding:1.25rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-8{padding-top:2rem;padding-bottom:2rem}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:py-2\.5{padding-top:0.625rem;padding-bottom:0.625rem}.sm\:pt-12{padding-top:3rem}.sm\:text-4xl{font-size:2.25rem;line-height:2.5rem}.sm\:text-sm{font-size:0.875rem;line-height:1.25rem}.sm\:text-lg{font-size:1.125rem;line-height:1.75rem}.sm\:text-xs{font-size:0.75rem;line-height:1rem}}@media (min-width: 768px){.md\:my-6{margin-top:1.5rem;margin-bottom:1.5rem}.md\:h-24{height:6rem}.md\:min-h-\[420px\]{min-height:420px}.md\:w-24{width:6rem}.md\:gap-8{gap:2rem}.md\:p-6{padding:1.5rem}.md\:text-5xl{font-size:3rem;line-height:1}.md\:text-sm{font-size:0.875rem;line-height:1.25rem}.md\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media (min-width: 1024px){.lg\:grid-cols-4{grid-template-columns:repeat(4, minmax(0, 1fr))}}
USER JOURNEY
Move More Hub
01
Inscription
Free
Credits
Visual sign-up bonus sur Free Credits
Sign up
02
Le Comptoir
%
Credit pack companies sur degressive pricing
Le Comptoir
03
Réservation
GAME
DAYS
KEEP
UP
Dynamic event booking on Keep Up challenges
Réservation
04
Progression
LEVEL
UP
Personal growth and achievement in this program.
Progression
© 2026 Move More Hub. Conçu pour tous supports.
const journeyData = [
{
id: 1,
title: "Inscription",
desc: "Visual sign-up bonus sur Free Credits",
btnText: "Sign up",
accentColor: "#06b6d4",
iconSvg: ``
},
{
id: 2,
title: "Le Comptoir",
desc: "Credit pack companies sur degressive pricing",
btnText: "Le Comptoir",
accentColor: "#a855f7",
iconSvg: ``
},
{
id: 3,
title: "Réservation",
desc: "Dynamic event booking on Keep Up challenges",
btnText: "Réservation",
accentColor: "#06b6d4",
iconSvg: ``
},
{
id: 4,
title: "Progression",
desc: "Personal growth and achievement in this program.",
btnText: "Progression",
accentColor: "#a855f7",
iconSvg: ``
}
];
// Rendu des cartes et rafraîchissement des liaisons
function renderCards() {
const container = document.getElementById('cards-container');
container.innerHTML = '';
journeyData.forEach((card, index) => {
const cardHtml = `
defs.innerHTML = '';
// Créer les dégradés dynamiques d'une carte vers la suivante
for (let i = 0; i < journeyData.length - 1; i++) {
const card1Data = journeyData[i];
const card2Data = journeyData[i+1];
const gradientId = `dyn-gradient-${i}`;
const linearGrad = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
linearGrad.setAttribute("id", gradientId);
linearGrad.setAttribute("x1", "0%");
linearGrad.setAttribute("y1", "0%");
linearGrad.setAttribute("x2", "100%");
linearGrad.setAttribute("y2", "0%");
const stop1 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
stop1.setAttribute("offset", "0%");
stop1.setAttribute("stop-color", card1Data.accentColor);
const stop2 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
stop2.setAttribute("offset", "100%");
stop2.setAttribute("stop-color", card2Data.accentColor);
linearGrad.appendChild(stop1);
linearGrad.appendChild(stop2);
defs.appendChild(linearGrad);
// Assigner le nouveau dégradé au chemin correspondant
if (paths[i]) {
paths[i].setAttribute('stroke', `url(#${gradientId})`);
}
}
// Réinitialise le tracé des lignes
paths.forEach(p => p?.setAttribute('d', ''));
if (cards.length < 2) return;
// Calcule la courbe d'une carte à la suivante par rapport à la grille parente
for (let i = 0; i < cards.length - 1; i++) {
const card1 = cards[i];
const card2 = cards[i+1];
const path = paths[i];
if (!card1 || !card2 || !path) continue;
// Récupération des positions physiques réelles
const r1 = card1.getBoundingClientRect();
const r2 = card2.getBoundingClientRect();
// Positions calculées relativement au conteneur principal
const x1_right = (r1.right - rect.left);
const y1_center = (r1.top + r1.height / 2 - rect.top);
const x1_center = (r1.left + r1.width / 2 - rect.left);
const y1_bottom = (r1.bottom - rect.top);
const x2_left = (r2.left - rect.left);
const y2_center = (r2.top + r2.height / 2 - rect.top);
const x2_center = (r2.left + r2.width / 2 - rect.left);
const y2_top = (r2.top - rect.top);
let d = '';
// Cas A : Les cartes sont sur la même ligne horizontale (mode Desktop)
if (r2.left > r1.right - 10) {
const startX = x1_right;
const startY = y1_center;
const endX = x2_left;
const endY = y2_center;
const cpX1 = startX + (endX - startX) * 0.4;
const cpY1 = startY;
const cpX2 = startX + (endX - startX) * 0.6;
const cpY2 = endY;
d = `M ${startX} ${startY} C ${cpX1} ${cpY1}, ${cpX2} ${cpY2}, ${endX} ${endY}`;
}
// Cas B : Retour à la ligne (mode Mobile / Tablette)
else {
const startX = x1_center;
const startY = y1_bottom;
const endX = x2_center;
const endY = y2_top;
const cpY1 = startY + (endY - startY) * 0.4;
const cpX1 = startX;
const cpY2 = startY + (endY - startY) * 0.6;
const cpX2 = endX;
d = `M ${startX} ${startY} C ${cpX1} ${cpY1}, ${cpX2} ${cpY2}, ${endX} ${endY}`;
}
path.setAttribute('d', d);
}
}
// Rendu de l'éditeur de contenu interactif
function renderEditor() {
const editorList = document.getElementById('card-editors-list');
editorList.innerHTML = '';
document.getElementById('input-header-subtitle').value = document.getElementById('header-subtitle').innerText;
document.getElementById('input-header-title').value = document.getElementById('header-title').innerText;
journeyData.forEach((card, idx) => {
const cardEditorHtml = `
`;
editorList.innerHTML += cardEditorHtml;
});
}
// Fonctions réactives de l'éditeur
function updateHeader() {
document.getElementById('header-subtitle').innerText = document.getElementById('input-header-subtitle').value;
document.getElementById('header-title').innerText = document.getElementById('input-header-title').value;
}
function updateBgColor(colorVal) {
document.body.style.backgroundColor = colorVal;
document.getElementById('input-bg-color').value = colorVal;
document.getElementById('input-bg-text').value = colorVal;
}
function updateCardText(id, field, value) {
const card = journeyData.find(c => c.id === id);
if (card) {
card[field] = value;
renderCards();
}
}
function updateCardColor(id, color) {
const card = journeyData.find(c => c.id === id);
if (card) {
card.accentColor = color;
renderCards();
renderEditor();
}
}
function toggleEditor() {
const panel = document.getElementById('editor-panel');
panel.classList.toggle('translate-x-full');
}
function copyHTML() {
const clonedDoc = document.documentElement.cloneNode(true);
const editorInClone = clonedDoc.querySelector('#editor-panel');
const editBtnInClone = clonedDoc.querySelector('button[onclick="toggleEditor()"]');
if (editorInClone) editorInClone.remove();
if (editBtnInClone) editBtnInClone.remove();
const cleanHtmlStr = clonedDoc.outerHTML;
const textarea = document.createElement('textarea');
textarea.value = cleanHtmlStr;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
const status = document.getElementById('copy-status');
status.classList.remove('opacity-0');
status.classList.add('opacity-100');
setTimeout(() => {
status.classList.remove('opacity-100');
status.classList.add('opacity-0');
}, 3000);
}
// Écouter le redimensionnement et le chargement d'images/polices pour recalculer les coordonnées
window.addEventListener('resize', drawConnections);
window.addEventListener('load', drawConnections);
window.onload = function() {
renderCards();
renderEditor();
};
0${index + 1}
`;
container.innerHTML += cardHtml;
});
// Laisse le temps au DOM de se positionner avant de calculer les raccordements
setTimeout(drawConnections, 100);
}
// Calcul dynamique et tracé parfait des lignes de connexion
function drawConnections() {
const container = document.getElementById('grid-container');
const svg = document.getElementById('connection-svg');
const defs = document.getElementById('svg-defs');
if (!container || !svg || !defs) return;
// Ajuste l'échelle interne du SVG au conteneur réel
const rect = container.getBoundingClientRect();
svg.setAttribute('width', rect.width);
svg.setAttribute('height', rect.height);
svg.setAttribute('viewBox', `0 0 ${rect.width} ${rect.height}`);
const cards = container.querySelectorAll('.glass-card');
const paths = [
document.getElementById('path-1'),
document.getElementById('path-2'),
document.getElementById('path-3')
];
// Vider les anciens gradients dans ${card.title}
${card.iconSvg}
${card.desc}
CARTE 0${idx + 1}
Changer notre approche du sport
From retirement planning, investment strategies, tax optimization, to estate planning, we offer bespoke solutions tailored to your unique circumstances.
Ecouter les besoins réels
From retirement planning, investment strategies, tax optimization, to estate planning, we offer bespoke solutions tailored to your unique circumstances.
Rompre avec les illogismes de l’activité physique
From retirement planning, investment strategies, tax optimization, to estate planning, we offer bespoke solutions tailored to your unique circumstances.
pratiquer à nouveau ensemble
From retirement planning, investment strategies, tax optimization, to estate planning, we offer bespoke solutions tailored to your unique circumstances.
100 façons de bouger autrement
et durablement
Activités encadrées
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sed finibus nisi, sed dictum eros.
Semi autonomie
Quisque aliquet velit sit amet sem interdum faucibus. In feugiat aliquet mollis etiam tincidunt ligula.
Activités en autonomie
Luctus lectus non quisque turpis bibendum posuere. Morbi tortor nibh, fringilla sed pretium sit amet.
Evolving with Monitoring and Rebalancing
Your financial voyage is an ongoing process. Regular evaluations of your mutual fund investments are pivotal to ensure alignment with your objectives. Fluctuations in market values necessitate periodic rebalancing for optimal risk and return management.



